Merge branch 'development' into new/whitelist-regex-support

Signed-off-by: DL6ER <dl6er@dl6er.de>
This commit is contained in:
DL6ER 2019-08-22 14:19:51 +02:00
commit 1820c2c598
No known key found for this signature in database
GPG key ID: FB60471F0575164A
12 changed files with 151 additions and 34 deletions

4
.github/FUNDING.yml vendored Normal file
View file

@ -0,0 +1,4 @@
# These are supported funding model platforms
patreon: pihole
custom: https://pi-hole.net/donate

View file

@ -11,9 +11,12 @@
# Please see LICENSE file for your rights under this license. # Please see LICENSE file for your rights under this license.
upgrade_gravityDB(){ upgrade_gravityDB(){
local database auditFile version local database piholeDir auditFile version
database="${1}" database="${1}"
auditFile="${2}" piholeDir="${2}"
auditFile="${piholeDir}/auditlog.list"
# Get database version
version="$(sqlite3 "${database}" "SELECT \"value\" FROM \"info\" WHERE \"property\" = 'version';")" version="$(sqlite3 "${database}" "SELECT \"value\" FROM \"info\" WHERE \"property\" = 'version';")"
if [[ "$version" == "1" ]]; then if [[ "$version" == "1" ]]; then

View file

@ -94,7 +94,35 @@ PIHOLE_RAW_BLOCKLIST_FILES="${PIHOLE_DIRECTORY}/list.*"
PIHOLE_LOCAL_HOSTS_FILE="${PIHOLE_DIRECTORY}/local.list" PIHOLE_LOCAL_HOSTS_FILE="${PIHOLE_DIRECTORY}/local.list"
PIHOLE_LOGROTATE_FILE="${PIHOLE_DIRECTORY}/logrotate" PIHOLE_LOGROTATE_FILE="${PIHOLE_DIRECTORY}/logrotate"
PIHOLE_SETUP_VARS_FILE="${PIHOLE_DIRECTORY}/setupVars.conf" PIHOLE_SETUP_VARS_FILE="${PIHOLE_DIRECTORY}/setupVars.conf"
PIHOLE_GRAVITY_DB_FILE="${PIHOLE_DIRECTORY}/gravity.db" PIHOLE_FTL_CONF_FILE="${PIHOLE_DIRECTORY}/pihole-FTL.conf"
# Read the value of an FTL config key. The value is printed to stdout.
#
# Args:
# 1. The key to read
# 2. The default if the setting or config does not exist
get_ftl_conf_value() {
local key=$1
local default=$2
local value
# Obtain key=... setting from pihole-FTL.conf
if [[ -e "$PIHOLE_FTL_CONF_FILE" ]]; then
# Constructed to return nothing when
# a) the setting is not present in the config file, or
# b) the setting is commented out (e.g. "#DBFILE=...")
value="$(sed -n -e "s/^\\s*$key=\\s*//p" ${PIHOLE_FTL_CONF_FILE})"
fi
# Test for missing value. Use default value in this case.
if [[ -z "$value" ]]; then
value="$default"
fi
echo "$value"
}
PIHOLE_GRAVITY_DB_FILE="$(get_ftl_conf_value "GRAVITYDB" "${PIHOLE_DIRECTORY}/gravity.db")"
PIHOLE_COMMAND="${BIN_DIRECTORY}/pihole" PIHOLE_COMMAND="${BIN_DIRECTORY}/pihole"
PIHOLE_COLTABLE_FILE="${BIN_DIRECTORY}/COL_TABLE" PIHOLE_COLTABLE_FILE="${BIN_DIRECTORY}/COL_TABLE"
@ -105,7 +133,7 @@ FTL_PORT="${RUN_DIRECTORY}/pihole-FTL.port"
PIHOLE_LOG="${LOG_DIRECTORY}/pihole.log" PIHOLE_LOG="${LOG_DIRECTORY}/pihole.log"
PIHOLE_LOG_GZIPS="${LOG_DIRECTORY}/pihole.log.[0-9].*" PIHOLE_LOG_GZIPS="${LOG_DIRECTORY}/pihole.log.[0-9].*"
PIHOLE_DEBUG_LOG="${LOG_DIRECTORY}/pihole_debug.log" PIHOLE_DEBUG_LOG="${LOG_DIRECTORY}/pihole_debug.log"
PIHOLE_FTL_LOG="${LOG_DIRECTORY}/pihole-FTL.log" PIHOLE_FTL_LOG="$(get_ftl_conf_value "LOGFILE" "${LOG_DIRECTORY}/pihole-FTL.log")"
PIHOLE_WEB_SERVER_ACCESS_LOG_FILE="${WEB_SERVER_LOG_DIRECTORY}/access.log" PIHOLE_WEB_SERVER_ACCESS_LOG_FILE="${WEB_SERVER_LOG_DIRECTORY}/access.log"
PIHOLE_WEB_SERVER_ERROR_LOG_FILE="${WEB_SERVER_LOG_DIRECTORY}/error.log" PIHOLE_WEB_SERVER_ERROR_LOG_FILE="${WEB_SERVER_LOG_DIRECTORY}/error.log"

View file

@ -115,7 +115,9 @@ scanDatabaseTable() {
wbMatch=true wbMatch=true
# Print table name # Print table name
echo " ${matchType^} found in ${COL_BOLD}${table^}${COL_NC}" if [[ -z "${blockpage}" ]]; then
echo " ${matchType^} found in ${COL_BOLD}${table^}${COL_NC}"
fi
# Loop over results and print them # Loop over results and print them
mapfile -t results <<< "${result}" mapfile -t results <<< "${result}"
@ -160,7 +162,7 @@ scanRegexDatabaseTable() {
# shellcheck disable=SC2001 # shellcheck disable=SC2001
echo "${str_result}" | sed 's/^/ /' echo "${str_result}" | sed 's/^/ /'
else else
echo "π Regex ${list}" echo "π .wildcard"
exit 0 exit 0
fi fi
fi fi

View file

@ -560,8 +560,7 @@ addAudit()
domains="" domains=""
for domain in "$@" for domain in "$@"
do do
# Insert only the domain here. The date_added field will be # Check domain to be added. Only continue if it is valid
# filled with its default value (date_added = current timestamp)
validDomain="$(checkDomain "${domain}")" validDomain="$(checkDomain "${domain}")"
if [[ -n "${validDomain}" ]]; then if [[ -n "${validDomain}" ]]; then
# Put comma in between domains when there is # Put comma in between domains when there is
@ -574,6 +573,8 @@ addAudit()
domains="${domains}('${domain}')" domains="${domains}('${domain}')"
fi fi
done done
# Insert only the domain here. The date_added field will be
# filled with its default value (date_added = current timestamp)
sqlite3 "${gravityDBfile}" "INSERT INTO domain_audit (domain) VALUES ${domains};" sqlite3 "${gravityDBfile}" "INSERT INTO domain_audit (domain) VALUES ${domains};"
} }

View file

@ -102,20 +102,30 @@ if ($blocklistglob === array()) {
die("[ERROR] There are no domain lists generated lists within <code>/etc/pihole/</code>! Please update gravity by running <code>pihole -g</code>, or repair Pi-hole using <code>pihole -r</code>."); die("[ERROR] There are no domain lists generated lists within <code>/etc/pihole/</code>! Please update gravity by running <code>pihole -g</code>, or repair Pi-hole using <code>pihole -r</code>.");
} }
// Set location of adlists file // Get possible non-standard location of FTL's database
if (is_file("/etc/pihole/adlists.list")) { $FTLsettings = parse_ini_file("/etc/pihole/pihole-FTL.conf");
$adLists = "/etc/pihole/adlists.list"; if (isset($FTLsettings["GRAVITYDB"])) {
} elseif (is_file("/etc/pihole/adlists.default")) { $gravityDBFile = $FTLsettings["GRAVITYDB"];
$adLists = "/etc/pihole/adlists.default";
} else { } else {
die("[ERROR] File not found: <code>/etc/pihole/adlists.list</code>"); $gravityDBFile = "/etc/pihole/gravity.db";
} }
// Get all URLs starting with "http" or "www" from adlists and re-index array numerically // Connect to gravity.db
$adlistsUrls = array_values(preg_grep("/(^http)|(^www)/i", file($adLists, FILE_IGNORE_NEW_LINES))); try {
$db = new SQLite3($gravityDBFile, SQLITE3_OPEN_READONLY);
} catch (Exception $exception) {
die("[ERROR]: Failed to connect to gravity.db");
}
// Get all adlist addresses
$adlistResults = $db->query("SELECT address FROM vw_adlist");
$adlistsUrls = array();
while ($row = $adlistResults->fetchArray()) {
array_push($adlistsUrls, $row[0]);
}
if (empty($adlistsUrls)) if (empty($adlistsUrls))
die("[ERROR]: There are no adlist URL's found within <code>$adLists</code>"); die("[ERROR]: There are no adlists enabled");
// Get total number of blocklists (Including Whitelist, Blacklist & Wildcard lists) // Get total number of blocklists (Including Whitelist, Blacklist & Wildcard lists)
$adlistsCount = count($adlistsUrls) + 3; $adlistsCount = count($adlistsUrls) + 3;

