Skip to content

Instantly share code, notes, and snippets.

@zenofile
Created September 27, 2020 15:11
Show Gist options
  • Select an option

  • Save zenofile/9b37e338470f8c34a3643730dedc1e1f to your computer and use it in GitHub Desktop.

Select an option

Save zenofile/9b37e338470f8c34a3643730dedc1e1f to your computer and use it in GitHub Desktop.
Populates a pi-hole group with adlists from firebog
#!/bin/bash
# This idempotent script populates a pi-hole group with adlists
# from firebog (https://v.firebog.net/hosts/lists.php)
#
# By default, 'nocross' is used, unless specified otherwise by the
# first argument (tick, nocross, all).
# The group is created and enabled automatically and each script
# invocation will update this group.
set -ou pipefail
MYTMP=$(mktemp -qd)
LIST=${MYTMP}/firebog.list
(( $# < 1 )) && set -- 'nocross'
log () {
printf '%s\n' "$*" >&2
}
error() {
log "$*"
exit 1
}
cleanup() {
# avoid rm -rf
rm -f "${LIST}"
rmdir --ignore-fail-on-non-empty "${MYTMP}"
}
validate() {
zero_len() { printf '%u' 0; }
# try http if https fails
local header url
url=$1
if ! header=$(curl --silent --fail --head -- "${url}"); then
log "!!URL IS INVALID!!: ${url}"
zero_len
return
fi
# connected but no valid header, shouldn't happen
if [[ -z $header ]]; then
log "!!NO VALID HEADER!!: ${url}"
zero_len
return
fi
# get the actual body size (http1.1/TE=chunked and http2 compatible)
local len
if ! len=$(curl --silent --fail --write-out '%{size_download}' -o /dev/null -- "${url}"); then
# this should never happen
log "!!NO VALID BODY!!: ${url}"
zero_len
return
fi
# extract content-length, lines are \r\n terminated
#local len=$(printf '%s' "${header}" | awk 'BEGIN {RS="\r\n";FS=": ";IGNORECASE=1};/^Content-Length/{print $2}')
# no valid content-length
if [[ -z $len || ! $len =~ ^[0-9]+$ ]]; then
log "!!NO VALID CONTENT-LENGTH!!: ${1}"
zero_len
return
fi
# print content-length
printf '%u' "${len}"
}
trap 'cleanup' EXIT
if ! curl --silent --fail --output "$LIST" -- "https://v.firebog.net/hosts/lists.php?type=${1}"; then
error "Error downloading list."
fi
if [[ -s $LIST ]]; then
# determine and wipe firebog group, firebog-{list}
group_id=$(sqlite3 /etc/pihole/gravity.db "SELECT id FROM 'group' WHERE name LIKE 'firebog-${1}';")
if [[ -z $group_id ]]; then
error "Firebog group not found. Nothing changed."
fi
sudo sqlite3 /etc/pihole/gravity.db "DELETE FROM adlist WHERE id in ( SELECT adlist_id FROM adlist_by_group WHERE group_id = \"$group_id\" );"
# create new default group entries
while read -r url
do
len=$(validate "${url}")
if (( len <= 0 )); then
# try http fallback
url=$(printf '%s' "${url}" | sed 's/^https/http/')
log "!!HTTP FALLBACK!!: ${url}"
len=$(validate "${url}")
if (( len <= 0 )); then
# still no luck, skip
log "!!FALLBACK FAILED!!: skipping"
continue
fi
fi
printf "%s: (%u)\n" "${url}" "${len}"
sudo sqlite3 /etc/pihole/gravity.db "INSERT OR IGNORE INTO adlist (address, comment, enabled) VALUES (\"${url}\", 'firebog-${1} (' || datetime('now','localtime') || ')', 1); UPDATE adlist_by_group SET group_id = \"$group_id\" WHERE adlist_id = last_insert_rowid();"
unset entry
done < "$LIST"
else
error "List is empty."
fi
pihole restartdns reload-lists
#EOF
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment