Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/pi-hole/pi-hole.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'advanced')
-rw-r--r--advanced/GIFs/25Bytes.gifbin35 -> 0 bytes
-rw-r--r--advanced/GIFs/26Bytes.gifbin26 -> 0 bytes
-rw-r--r--advanced/GIFs/37Bytes.gifbin37 -> 0 bytes
-rw-r--r--advanced/GIFs/43Bytes.gifbin43 -> 0 bytes
-rwxr-xr-xadvanced/Scripts/piholeDebug.sh153
-rwxr-xr-xadvanced/Scripts/query.sh64
-rwxr-xr-xadvanced/Scripts/setupLCD.sh74
-rwxr-xr-xadvanced/Scripts/updatecheck.sh69
-rwxr-xr-xadvanced/Scripts/utils.sh95
-rwxr-xr-xadvanced/Scripts/version.sh13
-rwxr-xr-xadvanced/Scripts/webpage.sh33
-rw-r--r--advanced/Templates/pihole-FTL.service60
-rw-r--r--advanced/bash-completion/pihole2
-rw-r--r--advanced/blockingpage.css455
-rw-r--r--advanced/cmdline.txt1
-rw-r--r--advanced/console-setup17
-rw-r--r--advanced/index.php375
-rw-r--r--advanced/lighttpd.conf.debian15
-rw-r--r--advanced/lighttpd.conf.fedora15
19 files changed, 322 insertions, 1119 deletions
diff --git a/advanced/GIFs/25Bytes.gif b/advanced/GIFs/25Bytes.gif
deleted file mode 100644
index 472727f2..00000000
--- a/advanced/GIFs/25Bytes.gif
+++ /dev/null
Binary files differ
diff --git a/advanced/GIFs/26Bytes.gif b/advanced/GIFs/26Bytes.gif
deleted file mode 100644
index 264e471a..00000000
--- a/advanced/GIFs/26Bytes.gif
+++ /dev/null
Binary files differ
diff --git a/advanced/GIFs/37Bytes.gif b/advanced/GIFs/37Bytes.gif
deleted file mode 100644
index b3aa80d8..00000000
--- a/advanced/GIFs/37Bytes.gif
+++ /dev/null
Binary files differ
diff --git a/advanced/GIFs/43Bytes.gif b/advanced/GIFs/43Bytes.gif
deleted file mode 100644
index 9884f476..00000000
--- a/advanced/GIFs/43Bytes.gif
+++ /dev/null
Binary files differ
diff --git a/advanced/Scripts/piholeDebug.sh b/advanced/Scripts/piholeDebug.sh
index 601677e2..6543efbb 100755
--- a/advanced/Scripts/piholeDebug.sh
+++ b/advanced/Scripts/piholeDebug.sh
@@ -332,17 +332,34 @@ compare_local_version_to_git_version() {
check_ftl_version() {
local ftl_name="FTL"
+ local FTL_VERSION FTL_COMMIT FTL_BRANCH
echo_current_diagnostic "${ftl_name} version"
# Use the built in command to check FTL's version
- FTL_VERSION=$(pihole-FTL version)
+ FTL_VERSION=$(pihole-FTL -vv | grep -m 1 Version | awk '{printf $2}')
+ FTL_BRANCH=$(pihole-FTL -vv | grep -m 1 Branch | awk '{printf $2}')
+ FTL_COMMIT=$(pihole-FTL -vv | grep -m 1 Commit | awk '{printf $2}')
+
# Compare the current FTL version to the remote version
if [[ "${FTL_VERSION}" == "$(pihole -v | awk '/FTL/ {print $6}' | cut -d ')' -f1)" ]]; then
# If they are the same, FTL is up-to-date
log_write "${TICK} ${ftl_name}: ${COL_GREEN}${FTL_VERSION}${COL_NC}"
else
# If not, show it in yellow, signifying there is an update
- log_write "${TICK} ${ftl_name}: ${COL_YELLOW}${FTL_VERSION}${COL_NC} (${FAQ_UPDATE_PI_HOLE})"
+ log_write "${INFO} ${ftl_name}: ${COL_YELLOW}${FTL_VERSION}${COL_NC} (${FAQ_UPDATE_PI_HOLE})"
+ fi
+
+ # If they use the master branch, they are on the stable codebase
+ if [[ "${FTL_BRANCH}" == "master" ]]; then
+ # so the color of the text is green
+ log_write "${INFO} Branch: ${COL_GREEN}${FTL_BRANCH}${COL_NC}"
+ # If it is any other branch, they are in a development branch
+ else
+ # So show that in yellow, signifying it's something to take a look at, but not a critical error
+ log_write "${INFO} Branch: ${COL_YELLOW}${FTL_BRANCH}${COL_NC} (${FAQ_CHECKOUT_COMMAND})"
fi
+
+ # echo the current commit
+ log_write "${INFO} Commit: ${FTL_COMMIT}"
}
# Checks the core version of the Pi-hole codebase
@@ -797,29 +814,13 @@ check_x_headers() {
# server is operating correctly
echo_current_diagnostic "Dashboard and block page"
# Use curl -I to get the header and parse out just the X-Pi-hole one
- local block_page
- block_page=$(curl -Is localhost | awk '/X-Pi-hole/' | tr -d '\r')
- # Do it for the dashboard as well, as the header is different than above
+ local full_curl_output_dashboard
local dashboard
- dashboard=$(curl -Is localhost/admin/ | awk '/X-Pi-hole/' | tr -d '\r')
+ full_curl_output_dashboard="$(curl -Is localhost/admin/)"
+ dashboard=$(echo "${full_curl_output_dashboard}" | awk '/X-Pi-hole/' | tr -d '\r')
# Store what the X-Header should be in variables for comparison later
- local block_page_working
- block_page_working="X-Pi-hole: A black hole for Internet advertisements."
local dashboard_working
dashboard_working="X-Pi-hole: The Pi-hole Web interface is working!"
- local full_curl_output_block_page
- full_curl_output_block_page="$(curl -Is localhost)"
- local full_curl_output_dashboard
- full_curl_output_dashboard="$(curl -Is localhost/admin/)"
- # If the X-header found by curl matches what is should be,
- if [[ $block_page == "$block_page_working" ]]; then
- # display a success message
- log_write "$TICK Block page X-Header: ${COL_GREEN}${block_page}${COL_NC}"
- else
- # Otherwise, show an error
- log_write "$CROSS Block page X-Header: ${COL_RED}X-Header does not match or could not be retrieved.${COL_NC}"
- log_write "${COL_RED}${full_curl_output_block_page}${COL_NC}"
- fi
# Same logic applies to the dashboard as above, if the X-Header matches what a working system should have,
if [[ $dashboard == "$dashboard_working" ]]; then
@@ -828,6 +829,7 @@ check_x_headers() {
else
# Otherwise, it's a failure since the X-Headers either don't exist or have been modified in some way
log_write "$CROSS Web interface X-Header: ${COL_RED}X-Header does not match or could not be retrieved.${COL_NC}"
+
log_write "${COL_RED}${full_curl_output_dashboard}${COL_NC}"
fi
}
@@ -1230,7 +1232,7 @@ check_dhcp_servers() {
OLD_IFS="$IFS"
IFS=$'\n'
local entries=()
- mapfile -t entries < <(pihole-FTL dhcp-discover)
+ mapfile -t entries < <(pihole-FTL dhcp-discover & spinner)
for line in "${entries[@]}"; do
log_write " ${line}"
@@ -1259,12 +1261,21 @@ show_messages() {
show_FTL_db_entries "Pi-hole diagnosis messages" "SELECT count (message) as count, datetime(max(timestamp),'unixepoch','localtime') as 'last timestamp', type, message, blob1, blob2, blob3, blob4, blob5 FROM message GROUP BY type, message, blob1, blob2, blob3, blob4, blob5;" "6 19 20 60 20 20 20 20 20"
}
+database_permissions() {
+ local permissions
+ permissions=$(ls -lhd "${1}")
+ log_write "${COL_GREEN}${permissions}${COL_NC}"
+}
+
analyze_gravity_list() {
echo_current_diagnostic "Gravity Database"
- local gravity_permissions
- gravity_permissions=$(ls -lhd "${PIHOLE_GRAVITY_DB_FILE}")
- log_write "${COL_GREEN}${gravity_permissions}${COL_NC}"
+ database_permissions "${PIHOLE_GRAVITY_DB_FILE}"
+
+ # if users want to check database integrity
+ if [[ "${CHECK_DATABASE}" = true ]]; then
+ database_integrity_check "${PIHOLE_FTL_DB_FILE}"
+ fi
show_db_entries "Info table" "SELECT property,value FROM info" "20 40"
gravity_updated_raw="$(pihole-FTL sqlite3 "${PIHOLE_GRAVITY_DB_FILE}" "SELECT value FROM info where property = 'updated'")"
@@ -1286,6 +1297,95 @@ analyze_gravity_list() {
IFS="$OLD_IFS"
}
+analyze_ftl_db() {
+ echo_current_diagnostic "Pi-hole FTL Query Database"
+ database_permissions "${PIHOLE_FTL_DB_FILE}"
+ # if users want to check database integrity
+ if [[ "${CHECK_DATABASE}" = true ]]; then
+ database_integrity_check "${PIHOLE_FTL_DB_FILE}"
+ fi
+}
+
+database_integrity_check(){
+ local result
+ local database="${1}"
+
+ log_write "${INFO} Checking integrity of ${database} ... (this can take several minutes)"
+ result="$(pihole-FTL "${database}" "PRAGMA integrity_check" 2>&1 & spinner)"
+ if [[ ${result} = "ok" ]]; then
+ log_write "${TICK} Integrity of ${database} intact"
+
+
+ log_write "${INFO} Checking foreign key constraints of ${database} ... (this can take several minutes)"
+ unset result
+ result="$(pihole-FTL sqlite3 "${database}" -cmd ".headers on" -cmd ".mode column" "PRAGMA foreign_key_check" 2>&1 & spinner)"
+ if [[ -z ${result} ]]; then
+ log_write "${TICK} No foreign key errors in ${database}"
+ else
+ log_write "${CROSS} ${COL_RED}Foreign key errors in ${database} found.${COL_NC}"
+ while IFS= read -r line ; do
+ log_write " $line"
+ done <<< "$result"
+ fi
+
+ else
+ log_write "${CROSS} ${COL_RED}Integrity errors in ${database} found.\n${COL_NC}"
+ while IFS= read -r line ; do
+ log_write " $line"
+ done <<< "$result"
+ fi
+
+}
+
+check_database_integrity() {
+ echo_current_diagnostic "Gravity Database"
+ database_permissions "${PIHOLE_GRAVITY_DB_FILE}"
+ database_integrity_check "${PIHOLE_GRAVITY_DB_FILE}"
+
+ echo_current_diagnostic "Pi-hole FTL Query Database"
+ database_permissions "${PIHOLE_FTL_DB_FILE}"
+ database_integrity_check "${PIHOLE_FTL_DB_FILE}"
+}
+
+# Show a text spinner during a long process run
+spinner(){
+ # Show the spinner only if there is a tty
+ if tty -s; then
+ # PID of the most recent background process
+ _PID=$!
+ _spin="/-\|"
+ _start=0
+ _elapsed=0
+ _i=1
+
+ # Start the counter
+ _start=$(date +%s)
+
+ # Hide the cursor
+ tput civis > /dev/tty
+
+ # ensures cursor is visible again, in case of premature exit
+ trap 'tput cnorm > /dev/tty' EXIT
+
+ while [ -d /proc/$_PID ]; do
+ _elapsed=$(( $(date +%s) - _start ))
+ # use hours only if needed
+ if [ "$_elapsed" -lt 3600 ]; then
+ printf "\r${_spin:_i++%${#_spin}:1} %02d:%02d" $((_elapsed/60)) $((_elapsed%60)) >"$(tty)"
+ else
+ printf "\r${_spin:_i++%${#_spin}:1} %02d:%02d:%02d" $((_elapsed/3600)) $(((_elapsed/60)%60)) $((_elapsed%60)) >"$(tty)"
+ fi
+ sleep 0.25
+ done
+
+ # Return to the begin of the line after completion (the spinner will be overwritten)
+ printf "\r" >"$(tty)"
+
+ # Restore cursor visibility
+ tput cnorm > /dev/tty
+ fi
+}
+
obfuscated_pihole_log() {
local pihole_log=("$@")
local line
@@ -1431,7 +1531,7 @@ upload_to_tricorder() {
if [[ "${WEBCALL}" ]] && [[ ! "${AUTOMATED}" ]]; then
:
else
- log_write "${CROSS} ${COL_RED}There was an error uploading your debug log.${COL_NC}"
+ log_write "${CROSS} ${COL_RED}There was an error uploading your debug log.${COL_NC}"
log_write " * Please try again or contact the Pi-hole team for assistance."
fi
fi
@@ -1460,6 +1560,7 @@ process_status
ftl_full_status
parse_setup_vars
check_x_headers
+analyze_ftl_db
analyze_gravity_list
show_groups
show_domainlist
diff --git a/advanced/Scripts/query.sh b/advanced/Scripts/query.sh
index 8f7bfea4..ae266ec0 100755
--- a/advanced/Scripts/query.sh
+++ b/advanced/Scripts/query.sh
@@ -16,7 +16,6 @@ GRAVITYDB="${piholeDir}/gravity.db"
options="$*"
all=""
exact=""
-blockpage=""
matchType="match"
# Source pihole-FTL from install script
pihole_FTL="${piholeDir}/pihole-FTL.conf"
@@ -34,7 +33,7 @@ source "${colfile}"
# Scan an array of files for matching strings
scanList(){
# Escape full stops
- local domain="${1}" esc_domain="${1//./\\.}" lists="${2}" type="${3:-}"
+ local domain="${1}" esc_domain="${1//./\\.}" lists="${2}" list_type="${3:-}"
# Prevent grep from printing file path
cd "$piholeDir" || exit 1
@@ -43,7 +42,7 @@ scanList(){
export LC_CTYPE=C
# /dev/null forces filename to be printed when only one list has been generated
- case "${type}" in
+ case "${list_type}" in
"exact" ) grep -i -E -l "(^|(?<!#)\\s)${esc_domain}($|\\s|#)" ${lists} /dev/null 2>/dev/null;;
# Iterate through each regexp and check whether it matches the domainQuery
# If it does, print the matching regexp and continue looping
@@ -71,18 +70,14 @@ Options:
fi
# Handle valid options
-if [[ "${options}" == *"-bp"* ]]; then
- exact="exact"; blockpage=true
-else
- [[ "${options}" == *"-all"* ]] && all=true
- if [[ "${options}" == *"-exact"* ]]; then
- exact="exact"; matchType="exact ${matchType}"
- fi
+[[ "${options}" == *"-all"* ]] && all=true
+if [[ "${options}" == *"-exact"* ]]; then
+ exact="exact"; matchType="exact ${matchType}"
fi
# Strip valid options, leaving only the domain and invalid options
# This allows users to place the options before or after the domain
-options=$(sed -E 's/ ?-(bp|adlists?|all|exact) ?//g' <<< "${options}")
+options=$(sed -E 's/ ?-(adlists?|all|exact) ?//g' <<< "${options}")
# Handle remaining options
# If $options contain non ASCII characters, convert to punycode
@@ -99,10 +94,10 @@ if [[ -n "${str:-}" ]]; then
fi
scanDatabaseTable() {
- local domain table type querystr result extra
+ local domain table list_type querystr result extra
domain="$(printf "%q" "${1}")"
table="${2}"
- type="${3:-}"
+ list_type="${3:-}"
# As underscores are legitimate parts of domains, we escape them when using the LIKE operator.
# Underscores are SQLite wildcards matching exactly one character. We obviously want to suppress this
@@ -115,8 +110,8 @@ scanDatabaseTable() {
esac
else
case "${exact}" in
- "exact" ) querystr="SELECT domain,enabled FROM domainlist WHERE type = '${type}' AND domain = '${domain}'";;
- * ) querystr="SELECT domain,enabled FROM domainlist WHERE type = '${type}' AND domain LIKE '%${domain//_/\\_}%' ESCAPE '\\'";;
+ "exact" ) querystr="SELECT domain,enabled FROM domainlist WHERE type = '${list_type}' AND domain = '${domain}'";;
+ * ) querystr="SELECT domain,enabled FROM domainlist WHERE type = '${list_type}' AND domain LIKE '%${domain//_/\\_}%' ESCAPE '\\'";;
esac
fi
@@ -136,17 +131,11 @@ scanDatabaseTable() {
wbMatch=true
# Print table name
- if [[ -z "${blockpage}" ]]; then
- echo " ${matchType^} found in ${COL_BOLD}exact ${table}${COL_NC}"
- fi
+ echo " ${matchType^} found in ${COL_BOLD}exact ${table}${COL_NC}"
# Loop over results and print them
mapfile -t results <<< "${result}"
for result in "${results[@]}"; do
- if [[ -n "${blockpage}" ]]; then
- echo "π ${result}"
- exit 0
- fi
domain="${result/|*}"
if [[ "${result#*|}" == "0" ]]; then
extra=" (disabled)"
@@ -158,13 +147,13 @@ scanDatabaseTable() {
}
scanRegexDatabaseTable() {
- local domain list
+ local domain list list_type
domain="${1}"
list="${2}"
- type="${3:-}"
+ list_type="${3:-}"
# Query all regex from the corresponding database tables
- mapfile -t regexList < <(pihole-FTL sqlite3 "${gravityDBfile}" "SELECT domain FROM domainlist WHERE type = ${type}" 2> /dev/null)
+ mapfile -t regexList < <(pihole-FTL sqlite3 "${gravityDBfile}" "SELECT domain FROM domainlist WHERE type = ${list_type}" 2> /dev/null)
# If we have regexps to process
if [[ "${#regexList[@]}" -ne 0 ]]; then
@@ -181,18 +170,13 @@ scanRegexDatabaseTable() {
# Form a "results" message
str_result="${COL_BOLD}${str_regexMatches}${COL_NC}"
# If we are displaying more than just the source of the block
- if [[ -z "${blockpage}" ]]; then
- # Set the wildcard match flag
- wcMatch=true
- # Echo the "matched" message, indented by one space
- echo " ${str_message}"
- # Echo the "results" message, each line indented by three spaces
- # shellcheck disable=SC2001
- echo "${str_result}" | sed 's/^/ /'
- else
- echo "π .wildcard"
- exit 0
- fi
+ # Set the wildcard match flag
+ wcMatch=true
+ # Echo the "matched" message, indented by one space
+ echo " ${str_message}"
+ # Echo the "results" message, each line indented by three spaces
+ # shellcheck disable=SC2001
+ echo "${str_result}" | sed 's/^/ /'
fi
fi
}
@@ -222,7 +206,7 @@ elif [[ -z "${all}" ]] && [[ "${#results[*]}" -ge 100 ]]; then
fi
# Print "Exact matches for" title
-if [[ -n "${exact}" ]] && [[ -z "${blockpage}" ]]; then
+if [[ -n "${exact}" ]]; then
plural=""; [[ "${#results[*]}" -gt 1 ]] && plural="es"
echo " ${matchType^}${plural} for ${COL_BOLD}${domainQuery}${COL_NC} found in:"
fi
@@ -238,9 +222,7 @@ for result in "${results[@]}"; do
extra=""
fi
- if [[ -n "${blockpage}" ]]; then
- echo "0 ${adlistAddress}"
- elif [[ -n "${exact}" ]]; then
+ if [[ -n "${exact}" ]]; then
echo " - ${adlistAddress}${extra}"
else
if [[ ! "${adlistAddress}" == "${adlistAddress_prev:-}" ]]; then
diff --git a/advanced/Scripts/setupLCD.sh b/advanced/Scripts/setupLCD.sh
deleted file mode 100755
index b4746dea..00000000
--- a/advanced/Scripts/setupLCD.sh
+++ /dev/null
@@ -1,74 +0,0 @@
-#!/usr/bin/env bash
-# Pi-hole: A black hole for Internet advertisements
-# (c) 2017 Pi-hole, LLC (https://pi-hole.net)
-# Network-wide ad blocking via your own hardware.
-#
-# Automatically configures the Pi to use the 2.8 LCD screen to display stats on it (also works over ssh)
-#
-# This file is copyright under the latest version of the EUPL.
-# Please see LICENSE file for your rights under this license.
-
-
-
-############ FUNCTIONS ###########
-
-# Borrowed from adafruit-pitft-helper < borrowed from raspi-config
-# https://github.com/adafruit/Adafruit-PiTFT-Helper/blob/master/adafruit-pitft-helper#L324-L334
-getInitSys() {
- if command -v systemctl > /dev/null && systemctl | grep -q '\-\.mount'; then
- SYSTEMD=1
- elif [ -f /etc/init.d/cron ] && [ ! -h /etc/init.d/cron ]; then
- SYSTEMD=0
- else
- echo "Unrecognized init system"
- return 1
- fi
-}
-
-# Borrowed from adafruit-pitft-helper:
-# https://github.com/adafruit/Adafruit-PiTFT-Helper/blob/master/adafruit-pitft-helper#L274-L285
-autoLoginPiToConsole() {
- if [ -e /etc/init.d/lightdm ]; then
- if [ ${SYSTEMD} -eq 1 ]; then
- systemctl set-default multi-user.target
- ln -fs /etc/systemd/system/autologin@.service /etc/systemd/system/getty.target.wants/getty@tty1.service
- else
- update-rc.d lightdm disable 2
- sed /etc/inittab -i -e "s/1:2345:respawn:\/sbin\/getty --noclear 38400 tty1/1:2345:respawn:\/bin\/login -f pi tty1 <\/dev\/tty1 >\/dev\/tty1 2>&1/"
- fi
- fi
-}
-
-######### SCRIPT ###########
-# Set pi to log in automatically
-getInitSys
-autoLoginPiToConsole
-
-# Set chronomter to run automatically when pi logs in
-echo /usr/local/bin/chronometer.sh >> /home/pi/.bashrc
-# OR
-#$SUDO echo /usr/local/bin/chronometer.sh >> /etc/profile
-
-# Set up the LCD screen based on Adafruits instructions:
-# https://learn.adafruit.com/adafruit-pitft-28-inch-resistive-touchscreen-display-raspberry-pi/easy-install
-curl -SLs https://apt.adafruit.com/add-pin | bash
-apt-get -y install raspberrypi-bootloader
-apt-get -y install adafruit-pitft-helper
-adafruit-pitft-helper -t 28r
-
-# Download the cmdline.txt file that prevents the screen from going blank after a period of time
-mv /boot/cmdline.txt /boot/cmdline.orig
-curl -o /boot/cmdline.txt https://raw.githubusercontent.com/pi-hole/pi-hole/master/advanced/cmdline.txt
-
-# Back up the original file and download the new one
-mv /etc/default/console-setup /etc/default/console-setup.orig
-curl -o /etc/default/console-setup https://raw.githubusercontent.com/pi-hole/pi-hole/master/advanced/console-setup
-
-# Instantly apply the font change to the LCD screen
-setupcon
-
-reboot
-
-# Start showing the stats on the screen by running the command on another tty:
-# https://unix.stackexchange.com/questions/170063/start-a-process-on-a-different-tty
-#setsid sh -c 'exec /usr/local/bin/chronometer.sh <> /dev/tty1 >&0 2>&1'
diff --git a/advanced/Scripts/updatecheck.sh b/advanced/Scripts/updatecheck.sh
index afb03ebb..37211cc6 100755
--- a/advanced/Scripts/updatecheck.sh
+++ b/advanced/Scripts/updatecheck.sh
@@ -8,23 +8,6 @@
# This file is copyright under the latest version of the EUPL.
# Please see LICENSE file for your rights under this license.
-# Credit: https://stackoverflow.com/a/46324904
-function json_extract() {
- local key=$1
- local json=$2
-
- local string_regex='"([^"\]|\\.)*"'
- local number_regex='-?(0|[1-9][0-9]*)(\.[0-9]+)?([eE][+-]?[0-9]+)?'
- local value_regex="${string_regex}|${number_regex}|true|false|null"
- local pair_regex="\"${key}\"[[:space:]]*:[[:space:]]*(${value_regex})"
-
- if [[ ${json} =~ ${pair_regex} ]]; then
- echo $(sed 's/^"\|"$//g' <<< "${BASH_REMATCH[1]}")
- else
- return 1
- fi
-}
-
function get_local_branch() {
# Return active branch
cd "${1}" 2> /dev/null || return 1
@@ -41,54 +24,64 @@ function get_local_version() {
# shellcheck disable=SC1091
. /etc/pihole/setupVars.conf
+# Source the utils file
+# shellcheck disable=SC1091
+. /opt/pihole/utils.sh
+
+# Remove the below three legacy files if they exist
+rm -f "/etc/pihole/GitHubVersions"
+rm -f "/etc/pihole/localbranches"
+rm -f "/etc/pihole/localversions"
+
+# Create new versions file if it does not exist
+VERSION_FILE="/etc/pihole/versions"
+touch "${VERSION_FILE}"
+chmod 644 "${VERSION_FILE}"
+
if [[ "$2" == "remote" ]]; then
if [[ "$3" == "reboot" ]]; then
sleep 30
fi
- GITHUB_VERSION_FILE="/etc/pihole/GitHubVersions"
-
- GITHUB_CORE_VERSION="$(json_extract tag_name "$(curl -s 'https://api.github.com/repos/pi-hole/pi-hole/releases/latest' 2> /dev/null)")"
- echo -n "${GITHUB_CORE_VERSION}" > "${GITHUB_VERSION_FILE}"
- chmod 644 "${GITHUB_VERSION_FILE}"
+ GITHUB_CORE_VERSION="$(curl -s 'https://api.github.com/repos/pi-hole/pi-hole/releases/latest' 2> /dev/null | jq --raw-output .tag_name)"
+ addOrEditKeyValPair "${VERSION_FILE}" "GITHUB_CORE_VERSION" "${GITHUB_CORE_VERSION}"
if [[ "${INSTALL_WEB_INTERFACE}" == true ]]; then
- GITHUB_WEB_VERSION="$(json_extract tag_name "$(curl -s 'https://api.github.com/repos/pi-hole/AdminLTE/releases/latest' 2> /dev/null)")"
- echo -n " ${GITHUB_WEB_VERSION}" >> "${GITHUB_VERSION_FILE}"
+ GITHUB_WEB_VERSION="$(curl -s 'https://api.github.com/repos/pi-hole/AdminLTE/releases/latest' 2> /dev/null | jq --raw-output .tag_name)"
+ addOrEditKeyValPair "${VERSION_FILE}" "GITHUB_WEB_VERSION" "${GITHUB_WEB_VERSION}"
fi
- GITHUB_FTL_VERSION="$(json_extract tag_name "$(curl -s 'https://api.github.com/repos/pi-hole/FTL/releases/latest' 2> /dev/null)")"
- echo -n " ${GITHUB_FTL_VERSION}" >> "${GITHUB_VERSION_FILE}"
+ GITHUB_FTL_VERSION="$(curl -s 'https://api.github.com/repos/pi-hole/FTL/releases/latest' 2> /dev/null | jq --raw-output .tag_name)"
+ addOrEditKeyValPair "${VERSION_FILE}" "GITHUB_FTL_VERSION" "${GITHUB_FTL_VERSION}"
-else
+ if [[ "${PIHOLE_DOCKER_TAG}" ]]; then
+ GITHUB_DOCKER_VERSION="$(curl -s 'https://api.github.com/repos/pi-hole/docker-pi-hole/releases/latest' 2> /dev/null | jq --raw-output .tag_name)"
+ addOrEditKeyValPair "${VERSION_FILE}" "GITHUB_DOCKER_VERSION" "${GITHUB_DOCKER_VERSION}"
+ fi
- LOCAL_BRANCH_FILE="/etc/pihole/localbranches"
+else
CORE_BRANCH="$(get_local_branch /etc/.pihole)"
- echo -n "${CORE_BRANCH}" > "${LOCAL_BRANCH_FILE}"
- chmod 644 "${LOCAL_BRANCH_FILE}"
+ addOrEditKeyValPair "${VERSION_FILE}" "CORE_BRANCH" "${CORE_BRANCH}"
if [[ "${INSTALL_WEB_INTERFACE}" == true ]]; then
WEB_BRANCH="$(get_local_branch /var/www/html/admin)"
- echo -n " ${WEB_BRANCH}" >> "${LOCAL_BRANCH_FILE}"
+ addOrEditKeyValPair "${VERSION_FILE}" "WEB_BRANCH" "${WEB_BRANCH}"
fi
FTL_BRANCH="$(pihole-FTL branch)"
- echo -n " ${FTL_BRANCH}" >> "${LOCAL_BRANCH_FILE}"
-
- LOCAL_VERSION_FILE="/etc/pihole/localversions"
+ addOrEditKeyValPair "${VERSION_FILE}" "FTL_BRANCH" "${FTL_BRANCH}"
CORE_VERSION="$(get_local_version /etc/.pihole)"
- echo -n "${CORE_VERSION}" > "${LOCAL_VERSION_FILE}"
- chmod 644 "${LOCAL_VERSION_FILE}"
+ addOrEditKeyValPair "${VERSION_FILE}" "CORE_VERSION" "${CORE_VERSION}"
if [[ "${INSTALL_WEB_INTERFACE}" == true ]]; then
WEB_VERSION="$(get_local_version /var/www/html/admin)"
- echo -n " ${WEB_VERSION}" >> "${LOCAL_VERSION_FILE}"
+ addOrEditKeyValPair "${VERSION_FILE}" "WEB_VERSION" "${WEB_VERSION}"
fi
FTL_VERSION="$(pihole-FTL version)"
- echo -n " ${FTL_VERSION}" >> "${LOCAL_VERSION_FILE}"
+ addOrEditKeyValPair "${VERSION_FILE}" "FTL_VERSION" "${FTL_VERSION}"
fi
diff --git a/advanced/Scripts/utils.sh b/advanced/Scripts/utils.sh
index cf24c098..a9e05692 100755
--- a/advanced/Scripts/utils.sh
+++ b/advanced/Scripts/utils.sh
@@ -71,28 +71,87 @@ removeKey() {
}
#######################
-# returns FTL's current telnet API port
+# returns path of FTL's port file
+#######################
+getFTLAPIPortFile() {
+ local FTLCONFFILE="/etc/pihole/pihole-FTL.conf"
+ local DEFAULT_PORT_FILE="/run/pihole-FTL.port"
+ local FTL_APIPORT_FILE
+
+ if [ -s "${FTLCONFFILE}" ]; then
+ # if PORTFILE is not set in pihole-FTL.conf, use the default path
+ FTL_APIPORT_FILE="$({ grep '^PORTFILE=' "${FTLCONFFILE}" || echo "${DEFAULT_PORT_FILE}"; } | cut -d'=' -f2-)"
+ else
+ # if there is no pihole-FTL.conf, use the default path
+ FTL_APIPORT_FILE="${DEFAULT_PORT_FILE}"
+ fi
+
+ echo "${FTL_APIPORT_FILE}"
+}
+
+
+#######################
+# returns FTL's current telnet API port based on the content of the pihole-FTL.port file
+#
+# Takes one argument: path to pihole-FTL.port
+# Example getFTLAPIPort "/run/pihole-FTL.port"
#######################
getFTLAPIPort(){
+ local PORTFILE="${1}"
+ local DEFAULT_FTL_PORT=4711
+ local ftl_api_port
+
+ if [ -s "$PORTFILE" ]; then
+ # -s: FILE exists and has a size greater than zero
+ ftl_api_port=$(cat "${PORTFILE}")
+ # Exploit prevention: unset the variable if there is malicious content
+ # Verify that the value read from the file is numeric
+ expr "$ftl_api_port" : "[^[:digit:]]" > /dev/null && unset ftl_api_port
+ fi
+
+ # echo the port found in the portfile or default to the default port
+ echo "${ftl_api_port:=$DEFAULT_FTL_PORT}"
+}
+
+#######################
+# returns path of FTL's PID file
+#######################
+getFTLPIDFile() {
local FTLCONFFILE="/etc/pihole/pihole-FTL.conf"
- local DEFAULT_PORT_FILE="/run/pihole-FTL.port"
- local DEFAULT_FTL_PORT=4711
- local PORTFILE
- local ftl_api_port
-
- if [ -f "$FTLCONFFILE" ]; then
- # if PORTFILE is not set in pihole-FTL.conf, use the default path
- PORTFILE="$( (grep "^PORTFILE=" $FTLCONFFILE || echo "$DEFAULT_PORT_FILE") | cut -d"=" -f2-)"
- fi
+ local DEFAULT_PID_FILE="/run/pihole-FTL.pid"
+ local FTL_PID_FILE
- if [ -s "$PORTFILE" ]; then
- # -s: FILE exists and has a size greater than zero
- ftl_api_port=$(cat "${PORTFILE}")
- # Exploit prevention: unset the variable if there is malicious content
- # Verify that the value read from the file is numeric
- expr "$ftl_api_port" : "[^[:digit:]]" > /dev/null && unset ftl_api_port
+ if [ -s "${FTLCONFFILE}" ]; then
+ # if PIDFILE is not set in pihole-FTL.conf, use the default path
+ FTL_PID_FILE="$({ grep '^PIDFILE=' "${FTLCONFFILE}" || echo "${DEFAULT_PID_FILE}"; } | cut -d'=' -f2-)"
+ else
+ # if there is no pihole-FTL.conf, use the default path
+ FTL_PID_FILE="${DEFAULT_PID_FILE}"
fi
- # echo the port found in the portfile or default to the default port
- echo "${ftl_api_port:=$DEFAULT_FTL_PORT}"
+ echo "${FTL_PID_FILE}"
+}
+
+#######################
+# returns FTL's PID based on the content of the pihole-FTL.pid file
+#
+# Takes one argument: path to pihole-FTL.pid
+# Example getFTLPID "/run/pihole-FTL.pid"
+#######################
+getFTLPID() {
+ local FTL_PID_FILE="${1}"
+ local FTL_PID
+
+ if [ -s "${FTL_PID_FILE}" ]; then
+ # -s: FILE exists and has a size greater than zero
+ FTL_PID="$(cat "${FTL_PID_FILE}")"
+ # Exploit prevention: unset the variable if there is malicious content
+ # Verify that the value read from the file is numeric
+ expr "${FTL_PID}" : "[^[:digit:]]" > /dev/null && unset FTL_PID
+ fi
+
+ # If FTL is not running, or the PID file contains malicious stuff, substitute
+ # negative PID to signal this
+ FTL_PID=${FTL_PID:=-1}
+ echo "${FTL_PID}"
}
diff --git a/advanced/Scripts/version.sh b/advanced/Scripts/version.sh
index 0b7b29dd..7f44d35e 100755
--- a/advanced/Scripts/version.sh
+++ b/advanced/Scripts/version.sh
@@ -89,17 +89,18 @@ getRemoteVersion(){
local daemon="${1}"
local version
local cachedVersions
- local arrCache
- cachedVersions="/etc/pihole/GitHubVersions"
+ cachedVersions="/etc/pihole/versions"
#If the above file exists, then we can read from that. Prevents overuse of GitHub API
if [[ -f "$cachedVersions" ]]; then
- IFS=' ' read -r -a arrCache < "$cachedVersions"
+
+ # shellcheck disable=SC1090
+ . "$cachedVersions"
case $daemon in
- "pi-hole" ) echo "${arrCache[0]}";;
- "AdminLTE" ) [[ "${INSTALL_WEB_INTERFACE}" == true ]] && echo "${arrCache[1]}";;
- "FTL" ) [[ "${INSTALL_WEB_INTERFACE}" == true ]] && echo "${arrCache[2]}" || echo "${arrCache[1]}";;
+ "pi-hole" ) echo "${GITHUB_CORE_VERSION}";;
+ "AdminLTE" ) [[ "${INSTALL_WEB_INTERFACE}" == true ]] && echo "${GITHUB_WEB_VERSION}";;
+ "FTL" ) echo "${GITHUB_FTL_VERSION}";;
esac
return 0
diff --git a/advanced/Scripts/webpage.sh b/advanced/Scripts/webpage.sh
index 29c53bd6..3ee48aef 100755
--- a/advanced/Scripts/webpage.sh
+++ b/advanced/Scripts/webpage.sh
@@ -46,7 +46,6 @@ Options:
-c, celsius Set Celsius as preferred temperature unit
-f, fahrenheit Set Fahrenheit as preferred temperature unit
-k, kelvin Set Kelvin as preferred temperature unit
- -e, email Set an administrative contact address for the Block Page
-h, --help Show this help dialog
-i, interface Specify dnsmasq's interface listening behavior
-l, privacylevel Set privacy level (0 = lowest, 3 = highest)
@@ -568,37 +567,6 @@ RemoveDHCPStaticAddress() {
}
-SetAdminEmail() {
- if [[ "${1}" == "-h" ]] || [[ "${1}" == "--help" ]]; then
- echo "Usage: pihole -a email <address>
-Example: 'pihole -a email admin@address.com'
-Set an administrative contact address for the Block Page
-
-Options:
- \"\" Empty: Remove admin contact
- -h, --help Show this help dialog"
- exit 0
- fi
-
- if [[ -n "${args[2]}" ]]; then
-
- # Sanitize email address in case of security issues
- # Regex from https://stackoverflow.com/a/2138832/4065967
- local regex
- regex="^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}\$"
- if [[ ! "${args[2]}" =~ ${regex} ]]; then
- echo -e " ${CROSS} Invalid email address"
- exit 0
- fi
-
- addOrEditKeyValPair "${setupVars}" "ADMIN_EMAIL" "${args[2]}"
- echo -e " ${TICK} Setting admin contact to ${args[2]}"
- else
- addOrEditKeyValPair "${setupVars}" "ADMIN_EMAIL" ""
- echo -e " ${TICK} Removing admin contact"
- fi
-}
-
SetListeningMode() {
source "${setupVars}"
@@ -847,7 +815,6 @@ main() {
"-h" | "--help" ) helpFunc;;
"addstaticdhcp" ) AddDHCPStaticAddress;;
"removestaticdhcp" ) RemoveDHCPStaticAddress;;
- "-e" | "email" ) SetAdminEmail "$3";;
"-i" | "interface" ) SetListeningMode "$@";;
"-t" | "teleporter" ) Teleporter;;
"adlist" ) CustomizeAdLists;;
diff --git a/advanced/Templates/pihole-FTL.service b/advanced/Templates/pihole-FTL.service
index f5abfcea..46e5c1f2 100644
--- a/advanced/Templates/pihole-FTL.service
+++ b/advanced/Templates/pihole-FTL.service
@@ -9,48 +9,10 @@
# Description: Enable service provided by pihole-FTL daemon
### END INIT INFO
-# Global variables
-FTLCONFFILE="/etc/pihole/pihole-FTL.conf"
-DEFAULT_PID_FILE="/run/pihole-FTL.pid"
-DEFAULT_PORT_FILE="/run/pihole-FTL.port"
-FTL_PID=''
-
-# Get the file path of the pihole-FTL.pid file
-getFTLPIDFile() {
- if [ -s "${FTLCONFFILE}" ]; then
- # if PIDFILE is not set in pihole-FTL.conf, use the default path
- FTL_PID_FILE="$({ grep '^PIDFILE=' "${FTLCONFFILE}" || echo "${DEFAULT_PID_FILE}"; } | cut -d'=' -f2-)"
- else
- # if there is no pihole-FTL.conf, use the default path
- FTL_PID_FILE="${DEFAULT_PID_FILE}"
- fi
-}
-
-# Get the PID of the FTL process based on the content of the pihole-FTL.pid file
-getFTLPID() {
- if [ -s "${FTL_PID_FILE}" ]; then
- # -s: FILE exists and has a size greater than zero
- FTL_PID="$(cat "${FTL_PID_FILE}")"
- # Exploit prevention: unset the variable if there is malicious content
- # Verify that the value read from the file is numeric
- expr "${FTL_PID}" : "[^[:digit:]]" > /dev/null && unset FTL_PID
- fi
-
- # If FTL is not running, or the PID file contains malicious stuff, substitute
- # negative PID to signal this
- FTL_PID=${FTL_PID:=-1}
-}
-
-# Get the file path of the pihole-FTL.port file
-getFTLPortFile() {
- if [ -s "${FTLCONFFILE}" ]; then
- # if PORTFILE is not set in pihole-FTL.conf, use the default path
- FTL_PORT_FILE="$({ grep '^PORTFILE=' "${FTLCONFFILE}" || echo "${DEFAULT_PORT_FILE}"; } | cut -d'=' -f2-)"
- else
- # if there is no pihole-FTL.conf, use the default path
- FTL_PORT_FILE="${DEFAULT_PORT_FILE}"
-fi
-}
+#source utils.sh for getFTLPIDFile(), getFTLPID (), getFTLAPIPortFile()
+PI_HOLE_SCRIPT_DIR="/opt/pihole"
+utilsfile="${PI_HOLE_SCRIPT_DIR}/utils.sh"
+. "${utilsfile}"
is_running() {
@@ -68,8 +30,8 @@ start() {
else
# Touch files to ensure they exist (create if non-existing, preserve if existing)
mkdir -pm 0755 /run/pihole /var/log/pihole
- [ ! -f "${FTL_PID_FILE}" ] && install -m 644 -o pihole -g pihole /dev/null "${FTL_PID_FILE}"
- [ ! -f "${FTL_PORT_FILE}" ] && install -m 644 -o pihole -g pihole /dev/null "${FTL_PORT_FILE}"
+ [ ! -f "${FTL_PID_FILE}" ] && install -D -m 644 -o pihole -g pihole /dev/null "${FTL_PID_FILE}"
+ [ ! -f "${FTL_PORT_FILE}" ] && install -D -m 644 -o pihole -g pihole /dev/null "${FTL_PORT_FILE}"
[ ! -f /var/log/pihole/FTL.log ] && install -m 644 -o pihole -g pihole /dev/null /var/log/pihole/FTL.log
[ ! -f /var/log/pihole/pihole.log ] && install -m 640 -o pihole -g pihole /dev/null /var/log/pihole/pihole.log
[ ! -f /etc/pihole/dhcp.leases ] && install -m 644 -o pihole -g pihole /dev/null /etc/pihole/dhcp.leases
@@ -96,10 +58,10 @@ start() {
fi
if setcap CAP_NET_BIND_SERVICE,CAP_NET_RAW,CAP_NET_ADMIN,CAP_SYS_NICE,CAP_IPC_LOCK,CAP_CHOWN+eip "/usr/bin/pihole-FTL"; then
- su -s /bin/sh -c "/usr/bin/pihole-FTL" pihole
+ su -s /bin/sh -c "/usr/bin/pihole-FTL" pihole || exit $?
else
echo "Warning: Starting pihole-FTL as root because setting capabilities is not supported on this system"
- /usr/bin/pihole-FTL
+ /usr/bin/pihole-FTL || exit $?
fi
echo
fi
@@ -148,11 +110,11 @@ status() {
### main logic ###
# Get file paths
-getFTLPIDFile
-getFTLPortFile
+FTL_PID_FILE="$(getFTLPIDFile)"
+FTL_PORT_FILE="$(getFTLAPIPortFile)"
# Get FTL's current PID
-getFTLPID
+FTL_PID="$(getFTLPID ${FTL_PID_FILE})"
case "$1" in
stop)
diff --git a/advanced/bash-completion/pihole b/advanced/bash-completion/pihole
index 25208a35..29a3270d 100644
--- a/advanced/bash-completion/pihole
+++ b/advanced/bash-completion/pihole
@@ -15,7 +15,7 @@ _pihole() {
COMPREPLY=( $(compgen -W "${opts_lists}" -- ${cur}) )
;;
"admin")
- opts_admin="celsius email fahrenheit interface kelvin password privacylevel"
+ opts_admin="celsius fahrenheit interface kelvin password privacylevel"
COMPREPLY=( $(compgen -W "${opts_admin}" -- ${cur}) )
;;
"checkout")
diff --git a/advanced/blockingpage.css b/advanced/blockingpage.css
deleted file mode 100644
index 0cc7a65c..00000000
--- a/advanced/blockingpage.css
+++ /dev/null
@@ -1,455 +0,0 @@
-/* Pi-hole: A black hole for Internet advertisements
-* (c) 2017 Pi-hole, LLC (https://pi-hole.net)
-* Network-wide ad blocking via your own hardware.
-*
-* This file is copyright under the latest version of the EUPL.
-* Please see LICENSE file for your rights under this license. */
-
-/* Text Customisation Options ======> */
-.title::before { content: "Website Blocked"; }
-.altBtn::before { content: "Why am I here?"; }
-.linkPH::before { content: "About Pi-hole"; }
-.linkEmail::before { content: "Contact Admin"; }
-
-#bpOutput.add::before { content: "Info"; }
-#bpOutput.add::after { content: "The domain is being whitelisted..."; }
-#bpOutput.error::before, .unhandled::before { content: "Error"; }
-#bpOutput.unhandled::after { content: "An unhandled exception occurred. This may happen when your browser is unable to load jQuery, or when the webserver is denying access to the Pi-hole API."; }
-#bpOutput.success::before { content: "Success"; }
-#bpOutput.success::after { content: "Website has been whitelisted! You may need to flush your DNS cache"; }
-
-.recentwl::before { content: "This site has been whitelisted. Please flush your DNS cache and/or restart your browser."; }
-.unknown::before { content: "This website is not found in any of Pi-hole's blacklists. The reason you have arrived here is unknown."; }
-.cname::before { content: "This site is an alias for "; } /* <a href="http://cname.com">cname.com</a> */
-.cname::after { content: ", which may be blocked by Pi-hole."; }
-
-.blacklist::before { content: "Manually Blacklisted"; }
-.wildcard::before { content: "Manually Blacklisted by Wildcard"; }
-.noblock::before { content: "Not found on any Blacklist"; }
-
-#bpBlock::before { content: "Access to the following website has been denied:"; }
-#bpFlag::before { content: "This is primarily due to being flagged as:"; }
-
-#bpHelpTxt::before { content: "If you have an ongoing use for this website, please "; }
-#bpHelpTxt a::before, #bpHelpTxt span::before { content: "ask the administrator"; }
-#bpHelpTxt::after{ content: " of the Pi-hole on this network to have it whitelisted"; }
-
-#bpBack::before { content: "Back to safety"; }
-#bpInfo::before { content: "Technical Info"; }
-#bpFoundIn::before { content: "This site is found in "; }
-#bpFoundIn span::after { content: " of "; }
-#bpFoundIn::after { content: " lists:"; }
-#bpWhitelist::before { content: "Whitelist"; }
-
-footer span::before { content: "Page generated on "; }
-
-/* Hide whitelisting form entirely */
-/* #bpWLButtons { display: none; } */
-
-/* Text Customisation Options <=============================== */
-
-/* http://necolas.github.io/normalize.css ======> */
-html { font-family: sans-serif; line-height: 1.15; -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; }
-body { margin: 0; }
-article, aside, footer, header, nav, section { display: block; }
-h1 { font-size: 2em; margin: 0.67em 0; }
-figcaption, figure, main { display: block; }
-figure { margin: 1em 40px; }
-hr { box-sizing: content-box; height: 0; overflow: visible; }
-pre { font-family: monospace, monospace; font-size: 1em; }
-a { background-color: transparent; -webkit-text-decoration-skip: objects; }
-a:active, a:hover { outline-width: 0; }
-abbr[title] { border-bottom: none; text-decoration: underline; text-decoration: underline dotted; }
-b, strong { font-weight: inherit; }
-b, strong { font-weight: bolder; }
-code, kbd, samp { font-family: monospace, monospace; font-size: 1em; }
-dfn { font-style: italic; }
-mark { background-color: #ff0; color: #000; }
-small { font-size: 80%; }
-sub, sup { font-size: 75%; line-height: 0; position: relative; vertical-align: baseline; }
-sub { bottom: -0.25em; }
-sup { top: -0.5em; }
-audio, video { display: inline-block; }
-audio:not([controls]) { display: none; height: 0; }
-img { border-style: none; }
-svg:not(:root) { overflow: hidden; }
-button, input, optgroup, select, textarea { font-family: sans-serif; font-size: 100%; line-height: 1.15; margin: 0; }
-button, input { overflow: visible; }
-button, select { text-transform: none; }
-button, html [type="button"], [type="reset"], [type="submit"] { -webkit-appearance: button; }
-button::-moz-focus-inner, [type="button"]::-moz-focus-inner, [type="reset"]::-moz-focus-inner, [type="submit"]::-moz-focus-inner { border-style: none; padding: 0; }
-button:-moz-focusring, [type="button"]:-moz-focusring, [type="reset"]:-moz-focusring, [type="submit"]:-moz-focusring { outline: 1px dotted ButtonText; }
-fieldset { border: 1px solid #c0c0c0; margin: 0 2px; padding: 0.35em 0.625em 0.75em; }
-legend { box-sizing: border-box; color: inherit; display: table; max-width: 100%; padding: 0; white-space: normal; }
-progress { display: inline-block; vertical-align: baseline; }
-textarea { overflow: auto; }
-[type="checkbox"], [type="radio"] { box-sizing: border-box; padding: 0; }
-[type="number"]::-webkit-inner-spin-button, [type="number"]::-webkit-outer-spin-button { height: auto; }
-[type="search"] { -webkit-appearance: textfield; outline-offset: -2px; }
-[type="search"]::-webkit-search-cancel-button, [type="search"]::-webkit-search-decoration { -webkit-appearance: none; }
-::-webkit-file-upload-button { -webkit-appearance: button; font: inherit; }
-details, menu { display: block; }
-summary { display: list-item; }
-canvas { display: inline-block; }
-template { display: none; }
-[hidden] { display: none; }
-/* Normalize.css <=============================== */
-
-html { font-size: 62.5%; }
-
-a { color: #3c8dbc; text-decoration: none; }
-a:hover { color: #72afda; text-decoration: underline; }
-b { color: rgb(68, 68, 68); }
-p { margin: 0; }
-
-label, .buttons a {
- -webkit-user-select: none;
- -moz-user-select: none;
- -ms-user-select: none;
- user-select: none;
-}
-
-label, .buttons *:not([disabled]) { cursor: pointer; }
-
-/* Touch device dark tap highlight */
-header h1 a, label, .buttons * { -webkit-tap-highlight-color: transparent; }
-
-/* Webkit Focus Glow */
-textarea, input, button { outline: none; }
-
-@font-face {
- font-family: "Source Sans Pro";
- font-style: normal;
- font-weight: 400;
- font-display: swap;
- src: local("Source Sans Pro Regular"), local("SourceSansPro-Regular"),
- url("/admin/style/vendor/SourceSansPro/source-sans-pro-v13-latin-regular.woff2") format("woff2"),
- url("/admin/style/vendor/SourceSansPro/source-sans-pro-v13-latin-regular.woff") format("woff");
-}
-
-@font-face {
- font-family: "Source Sans Pro";
- font-style: normal;
- font-weight: 700;
- font-display: swap;
- src: local("Source Sans Pro Bold"), local("SourceSansPro-Bold"),
- url("/admin/style/vendor/SourceSansPro/source-sans-pro-v13-latin-700.woff2") format("woff2"),
- url("/admin/style/vendor/SourceSansPro/source-sans-pro-v13-latin-700.woff") format("woff");
-}
-
-body {
- background: #dbdbdb url("/admin/img/boxed-bg.jpg") repeat fixed;
- color: #333;
- font: 1.4rem "Source Sans Pro", "Helvetica Neue", Helvetica, Arial, sans-serif;
- line-height: 2.2rem;
-}
-
-/* User is greeted with a splash page when browsing to Pi-hole IP address */
-#splashpage {
- background: #222;
- color: rgba(255, 255, 255, 0.7);
- text-align: center;
- width: 100%;
- height: 100%;
- display: flex;
- align-items: center;
- justify-content: center;
-}
-
-#splashpage img { margin: 5px; width: 256px; }
-#splashpage b { color: inherit; }
-
-#bpWrapper {
- margin: 0 auto;
- max-width: 1250px;
- box-shadow: 0 0 8px rgba(0, 0, 0, 0.5);
-}
-
-header {
- background: #3c8dbc;
- display: table;
- position: relative;
- width: 100%;
-}
-
-header h1, header h1 a, header .spc, header #bpAlt label {
- display: table-cell;
- color: #fff;
- white-space: nowrap;
- vertical-align: middle;
- height: 50px; /* Must match #bpAbout top value */
-}
-
-h1 a {
- background-color: rgba(0, 0, 0, 0.1);
- font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
- font-size: 2rem;
- font-weight: 400;
- min-width: 230px;
- text-align: center;
-}
-
-h1 a:hover, header #bpAlt:hover { background-color: rgba(0, 0, 0, 0.12); color: inherit; text-decoration: none; }
-
-header .spc { width: 100%; }
-
-header #bpAlt label {
- background: url("/admin/img/logo.svg") no-repeat center left 15px;
- background-size: 15px 23px;
- padding: 0 15px;
- text-indent: 30px;
-}
-
-[type="checkbox"][id$="Toggle"] { display: none; }
-[type="checkbox"][id$="Toggle"]:checked ~ #bpAbout,
-[type="checkbox"][id$="Toggle"]:checked ~ #bpMoreInfo {
- display: block;
-}
-
-html, body {
- height: 100%;
-}
-
-#pihole_card {
- width: 400px;
- height: auto;
- max-width: 400px;
-}
-
- #pihole_card p, #pihole_card a {
- font-size: 13pt;
- text-align: center;
- }
-
-#pihole_logo_splash {
- height: auto;
- width: 100%;
-}
-
-/* Click anywhere else on screen to hide #bpAbout */
-#bpAboutToggle:checked {
- display: block;
- height: 300px; /* VH Fallback */
- height: 100vh;
- left: 0;
- top: 0;
- opacity: 0;
- position: absolute;
- width: 100%;
-}
-
-#bpAbout {
- background: #3c8dbc;
- border-bottom-left-radius: 5px;
- border: 1px solid #fff;
- border-right-width: 0;
- box-shadow: -1px 1px 1px rgba(0, 0, 0, 0.12);
- box-sizing: border-box;
- display: none;
- font-size: 1.7rem;
- top: 50px;
- position: absolute;
- right: 0;
- width: 280px;
- z-index: 1;
-}
-
-.aboutPH {
- box-sizing: border-box;
- color: rgba(255, 255, 255, 0.8);
- display: block;
- padding: 10px;
- width: 100%;
- text-align: center;
-}
-
-.aboutImg {
- background: url("/admin/img/logo.svg") no-repeat center;
- background-size: 90px 90px;
- height: 90px;
- margin: 0 auto;
- padding: 2px;
- width: 90px;
-}
-
-.aboutPH p { margin: 10px 0; }
-.aboutPH small { display: block; font-size: 1.2rem; }
-
-.aboutLink {
- background: #fff;
- border-top: 1px solid #ddd;
- display: table;
- font-size: 1.4rem;
- text-align: center;
- width: 100%;
-}
-
-.aboutLink a {
- display: table-cell;
- padding: 14px;
- min-width: 50%;
-}
-
-main {
- background: #ecf0f5;
- font-size: 1.65rem;
- padding: 10px;
-}
-
-#bpOutput {
- background: #00c0ef;
- border-radius: 3px;
- border: 1px solid rgba(0, 0, 0, 0.1);
- color: #fff;
- font-size: 1.4rem;
- margin-bottom: 10px;
- margin-top: 5px;
- padding: 15px;
-}
-
-#bpOutput::before {
- background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='7' height='14' viewBox='0 0 7 14'%3E%3Cpath fill='%23fff' d='M6 11a1.371 1.371 0 011 1v1a1.371 1.371 0 01-1 1H1a1.371 1.371 0 01-1-1v-1a1.371 1.371 0 011-1h1V8H1a1.371 1.371 0 01-1-1V6a1.371 1.371 0 011-1h3a1.371 1.371 0 011 1v5h1zM3.5 0A1.5 1.5 0 112 1.5 1.5 1.5 0 013.5 0z'/%3E%3C/svg%3E") no-repeat center left;
- display: block;
- font-size: 1.8rem;
- text-indent: 15px;
-}
-
-#bpOutput.hidden { display: none; }
-#bpOutput.success { background: #00a65a; }
-#bpOutput.error { background: #dd4b39; }
-
-.blockMsg, .flagMsg {
- font: 700 1.8rem Consolas, Courier, monospace;
- padding: 5px 10px 10px;
- text-indent: 15px;
-}
-
-#bpHelpTxt { padding-bottom: 10px; }
-
-.buttons {
- border-spacing: 5px 0;
- display: table;
- width: 100%;
-}
-
-.buttons * {
- -moz-appearance: none;
- -webkit-appearance: none;
- border-radius: 3px;
- border: 1px solid rgba(0, 0, 0, 0.1);
- box-sizing: content-box;
- display: table-cell;
- font-size: 1.65rem;
- margin-right: 5px;
- min-height: 20px;
- padding: 6px 12px;
- position: relative;
- text-align: center;
- vertical-align: top;
- white-space: nowrap;
- width: auto;
-}
-
-.buttons a:hover { text-decoration: none; }
-
-/* Button hover dark overlay */
-.buttons *:not(input):not([disabled]):hover {
- background-image: linear-gradient(to bottom, rgba(0, 0, 0, 0.1), rgba(0, 0, 0, 0.1));
- color: #fff;
-}
-
-/* Button active shadow inset */
-.buttons *:not([disabled]):not(input):active {
- box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
-}
-
-/* Input border color */
-.buttons *:not([disabled]):hover, .buttons input:focus {
- border-color: rgba(0, 0, 0, 0.25);
-}
-
-#bpButtons * { width: 50%; color: #fff; }
-#bpBack { background-color: #00a65a; }
-#bpInfo { background-color: #3c8dbc; }
-#bpWhitelist { background-color: #dd4b39; }
-
-#blockpage .buttons [type="password"][disabled] { color: rgba(0, 0, 0, 1); }
-#blockpage .buttons [disabled] { color: rgba(0, 0, 0, 0.55); background-color: #e3e3e3; }
-#blockpage .buttons [type="password"]:-ms-input-placeholder { color: rgba(51, 51, 51, 0.8); }
-
-input[type="password"] { font-size: 1.5rem; }
-
-@-webkit-keyframes slidein { from { max-height: 0; opacity: 0; } to { max-height: 300px; opacity: 1; } }
-
-@keyframes slidein { from { max-height: 0; opacity: 0; } to { max-height: 300px; opacity: 1; } }
-#bpMoreToggle:checked ~ #bpMoreInfo { display: block; margin-top: 8px; -webkit-animation: slidein 0.05s linear; animation: slidein 0.05s linear; }
-#bpMoreInfo { display: none; margin-top: 10px; }
-
-#bpQueryOutput {
- font-size: 1.2rem;
- line-height: 1.65rem;
- margin: 5px 0 0;
- overflow: auto;
- padding: 0 5px;
- -webkit-overflow-scrolling: touch;
-}
-
-#bpQueryOutput span { margin-right: 4px; }
-
-#bpWLButtons { width: auto; margin-top: 10px; }
-#bpWLButtons * { display: inline-block; }
-#bpWLDomain { display: none; }
-#bpWLPassword { width: 160px; }
-#bpWhitelist { color: #fff; }
-
-footer {
- background: #fff;
- border-top: 1px solid #d2d6de;
- color: #444;
- font: 1.2rem Consolas, Courier, monospace;
- padding: 8px;
-}
-
-/* Responsive Content */
-@media only screen and (max-width: 500px) {
- h1 a {
- font-size: 1.8rem;
- min-width: 170px;
- }
-
- footer span::before {
- content: "Generated ";
- }
-
- footer span {
- display: block;
- }
-}
-
-@media only screen and (min-width: 1251px) {
- #bpWrapper, footer {
- border-radius: 0 0 5px 5px;
- }
-
- #bpAbout {
- border-right-width: 1px;
- }
-}
-
-@media only screen and (max-width: 400px) {
- #pihole_card {
- width: 100%;
- height: auto;
- }
-
- #pihole_card p, #pihole_card a {
- font-size: 100%;
- }
-}
-
-@media only screen and (max-width: 256px) {
- #pihole_logo_splash {
- width: 90% !important;
- height: auto;
- }
-}
diff --git a/advanced/cmdline.txt b/advanced/cmdline.txt
deleted file mode 100644
index 84d52b79..00000000
--- a/advanced/cmdline.txt
+++ /dev/null
@@ -1 +0,0 @@
-dwc_otg.lpm_enable=0 console=ttyAMA0,115200 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait fbcon=map:10 fbcon=font:VGA8x8 consoleblank=0
diff --git a/advanced/console-setup b/advanced/console-setup
deleted file mode 100644
index f12be6eb..00000000
--- a/advanced/console-setup
+++ /dev/null
@@ -1,17 +0,0 @@
-# CONFIGURATION FILE FOR SETUPCON
-
-# Consult the console-setup(5) manual page.
-
-ACTIVE_CONSOLES="/dev/tty[1-6]"
-
-CHARMAP="UTF-8"
-
-# For best results with the Adafruit 2.8 LCD and Pi-hole's chronometer
-CODESET="guess"
-FONTFACE="Terminus"
-FONTSIZE="10x20"
-
-VIDEOMODE=
-
-# The following is an example how to use a braille font
-# FONT='lat9w-08.psf.gz brl-8x8.psf'
diff --git a/advanced/index.php b/advanced/index.php
index cf0ab854..9a2b19e6 100644
--- a/advanced/index.php
+++ b/advanced/index.php
@@ -11,15 +11,6 @@ $serverName = htmlspecialchars($_SERVER["SERVER_NAME"]);
// Remove external ipv6 brackets if any
$serverName = preg_replace('/^\[(.*)\]$/', '${1}', $serverName);
-if (!is_file("/etc/pihole/setupVars.conf"))
- die("[ERROR] File not found: <code>/etc/pihole/setupVars.conf</code>");
-
-// Get values from setupVars.conf
-$setupVars = parse_ini_file("/etc/pihole/setupVars.conf");
-$svPasswd = !empty($setupVars["WEBPASSWORD"]);
-$svEmail = (!empty($setupVars["ADMIN_EMAIL"]) && filter_var($setupVars["ADMIN_EMAIL"], FILTER_VALIDATE_EMAIL)) ? $setupVars["ADMIN_EMAIL"] : "";
-unset($setupVars);
-
// Set landing page location, found within /var/www/html/
$landPage = "../landing.php";
@@ -34,21 +25,6 @@ if (!empty($_SERVER["FQDN"])) {
array_push($authorizedHosts, $_SERVER["VIRTUAL_HOST"]);
}
-// Set which extension types render as Block Page (Including "" for index.ext)
-$validExtTypes = array("asp", "htm", "html", "php", "rss", "xml", "");
-
-// Get extension of current URL
-$currentUrlExt = pathinfo($_SERVER["REQUEST_URI"], PATHINFO_EXTENSION);
-
-// Set mobile friendly viewport
-$viewPort = '<meta name="viewport" content="width=device-width, initial-scale=1">';
-
-// Set response header
-function setHeader($type = "x") {
- header("X-Pi-hole: A black hole for Internet advertisements.");
- if (isset($type) && $type === "js") header("Content-Type: application/javascript");
-}
-
// Determine block page type
if ($serverName === "pi.hole"
|| (!empty($_SERVER["VIRTUAL_HOST"]) && $serverName === $_SERVER["VIRTUAL_HOST"])) {
@@ -58,7 +34,7 @@ if ($serverName === "pi.hole"
// When directly browsing via IP or authorized hostname
// Render splash/landing page based off presence of $landPage file
// Unset variables so as to not be included in $landPage or $splashPage
- unset($svPasswd, $svEmail, $authorizedHosts, $validExtTypes, $currentUrlExt);
+ unset($authorizedHosts);
// If $landPage file is present
if (is_file(getcwd()."/$landPage")) {
unset($serverName, $viewPort); // unset extra variables not to be included in $landpage
@@ -71,347 +47,34 @@ if ($serverName === "pi.hole"
<html lang='en'>
<head>
<meta charset='utf-8'>
- $viewPort
+ <meta name='viewport' content='width=device-width, initial-scale=1'>
<title>● $serverName</title>
- <link rel='stylesheet' href='/pihole/blockingpage.css'>
<link rel='shortcut icon' href='/admin/img/favicons/favicon.ico' type='image/x-icon'>
+ <style>
+ html, body { height: 100% }
+ body { margin: 0; font: 13pt "Source Sans Pro", "Helvetica Neue", Helvetica, Arial, sans-serif; }
+ body { background: #222; color: rgba(255, 255, 255, 0.7); text-align: center; }
+ p { margin: 0; }
+ a { color: #3c8dbc; text-decoration: none; }
+ a:hover { color: #72afda; text-decoration: underline; }
+ #splashpage { display: flex; align-items: center; justify-content: center; }
+ #splashpage img { margin: 5px; width: 256px; }
+ #splashpage b { color: inherit; }
+ </style>
</head>
<body id='splashpage'>
- <div id="pihole_card">
- <img src='/admin/img/logo.svg' alt='Pi-hole logo' id="pihole_logo_splash" />
- <p>Pi-<strong>hole</strong>: Your black hole for Internet advertisements</p>
- <a href='/admin'>Did you mean to go to the admin panel?</a>
+ <div>
+ <img src='/admin/img/logo.svg' alt='Pi-hole logo' width='256' height='377'>
+ <br>
+ <p>Pi-<strong>hole</strong>: Your black hole for Internet advertisements</p>
+ <a href='/admin'>Did you mean to go to the admin panel?</a>
</div>
</body>
</html>
EOT;
exit($splashPage);
-} elseif ($currentUrlExt === "js") {
- // Serve Pi-hole JavaScript for blocked domains requesting JS
- exit(setHeader("js").'var x = "Pi-hole: A black hole for Internet advertisements."');
-} elseif (strpos($_SERVER["REQUEST_URI"], "?") !== FALSE && isset($_SERVER["HTTP_REFERER"])) {
- // Serve blank image upon receiving REQUEST_URI w/ query string & HTTP_REFERRER
- // e.g: An iframe of a blocked domain
- exit(setHeader().'<!doctype html>
- <html lang="en">
- <head>
- <meta charset="utf-8"><script>window.close();</script>
- </head>
- <body>
- <img src="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=">
- </body>
- </html>');
-} elseif (!in_array($currentUrlExt, $validExtTypes) || substr_count($_SERVER["REQUEST_URI"], "?")) {
- // Serve SVG upon receiving non $validExtTypes URL extension or query string
- // e.g: Not an iframe of a blocked domain, such as when browsing to a file/query directly
- // QoL addition: Allow the SVG to be clicked on in order to quickly show the full Block Page
- $blockImg = '<a href="/">
- <svg xmlns="http://www.w3.org/2000/svg" width="110" height="16">
- <circle cx="8" cy="8" r="7" fill="none" stroke="rgba(152,2,2,.5)" stroke-width="2"/>
- <path fill="rgba(152,2,2,.5)" d="M11.526 3.04l1.414 1.415-8.485 8.485-1.414-1.414z"/>
- <text x="19.3" y="12" opacity=".3" style="font:11px Arial">
- Blocked by Pi-hole
- </text>
- </svg>
- </a>';
- exit(setHeader()."<!doctype html>
- <html lang='en'>
- <head>
- <meta charset='utf-8'>
- $viewPort
- </head>
- <body>$blockImg</body>
- </html>");
}
-/* Start processing Block Page from here */
-
-// Define admin email address text based off $svEmail presence
-$bpAskAdmin = !empty($svEmail) ? '<a href="mailto:'.$svEmail.'?subject=Site Blocked: '.$serverName.'"></a>' : "<span/>";
-
-// Get possible non-standard location of FTL's database
-$FTLsettings = parse_ini_file("/etc/pihole/pihole-FTL.conf");
-if (isset($FTLsettings["GRAVITYDB"])) {
- $gravityDBFile = $FTLsettings["GRAVITYDB"];
-} else {
- $gravityDBFile = "/etc/pihole/gravity.db";
-}
-
-// Connect to gravity.db
-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))
- die("[ERROR]: There are no adlists enabled");
-
-// Get total number of blocklists (Including Whitelist, Blacklist & Wildcard lists)
-$adlistsCount = count($adlistsUrls) + 3;
-
-// Set query timeout
-ini_set("default_socket_timeout", 3);
-
-// Logic for querying blocklists
-function queryAds($serverName) {
- // Determine the time it takes while querying adlists
- $preQueryTime = microtime(true)-$_SERVER["REQUEST_TIME_FLOAT"];
-
- // Determine which protocol should be used
- $protocol = "http";
- if ((isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on') ||
- (isset($_SERVER['REQUEST_SCHEME']) && $_SERVER['REQUEST_SCHEME'] === 'https') ||
- (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https')
- ) {
- $protocol = "https";
- }
-
- // Format the URL
- $queryAdsURL = sprintf(
- "%s://127.0.0.1:%s/admin/scripts/pi-hole/php/queryads.php?domain=%s&bp",
- $protocol,
- $_SERVER["SERVER_PORT"],
- $serverName
- );
-
- // Request the file and receive the response
- $queryAdsFile = file($queryAdsURL, FILE_IGNORE_NEW_LINES);
-
- // $queryAdsFile must be an array (to avoid PHP 8.0+ error)
- if (is_array($queryAdsFile)) {
- $queryAds = array_values(array_filter(preg_replace("/data:\s+/", "", $queryAdsFile)));
- } else {
- // if not an array, return an error message
- return array("0" => "error", "1" => "<br>(".gettype($queryAdsFile).")<br>".print_r($queryAdsFile, true));
- }
+exit(header("HTTP/1.1 404 Not Found"));
- $queryTime = sprintf("%.0f", (microtime(true)-$_SERVER["REQUEST_TIME_FLOAT"]) - $preQueryTime);
-
- // Exception Handling
- try {
- // Define Exceptions
- if (strpos($queryAds[0], "No exact results") !== FALSE) {
- // Return "none" into $queryAds array
- return array("0" => "none");
- } else if ($queryTime >= ini_get("default_socket_timeout")) {
- // Connection Timeout
- throw new Exception ("Connection timeout (".ini_get("default_socket_timeout")."s)");
- } elseif (!strpos($queryAds[0], ".") !== false) {
- // Unknown $queryAds output
- throw new Exception ("Unhandled error message (<code>$queryAds[0]</code>)");
- }
- return $queryAds;
- } catch (Exception $e) {
- // Return exception as array
- return array("0" => "error", "1" => $e->getMessage());
- }
-}
-
-// Get results of queryads.php exact search
-$queryAds = queryAds($serverName);
-
-// Pass error through to Block Page
-if ($queryAds[0] === "error")
- die("[ERROR]: Unable to parse results from <i>queryads.php</i>: <code>".$queryAds[1]."</code>");
-
-// Count total number of matching blocklists
-$featuredTotal = count($queryAds);
-
-// Place results into key => value array
-$queryResults = null;
-foreach ($queryAds as $str) {
- $value = explode(" ", $str);
- @$queryResults[$value[0]] .= "$value[1]";
-}
-
-// Determine if domain has been blacklisted, whitelisted, wildcarded or CNAME blocked
-if (strpos($queryAds[0], "blacklist") !== FALSE) {
- $notableFlagClass = "blacklist";
- $adlistsUrls = array("π" => substr($queryAds[0], 2));
-} elseif (strpos($queryAds[0], "whitelist") !== FALSE) {
- $notableFlagClass = "noblock";
- $adlistsUrls = array("π" => substr($queryAds[0], 2));
- $wlInfo = "recentwl";
-} elseif (strpos($queryAds[0], "wildcard") !== FALSE) {
- $notableFlagClass = "wildcard";
- $adlistsUrls = array("π" => substr($queryAds[0], 2));
-} elseif ($queryAds[0] === "none") {
- $featuredTotal = "0";
- $notableFlagClass = "noblock";
-
- // QoL addition: Determine appropriate info message if CNAME exists
- // Suggests to the user that $serverName has a CNAME (alias) that may be blocked
- $dnsRecord = dns_get_record("$serverName")[0];
- if (array_key_exists("target", $dnsRecord)) {
- $wlInfo = $dnsRecord['target'];
- } else {
- $wlInfo = "unknown";
- }
-}
-
-// Set #bpOutput notification
-$wlOutputClass = (isset($wlInfo) && $wlInfo === "recentwl") ? $wlInfo : "hidden";
-$wlOutput = (isset($wlInfo) && $wlInfo !== "recentwl") ? "<a href='http://$wlInfo'>$wlInfo</a>" : "";
-
-// Get Pi-hole Core version
-$phVersion = exec("cd /etc/.pihole/ && git describe --long --tags");
-
-// Print $execTime on development branches
-// Testing for - is marginally faster than "git rev-parse --abbrev-ref HEAD"
-if (explode("-", $phVersion)[1] != "0")
- $execTime = microtime(true)-$_SERVER["REQUEST_TIME_FLOAT"];
-
-// Please Note: Text is added via CSS to allow an admin to provide a localized
-// language without the need to edit this file
-
-setHeader();
?>
-<!doctype html>
-<!-- Pi-hole: A black hole for Internet advertisements
-* (c) 2017 Pi-hole, LLC (https://pi-hole.net)
-* Network-wide ad blocking via your own hardware.
-*
-* This file is copyright under the latest version of the EUPL. -->
-<html>
-<head>
- <meta charset="utf-8">
- <?=$viewPort ?>
- <meta name="robots" content="noindex,nofollow">
- <meta http-equiv="x-dns-prefetch-control" content="off">
- <link rel="stylesheet" href="pihole/blockingpage.css">
- <link rel="shortcut icon" href="admin/img/favicons/favicon.ico" type="image/x-icon">
- <title>● <?=$serverName ?></title>
- <script src="admin/scripts/vendor/jquery.min.js"></script>
- <script>
- window.onload = function () {
- <?php
- // Remove href fallback from "Back to safety" button
- if ($featuredTotal > 0) {
- echo '$("#bpBack").removeAttr("href");';
-
- // Enable whitelisting if JS is available
- echo '$("#bpWhitelist").prop("disabled", false);';
-
- // Enable password input if necessary
- if (!empty($svPasswd)) {
- echo '$("#bpWLPassword").attr("placeholder", "Password");';
- echo '$("#bpWLPassword").prop("disabled", false);';
- }
- // Otherwise hide the input
- else {
- echo '$("#bpWLPassword").hide();';
- }
- }
- ?>
- }
- </script>
-</head>
-<body id="blockpage"><div id="bpWrapper">
-<header>
- <h1 id="bpTitle">
- <a class="title" href="/"><?php //Website Blocked ?></a>
- </h1>
- <div class="spc"></div>
-
- <input id="bpAboutToggle" type="checkbox">
- <div id="bpAbout">
- <div class="aboutPH">
- <div class="aboutImg"></div>
- <p>Open Source Ad Blocker
- <small>Designed for Raspberry Pi</small>
- </p>
- </div>
- <div class="aboutLink">
- <a class="linkPH" href="https://docs.pi-hole.net/"><?php //About PH ?></a>
- <?php if (!empty($svEmail)) echo '<a class="linkEmail" href="mailto:'.$svEmail.'"></a>'; ?>
- </div>
- </div>
-
- <div id="bpAlt">
- <label class="altBtn" for="bpAboutToggle"><?php //Why am I here? ?></label>
- </div>
-</header>
-
-<main>
- <div id="bpOutput" class="<?=$wlOutputClass ?>"><?=$wlOutput ?></div>
- <div id="bpBlock">
- <p class="blockMsg"><?=$serverName ?></p>
- </div>
- <?php if(isset($notableFlagClass)) { ?>
- <div id="bpFlag">
- <p class="flagMsg <?=$notableFlagClass ?>"></p>
- </div>
- <?php } ?>
- <div id="bpHelpTxt"><?=$bpAskAdmin ?></div>
- <div id="bpButtons" class="buttons">
- <a id="bpBack" onclick="javascript:history.back()" href="about:home"></a>
- <?php if ($featuredTotal > 0) echo '<label id="bpInfo" for="bpMoreToggle"></label>'; ?>
- </div>
- <input id="bpMoreToggle" type="checkbox">
- <div id="bpMoreInfo">
- <span id="bpFoundIn"><span><?=$featuredTotal ?></span><?=$adlistsCount ?></span>
- <pre id='bpQueryOutput'><?php if ($featuredTotal > 0) foreach ($queryResults as $num => $value) { echo "<span>[$num]:</span>$adlistsUrls[$num]\n"; } ?></pre>
-
- <form id="bpWLButtons" class="buttons">
- <input id="bpWLDomain" type="text" value="<?=$serverName ?>" disabled>
- <input id="bpWLPassword" type="password" placeholder="JavaScript disabled" disabled>
- <button id="bpWhitelist" type="button" disabled></button>
- </form>
- </div>
-</main>
-
-<footer><span><?=date("l g:i A, F dS"); ?>.</span> Pi-hole <?=$phVersion ?> (<?=gethostname()."/".$_SERVER["SERVER_ADDR"]; if (isset($execTime)) printf("/%.2fs", $execTime); ?>)</footer>
-</div>
-
-<script>
- function add() {
- $("#bpOutput").removeClass("hidden error exception");
- $("#bpOutput").addClass("add");
- var domain = "<?=$serverName ?>";
- var pw = $("#bpWLPassword");
- if(domain.length === 0) {
- return;
- }
- $.ajax({
- url: "/admin/scripts/pi-hole/php/add.php",
- method: "post",
- data: {"domain":domain, "list":"white", "pw":pw.val()},
- success: function(response) {
- if(response.indexOf("Pi-hole blocking") !== -1) {
- setTimeout(function(){window.location.reload(1);}, 10000);
- $("#bpOutput").removeClass("add");
- $("#bpOutput").addClass("success");
- $("#bpOutput").html("");
- } else {
- $("#bpOutput").removeClass("add");
- $("#bpOutput").addClass("error");
- $("#bpOutput").html(""+response+"");
- }
- },
- error: function(jqXHR, exception) {
- $("#bpOutput").removeClass("add");
- $("#bpOutput").addClass("exception");
- $("#bpOutput").html("");
- }
- });
- }
- <?php if ($featuredTotal > 0) { ?>
- $(document).keypress(function(e) {
- if(e.which === 13 && $("#bpWLPassword").is(":focus")) {
- add();
- }
- });
- $("#bpWhitelist").on("click", function() {
- add();
- });
- <?php } ?>
-</script>
-</body></html>
diff --git a/advanced/lighttpd.conf.debian b/advanced/lighttpd.conf.debian
index 4231a0c9..4545bb2e 100644
--- a/advanced/lighttpd.conf.debian
+++ b/advanced/lighttpd.conf.debian
@@ -78,10 +78,21 @@ include_shell "find /etc/lighttpd/conf-enabled -name '*.conf' -a ! -name 'letsen
# If the URL starts with /admin, it is the Web interface
$HTTP["url"] =~ "^/admin/" {
- # Create a response header for debugging using curl -I
+ # X-Pi-hole is a response header for debugging using curl -I
+ # X-Frame-Options prevents clickjacking attacks and helps ensure your content is not embedded into other sites via < frame >, < iframe > or < object >.
+ # X-XSS-Protection sets the configuration for the cross-site scripting filters built into most browsers. This is important because it tells the browser to block the response if a malicious script has been inserted from a user input.
+ # X-Content-Type-Options stops a browser from trying to MIME-sniff the content type and forces it to stick with the declared content-type. This is important because the browser will only load external resources if their content-type matches what is expected, and not malicious hidden code.
+ # Content-Security-Policy tells the browser where resources are allowed to be loaded and if it’s allowed to parse/run inline styles or Javascript. This is important because it prevents content injection attacks, such as Cross Site Scripting (XSS).
+ # X-Permitted-Cross-Domain-Policies is an XML document that grants a web client, such as Adobe Flash Player or Adobe Acrobat (though not necessarily limited to these), permission to handle data across domains.
+ # Referrer-Policy allows control/restriction of the amount of information present in the referral header for links away from your page—the URL path or even if the header is sent at all.
setenv.add-response-header = (
"X-Pi-hole" => "The Pi-hole Web interface is working!",
- "X-Frame-Options" => "DENY"
+ "X-Frame-Options" => "DENY",
+ "X-XSS-Protection" => "1; mode=block",
+ "X-Content-Type-Options" => "nosniff",
+ "Content-Security-Policy" => "default-src 'self' 'unsafe-inline';",
+ "X-Permitted-Cross-Domain-Policies" => "none",
+ "Referrer-Policy" => "same-origin"
)
}
diff --git a/advanced/lighttpd.conf.fedora b/advanced/lighttpd.conf.fedora
index c3c94986..12930302 100644
--- a/advanced/lighttpd.conf.fedora
+++ b/advanced/lighttpd.conf.fedora
@@ -86,10 +86,21 @@ fastcgi.server = (
# If the URL starts with /admin, it is the Web interface
$HTTP["url"] =~ "^/admin/" {
- # Create a response header for debugging using curl -I
+ # X-Pi-hole is a response header for debugging using curl -I
+ # X-Frame-Options prevents clickjacking attacks and helps ensure your content is not embedded into other sites via < frame >, < iframe > or < object >.
+ # X-XSS-Protection sets the configuration for the cross-site scripting filters built into most browsers. This is important because it tells the browser to block the response if a malicious script has been inserted from a user input.
+ # X-Content-Type-Options stops a browser from trying to MIME-sniff the content type and forces it to stick with the declared content-type. This is important because the browser will only load external resources if their content-type matches what is expected, and not malicious hidden code.
+ # Content-Security-Policy tells the browser where resources are allowed to be loaded and if it’s allowed to parse/run inline styles or Javascript. This is important because it prevents content injection attacks, such as Cross Site Scripting (XSS).
+ # X-Permitted-Cross-Domain-Policies is an XML document that grants a web client, such as Adobe Flash Player or Adobe Acrobat (though not necessarily limited to these), permission to handle data across domains.
+ # Referrer-Policy allows control/restriction of the amount of information present in the referral header for links away from your page—the URL path or even if the header is sent at all.
setenv.add-response-header = (
"X-Pi-hole" => "The Pi-hole Web interface is working!",
- "X-Frame-Options" => "DENY"
+ "X-Frame-Options" => "DENY",
+ "X-XSS-Protection" => "1; mode=block",
+ "X-Content-Type-Options" => "nosniff",
+ "Content-Security-Policy" => "default-src 'self' 'unsafe-inline';",
+ "X-Permitted-Cross-Domain-Policies" => "none",
+ "Referrer-Policy" => "same-origin"
)
}