View file

@ -27,7 +27,7 @@ server.modules = (
) )
server.document-root = "/var/www/html" server.document-root = "/var/www/html"
server.error-handler-404 = "pihole/index.php" server.error-handler-404 = "/pihole/index.php"
server.upload-dirs = ( "/var/cache/lighttpd/uploads" ) server.upload-dirs = ( "/var/cache/lighttpd/uploads" )
server.errorlog = "/var/log/lighttpd/error.log" server.errorlog = "/var/log/lighttpd/error.log"
server.pid-file = "/var/run/lighttpd.pid" server.pid-file = "/var/run/lighttpd.pid"

View file

@ -28,7 +28,7 @@ server.modules = (
) )
server.document-root = "/var/www/html" server.document-root = "/var/www/html"
server.error-handler-404 = "pihole/index.php" server.error-handler-404 = "/pihole/index.php"
server.upload-dirs = ( "/var/cache/lighttpd/uploads" ) server.upload-dirs = ( "/var/cache/lighttpd/uploads" )
server.errorlog = "/var/log/lighttpd/error.log" server.errorlog = "/var/log/lighttpd/error.log"
server.pid-file = "/var/run/lighttpd.pid" server.pid-file = "/var/run/lighttpd.pid"

View file

@ -84,8 +84,13 @@ if [ -z "${USER}" ]; then
fi fi
# Find the rows and columns will default to 80x24 if it can not be detected # Check if we are running on a real terminal and find the rows and columns
screen_size=$(stty size || printf '%d %d' 24 80) # If there is no real terminal, we will default to 80x24
if [ -t 0 ] ; then
screen_size=$(stty size)
else
screen_size="24 80"
fi
# Set rows variable to contain first number # Set rows variable to contain first number
printf -v rows '%d' "${screen_size%% *}" printf -v rows '%d' "${screen_size%% *}"
# Set columns variable to contain second number # Set columns variable to contain second number
@ -283,7 +288,7 @@ elif is_command rpm ; then
UPDATE_PKG_CACHE=":" UPDATE_PKG_CACHE=":"
PKG_INSTALL=("${PKG_MANAGER}" install -y) PKG_INSTALL=("${PKG_MANAGER}" install -y)
PKG_COUNT="${PKG_MANAGER} check-update | egrep '(.i686|.x86|.noarch|.arm|.src)' | wc -l" PKG_COUNT="${PKG_MANAGER} check-update | egrep '(.i686|.x86|.noarch|.arm|.src)' | wc -l"
INSTALLER_DEPS=(dialog git iproute newt procps-ng which) INSTALLER_DEPS=(dialog git iproute newt procps-ng which chkconfig)
PIHOLE_DEPS=(bind-utils cronie curl findutils nmap-ncat sudo unzip wget libidn2 psmisc sqlite libcap) PIHOLE_DEPS=(bind-utils cronie curl findutils nmap-ncat sudo unzip wget libidn2 psmisc sqlite libcap)
PIHOLE_WEB_DEPS=(lighttpd lighttpd-fastcgi php-common php-cli php-pdo) PIHOLE_WEB_DEPS=(lighttpd lighttpd-fastcgi php-common php-cli php-pdo)
LIGHTTPD_USER="lighttpd" LIGHTTPD_USER="lighttpd"
@ -934,7 +939,7 @@ valid_ip() {
# and set the new one to a dot (period) # and set the new one to a dot (period)
IFS='.' IFS='.'
# Put the IP into an array # Put the IP into an array
ip=("${ip}") read -r -a ip <<< "${ip}"
# Restore the IFS to what it was # Restore the IFS to what it was
IFS=${OIFS} IFS=${OIFS}
## Evaluate each octet by checking if it's less than or equal to 255 (the max for each octet) ## Evaluate each octet by checking if it's less than or equal to 255 (the max for each octet)
@ -1177,12 +1182,11 @@ chooseBlocklists() {
mv "${adlistFile}" "${adlistFile}.old" mv "${adlistFile}" "${adlistFile}.old"
fi fi
# Let user select (or not) blocklists via a checklist # Let user select (or not) blocklists via a checklist
cmd=(whiptail --separate-output --checklist "Pi-hole relies on third party lists in order to block ads.\\n\\nYou can use the suggestions below, and/or add your own after installation\\n\\nTo deselect any list, use the arrow keys and spacebar" "${r}" "${c}" 7) cmd=(whiptail --separate-output --checklist "Pi-hole relies on third party lists in order to block ads.\\n\\nYou can use the suggestions below, and/or add your own after installation\\n\\nTo deselect any list, use the arrow keys and spacebar" "${r}" "${c}" 6)
# In an array, show the options available (all off by default): # In an array, show the options available (all off by default):
options=(StevenBlack "StevenBlack's Unified Hosts List" on options=(StevenBlack "StevenBlack's Unified Hosts List" on
MalwareDom "MalwareDomains" on MalwareDom "MalwareDomains" on
Cameleon "Cameleon" on Cameleon "Cameleon" on
ZeusTracker "ZeusTracker" on
DisconTrack "Disconnect.me Tracking" on DisconTrack "Disconnect.me Tracking" on
DisconAd "Disconnect.me Ads" on DisconAd "Disconnect.me Ads" on
HostsFile "Hosts-file.net Ads" on) HostsFile "Hosts-file.net Ads" on)
@ -1205,7 +1209,6 @@ appendToListsFile() {
StevenBlack ) echo "https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts" >> "${adlistFile}";; StevenBlack ) echo "https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts" >> "${adlistFile}";;
MalwareDom ) echo "https://mirror1.malwaredomains.com/files/justdomains" >> "${adlistFile}";; MalwareDom ) echo "https://mirror1.malwaredomains.com/files/justdomains" >> "${adlistFile}";;
Cameleon ) echo "http://sysctl.org/cameleon/hosts" >> "${adlistFile}";; Cameleon ) echo "http://sysctl.org/cameleon/hosts" >> "${adlistFile}";;
ZeusTracker ) echo "https://zeustracker.abuse.ch/blocklist.php?download=domainblocklist" >> "${adlistFile}";;
DisconTrack ) echo "https://s3.amazonaws.com/lists.disconnect.me/simple_tracking.txt" >> "${adlistFile}";; DisconTrack ) echo "https://s3.amazonaws.com/lists.disconnect.me/simple_tracking.txt" >> "${adlistFile}";;
DisconAd ) echo "https://s3.amazonaws.com/lists.disconnect.me/simple_ad.txt" >> "${adlistFile}";; DisconAd ) echo "https://s3.amazonaws.com/lists.disconnect.me/simple_ad.txt" >> "${adlistFile}";;
HostsFile ) echo "https://hosts-file.net/ad_servers.txt" >> "${adlistFile}";; HostsFile ) echo "https://hosts-file.net/ad_servers.txt" >> "${adlistFile}";;
@ -1223,7 +1226,6 @@ installDefaultBlocklists() {
appendToListsFile StevenBlack appendToListsFile StevenBlack
appendToListsFile MalwareDom appendToListsFile MalwareDom
appendToListsFile Cameleon appendToListsFile Cameleon
appendToListsFile ZeusTracker
appendToListsFile DisconTrack appendToListsFile DisconTrack
appendToListsFile DisconAd appendToListsFile DisconAd
appendToListsFile HostsFile appendToListsFile HostsFile
@ -2402,8 +2404,16 @@ FTLcheckUpdate() {
if [[ ${ftlLoc} ]]; then if [[ ${ftlLoc} ]]; then
local FTLversion local FTLversion
FTLversion=$(/usr/bin/pihole-FTL tag) FTLversion=$(/usr/bin/pihole-FTL tag)
local FTLreleaseData
local FTLlatesttag local FTLlatesttag
FTLlatesttag=$(curl -sI https://github.com/pi-hole/FTL/releases/latest | grep 'Location' | awk -F '/' '{print $NF}' | tr -d '\r\n')
if ! FTLreleaseData=$(curl -sI https://github.com/pi-hole/FTL/releases/latest); then
# There was an issue while retrieving the latest version
printf " %b Failed to retrieve latest FTL release metadata" "${CROSS}"
return 3
fi
FTLlatesttag=$(grep 'Location' < "${FTLreleaseData}" | awk -F '/' '{print $NF}' | tr -d '\r\n')
if [[ "${FTLversion}" != "${FTLlatesttag}" ]]; then if [[ "${FTLversion}" != "${FTLlatesttag}" ]]; then
return 0 return 0

View file

@ -30,7 +30,6 @@ whitelistFile="${piholeDir}/whitelist.txt"
blacklistFile="${piholeDir}/blacklist.txt" blacklistFile="${piholeDir}/blacklist.txt"
regexFile="${piholeDir}/regex.list" regexFile="${piholeDir}/regex.list"
adListFile="${piholeDir}/adlists.list" adListFile="${piholeDir}/adlists.list"
auditFile="${piholeDir}/auditlog.list"
localList="${piholeDir}/local.list" localList="${piholeDir}/local.list"
VPNList="/etc/openvpn/ipp.txt" VPNList="/etc/openvpn/ipp.txt"
@ -127,8 +126,8 @@ database_table_from_file() {
do do
# Only add non-empty lines # Only add non-empty lines
if [[ -n "${domain}" ]]; then if [[ -n "${domain}" ]]; then
if [[ "${table}" == "auditlist" ]]; then if [[ "${table}" == "domain_audit" ]]; then
# Auditlist table format # domain_audit table format (no enable or modified fields)
echo "${rowid},\"${domain}\",${timestamp}" >> "${tmpFile}" echo "${rowid},\"${domain}\",${timestamp}" >> "${tmpFile}"
else else
# White-, black-, and regexlist format # White-, black-, and regexlist format
@ -194,7 +193,7 @@ migrate_to_database() {
fi fi
# Check if gravity database needs to be updated # Check if gravity database needs to be updated
upgrade_gravityDB "${gravityDBfile}" "${auditFile}" upgrade_gravityDB "${gravityDBfile}" "${piholeDir}"
} }
# Determine if DNS resolution is available before proceeding # Determine if DNS resolution is available before proceeding
@ -356,7 +355,7 @@ gravity_DownloadBlocklistFromUrl() {
else else
printf -v port "%s" "${PIHOLE_DNS_1#*#}" printf -v port "%s" "${PIHOLE_DNS_1#*#}"
fi fi
ip=$(dig "@${ip_addr}" -p "${port}" +short "${domain}") ip=$(dig "@${ip_addr}" -p "${port}" +short "${domain}" | tail -1)
if [[ $(echo "${url}" | awk -F '://' '{print $1}') = "https" ]]; then if [[ $(echo "${url}" | awk -F '://' '{print $1}') = "https" ]]; then
port=443; port=443;
else port=80 else port=80

View file

@ -1,4 +1,4 @@
FROM fedora:29 FROM fedora:30
ENV GITDIR /etc/.pihole ENV GITDIR /etc/.pihole
ENV SCRIPTDIR /opt/pihole ENV SCRIPTDIR /opt/pihole

View file

@ -486,6 +486,13 @@ def test_FTL_download_aarch64_no_errors(Pihole):
''' '''
confirms only aarch64 package is downloaded for FTL engine confirms only aarch64 package is downloaded for FTL engine
''' '''
# mock whiptail answers and ensure installer dependencies
mock_command('whiptail', {'*': ('', '0')}, Pihole)
Pihole.run('''
source /opt/pihole/basic-install.sh
distro_check
install_dependent_packages ${INSTALLER_DEPS[@]}
''')
download_binary = Pihole.run(''' download_binary = Pihole.run('''
source /opt/pihole/basic-install.sh source /opt/pihole/basic-install.sh
binary="pihole-FTL-aarch64-linux-gnu" binary="pihole-FTL-aarch64-linux-gnu"
@ -501,6 +508,13 @@ def test_FTL_download_unknown_fails_no_errors(Pihole):
''' '''
confirms unknown binary is not downloaded for FTL engine confirms unknown binary is not downloaded for FTL engine
''' '''
# mock whiptail answers and ensure installer dependencies
mock_command('whiptail', {'*': ('', '0')}, Pihole)
Pihole.run('''
source /opt/pihole/basic-install.sh
distro_check
install_dependent_packages ${INSTALLER_DEPS[@]}
''')
download_binary = Pihole.run(''' download_binary = Pihole.run('''
source /opt/pihole/basic-install.sh source /opt/pihole/basic-install.sh
binary="pihole-FTL-mips" binary="pihole-FTL-mips"
@ -519,6 +533,13 @@ def test_FTL_download_binary_unset_no_errors(Pihole):
''' '''
confirms unset binary variable does not download FTL engine confirms unset binary variable does not download FTL engine
''' '''
# mock whiptail answers and ensure installer dependencies
mock_command('whiptail', {'*': ('', '0')}, Pihole)
Pihole.run('''
source /opt/pihole/basic-install.sh
distro_check
install_dependent_packages ${INSTALLER_DEPS[@]}
''')
download_binary = Pihole.run(''' download_binary = Pihole.run('''
source /opt/pihole/basic-install.sh source /opt/pihole/basic-install.sh
create_pihole_user create_pihole_user
@ -679,3 +700,42 @@ def test_IPv6_ULA_GUA_test(Pihole):
''') ''')
expected_stdout = 'Found IPv6 ULA address, using it for blocking IPv6 ads' expected_stdout = 'Found IPv6 ULA address, using it for blocking IPv6 ads'
assert expected_stdout in detectPlatform.stdout assert expected_stdout in detectPlatform.stdout
def test_validate_ip_valid(Pihole):
'''
Given a valid IP address, valid_ip returns success
'''
output = Pihole.run('''
source /opt/pihole/basic-install.sh
valid_ip "192.168.1.1"
''')
assert output.rc == 0
def test_validate_ip_invalid_octet(Pihole):
'''
Given an invalid IP address (large octet), valid_ip returns an error
'''
output = Pihole.run('''
source /opt/pihole/basic-install.sh
valid_ip "1092.168.1.1"
''')
assert output.rc == 1
def test_validate_ip_invalid_letters(Pihole):
'''
Given an invalid IP address (contains letters), valid_ip returns an error
'''
output = Pihole.run('''
source /opt/pihole/basic-install.sh
valid_ip "not an IP"
''')
assert output.rc == 1