From ae30c285a23240211c4641832cec42905e5be328 Mon Sep 17 00:00:00 2001
From: Markus Napp
Date: Sun, 12 Mar 2017 15:45:11 +0100
Subject: [PATCH 001/162] Fix handling of wildcard help text
---
advanced/Scripts/list.sh | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/advanced/Scripts/list.sh b/advanced/Scripts/list.sh
index 2ac1e805..a094becb 100755
--- a/advanced/Scripts/list.sh
+++ b/advanced/Scripts/list.sh
@@ -31,13 +31,16 @@ helpFunc() {
if [[ ${listMain} == ${whitelist} ]]; then
letter="w"
word="white"
+ elif [[ ${listMain} == ${wildcardlist} ]]; then
+ letter="wild"
+ word="wildcard"
else
letter="b"
word="black"
fi
cat << EOM
-::: Immediately ${word}lists one or more domains in the hosts file
+::: Immediately add one or more domains to the ${word}list
:::
::: Usage: pihole -${letter} domain1 [domain2 ...]
:::
@@ -48,7 +51,7 @@ helpFunc() {
::: -h, --help Show this help dialog
::: -l, --list Display your ${word}listed domains
EOM
-if [[ "${letter}" == "b" ]]; then
+if [[ "${letter}" == "-wild" ]]; then
echo "::: -wild, --wildcard Add wildcard entry (only blacklist)"
fi
exit 0
From 9a475cc0107c263e814a17acd676a3f8f7ef68e1 Mon Sep 17 00:00:00 2001
From: Markus Napp
Date: Sun, 12 Mar 2017 15:50:48 +0100
Subject: [PATCH 002/162] Rewrite help text for better handling of params
---
advanced/Scripts/list.sh | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/advanced/Scripts/list.sh b/advanced/Scripts/list.sh
index a094becb..a4611a4a 100755
--- a/advanced/Scripts/list.sh
+++ b/advanced/Scripts/list.sh
@@ -49,9 +49,9 @@ helpFunc() {
::: -nr, --noreload Update ${word}list without refreshing dnsmasq
::: -q, --quiet Output is less verbose
::: -h, --help Show this help dialog
-::: -l, --list Display your ${word}listed domains
+::: -l, --list Display domains on the ${word}list
EOM
-if [[ "${letter}" == "-wild" ]]; then
+if [[ "${letter}" == "wild" ]]; then
echo "::: -wild, --wildcard Add wildcard entry (only blacklist)"
fi
exit 0
From bb7a7d94efe54b27e9e58af6c42314b6c45e4723 Mon Sep 17 00:00:00 2001
From: Markus Napp
Date: Sun, 12 Mar 2017 16:16:45 +0100
Subject: [PATCH 003/162] Replace misleading letter variable
---
advanced/Scripts/list.sh | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/advanced/Scripts/list.sh b/advanced/Scripts/list.sh
index a4611a4a..8eb0543d 100755
--- a/advanced/Scripts/list.sh
+++ b/advanced/Scripts/list.sh
@@ -29,20 +29,20 @@ listAlt=""
helpFunc() {
if [[ ${listMain} == ${whitelist} ]]; then
- letter="w"
+ param="w"
word="white"
elif [[ ${listMain} == ${wildcardlist} ]]; then
- letter="wild"
+ param="wild"
word="wildcard"
else
- letter="b"
+ param="b"
word="black"
fi
cat << EOM
::: Immediately add one or more domains to the ${word}list
:::
-::: Usage: pihole -${letter} domain1 [domain2 ...]
+::: Usage: pihole -${param} domain1 [domain2 ...]
:::
::: Options:
::: -d, --delmode Remove domains from the ${word}list
@@ -51,7 +51,7 @@ helpFunc() {
::: -h, --help Show this help dialog
::: -l, --list Display domains on the ${word}list
EOM
-if [[ "${letter}" == "wild" ]]; then
+if [[ "${param}" == "wild" ]]; then
echo "::: -wild, --wildcard Add wildcard entry (only blacklist)"
fi
exit 0
From 7abf3497304075ceafdc370429dada01ea81dfae Mon Sep 17 00:00:00 2001
From: DL6ER
Date: Sat, 13 May 2017 21:08:21 +0200
Subject: [PATCH 004/162] Use `echo "ABC" | pihole tricorder` to upload to
Pi-hole's medical tricorder. Uses SSL if available.
---
pihole | 16 +++++++++++++---
1 file changed, 13 insertions(+), 3 deletions(-)
diff --git a/pihole b/pihole
index 4fafe27a..f24461d3 100755
--- a/pihole
+++ b/pihole
@@ -94,7 +94,7 @@ scanList(){
queryFunc() {
method="${3}"
-
+
# If domain contains non ASCII characters, convert domain to punycode if python exists
# Cr: https://serverfault.com/a/335079
if [ -z "${2}" ]; then
@@ -105,7 +105,7 @@ queryFunc() {
else
domain="${2}"
fi
-
+
# Scan Whitelist, Blacklist and Wildcards
lists="/etc/pihole/whitelist.txt /etc/pihole/blacklist.txt $wildcardlist"
result=$(scanList ${domain} "${lists}" ${method})
@@ -122,7 +122,7 @@ queryFunc() {
[ -n "$method" ] && exact="exact "
echo "::: No ${exact}results found for ${domain}"
fi
-
+
exit 0
}
@@ -268,6 +268,14 @@ piholeCheckoutFunc() {
checkout "$@"
}
+tricorderFunc() {
+ if command -v openssl &> /dev/null; then
+ openssl s_client -quiet -connect tricorder.pi-hole.net:9998 2> /dev/null < /dev/stdin
+ else
+ nc tricorder.pi-hole.net 9999 < /dev/stdin
+ fi
+}
+
helpFunc() {
cat << EOM
::: Control all Pi-hole specific functions
@@ -302,6 +310,7 @@ helpFunc() {
::: 'pihole disable 5m' - will disable blocking for 5 minutes
::: restartdns Restart dnsmasq
::: checkout Check out different branches
+::: tricorder Upload log to Pi-hole's medical tricorder (uses SSL when possible)
EOM
exit 0
}
@@ -333,5 +342,6 @@ case "${1}" in
"-a" | "admin" ) webpageFunc "$@";;
"-t" | "tail" ) tailFunc;;
"checkout" ) piholeCheckoutFunc "$@";;
+ "tricorder" ) tricorderFunc;;
* ) helpFunc;;
esac
From 55f78e3b64470f82e088ecc714187ac5dd972456 Mon Sep 17 00:00:00 2001
From: Adam Hill
Date: Sat, 13 May 2017 18:44:41 -0500
Subject: [PATCH 005/162] Update list.sh
I believe this has feature parity with `sed /foo/ Id` but also supports busybox, and my alpine docker ;)
---
advanced/Scripts/list.sh | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/advanced/Scripts/list.sh b/advanced/Scripts/list.sh
index 537ebac3..52c4c569 100755
--- a/advanced/Scripts/list.sh
+++ b/advanced/Scripts/list.sh
@@ -157,8 +157,8 @@ RemoveDomain() {
if [[ "${bool}" == true ]]; then
# Remove it from the other one
echo "::: Removing $1 from $list..."
- # /I flag: search case-insensitive
- sed -i "/${domain}/Id" "${list}"
+ # Busybox sed compatible case-insensitive domain removal
+ sed -i "$(grep -in "^${domain}$" ${list} | awk -F':' '{print $1}' | tr '\n' ',' | sed 's/,$/\n/')d" ${list}
reload=true
else
if [[ "${verbose}" == true ]]; then
@@ -174,8 +174,8 @@ RemoveDomain() {
if [[ "${bool}" == true ]]; then
# Remove it from the other one
echo "::: Removing $1 from $list..."
- # /I flag: search case-insensitive
- sed -i "/address=\/${domain}/Id" "${list}"
+ # Busybox sed compatible case-insensitive domain removal
+ sed -i "$(grep -in "/${domain}/" ${list} | awk -F':' '{print $1}' | tr '\n' ',' | sed 's/,$/\n/')d" ${list}
reload=true
else
if [[ "${verbose}" == true ]]; then
From 25601b9fcc4a87220cbd641deaf2f079b71994ee Mon Sep 17 00:00:00 2001
From: Dan Schaper
Date: Sat, 13 May 2017 17:49:58 -0700
Subject: [PATCH 006/162] Document `sed` substitution for user readability
Comment the oneliner with explanations of what each step does.
---
advanced/Scripts/list.sh | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/advanced/Scripts/list.sh b/advanced/Scripts/list.sh
index 52c4c569..05806e46 100755
--- a/advanced/Scripts/list.sh
+++ b/advanced/Scripts/list.sh
@@ -158,6 +158,10 @@ RemoveDomain() {
# Remove it from the other one
echo "::: Removing $1 from $list..."
# Busybox sed compatible case-insensitive domain removal
+ # grep case insensitive domain from list, print line numbers
+ # split on ':' with awk and print the line number
+ # For conditions with more than one match, substitute newline with ','
+ # sed substitute final trailing ',' with newline
sed -i "$(grep -in "^${domain}$" ${list} | awk -F':' '{print $1}' | tr '\n' ',' | sed 's/,$/\n/')d" ${list}
reload=true
else
From b721ed49abaa7cacb743de5547199b3beb11cee4 Mon Sep 17 00:00:00 2001
From: WaLLy3K
Date: Sun, 14 May 2017 11:11:44 +1000
Subject: [PATCH 007/162] Update Help Output (#1467)
* File consistency
* Tabs to 2 spaces
* Corrected indenting
* Double braced conditionals
* Quoted variables within conditionals
* Standardise core help text
* Added help text for disable command
* Added help text for logging command
* Clean up
* Fixed certain new lines and spaces
* Sync with development branch
* Formatting consistency
* Tabs to 2 spaces
* Corrected indenting
* Double braced conditionals
* Quoted variables within conditionals
* Fixed certain newlines and spaces
* Admin help text
* Added help text for interface command
* Sync with development branch
* Formatting consistency
* Tabs to 2 spaces
* Fixed some wording
* Fixed certain spaces
* Formatting consistency
* Minor wording changes
* Tabs to 2 spaces
* Corrected indenting
* Double braced conditionals
* Quoted variables within conditionals
* Fixed certain newlines and spaces
* Blacklist help text
* Formatting consistency
* Tabs to 2 spaces
* Corrected indenting
* Cronometer help text
* Formatting consistency
* Fixed certain newlines and spaces
* Corrected indenting
* Checkout warning alteration
* Add checkout help text
* Corrected help output
---
advanced/Scripts/chronometer.sh | 131 ++++++------
advanced/Scripts/list.sh | 313 ++++++++++++++---------------
advanced/Scripts/piholeCheckout.sh | 30 +--
advanced/Scripts/version.sh | 168 +++++++++-------
advanced/Scripts/webpage.sh | 187 ++++++++---------
pihole | 250 ++++++++++++-----------
6 files changed, 547 insertions(+), 532 deletions(-)
diff --git a/advanced/Scripts/chronometer.sh b/advanced/Scripts/chronometer.sh
index 67ff495b..b5d54e5f 100755
--- a/advanced/Scripts/chronometer.sh
+++ b/advanced/Scripts/chronometer.sh
@@ -8,101 +8,98 @@
# This file is copyright under the latest version of the EUPL.
# Please see LICENSE file for your rights under this license.
-#Functions##############################################################################################################
+# Functions
piLog="/var/log/pihole.log"
gravity="/etc/pihole/gravity.list"
. /etc/pihole/setupVars.conf
function GetFTLData {
- # Open connection to FTL
- exec 3<>/dev/tcp/localhost/"$(cat /var/run/pihole-FTL.port)"
+ # Open connection to FTL
+ exec 3<>/dev/tcp/localhost/"$(cat /var/run/pihole-FTL.port)"
- # Test if connection is open
- if { >&3; } 2> /dev/null; then
- # Send command to FTL
- echo -e ">$1" >&3
+ # Test if connection is open
+ if { >&3; } 2> /dev/null; then
+ # Send command to FTL
+ echo -e ">$1" >&3
- # Read input
+ # Read input
+ read -r -t 1 LINE <&3
+ until [ ! $? ] || [[ "$LINE" == *"EOM"* ]]; do
+ echo "$LINE" >&1
read -r -t 1 LINE <&3
- until [ ! $? ] || [[ "$LINE" == *"EOM"* ]]; do
- echo "$LINE" >&1
- read -r -t 1 LINE <&3
- done
+ done
- # Close connection
- exec 3>&-
- exec 3<&-
- fi
+ # Close connection
+ exec 3>&-
+ exec 3<&-
+ fi
}
outputJSON() {
- get_summary_data
- echo "{\"domains_being_blocked\":${domains_being_blocked_raw},\"dns_queries_today\":${dns_queries_today_raw},\"ads_blocked_today\":${ads_blocked_today_raw},\"ads_percentage_today\":${ads_percentage_today_raw}}"
+ get_summary_data
+ echo "{\"domains_being_blocked\":${domains_being_blocked_raw},\"dns_queries_today\":${dns_queries_today_raw},\"ads_blocked_today\":${ads_blocked_today_raw},\"ads_percentage_today\":${ads_percentage_today_raw}}"
}
get_summary_data() {
- local summary=$(GetFTLData "stats")
- domains_being_blocked_raw=$(grep "domains_being_blocked" <<< "${summary}" | grep -Eo "[0-9]+$")
- domains_being_blocked=$(printf "%'.f" ${domains_being_blocked_raw})
- dns_queries_today_raw=$(grep "dns_queries_today" <<< "$summary" | grep -Eo "[0-9]+$")
- dns_queries_today=$(printf "%'.f" ${dns_queries_today_raw})
- ads_blocked_today_raw=$(grep "ads_blocked_today" <<< "$summary" | grep -Eo "[0-9]+$")
- ads_blocked_today=$(printf "%'.f" ${ads_blocked_today_raw})
- ads_percentage_today_raw=$(grep "ads_percentage_today" <<< "$summary" | grep -Eo "[0-9.]+$")
- LC_NUMERIC=C ads_percentage_today=$(printf "%'.f" ${ads_percentage_today_raw})
+ local summary=$(GetFTLData "stats")
+ domains_being_blocked_raw=$(grep "domains_being_blocked" <<< "${summary}" | grep -Eo "[0-9]+$")
+ domains_being_blocked=$(printf "%'.f" ${domains_being_blocked_raw})
+ dns_queries_today_raw=$(grep "dns_queries_today" <<< "$summary" | grep -Eo "[0-9]+$")
+ dns_queries_today=$(printf "%'.f" ${dns_queries_today_raw})
+ ads_blocked_today_raw=$(grep "ads_blocked_today" <<< "$summary" | grep -Eo "[0-9]+$")
+ ads_blocked_today=$(printf "%'.f" ${ads_blocked_today_raw})
+ ads_percentage_today_raw=$(grep "ads_percentage_today" <<< "$summary" | grep -Eo "[0-9.]+$")
+ LC_NUMERIC=C ads_percentage_today=$(printf "%'.f" ${ads_percentage_today_raw})
}
normalChrono() {
- for (( ; ; )); do
- get_summary_data
- domain=$(GetFTLData recentBlocked)
- clear
- # Displays a colorful Pi-hole logo
- echo " [0;1;35;95m_[0;1;31;91m__[0m [0;1;33;93m_[0m [0;1;34;94m_[0m [0;1;36;96m_[0m"
- echo "[0;1;31;91m|[0m [0;1;33;93m_[0m [0;1;32;92m(_[0;1;36;96m)_[0;1;34;94m__[0;1;35;95m|[0m [0;1;31;91m|_[0m [0;1;32;92m__[0;1;36;96m_|[0m [0;1;34;94m|[0;1;35;95m__[0;1;31;91m_[0m"
- echo "[0;1;33;93m|[0m [0;1;32;92m_[0;1;36;96m/[0m [0;1;34;94m|_[0;1;35;95m__[0;1;31;91m|[0m [0;1;33;93m'[0m [0;1;32;92m\/[0m [0;1;36;96m_[0m [0;1;34;94m\[0m [0;1;35;95m/[0m [0;1;31;91m-[0;1;33;93m_)[0m"
- echo "[0;1;32;92m|_[0;1;36;96m|[0m [0;1;34;94m|_[0;1;35;95m|[0m [0;1;33;93m|_[0;1;32;92m||[0;1;36;96m_\[0;1;34;94m__[0;1;35;95m_/[0;1;31;91m_\[0;1;33;93m__[0;1;32;92m_|[0m"
- echo ""
- echo " ${IPV4_ADDRESS}"
- echo ""
- uptime | cut -d' ' -f11-
- #uptime -p #Doesn't work on all versions of uptime
- uptime | awk -F'( |,|:)+' '{if ($7=="min") m=$6; else {if ($7~/^day/) {d=$6;h=$8;m=$9} else {h=$6;m=$7}}} {print d+0,"days,",h+0,"hours,",m+0,"minutes."}'
- echo "-------------------------------"
- echo "Recently blocked:"
- echo " $domain"
+ for (( ; ; )); do
+ get_summary_data
+ domain=$(GetFTLData recentBlocked)
+ clear
+ # Displays a colorful Pi-hole logo
+ echo " [0;1;35;95m_[0;1;31;91m__[0m [0;1;33;93m_[0m [0;1;34;94m_[0m [0;1;36;96m_[0m"
+ echo "[0;1;31;91m|[0m [0;1;33;93m_[0m [0;1;32;92m(_[0;1;36;96m)_[0;1;34;94m__[0;1;35;95m|[0m [0;1;31;91m|_[0m [0;1;32;92m__[0;1;36;96m_|[0m [0;1;34;94m|[0;1;35;95m__[0;1;31;91m_[0m"
+ echo "[0;1;33;93m|[0m [0;1;32;92m_[0;1;36;96m/[0m [0;1;34;94m|_[0;1;35;95m__[0;1;31;91m|[0m [0;1;33;93m'[0m [0;1;32;92m\/[0m [0;1;36;96m_[0m [0;1;34;94m\[0m [0;1;35;95m/[0m [0;1;31;91m-[0;1;33;93m_)[0m"
+ echo "[0;1;32;92m|_[0;1;36;96m|[0m [0;1;34;94m|_[0;1;35;95m|[0m [0;1;33;93m|_[0;1;32;92m||[0;1;36;96m_\[0;1;34;94m__[0;1;35;95m_/[0;1;31;91m_\[0;1;33;93m__[0;1;32;92m_|[0m"
+ echo ""
+ echo " ${IPV4_ADDRESS}"
+ echo ""
+ uptime | cut -d' ' -f11-
+ #uptime -p # Doesn't work on all versions of uptime
+ uptime | awk -F'( |,|:)+' '{if ($7=="min") m=$6; else {if ($7~/^day/) {d=$6;h=$8;m=$9} else {h=$6;m=$7}}} {print d+0,"days,",h+0,"hours,",m+0,"minutes."}'
+ echo "-------------------------------"
+ echo "Recently blocked:"
+ echo " $domain"
- echo "Blocking: ${domains_being_blocked}"
- echo "Queries: ${dns_queries_today}"
- echo "Pi-holed: ${ads_blocked_today} (${ads_percentage_today}%)"
+ echo "Blocking: ${domains_being_blocked}"
+ echo "Queries: ${dns_queries_today}"
+ echo "Pi-holed: ${ads_blocked_today} (${ads_percentage_today}%)"
- sleep 5
- done
+ sleep 5
+ done
}
displayHelp() {
- cat << EOM
-::: Displays stats about your piHole!
-:::
-::: Usage: sudo pihole -c [optional:-j]
-::: Note: If no option is passed, then stats are displayed on screen, updated every 5 seconds
-:::
-::: Options:
-::: -j, --json output stats as JSON formatted string
-::: -h, --help display this help text
-EOM
- exit 0
+ echo "Usage: pihole -c [options]
+Example: 'pihole -c -j'
+Calculates stats and displays to an LCD
+
+Options:
+ -j, --json Output stats as JSON formatted string
+ -h, --help Display this help text"
+ exit 0
}
if [[ $# = 0 ]]; then
- normalChrono
+ normalChrono
fi
for var in "$@"; do
- case "$var" in
- "-j" | "--json" ) outputJSON;;
- "-h" | "--help" ) displayHelp;;
- * ) exit 1;;
- esac
+ case "$var" in
+ "-j" | "--json" ) outputJSON;;
+ "-h" | "--help" ) displayHelp;;
+ * ) exit 1;;
+ esac
done
diff --git a/advanced/Scripts/list.sh b/advanced/Scripts/list.sh
index 537ebac3..14b18249 100755
--- a/advanced/Scripts/list.sh
+++ b/advanced/Scripts/list.sh
@@ -3,14 +3,12 @@
# (c) 2017 Pi-hole, LLC (https://pi-hole.net)
# Network-wide ad blocking via your own hardware.
#
-# Whitelists and blacklists domains
+# Whitelist and blacklist domains
#
# This file is copyright under the latest version of the EUPL.
# Please see LICENSE file for your rights under this license.
-
-
-#globals
+# Globals
basename=pihole
piholeDir=/etc/${basename}
whitelist=${piholeDir}/whitelist.txt
@@ -27,122 +25,120 @@ listMain=""
listAlt=""
helpFunc() {
+ if [[ "${listMain}" == "${whitelist}" ]]; then
+ letter="w"
+ word="white"
+ else
+ letter="b"
+ word="black"
+ fi
- if [[ ${listMain} == ${whitelist} ]]; then
- letter="w"
- word="white"
- else
- letter="b"
- word="black"
- fi
+ echo "Usage: pihole -${letter} [options]
+Example: 'pihole -${letter} site.com', or 'pihole -${letter} site1.com site2.com'
+${word^}list one or more domains
- cat << EOM
-::: Immediately ${word}lists one or more domains in the hosts file
-:::
-::: Usage: pihole -${letter} domain1 [domain2 ...]
-:::
-::: Options:
-::: -d, --delmode Remove domains from the ${word}list
-::: -nr, --noreload Update ${word}list without refreshing dnsmasq
-::: -q, --quiet Output is less verbose
-::: -h, --help Show this help dialog
-::: -l, --list Display your ${word}listed domains
-EOM
-if [[ "${letter}" == "b" ]]; then
- echo "::: -wild, --wildcard Add wildcard entry (only blacklist)"
-fi
- exit 0
+Options:"
+
+ if [[ "${letter}" == "b" ]]; then
+ echo " -wild, --wildcard Add wildcard entry to blacklist"
+ fi
+
+echo " -d, --delmode Remove domain(s) from the ${word}list
+ -nr, --noreload Update ${word}list without refreshing dnsmasq
+ -q, --quiet Make output less verbose
+ -h, --help Show this help dialog
+ -l, --list Display all your ${word}listed domains"
+
+exit 0
}
EscapeRegexp() {
- # This way we may safely insert an arbitrary
- # string in our regular expressions
- # Also remove leading "." if present
- echo $* | sed 's/^\.*//' | sed "s/[]\.|$(){}?+*^]/\\\\&/g" | sed "s/\\//\\\\\//g"
+ # This way we may safely insert an arbitrary
+ # string in our regular expressions
+ # Also remove leading "." if present
+ echo $* | sed 's/^\.*//' | sed "s/[]\.|$(){}?+*^]/\\\\&/g" | sed "s/\\//\\\\\//g"
}
-HandleOther(){
- # First, convert everything to lowercase
- domain=$(sed -e "y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/" <<< "$1")
+HandleOther() {
+ # First, convert everything to lowercase
+ domain=$(sed -e "y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/" <<< "$1")
- #check validity of domain
- validDomain=$(echo "${domain}" | perl -lne 'print if /(?!.*[^a-z0-9-\.].*)^((?=[a-z0-9-]{1,63}\.)(xn--)?[a-z0-9-]+\.)*[a-z]{2,63}/')
- if [ -z "${validDomain}" ]; then
- echo "::: $1 is not a valid argument or domain name"
- else
- domList=("${domList[@]}" ${validDomain})
- fi
+ # Check validity of domain
+ validDomain=$(echo "${domain}" | perl -lne 'print if /(?!.*[^a-z0-9-\.].*)^((?=[a-z0-9-]{1,63}\.)(xn--)?[a-z0-9-]+\.)*[a-z]{2,63}/')
+ if [[ -z "${validDomain}" ]]; then
+ echo "::: $1 is not a valid argument or domain name"
+ else
+ domList=("${domList[@]}" ${validDomain})
+ fi
}
PoplistFile() {
- #check whitelist file exists, and if not, create it
- if [[ ! -f ${whitelist} ]]; then
- touch ${whitelist}
- fi
- for dom in "${domList[@]}"; do
- # Logic : If addmode then add to desired list and remove from the other; if delmode then remove from desired list but do not add to the other
- if ${addmode}; then
- AddDomain "${dom}" "${listMain}"
- RemoveDomain "${dom}" "${listAlt}"
- if [[ "${listMain}" == "${whitelist}" || "${listMain}" == "${blacklist}" ]]; then
- RemoveDomain "${dom}" "${wildcardlist}"
- fi
- else
- RemoveDomain "${dom}" "${listMain}"
- fi
- done
+ # Check whitelist file exists, and if not, create it
+ if [[ ! -f ${whitelist} ]]; then
+ touch ${whitelist}
+ fi
+
+ for dom in "${domList[@]}"; do
+ # Logic: If addmode then add to desired list and remove from the other; if delmode then remove from desired list but do not add to the other
+ if ${addmode}; then
+ AddDomain "${dom}" "${listMain}"
+ RemoveDomain "${dom}" "${listAlt}"
+ if [[ "${listMain}" == "${whitelist}" || "${listMain}" == "${blacklist}" ]]; then
+ RemoveDomain "${dom}" "${wildcardlist}"
+ fi
+ else
+ RemoveDomain "${dom}" "${listMain}"
+ fi
+ done
}
AddDomain() {
- list="$2"
- domain=$(EscapeRegexp "$1")
+ list="$2"
+ domain=$(EscapeRegexp "$1")
- if [[ "${list}" == "${whitelist}" || "${list}" == "${blacklist}" ]]; then
+ if [[ "${list}" == "${whitelist}" || "${list}" == "${blacklist}" ]]; then
+ bool=true
+ # Is the domain in the list we want to add it to?
+ grep -Ex -q "${domain}" "${list}" > /dev/null 2>&1 || bool=false
- bool=true
- #Is the domain in the list we want to add it to?
- grep -Ex -q "${domain}" "${list}" > /dev/null 2>&1 || bool=false
+ if [[ "${bool}" == false ]]; then
+ # Domain not found in the whitelist file, add it!
+ if [[ "${verbose}" == true ]]; then
+ echo "::: Adding $1 to $list..."
+ fi
+ reload=true
+ # Add it to the list we want to add it to
+ echo "$1" >> "${list}"
+ else
+ if [[ "${verbose}" == true ]]; then
+ echo "::: ${1} already exists in ${list}, no need to add!"
+ fi
+ fi
+ elif [[ "${list}" == "${wildcardlist}" ]]; then
+ source "${piholeDir}/setupVars.conf"
+ # Remove the /* from the end of the IPv4addr.
+ IPV4_ADDRESS=${IPV4_ADDRESS%/*}
+ IPV6_ADDRESS=${IPV6_ADDRESS}
- if [[ "${bool}" == false ]]; then
- #domain not found in the whitelist file, add it!
- if [[ "${verbose}" == true ]]; then
- echo "::: Adding $1 to $list..."
- fi
- reload=true
- # Add it to the list we want to add it to
- echo "$1" >> "${list}"
- else
- if [[ "${verbose}" == true ]]; then
- echo "::: ${1} already exists in ${list}, no need to add!"
- fi
- fi
+ bool=true
+ # Is the domain in the list?
+ grep -e "address=\/${domain}\/" "${wildcardlist}" > /dev/null 2>&1 || bool=false
- elif [[ "${list}" == "${wildcardlist}" ]]; then
-
- source "${piholeDir}/setupVars.conf"
- #Remove the /* from the end of the IPv4addr.
- IPV4_ADDRESS=${IPV4_ADDRESS%/*}
- IPV6_ADDRESS=${IPV6_ADDRESS}
-
- bool=true
- #Is the domain in the list?
- grep -e "address=\/${domain}\/" "${wildcardlist}" > /dev/null 2>&1 || bool=false
-
- if [[ "${bool}" == false ]]; then
- if [[ "${verbose}" == true ]]; then
- echo "::: Adding $1 to wildcard blacklist..."
- fi
- reload=true
- echo "address=/$1/${IPV4_ADDRESS}" >> "${wildcardlist}"
- if [[ ${#IPV6_ADDRESS} > 0 ]] ; then
- echo "address=/$1/${IPV6_ADDRESS}" >> "${wildcardlist}"
- fi
- else
- if [[ "${verbose}" == true ]]; then
- echo "::: ${1} already exists in wildcard blacklist, no need to add!"
- fi
- fi
- fi
+ if [[ "${bool}" == false ]]; then
+ if [[ "${verbose}" == true ]]; then
+ echo "::: Adding $1 to wildcard blacklist..."
+ fi
+ reload=true
+ echo "address=/$1/${IPV4_ADDRESS}" >> "${wildcardlist}"
+ if [[ "${#IPV6_ADDRESS}" > 0 ]]; then
+ echo "address=/$1/${IPV6_ADDRESS}" >> "${wildcardlist}"
+ fi
+ else
+ if [[ "${verbose}" == true ]]; then
+ echo "::: ${1} already exists in wildcard blacklist, no need to add!"
+ fi
+ fi
+ fi
}
RemoveDomain() {
@@ -150,85 +146,82 @@ RemoveDomain() {
domain=$(EscapeRegexp "$1")
if [[ "${list}" == "${whitelist}" || "${list}" == "${blacklist}" ]]; then
-
- bool=true
- #Is it in the list? Logic follows that if its whitelisted it should not be blacklisted and vice versa
- grep -Ex -q "${domain}" "${list}" > /dev/null 2>&1 || bool=false
- if [[ "${bool}" == true ]]; then
- # Remove it from the other one
- echo "::: Removing $1 from $list..."
- # /I flag: search case-insensitive
- sed -i "/${domain}/Id" "${list}"
- reload=true
- else
- if [[ "${verbose}" == true ]]; then
- echo "::: ${1} does not exist in ${list}, no need to remove!"
- fi
+ bool=true
+ # Is it in the list? Logic follows that if its whitelisted it should not be blacklisted and vice versa
+ grep -Ex -q "${domain}" "${list}" > /dev/null 2>&1 || bool=false
+ if [[ "${bool}" == true ]]; then
+ # Remove it from the other one
+ echo "::: Removing $1 from $list..."
+ # /I flag: search case-insensitive
+ sed -i "/${domain}/Id" "${list}"
+ reload=true
+ else
+ if [[ "${verbose}" == true ]]; then
+ echo "::: ${1} does not exist in ${list}, no need to remove!"
fi
-
+ fi
elif [[ "${list}" == "${wildcardlist}" ]]; then
-
- bool=true
- #Is it in the list?
- grep -e "address=\/${domain}\/" "${wildcardlist}" > /dev/null 2>&1 || bool=false
- if [[ "${bool}" == true ]]; then
- # Remove it from the other one
- echo "::: Removing $1 from $list..."
- # /I flag: search case-insensitive
- sed -i "/address=\/${domain}/Id" "${list}"
- reload=true
- else
- if [[ "${verbose}" == true ]]; then
- echo "::: ${1} does not exist in ${list}, no need to remove!"
- fi
+ bool=true
+ # Is it in the list?
+ grep -e "address=\/${domain}\/" "${wildcardlist}" > /dev/null 2>&1 || bool=false
+ if [[ "${bool}" == true ]]; then
+ # Remove it from the other one
+ echo "::: Removing $1 from $list..."
+ # /I flag: search case-insensitive
+ sed -i "/address=\/${domain}/Id" "${list}"
+ reload=true
+ else
+ if [[ "${verbose}" == true ]]; then
+ echo "::: ${1} does not exist in ${list}, no need to remove!"
fi
+ fi
fi
}
Reload() {
- # Reload hosts file
- pihole -g -sd
+ # Reload hosts file
+ pihole -g -sd
}
Displaylist() {
- if [[ ${listMain} == ${whitelist} ]]; then
- string="gravity resistant domains"
- else
- string="domains caught in the sinkhole"
- fi
- verbose=false
- echo -e " Displaying $string \n"
- count=1
- while IFS= read -r RD; do
- echo "${count}: ${RD}"
- count=$((count+1))
- done < "${listMain}"
- exit 0;
+ if [[ "${listMain}" == "${whitelist}" ]]; then
+ string="gravity resistant domains"
+ else
+ string="domains caught in the sinkhole"
+ fi
+ verbose=false
+ echo -e "Displaying $string:\n"
+ count=1
+ while IFS= read -r RD; do
+ echo "${count}: ${RD}"
+ count=$((count+1))
+ done < "${listMain}"
+ exit 0;
}
for var in "$@"; do
- case "${var}" in
- "-w" | "whitelist" ) listMain="${whitelist}"; listAlt="${blacklist}";;
- "-b" | "blacklist" ) listMain="${blacklist}"; listAlt="${whitelist}";;
- "-wild" | "wildcard" ) listMain="${wildcardlist}";;
- "-nr"| "--noreload" ) reload=false;;
- "-d" | "--delmode" ) addmode=false;;
- "-f" | "--force" ) force=true;;
- "-q" | "--quiet" ) verbose=false;;
- "-h" | "--help" ) helpFunc;;
- "-l" | "--list" ) Displaylist;;
- * ) HandleOther "${var}";;
- esac
+ case "${var}" in
+ "-w" | "whitelist" ) listMain="${whitelist}"; listAlt="${blacklist}";;
+ "-b" | "blacklist" ) listMain="${blacklist}"; listAlt="${whitelist}";;
+ "-wild" | "wildcard" ) listMain="${wildcardlist}";;
+ "-nr"| "--noreload" ) reload=false;;
+ "-d" | "--delmode" ) addmode=false;;
+ "-f" | "--force" ) force=true;;
+ "-q" | "--quiet" ) verbose=false;;
+ "-h" | "--help" ) helpFunc;;
+ "-l" | "--list" ) Displaylist;;
+ * ) HandleOther "${var}";;
+ esac
done
shift
if [[ $# = 0 ]]; then
- helpFunc
+ helpFunc
fi
PoplistFile
if ${reload}; then
- Reload
+ Reload
fi
diff --git a/advanced/Scripts/piholeCheckout.sh b/advanced/Scripts/piholeCheckout.sh
index 09f20d6b..00bea12c 100644
--- a/advanced/Scripts/piholeCheckout.sh
+++ b/advanced/Scripts/piholeCheckout.sh
@@ -3,7 +3,7 @@
# (c) 2017 Pi-hole, LLC (https://pi-hole.net)
# Network-wide ad blocking via your own hardware.
#
-# Checkout other branches than master
+# Switch Pi-hole subsystems to a different Github branch
#
# This file is copyright under the latest version of the EUPL.
# Please see LICENSE file for your rights under this license.
@@ -18,9 +18,12 @@ PH_TEST="true" source "${PI_HOLE_FILES_DIR}/automated install/basic-install.sh"
# setupVars set in basic-install.sh
source "${setupVars}"
-
update="false"
+# Colour codes
+red="\e[1;31m"
+def="\e[0m"
+
fully_fetch_repo() {
# Add upstream branches to shallow clone
local directory="${1}"
@@ -35,7 +38,7 @@ fully_fetch_repo() {
return 0
}
-get_available_branches(){
+get_available_branches() {
# Return available branches
local directory="${1}"
@@ -79,23 +82,23 @@ checkout_pull_branch() {
}
warning1() {
- echo "::: Note that changing the branch is a severe change of your Pi-hole system."
- echo "::: This is not supported unless one of the developers explicitly asks you to do this!"
- read -r -p "::: Have you read and understood this? [y/N] " response
+ echo " Please note that changing branches severely alters your Pi-hole subsystems"
+ echo " Features that work on the master branch, may not on a development branch"
+ echo -e " ${red}This feature is NOT supported unless a Pi-hole developer explicitly asks!${def}"
+ read -r -p " Have you read and understood this? [Y/N] " response
case ${response} in
[yY][eE][sS]|[yY])
- echo "::: Continuing."
+ echo "::: Continuing with branch change."
return 0
;;
*)
- echo "::: Aborting."
+ echo "::: Branch change has been cancelled."
return 1
;;
esac
}
-checkout()
-{
+checkout() {
local corebranches
local webbranches
@@ -192,11 +195,10 @@ checkout()
if [[ ! "${1}" == "web" && "${update}" == "true" ]]; then
echo "::: Running installer to upgrade your installation"
if "${PI_HOLE_FILES_DIR}/automated install/basic-install.sh" --unattended; then
- exit 0
+ exit 0
else
- echo "Unable to complete update, contact Pi-hole"
- exit 1
+ echo "Unable to complete update, contact Pi-hole"
+ exit 1
fi
fi
}
-
diff --git a/advanced/Scripts/version.sh b/advanced/Scripts/version.sh
index 7f96e29a..73888295 100755
--- a/advanced/Scripts/version.sh
+++ b/advanced/Scripts/version.sh
@@ -3,24 +3,29 @@
# (c) 2017 Pi-hole, LLC (https://pi-hole.net)
# Network-wide ad blocking via your own hardware.
#
-# shows version numbers
+# Show version numbers
#
# This file is copyright under the latest version of the EUPL.
# Please see LICENSE file for your rights under this license.
# Variables
DEFAULT="-1"
-PHGITDIR="/etc/.pihole/"
+COREGITDIR="/etc/.pihole/"
WEBGITDIR="/var/www/html/admin/"
getLocalVersion() {
+ # FTL requires a different method
+ if [[ "$1" == "FTL" ]]; then
+ pihole-FTL version
+ return 0
+ fi
+
# Get the tagged version of the local repository
local directory="${1}"
local version
- cd "${directory}" || { echo "${DEFAULT}"; return 1; }
- version=$(git describe --tags --always || \
- echo "${DEFAULT}")
+ cd "${directory}" 2> /dev/null || { echo "${DEFAULT}"; return 1; }
+ version=$(git describe --tags --always || echo "$DEFAULT")
if [[ "${version}" =~ ^v ]]; then
echo "${version}"
elif [[ "${version}" == "${DEFAULT}" ]]; then
@@ -33,13 +38,18 @@ getLocalVersion() {
}
getLocalHash() {
+ # Local FTL hash does not exist on filesystem
+ if [[ "$1" == "FTL" ]]; then
+ echo "N/A"
+ return 0
+ fi
+
# Get the short hash of the local repository
local directory="${1}"
local hash
- cd "${directory}" || { echo "${DEFAULT}"; return 1; }
- hash=$(git rev-parse --short HEAD || \
- echo "${DEFAULT}")
+ cd "${directory}" 2> /dev/null || { echo "${DEFAULT}"; return 1; }
+ hash=$(git rev-parse --short HEAD || echo "$DEFAULT")
if [[ "${hash}" == "${DEFAULT}" ]]; then
echo "ERROR"
return 1
@@ -49,12 +59,33 @@ getLocalHash() {
return 0
}
+getRemoteHash(){
+ # Remote FTL hash is not applicable
+ if [[ "$1" == "FTL" ]]; then
+ echo "N/A"
+ return 0
+ fi
+
+ local daemon="${1}"
+ local branch="${2}"
+
+ hash=$(git ls-remote --heads "https://github.com/pi-hole/${daemon}" | \
+ awk -v bra="$branch" '$0~bra {print substr($0,0,8);exit}')
+ if [[ -n "$hash" ]]; then
+ echo "$hash"
+ else
+ echo "ERROR"
+ return 1
+ fi
+ return 0
+}
+
getRemoteVersion(){
# Get the version from the remote origin
local daemon="${1}"
local version
- version=$(curl --silent --fail https://api.github.com/repos/pi-hole/${daemon}/releases/latest | \
+ version=$(curl --silent --fail "https://api.github.com/repos/pi-hole/${daemon}/releases/latest" | \
awk -F: '$1 ~/tag_name/ { print $2 }' | \
tr -cd '[[:alnum:]]._-')
if [[ "${version}" =~ ^v ]]; then
@@ -66,72 +97,73 @@ getRemoteVersion(){
return 0
}
-#PHHASHLATEST=$(curl -s https://api.github.com/repos/pi-hole/pi-hole/commits/master | \
-# grep sha | \
-# head -n1 | \
-# awk -F ' ' '{ print $2 }' | \
-# tr -cd '[[:alnum:]]._-')
-
-#WEBHASHLATEST=$(curl -s https://api.github.com/repos/pi-hole/AdminLTE/commits/master | \
-# grep sha | \
-# head -n1 | \
-# awk -F ' ' '{ print $2 }' | \
-# tr -cd '[[:alnum:]]._-')
-
-
-normalOutput() {
- echo "::: Pi-hole version is $(getLocalVersion "${PHGITDIR}") (Latest version is $(getRemoteVersion pi-hole))"
- if [ -d "${WEBGITDIR}" ]; then
- echo "::: Web-Admin version is $(getLocalVersion "${WEBGITDIR}") (Latest version is $(getRemoteVersion AdminLTE))"
- fi
-}
-
-webOutput() {
- if [ -d "${WEBGITDIR}" ]; then
- case "${1}" in
- "-l" | "--latest" ) echo $(getRemoteVersion AdminLTE);;
- "-c" | "--current" ) echo $(getLocalVersion "${WEBGITDIR}");;
- "-h" | "--hash" ) echo $(getLocalHash "${WEBGITDIR}");;
- * ) echo "::: Invalid Option!"; exit 1;
- esac
- else
- echo "::: Web interface not installed!"; exit 1;
+versionOutput() {
+ [[ "$1" == "pi-hole" ]] && GITDIR=$COREGITDIR
+ [[ "$1" == "AdminLTE" ]] && GITDIR=$WEBGITDIR
+ [[ "$1" == "FTL" ]] && GITDIR="FTL"
+
+ [[ "$2" == "-c" ]] || [[ "$2" == "--current" ]] || [[ -z "$2" ]] && current=$(getLocalVersion $GITDIR)
+ [[ "$2" == "-l" ]] || [[ "$2" == "--latest" ]] || [[ -z "$2" ]] && latest=$(getRemoteVersion "$1")
+ if [[ "$2" == "-h" ]] || [[ "$2" == "--hash" ]]; then
+ [[ "$3" == "-c" ]] || [[ "$3" == "--current" ]] || [[ -z "$3" ]] && curHash=$(getLocalHash "$GITDIR")
+ [[ "$3" == "-l" ]] || [[ "$3" == "--latest" ]] || [[ -z "$3" ]] && latHash=$(getRemoteHash "$1" "$(cd "$GITDIR" 2> /dev/null && git rev-parse --abbrev-ref HEAD)")
fi
+
+ if [[ -n "$current" ]] && [[ -n "$latest" ]]; then
+ output="${1^} version is $current (Latest: $latest)"
+ elif [[ -n "$current" ]] && [[ -z "$latest" ]]; then
+ output="Current ${1^} version is $current"
+ elif [[ -z "$current" ]] && [[ -n "$latest" ]]; then
+ output="Latest ${1^} version is $latest"
+ elif [[ "$curHash" == "N/A" ]] || [[ "$latHash" == "N/A" ]]; then
+ output="${1^} hash is not applicable"
+ elif [[ -n "$curHash" ]] && [[ -n "$latHash" ]]; then
+ output="${1^} hash is $curHash (Latest: $latHash)"
+ elif [[ -n "$curHash" ]] && [[ -z "$latHash" ]]; then
+ output="Current ${1^} hash is $curHash"
+ elif [[ -z "$curHash" ]] && [[ -n "$latHash" ]]; then
+ output="Latest ${1^} hash is $latHash"
+ else
+ errorOutput
+ fi
+
+ [[ -n "$output" ]] && echo "$output"
}
-coreOutput() {
- case "${1}" in
- "-l" | "--latest" ) echo $(getRemoteVersion pi-hole);;
- "-c" | "--current" ) echo $(getLocalVersion "${PHGITDIR}");;
- "-h" | "--hash" ) echo $(getLocalHash "${PHGITDIR}");;
- * ) echo "::: Invalid Option!"; exit 1;
- esac
+errorOutput() {
+ echo "Invalid Option! Try 'pihole -v -h' for more information."
+ exit 1
+}
+
+defaultOutput() {
+ versionOutput "pi-hole" "$@"
+ versionOutput "AdminLTE" "$@"
+ versionOutput "FTL" "$@"
}
helpFunc() {
- cat << EOM
-:::
-::: Show Pi-hole/Web Admin versions
-:::
-::: Usage: pihole -v [ -a | -p ] [ -l | -c ]
-:::
-::: Options:
-::: -a, --admin Show both current and latest versions of web admin
-::: -p, --pihole Show both current and latest versions of Pi-hole core files
-::: -l, --latest (Only after -a | -p) Return only latest version
-::: -c, --current (Only after -a | -p) Return only current version
-::: -h, --help Show this help dialog
-:::
-EOM
- exit 0
+ echo "Usage: pihole -v [REPO | OPTION] [OPTION]
+Example: 'pihole -v -p -l'
+Show Pi-hole, Admin Console & FTL versions
+
+Repositories:
+ -p, --pihole Only retrieve info regarding Pi-hole repository
+ -a, --admin Only retrieve info regarding AdminLTE repository
+ -f, --ftl Only retrieve info regarding FTL repository
+
+Options:
+ -c, --current Return the current version
+ -l, --latest Return the latest version
+ -h, --hash Return the Github hash from your local repositories
+ --help Show this help dialog
+"
+ exit 0
}
-if [[ $# = 0 ]]; then
- normalOutput
-fi
-
case "${1}" in
- "-a" | "--admin" ) shift; webOutput "$@";;
- "-p" | "--pihole" ) shift; coreOutput "$@" ;;
- "-h" | "--help" ) helpFunc;;
+ "-p" | "--pihole" ) shift; versionOutput "pi-hole" "$@";;
+ "-a" | "--admin" ) shift; versionOutput "AdminLTE" "$@";;
+ "-f" | "--ftl" ) shift; versionOutput "FTL" "$@";;
+ "--help" ) helpFunc;;
+ * ) defaultOutput "$@";;
esac
diff --git a/advanced/Scripts/webpage.sh b/advanced/Scripts/webpage.sh
index d3ad3032..6626dab8 100755
--- a/advanced/Scripts/webpage.sh
+++ b/advanced/Scripts/webpage.sh
@@ -8,7 +8,6 @@
# This file is copyright under the latest version of the EUPL.
# Please see LICENSE file for your rights under this license.
-
readonly setupVars="/etc/pihole/setupVars.conf"
readonly dnsmasqconfig="/etc/dnsmasq.d/01-pihole.conf"
readonly dhcpconfig="/etc/dnsmasq.d/02-pihole-dhcp.conf"
@@ -16,23 +15,19 @@ readonly dhcpconfig="/etc/dnsmasq.d/02-pihole-dhcp.conf"
readonly dhcpstaticconfig="/etc/dnsmasq.d/04-pihole-static-dhcp.conf"
helpFunc() {
- cat << EOM
-::: Set admin options for the web interface of pihole
-:::
-::: Usage: pihole -a [options]
-:::
-::: Options:
-::: -p, password Set web interface password, an empty input will remove any previously set password
-::: -c, celsius Set Celsius temperature unit
-::: -f, fahrenheit Set Fahrenheit temperature unit
-::: -k, kelvin Set Kelvin temperature unit
-::: -h, --help Show this help dialog
-::: -i, interface Setup interface listening behavior of dnsmasq
-::: pihole -a -i local : Listen on all interfaces, but allow only queries from
-::: devices that are at most one hop away (local devices)
-::: pihole -a -i single : Listen only on one interface (see PIHOLE_INTERFACE)
-::: pihole -a -i all : Listen on all interfaces, permit all origins
-EOM
+ echo "Usage: pihole -a [options]
+Example: pihole -a -p password
+Set options for the Admin Console
+
+Options:
+ -f, flush Flush the Pi-hole log
+ -p, password Set Admin Console password
+ -c, celsius Set Celsius as preferred temperature unit
+ -f, fahrenheit Set Fahrenheit as preferred temperature unit
+ -k, kelvin Set Kelvin as preferred temperature unit
+ -h, --help Show this help dialog
+ -i, interface Specify dnsmasq's interface listening behavior
+ Add '-h' for more info on interface usage"
exit 0
}
@@ -61,21 +56,18 @@ delete_dnsmasq_setting() {
sed -i "/${1}/d" "${dnsmasqconfig}"
}
-SetTemperatureUnit(){
-
+SetTemperatureUnit() {
change_setting "TEMPERATUREUNIT" "${unit}"
-
}
-HashPassword(){
- # Compute password hash twice to avoid rainbow table vulnerability
- return=$(echo -n ${1} | sha256sum | sed 's/\s.*$//')
- return=$(echo -n ${return} | sha256sum | sed 's/\s.*$//')
- echo ${return}
+HashPassword() {
+ # Compute password hash twice to avoid rainbow table vulnerability
+ return=$(echo -n ${1} | sha256sum | sed 's/\s.*$//')
+ return=$(echo -n ${return} | sha256sum | sed 's/\s.*$//')
+ echo ${return}
}
-SetWebPassword(){
-
+SetWebPassword() {
if [ "${SUDO_USER}" == "www-data" ]; then
echo "Security measure: user www-data is not allowed to change webUI password!"
echo "Exiting"
@@ -175,8 +167,7 @@ trust-anchor=.,19036,8,2,49AAC11D7B6F6446702E54A1607371607A1A41855200FD2CE1CDDE3
}
-SetDNSServers(){
-
+SetDNSServers() {
# Save setting to file
delete_setting "PIHOLE_DNS"
IFS=',' read -r -a array <<< "${args[2]}"
@@ -207,72 +198,59 @@ SetDNSServers(){
# Restart dnsmasq to load new configuration
RestartDNS
-
}
-SetExcludeDomains(){
-
+SetExcludeDomains() {
change_setting "API_EXCLUDE_DOMAINS" "${args[2]}"
-
}
-SetExcludeClients(){
-
+SetExcludeClients() {
change_setting "API_EXCLUDE_CLIENTS" "${args[2]}"
-
}
-Reboot(){
-
+Reboot() {
nohup bash -c "sleep 5; reboot" &> /dev/null /dev/null
else
service dnsmasq restart &> /dev/null
fi
-
}
-SetQueryLogOptions(){
-
+SetQueryLogOptions() {
change_setting "API_QUERY_LOG_SHOW" "${args[2]}"
-
}
ProcessDHCPSettings() {
-
source "${setupVars}"
if [[ "${DHCP_ACTIVE}" == "true" ]]; then
+ interface=$(grep 'PIHOLE_INTERFACE=' /etc/pihole/setupVars.conf | sed "s/.*=//")
- interface=$(grep 'PIHOLE_INTERFACE=' /etc/pihole/setupVars.conf | sed "s/.*=//")
+ # Use eth0 as fallback interface
+ if [ -z ${interface} ]; then
+ interface="eth0"
+ fi
- # Use eth0 as fallback interface
- if [ -z ${interface} ]; then
- interface="eth0"
- fi
+ if [[ "${PIHOLE_DOMAIN}" == "" ]]; then
+ PIHOLE_DOMAIN="local"
+ change_setting "PIHOLE_DOMAIN" "${PIHOLE_DOMAIN}"
+ fi
- if [[ "${PIHOLE_DOMAIN}" == "" ]]; then
- PIHOLE_DOMAIN="local"
- change_setting "PIHOLE_DOMAIN" "${PIHOLE_DOMAIN}"
- fi
+ if [[ "${DHCP_LEASETIME}" == "0" ]]; then
+ leasetime="infinite"
+ elif [[ "${DHCP_LEASETIME}" == "" ]]; then
+ leasetime="24h"
+ change_setting "DHCP_LEASETIME" "${leasetime}"
+ else
+ leasetime="${DHCP_LEASETIME}h"
+ fi
- if [[ "${DHCP_LEASETIME}" == "0" ]]; then
- leasetime="infinite"
- elif [[ "${DHCP_LEASETIME}" == "" ]]; then
- leasetime="24h"
- change_setting "DHCP_LEASETIME" "${leasetime}"
- else
- leasetime="${DHCP_LEASETIME}h"
- fi
-
- # Write settings to file
- echo "###############################################################################
+ # Write settings to file
+ echo "###############################################################################
# DHCP SERVER CONFIG FILE AUTOMATICALLY POPULATED BY PI-HOLE WEB INTERFACE. #
# ANY CHANGES MADE TO THIS FILE WILL BE LOST ON CHANGE #
###############################################################################
@@ -283,26 +261,25 @@ dhcp-leasefile=/etc/pihole/dhcp.leases
#quiet-dhcp
" > "${dhcpconfig}"
-if [[ "${PIHOLE_DOMAIN}" != "none" ]]; then
- echo "domain=${PIHOLE_DOMAIN}" >> "${dhcpconfig}"
-fi
+ if [[ "${PIHOLE_DOMAIN}" != "none" ]]; then
+ echo "domain=${PIHOLE_DOMAIN}" >> "${dhcpconfig}"
+ fi
- if [[ "${DHCP_IPv6}" == "true" ]]; then
-echo "#quiet-dhcp6
+ if [[ "${DHCP_IPv6}" == "true" ]]; then
+ echo "#quiet-dhcp6
#enable-ra
dhcp-option=option6:dns-server,[::]
dhcp-range=::100,::1ff,constructor:${interface},ra-names,slaac,${leasetime}
ra-param=*,0,0
" >> "${dhcpconfig}"
- fi
+ fi
else
rm "${dhcpconfig}" &> /dev/null
fi
}
-EnableDHCP(){
-
+EnableDHCP() {
change_setting "DHCP_ACTIVE" "true"
change_setting "DHCP_START" "${args[2]}"
change_setting "DHCP_END" "${args[3]}"
@@ -320,8 +297,7 @@ EnableDHCP(){
RestartDNS
}
-DisableDHCP(){
-
+DisableDHCP() {
change_setting "DHCP_ACTIVE" "false"
# Remove possible old setting from file
@@ -333,23 +309,20 @@ DisableDHCP(){
RestartDNS
}
-SetWebUILayout(){
-
+SetWebUILayout() {
change_setting "WEBUIBOXEDLAYOUT" "${args[2]}"
-
}
CustomizeAdLists() {
-
list="/etc/pihole/adlists.list"
- if [[ "${args[2]}" == "enable" ]] ; then
+ if [[ "${args[2]}" == "enable" ]]; then
sed -i "\\@${args[3]}@s/^#http/http/g" "${list}"
- elif [[ "${args[2]}" == "disable" ]] ; then
+ elif [[ "${args[2]}" == "disable" ]]; then
sed -i "\\@${args[3]}@s/^http/#http/g" "${list}"
- elif [[ "${args[2]}" == "add" ]] ; then
+ elif [[ "${args[2]}" == "add" ]]; then
echo "${args[3]}" >> ${list}
- elif [[ "${args[2]}" == "del" ]] ; then
+ elif [[ "${args[2]}" == "del" ]]; then
var=$(echo "${args[3]}" | sed 's/\//\\\//g')
sed -i "/${var}/Id" "${list}"
else
@@ -358,18 +331,15 @@ CustomizeAdLists() {
fi
}
-SetPrivacyMode(){
-
- if [[ "${args[2]}" == "true" ]] ; then
+SetPrivacyMode() {
+ if [[ "${args[2]}" == "true" ]]; then
change_setting "API_PRIVACY_MODE" "true"
else
change_setting "API_PRIVACY_MODE" "false"
fi
-
}
ResolutionSettings() {
-
typ="${args[2]}"
state="${args[3]}"
@@ -378,11 +348,9 @@ ResolutionSettings() {
elif [[ "${typ}" == "clients" ]]; then
change_setting "API_GET_CLIENT_HOSTNAME" "${state}"
fi
-
}
AddDHCPStaticAddress() {
-
mac="${args[2]}"
ip="${args[3]}"
host="${args[4]}"
@@ -397,18 +365,14 @@ AddDHCPStaticAddress() {
# Full info given
echo "dhcp-host=${mac},${ip},${host}" >> "${dhcpstaticconfig}"
fi
-
}
RemoveDHCPStaticAddress() {
-
mac="${args[2]}"
sed -i "/dhcp-host=${mac}.*/d" "${dhcpstaticconfig}"
-
}
-SetHostRecord(){
-
+SetHostRecord() {
if [ -n "${args[3]}" ]; then
change_setting "HOSTRECORD" "${args[2]},${args[3]}"
echo "Setting host record for ${args[2]} -> ${args[3]}"
@@ -421,17 +385,28 @@ SetHostRecord(){
# Restart dnsmasq to load new configuration
RestartDNS
-
}
-SetListeningMode(){
-
+SetListeningMode() {
source "${setupVars}"
+
+ if [[ "$3" == "-h" ]]; then
+ echo "Usage: pihole -a -i [interface]
+Example: 'pihole -a -i local'
+Specify dnsmasq's network interface listening behavior
- if [[ "${args[2]}" == "all" ]] ; then
+Interfaces:
+ local Listen on all interfaces, but only allow queries from
+ devices that are at most one hop away (local devices)
+ single Listen only on ${PIHOLE_INTERFACE} interface
+ all Listen on all interfaces, permit all origins"
+ exit 0
+ fi
+
+ if [[ "${args[2]}" == "all" ]]; then
echo "Listening on all interfaces, permiting all origins, hope you have a firewall!"
change_setting "DNSMASQ_LISTENING" "all"
- elif [[ "${args[2]}" == "local" ]] ; then
+ elif [[ "${args[2]}" == "local" ]]; then
echo "Listening on all interfaces, permitting only origins that are at most one hop away (local devices)"
change_setting "DNSMASQ_LISTENING" "local"
else
@@ -446,17 +421,14 @@ SetListeningMode(){
# Restart dnsmasq to load new configuration
RestartDNS
fi
-
}
-Teleporter()
-{
+Teleporter() {
local datetimestamp=$(date "+%Y-%m-%d_%H-%M-%S")
php /var/www/html/admin/scripts/pi-hole/php/teleporter.php > "pi-hole-teleporter_${datetimestamp}.zip"
}
main() {
-
args=("$@")
case "${args[1]}" in
@@ -479,7 +451,7 @@ main() {
"addstaticdhcp" ) AddDHCPStaticAddress;;
"removestaticdhcp" ) RemoveDHCPStaticAddress;;
"hostrecord" ) SetHostRecord;;
- "-i" | "interface" ) SetListeningMode;;
+ "-i" | "interface" ) SetListeningMode "$@";;
"-t" | "teleporter" ) Teleporter;;
"adlist" ) CustomizeAdLists;;
* ) helpFunc;;
@@ -490,5 +462,4 @@ main() {
if [[ $# = 0 ]]; then
helpFunc
fi
-
}
diff --git a/pihole b/pihole
index 83e13000..79a5c35d 100755
--- a/pihole
+++ b/pihole
@@ -9,11 +9,11 @@
# Please see LICENSE file for your rights under this license.
readonly PI_HOLE_SCRIPT_DIR="/opt/pihole"
-
readonly wildcardlist="/etc/dnsmasq.d/03-pihole-wildcard.conf"
+
# Must be root to use this tool
if [[ ! $EUID -eq 0 ]];then
- if [ -x "$(command -v sudo)" ];then
+ if [[ -x "$(command -v sudo)" ]]; then
exec sudo bash "$0" "$@"
exit $?
else
@@ -80,66 +80,49 @@ updateGravityFunc() {
exit 0
}
-scanList(){
+scanList() {
domain="${1}"
list="${2}"
method="${3}"
- if [[ ${method} == "-exact" ]] ; then
- grep -i -E "(^|\s)${domain}($|\s)" "${list}"
- else
- grep -i "${domain}" "${list}"
- fi
-}
-processWildcards() {
- IFS="." read -r -a array <<< "${1}"
- for (( i=${#array[@]}-1; i>=0; i-- )); do
- ar=""
- for (( j=${#array[@]}-1; j>${#array[@]}-i-2; j-- )); do
- if [[ $j == $((${#array[@]}-1)) ]]; then
- ar="${array[$j]}"
- else
- ar="${array[$j]}.${ar}"
- fi
- done
- echo "${ar}"
- done
+ if [[ "${method}" == "-exact" ]]; then
+ grep -i -E -l "(^|\s|\/)${domain}($|\s|\/)" ${list}
+ else
+ grep -i "${domain}" ${list}
+ fi
}
queryFunc() {
- domain="${2}"
method="${3}"
- lists=( /etc/pihole/list.* /etc/pihole/blacklist.txt)
- for list in ${lists[@]}; do
- if [ -e "${list}" ]; then
- result=$(scanList ${domain} ${list} ${method})
- # Remove empty lines before couting number of results
- count=$(sed '/^\s*$/d' <<< "$result" | wc -l)
- echo "::: ${list} (${count} results)"
- if [[ ${count} > 0 ]]; then
- echo "${result}"
- fi
- echo ""
- else
- echo "::: ${list} does not exist"
- echo ""
- fi
- done
-
- # Scan for possible wildcard matches
- if [ -e "${wildcardlist}" ]; then
- local wildcards=($(processWildcards "${domain}"))
- for domain in ${wildcards[@]}; do
- result=$(scanList "\/${domain}\/" ${wildcardlist})
- # Remove empty lines before couting number of results
- count=$(sed '/^\s*$/d' <<< "$result" | wc -l)
- if [[ ${count} > 0 ]]; then
- echo "::: Wildcard blocking ${domain} (${count} results)"
- echo "${result}"
- echo ""
- fi
- done
+
+ # If domain contains non ASCII characters, convert domain to punycode if python exists
+ # Cr: https://serverfault.com/a/335079
+ if [[ -z "${2}" ]]; then
+ echo "::: No domain specified"
+ exit 1
+ elif [[ "${2}" = *[![:ascii:]]* ]]; then
+ [[ "$(which python)" ]] && domain=$(python -c 'import sys;print sys.argv[1].decode("utf-8").encode("idna")' "${2}")
+ else
+ domain="${2}"
fi
+
+ # Scan Whitelist, Blacklist and Wildcards
+ lists="/etc/pihole/whitelist.txt /etc/pihole/blacklist.txt $wildcardlist"
+ result=$(scanList ${domain} "${lists}" ${method})
+ if [[ -n "$result" ]]; then
+ echo "$result"
+ [[ ! -t 1 ]] && exit 0
+ fi
+
+ # Scan Domains lists
+ result=$(scanList ${domain} "/etc/pihole/*.domains" ${method})
+ if [[ -n "$result" ]]; then
+ sort -t . -k 2 -g <<< "$result"
+ else
+ [ -n "$method" ] && exact="exact "
+ echo "::: No ${exact}results found for ${domain}"
+ fi
+
exit 0
}
@@ -163,16 +146,16 @@ versionFunc() {
restartDNS() {
dnsmasqPid=$(pidof dnsmasq)
- if [[ ${dnsmasqPid} ]]; then
- # service already running - reload config
- if [ -x "$(command -v systemctl)" ]; then
+ if [[ "${dnsmasqPid}" ]]; then
+ # Service already running - reload config
+ if [[ -x "$(command -v systemctl)" ]]; then
systemctl restart dnsmasq
else
service dnsmasq restart
fi
else
- # service not running, start it up
- if [ -x "$(command -v systemctl)" ]; then
+ # Service not running, start it up
+ if [[ -x "$(command -v systemctl)" ]]; then
systemctl start dnsmasq
else
service dnsmasq start
@@ -181,16 +164,25 @@ restartDNS() {
}
piholeEnable() {
- if [[ "${1}" == "0" ]] ; then
- #Disable Pihole
+ if [[ "${2}" == "-h" ]]; then
+ echo "Usage: pihole disable [time]
+Example: 'pihole disable', or 'pihole disable 5m'
+Disable Pi-hole subsystems
+
+Time:
+ #s Disable Pi-hole functionality for # second(s)
+ #m Disable Pi-hole functionality for # minute(s)"
+ exit 0
+ elif [[ "${1}" == "0" ]]; then
+ # Disable Pi-hole
sed -i 's/^addn-hosts=\/etc\/pihole\/gravity.list/#addn-hosts=\/etc\/pihole\/gravity.list/' /etc/dnsmasq.d/01-pihole.conf
echo "::: Blocking has been disabled!"
- if [[ $# > 1 ]] ; then
- if [[ ${2} == *"s"* ]] ; then
+ if [[ $# > 1 ]]; then
+ if [[ "${2}" == *"s"* ]]; then
tt=${2%"s"}
echo "::: Blocking will be re-enabled in ${tt} seconds"
nohup bash -c "sleep ${tt}; pihole enable" /dev/null &
- elif [[ ${2} == *"m"* ]] ; then
+ elif [[ "${2}" == *"m"* ]]; then
tt=${2%"m"}
echo "::: Blocking will be re-enabled in ${tt} minutes"
tt=$((${tt}*60))
@@ -204,7 +196,7 @@ piholeEnable() {
fi
fi
else
- #Enable pihole
+ # Enable Pi-hole
echo "::: Blocking has been enabled!"
sed -i 's/^#addn-hosts/addn-hosts/' /etc/dnsmasq.d/01-pihole.conf
fi
@@ -213,15 +205,23 @@ piholeEnable() {
piholeLogging() {
shift
+ if [[ "${1}" == "-h" ]]; then
+ echo "Usage: pihole logging [options]
+Example: 'pihole logging on'
+Specify whether the Pi-hole log should be used
- if [[ "${1}" == "off" ]] ; then
- #Disable Logging
+Options:
+ on Enable the Pi-hole log at /var/log/pihole.log
+ off Disable the Pi-hole log at /var/log/pihole.log"
+ exit 0
+ elif [[ "${1}" == "off" ]]; then
+ # Disable logging
sed -i 's/^log-queries/#log-queries/' /etc/dnsmasq.d/01-pihole.conf
sed -i 's/^QUERY_LOGGING=true/QUERY_LOGGING=false/' /etc/pihole/setupVars.conf
pihole -f
echo "::: Logging has been disabled!"
- elif [[ "${1}" == "on" ]] ; then
- #Enable logging
+ elif [[ "${1}" == "on" ]]; then
+ # Enable logging
sed -i 's/^#log-queries/log-queries/' /etc/dnsmasq.d/01-pihole.conf
sed -i 's/^QUERY_LOGGING=false/QUERY_LOGGING=true/' /etc/pihole/setupVars.conf
echo "::: Logging has been enabled!"
@@ -233,12 +233,12 @@ piholeLogging() {
}
piholeStatus() {
- if [[ $(netstat -plnt | grep -c ':53 ') > 0 ]]; then
- if [[ "${1}" != "web" ]] ; then
+ if [[ "$(netstat -plnt | grep -c ':53 ')" -gt "0" ]]; then
+ if [[ "${1}" != "web" ]]; then
echo "::: DNS service is running"
fi
else
- if [[ "${1}" == "web" ]] ; then
+ if [[ "${1}" == "web" ]]; then
echo "-1";
else
echo "::: DNS service is NOT running"
@@ -246,28 +246,28 @@ piholeStatus() {
return
fi
- if [[ $(grep -i "^#addn-hosts=/" /etc/dnsmasq.d/01-pihole.conf) ]] ; then
- #list is commented out
- if [[ "${1}" == "web" ]] ; then
+ if [[ "$(grep -i "^#addn-hosts=/" /etc/dnsmasq.d/01-pihole.conf)" ]]; then
+ # List is commented out
+ if [[ "${1}" == "web" ]]; then
echo 0;
else
echo "::: Pi-hole blocking is Disabled";
fi
- elif [[ $(grep -i "^addn-hosts=/" /etc/dnsmasq.d/01-pihole.conf) ]] ; then
- #list set
- if [[ "${1}" == "web" ]] ; then
+ elif [[ "$(grep -i "^addn-hosts=/" /etc/dnsmasq.d/01-pihole.conf)" ]]; then
+ # List set
+ if [[ "${1}" == "web" ]]; then
echo 1;
else
echo "::: Pi-hole blocking is Enabled";
fi
else
- #addn-host not found
- if [[ "${1}" == "web" ]] ; then
+ # Addn-host not found
+ if [[ "${1}" == "web" ]]; then
echo 99
else
echo "::: No hosts file linked to dnsmasq, adding it in enabled state"
fi
- #add addn-host= to dnsmasq
+ # Add addn-host= to dnsmasq
echo "addn-hosts=/etc/pihole/gravity.list" >> /etc/dnsmasq.d/01-pihole.conf
restartDNS
fi
@@ -280,46 +280,66 @@ tailFunc() {
}
piholeCheckoutFunc() {
+ if [[ "$2" == "-h" ]]; then
+ echo "Usage: pihole checkout [repo] [branch]
+Example: 'pihole checkout master' or 'pihole checkout core dev'
+Switch Pi-hole subsystems to a different Github branch
+
+Repositories:
+ core [branch] Change the branch of Pi-hole's core subsystem
+ web [branch] Change the branch of Admin Console subsystem
+
+Branches:
+ master Update subsystems to the latest stable release
+ dev Update subsystems to the latest development release"
+ exit 0
+ fi
+
source "${PI_HOLE_SCRIPT_DIR}"/piholeCheckout.sh
shift
checkout "$@"
}
helpFunc() {
- cat << EOM
-::: Control all Pi-hole specific functions
-:::
-::: Usage: pihole [options]
-::: Add -h after -w (whitelist), -b (blacklist), -c (chronometer), or -a (admin) for more information on usage
-:::
-::: Options:
-::: -w, whitelist Whitelist domain(s)
-::: -b, blacklist Blacklist domain(s) (exact match)
-::: -wild, wildcard Blacklist whole domain(s) (wildcard)
-::: -d, debug Start a debugging session
-::: Automated debugging can be enabled with '-a'.
-::: 'pihole -d -a'
-::: -f, flush Flush the 'pihole.log' file
-::: -t, tail Output the last lines of the 'pihole.log' file. Lines are appended as the file grows
-::: -up, updatePihole Update Pi-hole components
-::: -r, reconfigure Reconfigure or Repair Pi-hole
-::: -g, updateGravity Update the list of ad-serving domains
-::: -c, chronometer Calculates stats and displays to an LCD
-::: -h, help Show this help dialog
-::: -v, version Show installed versions of Pi-hole and Web-Admin
-::: -q, query Query the adlists for a specific domain
-::: 'pihole -q domain -exact' shows exact matches only
-::: -l, logging Enable or Disable logging (pass 'on' or 'off')
-::: -a, admin Admin webpage options
-::: uninstall Uninstall Pi-hole from your system! :(
-::: status Display if Pi-hole is Enabled or Disabled
-::: enable Enable Pi-hole DNS Blocking
-::: disable Disable Pi-hole DNS Blocking
-::: Blocking can also be disabled only temporarily, e.g.,
-::: 'pihole disable 5m' - will disable blocking for 5 minutes
-::: restartdns Restart dnsmasq
-::: checkout Check out different branches
-EOM
+ echo "Usage: pihole [options]
+Example: 'pihole -w -h'
+Add '-h' after specific commands for more information on usage
+
+Whitelist/Blacklist Options:
+ -w, whitelist Whitelist domain(s)
+ -b, blacklist Blacklist domain(s)
+ -wild, wildcard Blacklist domain(s), and all its subdomains
+ Add '-h' for more info on whitelist/blacklist usage
+
+Debugging Options:
+ -d, debug Start a debugging session
+ Add '-a' to enable automated debugging
+ -f, flush Flush the Pi-hole log
+ -r, reconfigure Reconfigure or Repair Pi-hole subsystems
+ -t, tail View the live output of the Pi-hole log
+
+Options:
+ -a, admin Admin Console options
+ Add '-h' for more info on admin console usage
+ -c, chronometer Calculates stats and displays to an LCD
+ Add '-h' for more info on chronometer usage
+ -g, updateGravity Update the list of ad-serving domains
+ -h, --help, help Show this help dialog
+ -l, logging Specify whether the Pi-hole log should be used
+ Add '-h' for more info on logging usage
+ -q, query Query the adlists for a specified domain
+ Add '-exact' AFTER a specified domain for exact match
+ -up, updatePihole Update Pi-hole subsystems
+ -v, version Show installed versions of Pi-hole, Admin Console & FTL
+ Add '-h' for more info on version usage
+ uninstall Uninstall Pi-hole from your system
+ status Display the running status of Pi-hole subsystems
+ enable Enable Pi-hole subsystems
+ disable Disable Pi-hole subsystems
+ Add '-h' for more info on disable usage
+ restartdns Restart Pi-hole subsystems
+ checkout Switch Pi-hole subsystems to a different Github branch
+ Add '-h' for more info on checkout usage";
exit 0
}
@@ -344,7 +364,7 @@ case "${1}" in
"-l" | "logging" ) piholeLogging "$@";;
"uninstall" ) uninstallFunc;;
"enable" ) piholeEnable 1;;
- "disable" ) piholeEnable 0 $2;;
+ "disable" ) piholeEnable 0 "$2";;
"status" ) piholeStatus "$2";;
"restartdns" ) restartDNS;;
"-a" | "admin" ) webpageFunc "$@";;
From 0e4473685bb9fdc00f196cf2751be99c6877368c Mon Sep 17 00:00:00 2001
From: WaLLy3K
Date: Sun, 14 May 2017 11:47:56 +1000
Subject: [PATCH 008/162] Show help for "pihole -a -i --help"
---
advanced/Scripts/webpage.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/advanced/Scripts/webpage.sh b/advanced/Scripts/webpage.sh
index 6626dab8..8419aa8d 100755
--- a/advanced/Scripts/webpage.sh
+++ b/advanced/Scripts/webpage.sh
@@ -390,7 +390,7 @@ SetHostRecord() {
SetListeningMode() {
source "${setupVars}"
- if [[ "$3" == "-h" ]]; then
+ if [[ "$3" == "-h" ]] || [[ "$3" == "--help" ]]; then
echo "Usage: pihole -a -i [interface]
Example: 'pihole -a -i local'
Specify dnsmasq's network interface listening behavior
From 4eb7d2868ca2d347ed0a497b6fb5c3a195ac4bf6 Mon Sep 17 00:00:00 2001
From: WaLLy3K
Date: Sun, 14 May 2017 11:53:40 +1000
Subject: [PATCH 009/162] Fix "pihole disable --help" and "pihole -l --help"
---
pihole | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/pihole b/pihole
index 79a5c35d..1b75add5 100755
--- a/pihole
+++ b/pihole
@@ -164,7 +164,7 @@ restartDNS() {
}
piholeEnable() {
- if [[ "${2}" == "-h" ]]; then
+ if [[ "${2}" == "-h" ]] || [[ "${2}" == "--help" ]]; then
echo "Usage: pihole disable [time]
Example: 'pihole disable', or 'pihole disable 5m'
Disable Pi-hole subsystems
@@ -205,7 +205,7 @@ Time:
piholeLogging() {
shift
- if [[ "${1}" == "-h" ]]; then
+ if [[ "${1}" == "-h" ]] || [[ "${1}" == "--help" ]]; then
echo "Usage: pihole logging [options]
Example: 'pihole logging on'
Specify whether the Pi-hole log should be used
From 3bd677c102fddcce8ce72c81ae811b7453b8caa8 Mon Sep 17 00:00:00 2001
From: WaLLy3K
Date: Sun, 14 May 2017 11:57:46 +1000
Subject: [PATCH 010/162] Show help for "pihole -v -h"
* Indent output text
* Minor help text change
---
advanced/Scripts/version.sh | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/advanced/Scripts/version.sh b/advanced/Scripts/version.sh
index 73888295..50bdb608 100755
--- a/advanced/Scripts/version.sh
+++ b/advanced/Scripts/version.sh
@@ -104,7 +104,7 @@ versionOutput() {
[[ "$2" == "-c" ]] || [[ "$2" == "--current" ]] || [[ -z "$2" ]] && current=$(getLocalVersion $GITDIR)
[[ "$2" == "-l" ]] || [[ "$2" == "--latest" ]] || [[ -z "$2" ]] && latest=$(getRemoteVersion "$1")
- if [[ "$2" == "-h" ]] || [[ "$2" == "--hash" ]]; then
+ if [[ "$2" == "--hash" ]]; then
[[ "$3" == "-c" ]] || [[ "$3" == "--current" ]] || [[ -z "$3" ]] && curHash=$(getLocalHash "$GITDIR")
[[ "$3" == "-l" ]] || [[ "$3" == "--latest" ]] || [[ -z "$3" ]] && latHash=$(getRemoteHash "$1" "$(cd "$GITDIR" 2> /dev/null && git rev-parse --abbrev-ref HEAD)")
fi
@@ -127,11 +127,11 @@ versionOutput() {
errorOutput
fi
- [[ -n "$output" ]] && echo "$output"
+ [[ -n "$output" ]] && echo " $output"
}
errorOutput() {
- echo "Invalid Option! Try 'pihole -v -h' for more information."
+ echo " Invalid Option! Try 'pihole -v -h' for more information."
exit 1
}
@@ -142,7 +142,7 @@ defaultOutput() {
}
helpFunc() {
- echo "Usage: pihole -v [REPO | OPTION] [OPTION]
+ echo "Usage: pihole -v [repo | option] [option]
Example: 'pihole -v -p -l'
Show Pi-hole, Admin Console & FTL versions
@@ -154,8 +154,8 @@ Repositories:
Options:
-c, --current Return the current version
-l, --latest Return the latest version
- -h, --hash Return the Github hash from your local repositories
- --help Show this help dialog
+ --hash Return the Github hash from your local repositories
+ -h, --help Show this help dialog
"
exit 0
}
@@ -164,6 +164,6 @@ case "${1}" in
"-p" | "--pihole" ) shift; versionOutput "pi-hole" "$@";;
"-a" | "--admin" ) shift; versionOutput "AdminLTE" "$@";;
"-f" | "--ftl" ) shift; versionOutput "FTL" "$@";;
- "--help" ) helpFunc;;
+ "-h" | "--help" ) helpFunc;;
* ) defaultOutput "$@";;
esac
From 39b74ebfd47e1847ebaff7cfabccb6fdc7d20f90 Mon Sep 17 00:00:00 2001
From: WaLLy3K
Date: Sun, 14 May 2017 12:22:19 +1000
Subject: [PATCH 011/162] Show help for "pihole checkout --help"
---
pihole | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/pihole b/pihole
index 1b75add5..c1359ef9 100755
--- a/pihole
+++ b/pihole
@@ -280,7 +280,7 @@ tailFunc() {
}
piholeCheckoutFunc() {
- if [[ "$2" == "-h" ]]; then
+ if [[ "$2" == "-h" ]] || [[ "$2" == "--help" ]]; then
echo "Usage: pihole checkout [repo] [branch]
Example: 'pihole checkout master' or 'pihole checkout core dev'
Switch Pi-hole subsystems to a different Github branch
From da9ff0cc66929401f82cd6db2536288a187f8021 Mon Sep 17 00:00:00 2001
From: WaLLy3K
Date: Sun, 14 May 2017 19:27:14 +1000
Subject: [PATCH 012/162] Tricorder: Insecure Opt-out
* Check to see if Tricorder is being called directly
* Provide opt-out for insecure transmission of debug log
* Remove mention of internal function from help menu
---
pihole | 17 +++++++++++++++--
1 file changed, 15 insertions(+), 2 deletions(-)
diff --git a/pihole b/pihole
index f24461d3..8cffb5b2 100755
--- a/pihole
+++ b/pihole
@@ -269,10 +269,24 @@ piholeCheckoutFunc() {
}
tricorderFunc() {
+ if [ ! -p "/dev/stdin" ]; then
+ echo "Please do not call Tricorder directly."
+ exit 1
+ fi
+
if command -v openssl &> /dev/null; then
openssl s_client -quiet -connect tricorder.pi-hole.net:9998 2> /dev/null < /dev/stdin
else
- nc tricorder.pi-hole.net 9999 < /dev/stdin
+ echo "The debug log will be transmitted insecurely via plain-text"
+ echo "If you wish to cancel, press Ctrl-C to exit within 10 seconds"
+ secs="10"
+ while [ "$secs" -gt 0 ]; do
+ echo -ne "."
+ sleep 1
+ : $((secs--))
+ done
+ echo " "
+ nc tricorder.pi-hole.net 9999 < /dev/stdin < /dev/stdin
fi
}
@@ -310,7 +324,6 @@ helpFunc() {
::: 'pihole disable 5m' - will disable blocking for 5 minutes
::: restartdns Restart dnsmasq
::: checkout Check out different branches
-::: tricorder Upload log to Pi-hole's medical tricorder (uses SSL when possible)
EOM
exit 0
}
From 69f361a3a1884879fe18ec8c1dccc09fabfc3815 Mon Sep 17 00:00:00 2001
From: DL6ER
Date: Sun, 14 May 2017 16:28:35 +0200
Subject: [PATCH 013/162] :taco: is the new :shipit: squirrel
---
.pullapprove.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.pullapprove.yml b/.pullapprove.yml
index 39566b34..188a64f2 100644
--- a/.pullapprove.yml
+++ b/.pullapprove.yml
@@ -10,7 +10,7 @@ group_defaults:
reset_on_push:
enabled: true
reject_value: -2
- approve_regex: '^(Approved|:shipit:|:\+1:|Engage)'
+ approve_regex: '^(Approved|:shipit:|:\+1:|Engage|:taco:)'
reject_regex: '^(Rejected|:-1:|Borg)'
author_approval:
auto: true
From b9f2ba07173663d011f0bd4a2c2e7dea548ffac3 Mon Sep 17 00:00:00 2001
From: WaLLy3K
Date: Tue, 16 May 2017 09:48:46 +1000
Subject: [PATCH 014/162] Wording changes and bug fix
---
pihole | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/pihole b/pihole
index 8cffb5b2..a630d67d 100755
--- a/pihole
+++ b/pihole
@@ -277,7 +277,8 @@ tricorderFunc() {
if command -v openssl &> /dev/null; then
openssl s_client -quiet -connect tricorder.pi-hole.net:9998 2> /dev/null < /dev/stdin
else
- echo "The debug log will be transmitted insecurely via plain-text"
+ echo "Your debug log will be transmitted unencrypted via plain-text"
+ echo "There is a possibility that this could be intercepted by a third party"
echo "If you wish to cancel, press Ctrl-C to exit within 10 seconds"
secs="10"
while [ "$secs" -gt 0 ]; do
@@ -286,7 +287,7 @@ tricorderFunc() {
: $((secs--))
done
echo " "
- nc tricorder.pi-hole.net 9999 < /dev/stdin < /dev/stdin
+ nc tricorder.pi-hole.net 9999 < /dev/stdin
fi
}
From 7453bf2ee62dfb9c79384ef43856a7446e4173da Mon Sep 17 00:00:00 2001
From: WaLLy3K
Date: Tue, 16 May 2017 10:23:53 +1000
Subject: [PATCH 015/162] Fix wildcard help text
* -wild is not a valid option since we're already using -wild
---
advanced/Scripts/list.sh | 9 ++-------
1 file changed, 2 insertions(+), 7 deletions(-)
diff --git a/advanced/Scripts/list.sh b/advanced/Scripts/list.sh
index 378d8402..308e1f5e 100755
--- a/advanced/Scripts/list.sh
+++ b/advanced/Scripts/list.sh
@@ -40,13 +40,8 @@ helpFunc() {
Example: 'pihole -${param} site.com', or 'pihole -${param} site1.com site2.com'
${type^}list one or more domains
-Options:"
-
- if [[ "${listMain}" == "${wildcardlist}" ]]; then
- echo " -wild, --wildcard Block all subdomains of specified domain"
- fi
-
-echo " -d, --delmode Remove domain(s) from the ${type}list
+Options:
+ -d, --delmode Remove domain(s) from the ${type}list
-nr, --noreload Update ${type}list without refreshing dnsmasq
-q, --quiet Make output less verbose
-h, --help Show this help dialog
From 4e2c6a7b8e6e5825f6e609daf0694b483e27f55c Mon Sep 17 00:00:00 2001
From: DL6ER
Date: Wed, 17 May 2017 12:44:35 +0200
Subject: [PATCH 016/162] Fix logrotation: manual flushing should be done
twice, but automated rotation at midnight should only be done *once*!
---
advanced/Scripts/piholeLogFlush.sh | 34 ++++++++++++++++++++++--------
advanced/pihole.cron | 2 +-
pihole | 4 ++--
3 files changed, 28 insertions(+), 12 deletions(-)
diff --git a/advanced/Scripts/piholeLogFlush.sh b/advanced/Scripts/piholeLogFlush.sh
index 8e4c8266..0a4d12bc 100755
--- a/advanced/Scripts/piholeLogFlush.sh
+++ b/advanced/Scripts/piholeLogFlush.sh
@@ -9,16 +9,32 @@
# Please see LICENSE file for your rights under this license.
echo -n "::: Flushing /var/log/pihole.log ..."
-# Test if logrotate is available on this system
-if command -v /usr/sbin/logrotate >/dev/null; then
- # Flush twice to move all data out of sight of FTL
- /usr/sbin/logrotate --force /etc/pihole/logrotate; sleep 3
- /usr/sbin/logrotate --force /etc/pihole/logrotate
+if [[ "$@" == *"once"* ]]; then
+ # Nightly logrotation
+ if command -v /usr/sbin/logrotate >/dev/null; then
+ # Logrotate once
+ /usr/sbin/logrotate --force /etc/pihole/logrotate
+ else
+ # Copy pihole.log over to pihole.log.1
+ # and empty out pihole.log
+ # Note that moving the file is not an option, as
+ # dnsmasq would happily continue writing into the
+ # moved file (it will have the same file handler)
+ cp /var/log/pihole.log /var/log/pihole.log.1
+ echo " " > /var/log/pihole.log
+ fi
else
- # Flush both pihole.log and pihole.log.1 (if existing)
- echo " " > /var/log/pihole.log
- if [ -f /var/log/pihole.log.1 ]; then
- echo " " > /var/log/pihole.log.1
+ # Manual flushing
+ if command -v /usr/sbin/logrotate >/dev/null; then
+ # Logrotate twice to move all data out of sight of FTL
+ /usr/sbin/logrotate --force /etc/pihole/logrotate; sleep 3
+ /usr/sbin/logrotate --force /etc/pihole/logrotate
+ else
+ # Flush both pihole.log and pihole.log.1 (if existing)
+ echo " " > /var/log/pihole.log
+ if [ -f /var/log/pihole.log.1 ]; then
+ echo " " > /var/log/pihole.log.1
+ fi
fi
fi
echo "... done!"
diff --git a/advanced/pihole.cron b/advanced/pihole.cron
index c885b371..be35dc50 100644
--- a/advanced/pihole.cron
+++ b/advanced/pihole.cron
@@ -24,6 +24,6 @@
# Pi-hole: Flush the log daily at 00:00 so it doesn't get out of control
# Stats will be viewable in the Web interface thanks to the cron job above
# The flush script will use logrotate if available
-00 00 * * * root PATH="$PATH:/usr/local/bin/" pihole flush
+00 00 * * * root PATH="$PATH:/usr/local/bin/" pihole flush once
@reboot root /usr/sbin/logrotate /etc/pihole/logrotate
diff --git a/pihole b/pihole
index feebbc1c..d116e248 100755
--- a/pihole
+++ b/pihole
@@ -61,7 +61,7 @@ debugFunc() {
}
flushFunc() {
- "${PI_HOLE_SCRIPT_DIR}"/piholeLogFlush.sh
+ "${PI_HOLE_SCRIPT_DIR}"/piholeLogFlush.sh "$@"
exit 0
}
@@ -353,7 +353,7 @@ case "${1}" in
"-b" | "blacklist" ) blacklistFunc "$@";;
"-wild" | "wildcard" ) wildcardFunc "$@";;
"-d" | "debug" ) debugFunc "$@";;
- "-f" | "flush" ) flushFunc;;
+ "-f" | "flush" ) flushFunc "$@";;
"-up" | "updatePihole" ) updatePiholeFunc;;
"-r" | "reconfigure" ) reconfigurePiholeFunc;;
"-g" | "updateGravity" ) updateGravityFunc "$@";;
From c9042ffedd110485bd4e248fb2737a6c283fcc01 Mon Sep 17 00:00:00 2001
From: DL6ER
Date: Wed, 17 May 2017 12:51:04 +0200
Subject: [PATCH 017/162] Print echos only when manual flushing is requested
---
advanced/Scripts/piholeLogFlush.sh | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/advanced/Scripts/piholeLogFlush.sh b/advanced/Scripts/piholeLogFlush.sh
index 0a4d12bc..9801d8ac 100755
--- a/advanced/Scripts/piholeLogFlush.sh
+++ b/advanced/Scripts/piholeLogFlush.sh
@@ -8,7 +8,6 @@
# This file is copyright under the latest version of the EUPL.
# Please see LICENSE file for your rights under this license.
-echo -n "::: Flushing /var/log/pihole.log ..."
if [[ "$@" == *"once"* ]]; then
# Nightly logrotation
if command -v /usr/sbin/logrotate >/dev/null; then
@@ -25,6 +24,7 @@ if [[ "$@" == *"once"* ]]; then
fi
else
# Manual flushing
+ echo -n "::: Flushing /var/log/pihole.log ..."
if command -v /usr/sbin/logrotate >/dev/null; then
# Logrotate twice to move all data out of sight of FTL
/usr/sbin/logrotate --force /etc/pihole/logrotate; sleep 3
@@ -36,5 +36,5 @@ else
echo " " > /var/log/pihole.log.1
fi
fi
+ echo "... done!"
fi
-echo "... done!"
From 42eb811910ddb2fcd4a39a1a49b922686126ebce Mon Sep 17 00:00:00 2001
From: DL6ER
Date: Wed, 17 May 2017 12:54:43 +0200
Subject: [PATCH 018/162] Add "quiet" mode + update comments in the cron file
---
advanced/Scripts/piholeLogFlush.sh | 7 ++++++-
advanced/pihole.cron | 7 ++++---
2 files changed, 10 insertions(+), 4 deletions(-)
diff --git a/advanced/Scripts/piholeLogFlush.sh b/advanced/Scripts/piholeLogFlush.sh
index 9801d8ac..cc553b32 100755
--- a/advanced/Scripts/piholeLogFlush.sh
+++ b/advanced/Scripts/piholeLogFlush.sh
@@ -8,6 +8,9 @@
# This file is copyright under the latest version of the EUPL.
# Please see LICENSE file for your rights under this license.
+if [[ "$@" != *"quiet"* ]]; then
+ echo -n "::: Flushing /var/log/pihole.log ..."
+fi
if [[ "$@" == *"once"* ]]; then
# Nightly logrotation
if command -v /usr/sbin/logrotate >/dev/null; then
@@ -24,7 +27,6 @@ if [[ "$@" == *"once"* ]]; then
fi
else
# Manual flushing
- echo -n "::: Flushing /var/log/pihole.log ..."
if command -v /usr/sbin/logrotate >/dev/null; then
# Logrotate twice to move all data out of sight of FTL
/usr/sbin/logrotate --force /etc/pihole/logrotate; sleep 3
@@ -36,5 +38,8 @@ else
echo " " > /var/log/pihole.log.1
fi
fi
+fi
+
+if [[ "$@" != *"quiet"* ]]; then
echo "... done!"
fi
diff --git a/advanced/pihole.cron b/advanced/pihole.cron
index be35dc50..f1beb08c 100644
--- a/advanced/pihole.cron
+++ b/advanced/pihole.cron
@@ -21,9 +21,10 @@
# Pi-hole: Update Pi-hole! Uncomment to enable auto update
#30 2 * * 7 root PATH="$PATH:/usr/local/bin/" pihole updatePihole
-# Pi-hole: Flush the log daily at 00:00 so it doesn't get out of control
-# Stats will be viewable in the Web interface thanks to the cron job above
+# Pi-hole: Flush the log daily at 00:00
# The flush script will use logrotate if available
-00 00 * * * root PATH="$PATH:/usr/local/bin/" pihole flush once
+# parameter "once": logrotate only once (default is twice)
+# parameter "quiet": don't print messages
+00 00 * * * root PATH="$PATH:/usr/local/bin/" pihole flush once quiet
@reboot root /usr/sbin/logrotate /etc/pihole/logrotate
From 1f3db8b6025e6f81b41d7d134ac07559ea6d8ead Mon Sep 17 00:00:00 2001
From: WaLLy3K
Date: Thu, 18 May 2017 12:43:17 +1000
Subject: [PATCH 019/162] Confirm Tricorder is online
* Scan port 9998 to confirm the availability of "tricorder.pi-hole.net"
* Exit codes for upload process
---
pihole | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/pihole b/pihole
index 11369ae1..3db64172 100755
--- a/pihole
+++ b/pihole
@@ -305,9 +305,15 @@ tricorderFunc() {
echo "Please do not call Tricorder directly."
exit 1
fi
+
+ if ! timeout 2 nc -z tricorder.pi-hole.net 9998 &> /dev/null; then
+ echo "Unable to connect to Pi-hole's Tricorder server."
+ exit 1
+ fi
if command -v openssl &> /dev/null; then
openssl s_client -quiet -connect tricorder.pi-hole.net:9998 2> /dev/null < /dev/stdin
+ exit "$?"
else
echo "Your debug log will be transmitted unencrypted via plain-text"
echo "There is a possibility that this could be intercepted by a third party"
@@ -320,6 +326,7 @@ tricorderFunc() {
done
echo " "
nc tricorder.pi-hole.net 9999 < /dev/stdin
+ exit "$?"
fi
}
From a620a5c430f34e0c4bcd4ae906ee60aa982520bd Mon Sep 17 00:00:00 2001
From: WaLLy3K
Date: Thu, 18 May 2017 12:53:32 +1000
Subject: [PATCH 020/162] Formatting consistency
---
pihole | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/pihole b/pihole
index 3db64172..869db5ba 100755
--- a/pihole
+++ b/pihole
@@ -301,7 +301,7 @@ Branches:
}
tricorderFunc() {
- if [ ! -p "/dev/stdin" ]; then
+ if [[ ! -p "/dev/stdin" ]]; then
echo "Please do not call Tricorder directly."
exit 1
fi
@@ -319,7 +319,7 @@ tricorderFunc() {
echo "There is a possibility that this could be intercepted by a third party"
echo "If you wish to cancel, press Ctrl-C to exit within 10 seconds"
secs="10"
- while [ "$secs" -gt 0 ]; do
+ while [[ "$secs" -gt "0" ]]; do
echo -ne "."
sleep 1
: $((secs--))
From 69b41dd72e19e7ed490ce7233638b04d5bc2f4bd Mon Sep 17 00:00:00 2001
From: Mcat12
Date: Fri, 19 May 2017 11:16:34 -0400
Subject: [PATCH 021/162] Add link to Windows DNS Swapper
See #1400
---
README.md | 1 +
1 file changed, 1 insertion(+)
diff --git a/README.md b/README.md
index 75c548e5..6f8813fa 100644
--- a/README.md
+++ b/README.md
@@ -156,6 +156,7 @@ You can view [real-time stats](https://discourse.pi-hole.net/t/how-do-i-view-my-
- [Let your blink1 device blink when Pi-hole filters ads](https://gist.github.com/elpatron68/ec0b4c582e5abf604885ac1e068d233f)
- [Pi-hole Prometheus exporter](https://github.com/nlamirault/pihole_exporter): a [Prometheus](https://prometheus.io/) exporter for Pi-hole
- [Pi-hole Droid - open source Android client](https://github.com/friimaind/pi-hole-droid)
+- [Windows DNS Swapper](https://github.com/roots84/DNS-Swapper), see [#1400](https://github.com/pi-hole/pi-hole/issues/1400)
## Coverage
From 6fa00e7cc86a8fb661ab3343c67b2d30e5d583f1 Mon Sep 17 00:00:00 2001
From: Jacob Salmela
Date: Sat, 20 May 2017 01:34:13 -0500
Subject: [PATCH 022/162] first functions with pretty colors. check OS,
setupVars, and contents of .d dirs
---
advanced/Scripts/piholeDebug.sh | 622 +++++++-------------------------
1 file changed, 128 insertions(+), 494 deletions(-)
diff --git a/advanced/Scripts/piholeDebug.sh b/advanced/Scripts/piholeDebug.sh
index 8020cc80..8d57b085 100755
--- a/advanced/Scripts/piholeDebug.sh
+++ b/advanced/Scripts/piholeDebug.sh
@@ -9,7 +9,9 @@
# Please see LICENSE file for your rights under this license.
-
+# causes a pipeline to produce a failure return code if any command errors.
+# Normally, pipelines only return a failure if the last command errors.
+# In combination with set -e, this will make your script exit if any command in a pipeline errors.
set -o pipefail
######## GLOBAL VARS ########
@@ -28,515 +30,147 @@ PIHOLEGITDIR="/etc/.pihole/"
ADMINGITDIR="/var/www/html/admin/"
WHITELISTMATCHES="/tmp/whitelistmatches.list"
readonly FTLLOG="/var/log/pihole-FTL.log"
+coltable=/opt/pihole/COL_TABLE
-TIMEOUT=60
-# Header info and introduction
-cat << EOM
-::: Beginning Pi-hole debug at $(date)!
-:::
-::: This process collects information from your Pi-hole, and optionally uploads
-::: it to a unique and random directory on tricorder.pi-hole.net.
-:::
-::: NOTE: All log files auto-delete after 48 hours and ONLY the Pi-hole developers
-::: can access your data via the given token. We have taken these extra steps to
-::: secure your data and will work to further reduce any personal information gathered.
-:::
-::: Please read and note any issues, and follow any directions advised during this process.
-EOM
+if [[ -f ${coltable} ]]; then
+ source ${coltable}
+else
+ COL_NC='\e[0m' # No Color
+ COL_YELLOW='\e[1;33m'
+ COL_LIGHT_PURPLE='\e[1;35m'
+ COL_CYAN='\e[0;36m'
+ TICK="[${COL_LIGHT_GREEN}✓${COL_NC}]"
+ CROSS="[${COL_LIGHT_RED}✗${COL_NC}]"
+ INFO="[i]"
+ DONE="${COL_LIGHT_GREEN} done!${COL_NC}"
+ OVER="\r\033[K"
+fi
-source ${VARSFILE}
-
-### Private functions exist here ###
-log_write() {
- echo "${@}" >&3
-}
-
-log_echo() {
- case ${1} in
- -n)
- echo -n "::: ${2}"
- log_write "${2}"
- ;;
- -r)
- echo "::: ${2}"
- log_write "${2}"
- ;;
- -l)
- echo "${2}"
- log_write "${2}"
- ;;
- *)
- echo "::: ${1}"
- log_write "${1}"
- esac
-}
-
-header_write() {
- log_echo ""
- log_echo "---= ${1}"
- log_write ""
-}
-
-file_parse() {
- while read -r line; do
- if [ ! -z "${line}" ]; then
- [[ "${line}" =~ ^#.*$ || ! "${line}" || "${line}" == "WEBPASSWORD="* ]] && continue
- log_write "${line}"
- fi
- done < "${1}"
- log_write ""
-}
-
-block_parse() {
- log_write "${1}"
-}
-
-lsof_parse() {
- local user
- local process
-
- user=$(echo ${1} | cut -f 3 -d ' ' | cut -c 2-)
- process=$(echo ${1} | cut -f 2 -d ' ' | cut -c 2-)
- [[ ${2} -eq ${process} ]] \
- && echo "::: Correctly configured." \
- || log_echo "::: Failure: Incorrectly configured daemon."
-
- log_write "Found user ${user} with process ${process}"
-}
-
-
-version_check() {
- header_write "Detecting Installed Package Versions:"
-
- local error_found
- local pi_hole_ver
- local pi_hole_branch
- local pi_hole_commit
- local admin_ver
- local admin_branch
- local admin_commit
- local light_ver
- local php_ver
- local status
- error_found=0
-
- cd "${PIHOLEGITDIR}" &> /dev/null || \
- { status="Pi-hole git directory not found."; error_found=1; }
- if git status &> /dev/null; then
- pi_hole_ver=$(git describe --tags --abbrev=0)
- pi_hole_branch=$(git rev-parse --abbrev-ref HEAD)
- pi_hole_commit=$(git describe --long --dirty --tags --always)
- log_echo -r "Pi-hole: ${pi_hole_ver:-Untagged} (${pi_hole_branch:-Detached}:${pi_hole_commit})"
+echo_succes_or_fail() {
+ local message="${1}"
+ if [ $? -eq 0 ]; then
+ echo -e " ${TICK} ${message}"
else
- status=${status:-"Pi-hole repository damaged."}
- error_found=1
- fi
- if [[ "${status}" ]]; then
- log_echo "${status}"
- unset status
+ echo -e " ${CROSS} ${message}"
fi
+}
- cd "${ADMINGITDIR}" || \
- { status="Pi-hole Dashboard git directory not found."; error_found=1; }
- if git status &> /dev/null; then
- admin_ver=$(git describe --tags --abbrev=0)
- admin_branch=$(git rev-parse --abbrev-ref HEAD)
- admin_commit=$(git describe --long --dirty --tags --always)
- log_echo -r "Pi-hole Dashboard: ${admin_ver:-Untagged} (${admin_branch:-Detached}:${admin_commit})"
+initiate_debug() {
+ # Clear the screen so the debug log is readable
+ clear
+ echo -e "${COL_LIGHT_PURPLE}*** [ INITIALIZING ]${COL_NC}"
+ echo -e " ${INFO} $(date "+%Y-%m-%d:%H:%M:%S") debug log has been initiated."
+}
+
+# This is a function for visually displaying the curent test that is being run.
+# Accepts one variable: the name of what is being diagnosed
+echo_current_diagnostic() {
+ # Colors are used for visually distinguishing each test in the output
+ echo -e "\n${COL_LIGHT_PURPLE}*** [ DIAGNOSING ]:${COL_NC} ${1}"
+}
+
+if_file_exists() {
+ local file_to_test="${1}"
+ # If the file is readable
+ if [[ -r "${file_to_test}" ]]; then
+ # Return success
+ return 0
else
- status=${status:-"Pi-hole Dashboard repository damaged."}
- error_found=1
- fi
- if [[ "${status}" ]]; then
- log_echo "${status}"
- unset status
+ # Otherwise, return a failure
+ return 1
fi
+}
- if light_ver=$(lighttpd -v |& head -n1 | cut -d " " -f1); then
- log_echo -r "${light_ver}"
- else
- log_echo "lighttpd not installed."
- error_found=1
- fi
- if php_ver=$(php -v |& head -n1); then
- log_echo -r "${php_ver}"
- else
- log_echo "PHP not installed."
- error_found=1
- fi
+get_distro_attributes() {
+ # Put the current Internal Field Separator into another variable so it can be restored later
+ OLD_IFS="$IFS"
+ # Store the distro info in an array and make it global since the OS won't change,
+ # but we'll keep it within the function for better unit testing
+ IFS=$'\r\n' command eval 'distro_info=( $(cat /etc/*release) )'
- return "${error_found}"
+ local distro_attribute
+ for distro_attribute in "${distro_info[@]}"; do
+ # Display the information with the ${INFO} icon
+ # No need to show the support URLs so they are grepped out
+ echo " ${INFO} ${distro_attribute}" | grep -v "_URL" | tr -d '"'
+ done
+ # Set the IFS back to what it was
+ IFS="$OLD_IFS"
+}
+
+diagnose_operating_system() {
+ # Display the current test that is running
+ echo_current_diagnostic "Operating system"
+
+ # If there is a /etc/*release file, it's probably a supported operating system, so we can
+ if_file_exists /etc/*release && \
+ # display the attributes to the user
+ get_distro_attributes || \
+ # If it doesn't exist, it's not a system we currently support
+ echo -e " ${CROSS} ${COL_LIGHT_RED}Distribution unknown -- most likely you are on an unsupported platform and may run into issues.${COL_NC}
+ ${INFO} ${COL_LIGHT_RED}Please see${COL_NC}: ${COL_CYAN}https://discourse.pi-hole.net/t/hardware-software-requirements/273${COL_NC}"
+}
+
+parse_file() {
+ local filename="${1}"
+ OLD_IFS="$IFS"
+ IFS=$'\r\n' command eval 'file_info=( $(cat "${filename}") )'
+
+ local file_lines
+ for file_lines in "${file_info[@]}"; do
+ # Display the information with the ${INFO} icon
+ # No need to show the support URLs so they are grepped out
+ echo " ${INFO} ${file_lines}"
+ done
+ # Set the IFS back to what it was
+ IFS="$OLD_IFS"
+}
+
+diagnose_setup_variables() {
+ # Display the current test that is running
+ echo_current_diagnostic "Setup variables"
+
+ # If the variable file exists,
+ if_file_exists "${VARSFILE}" && \
+ # source it
+ echo -e " ${INFO} Sourcing ${VARSFILE}...";
+ source ${VARSFILE};
+ # and display a green check mark with ${DONE}
+ echo_succes_or_fail "${VARSFILE} is readable and has been sourced." || \
+ # Othwerwise, error out
+ echo_succes_or_fail "${VARSFILE} is not readable.
+ ${INFO} $(ls -l ${VARSFILE} 2>/dev/null)";
+ parse_file "${VARSFILE}"
}
dir_check() {
- header_write "Detecting contents of ${1}:"
- for file in $1*; do
- header_write "File ${file} found"
- echo -n "::: Parsing..."
- file_parse "${file}"
- echo "done"
- done
- echo ":::"
-}
-
-files_check() {
- #Check non-zero length existence of ${1}
- header_write "Detecting existence of ${1}:"
- local search_file="${1}"
- if [[ -s ${search_file} ]]; then
- echo -n "::: File exists, parsing..."
- file_parse "${search_file}"
- echo "done"
- return 0
- else
- log_echo "${1} not found!"
- return 1
- fi
- echo ":::"
-}
-
-source_file() {
- local file_found=$(files_check "${1}") \
- && (source "${1}" &> /dev/null && echo "${file_found} and was successfully sourced") \
- || log_echo -l "${file_found} and could not be sourced"
-}
-
-distro_check() {
- local soft_fail
- header_write "Detecting installed OS Distribution"
- soft_fail=0
- local distro="$(cat /etc/*release)" && block_parse "${distro}" || (log_echo "Distribution details not found." && soft_fail=1)
- return "${soft_fail}"
-}
-
-processor_check() {
- header_write "Checking processor variety"
- log_write $(uname -m) && return 0 || return 1
-}
-
-ipv6_check() {
- # Check if system is IPv6 enabled, for use in other functions
- if [[ $IPV6_ADDRESS ]]; then
- ls /proc/net/if_inet6 &>/dev/null
- return 0
- else
- return 1
- fi
-}
-
-ip_check() {
- local protocol=${1}
- local gravity=${2}
- header_write "Checking IPv${protocol} Stack"
-
- local ip_addr_list="$(ip -${protocol} addr show dev ${PIHOLE_INTERFACE} | awk -F ' ' '{ for(i=1;i<=NF;i++) if ($i ~ '/^inet/') print $(i+1) }')"
- if [[ -n ${ip_addr_list} ]]; then
- log_write "IPv${protocol} on ${PIHOLE_INTERFACE}"
- log_write "Gravity configured for: ${2:-NOT CONFIGURED}"
- log_write "----"
- log_write "${ip_addr_list}"
- echo "::: IPv${protocol} addresses located on ${PIHOLE_INTERFACE}"
- ip_ping_check ${protocol}
- return $(( 0 + $? ))
- else
- log_echo "No IPv${protocol} found on ${PIHOLE_INTERFACE}"
- return 1
- fi
-}
-
-ip_ping_check() {
- local protocol=${1}
- local cmd
-
- if [[ ${protocol} == "6" ]]; then
- cmd="ping6"
- g_addr="2001:4860:4860::8888"
- else
- cmd="ping"
- g_addr="8.8.8.8"
- fi
-
- local ip_def_gateway=$(ip -${protocol} route | grep default | cut -d ' ' -f 3)
- if [[ -n ${ip_def_gateway} ]]; then
- echo -n "::: Pinging default IPv${protocol} gateway: "
- if ! ping_gateway="$(${cmd} -q -W 3 -c 3 -n ${ip_def_gateway} -I ${PIHOLE_INTERFACE} | tail -n 3)"; then
- log_echo "Gateway did not respond."
- return 1
- else
- log_echo "Gateway responded."
- log_write "${ping_gateway}"
- fi
- echo -n "::: Pinging Internet via IPv${protocol}: "
- if ! ping_inet="$(${cmd} -q -W 3 -c 3 -n ${g_addr} -I ${PIHOLE_INTERFACE} | tail -n 3)"; then
- log_echo "Query did not respond."
- return 1
- else
- log_echo "Query responded."
- log_write "${ping_inet}"
- fi
- else
- log_echo " No gateway detected."
- fi
- return 0
-}
-
-port_check() {
- local lsof_value
-
- lsof_value=$(lsof -i ${1}:${2} -FcL | tr '\n' ' ') \
- && lsof_parse "${lsof_value}" "${3}" \
- || log_echo "Failure: IPv${1} Port not in use"
-}
-
-daemon_check() {
- # Check for daemon ${1} on port ${2}
- header_write "Daemon Process Information"
-
- echo "::: Checking ${2} port for ${1} listener."
-
- if [[ ${IPV6_READY} ]]; then
- port_check 6 "${2}" "${1}"
- fi
- lsof_value=$(lsof -i 4:${2} -FcL | tr '\n' ' ') \
- port_check 4 "${2}" "${1}"
-}
-
-testResolver() {
- local protocol="${1}"
- header_write "Resolver Functions Check (IPv${protocol})"
- local IP="${2}"
- local g_addr
- local l_addr
- local url
- local testurl
- local localdig
- local piholedig
- local remotedig
-
- if [[ ${protocol} == "6" ]]; then
- g_addr="2001:4860:4860::8888"
- l_addr="::1"
- r_type="AAAA"
- else
- g_addr="8.8.8.8"
- l_addr="127.0.0.1"
- r_type="A"
- fi
-
- # Find a blocked url that has not been whitelisted.
- url=$(shuf -n 1 "${GRAVITYFILE}" | awk -F ' ' '{ print $2 }')
-
- testurl="${url:-doubleclick.com}"
-
-
- log_write "Resolution of ${testurl} from Pi-hole (${l_addr}):"
- if localdig=$(dig -"${protocol}" "${testurl}" @${l_addr} +short "${r_type}"); then
- log_write "${localdig}"
- else
- log_write "Failed to resolve ${testurl} on Pi-hole (${l_addr})"
- fi
- log_write ""
-
- log_write "Resolution of ${testurl} from Pi-hole (${IP}):"
- if piholedig=$(dig -"${protocol}" "${testurl}" @"${IP}" +short "${r_type}"); then
- log_write "${piholedig}"
- else
- log_write "Failed to resolve ${testurl} on Pi-hole (${IP})"
- fi
- log_write ""
-
-
- log_write "Resolution of ${testurl} from ${g_addr}:"
- if remotedig=$(dig -"${protocol}" "${testurl}" @${g_addr} +short "${r_type}"); then
- log_write "${remotedig:-NXDOMAIN}"
- else
- log_write "Failed to resolve ${testurl} on upstream server ${g_addr}"
- fi
- log_write ""
-}
-
-testChaos(){
- # Check Pi-hole specific records
-
- log_write "Pi-hole dnsmasq specific records lookups"
- log_write "Cache Size:"
- log_write $(dig +short chaos txt cachesize.bind)
- log_write "Upstream Servers:"
- log_write $(dig +short chaos txt servers.bind)
- log_write ""
-
-}
-checkProcesses() {
- header_write "Processes Check"
-
- echo "::: Logging status of lighttpd, dnsmasq and pihole-FTL..."
- PROCESSES=( lighttpd dnsmasq pihole-FTL )
- for i in "${PROCESSES[@]}"; do
- log_write "Status for ${i} daemon:"
- log_write $(systemctl is-active "${i}")
- done
- log_write ""
-}
-
-debugLighttpd() {
- echo "::: Checking for necessary lighttpd files."
- files_check "${LIGHTTPDFILE}"
- files_check "${LIGHTTPDERRFILE}"
- echo ":::"
-}
-
-countdown() {
- local tuvix
- tuvix=${TIMEOUT}
- printf "::: Logging will automatically teminate in %s seconds\n" "${TIMEOUT}"
- while [ $tuvix -ge 1 ]
- do
- printf ":::\t%s seconds left. " "${tuvix}"
- if [[ -z "${WEBCALL}" ]]; then
- printf "\r"
- else
- printf "\n"
- fi
- sleep 5
- tuvix=$(( tuvix - 5 ))
+ local directory="${1}"
+ echo_current_diagnostic "contents of ${directory}"
+ for filename in "${directory}"*; do
+ if_file_exists "${filename}" && \
+ echo_succes_or_fail "Files detected" || \
+ echo_succes_or_fail "directory does not exist"
done
}
-# Continuously append the pihole.log file to the pihole_debug.log file
-dumpPiHoleLog() {
- trap '{ echo -e "\n::: Finishing debug write from interrupt... Quitting!" ; exit 1; }' INT
- echo "::: "
- echo "::: --= User Action Required =--"
- echo -e "::: Try loading a site that you are having trouble with now from a client web browser.. \n:::\t(Press CTRL+C to finish logging.)"
- header_write "pihole.log"
- if [ -e "${PIHOLELOG}" ]; then
- # Dummy process to use for flagging down tail to terminate
- countdown &
- tail -n0 -f --pid=$! "${PIHOLELOG}" >&4
- else
- log_write "No pihole.log file found!"
- printf ":::\tNo pihole.log file found!\n"
- fi
+list_files_in_dir() {
+ local dir_to_parse="${1}"
+ local filename
+ files_found=( $(ls "${dir_to_parse}") )
+ for each_file in "${files_found[@]}"; do
+ # Display the information with the ${INFO} icon
+ echo " ${INFO} ${each_file}"
+ done
+
}
-# Anything to be done after capturing of pihole.log terminates
-finalWork() {
- local tricorder
- echo "::: Finshed debugging!"
-
- # Ensure the file exists, create if not, clear if exists.
- truncate --size=0 "${DEBUG_LOG}"
- chmod 644 ${DEBUG_LOG}
- chown "$USER":pihole ${DEBUG_LOG}
- # copy working temp file to final log location
- cat /proc/$$/fd/3 >> "${DEBUG_LOG}"
- # Straight dump of tailing the logs, can sanitize later if needed.
- cat /proc/$$/fd/4 >> "${DEBUG_LOG}"
-
- echo "::: The debug log can be uploaded to tricorder.pi-hole.net for sharing with developers only."
- if [[ "${AUTOMATED}" ]]; then
- echo "::: Debug script running in automated mode, uploading log to tricorder..."
- tricorder=$(cat /var/log/pihole_debug.log | nc tricorder.pi-hole.net 9999)
- else
- read -r -p "::: Would you like to upload the log? [y/N] " response
- case ${response} in
- [yY][eE][sS]|[yY])
- tricorder=$(cat /var/log/pihole_debug.log | nc tricorder.pi-hole.net 9999)
- ;;
- *)
- echo "::: Log will NOT be uploaded to tricorder."
- ;;
- esac
- fi
- # Check if tricorder.pi-hole.net is reachable and provide token.
- if [ -n "${tricorder}" ]; then
- echo "::: ---=== Your debug token is : ${tricorder} Please make a note of it. ===---"
- echo "::: Contact the Pi-hole team with your token for assistance."
- echo "::: Thank you."
- else
- echo "::: There was an error uploading your debug log."
- echo "::: Please try again or contact the Pi-hole team for assistance."
- fi
- echo "::: A local copy of the Debug log can be found at : /var/log/pihole_debug.log"
+check_dnsmasq_d() {
+ local directory=/etc/dnsmasq.d
+ dir_check "${directory}"
+ list_files_in_dir "${directory}"
}
-### END FUNCTIONS ###
-# Create temporary file for log
-TEMPLOG=$(mktemp /tmp/pihole_temp.XXXXXX)
-# Open handle 3 for templog
-exec 3>"$TEMPLOG"
-# Delete templog, but allow for addressing via file handle.
-rm "$TEMPLOG"
-
-# Create temporary file for logdump using file handle 4
-DUMPLOG=$(mktemp /tmp/pihole_temp.XXXXXX)
-exec 4>"$DUMPLOG"
-rm "$DUMPLOG"
-
-# Gather version of required packages / repositories
-version_check || echo "REQUIRED FILES MISSING"
-# Check for newer setupVars storage file
-source_file "/etc/pihole/setupVars.conf"
-# Gather information about the running distribution
-distro_check || echo "Distro Check soft fail"
-# Gather processor type
-processor_check || echo "Processor Check soft fail"
-
-ip_check 6 ${IPV6_ADDRESS}
-ip_check 4 ${IPV4_ADDRESS}
-
-daemon_check lighttpd http
-daemon_check dnsmasq domain
-daemon_check pihole-FTL 4711
-checkProcesses
-
-# Check local/IP/Google for IPv4 Resolution
-testResolver 4 "${IPV4_ADDRESS%/*}"
-# If IPv6 enabled, check resolution
-if [[ "${IPV6_ADDRESS}" ]]; then
- testResolver 6 "${IPV6_ADDRESS%/*}"
-fi
-# Poll dnsmasq Pi-hole specific queries
-testChaos
-
-debugLighttpd
-
-files_check "${DNSMASQFILE}"
-dir_check "${DNSMASQCONFDIR}"
-files_check "${WHITELISTFILE}"
-files_check "${BLACKLISTFILE}"
-files_check "${ADLISTFILE}"
-
-
-header_write "Analyzing gravity.list"
-
- gravity_length=$(grep -c ^ "${GRAVITYFILE}") \
- && log_write "${GRAVITYFILE} is ${gravity_length} lines long." \
- || log_echo "Warning: No gravity.list file found!"
-
-header_write "Analyzing pihole.log"
-
- pihole_length=$(grep -c ^ "${PIHOLELOG}") \
- && log_write "${PIHOLELOG} is ${pihole_length} lines long." \
- || log_echo "Warning: No pihole.log file found!"
-
- pihole_size=$(du -h "${PIHOLELOG}" | awk '{ print $1 }') \
- && log_write "${PIHOLELOG} is ${pihole_size}." \
- || log_echo "Warning: No pihole.log file found!"
-
-header_write "Analyzing pihole-FTL.log"
-
- FTL_length=$(grep -c ^ "${FTLLOG}") \
- && log_write "${FTLLOG} is ${FTL_length} lines long." \
- || log_echo "Warning: No pihole-FTL.log file found!"
-
- FTL_size=$(du -h "${FTLLOG}" | awk '{ print $1 }') \
- && log_write "${FTLLOG} is ${FTL_size}." \
- || log_echo "Warning: No pihole-FTL.log file found!"
-
-tail -n50 "${FTLLOG}" >&3
-
-trap finalWork EXIT
-
-### Method calls for additional logging ###
-dumpPiHoleLog
+initiate_debug
+diagnose_operating_system
+diagnose_setup_variables
+check_dnsmasq_d
From 5d7ef9281f3b7ee02070e3bb8797da4bc97007ca Mon Sep 17 00:00:00 2001
From: Jacob Salmela
Date: Sat, 20 May 2017 02:01:56 -0500
Subject: [PATCH 023/162] get just the OS pretty name for Dan
---
advanced/Scripts/piholeDebug.sh | 11 ++++++++---
1 file changed, 8 insertions(+), 3 deletions(-)
diff --git a/advanced/Scripts/piholeDebug.sh b/advanced/Scripts/piholeDebug.sh
index 8d57b085..c89218b6 100755
--- a/advanced/Scripts/piholeDebug.sh
+++ b/advanced/Scripts/piholeDebug.sh
@@ -90,9 +90,14 @@ get_distro_attributes() {
local distro_attribute
for distro_attribute in "${distro_info[@]}"; do
- # Display the information with the ${INFO} icon
- # No need to show the support URLs so they are grepped out
- echo " ${INFO} ${distro_attribute}" | grep -v "_URL" | tr -d '"'
+ # Display the information with the ${INFO} icon (we need just the OS PRETTY_NAME)
+ pretty_name_key=$(echo "${distro_attribute}" | grep "PRETTY_NAME" | cut -d '=' -f1)
+ if [[ "${pretty_name_key}" == "PRETTY_NAME" ]]; then
+ PRETTY_NAME=$(echo "${distro_attribute}" | grep "PRETTY_NAME" | cut -d '=' -f2- | tr -d '"')
+ echo " ${INFO} ${PRETTY_NAME}"
+ else
+ :
+ fi
done
# Set the IFS back to what it was
IFS="$OLD_IFS"
From c655e6ea7343ffb1bce2f813c4e38f5c5fc6eac4 Mon Sep 17 00:00:00 2001
From: DL6ER
Date: Sat, 20 May 2017 15:47:51 +0200
Subject: [PATCH 024/162] Install loopback firewall rules for FTL (#1419)
* Install loopback firewall rules for FTL
* FirewallD FTL ports
Signed-off-by: Dan Schaper
* Remove firewallD FTL local rules.
Local rules should not be blocked in firewallD, not requred for internal service FTD>
* Reinstate https rules, and delete FTL rules
Fixes earlier commit.
---
automated install/basic-install.sh | 1 +
1 file changed, 1 insertion(+)
diff --git a/automated install/basic-install.sh b/automated install/basic-install.sh
index 7d5a5d0e..a2aff252 100755
--- a/automated install/basic-install.sh
+++ b/automated install/basic-install.sh
@@ -980,6 +980,7 @@ configureFirewall() {
iptables -C INPUT -p tcp -m tcp --dport 80 -j ACCEPT &> /dev/null || iptables -I INPUT 1 -p tcp -m tcp --dport 80 -j ACCEPT
iptables -C INPUT -p tcp -m tcp --dport 53 -j ACCEPT &> /dev/null || iptables -I INPUT 1 -p tcp -m tcp --dport 53 -j ACCEPT
iptables -C INPUT -p udp -m udp --dport 53 -j ACCEPT &> /dev/null || iptables -I INPUT 1 -p udp -m udp --dport 53 -j ACCEPT
+ iptables -C INPUT -p tcp -m tcp --dport 4711:4720 -i lo -j ACCEPT &> /dev/null || iptables -I INPUT 1 -p tcp -m tcp --dport 4711:4720 -i lo -j ACCEPT
return 0
fi
else
From 2ef87ad110f849dce59a3f3dd336fb35e459ce5b Mon Sep 17 00:00:00 2001
From: WaLLy3K
Date: Mon, 22 May 2017 06:47:26 +1000
Subject: [PATCH 025/162] Retrieve local repos on repair (#1481)
* Retrieve local repos on repair
* Change conditional to check for repair
* Change wording of Update/Reconfigure message
* Fixed indenting
* Perform "git reset --hard" on reconfigure
---
automated install/basic-install.sh | 29 +++++++++++++++--------------
1 file changed, 15 insertions(+), 14 deletions(-)
diff --git a/automated install/basic-install.sh b/automated install/basic-install.sh
index a2aff252..5d893067 100755
--- a/automated install/basic-install.sh
+++ b/automated install/basic-install.sh
@@ -1180,22 +1180,23 @@ update_dialogs() {
}
clone_or_update_repos() {
-if [[ "${reconfigure}" == true ]]; then
- echo "::: --reconfigure passed to install script. Not downloading/updating local repos"
- else
- # Get Git files for Core and Admin
- getGitFiles ${PI_HOLE_LOCAL_REPO} ${piholeGitUrl} || \
- { echo "!!! Unable to clone ${piholeGitUrl} into ${PI_HOLE_LOCAL_REPO}, unable to continue."; \
- exit 1; \
- }
+ if [[ "${reconfigure}" == true ]]; then
+ echo "::: --reconfigure passed to install script. Resetting changes to local repos"
+ git reset --hard
+ else
+ # Get Git files for Core and Admin
+ getGitFiles ${PI_HOLE_LOCAL_REPO} ${piholeGitUrl} || \
+ { echo "!!! Unable to clone ${piholeGitUrl} into ${PI_HOLE_LOCAL_REPO}, unable to continue."; \
+ exit 1; \
+ }
- if [[ ${INSTALL_WEB} == true ]]; then
- getGitFiles ${webInterfaceDir} ${webInterfaceGitUrl} || \
- { echo "!!! Unable to clone ${webInterfaceGitUrl} into ${webInterfaceDir}, unable to continue."; \
- exit 1; \
- }
- fi
+ if [[ ${INSTALL_WEB} == true ]]; then
+ getGitFiles ${webInterfaceDir} ${webInterfaceGitUrl} || \
+ { echo "!!! Unable to clone ${webInterfaceGitUrl} into ${webInterfaceDir}, unable to continue."; \
+ exit 1; \
+ }
fi
+ fi
}
FTLinstall() {
From 69fe889f92904ed73a02f75f01be80111cf9fe67 Mon Sep 17 00:00:00 2001
From: Jacob Salmela
Date: Sun, 21 May 2017 23:25:53 -0500
Subject: [PATCH 026/162] comments for all lines and small formatting changes
---
advanced/Scripts/piholeDebug.sh | 62 +++++++++++++++++++++++++--------
1 file changed, 47 insertions(+), 15 deletions(-)
diff --git a/advanced/Scripts/piholeDebug.sh b/advanced/Scripts/piholeDebug.sh
index c89218b6..faf68fb9 100755
--- a/advanced/Scripts/piholeDebug.sh
+++ b/advanced/Scripts/piholeDebug.sh
@@ -47,11 +47,15 @@ else
fi
echo_succes_or_fail() {
+ # Set the first argument passed to tihs function as a named variable for better readability
local message="${1}"
+ # If the command was successful (a zero),
if [ $? -eq 0 ]; then
- echo -e " ${TICK} ${message}"
+ # show success
+ echo -e " ${TICK} ${message}"
else
- echo -e " ${CROSS} ${message}"
+ # Otherwise, show a error
+ echo -e " ${CROSS} ${message}"
fi
}
@@ -59,17 +63,20 @@ initiate_debug() {
# Clear the screen so the debug log is readable
clear
echo -e "${COL_LIGHT_PURPLE}*** [ INITIALIZING ]${COL_NC}"
- echo -e " ${INFO} $(date "+%Y-%m-%d:%H:%M:%S") debug log has been initiated."
+ # Timestamp the start of the log
+ echo -e " ${INFO} $(date "+%Y-%m-%d:%H:%M:%S") debug log has been initiated."
}
# This is a function for visually displaying the curent test that is being run.
# Accepts one variable: the name of what is being diagnosed
+# Colors do not show in the dasboard, but the icons do: [i], [✓], and [✗]
echo_current_diagnostic() {
# Colors are used for visually distinguishing each test in the output
echo -e "\n${COL_LIGHT_PURPLE}*** [ DIAGNOSING ]:${COL_NC} ${1}"
}
if_file_exists() {
+ # Set the first argument passed to tihs function as a named variable for better readability
local file_to_test="${1}"
# If the file is readable
if [[ -r "${file_to_test}" ]]; then
@@ -88,13 +95,17 @@ get_distro_attributes() {
# but we'll keep it within the function for better unit testing
IFS=$'\r\n' command eval 'distro_info=( $(cat /etc/*release) )'
+ # Set a named variable for better readability
local distro_attribute
+ # For each line found in an /etc/*release file,
for distro_attribute in "${distro_info[@]}"; do
- # Display the information with the ${INFO} icon (we need just the OS PRETTY_NAME)
+ # display the information with the ${INFO} icon
pretty_name_key=$(echo "${distro_attribute}" | grep "PRETTY_NAME" | cut -d '=' -f1)
+ # we need just the OS PRETTY_NAME, so print it when we find it
if [[ "${pretty_name_key}" == "PRETTY_NAME" ]]; then
PRETTY_NAME=$(echo "${distro_attribute}" | grep "PRETTY_NAME" | cut -d '=' -f2- | tr -d '"')
- echo " ${INFO} ${PRETTY_NAME}"
+ echo " ${INFO} ${PRETTY_NAME}"
+ # Otherwise, do nothing
else
:
fi
@@ -104,6 +115,8 @@ get_distro_attributes() {
}
diagnose_operating_system() {
+ local faq_url="https://discourse.pi-hole.net/t/hardware-software-requirements/273"
+ local error_msg="Distribution unknown -- most likely you are on an unsupported platform and may run into issues."
# Display the current test that is running
echo_current_diagnostic "Operating system"
@@ -111,21 +124,25 @@ diagnose_operating_system() {
if_file_exists /etc/*release && \
# display the attributes to the user
get_distro_attributes || \
- # If it doesn't exist, it's not a system we currently support
- echo -e " ${CROSS} ${COL_LIGHT_RED}Distribution unknown -- most likely you are on an unsupported platform and may run into issues.${COL_NC}
- ${INFO} ${COL_LIGHT_RED}Please see${COL_NC}: ${COL_CYAN}https://discourse.pi-hole.net/t/hardware-software-requirements/273${COL_NC}"
+ # If it doesn't exist, it's not a system we currently support and link to FAQ
+ echo -e " ${CROSS} ${COL_LIGHT_RED}${error_msg}${COL_NC}
+ ${INFO} ${COL_LIGHT_RED}Please see${COL_NC}: ${COL_CYAN}${faq_url}${COL_NC}"
}
parse_file() {
+ # Set the first argument passed to tihs function as a named variable for better readability
local filename="${1}"
+ # Put the current Internal Field Separator into another variable so it can be restored later
OLD_IFS="$IFS"
+ # Get the lines that are in the file(s) and store them in an array for parsing later
IFS=$'\r\n' command eval 'file_info=( $(cat "${filename}") )'
+ # Set a named variable for better readability
local file_lines
+ # For each lin in the file,
for file_lines in "${file_info[@]}"; do
- # Display the information with the ${INFO} icon
- # No need to show the support URLs so they are grepped out
- echo " ${INFO} ${file_lines}"
+ # display the information with the ${INFO} icon
+ echo " ${INFO} ${file_lines}"
done
# Set the IFS back to what it was
IFS="$OLD_IFS"
@@ -138,40 +155,55 @@ diagnose_setup_variables() {
# If the variable file exists,
if_file_exists "${VARSFILE}" && \
# source it
- echo -e " ${INFO} Sourcing ${VARSFILE}...";
+ echo -e " ${INFO} Sourcing ${VARSFILE}...";
source ${VARSFILE};
# and display a green check mark with ${DONE}
echo_succes_or_fail "${VARSFILE} is readable and has been sourced." || \
# Othwerwise, error out
echo_succes_or_fail "${VARSFILE} is not readable.
- ${INFO} $(ls -l ${VARSFILE} 2>/dev/null)";
+ ${INFO} $(ls -l ${VARSFILE} 2>/dev/null)";
parse_file "${VARSFILE}"
}
+# This function can check a directory exists
+# Pi-hole has files in several places, so we will reuse this function
dir_check() {
+ # Set the first argument passed to tihs function as a named variable for better readability
local directory="${1}"
+ # Display the current test that is running
echo_current_diagnostic "contents of ${directory}"
+ # For each file in the directory,
for filename in "${directory}"*; do
+ # check if exists first; if it does,
if_file_exists "${filename}" && \
+ # show a success message
echo_succes_or_fail "Files detected" || \
+ # Otherwise, show an error
echo_succes_or_fail "directory does not exist"
done
}
list_files_in_dir() {
+ # Set the first argument passed to tihs function as a named variable for better readability
local dir_to_parse="${1}"
+ # Set another local variable for better readability
local filename
+ # Store the files found in an array
files_found=( $(ls "${dir_to_parse}") )
+ # For each file in the arry,
for each_file in "${files_found[@]}"; do
- # Display the information with the ${INFO} icon
- echo " ${INFO} ${each_file}"
+ # display the information with the ${INFO} icon
+ echo " ${INFO} ${each_file}"
done
}
check_dnsmasq_d() {
+ # Set a local variable for better readability
local directory=/etc/dnsmasq.d
+ # Check if the directory exists
dir_check "${directory}"
+ # if it does, list the files in it
list_files_in_dir "${directory}"
}
From 1aa5943e67d8237344538074990556d5a3522319 Mon Sep 17 00:00:00 2001
From: Jacob Salmela
Date: Mon, 22 May 2017 01:06:15 -0500
Subject: [PATCH 027/162] add if directory exists function
---
advanced/Scripts/piholeDebug.sh | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/advanced/Scripts/piholeDebug.sh b/advanced/Scripts/piholeDebug.sh
index faf68fb9..9da749e7 100755
--- a/advanced/Scripts/piholeDebug.sh
+++ b/advanced/Scripts/piholeDebug.sh
@@ -88,6 +88,19 @@ if_file_exists() {
fi
}
+if_directory_exists() {
+ # Set the first argument passed to tihs function as a named variable for better readability
+ local directory_to_test="${1}"
+ # If the file is readable
+ if [[ -d "${directory_to_test}" ]]; then
+ # Return success
+ return 0
+ else
+ # Otherwise, return a failure
+ return 1
+ fi
+}
+
get_distro_attributes() {
# Put the current Internal Field Separator into another variable so it can be restored later
OLD_IFS="$IFS"
From 6c4a7b626ec9e6286c97ccafd43cbe50a8b459a4 Mon Sep 17 00:00:00 2001
From: Jacob Salmela
Date: Mon, 22 May 2017 02:39:00 -0500
Subject: [PATCH 028/162] add pihole version check functions
---
advanced/Scripts/piholeDebug.sh | 53 ++++++++++++++++++++++++++++++---
1 file changed, 49 insertions(+), 4 deletions(-)
diff --git a/advanced/Scripts/piholeDebug.sh b/advanced/Scripts/piholeDebug.sh
index 9da749e7..71d59d39 100755
--- a/advanced/Scripts/piholeDebug.sh
+++ b/advanced/Scripts/piholeDebug.sh
@@ -75,7 +75,7 @@ echo_current_diagnostic() {
echo -e "\n${COL_LIGHT_PURPLE}*** [ DIAGNOSING ]:${COL_NC} ${1}"
}
-if_file_exists() {
+file_exists() {
# Set the first argument passed to tihs function as a named variable for better readability
local file_to_test="${1}"
# If the file is readable
@@ -101,6 +101,48 @@ if_directory_exists() {
fi
}
+check_core_version() {
+ echo_current_diagnostic "Pi-hole Versions"
+ local error_msg="git status failed"
+ if_directory_exists "${PIHOLEGITDIR}" && \
+ cd "${PIHOLEGITDIR}" || \
+ echo "pihole repo does not exist"
+ if git status &> /dev/null; then
+ PI_HOLE_VERSION=$(git describe --tags --abbrev=0);
+ PI_HOLE_BRANCH=$(git rev-parse --abbrev-ref HEAD);
+ PI_HOLE_COMMIT=$(git describe --long --dirty --tags --always)
+ echo -e " ${INFO} Core: ${PI_HOLE_VERSION}
+ ${INFO} Branch: ${PI_HOLE_BRANCH}
+ ${INFO} Commit: ${PI_HOLE_COMMIT}"
+ else
+ echo "${error_msg}"
+ return 1
+ fi
+}
+
+check_web_version() {
+ local error_msg="git status failed"
+ if_directory_exists "${ADMINGITDIR}" && \
+ cd "${ADMINGITDIR}" || \
+ echo "repo does not exist"
+ if git status &> /dev/null; then
+ WEB_VERSION=$(git describe --tags --abbrev=0);
+ WEB_BRANCH=$(git rev-parse --abbrev-ref HEAD);
+ WEB_COMMIT=$(git describe --long --dirty --tags --always)
+ echo -e " ${INFO} Web: ${WEB_VERSION}
+ ${INFO} Branch: ${WEB_BRANCH}
+ ${INFO} Commit: ${WEB_COMMIT}"
+ else
+ echo "${error_msg}"
+ return 1
+ fi
+}
+
+check_ftl_version() {
+ FTL_VERSION=$(pihole-FTL version)
+ echo -e " ${INFO} FTL: ${FTL_VERSION}"
+}
+
get_distro_attributes() {
# Put the current Internal Field Separator into another variable so it can be restored later
OLD_IFS="$IFS"
@@ -134,7 +176,7 @@ diagnose_operating_system() {
echo_current_diagnostic "Operating system"
# If there is a /etc/*release file, it's probably a supported operating system, so we can
- if_file_exists /etc/*release && \
+ file_exists /etc/*release && \
# display the attributes to the user
get_distro_attributes || \
# If it doesn't exist, it's not a system we currently support and link to FAQ
@@ -166,7 +208,7 @@ diagnose_setup_variables() {
echo_current_diagnostic "Setup variables"
# If the variable file exists,
- if_file_exists "${VARSFILE}" && \
+ file_exists "${VARSFILE}" && \
# source it
echo -e " ${INFO} Sourcing ${VARSFILE}...";
source ${VARSFILE};
@@ -188,7 +230,7 @@ dir_check() {
# For each file in the directory,
for filename in "${directory}"*; do
# check if exists first; if it does,
- if_file_exists "${filename}" && \
+ file_exists "${filename}" && \
# show a success message
echo_succes_or_fail "Files detected" || \
# Otherwise, show an error
@@ -221,6 +263,9 @@ check_dnsmasq_d() {
}
initiate_debug
+check_core_version
+check_web_version
+check_ftl_version
diagnose_operating_system
diagnose_setup_variables
check_dnsmasq_d
From daff5d8b5a21182fa86f75d4c325afdfeb8697b6 Mon Sep 17 00:00:00 2001
From: Jacob Salmela
Date: Mon, 22 May 2017 03:05:51 -0500
Subject: [PATCH 029/162] add critical dependencies version check functions
---
advanced/Scripts/piholeDebug.sh | 29 +++++++++++++++++++++++++++++
1 file changed, 29 insertions(+)
diff --git a/advanced/Scripts/piholeDebug.sh b/advanced/Scripts/piholeDebug.sh
index 71d59d39..d1f49f7c 100755
--- a/advanced/Scripts/piholeDebug.sh
+++ b/advanced/Scripts/piholeDebug.sh
@@ -143,6 +143,34 @@ check_ftl_version() {
echo -e " ${INFO} FTL: ${FTL_VERSION}"
}
+check_web_server_version() {
+ WEB_SERVER="lighttpd"
+ WEB_SERVER_VERSON="$(lighttpd -v |& head -n1 | cut -d '/' -f2 | cut -d ' ' -f1)"
+ echo -e " ${INFO} ${WEB_SERVER}"
+ if [[ -z "${WEB_SERVER_VERSON}" ]]; then
+ echo -e " ${CROSS} ${WEB_SERVER} version could not be detected."
+ else
+ echo -e " ${TICK} ${WEB_SERVER_VERSON}"
+ fi
+}
+
+check_resolver_version() {
+ RESOLVER="dnsmasq"
+ RESOVLER_VERSON="$(dnsmasq -v |& head -n1 | awk '{print $3}')"
+ echo -e " ${INFO} ${RESOLVER}"
+ if [[ -z "${RESOVLER_VERSON}" ]]; then
+ echo -e " ${CROSS} ${RESOLVER} version could not be detected."
+ else
+ echo -e " ${TICK} ${RESOVLER_VERSON}"
+ fi
+}
+
+check_critical_dependencies() {
+ echo_current_diagnostic "Versions of critical dependencies"
+ check_web_server_version
+ check_web_server_version
+}
+
get_distro_attributes() {
# Put the current Internal Field Separator into another variable so it can be restored later
OLD_IFS="$IFS"
@@ -267,5 +295,6 @@ check_core_version
check_web_version
check_ftl_version
diagnose_operating_system
+check_critical_dependencies
diagnose_setup_variables
check_dnsmasq_d
From 8c5c1316dd83295bbb196d218faed5ec80403b55 Mon Sep 17 00:00:00 2001
From: Jacob Salmela
Date: Mon, 22 May 2017 08:48:56 -0500
Subject: [PATCH 030/162] add php version and processor check functions
---
advanced/Scripts/piholeDebug.sh | 23 +++++++++++++++++++++++
1 file changed, 23 insertions(+)
diff --git a/advanced/Scripts/piholeDebug.sh b/advanced/Scripts/piholeDebug.sh
index d1f49f7c..50db8a97 100755
--- a/advanced/Scripts/piholeDebug.sh
+++ b/advanced/Scripts/piholeDebug.sh
@@ -165,10 +165,22 @@ check_resolver_version() {
fi
}
+check_php_version() {
+ PHP_VERSION=$(php -v |& head -n1 | cut -d '-' -f1 | cut -d ' ' -f2)
+ echo -e " ${INFO} PHP"
+ if [[ -z "${PHP_VERSION}" ]]; then
+ echo -e " ${CROSS} PHP version could not be detected."
+ else
+ echo -e " ${TICK} ${PHP_VERSION}"
+ fi
+
+}
+
check_critical_dependencies() {
echo_current_diagnostic "Versions of critical dependencies"
check_web_server_version
check_web_server_version
+ check_php_version
}
get_distro_attributes() {
@@ -212,6 +224,16 @@ diagnose_operating_system() {
${INFO} ${COL_LIGHT_RED}Please see${COL_NC}: ${COL_CYAN}${faq_url}${COL_NC}"
}
+processor_check() {
+ echo_current_diagnostic "Processor"
+ PROCESSOR=$(uname -m)
+ if [[ -z "${PROCESSOR}" ]]; then
+ echo -e " ${CROSS} Processor could not be identified."
+ else
+ echo -e " ${INFO} ${PROCESSOR}"
+ fi
+}
+
parse_file() {
# Set the first argument passed to tihs function as a named variable for better readability
local filename="${1}"
@@ -295,6 +317,7 @@ check_core_version
check_web_version
check_ftl_version
diagnose_operating_system
+processor_check
check_critical_dependencies
diagnose_setup_variables
check_dnsmasq_d
From 8fd9a22d18c36f429a9bfa3e79f05e26e5c027b7 Mon Sep 17 00:00:00 2001
From: Jacob Salmela
Date: Mon, 22 May 2017 12:05:42 -0500
Subject: [PATCH 031/162] add detect IP function
---
advanced/Scripts/piholeDebug.sh | 33 +++++++++++++++++++++++++++++----
1 file changed, 29 insertions(+), 4 deletions(-)
diff --git a/advanced/Scripts/piholeDebug.sh b/advanced/Scripts/piholeDebug.sh
index 50db8a97..e13bff0f 100755
--- a/advanced/Scripts/piholeDebug.sh
+++ b/advanced/Scripts/piholeDebug.sh
@@ -228,9 +228,34 @@ processor_check() {
echo_current_diagnostic "Processor"
PROCESSOR=$(uname -m)
if [[ -z "${PROCESSOR}" ]]; then
- echo -e " ${CROSS} Processor could not be identified."
+ echo -e " ${CROSS} Processor could not be identified."
else
- echo -e " ${INFO} ${PROCESSOR}"
+ echo -e " ${INFO} ${PROCESSOR}"
+ fi
+}
+
+detect_ip_addresses() {
+ # First argument should be a 4 or a 6
+ local protocol=${1}
+ # Use ip to show the addresses for the chosen protocol
+ # Store the values in an arry so they can be looped through
+ # Get the lines that are in the file(s) and store them in an array for parsing later
+ declare -a ip_addr_list=( $(ip -${protocol} addr show dev ${PIHOLE_INTERFACE} | awk -F ' ' '{ for(i=1;i<=NF;i++) if ($i ~ '/^inet/') print $(i+1) }') )
+
+ # If there is something in the IP address list,
+ if [[ -n ${ip_addr_list} ]]; then
+ # Local iterator
+ local i
+ echo -e " ${INFO} IPv${protocol}"
+ # display the contents to the user
+ echo -e " ${INFO} Interface: ${PIHOLE_INTERFACE}"
+ for i in "${ip_addr_list[@]}"; do
+ echo -e " ${INFO} $i"
+ done
+ # Othwerwise explain that the protocol is not configured
+ else
+ echo -e " ${CROSS} No IPv${protocol} found on ${PIHOLE_INTERFACE}"
+ return 1
fi
}
@@ -260,8 +285,8 @@ diagnose_setup_variables() {
# If the variable file exists,
file_exists "${VARSFILE}" && \
# source it
- echo -e " ${INFO} Sourcing ${VARSFILE}...";
source ${VARSFILE};
+ echo -e " ${INFO} Sourcing ${VARSFILE}...";
# and display a green check mark with ${DONE}
echo_succes_or_fail "${VARSFILE} is readable and has been sourced." || \
# Othwerwise, error out
@@ -316,8 +341,8 @@ initiate_debug
check_core_version
check_web_version
check_ftl_version
+diagnose_setup_variables
diagnose_operating_system
processor_check
check_critical_dependencies
-diagnose_setup_variables
check_dnsmasq_d
From 107babe8f4578bacc436c4fc519eb31fafc1fff3 Mon Sep 17 00:00:00 2001
From: Jacob Salmela
Date: Mon, 22 May 2017 12:35:57 -0500
Subject: [PATCH 032/162] add ping gateway function
---
advanced/Scripts/piholeDebug.sh | 63 +++++++++++++++++++++++++++++----
1 file changed, 57 insertions(+), 6 deletions(-)
diff --git a/advanced/Scripts/piholeDebug.sh b/advanced/Scripts/piholeDebug.sh
index e13bff0f..b47d0203 100755
--- a/advanced/Scripts/piholeDebug.sh
+++ b/advanced/Scripts/piholeDebug.sh
@@ -246,19 +246,69 @@ detect_ip_addresses() {
if [[ -n ${ip_addr_list} ]]; then
# Local iterator
local i
- echo -e " ${INFO} IPv${protocol}"
- # display the contents to the user
- echo -e " ${INFO} Interface: ${PIHOLE_INTERFACE}"
- for i in "${ip_addr_list[@]}"; do
- echo -e " ${INFO} $i"
+ echo -e " ${TICK} IPv${protocol} on ${PIHOLE_INTERFACE}"
+ for i in "${!ip_addr_list[@]}"; do
+ echo -e " [$i] ${ip_addr_list[$i]}"
done
# Othwerwise explain that the protocol is not configured
else
- echo -e " ${CROSS} No IPv${protocol} found on ${PIHOLE_INTERFACE}"
+ echo -e " ${CROSS} No IPv${protocol} found on ${PIHOLE_INTERFACE}"
return 1
fi
}
+
+ping_gateway() {
+ # First argument should be a 4 or a 6
+ local protocol="${1}"
+ # If the protocol is 6,
+ if [[ ${protocol} == "6" ]]; then
+ # use ping6
+ local cmd="ping6"
+ # and Google's public IPv6 address
+ local public_address="2001:4860:4860::8888"
+ # Otherwise,
+ else
+ # use ping
+ local cmd="ping"
+ # and Google's public IPv4 address
+ local public_address="8.8.8.8"
+ fi
+
+ # Find the default gateway using IPv4 or IPv6
+ local gateway
+ gateway="$(ip -${protocol} route | grep default | cut -d ' ' -f 3)"
+
+ # If the gateway variable has a value (meaning a gateway was found),
+ if [[ -n "${gateway}" ]]; then
+ # Let the user know we will ping the gateway for a response
+ echo -e " ${INFO} Trying three pings on IPv${protocol} gateway at ${gateway}..."
+ # Try to quietly ping the gateway 3 times, with a timeout of 3 seconds, using numeric output only,
+ # on the pihole interface, and tail the last three lines of the output
+ # If pinging the gateway is not successful,
+ if ! ping_cmd="$(${cmd} -q -c 3 -W 3 -n ${gateway} -I ${PIHOLE_INTERFACE} | tail -n 3)"; then
+ # let the user know
+ echo -e " ${CROSS} Gateway did not respond."
+ # and return an error code
+ return 1
+ # Otherwise,
+ else
+ # show a success
+ echo -e " ${TICK} Gateway responded."
+ # and return a success code
+ return 0
+ fi
+ fi
+}
+
+check_networking() {
+ echo_current_diagnostic "Networking"
+ detect_ip_addresses "4"
+ ping_gateway "4"
+ detect_ip_addresses "6"
+ ping_gateway "6"
+}
+
parse_file() {
# Set the first argument passed to tihs function as a named variable for better readability
local filename="${1}"
@@ -344,5 +394,6 @@ check_ftl_version
diagnose_setup_variables
diagnose_operating_system
processor_check
+check_networking
check_critical_dependencies
check_dnsmasq_d
From b74300f67cfb9ae356250b96deeb2dbfef787087 Mon Sep 17 00:00:00 2001
From: Jacob Salmela
Date: Mon, 22 May 2017 12:57:55 -0500
Subject: [PATCH 033/162] add ping internet function and fix some spacing
issues
---
advanced/Scripts/piholeDebug.sh | 37 +++++++++++++++++++++++++++------
1 file changed, 31 insertions(+), 6 deletions(-)
diff --git a/advanced/Scripts/piholeDebug.sh b/advanced/Scripts/piholeDebug.sh
index b47d0203..634e2ffa 100755
--- a/advanced/Scripts/piholeDebug.sh
+++ b/advanced/Scripts/piholeDebug.sh
@@ -148,9 +148,9 @@ check_web_server_version() {
WEB_SERVER_VERSON="$(lighttpd -v |& head -n1 | cut -d '/' -f2 | cut -d ' ' -f1)"
echo -e " ${INFO} ${WEB_SERVER}"
if [[ -z "${WEB_SERVER_VERSON}" ]]; then
- echo -e " ${CROSS} ${WEB_SERVER} version could not be detected."
+ echo -e " ${CROSS} ${WEB_SERVER} version could not be detected."
else
- echo -e " ${TICK} ${WEB_SERVER_VERSON}"
+ echo -e " ${TICK} ${WEB_SERVER_VERSON}"
fi
}
@@ -159,9 +159,9 @@ check_resolver_version() {
RESOVLER_VERSON="$(dnsmasq -v |& head -n1 | awk '{print $3}')"
echo -e " ${INFO} ${RESOLVER}"
if [[ -z "${RESOVLER_VERSON}" ]]; then
- echo -e " ${CROSS} ${RESOLVER} version could not be detected."
+ echo -e " ${CROSS} ${RESOLVER} version could not be detected."
else
- echo -e " ${TICK} ${RESOVLER_VERSON}"
+ echo -e " ${TICK} ${RESOVLER_VERSON}"
fi
}
@@ -169,9 +169,9 @@ check_php_version() {
PHP_VERSION=$(php -v |& head -n1 | cut -d '-' -f1 | cut -d ' ' -f2)
echo -e " ${INFO} PHP"
if [[ -z "${PHP_VERSION}" ]]; then
- echo -e " ${CROSS} PHP version could not be detected."
+ echo -e " ${CROSS} PHP version could not be detected."
else
- echo -e " ${TICK} ${PHP_VERSION}"
+ echo -e " ${TICK} ${PHP_VERSION}"
fi
}
@@ -301,6 +301,31 @@ ping_gateway() {
fi
}
+ping_internet() {
+ local protocol="${1}"
+ # If the protocol is 6,
+ if [[ ${protocol} == "6" ]]; then
+ # use ping6
+ local cmd="ping6"
+ # and Google's public IPv6 address
+ local public_address="2001:4860:4860::8888"
+ # Otherwise,
+ else
+ # use ping
+ local cmd="ping"
+ # and Google's public IPv4 address
+ local public_address="8.8.8.8"
+ fi
+ echo -n " ${INFO} Trying three pings on IPv${protocol} to reach the Internet..."
+ if ! ping_inet="$(${cmd} -q -W 3 -c 3 -n ${public_address} -I ${PIHOLE_INTERFACE} | tail -n 3)"; then
+ echo -e " ${CROSS} Cannot reach the Internet"
+ return 1
+ else
+ echo -e " ${TICK} Query responded."
+ return 0
+ fi
+}
+
check_networking() {
echo_current_diagnostic "Networking"
detect_ip_addresses "4"
From 74eb8c8622ef701aad3d509bf88d9d7e3c6ceb40 Mon Sep 17 00:00:00 2001
From: DL6ER
Date: Mon, 22 May 2017 23:43:52 +0200
Subject: [PATCH 034/162] Change directory before trying to reset repository.
Fixes #1489
---
automated install/basic-install.sh | 24 +++++++++++++++++++++++-
1 file changed, 23 insertions(+), 1 deletion(-)
diff --git a/automated install/basic-install.sh b/automated install/basic-install.sh
index 5d893067..2f4459d4 100755
--- a/automated install/basic-install.sh
+++ b/automated install/basic-install.sh
@@ -220,6 +220,19 @@ getGitFiles() {
return 0
}
+resetRepo() {
+ local directory="${1}"
+ local curdir
+
+ curdir="${PWD}"
+ cd "${directory}" &> /dev/null || return 1
+ echo -n "::: Resetting repo in ${1}..."
+ git reset --hard &> /dev/null || return $?
+ echo " done!"
+ cd "${curdir}" &> /dev/null || return 1
+ return 0
+}
+
find_IPv4_information() {
local route
# Find IP used to route to outside world
@@ -1182,7 +1195,16 @@ update_dialogs() {
clone_or_update_repos() {
if [[ "${reconfigure}" == true ]]; then
echo "::: --reconfigure passed to install script. Resetting changes to local repos"
- git reset --hard
+ resetRepo ${PI_HOLE_LOCAL_REPO} || \
+ { echo "!!! Unable to reset ${PI_HOLE_LOCAL_REPO}, unable to continue."; \
+ exit 1; \
+ }
+ if [[ ${INSTALL_WEB} == true ]]; then
+ resetRepo ${webInterfaceDir} || \
+ { echo "!!! Unable to reset ${webInterfaceDir}, unable to continue."; \
+ exit 1; \
+ }
+ fi
else
# Get Git files for Core and Admin
getGitFiles ${PI_HOLE_LOCAL_REPO} ${piholeGitUrl} || \
From 5004cf331abf54a80c12109ecc5f8f80538686f5 Mon Sep 17 00:00:00 2001
From: Dan Schaper
Date: Mon, 22 May 2017 15:36:51 -0700
Subject: [PATCH 035/162] No need to `cd $PWD` as it doesn't affect flow of
caller script.
Signed-off-by: Dan Schaper
---
automated install/basic-install.sh | 3 ---
1 file changed, 3 deletions(-)
diff --git a/automated install/basic-install.sh b/automated install/basic-install.sh
index 2f4459d4..ebf93f4a 100755
--- a/automated install/basic-install.sh
+++ b/automated install/basic-install.sh
@@ -222,14 +222,11 @@ getGitFiles() {
resetRepo() {
local directory="${1}"
- local curdir
- curdir="${PWD}"
cd "${directory}" &> /dev/null || return 1
echo -n "::: Resetting repo in ${1}..."
git reset --hard &> /dev/null || return $?
echo " done!"
- cd "${curdir}" &> /dev/null || return 1
return 0
}
From 3035c9a366e2816397df3ab85e7abc8f2418cee3 Mon Sep 17 00:00:00 2001
From: DL6ER
Date: Tue, 23 May 2017 10:44:11 +0200
Subject: [PATCH 036/162] Refine output of password status in
basic-install.sh:displayFinalMessage(). Fixes #1488 (#1490)
---
automated install/basic-install.sh | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/automated install/basic-install.sh b/automated install/basic-install.sh
index 5d893067..15fd93be 100755
--- a/automated install/basic-install.sh
+++ b/automated install/basic-install.sh
@@ -1129,10 +1129,18 @@ checkSelinux() {
displayFinalMessage() {
+ if [[ ${#1} -gt 0 ]] ; then
+ pwstring="$1"
+ elif [[ $(grep 'WEBPASSWORD' -c /etc/pihole/setupVars.conf) -gt 0 ]]; then
+ pwstring="unchanged"
+ else
+ pwstring="NOT SET"
+ fi
+
if [[ ${INSTALL_WEB} == true ]]; then
additional="View the web interface at http://pi.hole/admin or http://${IPV4_ADDRESS%/*}/admin
-Your Admin Webpage login password is ${1:-"NOT SET"}"
+Your Admin Webpage login password is ${pwstring}"
fi
# Final completion message to user
From 085f2c6ca0f1f19649a523f14df6327b71adbb48 Mon Sep 17 00:00:00 2001
From: Jacob Salmela
Date: Tue, 23 May 2017 22:32:30 -0500
Subject: [PATCH 037/162] add port check function
---
advanced/Scripts/piholeDebug.sh | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
diff --git a/advanced/Scripts/piholeDebug.sh b/advanced/Scripts/piholeDebug.sh
index 634e2ffa..5215794e 100755
--- a/advanced/Scripts/piholeDebug.sh
+++ b/advanced/Scripts/piholeDebug.sh
@@ -326,12 +326,29 @@ ping_internet() {
fi
}
+check_required_ports() {
+ echo -e " ${INFO} Ports in use:"
+ ports_in_use=()
+ while IFS= read -r line; do
+ ports_in_use+=( "$line" )
+ done < <( lsof -i -P -n | awk -F' ' '/LISTEN/ {print $9, $1}' | sort | uniq | cut -d':' -f2 )
+
+ for i in ${!ports_in_use[@]}; do
+ local port_number="$(echo "${ports_in_use[$i]}" | awk '{print $1}')"
+ local service_name=$(echo "${ports_in_use[$i]}" | awk '{print $2}')
+ echo -e " [${port_number}] is in use by ${service_name}"
+ done
+}
+
+
check_networking() {
echo_current_diagnostic "Networking"
detect_ip_addresses "4"
ping_gateway "4"
detect_ip_addresses "6"
ping_gateway "6"
+ port_check 4 http
+ check_required_ports
}
parse_file() {
From 1a87d3a6592593cb58aaed8c7dd46a7af8c76d22 Mon Sep 17 00:00:00 2001
From: Jacob Salmela
Date: Tue, 23 May 2017 22:57:22 -0500
Subject: [PATCH 038/162] add process check function
---
advanced/Scripts/piholeDebug.sh | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/advanced/Scripts/piholeDebug.sh b/advanced/Scripts/piholeDebug.sh
index 5215794e..42d126d4 100755
--- a/advanced/Scripts/piholeDebug.sh
+++ b/advanced/Scripts/piholeDebug.sh
@@ -351,6 +351,16 @@ check_networking() {
check_required_ports
}
+process_status(){
+ echo_current_diagnostic "Pi-hole processes"
+ PROCESSES=( dnsmasq lighttpd pihole-FTL )
+ local i
+ for i in "${PROCESSES[@]}"; do
+ local status_of_process=$(systemctl is-active "${i}")
+ echo -e " [i] ${i} daemon is ${status_of_process}"
+ done
+}
+
parse_file() {
# Set the first argument passed to tihs function as a named variable for better readability
local filename="${1}"
@@ -437,5 +447,6 @@ diagnose_setup_variables
diagnose_operating_system
processor_check
check_networking
+process_status
check_critical_dependencies
check_dnsmasq_d
From 4ad0cdf5d40d1b5bc1517837b62682366237a783 Mon Sep 17 00:00:00 2001
From: WaLLy3K
Date: Thu, 25 May 2017 01:03:13 +1000
Subject: [PATCH 039/162] Rewrite Chronometer to output more stats
---
advanced/Scripts/chronometer.sh | 456 +++++++++++++++++++++++++++-----
1 file changed, 393 insertions(+), 63 deletions(-)
diff --git a/advanced/Scripts/chronometer.sh b/advanced/Scripts/chronometer.sh
index b5d54e5f..763091d8 100755
--- a/advanced/Scripts/chronometer.sh
+++ b/advanced/Scripts/chronometer.sh
@@ -8,98 +8,428 @@
# This file is copyright under the latest version of the EUPL.
# Please see LICENSE file for your rights under this license.
-# Functions
-piLog="/var/log/pihole.log"
-gravity="/etc/pihole/gravity.list"
+# Retrieve stats from FTL engine
+pihole-FTL() {
+ ftl_port=$(cat /var/run/pihole-FTL.port 2> /dev/null)
+ if [[ -n "$ftl_port" ]]; then
+ # Open connection to FTL
+ exec 3<>"/dev/tcp/localhost/$ftl_port"
-. /etc/pihole/setupVars.conf
+ # Test if connection is open
+ if { "true" >&3; } 2> /dev/null; then
+ # Send command to FTL
+ echo -e ">$1" >&3
-function GetFTLData {
- # Open connection to FTL
- exec 3<>/dev/tcp/localhost/"$(cat /var/run/pihole-FTL.port)"
+ # Read input
+ read -r -t 1 LINE <&3
+ until [[ ! $? ]] || [[ "$LINE" == *"EOM"* ]]; do
+ echo "$LINE" >&1
+ read -r -t 1 LINE <&3
+ done
- # Test if connection is open
- if { >&3; } 2> /dev/null; then
- # Send command to FTL
- echo -e ">$1" >&3
-
- # Read input
- read -r -t 1 LINE <&3
- until [ ! $? ] || [[ "$LINE" == *"EOM"* ]]; do
- echo "$LINE" >&1
- read -r -t 1 LINE <&3
- done
-
- # Close connection
- exec 3>&-
- exec 3<&-
+ # Close connection
+ exec 3>&-
+ exec 3<&-
+ fi
+ else
+ echo -e "${COL_LIGHT_RED}FTL offline${COL_NC}"
fi
}
-outputJSON() {
- get_summary_data
- echo "{\"domains_being_blocked\":${domains_being_blocked_raw},\"dns_queries_today\":${dns_queries_today_raw},\"ads_blocked_today\":${ads_blocked_today_raw},\"ads_percentage_today\":${ads_percentage_today_raw}}"
+# Print spaces to align right-side content
+printFunc() {
+ txt_len="${#2}"
+
+ # Reduce string length when using colour code
+ [ "${2:0:1}" == "" ] && txt_len=$((txt_len-7))
+
+ if [[ "$3" == "last" ]]; then
+ # Prevent final line from printing trailing newline
+ scr_size=( $(stty size 2>/dev/null || echo 24 80) )
+ scr_width="${scr_size[1]}"
+
+ title_len="${#1}"
+ spc_num=$(( (scr_width - title_len) - txt_len ))
+ [[ "$spc_num" -lt 0 ]] && spc_num="0"
+ spc=$(printf "%${spc_num}s")
+
+ printf "%s%s$spc" "$1" "$2"
+ else
+ # Determine number of spaces for padding
+ spc_num=$(( 20 - txt_len ))
+ [[ "$spc_num" -lt 0 ]] && spc_num="0"
+ spc=$(printf "%${spc_num}s")
+
+ # Print string (Max 20 characters, prevents overflow)
+ printf "%s%s$spc" "$1" "${2:0:20}"
+ fi
}
-get_summary_data() {
- local summary=$(GetFTLData "stats")
- domains_being_blocked_raw=$(grep "domains_being_blocked" <<< "${summary}" | grep -Eo "[0-9]+$")
- domains_being_blocked=$(printf "%'.f" ${domains_being_blocked_raw})
- dns_queries_today_raw=$(grep "dns_queries_today" <<< "$summary" | grep -Eo "[0-9]+$")
- dns_queries_today=$(printf "%'.f" ${dns_queries_today_raw})
- ads_blocked_today_raw=$(grep "ads_blocked_today" <<< "$summary" | grep -Eo "[0-9]+$")
- ads_blocked_today=$(printf "%'.f" ${ads_blocked_today_raw})
- ads_percentage_today_raw=$(grep "ads_percentage_today" <<< "$summary" | grep -Eo "[0-9.]+$")
- LC_NUMERIC=C ads_percentage_today=$(printf "%'.f" ${ads_percentage_today_raw})
+# Perform on first Chrono run (not for JSON formatted string)
+get_init_stats() {
+ LC_NUMERIC=C
+ calcFunc(){ awk "BEGIN {print $*}"; }
+
+ # Convert bytes to human-readable format
+ hrBytes() {
+ awk '{
+ num=$1;
+ if(num==0) {
+ print "0 B"
+ } else {
+ xxx=(num<0?-num:num)
+ sss=(num<0?-1:1)
+ split("B KB MB GB TB PB",type)
+ for(i=5;yyy < 1;i--) {
+ yyy=xxx / (2^(10*i))
+ }
+ printf "%.0f " type[i+2], yyy*sss
+ }
+ }' <<< "$1";
+ }
+
+ # Convert seconds to human-readable format
+ hrSecs() {
+ day=$(( $1/60/60/24 )); hrs=$(( $1/3600%24 )); mins=$(( ($1%3600)/60 )); secs=$(( $1%60 ))
+ [[ "$day" -ge "2" ]] && plu="s"
+ [[ "$day" -ge "1" ]] && days="$day day${plu}, " || days=""
+ printf "%s%02d:%02d:%02d\n" "$days" "$hrs" "$mins" "$secs"
+ }
+
+ # Set Colour Codes
+ coltable="/opt/pihole/COL_TABLE"
+ if [[ -f "${coltable}" ]]; then
+ source ${coltable}
+ else
+ COL_NC='[0m'
+ COL_DARK_GRAY='[1;30m'
+ COL_LIGHT_GREEN='[1;32m'
+ COL_LIGHT_BLUE='[1;34m'
+ COL_LIGHT_RED='[1;31m'
+ COL_YELLOW='[1;33m'
+ COL_LIGHT_RED='[1;31m'
+ COL_URG_RED='[39;41m'
+ fi
+
+ # Get RPi model number, or OS distro info
+ if command -v vcgencmd &> /dev/null; then
+ sys_rev=$(awk '/Revision/ {print $3}' < /proc/cpuinfo)
+ case "$sys_rev" in
+ 000[2-6]) sys_model=" 1, Model B";; # 256MB
+ 000[7-9]) sys_model=" 1, Model A" ;; # 256MB
+ 000d|000e|000f) sys_model=" 1, Model B";; # 512MB
+ 0010|0013) sys_model=" 1, Model B+";; # 512MB
+ 0012|0015) sys_model=" 1, Model A+";; # 256MB
+ a0104[0-1]|a21041|a22042) sys_model=" 2, Model B";; # 1GB
+ 900021) sys_model=" 1, Model A+";; # 512MB
+ 900032) sys_model=" 1, Model B+";; # 512MB
+ 90009[2-3]|920093) sys_model=" Zero";; # 512MB
+ 9000c1) sys_model=" Zero W";; # 512MB
+ a02082|a[2-3]2082) sys_model=" 3, Model B";; # 1GB
+ *) sys_model="" ;;
+ esac
+ sys_type="Raspberry Pi$sys_model"
+ else
+ source "/etc/os-release"
+ CODENAME=$(sed 's/[()]//g' <<< "${VERSION/* /}")
+ sys_type="${NAME/ */} ${CODENAME^} $VERSION_ID"
+ fi
+
+ # Get core count
+ sys_cores=$(grep -c "^processor" /proc/cpuinfo)
+ [[ "$sys_cores" -ne 1 ]] && sys_cores_plu="cores" || sys_cores_plu="core"
+
+ # Test existence of clock speed file for ARM CPU
+ if [[ -f "/sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq" ]]; then
+ scaling_freq_file="/sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq"
+ fi
+
+ # Test existence of temperature file
+ if [[ -f "/sys/class/thermal/thermal_zone0/temp" ]]; then
+ temp_file="/sys/class/thermal/thermal_zone0/temp"
+ elif [[ -f "/sys/class/hwmon/hwmon0/temp1_input" ]]; then
+ temp_file="/sys/class/hwmon/hwmon0/temp1_input"
+ else
+ temp_file=""
+ fi
+
+ # Test existence of setupVars config
+ if [[ -f "/etc/pihole/setupVars.conf" ]]; then
+ setupVars="/etc/pihole/setupVars.conf"
+ fi
}
-normalChrono() {
+get_sys_stats() {
+ local ph_ver_raw
+ local cpu_raw
+ local ram_raw
+ local disk_raw
+
+ # Update every 12 refreshes (Def: every 60s)
+ count=$((count+1))
+ if [[ "$count" == "1" ]] || (( "$count" % 12 == 0 )); then
+ [[ -n "$setupVars" ]] && source "$setupVars"
+
+
+ ph_ver_raw=($(pihole -v -c 2> /dev/null | sed -n 's/^.* v/v/p'))
+ if [[ -n "${ph_ver_raw[0]}" ]]; then
+ ph_core_ver="${ph_ver_raw[0]}"
+ ph_lte_ver="${ph_ver_raw[1]}"
+ ph_ftl_ver="${ph_ver_raw[2]}"
+ else
+ ph_core_ver="${COL_LIGHT_RED}API unavailable${COL_NC}"
+ fi
+
+ sys_name=$(hostname)
+
+ [[ -n "$TEMPERATUREUNIT" ]] && temp_unit="$TEMPERATUREUNIT" || temp_unit="c"
+
+ # Get storage stats for partition mounted on /
+ disk_raw=($(df -B1 / 2> /dev/null | awk 'END{ print $3,$2,$5 }'))
+ disk_used="${disk_raw[0]}"
+ disk_total="${disk_raw[1]}"
+ disk_perc="${disk_raw[2]}"
+
+ net_gateway=$(route -n | awk '$4 == "UG" {print $2;exit}')
+
+ # Get DHCP stats, if feature is enabled
+ if [[ "$DHCP_ACTIVE" == "true" ]]; then
+ ph_dhcp_eip="${DHCP_END##*.}"
+ ph_dhcp_max=$(( ${DHCP_END##*.} - ${DHCP_START##*.} + 1 ))
+ fi
+
+ # Get alt DNS server, or print total count of alt DNS servers
+ if [[ -z "${PIHOLE_DNS_3}" ]]; then
+ ph_alts="${PIHOLE_DNS_2}"
+ else
+ dns_count="0"
+ [[ -n "${PIHOLE_DNS_2}" ]] && dns_count=$((dns_count+1))
+ [[ -n "${PIHOLE_DNS_3}" ]] && dns_count=$((dns_count+1))
+ [[ -n "${PIHOLE_DNS_4}" ]] && dns_count=$((dns_count+1))
+ [[ -n "${PIHOLE_DNS_5}" ]] && dns_count=$((dns_count+1))
+ [[ -n "${PIHOLE_DNS_6}" ]] && dns_count=$((dns_count+1))
+ [[ -n "${PIHOLE_DNS_7}" ]] && dns_count=$((dns_count+1))
+ [[ -n "${PIHOLE_DNS_8}" ]] && dns_count=$((dns_count+1))
+ [[ -n "${PIHOLE_DNS_9}" ]] && dns_count="$dns_count+"
+ ph_alts="${dns_count} others"
+ fi
+ fi
+
+ sys_uptime=$(hrSecs "$(cut -d. -f1 /proc/uptime)")
+ sys_loadavg=$(cut -d " " -f1,2,3 /proc/loadavg)
+
+ # Get CPU usage, only counting processes over 1% CPU as active
+ cpu_raw=$(ps -eo pcpu,rss --no-headers | grep -E -v " 0")
+ cpu_tasks=$(wc -l <<< "$cpu_raw")
+ cpu_taskact=$(sed -r "/(^ 0.)/d" <<< "$cpu_raw" | wc -l)
+ cpu_perc=$(awk '{sum+=$1} END {printf "%.0f\n", sum/'"$sys_cores"'}' <<< "$cpu_raw")
+
+ # Get CPU clock speed
+ if [[ -n "$scaling_freq_file" ]]; then
+ cpu_mhz=$(( $(< /sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq) / 1000 ))
+ else
+ cpu_mhz=$(lscpu | awk -F "[ .]+" '/MHz/ {print $4;exit}')
+ fi
+
+ # Determine correct string format for CPU clock speed
+ if [[ -n "$cpu_mhz" ]]; then
+ [[ "$cpu_mhz" -le "999" ]] && cpu_freq="$cpu_mhz MHz" || cpu_freq="$(calcFunc "$cpu_mhz"/1000) Ghz"
+ [[ -n "$cpu_freq" ]] && cpu_freq_str=" @ $cpu_freq" || cpu_freq_str=""
+ fi
+
+ # Determine colour for temperature
+ if [[ -n "$temp_file" ]]; then
+ if [[ "$temp_unit" == "C" ]]; then
+ cpu_temp=$(printf "%'.0fc\n" "$(calcFunc "$(< $temp_file) / 1000")")
+
+ case "${cpu_temp::-1}" in
+ -*|[0-9]|[1-3][0-9]) cpu_col="$COL_LIGHT_BLUE";;
+ 4[0-9]) cpu_col="";;
+ 5[0-9]) cpu_col="$COL_YELLOW";;
+ 6[0-9]) cpu_col="$COL_LIGHT_RED";;
+ *) cpu_col="$COL_URG_RED";;
+ esac
+
+ # $COL_NC$COL_DARK_GRAY is needed for $COL_URG_RED
+ cpu_temp_str=", $cpu_col$cpu_temp$COL_NC$COL_DARK_GRAY"
+
+ elif [[ "$temp_unit" == "F" ]]; then
+ cpu_temp=$(printf "%'.0ff\n" "$(calcFunc "($(< $temp_file) / 1000) * 9 / 5 + 32")")
+
+ case "${cpu_temp::-1}" in
+ -*|[0-9]|[0-9][0-9]) cpu_col="$COL_LIGHT_BLUE";;
+ 1[0-1][0-9]) cpu_col="";;
+ 1[2-3][0-9]) cpu_col="$COL_YELLOW";;
+ 1[4-5][0-9]) cpu_col="$COL_LIGHT_RED";;
+ *) cpu_col="$COL_URG_RED";;
+ esac
+
+ cpu_temp_str=", $cpu_col$cpu_temp$COL_NC$COL_DARK_GRAY"
+
+ else
+ cpu_temp_str=$(printf ", %'.0fk\n" "$(calcFunc "($(< $temp_file) / 1000) + 273.15")")
+ fi
+ else
+ cpu_temp_str=""
+ fi
+
+ ram_raw=($(awk '/MemTotal:/{total=$2} /MemFree:/{free=$2} /Buffers:/{buffers=$2} /^Cached:/{cached=$2} END {printf "%.0f %.0f %.0f", (total-free-buffers-cached)*100/total, (total-free-buffers-cached)*1024, total*1024}' /proc/meminfo))
+ ram_perc="${ram_raw[0]}"
+ ram_used="${ram_raw[1]}"
+ ram_total="${ram_raw[2]}"
+
+ if [[ "$(pihole status web 2> /dev/null)" == "1" ]]; then
+ ph_status="${COL_LIGHT_GREEN}Active"
+ else
+ ph_status="${COL_LIGHT_RED}Inactive"
+ fi
+
+ if [[ "$DHCP_ACTIVE" == "true" ]]; then
+ ph_dhcp_num=$(wc -l 2> /dev/null < "/etc/pihole/dhcp.leases")
+ fi
+}
+
+get_ftl_stats() {
+ local stats_raw
+
+ stats_raw=($(pihole-FTL "stats"))
+ domains_being_blocked_raw="${stats_raw[1]}"
+ dns_queries_today_raw="${stats_raw[3]}"
+ ads_blocked_today_raw="${stats_raw[5]}"
+ ads_percentage_today_raw="${stats_raw[7]}"
+
+ # Only retrieve these stats when not called from jsonFunc
+ if [[ -z "$1" ]]; then
+ local recent_blocked_raw
+ local top_ad_raw
+ local top_domain_raw
+ local top_client_raw
+
+ domains_being_blocked=$(printf "%'.0f\n" "${domains_being_blocked_raw}")
+ dns_queries_today=$(printf "%'.0f\n" "${dns_queries_today_raw}")
+ ads_blocked_today=$(printf "%'.0f\n" "${ads_blocked_today_raw}")
+ ads_percentage_today=$(printf "%'.0f\n" "${ads_percentage_today_raw}")
+
+ recent_blocked_raw=$(pihole-FTL recentBlocked)
+ top_ad_raw=($(pihole-FTL "top-ads (1)"))
+ top_domain_raw=($(pihole-FTL "top-domains (1)"))
+ top_client_raw=($(pihole-FTL "top-clients (1)"))
+
+ # Limit strings to 40 characters to prevent overflow
+ recent_blocked="${recent_blocked_raw:0:40}"
+ top_ad="${top_ad_raw[2]:0:40}"
+ top_domain="${top_domain_raw[2]:0:40}"
+ [[ "${top_client_raw[3]}" ]] && top_client="${top_client_raw[3]:0:40}" || top_client="${top_client_raw[2]:0:40}"
+ fi
+}
+
+chronoFunc() {
+ get_init_stats
+
for (( ; ; )); do
- get_summary_data
- domain=$(GetFTLData recentBlocked)
+ get_sys_stats
+ get_ftl_stats
+
+ # Do not print LTE/FTL strings if API is unavailable
+ ph_core_str=" ${COL_DARK_GRAY}Pi-hole: $ph_core_ver${COL_NC}"
+ if [[ -n "$ph_lte_ver" ]]; then
+ ph_lte_str=" ${COL_DARK_GRAY}AdminLTE: $ph_lte_ver${COL_NC}"
+ ph_ftl_str=" ${COL_DARK_GRAY}FTL: $ph_ftl_ver${COL_NC}"
+ fi
+
clear
- # Displays a colorful Pi-hole logo
- echo " [0;1;35;95m_[0;1;31;91m__[0m [0;1;33;93m_[0m [0;1;34;94m_[0m [0;1;36;96m_[0m"
- echo "[0;1;31;91m|[0m [0;1;33;93m_[0m [0;1;32;92m(_[0;1;36;96m)_[0;1;34;94m__[0;1;35;95m|[0m [0;1;31;91m|_[0m [0;1;32;92m__[0;1;36;96m_|[0m [0;1;34;94m|[0;1;35;95m__[0;1;31;91m_[0m"
- echo "[0;1;33;93m|[0m [0;1;32;92m_[0;1;36;96m/[0m [0;1;34;94m|_[0;1;35;95m__[0;1;31;91m|[0m [0;1;33;93m'[0m [0;1;32;92m\/[0m [0;1;36;96m_[0m [0;1;34;94m\[0m [0;1;35;95m/[0m [0;1;31;91m-[0;1;33;93m_)[0m"
- echo "[0;1;32;92m|_[0;1;36;96m|[0m [0;1;34;94m|_[0;1;35;95m|[0m [0;1;33;93m|_[0;1;32;92m||[0;1;36;96m_\[0;1;34;94m__[0;1;35;95m_/[0;1;31;91m_\[0;1;33;93m__[0;1;32;92m_|[0m"
- echo ""
- echo " ${IPV4_ADDRESS}"
- echo ""
- uptime | cut -d' ' -f11-
- #uptime -p # Doesn't work on all versions of uptime
- uptime | awk -F'( |,|:)+' '{if ($7=="min") m=$6; else {if ($7~/^day/) {d=$6;h=$8;m=$9} else {h=$6;m=$7}}} {print d+0,"days,",h+0,"hours,",m+0,"minutes."}'
- echo "-------------------------------"
- echo "Recently blocked:"
- echo " $domain"
+
+ echo -e "[0;1;31;91m|¯[0;1;33;93m¯[0;1;32;92m¯[0;1;32;92m(¯[0;1;36;96m)_[0;1;34;94m_[0;1;35;95m|[0;1;33;93m¯[0;1;31;91m|_ [0;1;32;92m__[0;1;36;96m_|[0;1;31;91m¯[0;1;34;94m|[0;1;35;95m__[0;1;31;91m_[0m$ph_core_str
+[0;1;33;93m| ¯[0;1;32;92m_[0;1;36;96m/¯[0;1;34;94m|_[0;1;35;95m_[0;1;31;91m| [0;1;33;93m' [0;1;32;92m\/ [0;1;36;96m_ [0;1;34;94m\ [0;1;35;95m/ [0;1;31;91m-[0;1;33;93m_)[0m$ph_lte_str
+[0;1;32;92m|_[0;1;36;96m| [0;1;34;94m|_[0;1;35;95m| [0;1;33;93m|_[0;1;32;92m||[0;1;36;96m_\[0;1;34;94m__[0;1;35;95m_/[0;1;31;91m_\[0;1;33;93m__[0;1;32;92m_|[0m$ph_ftl_str
+ ${COL_DARK_GRAY}——————————————————————————————————————————————————————————${COL_NC}"
- echo "Blocking: ${domains_being_blocked}"
- echo "Queries: ${dns_queries_today}"
- echo "Pi-holed: ${ads_blocked_today} (${ads_percentage_today}%)"
-
- sleep 5
+ printFunc " Hostname: " "$sys_name"
+ [ -n "$sys_type" ] && printf "%s(%s)%s\n" "$COL_DARK_GRAY" "$sys_type" "$COL_NC" || printf "\n"
+
+ printf "%s\n" " Uptime: $sys_uptime"
+
+ printFunc " Task Load: " "$sys_loadavg"
+ printf "%s(%s)%s\n" "$COL_DARK_GRAY" "Active: $cpu_taskact of $cpu_tasks tasks" "$COL_NC"
+
+ printFunc " CPU usage: " "$cpu_perc%"
+ printf "%s(%s)%s\n" "$COL_DARK_GRAY" "$sys_cores $sys_cores_plu$cpu_freq_str$cpu_temp_str" "$COL_NC"
+
+ printFunc " RAM usage: " "$ram_perc%"
+ printf "%s(%s)%s\n" "$COL_DARK_GRAY" "Used: $(hrBytes "$ram_used") of $(hrBytes "$ram_total")" "$COL_NC"
+
+ printFunc " HDD usage: " "$disk_perc"
+ printf "%s(%s)%s\n" "$COL_DARK_GRAY" "Used: $(hrBytes "$disk_used") of $(hrBytes "$disk_total")" "$COL_NC"
+
+ printFunc " LAN addr: " "${IPV4_ADDRESS:0:-3}"
+ printf "%s(%s)%s\n" "$COL_DARK_GRAY" "Gateway: $net_gateway" "$COL_NC"
+
+ if [[ "$DHCP_ACTIVE" == "true" ]]; then
+ printFunc " DHCP: " "$DHCP_START to $ph_dhcp_eip"
+ printf "%s(%s)%s\n" "$COL_DARK_GRAY" "Leased: $ph_dhcp_num of $ph_dhcp_max" "$COL_NC"
+ fi
+
+ printFunc " Pi-hole: " "$ph_status"
+ printf "%s(%s)%s\n" "$COL_DARK_GRAY" "Blocking: $domains_being_blocked sites" "$COL_NC"
+
+ printFunc " Ads Today: " "$ads_percentage_today%"
+ printf "%s(%s)%s\n" "$COL_DARK_GRAY" "$ads_blocked_today of $dns_queries_today queries" "$COL_NC"
+
+ printFunc " Fwd DNS: " "$PIHOLE_DNS_1"
+ printf "%s(%s)%s\n" "$COL_DARK_GRAY" "Alt DNS: $ph_alts" "$COL_NC"
+
+ echo -e " ${COL_DARK_GRAY}——————————————————————————————————————————————————————————${COL_NC}"
+ echo " Recently blocked: $recent_blocked"
+ echo " Top Advertiser: $top_ad"
+ echo " Top Domain: $top_domain"
+ printFunc " Top Client: " "$top_client" "last"
+
+ if [[ "$1" == "exit" ]]; then
+ exit 0
+ else
+ if [[ -n "$1" ]]; then
+ sleep "${1}"
+ else
+ sleep 5
+ fi
+ fi
+
done
}
-displayHelp() {
- echo "Usage: pihole -c [options]
+jsonFunc() {
+ get_ftl_stats "json"
+ echo "{\"domains_being_blocked\":${domains_being_blocked_raw},\"dns_queries_today\":${dns_queries_today_raw},\"ads_blocked_today\":${ads_blocked_today_raw},\"ads_percentage_today\":${ads_percentage_today_raw}}"
+}
+
+helpFunc() {
+ if [[ "$1" == "?" ]]; then
+ echo "Unknown option. Please view 'pihole -c --help' for more information"
+ else
+ echo "Usage: pihole -c [options]
Example: 'pihole -c -j'
Calculates stats and displays to an LCD
Options:
-j, --json Output stats as JSON formatted string
+ -r, --refresh Set update frequency (in seconds)
+ -e, --exit Output stats and exit witout refreshing
-h, --help Display this help text"
+ fi
+
exit 0
}
if [[ $# = 0 ]]; then
- normalChrono
+ chronoFunc
fi
for var in "$@"; do
case "$var" in
- "-j" | "--json" ) outputJSON;;
- "-h" | "--help" ) displayHelp;;
- * ) exit 1;;
+ "-j" | "--json" ) jsonFunc;;
+ "-h" | "--help" ) helpFunc;;
+ "-r" | "--refresh" ) chronoFunc "$2";;
+ "-e" | "--exit" ) chronoFunc "exit";;
+ * ) helpFunc "?";;
esac
done
From 76266cf31b1b631a6646add520e6b712b76f2acd Mon Sep 17 00:00:00 2001
From: Jacob Salmela
Date: Wed, 24 May 2017 15:29:31 -0500
Subject: [PATCH 040/162] add resolver functions and check directory content
functions
---
advanced/Scripts/piholeDebug.sh | 93 ++++++++++++++++++++++++++++++---
1 file changed, 87 insertions(+), 6 deletions(-)
diff --git a/advanced/Scripts/piholeDebug.sh b/advanced/Scripts/piholeDebug.sh
index 42d126d4..8e805536 100755
--- a/advanced/Scripts/piholeDebug.sh
+++ b/advanced/Scripts/piholeDebug.sh
@@ -340,17 +340,63 @@ check_required_ports() {
done
}
-
check_networking() {
echo_current_diagnostic "Networking"
detect_ip_addresses "4"
ping_gateway "4"
detect_ip_addresses "6"
ping_gateway "6"
- port_check 4 http
check_required_ports
}
+check_x_headers() {
+ curl -Is localhost | awk '/X-Pi-hole/'
+ curl -Is localhost/admin/ | awk '/X-Pi-hole/'
+}
+
+dig_at() {
+ local protocol="${1}"
+ local IP="${2}"
+ echo_current_diagnostic "Domain name resolution (IPv${protocol}) using a random blocked domain"
+ local url
+ local local_dig
+ local pihole_dig
+ local remote_dig
+
+ if [[ ${protocol} == "6" ]]; then
+ local local_address="::1"
+ local pihole_address="${IPV6_ADDRESS%/*}"
+ local remote_address="2001:4860:4860::8888"
+ local record_type="AAAA"
+ else
+ local local_address="127.0.0.1"
+ local pihole_address="${IPV4_ADDRESS%/*}"
+ local remote_address="8.8.8.8"
+ local record_type="A"
+ fi
+
+ # Find a random blocked url that has not been whitelisted.
+ local random_url=$(shuf -n 1 "${GRAVITYFILE}" | awk -F ' ' '{ print $2 }')
+
+ if local_dig=$(dig -"${protocol}" "${random_url}" @${local_address} +short "${record_type}"); then
+ echo -e " ${TICK} ${random_url} is ${local_dig} via localhost (${local_address})"
+ else
+ echo -e " ${CROSS} Failed to resolve ${random_url} via localhot (${local_address})"
+ fi
+
+ if pihole_dig=$(dig -"${protocol}" "${random_url}" @${pihole_address} +short "${record_type}"); then
+ echo -e " ${TICK} ${random_url} is ${pihole_dig} via Pi-hole (${pihole_address})"
+ else
+ echo -e " ${CROSS} Failed to resolve ${random_url} via Pi-hole (${pihole_address})"
+ fi
+
+ if remote_dig=$(dig -"${protocol}" "${random_url}" @${remote_address} +short "${record_type}"); then
+ echo -e " ${TICK} ${random_url} is ${remote_dig} via a remote, public DNS server (${remote_address})"
+ else
+ echo -e " ${CROSS} Failed to resolve ${random_url} via a remote, public DNS server (${remote_address})"
+ fi
+}
+
process_status(){
echo_current_diagnostic "Pi-hole processes"
PROCESSES=( dnsmasq lighttpd pihole-FTL )
@@ -397,6 +443,15 @@ diagnose_setup_variables() {
parse_file "${VARSFILE}"
}
+check_name_resolution() {
+ # Check name resoltion from localhost, Pi-hole's IP, and Google's name severs
+ dig_at 4 "${IPV4_ADDRESS%/*}"
+ # If IPv6 enabled, check resolution
+ if [[ "${IPV6_ADDRESS}" ]]; then
+ dig_at 6 "${IPV6_ADDRESS%/*}"
+ fi
+}
+
# This function can check a directory exists
# Pi-hole has files in several places, so we will reuse this function
dir_check() {
@@ -405,7 +460,7 @@ dir_check() {
# Display the current test that is running
echo_current_diagnostic "contents of ${directory}"
# For each file in the directory,
- for filename in "${directory}"*; do
+ for filename in "${directory}"; do
# check if exists first; if it does,
file_exists "${filename}" && \
# show a success message
@@ -418,14 +473,13 @@ dir_check() {
list_files_in_dir() {
# Set the first argument passed to tihs function as a named variable for better readability
local dir_to_parse="${1}"
- # Set another local variable for better readability
- local filename
# Store the files found in an array
files_found=( $(ls "${dir_to_parse}") )
# For each file in the arry,
for each_file in "${files_found[@]}"; do
# display the information with the ${INFO} icon
- echo " ${INFO} ${each_file}"
+ # Also print the permissions and the user/group
+ echo -e " ${INFO} ${each_file} ( $(ls -ld ${dir_to_parse}/${each_file} | awk '{print $1, $3, $4}') )"
done
}
@@ -439,6 +493,30 @@ check_dnsmasq_d() {
list_files_in_dir "${directory}"
}
+check_cron_d() {
+ # Set a local variable for better readability
+ local directory=/etc/cron.d
+ # Check if the directory exists
+ dir_check "${directory}"
+ # if it does, list the files in it
+ list_files_in_dir "${directory}"
+}
+
+check_http_directory() {
+ # Set a local variable for better readability
+ local directory=/var/www/html
+ # Check if the directory exists
+ dir_check "${directory}"
+ # if it does, list the files in it
+ list_files_in_dir "${directory}"
+}
+
+upload_to_tricorder() {
+echo tricorder
+}
+
+upload_to_tricorder
+
initiate_debug
check_core_version
check_web_version
@@ -447,6 +525,9 @@ diagnose_setup_variables
diagnose_operating_system
processor_check
check_networking
+check_name_resolution
process_status
check_critical_dependencies
check_dnsmasq_d
+check_http_directory
+check_cron_d
From 8bafd12f95eca26ad023728946f39271182e5067 Mon Sep 17 00:00:00 2001
From: Jacob Salmela
Date: Wed, 24 May 2017 16:10:14 -0500
Subject: [PATCH 041/162] fix resolver functions and add x-header function
---
advanced/Scripts/piholeDebug.sh | 35 ++++++++++++++++++++++++---------
1 file changed, 26 insertions(+), 9 deletions(-)
diff --git a/advanced/Scripts/piholeDebug.sh b/advanced/Scripts/piholeDebug.sh
index 8e805536..b275c4e5 100755
--- a/advanced/Scripts/piholeDebug.sh
+++ b/advanced/Scripts/piholeDebug.sh
@@ -350,8 +350,22 @@ check_networking() {
}
check_x_headers() {
- curl -Is localhost | awk '/X-Pi-hole/'
- curl -Is localhost/admin/ | awk '/X-Pi-hole/'
+ echo_current_diagnostic "Dashboard and block page"
+ local block_page=$(curl -Is localhost | awk '/X-Pi-hole/' | tr -d '\r')
+ local dashboard=$(curl -Is localhost/admin/ | awk '/X-Pi-hole/' | tr -d '\r')
+ local block_page_working="X-Pi-hole: A black hole for Internet advertisements.."
+ local dashboard_working="X-Pi-hole: The Pi-hole Web interface is working!!"
+ if [[ $block_page == $block_page_working ]]; then
+ echo -e " $TICK ${block_page}"
+ else
+ echo -e " $CROSS X-Header does not match or could not be retrieved"
+ fi
+
+ if [[ $dashboard == $dashboard_working ]]; then
+ echo -e " $TICK ${dashboard}"
+ else
+ echo -e " $CROSS X-Header does not match or could not be retrieved"
+ fi
}
dig_at() {
@@ -378,22 +392,24 @@ dig_at() {
# Find a random blocked url that has not been whitelisted.
local random_url=$(shuf -n 1 "${GRAVITYFILE}" | awk -F ' ' '{ print $2 }')
+ local remote_url="doubleclick.com"
+
if local_dig=$(dig -"${protocol}" "${random_url}" @${local_address} +short "${record_type}"); then
- echo -e " ${TICK} ${random_url} is ${local_dig} via localhost (${local_address})"
+ echo -e " ${TICK} ${random_url} is ${local_dig} via localhost (${local_address})"
else
- echo -e " ${CROSS} Failed to resolve ${random_url} via localhot (${local_address})"
+ echo -e " ${CROSS} Failed to resolve ${random_url} via localhot (${local_address})"
fi
if pihole_dig=$(dig -"${protocol}" "${random_url}" @${pihole_address} +short "${record_type}"); then
- echo -e " ${TICK} ${random_url} is ${pihole_dig} via Pi-hole (${pihole_address})"
+ echo -e " ${TICK} ${random_url} is ${pihole_dig} via Pi-hole (${pihole_address})"
else
- echo -e " ${CROSS} Failed to resolve ${random_url} via Pi-hole (${pihole_address})"
+ echo -e " ${CROSS} Failed to resolve ${random_url} via Pi-hole (${pihole_address})"
fi
- if remote_dig=$(dig -"${protocol}" "${random_url}" @${remote_address} +short "${record_type}"); then
- echo -e " ${TICK} ${random_url} is ${remote_dig} via a remote, public DNS server (${remote_address})"
+ if remote_dig=$(dig -"${protocol}" "${remote_url}" @${remote_address} +short "${record_type}" | head -n1); then
+ echo -e " ${TICK} ${random_url} is ${remote_dig} via a remote, public DNS server (${remote_address})"
else
- echo -e " ${CROSS} Failed to resolve ${random_url} via a remote, public DNS server (${remote_address})"
+ echo -e " ${CROSS} Failed to resolve ${remote_url} via a remote, public DNS server (${remote_address})"
fi
}
@@ -527,6 +543,7 @@ processor_check
check_networking
check_name_resolution
process_status
+check_x_headers
check_critical_dependencies
check_dnsmasq_d
check_http_directory
From 6684af9938e52137349674830a4339e1a9b02ab8 Mon Sep 17 00:00:00 2001
From: Jacob Salmela
Date: Wed, 24 May 2017 18:31:55 -0500
Subject: [PATCH 042/162] add lighttpd list function and gravity analysis
---
advanced/Scripts/piholeDebug.sh | 61 ++++++++++++++++++++++++++++++---
1 file changed, 56 insertions(+), 5 deletions(-)
diff --git a/advanced/Scripts/piholeDebug.sh b/advanced/Scripts/piholeDebug.sh
index b275c4e5..1cff71c8 100755
--- a/advanced/Scripts/piholeDebug.sh
+++ b/advanced/Scripts/piholeDebug.sh
@@ -353,8 +353,8 @@ check_x_headers() {
echo_current_diagnostic "Dashboard and block page"
local block_page=$(curl -Is localhost | awk '/X-Pi-hole/' | tr -d '\r')
local dashboard=$(curl -Is localhost/admin/ | awk '/X-Pi-hole/' | tr -d '\r')
- local block_page_working="X-Pi-hole: A black hole for Internet advertisements.."
- local dashboard_working="X-Pi-hole: The Pi-hole Web interface is working!!"
+ local block_page_working="X-Pi-hole: A black hole for Internet advertisements."
+ local dashboard_working="X-Pi-hole: The Pi-hole Web interface is working!"
if [[ $block_page == $block_page_working ]]; then
echo -e " $TICK ${block_page}"
else
@@ -509,6 +509,15 @@ check_dnsmasq_d() {
list_files_in_dir "${directory}"
}
+check_lighttpd_d() {
+ # Set a local variable for better readability
+ local directory=/etc/lighttpd
+ # Check if the directory exists
+ dir_check "${directory}"
+ # if it does, list the files in it
+ list_files_in_dir "${directory}"
+}
+
check_cron_d() {
# Set a local variable for better readability
local directory=/etc/cron.d
@@ -527,11 +536,51 @@ check_http_directory() {
list_files_in_dir "${directory}"
}
-upload_to_tricorder() {
-echo tricorder
+analyze_gravity_list() {
+ gravity_length=$(grep -c ^ "${GRAVITYFILE}") && \
+ echo -e " ${INFO} ${GRAVITYFILE} is ${gravity_length} lines long." || \
+ echo -e " ${CROSS} ${GRAVITYFILE} not found!"
}
-upload_to_tricorder
+upload_to_tricorder() {
+ local tricorder
+ echo "${TICK} Finshed debugging!"
+
+ # Ensure the file exists, create if not, clear if exists.
+ truncate --size=0 "${DEBUG_LOG}"
+ # Set the permissions and owner
+ chmod 644 ${DEBUG_LOG}
+ chown "$USER":pihole ${DEBUG_LOG}
+ # Copy working temp file to final log location
+ cat /proc/$$/fd/3 >> "${DEBUG_LOG}"
+ # Straight dump of tailing the logs, can sanitize later if needed.
+ cat /proc/$$/fd/4 >> "${DEBUG_LOG}"
+
+ echo "::: The debug log can be uploaded to tricorder.pi-hole.net for sharing with developers only."
+ if [[ "${AUTOMATED}" ]]; then
+ echo "${INFO} Debug script running in automated mode; uploading log to tricorder..."
+ tricorder=$(cat /var/log/pihole_debug.log | nc tricorder.pi-hole.net 9999)
+ else
+ read -r -p "\n\n[?] Would you like to upload the log? [y/N] " response
+ case ${response} in
+ [yY][eE][sS]|[yY]) tricorder=$(cat /var/log/pihole_debug.log | nc tricorder.pi-hole.net 9999);;
+ *) echo "${INFO} Log will NOT be uploaded to tricorder.";;
+ esac
+ fi
+ # Check if tricorder.pi-hole.net is reachable and provide token.
+ if [[ -n "${tricorder}" ]]; then
+ echo "::: ---=== Your debug token is : ${tricorder} Please make a note of it. ===---"
+ echo "::: Contact the Pi-hole team with your token for assistance."
+ echo "::: Thank you."
+ else
+ echo "::: There was an error uploading your debug log."
+ echo "::: Please try again or contact the Pi-hole team for assistance."
+ fi
+ echo "::: A local copy of the Debug log can be found at : /var/log/pihole_debug.log"
+
+}
+
+
initiate_debug
check_core_version
@@ -546,5 +595,7 @@ process_status
check_x_headers
check_critical_dependencies
check_dnsmasq_d
+check_lighttpd_d
check_http_directory
check_cron_d
+upload_to_tricorder
From c995c81fff30731064c1a41c5a99ab9786b612a4 Mon Sep 17 00:00:00 2001
From: Jacob Salmela
Date: Wed, 24 May 2017 19:36:06 -0500
Subject: [PATCH 043/162] adjust some spacing
---
advanced/Scripts/piholeDebug.sh | 20 ++++++++++----------
1 file changed, 10 insertions(+), 10 deletions(-)
diff --git a/advanced/Scripts/piholeDebug.sh b/advanced/Scripts/piholeDebug.sh
index 1cff71c8..75809b74 100755
--- a/advanced/Scripts/piholeDebug.sh
+++ b/advanced/Scripts/piholeDebug.sh
@@ -356,15 +356,15 @@ check_x_headers() {
local block_page_working="X-Pi-hole: A black hole for Internet advertisements."
local dashboard_working="X-Pi-hole: The Pi-hole Web interface is working!"
if [[ $block_page == $block_page_working ]]; then
- echo -e " $TICK ${block_page}"
+ echo -e " $TICK ${block_page}"
else
- echo -e " $CROSS X-Header does not match or could not be retrieved"
+ echo -e " $CROSS X-Header does not match or could not be retrieved"
fi
if [[ $dashboard == $dashboard_working ]]; then
- echo -e " $TICK ${dashboard}"
+ echo -e " $TICK ${dashboard}"
else
- echo -e " $CROSS X-Header does not match or could not be retrieved"
+ echo -e " $CROSS X-Header does not match or could not be retrieved"
fi
}
@@ -395,21 +395,21 @@ dig_at() {
local remote_url="doubleclick.com"
if local_dig=$(dig -"${protocol}" "${random_url}" @${local_address} +short "${record_type}"); then
- echo -e " ${TICK} ${random_url} is ${local_dig} via localhost (${local_address})"
+ echo -e " ${TICK} ${random_url} is ${local_dig} via localhost (${local_address})"
else
- echo -e " ${CROSS} Failed to resolve ${random_url} via localhot (${local_address})"
+ echo -e " ${CROSS} Failed to resolve ${random_url} via localhot (${local_address})"
fi
if pihole_dig=$(dig -"${protocol}" "${random_url}" @${pihole_address} +short "${record_type}"); then
- echo -e " ${TICK} ${random_url} is ${pihole_dig} via Pi-hole (${pihole_address})"
+ echo -e " ${TICK} ${random_url} is ${pihole_dig} via Pi-hole (${pihole_address})"
else
- echo -e " ${CROSS} Failed to resolve ${random_url} via Pi-hole (${pihole_address})"
+ echo -e " ${CROSS} Failed to resolve ${random_url} via Pi-hole (${pihole_address})"
fi
if remote_dig=$(dig -"${protocol}" "${remote_url}" @${remote_address} +short "${record_type}" | head -n1); then
- echo -e " ${TICK} ${random_url} is ${remote_dig} via a remote, public DNS server (${remote_address})"
+ echo -e " ${TICK} ${random_url} is ${remote_dig} via a remote, public DNS server (${remote_address})"
else
- echo -e " ${CROSS} Failed to resolve ${remote_url} via a remote, public DNS server (${remote_address})"
+ echo -e " ${CROSS} Failed to resolve ${remote_url} via a remote, public DNS server (${remote_address})"
fi
}
From 1102fdc44bc4ea1fa67b08b5c8137de674a8345d Mon Sep 17 00:00:00 2001
From: Jacob Salmela
Date: Wed, 24 May 2017 20:24:23 -0500
Subject: [PATCH 044/162] append everything the user sees to the
pihole_debug.log file
---
advanced/Scripts/piholeDebug.sh | 110 ++++++++++++++++----------------
1 file changed, 55 insertions(+), 55 deletions(-)
diff --git a/advanced/Scripts/piholeDebug.sh b/advanced/Scripts/piholeDebug.sh
index 75809b74..84074160 100755
--- a/advanced/Scripts/piholeDebug.sh
+++ b/advanced/Scripts/piholeDebug.sh
@@ -50,21 +50,21 @@ echo_succes_or_fail() {
# Set the first argument passed to tihs function as a named variable for better readability
local message="${1}"
# If the command was successful (a zero),
- if [ $? -eq 0 ]; then
+ if [[ $? -eq 0 ]]; then
# show success
- echo -e " ${TICK} ${message}"
+ echo -e " ${TICK} ${message}" 2>&1 | tee -a "${DEBUG_LOG}"
else
# Otherwise, show a error
- echo -e " ${CROSS} ${message}"
+ echo -e " ${CROSS} ${message}" 2>&1 | tee -a "${DEBUG_LOG}"
fi
}
initiate_debug() {
# Clear the screen so the debug log is readable
clear
- echo -e "${COL_LIGHT_PURPLE}*** [ INITIALIZING ]${COL_NC}"
+ echo -e "${COL_LIGHT_PURPLE}*** [ INITIALIZING ]${COL_NC}" 2>&1 | tee "${DEBUG_LOG}"
# Timestamp the start of the log
- echo -e " ${INFO} $(date "+%Y-%m-%d:%H:%M:%S") debug log has been initiated."
+ echo -e " ${INFO} $(date "+%Y-%m-%d:%H:%M:%S") debug log has been initiated." 2>&1 | tee -a "${DEBUG_LOG}"
}
# This is a function for visually displaying the curent test that is being run.
@@ -72,7 +72,7 @@ initiate_debug() {
# Colors do not show in the dasboard, but the icons do: [i], [✓], and [✗]
echo_current_diagnostic() {
# Colors are used for visually distinguishing each test in the output
- echo -e "\n${COL_LIGHT_PURPLE}*** [ DIAGNOSING ]:${COL_NC} ${1}"
+ echo -e "\n${COL_LIGHT_PURPLE}*** [ DIAGNOSING ]:${COL_NC} ${1}" 2>&1 | tee -a "${DEBUG_LOG}"
}
file_exists() {
@@ -106,16 +106,16 @@ check_core_version() {
local error_msg="git status failed"
if_directory_exists "${PIHOLEGITDIR}" && \
cd "${PIHOLEGITDIR}" || \
- echo "pihole repo does not exist"
+ echo -e "pihole repo does not exist" 2>&1 | tee -a "${DEBUG_LOG}"
if git status &> /dev/null; then
PI_HOLE_VERSION=$(git describe --tags --abbrev=0);
PI_HOLE_BRANCH=$(git rev-parse --abbrev-ref HEAD);
PI_HOLE_COMMIT=$(git describe --long --dirty --tags --always)
echo -e " ${INFO} Core: ${PI_HOLE_VERSION}
${INFO} Branch: ${PI_HOLE_BRANCH}
- ${INFO} Commit: ${PI_HOLE_COMMIT}"
+ ${INFO} Commit: ${PI_HOLE_COMMIT}" 2>&1 | tee -a "${DEBUG_LOG}"
else
- echo "${error_msg}"
+ echo -e "${error_msg}" 2>&1 | tee -a "${DEBUG_LOG}"
return 1
fi
}
@@ -124,54 +124,54 @@ check_web_version() {
local error_msg="git status failed"
if_directory_exists "${ADMINGITDIR}" && \
cd "${ADMINGITDIR}" || \
- echo "repo does not exist"
+ echo -e "repo does not exist" 2>&1 | tee -a "${DEBUG_LOG}"
if git status &> /dev/null; then
WEB_VERSION=$(git describe --tags --abbrev=0);
WEB_BRANCH=$(git rev-parse --abbrev-ref HEAD);
WEB_COMMIT=$(git describe --long --dirty --tags --always)
echo -e " ${INFO} Web: ${WEB_VERSION}
${INFO} Branch: ${WEB_BRANCH}
- ${INFO} Commit: ${WEB_COMMIT}"
+ ${INFO} Commit: ${WEB_COMMIT}" 2>&1 | tee -a "${DEBUG_LOG}"
else
- echo "${error_msg}"
+ echo -e "${error_msg}" 2>&1 | tee -a "${DEBUG_LOG}"
return 1
fi
}
check_ftl_version() {
FTL_VERSION=$(pihole-FTL version)
- echo -e " ${INFO} FTL: ${FTL_VERSION}"
+ echo -e " ${INFO} FTL: ${FTL_VERSION}" 2>&1 | tee -a "${DEBUG_LOG}"
}
check_web_server_version() {
WEB_SERVER="lighttpd"
WEB_SERVER_VERSON="$(lighttpd -v |& head -n1 | cut -d '/' -f2 | cut -d ' ' -f1)"
- echo -e " ${INFO} ${WEB_SERVER}"
+ echo -e " ${INFO} ${WEB_SERVER}" 2>&1 | tee -a "${DEBUG_LOG}"
if [[ -z "${WEB_SERVER_VERSON}" ]]; then
- echo -e " ${CROSS} ${WEB_SERVER} version could not be detected."
+ echo -e " ${CROSS} ${WEB_SERVER} version could not be detected." 2>&1 | tee -a "${DEBUG_LOG}"
else
- echo -e " ${TICK} ${WEB_SERVER_VERSON}"
+ echo -e " ${TICK} ${WEB_SERVER_VERSON}" 2>&1 | tee -a "${DEBUG_LOG}"
fi
}
check_resolver_version() {
RESOLVER="dnsmasq"
RESOVLER_VERSON="$(dnsmasq -v |& head -n1 | awk '{print $3}')"
- echo -e " ${INFO} ${RESOLVER}"
+ echo -e " ${INFO} ${RESOLVER}" 2>&1 | tee -a "${DEBUG_LOG}"
if [[ -z "${RESOVLER_VERSON}" ]]; then
- echo -e " ${CROSS} ${RESOLVER} version could not be detected."
+ echo -e " ${CROSS} ${RESOLVER} version could not be detected." 2>&1 | tee -a "${DEBUG_LOG}"
else
- echo -e " ${TICK} ${RESOVLER_VERSON}"
+ echo -e " ${TICK} ${RESOVLER_VERSON}" 2>&1 | tee -a "${DEBUG_LOG}"
fi
}
check_php_version() {
PHP_VERSION=$(php -v |& head -n1 | cut -d '-' -f1 | cut -d ' ' -f2)
- echo -e " ${INFO} PHP"
+ echo -e " ${INFO} PHP" 2>&1 | tee -a "${DEBUG_LOG}"
if [[ -z "${PHP_VERSION}" ]]; then
- echo -e " ${CROSS} PHP version could not be detected."
+ echo -e " ${CROSS} PHP version could not be detected." 2>&1 | tee -a "${DEBUG_LOG}"
else
- echo -e " ${TICK} ${PHP_VERSION}"
+ echo -e " ${TICK} ${PHP_VERSION}" 2>&1 | tee -a "${DEBUG_LOG}"
fi
}
@@ -199,7 +199,7 @@ get_distro_attributes() {
# we need just the OS PRETTY_NAME, so print it when we find it
if [[ "${pretty_name_key}" == "PRETTY_NAME" ]]; then
PRETTY_NAME=$(echo "${distro_attribute}" | grep "PRETTY_NAME" | cut -d '=' -f2- | tr -d '"')
- echo " ${INFO} ${PRETTY_NAME}"
+ echo -e " ${INFO} ${PRETTY_NAME}" 2>&1 | tee -a "${DEBUG_LOG}"
# Otherwise, do nothing
else
:
@@ -221,16 +221,16 @@ diagnose_operating_system() {
get_distro_attributes || \
# If it doesn't exist, it's not a system we currently support and link to FAQ
echo -e " ${CROSS} ${COL_LIGHT_RED}${error_msg}${COL_NC}
- ${INFO} ${COL_LIGHT_RED}Please see${COL_NC}: ${COL_CYAN}${faq_url}${COL_NC}"
+ ${INFO} ${COL_LIGHT_RED}Please see${COL_NC}: ${COL_CYAN}${faq_url}${COL_NC}" 2>&1 | tee -a "${DEBUG_LOG}"
}
processor_check() {
echo_current_diagnostic "Processor"
PROCESSOR=$(uname -m)
if [[ -z "${PROCESSOR}" ]]; then
- echo -e " ${CROSS} Processor could not be identified."
+ echo -e " ${CROSS} Processor could not be identified." 2>&1 | tee -a "${DEBUG_LOG}"
else
- echo -e " ${INFO} ${PROCESSOR}"
+ echo -e " ${INFO} ${PROCESSOR}" 2>&1 | tee -a "${DEBUG_LOG}"
fi
}
@@ -246,13 +246,13 @@ detect_ip_addresses() {
if [[ -n ${ip_addr_list} ]]; then
# Local iterator
local i
- echo -e " ${TICK} IPv${protocol} on ${PIHOLE_INTERFACE}"
+ echo -e " ${TICK} IPv${protocol} on ${PIHOLE_INTERFACE}" 2>&1 | tee -a "${DEBUG_LOG}"
for i in "${!ip_addr_list[@]}"; do
- echo -e " [$i] ${ip_addr_list[$i]}"
+ echo -e " [$i] ${ip_addr_list[$i]}" 2>&1 | tee -a "${DEBUG_LOG}"
done
# Othwerwise explain that the protocol is not configured
else
- echo -e " ${CROSS} No IPv${protocol} found on ${PIHOLE_INTERFACE}"
+ echo -e " ${CROSS} No IPv${protocol} found on ${PIHOLE_INTERFACE}" 2>&1 | tee -a "${DEBUG_LOG}"
return 1
fi
}
@@ -282,19 +282,19 @@ ping_gateway() {
# If the gateway variable has a value (meaning a gateway was found),
if [[ -n "${gateway}" ]]; then
# Let the user know we will ping the gateway for a response
- echo -e " ${INFO} Trying three pings on IPv${protocol} gateway at ${gateway}..."
+ echo -e " ${INFO} Trying three pings on IPv${protocol} gateway at ${gateway}..." 2>&1 | tee -a "${DEBUG_LOG}"
# Try to quietly ping the gateway 3 times, with a timeout of 3 seconds, using numeric output only,
# on the pihole interface, and tail the last three lines of the output
# If pinging the gateway is not successful,
if ! ping_cmd="$(${cmd} -q -c 3 -W 3 -n ${gateway} -I ${PIHOLE_INTERFACE} | tail -n 3)"; then
# let the user know
- echo -e " ${CROSS} Gateway did not respond."
+ echo -e " ${CROSS} Gateway did not respond." 2>&1 | tee -a "${DEBUG_LOG}"
# and return an error code
return 1
# Otherwise,
else
# show a success
- echo -e " ${TICK} Gateway responded."
+ echo -e " ${TICK} Gateway responded." 2>&1 | tee -a "${DEBUG_LOG}"
# and return a success code
return 0
fi
@@ -316,18 +316,18 @@ ping_internet() {
# and Google's public IPv4 address
local public_address="8.8.8.8"
fi
- echo -n " ${INFO} Trying three pings on IPv${protocol} to reach the Internet..."
+ echo -n " ${INFO} Trying three pings on IPv${protocol} to reach the Internet..." 2>&1 | tee -a "${DEBUG_LOG}"
if ! ping_inet="$(${cmd} -q -W 3 -c 3 -n ${public_address} -I ${PIHOLE_INTERFACE} | tail -n 3)"; then
- echo -e " ${CROSS} Cannot reach the Internet"
+ echo -e " ${CROSS} Cannot reach the Internet" 2>&1 | tee -a "${DEBUG_LOG}"
return 1
else
- echo -e " ${TICK} Query responded."
+ echo -e " ${TICK} Query responded." 2>&1 | tee -a "${DEBUG_LOG}"
return 0
fi
}
check_required_ports() {
- echo -e " ${INFO} Ports in use:"
+ echo -e " ${INFO} Ports in use:" 2>&1 | tee -a "${DEBUG_LOG}"
ports_in_use=()
while IFS= read -r line; do
ports_in_use+=( "$line" )
@@ -336,7 +336,7 @@ check_required_ports() {
for i in ${!ports_in_use[@]}; do
local port_number="$(echo "${ports_in_use[$i]}" | awk '{print $1}')"
local service_name=$(echo "${ports_in_use[$i]}" | awk '{print $2}')
- echo -e " [${port_number}] is in use by ${service_name}"
+ echo -e " [${port_number}] is in use by ${service_name}" 2>&1 | tee -a "${DEBUG_LOG}"
done
}
@@ -356,15 +356,15 @@ check_x_headers() {
local block_page_working="X-Pi-hole: A black hole for Internet advertisements."
local dashboard_working="X-Pi-hole: The Pi-hole Web interface is working!"
if [[ $block_page == $block_page_working ]]; then
- echo -e " $TICK ${block_page}"
+ echo -e " $TICK ${block_page}" 2>&1 | tee -a "${DEBUG_LOG}"
else
- echo -e " $CROSS X-Header does not match or could not be retrieved"
+ echo -e " $CROSS X-Header does not match or could not be retrieved" 2>&1 | tee -a "${DEBUG_LOG}"
fi
if [[ $dashboard == $dashboard_working ]]; then
- echo -e " $TICK ${dashboard}"
+ echo -e " $TICK ${dashboard}" 2>&1 | tee -a "${DEBUG_LOG}"
else
- echo -e " $CROSS X-Header does not match or could not be retrieved"
+ echo -e " $CROSS X-Header does not match or could not be retrieved" 2>&1 | tee -a "${DEBUG_LOG}"
fi
}
@@ -395,21 +395,21 @@ dig_at() {
local remote_url="doubleclick.com"
if local_dig=$(dig -"${protocol}" "${random_url}" @${local_address} +short "${record_type}"); then
- echo -e " ${TICK} ${random_url} is ${local_dig} via localhost (${local_address})"
+ echo -e " ${TICK} ${random_url} is ${local_dig} via localhost (${local_address})" 2>&1 | tee -a "${DEBUG_LOG}"
else
- echo -e " ${CROSS} Failed to resolve ${random_url} via localhot (${local_address})"
+ echo -e " ${CROSS} Failed to resolve ${random_url} via localhot (${local_address})" 2>&1 | tee -a "${DEBUG_LOG}"
fi
if pihole_dig=$(dig -"${protocol}" "${random_url}" @${pihole_address} +short "${record_type}"); then
- echo -e " ${TICK} ${random_url} is ${pihole_dig} via Pi-hole (${pihole_address})"
+ echo -e " ${TICK} ${random_url} is ${pihole_dig} via Pi-hole (${pihole_address})" 2>&1 | tee -a "${DEBUG_LOG}"
else
- echo -e " ${CROSS} Failed to resolve ${random_url} via Pi-hole (${pihole_address})"
+ echo -e " ${CROSS} Failed to resolve ${random_url} via Pi-hole (${pihole_address})" 2>&1 | tee -a "${DEBUG_LOG}"
fi
if remote_dig=$(dig -"${protocol}" "${remote_url}" @${remote_address} +short "${record_type}" | head -n1); then
- echo -e " ${TICK} ${random_url} is ${remote_dig} via a remote, public DNS server (${remote_address})"
+ echo -e " ${TICK} ${random_url} is ${remote_dig} via a remote, public DNS server (${remote_address})" 2>&1 | tee -a "${DEBUG_LOG}"
else
- echo -e " ${CROSS} Failed to resolve ${remote_url} via a remote, public DNS server (${remote_address})"
+ echo -e " ${CROSS} Failed to resolve ${remote_url} via a remote, public DNS server (${remote_address})" 2>&1 | tee -a "${DEBUG_LOG}"
fi
}
@@ -419,7 +419,7 @@ process_status(){
local i
for i in "${PROCESSES[@]}"; do
local status_of_process=$(systemctl is-active "${i}")
- echo -e " [i] ${i} daemon is ${status_of_process}"
+ echo -e " [i] ${i} daemon is ${status_of_process}" 2>&1 | tee -a "${DEBUG_LOG}"
done
}
@@ -436,7 +436,7 @@ parse_file() {
# For each lin in the file,
for file_lines in "${file_info[@]}"; do
# display the information with the ${INFO} icon
- echo " ${INFO} ${file_lines}"
+ echo -e " ${INFO} ${file_lines}" 2>&1 | tee -a "${DEBUG_LOG}"
done
# Set the IFS back to what it was
IFS="$OLD_IFS"
@@ -450,7 +450,7 @@ diagnose_setup_variables() {
file_exists "${VARSFILE}" && \
# source it
source ${VARSFILE};
- echo -e " ${INFO} Sourcing ${VARSFILE}...";
+ echo -e " ${INFO} Sourcing ${VARSFILE}..." 2>&1 | tee -a "${DEBUG_LOG}";
# and display a green check mark with ${DONE}
echo_succes_or_fail "${VARSFILE} is readable and has been sourced." || \
# Othwerwise, error out
@@ -495,7 +495,7 @@ list_files_in_dir() {
for each_file in "${files_found[@]}"; do
# display the information with the ${INFO} icon
# Also print the permissions and the user/group
- echo -e " ${INFO} ${each_file} ( $(ls -ld ${dir_to_parse}/${each_file} | awk '{print $1, $3, $4}') )"
+ echo -e " ${INFO} ${each_file} ( $(ls -ld ${dir_to_parse}/${each_file} | awk '{print $1, $3, $4}') )" 2>&1 | tee -a "${DEBUG_LOG}"
done
}
@@ -538,13 +538,13 @@ check_http_directory() {
analyze_gravity_list() {
gravity_length=$(grep -c ^ "${GRAVITYFILE}") && \
- echo -e " ${INFO} ${GRAVITYFILE} is ${gravity_length} lines long." || \
- echo -e " ${CROSS} ${GRAVITYFILE} not found!"
+ echo -e " ${INFO} ${GRAVITYFILE} is ${gravity_length} lines long." 2>&1 | tee -a "${DEBUG_LOG}" || \
+ echo -e " ${CROSS} ${GRAVITYFILE} not found!" 2>&1 | tee -a "${DEBUG_LOG}"
}
upload_to_tricorder() {
local tricorder
- echo "${TICK} Finshed debugging!"
+ echo -e "${TICK} Finshed debugging!" 2>&1 | tee -a "${DEBUG_LOG}"
# Ensure the file exists, create if not, clear if exists.
truncate --size=0 "${DEBUG_LOG}"
@@ -598,4 +598,4 @@ check_dnsmasq_d
check_lighttpd_d
check_http_directory
check_cron_d
-upload_to_tricorder
+#upload_to_tricorder
From cc946ce068b7b153ad4d3761b161f400e21c0b2d Mon Sep 17 00:00:00 2001
From: Jacob Salmela
Date: Wed, 24 May 2017 21:11:15 -0500
Subject: [PATCH 045/162] upload to tricorder functions
---
advanced/Scripts/piholeDebug.sh | 67 +++++++++++++++++++++------------
1 file changed, 42 insertions(+), 25 deletions(-)
diff --git a/advanced/Scripts/piholeDebug.sh b/advanced/Scripts/piholeDebug.sh
index 84074160..d484354a 100755
--- a/advanced/Scripts/piholeDebug.sh
+++ b/advanced/Scripts/piholeDebug.sh
@@ -542,46 +542,63 @@ analyze_gravity_list() {
echo -e " ${CROSS} ${GRAVITYFILE} not found!" 2>&1 | tee -a "${DEBUG_LOG}"
}
-upload_to_tricorder() {
- local tricorder
- echo -e "${TICK} Finshed debugging!" 2>&1 | tee -a "${DEBUG_LOG}"
+tricorder_nc_or_ssl() {
+ if command -v openssl &> /dev/null; then
+ echo -e " ${INFO} Using openssl for transmission." 2>&1 | tee -a "${DEBUG_LOG}"
+ tricorder=$(cat /var/log/pihole_debug.log | openssl s_client -quiet -connect tricorder.pi-hole.net:9998 2> /dev/null)
+ else
+ echo -e " ${INFO} Using netcat for transmission." 2>&1 | tee -a "${DEBUG_LOG}"
+ tricorder=$(cat /var/log/pihole_debug.log | nc tricorder.pi-hole.net 9999)
+ fi
+}
- # Ensure the file exists, create if not, clear if exists.
- truncate --size=0 "${DEBUG_LOG}"
+
+upload_to_tricorder() {
# Set the permissions and owner
chmod 644 ${DEBUG_LOG}
chown "$USER":pihole ${DEBUG_LOG}
- # Copy working temp file to final log location
- cat /proc/$$/fd/3 >> "${DEBUG_LOG}"
- # Straight dump of tailing the logs, can sanitize later if needed.
- cat /proc/$$/fd/4 >> "${DEBUG_LOG}"
- echo "::: The debug log can be uploaded to tricorder.pi-hole.net for sharing with developers only."
+ echo ""
+ echo -e "${TICK} Finshed debugging!" 2>&1 | tee -a "${DEBUG_LOG}"
+
+ echo -e " ${INFO} The debug log can be uploaded to tricorder.pi-hole.net for sharing with developers only."
+ echo -e " For more information, see: https://pi-hole.net/2016/11/07/crack-our-medical-tricorder-win-a-raspberry-pi-3/"
if [[ "${AUTOMATED}" ]]; then
- echo "${INFO} Debug script running in automated mode; uploading log to tricorder..."
- tricorder=$(cat /var/log/pihole_debug.log | nc tricorder.pi-hole.net 9999)
+ echo -e " ${INFO} Debug script running in automated mode" 2>&1 | tee -a "${DEBUG_LOG}"
+ if command -v openssl &> /dev/null; then
+ echo -e " ${INFO} Using openssl for transmission." 2>&1 | tee -a "${DEBUG_LOG}"
+ openssl s_client -quiet -connect tricorder.pi-hole.net:9998 2> /dev/null < /dev/stdin
+ else
+ echo -e " ${INFO} Using netcat for transmission." 2>&1 | tee -a "${DEBUG_LOG}"
+ nc tricorder.pi-hole.net 9999 < /dev/stdin
+ fi
else
- read -r -p "\n\n[?] Would you like to upload the log? [y/N] " response
+ echo ""
+ read -r -p "[?] Would you like to upload the log? [y/N] " response
case ${response} in
- [yY][eE][sS]|[yY]) tricorder=$(cat /var/log/pihole_debug.log | nc tricorder.pi-hole.net 9999);;
- *) echo "${INFO} Log will NOT be uploaded to tricorder.";;
+ [yY][eE][sS]|[yY]) tricorder_nc_or_ssl;;
+ *) echo -e " ${INFO} Log will NOT be uploaded to tricorder.";exit;
esac
fi
# Check if tricorder.pi-hole.net is reachable and provide token.
if [[ -n "${tricorder}" ]]; then
- echo "::: ---=== Your debug token is : ${tricorder} Please make a note of it. ===---"
- echo "::: Contact the Pi-hole team with your token for assistance."
- echo "::: Thank you."
+ echo ""
+ echo -e "${COL_LIGHT_PURPLE}***********************************${COL_NC}"
+ echo -e "${TICK} Your debug token is: ${COL_LIGHT_GREEN}${tricorder}${COL_NC}"
+ echo -e "${COL_LIGHT_PURPLE}***********************************${COL_NC}"
+ echo -e ""
+ echo -e " Provide this token to the Pi-hole team for assistance:"
+ echo ""
+ echo -e " https://discourse.pi-hole.net"
else
- echo "::: There was an error uploading your debug log."
- echo "::: Please try again or contact the Pi-hole team for assistance."
+ echo -e " ${CROSS} There was an error uploading your debug log."
+ echo -e " Please try again or contact the Pi-hole team for assistance."
fi
- echo "::: A local copy of the Debug log can be found at : /var/log/pihole_debug.log"
-
+ echo ""
+ echo -e " A local copy of the debug log can be found at : /var/log/pihole_debug.log"
+ echo ""
}
-
-
initiate_debug
check_core_version
check_web_version
@@ -598,4 +615,4 @@ check_dnsmasq_d
check_lighttpd_d
check_http_directory
check_cron_d
-#upload_to_tricorder
+upload_to_tricorder
From 5902be2a49214f614b29c114c810dda4d3c047f9 Mon Sep 17 00:00:00 2001
From: Jacob Salmela
Date: Wed, 24 May 2017 22:07:15 -0500
Subject: [PATCH 046/162] comments for every line
---
advanced/Scripts/piholeDebug.sh | 145 ++++++++++++++++++++++++++++++--
1 file changed, 138 insertions(+), 7 deletions(-)
diff --git a/advanced/Scripts/piholeDebug.sh b/advanced/Scripts/piholeDebug.sh
index d484354a..5e280e62 100755
--- a/advanced/Scripts/piholeDebug.sh
+++ b/advanced/Scripts/piholeDebug.sh
@@ -32,6 +32,7 @@ WHITELISTMATCHES="/tmp/whitelistmatches.list"
readonly FTLLOG="/var/log/pihole-FTL.log"
coltable=/opt/pihole/COL_TABLE
+# These provide the colors we need for making the log more readable
if [[ -f ${coltable} ]]; then
source ${coltable}
else
@@ -47,7 +48,7 @@ else
fi
echo_succes_or_fail() {
- # Set the first argument passed to tihs function as a named variable for better readability
+ # Set the first argument passed to this function as a named variable for better readability
local message="${1}"
# If the command was successful (a zero),
if [[ $? -eq 0 ]]; then
@@ -102,80 +103,133 @@ if_directory_exists() {
}
check_core_version() {
+ # Checks the core version of the Pi-hole codebase
echo_current_diagnostic "Pi-hole Versions"
+ # Store the error message in a variable in case we want to change and/or reuse it
local error_msg="git status failed"
+ # If the pihole git directory exists,
if_directory_exists "${PIHOLEGITDIR}" && \
+ # move into it
cd "${PIHOLEGITDIR}" || \
+ # if not, report an error
echo -e "pihole repo does not exist" 2>&1 | tee -a "${DEBUG_LOG}"
+ # If the git status command completes successfully,
+ # we can assume we can get the information we want
if git status &> /dev/null; then
+ # The current version the user is on
PI_HOLE_VERSION=$(git describe --tags --abbrev=0);
+ # What branch they are on
PI_HOLE_BRANCH=$(git rev-parse --abbrev-ref HEAD);
+ # The commit they are on
PI_HOLE_COMMIT=$(git describe --long --dirty --tags --always)
+ # echo this information out to the user in a nice format
echo -e " ${INFO} Core: ${PI_HOLE_VERSION}
${INFO} Branch: ${PI_HOLE_BRANCH}
${INFO} Commit: ${PI_HOLE_COMMIT}" 2>&1 | tee -a "${DEBUG_LOG}"
+ # If git status failed,
else
+ # Return an error message
echo -e "${error_msg}" 2>&1 | tee -a "${DEBUG_LOG}"
+ # and exit with a non zero code
return 1
fi
}
check_web_version() {
+ # Local variable for the error message
local error_msg="git status failed"
+ # If the directory exists,
if_directory_exists "${ADMINGITDIR}" && \
+ # move into it
cd "${ADMINGITDIR}" || \
+ # if not, give an error message
echo -e "repo does not exist" 2>&1 | tee -a "${DEBUG_LOG}"
+ # If the git status command completes successfully,
+ # we can assume we can get the information we want
if git status &> /dev/null; then
+ # The current version the user is on
WEB_VERSION=$(git describe --tags --abbrev=0);
+ # What branch they are on
WEB_BRANCH=$(git rev-parse --abbrev-ref HEAD);
+ # The commit they are on
WEB_COMMIT=$(git describe --long --dirty --tags --always)
+ # echo this information out to the user in a nice format
echo -e " ${INFO} Web: ${WEB_VERSION}
${INFO} Branch: ${WEB_BRANCH}
${INFO} Commit: ${WEB_COMMIT}" 2>&1 | tee -a "${DEBUG_LOG}"
+ # If git status failed,
else
+ # Return an error message
echo -e "${error_msg}" 2>&1 | tee -a "${DEBUG_LOG}"
+ # and exit with a non zero code
return 1
fi
}
check_ftl_version() {
+ # Use the built in command to check FTL's version
FTL_VERSION=$(pihole-FTL version)
+ # and display it to the user
echo -e " ${INFO} FTL: ${FTL_VERSION}" 2>&1 | tee -a "${DEBUG_LOG}"
}
+# Check the current version of the Web server
check_web_server_version() {
+ # Store the name in a variable in case we ever want to change it
WEB_SERVER="lighttpd"
+ # Parse out just the version number
WEB_SERVER_VERSON="$(lighttpd -v |& head -n1 | cut -d '/' -f2 | cut -d ' ' -f1)"
+ # Display the information to the user
echo -e " ${INFO} ${WEB_SERVER}" 2>&1 | tee -a "${DEBUG_LOG}"
+ # If the Web server does not have a version (the variable is empty)
if [[ -z "${WEB_SERVER_VERSON}" ]]; then
+ # Display and error
echo -e " ${CROSS} ${WEB_SERVER} version could not be detected." 2>&1 | tee -a "${DEBUG_LOG}"
+ # Otherwise,
else
+ # display the version
echo -e " ${TICK} ${WEB_SERVER_VERSON}" 2>&1 | tee -a "${DEBUG_LOG}"
fi
}
+# Check the current version of the DNS server
check_resolver_version() {
+ # Store the name in a variable in case we ever want to change it
RESOLVER="dnsmasq"
+ # Parse out just the version number
RESOVLER_VERSON="$(dnsmasq -v |& head -n1 | awk '{print $3}')"
+ # Display the information to the user
echo -e " ${INFO} ${RESOLVER}" 2>&1 | tee -a "${DEBUG_LOG}"
+ # If the DNS server does not have a version (the variable is empty)
if [[ -z "${RESOVLER_VERSON}" ]]; then
+ # Display and error
echo -e " ${CROSS} ${RESOLVER} version could not be detected." 2>&1 | tee -a "${DEBUG_LOG}"
+ # Otherwise,
else
+ # display the version
echo -e " ${TICK} ${RESOVLER_VERSON}" 2>&1 | tee -a "${DEBUG_LOG}"
fi
}
check_php_version() {
+ # Parse out just the version number
PHP_VERSION=$(php -v |& head -n1 | cut -d '-' -f1 | cut -d ' ' -f2)
+ # Display the info to the user
echo -e " ${INFO} PHP" 2>&1 | tee -a "${DEBUG_LOG}"
+ # If no version is detected,
if [[ -z "${PHP_VERSION}" ]]; then
+ # show an error
echo -e " ${CROSS} PHP version could not be detected." 2>&1 | tee -a "${DEBUG_LOG}"
+ # otherwise,
else
+ # Show the version
echo -e " ${TICK} ${PHP_VERSION}" 2>&1 | tee -a "${DEBUG_LOG}"
fi
}
+# These are the most critical dependencies of Pi-hole, so we check for them
+# and their versions, using the functions above.
check_critical_dependencies() {
echo_current_diagnostic "Versions of critical dependencies"
check_web_server_version
@@ -210,14 +264,16 @@ get_distro_attributes() {
}
diagnose_operating_system() {
+ # local variable for system requirements
local faq_url="https://discourse.pi-hole.net/t/hardware-software-requirements/273"
+ # error message in a variable so we can easily modify it later (or re-use it)
local error_msg="Distribution unknown -- most likely you are on an unsupported platform and may run into issues."
# Display the current test that is running
echo_current_diagnostic "Operating system"
# If there is a /etc/*release file, it's probably a supported operating system, so we can
file_exists /etc/*release && \
- # display the attributes to the user
+ # display the attributes to the user from the function made earlier
get_distro_attributes || \
# If it doesn't exist, it's not a system we currently support and link to FAQ
echo -e " ${CROSS} ${COL_LIGHT_RED}${error_msg}${COL_NC}
@@ -226,10 +282,15 @@ diagnose_operating_system() {
processor_check() {
echo_current_diagnostic "Processor"
+ # Store the processor type in a variable
PROCESSOR=$(uname -m)
+ # If it does not contain a value,
if [[ -z "${PROCESSOR}" ]]; then
+ # we couldn't detect it, so show an error
echo -e " ${CROSS} Processor could not be identified." 2>&1 | tee -a "${DEBUG_LOG}"
+ # Otherwise,
else
+ # Show the processor type
echo -e " ${INFO} ${PROCESSOR}" 2>&1 | tee -a "${DEBUG_LOG}"
fi
}
@@ -246,12 +307,16 @@ detect_ip_addresses() {
if [[ -n ${ip_addr_list} ]]; then
# Local iterator
local i
+ # Display the protocol and interface
echo -e " ${TICK} IPv${protocol} on ${PIHOLE_INTERFACE}" 2>&1 | tee -a "${DEBUG_LOG}"
+ # Since there may be more than one IP address, store them in an array
for i in "${!ip_addr_list[@]}"; do
+ # For each one in the list, print it out using the iterator as a numbered list
echo -e " [$i] ${ip_addr_list[$i]}" 2>&1 | tee -a "${DEBUG_LOG}"
done
- # Othwerwise explain that the protocol is not configured
+ # Othwerwise,
else
+ # explain that the protocol is not configured
echo -e " ${CROSS} No IPv${protocol} found on ${PIHOLE_INTERFACE}" 2>&1 | tee -a "${DEBUG_LOG}"
return 1
fi
@@ -302,6 +367,7 @@ ping_gateway() {
}
ping_internet() {
+ # Give the first argument a readable name
local protocol="${1}"
# If the protocol is 6,
if [[ ${protocol} == "6" ]]; then
@@ -317,30 +383,42 @@ ping_internet() {
local public_address="8.8.8.8"
fi
echo -n " ${INFO} Trying three pings on IPv${protocol} to reach the Internet..." 2>&1 | tee -a "${DEBUG_LOG}"
+ # Try to ping the address 3 times
if ! ping_inet="$(${cmd} -q -W 3 -c 3 -n ${public_address} -I ${PIHOLE_INTERFACE} | tail -n 3)"; then
+ # if it's unsuccessful, show an error
echo -e " ${CROSS} Cannot reach the Internet" 2>&1 | tee -a "${DEBUG_LOG}"
return 1
+ # Otherwise,
else
+ # show success
echo -e " ${TICK} Query responded." 2>&1 | tee -a "${DEBUG_LOG}"
return 0
fi
}
check_required_ports() {
+ # Since Pi-hole needs 53, 80, and 4711, check what they are being used by
+ # so we can detect any issues
echo -e " ${INFO} Ports in use:" 2>&1 | tee -a "${DEBUG_LOG}"
+ # Create an array for these ports in use
ports_in_use=()
+ # Sort the addresses and remove duplicates
while IFS= read -r line; do
ports_in_use+=( "$line" )
done < <( lsof -i -P -n | awk -F' ' '/LISTEN/ {print $9, $1}' | sort | uniq | cut -d':' -f2 )
+ # Now that we have the values stored,
for i in ${!ports_in_use[@]}; do
local port_number="$(echo "${ports_in_use[$i]}" | awk '{print $1}')"
local service_name=$(echo "${ports_in_use[$i]}" | awk '{print $2}')
+ # display the information nicely to the user
echo -e " [${port_number}] is in use by ${service_name}" 2>&1 | tee -a "${DEBUG_LOG}"
done
}
check_networking() {
+ # Runs through several of the functions made earlier; we just clump them
+ # together since they are all related to the networking aspect of things
echo_current_diagnostic "Networking"
detect_ip_addresses "4"
ping_gateway "4"
@@ -350,17 +428,27 @@ check_networking() {
}
check_x_headers() {
+ # The X-Headers allow us to determine from the command line if the Web
+ # 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=$(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 dashboard=$(curl -Is localhost/admin/ | awk '/X-Pi-hole/' | tr -d '\r')
+ # Store what the X-Header shoud be in variables for comparision later
local block_page_working="X-Pi-hole: A black hole for Internet advertisements."
local dashboard_working="X-Pi-hole: The Pi-hole Web interface is working!"
+ # If the X-header found by curl matches what is should be,
if [[ $block_page == $block_page_working ]]; then
+ # display a success message
echo -e " $TICK ${block_page}" 2>&1 | tee -a "${DEBUG_LOG}"
+ # Otherwise,
else
+ # show an error
echo -e " $CROSS X-Header does not match or could not be retrieved" 2>&1 | tee -a "${DEBUG_LOG}"
fi
+ # Same logic applies to the dashbord as above
if [[ $dashboard == $dashboard_working ]]; then
echo -e " $TICK ${dashboard}" 2>&1 | tee -a "${DEBUG_LOG}"
else
@@ -369,20 +457,29 @@ check_x_headers() {
}
dig_at() {
+ # We need to test if Pi-hole can properly resolve domain names as it is an
+ # essential piece of the software that needs to work
+
+ # Store the arguments as variables with names
local protocol="${1}"
local IP="${2}"
echo_current_diagnostic "Domain name resolution (IPv${protocol}) using a random blocked domain"
+ # Set more local variables
local url
local local_dig
local pihole_dig
local remote_dig
+ # If the protocol (4 or 6) is 6,
if [[ ${protocol} == "6" ]]; then
+ # Set the IPv6 variables and record type
local local_address="::1"
local pihole_address="${IPV6_ADDRESS%/*}"
local remote_address="2001:4860:4860::8888"
local record_type="AAAA"
+ # Othwerwise, it should be 4
else
+ # so use the IPv4 values
local local_address="127.0.0.1"
local pihole_address="${IPV4_ADDRESS%/*}"
local remote_address="8.8.8.8"
@@ -392,33 +489,45 @@ dig_at() {
# Find a random blocked url that has not been whitelisted.
local random_url=$(shuf -n 1 "${GRAVITYFILE}" | awk -F ' ' '{ print $2 }')
- local remote_url="doubleclick.com"
-
+ # First do a dig on localhost, to see if Pi-hole can use itself to block a domain
if local_dig=$(dig -"${protocol}" "${random_url}" @${local_address} +short "${record_type}"); then
+ # If it can, show sucess
echo -e " ${TICK} ${random_url} is ${local_dig} via localhost (${local_address})" 2>&1 | tee -a "${DEBUG_LOG}"
+ # Otherwise,
else
+ # show a failure
echo -e " ${CROSS} Failed to resolve ${random_url} via localhot (${local_address})" 2>&1 | tee -a "${DEBUG_LOG}"
fi
+ # Next we need to check if Pi-hole can resolve a domain when the query is sent to it's IP address
+ # This better emulates how clients will interact with Pi-hole as opposed to above where Pi-hole is
+ # just asing itself locally
if pihole_dig=$(dig -"${protocol}" "${random_url}" @${pihole_address} +short "${record_type}"); then
echo -e " ${TICK} ${random_url} is ${pihole_dig} via Pi-hole (${pihole_address})" 2>&1 | tee -a "${DEBUG_LOG}"
else
echo -e " ${CROSS} Failed to resolve ${random_url} via Pi-hole (${pihole_address})" 2>&1 | tee -a "${DEBUG_LOG}"
fi
+ # Finally, we need to make sure legitimate sites can out if using an external, public DNS server
if remote_dig=$(dig -"${protocol}" "${remote_url}" @${remote_address} +short "${record_type}" | head -n1); then
+ # If successful, the real IP of the domain will be returned instead of Pi-hole's IP
echo -e " ${TICK} ${random_url} is ${remote_dig} via a remote, public DNS server (${remote_address})" 2>&1 | tee -a "${DEBUG_LOG}"
else
- echo -e " ${CROSS} Failed to resolve ${remote_url} via a remote, public DNS server (${remote_address})" 2>&1 | tee -a "${DEBUG_LOG}"
+ echo -e " ${CROSS} Failed to resolve ${random_url} via a remote, public DNS server (${remote_address})" 2>&1 | tee -a "${DEBUG_LOG}"
fi
}
process_status(){
+ # Check to make sure Pi-hole's services are running and active
echo_current_diagnostic "Pi-hole processes"
+ # Store them in an array for easy use
PROCESSES=( dnsmasq lighttpd pihole-FTL )
local i
+ # For each process,
for i in "${PROCESSES[@]}"; do
+ # get it's status
local status_of_process=$(systemctl is-active "${i}")
+ # and print it out to the user
echo -e " [i] ${i} daemon is ${status_of_process}" 2>&1 | tee -a "${DEBUG_LOG}"
done
}
@@ -461,6 +570,7 @@ diagnose_setup_variables() {
check_name_resolution() {
# Check name resoltion from localhost, Pi-hole's IP, and Google's name severs
+ # using the function we created earlier
dig_at 4 "${IPV4_ADDRESS%/*}"
# If IPv6 enabled, check resolution
if [[ "${IPV6_ADDRESS}" ]]; then
@@ -537,16 +647,24 @@ check_http_directory() {
}
analyze_gravity_list() {
+ # It's helpful to know how big a user's gravity file is
gravity_length=$(grep -c ^ "${GRAVITYFILE}") && \
echo -e " ${INFO} ${GRAVITYFILE} is ${gravity_length} lines long." 2>&1 | tee -a "${DEBUG_LOG}" || \
+ # If the previous command failed, something is wrong with the file
echo -e " ${CROSS} ${GRAVITYFILE} not found!" 2>&1 | tee -a "${DEBUG_LOG}"
}
tricorder_nc_or_ssl() {
+ # Users can submit their debug logs using nc (unencrypted) or opensll (enrypted) if available
+ # Check fist for openssl since encryption is a good thing
if command -v openssl &> /dev/null; then
+ # If successful
echo -e " ${INFO} Using openssl for transmission." 2>&1 | tee -a "${DEBUG_LOG}"
+ # transmit the log and store the token returned in the tricorder variable
tricorder=$(cat /var/log/pihole_debug.log | openssl s_client -quiet -connect tricorder.pi-hole.net:9998 2> /dev/null)
+ # Otherwise,
else
+ # use net cat
echo -e " ${INFO} Using netcat for transmission." 2>&1 | tee -a "${DEBUG_LOG}"
tricorder=$(cat /var/log/pihole_debug.log | nc tricorder.pi-hole.net 9999)
fi
@@ -558,13 +676,18 @@ upload_to_tricorder() {
chmod 644 ${DEBUG_LOG}
chown "$USER":pihole ${DEBUG_LOG}
+ # Let the user know debugging is complete
echo ""
echo -e "${TICK} Finshed debugging!" 2>&1 | tee -a "${DEBUG_LOG}"
+ # Provide information on what they should do with their token
echo -e " ${INFO} The debug log can be uploaded to tricorder.pi-hole.net for sharing with developers only."
echo -e " For more information, see: https://pi-hole.net/2016/11/07/crack-our-medical-tricorder-win-a-raspberry-pi-3/"
+ # If pihole -d is running automatically (usually throught the dashboard)
if [[ "${AUTOMATED}" ]]; then
+ # let the user know
echo -e " ${INFO} Debug script running in automated mode" 2>&1 | tee -a "${DEBUG_LOG}"
+ # and then decide again which tool to use to submit it
if command -v openssl &> /dev/null; then
echo -e " ${INFO} Using openssl for transmission." 2>&1 | tee -a "${DEBUG_LOG}"
openssl s_client -quiet -connect tricorder.pi-hole.net:9998 2> /dev/null < /dev/stdin
@@ -574,13 +697,18 @@ upload_to_tricorder() {
fi
else
echo ""
+ # Give the user a choice of uploading it or not
+ # Users can review the log file locally and try to self-diagnose their problem
read -r -p "[?] Would you like to upload the log? [y/N] " response
case ${response} in
+ # If they say yes, run our function for uploading the log
[yY][eE][sS]|[yY]) tricorder_nc_or_ssl;;
+ # If they choose no, just exit out of the script
*) echo -e " ${INFO} Log will NOT be uploaded to tricorder.";exit;
esac
fi
- # Check if tricorder.pi-hole.net is reachable and provide token.
+ # Check if tricorder.pi-hole.net is reachable and provide token
+ # along with some additional useful information
if [[ -n "${tricorder}" ]]; then
echo ""
echo -e "${COL_LIGHT_PURPLE}***********************************${COL_NC}"
@@ -599,10 +727,13 @@ upload_to_tricorder() {
echo ""
}
+# Run through all the functions we made
initiate_debug
check_core_version
check_web_version
check_ftl_version
+# setupVars.conf needs to be sourced before the networking so the values are
+# available to the check_networking function
diagnose_setup_variables
diagnose_operating_system
processor_check
From 10139241f5168e53015dd8e238f44289882c76e3 Mon Sep 17 00:00:00 2001
From: WaLLy3K
Date: Fri, 26 May 2017 17:57:27 +1000
Subject: [PATCH 047/162] Fix output IPv4 addr when removing CIDR notation
(#1498)
---
advanced/Scripts/chronometer.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/advanced/Scripts/chronometer.sh b/advanced/Scripts/chronometer.sh
index 763091d8..d9b7d05b 100755
--- a/advanced/Scripts/chronometer.sh
+++ b/advanced/Scripts/chronometer.sh
@@ -361,7 +361,7 @@ chronoFunc() {
printFunc " HDD usage: " "$disk_perc"
printf "%s(%s)%s\n" "$COL_DARK_GRAY" "Used: $(hrBytes "$disk_used") of $(hrBytes "$disk_total")" "$COL_NC"
- printFunc " LAN addr: " "${IPV4_ADDRESS:0:-3}"
+ printFunc " LAN addr: " "${IPV4_ADDRESS/\/*/}"
printf "%s(%s)%s\n" "$COL_DARK_GRAY" "Gateway: $net_gateway" "$COL_NC"
if [[ "$DHCP_ACTIVE" == "true" ]]; then
From 96f01e670fa13f0d5c77a7d305285d3b750d1668 Mon Sep 17 00:00:00 2001
From: Jacob Salmela
Date: Fri, 26 May 2017 12:16:22 -0500
Subject: [PATCH 048/162] add functions to write to console and log at the same
time
---
advanced/Scripts/piholeDebug.sh | 177 ++++++++++++++++++--------------
1 file changed, 101 insertions(+), 76 deletions(-)
diff --git a/advanced/Scripts/piholeDebug.sh b/advanced/Scripts/piholeDebug.sh
index 5e280e62..a9efcbbc 100755
--- a/advanced/Scripts/piholeDebug.sh
+++ b/advanced/Scripts/piholeDebug.sh
@@ -9,10 +9,14 @@
# Please see LICENSE file for your rights under this license.
-# causes a pipeline to produce a failure return code if any command errors.
-# Normally, pipelines only return a failure if the last command errors.
-# In combination with set -e, this will make your script exit if any command in a pipeline errors.
+# -e option instructs bash to immediately exit if any command [1] has a non-zero exit status
+# -u a reference to any variable you haven't previously defined
+# with the exceptions of $* and $@ - is an error, and causes the program to immediately exit
+# -o pipefail prevents errors in a pipeline from being masked. If any command in a pipeline fails,
+# that return code will be used as the return code of the whole pipeline. By default, the
+# pipeline's return code is that of the last command - even if it succeeds
set -o pipefail
+IFS=$'\n\t'
######## GLOBAL VARS ########
VARSFILE="/etc/pihole/setupVars.conf"
@@ -47,25 +51,44 @@ else
OVER="\r\033[K"
fi
+make_temporary_log() {
+ # Create temporary file for log
+ TEMPLOG=$(mktemp /tmp/pihole_temp.XXXXXX)
+ # Open handle 3 for templog
+ # https://stackoverflow.com/questions/18460186/writing-outputs-to-log-file-and-console
+ exec 3>"$TEMPLOG"
+ # Delete templog, but allow for addressing via file handle.
+ rm "$TEMPLOG"
+}
+
+log_write() {
+ # echo arguments to both the log and the console"
+ echo -e "${@}" | tee -a /proc/$$/fd/3
+}
+
+copy_to_debug_log() {
+ cat /proc/$$/fd/3 >> "${DEBUG_LOG}"
+}
+
echo_succes_or_fail() {
# Set the first argument passed to this function as a named variable for better readability
local message="${1}"
# If the command was successful (a zero),
if [[ $? -eq 0 ]]; then
# show success
- echo -e " ${TICK} ${message}" 2>&1 | tee -a "${DEBUG_LOG}"
+ log_write " ${TICK} ${message}"
else
# Otherwise, show a error
- echo -e " ${CROSS} ${message}" 2>&1 | tee -a "${DEBUG_LOG}"
+ log_write " ${CROSS} ${message}"
fi
}
initiate_debug() {
# Clear the screen so the debug log is readable
clear
- echo -e "${COL_LIGHT_PURPLE}*** [ INITIALIZING ]${COL_NC}" 2>&1 | tee "${DEBUG_LOG}"
+ log_write "${COL_LIGHT_PURPLE}*** [ INITIALIZING ]${COL_NC}" 2>&1 | tee "${DEBUG_LOG}"
# Timestamp the start of the log
- echo -e " ${INFO} $(date "+%Y-%m-%d:%H:%M:%S") debug log has been initiated." 2>&1 | tee -a "${DEBUG_LOG}"
+ log_write " ${INFO} $(date "+%Y-%m-%d:%H:%M:%S") debug log has been initiated."
}
# This is a function for visually displaying the curent test that is being run.
@@ -73,7 +96,7 @@ initiate_debug() {
# Colors do not show in the dasboard, but the icons do: [i], [✓], and [✗]
echo_current_diagnostic() {
# Colors are used for visually distinguishing each test in the output
- echo -e "\n${COL_LIGHT_PURPLE}*** [ DIAGNOSING ]:${COL_NC} ${1}" 2>&1 | tee -a "${DEBUG_LOG}"
+ log_write "\n${COL_LIGHT_PURPLE}*** [ DIAGNOSING ]:${COL_NC} ${1}"
}
file_exists() {
@@ -112,7 +135,7 @@ check_core_version() {
# move into it
cd "${PIHOLEGITDIR}" || \
# if not, report an error
- echo -e "pihole repo does not exist" 2>&1 | tee -a "${DEBUG_LOG}"
+ log_write "pihole repo does not exist"
# If the git status command completes successfully,
# we can assume we can get the information we want
if git status &> /dev/null; then
@@ -123,13 +146,13 @@ check_core_version() {
# The commit they are on
PI_HOLE_COMMIT=$(git describe --long --dirty --tags --always)
# echo this information out to the user in a nice format
- echo -e " ${INFO} Core: ${PI_HOLE_VERSION}
+ log_write " ${INFO} Core: ${PI_HOLE_VERSION}
${INFO} Branch: ${PI_HOLE_BRANCH}
- ${INFO} Commit: ${PI_HOLE_COMMIT}" 2>&1 | tee -a "${DEBUG_LOG}"
+ ${INFO} Commit: ${PI_HOLE_COMMIT}"
# If git status failed,
else
# Return an error message
- echo -e "${error_msg}" 2>&1 | tee -a "${DEBUG_LOG}"
+ log_write "${error_msg}"
# and exit with a non zero code
return 1
fi
@@ -143,7 +166,7 @@ check_web_version() {
# move into it
cd "${ADMINGITDIR}" || \
# if not, give an error message
- echo -e "repo does not exist" 2>&1 | tee -a "${DEBUG_LOG}"
+ log_write "repo does not exist"
# If the git status command completes successfully,
# we can assume we can get the information we want
if git status &> /dev/null; then
@@ -154,13 +177,13 @@ check_web_version() {
# The commit they are on
WEB_COMMIT=$(git describe --long --dirty --tags --always)
# echo this information out to the user in a nice format
- echo -e " ${INFO} Web: ${WEB_VERSION}
+ log_write " ${INFO} Web: ${WEB_VERSION}
${INFO} Branch: ${WEB_BRANCH}
- ${INFO} Commit: ${WEB_COMMIT}" 2>&1 | tee -a "${DEBUG_LOG}"
+ ${INFO} Commit: ${WEB_COMMIT}"
# If git status failed,
else
# Return an error message
- echo -e "${error_msg}" 2>&1 | tee -a "${DEBUG_LOG}"
+ log_write "${error_msg}"
# and exit with a non zero code
return 1
fi
@@ -170,7 +193,7 @@ check_ftl_version() {
# Use the built in command to check FTL's version
FTL_VERSION=$(pihole-FTL version)
# and display it to the user
- echo -e " ${INFO} FTL: ${FTL_VERSION}" 2>&1 | tee -a "${DEBUG_LOG}"
+ log_write " ${INFO} FTL: ${FTL_VERSION}"
}
# Check the current version of the Web server
@@ -180,15 +203,15 @@ check_web_server_version() {
# Parse out just the version number
WEB_SERVER_VERSON="$(lighttpd -v |& head -n1 | cut -d '/' -f2 | cut -d ' ' -f1)"
# Display the information to the user
- echo -e " ${INFO} ${WEB_SERVER}" 2>&1 | tee -a "${DEBUG_LOG}"
+ log_write " ${INFO} ${WEB_SERVER}"
# If the Web server does not have a version (the variable is empty)
if [[ -z "${WEB_SERVER_VERSON}" ]]; then
# Display and error
- echo -e " ${CROSS} ${WEB_SERVER} version could not be detected." 2>&1 | tee -a "${DEBUG_LOG}"
+ log_write " ${CROSS} ${WEB_SERVER} version could not be detected."
# Otherwise,
else
# display the version
- echo -e " ${TICK} ${WEB_SERVER_VERSON}" 2>&1 | tee -a "${DEBUG_LOG}"
+ log_write " ${TICK} ${WEB_SERVER_VERSON}"
fi
}
@@ -199,15 +222,15 @@ check_resolver_version() {
# Parse out just the version number
RESOVLER_VERSON="$(dnsmasq -v |& head -n1 | awk '{print $3}')"
# Display the information to the user
- echo -e " ${INFO} ${RESOLVER}" 2>&1 | tee -a "${DEBUG_LOG}"
+ log_write " ${INFO} ${RESOLVER}"
# If the DNS server does not have a version (the variable is empty)
if [[ -z "${RESOVLER_VERSON}" ]]; then
# Display and error
- echo -e " ${CROSS} ${RESOLVER} version could not be detected." 2>&1 | tee -a "${DEBUG_LOG}"
+ log_write " ${CROSS} ${RESOLVER} version could not be detected."
# Otherwise,
else
# display the version
- echo -e " ${TICK} ${RESOVLER_VERSON}" 2>&1 | tee -a "${DEBUG_LOG}"
+ log_write " ${TICK} ${RESOVLER_VERSON}"
fi
}
@@ -215,15 +238,15 @@ check_php_version() {
# Parse out just the version number
PHP_VERSION=$(php -v |& head -n1 | cut -d '-' -f1 | cut -d ' ' -f2)
# Display the info to the user
- echo -e " ${INFO} PHP" 2>&1 | tee -a "${DEBUG_LOG}"
+ log_write " ${INFO} PHP"
# If no version is detected,
if [[ -z "${PHP_VERSION}" ]]; then
# show an error
- echo -e " ${CROSS} PHP version could not be detected." 2>&1 | tee -a "${DEBUG_LOG}"
+ log_write " ${CROSS} PHP version could not be detected."
# otherwise,
else
# Show the version
- echo -e " ${TICK} ${PHP_VERSION}" 2>&1 | tee -a "${DEBUG_LOG}"
+ log_write " ${TICK} ${PHP_VERSION}"
fi
}
@@ -253,7 +276,7 @@ get_distro_attributes() {
# we need just the OS PRETTY_NAME, so print it when we find it
if [[ "${pretty_name_key}" == "PRETTY_NAME" ]]; then
PRETTY_NAME=$(echo "${distro_attribute}" | grep "PRETTY_NAME" | cut -d '=' -f2- | tr -d '"')
- echo -e " ${INFO} ${PRETTY_NAME}" 2>&1 | tee -a "${DEBUG_LOG}"
+ log_write " ${INFO} ${PRETTY_NAME}"
# Otherwise, do nothing
else
:
@@ -276,8 +299,8 @@ diagnose_operating_system() {
# display the attributes to the user from the function made earlier
get_distro_attributes || \
# If it doesn't exist, it's not a system we currently support and link to FAQ
- echo -e " ${CROSS} ${COL_LIGHT_RED}${error_msg}${COL_NC}
- ${INFO} ${COL_LIGHT_RED}Please see${COL_NC}: ${COL_CYAN}${faq_url}${COL_NC}" 2>&1 | tee -a "${DEBUG_LOG}"
+ log_write " ${CROSS} ${COL_LIGHT_RED}${error_msg}${COL_NC}
+ ${INFO} ${COL_LIGHT_RED}Please see${COL_NC}: ${COL_CYAN}${faq_url}${COL_NC}"
}
processor_check() {
@@ -287,11 +310,11 @@ processor_check() {
# If it does not contain a value,
if [[ -z "${PROCESSOR}" ]]; then
# we couldn't detect it, so show an error
- echo -e " ${CROSS} Processor could not be identified." 2>&1 | tee -a "${DEBUG_LOG}"
+ log_write " ${CROSS} Processor could not be identified."
# Otherwise,
else
# Show the processor type
- echo -e " ${INFO} ${PROCESSOR}" 2>&1 | tee -a "${DEBUG_LOG}"
+ log_write " ${INFO} ${PROCESSOR}"
fi
}
@@ -308,16 +331,16 @@ detect_ip_addresses() {
# Local iterator
local i
# Display the protocol and interface
- echo -e " ${TICK} IPv${protocol} on ${PIHOLE_INTERFACE}" 2>&1 | tee -a "${DEBUG_LOG}"
+ log_write " ${TICK} IPv${protocol} on ${PIHOLE_INTERFACE}"
# Since there may be more than one IP address, store them in an array
for i in "${!ip_addr_list[@]}"; do
# For each one in the list, print it out using the iterator as a numbered list
- echo -e " [$i] ${ip_addr_list[$i]}" 2>&1 | tee -a "${DEBUG_LOG}"
+ log_write " [$i] ${ip_addr_list[$i]}"
done
# Othwerwise,
else
# explain that the protocol is not configured
- echo -e " ${CROSS} No IPv${protocol} found on ${PIHOLE_INTERFACE}" 2>&1 | tee -a "${DEBUG_LOG}"
+ log_write " ${CROSS} No IPv${protocol} found on ${PIHOLE_INTERFACE}"
return 1
fi
}
@@ -347,19 +370,19 @@ ping_gateway() {
# If the gateway variable has a value (meaning a gateway was found),
if [[ -n "${gateway}" ]]; then
# Let the user know we will ping the gateway for a response
- echo -e " ${INFO} Trying three pings on IPv${protocol} gateway at ${gateway}..." 2>&1 | tee -a "${DEBUG_LOG}"
+ log_write " ${INFO} Trying three pings on IPv${protocol} gateway at ${gateway}..."
# Try to quietly ping the gateway 3 times, with a timeout of 3 seconds, using numeric output only,
# on the pihole interface, and tail the last three lines of the output
# If pinging the gateway is not successful,
if ! ping_cmd="$(${cmd} -q -c 3 -W 3 -n ${gateway} -I ${PIHOLE_INTERFACE} | tail -n 3)"; then
# let the user know
- echo -e " ${CROSS} Gateway did not respond." 2>&1 | tee -a "${DEBUG_LOG}"
+ log_write " ${CROSS} Gateway did not respond."
# and return an error code
return 1
# Otherwise,
else
# show a success
- echo -e " ${TICK} Gateway responded." 2>&1 | tee -a "${DEBUG_LOG}"
+ log_write " ${TICK} Gateway responded."
# and return a success code
return 0
fi
@@ -382,16 +405,16 @@ ping_internet() {
# and Google's public IPv4 address
local public_address="8.8.8.8"
fi
- echo -n " ${INFO} Trying three pings on IPv${protocol} to reach the Internet..." 2>&1 | tee -a "${DEBUG_LOG}"
+ echo -n " ${INFO} Trying three pings on IPv${protocol} to reach the Internet..."
# Try to ping the address 3 times
if ! ping_inet="$(${cmd} -q -W 3 -c 3 -n ${public_address} -I ${PIHOLE_INTERFACE} | tail -n 3)"; then
# if it's unsuccessful, show an error
- echo -e " ${CROSS} Cannot reach the Internet" 2>&1 | tee -a "${DEBUG_LOG}"
+ log_write " ${CROSS} Cannot reach the Internet"
return 1
# Otherwise,
else
# show success
- echo -e " ${TICK} Query responded." 2>&1 | tee -a "${DEBUG_LOG}"
+ log_write " ${TICK} Query responded."
return 0
fi
}
@@ -399,7 +422,7 @@ ping_internet() {
check_required_ports() {
# Since Pi-hole needs 53, 80, and 4711, check what they are being used by
# so we can detect any issues
- echo -e " ${INFO} Ports in use:" 2>&1 | tee -a "${DEBUG_LOG}"
+ log_write " ${INFO} Ports in use:"
# Create an array for these ports in use
ports_in_use=()
# Sort the addresses and remove duplicates
@@ -412,7 +435,7 @@ check_required_ports() {
local port_number="$(echo "${ports_in_use[$i]}" | awk '{print $1}')"
local service_name=$(echo "${ports_in_use[$i]}" | awk '{print $2}')
# display the information nicely to the user
- echo -e " [${port_number}] is in use by ${service_name}" 2>&1 | tee -a "${DEBUG_LOG}"
+ log_write " [${port_number}] is in use by ${service_name}"
done
}
@@ -441,18 +464,18 @@ check_x_headers() {
# If the X-header found by curl matches what is should be,
if [[ $block_page == $block_page_working ]]; then
# display a success message
- echo -e " $TICK ${block_page}" 2>&1 | tee -a "${DEBUG_LOG}"
+ log_write " $TICK ${block_page}"
# Otherwise,
else
# show an error
- echo -e " $CROSS X-Header does not match or could not be retrieved" 2>&1 | tee -a "${DEBUG_LOG}"
+ log_write " $CROSS X-Header does not match or could not be retrieved"
fi
# Same logic applies to the dashbord as above
if [[ $dashboard == $dashboard_working ]]; then
- echo -e " $TICK ${dashboard}" 2>&1 | tee -a "${DEBUG_LOG}"
+ log_write " $TICK ${dashboard}"
else
- echo -e " $CROSS X-Header does not match or could not be retrieved" 2>&1 | tee -a "${DEBUG_LOG}"
+ log_write " $CROSS X-Header does not match or could not be retrieved"
fi
}
@@ -492,28 +515,28 @@ dig_at() {
# First do a dig on localhost, to see if Pi-hole can use itself to block a domain
if local_dig=$(dig -"${protocol}" "${random_url}" @${local_address} +short "${record_type}"); then
# If it can, show sucess
- echo -e " ${TICK} ${random_url} is ${local_dig} via localhost (${local_address})" 2>&1 | tee -a "${DEBUG_LOG}"
+ log_write " ${TICK} ${random_url} is ${local_dig} via localhost (${local_address})"
# Otherwise,
else
# show a failure
- echo -e " ${CROSS} Failed to resolve ${random_url} via localhot (${local_address})" 2>&1 | tee -a "${DEBUG_LOG}"
+ log_write " ${CROSS} Failed to resolve ${random_url} via localhot (${local_address})"
fi
# Next we need to check if Pi-hole can resolve a domain when the query is sent to it's IP address
# This better emulates how clients will interact with Pi-hole as opposed to above where Pi-hole is
# just asing itself locally
if pihole_dig=$(dig -"${protocol}" "${random_url}" @${pihole_address} +short "${record_type}"); then
- echo -e " ${TICK} ${random_url} is ${pihole_dig} via Pi-hole (${pihole_address})" 2>&1 | tee -a "${DEBUG_LOG}"
+ log_write " ${TICK} ${random_url} is ${pihole_dig} via Pi-hole (${pihole_address})"
else
- echo -e " ${CROSS} Failed to resolve ${random_url} via Pi-hole (${pihole_address})" 2>&1 | tee -a "${DEBUG_LOG}"
+ log_write " ${CROSS} Failed to resolve ${random_url} via Pi-hole (${pihole_address})"
fi
# Finally, we need to make sure legitimate sites can out if using an external, public DNS server
if remote_dig=$(dig -"${protocol}" "${remote_url}" @${remote_address} +short "${record_type}" | head -n1); then
# If successful, the real IP of the domain will be returned instead of Pi-hole's IP
- echo -e " ${TICK} ${random_url} is ${remote_dig} via a remote, public DNS server (${remote_address})" 2>&1 | tee -a "${DEBUG_LOG}"
+ log_write " ${TICK} ${random_url} is ${remote_dig} via a remote, public DNS server (${remote_address})"
else
- echo -e " ${CROSS} Failed to resolve ${random_url} via a remote, public DNS server (${remote_address})" 2>&1 | tee -a "${DEBUG_LOG}"
+ log_write " ${CROSS} Failed to resolve ${random_url} via a remote, public DNS server (${remote_address})"
fi
}
@@ -528,7 +551,7 @@ process_status(){
# get it's status
local status_of_process=$(systemctl is-active "${i}")
# and print it out to the user
- echo -e " [i] ${i} daemon is ${status_of_process}" 2>&1 | tee -a "${DEBUG_LOG}"
+ log_write " [i] ${i} daemon is ${status_of_process}"
done
}
@@ -545,7 +568,7 @@ parse_file() {
# For each lin in the file,
for file_lines in "${file_info[@]}"; do
# display the information with the ${INFO} icon
- echo -e " ${INFO} ${file_lines}" 2>&1 | tee -a "${DEBUG_LOG}"
+ log_write " ${INFO} ${file_lines}"
done
# Set the IFS back to what it was
IFS="$OLD_IFS"
@@ -559,7 +582,7 @@ diagnose_setup_variables() {
file_exists "${VARSFILE}" && \
# source it
source ${VARSFILE};
- echo -e " ${INFO} Sourcing ${VARSFILE}..." 2>&1 | tee -a "${DEBUG_LOG}";
+ log_write " ${INFO} Sourcing ${VARSFILE}...";
# and display a green check mark with ${DONE}
echo_succes_or_fail "${VARSFILE} is readable and has been sourced." || \
# Othwerwise, error out
@@ -605,7 +628,7 @@ list_files_in_dir() {
for each_file in "${files_found[@]}"; do
# display the information with the ${INFO} icon
# Also print the permissions and the user/group
- echo -e " ${INFO} ${each_file} ( $(ls -ld ${dir_to_parse}/${each_file} | awk '{print $1, $3, $4}') )" 2>&1 | tee -a "${DEBUG_LOG}"
+ log_write " ${INFO} ${each_file} ( $(ls -ld ${dir_to_parse}/${each_file} | awk '{print $1, $3, $4}') )"
done
}
@@ -649,9 +672,9 @@ check_http_directory() {
analyze_gravity_list() {
# It's helpful to know how big a user's gravity file is
gravity_length=$(grep -c ^ "${GRAVITYFILE}") && \
- echo -e " ${INFO} ${GRAVITYFILE} is ${gravity_length} lines long." 2>&1 | tee -a "${DEBUG_LOG}" || \
+ log_write " ${INFO} ${GRAVITYFILE} is ${gravity_length} lines long." || \
# If the previous command failed, something is wrong with the file
- echo -e " ${CROSS} ${GRAVITYFILE} not found!" 2>&1 | tee -a "${DEBUG_LOG}"
+ log_write " ${CROSS} ${GRAVITYFILE} not found!"
}
tricorder_nc_or_ssl() {
@@ -659,13 +682,13 @@ tricorder_nc_or_ssl() {
# Check fist for openssl since encryption is a good thing
if command -v openssl &> /dev/null; then
# If successful
- echo -e " ${INFO} Using openssl for transmission." 2>&1 | tee -a "${DEBUG_LOG}"
+ log_write " ${INFO} Using openssl for transmission."
# transmit the log and store the token returned in the tricorder variable
tricorder=$(cat /var/log/pihole_debug.log | openssl s_client -quiet -connect tricorder.pi-hole.net:9998 2> /dev/null)
# Otherwise,
else
# use net cat
- echo -e " ${INFO} Using netcat for transmission." 2>&1 | tee -a "${DEBUG_LOG}"
+ log_write " ${INFO} Using netcat for transmission."
tricorder=$(cat /var/log/pihole_debug.log | nc tricorder.pi-hole.net 9999)
fi
}
@@ -678,21 +701,21 @@ upload_to_tricorder() {
# Let the user know debugging is complete
echo ""
- echo -e "${TICK} Finshed debugging!" 2>&1 | tee -a "${DEBUG_LOG}"
+ log_write "${TICK} Finshed debugging!"
# Provide information on what they should do with their token
- echo -e " ${INFO} The debug log can be uploaded to tricorder.pi-hole.net for sharing with developers only."
- echo -e " For more information, see: https://pi-hole.net/2016/11/07/crack-our-medical-tricorder-win-a-raspberry-pi-3/"
+ log_write " ${INFO} The debug log can be uploaded to tricorder.pi-hole.net for sharing with developers only."
+ log_write " For more information, see: https://pi-hole.net/2016/11/07/crack-our-medical-tricorder-win-a-raspberry-pi-3/"
# If pihole -d is running automatically (usually throught the dashboard)
if [[ "${AUTOMATED}" ]]; then
# let the user know
- echo -e " ${INFO} Debug script running in automated mode" 2>&1 | tee -a "${DEBUG_LOG}"
+ log_write " ${INFO} Debug script running in automated mode"
# and then decide again which tool to use to submit it
if command -v openssl &> /dev/null; then
- echo -e " ${INFO} Using openssl for transmission." 2>&1 | tee -a "${DEBUG_LOG}"
+ log_write " ${INFO} Using openssl for transmission."
openssl s_client -quiet -connect tricorder.pi-hole.net:9998 2> /dev/null < /dev/stdin
else
- echo -e " ${INFO} Using netcat for transmission." 2>&1 | tee -a "${DEBUG_LOG}"
+ log_write " ${INFO} Using netcat for transmission."
nc tricorder.pi-hole.net 9999 < /dev/stdin
fi
else
@@ -704,30 +727,31 @@ upload_to_tricorder() {
# If they say yes, run our function for uploading the log
[yY][eE][sS]|[yY]) tricorder_nc_or_ssl;;
# If they choose no, just exit out of the script
- *) echo -e " ${INFO} Log will NOT be uploaded to tricorder.";exit;
+ *) log_write " ${INFO} Log will NOT be uploaded to tricorder.";exit;
esac
fi
# Check if tricorder.pi-hole.net is reachable and provide token
# along with some additional useful information
if [[ -n "${tricorder}" ]]; then
echo ""
- echo -e "${COL_LIGHT_PURPLE}***********************************${COL_NC}"
- echo -e "${TICK} Your debug token is: ${COL_LIGHT_GREEN}${tricorder}${COL_NC}"
- echo -e "${COL_LIGHT_PURPLE}***********************************${COL_NC}"
- echo -e ""
- echo -e " Provide this token to the Pi-hole team for assistance:"
+ log_write "${COL_LIGHT_PURPLE}***********************************${COL_NC}"
+ log_write "${TICK} Your debug token is: ${COL_LIGHT_GREEN}${tricorder}${COL_NC}"
+ log_write "${COL_LIGHT_PURPLE}***********************************${COL_NC}"
+ log_write ""
+ log_write " Provide this token to the Pi-hole team for assistance:"
echo ""
- echo -e " https://discourse.pi-hole.net"
+ log_write " https://discourse.pi-hole.net"
else
- echo -e " ${CROSS} There was an error uploading your debug log."
- echo -e " Please try again or contact the Pi-hole team for assistance."
+ log_write " ${CROSS} There was an error uploading your debug log."
+ log_write " Please try again or contact the Pi-hole team for assistance."
fi
echo ""
- echo -e " A local copy of the debug log can be found at : /var/log/pihole_debug.log"
+ log_write " A local copy of the debug log can be found at : /var/log/pihole_debug.log"
echo ""
}
# Run through all the functions we made
+make_temporary_log
initiate_debug
check_core_version
check_web_version
@@ -746,4 +770,5 @@ check_dnsmasq_d
check_lighttpd_d
check_http_directory
check_cron_d
+copy_to_debug_log
upload_to_tricorder
From ef5a6e7880901ed0c6d9aef4cf658f12fa04aa2c Mon Sep 17 00:00:00 2001
From: Jacob Salmela
Date: Fri, 26 May 2017 14:26:02 -0500
Subject: [PATCH 049/162] add faq urls to some functions, added more colors,
also use a static url for remote digs
---
advanced/Scripts/piholeDebug.sh | 103 +++++++++++++++++++++++++-------
1 file changed, 81 insertions(+), 22 deletions(-)
diff --git a/advanced/Scripts/piholeDebug.sh b/advanced/Scripts/piholeDebug.sh
index a9efcbbc..5691b6af 100755
--- a/advanced/Scripts/piholeDebug.sh
+++ b/advanced/Scripts/piholeDebug.sh
@@ -16,7 +16,7 @@
# that return code will be used as the return code of the whole pipeline. By default, the
# pipeline's return code is that of the last command - even if it succeeds
set -o pipefail
-IFS=$'\n\t'
+#IFS=$'\n\t'
######## GLOBAL VARS ########
VARSFILE="/etc/pihole/setupVars.conf"
@@ -67,6 +67,7 @@ log_write() {
}
copy_to_debug_log() {
+ # Copy the contents of file descriptor 3 into the debug log so it can be uploaded to tricorder
cat /proc/$$/fd/3 >> "${DEBUG_LOG}"
}
@@ -146,9 +147,21 @@ check_core_version() {
# The commit they are on
PI_HOLE_COMMIT=$(git describe --long --dirty --tags --always)
# echo this information out to the user in a nice format
- log_write " ${INFO} Core: ${PI_HOLE_VERSION}
- ${INFO} Branch: ${PI_HOLE_BRANCH}
- ${INFO} Commit: ${PI_HOLE_COMMIT}"
+ # If the current version matches what pihole -v produces, the user is up-to-date
+ if [[ "${PI_HOLE_VERSION}" == "$(pihole -v | awk '/Pi-hole/ {print $6}' | cut -d ')' -f1)" ]]; then
+ log_write " ${TICK} Core: ${COL_LIGHT_GREEN}${PI_HOLE_VERSION}${COL_NC}"
+ # If not,
+ else
+ # pring the current version in yellow
+ log_write " ${INFO} Core: ${COL_YELLOW}${PI_HOLE_VERSION:-Untagged}${COL_NC} (See ${COL_CYAN}https://discourse.pi-hole.net/t/how-do-i-update-pi-hole/249${COL_NC} on how to update Pi-hole)"
+ fi
+
+ if [[ "${PI_HOLE_BRANCH}" == "master" ]]; then
+ log_write " ${INFO} Branch: ${COL_LIGHT_GREEN}${PI_HOLE_BRANCH}${COL_NC}"
+ else
+ log_write " ${INFO} Branch: ${COL_YELLOW}${PI_HOLE_BRANCH:-Detached}${COL_NC} (See ${COL_CYAN}https://discourse.pi-hole.net/t/the-pihole-command-with-examples/738#checkout${COL_NC} for more information)"
+ fi
+ log_write " ${INFO} Commit: ${PI_HOLE_COMMIT}"
# If git status failed,
else
# Return an error message
@@ -177,9 +190,18 @@ check_web_version() {
# The commit they are on
WEB_COMMIT=$(git describe --long --dirty --tags --always)
# echo this information out to the user in a nice format
- log_write " ${INFO} Web: ${WEB_VERSION}
- ${INFO} Branch: ${WEB_BRANCH}
- ${INFO} Commit: ${WEB_COMMIT}"
+ if [[ "${WEB_VERSION}" == "$(pihole -v | awk '/AdminLTE/ {print $6}' | cut -d ')' -f1)" ]]; then
+ log_write " ${TICK} Web: ${COL_LIGHT_GREEN}${WEB_VERSION}${COL_NC}"
+ else
+ log_write " ${INFO} Web: ${COL_YELLOW}${WEB_VERSION:-Untagged}${COL_NC} (See ${COL_CYAN}https://discourse.pi-hole.net/t/how-do-i-update-pi-hole/249${COL_NC} on how to update Pi-hole)"
+ fi
+
+ if [[ "${WEB_BRANCH}" == "master" ]]; then
+ log_write " ${TICK} Branch: ${COL_LIGHT_GREEN}${WEB_BRANCH}${COL_NC}"
+ else
+ log_write " ${INFO} Branch: ${COL_YELLOW}${WEB_BRANCH:-Detached}${COL_NC} (See ${COL_CYAN}https://discourse.pi-hole.net/t/the-pihole-command-with-examples/738#checkout${COL_NC} for more information)"
+ fi
+ log_write " ${INFO} Commit: ${WEB_COMMIT}"
# If git status failed,
else
# Return an error message
@@ -216,7 +238,7 @@ check_web_server_version() {
}
# Check the current version of the DNS server
-check_resolver_version() {
+check_resolver_server_version() {
# Store the name in a variable in case we ever want to change it
RESOLVER="dnsmasq"
# Parse out just the version number
@@ -256,7 +278,7 @@ check_php_version() {
check_critical_dependencies() {
echo_current_diagnostic "Versions of critical dependencies"
check_web_server_version
- check_web_server_version
+ check_resolver_server_version
check_php_version
}
@@ -428,14 +450,45 @@ check_required_ports() {
# Sort the addresses and remove duplicates
while IFS= read -r line; do
ports_in_use+=( "$line" )
- done < <( lsof -i -P -n | awk -F' ' '/LISTEN/ {print $9, $1}' | sort | uniq | cut -d':' -f2 )
+ done < <( lsof -i -P -n | awk -F' ' '/LISTEN/ {print $9, $1}' | sort -n | uniq | cut -d':' -f2 )
# Now that we have the values stored,
for i in ${!ports_in_use[@]}; do
local port_number="$(echo "${ports_in_use[$i]}" | awk '{print $1}')"
local service_name=$(echo "${ports_in_use[$i]}" | awk '{print $2}')
- # display the information nicely to the user
- log_write " [${port_number}] is in use by ${service_name}"
+ case "${port_number}" in
+ 53) if [[ "${service_name}" == "dnsmasq" ]]; then
+ # if port 53 is dnsmasq, show it in green as it's standard
+ log_write " [${COL_LIGHT_GREEN}${port_number}${COL_NC}] is in use by ${COL_LIGHT_GREEN}${service_name}${COL_NC}"
+ # Otherwise,
+ else
+ # Show the service name in red since it's non-standard
+ log_write " [${COL_LIGHT_RED}${port_number}${COL_NC}] is in use by ${COL_LIGHT_RED}${service_name}${COL_NC}
+ Please see: ${COL_CYAN}https://discourse.pi-hole.net/t/hardware-software-requirements/273#ports${COL_NC}"
+ fi
+ ;;
+ 80) if [[ "${service_name}" == "lighttpd" ]]; then
+ # if port 53 is dnsmasq, show it in green as it's standard
+ log_write " [${COL_LIGHT_GREEN}${port_number}${COL_NC}] is in use by ${COL_LIGHT_GREEN}${service_name}${COL_NC}"
+ # Otherwise,
+ else
+ # Show the service name in red since it's non-standard
+ log_write " [${COL_LIGHT_RED}${port_number}${COL_NC}] is in use by ${COL_LIGHT_RED}${service_name}${COL_NC}
+ Please see: ${COL_CYAN}https://discourse.pi-hole.net/t/hardware-software-requirements/273#ports${COL_NC}"
+ fi
+ ;;
+ 4711) if [[ "${service_name}" == "pihole-FT" ]]; then
+ # if port 4711 is pihole-FTL, show it in green as it's standard
+ log_write " [${COL_LIGHT_GREEN}${port_number}${COL_NC}] is in use by ${COL_LIGHT_GREEN}${service_name}${COL_NC}"
+ # Otherwise,
+ else
+ # Show the service name in yellow since it's non-standard, but should still work
+ log_write " [${COL_YELLOW}${port_number}${COL_NC}] is in use by ${COL_YELLOW}${service_name}${COL_NC}
+ Please see: ${COL_CYAN}https://discourse.pi-hole.net/t/hardware-software-requirements/273#ports${COL_NC}"
+ fi
+ ;;
+ *) log_write " [${port_number}] is in use by ${service_name}";
+ esac
done
}
@@ -492,6 +545,8 @@ dig_at() {
local local_dig
local pihole_dig
local remote_dig
+ # Use a static domain that we know has IPv4 and IPv6 to avoid false positives
+ local remote_url="doubleclick.com"
# If the protocol (4 or 6) is 6,
if [[ ${protocol} == "6" ]]; then
@@ -519,7 +574,7 @@ dig_at() {
# Otherwise,
else
# show a failure
- log_write " ${CROSS} Failed to resolve ${random_url} via localhot (${local_address})"
+ log_write " ${CROSS} Failed to resolve ${random_url} via localhost (${local_address})"
fi
# Next we need to check if Pi-hole can resolve a domain when the query is sent to it's IP address
@@ -534,9 +589,9 @@ dig_at() {
# Finally, we need to make sure legitimate sites can out if using an external, public DNS server
if remote_dig=$(dig -"${protocol}" "${remote_url}" @${remote_address} +short "${record_type}" | head -n1); then
# If successful, the real IP of the domain will be returned instead of Pi-hole's IP
- log_write " ${TICK} ${random_url} is ${remote_dig} via a remote, public DNS server (${remote_address})"
+ log_write " ${TICK} ${remote_url} is ${remote_dig} via a remote, public DNS server (${remote_address})"
else
- log_write " ${CROSS} Failed to resolve ${random_url} via a remote, public DNS server (${remote_address})"
+ log_write " ${CROSS} Failed to resolve ${remote_url} via a remote, public DNS server (${remote_address})"
fi
}
@@ -551,7 +606,11 @@ process_status(){
# get it's status
local status_of_process=$(systemctl is-active "${i}")
# and print it out to the user
- log_write " [i] ${i} daemon is ${status_of_process}"
+ if [[ "${status_of_process}" == "active" ]]; then
+ log_write " ${TICK} ${COL_LIGHT_GREEN}${i}${COL_NC} daemon is ${COL_LIGHT_GREEN}${status_of_process}${COL_NC}"
+ else
+ log_write " ${TICK} ${COL_LIGHT_RED}${i}${COL_NC} daemon is ${COL_LIGHT_RED}${status_of_process}${COL_NC}"
+ fi
done
}
@@ -628,7 +687,7 @@ list_files_in_dir() {
for each_file in "${files_found[@]}"; do
# display the information with the ${INFO} icon
# Also print the permissions and the user/group
- log_write " ${INFO} ${each_file} ( $(ls -ld ${dir_to_parse}/${each_file} | awk '{print $1, $3, $4}') )"
+ log_write " ${INFO} $(ls -ld ${dir_to_parse}/${each_file})"
done
}
@@ -682,7 +741,7 @@ tricorder_nc_or_ssl() {
# Check fist for openssl since encryption is a good thing
if command -v openssl &> /dev/null; then
# If successful
- log_write " ${INFO} Using openssl for transmission."
+ log_write " * Using openssl for transmission."
# transmit the log and store the token returned in the tricorder variable
tricorder=$(cat /var/log/pihole_debug.log | openssl s_client -quiet -connect tricorder.pi-hole.net:9998 2> /dev/null)
# Otherwise,
@@ -701,11 +760,11 @@ upload_to_tricorder() {
# Let the user know debugging is complete
echo ""
- log_write "${TICK} Finshed debugging!"
+ log_write "${TICK} Finished debugging!"
# Provide information on what they should do with their token
- log_write " ${INFO} The debug log can be uploaded to tricorder.pi-hole.net for sharing with developers only."
- log_write " For more information, see: https://pi-hole.net/2016/11/07/crack-our-medical-tricorder-win-a-raspberry-pi-3/"
+ log_write " * The debug log can be uploaded to tricorder.pi-hole.net for sharing with developers only."
+ log_write " * For more information, see: https://pi-hole.net/2016/11/07/crack-our-medical-tricorder-win-a-raspberry-pi-3/"
# If pihole -d is running automatically (usually throught the dashboard)
if [[ "${AUTOMATED}" ]]; then
# let the user know
@@ -746,7 +805,7 @@ upload_to_tricorder() {
log_write " Please try again or contact the Pi-hole team for assistance."
fi
echo ""
- log_write " A local copy of the debug log can be found at : /var/log/pihole_debug.log"
+ log_write " A local copy of the debug log can be found at : /var/log/pihole_debug.log"
echo ""
}
From 7873da1ae57c61fb330d7128d85bfbfb37cce4bf Mon Sep 17 00:00:00 2001
From: Jacob Salmela
Date: Fri, 26 May 2017 15:17:26 -0500
Subject: [PATCH 050/162] more colors. shortened dig timeouts
---
advanced/Scripts/piholeDebug.sh | 74 ++++++++++++++++-----------------
1 file changed, 35 insertions(+), 39 deletions(-)
diff --git a/advanced/Scripts/piholeDebug.sh b/advanced/Scripts/piholeDebug.sh
index 5691b6af..66c2ebef 100755
--- a/advanced/Scripts/piholeDebug.sh
+++ b/advanced/Scripts/piholeDebug.sh
@@ -153,13 +153,13 @@ check_core_version() {
# If not,
else
# pring the current version in yellow
- log_write " ${INFO} Core: ${COL_YELLOW}${PI_HOLE_VERSION:-Untagged}${COL_NC} (See ${COL_CYAN}https://discourse.pi-hole.net/t/how-do-i-update-pi-hole/249${COL_NC} on how to update Pi-hole)"
+ log_write " ${INFO} Core: ${COL_YELLOW}${PI_HOLE_VERSION:-Untagged}${COL_NC} (${COL_CYAN}https://discourse.pi-hole.net/t/how-do-i-update-pi-hole/249${COL_NC})"
fi
if [[ "${PI_HOLE_BRANCH}" == "master" ]]; then
log_write " ${INFO} Branch: ${COL_LIGHT_GREEN}${PI_HOLE_BRANCH}${COL_NC}"
else
- log_write " ${INFO} Branch: ${COL_YELLOW}${PI_HOLE_BRANCH:-Detached}${COL_NC} (See ${COL_CYAN}https://discourse.pi-hole.net/t/the-pihole-command-with-examples/738#checkout${COL_NC} for more information)"
+ log_write " ${INFO} Branch: ${COL_YELLOW}${PI_HOLE_BRANCH:-Detached}${COL_NC} (${COL_CYAN}https://discourse.pi-hole.net/t/the-pihole-command-with-examples/738#checkout${COL_NC})"
fi
log_write " ${INFO} Commit: ${PI_HOLE_COMMIT}"
# If git status failed,
@@ -193,13 +193,13 @@ check_web_version() {
if [[ "${WEB_VERSION}" == "$(pihole -v | awk '/AdminLTE/ {print $6}' | cut -d ')' -f1)" ]]; then
log_write " ${TICK} Web: ${COL_LIGHT_GREEN}${WEB_VERSION}${COL_NC}"
else
- log_write " ${INFO} Web: ${COL_YELLOW}${WEB_VERSION:-Untagged}${COL_NC} (See ${COL_CYAN}https://discourse.pi-hole.net/t/how-do-i-update-pi-hole/249${COL_NC} on how to update Pi-hole)"
+ log_write " ${INFO} Web: ${COL_YELLOW}${WEB_VERSION:-Untagged}${COL_NC} (${COL_CYAN}https://discourse.pi-hole.net/t/how-do-i-update-pi-hole/249${COL_NC})"
fi
if [[ "${WEB_BRANCH}" == "master" ]]; then
log_write " ${TICK} Branch: ${COL_LIGHT_GREEN}${WEB_BRANCH}${COL_NC}"
else
- log_write " ${INFO} Branch: ${COL_YELLOW}${WEB_BRANCH:-Detached}${COL_NC} (See ${COL_CYAN}https://discourse.pi-hole.net/t/the-pihole-command-with-examples/738#checkout${COL_NC} for more information)"
+ log_write " ${INFO} Branch: ${COL_YELLOW}${WEB_BRANCH:-Detached}${COL_NC} (${COL_CYAN}https://discourse.pi-hole.net/t/the-pihole-command-with-examples/738#checkout${COL_NC})"
fi
log_write " ${INFO} Commit: ${WEB_COMMIT}"
# If git status failed,
@@ -224,16 +224,14 @@ check_web_server_version() {
WEB_SERVER="lighttpd"
# Parse out just the version number
WEB_SERVER_VERSON="$(lighttpd -v |& head -n1 | cut -d '/' -f2 | cut -d ' ' -f1)"
- # Display the information to the user
- log_write " ${INFO} ${WEB_SERVER}"
# If the Web server does not have a version (the variable is empty)
if [[ -z "${WEB_SERVER_VERSON}" ]]; then
# Display and error
- log_write " ${CROSS} ${WEB_SERVER} version could not be detected."
+ log_write " ${CROSS} ${WEB_SERVER} version could not be detected."
# Otherwise,
else
# display the version
- log_write " ${TICK} ${WEB_SERVER_VERSON}"
+ log_write " ${TICK} ${WEB_SERVER}: ${WEB_SERVER_VERSON}"
fi
}
@@ -243,32 +241,28 @@ check_resolver_server_version() {
RESOLVER="dnsmasq"
# Parse out just the version number
RESOVLER_VERSON="$(dnsmasq -v |& head -n1 | awk '{print $3}')"
- # Display the information to the user
- log_write " ${INFO} ${RESOLVER}"
# If the DNS server does not have a version (the variable is empty)
if [[ -z "${RESOVLER_VERSON}" ]]; then
# Display and error
- log_write " ${CROSS} ${RESOLVER} version could not be detected."
+ log_write " ${CROSS} ${RESOLVER} version could not be detected."
# Otherwise,
else
# display the version
- log_write " ${TICK} ${RESOVLER_VERSON}"
+ log_write " ${TICK} ${RESOLVER}: ${RESOVLER_VERSON}"
fi
}
check_php_version() {
# Parse out just the version number
PHP_VERSION=$(php -v |& head -n1 | cut -d '-' -f1 | cut -d ' ' -f2)
- # Display the info to the user
- log_write " ${INFO} PHP"
# If no version is detected,
if [[ -z "${PHP_VERSION}" ]]; then
# show an error
- log_write " ${CROSS} PHP version could not be detected."
+ log_write " ${CROSS} PHP version could not be detected."
# otherwise,
else
# Show the version
- log_write " ${TICK} ${PHP_VERSION}"
+ log_write " ${TICK} PHP: ${PHP_VERSION}"
fi
}
@@ -392,19 +386,19 @@ ping_gateway() {
# If the gateway variable has a value (meaning a gateway was found),
if [[ -n "${gateway}" ]]; then
# Let the user know we will ping the gateway for a response
- log_write " ${INFO} Trying three pings on IPv${protocol} gateway at ${gateway}..."
+ log_write " * Trying three pings on IPv${protocol} gateway at ${gateway}..."
# Try to quietly ping the gateway 3 times, with a timeout of 3 seconds, using numeric output only,
# on the pihole interface, and tail the last three lines of the output
# If pinging the gateway is not successful,
if ! ping_cmd="$(${cmd} -q -c 3 -W 3 -n ${gateway} -I ${PIHOLE_INTERFACE} | tail -n 3)"; then
# let the user know
- log_write " ${CROSS} Gateway did not respond."
+ log_write " ${CROSS} ${COL_LIGHT_RED}Gateway did not respond.${COL_NC}"
# and return an error code
return 1
# Otherwise,
else
# show a success
- log_write " ${TICK} Gateway responded."
+ log_write " ${TICK} ${COL_LIGHT_GREEN}Gateway responded.${COL_NC}"
# and return a success code
return 0
fi
@@ -517,18 +511,18 @@ check_x_headers() {
# 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}"
+ log_write " $TICK ${COL_LIGHT_GREEN}${block_page}${COL_NC}"
# Otherwise,
else
# show an error
- log_write " $CROSS X-Header does not match or could not be retrieved"
+ log_write " $CROSS ${COL_LIGHT_RED}X-Header does not match or could not be retrieved.${COL_NC}"
fi
# Same logic applies to the dashbord as above
if [[ $dashboard == $dashboard_working ]]; then
- log_write " $TICK ${dashboard}"
+ log_write " $TICK ${COL_LIGHT_GREEN}${dashboard}${COL_NC}"
else
- log_write " $CROSS X-Header does not match or could not be retrieved"
+ log_write " $CROSS ${COL_LIGHT_RED}X-Header does not match or could not be retrieved.${COL_NC}"
fi
}
@@ -568,30 +562,30 @@ dig_at() {
local random_url=$(shuf -n 1 "${GRAVITYFILE}" | awk -F ' ' '{ print $2 }')
# First do a dig on localhost, to see if Pi-hole can use itself to block a domain
- if local_dig=$(dig -"${protocol}" "${random_url}" @${local_address} +short "${record_type}"); then
+ if local_dig=$(dig +tries=1 +time=2 -"${protocol}" "${random_url}" @${local_address} +short "${record_type}"); then
# If it can, show sucess
- log_write " ${TICK} ${random_url} is ${local_dig} via localhost (${local_address})"
+ log_write " ${TICK} ${COL_LIGHT_GREEN}${random_url} is ${local_dig}${COL_NC} via localhost (${local_address})"
# Otherwise,
else
# show a failure
- log_write " ${CROSS} Failed to resolve ${random_url} via localhost (${local_address})"
+ log_write " ${CROSS} ${COL_LIGHT_RED}Failed to resolve${COL_NC} ${random_url} ${COL_LIGHT_RED}via localhost${COL_NC} (${local_address})"
fi
# Next we need to check if Pi-hole can resolve a domain when the query is sent to it's IP address
# This better emulates how clients will interact with Pi-hole as opposed to above where Pi-hole is
# just asing itself locally
- if pihole_dig=$(dig -"${protocol}" "${random_url}" @${pihole_address} +short "${record_type}"); then
- log_write " ${TICK} ${random_url} is ${pihole_dig} via Pi-hole (${pihole_address})"
+ if pihole_dig=$(dig +tries=1 +time=2 -"${protocol}" "${random_url}" @${pihole_address} +short "${record_type}"); then
+ log_write " ${TICK} ${COL_LIGHT_GREEN}${random_url} is ${pihole_dig}${COL_NC} via Pi-hole (${pihole_address})"
else
- log_write " ${CROSS} Failed to resolve ${random_url} via Pi-hole (${pihole_address})"
+ log_write " ${CROSS} ${COL_LIGHT_RED}Failed to resolve${COL_NC} ${random_url} ${COL_LIGHT_RED}via Pi-hole${COL_NC} (${pihole_address})"
fi
# Finally, we need to make sure legitimate sites can out if using an external, public DNS server
- if remote_dig=$(dig -"${protocol}" "${remote_url}" @${remote_address} +short "${record_type}" | head -n1); then
+ if remote_dig=$(dig +tries=1 +time=2 -"${protocol}" "${remote_url}" @${remote_address} +short "${record_type}" | head -n1); then
# If successful, the real IP of the domain will be returned instead of Pi-hole's IP
- log_write " ${TICK} ${remote_url} is ${remote_dig} via a remote, public DNS server (${remote_address})"
+ log_write " ${TICK} ${COL_LIGHT_GREEN}${remote_url} is ${remote_dig}${COL_NC} via a remote, public DNS server (${remote_address})"
else
- log_write " ${CROSS} Failed to resolve ${remote_url} via a remote, public DNS server (${remote_address})"
+ log_write " ${CROSS} ${COL_LIGHT_RED}Failed to resolve${COL_NC} ${remote_url} ${COL_LIGHT_RED}via a remote, public DNS server${COL_NC} (${remote_address})"
fi
}
@@ -609,7 +603,7 @@ process_status(){
if [[ "${status_of_process}" == "active" ]]; then
log_write " ${TICK} ${COL_LIGHT_GREEN}${i}${COL_NC} daemon is ${COL_LIGHT_GREEN}${status_of_process}${COL_NC}"
else
- log_write " ${TICK} ${COL_LIGHT_RED}${i}${COL_NC} daemon is ${COL_LIGHT_RED}${status_of_process}${COL_NC}"
+ log_write " ${CROSS} ${COL_LIGHT_RED}${i}${COL_NC} daemon is ${COL_LIGHT_RED}${status_of_process}${COL_NC}"
fi
done
}
@@ -741,13 +735,13 @@ tricorder_nc_or_ssl() {
# Check fist for openssl since encryption is a good thing
if command -v openssl &> /dev/null; then
# If successful
- log_write " * Using openssl for transmission."
+ log_write " * Using ${COL_LIGHT_GREEN}openssl${COL_NC} for transmission."
# transmit the log and store the token returned in the tricorder variable
tricorder=$(cat /var/log/pihole_debug.log | openssl s_client -quiet -connect tricorder.pi-hole.net:9998 2> /dev/null)
# Otherwise,
else
# use net cat
- log_write " ${INFO} Using netcat for transmission."
+ log_write " ${INFO} Using ${COL_YELLOW}netcat${COL_NC} for transmission."
tricorder=$(cat /var/log/pihole_debug.log | nc tricorder.pi-hole.net 9999)
fi
}
@@ -764,17 +758,19 @@ upload_to_tricorder() {
# Provide information on what they should do with their token
log_write " * The debug log can be uploaded to tricorder.pi-hole.net for sharing with developers only."
- log_write " * For more information, see: https://pi-hole.net/2016/11/07/crack-our-medical-tricorder-win-a-raspberry-pi-3/"
+ log_write " * For more information, see: ${COL_CYAN}https://pi-hole.net/2016/11/07/crack-our-medical-tricorder-win-a-raspberry-pi-3/${COL_NC}"
+ log_write ""
+ log_write " * If available, we'll use openssl to upload the log, otherwise it will fall back to netcat."
# If pihole -d is running automatically (usually throught the dashboard)
if [[ "${AUTOMATED}" ]]; then
# let the user know
log_write " ${INFO} Debug script running in automated mode"
# and then decide again which tool to use to submit it
if command -v openssl &> /dev/null; then
- log_write " ${INFO} Using openssl for transmission."
+ log_write " ${INFO} Using ${COL_LIGHT_GREEN}openssl${COL_NC} for transmission."
openssl s_client -quiet -connect tricorder.pi-hole.net:9998 2> /dev/null < /dev/stdin
else
- log_write " ${INFO} Using netcat for transmission."
+ log_write " ${INFO} Using ${COL_YELLOW}netcat${COL_NC} for transmission."
nc tricorder.pi-hole.net 9999 < /dev/stdin
fi
else
@@ -786,7 +782,7 @@ upload_to_tricorder() {
# If they say yes, run our function for uploading the log
[yY][eE][sS]|[yY]) tricorder_nc_or_ssl;;
# If they choose no, just exit out of the script
- *) log_write " ${INFO} Log will NOT be uploaded to tricorder.";exit;
+ *) log_write " * Log will NOT be uploaded to tricorder.";exit;
esac
fi
# Check if tricorder.pi-hole.net is reachable and provide token
From 7ec169ab10fb5e99eeb8a0c0905acae9c10dc861 Mon Sep 17 00:00:00 2001
From: Jacob Salmela
Date: Fri, 26 May 2017 22:05:50 -0500
Subject: [PATCH 051/162] more comments, fixed automated tricorder,
variablizing echos, verify FTL version
---
advanced/Scripts/piholeDebug.sh | 196 +++++++++++++++++++-------------
1 file changed, 118 insertions(+), 78 deletions(-)
diff --git a/advanced/Scripts/piholeDebug.sh b/advanced/Scripts/piholeDebug.sh
index 66c2ebef..af9802a9 100755
--- a/advanced/Scripts/piholeDebug.sh
+++ b/advanced/Scripts/piholeDebug.sh
@@ -36,6 +36,10 @@ WHITELISTMATCHES="/tmp/whitelistmatches.list"
readonly FTLLOG="/var/log/pihole-FTL.log"
coltable=/opt/pihole/COL_TABLE
+# FAQ URLs
+FAQ_UPDATE_PI_HOLE="https://discourse.pi-hole.net/t/how-do-i-update-pi-hole/249"
+FAQ_CHECKOUT_COMMAND="https://discourse.pi-hole.net/t/the-pihole-command-with-examples/738#checkout"
+
# These provide the colors we need for making the log more readable
if [[ -f ${coltable} ]]; then
source ${coltable}
@@ -87,7 +91,8 @@ echo_succes_or_fail() {
initiate_debug() {
# Clear the screen so the debug log is readable
clear
- log_write "${COL_LIGHT_PURPLE}*** [ INITIALIZING ]${COL_NC}" 2>&1 | tee "${DEBUG_LOG}"
+ # Display that the debug process is beginning
+ log_write "${COL_LIGHT_PURPLE}*** [ INITIALIZING ]${COL_NC}"
# Timestamp the start of the log
log_write " ${INFO} $(date "+%Y-%m-%d:%H:%M:%S") debug log has been initiated."
}
@@ -97,6 +102,7 @@ initiate_debug() {
# Colors do not show in the dasboard, but the icons do: [i], [✓], and [✗]
echo_current_diagnostic() {
# Colors are used for visually distinguishing each test in the output
+ # These colors do not show in the GUI, but the formatting will
log_write "\n${COL_LIGHT_PURPLE}*** [ DIAGNOSING ]:${COL_NC} ${1}"
}
@@ -126,9 +132,9 @@ if_directory_exists() {
fi
}
+# Checks the core version of the Pi-hole codebase
check_core_version() {
- # Checks the core version of the Pi-hole codebase
- echo_current_diagnostic "Pi-hole Versions"
+ echo_current_diagnostic "Pi-hole versions"
# Store the error message in a variable in case we want to change and/or reuse it
local error_msg="git status failed"
# If the pihole git directory exists,
@@ -152,15 +158,21 @@ check_core_version() {
log_write " ${TICK} Core: ${COL_LIGHT_GREEN}${PI_HOLE_VERSION}${COL_NC}"
# If not,
else
- # pring the current version in yellow
- log_write " ${INFO} Core: ${COL_YELLOW}${PI_HOLE_VERSION:-Untagged}${COL_NC} (${COL_CYAN}https://discourse.pi-hole.net/t/how-do-i-update-pi-hole/249${COL_NC})"
+ # echo the current version in yellow, signifying it's something to take a look at, but not a critical error
+ # Also add a URL to an FAQ
+ log_write " ${INFO} Core: ${COL_YELLOW}${PI_HOLE_VERSION:-Untagged}${COL_NC} (${COL_CYAN}${FAQ_UPDATE_PI_HOLE}${COL_NC})"
fi
+ # If the repo is on the master branch, they are on the stable codebase
if [[ "${PI_HOLE_BRANCH}" == "master" ]]; then
+ # so the color of the text is green
log_write " ${INFO} Branch: ${COL_LIGHT_GREEN}${PI_HOLE_BRANCH}${COL_NC}"
+ # If it is any other branch, they are in a developement branch
else
- log_write " ${INFO} Branch: ${COL_YELLOW}${PI_HOLE_BRANCH:-Detached}${COL_NC} (${COL_CYAN}https://discourse.pi-hole.net/t/the-pihole-command-with-examples/738#checkout${COL_NC})"
+ # 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}${PI_HOLE_BRANCH:-Detached}${COL_NC} (${COL_CYAN}${FAQ_CHECKOUT_COMMAND}${COL_NC})"
fi
+ # echo the current commit
log_write " ${INFO} Commit: ${PI_HOLE_COMMIT}"
# If git status failed,
else
@@ -189,18 +201,27 @@ check_web_version() {
WEB_BRANCH=$(git rev-parse --abbrev-ref HEAD);
# The commit they are on
WEB_COMMIT=$(git describe --long --dirty --tags --always)
- # echo this information out to the user in a nice format
+ # If the Web version reported by pihole -v matches the current version
if [[ "${WEB_VERSION}" == "$(pihole -v | awk '/AdminLTE/ {print $6}' | cut -d ')' -f1)" ]]; then
+ # echo it in green
log_write " ${TICK} Web: ${COL_LIGHT_GREEN}${WEB_VERSION}${COL_NC}"
+ # Otherwise,
else
- log_write " ${INFO} Web: ${COL_YELLOW}${WEB_VERSION:-Untagged}${COL_NC} (${COL_CYAN}https://discourse.pi-hole.net/t/how-do-i-update-pi-hole/249${COL_NC})"
+ # Show it in yellow with a link to update Pi-hole
+ log_write " ${INFO} Web: ${COL_YELLOW}${WEB_VERSION:-Untagged}${COL_NC} (${COL_CYAN}${FAQ_UPDATE_PI_HOLE}${COL_NC})"
fi
+
+ # If the repo is on the master branch, they are on the stable codebase
if [[ "${WEB_BRANCH}" == "master" ]]; then
+ # so the color of the text is green
log_write " ${TICK} Branch: ${COL_LIGHT_GREEN}${WEB_BRANCH}${COL_NC}"
else
- log_write " ${INFO} Branch: ${COL_YELLOW}${WEB_BRANCH:-Detached}${COL_NC} (${COL_CYAN}https://discourse.pi-hole.net/t/the-pihole-command-with-examples/738#checkout${COL_NC})"
+ # If it is any other branch, they are in a developement branch
+ # 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}${WEB_BRANCH:-Detached}${COL_NC} (${COL_CYAN}${FAQ_CHECKOUT_COMMAND}${COL_NC})"
fi
+ # echo the current commit
log_write " ${INFO} Commit: ${WEB_COMMIT}"
# If git status failed,
else
@@ -214,8 +235,14 @@ check_web_version() {
check_ftl_version() {
# Use the built in command to check FTL's version
FTL_VERSION=$(pihole-FTL version)
- # and display it to the user
- log_write " ${INFO} FTL: ${FTL_VERSION}"
+ # 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: ${COL_LIGHT_GREEN}${FTL_VERSION}${COL_NC}"
+ else
+ # If not, show it in yellow, signifying there is an update
+ log_write " ${TICK} FTL: ${COL_YELLOW}${FTL_VERSION}${COL_NC}"
+ fi
}
# Check the current version of the Web server
@@ -227,10 +254,9 @@ check_web_server_version() {
# If the Web server does not have a version (the variable is empty)
if [[ -z "${WEB_SERVER_VERSON}" ]]; then
# Display and error
- log_write " ${CROSS} ${WEB_SERVER} version could not be detected."
- # Otherwise,
+ log_write " ${CROSS} ${COL_LIGHT_RED}${WEB_SERVER} version could not be detected.${COL_NC}"
else
- # display the version
+ # Otherwise, display the version
log_write " ${TICK} ${WEB_SERVER}: ${WEB_SERVER_VERSON}"
fi
}
@@ -244,10 +270,9 @@ check_resolver_server_version() {
# If the DNS server does not have a version (the variable is empty)
if [[ -z "${RESOVLER_VERSON}" ]]; then
# Display and error
- log_write " ${CROSS} ${RESOLVER} version could not be detected."
- # Otherwise,
+ log_write " ${CROSS} ${COL_LIGHT_RED}${RESOLVER} version could not be detected.${COL_NC}"
else
- # display the version
+ # Otherwise, display the version
log_write " ${TICK} ${RESOLVER}: ${RESOVLER_VERSON}"
fi
}
@@ -258,19 +283,18 @@ check_php_version() {
# If no version is detected,
if [[ -z "${PHP_VERSION}" ]]; then
# show an error
- log_write " ${CROSS} PHP version could not be detected."
- # otherwise,
+ log_write " ${CROSS} ${COL_LIGHT_RED}PHP version could not be detected.${COL_NC}"
else
- # Show the version
+ # Otherwise, show the version
log_write " ${TICK} PHP: ${PHP_VERSION}"
fi
-
}
# These are the most critical dependencies of Pi-hole, so we check for them
# and their versions, using the functions above.
check_critical_dependencies() {
echo_current_diagnostic "Versions of critical dependencies"
+ # Use the function created earlier and bundle them into one function that checks all the version numbers
check_web_server_version
check_resolver_server_version
check_php_version
@@ -287,14 +311,16 @@ get_distro_attributes() {
local distro_attribute
# For each line found in an /etc/*release file,
for distro_attribute in "${distro_info[@]}"; do
- # display the information with the ${INFO} icon
- pretty_name_key=$(echo "${distro_attribute}" | grep "PRETTY_NAME" | cut -d '=' -f1)
- # we need just the OS PRETTY_NAME, so print it when we find it
+ # store the key in a variable
+ local pretty_name_key=$(echo "${distro_attribute}" | grep "PRETTY_NAME" | cut -d '=' -f1)
+ # we need just the OS PRETTY_NAME,
if [[ "${pretty_name_key}" == "PRETTY_NAME" ]]; then
- PRETTY_NAME=$(echo "${distro_attribute}" | grep "PRETTY_NAME" | cut -d '=' -f2- | tr -d '"')
- log_write " ${INFO} ${PRETTY_NAME}"
- # Otherwise, do nothing
+ # so print it when we find it
+ PRETTY_NAME_VALUE=$(echo "${distro_attribute}" | grep "PRETTY_NAME" | cut -d '=' -f2- | tr -d '"')
+ # and then echoed out to the screen
+ log_write " ${INFO} ${PRETTY_NAME_VALUE}"
else
+ # Since we only need the pretty name, we can just skip over anything that is not a match
:
fi
done
@@ -304,7 +330,7 @@ get_distro_attributes() {
diagnose_operating_system() {
# local variable for system requirements
- local faq_url="https://discourse.pi-hole.net/t/hardware-software-requirements/273"
+ FAQ_HARDWARE_REQUIREMENTS="https://discourse.pi-hole.net/t/hardware-software-requirements/273"
# error message in a variable so we can easily modify it later (or re-use it)
local error_msg="Distribution unknown -- most likely you are on an unsupported platform and may run into issues."
# Display the current test that is running
@@ -315,8 +341,7 @@ diagnose_operating_system() {
# display the attributes to the user from the function made earlier
get_distro_attributes || \
# If it doesn't exist, it's not a system we currently support and link to FAQ
- log_write " ${CROSS} ${COL_LIGHT_RED}${error_msg}${COL_NC}
- ${INFO} ${COL_LIGHT_RED}Please see${COL_NC}: ${COL_CYAN}${faq_url}${COL_NC}"
+ log_write " ${CROSS} ${COL_LIGHT_RED}${error_msg}${COL_NC} (${COL_CYAN}${FAQ_HARDWARE_REQUIREMENTS}${COL_NC})"
}
processor_check() {
@@ -326,10 +351,9 @@ processor_check() {
# If it does not contain a value,
if [[ -z "${PROCESSOR}" ]]; then
# we couldn't detect it, so show an error
- log_write " ${CROSS} Processor could not be identified."
- # Otherwise,
+ log_write " ${CROSS} ${COL_LIGHT_RED}Processor could not be identified.${COL_NC}"
else
- # Show the processor type
+ # Otherwise, show the processor type
log_write " ${INFO} ${PROCESSOR}"
fi
}
@@ -353,10 +377,9 @@ detect_ip_addresses() {
# For each one in the list, print it out using the iterator as a numbered list
log_write " [$i] ${ip_addr_list[$i]}"
done
- # Othwerwise,
else
- # explain that the protocol is not configured
- log_write " ${CROSS} No IPv${protocol} found on ${PIHOLE_INTERFACE}"
+ # If there are no IPs detected, explain that the protocol is not configured
+ log_write " ${CROSS} ${COL_LIGHT_RED}No IPv${protocol} found on ${PIHOLE_INTERFACE}${COL_NC}"
return 1
fi
}
@@ -371,9 +394,8 @@ ping_gateway() {
local cmd="ping6"
# and Google's public IPv6 address
local public_address="2001:4860:4860::8888"
- # Otherwise,
else
- # use ping
+ # Otherwise, just use ping
local cmd="ping"
# and Google's public IPv4 address
local public_address="8.8.8.8"
@@ -406,7 +428,7 @@ ping_gateway() {
}
ping_internet() {
- # Give the first argument a readable name
+ # Give the first argument a readable name (a 4 or a six should be the argument)
local protocol="${1}"
# If the protocol is 6,
if [[ ${protocol} == "6" ]]; then
@@ -414,9 +436,8 @@ ping_internet() {
local cmd="ping6"
# and Google's public IPv6 address
local public_address="2001:4860:4860::8888"
- # Otherwise,
else
- # use ping
+ # Otherwise, just use ping
local cmd="ping"
# and Google's public IPv4 address
local public_address="8.8.8.8"
@@ -425,12 +446,11 @@ ping_internet() {
# Try to ping the address 3 times
if ! ping_inet="$(${cmd} -q -W 3 -c 3 -n ${public_address} -I ${PIHOLE_INTERFACE} | tail -n 3)"; then
# if it's unsuccessful, show an error
- log_write " ${CROSS} Cannot reach the Internet"
+ log_write " ${CROSS} ${COL_LIGHT_RED}Cannot reach the Internet.${COL_NC}"
return 1
- # Otherwise,
else
- # show success
- log_write " ${TICK} Query responded."
+ # Otherwise, show success
+ log_write " ${TICK} ${COL_LIGHT_GREEN}Query responded.${COL_NC}"
return 0
fi
}
@@ -448,8 +468,10 @@ check_required_ports() {
# Now that we have the values stored,
for i in ${!ports_in_use[@]}; do
+ # loop through them and assign some local variables
local port_number="$(echo "${ports_in_use[$i]}" | awk '{print $1}')"
local service_name=$(echo "${ports_in_use[$i]}" | awk '{print $2}')
+ # Use a case statement to determine if the right services are using the right ports
case "${port_number}" in
53) if [[ "${service_name}" == "dnsmasq" ]]; then
# if port 53 is dnsmasq, show it in green as it's standard
@@ -512,23 +534,24 @@ check_x_headers() {
if [[ $block_page == $block_page_working ]]; then
# display a success message
log_write " $TICK ${COL_LIGHT_GREEN}${block_page}${COL_NC}"
- # Otherwise,
else
- # show an error
+ # Otherwise, show an error
log_write " $CROSS ${COL_LIGHT_RED}X-Header does not match or could not be retrieved.${COL_NC}"
fi
- # Same logic applies to the dashbord as above
+ # Same logic applies to the dashbord as above, if the X-Header matches what a working system shoud have,
if [[ $dashboard == $dashboard_working ]]; then
+ # then we can show a success
log_write " $TICK ${COL_LIGHT_GREEN}${dashboard}${COL_NC}"
else
+ # Othewise, it's a failure since the X-Headers either don't exist or have been modified in some way
log_write " $CROSS ${COL_LIGHT_RED}X-Header does not match or could not be retrieved.${COL_NC}"
fi
}
dig_at() {
- # We need to test if Pi-hole can properly resolve domain names as it is an
- # essential piece of the software that needs to work
+ # We need to test if Pi-hole can properly resolve domain names
+ # as it is an essential piece of the software
# Store the arguments as variables with names
local protocol="${1}"
@@ -540,6 +563,7 @@ dig_at() {
local pihole_dig
local remote_dig
# Use a static domain that we know has IPv4 and IPv6 to avoid false positives
+ # Sometimes the randomly chosen domains don't use IPv6, or something else is wrong with them
local remote_url="doubleclick.com"
# If the protocol (4 or 6) is 6,
@@ -559,32 +583,40 @@ dig_at() {
fi
# Find a random blocked url that has not been whitelisted.
+ # This helps emulate queries to different domains that a user might query
+ # It will also give extra assurance that Pi-hole is correctly resolving and blocking domains
local random_url=$(shuf -n 1 "${GRAVITYFILE}" | awk -F ' ' '{ print $2 }')
- # First do a dig on localhost, to see if Pi-hole can use itself to block a domain
+ # First, do a dig on localhost to see if Pi-hole can use itself to block a domain
if local_dig=$(dig +tries=1 +time=2 -"${protocol}" "${random_url}" @${local_address} +short "${record_type}"); then
# If it can, show sucess
log_write " ${TICK} ${COL_LIGHT_GREEN}${random_url} is ${local_dig}${COL_NC} via localhost (${local_address})"
- # Otherwise,
else
- # show a failure
+ # Otherwise, show a failure
log_write " ${CROSS} ${COL_LIGHT_RED}Failed to resolve${COL_NC} ${random_url} ${COL_LIGHT_RED}via localhost${COL_NC} (${local_address})"
fi
# Next we need to check if Pi-hole can resolve a domain when the query is sent to it's IP address
# This better emulates how clients will interact with Pi-hole as opposed to above where Pi-hole is
# just asing itself locally
+ # The default timeouts and tries are reduced in case the DNS server isn't working, so the user isn't waiting for too long
+
+ # If Pi-hole can dig itself from it's IP (not the loopback address)
if pihole_dig=$(dig +tries=1 +time=2 -"${protocol}" "${random_url}" @${pihole_address} +short "${record_type}"); then
+ # show a success
log_write " ${TICK} ${COL_LIGHT_GREEN}${random_url} is ${pihole_dig}${COL_NC} via Pi-hole (${pihole_address})"
else
+ # Othewise, show a failure
log_write " ${CROSS} ${COL_LIGHT_RED}Failed to resolve${COL_NC} ${random_url} ${COL_LIGHT_RED}via Pi-hole${COL_NC} (${pihole_address})"
fi
- # Finally, we need to make sure legitimate sites can out if using an external, public DNS server
+ # Finally, we need to make sure legitimate queries can out to the Internet using an external, public DNS server
+ # We are using the static remote_url here instead of a random one because we know it works with IPv4 and IPv6
if remote_dig=$(dig +tries=1 +time=2 -"${protocol}" "${remote_url}" @${remote_address} +short "${record_type}" | head -n1); then
# If successful, the real IP of the domain will be returned instead of Pi-hole's IP
log_write " ${TICK} ${COL_LIGHT_GREEN}${remote_url} is ${remote_dig}${COL_NC} via a remote, public DNS server (${remote_address})"
else
+ # Otherwise, show an error
log_write " ${CROSS} ${COL_LIGHT_RED}Failed to resolve${COL_NC} ${remote_url} ${COL_LIGHT_RED}via a remote, public DNS server${COL_NC} (${remote_address})"
fi
}
@@ -594,22 +626,25 @@ process_status(){
echo_current_diagnostic "Pi-hole processes"
# Store them in an array for easy use
PROCESSES=( dnsmasq lighttpd pihole-FTL )
+ # Local iterator
local i
# For each process,
for i in "${PROCESSES[@]}"; do
- # get it's status
+ # get its status
local status_of_process=$(systemctl is-active "${i}")
# and print it out to the user
if [[ "${status_of_process}" == "active" ]]; then
+ # If it's active, show it in green
log_write " ${TICK} ${COL_LIGHT_GREEN}${i}${COL_NC} daemon is ${COL_LIGHT_GREEN}${status_of_process}${COL_NC}"
else
+ # If it's not, show it in red
log_write " ${CROSS} ${COL_LIGHT_RED}${i}${COL_NC} daemon is ${COL_LIGHT_RED}${status_of_process}${COL_NC}"
fi
done
}
parse_file() {
- # Set the first argument passed to tihs function as a named variable for better readability
+ # Set the first argument passed to this function as a named variable for better readability
local filename="${1}"
# Put the current Internal Field Separator into another variable so it can be restored later
OLD_IFS="$IFS"
@@ -618,7 +653,7 @@ parse_file() {
# Set a named variable for better readability
local file_lines
- # For each lin in the file,
+ # For each line in the file,
for file_lines in "${file_info[@]}"; do
# display the information with the ${INFO} icon
log_write " ${INFO} ${file_lines}"
@@ -633,13 +668,13 @@ diagnose_setup_variables() {
# If the variable file exists,
file_exists "${VARSFILE}" && \
+ log_write " * Sourcing ${VARSFILE}...";
# source it
source ${VARSFILE};
- log_write " ${INFO} Sourcing ${VARSFILE}...";
# and display a green check mark with ${DONE}
- echo_succes_or_fail "${VARSFILE} is readable and has been sourced." || \
+ echo_succes_or_fail "${COL_LIGHT_GREEN}${VARSFILE}${COL_NC} is readable and ${COL_LIGHT_GREEN}has been sourced.${COL_NC}" || \
# Othwerwise, error out
- echo_succes_or_fail "${VARSFILE} is not readable.
+ echo_succes_or_fail "${VARSFILE} ${COL_LIGHT_RED}is not readable.${COL_NC}
${INFO} $(ls -l ${VARSFILE} 2>/dev/null)";
parse_file "${VARSFILE}"
}
@@ -648,8 +683,9 @@ check_name_resolution() {
# Check name resoltion from localhost, Pi-hole's IP, and Google's name severs
# using the function we created earlier
dig_at 4 "${IPV4_ADDRESS%/*}"
- # If IPv6 enabled, check resolution
+ # If IPv6 enabled,
if [[ "${IPV6_ADDRESS}" ]]; then
+ # check resolution
dig_at 6 "${IPV6_ADDRESS%/*}"
fi
}
@@ -668,7 +704,7 @@ dir_check() {
# show a success message
echo_succes_or_fail "Files detected" || \
# Otherwise, show an error
- echo_succes_or_fail "directory does not exist"
+ echo_succes_or_fail "${COL_LIGHT_RED}irectory does not exist.${COL_NC}"
done
}
@@ -683,7 +719,6 @@ list_files_in_dir() {
# Also print the permissions and the user/group
log_write " ${INFO} $(ls -ld ${dir_to_parse}/${each_file})"
done
-
}
check_dnsmasq_d() {
@@ -723,26 +758,28 @@ check_http_directory() {
}
analyze_gravity_list() {
+ echo_current_diagnostic "Gravity list"
# It's helpful to know how big a user's gravity file is
gravity_length=$(grep -c ^ "${GRAVITYFILE}") && \
- log_write " ${INFO} ${GRAVITYFILE} is ${gravity_length} lines long." || \
+ log_write " ${INFO} ${GRAVITYFILE} is ${gravity_length} lines long.";
+ parse_file ${GRAVITYFILE} || \
# If the previous command failed, something is wrong with the file
- log_write " ${CROSS} ${GRAVITYFILE} not found!"
+ log_write " ${CROSS} ${COL_LIGHT_RED}${GRAVITYFILE} not found!${COL_NC}"
}
-tricorder_nc_or_ssl() {
- # Users can submit their debug logs using nc (unencrypted) or opensll (enrypted) if available
- # Check fist for openssl since encryption is a good thing
+tricorder_use_nc_or_ssl() {
+ # Users can submit their debug logs using nc (unencrypted) or openssl (enrypted) if available
+ # Check for openssl first since encryption is a good thing
if command -v openssl &> /dev/null; then
- # If successful
+ # If the command exists,
log_write " * Using ${COL_LIGHT_GREEN}openssl${COL_NC} for transmission."
- # transmit the log and store the token returned in the tricorder variable
- tricorder=$(cat /var/log/pihole_debug.log | openssl s_client -quiet -connect tricorder.pi-hole.net:9998 2> /dev/null)
+ # encrypt and transmit the log and store the token returned in a variable
+ tricorder_token=$(cat ${DEBUG_LOG} | openssl s_client -quiet -connect tricorder.pi-hole.net:9998 2> /dev/null)
# Otherwise,
else
# use net cat
log_write " ${INFO} Using ${COL_YELLOW}netcat${COL_NC} for transmission."
- tricorder=$(cat /var/log/pihole_debug.log | nc tricorder.pi-hole.net 9999)
+ tricorder_token=$(cat ${DEBUG_LOG} | nc tricorder.pi-hole.net 9999)
fi
}
@@ -768,10 +805,10 @@ upload_to_tricorder() {
# and then decide again which tool to use to submit it
if command -v openssl &> /dev/null; then
log_write " ${INFO} Using ${COL_LIGHT_GREEN}openssl${COL_NC} for transmission."
- openssl s_client -quiet -connect tricorder.pi-hole.net:9998 2> /dev/null < /dev/stdin
+ tricorder_token=$(openssl s_client -quiet -connect tricorder.pi-hole.net:9998 2> /dev/null < /dev/stdin)
else
log_write " ${INFO} Using ${COL_YELLOW}netcat${COL_NC} for transmission."
- nc tricorder.pi-hole.net 9999 < /dev/stdin
+ tricorder_token=$(nc tricorder.pi-hole.net 9999 < /dev/stdin)
fi
else
echo ""
@@ -780,22 +817,24 @@ upload_to_tricorder() {
read -r -p "[?] Would you like to upload the log? [y/N] " response
case ${response} in
# If they say yes, run our function for uploading the log
- [yY][eE][sS]|[yY]) tricorder_nc_or_ssl;;
+ [yY][eE][sS]|[yY]) tricorder_use_nc_or_ssl;;
# If they choose no, just exit out of the script
- *) log_write " * Log will NOT be uploaded to tricorder.";exit;
+ *) log_write " * Log will ${COL_LIGHT_GREE}NOT${COL_NC} be uploaded to tricorder.";exit;
esac
fi
# Check if tricorder.pi-hole.net is reachable and provide token
# along with some additional useful information
- if [[ -n "${tricorder}" ]]; then
+ if [[ -n "${tricorder_token}" ]]; then
echo ""
log_write "${COL_LIGHT_PURPLE}***********************************${COL_NC}"
- log_write "${TICK} Your debug token is: ${COL_LIGHT_GREEN}${tricorder}${COL_NC}"
+ log_write "${TICK} Your debug token is: ${COL_LIGHT_GREEN}${tricorder_token}${COL_NC}"
log_write "${COL_LIGHT_PURPLE}***********************************${COL_NC}"
log_write ""
log_write " Provide this token to the Pi-hole team for assistance:"
echo ""
log_write " https://discourse.pi-hole.net"
+ echo ""
+ log_write " Your log will self-destruct after 48 hours."
else
log_write " ${CROSS} There was an error uploading your debug log."
log_write " Please try again or contact the Pi-hole team for assistance."
@@ -821,6 +860,7 @@ check_name_resolution
process_status
check_x_headers
check_critical_dependencies
+analyze_gravity_list
check_dnsmasq_d
check_lighttpd_d
check_http_directory
From 36907edd5002e5f7e586fb875070de1c6bfb19e5 Mon Sep 17 00:00:00 2001
From: Jacob Salmela
Date: Sat, 27 May 2017 00:04:42 -0500
Subject: [PATCH 052/162] parse contents of each file in each dir, several
log_writes
---
advanced/Scripts/piholeDebug.sh | 201 +++++++++++++++++---------------
1 file changed, 109 insertions(+), 92 deletions(-)
diff --git a/advanced/Scripts/piholeDebug.sh b/advanced/Scripts/piholeDebug.sh
index af9802a9..86ee4e23 100755
--- a/advanced/Scripts/piholeDebug.sh
+++ b/advanced/Scripts/piholeDebug.sh
@@ -66,7 +66,7 @@ make_temporary_log() {
}
log_write() {
- # echo arguments to both the log and the console"
+ # echo arguments to both the log and the console
echo -e "${@}" | tee -a /proc/$$/fd/3
}
@@ -76,15 +76,16 @@ copy_to_debug_log() {
}
echo_succes_or_fail() {
- # Set the first argument passed to this function as a named variable for better readability
- local message="${1}"
# If the command was successful (a zero),
if [[ $? -eq 0 ]]; then
+ # Set the first argument passed to this function as a named variable for better readability
+ local message="${1}"
# show success
- log_write " ${TICK} ${message}"
+ log_write "${TICK} ${message}"
else
+ local message="${1}"
# Otherwise, show a error
- log_write " ${CROSS} ${message}"
+ log_write "${CROSS} ${message}"
fi
}
@@ -94,7 +95,7 @@ initiate_debug() {
# Display that the debug process is beginning
log_write "${COL_LIGHT_PURPLE}*** [ INITIALIZING ]${COL_NC}"
# Timestamp the start of the log
- log_write " ${INFO} $(date "+%Y-%m-%d:%H:%M:%S") debug log has been initiated."
+ log_write "${INFO} $(date "+%Y-%m-%d:%H:%M:%S") debug log has been initiated."
}
# This is a function for visually displaying the curent test that is being run.
@@ -155,25 +156,25 @@ check_core_version() {
# echo this information out to the user in a nice format
# If the current version matches what pihole -v produces, the user is up-to-date
if [[ "${PI_HOLE_VERSION}" == "$(pihole -v | awk '/Pi-hole/ {print $6}' | cut -d ')' -f1)" ]]; then
- log_write " ${TICK} Core: ${COL_LIGHT_GREEN}${PI_HOLE_VERSION}${COL_NC}"
+ log_write "${TICK} Core: ${COL_LIGHT_GREEN}${PI_HOLE_VERSION}${COL_NC}"
# If not,
else
# echo the current version in yellow, signifying it's something to take a look at, but not a critical error
# Also add a URL to an FAQ
- log_write " ${INFO} Core: ${COL_YELLOW}${PI_HOLE_VERSION:-Untagged}${COL_NC} (${COL_CYAN}${FAQ_UPDATE_PI_HOLE}${COL_NC})"
+ log_write "${INFO} Core: ${COL_YELLOW}${PI_HOLE_VERSION:-Untagged}${COL_NC} (${COL_CYAN}${FAQ_UPDATE_PI_HOLE}${COL_NC})"
fi
# If the repo is on the master branch, they are on the stable codebase
if [[ "${PI_HOLE_BRANCH}" == "master" ]]; then
# so the color of the text is green
- log_write " ${INFO} Branch: ${COL_LIGHT_GREEN}${PI_HOLE_BRANCH}${COL_NC}"
+ log_write "${INFO} Branch: ${COL_LIGHT_GREEN}${PI_HOLE_BRANCH}${COL_NC}"
# If it is any other branch, they are in a developement 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}${PI_HOLE_BRANCH:-Detached}${COL_NC} (${COL_CYAN}${FAQ_CHECKOUT_COMMAND}${COL_NC})"
+ log_write "${INFO} Branch: ${COL_YELLOW}${PI_HOLE_BRANCH:-Detached}${COL_NC} (${COL_CYAN}${FAQ_CHECKOUT_COMMAND}${COL_NC})"
fi
# echo the current commit
- log_write " ${INFO} Commit: ${PI_HOLE_COMMIT}"
+ log_write "${INFO} Commit: ${PI_HOLE_COMMIT}\n"
# If git status failed,
else
# Return an error message
@@ -204,25 +205,25 @@ check_web_version() {
# If the Web version reported by pihole -v matches the current version
if [[ "${WEB_VERSION}" == "$(pihole -v | awk '/AdminLTE/ {print $6}' | cut -d ')' -f1)" ]]; then
# echo it in green
- log_write " ${TICK} Web: ${COL_LIGHT_GREEN}${WEB_VERSION}${COL_NC}"
+ log_write "${TICK} Web: ${COL_LIGHT_GREEN}${WEB_VERSION}${COL_NC}"
# Otherwise,
else
# Show it in yellow with a link to update Pi-hole
- log_write " ${INFO} Web: ${COL_YELLOW}${WEB_VERSION:-Untagged}${COL_NC} (${COL_CYAN}${FAQ_UPDATE_PI_HOLE}${COL_NC})"
+ log_write "${INFO} Web: ${COL_YELLOW}${WEB_VERSION:-Untagged}${COL_NC} (${COL_CYAN}${FAQ_UPDATE_PI_HOLE}${COL_NC})"
fi
# If the repo is on the master branch, they are on the stable codebase
if [[ "${WEB_BRANCH}" == "master" ]]; then
# so the color of the text is green
- log_write " ${TICK} Branch: ${COL_LIGHT_GREEN}${WEB_BRANCH}${COL_NC}"
+ log_write "${TICK} Branch: ${COL_LIGHT_GREEN}${WEB_BRANCH}${COL_NC}"
else
# If it is any other branch, they are in a developement branch
# 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}${WEB_BRANCH:-Detached}${COL_NC} (${COL_CYAN}${FAQ_CHECKOUT_COMMAND}${COL_NC})"
+ log_write "${INFO} Branch: ${COL_YELLOW}${WEB_BRANCH:-Detached}${COL_NC} (${COL_CYAN}${FAQ_CHECKOUT_COMMAND}${COL_NC})"
fi
# echo the current commit
- log_write " ${INFO} Commit: ${WEB_COMMIT}"
+ log_write "${INFO} Commit: ${WEB_COMMIT}\n"
# If git status failed,
else
# Return an error message
@@ -238,10 +239,10 @@ check_ftl_version() {
# 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: ${COL_LIGHT_GREEN}${FTL_VERSION}${COL_NC}"
+ log_write "${TICK} FTL: ${COL_LIGHT_GREEN}${FTL_VERSION}${COL_NC}"
else
# If not, show it in yellow, signifying there is an update
- log_write " ${TICK} FTL: ${COL_YELLOW}${FTL_VERSION}${COL_NC}"
+ log_write "${TICK} FTL: ${COL_YELLOW}${FTL_VERSION}${COL_NC}"
fi
}
@@ -254,10 +255,10 @@ check_web_server_version() {
# If the Web server does not have a version (the variable is empty)
if [[ -z "${WEB_SERVER_VERSON}" ]]; then
# Display and error
- log_write " ${CROSS} ${COL_LIGHT_RED}${WEB_SERVER} version could not be detected.${COL_NC}"
+ log_write "${CROSS} ${COL_LIGHT_RED}${WEB_SERVER} version could not be detected.${COL_NC}"
else
# Otherwise, display the version
- log_write " ${TICK} ${WEB_SERVER}: ${WEB_SERVER_VERSON}"
+ log_write "${TICK} ${WEB_SERVER}: ${WEB_SERVER_VERSON}"
fi
}
@@ -270,10 +271,10 @@ check_resolver_server_version() {
# If the DNS server does not have a version (the variable is empty)
if [[ -z "${RESOVLER_VERSON}" ]]; then
# Display and error
- log_write " ${CROSS} ${COL_LIGHT_RED}${RESOLVER} version could not be detected.${COL_NC}"
+ log_write "${CROSS} ${COL_LIGHT_RED}${RESOLVER} version could not be detected.${COL_NC}"
else
# Otherwise, display the version
- log_write " ${TICK} ${RESOLVER}: ${RESOVLER_VERSON}"
+ log_write "${TICK} ${RESOLVER}: ${RESOVLER_VERSON}"
fi
}
@@ -283,10 +284,10 @@ check_php_version() {
# If no version is detected,
if [[ -z "${PHP_VERSION}" ]]; then
# show an error
- log_write " ${CROSS} ${COL_LIGHT_RED}PHP version could not be detected.${COL_NC}"
+ log_write "${CROSS} ${COL_LIGHT_RED}PHP version could not be detected.${COL_NC}"
else
# Otherwise, show the version
- log_write " ${TICK} PHP: ${PHP_VERSION}"
+ log_write "${TICK} PHP: ${PHP_VERSION}"
fi
}
@@ -318,7 +319,7 @@ get_distro_attributes() {
# so print it when we find it
PRETTY_NAME_VALUE=$(echo "${distro_attribute}" | grep "PRETTY_NAME" | cut -d '=' -f2- | tr -d '"')
# and then echoed out to the screen
- log_write " ${INFO} ${PRETTY_NAME_VALUE}"
+ log_write "${INFO} ${PRETTY_NAME_VALUE}"
else
# Since we only need the pretty name, we can just skip over anything that is not a match
:
@@ -341,7 +342,7 @@ diagnose_operating_system() {
# display the attributes to the user from the function made earlier
get_distro_attributes || \
# If it doesn't exist, it's not a system we currently support and link to FAQ
- log_write " ${CROSS} ${COL_LIGHT_RED}${error_msg}${COL_NC} (${COL_CYAN}${FAQ_HARDWARE_REQUIREMENTS}${COL_NC})"
+ log_write "${CROSS} ${COL_LIGHT_RED}${error_msg}${COL_NC} (${COL_CYAN}${FAQ_HARDWARE_REQUIREMENTS}${COL_NC})"
}
processor_check() {
@@ -351,10 +352,10 @@ processor_check() {
# If it does not contain a value,
if [[ -z "${PROCESSOR}" ]]; then
# we couldn't detect it, so show an error
- log_write " ${CROSS} ${COL_LIGHT_RED}Processor could not be identified.${COL_NC}"
+ log_write "${CROSS} ${COL_LIGHT_RED}Processor could not be identified.${COL_NC}"
else
# Otherwise, show the processor type
- log_write " ${INFO} ${PROCESSOR}"
+ log_write "${INFO} ${PROCESSOR}"
fi
}
@@ -371,15 +372,16 @@ detect_ip_addresses() {
# Local iterator
local i
# Display the protocol and interface
- log_write " ${TICK} IPv${protocol} on ${PIHOLE_INTERFACE}"
+ log_write "${TICK} IPv${protocol} on ${PIHOLE_INTERFACE}"
# Since there may be more than one IP address, store them in an array
for i in "${!ip_addr_list[@]}"; do
- # For each one in the list, print it out using the iterator as a numbered list
- log_write " [$i] ${ip_addr_list[$i]}"
+ # For each one in the list, print it out
+ log_write "${ip_addr_list[$i]}"
done
+ log_write ""
else
# If there are no IPs detected, explain that the protocol is not configured
- log_write " ${CROSS} ${COL_LIGHT_RED}No IPv${protocol} found on ${PIHOLE_INTERFACE}${COL_NC}"
+ log_write "${CROSS} ${COL_LIGHT_RED}No IPv${protocol} found on ${PIHOLE_INTERFACE}${COL_NC}\n"
return 1
fi
}
@@ -408,19 +410,19 @@ ping_gateway() {
# If the gateway variable has a value (meaning a gateway was found),
if [[ -n "${gateway}" ]]; then
# Let the user know we will ping the gateway for a response
- log_write " * Trying three pings on IPv${protocol} gateway at ${gateway}..."
+ log_write "* Trying three pings on IPv${protocol} gateway at ${gateway}..."
# Try to quietly ping the gateway 3 times, with a timeout of 3 seconds, using numeric output only,
# on the pihole interface, and tail the last three lines of the output
# If pinging the gateway is not successful,
if ! ping_cmd="$(${cmd} -q -c 3 -W 3 -n ${gateway} -I ${PIHOLE_INTERFACE} | tail -n 3)"; then
# let the user know
- log_write " ${CROSS} ${COL_LIGHT_RED}Gateway did not respond.${COL_NC}"
+ log_write "${CROSS} ${COL_LIGHT_RED}Gateway did not respond.${COL_NC}\n"
# and return an error code
return 1
# Otherwise,
else
# show a success
- log_write " ${TICK} ${COL_LIGHT_GREEN}Gateway responded.${COL_NC}"
+ log_write "${TICK} ${COL_LIGHT_GREEN}Gateway responded.${COL_NC}\n"
# and return a success code
return 0
fi
@@ -442,15 +444,15 @@ ping_internet() {
# and Google's public IPv4 address
local public_address="8.8.8.8"
fi
- echo -n " ${INFO} Trying three pings on IPv${protocol} to reach the Internet..."
+ echo -n "${INFO} Trying three pings on IPv${protocol} to reach the Internet..."
# Try to ping the address 3 times
if ! ping_inet="$(${cmd} -q -W 3 -c 3 -n ${public_address} -I ${PIHOLE_INTERFACE} | tail -n 3)"; then
# if it's unsuccessful, show an error
- log_write " ${CROSS} ${COL_LIGHT_RED}Cannot reach the Internet.${COL_NC}"
+ log_write "${CROSS} ${COL_LIGHT_RED}Cannot reach the Internet.${COL_NC}\n"
return 1
else
# Otherwise, show success
- log_write " ${TICK} ${COL_LIGHT_GREEN}Query responded.${COL_NC}"
+ log_write "${TICK} ${COL_LIGHT_GREEN}Query responded.${COL_NC}\n"
return 0
fi
}
@@ -458,7 +460,7 @@ ping_internet() {
check_required_ports() {
# Since Pi-hole needs 53, 80, and 4711, check what they are being used by
# so we can detect any issues
- log_write " ${INFO} Ports in use:"
+ log_write "${INFO} Ports in use:"
# Create an array for these ports in use
ports_in_use=()
# Sort the addresses and remove duplicates
@@ -475,35 +477,35 @@ check_required_ports() {
case "${port_number}" in
53) if [[ "${service_name}" == "dnsmasq" ]]; then
# if port 53 is dnsmasq, show it in green as it's standard
- log_write " [${COL_LIGHT_GREEN}${port_number}${COL_NC}] is in use by ${COL_LIGHT_GREEN}${service_name}${COL_NC}"
+ log_write "[${COL_LIGHT_GREEN}${port_number}${COL_NC}] is in use by ${COL_LIGHT_GREEN}${service_name}${COL_NC}"
# Otherwise,
else
# Show the service name in red since it's non-standard
- log_write " [${COL_LIGHT_RED}${port_number}${COL_NC}] is in use by ${COL_LIGHT_RED}${service_name}${COL_NC}
+ log_write "[${COL_LIGHT_RED}${port_number}${COL_NC}] is in use by ${COL_LIGHT_RED}${service_name}${COL_NC}
Please see: ${COL_CYAN}https://discourse.pi-hole.net/t/hardware-software-requirements/273#ports${COL_NC}"
fi
;;
80) if [[ "${service_name}" == "lighttpd" ]]; then
# if port 53 is dnsmasq, show it in green as it's standard
- log_write " [${COL_LIGHT_GREEN}${port_number}${COL_NC}] is in use by ${COL_LIGHT_GREEN}${service_name}${COL_NC}"
+ log_write "[${COL_LIGHT_GREEN}${port_number}${COL_NC}] is in use by ${COL_LIGHT_GREEN}${service_name}${COL_NC}"
# Otherwise,
else
# Show the service name in red since it's non-standard
- log_write " [${COL_LIGHT_RED}${port_number}${COL_NC}] is in use by ${COL_LIGHT_RED}${service_name}${COL_NC}
+ log_write "[${COL_LIGHT_RED}${port_number}${COL_NC}] is in use by ${COL_LIGHT_RED}${service_name}${COL_NC}
Please see: ${COL_CYAN}https://discourse.pi-hole.net/t/hardware-software-requirements/273#ports${COL_NC}"
fi
;;
4711) if [[ "${service_name}" == "pihole-FT" ]]; then
# if port 4711 is pihole-FTL, show it in green as it's standard
- log_write " [${COL_LIGHT_GREEN}${port_number}${COL_NC}] is in use by ${COL_LIGHT_GREEN}${service_name}${COL_NC}"
+ log_write "[${COL_LIGHT_GREEN}${port_number}${COL_NC}] is in use by ${COL_LIGHT_GREEN}${service_name}${COL_NC}"
# Otherwise,
else
# Show the service name in yellow since it's non-standard, but should still work
- log_write " [${COL_YELLOW}${port_number}${COL_NC}] is in use by ${COL_YELLOW}${service_name}${COL_NC}
+ log_write "[${COL_YELLOW}${port_number}${COL_NC}] is in use by ${COL_YELLOW}${service_name}${COL_NC}
Please see: ${COL_CYAN}https://discourse.pi-hole.net/t/hardware-software-requirements/273#ports${COL_NC}"
fi
;;
- *) log_write " [${port_number}] is in use by ${service_name}";
+ *) log_write "[${port_number}] is in use by ${service_name}";
esac
done
}
@@ -533,19 +535,19 @@ check_x_headers() {
# 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 ${COL_LIGHT_GREEN}${block_page}${COL_NC}"
+ log_write "$TICK ${COL_LIGHT_GREEN}${block_page}${COL_NC}"
else
# Otherwise, show an error
- log_write " $CROSS ${COL_LIGHT_RED}X-Header does not match or could not be retrieved.${COL_NC}"
+ log_write "$CROSS ${COL_LIGHT_RED}X-Header does not match or could not be retrieved.${COL_NC}"
fi
# Same logic applies to the dashbord as above, if the X-Header matches what a working system shoud have,
if [[ $dashboard == $dashboard_working ]]; then
# then we can show a success
- log_write " $TICK ${COL_LIGHT_GREEN}${dashboard}${COL_NC}"
+ log_write "$TICK ${COL_LIGHT_GREEN}${dashboard}${COL_NC}"
else
# Othewise, it's a failure since the X-Headers either don't exist or have been modified in some way
- log_write " $CROSS ${COL_LIGHT_RED}X-Header does not match or could not be retrieved.${COL_NC}"
+ log_write "$CROSS ${COL_LIGHT_RED}X-Header does not match or could not be retrieved.${COL_NC}"
fi
}
@@ -590,10 +592,10 @@ dig_at() {
# First, do a dig on localhost to see if Pi-hole can use itself to block a domain
if local_dig=$(dig +tries=1 +time=2 -"${protocol}" "${random_url}" @${local_address} +short "${record_type}"); then
# If it can, show sucess
- log_write " ${TICK} ${COL_LIGHT_GREEN}${random_url} is ${local_dig}${COL_NC} via localhost (${local_address})"
+ log_write "${TICK} ${random_url} ${COL_LIGHT_GREEN}is ${local_dig}${COL_NC} via localhost (${local_address})"
else
# Otherwise, show a failure
- log_write " ${CROSS} ${COL_LIGHT_RED}Failed to resolve${COL_NC} ${random_url} ${COL_LIGHT_RED}via localhost${COL_NC} (${local_address})"
+ log_write "${CROSS} ${COL_LIGHT_RED}Failed to resolve${COL_NC} ${random_url} ${COL_LIGHT_RED}via localhost${COL_NC} (${local_address})"
fi
# Next we need to check if Pi-hole can resolve a domain when the query is sent to it's IP address
@@ -604,20 +606,20 @@ dig_at() {
# If Pi-hole can dig itself from it's IP (not the loopback address)
if pihole_dig=$(dig +tries=1 +time=2 -"${protocol}" "${random_url}" @${pihole_address} +short "${record_type}"); then
# show a success
- log_write " ${TICK} ${COL_LIGHT_GREEN}${random_url} is ${pihole_dig}${COL_NC} via Pi-hole (${pihole_address})"
+ log_write "${TICK} ${random_url} ${COL_LIGHT_GREEN}is ${pihole_dig}${COL_NC} via Pi-hole (${pihole_address})"
else
# Othewise, show a failure
- log_write " ${CROSS} ${COL_LIGHT_RED}Failed to resolve${COL_NC} ${random_url} ${COL_LIGHT_RED}via Pi-hole${COL_NC} (${pihole_address})"
+ log_write "${CROSS} ${COL_LIGHT_RED}Failed to resolve${COL_NC} ${random_url} ${COL_LIGHT_RED}via Pi-hole${COL_NC} (${pihole_address})"
fi
# Finally, we need to make sure legitimate queries can out to the Internet using an external, public DNS server
# We are using the static remote_url here instead of a random one because we know it works with IPv4 and IPv6
if remote_dig=$(dig +tries=1 +time=2 -"${protocol}" "${remote_url}" @${remote_address} +short "${record_type}" | head -n1); then
# If successful, the real IP of the domain will be returned instead of Pi-hole's IP
- log_write " ${TICK} ${COL_LIGHT_GREEN}${remote_url} is ${remote_dig}${COL_NC} via a remote, public DNS server (${remote_address})"
+ log_write "${TICK} ${remote_url} ${COL_LIGHT_GREEN}is ${remote_dig}${COL_NC} via a remote, public DNS server (${remote_address})"
else
# Otherwise, show an error
- log_write " ${CROSS} ${COL_LIGHT_RED}Failed to resolve${COL_NC} ${remote_url} ${COL_LIGHT_RED}via a remote, public DNS server${COL_NC} (${remote_address})"
+ log_write "${CROSS} ${COL_LIGHT_RED}Failed to resolve${COL_NC} ${remote_url} ${COL_LIGHT_RED}via a remote, public DNS server${COL_NC} (${remote_address})"
fi
}
@@ -635,14 +637,25 @@ process_status(){
# and print it out to the user
if [[ "${status_of_process}" == "active" ]]; then
# If it's active, show it in green
- log_write " ${TICK} ${COL_LIGHT_GREEN}${i}${COL_NC} daemon is ${COL_LIGHT_GREEN}${status_of_process}${COL_NC}"
+ log_write "${TICK} ${COL_LIGHT_GREEN}${i}${COL_NC} daemon is ${COL_LIGHT_GREEN}${status_of_process}${COL_NC}"
else
# If it's not, show it in red
- log_write " ${CROSS} ${COL_LIGHT_RED}${i}${COL_NC} daemon is ${COL_LIGHT_RED}${status_of_process}${COL_NC}"
+ log_write "${CROSS} ${COL_LIGHT_RED}${i}${COL_NC} daemon is ${COL_LIGHT_RED}${status_of_process}${COL_NC}"
fi
done
}
+make_array_from_file() {
+ local filename="${1}"
+ if [[ -d "${filename}" ]]; then
+ :
+ else
+ while IFS= read -r line;do
+ file_content+=("${line}")
+ done < "${filename}"
+ fi
+}
+
parse_file() {
# Set the first argument passed to this function as a named variable for better readability
local filename="${1}"
@@ -655,8 +668,8 @@ parse_file() {
local file_lines
# For each line in the file,
for file_lines in "${file_info[@]}"; do
- # display the information with the ${INFO} icon
- log_write " ${INFO} ${file_lines}"
+ # Display the file's content
+ log_write " ${file_lines}" | grep -v "#" | sed '/^$/d'
done
# Set the IFS back to what it was
IFS="$OLD_IFS"
@@ -668,7 +681,7 @@ diagnose_setup_variables() {
# If the variable file exists,
file_exists "${VARSFILE}" && \
- log_write " * Sourcing ${VARSFILE}...";
+ log_write "* Sourcing ${VARSFILE}...";
# source it
source ${VARSFILE};
# and display a green check mark with ${DONE}
@@ -701,10 +714,10 @@ dir_check() {
for filename in "${directory}"; do
# check if exists first; if it does,
file_exists "${filename}" && \
- # show a success message
- echo_succes_or_fail "Files detected" || \
+ # do nothing
+ : || \
# Otherwise, show an error
- echo_succes_or_fail "${COL_LIGHT_RED}irectory does not exist.${COL_NC}"
+ echo_succes_or_fail "${COL_LIGHT_RED}directory does not exist.${COL_NC}"
done
}
@@ -715,9 +728,19 @@ list_files_in_dir() {
files_found=( $(ls "${dir_to_parse}") )
# For each file in the arry,
for each_file in "${files_found[@]}"; do
- # display the information with the ${INFO} icon
- # Also print the permissions and the user/group
- log_write " ${INFO} $(ls -ld ${dir_to_parse}/${each_file})"
+ if [[ -d "${each_file}" ]]; then
+ :
+ else
+ # display the information with the ${INFO} icon
+ # Also print the permissions and the user/group
+ log_write "\n${COL_LIGHT_GREEN}$(ls -ld ${dir_to_parse}/${each_file})${COL_NC}"
+ # Otherwise, parse the file's content
+ make_array_from_file "${dir_to_parse}/${each_file}"
+ for each_line in "${file_content[@]}"; do
+ log_write " ${each_line}"
+ done
+ fi
+ file_content=()
done
}
@@ -761,10 +784,9 @@ analyze_gravity_list() {
echo_current_diagnostic "Gravity list"
# It's helpful to know how big a user's gravity file is
gravity_length=$(grep -c ^ "${GRAVITYFILE}") && \
- log_write " ${INFO} ${GRAVITYFILE} is ${gravity_length} lines long.";
- parse_file ${GRAVITYFILE} || \
+ log_write "${INFO} ${GRAVITYFILE} is ${gravity_length} lines long." || \
# If the previous command failed, something is wrong with the file
- log_write " ${CROSS} ${COL_LIGHT_RED}${GRAVITYFILE} not found!${COL_NC}"
+ log_write "${CROSS} ${COL_LIGHT_RED}${GRAVITYFILE} not found!${COL_NC}"
}
tricorder_use_nc_or_ssl() {
@@ -772,13 +794,13 @@ tricorder_use_nc_or_ssl() {
# Check for openssl first since encryption is a good thing
if command -v openssl &> /dev/null; then
# If the command exists,
- log_write " * Using ${COL_LIGHT_GREEN}openssl${COL_NC} for transmission."
+ log_write " * Using ${COL_LIGHT_GREEN}openssl${COL_NC} for transmission."
# encrypt and transmit the log and store the token returned in a variable
tricorder_token=$(cat ${DEBUG_LOG} | openssl s_client -quiet -connect tricorder.pi-hole.net:9998 2> /dev/null)
# Otherwise,
else
# use net cat
- log_write " ${INFO} Using ${COL_YELLOW}netcat${COL_NC} for transmission."
+ log_write "${INFO} Using ${COL_YELLOW}netcat${COL_NC} for transmission."
tricorder_token=$(cat ${DEBUG_LOG} | nc tricorder.pi-hole.net 9999)
fi
}
@@ -791,23 +813,22 @@ upload_to_tricorder() {
# Let the user know debugging is complete
echo ""
- log_write "${TICK} Finished debugging!"
+ log_write "${TICK} ${COL_LIGHT_GREEN}** Finished debugging! **${COL_NC}\n"
# Provide information on what they should do with their token
- log_write " * The debug log can be uploaded to tricorder.pi-hole.net for sharing with developers only."
- log_write " * For more information, see: ${COL_CYAN}https://pi-hole.net/2016/11/07/crack-our-medical-tricorder-win-a-raspberry-pi-3/${COL_NC}"
- log_write ""
- log_write " * If available, we'll use openssl to upload the log, otherwise it will fall back to netcat."
+ log_write " * The debug log can be uploaded to tricorder.pi-hole.net for sharing with developers only."
+ log_write " * For more information, see: ${COL_CYAN}https://pi-hole.net/2016/11/07/crack-our-medical-tricorder-win-a-raspberry-pi-3/${COL_NC}"
+ log_write " * If available, we'll use openssl to upload the log, otherwise it will fall back to netcat."
# If pihole -d is running automatically (usually throught the dashboard)
if [[ "${AUTOMATED}" ]]; then
# let the user know
- log_write " ${INFO} Debug script running in automated mode"
+ log_write "${INFO} Debug script running in automated mode"
# and then decide again which tool to use to submit it
if command -v openssl &> /dev/null; then
- log_write " ${INFO} Using ${COL_LIGHT_GREEN}openssl${COL_NC} for transmission."
+ log_write "${INFO} Using ${COL_LIGHT_GREEN}openssl${COL_NC} for transmission."
tricorder_token=$(openssl s_client -quiet -connect tricorder.pi-hole.net:9998 2> /dev/null < /dev/stdin)
else
- log_write " ${INFO} Using ${COL_YELLOW}netcat${COL_NC} for transmission."
+ log_write "${INFO} Using ${COL_YELLOW}netcat${COL_NC} for transmission."
tricorder_token=$(nc tricorder.pi-hole.net 9999 < /dev/stdin)
fi
else
@@ -819,7 +840,7 @@ upload_to_tricorder() {
# If they say yes, run our function for uploading the log
[yY][eE][sS]|[yY]) tricorder_use_nc_or_ssl;;
# If they choose no, just exit out of the script
- *) log_write " * Log will ${COL_LIGHT_GREE}NOT${COL_NC} be uploaded to tricorder.";exit;
+ *) log_write " * Log will ${COL_LIGHT_GREEN}NOT${COL_NC} be uploaded to tricorder.";exit;
esac
fi
# Check if tricorder.pi-hole.net is reachable and provide token
@@ -829,19 +850,15 @@ upload_to_tricorder() {
log_write "${COL_LIGHT_PURPLE}***********************************${COL_NC}"
log_write "${TICK} Your debug token is: ${COL_LIGHT_GREEN}${tricorder_token}${COL_NC}"
log_write "${COL_LIGHT_PURPLE}***********************************${COL_NC}"
- log_write ""
- log_write " Provide this token to the Pi-hole team for assistance:"
- echo ""
- log_write " https://discourse.pi-hole.net"
- echo ""
- log_write " Your log will self-destruct after 48 hours."
+
+ log_write " * Provide this token to the Pi-hole team for assistance:"
+ log_write " * ${COL_CYAN}https://discourse.pi-hole.net${COL_NC}"
+ log_write " * Your log will self-destruct after ${COL_LIGHT_RED}48 hours${COL_NC}."
else
- log_write " ${CROSS} There was an error uploading your debug log."
- log_write " Please try again or contact the Pi-hole team for assistance."
+ log_write "${CROSS} ${COL_LIGHT_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
- echo ""
- log_write " A local copy of the debug log can be found at : /var/log/pihole_debug.log"
- echo ""
+ log_write " * A local copy of the debug log can be found at : ${COL_CYAN}${DEBUG_LOG}${COL_NC}\n"
}
# Run through all the functions we made
From d9135347935d9150443e405b4d0ef92f64c03f63 Mon Sep 17 00:00:00 2001
From: DL6ER
Date: Sat, 27 May 2017 17:51:41 +0200
Subject: [PATCH 053/162] Move wildcards file if blocking is disabled (#1495)
* Move wildcards file if blocking is diabled
* Delete newline
---
pihole | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/pihole b/pihole
index f89b67b2..1fb985e1 100755
--- a/pihole
+++ b/pihole
@@ -176,6 +176,9 @@ Time:
elif [[ "${1}" == "0" ]]; then
# Disable Pi-hole
sed -i 's/^addn-hosts=\/etc\/pihole\/gravity.list/#addn-hosts=\/etc\/pihole\/gravity.list/' /etc/dnsmasq.d/01-pihole.conf
+ if [[ -e "$wildcardlist" ]]; then
+ mv "$wildcardlist" "/etc/pihole/wildcard.list"
+ fi
echo "::: Blocking has been disabled!"
if [[ $# > 1 ]]; then
if [[ "${2}" == *"s"* ]]; then
@@ -199,6 +202,9 @@ Time:
# Enable Pi-hole
echo "::: Blocking has been enabled!"
sed -i 's/^#addn-hosts/addn-hosts/' /etc/dnsmasq.d/01-pihole.conf
+ if [[ -e "/etc/pihole/wildcard.list" ]]; then
+ mv "/etc/pihole/wildcard.list" "$wildcardlist"
+ fi
fi
restartDNS
}
@@ -305,7 +311,7 @@ tricorderFunc() {
echo "Please do not call Tricorder directly."
exit 1
fi
-
+
if ! timeout 2 nc -z tricorder.pi-hole.net 9998 &> /dev/null; then
echo "Unable to connect to Pi-hole's Tricorder server."
exit 1
From d51e0c49b1009c2637d52deecd71a4314c32b2a4 Mon Sep 17 00:00:00 2001
From: Jacob Salmela
Date: Sat, 27 May 2017 13:44:33 -0500
Subject: [PATCH 054/162] remove comments and blank lines when parsing files
---
advanced/Scripts/piholeDebug.sh | 35 ++++++++++++++++++++++-----------
1 file changed, 24 insertions(+), 11 deletions(-)
diff --git a/advanced/Scripts/piholeDebug.sh b/advanced/Scripts/piholeDebug.sh
index 86ee4e23..dff5efeb 100755
--- a/advanced/Scripts/piholeDebug.sh
+++ b/advanced/Scripts/piholeDebug.sh
@@ -107,7 +107,7 @@ echo_current_diagnostic() {
log_write "\n${COL_LIGHT_PURPLE}*** [ DIAGNOSING ]:${COL_NC} ${1}"
}
-file_exists() {
+if_file_exists() {
# Set the first argument passed to tihs function as a named variable for better readability
local file_to_test="${1}"
# If the file is readable
@@ -338,7 +338,7 @@ diagnose_operating_system() {
echo_current_diagnostic "Operating system"
# If there is a /etc/*release file, it's probably a supported operating system, so we can
- file_exists /etc/*release && \
+ if_file_exists /etc/*release && \
# display the attributes to the user from the function made earlier
get_distro_attributes || \
# If it doesn't exist, it's not a system we currently support and link to FAQ
@@ -409,6 +409,7 @@ ping_gateway() {
# If the gateway variable has a value (meaning a gateway was found),
if [[ -n "${gateway}" ]]; then
+ log_write "${INFO} Default gateway: ${gateway}"
# Let the user know we will ping the gateway for a response
log_write "* Trying three pings on IPv${protocol} gateway at ${gateway}..."
# Try to quietly ping the gateway 3 times, with a timeout of 3 seconds, using numeric output only,
@@ -647,11 +648,23 @@ process_status(){
make_array_from_file() {
local filename="${1}"
+ # If the file is a directory
if [[ -d "${filename}" ]]; then
+ # do nothing since it cannot be parsed
:
else
+ # Otherwise, read the file line by line
while IFS= read -r line;do
- file_content+=("${line}")
+ # Strip out comments and blank lines
+ new_line=$(echo "${line}" | sed -e 's/#.*$//' -e '/^$/d')
+ # If the line still has content
+ if [[ -n "${new_line}" ]]; then
+ # Put it into the array
+ file_content+=("${new_line}")
+ else
+ # Otherwise, it's a blank line or comment, so do nothing
+ :
+ fi
done < "${filename}"
fi
}
@@ -669,7 +682,7 @@ parse_file() {
# For each line in the file,
for file_lines in "${file_info[@]}"; do
# Display the file's content
- log_write " ${file_lines}" | grep -v "#" | sed '/^$/d'
+ log_write " ${file_lines}"
done
# Set the IFS back to what it was
IFS="$OLD_IFS"
@@ -680,7 +693,7 @@ diagnose_setup_variables() {
echo_current_diagnostic "Setup variables"
# If the variable file exists,
- file_exists "${VARSFILE}" && \
+ if_file_exists "${VARSFILE}" && \
log_write "* Sourcing ${VARSFILE}...";
# source it
source ${VARSFILE};
@@ -713,7 +726,7 @@ dir_check() {
# For each file in the directory,
for filename in "${directory}"; do
# check if exists first; if it does,
- file_exists "${filename}" && \
+ if_file_exists "${filename}" && \
# do nothing
: || \
# Otherwise, show an error
@@ -851,14 +864,14 @@ upload_to_tricorder() {
log_write "${TICK} Your debug token is: ${COL_LIGHT_GREEN}${tricorder_token}${COL_NC}"
log_write "${COL_LIGHT_PURPLE}***********************************${COL_NC}"
- log_write " * Provide this token to the Pi-hole team for assistance:"
- log_write " * ${COL_CYAN}https://discourse.pi-hole.net${COL_NC}"
- log_write " * Your log will self-destruct after ${COL_LIGHT_RED}48 hours${COL_NC}."
+ log_write " * Provide this token to the Pi-hole team for assistance:"
+ log_write " * ${COL_CYAN}https://discourse.pi-hole.net${COL_NC}"
+ log_write " * Your log will self-destruct after ${COL_LIGHT_RED}48 hours${COL_NC}."
else
log_write "${CROSS} ${COL_LIGHT_RED}There was an error uploading your debug log.${COL_NC}"
- log_write " * Please try again or contact the Pi-hole team for assistance."
+ log_write " * Please try again or contact the Pi-hole team for assistance."
fi
- log_write " * A local copy of the debug log can be found at : ${COL_CYAN}${DEBUG_LOG}${COL_NC}\n"
+ log_write " * A local copy of the debug log can be found at : ${COL_CYAN}${DEBUG_LOG}${COL_NC}\n"
}
# Run through all the functions we made
From 2b8a8b03a82c942c54cf1d9d7605cfe065e1f149 Mon Sep 17 00:00:00 2001
From: WaLLy3K
Date: Sun, 28 May 2017 06:42:44 +1000
Subject: [PATCH 055/162] Roll back merge #1417 (#1494)
---
pihole | 81 +++++++++++++++++++++++++++++++++++-----------------------
1 file changed, 49 insertions(+), 32 deletions(-)
diff --git a/pihole b/pihole
index 1fb985e1..08e6b094 100755
--- a/pihole
+++ b/pihole
@@ -80,49 +80,66 @@ updateGravityFunc() {
exit 0
}
-scanList() {
+scanList(){
domain="${1}"
list="${2}"
method="${3}"
-
- if [[ "${method}" == "-exact" ]]; then
- grep -i -E -l "(^|\s|\/)${domain}($|\s|\/)" ${list}
+ if [[ ${method} == "-exact" ]] ; then
+ grep -i -E "(^|\s)${domain}($|\s)" "${list}"
else
- grep -i "${domain}" ${list}
+ grep -i "${domain}" "${list}"
fi
}
+processWildcards() {
+ IFS="." read -r -a array <<< "${1}"
+ for (( i=${#array[@]}-1; i>=0; i-- )); do
+ ar=""
+ for (( j=${#array[@]}-1; j>${#array[@]}-i-2; j-- )); do
+ if [[ $j == $((${#array[@]}-1)) ]]; then
+ ar="${array[$j]}"
+ else
+ ar="${array[$j]}.${ar}"
+ fi
+ done
+ echo "${ar}"
+ done
+}
+
queryFunc() {
+ domain="${2}"
method="${3}"
+ lists=( /etc/pihole/list.* /etc/pihole/blacklist.txt)
+ for list in ${lists[@]}; do
+ if [ -e "${list}" ]; then
+ result=$(scanList ${domain} ${list} ${method})
+ # Remove empty lines before couting number of results
+ count=$(sed '/^\s*$/d' <<< "$result" | wc -l)
+ echo "::: ${list} (${count} results)"
+ if [[ ${count} > 0 ]]; then
+ echo "${result}"
+ fi
+ echo ""
+ else
+ echo "::: ${list} does not exist"
+ echo ""
+ fi
+ done
- # If domain contains non ASCII characters, convert domain to punycode if python exists
- # Cr: https://serverfault.com/a/335079
- if [[ -z "${2}" ]]; then
- echo "::: No domain specified"
- exit 1
- elif [[ "${2}" = *[![:ascii:]]* ]]; then
- [[ "$(which python)" ]] && domain=$(python -c 'import sys;print sys.argv[1].decode("utf-8").encode("idna")' "${2}")
- else
- domain="${2}"
+ # Scan for possible wildcard matches
+ if [ -e "${wildcardlist}" ]; then
+ local wildcards=($(processWildcards "${domain}"))
+ for domain in ${wildcards[@]}; do
+ result=$(scanList "\/${domain}\/" ${wildcardlist})
+ # Remove empty lines before couting number of results
+ count=$(sed '/^\s*$/d' <<< "$result" | wc -l)
+ if [[ ${count} > 0 ]]; then
+ echo "::: Wildcard blocking ${domain} (${count} results)"
+ echo "${result}"
+ echo ""
+ fi
+ done
fi
-
- # Scan Whitelist, Blacklist and Wildcards
- lists="/etc/pihole/whitelist.txt /etc/pihole/blacklist.txt $wildcardlist"
- result=$(scanList ${domain} "${lists}" ${method})
- if [[ -n "$result" ]]; then
- echo "$result"
- [[ ! -t 1 ]] && exit 0
- fi
-
- # Scan Domains lists
- result=$(scanList ${domain} "/etc/pihole/*.domains" ${method})
- if [[ -n "$result" ]]; then
- sort -t . -k 2 -g <<< "$result"
- else
- [ -n "$method" ] && exact="exact "
- echo "::: No ${exact}results found for ${domain}"
- fi
-
exit 0
}
From 2fea5d428d95030ad22393e9f8fc1d9653136375 Mon Sep 17 00:00:00 2001
From: Jacob Salmela
Date: Sat, 27 May 2017 15:47:15 -0500
Subject: [PATCH 056/162] condense repetitive code into functions
---
advanced/Scripts/piholeDebug.sh | 183 ++++++++++++--------------------
1 file changed, 66 insertions(+), 117 deletions(-)
diff --git a/advanced/Scripts/piholeDebug.sh b/advanced/Scripts/piholeDebug.sh
index dff5efeb..3c04d909 100755
--- a/advanced/Scripts/piholeDebug.sh
+++ b/advanced/Scripts/piholeDebug.sh
@@ -1,4 +1,4 @@
-#!/usr/bin/env bash
+check_critical_program_versions#!/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.
@@ -133,48 +133,57 @@ if_directory_exists() {
fi
}
-# Checks the core version of the Pi-hole codebase
-check_core_version() {
- echo_current_diagnostic "Pi-hole versions"
+compare_local_version_to_git_version() {
+ # The git directory to check
+ local git_dir="${1}"
+ # The named component of the project (Core or Web)
+ local pihole_component="${2}"
+ # If we are checking the Core versions,
+ if [[ "${pihole_component}" == "Core" ]]; then
+ # We need to search for "Pi-hole" when using pihole -v
+ local search_term="Pi-hole"
+ elif [[ "${pihole_component}" == "Web" ]]; then
+ local search_term="AdminLTE"
+ fi
+ # Display what we are checking
+ echo_current_diagnostic "${pihole_component} version"
# Store the error message in a variable in case we want to change and/or reuse it
local error_msg="git status failed"
# If the pihole git directory exists,
- if_directory_exists "${PIHOLEGITDIR}" && \
+ if_directory_exists "${git_dir}" && \
# move into it
- cd "${PIHOLEGITDIR}" || \
- # if not, report an error
- log_write "pihole repo does not exist"
- # If the git status command completes successfully,
- # we can assume we can get the information we want
+ cd "${git_dir}" || \
+ # If not, show an error
+ log_write "${COL_LIGHT_RED}Could not cd into ${git_dir}$COL_NC"
if git status &> /dev/null; then
# The current version the user is on
- PI_HOLE_VERSION=$(git describe --tags --abbrev=0);
+ local remote_version=$(git describe --tags --abbrev=0);
# What branch they are on
- PI_HOLE_BRANCH=$(git rev-parse --abbrev-ref HEAD);
+ local remote_branch=$(git rev-parse --abbrev-ref HEAD);
# The commit they are on
- PI_HOLE_COMMIT=$(git describe --long --dirty --tags --always)
+ local remote_commit=$(git describe --long --dirty --tags --always)
# echo this information out to the user in a nice format
# If the current version matches what pihole -v produces, the user is up-to-date
- if [[ "${PI_HOLE_VERSION}" == "$(pihole -v | awk '/Pi-hole/ {print $6}' | cut -d ')' -f1)" ]]; then
- log_write "${TICK} Core: ${COL_LIGHT_GREEN}${PI_HOLE_VERSION}${COL_NC}"
+ if [[ "${remote_version}" == "$(pihole -v | awk '/${search_term}/ {print $6}' | cut -d ')' -f1)" ]]; then
+ log_write "${TICK} ${pihole_component}: ${COL_LIGHT_GREEN}${remote_version}${COL_NC}"
# If not,
else
# echo the current version in yellow, signifying it's something to take a look at, but not a critical error
# Also add a URL to an FAQ
- log_write "${INFO} Core: ${COL_YELLOW}${PI_HOLE_VERSION:-Untagged}${COL_NC} (${COL_CYAN}${FAQ_UPDATE_PI_HOLE}${COL_NC})"
+ log_write "${INFO} ${pihole_component}: ${COL_YELLOW}${remote_version:-Untagged}${COL_NC} (${COL_CYAN}${FAQ_UPDATE_PI_HOLE}${COL_NC})"
fi
# If the repo is on the master branch, they are on the stable codebase
- if [[ "${PI_HOLE_BRANCH}" == "master" ]]; then
+ if [[ "${remote_branch}" == "master" ]]; then
# so the color of the text is green
- log_write "${INFO} Branch: ${COL_LIGHT_GREEN}${PI_HOLE_BRANCH}${COL_NC}"
+ log_write "${INFO} Branch: ${COL_LIGHT_GREEN}${remote_branch}${COL_NC}"
# If it is any other branch, they are in a developement 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}${PI_HOLE_BRANCH:-Detached}${COL_NC} (${COL_CYAN}${FAQ_CHECKOUT_COMMAND}${COL_NC})"
+ log_write "${INFO} Branch: ${COL_YELLOW}${remote_branch:-Detached}${COL_NC} (${COL_CYAN}${FAQ_CHECKOUT_COMMAND}${COL_NC})"
fi
# echo the current commit
- log_write "${INFO} Commit: ${PI_HOLE_COMMIT}\n"
+ log_write "${INFO} Commit: ${remote_commit}"
# If git status failed,
else
# Return an error message
@@ -182,123 +191,65 @@ check_core_version() {
# and exit with a non zero code
return 1
fi
-}
-check_web_version() {
- # Local variable for the error message
- local error_msg="git status failed"
- # If the directory exists,
- if_directory_exists "${ADMINGITDIR}" && \
- # move into it
- cd "${ADMINGITDIR}" || \
- # if not, give an error message
- log_write "repo does not exist"
- # If the git status command completes successfully,
- # we can assume we can get the information we want
- if git status &> /dev/null; then
- # The current version the user is on
- WEB_VERSION=$(git describe --tags --abbrev=0);
- # What branch they are on
- WEB_BRANCH=$(git rev-parse --abbrev-ref HEAD);
- # The commit they are on
- WEB_COMMIT=$(git describe --long --dirty --tags --always)
- # If the Web version reported by pihole -v matches the current version
- if [[ "${WEB_VERSION}" == "$(pihole -v | awk '/AdminLTE/ {print $6}' | cut -d ')' -f1)" ]]; then
- # echo it in green
- log_write "${TICK} Web: ${COL_LIGHT_GREEN}${WEB_VERSION}${COL_NC}"
- # Otherwise,
- else
- # Show it in yellow with a link to update Pi-hole
- log_write "${INFO} Web: ${COL_YELLOW}${WEB_VERSION:-Untagged}${COL_NC} (${COL_CYAN}${FAQ_UPDATE_PI_HOLE}${COL_NC})"
- fi
-
-
- # If the repo is on the master branch, they are on the stable codebase
- if [[ "${WEB_BRANCH}" == "master" ]]; then
- # so the color of the text is green
- log_write "${TICK} Branch: ${COL_LIGHT_GREEN}${WEB_BRANCH}${COL_NC}"
- else
- # If it is any other branch, they are in a developement branch
- # 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}${WEB_BRANCH:-Detached}${COL_NC} (${COL_CYAN}${FAQ_CHECKOUT_COMMAND}${COL_NC})"
- fi
- # echo the current commit
- log_write "${INFO} Commit: ${WEB_COMMIT}\n"
- # If git status failed,
- else
- # Return an error message
- log_write "${error_msg}"
- # and exit with a non zero code
- return 1
- fi
}
check_ftl_version() {
+ local ftl_name="FTL"
+ echo_current_diagnostic "${ftl_name} version"
# Use the built in command to check FTL's version
FTL_VERSION=$(pihole-FTL version)
# 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: ${COL_LIGHT_GREEN}${FTL_VERSION}${COL_NC}"
+ log_write "${TICK} ${ftl_name}: ${COL_LIGHT_GREEN}${FTL_VERSION}${COL_NC}"
else
# If not, show it in yellow, signifying there is an update
- log_write "${TICK} FTL: ${COL_YELLOW}${FTL_VERSION}${COL_NC}"
+ log_write "${TICK} ${ftl_name}: ${COL_YELLOW}${FTL_VERSION}${COL_NC}"
fi
}
-# Check the current version of the Web server
-check_web_server_version() {
- # Store the name in a variable in case we ever want to change it
- WEB_SERVER="lighttpd"
- # Parse out just the version number
- WEB_SERVER_VERSON="$(lighttpd -v |& head -n1 | cut -d '/' -f2 | cut -d ' ' -f1)"
+# Checks the core version of the Pi-hole codebase
+check_component_versions() {
+ # Check the Web version, branch, and commit
+ compare_local_version_to_git_version "${PIHOLEGITDIR}" "Core"
+ # Check the Web version, branch, and commit
+ compare_local_version_to_git_version "${ADMINGITDIR}" "Web"
+ # Check the FTL version
+ check_ftl_version
+}
+
+
+get_program_version() {
+ local program_name="${1}"
+ local program_version
+ echo_current_diagnostic "${program_name} version"
+ case "${program_name}" in
+ "lighttpd") program_version="$(${program_name} -v |& head -n1 | cut -d '/' -f2 | cut -d ' ' -f1)"
+ ;;
+ "dnsmasq") program_version="$(${program_name} -v |& head -n1 | awk '{print $3}')"
+ ;;
+ "php") program_version="$(${program_name} -v |& head -n1 | cut -d '-' -f1 | cut -d ' ' -f2)"
+ ;;
+ *) echo "Unrecognized program";
+ esac
# If the Web server does not have a version (the variable is empty)
- if [[ -z "${WEB_SERVER_VERSON}" ]]; then
+ if [[ -z "${program_version}" ]]; then
# Display and error
- log_write "${CROSS} ${COL_LIGHT_RED}${WEB_SERVER} version could not be detected.${COL_NC}"
+ log_write "${CROSS} ${COL_LIGHT_RED}${program_name} version could not be detected.${COL_NC}"
else
# Otherwise, display the version
- log_write "${TICK} ${WEB_SERVER}: ${WEB_SERVER_VERSON}"
- fi
-}
-
-# Check the current version of the DNS server
-check_resolver_server_version() {
- # Store the name in a variable in case we ever want to change it
- RESOLVER="dnsmasq"
- # Parse out just the version number
- RESOVLER_VERSON="$(dnsmasq -v |& head -n1 | awk '{print $3}')"
- # If the DNS server does not have a version (the variable is empty)
- if [[ -z "${RESOVLER_VERSON}" ]]; then
- # Display and error
- log_write "${CROSS} ${COL_LIGHT_RED}${RESOLVER} version could not be detected.${COL_NC}"
- else
- # Otherwise, display the version
- log_write "${TICK} ${RESOLVER}: ${RESOVLER_VERSON}"
- fi
-}
-
-check_php_version() {
- # Parse out just the version number
- PHP_VERSION=$(php -v |& head -n1 | cut -d '-' -f1 | cut -d ' ' -f2)
- # If no version is detected,
- if [[ -z "${PHP_VERSION}" ]]; then
- # show an error
- log_write "${CROSS} ${COL_LIGHT_RED}PHP version could not be detected.${COL_NC}"
- else
- # Otherwise, show the version
- log_write "${TICK} PHP: ${PHP_VERSION}"
+ log_write "${TICK} ${program_name}: ${program_version}"
fi
}
# These are the most critical dependencies of Pi-hole, so we check for them
# and their versions, using the functions above.
-check_critical_dependencies() {
- echo_current_diagnostic "Versions of critical dependencies"
+check_critical_program_versions() {
# Use the function created earlier and bundle them into one function that checks all the version numbers
- check_web_server_version
- check_resolver_server_version
- check_php_version
+ get_program_version "dnsmasq"
+ get_program_version "lighttpd"
+ get_program_version "php"
}
get_distro_attributes() {
@@ -877,9 +828,8 @@ upload_to_tricorder() {
# Run through all the functions we made
make_temporary_log
initiate_debug
-check_core_version
-check_web_version
-check_ftl_version
+check_component_versions
+check_critical_program_versions
# setupVars.conf needs to be sourced before the networking so the values are
# available to the check_networking function
diagnose_setup_variables
@@ -889,7 +839,6 @@ check_networking
check_name_resolution
process_status
check_x_headers
-check_critical_dependencies
analyze_gravity_list
check_dnsmasq_d
check_lighttpd_d
From d51c067e1bddfc8d5d3b9264b72275cb064c8b8d Mon Sep 17 00:00:00 2001
From: Jacob Salmela
Date: Sat, 27 May 2017 21:21:18 -0500
Subject: [PATCH 057/162] change some verbiage; new function to compare the
ports in use to the services assigned to them.
---
advanced/Scripts/piholeDebug.sh | 117 ++++++++++++++++----------------
1 file changed, 57 insertions(+), 60 deletions(-)
diff --git a/advanced/Scripts/piholeDebug.sh b/advanced/Scripts/piholeDebug.sh
index 3c04d909..8fe1d346 100755
--- a/advanced/Scripts/piholeDebug.sh
+++ b/advanced/Scripts/piholeDebug.sh
@@ -55,6 +55,18 @@ else
OVER="\r\033[K"
fi
+source_setup_variables() {
+ # Display the current test that is running
+ log_write "\n${COL_LIGHT_PURPLE}*** [ INITIALIZING ]${COL_NC} Sourcing setup varibles"
+ # If the variable file exists,
+ if_file_exists "${VARSFILE}" && \
+ log_write "${INFO} Sourcing ${VARSFILE}...";
+ # source it
+ source ${VARSFILE} || \
+ # If it can't, show an error
+ log_write "${VARSFILE} ${COL_LIGHT_RED}does not exist or cannot be read.${COL_NC}"
+}
+
make_temporary_log() {
# Create temporary file for log
TEMPLOG=$(mktemp /tmp/pihole_temp.XXXXXX)
@@ -205,7 +217,7 @@ check_ftl_version() {
log_write "${TICK} ${ftl_name}: ${COL_LIGHT_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}"
+ log_write "${TICK} ${ftl_name}: ${COL_YELLOW}${FTL_VERSION}${COL_NC} ${FAQ_UPDATE_PI_HOLE}"
fi
}
@@ -310,6 +322,13 @@ processor_check() {
fi
}
+parse_setup_vars() {
+ echo_current_diagnostic "Setup variables"
+ if_file_exists "${VARSFILE}" && \
+ parse_file "${VARSFILE}" || \
+ log_write "${CROSS} ${COL_LIGHT_RED}Could not read ${VARSFILE}.${COL_NC}"
+}
+
detect_ip_addresses() {
# First argument should be a 4 or a 6
local protocol=${1}
@@ -323,16 +342,16 @@ detect_ip_addresses() {
# Local iterator
local i
# Display the protocol and interface
- log_write "${TICK} IPv${protocol} on ${PIHOLE_INTERFACE}"
+ log_write "${TICK} IPv${protocol} address(es) bound to the ${PIHOLE_INTERFACE} interface:"
# Since there may be more than one IP address, store them in an array
for i in "${!ip_addr_list[@]}"; do
# For each one in the list, print it out
- log_write "${ip_addr_list[$i]}"
+ log_write " ${ip_addr_list[$i]}"
done
log_write ""
else
# If there are no IPs detected, explain that the protocol is not configured
- log_write "${CROSS} ${COL_LIGHT_RED}No IPv${protocol} found on ${PIHOLE_INTERFACE}${COL_NC}\n"
+ log_write "${CROSS} ${COL_LIGHT_RED}No IPv${protocol} address(es) found on the ${PIHOLE_INTERFACE}${COL_NC} interace.\n"
return 1
fi
}
@@ -360,21 +379,21 @@ ping_gateway() {
# If the gateway variable has a value (meaning a gateway was found),
if [[ -n "${gateway}" ]]; then
- log_write "${INFO} Default gateway: ${gateway}"
+ log_write "${INFO} Default IPv${protocol} gateway: ${gateway}"
# Let the user know we will ping the gateway for a response
- log_write "* Trying three pings on IPv${protocol} gateway at ${gateway}..."
+ log_write "* Pinging IPv${protocol} gateway..."
# Try to quietly ping the gateway 3 times, with a timeout of 3 seconds, using numeric output only,
# on the pihole interface, and tail the last three lines of the output
# If pinging the gateway is not successful,
- if ! ping_cmd="$(${cmd} -q -c 3 -W 3 -n ${gateway} -I ${PIHOLE_INTERFACE} | tail -n 3)"; then
+ if ! ${cmd} -c 3 -W 3 -n ${gateway} -I ${PIHOLE_INTERFACE} | tail -n 3; then
# let the user know
- log_write "${CROSS} ${COL_LIGHT_RED}Gateway did not respond.${COL_NC}\n"
+ log_write "${CROSS} ${COL_LIGHT_RED}Gateway did not respond.${COL_NC}"
# and return an error code
return 1
# Otherwise,
else
# show a success
- log_write "${TICK} ${COL_LIGHT_GREEN}Gateway responded.${COL_NC}\n"
+ log_write "${TICK} ${COL_LIGHT_GREEN}Gateway responded.${COL_NC}"
# and return a success code
return 0
fi
@@ -396,9 +415,9 @@ ping_internet() {
# and Google's public IPv4 address
local public_address="8.8.8.8"
fi
- echo -n "${INFO} Trying three pings on IPv${protocol} to reach the Internet..."
+ log_write "* Checking Internet connectivity via IPv${protocol}..."
# Try to ping the address 3 times
- if ! ping_inet="$(${cmd} -q -W 3 -c 3 -n ${public_address} -I ${PIHOLE_INTERFACE} | tail -n 3)"; then
+ if ! ping_inet="$(${cmd} -W 3 -c 3 -n ${public_address} -I ${PIHOLE_INTERFACE} | tail -n 3)"; then
# if it's unsuccessful, show an error
log_write "${CROSS} ${COL_LIGHT_RED}Cannot reach the Internet.${COL_NC}\n"
return 1
@@ -409,10 +428,28 @@ ping_internet() {
fi
}
+compare_port_to_service_assigned() {
+ local service_name="${1}"
+ local resolver="dnsmasq"
+ local web_server="lighttpd"
+ local ftl="pihole-FT"
+ if [[ "${service_name}" == "${resolver}" ]] || [[ "${service_name}" == "${web_server}" ]] || [[ "${service_name}" == "${ftl}" ]]; then
+ # if port 53 is dnsmasq, show it in green as it's standard
+ log_write "[${COL_LIGHT_GREEN}${port_number}${COL_NC}] is in use by ${COL_LIGHT_GREEN}${service_name}${COL_NC}"
+ # Otherwise,
+ else
+ # Show the service name in red since it's non-standard
+ log_write "[${COL_LIGHT_RED}${port_number}${COL_NC}] is in use by ${COL_LIGHT_RED}${service_name}${COL_NC} (${COL_CYAN}https://discourse.pi-hole.net/t/hardware-software-requirements/273#ports${COL_NC})"
+ fi
+}
+
check_required_ports() {
+ echo_current_diagnostic "Ports in use"
# Since Pi-hole needs 53, 80, and 4711, check what they are being used by
# so we can detect any issues
- log_write "${INFO} Ports in use:"
+ local resolver="dnsmasq"
+ local web_server="lighttpd"
+ local ftl="pihole-FT"
# Create an array for these ports in use
ports_in_use=()
# Sort the addresses and remove duplicates
@@ -427,35 +464,11 @@ check_required_ports() {
local service_name=$(echo "${ports_in_use[$i]}" | awk '{print $2}')
# Use a case statement to determine if the right services are using the right ports
case "${port_number}" in
- 53) if [[ "${service_name}" == "dnsmasq" ]]; then
- # if port 53 is dnsmasq, show it in green as it's standard
- log_write "[${COL_LIGHT_GREEN}${port_number}${COL_NC}] is in use by ${COL_LIGHT_GREEN}${service_name}${COL_NC}"
- # Otherwise,
- else
- # Show the service name in red since it's non-standard
- log_write "[${COL_LIGHT_RED}${port_number}${COL_NC}] is in use by ${COL_LIGHT_RED}${service_name}${COL_NC}
- Please see: ${COL_CYAN}https://discourse.pi-hole.net/t/hardware-software-requirements/273#ports${COL_NC}"
- fi
+ 53) compare_port_to_service_assigned "${resolver}"
;;
- 80) if [[ "${service_name}" == "lighttpd" ]]; then
- # if port 53 is dnsmasq, show it in green as it's standard
- log_write "[${COL_LIGHT_GREEN}${port_number}${COL_NC}] is in use by ${COL_LIGHT_GREEN}${service_name}${COL_NC}"
- # Otherwise,
- else
- # Show the service name in red since it's non-standard
- log_write "[${COL_LIGHT_RED}${port_number}${COL_NC}] is in use by ${COL_LIGHT_RED}${service_name}${COL_NC}
- Please see: ${COL_CYAN}https://discourse.pi-hole.net/t/hardware-software-requirements/273#ports${COL_NC}"
- fi
+ 80) compare_port_to_service_assigned "${web_server}"
;;
- 4711) if [[ "${service_name}" == "pihole-FT" ]]; then
- # if port 4711 is pihole-FTL, show it in green as it's standard
- log_write "[${COL_LIGHT_GREEN}${port_number}${COL_NC}] is in use by ${COL_LIGHT_GREEN}${service_name}${COL_NC}"
- # Otherwise,
- else
- # Show the service name in yellow since it's non-standard, but should still work
- log_write "[${COL_YELLOW}${port_number}${COL_NC}] is in use by ${COL_YELLOW}${service_name}${COL_NC}
- Please see: ${COL_CYAN}https://discourse.pi-hole.net/t/hardware-software-requirements/273#ports${COL_NC}"
- fi
+ 4711) compare_port_to_service_assigned "${ftl}"
;;
*) log_write "[${port_number}] is in use by ${service_name}";
esac
@@ -467,8 +480,8 @@ check_networking() {
# together since they are all related to the networking aspect of things
echo_current_diagnostic "Networking"
detect_ip_addresses "4"
- ping_gateway "4"
detect_ip_addresses "6"
+ ping_gateway "4"
ping_gateway "6"
check_required_ports
}
@@ -639,23 +652,6 @@ parse_file() {
IFS="$OLD_IFS"
}
-diagnose_setup_variables() {
- # Display the current test that is running
- echo_current_diagnostic "Setup variables"
-
- # If the variable file exists,
- if_file_exists "${VARSFILE}" && \
- log_write "* Sourcing ${VARSFILE}...";
- # source it
- source ${VARSFILE};
- # and display a green check mark with ${DONE}
- echo_succes_or_fail "${COL_LIGHT_GREEN}${VARSFILE}${COL_NC} is readable and ${COL_LIGHT_GREEN}has been sourced.${COL_NC}" || \
- # Othwerwise, error out
- echo_succes_or_fail "${VARSFILE} ${COL_LIGHT_RED}is not readable.${COL_NC}
- ${INFO} $(ls -l ${VARSFILE} 2>/dev/null)";
- parse_file "${VARSFILE}"
-}
-
check_name_resolution() {
# Check name resoltion from localhost, Pi-hole's IP, and Google's name severs
# using the function we created earlier
@@ -827,17 +823,18 @@ upload_to_tricorder() {
# Run through all the functions we made
make_temporary_log
+# setupVars.conf needs to be sourced before the networking so the values are
+# available to the other functions
initiate_debug
+source_setup_variables
check_component_versions
check_critical_program_versions
-# setupVars.conf needs to be sourced before the networking so the values are
-# available to the check_networking function
-diagnose_setup_variables
diagnose_operating_system
processor_check
check_networking
check_name_resolution
process_status
+parse_setup_vars
check_x_headers
analyze_gravity_list
check_dnsmasq_d
From 570c54002f3dfb212dff57a3708e83b1b27a4252 Mon Sep 17 00:00:00 2001
From: Dan Schaper
Date: Tue, 30 May 2017 23:51:22 -0700
Subject: [PATCH 058/162] Update ISSUE_TEMPLATE.md
---
.github/ISSUE_TEMPLATE.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md
index 3014625b..066b3f8f 100644
--- a/.github/ISSUE_TEMPLATE.md
+++ b/.github/ISSUE_TEMPLATE.md
@@ -9,7 +9,7 @@
_{replace this text with a number from 1 to 10, with 1 being not familiar, and 10 being very familiar}_
---
-**[FEATURE REQUEST | QUESTION | OTHER]:**
+**[BUG REPORT | QUESTION | OTHER]:**
Please [submit your feature request here](https://discourse.pi-hole.net/c/feature-requests), so it is votable by the community. It's also easier for us to track.
From 3a58e9d33abf843e42c44d1bfda69339b468450b Mon Sep 17 00:00:00 2001
From: Dan Schaper
Date: Wed, 31 May 2017 00:02:57 -0700
Subject: [PATCH 059/162] Remove Question option
---
.github/ISSUE_TEMPLATE.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md
index 066b3f8f..23e67795 100644
--- a/.github/ISSUE_TEMPLATE.md
+++ b/.github/ISSUE_TEMPLATE.md
@@ -9,7 +9,7 @@
_{replace this text with a number from 1 to 10, with 1 being not familiar, and 10 being very familiar}_
---
-**[BUG REPORT | QUESTION | OTHER]:**
+**[BUG REPORT | OTHER]:**
Please [submit your feature request here](https://discourse.pi-hole.net/c/feature-requests), so it is votable by the community. It's also easier for us to track.
From b207fadc04f16422d00a9b0bf9c03567f1ef5fcd Mon Sep 17 00:00:00 2001
From: Jacob Salmela
Date: Thu, 1 Jun 2017 00:18:06 -0500
Subject: [PATCH 060/162] check if os is supported based on pretty name
---
advanced/Scripts/piholeDebug.sh | 37 ++++++++++++++++++++++-----------
1 file changed, 25 insertions(+), 12 deletions(-)
diff --git a/advanced/Scripts/piholeDebug.sh b/advanced/Scripts/piholeDebug.sh
index 8fe1d346..d5e2c9d7 100755
--- a/advanced/Scripts/piholeDebug.sh
+++ b/advanced/Scripts/piholeDebug.sh
@@ -19,6 +19,8 @@ set -o pipefail
#IFS=$'\n\t'
######## GLOBAL VARS ########
+SUPPORTED_OS=("Raspbian" "Ubduntu" "Fedora" "Debian" "CentOS")
+
VARSFILE="/etc/pihole/setupVars.conf"
DEBUG_LOG="/var/log/pihole_debug.log"
DNSMASQFILE="/etc/dnsmasq.conf"
@@ -37,8 +39,9 @@ readonly FTLLOG="/var/log/pihole-FTL.log"
coltable=/opt/pihole/COL_TABLE
# FAQ URLs
-FAQ_UPDATE_PI_HOLE="https://discourse.pi-hole.net/t/how-do-i-update-pi-hole/249"
-FAQ_CHECKOUT_COMMAND="https://discourse.pi-hole.net/t/the-pihole-command-with-examples/738#checkout"
+FAQ_UPDATE_PI_HOLE="${COL_CYAN}https://discourse.pi-hole.net/t/how-do-i-update-pi-hole/249${COL_NC}"
+FAQ_CHECKOUT_COMMAND="${COL_CYAN}https://discourse.pi-hole.net/t/the-pihole-command-with-examples/738#checkout${COL_NC}"
+FAQ_HARDWARE_REQUIREMENTS="${COL_CYAN}https://discourse.pi-hole.net/t/hardware-software-requirements/273${COL_NC}"
# These provide the colors we need for making the log more readable
if [[ -f ${coltable} ]]; then
@@ -182,7 +185,7 @@ compare_local_version_to_git_version() {
else
# echo the current version in yellow, signifying it's something to take a look at, but not a critical error
# Also add a URL to an FAQ
- log_write "${INFO} ${pihole_component}: ${COL_YELLOW}${remote_version:-Untagged}${COL_NC} (${COL_CYAN}${FAQ_UPDATE_PI_HOLE}${COL_NC})"
+ log_write "${INFO} ${pihole_component}: ${COL_YELLOW}${remote_version:-Untagged}${COL_NC} (${FAQ_UPDATE_PI_HOLE})"
fi
# If the repo is on the master branch, they are on the stable codebase
@@ -192,7 +195,7 @@ compare_local_version_to_git_version() {
# If it is any other branch, they are in a developement 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}${remote_branch:-Detached}${COL_NC} (${COL_CYAN}${FAQ_CHECKOUT_COMMAND}${COL_NC})"
+ log_write "${INFO} Branch: ${COL_YELLOW}${remote_branch:-Detached}${COL_NC} (${FAQ_CHECKOUT_COMMAND})"
fi
# echo the current commit
log_write "${INFO} Commit: ${remote_commit}"
@@ -203,7 +206,6 @@ compare_local_version_to_git_version() {
# and exit with a non zero code
return 1
fi
-
}
check_ftl_version() {
@@ -217,7 +219,7 @@ check_ftl_version() {
log_write "${TICK} ${ftl_name}: ${COL_LIGHT_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 "${TICK} ${ftl_name}: ${COL_YELLOW}${FTL_VERSION}${COL_NC} (${FAQ_UPDATE_PI_HOLE})"
fi
}
@@ -264,6 +266,19 @@ check_critical_program_versions() {
get_program_version "php"
}
+is_os_supported() {
+ local os_to_check="${1}"
+ the_os=$(echo ${os_to_check} | sed 's/ .*//')
+ case "${the_os}" in
+ "Raspbian") log_write "${TICK} ${COL_LIGHT_GREEN}${os_to_check}${COL_NC}";;
+ "Ubsuntu") log_write "${TICK} ${COL_LIGHT_GREEN}${os_to_check}${COL_NC}";;
+ "Fedora") log_write "${TICK} ${COL_LIGHT_GREEN}${os_to_check}${COL_NC}";;
+ "Debian") log_write "${TICK} ${COL_LIGHT_GREEN}${os_to_check}${COL_NC}";;
+ "CentOS") log_write "${TICK} ${COL_LIGHT_GREEN}${os_to_check}${COL_NC}";;
+ *) log_write "${CROSS} ${COL_LIGHT_RED}${os_to_check}${COL_NC} (${FAQ_HARDWARE_REQUIREMENTS})";
+ esac
+}
+
get_distro_attributes() {
# Put the current Internal Field Separator into another variable so it can be restored later
OLD_IFS="$IFS"
@@ -279,10 +294,10 @@ get_distro_attributes() {
local pretty_name_key=$(echo "${distro_attribute}" | grep "PRETTY_NAME" | cut -d '=' -f1)
# we need just the OS PRETTY_NAME,
if [[ "${pretty_name_key}" == "PRETTY_NAME" ]]; then
- # so print it when we find it
+ # so save in in a variable when we find it
PRETTY_NAME_VALUE=$(echo "${distro_attribute}" | grep "PRETTY_NAME" | cut -d '=' -f2- | tr -d '"')
- # and then echoed out to the screen
- log_write "${INFO} ${PRETTY_NAME_VALUE}"
+ # then pass it as an argument that checks if the OS is supported
+ is_os_supported "${PRETTY_NAME_VALUE}"
else
# Since we only need the pretty name, we can just skip over anything that is not a match
:
@@ -293,8 +308,6 @@ get_distro_attributes() {
}
diagnose_operating_system() {
- # local variable for system requirements
- FAQ_HARDWARE_REQUIREMENTS="https://discourse.pi-hole.net/t/hardware-software-requirements/273"
# error message in a variable so we can easily modify it later (or re-use it)
local error_msg="Distribution unknown -- most likely you are on an unsupported platform and may run into issues."
# Display the current test that is running
@@ -305,7 +318,7 @@ diagnose_operating_system() {
# display the attributes to the user from the function made earlier
get_distro_attributes || \
# If it doesn't exist, it's not a system we currently support and link to FAQ
- log_write "${CROSS} ${COL_LIGHT_RED}${error_msg}${COL_NC} (${COL_CYAN}${FAQ_HARDWARE_REQUIREMENTS}${COL_NC})"
+ log_write "${CROSS} ${COL_LIGHT_RED}${error_msg}${COL_NC} (${FAQ_HARDWARE_REQUIREMENTS})"
}
processor_check() {
From 02a601deff7f46f470b533a88915b766dc939e27 Mon Sep 17 00:00:00 2001
From: Jacob Salmela
Date: Thu, 1 Jun 2017 00:19:15 -0500
Subject: [PATCH 061/162] comment out dir checks for lighttpd, cronm and http
as they have a lot of other files that need parsing through. May need to
increase the logic there if this is information we really need to know.
---
advanced/Scripts/piholeDebug.sh | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/advanced/Scripts/piholeDebug.sh b/advanced/Scripts/piholeDebug.sh
index d5e2c9d7..15576223 100755
--- a/advanced/Scripts/piholeDebug.sh
+++ b/advanced/Scripts/piholeDebug.sh
@@ -851,8 +851,8 @@ parse_setup_vars
check_x_headers
analyze_gravity_list
check_dnsmasq_d
-check_lighttpd_d
-check_http_directory
-check_cron_d
+# check_lighttpd_d
+# check_http_directory
+# check_cron_d
copy_to_debug_log
upload_to_tricorder
From 8b4c0b456b672713bfa138af7bb79b8df283e89d Mon Sep 17 00:00:00 2001
From: Jacob Salmela
Date: Thu, 1 Jun 2017 01:15:11 -0500
Subject: [PATCH 062/162] exclude webpassword from being uploaded. also check
that the IP addresses detected match those defined in setupVars.conf
---
advanced/Scripts/piholeDebug.sh | 111 +++++++++++++++++++++-----------
1 file changed, 74 insertions(+), 37 deletions(-)
diff --git a/advanced/Scripts/piholeDebug.sh b/advanced/Scripts/piholeDebug.sh
index 15576223..954c6c31 100755
--- a/advanced/Scripts/piholeDebug.sh
+++ b/advanced/Scripts/piholeDebug.sh
@@ -19,7 +19,7 @@ set -o pipefail
#IFS=$'\n\t'
######## GLOBAL VARS ########
-SUPPORTED_OS=("Raspbian" "Ubduntu" "Fedora" "Debian" "CentOS")
+SUPPORTED_OS=("Raspbian" "Ubuntu" "Fedora" "Debian" "CentOS")
VARSFILE="/etc/pihole/setupVars.conf"
DEBUG_LOG="/var/log/pihole_debug.log"
@@ -38,11 +38,6 @@ WHITELISTMATCHES="/tmp/whitelistmatches.list"
readonly FTLLOG="/var/log/pihole-FTL.log"
coltable=/opt/pihole/COL_TABLE
-# FAQ URLs
-FAQ_UPDATE_PI_HOLE="${COL_CYAN}https://discourse.pi-hole.net/t/how-do-i-update-pi-hole/249${COL_NC}"
-FAQ_CHECKOUT_COMMAND="${COL_CYAN}https://discourse.pi-hole.net/t/the-pihole-command-with-examples/738#checkout${COL_NC}"
-FAQ_HARDWARE_REQUIREMENTS="${COL_CYAN}https://discourse.pi-hole.net/t/hardware-software-requirements/273${COL_NC}"
-
# These provide the colors we need for making the log more readable
if [[ -f ${coltable} ]]; then
source ${coltable}
@@ -58,6 +53,13 @@ else
OVER="\r\033[K"
fi
+# FAQ URLs
+FAQ_UPDATE_PI_HOLE="${COL_CYAN}https://discourse.pi-hole.net/t/how-do-i-update-pi-hole/249${COL_NC}"
+FAQ_CHECKOUT_COMMAND="${COL_CYAN}https://discourse.pi-hole.net/t/the-pihole-command-with-examples/738#checkout${COL_NC}"
+FAQ_HARDWARE_REQUIREMENTS="${COL_CYAN}https://discourse.pi-hole.net/t/hardware-software-requirements/273${COL_NC}"
+FAQ_GATEWAY="${COL_CYAN}https://discourse.pi-hole.net/{PLACEHOLDER}${COL_NC}"
+FAQ_ULA="${COL_CYAN}https://discourse.pi-hole.net/t/use-ipv6-ula-addresses-for-pi-hole/2127${COL_NC}"
+
source_setup_variables() {
# Display the current test that is running
log_write "\n${COL_LIGHT_PURPLE}*** [ INITIALIZING ]${COL_NC} Sourcing setup varibles"
@@ -271,7 +273,7 @@ is_os_supported() {
the_os=$(echo ${os_to_check} | sed 's/ .*//')
case "${the_os}" in
"Raspbian") log_write "${TICK} ${COL_LIGHT_GREEN}${os_to_check}${COL_NC}";;
- "Ubsuntu") log_write "${TICK} ${COL_LIGHT_GREEN}${os_to_check}${COL_NC}";;
+ "Ubuntu") log_write "${TICK} ${COL_LIGHT_GREEN}${os_to_check}${COL_NC}";;
"Fedora") log_write "${TICK} ${COL_LIGHT_GREEN}${os_to_check}${COL_NC}";;
"Debian") log_write "${TICK} ${COL_LIGHT_GREEN}${os_to_check}${COL_NC}";;
"CentOS") log_write "${TICK} ${COL_LIGHT_GREEN}${os_to_check}${COL_NC}";;
@@ -342,6 +344,37 @@ parse_setup_vars() {
log_write "${CROSS} ${COL_LIGHT_RED}Could not read ${VARSFILE}.${COL_NC}"
}
+does_ip_match_setup_vars() {
+ # Check for IPv4 or 6
+ local protocol="${1}"
+ # IP address to check for
+ local ip_address="${2}"
+ # See what IP is in the setupVars.conf file
+ local setup_vars_ip=$(cat ${VARSFILE} | grep IPV${protocol}_ADDRESS | cut -d '=' -f2)
+ # If it's an IPv6 address
+ if [[ "${protocol}" == "6" ]]; then
+ # Strip off the /
+ if [[ "${ip_address%/*}" == "${setup_vars_ip}" ]]; then
+ # if it matches, show it in green
+ log_write " ${COL_LIGHT_GREEN}${ip_address%/*}${COL_NC}"
+ else
+ # otherwise show it in red with an FAQ URL
+ log_write " ${COL_LIGHT_RED}${ip_address%/*}${COL_NC} (${FAQ_ULA})"
+ fi
+
+ else
+ # if the protocol isn't 6, it's 4 so no need to strip the CIDR notation
+ # since it exists in the setupVars.conf that way
+ if [[ "${ip_address}" == "${setup_vars_ip}" ]]; then
+ # show in green if it matches
+ log_write " ${COL_LIGHT_GREEN}${ip_address}${COL_NC}"
+ else
+ # otherwise show it in red
+ log_write " ${COL_LIGHT_RED}${ip_address}${COL_NC} (${FAQ_ULA})"
+ fi
+ fi
+}
+
detect_ip_addresses() {
# First argument should be a 4 or a 6
local protocol=${1}
@@ -359,7 +392,8 @@ detect_ip_addresses() {
# Since there may be more than one IP address, store them in an array
for i in "${!ip_addr_list[@]}"; do
# For each one in the list, print it out
- log_write " ${ip_addr_list[$i]}"
+ does_ip_match_setup_vars "${protocol}" "${ip_addr_list[$i]}"
+ # log_write " ${ip_addr_list[$i]}"
done
log_write ""
else
@@ -367,25 +401,36 @@ detect_ip_addresses() {
log_write "${CROSS} ${COL_LIGHT_RED}No IPv${protocol} address(es) found on the ${PIHOLE_INTERFACE}${COL_NC} interace.\n"
return 1
fi
+ # If the protocol is v6
+ if [[ "${protocol}" == "6" ]]; then
+ # let the user know that as long as there is one green address, things should be ok
+ log_write " ^ Please note that you may have more than one IPv${protocol} address listed."
+ log_write " As long as one of them is green, it matches what is in ${VARSFILE} so there is no need for concern.\n"
+ log_write " The link to the FAQ is for an issue that sometimes occurs when the IPv6 address changes, which is why we check for it."
+ fi
}
-
-ping_gateway() {
- # First argument should be a 4 or a 6
+ping_ipv4_or_ipv6() {
+ # Give the first argument a readable name (a 4 or a six should be the argument)
local protocol="${1}"
# If the protocol is 6,
if [[ ${protocol} == "6" ]]; then
# use ping6
- local cmd="ping6"
+ cmd="ping6"
# and Google's public IPv6 address
- local public_address="2001:4860:4860::8888"
+ public_address="2001:4860:4860::8888"
else
# Otherwise, just use ping
- local cmd="ping"
+ cmd="ping"
# and Google's public IPv4 address
- local public_address="8.8.8.8"
+ public_address="8.8.8.8"
fi
+}
+ping_gateway() {
+ local protocol="${1}"
+ ping_ipv4_or_ipv6 "${protocol}"
+ # Check if we are using IPv4 or IPv6
# Find the default gateway using IPv4 or IPv6
local gateway
gateway="$(ip -${protocol} route | grep default | cut -d ' ' -f 3)"
@@ -394,13 +439,13 @@ ping_gateway() {
if [[ -n "${gateway}" ]]; then
log_write "${INFO} Default IPv${protocol} gateway: ${gateway}"
# Let the user know we will ping the gateway for a response
- log_write "* Pinging IPv${protocol} gateway..."
+ log_write "* Pinging ${gateway}..."
# Try to quietly ping the gateway 3 times, with a timeout of 3 seconds, using numeric output only,
# on the pihole interface, and tail the last three lines of the output
# If pinging the gateway is not successful,
- if ! ${cmd} -c 3 -W 3 -n ${gateway} -I ${PIHOLE_INTERFACE} | tail -n 3; then
+ if ! ${cmd} -c 3 -W 2 -n ${gateway} -I ${PIHOLE_INTERFACE} >/dev/null; then
# let the user know
- log_write "${CROSS} ${COL_LIGHT_RED}Gateway did not respond.${COL_NC}"
+ log_write "${CROSS} ${COL_LIGHT_RED}Gateway did not respond.${COL_NC} ($FAQ_GATEWAY)\n"
# and return an error code
return 1
# Otherwise,
@@ -414,23 +459,11 @@ ping_gateway() {
}
ping_internet() {
- # Give the first argument a readable name (a 4 or a six should be the argument)
local protocol="${1}"
- # If the protocol is 6,
- if [[ ${protocol} == "6" ]]; then
- # use ping6
- local cmd="ping6"
- # and Google's public IPv6 address
- local public_address="2001:4860:4860::8888"
- else
- # Otherwise, just use ping
- local cmd="ping"
- # and Google's public IPv4 address
- local public_address="8.8.8.8"
- fi
+ ping_ipv4_or_ipv6 "${protocol}"
log_write "* Checking Internet connectivity via IPv${protocol}..."
# Try to ping the address 3 times
- if ! ping_inet="$(${cmd} -W 3 -c 3 -n ${public_address} -I ${PIHOLE_INTERFACE} | tail -n 3)"; then
+ if ! ${cmd} -W 2 -c 3 -n ${public_address} -I ${PIHOLE_INTERFACE} >/dev/null; then
# if it's unsuccessful, show an error
log_write "${CROSS} ${COL_LIGHT_RED}Cannot reach the Internet.${COL_NC}\n"
return 1
@@ -658,8 +691,12 @@ parse_file() {
local file_lines
# For each line in the file,
for file_lines in "${file_info[@]}"; do
- # Display the file's content
+ if [[ ! -z "${file_lines}" ]]; then
+ # don't include the Web password hash
+ [[ "${file_linesline}" =~ ^\#.*$ || ! "${file_lines}" || "${file_lines}" == "WEBPASSWORD="* ]] && continue
+ # otherwise, display the lines of the file
log_write " ${file_lines}"
+ fi
done
# Set the IFS back to what it was
IFS="$OLD_IFS"
@@ -823,15 +860,15 @@ upload_to_tricorder() {
log_write "${COL_LIGHT_PURPLE}***********************************${COL_NC}"
log_write "${TICK} Your debug token is: ${COL_LIGHT_GREEN}${tricorder_token}${COL_NC}"
log_write "${COL_LIGHT_PURPLE}***********************************${COL_NC}"
-
- log_write " * Provide this token to the Pi-hole team for assistance:"
+ log_write ""
+ log_write " * Provide this token to the Pi-hole team for assistance at"
log_write " * ${COL_CYAN}https://discourse.pi-hole.net${COL_NC}"
- log_write " * Your log will self-destruct after ${COL_LIGHT_RED}48 hours${COL_NC}."
+ log_write " * Your log will self-destruct on our server after ${COL_LIGHT_RED}48 hours${COL_NC}."
else
log_write "${CROSS} ${COL_LIGHT_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
- log_write " * A local copy of the debug log can be found at : ${COL_CYAN}${DEBUG_LOG}${COL_NC}\n"
+ log_write " * A local copy of the debug log can be found at: ${COL_CYAN}${DEBUG_LOG}${COL_NC}\n"
}
# Run through all the functions we made
From 01e091fd170229c98d33adf96a8c207717cc16ea Mon Sep 17 00:00:00 2001
From: DL6ER
Date: Fri, 2 Jun 2017 23:01:48 +0200
Subject: [PATCH 063/162] Prefer ULA over GUA addresses [IPv6] (#1508)
* On installs with GUA and ULA's we should prefer ULA's as it's been demonstrated that GUA's can and often are rotated by ISPs. Fixes #1473
* Add test for link-local address detection
* Add ULA-only and GUA-only tests
* Add test_IPv6_GUA_ULA_test and test_IPv6_ULA_GUA_test
* Add ""
* Add mock_command_2 command that can mock a command with more than one argument (as "ip -6 address") and result multiple lines of results
* Make mock_command_2 more similar to the original mock_command
* Correct comments
* Fixed remaining comments
* Fixed one last comment...
* Fixed a comment...
---
automated install/basic-install.sh | 34 +++++++++++--
test/test_automated_install.py | 76 ++++++++++++++++++++++++++++++
2 files changed, 107 insertions(+), 3 deletions(-)
diff --git a/automated install/basic-install.sh b/automated install/basic-install.sh
index 42e06bdf..b8b44550 100755
--- a/automated install/basic-install.sh
+++ b/automated install/basic-install.sh
@@ -327,16 +327,44 @@ chooseInterface() {
fi
}
+# See https://github.com/pi-hole/pi-hole/issues/1473#issuecomment-301745953
+testIPv6() {
+ first="$(cut -f1 -d":" <<< "$1")"
+ value1=$(((0x$first)/256))
+ value2=$(((0x$first)%256))
+ ((($value1&254)==252)) && echo "ULA" || true
+ ((($value1&112)==32)) && echo "GUA" || true
+ ((($value1==254) && (($value2&192)==128))) && echo "Link-local" || true
+}
+
useIPv6dialog() {
- # Show the IPv6 address used for blocking
- IPV6_ADDRESS=$(ip -6 route get 2001:4860:4860::8888 | grep -v "unreachable" | awk -F " " '{ for(i=1;i<=NF;i++) if ($i == "src") print $(i+1) }')
+ # Determine the IPv6 address used for blocking
+ IPV6_ADDRESSES=($(ip -6 address | grep 'scope global' | awk '{print $2}'))
+
+ # Determine type of found IPv6 addresses
+ for i in "${IPV6_ADDRESSES[@]}"; do
+ result=$(testIPv6 "$i")
+ [[ "${result}" == "ULA" ]] && ULA_ADDRESS="$i"
+ [[ "${result}" == "GUA" ]] && GUA_ADDRESS="$i"
+ done
+
+ # Determine which address to be used: Prefer ULA over GUA or don't use any if none found
+ if [[ ! -z "${ULA_ADDRESS}" ]]; then
+ IPV6_ADDRESS="${ULA_ADDRESS}"
+ echo "::: Found IPv6 ULA address, using it for blocking IPv6 ads"
+ elif [[ ! -z "${GUA_ADDRESS}" ]]; then
+ echo "::: Found IPv6 GUA address, using it for blocking IPv6 ads"
+ IPV6_ADDRESS="${GUA_ADDRESS}"
+ else
+ echo "::: Found neither IPv6 ULA nor GUA address, blocking IPv6 ads will not be enabled"
+ IPV6_ADDRESS=""
+ fi
if [[ ! -z "${IPV6_ADDRESS}" ]]; then
whiptail --msgbox --backtitle "IPv6..." --title "IPv6 Supported" "$IPV6_ADDRESS will be used to block ads." ${r} ${c}
fi
}
-
use4andor6() {
local useIPv4
local useIPv6
diff --git a/test/test_automated_install.py b/test/test_automated_install.py
index 8e36fc96..60772625 100644
--- a/test/test_automated_install.py
+++ b/test/test_automated_install.py
@@ -402,6 +402,61 @@ def test_FTL_binary_installed_and_responsive_no_errors(Pihole):
# assert '644 /run/pihole-FTL.pid' in support_files.stdout
# assert '644 /var/log/pihole-FTL.log' in support_files.stdout
+def test_IPv6_only_link_local(Pihole):
+ ''' confirms IPv6 blocking is disabled for Link-local address '''
+ # mock ip -6 address to return Link-local address
+ mock_command_2('ip', {'-6 address':('inet6 fe80::d210:52fa:fe00:7ad7/64 scope link', '0')}, Pihole)
+ detectPlatform = Pihole.run('''
+ source /opt/pihole/basic-install.sh
+ useIPv6dialog
+ ''')
+ expected_stdout = 'Found neither IPv6 ULA nor GUA address, blocking IPv6 ads will not be enabled'
+ assert expected_stdout in detectPlatform.stdout
+
+def test_IPv6_only_ULA(Pihole):
+ ''' confirms IPv6 blocking is enabled for ULA addresses '''
+ # mock ip -6 address to return ULA address
+ mock_command_2('ip', {'-6 address':('inet6 fda2:2001:5555:0:d210:52fa:fe00:7ad7/64 scope global', '0')}, Pihole)
+ detectPlatform = Pihole.run('''
+ source /opt/pihole/basic-install.sh
+ useIPv6dialog
+ ''')
+ expected_stdout = 'Found IPv6 ULA address, using it for blocking IPv6 ads'
+ assert expected_stdout in detectPlatform.stdout
+
+def test_IPv6_only_GUA(Pihole):
+ ''' confirms IPv6 blocking is enabled for GUA addresses '''
+ # mock ip -6 address to return GUA address
+ mock_command_2('ip', {'-6 address':('inet6 2003:12:1e43:301:d210:52fa:fe00:7ad7/64 scope global', '0')}, Pihole)
+ detectPlatform = Pihole.run('''
+ source /opt/pihole/basic-install.sh
+ useIPv6dialog
+ ''')
+ expected_stdout = 'Found IPv6 GUA address, using it for blocking IPv6 ads'
+ assert expected_stdout in detectPlatform.stdout
+
+def test_IPv6_GUA_ULA_test(Pihole):
+ ''' confirms IPv6 blocking is enabled for GUA and ULA addresses '''
+ # mock ip -6 address to return GUA and ULA addresses
+ mock_command_2('ip', {'-6 address':('inet6 2003:12:1e43:301:d210:52fa:fe00:7ad7/64 scope global\ninet6 fda2:2001:5555:0:d210:52fa:fe00:7ad7/64 scope global', '0')}, Pihole)
+ detectPlatform = Pihole.run('''
+ source /opt/pihole/basic-install.sh
+ useIPv6dialog
+ ''')
+ expected_stdout = 'Found IPv6 ULA address, using it for blocking IPv6 ads'
+ assert expected_stdout in detectPlatform.stdout
+
+def test_IPv6_ULA_GUA_test(Pihole):
+ ''' confirms IPv6 blocking is enabled for GUA and ULA addresses '''
+ # mock ip -6 address to return ULA and GUA addresses
+ mock_command_2('ip', {'-6 address':('inet6 fda2:2001:5555:0:d210:52fa:fe00:7ad7/64 scope global\ninet6 2003:12:1e43:301:d210:52fa:fe00:7ad7/64 scope global', '0')}, Pihole)
+ detectPlatform = Pihole.run('''
+ source /opt/pihole/basic-install.sh
+ useIPv6dialog
+ ''')
+ expected_stdout = 'Found IPv6 ULA address, using it for blocking IPv6 ads'
+ assert expected_stdout in detectPlatform.stdout
+
# Helper functions
def mock_command(script, args, container):
''' Allows for setup of commands we don't really want to have to run for real in unit tests '''
@@ -424,6 +479,27 @@ def mock_command(script, args, container):
chmod +x {script}
rm -f /var/log/{scriptlog}'''.format(script=full_script_path, content=mock_script, scriptlog=script))
+def mock_command_2(script, args, container):
+ ''' Allows for setup of commands we don't really want to have to run for real in unit tests '''
+ full_script_path = '/usr/local/bin/{}'.format(script)
+ mock_script = dedent('''\
+ #!/bin/bash -e
+ echo "\$0 \$@" >> /var/log/{script}
+ case "\$1 \$2" in'''.format(script=script))
+ for k, v in args.iteritems():
+ case = dedent('''
+ \"{arg}\")
+ echo \"{res}\"
+ exit {retcode}
+ ;;'''.format(arg=k, res=v[0], retcode=v[1]))
+ mock_script += case
+ mock_script += dedent('''
+ esac''')
+ container.run('''
+ cat < {script}\n{content}\nEOF
+ chmod +x {script}
+ rm -f /var/log/{scriptlog}'''.format(script=full_script_path, content=mock_script, scriptlog=script))
+
def run_script(Pihole, script):
result = Pihole.run(script)
assert result.rc == 0
From 8ef64dbe7491c9028a45b14d415bcf86d6743bbf Mon Sep 17 00:00:00 2001
From: DL6ER
Date: Sat, 3 Jun 2017 14:51:35 +0200
Subject: [PATCH 064/162] Add weekly logrotation of FTL's log (#1509)
---
advanced/logrotate | 11 +++++++++++
automated install/basic-install.sh | 2 +-
2 files changed, 12 insertions(+), 1 deletion(-)
diff --git a/advanced/logrotate b/advanced/logrotate
index 570e7548..ffed910b 100644
--- a/advanced/logrotate
+++ b/advanced/logrotate
@@ -8,3 +8,14 @@
notifempty
nomail
}
+
+/var/log/pihole-FTL.log {
+ # su #
+ weekly
+ copytruncate
+ rotate 3
+ compress
+ delaycompress
+ notifempty
+ nomail
+}
diff --git a/automated install/basic-install.sh b/automated install/basic-install.sh
index b8b44550..e8b28f62 100755
--- a/automated install/basic-install.sh
+++ b/automated install/basic-install.sh
@@ -1080,7 +1080,7 @@ installLogrotate() {
# the local properties of the /var/log directory
logusergroup="$(stat -c '%U %G' /var/log)"
if [[ ! -z $logusergroup ]]; then
- sed -i "s/# su #/su ${logusergroup}/" /etc/pihole/logrotate
+ sed -i "s/# su #/su ${logusergroup}/g;" /etc/pihole/logrotate
fi
echo " done!"
}
From 288f93c5dd3c3646991e454c461927ac057d8eba Mon Sep 17 00:00:00 2001
From: DL6ER
Date: Sat, 3 Jun 2017 15:06:00 +0200
Subject: [PATCH 065/162] Update LICENSE of the project to EUPL v1.2
---
LICENSE | 119 +++++++++++++++++++++++---------------------------------
1 file changed, 49 insertions(+), 70 deletions(-)
diff --git a/LICENSE b/LICENSE
index 9fddaad1..9ce6e5b0 100644
--- a/LICENSE
+++ b/LICENSE
@@ -12,81 +12,63 @@ This license applies to the whole project EXCEPT:
The licenses that existed prior to this change have remained intact.
-------------------------------------------------------------
+EUROPEAN UNION PUBLIC LICENCE v. 1.2
-European Union Public Licence
-V. 1.1
+EUPL © the European Union 2007, 2016
-EUPL (C) the European Community 2007
-
-This European Union Public Licence (the "EUPL") applies to the Work or Software (as defined below) which is provided under the terms of this Licence. Any use of the Work, other than as authorised under this Licence is prohibited (to the extent such use is covered by a right of the copyright holder of the Work).
-
-The Original Work is provided under the terms of this Licence when the Licensor (as defined below) has placed the following notice immediately following the copyright notice for the Original Work:
-
-Licensed under the EUPL V.1.1
-
-or has expressed by any other mean his willingness to license under the EUPL.
+This European Union Public Licence (the EUPL) applies to the Work (as defined below) which is provided under the terms of this Licence. Any use of the Work, other than as authorised under this Licence is prohibited (to the extent such use is covered by a right of the copyright holder of the Work).
+The Work is provided under the terms of this Licence when the Licensor (as defined below) has placed the following notice immediately following the copyright notice for the Work:
+Licensed under the EUPL
+or has expressed by any other means his willingness to license under the EUPL.
1. Definitions
In this Licence, the following terms have the following meaning:
- The Licence: this Licence.
-
-- The Original Work or the Software: the software distributed and/or communicated by the Licensor under this Licence, available as Source Code and also as Executable Code as the case may be.
-
+- The Original Work: the work or software distributed or communicated by the Licensor under this Licence, available as Source Code and also as Executable Code as the case may be.
- Derivative Works: the works or software that could be created by the Licensee, based upon the Original Work or modifications thereof. This Licence does not define the extent of modification or dependence on the Original Work required in order to classify a work as a Derivative Work; this extent is determined by copyright law applicable in the country mentioned in Article 15.
-
-- The Work: the Original Work and/or its Derivative Works.
-
+- The Work: the Original Work or its Derivative Works.
- The Source Code: the human-readable form of the Work which is the most convenient for people to study and modify.
-
- The Executable Code: any code which has generally been compiled and which is meant to be interpreted by a computer as a program.
-
-- The Licensor: the natural or legal person that distributes and/or communicates the Work under the Licence.
-
+- The Licensor: the natural or legal person that distributes or communicates the Work under the Licence.
- Contributor(s): any natural or legal person who modifies the Work under the Licence, or otherwise contributes to the creation of a Derivative Work.
-
-- The Licensee or "You": any natural or legal person who makes any usage of the Software under the terms of the Licence.
-
-- Distribution and/or Communication: any act of selling, giving, lending, renting, distributing, communicating, transmitting, or otherwise making available, on-line or off-line, copies of the Work or providing access to its essential functionalities at the disposal of any other natural or legal person.
+- The Licensee or You: any natural or legal person who makes any usage of the Work under the terms of the Licence.
+- Distribution or Communication: any act of selling, giving, lending, renting, distributing, communicating, transmitting, or otherwise making available, online or offline, copies of the Work or providing access to its essential functionalities at the disposal of any other natural or legal person.
2. Scope of the rights granted by the Licence
-The Licensor hereby grants You a world-wide, royalty-free, non-exclusive, sub-licensable licence to do the following, for the duration of copyright vested in the Original Work:
-
+The Licensor hereby grants You a worldwide, royalty-free, non-exclusive, sublicensable licence to do the following, for the duration of copyright vested in the Original Work:
- use the Work in any circumstance and for all usage,
- reproduce the Work,
-- modify the Original Work, and make Derivative Works based upon the Work,
+- modify the Work, and make Derivative Works based upon the Work,
- communicate to the public, including the right to make available or display the Work or copies thereof to the public and perform publicly, as the case may be, the Work,
- distribute the Work or copies thereof,
- lend and rent the Work or copies thereof,
-- sub-license rights in the Work or copies thereof.
-
+- sublicense rights in the Work or copies thereof.
Those rights can be exercised on any media, supports and formats, whether now known or later invented, as far as the applicable law permits so.
-
In the countries where moral rights apply, the Licensor waives his right to exercise his moral right to the extent allowed by law in order to make effective the licence of the economic rights here above listed.
-
-The Licensor grants to the Licensee royalty-free, non exclusive usage rights to any patents held by the Licensor, to the extent necessary to make use of the rights granted on the Work under this Licence.
+The Licensor grants to the Licensee royalty-free, non-exclusive usage rights to any patents held by the Licensor, to the extent necessary to make use of the rights granted on the Work under this Licence.
3. Communication of the Source Code
-The Licensor may provide the Work either in its Source Code form, or as Executable Code. If the Work is provided as Executable Code, the Licensor provides in addition a machine-readable copy of the Source Code of the Work along with each copy of the Work that the Licensor distributes or indicates, in a notice following the copyright notice attached to the Work, a repository where the Source Code is easily and freely accessible for as long as the Licensor continues to distribute and/or communicate the Work.
+The Licensor may provide the Work either in its Source Code form, or as Executable Code. If the Work is provided as Executable Code, the Licensor provides in addition a machine-readable copy of the Source Code of the Work along with each copy of the Work that the Licensor distributes or indicates, in a notice following the copyright notice attached to the Work, a repository where the Source Code is easily and freely accessible for as long as the Licensor continues to distribute or communicate the Work.
4. Limitations on copyright
-Nothing in this Licence is intended to deprive the Licensee of the benefits from any exception or limitation to the exclusive rights of the rights owners in the Original Work or Software, of the exhaustion of those rights or of other applicable limitations thereto.
+Nothing in this Licence is intended to deprive the Licensee of the benefits from any exception or limitation to the exclusive rights of the rights owners in the Work, of the exhaustion of those rights or of other applicable limitations thereto.
5. Obligations of the Licensee
The grant of the rights mentioned above is subject to some restrictions and obligations imposed on the Licensee. Those obligations are the following:
-Attribution right: the Licensee shall keep intact all copyright, patent or trademarks notices and all notices that refer to the Licence and to the disclaimer of warranties. The Licensee must include a copy of such notices and a copy of the Licence with every copy of the Work he/she distributes and/or communicates. The Licensee must cause any Derivative Work to carry prominent notices stating that the Work has been modified and the date of modification.
+Attribution right: The Licensee shall keep intact all copyright, patent or trademarks notices and all notices that refer to the Licence and to the disclaimer of warranties. The Licensee must include a copy of such notices and a copy of the Licence with every copy of the Work he/she distributes or communicates. The Licensee must cause any Derivative Work to carry prominent notices stating that the Work has been modified and the date of modification.
-Copyleft clause: If the Licensee distributes and/or communicates copies of the Original Works or Derivative Works based upon the Original Work, this Distribution and/or Communication will be done under the terms of this Licence or of a later version of this Licence unless the Original Work is expressly distributed only under this version of the Licence. The Licensee (becoming Licensor) cannot offer or impose any additional terms or conditions on the Work or Derivative Work that alter or restrict the terms of the Licence.
+Copyleft clause: If the Licensee distributes or communicates copies of the Original Works or Derivative Works, this Distribution or Communication will be done under the terms of this Licence or of a later version of this Licence unless the Original Work is expressly distributed only under this version of the Licence - for example by communicating EUPL v. 1.2 only. The Licensee (becoming Licensor) cannot offer or impose any additional terms or conditions on the Work or Derivative Work that alter or restrict the terms of the Licence.
-Compatibility clause: If the Licensee Distributes and/or Communicates Derivative Works or copies thereof based upon both the Original Work and another work licensed under a Compatible Licence, this Distribution and/or Communication can be done under the terms of this Compatible Licence. For the sake of this clause, "Compatible Licence" refers to the licences listed in the appendix attached to this Licence. Should the Licensee’s obligations under the Compatible Licence conflict with his/her obligations under this Licence, the obligations of the Compatible Licence shall prevail.
+Compatibility clause: If the Licensee Distributes or Communicates Derivative Works or copies thereof based upon both the Work and another work licensed under a Compatible Licence, this Distribution or Communication can be done under the terms of this Compatible Licence. For the sake of this clause, Compatible Licence refers to the licences listed in the appendix attached to this Licence. Should the Licensee's obligations under the Compatible Licence conflict with his/her obligations under this Licence, the obligations of the Compatible Licence shall prevail.
-Provision of Source Code: When distributing and/or communicating copies of the Work, the Licensee will provide a machine-readable copy of the Source Code or indicate a repository where this Source will be easily and freely available for as long as the Licensee continues to distribute and/or communicate the Work.
+Provision of Source Code: When distributing or communicating copies of the Work, the Licensee will provide a machine-readable copy of the Source Code or indicate a repository where this Source will be easily and freely available for as long as the Licensee continues to distribute or communicate the Work.
Legal Protection: This Licence does not grant permission to use the trade names, trademarks, service marks, or names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the copyright notice.
@@ -100,10 +82,8 @@ Each time You accept the Licence, the original Licensor and subsequent Contribut
7. Disclaimer of Warranty
-The Work is a work in progress, which is continuously improved by numerous contributors. It is not a finished work and may therefore contain defects or "bugs" inherent to this type of software development.
-
-For the above reason, the Work is provided under the Licence on an "as is" basis and without warranties of any kind concerning the Work, including without limitation merchantability, fitness for a particular purpose, absence of defects or errors, accuracy, non-infringement of intellectual property rights other than copyright as stated in Article 6 of this Licence.
-
+The Work is a work in progress, which is continuously improved by numerous Contributors. It is not a finished work and may therefore contain defects or bugs inherent to this type of development.
+For the above reason, the Work is provided under the Licence on an as is basis and without warranties of any kind concerning the Work, including without limitation merchantability, fitness for a particular purpose, absence of defects or errors, accuracy, non-infringement of intellectual property rights other than copyright as stated in Article 6 of this Licence.
This disclaimer of warranty is an essential part of the Licence and a condition for the grant of any rights to the Work.
8. Disclaimer of Liability
@@ -112,56 +92,55 @@ Except in the cases of wilful misconduct or damages directly caused to natural p
9. Additional agreements
-While distributing the Original Work or Derivative Works, You may choose to conclude an additional agreement to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or services consistent with this Licence. However, in accepting such obligations, You may act only on your own behalf and on your sole responsibility, not on behalf of the original Licensor or any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against such Contributor by the fact You have accepted any such warranty or additional liability.
+While distributing the Work, You may choose to conclude an additional agreement, defining obligations or services consistent with this Licence. However, if accepting obligations, You may act only on your own behalf and on your sole responsibility, not on behalf of the original Licensor or any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against such Contributor by the fact You have accepted any warranty or additional liability.
10. Acceptance of the Licence
-The provisions of this Licence can be accepted by clicking on an icon "I agree" placed under the bottom of a window displaying the text of this Licence or by affirming consent in any other similar way, in accordance with the rules of applicable law. Clicking on that icon indicates your clear and irrevocable acceptance of this Licence and all of its terms and conditions.
-
-Similarly, you irrevocably accept this Licence and all of its terms and conditions by exercising any rights granted to You by Article 2 of this Licence, such as the use of the Work, the creation by You of a Derivative Work or the Distribution and/or Communication by You of the Work or copies thereof.
+The provisions of this Licence can be accepted by clicking on an icon I agree placed under the bottom of a window displaying the text of this Licence or by affirming consent in any other similar way, in accordance with the rules of applicable law. Clicking on that icon indicates your clear and irrevocable acceptance of this Licence and all of its terms and conditions.
+Similarly, you irrevocably accept this Licence and all of its terms and conditions by exercising any rights granted to You by Article 2 of this Licence, such as the use of the Work, the creation by You of a Derivative Work or the Distribution or Communication by You of the Work or copies thereof.
11. Information to the public
-In case of any Distribution and/or Communication of the Work by means of electronic communication by You (for example, by offering to download the Work from a remote location) the distribution channel or media (for example, a website) must at least provide to the public the information requested by the applicable law regarding the Licensor, the Licence and the way it may be accessible, concluded, stored and reproduced by the Licensee.
+In case of any Distribution or Communication of the Work by means of electronic communication by You (for example, by offering to download the Work from a remote location) the distribution channel or media (for example, a website) must at least provide to the public the information requested by the applicable law regarding the Licensor, the Licence and the way it may be accessible, concluded, stored and reproduced by the Licensee.
12. Termination of the Licence
The Licence and the rights granted hereunder will terminate automatically upon any breach by the Licensee of the terms of the Licence.
-
Such a termination will not terminate the licences of any person who has received the Work from the Licensee under the Licence, provided such persons remain in full compliance with the Licence.
13. Miscellaneous
-Without prejudice of Article 9 above, the Licence represents the complete agreement between the Parties as to the Work licensed hereunder.
-
-If any provision of the Licence is invalid or unenforceable under applicable law, this will not affect the validity or enforceability of the Licence as a whole. Such provision will be construed and/or reformed so as necessary to make it valid and enforceable.
-
-The European Commission may publish other linguistic versions and/or new versions of this Licence, so far this is required and reasonable, without reducing the scope of the rights granted by the Licence. New versions of the Licence will be published with a unique version number.
-
+Without prejudice of Article 9 above, the Licence represents the complete agreement between the Parties as to the Work.
+If any provision of the Licence is invalid or unenforceable under applicable law, this will not affect the validity or enforceability of the Licence as a whole. Such provision will be construed or reformed so as necessary to make it valid and enforceable.
+The European Commission may publish other linguistic versions or new versions of this Licence or updated versions of the Appendix, so far this is required and reasonable, without reducing the scope of the rights granted by the Licence. New versions of the Licence will be published with a unique version number.
All linguistic versions of this Licence, approved by the European Commission, have identical value. Parties can take advantage of the linguistic version of their choice.
14. Jurisdiction
-Any litigation resulting from the interpretation of this License, arising between the European Commission, as a Licensor, and any Licensee, will be subject to the jurisdiction of the Court of Justice of the European Communities, as laid down in article 238 of the Treaty establishing the European Community.
-
-Any litigation arising between Parties, other than the European Commission, and resulting from the interpretation of this License, will be subject to the exclusive jurisdiction of the competent court where the Licensor resides or conducts its primary business.
+Without prejudice to specific agreement between parties,
+- any litigation resulting from the interpretation of this License, arising between the European Union institutions, bodies, offices or agencies, as a Licensor, and any Licensee, will be subject to the jurisdiction of the Court of Justice of the European Union, as laid down in article 272 of the Treaty on the Functioning of the European Union,
+- any litigation arising between other parties and resulting from the interpretation of this License, will be subject to the exclusive jurisdiction of the competent court where the Licensor resides or conducts its primary business.
15. Applicable Law
-This Licence shall be governed by the law of the European Union country where the Licensor resides or has his registered office.
-
-This licence shall be governed by the Belgian law if:
-
-- a litigation arises between the European Commission, as a Licensor, and any Licensee;
-- the Licensor, other than the European Commission, has no residence or registered office inside a European Union country.
-
+Without prejudice to specific agreement between parties,
+- this Licence shall be governed by the law of the European Union Member State where the Licensor has his seat, resides or has his registered office,
+- this licence shall be governed by Belgian law if the Licensor has no seat, residence or registered office inside a European Union Member State.
===
+
Appendix
-"Compatible Licences" according to article 5 EUPL are:
-- GNU General Public License (GNU GPL) v. 2
+Compatible Licences according to Article 5 EUPL are:
+- GNU General Public License (GPL) v. 2, v. 3
+- GNU Affero General Public License (AGPL) v. 3
- Open Software License (OSL) v. 2.1, v. 3.0
-- Common Public License v. 1.0
-- Eclipse Public License v. 1.0
-- Cecill v. 2.0
+- Eclipse Public License (EPL) v. 1.0
+- CeCILL v. 2.0, v. 2.1
+- Mozilla Public Licence (MPL) v. 2
+- GNU Lesser General Public Licence (LGPL) v. 2.1, v. 3
+- Creative Commons Attribution-ShareAlike v. 3.0 Unported (CC BY-SA 3.0) for works other than software
+- European Union Public Licence (EUPL) v. 1.1, v. 1.2
+- Québec Free and Open-Source Licence - Reciprocity (LiLiQ-R) or Strong Reciprocity (LiLiQ-R+)
+- The European Commission may update this Appendix to later versions of the above licences without producing a new version of the EUPL, as long as they provide the rights granted in Article 2 of this Licence and protect the covered Source Code from exclusive appropriation.
+- All other changes or additions to this Appendix require the production of a new EUPL version.
From 2516a1e298068aacc3d98d198caee10277c9460c Mon Sep 17 00:00:00 2001
From: DL6ER
Date: Sat, 3 Jun 2017 17:23:47 +0200
Subject: [PATCH 066/162] Make clear that NO is the default if the user just
hits return (#1514)
---
advanced/Scripts/piholeCheckout.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/advanced/Scripts/piholeCheckout.sh b/advanced/Scripts/piholeCheckout.sh
index 286edb2e..e2c0ab11 100644
--- a/advanced/Scripts/piholeCheckout.sh
+++ b/advanced/Scripts/piholeCheckout.sh
@@ -87,7 +87,7 @@ warning1() {
echo " Please note that changing branches severely alters your Pi-hole subsystems"
echo " Features that work on the master branch, may not on a development branch"
echo -e " ${red}This feature is NOT supported unless a Pi-hole developer explicitly asks!${def}"
- read -r -p " Have you read and understood this? [Y/N] " response
+ read -r -p " Have you read and understood this? [y/N] " response
case ${response} in
[yY][eE][sS]|[yY])
echo "::: Continuing with branch change."
From 6823a6264455a28242a30b46d1a5fc759d5f12b3 Mon Sep 17 00:00:00 2001
From: WaLLy3K
Date: Sun, 4 Jun 2017 03:13:40 +1000
Subject: [PATCH 067/162] Add tricorderFunc back as usable function (#1515)
As per #1464
---
pihole | 1 +
1 file changed, 1 insertion(+)
diff --git a/pihole b/pihole
index 08e6b094..f2bc7000 100755
--- a/pihole
+++ b/pihole
@@ -423,5 +423,6 @@ case "${1}" in
"-a" | "admin" ) webpageFunc "$@";;
"-t" | "tail" ) tailFunc;;
"checkout" ) piholeCheckoutFunc "$@";;
+ "tricorder" ) tricorderFunc;;
* ) helpFunc;;
esac
From f1146a344356a6e9b74dc02f70d92f4f9fccf1a0 Mon Sep 17 00:00:00 2001
From: DL6ER
Date: Sun, 4 Jun 2017 12:40:57 +0200
Subject: [PATCH 068/162] Don't update FTL when there is a core update (as this
will update FTL a second time). Fixes #1516
---
advanced/Scripts/update.sh | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/advanced/Scripts/update.sh b/advanced/Scripts/update.sh
index 4fceb931..24b30de4 100755
--- a/advanced/Scripts/update.sh
+++ b/advanced/Scripts/update.sh
@@ -117,7 +117,10 @@ main() {
echo "::: FTL: up to date"
fi
- if ${FTL_update}; then
+ # Logic: Don't update FTL when there is a core update available
+ # since the core update will run the installer which will itself
+ # re-install (i.e. update) FTL
+ if ${FTL_update} && ! ${core_update}; then
echo ":::"
echo "::: FTL out of date"
FTLdetect
From cf6a1ac9adb4e26570cc5da7c8be628080f37e0f Mon Sep 17 00:00:00 2001
From: DL6ER
Date: Sun, 4 Jun 2017 13:23:56 +0200
Subject: [PATCH 069/162] Add FTL tests to the test suite (#1510)
* Add first version of FTL tests
* Wait one second to allow FTL to start up and analyze our mock log
* Add test_FTL_telnet_statistics
* Added test_FTL_telnet_top_clients
* Add test_FTL_telnet_top_domains
---
test/FTL-test.sh | 76 ++++++++++++++++++++++++++++++++++
test/test_automated_install.py | 64 ++++++++++++++++++++++++++++
2 files changed, 140 insertions(+)
create mode 100755 test/FTL-test.sh
diff --git a/test/FTL-test.sh b/test/FTL-test.sh
new file mode 100755
index 00000000..7e139c8a
--- /dev/null
+++ b/test/FTL-test.sh
@@ -0,0 +1,76 @@
+#!/bin/bash
+FTL_communicate() {
+ # Open connection to FTL
+ exec 3<>"/dev/tcp/localhost/4711"
+
+ # Test if connection is open
+ if { "true" >&3; } 2> /dev/null; then
+ # Send command to FTL
+ echo -e ">$1" >&3
+
+ # Read input
+ read -r -t 1 LINE <&3
+ until [[ ! $? ]] || [[ "$LINE" == *"EOM"* ]]; do
+ echo "$LINE" >&1
+ read -r -t 1 LINE <&3
+ done
+
+ # Close connection
+ exec 3>&-
+ exec 3<&-
+ fi
+}
+
+FTL_get_version() {
+ FTL_communicate "version"
+}
+
+FTL_get_stats() {
+ FTL_communicate "stats"
+}
+
+FTL_get_top_clients() {
+ FTL_communicate "top-clients"
+}
+
+FTL_get_top_domains() {
+ FTL_communicate "top-domains"
+}
+
+FTL_prepare_files() {
+ ts=$(dnsmasq_pre)
+cat <> /var/log/pihole.log
+${ts} query[AAAA] raspberrypi from 127.0.0.1
+${ts} /etc/pihole/local.list raspberrypi is fda2:2001:5647:0:ba27:ebff:fe37:4205
+${ts} query[A] checkip.dyndns.org from 127.0.0.1
+${ts} forwarded checkip.dyndns.org to 2001:1608:10:25::9249:d69b
+${ts} forwarded checkip.dyndns.org to 2001:1608:10:25::1c04:b12f
+${ts} forwarded checkip.dyndns.org to 2620:0:ccd::2
+${ts} forwarded checkip.dyndns.org to 2620:0:ccc::2
+${ts} reply checkip.dyndns.org is
+${ts} reply checkip.dyndns.com is 216.146.38.70
+${ts} reply checkip.dyndns.com is 216.146.43.71
+${ts} reply checkip.dyndns.com is 91.198.22.70
+${ts} reply checkip.dyndns.com is 216.146.43.70
+${ts} query[A] pi.hole from 10.8.0.2
+${ts} /etc/pihole/local.list pi.hole is 192.168.2.10
+${ts} query[A] play.google.com from 192.168.2.208
+${ts} forwarded play.google.com to 2001:1608:10:25::9249:d69b
+${ts} forwarded play.google.com to 2001:1608:10:25::1c04:b12f
+${ts} forwarded play.google.com to 2620:0:ccd::2
+${ts} forwarded play.google.com to 2620:0:ccc::2
+${ts} reply play.google.com is
+${ts} reply play.l.google.com is 216.58.208.110
+${ts} reply play.l.google.com is 216.58.208.110
+${ts} reply play.l.google.com is 216.58.208.110
+${ts} reply play.google.com is
+${ts} query[AAAA] play.google.com from 192.168.2.208
+${ts} forwarded play.google.com to 2620:0:ccd::2
+${ts} reply play.l.google.com is 2a00:1450:4017:802::200e
+EOT
+}
+
+dnsmasq_pre() {
+ echo -n $(date +"%b %e %H:%M:%S")
+ echo -n "dnsmasq[123]:"
+}
diff --git a/test/test_automated_install.py b/test/test_automated_install.py
index 60772625..60a0f123 100644
--- a/test/test_automated_install.py
+++ b/test/test_automated_install.py
@@ -402,6 +402,70 @@ def test_FTL_binary_installed_and_responsive_no_errors(Pihole):
# assert '644 /run/pihole-FTL.pid' in support_files.stdout
# assert '644 /var/log/pihole-FTL.log' in support_files.stdout
+def test_FTL_telnet_version(Pihole):
+ ''' confirms FTL binary is copied and functional in installed location and through telnet '''
+ FTLtest = Pihole.run('''
+ source /opt/pihole/basic-install.sh
+ source /etc/.pihole/test/FTL-test.sh
+ FTL_prepare_files
+ FTLdetect
+ pihole-FTL
+ sleep 1
+ FTL_get_version
+ ''')
+ assert 'version' in FTLtest.stdout
+ assert 'tag' in FTLtest.stdout
+ assert 'branch' in FTLtest.stdout
+ assert 'date' in FTLtest.stdout
+
+def test_FTL_telnet_statistics(Pihole):
+ ''' confirms FTL binary is copied and functional in installed location and through telnet '''
+ FTLtest = Pihole.run('''
+ source /opt/pihole/basic-install.sh
+ source /etc/.pihole/test/FTL-test.sh
+ FTL_prepare_files
+ FTLdetect
+ pihole-FTL
+ sleep 1
+ FTL_get_stats
+ ''')
+ assert 'domains_being_blocked' in FTLtest.stdout
+ assert 'dns_queries_today 5' in FTLtest.stdout
+ assert 'unique_domains 4' in FTLtest.stdout
+ assert 'queries_forwarded 3' in FTLtest.stdout
+ assert 'queries_cached 2' in FTLtest.stdout
+
+def test_FTL_telnet_top_clients(Pihole):
+ ''' confirms FTL binary is copied and functional in installed location and through telnet '''
+ FTLtest = Pihole.run('''
+ source /opt/pihole/basic-install.sh
+ source /etc/.pihole/test/FTL-test.sh
+ FTL_prepare_files
+ FTLdetect
+ pihole-FTL
+ sleep 1
+ FTL_get_top_clients
+ ''')
+ assert '0 2 192.168.2.208' in FTLtest.stdout
+ assert '1 2 127.0.0.1' in FTLtest.stdout
+ assert '2 1 10.8.0.2' in FTLtest.stdout
+
+def test_FTL_telnet_top_domains(Pihole):
+ ''' confirms FTL binary is copied and functional in installed location and through telnet '''
+ FTLtest = Pihole.run('''
+ source /opt/pihole/basic-install.sh
+ source /etc/.pihole/test/FTL-test.sh
+ FTL_prepare_files
+ FTLdetect
+ pihole-FTL
+ sleep 1
+ FTL_get_top_domains
+ ''')
+ assert '0 2 play.google.com' in FTLtest.stdout
+ assert '1 1 pi.hole' in FTLtest.stdout
+ assert '2 1 checkip.dyndns.org' in FTLtest.stdout
+ assert '3 1 raspberrypi' in FTLtest.stdout
+
def test_IPv6_only_link_local(Pihole):
''' confirms IPv6 blocking is disabled for Link-local address '''
# mock ip -6 address to return Link-local address
From 939055f19c2e2389b9a9db8db263f9cd26838a17 Mon Sep 17 00:00:00 2001
From: DL6ER
Date: Mon, 5 Jun 2017 13:51:13 +0200
Subject: [PATCH 070/162] Revert "Add FTL tests to the test suite (#1510)"
(#1519)
This reverts commit cf6a1ac9adb4e26570cc5da7c8be628080f37e0f.
---
test/FTL-test.sh | 76 ----------------------------------
test/test_automated_install.py | 64 ----------------------------
2 files changed, 140 deletions(-)
delete mode 100755 test/FTL-test.sh
diff --git a/test/FTL-test.sh b/test/FTL-test.sh
deleted file mode 100755
index 7e139c8a..00000000
--- a/test/FTL-test.sh
+++ /dev/null
@@ -1,76 +0,0 @@
-#!/bin/bash
-FTL_communicate() {
- # Open connection to FTL
- exec 3<>"/dev/tcp/localhost/4711"
-
- # Test if connection is open
- if { "true" >&3; } 2> /dev/null; then
- # Send command to FTL
- echo -e ">$1" >&3
-
- # Read input
- read -r -t 1 LINE <&3
- until [[ ! $? ]] || [[ "$LINE" == *"EOM"* ]]; do
- echo "$LINE" >&1
- read -r -t 1 LINE <&3
- done
-
- # Close connection
- exec 3>&-
- exec 3<&-
- fi
-}
-
-FTL_get_version() {
- FTL_communicate "version"
-}
-
-FTL_get_stats() {
- FTL_communicate "stats"
-}
-
-FTL_get_top_clients() {
- FTL_communicate "top-clients"
-}
-
-FTL_get_top_domains() {
- FTL_communicate "top-domains"
-}
-
-FTL_prepare_files() {
- ts=$(dnsmasq_pre)
-cat <> /var/log/pihole.log
-${ts} query[AAAA] raspberrypi from 127.0.0.1
-${ts} /etc/pihole/local.list raspberrypi is fda2:2001:5647:0:ba27:ebff:fe37:4205
-${ts} query[A] checkip.dyndns.org from 127.0.0.1
-${ts} forwarded checkip.dyndns.org to 2001:1608:10:25::9249:d69b
-${ts} forwarded checkip.dyndns.org to 2001:1608:10:25::1c04:b12f
-${ts} forwarded checkip.dyndns.org to 2620:0:ccd::2
-${ts} forwarded checkip.dyndns.org to 2620:0:ccc::2
-${ts} reply checkip.dyndns.org is
-${ts} reply checkip.dyndns.com is 216.146.38.70
-${ts} reply checkip.dyndns.com is 216.146.43.71
-${ts} reply checkip.dyndns.com is 91.198.22.70
-${ts} reply checkip.dyndns.com is 216.146.43.70
-${ts} query[A] pi.hole from 10.8.0.2
-${ts} /etc/pihole/local.list pi.hole is 192.168.2.10
-${ts} query[A] play.google.com from 192.168.2.208
-${ts} forwarded play.google.com to 2001:1608:10:25::9249:d69b
-${ts} forwarded play.google.com to 2001:1608:10:25::1c04:b12f
-${ts} forwarded play.google.com to 2620:0:ccd::2
-${ts} forwarded play.google.com to 2620:0:ccc::2
-${ts} reply play.google.com is
-${ts} reply play.l.google.com is 216.58.208.110
-${ts} reply play.l.google.com is 216.58.208.110
-${ts} reply play.l.google.com is 216.58.208.110
-${ts} reply play.google.com is
-${ts} query[AAAA] play.google.com from 192.168.2.208
-${ts} forwarded play.google.com to 2620:0:ccd::2
-${ts} reply play.l.google.com is 2a00:1450:4017:802::200e
-EOT
-}
-
-dnsmasq_pre() {
- echo -n $(date +"%b %e %H:%M:%S")
- echo -n "dnsmasq[123]:"
-}
diff --git a/test/test_automated_install.py b/test/test_automated_install.py
index 60a0f123..60772625 100644
--- a/test/test_automated_install.py
+++ b/test/test_automated_install.py
@@ -402,70 +402,6 @@ def test_FTL_binary_installed_and_responsive_no_errors(Pihole):
# assert '644 /run/pihole-FTL.pid' in support_files.stdout
# assert '644 /var/log/pihole-FTL.log' in support_files.stdout
-def test_FTL_telnet_version(Pihole):
- ''' confirms FTL binary is copied and functional in installed location and through telnet '''
- FTLtest = Pihole.run('''
- source /opt/pihole/basic-install.sh
- source /etc/.pihole/test/FTL-test.sh
- FTL_prepare_files
- FTLdetect
- pihole-FTL
- sleep 1
- FTL_get_version
- ''')
- assert 'version' in FTLtest.stdout
- assert 'tag' in FTLtest.stdout
- assert 'branch' in FTLtest.stdout
- assert 'date' in FTLtest.stdout
-
-def test_FTL_telnet_statistics(Pihole):
- ''' confirms FTL binary is copied and functional in installed location and through telnet '''
- FTLtest = Pihole.run('''
- source /opt/pihole/basic-install.sh
- source /etc/.pihole/test/FTL-test.sh
- FTL_prepare_files
- FTLdetect
- pihole-FTL
- sleep 1
- FTL_get_stats
- ''')
- assert 'domains_being_blocked' in FTLtest.stdout
- assert 'dns_queries_today 5' in FTLtest.stdout
- assert 'unique_domains 4' in FTLtest.stdout
- assert 'queries_forwarded 3' in FTLtest.stdout
- assert 'queries_cached 2' in FTLtest.stdout
-
-def test_FTL_telnet_top_clients(Pihole):
- ''' confirms FTL binary is copied and functional in installed location and through telnet '''
- FTLtest = Pihole.run('''
- source /opt/pihole/basic-install.sh
- source /etc/.pihole/test/FTL-test.sh
- FTL_prepare_files
- FTLdetect
- pihole-FTL
- sleep 1
- FTL_get_top_clients
- ''')
- assert '0 2 192.168.2.208' in FTLtest.stdout
- assert '1 2 127.0.0.1' in FTLtest.stdout
- assert '2 1 10.8.0.2' in FTLtest.stdout
-
-def test_FTL_telnet_top_domains(Pihole):
- ''' confirms FTL binary is copied and functional in installed location and through telnet '''
- FTLtest = Pihole.run('''
- source /opt/pihole/basic-install.sh
- source /etc/.pihole/test/FTL-test.sh
- FTL_prepare_files
- FTLdetect
- pihole-FTL
- sleep 1
- FTL_get_top_domains
- ''')
- assert '0 2 play.google.com' in FTLtest.stdout
- assert '1 1 pi.hole' in FTLtest.stdout
- assert '2 1 checkip.dyndns.org' in FTLtest.stdout
- assert '3 1 raspberrypi' in FTLtest.stdout
-
def test_IPv6_only_link_local(Pihole):
''' confirms IPv6 blocking is disabled for Link-local address '''
# mock ip -6 address to return Link-local address
From 92b5fe4be45552aff30f7acbbe78bca9ec0e67cd Mon Sep 17 00:00:00 2001
From: Jacob Salmela
Date: Mon, 5 Jun 2017 14:55:58 -0500
Subject: [PATCH 071/162] check arch compatibility and add gateway faq url
---
advanced/Scripts/piholeDebug.sh | 39 +++++++++++++++++++++++----------
1 file changed, 27 insertions(+), 12 deletions(-)
diff --git a/advanced/Scripts/piholeDebug.sh b/advanced/Scripts/piholeDebug.sh
index 954c6c31..7ad503bb 100755
--- a/advanced/Scripts/piholeDebug.sh
+++ b/advanced/Scripts/piholeDebug.sh
@@ -1,4 +1,4 @@
-check_critical_program_versions#!/usr/bin/env bash
+#!/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.
@@ -57,8 +57,9 @@ fi
FAQ_UPDATE_PI_HOLE="${COL_CYAN}https://discourse.pi-hole.net/t/how-do-i-update-pi-hole/249${COL_NC}"
FAQ_CHECKOUT_COMMAND="${COL_CYAN}https://discourse.pi-hole.net/t/the-pihole-command-with-examples/738#checkout${COL_NC}"
FAQ_HARDWARE_REQUIREMENTS="${COL_CYAN}https://discourse.pi-hole.net/t/hardware-software-requirements/273${COL_NC}"
-FAQ_GATEWAY="${COL_CYAN}https://discourse.pi-hole.net/{PLACEHOLDER}${COL_NC}"
+FAQ_GATEWAY="${COL_CYAN}https://discourse.pi-hole.net/t/why-is-a-default-gateway-important-for-pi-hole/3546${COL_NC}"
FAQ_ULA="${COL_CYAN}https://discourse.pi-hole.net/t/use-ipv6-ula-addresses-for-pi-hole/2127${COL_NC}"
+FAQ_FTL_COMPATIBILITY="${COL_CYAN}https://github.com/pi-hole/FTL#compatibility-list${COL_NC}"
source_setup_variables() {
# Display the current test that is running
@@ -330,10 +331,24 @@ processor_check() {
# If it does not contain a value,
if [[ -z "${PROCESSOR}" ]]; then
# we couldn't detect it, so show an error
- log_write "${CROSS} ${COL_LIGHT_RED}Processor could not be identified.${COL_NC}"
+ PROCESSOR=$(lscpu | awk '/Architecture/ {print $2}')
+ log_write "${CROSS} ${COL_LIGHT_RED}${PROCESSOR}${COL_NC} has not been tested with FTL, but may still work: (${FAQ_FTL_COMPATIBILITY})"
else
+ # Check if the architecture is currently supported for FTL
+ case "${PROCESSOR}" in
+ "amd64") "${TICK} ${COL_LIGHT_GREEN}${PROCESSOR}${COL_NC}"
+ ;;
+ "armv6l") "${TICK} ${COL_LIGHT_GREEN}${PROCESSOR}${COL_NC}"
+ ;;
+ "armv6") "${TICK} ${COL_LIGHT_GREEN}${PROCESSOR}${COL_NC}"
+ ;;
+ "armv7l") "${TICK} ${COL_LIGHT_GREEN}${PROCESSOR}${COL_NC}"
+ ;;
+ "aarch64") "${TICK} ${COL_LIGHT_GREEN}${PROCESSOR}${COL_NC}"
+ ;;
# Otherwise, show the processor type
- log_write "${INFO} ${PROCESSOR}"
+ *) log_write "${INFO} ${PROCESSOR}";
+ esac
fi
}
@@ -356,10 +371,10 @@ does_ip_match_setup_vars() {
# Strip off the /
if [[ "${ip_address%/*}" == "${setup_vars_ip}" ]]; then
# if it matches, show it in green
- log_write " ${COL_LIGHT_GREEN}${ip_address%/*}${COL_NC}"
+ log_write " ${COL_LIGHT_GREEN}${ip_address%/*}${COL_NC} matches the IP found in ${VARSFILE}"
else
# otherwise show it in red with an FAQ URL
- log_write " ${COL_LIGHT_RED}${ip_address%/*}${COL_NC} (${FAQ_ULA})"
+ log_write " ${COL_LIGHT_RED}${ip_address%/*}${COL_NC} does not match the IP found in ${VARSFILE}(${FAQ_ULA})"
fi
else
@@ -367,10 +382,10 @@ does_ip_match_setup_vars() {
# since it exists in the setupVars.conf that way
if [[ "${ip_address}" == "${setup_vars_ip}" ]]; then
# show in green if it matches
- log_write " ${COL_LIGHT_GREEN}${ip_address}${COL_NC}"
+ log_write " ${COL_LIGHT_GREEN}${ip_address}${COL_NC} matches the IP found in ${VARSFILE}"
else
# otherwise show it in red
- log_write " ${COL_LIGHT_RED}${ip_address}${COL_NC} (${FAQ_ULA})"
+ log_write " ${COL_LIGHT_RED}${ip_address}${COL_NC} does not match the IP found in ${VARSFILE} (${FAQ_ULA})"
fi
fi
}
@@ -404,9 +419,9 @@ detect_ip_addresses() {
# If the protocol is v6
if [[ "${protocol}" == "6" ]]; then
# let the user know that as long as there is one green address, things should be ok
- log_write " ^ Please note that you may have more than one IPv${protocol} address listed."
- log_write " As long as one of them is green, it matches what is in ${VARSFILE} so there is no need for concern.\n"
- log_write " The link to the FAQ is for an issue that sometimes occurs when the IPv6 address changes, which is why we check for it."
+ log_write " ^ Please note that you may have more than one IP address listed."
+ log_write " As long as one of them is green, and it matches what is in ${VARSFILE}, there is no need for concern.\n"
+ log_write " The link to the FAQ is for an issue that sometimes occurs when the IPv6 address changes, which is why we check for it.\n"
fi
}
@@ -569,7 +584,7 @@ dig_at() {
# Store the arguments as variables with names
local protocol="${1}"
local IP="${2}"
- echo_current_diagnostic "Domain name resolution (IPv${protocol}) using a random blocked domain"
+ echo_current_diagnostic "Name resolution (IPv${protocol}) using a random blocked domain and a known ad-serving domain"
# Set more local variables
local url
local local_dig
From 24aa72c19d1b81be2d341712f33f619eb0b73da9 Mon Sep 17 00:00:00 2001
From: Jacob Salmela
Date: Wed, 7 Jun 2017 12:25:00 -0500
Subject: [PATCH 072/162] condense repetative code into functions; parse the
content of each file
---
advanced/Scripts/piholeDebug.sh | 62 ++++++++++++---------------------
1 file changed, 23 insertions(+), 39 deletions(-)
diff --git a/advanced/Scripts/piholeDebug.sh b/advanced/Scripts/piholeDebug.sh
index 7ad503bb..187bfba2 100755
--- a/advanced/Scripts/piholeDebug.sh
+++ b/advanced/Scripts/piholeDebug.sh
@@ -24,7 +24,7 @@ SUPPORTED_OS=("Raspbian" "Ubuntu" "Fedora" "Debian" "CentOS")
VARSFILE="/etc/pihole/setupVars.conf"
DEBUG_LOG="/var/log/pihole_debug.log"
DNSMASQFILE="/etc/dnsmasq.conf"
-DNSMASQCONFDIR="/etc/dnsmasq.d/*"
+DNSMASQCONFDIR="/etc/dnsmasq.d"
LIGHTTPDFILE="/etc/lighttpd/lighttpd.conf"
LIGHTTPDERRFILE="/var/log/lighttpd/error.log"
GRAVITYFILE="/etc/pihole/gravity.list"
@@ -37,6 +37,9 @@ ADMINGITDIR="/var/www/html/admin/"
WHITELISTMATCHES="/tmp/whitelistmatches.list"
readonly FTLLOG="/var/log/pihole-FTL.log"
coltable=/opt/pihole/COL_TABLE
+FTL_LOG="/var/log/pihole-FTL.log"
+FTL_PID="/run/pihole-FTL.pid"
+FTL_PORT="/run/pihole-FTL.port"
# These provide the colors we need for making the log more readable
if [[ -f ${coltable} ]]; then
@@ -673,6 +676,7 @@ process_status(){
make_array_from_file() {
local filename="${1}"
+ local file_content=()
# If the file is a directory
if [[ -d "${filename}" ]]; then
# do nothing since it cannot be parsed
@@ -682,7 +686,7 @@ make_array_from_file() {
while IFS= read -r line;do
# Strip out comments and blank lines
new_line=$(echo "${line}" | sed -e 's/#.*$//' -e '/^$/d')
- # If the line still has content
+ # If the line still has content (a non-zero value)
if [[ -n "${new_line}" ]]; then
# Put it into the array
file_content+=("${new_line}")
@@ -750,59 +754,42 @@ list_files_in_dir() {
# Set the first argument passed to tihs function as a named variable for better readability
local dir_to_parse="${1}"
# Store the files found in an array
- files_found=( $(ls "${dir_to_parse}") )
- # For each file in the arry,
+ local files_found=( $(ls "${dir_to_parse}") )
+ # For each file in the array,
for each_file in "${files_found[@]}"; do
if [[ -d "${each_file}" ]]; then
+ # If it's a directoy, do nothing
:
else
- # display the information with the ${INFO} icon
- # Also print the permissions and the user/group
+ # Othwerise, display the filename
log_write "\n${COL_LIGHT_GREEN}$(ls -ld ${dir_to_parse}/${each_file})${COL_NC}"
- # Otherwise, parse the file's content
+ # Then, parse the file's content into an array so each line can be analyzed if need be
make_array_from_file "${dir_to_parse}/${each_file}"
for each_line in "${file_content[@]}"; do
log_write " ${each_line}"
done
fi
- file_content=()
done
}
-check_dnsmasq_d() {
+show_content_of_files_in_dir() {
# Set a local variable for better readability
- local directory=/etc/dnsmasq.d
+ local directory="${1}"
# Check if the directory exists
dir_check "${directory}"
# if it does, list the files in it
list_files_in_dir "${directory}"
}
-check_lighttpd_d() {
- # Set a local variable for better readability
- local directory=/etc/lighttpd
- # Check if the directory exists
- dir_check "${directory}"
- # if it does, list the files in it
- list_files_in_dir "${directory}"
-}
-
-check_cron_d() {
- # Set a local variable for better readability
- local directory=/etc/cron.d
- # Check if the directory exists
- dir_check "${directory}"
- # if it does, list the files in it
- list_files_in_dir "${directory}"
-}
-
-check_http_directory() {
- # Set a local variable for better readability
- local directory=/var/www/html
- # Check if the directory exists
- dir_check "${directory}"
- # if it does, list the files in it
- list_files_in_dir "${directory}"
+show_content_of_pihole_files() {
+ # Show the content of the files in /etc/dnsmasq.d
+ show_content_of_files_in_dir "${DNSMASQCONFDIR}"
+ # Show the content of the files in /etc/lighttpd
+ show_content_of_files_in_dir "/etc/lighttpd"
+ # Show the content of the files in /etc/lighttpd
+ show_content_of_files_in_dir "/etc/cron.d"
+ # Show the content of the files in /var/www/html
+ # show_content_of_files_in_dir "${ADMINGITDIR}"
}
analyze_gravity_list() {
@@ -902,9 +889,6 @@ process_status
parse_setup_vars
check_x_headers
analyze_gravity_list
-check_dnsmasq_d
-# check_lighttpd_d
-# check_http_directory
-# check_cron_d
+show_content_of_pihole_files
copy_to_debug_log
upload_to_tricorder
From 048eacd3050dcb1a5a11b0998ea5e9fafabf5eb6 Mon Sep 17 00:00:00 2001
From: Jacob Salmela
Date: Wed, 7 Jun 2017 12:31:08 -0500
Subject: [PATCH 073/162] parse array in correct location
---
advanced/Scripts/piholeDebug.sh | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/advanced/Scripts/piholeDebug.sh b/advanced/Scripts/piholeDebug.sh
index 187bfba2..a488248a 100755
--- a/advanced/Scripts/piholeDebug.sh
+++ b/advanced/Scripts/piholeDebug.sh
@@ -695,6 +695,9 @@ make_array_from_file() {
:
fi
done < "${filename}"
+ for each_line in "${file_content[@]}"; do
+ log_write " ${each_line}"
+ done
fi
}
@@ -765,9 +768,6 @@ list_files_in_dir() {
log_write "\n${COL_LIGHT_GREEN}$(ls -ld ${dir_to_parse}/${each_file})${COL_NC}"
# Then, parse the file's content into an array so each line can be analyzed if need be
make_array_from_file "${dir_to_parse}/${each_file}"
- for each_line in "${file_content[@]}"; do
- log_write " ${each_line}"
- done
fi
done
}
From 64171fa2a11140d38432f0dbc24da180212df372 Mon Sep 17 00:00:00 2001
From: Jacob Salmela
Date: Fri, 9 Jun 2017 15:42:54 -0500
Subject: [PATCH 074/162] small color and formatting changes
---
advanced/Scripts/piholeDebug.sh | 22 +++++++++++-----------
1 file changed, 11 insertions(+), 11 deletions(-)
diff --git a/advanced/Scripts/piholeDebug.sh b/advanced/Scripts/piholeDebug.sh
index a488248a..f2dabc14 100755
--- a/advanced/Scripts/piholeDebug.sh
+++ b/advanced/Scripts/piholeDebug.sh
@@ -259,7 +259,7 @@ get_program_version() {
log_write "${CROSS} ${COL_LIGHT_RED}${program_name} version could not be detected.${COL_NC}"
else
# Otherwise, display the version
- log_write "${TICK} ${program_name}: ${program_version}"
+ log_write "${INFO} ${program_version}"
fi
}
@@ -377,7 +377,7 @@ does_ip_match_setup_vars() {
log_write " ${COL_LIGHT_GREEN}${ip_address%/*}${COL_NC} matches the IP found in ${VARSFILE}"
else
# otherwise show it in red with an FAQ URL
- log_write " ${COL_LIGHT_RED}${ip_address%/*}${COL_NC} does not match the IP found in ${VARSFILE}(${FAQ_ULA})"
+ log_write " ${COL_LIGHT_RED}${ip_address%/*}${COL_NC} does not match the IP found in ${VARSFILE} (${FAQ_ULA})"
fi
else
@@ -457,7 +457,7 @@ ping_gateway() {
if [[ -n "${gateway}" ]]; then
log_write "${INFO} Default IPv${protocol} gateway: ${gateway}"
# Let the user know we will ping the gateway for a response
- log_write "* Pinging ${gateway}..."
+ log_write " * Pinging ${gateway}..."
# Try to quietly ping the gateway 3 times, with a timeout of 3 seconds, using numeric output only,
# on the pihole interface, and tail the last three lines of the output
# If pinging the gateway is not successful,
@@ -621,10 +621,10 @@ dig_at() {
# First, do a dig on localhost to see if Pi-hole can use itself to block a domain
if local_dig=$(dig +tries=1 +time=2 -"${protocol}" "${random_url}" @${local_address} +short "${record_type}"); then
# If it can, show sucess
- log_write "${TICK} ${random_url} ${COL_LIGHT_GREEN}is ${local_dig}${COL_NC} via localhost (${local_address})"
+ log_write "${TICK} ${random_url} ${COL_LIGHT_GREEN}is ${local_dig}${COL_NC} via ${COL_CYAN}localhost$COL_NC (${local_address})"
else
# Otherwise, show a failure
- log_write "${CROSS} ${COL_LIGHT_RED}Failed to resolve${COL_NC} ${random_url} ${COL_LIGHT_RED}via localhost${COL_NC} (${local_address})"
+ log_write "${CROSS} ${COL_LIGHT_RED}Failed to resolve${COL_NC} ${random_url} via ${COL_LIGHT_RED}localhost${COL_NC} (${local_address})"
fi
# Next we need to check if Pi-hole can resolve a domain when the query is sent to it's IP address
@@ -635,20 +635,20 @@ dig_at() {
# If Pi-hole can dig itself from it's IP (not the loopback address)
if pihole_dig=$(dig +tries=1 +time=2 -"${protocol}" "${random_url}" @${pihole_address} +short "${record_type}"); then
# show a success
- log_write "${TICK} ${random_url} ${COL_LIGHT_GREEN}is ${pihole_dig}${COL_NC} via Pi-hole (${pihole_address})"
+ log_write "${TICK} ${random_url} ${COL_LIGHT_GREEN}is ${pihole_dig}${COL_NC} via ${COL_CYAN}Pi-hole${COL_NC} (${pihole_address})"
else
# Othewise, show a failure
- log_write "${CROSS} ${COL_LIGHT_RED}Failed to resolve${COL_NC} ${random_url} ${COL_LIGHT_RED}via Pi-hole${COL_NC} (${pihole_address})"
+ log_write "${CROSS} ${COL_LIGHT_RED}Failed to resolve${COL_NC} ${random_url} via ${COL_LIGHT_RED}Pi-hole${COL_NC} (${pihole_address})"
fi
# Finally, we need to make sure legitimate queries can out to the Internet using an external, public DNS server
# We are using the static remote_url here instead of a random one because we know it works with IPv4 and IPv6
if remote_dig=$(dig +tries=1 +time=2 -"${protocol}" "${remote_url}" @${remote_address} +short "${record_type}" | head -n1); then
# If successful, the real IP of the domain will be returned instead of Pi-hole's IP
- log_write "${TICK} ${remote_url} ${COL_LIGHT_GREEN}is ${remote_dig}${COL_NC} via a remote, public DNS server (${remote_address})"
+ log_write "${TICK} ${remote_url} ${COL_LIGHT_GREEN}is ${remote_dig}${COL_NC} via ${COL_CYAN}a remote, public DNS server${COL_NC} (${remote_address})"
else
# Otherwise, show an error
- log_write "${CROSS} ${COL_LIGHT_RED}Failed to resolve${COL_NC} ${remote_url} ${COL_LIGHT_RED}via a remote, public DNS server${COL_NC} (${remote_address})"
+ log_write "${CROSS} ${COL_LIGHT_RED}Failed to resolve${COL_NC} ${remote_url} via ${COL_LIGHT_RED}a remote, public DNS server${COL_NC} (${remote_address})"
fi
}
@@ -741,7 +741,7 @@ dir_check() {
# Set the first argument passed to tihs function as a named variable for better readability
local directory="${1}"
# Display the current test that is running
- echo_current_diagnostic "contents of ${directory}"
+ echo_current_diagnostic "contents of ${COL_CYAN}${directory}${COL_NC}"
# For each file in the directory,
for filename in "${directory}"; do
# check if exists first; if it does,
@@ -749,7 +749,7 @@ dir_check() {
# do nothing
: || \
# Otherwise, show an error
- echo_succes_or_fail "${COL_LIGHT_RED}directory does not exist.${COL_NC}"
+ echo_succes_or_fail "${COL_LIGHT_RED}${directory} does not exist.${COL_NC}"
done
}
From b4f1fe08f0cc83a8aa760002b3621c3668d8896a Mon Sep 17 00:00:00 2001
From: Jacob Salmela
Date: Fri, 9 Jun 2017 23:22:37 -0500
Subject: [PATCH 075/162] variablize all files and directories. also put
required files and folders into an arry so we can compare them in later
functions by parsing through them
---
advanced/Scripts/piholeDebug.sh | 202 +++++++++++++++++++++++---------
1 file changed, 146 insertions(+), 56 deletions(-)
diff --git a/advanced/Scripts/piholeDebug.sh b/advanced/Scripts/piholeDebug.sh
index f2dabc14..fe2bf36b 100755
--- a/advanced/Scripts/piholeDebug.sh
+++ b/advanced/Scripts/piholeDebug.sh
@@ -19,31 +19,14 @@ set -o pipefail
#IFS=$'\n\t'
######## GLOBAL VARS ########
-SUPPORTED_OS=("Raspbian" "Ubuntu" "Fedora" "Debian" "CentOS")
-
-VARSFILE="/etc/pihole/setupVars.conf"
-DEBUG_LOG="/var/log/pihole_debug.log"
-DNSMASQFILE="/etc/dnsmasq.conf"
-DNSMASQCONFDIR="/etc/dnsmasq.d"
-LIGHTTPDFILE="/etc/lighttpd/lighttpd.conf"
-LIGHTTPDERRFILE="/var/log/lighttpd/error.log"
-GRAVITYFILE="/etc/pihole/gravity.list"
-WHITELISTFILE="/etc/pihole/whitelist.txt"
-BLACKLISTFILE="/etc/pihole/blacklist.txt"
-ADLISTFILE="/etc/pihole/adlists.list"
-PIHOLELOG="/var/log/pihole.log"
-PIHOLEGITDIR="/etc/.pihole/"
-ADMINGITDIR="/var/www/html/admin/"
-WHITELISTMATCHES="/tmp/whitelistmatches.list"
-readonly FTLLOG="/var/log/pihole-FTL.log"
-coltable=/opt/pihole/COL_TABLE
-FTL_LOG="/var/log/pihole-FTL.log"
-FTL_PID="/run/pihole-FTL.pid"
-FTL_PORT="/run/pihole-FTL.port"
+# These variables would normally be next to the other files
+# but we need them to be first in order to get the colors needed for the script output
+PIHOLE_SCRIPTS_DIRECTORY="/opt/pihole"
+PIHOLE_COLTABLE_FILE="${PIHOLE_SCRIPTS_DIRECTORY}/COL_TABLE"
# These provide the colors we need for making the log more readable
-if [[ -f ${coltable} ]]; then
- source ${coltable}
+if [[ -f ${PIHOLE_COLTABLE_FILE} ]]; then
+ source ${PIHOLE_COLTABLE_FILE}
else
COL_NC='\e[0m' # No Color
COL_YELLOW='\e[1;33m'
@@ -56,7 +39,7 @@ else
OVER="\r\033[K"
fi
-# FAQ URLs
+# FAQ URLs for use in showing the debug log
FAQ_UPDATE_PI_HOLE="${COL_CYAN}https://discourse.pi-hole.net/t/how-do-i-update-pi-hole/249${COL_NC}"
FAQ_CHECKOUT_COMMAND="${COL_CYAN}https://discourse.pi-hole.net/t/the-pihole-command-with-examples/738#checkout${COL_NC}"
FAQ_HARDWARE_REQUIREMENTS="${COL_CYAN}https://discourse.pi-hole.net/t/hardware-software-requirements/273${COL_NC}"
@@ -64,16 +47,123 @@ FAQ_GATEWAY="${COL_CYAN}https://discourse.pi-hole.net/t/why-is-a-default-gateway
FAQ_ULA="${COL_CYAN}https://discourse.pi-hole.net/t/use-ipv6-ula-addresses-for-pi-hole/2127${COL_NC}"
FAQ_FTL_COMPATIBILITY="${COL_CYAN}https://github.com/pi-hole/FTL#compatibility-list${COL_NC}"
+# Other URLs we may use
+FORUMS_URL="${COL_CYAN}https://discourse.pi-hole.net${COL_NC}"
+TRICORDER_CONTEST="${COL_CYAN}https://pi-hole.net/2016/11/07/crack-our-medical-tricorder-win-a-raspberry-pi-3/${COL_NC}"
+
+# Port numbers used for uploading the debug log
+TRICORDER_NC_PORT_NUMBER=9999
+TRICORDER_SSL_PORT_NUMBER=9998
+
+# Directories required by Pi-hole
+# https://discourse.pi-hole.net/t/what-files-does-pi-hole-use/1684
+CORE_GIT_DIRECTORY="/etc/.pihole"
+CRON_D_DIRECTORY="/etc/cron.d"
+DNSMASQ_D_DIRECTORY="/etc/dnsmasq.d"
+PIHOLE_DIRECTORY="/etc/pihole"
+PIHOLE_SCRIPTS_DIRECTORY="/opt/pihole"
+BIN_DIRECTORY="/usr/local/bin"
+RUN_DIRECTORY="/run"
+LOG_DIRECTORY="/var/log"
+WEB_SERVER_LOG_DIRECTORY="${LOG_DIRECTORY}/lighttpd"
+WEB_SERVER_CONFIG_DIRECTORY="/etc/lighttpd"
+HTML_DIRECTORY="/var/www/html"
+WEB_GIT_DIRECTORY="${HTML_DIRECTORY}/admin"
+BLOCK_PAGE_DIRECTORY="${HTML_DIRECTORY}/pihole"
+
+# Files required by Pi-hole
+# https://discourse.pi-hole.net/t/what-files-does-pi-hole-use/1684
+PIHOLE_CRON_FILE="${CRON_D_DIRECTORY}/pihole"
+
+PIHOLE_DNS_CONFIG_FILE="${DNSMASQ_D_DIRECTORY}/01-pihole.conf"
+PIHOLE_DHCP_CONFIG_FILE="${DNSMASQ_D_DIRECTORY}/02-pihole-dhcp.conf"
+PIHOLE_WILDCARD_CONFIG_FILE="${DNSMASQ_D_DIRECTORY}/03-wildcard.conf"
+
+WEB_SERVER_CONFIG_FILE="${WEB_SERVER_CONFIG_DIRECTORY}/lighttpd.conf"
+
+PIHOLE_DEFAULT_AD_LISTS="${PIHOLE_DIRECTORY}/adlists.default"
+PIHOLE_USER_DEFINED_AD_LISTS="${PIHOLE_DIRECTORY}/adlists.list"
+PIHOLE_BLACKLIST_FILE="${PIHOLE_DIRECTORY}/blacklist.txt"
+PIHOLE_BLOCKLIST_FILE="${PIHOLE_DIRECTORY}/gravity.list"
+PIHOLE_INSTALL_LOG_FILE="${PIHOLE_DIRECTORY}/install.log"
+PIHOLE_RAW_BLOCKLIST_FILES=${PIHOLE_DIRECTORY}/list.*
+PIHOLE_LOCAL_HOSTS_FILE="${PIHOLE_DIRECTORY}/local.list"
+PIHOLE_LOGROTATE_FILE="${PIHOLE_DIRECTORY}/logrotate"
+PIHOLE_SETUP_VARS_FILE="${PIHOLE_DIRECTORY}/setupVars.conf"
+PIHOLE_WHITELIST_FILE="${PIHOLE_DIRECTORY}/whitelist.txt"
+
+PIHOLE_COMMAND="${BIN_DIRECTORY}/pihole"
+PIHOLE_COLTABLE_FILE="${BIN_DIRECTORY}/COL_TABLE"
+
+FTL_PID="${RUN_DIRECTORY}/pihole-FTL.pid"
+FTL_PORT="${RUN_DIRECTORY}/pihole-FTL.port"
+
+PIHOLE_LOG="${LOG_DIRECTORY}/pihole.log"
+PIHOLE_LOG_GZIPS=${LOG_DIRECTORY}/pihole.log.[0-9].*
+PIHOLE_DEBUG_LOG="${LOG_DIRECTORY}/pihole_debug.log"
+PIHOLE_FTL_LOG="${LOG_DIRECTORY}/pihole-FTL.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"
+
+# An array of operating system "pretty names" that we officialy support
+# We can loop through the array at any time to see if it matches a value
+SUPPORTED_OS=("Raspbian" "Ubuntu" "Fedora" "Debian" "CentOS")
+
+# In a similar fashion, these are the folders Pi-hole needs
+# https://discourse.pi-hole.net/t/what-files-does-pi-hole-use/1684
+REQUIRED_DIRECTORIES=(${CORE_GIT_DIRECTORY}
+${CRON_D_DIRECTORY}
+${DNSMASQ_D_DIRECTORY}
+${PIHOLE_DIRECTORY}
+${PIHOLE_SCRIPTS_DIRECTORY}
+${BIN_DIRECTORY}
+${RUN_DIRECTORY}
+${LOG_DIRECTORY}
+${WEB_SERVER_LOG_DIRECTORY}
+${WEB_SERVER_CONFIG_DIRECTORY}
+${HTML_DIRECTORY}
+${WEB_GIT_DIRECTORY}
+${BLOCK_PAGE_DIRECTORY})
+
+# These are the files Pi-hole needs--also stored in array for parsing through
+# https://discourse.pi-hole.net/t/what-files-does-pi-hole-use/1684
+REQUIRED_FILES=(${PIHOLE_CRON_FILE}
+${PIHOLE_DNS_CONFIG_FILE}
+${PIHOLE_DHCP_CONFIG_FILE}
+${PIHOLE_WILDCARD_CONFIG_FILE}
+${WEB_SERVER_CONFIG_FILE}
+${PIHOLE_DEFAULT_AD_LISTS}
+${PIHOLE_USER_DEFINED_AD_LISTS}
+${PIHOLE_BLACKLIST_FILE}
+${PIHOLE_BLOCKLIST_FILE}
+${PIHOLE_INSTALL_LOG_FILE}
+${PIHOLE_RAW_BLOCKLIST_FILES}
+${PIHOLE_LOCAL_HOSTS_FILE}
+${PIHOLE_LOGROTATE_FILE}
+${PIHOLE_SETUP_VARS_FILE}
+${PIHOLE_WHITELIST_FILE}
+${PIHOLE_COMMAND}
+${PIHOLE_COLTABLE_FILE}
+${FTL_PID}
+${FTL_PORT}
+${PIHOLE_LOG}
+${PIHOLE_LOG_GZIPS}
+${PIHOLE_DEBUG_LOG}
+${PIHOLE_FTL_LOG}
+${PIHOLE_WEB_SERVER_ACCESS_LOG_FILE}
+${PIHOLE_WEB_SERVER_ERROR_LOG_FILE})
+
source_setup_variables() {
# Display the current test that is running
- log_write "\n${COL_LIGHT_PURPLE}*** [ INITIALIZING ]${COL_NC} Sourcing setup varibles"
+ log_write "\n${COL_LIGHT_PURPLE}*** [ INITIALIZING ]${COL_NC} Sourcing setup variables"
# If the variable file exists,
- if_file_exists "${VARSFILE}" && \
- log_write "${INFO} Sourcing ${VARSFILE}...";
+ if_file_exists "${PIHOLE_SETUP_VARS_FILE}" && \
+ log_write "${INFO} Sourcing ${PIHOLE_SETUP_VARS_FILE}...";
# source it
- source ${VARSFILE} || \
+ source ${PIHOLE_SETUP_VARS_FILE} || \
# If it can't, show an error
- log_write "${VARSFILE} ${COL_LIGHT_RED}does not exist or cannot be read.${COL_NC}"
+ log_write "${PIHOLE_SETUP_VARS_FILE} ${COL_LIGHT_RED}does not exist or cannot be read.${COL_NC}"
}
make_temporary_log() {
@@ -93,7 +183,7 @@ log_write() {
copy_to_debug_log() {
# Copy the contents of file descriptor 3 into the debug log so it can be uploaded to tricorder
- cat /proc/$$/fd/3 >> "${DEBUG_LOG}"
+ cat /proc/$$/fd/3 >> "${PIHOLE_DEBUG_LOG}"
}
echo_succes_or_fail() {
@@ -232,9 +322,9 @@ check_ftl_version() {
# Checks the core version of the Pi-hole codebase
check_component_versions() {
# Check the Web version, branch, and commit
- compare_local_version_to_git_version "${PIHOLEGITDIR}" "Core"
+ compare_local_version_to_git_version "${CORE_GIT_DIRECTORY}" "Core"
# Check the Web version, branch, and commit
- compare_local_version_to_git_version "${ADMINGITDIR}" "Web"
+ compare_local_version_to_git_version "${WEB_GIT_DIRECTORY}" "Web"
# Check the FTL version
check_ftl_version
}
@@ -357,9 +447,9 @@ processor_check() {
parse_setup_vars() {
echo_current_diagnostic "Setup variables"
- if_file_exists "${VARSFILE}" && \
- parse_file "${VARSFILE}" || \
- log_write "${CROSS} ${COL_LIGHT_RED}Could not read ${VARSFILE}.${COL_NC}"
+ if_file_exists "${PIHOLE_SETUP_VARS_FILE}" && \
+ parse_file "${PIHOLE_SETUP_VARS_FILE}" || \
+ log_write "${CROSS} ${COL_LIGHT_RED}Could not read ${PIHOLE_SETUP_VARS_FILE}.${COL_NC}"
}
does_ip_match_setup_vars() {
@@ -368,16 +458,16 @@ does_ip_match_setup_vars() {
# IP address to check for
local ip_address="${2}"
# See what IP is in the setupVars.conf file
- local setup_vars_ip=$(cat ${VARSFILE} | grep IPV${protocol}_ADDRESS | cut -d '=' -f2)
+ local setup_vars_ip=$(cat ${PIHOLE_SETUP_VARS_FILE} | grep IPV${protocol}_ADDRESS | cut -d '=' -f2)
# If it's an IPv6 address
if [[ "${protocol}" == "6" ]]; then
# Strip off the /
if [[ "${ip_address%/*}" == "${setup_vars_ip}" ]]; then
# if it matches, show it in green
- log_write " ${COL_LIGHT_GREEN}${ip_address%/*}${COL_NC} matches the IP found in ${VARSFILE}"
+ log_write " ${COL_LIGHT_GREEN}${ip_address%/*}${COL_NC} matches the IP found in ${PIHOLE_SETUP_VARS_FILE}"
else
# otherwise show it in red with an FAQ URL
- log_write " ${COL_LIGHT_RED}${ip_address%/*}${COL_NC} does not match the IP found in ${VARSFILE} (${FAQ_ULA})"
+ log_write " ${COL_LIGHT_RED}${ip_address%/*}${COL_NC} does not match the IP found in ${PIHOLE_SETUP_VARS_FILE} (${FAQ_ULA})"
fi
else
@@ -385,10 +475,10 @@ does_ip_match_setup_vars() {
# since it exists in the setupVars.conf that way
if [[ "${ip_address}" == "${setup_vars_ip}" ]]; then
# show in green if it matches
- log_write " ${COL_LIGHT_GREEN}${ip_address}${COL_NC} matches the IP found in ${VARSFILE}"
+ log_write " ${COL_LIGHT_GREEN}${ip_address}${COL_NC} matches the IP found in ${PIHOLE_SETUP_VARS_FILE}"
else
# otherwise show it in red
- log_write " ${COL_LIGHT_RED}${ip_address}${COL_NC} does not match the IP found in ${VARSFILE} (${FAQ_ULA})"
+ log_write " ${COL_LIGHT_RED}${ip_address}${COL_NC} does not match the IP found in ${PIHOLE_SETUP_VARS_FILE} (${FAQ_ULA})"
fi
fi
}
@@ -423,7 +513,7 @@ detect_ip_addresses() {
if [[ "${protocol}" == "6" ]]; then
# let the user know that as long as there is one green address, things should be ok
log_write " ^ Please note that you may have more than one IP address listed."
- log_write " As long as one of them is green, and it matches what is in ${VARSFILE}, there is no need for concern.\n"
+ log_write " As long as one of them is green, and it matches what is in ${PIHOLE_SETUP_VARS_FILE}, there is no need for concern.\n"
log_write " The link to the FAQ is for an issue that sometimes occurs when the IPv6 address changes, which is why we check for it.\n"
fi
}
@@ -616,7 +706,7 @@ dig_at() {
# Find a random blocked url that has not been whitelisted.
# This helps emulate queries to different domains that a user might query
# It will also give extra assurance that Pi-hole is correctly resolving and blocking domains
- local random_url=$(shuf -n 1 "${GRAVITYFILE}" | awk -F ' ' '{ print $2 }')
+ local random_url=$(shuf -n 1 "${PIHOLE_BLOCKLIST_FILE}" | awk -F ' ' '{ print $2 }')
# First, do a dig on localhost to see if Pi-hole can use itself to block a domain
if local_dig=$(dig +tries=1 +time=2 -"${protocol}" "${random_url}" @${local_address} +short "${record_type}"); then
@@ -783,22 +873,22 @@ show_content_of_files_in_dir() {
show_content_of_pihole_files() {
# Show the content of the files in /etc/dnsmasq.d
- show_content_of_files_in_dir "${DNSMASQCONFDIR}"
+ show_content_of_files_in_dir "${DNSMASQ_D_DIRECTORY}"
# Show the content of the files in /etc/lighttpd
show_content_of_files_in_dir "/etc/lighttpd"
# Show the content of the files in /etc/lighttpd
show_content_of_files_in_dir "/etc/cron.d"
# Show the content of the files in /var/www/html
- # show_content_of_files_in_dir "${ADMINGITDIR}"
+ # show_content_of_files_in_dir "${WEB_GIT_DIRECTORY}"
}
analyze_gravity_list() {
echo_current_diagnostic "Gravity list"
# It's helpful to know how big a user's gravity file is
- gravity_length=$(grep -c ^ "${GRAVITYFILE}") && \
- log_write "${INFO} ${GRAVITYFILE} is ${gravity_length} lines long." || \
+ gravity_length=$(grep -c ^ "${PIHOLE_BLOCKLIST_FILE}") && \
+ log_write "${INFO} ${PIHOLE_BLOCKLIST_FILE} is ${gravity_length} lines long." || \
# If the previous command failed, something is wrong with the file
- log_write "${CROSS} ${COL_LIGHT_RED}${GRAVITYFILE} not found!${COL_NC}"
+ log_write "${CROSS} ${COL_LIGHT_RED}${PIHOLE_BLOCKLIST_FILE} not found!${COL_NC}"
}
tricorder_use_nc_or_ssl() {
@@ -808,20 +898,20 @@ tricorder_use_nc_or_ssl() {
# If the command exists,
log_write " * Using ${COL_LIGHT_GREEN}openssl${COL_NC} for transmission."
# encrypt and transmit the log and store the token returned in a variable
- tricorder_token=$(cat ${DEBUG_LOG} | openssl s_client -quiet -connect tricorder.pi-hole.net:9998 2> /dev/null)
+ tricorder_token=$(cat ${PIHOLE_DEBUG_LOG} | openssl s_client -quiet -connect tricorder.pi-hole.net:${TRICORDER_SSL_PORT_NUMBER} 2> /dev/null)
# Otherwise,
else
# use net cat
log_write "${INFO} Using ${COL_YELLOW}netcat${COL_NC} for transmission."
- tricorder_token=$(cat ${DEBUG_LOG} | nc tricorder.pi-hole.net 9999)
+ tricorder_token=$(cat ${PIHOLE_DEBUG_LOG} | nc tricorder.pi-hole.net ${TRICORDER_NC_PORT_NUMBER})
fi
}
upload_to_tricorder() {
# Set the permissions and owner
- chmod 644 ${DEBUG_LOG}
- chown "$USER":pihole ${DEBUG_LOG}
+ chmod 644 ${PIHOLE_DEBUG_LOG}
+ chown "$USER":pihole ${PIHOLE_DEBUG_LOG}
# Let the user know debugging is complete
echo ""
@@ -829,7 +919,7 @@ upload_to_tricorder() {
# Provide information on what they should do with their token
log_write " * The debug log can be uploaded to tricorder.pi-hole.net for sharing with developers only."
- log_write " * For more information, see: ${COL_CYAN}https://pi-hole.net/2016/11/07/crack-our-medical-tricorder-win-a-raspberry-pi-3/${COL_NC}"
+ log_write " * For more information, see: ${TRICORDER_CONTEST}"
log_write " * If available, we'll use openssl to upload the log, otherwise it will fall back to netcat."
# If pihole -d is running automatically (usually throught the dashboard)
if [[ "${AUTOMATED}" ]]; then
@@ -838,10 +928,10 @@ upload_to_tricorder() {
# and then decide again which tool to use to submit it
if command -v openssl &> /dev/null; then
log_write "${INFO} Using ${COL_LIGHT_GREEN}openssl${COL_NC} for transmission."
- tricorder_token=$(openssl s_client -quiet -connect tricorder.pi-hole.net:9998 2> /dev/null < /dev/stdin)
+ tricorder_token=$(openssl s_client -quiet -connect tricorder.pi-hole.net:${TRICORDER_SSL_PORT_NUMBER} 2> /dev/null < /dev/stdin)
else
log_write "${INFO} Using ${COL_YELLOW}netcat${COL_NC} for transmission."
- tricorder_token=$(nc tricorder.pi-hole.net 9999 < /dev/stdin)
+ tricorder_token=$(nc tricorder.pi-hole.net ${TRICORDER_NC_PORT_NUMBER} < /dev/stdin)
fi
else
echo ""
@@ -864,13 +954,13 @@ upload_to_tricorder() {
log_write "${COL_LIGHT_PURPLE}***********************************${COL_NC}"
log_write ""
log_write " * Provide this token to the Pi-hole team for assistance at"
- log_write " * ${COL_CYAN}https://discourse.pi-hole.net${COL_NC}"
+ log_write " * ${FORUMS_URL}"
log_write " * Your log will self-destruct on our server after ${COL_LIGHT_RED}48 hours${COL_NC}."
else
log_write "${CROSS} ${COL_LIGHT_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
- log_write " * A local copy of the debug log can be found at: ${COL_CYAN}${DEBUG_LOG}${COL_NC}\n"
+ log_write " * A local copy of the debug log can be found at: ${COL_CYAN}${PIHOLE_DEBUG_LOG}${COL_NC}\n"
}
# Run through all the functions we made
From e10182c839b0d9b560b043332410f547e11845b6 Mon Sep 17 00:00:00 2001
From: Jacob Salmela
Date: Sat, 10 Jun 2017 12:27:05 -0500
Subject: [PATCH 076/162] only parse files required by Pi-hole
---
advanced/Scripts/piholeDebug.sh | 13 ++++++++++---
1 file changed, 10 insertions(+), 3 deletions(-)
diff --git a/advanced/Scripts/piholeDebug.sh b/advanced/Scripts/piholeDebug.sh
index fe2bf36b..b3fdfce1 100755
--- a/advanced/Scripts/piholeDebug.sh
+++ b/advanced/Scripts/piholeDebug.sh
@@ -854,10 +854,17 @@ list_files_in_dir() {
# If it's a directoy, do nothing
:
else
- # Othwerise, display the filename
- log_write "\n${COL_LIGHT_GREEN}$(ls -ld ${dir_to_parse}/${each_file})${COL_NC}"
# Then, parse the file's content into an array so each line can be analyzed if need be
- make_array_from_file "${dir_to_parse}/${each_file}"
+ for i in "${!REQUIRED_FILES[@]}"; do
+ if [[ "${dir_to_parse}/${each_file}" == ${REQUIRED_FILES[$i]} ]]; then
+ # display the filename
+ log_write "\n${COL_LIGHT_GREEN}$(ls -ld ${dir_to_parse}/${each_file})${COL_NC}"
+ # and parse the file into an array in case we ever need to analyze it line-by-line
+ make_array_from_file "${dir_to_parse}/${each_file}"
+ else
+ :
+ fi
+ done
fi
done
}
From b0cc1a38c3a2786cc72b1354ed67ac898c799f51 Mon Sep 17 00:00:00 2001
From: Jacob Salmela
Date: Sat, 10 Jun 2017 15:28:04 -0500
Subject: [PATCH 077/162] adjust minor formatting for better readability
---
advanced/Scripts/piholeDebug.sh | 12 ++++++++----
1 file changed, 8 insertions(+), 4 deletions(-)
diff --git a/advanced/Scripts/piholeDebug.sh b/advanced/Scripts/piholeDebug.sh
index b3fdfce1..c754f4b1 100755
--- a/advanced/Scripts/piholeDebug.sh
+++ b/advanced/Scripts/piholeDebug.sh
@@ -921,8 +921,10 @@ upload_to_tricorder() {
chown "$USER":pihole ${PIHOLE_DEBUG_LOG}
# Let the user know debugging is complete
- echo ""
- log_write "${TICK} ${COL_LIGHT_GREEN}** Finished debugging! **${COL_NC}\n"
+ log_write ""
+ log_write "${COL_LIGHT_PURPLE}********************************************${COL_NC}"
+ log_write "${COL_LIGHT_PURPLE}********************************************${COL_NC}"
+ log_write "${TICK} ${COL_LIGHT_GREEN}** FINISHED DEBUGGING! **${COL_NC}\n"
# Provide information on what they should do with their token
log_write " * The debug log can be uploaded to tricorder.pi-hole.net for sharing with developers only."
@@ -955,12 +957,14 @@ upload_to_tricorder() {
# Check if tricorder.pi-hole.net is reachable and provide token
# along with some additional useful information
if [[ -n "${tricorder_token}" ]]; then
- echo ""
+ log_write ""
+ log_write "${COL_LIGHT_PURPLE}***********************************${COL_NC}"
log_write "${COL_LIGHT_PURPLE}***********************************${COL_NC}"
log_write "${TICK} Your debug token is: ${COL_LIGHT_GREEN}${tricorder_token}${COL_NC}"
log_write "${COL_LIGHT_PURPLE}***********************************${COL_NC}"
+ log_write "${COL_LIGHT_PURPLE}***********************************${COL_NC}"
log_write ""
- log_write " * Provide this token to the Pi-hole team for assistance at"
+ log_write " * Provide the token above to the Pi-hole team for assistance at"
log_write " * ${FORUMS_URL}"
log_write " * Your log will self-destruct on our server after ${COL_LIGHT_RED}48 hours${COL_NC}."
else
From 3275c5f7109554ebfb5c6bb8771779b662cd905f Mon Sep 17 00:00:00 2001
From: Jacob Salmela
Date: Sat, 10 Jun 2017 15:54:27 -0500
Subject: [PATCH 078/162] more comments to help understand the script
---
advanced/Scripts/piholeDebug.sh | 78 ++++++++++++++++++++++-----------
1 file changed, 53 insertions(+), 25 deletions(-)
diff --git a/advanced/Scripts/piholeDebug.sh b/advanced/Scripts/piholeDebug.sh
index c754f4b1..3a2f9803 100755
--- a/advanced/Scripts/piholeDebug.sh
+++ b/advanced/Scripts/piholeDebug.sh
@@ -110,8 +110,10 @@ PIHOLE_WEB_SERVER_ERROR_LOG_FILE="${WEB_SERVER_LOG_DIRECTORY}/error.log"
# We can loop through the array at any time to see if it matches a value
SUPPORTED_OS=("Raspbian" "Ubuntu" "Fedora" "Debian" "CentOS")
-# In a similar fashion, these are the folders Pi-hole needs
-# https://discourse.pi-hole.net/t/what-files-does-pi-hole-use/1684
+# Store Pi-hole's processes in an array for easy use and parsing
+PIHOLE_PROCESSES=( dnsmasq lighttpd pihole-FTL )
+
+# Store the required directories in an array so it can be parsed through
REQUIRED_DIRECTORIES=(${CORE_GIT_DIRECTORY}
${CRON_D_DIRECTORY}
${DNSMASQ_D_DIRECTORY}
@@ -126,8 +128,7 @@ ${HTML_DIRECTORY}
${WEB_GIT_DIRECTORY}
${BLOCK_PAGE_DIRECTORY})
-# These are the files Pi-hole needs--also stored in array for parsing through
-# https://discourse.pi-hole.net/t/what-files-does-pi-hole-use/1684
+# Store the required directories in an array so it can be parsed through
REQUIRED_FILES=(${PIHOLE_CRON_FILE}
${PIHOLE_DNS_CONFIG_FILE}
${PIHOLE_DHCP_CONFIG_FILE}
@@ -167,12 +168,13 @@ source_setup_variables() {
}
make_temporary_log() {
- # Create temporary file for log
+ # Create a random temporary file for the log
TEMPLOG=$(mktemp /tmp/pihole_temp.XXXXXX)
# Open handle 3 for templog
# https://stackoverflow.com/questions/18460186/writing-outputs-to-log-file-and-console
exec 3>"$TEMPLOG"
- # Delete templog, but allow for addressing via file handle.
+ # Delete templog, but allow for addressing via file handle
+ # This lets us write to the log without having a temporary file on the drive
rm "$TEMPLOG"
}
@@ -254,6 +256,7 @@ compare_local_version_to_git_version() {
# We need to search for "Pi-hole" when using pihole -v
local search_term="Pi-hole"
elif [[ "${pihole_component}" == "Web" ]]; then
+ # We need to search for "AdminLTE" so store it in a variable as well
local search_term="AdminLTE"
fi
# Display what we are checking
@@ -332,8 +335,10 @@ check_component_versions() {
get_program_version() {
local program_name="${1}"
+ # Create a loval variable so this function can be safely reused
local program_version
echo_current_diagnostic "${program_name} version"
+ # Evalutate the program we are checking, if it is any of the ones below, show the version
case "${program_name}" in
"lighttpd") program_version="$(${program_name} -v |& head -n1 | cut -d '/' -f2 | cut -d ' ' -f1)"
;;
@@ -341,9 +346,10 @@ get_program_version() {
;;
"php") program_version="$(${program_name} -v |& head -n1 | cut -d '-' -f1 | cut -d ' ' -f2)"
;;
+ # If a match is not found, show an error
*) echo "Unrecognized program";
esac
- # If the Web server does not have a version (the variable is empty)
+ # If the program does not have a version (the variable is empty)
if [[ -z "${program_version}" ]]; then
# Display and error
log_write "${CROSS} ${COL_LIGHT_RED}${program_name} version could not be detected.${COL_NC}"
@@ -364,13 +370,17 @@ check_critical_program_versions() {
is_os_supported() {
local os_to_check="${1}"
+ # Strip just the base name of the system using sed
the_os=$(echo ${os_to_check} | sed 's/ .*//')
+ # If the variable is one of our supported OSes,
case "${the_os}" in
+ # Print it in green
"Raspbian") log_write "${TICK} ${COL_LIGHT_GREEN}${os_to_check}${COL_NC}";;
"Ubuntu") log_write "${TICK} ${COL_LIGHT_GREEN}${os_to_check}${COL_NC}";;
"Fedora") log_write "${TICK} ${COL_LIGHT_GREEN}${os_to_check}${COL_NC}";;
"Debian") log_write "${TICK} ${COL_LIGHT_GREEN}${os_to_check}${COL_NC}";;
"CentOS") log_write "${TICK} ${COL_LIGHT_GREEN}${os_to_check}${COL_NC}";;
+ # If not, show it in red and link to our software requirements page
*) log_write "${CROSS} ${COL_LIGHT_RED}${os_to_check}${COL_NC} (${FAQ_HARDWARE_REQUIREMENTS})";
esac
}
@@ -447,8 +457,11 @@ processor_check() {
parse_setup_vars() {
echo_current_diagnostic "Setup variables"
+ # If the file exists,
if_file_exists "${PIHOLE_SETUP_VARS_FILE}" && \
+ # parse it
parse_file "${PIHOLE_SETUP_VARS_FILE}" || \
+ # If not, show an error
log_write "${CROSS} ${COL_LIGHT_RED}Could not read ${PIHOLE_SETUP_VARS_FILE}.${COL_NC}"
}
@@ -461,7 +474,7 @@ does_ip_match_setup_vars() {
local setup_vars_ip=$(cat ${PIHOLE_SETUP_VARS_FILE} | grep IPV${protocol}_ADDRESS | cut -d '=' -f2)
# If it's an IPv6 address
if [[ "${protocol}" == "6" ]]; then
- # Strip off the /
+ # Strip off the / (CIDR notation)
if [[ "${ip_address%/*}" == "${setup_vars_ip}" ]]; then
# if it matches, show it in green
log_write " ${COL_LIGHT_GREEN}${ip_address%/*}${COL_NC} matches the IP found in ${PIHOLE_SETUP_VARS_FILE}"
@@ -501,8 +514,8 @@ detect_ip_addresses() {
for i in "${!ip_addr_list[@]}"; do
# For each one in the list, print it out
does_ip_match_setup_vars "${protocol}" "${ip_addr_list[$i]}"
- # log_write " ${ip_addr_list[$i]}"
done
+ # Print a blank line just for formatting
log_write ""
else
# If there are no IPs detected, explain that the protocol is not configured
@@ -568,6 +581,7 @@ ping_gateway() {
ping_internet() {
local protocol="${1}"
+ # Ping a public address using the protocol passed as an argument
ping_ipv4_or_ipv6 "${protocol}"
log_write "* Checking Internet connectivity via IPv${protocol}..."
# Try to ping the address 3 times
@@ -584,6 +598,7 @@ ping_internet() {
compare_port_to_service_assigned() {
local service_name="${1}"
+ # The programs we use may change at some point, so they are in a varible here
local resolver="dnsmasq"
local web_server="lighttpd"
local ftl="pihole-FT"
@@ -624,6 +639,7 @@ check_required_ports() {
;;
4711) compare_port_to_service_assigned "${ftl}"
;;
+ # If it's not a default port that Pi-hole needs, just print it out for the user to see
*) log_write "[${port_number}] is in use by ${service_name}";
esac
done
@@ -679,6 +695,7 @@ dig_at() {
local IP="${2}"
echo_current_diagnostic "Name resolution (IPv${protocol}) using a random blocked domain and a known ad-serving domain"
# Set more local variables
+ # We need to test name resolution locally, via Pi-hole, and via a public resolver
local url
local local_dig
local pihole_dig
@@ -745,13 +762,11 @@ dig_at() {
process_status(){
# Check to make sure Pi-hole's services are running and active
echo_current_diagnostic "Pi-hole processes"
- # Store them in an array for easy use
- PROCESSES=( dnsmasq lighttpd pihole-FTL )
# Local iterator
local i
# For each process,
- for i in "${PROCESSES[@]}"; do
- # get its status
+ for i in "${PIHOLE_PROCESSES=[@]}"; do
+ # get its status via systemctl
local status_of_process=$(systemctl is-active "${i}")
# and print it out to the user
if [[ "${status_of_process}" == "active" ]]; then
@@ -766,6 +781,7 @@ process_status(){
make_array_from_file() {
local filename="${1}"
+ # Set the array to be empty so we can start fresh when the function is used
local file_content=()
# If the file is a directory
if [[ -d "${filename}" ]]; then
@@ -785,7 +801,10 @@ make_array_from_file() {
:
fi
done < "${filename}"
+ # Now the we have made an array of the file's content
for each_line in "${file_content[@]}"; do
+ # Print each line
+ # At some point, we may want to check the file line-by-line, so that's the reason for an array
log_write " ${each_line}"
done
fi
@@ -862,6 +881,7 @@ list_files_in_dir() {
# and parse the file into an array in case we ever need to analyze it line-by-line
make_array_from_file "${dir_to_parse}/${each_file}"
else
+ # Otherwise, do nothing since it's not a file needed for Pi-hole so we don't care about it
:
fi
done
@@ -879,14 +899,10 @@ show_content_of_files_in_dir() {
}
show_content_of_pihole_files() {
- # Show the content of the files in /etc/dnsmasq.d
+ # Show the content of the files in each of Pi-hole's folders
show_content_of_files_in_dir "${DNSMASQ_D_DIRECTORY}"
- # Show the content of the files in /etc/lighttpd
- show_content_of_files_in_dir "/etc/lighttpd"
- # Show the content of the files in /etc/lighttpd
- show_content_of_files_in_dir "/etc/cron.d"
- # Show the content of the files in /var/www/html
- # show_content_of_files_in_dir "${WEB_GIT_DIRECTORY}"
+ show_content_of_files_in_dir "${WEB_SERVER_CONFIG_DIRECTORY}"
+ show_content_of_files_in_dir "${CRON_D_DIRECTORY}"
}
analyze_gravity_list() {
@@ -910,17 +926,19 @@ tricorder_use_nc_or_ssl() {
else
# use net cat
log_write "${INFO} Using ${COL_YELLOW}netcat${COL_NC} for transmission."
+ # Save the token returned by our server in a variable
tricorder_token=$(cat ${PIHOLE_DEBUG_LOG} | nc tricorder.pi-hole.net ${TRICORDER_NC_PORT_NUMBER})
fi
}
upload_to_tricorder() {
+ local username="pihole"
# Set the permissions and owner
chmod 644 ${PIHOLE_DEBUG_LOG}
- chown "$USER":pihole ${PIHOLE_DEBUG_LOG}
+ chown "$USER":"${username}" ${PIHOLE_DEBUG_LOG}
- # Let the user know debugging is complete
+ # Let the user know debugging is complete with something strikingly visual
log_write ""
log_write "${COL_LIGHT_PURPLE}********************************************${COL_NC}"
log_write "${COL_LIGHT_PURPLE}********************************************${COL_NC}"
@@ -936,16 +954,21 @@ upload_to_tricorder() {
log_write "${INFO} Debug script running in automated mode"
# and then decide again which tool to use to submit it
if command -v openssl &> /dev/null; then
+ # If openssl is available, use it
log_write "${INFO} Using ${COL_LIGHT_GREEN}openssl${COL_NC} for transmission."
+ # Save the token returned by our server in a variable
tricorder_token=$(openssl s_client -quiet -connect tricorder.pi-hole.net:${TRICORDER_SSL_PORT_NUMBER} 2> /dev/null < /dev/stdin)
else
+ # Otherwise, fallback to netcat
log_write "${INFO} Using ${COL_YELLOW}netcat${COL_NC} for transmission."
+ # Save the token returned by our server in a variable
tricorder_token=$(nc tricorder.pi-hole.net ${TRICORDER_NC_PORT_NUMBER} < /dev/stdin)
fi
+ # If we're not running in automated mode,
else
echo ""
- # Give the user a choice of uploading it or not
- # Users can review the log file locally and try to self-diagnose their problem
+ # give the user a choice of uploading it or not
+ # Users can review the log file locally (or the output of the script since they are the same) and try to self-diagnose their problem
read -r -p "[?] Would you like to upload the log? [y/N] " response
case ${response} in
# If they say yes, run our function for uploading the log
@@ -957,6 +980,8 @@ upload_to_tricorder() {
# Check if tricorder.pi-hole.net is reachable and provide token
# along with some additional useful information
if [[ -n "${tricorder_token}" ]]; then
+ # Again, try to make this visually striking so the user realizes they need to do something with this information
+ # Namely, provide the Pi-hole devs with the token
log_write ""
log_write "${COL_LIGHT_PURPLE}***********************************${COL_NC}"
log_write "${COL_LIGHT_PURPLE}***********************************${COL_NC}"
@@ -967,10 +992,13 @@ upload_to_tricorder() {
log_write " * Provide the token above to the Pi-hole team for assistance at"
log_write " * ${FORUMS_URL}"
log_write " * Your log will self-destruct on our server after ${COL_LIGHT_RED}48 hours${COL_NC}."
- else
+ # If no token was generated
+ else
+ # Show an error and some help instructions
log_write "${CROSS} ${COL_LIGHT_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
+ # Finally, show where the log file is no matter the outcome of the function so users can look at it
log_write " * A local copy of the debug log can be found at: ${COL_CYAN}${PIHOLE_DEBUG_LOG}${COL_NC}\n"
}
From 881819ed5fda3c8c7f581f90bee3a782bcb02d38 Mon Sep 17 00:00:00 2001
From: Jacob Salmela
Date: Sat, 10 Jun 2017 18:37:28 -0500
Subject: [PATCH 079/162] ignore big files we dont need to know about; also fix
diagnosing pihole processes
---
advanced/Scripts/piholeDebug.sh | 17 +++++++++++++++--
1 file changed, 15 insertions(+), 2 deletions(-)
diff --git a/advanced/Scripts/piholeDebug.sh b/advanced/Scripts/piholeDebug.sh
index 3a2f9803..7fb63b65 100755
--- a/advanced/Scripts/piholeDebug.sh
+++ b/advanced/Scripts/piholeDebug.sh
@@ -80,6 +80,7 @@ PIHOLE_DHCP_CONFIG_FILE="${DNSMASQ_D_DIRECTORY}/02-pihole-dhcp.conf"
PIHOLE_WILDCARD_CONFIG_FILE="${DNSMASQ_D_DIRECTORY}/03-wildcard.conf"
WEB_SERVER_CONFIG_FILE="${WEB_SERVER_CONFIG_DIRECTORY}/lighttpd.conf"
+WEB_SERVER_CUSTOM_CONFIG_FILE="${WEB_SERVER_CONFIG_DIRECTORY}/external.conf"
PIHOLE_DEFAULT_AD_LISTS="${PIHOLE_DIRECTORY}/adlists.default"
PIHOLE_USER_DEFINED_AD_LISTS="${PIHOLE_DIRECTORY}/adlists.list"
@@ -111,7 +112,7 @@ PIHOLE_WEB_SERVER_ERROR_LOG_FILE="${WEB_SERVER_LOG_DIRECTORY}/error.log"
SUPPORTED_OS=("Raspbian" "Ubuntu" "Fedora" "Debian" "CentOS")
# Store Pi-hole's processes in an array for easy use and parsing
-PIHOLE_PROCESSES=( dnsmasq lighttpd pihole-FTL )
+PIHOLE_PROCESSES=( "dnsmasq" "lighttpd" "pihole-FTL" )
# Store the required directories in an array so it can be parsed through
REQUIRED_DIRECTORIES=(${CORE_GIT_DIRECTORY}
@@ -765,7 +766,7 @@ process_status(){
# Local iterator
local i
# For each process,
- for i in "${PIHOLE_PROCESSES=[@]}"; do
+ for i in "${PIHOLE_PROCESSES[@]}"; do
# get its status via systemctl
local status_of_process=$(systemctl is-active "${i}")
# and print it out to the user
@@ -872,6 +873,16 @@ list_files_in_dir() {
if [[ -d "${each_file}" ]]; then
# If it's a directoy, do nothing
:
+ elif [[ "${dir_to_parse}/${each_file}" == "${PIHOLE_BLOCKLIST_FILE}" ]] || \
+ [[ "${dir_to_parse}/${each_file}" == "${PIHOLE_FTL_LOG}" ]] || \
+ [[ "${dir_to_parse}/${each_file}" == "${PIHOLE_DEBUG_LOG}" ]] || \
+ [[ ${dir_to_parse}/${each_file} == ${PIHOLE_RAW_BLOCKLIST_FILES} ]] || \
+ [[ "${dir_to_parse}/${each_file}" == "${PIHOLE_INSTALL_LOG_FILE}" ]] || \
+ [[ "${dir_to_parse}/${each_file}" == "${PIHOLE_SETUP_VARS_FILE}" ]] || \
+ [[ "${dir_to_parse}/${each_file}" == "${PIHOLE_LOG}" ]] || \
+ [[ "${dir_to_parse}/${each_file}" == "${PIHOLE_WEB_SERVER_ACCESS_LOG_FILE}" ]] || \
+ [[ ${dir_to_parse}/${each_file} == ${PIHOLE_LOG_GZIPS} ]]; then
+ :
else
# Then, parse the file's content into an array so each line can be analyzed if need be
for i in "${!REQUIRED_FILES[@]}"; do
@@ -900,9 +911,11 @@ show_content_of_files_in_dir() {
show_content_of_pihole_files() {
# Show the content of the files in each of Pi-hole's folders
+ show_content_of_files_in_dir "${PIHOLE_DIRECTORY}"
show_content_of_files_in_dir "${DNSMASQ_D_DIRECTORY}"
show_content_of_files_in_dir "${WEB_SERVER_CONFIG_DIRECTORY}"
show_content_of_files_in_dir "${CRON_D_DIRECTORY}"
+ show_content_of_files_in_dir "${WEB_SERVER_LOG_DIRECTORY}"
}
analyze_gravity_list() {
From 6d10a498a5178fa1060e333bf5159fbd3596d94f Mon Sep 17 00:00:00 2001
From: Jacob Salmela
Date: Sat, 10 Jun 2017 21:57:17 -0500
Subject: [PATCH 080/162] implement a limit on how many lines of a file we want
to view
---
advanced/Scripts/piholeDebug.sh | 45 +++++++++++++++++++++++++--------
1 file changed, 34 insertions(+), 11 deletions(-)
diff --git a/advanced/Scripts/piholeDebug.sh b/advanced/Scripts/piholeDebug.sh
index 7fb63b65..103e9495 100755
--- a/advanced/Scripts/piholeDebug.sh
+++ b/advanced/Scripts/piholeDebug.sh
@@ -782,6 +782,11 @@ process_status(){
make_array_from_file() {
local filename="${1}"
+ # The second argument can put a limit on how many line should be read from the file
+ # Since some of the files are so large, this is helpful to limit the output
+ local limit=${2}
+ # A local iterator for testing if we are at the limit above
+ local i=0
# Set the array to be empty so we can start fresh when the function is used
local file_content=()
# If the file is a directory
@@ -791,7 +796,7 @@ make_array_from_file() {
else
# Otherwise, read the file line by line
while IFS= read -r line;do
- # Strip out comments and blank lines
+ # Othwerise, strip out comments and blank lines
new_line=$(echo "${line}" | sed -e 's/#.*$//' -e '/^$/d')
# If the line still has content (a non-zero value)
if [[ -n "${new_line}" ]]; then
@@ -801,14 +806,23 @@ make_array_from_file() {
# Otherwise, it's a blank line or comment, so do nothing
:
fi
+ # Increment the iterator +1
+ i=$((i+1))
+ # but if the limit of lines we want to see is exceeded
+ if [[ -z ${limit} ]]; then
+ # do nothing
+ :
+ elif [[ $i -eq ${limit} ]]; then
+ break
+ fi
done < "${filename}"
- # Now the we have made an array of the file's content
- for each_line in "${file_content[@]}"; do
- # Print each line
- # At some point, we may want to check the file line-by-line, so that's the reason for an array
- log_write " ${each_line}"
- done
- fi
+ # Now the we have made an array of the file's content
+ for each_line in "${file_content[@]}"; do
+ # Print each line
+ # At some point, we may want to check the file line-by-line, so that's the reason for an array
+ log_write " ${each_line}"
+ done
+ fi
}
parse_file() {
@@ -870,7 +884,7 @@ list_files_in_dir() {
local files_found=( $(ls "${dir_to_parse}") )
# For each file in the array,
for each_file in "${files_found[@]}"; do
- if [[ -d "${each_file}" ]]; then
+ if [[ -d "${dir_to_parse}/${each_file}" ]]; then
# If it's a directoy, do nothing
:
elif [[ "${dir_to_parse}/${each_file}" == "${PIHOLE_BLOCKLIST_FILE}" ]] || \
@@ -889,8 +903,17 @@ list_files_in_dir() {
if [[ "${dir_to_parse}/${each_file}" == ${REQUIRED_FILES[$i]} ]]; then
# display the filename
log_write "\n${COL_LIGHT_GREEN}$(ls -ld ${dir_to_parse}/${each_file})${COL_NC}"
- # and parse the file into an array in case we ever need to analyze it line-by-line
- make_array_from_file "${dir_to_parse}/${each_file}"
+ # Check if the file we want to view has a limit (because sometimes we just need a little bit of info from the file, not the entire thing)
+ case "${dir_to_parse}/${each_file}" in
+ # If it's Web server error log, just give the first 25 lines
+ "${PIHOLE_WEB_SERVER_ERROR_LOG_FILE}") make_array_from_file "${dir_to_parse}/${each_file}" 25
+ ;;
+ # Same for the FTL log
+ "${PIHOLE_FTL_LOG}") make_array_from_file "${dir_to_parse}/${each_file}" 25
+ ;;
+ # parse the file into an array in case we ever need to analyze it line-by-line
+ *) make_array_from_file "${dir_to_parse}/${each_file}";
+ esac
else
# Otherwise, do nothing since it's not a file needed for Pi-hole so we don't care about it
:
From 172b8d2427a34d88d04c5548c72c6fc99c1e9adb Mon Sep 17 00:00:00 2001
From: Jacob Salmela
Date: Sat, 10 Jun 2017 22:18:33 -0500
Subject: [PATCH 081/162] parse ftl log
---
advanced/Scripts/piholeDebug.sh | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/advanced/Scripts/piholeDebug.sh b/advanced/Scripts/piholeDebug.sh
index 103e9495..8662422c 100755
--- a/advanced/Scripts/piholeDebug.sh
+++ b/advanced/Scripts/piholeDebug.sh
@@ -43,6 +43,7 @@ fi
FAQ_UPDATE_PI_HOLE="${COL_CYAN}https://discourse.pi-hole.net/t/how-do-i-update-pi-hole/249${COL_NC}"
FAQ_CHECKOUT_COMMAND="${COL_CYAN}https://discourse.pi-hole.net/t/the-pihole-command-with-examples/738#checkout${COL_NC}"
FAQ_HARDWARE_REQUIREMENTS="${COL_CYAN}https://discourse.pi-hole.net/t/hardware-software-requirements/273${COL_NC}"
+FAQ_HARDWARE_REQUIREMENTS_PORTS="${COL_CYAN}https://discourse.pi-hole.net/t/hardware-software-requirements/273#ports${COL_NC}"
FAQ_GATEWAY="${COL_CYAN}https://discourse.pi-hole.net/t/why-is-a-default-gateway-important-for-pi-hole/3546${COL_NC}"
FAQ_ULA="${COL_CYAN}https://discourse.pi-hole.net/t/use-ipv6-ula-addresses-for-pi-hole/2127${COL_NC}"
FAQ_FTL_COMPATIBILITY="${COL_CYAN}https://github.com/pi-hole/FTL#compatibility-list${COL_NC}"
@@ -609,7 +610,7 @@ compare_port_to_service_assigned() {
# Otherwise,
else
# Show the service name in red since it's non-standard
- log_write "[${COL_LIGHT_RED}${port_number}${COL_NC}] is in use by ${COL_LIGHT_RED}${service_name}${COL_NC} (${COL_CYAN}https://discourse.pi-hole.net/t/hardware-software-requirements/273#ports${COL_NC})"
+ log_write "[${COL_LIGHT_RED}${port_number}${COL_NC}] is in use by ${COL_LIGHT_RED}${service_name}${COL_NC} (${FAQ_HARDWARE_REQUIREMENTS_PORTS})"
fi
}
@@ -888,7 +889,6 @@ list_files_in_dir() {
# If it's a directoy, do nothing
:
elif [[ "${dir_to_parse}/${each_file}" == "${PIHOLE_BLOCKLIST_FILE}" ]] || \
- [[ "${dir_to_parse}/${each_file}" == "${PIHOLE_FTL_LOG}" ]] || \
[[ "${dir_to_parse}/${each_file}" == "${PIHOLE_DEBUG_LOG}" ]] || \
[[ ${dir_to_parse}/${each_file} == ${PIHOLE_RAW_BLOCKLIST_FILES} ]] || \
[[ "${dir_to_parse}/${each_file}" == "${PIHOLE_INSTALL_LOG_FILE}" ]] || \
@@ -939,6 +939,7 @@ show_content_of_pihole_files() {
show_content_of_files_in_dir "${WEB_SERVER_CONFIG_DIRECTORY}"
show_content_of_files_in_dir "${CRON_D_DIRECTORY}"
show_content_of_files_in_dir "${WEB_SERVER_LOG_DIRECTORY}"
+ show_content_of_files_in_dir "${LOG_DIRECTORY}"
}
analyze_gravity_list() {
From fc0440546f95db37c3944ea40299f2e83235fe3e Mon Sep 17 00:00:00 2001
From: Jacob Salmela
Date: Sat, 10 Jun 2017 23:20:27 -0500
Subject: [PATCH 082/162] add functions to parse head and tails of gravity.list
and pihole.log
---
advanced/Scripts/piholeDebug.sh | 49 +++++++++++++++++++++++++++++----
1 file changed, 44 insertions(+), 5 deletions(-)
diff --git a/advanced/Scripts/piholeDebug.sh b/advanced/Scripts/piholeDebug.sh
index 8662422c..d6526d9c 100755
--- a/advanced/Scripts/piholeDebug.sh
+++ b/advanced/Scripts/piholeDebug.sh
@@ -944,11 +944,49 @@ show_content_of_pihole_files() {
analyze_gravity_list() {
echo_current_diagnostic "Gravity list"
- # It's helpful to know how big a user's gravity file is
- gravity_length=$(grep -c ^ "${PIHOLE_BLOCKLIST_FILE}") && \
- log_write "${INFO} ${PIHOLE_BLOCKLIST_FILE} is ${gravity_length} lines long." || \
- # If the previous command failed, something is wrong with the file
- log_write "${CROSS} ${COL_LIGHT_RED}${PIHOLE_BLOCKLIST_FILE} not found!${COL_NC}"
+ local head_line
+ local tail_line
+ # Put the current Internal Field Separator into another variable so it can be restored later
+ OLD_IFS="$IFS"
+ # Get the lines that are in the file(s) and store them in an array for parsing later
+ IFS=$'\r\n'
+ local gravity_permissions=$(ls -ld "${PIHOLE_BLOCKLIST_FILE}")
+ log_write "${COL_LIGHT_GREEN}${gravity_permissions}${COL_NC}"
+ local gravity_head=()
+ gravity_head=( $(head -n 4 ${PIHOLE_BLOCKLIST_FILE}) )
+ log_write " ${COL_CYAN}-----head of $(basename ${PIHOLE_BLOCKLIST_FILE})------${COL_NC}"
+ for head_line in "${gravity_head[@]}"; do
+ log_write " ${head_line}"
+ done
+ log_write ""
+ local gravity_tail=()
+ gravity_tail=( $(tail -n 4 ${PIHOLE_BLOCKLIST_FILE}) )
+ log_write " ${COL_CYAN}-----tail of $(basename ${PIHOLE_BLOCKLIST_FILE})------${COL_NC}"
+ for tail_line in "${gravity_tail[@]}"; do
+ log_write " ${tail_line}"
+ done
+ # Set the IFS back to what it was
+ IFS="$OLD_IFS"
+}
+
+analyze_pihole_log() {
+ echo_current_diagnostic "Pi-hole log"
+ local head_line
+ # Put the current Internal Field Separator into another variable so it can be restored later
+ OLD_IFS="$IFS"
+ # Get the lines that are in the file(s) and store them in an array for parsing later
+ IFS=$'\r\n'
+ local pihole_log_permissions=$(ls -ld "${PIHOLE_LOG}")
+ log_write "${COL_LIGHT_GREEN}${pihole_log_permissions}${COL_NC}"
+ local pihole_log_head=()
+ pihole_log_head=( $(head -n 20 ${PIHOLE_LOG}) )
+ log_write " ${COL_CYAN}-----head of $(basename ${PIHOLE_LOG})------${COL_NC}"
+ for head_line in "${pihole_log_head[@]}"; do
+ log_write " ${head_line}"
+ done
+ log_write ""
+ # Set the IFS back to what it was
+ IFS="$OLD_IFS"
}
tricorder_use_nc_or_ssl() {
@@ -1056,5 +1094,6 @@ parse_setup_vars
check_x_headers
analyze_gravity_list
show_content_of_pihole_files
+analyze_pihole_log
copy_to_debug_log
upload_to_tricorder
From aff5ff08d55b3a46bf98e0ca649f25895a4211ca Mon Sep 17 00:00:00 2001
From: WaLLy3K
Date: Thu, 15 Jun 2017 17:50:05 +1000
Subject: [PATCH 083/162] Trim version output when update is successful (#1527)
---
advanced/Scripts/update.sh | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/advanced/Scripts/update.sh b/advanced/Scripts/update.sh
index 24b30de4..6aef183b 100755
--- a/advanced/Scripts/update.sh
+++ b/advanced/Scripts/update.sh
@@ -197,21 +197,21 @@ main() {
if [[ "${web_update}" == true ]]; then
web_version_current="$(/usr/local/bin/pihole version --admin --current)"
echo ":::"
- echo "::: Web Admin version is now at ${web_version_current}"
+ echo "::: Web Admin version is now at ${web_version_current/* v/v}}"
echo "::: If you had made any changes in '/var/www/html/admin/', they have been stashed using 'git stash'"
fi
if [[ "${core_update}" == true ]]; then
pihole_version_current="$(/usr/local/bin/pihole version --pihole --current)"
echo ":::"
- echo "::: Pi-hole version is now at ${pihole_version_current}"
+ echo "::: Pi-hole version is now at ${pihole_version_current/* v/v}}"
echo "::: If you had made any changes in '/etc/.pihole/', they have been stashed using 'git stash'"
fi
if [[ ${FTL_update} == true ]]; then
- FTL_version_current="$(/usr/bin/pihole-FTL tag)"
+ FTL_version_current="$(/usr/local/bin/pihole version --ftl --current)"
echo ":::"
- echo "::: FTL version is now at ${FTL_version_current}"
+ echo "::: FTL version is now at ${FTL_version_current/* v/v}}"
start_service pihole-FTL
enable_service pihole-FTL
fi
From 54a88ab5ab7fcc1ec440677ed9a6eec67d52fa23 Mon Sep 17 00:00:00 2001
From: DL6ER
Date: Sat, 17 Jun 2017 08:43:05 +0200
Subject: [PATCH 084/162] Change ownership of /etc/pihole to user/group pihole.
Fixes #1529 (#1530)
---
advanced/pihole-FTL.service | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/advanced/pihole-FTL.service b/advanced/pihole-FTL.service
index 30cd140f..627fad8c 100644
--- a/advanced/pihole-FTL.service
+++ b/advanced/pihole-FTL.service
@@ -26,7 +26,7 @@ start() {
echo "pihole-FTL is already running"
else
touch /var/log/pihole-FTL.log /run/pihole-FTL.pid /run/pihole-FTL.port
- chown pihole:pihole /var/log/pihole-FTL.log /run/pihole-FTL.pid /run/pihole-FTL.port
+ chown pihole:pihole /var/log/pihole-FTL.log /run/pihole-FTL.pid /run/pihole-FTL.port /etc/pihole
chmod 0644 /var/log/pihole-FTL.log /run/pihole-FTL.pid /run/pihole-FTL.port
su -s /bin/sh -c "/usr/bin/pihole-FTL" "$FTLUSER"
echo
From 3d7582faec8232e15dccf94909fc1416794915f3 Mon Sep 17 00:00:00 2001
From: DL6ER
Date: Sat, 17 Jun 2017 08:54:26 +0200
Subject: [PATCH 085/162] Delete temporary files after installing the FTL
binary. Fixes #1525
---
automated install/basic-install.sh | 1 +
1 file changed, 1 insertion(+)
diff --git a/automated install/basic-install.sh b/automated install/basic-install.sh
index e8b28f62..053e04ba 100755
--- a/automated install/basic-install.sh
+++ b/automated install/basic-install.sh
@@ -1277,6 +1277,7 @@ FTLinstall() {
echo -n "transferred... "
stop_service pihole-FTL &> /dev/null
install -T -m 0755 /tmp/${binary} /usr/bin/pihole-FTL
+ rm /tmp/${binary} /tmp/${binary}.sha1
cd "${orig_dir}"
install -T -m 0755 "${PI_HOLE_LOCAL_REPO}/advanced/pihole-FTL.service" "/etc/init.d/pihole-FTL"
echo "done."
From b32096b16e3a7d81f44752cf41547d98a315b61c Mon Sep 17 00:00:00 2001
From: Dan Schaper
Date: Sat, 17 Jun 2017 03:59:27 -0700
Subject: [PATCH 086/162] Change from admin to approvers teams
---
.pullapprove.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.pullapprove.yml b/.pullapprove.yml
index 39566b34..6beb4d34 100644
--- a/.pullapprove.yml
+++ b/.pullapprove.yml
@@ -35,4 +35,4 @@ groups:
- master
required: 4
teams:
- - admin
+ - approvers
From 0283a1ab74f7a404b96cf28fd055e5077f9b248d Mon Sep 17 00:00:00 2001
From: DL6ER
Date: Sat, 17 Jun 2017 13:50:10 +0200
Subject: [PATCH 087/162] Introduce new file black.list for blacklist content
---
advanced/01-pihole.conf | 1 +
gravity.sh | 57 ++++++++++++++++++++++++-----------------
2 files changed, 34 insertions(+), 24 deletions(-)
diff --git a/advanced/01-pihole.conf b/advanced/01-pihole.conf
index 1b157f88..79735c15 100644
--- a/advanced/01-pihole.conf
+++ b/advanced/01-pihole.conf
@@ -22,6 +22,7 @@
addn-hosts=/etc/pihole/gravity.list
addn-hosts=/etc/pihole/local.list
+addn-hosts=/etc/pihole/black.list
domain-needed
diff --git a/gravity.sh b/gravity.sh
index a5231d5e..cb6768e4 100755
--- a/gravity.sh
+++ b/gravity.sh
@@ -54,6 +54,7 @@ IPV6_ADDRESS=${IPV6_ADDRESS}
basename=pihole
piholeDir=/etc/${basename}
adList=${piholeDir}/gravity.list
+blackList=${piholeDir}/black.list
localList=${piholeDir}/local.list
justDomainsExtension=domains
matterAndLight=${basename}.0.matterandlight.txt
@@ -236,7 +237,7 @@ gravity_Blacklist() {
numBlacklisted=$(wc -l < "${blacklistFile}")
plural=; [[ "$numBlacklisted" != "1" ]] && plural=s
echo -n "::: Blacklisting $numBlacklisted domain${plural}..."
- cat ${blacklistFile} >> ${piholeDir}/${eventHorizon}
+ cat "${blacklistFile}" > "${blackList}.tmp"
echo " done!"
else
echo "::: Nothing to blacklist!"
@@ -299,6 +300,23 @@ gravity_unique() {
echo "::: $numberOf unique domains trapped in the event horizon."
}
+gravity_doHostFormat() {
+ # Check vars from setupVars.conf to see if we're using IPv4, IPv6, Or both.
+ if [[ -n "${IPV4_ADDRESS}" && -n "${IPV6_ADDRESS}" ]];then
+ # Both IPv4 and IPv6
+ cat "${1}" | awk -v ipv4addr="$IPV4_ADDRESS" -v ipv6addr="$IPV6_ADDRESS" '{sub(/\r$/,""); print ipv4addr" "$0"\n"ipv6addr" "$0}' >> "${2}"
+ elif [[ -n "${IPV4_ADDRESS}" && -z "${IPV6_ADDRESS}" ]];then
+ # Only IPv4
+ cat "${1}" | awk -v ipv4addr="$IPV4_ADDRESS" '{sub(/\r$/,""); print ipv4addr" "$0}' >> "${2}"
+ elif [[ -z "${IPV4_ADDRESS}" && -n "${IPV6_ADDRESS}" ]];then
+ # Only IPv6
+ cat "${1}" | awk -v ipv6addr="$IPV6_ADDRESS" '{sub(/\r$/,""); print ipv6addr" "$0}' >> "${2}"
+ elif [[ -z "${IPV4_ADDRESS}" && -z "${IPV6_ADDRESS}" ]];then
+ echo "::: No IP Values found! Please run 'pihole -r' and choose reconfigure to restore values"
+ exit 1
+ fi
+}
+
gravity_hostFormat() {
# Format domain list as "192.168.x.x domain.com"
echo -n "::: Formatting domains into a HOSTS file..."
@@ -310,32 +328,23 @@ gravity_hostFormat() {
else
echo "::: Error: Unable to determine fully qualified domain name of host"
fi
- # Check vars from setupVars.conf to see if we're using IPv4, IPv6, Or both.
- if [[ -n "${IPV4_ADDRESS}" && -n "${IPV6_ADDRESS}" ]];then
- echo -e "${IPV4_ADDRESS} ${hostname}\n${IPV6_ADDRESS} ${hostname}\n${IPV4_ADDRESS} pi.hole\n${IPV6_ADDRESS} pi.hole" > ${localList}
- # Both IPv4 and IPv6
- cat ${piholeDir}/${eventHorizon} | awk -v ipv4addr="$IPV4_ADDRESS" -v ipv6addr="$IPV6_ADDRESS" '{sub(/\r$/,""); print ipv4addr" "$0"\n"ipv6addr" "$0}' >> ${piholeDir}/${accretionDisc}
-
- elif [[ -n "${IPV4_ADDRESS}" && -z "${IPV6_ADDRESS}" ]];then
-
- echo -e "${IPV4_ADDRESS} ${hostname}\n${IPV4_ADDRESS} pi.hole" > ${localList}
- # Only IPv4
- cat ${piholeDir}/${eventHorizon} | awk -v ipv4addr="$IPV4_ADDRESS" '{sub(/\r$/,""); print ipv4addr" "$0}' >> ${piholeDir}/${accretionDisc}
-
- elif [[ -z "${IPV4_ADDRESS}" && -n "${IPV6_ADDRESS}" ]];then
-
- echo -e "${IPV6_ADDRESS} ${hostname}\n${IPV6_ADDRESS} pi.hole" > ${localList}
- # Only IPv6
- cat ${piholeDir}/${eventHorizon} | awk -v ipv6addr="$IPV6_ADDRESS" '{sub(/\r$/,""); print ipv6addr" "$0}' >> ${piholeDir}/${accretionDisc}
-
- elif [[ -z "${IPV4_ADDRESS}" && -z "${IPV6_ADDRESS}" ]];then
- echo "::: No IP Values found! Please run 'pihole -r' and choose reconfigure to restore values"
- exit 1
- fi
+ echo -e "${hostname}\npi.hole" > "${localList}.tmp"
+ # Copy the file over as /etc/pihole/local.list so dnsmasq can use it
+ gravity_doHostFormat "${localList}.tmp" "${localList}"
+ rm "${localList}.tmp"
+ echo "" > "${piholeDir}/${accretionDisc}"
+ gravity_doHostFormat "${piholeDir}/${eventHorizon}" "${piholeDir}/${accretionDisc}"
# Copy the file over as /etc/pihole/gravity.list so dnsmasq can use it
- cp ${piholeDir}/${accretionDisc} ${adList}
+ cp "${piholeDir}/${accretionDisc}" "${adList}"
+ rm "${piholeDir}/${accretionDisc}"
+
+ echo -e "" > "${blackList}.tmp"
+ gravity_doHostFormat "${blackList}.tmp" "${blackList}"
+ # Copy the file over as /etc/pihole/black.list so dnsmasq can use it
+ cp "${blackList}.tmp" "${blackList}"
+ rm "${blackList}.tmp"
echo " done!"
}
From 0a9c2341272d45dd8b161a24d23cc5fe36a50d0c Mon Sep 17 00:00:00 2001
From: DL6ER
Date: Sat, 17 Jun 2017 13:57:27 +0200
Subject: [PATCH 088/162] Add "pihole -g -b" to *only* update black.list (saves
a bunch of time when adding/changing only blacklisted files - won'tdownload
lal lists, but only processes the blacklist and restars dnsmasq)
---
gravity.sh | 47 ++++++++++++++++++++++++++++++++---------------
1 file changed, 32 insertions(+), 15 deletions(-)
diff --git a/gravity.sh b/gravity.sh
index cb6768e4..2b860183 100755
--- a/gravity.sh
+++ b/gravity.sh
@@ -317,9 +317,8 @@ gravity_doHostFormat() {
fi
}
-gravity_hostFormat() {
+gravity_hostFormatLocal() {
# Format domain list as "192.168.x.x domain.com"
- echo -n "::: Formatting domains into a HOSTS file..."
if [[ -f /etc/hostname ]]; then
hostname=$( "${piholeDir}/${accretionDisc}"
gravity_doHostFormat "${piholeDir}/${eventHorizon}" "${piholeDir}/${accretionDisc}"
# Copy the file over as /etc/pihole/gravity.list so dnsmasq can use it
cp "${piholeDir}/${accretionDisc}" "${adList}"
rm "${piholeDir}/${accretionDisc}"
+}
+gravity_hostFormatBlack() {
+ # Format domain list as "192.168.x.x domain.com"
echo -e "" > "${blackList}.tmp"
gravity_doHostFormat "${blackList}.tmp" "${blackList}"
# Copy the file over as /etc/pihole/black.list so dnsmasq can use it
cp "${blackList}.tmp" "${blackList}"
rm "${blackList}.tmp"
- echo " done!"
}
# blackbody - remove any remnant files from script processes
@@ -386,11 +390,6 @@ gravity_advanced() {
}
gravity_reload() {
- #Clear no longer needed files...
- echo ":::"
- echo -n "::: Cleaning up un-needed files..."
- rm ${piholeDir}/pihole.*.txt
- echo " done!"
# Reload hosts file
echo ":::"
@@ -411,6 +410,7 @@ for var in "$@"; do
"-f" | "--force" ) forceGrav=true;;
"-h" | "--help" ) helpFunc;;
"-sd" | "--skip-download" ) skipDownload=true;;
+ "-b" | "--blacklist-only" ) blackListOnly=true;;
esac
done
@@ -420,22 +420,39 @@ if [[ "${forceGrav}" == true ]]; then
echo " done!"
fi
-gravity_collapse
-gravity_spinup
-if [[ "${skipDownload}" == false ]]; then
+if [[ ! "${blackListOnly}" == true ]]; then
+ gravity_collapse
+ gravity_spinup
+ if [[ "${skipDownload}" == false ]]; then
gravity_Schwarzchild
gravity_advanced
-else
+ else
echo "::: Using cached Event Horizon list..."
numberOf=$(wc -l < ${piholeDir}/${preEventHorizon})
- echo "::: $numberOf unique domains trapped in the event horizon."
+ echo "::: $numberOf unique domains trapped in the event horizon."
+ fi
+ gravity_Whitelist
fi
-gravity_Whitelist
gravity_Blacklist
gravity_Wildcard
-gravity_hostFormat
+echo -n "::: Formatting domains into a HOSTS file..."
+if [[ ! "${blackListOnly}" == true ]]; then
+ gravity_hostFormatLocal
+ gravity_hostFormatGravity
+fi
+gravity_hostFormatBlack
+echo " done!"
+
gravity_blackbody
+if [[ ! "${blackListOnly}" == true ]]; then
+ #Clear no longer needed files...
+ echo ":::"
+ echo -n "::: Cleaning up un-needed files..."
+ rm ${piholeDir}/pihole.*.txt
+ echo " done!"
+fi
+
gravity_reload
"${PIHOLE_COMMAND}" status
From 92e691408f58e6ae8fd3eae7acfcfd0175245abc Mon Sep 17 00:00:00 2001
From: DL6ER
Date: Sat, 17 Jun 2017 14:14:07 +0200
Subject: [PATCH 089/162] Remove useless cat
---
gravity.sh | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/gravity.sh b/gravity.sh
index 2b860183..558cbd18 100755
--- a/gravity.sh
+++ b/gravity.sh
@@ -304,13 +304,13 @@ gravity_doHostFormat() {
# Check vars from setupVars.conf to see if we're using IPv4, IPv6, Or both.
if [[ -n "${IPV4_ADDRESS}" && -n "${IPV6_ADDRESS}" ]];then
# Both IPv4 and IPv6
- cat "${1}" | awk -v ipv4addr="$IPV4_ADDRESS" -v ipv6addr="$IPV6_ADDRESS" '{sub(/\r$/,""); print ipv4addr" "$0"\n"ipv6addr" "$0}' >> "${2}"
+ awk -v ipv4addr="$IPV4_ADDRESS" -v ipv6addr="$IPV6_ADDRESS" '{sub(/\r$/,""); print ipv4addr" "$0"\n"ipv6addr" "$0}' >> "${2}" < "${1}"
elif [[ -n "${IPV4_ADDRESS}" && -z "${IPV6_ADDRESS}" ]];then
# Only IPv4
- cat "${1}" | awk -v ipv4addr="$IPV4_ADDRESS" '{sub(/\r$/,""); print ipv4addr" "$0}' >> "${2}"
+ awk -v ipv4addr="$IPV4_ADDRESS" '{sub(/\r$/,""); print ipv4addr" "$0}' >> "${2}" < "${1}"
elif [[ -z "${IPV4_ADDRESS}" && -n "${IPV6_ADDRESS}" ]];then
# Only IPv6
- cat "${1}" | awk -v ipv6addr="$IPV6_ADDRESS" '{sub(/\r$/,""); print ipv6addr" "$0}' >> "${2}"
+ awk -v ipv6addr="$IPV6_ADDRESS" '{sub(/\r$/,""); print ipv6addr" "$0}' >> "${2}" < "${1}"
elif [[ -z "${IPV4_ADDRESS}" && -z "${IPV6_ADDRESS}" ]];then
echo "::: No IP Values found! Please run 'pihole -r' and choose reconfigure to restore values"
exit 1
@@ -330,6 +330,7 @@ gravity_hostFormatLocal() {
echo -e "${hostname}\npi.hole" > "${localList}.tmp"
# Copy the file over as /etc/pihole/local.list so dnsmasq can use it
+ rm "${localList}"
gravity_doHostFormat "${localList}.tmp" "${localList}"
rm "${localList}.tmp"
}
From 8bad56e89799f05d64d30d367361e9814b48f03c Mon Sep 17 00:00:00 2001
From: DL6ER
Date: Sat, 17 Jun 2017 14:24:30 +0200
Subject: [PATCH 090/162] Improve displayed messages and overall logic
---
gravity.sh | 20 +++++++++++---------
1 file changed, 11 insertions(+), 9 deletions(-)
diff --git a/gravity.sh b/gravity.sh
index 558cbd18..f333b706 100755
--- a/gravity.sh
+++ b/gravity.sh
@@ -236,9 +236,7 @@ gravity_Blacklist() {
if [[ -f "${blacklistFile}" ]]; then
numBlacklisted=$(wc -l < "${blacklistFile}")
plural=; [[ "$numBlacklisted" != "1" ]] && plural=s
- echo -n "::: Blacklisting $numBlacklisted domain${plural}..."
- cat "${blacklistFile}" > "${blackList}.tmp"
- echo " done!"
+ echo "::: Exact blocked domain${plural}: $numBlacklisted"
else
echo "::: Nothing to blacklist!"
fi
@@ -345,12 +343,16 @@ gravity_hostFormatGravity() {
}
gravity_hostFormatBlack() {
- # Format domain list as "192.168.x.x domain.com"
- echo -e "" > "${blackList}.tmp"
- gravity_doHostFormat "${blackList}.tmp" "${blackList}"
- # Copy the file over as /etc/pihole/black.list so dnsmasq can use it
- cp "${blackList}.tmp" "${blackList}"
- rm "${blackList}.tmp"
+ if [[ -f "${blacklistFile}" ]]; then
+ numBlacklisted=$(wc -l < "${blacklistFile}")
+ # Format domain list as "192.168.x.x domain.com"
+ gravity_doHostFormat "${blacklistFile}" "${blackList}.tmp"
+ # Copy the file over as /etc/pihole/black.list so dnsmasq can use it
+ cp "${blackList}.tmp" "${blackList}"
+ rm "${blackList}.tmp"
+ else
+ echo "::: Nothing to blacklist!"
+ fi
}
# blackbody - remove any remnant files from script processes
From e4cc5b3847314235f88953835fdbae2aea7adb70 Mon Sep 17 00:00:00 2001
From: DL6ER
Date: Sat, 17 Jun 2017 14:49:02 +0200
Subject: [PATCH 091/162] Disable black.list on "pihole disable"
---
pihole | 1 +
1 file changed, 1 insertion(+)
diff --git a/pihole b/pihole
index f2bc7000..055d6bce 100755
--- a/pihole
+++ b/pihole
@@ -193,6 +193,7 @@ Time:
elif [[ "${1}" == "0" ]]; then
# Disable Pi-hole
sed -i 's/^addn-hosts=\/etc\/pihole\/gravity.list/#addn-hosts=\/etc\/pihole\/gravity.list/' /etc/dnsmasq.d/01-pihole.conf
+ sed -i 's/^addn-hosts=\/etc\/pihole\/black.list/#addn-hosts=\/etc\/pihole\/black.list/' /etc/dnsmasq.d/01-pihole.conf
if [[ -e "$wildcardlist" ]]; then
mv "$wildcardlist" "/etc/pihole/wildcard.list"
fi
From 05798fe07a363bc1b25e89396efec74b3abc6ace Mon Sep 17 00:00:00 2001
From: DL6ER
Date: Mon, 19 Jun 2017 20:21:47 +0200
Subject: [PATCH 092/162] cp + rm === mv (well, almost)
---
gravity.sh | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/gravity.sh b/gravity.sh
index f333b706..285ce5c3 100755
--- a/gravity.sh
+++ b/gravity.sh
@@ -338,8 +338,7 @@ gravity_hostFormatGravity() {
echo "" > "${piholeDir}/${accretionDisc}"
gravity_doHostFormat "${piholeDir}/${eventHorizon}" "${piholeDir}/${accretionDisc}"
# Copy the file over as /etc/pihole/gravity.list so dnsmasq can use it
- cp "${piholeDir}/${accretionDisc}" "${adList}"
- rm "${piholeDir}/${accretionDisc}"
+ mv "${piholeDir}/${accretionDisc}" "${adList}"
}
gravity_hostFormatBlack() {
@@ -348,8 +347,7 @@ gravity_hostFormatBlack() {
# Format domain list as "192.168.x.x domain.com"
gravity_doHostFormat "${blacklistFile}" "${blackList}.tmp"
# Copy the file over as /etc/pihole/black.list so dnsmasq can use it
- cp "${blackList}.tmp" "${blackList}"
- rm "${blackList}.tmp"
+ mv "${blackList}.tmp" "${blackList}"
else
echo "::: Nothing to blacklist!"
fi
From 5b472ff67cb901b2bbb79d917ae8e6a2115a00f0 Mon Sep 17 00:00:00 2001
From: Terror
Date: Tue, 20 Jun 2017 08:28:04 +1200
Subject: [PATCH 093/162] Add support for PowerPC architecture
Related to https://github.com/pi-hole/FTL/pull/88
---
automated install/basic-install.sh | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/automated install/basic-install.sh b/automated install/basic-install.sh
index c65ef49f..ade1a1d4 100755
--- a/automated install/basic-install.sh
+++ b/automated install/basic-install.sh
@@ -1265,6 +1265,10 @@ FTLdetect() {
echo "::: Detected ARM architecture"
binary="pihole-FTL-arm-linux-gnueabi"
fi
+ elif [[ $machine == ppc ]]; then
+ # PowerPC
+ echo "::: Detected PowerPC architecture"
+ binary="pihole-FTL-powerpc-linux-gnu"
elif [[ $machine == x86_64 ]]; then
# 64bit
echo "::: Detected x86_64 architecture"
From ecde2225122904a89543712ec8f2b0fd1da26ff6 Mon Sep 17 00:00:00 2001
From: Adam Warner
Date: Tue, 20 Jun 2017 22:17:41 +0100
Subject: [PATCH 094/162] [Staging] 3.1 (#1502)
* Fix handling of wildcard help text
* Rewrite help text for better handling of params
* Replace misleading letter variable
* stash changes on branch switch, else it fails if any changes have been made.
* Make changes according to comment in #1384
* Update queryFunc()
* Allow scanList() to search files using a wildcard by removing quotes wrapped around `${list}`
* scanList() will not provide a domain ouput on each string if exact is specified (`grep -l`)
* Remove unused processWildcards() function
* Return a message if no domain is specified
* IDN domains are converted to punycode when running a `pihole -q` search if the `python` package is available, otherwise will revert to current behaviour
* Scan Blacklist & Wildcards first, exiting from search if a match is found (Fixes #1330)
* Use one `grep` subshell to search for all "*.domains" lists at once (opposed to looping to get every matching file name, and then spawning a `grep` instance for every matching file)
* queryFunc() will not return "(0 results)" output from files where no match is found
* Sort results based off list number
* Return a message if no results are found
* Update basic-install.sh
* Update block page. Allow for setupVars setting of CUSTOMBLOCKPAGE (bool) to prevent it being overwritten
* simplify
* further simplify
* fix inteliJ IDEA complaints
* even further simplify
* tidy up output
* revert line, looks tidyer
* clarify
* Revert "Ensure any changes to blocking page are updated."
* We test for dpkg lock on line 830 directly, no need for the check also
in the template section.
Signed-off-by: Dan Schaper
* Display FTL version & version.sh rewrite
While testing to make sure `pihole -v` would output `pihole-FTL version`, I noticed some options didn't work how I expected them to. For example, if I use `pihole -v -p`, I would expect to see the version output of Pi-hole Core. Instead, I'm informed that it's an invalid option.
I've had the following things in mind while rewriting this:
* I'm operating under the assumption that FTL is only installed if the Admin Console is (Line 113 exit 0)
* I have modified the help text to only output with `pihole -v --help`
* I have modified all output to be more similar to the output style of `grep` and `curl` (Ditching ":::")
Testing output:
```
w3k@MCT:~$ pihole -v
Pi-hole version is v3.0.1-14-ga928cd3 (Latest: v3.0.1)
Admin Console version is v3.0-9-g3760482 (Latest: v3.0.1)
FTL version is v2.6.2 (Latest: v2.6.2)
w3k@MCT:~$ pihole -v -c
Current Pi-hole version is v3.0.1-14-ga928cd3
Current Admin Console version is v3.0-9-g3760482
Current FTL version is v2.6.2
w3k@MCT:~$ pihole -v -l
Latest Pi-hole version is v3.0.1
Latest Admin Console version is v3.0.1
Latest FTL version is v2.6.2
w3k@MCT:~$ pihole -v -p --hash
Current Pi-hole hash is a928cd3
w3k@MCT:~$ pihole -v -a --hash
Current Admin Console hash is 3760482
w3k@MCT:~$ pihole -v --help
Usage: pihole -v [REPO | OPTION] [OPTION]
Show Pi-hole, Web Admin & FTL versions
w3k@MCT:~$ pihole -v -foo
Invalid Option!
```
* Update -h to work as --hash
Also provide error output as per https://github.com/pi-hole/pi-hole/pull/1447#issuecomment-300600093
* Perform EXACT searches on HOSTS lists correctly
`\s` on the end may be overkill, but it is the existing scanList() behaviour.
* Fixed indentation
* Minimise string duplication & other minor changes
Instead of duplicating output strings, rewrite core/web/ftlOutput() into one neat versionOutput().
* Modified syntax to be valid for Shellcheck
* Log and echo gateway responses
* Update queryFunc() to search Whitelist
If there is a match in Whitelist/Blacklist/Wildcards, `[ ! -t 1 ]` will cause the search to end if the terminal is closed when the script is called. This has the intended effect of allowing a user to search for a W/B/W domain (as well as all the adlists it's found in) using `pihole -q` via Terminal, but the script will stop searching after a W/B/W match when called by the block page.
* Wrap in double brackets
* Provide remote hashes for version.sh
* Provide remote hashes for comparison
* Use double braces for all conditions (for consistency)
* Suppress potential "cd" error output
* Provide "not applicable" output upon any hash request for FTL
* whitelist on website blocked doesnt work (#1452)
Since Pi-hole redirects ad domains to itself, accessing the script via de.ign.com is the same as pi.hole in this case. The fix should be as simple as adding a / before admin on this line.
* Solve piholeLogFlush.sh having to be issued 2 x to clear logs (#1460)
Simplified the command -v syntax, and added a sleep 3 timer to the first execution of the log rotation. The second execution was being issued while the first was still running, thus it would fail and you would have to issue the "Flush Logs" command a second time.
* Use `echo "ABC" | pihole tricorder` to upload to Pi-hole's medical tricorder. Uses SSL if available.
* Update list.sh
I believe this has feature parity with `sed /foo/ Id` but also supports busybox, and my alpine docker ;)
* Document `sed` substitution for user readability
Comment the oneliner with explanations of what each step does.
* Update Help Output (#1467)
* File consistency
* Tabs to 2 spaces
* Corrected indenting
* Double braced conditionals
* Quoted variables within conditionals
* Standardise core help text
* Added help text for disable command
* Added help text for logging command
* Clean up
* Fixed certain new lines and spaces
* Sync with development branch
* Formatting consistency
* Tabs to 2 spaces
* Corrected indenting
* Double braced conditionals
* Quoted variables within conditionals
* Fixed certain newlines and spaces
* Admin help text
* Added help text for interface command
* Sync with development branch
* Formatting consistency
* Tabs to 2 spaces
* Fixed some wording
* Fixed certain spaces
* Formatting consistency
* Minor wording changes
* Tabs to 2 spaces
* Corrected indenting
* Double braced conditionals
* Quoted variables within conditionals
* Fixed certain newlines and spaces
* Blacklist help text
* Formatting consistency
* Tabs to 2 spaces
* Corrected indenting
* Cronometer help text
* Formatting consistency
* Fixed certain newlines and spaces
* Corrected indenting
* Checkout warning alteration
* Add checkout help text
* Corrected help output
* Show help for "pihole -a -i --help"
* Fix "pihole disable --help" and "pihole -l --help"
* Show help for "pihole -v -h"
* Indent output text
* Minor help text change
* Show help for "pihole checkout --help"
* Tricorder: Insecure Opt-out
* Check to see if Tricorder is being called directly
* Provide opt-out for insecure transmission of debug log
* Remove mention of internal function from help menu
* :taco: is the new :shipit: squirrel
* Wording changes and bug fix
* Fix wildcard help text
* -wild is not a valid option since we're already using -wild
* Fix logrotation: manual flushing should be done twice, but automated rotation at midnight should only be done *once*!
* Print echos only when manual flushing is requested
* Add "quiet" mode + update comments in the cron file
* Confirm Tricorder is online
* Scan port 9998 to confirm the availability of "tricorder.pi-hole.net"
* Exit codes for upload process
* Formatting consistency
* Add link to Windows DNS Swapper
See #1400
* Install loopback firewall rules for FTL (#1419)
* Install loopback firewall rules for FTL
* FirewallD FTL ports
Signed-off-by: Dan Schaper
* Remove firewallD FTL local rules.
Local rules should not be blocked in firewallD, not requred for internal service FTD>
* Reinstate https rules, and delete FTL rules
Fixes earlier commit.
* Retrieve local repos on repair (#1481)
* Retrieve local repos on repair
* Change conditional to check for repair
* Change wording of Update/Reconfigure message
* Fixed indenting
* Perform "git reset --hard" on reconfigure
* Change directory before trying to reset repository. Fixes #1489
* No need to `cd $PWD` as it doesn't affect flow of caller script.
Signed-off-by: Dan Schaper
* Refine output of password status in basic-install.sh:displayFinalMessage(). Fixes #1488 (#1490)
* Rewrite Chronometer to output more stats
* Fix output IPv4 addr when removing CIDR notation (#1498)
* Move wildcards file if blocking is disabled (#1495)
* Move wildcards file if blocking is diabled
* Delete newline
* Roll back merge #1417 (#1494)
* Update ISSUE_TEMPLATE.md
* Remove Question option
* Prefer ULA over GUA addresses [IPv6] (#1508)
* On installs with GUA and ULA's we should prefer ULA's as it's been demonstrated that GUA's can and often are rotated by ISPs. Fixes #1473
* Add test for link-local address detection
* Add ULA-only and GUA-only tests
* Add test_IPv6_GUA_ULA_test and test_IPv6_ULA_GUA_test
* Add ""
* Add mock_command_2 command that can mock a command with more than one argument (as "ip -6 address") and result multiple lines of results
* Make mock_command_2 more similar to the original mock_command
* Correct comments
* Fixed remaining comments
* Fixed one last comment...
* Fixed a comment...
* Add weekly logrotation of FTL's log (#1509)
* Update LICENSE of the project to EUPL v1.2
* Make clear that NO is the default if the user just hits return (#1514)
* Add tricorderFunc back as usable function (#1515)
As per #1464
* Don't update FTL when there is a core update (as this will update FTL a second time). Fixes #1516
* Add FTL tests to the test suite (#1510)
* Add first version of FTL tests
* Wait one second to allow FTL to start up and analyze our mock log
* Add test_FTL_telnet_statistics
* Added test_FTL_telnet_top_clients
* Add test_FTL_telnet_top_domains
* Revert "Add FTL tests to the test suite (#1510)" (#1519)
This reverts commit cf6a1ac9adb4e26570cc5da7c8be628080f37e0f.
* Trim version output when update is successful (#1527)
* Change ownership of /etc/pihole to user/group pihole. Fixes #1529 (#1530)
* Delete temporary files after installing the FTL binary. Fixes #1525
* Change from admin to approvers teams
* Introduce new file black.list for blacklist content
* Add "pihole -g -b" to *only* update black.list (saves a bunch of time when adding/changing only blacklisted files - won'tdownload lal lists, but only processes the blacklist and restars dnsmasq)
* Remove useless cat
* Improve displayed messages and overall logic
* Disable black.list on "pihole disable"
* cp + rm === mv (well, almost)
---
.github/ISSUE_TEMPLATE.md | 2 +-
.pullapprove.yml | 4 +-
LICENSE | 119 +++----
README.md | 1 +
advanced/01-pihole.conf | 1 +
advanced/Scripts/chronometer.sh | 479 ++++++++++++++++++++++++-----
advanced/Scripts/list.sh | 311 +++++++++----------
advanced/Scripts/piholeCheckout.sh | 32 +-
advanced/Scripts/piholeDebug.sh | 8 +-
advanced/Scripts/piholeLogFlush.sh | 43 ++-
advanced/Scripts/update.sh | 13 +-
advanced/Scripts/version.sh | 165 ++++++----
advanced/Scripts/webpage.sh | 187 +++++------
advanced/index.php | 2 +-
advanced/logrotate | 11 +
advanced/pihole-FTL.service | 2 +-
advanced/pihole.cron | 7 +-
automated install/basic-install.sh | 98 ++++--
gravity.sh | 109 ++++---
pihole | 207 +++++++++----
test/test_automated_install.py | 76 +++++
21 files changed, 1227 insertions(+), 650 deletions(-)
diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md
index 3014625b..23e67795 100644
--- a/.github/ISSUE_TEMPLATE.md
+++ b/.github/ISSUE_TEMPLATE.md
@@ -9,7 +9,7 @@
_{replace this text with a number from 1 to 10, with 1 being not familiar, and 10 being very familiar}_
---
-**[FEATURE REQUEST | QUESTION | OTHER]:**
+**[BUG REPORT | OTHER]:**
Please [submit your feature request here](https://discourse.pi-hole.net/c/feature-requests), so it is votable by the community. It's also easier for us to track.
diff --git a/.pullapprove.yml b/.pullapprove.yml
index 39566b34..30888234 100644
--- a/.pullapprove.yml
+++ b/.pullapprove.yml
@@ -10,7 +10,7 @@ group_defaults:
reset_on_push:
enabled: true
reject_value: -2
- approve_regex: '^(Approved|:shipit:|:\+1:|Engage)'
+ approve_regex: '^(Approved|:shipit:|:\+1:|Engage|:taco:)'
reject_regex: '^(Rejected|:-1:|Borg)'
author_approval:
auto: true
@@ -35,4 +35,4 @@ groups:
- master
required: 4
teams:
- - admin
+ - approvers
diff --git a/LICENSE b/LICENSE
index 9fddaad1..9ce6e5b0 100644
--- a/LICENSE
+++ b/LICENSE
@@ -12,81 +12,63 @@ This license applies to the whole project EXCEPT:
The licenses that existed prior to this change have remained intact.
-------------------------------------------------------------
+EUROPEAN UNION PUBLIC LICENCE v. 1.2
-European Union Public Licence
-V. 1.1
+EUPL © the European Union 2007, 2016
-EUPL (C) the European Community 2007
-
-This European Union Public Licence (the "EUPL") applies to the Work or Software (as defined below) which is provided under the terms of this Licence. Any use of the Work, other than as authorised under this Licence is prohibited (to the extent such use is covered by a right of the copyright holder of the Work).
-
-The Original Work is provided under the terms of this Licence when the Licensor (as defined below) has placed the following notice immediately following the copyright notice for the Original Work:
-
-Licensed under the EUPL V.1.1
-
-or has expressed by any other mean his willingness to license under the EUPL.
+This European Union Public Licence (the EUPL) applies to the Work (as defined below) which is provided under the terms of this Licence. Any use of the Work, other than as authorised under this Licence is prohibited (to the extent such use is covered by a right of the copyright holder of the Work).
+The Work is provided under the terms of this Licence when the Licensor (as defined below) has placed the following notice immediately following the copyright notice for the Work:
+Licensed under the EUPL
+or has expressed by any other means his willingness to license under the EUPL.
1. Definitions
In this Licence, the following terms have the following meaning:
- The Licence: this Licence.
-
-- The Original Work or the Software: the software distributed and/or communicated by the Licensor under this Licence, available as Source Code and also as Executable Code as the case may be.
-
+- The Original Work: the work or software distributed or communicated by the Licensor under this Licence, available as Source Code and also as Executable Code as the case may be.
- Derivative Works: the works or software that could be created by the Licensee, based upon the Original Work or modifications thereof. This Licence does not define the extent of modification or dependence on the Original Work required in order to classify a work as a Derivative Work; this extent is determined by copyright law applicable in the country mentioned in Article 15.
-
-- The Work: the Original Work and/or its Derivative Works.
-
+- The Work: the Original Work or its Derivative Works.
- The Source Code: the human-readable form of the Work which is the most convenient for people to study and modify.
-
- The Executable Code: any code which has generally been compiled and which is meant to be interpreted by a computer as a program.
-
-- The Licensor: the natural or legal person that distributes and/or communicates the Work under the Licence.
-
+- The Licensor: the natural or legal person that distributes or communicates the Work under the Licence.
- Contributor(s): any natural or legal person who modifies the Work under the Licence, or otherwise contributes to the creation of a Derivative Work.
-
-- The Licensee or "You": any natural or legal person who makes any usage of the Software under the terms of the Licence.
-
-- Distribution and/or Communication: any act of selling, giving, lending, renting, distributing, communicating, transmitting, or otherwise making available, on-line or off-line, copies of the Work or providing access to its essential functionalities at the disposal of any other natural or legal person.
+- The Licensee or You: any natural or legal person who makes any usage of the Work under the terms of the Licence.
+- Distribution or Communication: any act of selling, giving, lending, renting, distributing, communicating, transmitting, or otherwise making available, online or offline, copies of the Work or providing access to its essential functionalities at the disposal of any other natural or legal person.
2. Scope of the rights granted by the Licence
-The Licensor hereby grants You a world-wide, royalty-free, non-exclusive, sub-licensable licence to do the following, for the duration of copyright vested in the Original Work:
-
+The Licensor hereby grants You a worldwide, royalty-free, non-exclusive, sublicensable licence to do the following, for the duration of copyright vested in the Original Work:
- use the Work in any circumstance and for all usage,
- reproduce the Work,
-- modify the Original Work, and make Derivative Works based upon the Work,
+- modify the Work, and make Derivative Works based upon the Work,
- communicate to the public, including the right to make available or display the Work or copies thereof to the public and perform publicly, as the case may be, the Work,
- distribute the Work or copies thereof,
- lend and rent the Work or copies thereof,
-- sub-license rights in the Work or copies thereof.
-
+- sublicense rights in the Work or copies thereof.
Those rights can be exercised on any media, supports and formats, whether now known or later invented, as far as the applicable law permits so.
-
In the countries where moral rights apply, the Licensor waives his right to exercise his moral right to the extent allowed by law in order to make effective the licence of the economic rights here above listed.
-
-The Licensor grants to the Licensee royalty-free, non exclusive usage rights to any patents held by the Licensor, to the extent necessary to make use of the rights granted on the Work under this Licence.
+The Licensor grants to the Licensee royalty-free, non-exclusive usage rights to any patents held by the Licensor, to the extent necessary to make use of the rights granted on the Work under this Licence.
3. Communication of the Source Code
-The Licensor may provide the Work either in its Source Code form, or as Executable Code. If the Work is provided as Executable Code, the Licensor provides in addition a machine-readable copy of the Source Code of the Work along with each copy of the Work that the Licensor distributes or indicates, in a notice following the copyright notice attached to the Work, a repository where the Source Code is easily and freely accessible for as long as the Licensor continues to distribute and/or communicate the Work.
+The Licensor may provide the Work either in its Source Code form, or as Executable Code. If the Work is provided as Executable Code, the Licensor provides in addition a machine-readable copy of the Source Code of the Work along with each copy of the Work that the Licensor distributes or indicates, in a notice following the copyright notice attached to the Work, a repository where the Source Code is easily and freely accessible for as long as the Licensor continues to distribute or communicate the Work.
4. Limitations on copyright
-Nothing in this Licence is intended to deprive the Licensee of the benefits from any exception or limitation to the exclusive rights of the rights owners in the Original Work or Software, of the exhaustion of those rights or of other applicable limitations thereto.
+Nothing in this Licence is intended to deprive the Licensee of the benefits from any exception or limitation to the exclusive rights of the rights owners in the Work, of the exhaustion of those rights or of other applicable limitations thereto.
5. Obligations of the Licensee
The grant of the rights mentioned above is subject to some restrictions and obligations imposed on the Licensee. Those obligations are the following:
-Attribution right: the Licensee shall keep intact all copyright, patent or trademarks notices and all notices that refer to the Licence and to the disclaimer of warranties. The Licensee must include a copy of such notices and a copy of the Licence with every copy of the Work he/she distributes and/or communicates. The Licensee must cause any Derivative Work to carry prominent notices stating that the Work has been modified and the date of modification.
+Attribution right: The Licensee shall keep intact all copyright, patent or trademarks notices and all notices that refer to the Licence and to the disclaimer of warranties. The Licensee must include a copy of such notices and a copy of the Licence with every copy of the Work he/she distributes or communicates. The Licensee must cause any Derivative Work to carry prominent notices stating that the Work has been modified and the date of modification.
-Copyleft clause: If the Licensee distributes and/or communicates copies of the Original Works or Derivative Works based upon the Original Work, this Distribution and/or Communication will be done under the terms of this Licence or of a later version of this Licence unless the Original Work is expressly distributed only under this version of the Licence. The Licensee (becoming Licensor) cannot offer or impose any additional terms or conditions on the Work or Derivative Work that alter or restrict the terms of the Licence.
+Copyleft clause: If the Licensee distributes or communicates copies of the Original Works or Derivative Works, this Distribution or Communication will be done under the terms of this Licence or of a later version of this Licence unless the Original Work is expressly distributed only under this version of the Licence - for example by communicating EUPL v. 1.2 only. The Licensee (becoming Licensor) cannot offer or impose any additional terms or conditions on the Work or Derivative Work that alter or restrict the terms of the Licence.
-Compatibility clause: If the Licensee Distributes and/or Communicates Derivative Works or copies thereof based upon both the Original Work and another work licensed under a Compatible Licence, this Distribution and/or Communication can be done under the terms of this Compatible Licence. For the sake of this clause, "Compatible Licence" refers to the licences listed in the appendix attached to this Licence. Should the Licensee’s obligations under the Compatible Licence conflict with his/her obligations under this Licence, the obligations of the Compatible Licence shall prevail.
+Compatibility clause: If the Licensee Distributes or Communicates Derivative Works or copies thereof based upon both the Work and another work licensed under a Compatible Licence, this Distribution or Communication can be done under the terms of this Compatible Licence. For the sake of this clause, Compatible Licence refers to the licences listed in the appendix attached to this Licence. Should the Licensee's obligations under the Compatible Licence conflict with his/her obligations under this Licence, the obligations of the Compatible Licence shall prevail.
-Provision of Source Code: When distributing and/or communicating copies of the Work, the Licensee will provide a machine-readable copy of the Source Code or indicate a repository where this Source will be easily and freely available for as long as the Licensee continues to distribute and/or communicate the Work.
+Provision of Source Code: When distributing or communicating copies of the Work, the Licensee will provide a machine-readable copy of the Source Code or indicate a repository where this Source will be easily and freely available for as long as the Licensee continues to distribute or communicate the Work.
Legal Protection: This Licence does not grant permission to use the trade names, trademarks, service marks, or names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the copyright notice.
@@ -100,10 +82,8 @@ Each time You accept the Licence, the original Licensor and subsequent Contribut
7. Disclaimer of Warranty
-The Work is a work in progress, which is continuously improved by numerous contributors. It is not a finished work and may therefore contain defects or "bugs" inherent to this type of software development.
-
-For the above reason, the Work is provided under the Licence on an "as is" basis and without warranties of any kind concerning the Work, including without limitation merchantability, fitness for a particular purpose, absence of defects or errors, accuracy, non-infringement of intellectual property rights other than copyright as stated in Article 6 of this Licence.
-
+The Work is a work in progress, which is continuously improved by numerous Contributors. It is not a finished work and may therefore contain defects or bugs inherent to this type of development.
+For the above reason, the Work is provided under the Licence on an as is basis and without warranties of any kind concerning the Work, including without limitation merchantability, fitness for a particular purpose, absence of defects or errors, accuracy, non-infringement of intellectual property rights other than copyright as stated in Article 6 of this Licence.
This disclaimer of warranty is an essential part of the Licence and a condition for the grant of any rights to the Work.
8. Disclaimer of Liability
@@ -112,56 +92,55 @@ Except in the cases of wilful misconduct or damages directly caused to natural p
9. Additional agreements
-While distributing the Original Work or Derivative Works, You may choose to conclude an additional agreement to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or services consistent with this Licence. However, in accepting such obligations, You may act only on your own behalf and on your sole responsibility, not on behalf of the original Licensor or any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against such Contributor by the fact You have accepted any such warranty or additional liability.
+While distributing the Work, You may choose to conclude an additional agreement, defining obligations or services consistent with this Licence. However, if accepting obligations, You may act only on your own behalf and on your sole responsibility, not on behalf of the original Licensor or any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against such Contributor by the fact You have accepted any warranty or additional liability.
10. Acceptance of the Licence
-The provisions of this Licence can be accepted by clicking on an icon "I agree" placed under the bottom of a window displaying the text of this Licence or by affirming consent in any other similar way, in accordance with the rules of applicable law. Clicking on that icon indicates your clear and irrevocable acceptance of this Licence and all of its terms and conditions.
-
-Similarly, you irrevocably accept this Licence and all of its terms and conditions by exercising any rights granted to You by Article 2 of this Licence, such as the use of the Work, the creation by You of a Derivative Work or the Distribution and/or Communication by You of the Work or copies thereof.
+The provisions of this Licence can be accepted by clicking on an icon I agree placed under the bottom of a window displaying the text of this Licence or by affirming consent in any other similar way, in accordance with the rules of applicable law. Clicking on that icon indicates your clear and irrevocable acceptance of this Licence and all of its terms and conditions.
+Similarly, you irrevocably accept this Licence and all of its terms and conditions by exercising any rights granted to You by Article 2 of this Licence, such as the use of the Work, the creation by You of a Derivative Work or the Distribution or Communication by You of the Work or copies thereof.
11. Information to the public
-In case of any Distribution and/or Communication of the Work by means of electronic communication by You (for example, by offering to download the Work from a remote location) the distribution channel or media (for example, a website) must at least provide to the public the information requested by the applicable law regarding the Licensor, the Licence and the way it may be accessible, concluded, stored and reproduced by the Licensee.
+In case of any Distribution or Communication of the Work by means of electronic communication by You (for example, by offering to download the Work from a remote location) the distribution channel or media (for example, a website) must at least provide to the public the information requested by the applicable law regarding the Licensor, the Licence and the way it may be accessible, concluded, stored and reproduced by the Licensee.
12. Termination of the Licence
The Licence and the rights granted hereunder will terminate automatically upon any breach by the Licensee of the terms of the Licence.
-
Such a termination will not terminate the licences of any person who has received the Work from the Licensee under the Licence, provided such persons remain in full compliance with the Licence.
13. Miscellaneous
-Without prejudice of Article 9 above, the Licence represents the complete agreement between the Parties as to the Work licensed hereunder.
-
-If any provision of the Licence is invalid or unenforceable under applicable law, this will not affect the validity or enforceability of the Licence as a whole. Such provision will be construed and/or reformed so as necessary to make it valid and enforceable.
-
-The European Commission may publish other linguistic versions and/or new versions of this Licence, so far this is required and reasonable, without reducing the scope of the rights granted by the Licence. New versions of the Licence will be published with a unique version number.
-
+Without prejudice of Article 9 above, the Licence represents the complete agreement between the Parties as to the Work.
+If any provision of the Licence is invalid or unenforceable under applicable law, this will not affect the validity or enforceability of the Licence as a whole. Such provision will be construed or reformed so as necessary to make it valid and enforceable.
+The European Commission may publish other linguistic versions or new versions of this Licence or updated versions of the Appendix, so far this is required and reasonable, without reducing the scope of the rights granted by the Licence. New versions of the Licence will be published with a unique version number.
All linguistic versions of this Licence, approved by the European Commission, have identical value. Parties can take advantage of the linguistic version of their choice.
14. Jurisdiction
-Any litigation resulting from the interpretation of this License, arising between the European Commission, as a Licensor, and any Licensee, will be subject to the jurisdiction of the Court of Justice of the European Communities, as laid down in article 238 of the Treaty establishing the European Community.
-
-Any litigation arising between Parties, other than the European Commission, and resulting from the interpretation of this License, will be subject to the exclusive jurisdiction of the competent court where the Licensor resides or conducts its primary business.
+Without prejudice to specific agreement between parties,
+- any litigation resulting from the interpretation of this License, arising between the European Union institutions, bodies, offices or agencies, as a Licensor, and any Licensee, will be subject to the jurisdiction of the Court of Justice of the European Union, as laid down in article 272 of the Treaty on the Functioning of the European Union,
+- any litigation arising between other parties and resulting from the interpretation of this License, will be subject to the exclusive jurisdiction of the competent court where the Licensor resides or conducts its primary business.
15. Applicable Law
-This Licence shall be governed by the law of the European Union country where the Licensor resides or has his registered office.
-
-This licence shall be governed by the Belgian law if:
-
-- a litigation arises between the European Commission, as a Licensor, and any Licensee;
-- the Licensor, other than the European Commission, has no residence or registered office inside a European Union country.
-
+Without prejudice to specific agreement between parties,
+- this Licence shall be governed by the law of the European Union Member State where the Licensor has his seat, resides or has his registered office,
+- this licence shall be governed by Belgian law if the Licensor has no seat, residence or registered office inside a European Union Member State.
===
+
Appendix
-"Compatible Licences" according to article 5 EUPL are:
-- GNU General Public License (GNU GPL) v. 2
+Compatible Licences according to Article 5 EUPL are:
+- GNU General Public License (GPL) v. 2, v. 3
+- GNU Affero General Public License (AGPL) v. 3
- Open Software License (OSL) v. 2.1, v. 3.0
-- Common Public License v. 1.0
-- Eclipse Public License v. 1.0
-- Cecill v. 2.0
+- Eclipse Public License (EPL) v. 1.0
+- CeCILL v. 2.0, v. 2.1
+- Mozilla Public Licence (MPL) v. 2
+- GNU Lesser General Public Licence (LGPL) v. 2.1, v. 3
+- Creative Commons Attribution-ShareAlike v. 3.0 Unported (CC BY-SA 3.0) for works other than software
+- European Union Public Licence (EUPL) v. 1.1, v. 1.2
+- Québec Free and Open-Source Licence - Reciprocity (LiLiQ-R) or Strong Reciprocity (LiLiQ-R+)
+- The European Commission may update this Appendix to later versions of the above licences without producing a new version of the EUPL, as long as they provide the rights granted in Article 2 of this Licence and protect the covered Source Code from exclusive appropriation.
+- All other changes or additions to this Appendix require the production of a new EUPL version.
diff --git a/README.md b/README.md
index 75c548e5..6f8813fa 100644
--- a/README.md
+++ b/README.md
@@ -156,6 +156,7 @@ You can view [real-time stats](https://discourse.pi-hole.net/t/how-do-i-view-my-
- [Let your blink1 device blink when Pi-hole filters ads](https://gist.github.com/elpatron68/ec0b4c582e5abf604885ac1e068d233f)
- [Pi-hole Prometheus exporter](https://github.com/nlamirault/pihole_exporter): a [Prometheus](https://prometheus.io/) exporter for Pi-hole
- [Pi-hole Droid - open source Android client](https://github.com/friimaind/pi-hole-droid)
+- [Windows DNS Swapper](https://github.com/roots84/DNS-Swapper), see [#1400](https://github.com/pi-hole/pi-hole/issues/1400)
## Coverage
diff --git a/advanced/01-pihole.conf b/advanced/01-pihole.conf
index 1b157f88..79735c15 100644
--- a/advanced/01-pihole.conf
+++ b/advanced/01-pihole.conf
@@ -22,6 +22,7 @@
addn-hosts=/etc/pihole/gravity.list
addn-hosts=/etc/pihole/local.list
+addn-hosts=/etc/pihole/black.list
domain-needed
diff --git a/advanced/Scripts/chronometer.sh b/advanced/Scripts/chronometer.sh
index 67ff495b..d9b7d05b 100755
--- a/advanced/Scripts/chronometer.sh
+++ b/advanced/Scripts/chronometer.sh
@@ -8,101 +8,428 @@
# This file is copyright under the latest version of the EUPL.
# Please see LICENSE file for your rights under this license.
-#Functions##############################################################################################################
-piLog="/var/log/pihole.log"
-gravity="/etc/pihole/gravity.list"
-
-. /etc/pihole/setupVars.conf
-
-function GetFTLData {
+# Retrieve stats from FTL engine
+pihole-FTL() {
+ ftl_port=$(cat /var/run/pihole-FTL.port 2> /dev/null)
+ if [[ -n "$ftl_port" ]]; then
# Open connection to FTL
- exec 3<>/dev/tcp/localhost/"$(cat /var/run/pihole-FTL.port)"
+ exec 3<>"/dev/tcp/localhost/$ftl_port"
# Test if connection is open
- if { >&3; } 2> /dev/null; then
- # Send command to FTL
- echo -e ">$1" >&3
+ if { "true" >&3; } 2> /dev/null; then
+ # Send command to FTL
+ echo -e ">$1" >&3
- # Read input
- read -r -t 1 LINE <&3
- until [ ! $? ] || [[ "$LINE" == *"EOM"* ]]; do
- echo "$LINE" >&1
- read -r -t 1 LINE <&3
- done
+ # Read input
+ read -r -t 1 LINE <&3
+ until [[ ! $? ]] || [[ "$LINE" == *"EOM"* ]]; do
+ echo "$LINE" >&1
+ read -r -t 1 LINE <&3
+ done
- # Close connection
- exec 3>&-
- exec 3<&-
+ # Close connection
+ exec 3>&-
+ exec 3<&-
fi
+ else
+ echo -e "${COL_LIGHT_RED}FTL offline${COL_NC}"
+ fi
}
-outputJSON() {
- get_summary_data
- echo "{\"domains_being_blocked\":${domains_being_blocked_raw},\"dns_queries_today\":${dns_queries_today_raw},\"ads_blocked_today\":${ads_blocked_today_raw},\"ads_percentage_today\":${ads_percentage_today_raw}}"
+# Print spaces to align right-side content
+printFunc() {
+ txt_len="${#2}"
+
+ # Reduce string length when using colour code
+ [ "${2:0:1}" == "" ] && txt_len=$((txt_len-7))
+
+ if [[ "$3" == "last" ]]; then
+ # Prevent final line from printing trailing newline
+ scr_size=( $(stty size 2>/dev/null || echo 24 80) )
+ scr_width="${scr_size[1]}"
+
+ title_len="${#1}"
+ spc_num=$(( (scr_width - title_len) - txt_len ))
+ [[ "$spc_num" -lt 0 ]] && spc_num="0"
+ spc=$(printf "%${spc_num}s")
+
+ printf "%s%s$spc" "$1" "$2"
+ else
+ # Determine number of spaces for padding
+ spc_num=$(( 20 - txt_len ))
+ [[ "$spc_num" -lt 0 ]] && spc_num="0"
+ spc=$(printf "%${spc_num}s")
+
+ # Print string (Max 20 characters, prevents overflow)
+ printf "%s%s$spc" "$1" "${2:0:20}"
+ fi
}
-get_summary_data() {
- local summary=$(GetFTLData "stats")
- domains_being_blocked_raw=$(grep "domains_being_blocked" <<< "${summary}" | grep -Eo "[0-9]+$")
- domains_being_blocked=$(printf "%'.f" ${domains_being_blocked_raw})
- dns_queries_today_raw=$(grep "dns_queries_today" <<< "$summary" | grep -Eo "[0-9]+$")
- dns_queries_today=$(printf "%'.f" ${dns_queries_today_raw})
- ads_blocked_today_raw=$(grep "ads_blocked_today" <<< "$summary" | grep -Eo "[0-9]+$")
- ads_blocked_today=$(printf "%'.f" ${ads_blocked_today_raw})
- ads_percentage_today_raw=$(grep "ads_percentage_today" <<< "$summary" | grep -Eo "[0-9.]+$")
- LC_NUMERIC=C ads_percentage_today=$(printf "%'.f" ${ads_percentage_today_raw})
+# Perform on first Chrono run (not for JSON formatted string)
+get_init_stats() {
+ LC_NUMERIC=C
+ calcFunc(){ awk "BEGIN {print $*}"; }
+
+ # Convert bytes to human-readable format
+ hrBytes() {
+ awk '{
+ num=$1;
+ if(num==0) {
+ print "0 B"
+ } else {
+ xxx=(num<0?-num:num)
+ sss=(num<0?-1:1)
+ split("B KB MB GB TB PB",type)
+ for(i=5;yyy < 1;i--) {
+ yyy=xxx / (2^(10*i))
+ }
+ printf "%.0f " type[i+2], yyy*sss
+ }
+ }' <<< "$1";
+ }
+
+ # Convert seconds to human-readable format
+ hrSecs() {
+ day=$(( $1/60/60/24 )); hrs=$(( $1/3600%24 )); mins=$(( ($1%3600)/60 )); secs=$(( $1%60 ))
+ [[ "$day" -ge "2" ]] && plu="s"
+ [[ "$day" -ge "1" ]] && days="$day day${plu}, " || days=""
+ printf "%s%02d:%02d:%02d\n" "$days" "$hrs" "$mins" "$secs"
+ }
+
+ # Set Colour Codes
+ coltable="/opt/pihole/COL_TABLE"
+ if [[ -f "${coltable}" ]]; then
+ source ${coltable}
+ else
+ COL_NC='[0m'
+ COL_DARK_GRAY='[1;30m'
+ COL_LIGHT_GREEN='[1;32m'
+ COL_LIGHT_BLUE='[1;34m'
+ COL_LIGHT_RED='[1;31m'
+ COL_YELLOW='[1;33m'
+ COL_LIGHT_RED='[1;31m'
+ COL_URG_RED='[39;41m'
+ fi
+
+ # Get RPi model number, or OS distro info
+ if command -v vcgencmd &> /dev/null; then
+ sys_rev=$(awk '/Revision/ {print $3}' < /proc/cpuinfo)
+ case "$sys_rev" in
+ 000[2-6]) sys_model=" 1, Model B";; # 256MB
+ 000[7-9]) sys_model=" 1, Model A" ;; # 256MB
+ 000d|000e|000f) sys_model=" 1, Model B";; # 512MB
+ 0010|0013) sys_model=" 1, Model B+";; # 512MB
+ 0012|0015) sys_model=" 1, Model A+";; # 256MB
+ a0104[0-1]|a21041|a22042) sys_model=" 2, Model B";; # 1GB
+ 900021) sys_model=" 1, Model A+";; # 512MB
+ 900032) sys_model=" 1, Model B+";; # 512MB
+ 90009[2-3]|920093) sys_model=" Zero";; # 512MB
+ 9000c1) sys_model=" Zero W";; # 512MB
+ a02082|a[2-3]2082) sys_model=" 3, Model B";; # 1GB
+ *) sys_model="" ;;
+ esac
+ sys_type="Raspberry Pi$sys_model"
+ else
+ source "/etc/os-release"
+ CODENAME=$(sed 's/[()]//g' <<< "${VERSION/* /}")
+ sys_type="${NAME/ */} ${CODENAME^} $VERSION_ID"
+ fi
+
+ # Get core count
+ sys_cores=$(grep -c "^processor" /proc/cpuinfo)
+ [[ "$sys_cores" -ne 1 ]] && sys_cores_plu="cores" || sys_cores_plu="core"
+
+ # Test existence of clock speed file for ARM CPU
+ if [[ -f "/sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq" ]]; then
+ scaling_freq_file="/sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq"
+ fi
+
+ # Test existence of temperature file
+ if [[ -f "/sys/class/thermal/thermal_zone0/temp" ]]; then
+ temp_file="/sys/class/thermal/thermal_zone0/temp"
+ elif [[ -f "/sys/class/hwmon/hwmon0/temp1_input" ]]; then
+ temp_file="/sys/class/hwmon/hwmon0/temp1_input"
+ else
+ temp_file=""
+ fi
+
+ # Test existence of setupVars config
+ if [[ -f "/etc/pihole/setupVars.conf" ]]; then
+ setupVars="/etc/pihole/setupVars.conf"
+ fi
}
-normalChrono() {
- for (( ; ; )); do
- get_summary_data
- domain=$(GetFTLData recentBlocked)
- clear
- # Displays a colorful Pi-hole logo
- echo " [0;1;35;95m_[0;1;31;91m__[0m [0;1;33;93m_[0m [0;1;34;94m_[0m [0;1;36;96m_[0m"
- echo "[0;1;31;91m|[0m [0;1;33;93m_[0m [0;1;32;92m(_[0;1;36;96m)_[0;1;34;94m__[0;1;35;95m|[0m [0;1;31;91m|_[0m [0;1;32;92m__[0;1;36;96m_|[0m [0;1;34;94m|[0;1;35;95m__[0;1;31;91m_[0m"
- echo "[0;1;33;93m|[0m [0;1;32;92m_[0;1;36;96m/[0m [0;1;34;94m|_[0;1;35;95m__[0;1;31;91m|[0m [0;1;33;93m'[0m [0;1;32;92m\/[0m [0;1;36;96m_[0m [0;1;34;94m\[0m [0;1;35;95m/[0m [0;1;31;91m-[0;1;33;93m_)[0m"
- echo "[0;1;32;92m|_[0;1;36;96m|[0m [0;1;34;94m|_[0;1;35;95m|[0m [0;1;33;93m|_[0;1;32;92m||[0;1;36;96m_\[0;1;34;94m__[0;1;35;95m_/[0;1;31;91m_\[0;1;33;93m__[0;1;32;92m_|[0m"
- echo ""
- echo " ${IPV4_ADDRESS}"
- echo ""
- uptime | cut -d' ' -f11-
- #uptime -p #Doesn't work on all versions of uptime
- uptime | awk -F'( |,|:)+' '{if ($7=="min") m=$6; else {if ($7~/^day/) {d=$6;h=$8;m=$9} else {h=$6;m=$7}}} {print d+0,"days,",h+0,"hours,",m+0,"minutes."}'
- echo "-------------------------------"
- echo "Recently blocked:"
- echo " $domain"
+get_sys_stats() {
+ local ph_ver_raw
+ local cpu_raw
+ local ram_raw
+ local disk_raw
- echo "Blocking: ${domains_being_blocked}"
- echo "Queries: ${dns_queries_today}"
- echo "Pi-holed: ${ads_blocked_today} (${ads_percentage_today}%)"
-
- sleep 5
- done
+ # Update every 12 refreshes (Def: every 60s)
+ count=$((count+1))
+ if [[ "$count" == "1" ]] || (( "$count" % 12 == 0 )); then
+ [[ -n "$setupVars" ]] && source "$setupVars"
+
+
+ ph_ver_raw=($(pihole -v -c 2> /dev/null | sed -n 's/^.* v/v/p'))
+ if [[ -n "${ph_ver_raw[0]}" ]]; then
+ ph_core_ver="${ph_ver_raw[0]}"
+ ph_lte_ver="${ph_ver_raw[1]}"
+ ph_ftl_ver="${ph_ver_raw[2]}"
+ else
+ ph_core_ver="${COL_LIGHT_RED}API unavailable${COL_NC}"
+ fi
+
+ sys_name=$(hostname)
+
+ [[ -n "$TEMPERATUREUNIT" ]] && temp_unit="$TEMPERATUREUNIT" || temp_unit="c"
+
+ # Get storage stats for partition mounted on /
+ disk_raw=($(df -B1 / 2> /dev/null | awk 'END{ print $3,$2,$5 }'))
+ disk_used="${disk_raw[0]}"
+ disk_total="${disk_raw[1]}"
+ disk_perc="${disk_raw[2]}"
+
+ net_gateway=$(route -n | awk '$4 == "UG" {print $2;exit}')
+
+ # Get DHCP stats, if feature is enabled
+ if [[ "$DHCP_ACTIVE" == "true" ]]; then
+ ph_dhcp_eip="${DHCP_END##*.}"
+ ph_dhcp_max=$(( ${DHCP_END##*.} - ${DHCP_START##*.} + 1 ))
+ fi
+
+ # Get alt DNS server, or print total count of alt DNS servers
+ if [[ -z "${PIHOLE_DNS_3}" ]]; then
+ ph_alts="${PIHOLE_DNS_2}"
+ else
+ dns_count="0"
+ [[ -n "${PIHOLE_DNS_2}" ]] && dns_count=$((dns_count+1))
+ [[ -n "${PIHOLE_DNS_3}" ]] && dns_count=$((dns_count+1))
+ [[ -n "${PIHOLE_DNS_4}" ]] && dns_count=$((dns_count+1))
+ [[ -n "${PIHOLE_DNS_5}" ]] && dns_count=$((dns_count+1))
+ [[ -n "${PIHOLE_DNS_6}" ]] && dns_count=$((dns_count+1))
+ [[ -n "${PIHOLE_DNS_7}" ]] && dns_count=$((dns_count+1))
+ [[ -n "${PIHOLE_DNS_8}" ]] && dns_count=$((dns_count+1))
+ [[ -n "${PIHOLE_DNS_9}" ]] && dns_count="$dns_count+"
+ ph_alts="${dns_count} others"
+ fi
+ fi
+
+ sys_uptime=$(hrSecs "$(cut -d. -f1 /proc/uptime)")
+ sys_loadavg=$(cut -d " " -f1,2,3 /proc/loadavg)
+
+ # Get CPU usage, only counting processes over 1% CPU as active
+ cpu_raw=$(ps -eo pcpu,rss --no-headers | grep -E -v " 0")
+ cpu_tasks=$(wc -l <<< "$cpu_raw")
+ cpu_taskact=$(sed -r "/(^ 0.)/d" <<< "$cpu_raw" | wc -l)
+ cpu_perc=$(awk '{sum+=$1} END {printf "%.0f\n", sum/'"$sys_cores"'}' <<< "$cpu_raw")
+
+ # Get CPU clock speed
+ if [[ -n "$scaling_freq_file" ]]; then
+ cpu_mhz=$(( $(< /sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq) / 1000 ))
+ else
+ cpu_mhz=$(lscpu | awk -F "[ .]+" '/MHz/ {print $4;exit}')
+ fi
+
+ # Determine correct string format for CPU clock speed
+ if [[ -n "$cpu_mhz" ]]; then
+ [[ "$cpu_mhz" -le "999" ]] && cpu_freq="$cpu_mhz MHz" || cpu_freq="$(calcFunc "$cpu_mhz"/1000) Ghz"
+ [[ -n "$cpu_freq" ]] && cpu_freq_str=" @ $cpu_freq" || cpu_freq_str=""
+ fi
+
+ # Determine colour for temperature
+ if [[ -n "$temp_file" ]]; then
+ if [[ "$temp_unit" == "C" ]]; then
+ cpu_temp=$(printf "%'.0fc\n" "$(calcFunc "$(< $temp_file) / 1000")")
+
+ case "${cpu_temp::-1}" in
+ -*|[0-9]|[1-3][0-9]) cpu_col="$COL_LIGHT_BLUE";;
+ 4[0-9]) cpu_col="";;
+ 5[0-9]) cpu_col="$COL_YELLOW";;
+ 6[0-9]) cpu_col="$COL_LIGHT_RED";;
+ *) cpu_col="$COL_URG_RED";;
+ esac
+
+ # $COL_NC$COL_DARK_GRAY is needed for $COL_URG_RED
+ cpu_temp_str=", $cpu_col$cpu_temp$COL_NC$COL_DARK_GRAY"
+
+ elif [[ "$temp_unit" == "F" ]]; then
+ cpu_temp=$(printf "%'.0ff\n" "$(calcFunc "($(< $temp_file) / 1000) * 9 / 5 + 32")")
+
+ case "${cpu_temp::-1}" in
+ -*|[0-9]|[0-9][0-9]) cpu_col="$COL_LIGHT_BLUE";;
+ 1[0-1][0-9]) cpu_col="";;
+ 1[2-3][0-9]) cpu_col="$COL_YELLOW";;
+ 1[4-5][0-9]) cpu_col="$COL_LIGHT_RED";;
+ *) cpu_col="$COL_URG_RED";;
+ esac
+
+ cpu_temp_str=", $cpu_col$cpu_temp$COL_NC$COL_DARK_GRAY"
+
+ else
+ cpu_temp_str=$(printf ", %'.0fk\n" "$(calcFunc "($(< $temp_file) / 1000) + 273.15")")
+ fi
+ else
+ cpu_temp_str=""
+ fi
+
+ ram_raw=($(awk '/MemTotal:/{total=$2} /MemFree:/{free=$2} /Buffers:/{buffers=$2} /^Cached:/{cached=$2} END {printf "%.0f %.0f %.0f", (total-free-buffers-cached)*100/total, (total-free-buffers-cached)*1024, total*1024}' /proc/meminfo))
+ ram_perc="${ram_raw[0]}"
+ ram_used="${ram_raw[1]}"
+ ram_total="${ram_raw[2]}"
+
+ if [[ "$(pihole status web 2> /dev/null)" == "1" ]]; then
+ ph_status="${COL_LIGHT_GREEN}Active"
+ else
+ ph_status="${COL_LIGHT_RED}Inactive"
+ fi
+
+ if [[ "$DHCP_ACTIVE" == "true" ]]; then
+ ph_dhcp_num=$(wc -l 2> /dev/null < "/etc/pihole/dhcp.leases")
+ fi
}
-displayHelp() {
- cat << EOM
-::: Displays stats about your piHole!
-:::
-::: Usage: sudo pihole -c [optional:-j]
-::: Note: If no option is passed, then stats are displayed on screen, updated every 5 seconds
-:::
-::: Options:
-::: -j, --json output stats as JSON formatted string
-::: -h, --help display this help text
-EOM
- exit 0
+get_ftl_stats() {
+ local stats_raw
+
+ stats_raw=($(pihole-FTL "stats"))
+ domains_being_blocked_raw="${stats_raw[1]}"
+ dns_queries_today_raw="${stats_raw[3]}"
+ ads_blocked_today_raw="${stats_raw[5]}"
+ ads_percentage_today_raw="${stats_raw[7]}"
+
+ # Only retrieve these stats when not called from jsonFunc
+ if [[ -z "$1" ]]; then
+ local recent_blocked_raw
+ local top_ad_raw
+ local top_domain_raw
+ local top_client_raw
+
+ domains_being_blocked=$(printf "%'.0f\n" "${domains_being_blocked_raw}")
+ dns_queries_today=$(printf "%'.0f\n" "${dns_queries_today_raw}")
+ ads_blocked_today=$(printf "%'.0f\n" "${ads_blocked_today_raw}")
+ ads_percentage_today=$(printf "%'.0f\n" "${ads_percentage_today_raw}")
+
+ recent_blocked_raw=$(pihole-FTL recentBlocked)
+ top_ad_raw=($(pihole-FTL "top-ads (1)"))
+ top_domain_raw=($(pihole-FTL "top-domains (1)"))
+ top_client_raw=($(pihole-FTL "top-clients (1)"))
+
+ # Limit strings to 40 characters to prevent overflow
+ recent_blocked="${recent_blocked_raw:0:40}"
+ top_ad="${top_ad_raw[2]:0:40}"
+ top_domain="${top_domain_raw[2]:0:40}"
+ [[ "${top_client_raw[3]}" ]] && top_client="${top_client_raw[3]:0:40}" || top_client="${top_client_raw[2]:0:40}"
+ fi
+}
+
+chronoFunc() {
+ get_init_stats
+
+ for (( ; ; )); do
+ get_sys_stats
+ get_ftl_stats
+
+ # Do not print LTE/FTL strings if API is unavailable
+ ph_core_str=" ${COL_DARK_GRAY}Pi-hole: $ph_core_ver${COL_NC}"
+ if [[ -n "$ph_lte_ver" ]]; then
+ ph_lte_str=" ${COL_DARK_GRAY}AdminLTE: $ph_lte_ver${COL_NC}"
+ ph_ftl_str=" ${COL_DARK_GRAY}FTL: $ph_ftl_ver${COL_NC}"
+ fi
+
+ clear
+
+ echo -e "[0;1;31;91m|¯[0;1;33;93m¯[0;1;32;92m¯[0;1;32;92m(¯[0;1;36;96m)_[0;1;34;94m_[0;1;35;95m|[0;1;33;93m¯[0;1;31;91m|_ [0;1;32;92m__[0;1;36;96m_|[0;1;31;91m¯[0;1;34;94m|[0;1;35;95m__[0;1;31;91m_[0m$ph_core_str
+[0;1;33;93m| ¯[0;1;32;92m_[0;1;36;96m/¯[0;1;34;94m|_[0;1;35;95m_[0;1;31;91m| [0;1;33;93m' [0;1;32;92m\/ [0;1;36;96m_ [0;1;34;94m\ [0;1;35;95m/ [0;1;31;91m-[0;1;33;93m_)[0m$ph_lte_str
+[0;1;32;92m|_[0;1;36;96m| [0;1;34;94m|_[0;1;35;95m| [0;1;33;93m|_[0;1;32;92m||[0;1;36;96m_\[0;1;34;94m__[0;1;35;95m_/[0;1;31;91m_\[0;1;33;93m__[0;1;32;92m_|[0m$ph_ftl_str
+ ${COL_DARK_GRAY}——————————————————————————————————————————————————————————${COL_NC}"
+
+ printFunc " Hostname: " "$sys_name"
+ [ -n "$sys_type" ] && printf "%s(%s)%s\n" "$COL_DARK_GRAY" "$sys_type" "$COL_NC" || printf "\n"
+
+ printf "%s\n" " Uptime: $sys_uptime"
+
+ printFunc " Task Load: " "$sys_loadavg"
+ printf "%s(%s)%s\n" "$COL_DARK_GRAY" "Active: $cpu_taskact of $cpu_tasks tasks" "$COL_NC"
+
+ printFunc " CPU usage: " "$cpu_perc%"
+ printf "%s(%s)%s\n" "$COL_DARK_GRAY" "$sys_cores $sys_cores_plu$cpu_freq_str$cpu_temp_str" "$COL_NC"
+
+ printFunc " RAM usage: " "$ram_perc%"
+ printf "%s(%s)%s\n" "$COL_DARK_GRAY" "Used: $(hrBytes "$ram_used") of $(hrBytes "$ram_total")" "$COL_NC"
+
+ printFunc " HDD usage: " "$disk_perc"
+ printf "%s(%s)%s\n" "$COL_DARK_GRAY" "Used: $(hrBytes "$disk_used") of $(hrBytes "$disk_total")" "$COL_NC"
+
+ printFunc " LAN addr: " "${IPV4_ADDRESS/\/*/}"
+ printf "%s(%s)%s\n" "$COL_DARK_GRAY" "Gateway: $net_gateway" "$COL_NC"
+
+ if [[ "$DHCP_ACTIVE" == "true" ]]; then
+ printFunc " DHCP: " "$DHCP_START to $ph_dhcp_eip"
+ printf "%s(%s)%s\n" "$COL_DARK_GRAY" "Leased: $ph_dhcp_num of $ph_dhcp_max" "$COL_NC"
+ fi
+
+ printFunc " Pi-hole: " "$ph_status"
+ printf "%s(%s)%s\n" "$COL_DARK_GRAY" "Blocking: $domains_being_blocked sites" "$COL_NC"
+
+ printFunc " Ads Today: " "$ads_percentage_today%"
+ printf "%s(%s)%s\n" "$COL_DARK_GRAY" "$ads_blocked_today of $dns_queries_today queries" "$COL_NC"
+
+ printFunc " Fwd DNS: " "$PIHOLE_DNS_1"
+ printf "%s(%s)%s\n" "$COL_DARK_GRAY" "Alt DNS: $ph_alts" "$COL_NC"
+
+ echo -e " ${COL_DARK_GRAY}——————————————————————————————————————————————————————————${COL_NC}"
+ echo " Recently blocked: $recent_blocked"
+ echo " Top Advertiser: $top_ad"
+ echo " Top Domain: $top_domain"
+ printFunc " Top Client: " "$top_client" "last"
+
+ if [[ "$1" == "exit" ]]; then
+ exit 0
+ else
+ if [[ -n "$1" ]]; then
+ sleep "${1}"
+ else
+ sleep 5
+ fi
+ fi
+
+ done
+}
+
+jsonFunc() {
+ get_ftl_stats "json"
+ echo "{\"domains_being_blocked\":${domains_being_blocked_raw},\"dns_queries_today\":${dns_queries_today_raw},\"ads_blocked_today\":${ads_blocked_today_raw},\"ads_percentage_today\":${ads_percentage_today_raw}}"
+}
+
+helpFunc() {
+ if [[ "$1" == "?" ]]; then
+ echo "Unknown option. Please view 'pihole -c --help' for more information"
+ else
+ echo "Usage: pihole -c [options]
+Example: 'pihole -c -j'
+Calculates stats and displays to an LCD
+
+Options:
+ -j, --json Output stats as JSON formatted string
+ -r, --refresh Set update frequency (in seconds)
+ -e, --exit Output stats and exit witout refreshing
+ -h, --help Display this help text"
+ fi
+
+ exit 0
}
if [[ $# = 0 ]]; then
- normalChrono
+ chronoFunc
fi
for var in "$@"; do
- case "$var" in
- "-j" | "--json" ) outputJSON;;
- "-h" | "--help" ) displayHelp;;
- * ) exit 1;;
- esac
+ case "$var" in
+ "-j" | "--json" ) jsonFunc;;
+ "-h" | "--help" ) helpFunc;;
+ "-r" | "--refresh" ) chronoFunc "$2";;
+ "-e" | "--exit" ) chronoFunc "exit";;
+ * ) helpFunc "?";;
+ esac
done
diff --git a/advanced/Scripts/list.sh b/advanced/Scripts/list.sh
index 537ebac3..308e1f5e 100755
--- a/advanced/Scripts/list.sh
+++ b/advanced/Scripts/list.sh
@@ -3,14 +3,12 @@
# (c) 2017 Pi-hole, LLC (https://pi-hole.net)
# Network-wide ad blocking via your own hardware.
#
-# Whitelists and blacklists domains
+# Whitelist and blacklist domains
#
# This file is copyright under the latest version of the EUPL.
# Please see LICENSE file for your rights under this license.
-
-
-#globals
+# Globals
basename=pihole
piholeDir=/etc/${basename}
whitelist=${piholeDir}/whitelist.txt
@@ -27,122 +25,118 @@ listMain=""
listAlt=""
helpFunc() {
+ if [[ "${listMain}" == "${whitelist}" ]]; then
+ param="w"
+ type="white"
+ elif [[ "${listMain}" == "${wildcardlist}" ]]; then
+ param="wild"
+ type="wildcard black"
+ else
+ param="b"
+ type="black"
+ fi
- if [[ ${listMain} == ${whitelist} ]]; then
- letter="w"
- word="white"
- else
- letter="b"
- word="black"
- fi
+ echo "Usage: pihole -${param} [options]
+Example: 'pihole -${param} site.com', or 'pihole -${param} site1.com site2.com'
+${type^}list one or more domains
- cat << EOM
-::: Immediately ${word}lists one or more domains in the hosts file
-:::
-::: Usage: pihole -${letter} domain1 [domain2 ...]
-:::
-::: Options:
-::: -d, --delmode Remove domains from the ${word}list
-::: -nr, --noreload Update ${word}list without refreshing dnsmasq
-::: -q, --quiet Output is less verbose
-::: -h, --help Show this help dialog
-::: -l, --list Display your ${word}listed domains
-EOM
-if [[ "${letter}" == "b" ]]; then
- echo "::: -wild, --wildcard Add wildcard entry (only blacklist)"
-fi
- exit 0
+Options:
+ -d, --delmode Remove domain(s) from the ${type}list
+ -nr, --noreload Update ${type}list without refreshing dnsmasq
+ -q, --quiet Make output less verbose
+ -h, --help Show this help dialog
+ -l, --list Display all your ${type}listed domains"
+
+ exit 0
}
EscapeRegexp() {
- # This way we may safely insert an arbitrary
- # string in our regular expressions
- # Also remove leading "." if present
- echo $* | sed 's/^\.*//' | sed "s/[]\.|$(){}?+*^]/\\\\&/g" | sed "s/\\//\\\\\//g"
+ # This way we may safely insert an arbitrary
+ # string in our regular expressions
+ # Also remove leading "." if present
+ echo $* | sed 's/^\.*//' | sed "s/[]\.|$(){}?+*^]/\\\\&/g" | sed "s/\\//\\\\\//g"
}
-HandleOther(){
- # First, convert everything to lowercase
- domain=$(sed -e "y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/" <<< "$1")
+HandleOther() {
+ # First, convert everything to lowercase
+ domain=$(sed -e "y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/" <<< "$1")
- #check validity of domain
- validDomain=$(echo "${domain}" | perl -lne 'print if /(?!.*[^a-z0-9-\.].*)^((?=[a-z0-9-]{1,63}\.)(xn--)?[a-z0-9-]+\.)*[a-z]{2,63}/')
- if [ -z "${validDomain}" ]; then
- echo "::: $1 is not a valid argument or domain name"
- else
- domList=("${domList[@]}" ${validDomain})
- fi
+ # Check validity of domain
+ validDomain=$(echo "${domain}" | perl -lne 'print if /(?!.*[^a-z0-9-\.].*)^((?=[a-z0-9-]{1,63}\.)(xn--)?[a-z0-9-]+\.)*[a-z]{2,63}/')
+ if [[ -z "${validDomain}" ]]; then
+ echo "::: $1 is not a valid argument or domain name"
+ else
+ domList=("${domList[@]}" ${validDomain})
+ fi
}
PoplistFile() {
- #check whitelist file exists, and if not, create it
- if [[ ! -f ${whitelist} ]]; then
- touch ${whitelist}
- fi
- for dom in "${domList[@]}"; do
- # Logic : If addmode then add to desired list and remove from the other; if delmode then remove from desired list but do not add to the other
- if ${addmode}; then
- AddDomain "${dom}" "${listMain}"
- RemoveDomain "${dom}" "${listAlt}"
- if [[ "${listMain}" == "${whitelist}" || "${listMain}" == "${blacklist}" ]]; then
- RemoveDomain "${dom}" "${wildcardlist}"
- fi
- else
- RemoveDomain "${dom}" "${listMain}"
- fi
- done
+ # Check whitelist file exists, and if not, create it
+ if [[ ! -f ${whitelist} ]]; then
+ touch ${whitelist}
+ fi
+
+ for dom in "${domList[@]}"; do
+ # Logic: If addmode then add to desired list and remove from the other; if delmode then remove from desired list but do not add to the other
+ if ${addmode}; then
+ AddDomain "${dom}" "${listMain}"
+ RemoveDomain "${dom}" "${listAlt}"
+ if [[ "${listMain}" == "${whitelist}" || "${listMain}" == "${blacklist}" ]]; then
+ RemoveDomain "${dom}" "${wildcardlist}"
+ fi
+ else
+ RemoveDomain "${dom}" "${listMain}"
+ fi
+ done
}
AddDomain() {
- list="$2"
- domain=$(EscapeRegexp "$1")
+ list="$2"
+ domain=$(EscapeRegexp "$1")
- if [[ "${list}" == "${whitelist}" || "${list}" == "${blacklist}" ]]; then
+ if [[ "${list}" == "${whitelist}" || "${list}" == "${blacklist}" ]]; then
+ bool=true
+ # Is the domain in the list we want to add it to?
+ grep -Ex -q "${domain}" "${list}" > /dev/null 2>&1 || bool=false
- bool=true
- #Is the domain in the list we want to add it to?
- grep -Ex -q "${domain}" "${list}" > /dev/null 2>&1 || bool=false
+ if [[ "${bool}" == false ]]; then
+ # Domain not found in the whitelist file, add it!
+ if [[ "${verbose}" == true ]]; then
+ echo "::: Adding $1 to $list..."
+ fi
+ reload=true
+ # Add it to the list we want to add it to
+ echo "$1" >> "${list}"
+ else
+ if [[ "${verbose}" == true ]]; then
+ echo "::: ${1} already exists in ${list}, no need to add!"
+ fi
+ fi
+ elif [[ "${list}" == "${wildcardlist}" ]]; then
+ source "${piholeDir}/setupVars.conf"
+ # Remove the /* from the end of the IPv4addr.
+ IPV4_ADDRESS=${IPV4_ADDRESS%/*}
+ IPV6_ADDRESS=${IPV6_ADDRESS}
- if [[ "${bool}" == false ]]; then
- #domain not found in the whitelist file, add it!
- if [[ "${verbose}" == true ]]; then
- echo "::: Adding $1 to $list..."
- fi
- reload=true
- # Add it to the list we want to add it to
- echo "$1" >> "${list}"
- else
- if [[ "${verbose}" == true ]]; then
- echo "::: ${1} already exists in ${list}, no need to add!"
- fi
- fi
+ bool=true
+ # Is the domain in the list?
+ grep -e "address=\/${domain}\/" "${wildcardlist}" > /dev/null 2>&1 || bool=false
- elif [[ "${list}" == "${wildcardlist}" ]]; then
-
- source "${piholeDir}/setupVars.conf"
- #Remove the /* from the end of the IPv4addr.
- IPV4_ADDRESS=${IPV4_ADDRESS%/*}
- IPV6_ADDRESS=${IPV6_ADDRESS}
-
- bool=true
- #Is the domain in the list?
- grep -e "address=\/${domain}\/" "${wildcardlist}" > /dev/null 2>&1 || bool=false
-
- if [[ "${bool}" == false ]]; then
- if [[ "${verbose}" == true ]]; then
- echo "::: Adding $1 to wildcard blacklist..."
- fi
- reload=true
- echo "address=/$1/${IPV4_ADDRESS}" >> "${wildcardlist}"
- if [[ ${#IPV6_ADDRESS} > 0 ]] ; then
- echo "address=/$1/${IPV6_ADDRESS}" >> "${wildcardlist}"
- fi
- else
- if [[ "${verbose}" == true ]]; then
- echo "::: ${1} already exists in wildcard blacklist, no need to add!"
- fi
- fi
- fi
+ if [[ "${bool}" == false ]]; then
+ if [[ "${verbose}" == true ]]; then
+ echo "::: Adding $1 to wildcard blacklist..."
+ fi
+ reload=true
+ echo "address=/$1/${IPV4_ADDRESS}" >> "${wildcardlist}"
+ if [[ "${#IPV6_ADDRESS}" > 0 ]]; then
+ echo "address=/$1/${IPV6_ADDRESS}" >> "${wildcardlist}"
+ fi
+ else
+ if [[ "${verbose}" == true ]]; then
+ echo "::: ${1} already exists in wildcard blacklist, no need to add!"
+ fi
+ fi
+ fi
}
RemoveDomain() {
@@ -150,85 +144,82 @@ RemoveDomain() {
domain=$(EscapeRegexp "$1")
if [[ "${list}" == "${whitelist}" || "${list}" == "${blacklist}" ]]; then
-
- bool=true
- #Is it in the list? Logic follows that if its whitelisted it should not be blacklisted and vice versa
- grep -Ex -q "${domain}" "${list}" > /dev/null 2>&1 || bool=false
- if [[ "${bool}" == true ]]; then
- # Remove it from the other one
- echo "::: Removing $1 from $list..."
- # /I flag: search case-insensitive
- sed -i "/${domain}/Id" "${list}"
- reload=true
- else
- if [[ "${verbose}" == true ]]; then
- echo "::: ${1} does not exist in ${list}, no need to remove!"
- fi
+ bool=true
+ # Is it in the list? Logic follows that if its whitelisted it should not be blacklisted and vice versa
+ grep -Ex -q "${domain}" "${list}" > /dev/null 2>&1 || bool=false
+ if [[ "${bool}" == true ]]; then
+ # Remove it from the other one
+ echo "::: Removing $1 from $list..."
+ # /I flag: search case-insensitive
+ sed -i "/${domain}/Id" "${list}"
+ reload=true
+ else
+ if [[ "${verbose}" == true ]]; then
+ echo "::: ${1} does not exist in ${list}, no need to remove!"
fi
-
+ fi
elif [[ "${list}" == "${wildcardlist}" ]]; then
-
- bool=true
- #Is it in the list?
- grep -e "address=\/${domain}\/" "${wildcardlist}" > /dev/null 2>&1 || bool=false
- if [[ "${bool}" == true ]]; then
- # Remove it from the other one
- echo "::: Removing $1 from $list..."
- # /I flag: search case-insensitive
- sed -i "/address=\/${domain}/Id" "${list}"
- reload=true
- else
- if [[ "${verbose}" == true ]]; then
- echo "::: ${1} does not exist in ${list}, no need to remove!"
- fi
+ bool=true
+ # Is it in the list?
+ grep -e "address=\/${domain}\/" "${wildcardlist}" > /dev/null 2>&1 || bool=false
+ if [[ "${bool}" == true ]]; then
+ # Remove it from the other one
+ echo "::: Removing $1 from $list..."
+ # /I flag: search case-insensitive
+ sed -i "/address=\/${domain}/Id" "${list}"
+ reload=true
+ else
+ if [[ "${verbose}" == true ]]; then
+ echo "::: ${1} does not exist in ${list}, no need to remove!"
fi
+ fi
fi
}
Reload() {
- # Reload hosts file
- pihole -g -sd
+ # Reload hosts file
+ pihole -g -sd
}
Displaylist() {
- if [[ ${listMain} == ${whitelist} ]]; then
- string="gravity resistant domains"
- else
- string="domains caught in the sinkhole"
- fi
- verbose=false
- echo -e " Displaying $string \n"
- count=1
- while IFS= read -r RD; do
- echo "${count}: ${RD}"
- count=$((count+1))
- done < "${listMain}"
- exit 0;
+ if [[ "${listMain}" == "${whitelist}" ]]; then
+ string="gravity resistant domains"
+ else
+ string="domains caught in the sinkhole"
+ fi
+ verbose=false
+ echo -e "Displaying $string:\n"
+ count=1
+ while IFS= read -r RD; do
+ echo "${count}: ${RD}"
+ count=$((count+1))
+ done < "${listMain}"
+ exit 0;
}
for var in "$@"; do
- case "${var}" in
- "-w" | "whitelist" ) listMain="${whitelist}"; listAlt="${blacklist}";;
- "-b" | "blacklist" ) listMain="${blacklist}"; listAlt="${whitelist}";;
- "-wild" | "wildcard" ) listMain="${wildcardlist}";;
- "-nr"| "--noreload" ) reload=false;;
- "-d" | "--delmode" ) addmode=false;;
- "-f" | "--force" ) force=true;;
- "-q" | "--quiet" ) verbose=false;;
- "-h" | "--help" ) helpFunc;;
- "-l" | "--list" ) Displaylist;;
- * ) HandleOther "${var}";;
- esac
+ case "${var}" in
+ "-w" | "whitelist" ) listMain="${whitelist}"; listAlt="${blacklist}";;
+ "-b" | "blacklist" ) listMain="${blacklist}"; listAlt="${whitelist}";;
+ "-wild" | "wildcard" ) listMain="${wildcardlist}";;
+ "-nr"| "--noreload" ) reload=false;;
+ "-d" | "--delmode" ) addmode=false;;
+ "-f" | "--force" ) force=true;;
+ "-q" | "--quiet" ) verbose=false;;
+ "-h" | "--help" ) helpFunc;;
+ "-l" | "--list" ) Displaylist;;
+ * ) HandleOther "${var}";;
+ esac
done
shift
if [[ $# = 0 ]]; then
- helpFunc
+ helpFunc
fi
PoplistFile
if ${reload}; then
- Reload
+ Reload
fi
diff --git a/advanced/Scripts/piholeCheckout.sh b/advanced/Scripts/piholeCheckout.sh
index 09f20d6b..e2c0ab11 100644
--- a/advanced/Scripts/piholeCheckout.sh
+++ b/advanced/Scripts/piholeCheckout.sh
@@ -3,7 +3,7 @@
# (c) 2017 Pi-hole, LLC (https://pi-hole.net)
# Network-wide ad blocking via your own hardware.
#
-# Checkout other branches than master
+# Switch Pi-hole subsystems to a different Github branch
#
# This file is copyright under the latest version of the EUPL.
# Please see LICENSE file for your rights under this license.
@@ -18,9 +18,12 @@ PH_TEST="true" source "${PI_HOLE_FILES_DIR}/automated install/basic-install.sh"
# setupVars set in basic-install.sh
source "${setupVars}"
-
update="false"
+# Colour codes
+red="\e[1;31m"
+def="\e[0m"
+
fully_fetch_repo() {
# Add upstream branches to shallow clone
local directory="${1}"
@@ -35,7 +38,7 @@ fully_fetch_repo() {
return 0
}
-get_available_branches(){
+get_available_branches() {
# Return available branches
local directory="${1}"
@@ -54,6 +57,8 @@ fetch_checkout_pull_branch() {
# Set the reference for the requested branch, fetch, check it put and pull it
cd "${directory}"
git remote set-branches origin "${branch}" || return 1
+ git stash --all --quiet &> /dev/null || true
+ git clean --force -d || true
git fetch --quiet || return 1
checkout_pull_branch "${directory}" "${branch}" || return 1
}
@@ -79,23 +84,23 @@ checkout_pull_branch() {
}
warning1() {
- echo "::: Note that changing the branch is a severe change of your Pi-hole system."
- echo "::: This is not supported unless one of the developers explicitly asks you to do this!"
- read -r -p "::: Have you read and understood this? [y/N] " response
+ echo " Please note that changing branches severely alters your Pi-hole subsystems"
+ echo " Features that work on the master branch, may not on a development branch"
+ echo -e " ${red}This feature is NOT supported unless a Pi-hole developer explicitly asks!${def}"
+ read -r -p " Have you read and understood this? [y/N] " response
case ${response} in
[yY][eE][sS]|[yY])
- echo "::: Continuing."
+ echo "::: Continuing with branch change."
return 0
;;
*)
- echo "::: Aborting."
+ echo "::: Branch change has been cancelled."
return 1
;;
esac
}
-checkout()
-{
+checkout() {
local corebranches
local webbranches
@@ -192,11 +197,10 @@ checkout()
if [[ ! "${1}" == "web" && "${update}" == "true" ]]; then
echo "::: Running installer to upgrade your installation"
if "${PI_HOLE_FILES_DIR}/automated install/basic-install.sh" --unattended; then
- exit 0
+ exit 0
else
- echo "Unable to complete update, contact Pi-hole"
- exit 1
+ echo "Unable to complete update, contact Pi-hole"
+ exit 1
fi
fi
}
-
diff --git a/advanced/Scripts/piholeDebug.sh b/advanced/Scripts/piholeDebug.sh
index 10dd1e8b..8020cc80 100755
--- a/advanced/Scripts/piholeDebug.sh
+++ b/advanced/Scripts/piholeDebug.sh
@@ -260,18 +260,18 @@ ip_ping_check() {
if [[ -n ${ip_def_gateway} ]]; then
echo -n "::: Pinging default IPv${protocol} gateway: "
if ! ping_gateway="$(${cmd} -q -W 3 -c 3 -n ${ip_def_gateway} -I ${PIHOLE_INTERFACE} | tail -n 3)"; then
- echo "Gateway did not respond."
+ log_echo "Gateway did not respond."
return 1
else
- echo "Gateway responded."
+ log_echo "Gateway responded."
log_write "${ping_gateway}"
fi
echo -n "::: Pinging Internet via IPv${protocol}: "
if ! ping_inet="$(${cmd} -q -W 3 -c 3 -n ${g_addr} -I ${PIHOLE_INTERFACE} | tail -n 3)"; then
- echo "Query did not respond."
+ log_echo "Query did not respond."
return 1
else
- echo "Query responded."
+ log_echo "Query responded."
log_write "${ping_inet}"
fi
else
diff --git a/advanced/Scripts/piholeLogFlush.sh b/advanced/Scripts/piholeLogFlush.sh
index fd66b255..cc553b32 100755
--- a/advanced/Scripts/piholeLogFlush.sh
+++ b/advanced/Scripts/piholeLogFlush.sh
@@ -8,17 +8,38 @@
# This file is copyright under the latest version of the EUPL.
# Please see LICENSE file for your rights under this license.
-echo -n "::: Flushing /var/log/pihole.log ..."
-# Test if logrotate is available on this system
-if command -v /usr/sbin/logrotate &> /dev/null; then
- # Flush twice to move all data out of sight of FTL
- /usr/sbin/logrotate --force /etc/pihole/logrotate
- /usr/sbin/logrotate --force /etc/pihole/logrotate
+if [[ "$@" != *"quiet"* ]]; then
+ echo -n "::: Flushing /var/log/pihole.log ..."
+fi
+if [[ "$@" == *"once"* ]]; then
+ # Nightly logrotation
+ if command -v /usr/sbin/logrotate >/dev/null; then
+ # Logrotate once
+ /usr/sbin/logrotate --force /etc/pihole/logrotate
+ else
+ # Copy pihole.log over to pihole.log.1
+ # and empty out pihole.log
+ # Note that moving the file is not an option, as
+ # dnsmasq would happily continue writing into the
+ # moved file (it will have the same file handler)
+ cp /var/log/pihole.log /var/log/pihole.log.1
+ echo " " > /var/log/pihole.log
+ fi
else
- # Flush both pihole.log and pihole.log.1 (if existing)
- echo " " > /var/log/pihole.log
- if [ -f /var/log/pihole.log.1 ]; then
- echo " " > /var/log/pihole.log.1
+ # Manual flushing
+ if command -v /usr/sbin/logrotate >/dev/null; then
+ # Logrotate twice to move all data out of sight of FTL
+ /usr/sbin/logrotate --force /etc/pihole/logrotate; sleep 3
+ /usr/sbin/logrotate --force /etc/pihole/logrotate
+ else
+ # Flush both pihole.log and pihole.log.1 (if existing)
+ echo " " > /var/log/pihole.log
+ if [ -f /var/log/pihole.log.1 ]; then
+ echo " " > /var/log/pihole.log.1
+ fi
fi
fi
-echo "... done!"
+
+if [[ "$@" != *"quiet"* ]]; then
+ echo "... done!"
+fi
diff --git a/advanced/Scripts/update.sh b/advanced/Scripts/update.sh
index 4fceb931..6aef183b 100755
--- a/advanced/Scripts/update.sh
+++ b/advanced/Scripts/update.sh
@@ -117,7 +117,10 @@ main() {
echo "::: FTL: up to date"
fi
- if ${FTL_update}; then
+ # Logic: Don't update FTL when there is a core update available
+ # since the core update will run the installer which will itself
+ # re-install (i.e. update) FTL
+ if ${FTL_update} && ! ${core_update}; then
echo ":::"
echo "::: FTL out of date"
FTLdetect
@@ -194,21 +197,21 @@ main() {
if [[ "${web_update}" == true ]]; then
web_version_current="$(/usr/local/bin/pihole version --admin --current)"
echo ":::"
- echo "::: Web Admin version is now at ${web_version_current}"
+ echo "::: Web Admin version is now at ${web_version_current/* v/v}}"
echo "::: If you had made any changes in '/var/www/html/admin/', they have been stashed using 'git stash'"
fi
if [[ "${core_update}" == true ]]; then
pihole_version_current="$(/usr/local/bin/pihole version --pihole --current)"
echo ":::"
- echo "::: Pi-hole version is now at ${pihole_version_current}"
+ echo "::: Pi-hole version is now at ${pihole_version_current/* v/v}}"
echo "::: If you had made any changes in '/etc/.pihole/', they have been stashed using 'git stash'"
fi
if [[ ${FTL_update} == true ]]; then
- FTL_version_current="$(/usr/bin/pihole-FTL tag)"
+ FTL_version_current="$(/usr/local/bin/pihole version --ftl --current)"
echo ":::"
- echo "::: FTL version is now at ${FTL_version_current}"
+ echo "::: FTL version is now at ${FTL_version_current/* v/v}}"
start_service pihole-FTL
enable_service pihole-FTL
fi
diff --git a/advanced/Scripts/version.sh b/advanced/Scripts/version.sh
index 7f96e29a..f5e0f51d 100755
--- a/advanced/Scripts/version.sh
+++ b/advanced/Scripts/version.sh
@@ -3,24 +3,29 @@
# (c) 2017 Pi-hole, LLC (https://pi-hole.net)
# Network-wide ad blocking via your own hardware.
#
-# shows version numbers
+# Show version numbers
#
# This file is copyright under the latest version of the EUPL.
# Please see LICENSE file for your rights under this license.
# Variables
DEFAULT="-1"
-PHGITDIR="/etc/.pihole/"
+COREGITDIR="/etc/.pihole/"
WEBGITDIR="/var/www/html/admin/"
getLocalVersion() {
+ # FTL requires a different method
+ if [[ "$1" == "FTL" ]]; then
+ pihole-FTL version
+ return 0
+ fi
+
# Get the tagged version of the local repository
local directory="${1}"
local version
- cd "${directory}" || { echo "${DEFAULT}"; return 1; }
- version=$(git describe --tags --always || \
- echo "${DEFAULT}")
+ cd "${directory}" 2> /dev/null || { echo "${DEFAULT}"; return 1; }
+ version=$(git describe --tags --always || echo "$DEFAULT")
if [[ "${version}" =~ ^v ]]; then
echo "${version}"
elif [[ "${version}" == "${DEFAULT}" ]]; then
@@ -33,13 +38,18 @@ getLocalVersion() {
}
getLocalHash() {
+ # Local FTL hash does not exist on filesystem
+ if [[ "$1" == "FTL" ]]; then
+ echo "N/A"
+ return 0
+ fi
+
# Get the short hash of the local repository
local directory="${1}"
local hash
- cd "${directory}" || { echo "${DEFAULT}"; return 1; }
- hash=$(git rev-parse --short HEAD || \
- echo "${DEFAULT}")
+ cd "${directory}" 2> /dev/null || { echo "${DEFAULT}"; return 1; }
+ hash=$(git rev-parse --short HEAD || echo "$DEFAULT")
if [[ "${hash}" == "${DEFAULT}" ]]; then
echo "ERROR"
return 1
@@ -49,12 +59,33 @@ getLocalHash() {
return 0
}
+getRemoteHash(){
+ # Remote FTL hash is not applicable
+ if [[ "$1" == "FTL" ]]; then
+ echo "N/A"
+ return 0
+ fi
+
+ local daemon="${1}"
+ local branch="${2}"
+
+ hash=$(git ls-remote --heads "https://github.com/pi-hole/${daemon}" | \
+ awk -v bra="$branch" '$0~bra {print substr($0,0,8);exit}')
+ if [[ -n "$hash" ]]; then
+ echo "$hash"
+ else
+ echo "ERROR"
+ return 1
+ fi
+ return 0
+}
+
getRemoteVersion(){
# Get the version from the remote origin
local daemon="${1}"
local version
- version=$(curl --silent --fail https://api.github.com/repos/pi-hole/${daemon}/releases/latest | \
+ version=$(curl --silent --fail "https://api.github.com/repos/pi-hole/${daemon}/releases/latest" | \
awk -F: '$1 ~/tag_name/ { print $2 }' | \
tr -cd '[[:alnum:]]._-')
if [[ "${version}" =~ ^v ]]; then
@@ -66,72 +97,72 @@ getRemoteVersion(){
return 0
}
-#PHHASHLATEST=$(curl -s https://api.github.com/repos/pi-hole/pi-hole/commits/master | \
-# grep sha | \
-# head -n1 | \
-# awk -F ' ' '{ print $2 }' | \
-# tr -cd '[[:alnum:]]._-')
-
-#WEBHASHLATEST=$(curl -s https://api.github.com/repos/pi-hole/AdminLTE/commits/master | \
-# grep sha | \
-# head -n1 | \
-# awk -F ' ' '{ print $2 }' | \
-# tr -cd '[[:alnum:]]._-')
-
-
-normalOutput() {
- echo "::: Pi-hole version is $(getLocalVersion "${PHGITDIR}") (Latest version is $(getRemoteVersion pi-hole))"
- if [ -d "${WEBGITDIR}" ]; then
- echo "::: Web-Admin version is $(getLocalVersion "${WEBGITDIR}") (Latest version is $(getRemoteVersion AdminLTE))"
- fi
-}
-
-webOutput() {
- if [ -d "${WEBGITDIR}" ]; then
- case "${1}" in
- "-l" | "--latest" ) echo $(getRemoteVersion AdminLTE);;
- "-c" | "--current" ) echo $(getLocalVersion "${WEBGITDIR}");;
- "-h" | "--hash" ) echo $(getLocalHash "${WEBGITDIR}");;
- * ) echo "::: Invalid Option!"; exit 1;
- esac
- else
- echo "::: Web interface not installed!"; exit 1;
+versionOutput() {
+ [[ "$1" == "pi-hole" ]] && GITDIR=$COREGITDIR
+ [[ "$1" == "AdminLTE" ]] && GITDIR=$WEBGITDIR
+ [[ "$1" == "FTL" ]] && GITDIR="FTL"
+
+ [[ "$2" == "-c" ]] || [[ "$2" == "--current" ]] || [[ -z "$2" ]] && current=$(getLocalVersion $GITDIR)
+ [[ "$2" == "-l" ]] || [[ "$2" == "--latest" ]] || [[ -z "$2" ]] && latest=$(getRemoteVersion "$1")
+ if [[ "$2" == "-h" ]] || [[ "$2" == "--hash" ]]; then
+ [[ "$3" == "-c" ]] || [[ "$3" == "--current" ]] || [[ -z "$3" ]] && curHash=$(getLocalHash "$GITDIR")
+ [[ "$3" == "-l" ]] || [[ "$3" == "--latest" ]] || [[ -z "$3" ]] && latHash=$(getRemoteHash "$1" "$(cd "$GITDIR" 2> /dev/null && git rev-parse --abbrev-ref HEAD)")
fi
+
+ if [[ -n "$current" ]] && [[ -n "$latest" ]]; then
+ output="${1^} version is $current (Latest: $latest)"
+ elif [[ -n "$current" ]] && [[ -z "$latest" ]]; then
+ output="Current ${1^} version is $current"
+ elif [[ -z "$current" ]] && [[ -n "$latest" ]]; then
+ output="Latest ${1^} version is $latest"
+ elif [[ "$curHash" == "N/A" ]] || [[ "$latHash" == "N/A" ]]; then
+ output="${1^} hash is not applicable"
+ elif [[ -n "$curHash" ]] && [[ -n "$latHash" ]]; then
+ output="${1^} hash is $curHash (Latest: $latHash)"
+ elif [[ -n "$curHash" ]] && [[ -z "$latHash" ]]; then
+ output="Current ${1^} hash is $curHash"
+ elif [[ -z "$curHash" ]] && [[ -n "$latHash" ]]; then
+ output="Latest ${1^} hash is $latHash"
+ else
+ errorOutput
+ fi
+
+ [[ -n "$output" ]] && echo " $output"
}
-coreOutput() {
- case "${1}" in
- "-l" | "--latest" ) echo $(getRemoteVersion pi-hole);;
- "-c" | "--current" ) echo $(getLocalVersion "${PHGITDIR}");;
- "-h" | "--hash" ) echo $(getLocalHash "${PHGITDIR}");;
- * ) echo "::: Invalid Option!"; exit 1;
- esac
+errorOutput() {
+ echo " Invalid Option! Try 'pihole -v --help' for more information."
+ exit 1
+}
+
+defaultOutput() {
+ versionOutput "pi-hole" "$@"
+ versionOutput "AdminLTE" "$@"
+ versionOutput "FTL" "$@"
}
helpFunc() {
- cat << EOM
-:::
-::: Show Pi-hole/Web Admin versions
-:::
-::: Usage: pihole -v [ -a | -p ] [ -l | -c ]
-:::
-::: Options:
-::: -a, --admin Show both current and latest versions of web admin
-::: -p, --pihole Show both current and latest versions of Pi-hole core files
-::: -l, --latest (Only after -a | -p) Return only latest version
-::: -c, --current (Only after -a | -p) Return only current version
-::: -h, --help Show this help dialog
-:::
-EOM
- exit 0
+ echo "Usage: pihole -v [repo | option] [option]
+Example: 'pihole -v -p -l'
+Show Pi-hole, Admin Console & FTL versions
+
+Repositories:
+ -p, --pihole Only retrieve info regarding Pi-hole repository
+ -a, --admin Only retrieve info regarding AdminLTE repository
+ -f, --ftl Only retrieve info regarding FTL repository
+
+Options:
+ -c, --current Return the current version
+ -l, --latest Return the latest version
+ --hash Return the Github hash from your local repositories
+ -h, --help Show this help dialog"
+ exit 0
}
-if [[ $# = 0 ]]; then
- normalOutput
-fi
-
case "${1}" in
- "-a" | "--admin" ) shift; webOutput "$@";;
- "-p" | "--pihole" ) shift; coreOutput "$@" ;;
+ "-p" | "--pihole" ) shift; versionOutput "pi-hole" "$@";;
+ "-a" | "--admin" ) shift; versionOutput "AdminLTE" "$@";;
+ "-f" | "--ftl" ) shift; versionOutput "FTL" "$@";;
"-h" | "--help" ) helpFunc;;
+ * ) defaultOutput "$@";;
esac
diff --git a/advanced/Scripts/webpage.sh b/advanced/Scripts/webpage.sh
index d3ad3032..8419aa8d 100755
--- a/advanced/Scripts/webpage.sh
+++ b/advanced/Scripts/webpage.sh
@@ -8,7 +8,6 @@
# This file is copyright under the latest version of the EUPL.
# Please see LICENSE file for your rights under this license.
-
readonly setupVars="/etc/pihole/setupVars.conf"
readonly dnsmasqconfig="/etc/dnsmasq.d/01-pihole.conf"
readonly dhcpconfig="/etc/dnsmasq.d/02-pihole-dhcp.conf"
@@ -16,23 +15,19 @@ readonly dhcpconfig="/etc/dnsmasq.d/02-pihole-dhcp.conf"
readonly dhcpstaticconfig="/etc/dnsmasq.d/04-pihole-static-dhcp.conf"
helpFunc() {
- cat << EOM
-::: Set admin options for the web interface of pihole
-:::
-::: Usage: pihole -a [options]
-:::
-::: Options:
-::: -p, password Set web interface password, an empty input will remove any previously set password
-::: -c, celsius Set Celsius temperature unit
-::: -f, fahrenheit Set Fahrenheit temperature unit
-::: -k, kelvin Set Kelvin temperature unit
-::: -h, --help Show this help dialog
-::: -i, interface Setup interface listening behavior of dnsmasq
-::: pihole -a -i local : Listen on all interfaces, but allow only queries from
-::: devices that are at most one hop away (local devices)
-::: pihole -a -i single : Listen only on one interface (see PIHOLE_INTERFACE)
-::: pihole -a -i all : Listen on all interfaces, permit all origins
-EOM
+ echo "Usage: pihole -a [options]
+Example: pihole -a -p password
+Set options for the Admin Console
+
+Options:
+ -f, flush Flush the Pi-hole log
+ -p, password Set Admin Console password
+ -c, celsius Set Celsius as preferred temperature unit
+ -f, fahrenheit Set Fahrenheit as preferred temperature unit
+ -k, kelvin Set Kelvin as preferred temperature unit
+ -h, --help Show this help dialog
+ -i, interface Specify dnsmasq's interface listening behavior
+ Add '-h' for more info on interface usage"
exit 0
}
@@ -61,21 +56,18 @@ delete_dnsmasq_setting() {
sed -i "/${1}/d" "${dnsmasqconfig}"
}
-SetTemperatureUnit(){
-
+SetTemperatureUnit() {
change_setting "TEMPERATUREUNIT" "${unit}"
-
}
-HashPassword(){
- # Compute password hash twice to avoid rainbow table vulnerability
- return=$(echo -n ${1} | sha256sum | sed 's/\s.*$//')
- return=$(echo -n ${return} | sha256sum | sed 's/\s.*$//')
- echo ${return}
+HashPassword() {
+ # Compute password hash twice to avoid rainbow table vulnerability
+ return=$(echo -n ${1} | sha256sum | sed 's/\s.*$//')
+ return=$(echo -n ${return} | sha256sum | sed 's/\s.*$//')
+ echo ${return}
}
-SetWebPassword(){
-
+SetWebPassword() {
if [ "${SUDO_USER}" == "www-data" ]; then
echo "Security measure: user www-data is not allowed to change webUI password!"
echo "Exiting"
@@ -175,8 +167,7 @@ trust-anchor=.,19036,8,2,49AAC11D7B6F6446702E54A1607371607A1A41855200FD2CE1CDDE3
}
-SetDNSServers(){
-
+SetDNSServers() {
# Save setting to file
delete_setting "PIHOLE_DNS"
IFS=',' read -r -a array <<< "${args[2]}"
@@ -207,72 +198,59 @@ SetDNSServers(){
# Restart dnsmasq to load new configuration
RestartDNS
-
}
-SetExcludeDomains(){
-
+SetExcludeDomains() {
change_setting "API_EXCLUDE_DOMAINS" "${args[2]}"
-
}
-SetExcludeClients(){
-
+SetExcludeClients() {
change_setting "API_EXCLUDE_CLIENTS" "${args[2]}"
-
}
-Reboot(){
-
+Reboot() {
nohup bash -c "sleep 5; reboot" &> /dev/null /dev/null
else
service dnsmasq restart &> /dev/null
fi
-
}
-SetQueryLogOptions(){
-
+SetQueryLogOptions() {
change_setting "API_QUERY_LOG_SHOW" "${args[2]}"
-
}
ProcessDHCPSettings() {
-
source "${setupVars}"
if [[ "${DHCP_ACTIVE}" == "true" ]]; then
+ interface=$(grep 'PIHOLE_INTERFACE=' /etc/pihole/setupVars.conf | sed "s/.*=//")
- interface=$(grep 'PIHOLE_INTERFACE=' /etc/pihole/setupVars.conf | sed "s/.*=//")
+ # Use eth0 as fallback interface
+ if [ -z ${interface} ]; then
+ interface="eth0"
+ fi
- # Use eth0 as fallback interface
- if [ -z ${interface} ]; then
- interface="eth0"
- fi
+ if [[ "${PIHOLE_DOMAIN}" == "" ]]; then
+ PIHOLE_DOMAIN="local"
+ change_setting "PIHOLE_DOMAIN" "${PIHOLE_DOMAIN}"
+ fi
- if [[ "${PIHOLE_DOMAIN}" == "" ]]; then
- PIHOLE_DOMAIN="local"
- change_setting "PIHOLE_DOMAIN" "${PIHOLE_DOMAIN}"
- fi
+ if [[ "${DHCP_LEASETIME}" == "0" ]]; then
+ leasetime="infinite"
+ elif [[ "${DHCP_LEASETIME}" == "" ]]; then
+ leasetime="24h"
+ change_setting "DHCP_LEASETIME" "${leasetime}"
+ else
+ leasetime="${DHCP_LEASETIME}h"
+ fi
- if [[ "${DHCP_LEASETIME}" == "0" ]]; then
- leasetime="infinite"
- elif [[ "${DHCP_LEASETIME}" == "" ]]; then
- leasetime="24h"
- change_setting "DHCP_LEASETIME" "${leasetime}"
- else
- leasetime="${DHCP_LEASETIME}h"
- fi
-
- # Write settings to file
- echo "###############################################################################
+ # Write settings to file
+ echo "###############################################################################
# DHCP SERVER CONFIG FILE AUTOMATICALLY POPULATED BY PI-HOLE WEB INTERFACE. #
# ANY CHANGES MADE TO THIS FILE WILL BE LOST ON CHANGE #
###############################################################################
@@ -283,26 +261,25 @@ dhcp-leasefile=/etc/pihole/dhcp.leases
#quiet-dhcp
" > "${dhcpconfig}"
-if [[ "${PIHOLE_DOMAIN}" != "none" ]]; then
- echo "domain=${PIHOLE_DOMAIN}" >> "${dhcpconfig}"
-fi
+ if [[ "${PIHOLE_DOMAIN}" != "none" ]]; then
+ echo "domain=${PIHOLE_DOMAIN}" >> "${dhcpconfig}"
+ fi
- if [[ "${DHCP_IPv6}" == "true" ]]; then
-echo "#quiet-dhcp6
+ if [[ "${DHCP_IPv6}" == "true" ]]; then
+ echo "#quiet-dhcp6
#enable-ra
dhcp-option=option6:dns-server,[::]
dhcp-range=::100,::1ff,constructor:${interface},ra-names,slaac,${leasetime}
ra-param=*,0,0
" >> "${dhcpconfig}"
- fi
+ fi
else
rm "${dhcpconfig}" &> /dev/null
fi
}
-EnableDHCP(){
-
+EnableDHCP() {
change_setting "DHCP_ACTIVE" "true"
change_setting "DHCP_START" "${args[2]}"
change_setting "DHCP_END" "${args[3]}"
@@ -320,8 +297,7 @@ EnableDHCP(){
RestartDNS
}
-DisableDHCP(){
-
+DisableDHCP() {
change_setting "DHCP_ACTIVE" "false"
# Remove possible old setting from file
@@ -333,23 +309,20 @@ DisableDHCP(){
RestartDNS
}
-SetWebUILayout(){
-
+SetWebUILayout() {
change_setting "WEBUIBOXEDLAYOUT" "${args[2]}"
-
}
CustomizeAdLists() {
-
list="/etc/pihole/adlists.list"
- if [[ "${args[2]}" == "enable" ]] ; then
+ if [[ "${args[2]}" == "enable" ]]; then
sed -i "\\@${args[3]}@s/^#http/http/g" "${list}"
- elif [[ "${args[2]}" == "disable" ]] ; then
+ elif [[ "${args[2]}" == "disable" ]]; then
sed -i "\\@${args[3]}@s/^http/#http/g" "${list}"
- elif [[ "${args[2]}" == "add" ]] ; then
+ elif [[ "${args[2]}" == "add" ]]; then
echo "${args[3]}" >> ${list}
- elif [[ "${args[2]}" == "del" ]] ; then
+ elif [[ "${args[2]}" == "del" ]]; then
var=$(echo "${args[3]}" | sed 's/\//\\\//g')
sed -i "/${var}/Id" "${list}"
else
@@ -358,18 +331,15 @@ CustomizeAdLists() {
fi
}
-SetPrivacyMode(){
-
- if [[ "${args[2]}" == "true" ]] ; then
+SetPrivacyMode() {
+ if [[ "${args[2]}" == "true" ]]; then
change_setting "API_PRIVACY_MODE" "true"
else
change_setting "API_PRIVACY_MODE" "false"
fi
-
}
ResolutionSettings() {
-
typ="${args[2]}"
state="${args[3]}"
@@ -378,11 +348,9 @@ ResolutionSettings() {
elif [[ "${typ}" == "clients" ]]; then
change_setting "API_GET_CLIENT_HOSTNAME" "${state}"
fi
-
}
AddDHCPStaticAddress() {
-
mac="${args[2]}"
ip="${args[3]}"
host="${args[4]}"
@@ -397,18 +365,14 @@ AddDHCPStaticAddress() {
# Full info given
echo "dhcp-host=${mac},${ip},${host}" >> "${dhcpstaticconfig}"
fi
-
}
RemoveDHCPStaticAddress() {
-
mac="${args[2]}"
sed -i "/dhcp-host=${mac}.*/d" "${dhcpstaticconfig}"
-
}
-SetHostRecord(){
-
+SetHostRecord() {
if [ -n "${args[3]}" ]; then
change_setting "HOSTRECORD" "${args[2]},${args[3]}"
echo "Setting host record for ${args[2]} -> ${args[3]}"
@@ -421,17 +385,28 @@ SetHostRecord(){
# Restart dnsmasq to load new configuration
RestartDNS
-
}
-SetListeningMode(){
-
+SetListeningMode() {
source "${setupVars}"
+
+ if [[ "$3" == "-h" ]] || [[ "$3" == "--help" ]]; then
+ echo "Usage: pihole -a -i [interface]
+Example: 'pihole -a -i local'
+Specify dnsmasq's network interface listening behavior
- if [[ "${args[2]}" == "all" ]] ; then
+Interfaces:
+ local Listen on all interfaces, but only allow queries from
+ devices that are at most one hop away (local devices)
+ single Listen only on ${PIHOLE_INTERFACE} interface
+ all Listen on all interfaces, permit all origins"
+ exit 0
+ fi
+
+ if [[ "${args[2]}" == "all" ]]; then
echo "Listening on all interfaces, permiting all origins, hope you have a firewall!"
change_setting "DNSMASQ_LISTENING" "all"
- elif [[ "${args[2]}" == "local" ]] ; then
+ elif [[ "${args[2]}" == "local" ]]; then
echo "Listening on all interfaces, permitting only origins that are at most one hop away (local devices)"
change_setting "DNSMASQ_LISTENING" "local"
else
@@ -446,17 +421,14 @@ SetListeningMode(){
# Restart dnsmasq to load new configuration
RestartDNS
fi
-
}
-Teleporter()
-{
+Teleporter() {
local datetimestamp=$(date "+%Y-%m-%d_%H-%M-%S")
php /var/www/html/admin/scripts/pi-hole/php/teleporter.php > "pi-hole-teleporter_${datetimestamp}.zip"
}
main() {
-
args=("$@")
case "${args[1]}" in
@@ -479,7 +451,7 @@ main() {
"addstaticdhcp" ) AddDHCPStaticAddress;;
"removestaticdhcp" ) RemoveDHCPStaticAddress;;
"hostrecord" ) SetHostRecord;;
- "-i" | "interface" ) SetListeningMode;;
+ "-i" | "interface" ) SetListeningMode "$@";;
"-t" | "teleporter" ) Teleporter;;
"adlist" ) CustomizeAdLists;;
* ) helpFunc;;
@@ -490,5 +462,4 @@ main() {
if [[ $# = 0 ]]; then
helpFunc
fi
-
}
diff --git a/advanced/index.php b/advanced/index.php
index bfc44a1d..1dd5acc7 100644
--- a/advanced/index.php
+++ b/advanced/index.php
@@ -185,7 +185,7 @@ function add() {
}
$.ajax({
- url: "admin/scripts/pi-hole/php/add.php",
+ url: "/admin/scripts/pi-hole/php/add.php",
method: "post",
data: {"domain":domain.val(), "list":"white", "pw":pw.val()},
success: function(response) {
diff --git a/advanced/logrotate b/advanced/logrotate
index 570e7548..ffed910b 100644
--- a/advanced/logrotate
+++ b/advanced/logrotate
@@ -8,3 +8,14 @@
notifempty
nomail
}
+
+/var/log/pihole-FTL.log {
+ # su #
+ weekly
+ copytruncate
+ rotate 3
+ compress
+ delaycompress
+ notifempty
+ nomail
+}
diff --git a/advanced/pihole-FTL.service b/advanced/pihole-FTL.service
index 30cd140f..627fad8c 100644
--- a/advanced/pihole-FTL.service
+++ b/advanced/pihole-FTL.service
@@ -26,7 +26,7 @@ start() {
echo "pihole-FTL is already running"
else
touch /var/log/pihole-FTL.log /run/pihole-FTL.pid /run/pihole-FTL.port
- chown pihole:pihole /var/log/pihole-FTL.log /run/pihole-FTL.pid /run/pihole-FTL.port
+ chown pihole:pihole /var/log/pihole-FTL.log /run/pihole-FTL.pid /run/pihole-FTL.port /etc/pihole
chmod 0644 /var/log/pihole-FTL.log /run/pihole-FTL.pid /run/pihole-FTL.port
su -s /bin/sh -c "/usr/bin/pihole-FTL" "$FTLUSER"
echo
diff --git a/advanced/pihole.cron b/advanced/pihole.cron
index c885b371..f1beb08c 100644
--- a/advanced/pihole.cron
+++ b/advanced/pihole.cron
@@ -21,9 +21,10 @@
# Pi-hole: Update Pi-hole! Uncomment to enable auto update
#30 2 * * 7 root PATH="$PATH:/usr/local/bin/" pihole updatePihole
-# Pi-hole: Flush the log daily at 00:00 so it doesn't get out of control
-# Stats will be viewable in the Web interface thanks to the cron job above
+# Pi-hole: Flush the log daily at 00:00
# The flush script will use logrotate if available
-00 00 * * * root PATH="$PATH:/usr/local/bin/" pihole flush
+# parameter "once": logrotate only once (default is twice)
+# parameter "quiet": don't print messages
+00 00 * * * root PATH="$PATH:/usr/local/bin/" pihole flush once quiet
@reboot root /usr/sbin/logrotate /etc/pihole/logrotate
diff --git a/automated install/basic-install.sh b/automated install/basic-install.sh
index c65ef49f..053e04ba 100755
--- a/automated install/basic-install.sh
+++ b/automated install/basic-install.sh
@@ -86,7 +86,7 @@ if command -v apt-get &> /dev/null; then
#Debian Family
#############################################
PKG_MANAGER="apt-get"
- UPDATE_PKG_CACHE="test_dpkg_lock; ${PKG_MANAGER} update"
+ UPDATE_PKG_CACHE="${PKG_MANAGER} update"
PKG_INSTALL=(${PKG_MANAGER} --yes --no-install-recommends install)
# grep -c will return 1 retVal on 0 matches, block this throwing the set -e with an OR TRUE
PKG_COUNT="${PKG_MANAGER} -s -o Debug::NoLocking=true upgrade | grep -c ^Inst || true"
@@ -220,6 +220,16 @@ getGitFiles() {
return 0
}
+resetRepo() {
+ local directory="${1}"
+
+ cd "${directory}" &> /dev/null || return 1
+ echo -n "::: Resetting repo in ${1}..."
+ git reset --hard &> /dev/null || return $?
+ echo " done!"
+ return 0
+}
+
find_IPv4_information() {
local route
# Find IP used to route to outside world
@@ -317,16 +327,44 @@ chooseInterface() {
fi
}
+# See https://github.com/pi-hole/pi-hole/issues/1473#issuecomment-301745953
+testIPv6() {
+ first="$(cut -f1 -d":" <<< "$1")"
+ value1=$(((0x$first)/256))
+ value2=$(((0x$first)%256))
+ ((($value1&254)==252)) && echo "ULA" || true
+ ((($value1&112)==32)) && echo "GUA" || true
+ ((($value1==254) && (($value2&192)==128))) && echo "Link-local" || true
+}
+
useIPv6dialog() {
- # Show the IPv6 address used for blocking
- IPV6_ADDRESS=$(ip -6 route get 2001:4860:4860::8888 | grep -v "unreachable" | awk -F " " '{ for(i=1;i<=NF;i++) if ($i == "src") print $(i+1) }')
+ # Determine the IPv6 address used for blocking
+ IPV6_ADDRESSES=($(ip -6 address | grep 'scope global' | awk '{print $2}'))
+
+ # Determine type of found IPv6 addresses
+ for i in "${IPV6_ADDRESSES[@]}"; do
+ result=$(testIPv6 "$i")
+ [[ "${result}" == "ULA" ]] && ULA_ADDRESS="$i"
+ [[ "${result}" == "GUA" ]] && GUA_ADDRESS="$i"
+ done
+
+ # Determine which address to be used: Prefer ULA over GUA or don't use any if none found
+ if [[ ! -z "${ULA_ADDRESS}" ]]; then
+ IPV6_ADDRESS="${ULA_ADDRESS}"
+ echo "::: Found IPv6 ULA address, using it for blocking IPv6 ads"
+ elif [[ ! -z "${GUA_ADDRESS}" ]]; then
+ echo "::: Found IPv6 GUA address, using it for blocking IPv6 ads"
+ IPV6_ADDRESS="${GUA_ADDRESS}"
+ else
+ echo "::: Found neither IPv6 ULA nor GUA address, blocking IPv6 ads will not be enabled"
+ IPV6_ADDRESS=""
+ fi
if [[ ! -z "${IPV6_ADDRESS}" ]]; then
whiptail --msgbox --backtitle "IPv6..." --title "IPv6 Supported" "$IPV6_ADDRESS will be used to block ads." ${r} ${c}
fi
}
-
use4andor6() {
local useIPv4
local useIPv6
@@ -408,7 +446,7 @@ setDHCPCD() {
echo "interface ${PIHOLE_INTERFACE}
static ip_address=${IPV4_ADDRESS}
static routers=${IPv4gw}
- static domain_name_servers=${IPv4gw}" | tee -a /etc/dhcpcd.conf >/dev/null
+ static domain_name_servers=127.0.0.1" | tee -a /etc/dhcpcd.conf >/dev/null
}
setStaticIPv4() {
@@ -980,6 +1018,7 @@ configureFirewall() {
iptables -C INPUT -p tcp -m tcp --dport 80 -j ACCEPT &> /dev/null || iptables -I INPUT 1 -p tcp -m tcp --dport 80 -j ACCEPT
iptables -C INPUT -p tcp -m tcp --dport 53 -j ACCEPT &> /dev/null || iptables -I INPUT 1 -p tcp -m tcp --dport 53 -j ACCEPT
iptables -C INPUT -p udp -m udp --dport 53 -j ACCEPT &> /dev/null || iptables -I INPUT 1 -p udp -m udp --dport 53 -j ACCEPT
+ iptables -C INPUT -p tcp -m tcp --dport 4711:4720 -i lo -j ACCEPT &> /dev/null || iptables -I INPUT 1 -p tcp -m tcp --dport 4711:4720 -i lo -j ACCEPT
return 0
fi
else
@@ -1041,7 +1080,7 @@ installLogrotate() {
# the local properties of the /var/log directory
logusergroup="$(stat -c '%U %G' /var/log)"
if [[ ! -z $logusergroup ]]; then
- sed -i "s/# su #/su ${logusergroup}/" /etc/pihole/logrotate
+ sed -i "s/# su #/su ${logusergroup}/g;" /etc/pihole/logrotate
fi
echo " done!"
}
@@ -1128,10 +1167,18 @@ checkSelinux() {
displayFinalMessage() {
+ if [[ ${#1} -gt 0 ]] ; then
+ pwstring="$1"
+ elif [[ $(grep 'WEBPASSWORD' -c /etc/pihole/setupVars.conf) -gt 0 ]]; then
+ pwstring="unchanged"
+ else
+ pwstring="NOT SET"
+ fi
+
if [[ ${INSTALL_WEB} == true ]]; then
additional="View the web interface at http://pi.hole/admin or http://${IPV4_ADDRESS%/*}/admin
-Your Admin Webpage login password is ${1:-"NOT SET"}"
+Your Admin Webpage login password is ${pwstring}"
fi
# Final completion message to user
@@ -1179,22 +1226,32 @@ update_dialogs() {
}
clone_or_update_repos() {
-if [[ "${reconfigure}" == true ]]; then
- echo "::: --reconfigure passed to install script. Not downloading/updating local repos"
- else
- # Get Git files for Core and Admin
- getGitFiles ${PI_HOLE_LOCAL_REPO} ${piholeGitUrl} || \
- { echo "!!! Unable to clone ${piholeGitUrl} into ${PI_HOLE_LOCAL_REPO}, unable to continue."; \
+ if [[ "${reconfigure}" == true ]]; then
+ echo "::: --reconfigure passed to install script. Resetting changes to local repos"
+ resetRepo ${PI_HOLE_LOCAL_REPO} || \
+ { echo "!!! Unable to reset ${PI_HOLE_LOCAL_REPO}, unable to continue."; \
+ exit 1; \
+ }
+ if [[ ${INSTALL_WEB} == true ]]; then
+ resetRepo ${webInterfaceDir} || \
+ { echo "!!! Unable to reset ${webInterfaceDir}, unable to continue."; \
exit 1; \
}
-
- if [[ ${INSTALL_WEB} == true ]]; then
- getGitFiles ${webInterfaceDir} ${webInterfaceGitUrl} || \
- { echo "!!! Unable to clone ${webInterfaceGitUrl} into ${webInterfaceDir}, unable to continue."; \
- exit 1; \
- }
- fi
fi
+ else
+ # Get Git files for Core and Admin
+ getGitFiles ${PI_HOLE_LOCAL_REPO} ${piholeGitUrl} || \
+ { echo "!!! Unable to clone ${piholeGitUrl} into ${PI_HOLE_LOCAL_REPO}, unable to continue."; \
+ exit 1; \
+ }
+
+ if [[ ${INSTALL_WEB} == true ]]; then
+ getGitFiles ${webInterfaceDir} ${webInterfaceGitUrl} || \
+ { echo "!!! Unable to clone ${webInterfaceGitUrl} into ${webInterfaceDir}, unable to continue."; \
+ exit 1; \
+ }
+ fi
+ fi
}
FTLinstall() {
@@ -1220,6 +1277,7 @@ FTLinstall() {
echo -n "transferred... "
stop_service pihole-FTL &> /dev/null
install -T -m 0755 /tmp/${binary} /usr/bin/pihole-FTL
+ rm /tmp/${binary} /tmp/${binary}.sha1
cd "${orig_dir}"
install -T -m 0755 "${PI_HOLE_LOCAL_REPO}/advanced/pihole-FTL.service" "/etc/init.d/pihole-FTL"
echo "done."
diff --git a/gravity.sh b/gravity.sh
index a5231d5e..285ce5c3 100755
--- a/gravity.sh
+++ b/gravity.sh
@@ -54,6 +54,7 @@ IPV6_ADDRESS=${IPV6_ADDRESS}
basename=pihole
piholeDir=/etc/${basename}
adList=${piholeDir}/gravity.list
+blackList=${piholeDir}/black.list
localList=${piholeDir}/local.list
justDomainsExtension=domains
matterAndLight=${basename}.0.matterandlight.txt
@@ -235,9 +236,7 @@ gravity_Blacklist() {
if [[ -f "${blacklistFile}" ]]; then
numBlacklisted=$(wc -l < "${blacklistFile}")
plural=; [[ "$numBlacklisted" != "1" ]] && plural=s
- echo -n "::: Blacklisting $numBlacklisted domain${plural}..."
- cat ${blacklistFile} >> ${piholeDir}/${eventHorizon}
- echo " done!"
+ echo "::: Exact blocked domain${plural}: $numBlacklisted"
else
echo "::: Nothing to blacklist!"
fi
@@ -299,9 +298,25 @@ gravity_unique() {
echo "::: $numberOf unique domains trapped in the event horizon."
}
-gravity_hostFormat() {
+gravity_doHostFormat() {
+ # Check vars from setupVars.conf to see if we're using IPv4, IPv6, Or both.
+ if [[ -n "${IPV4_ADDRESS}" && -n "${IPV6_ADDRESS}" ]];then
+ # Both IPv4 and IPv6
+ awk -v ipv4addr="$IPV4_ADDRESS" -v ipv6addr="$IPV6_ADDRESS" '{sub(/\r$/,""); print ipv4addr" "$0"\n"ipv6addr" "$0}' >> "${2}" < "${1}"
+ elif [[ -n "${IPV4_ADDRESS}" && -z "${IPV6_ADDRESS}" ]];then
+ # Only IPv4
+ awk -v ipv4addr="$IPV4_ADDRESS" '{sub(/\r$/,""); print ipv4addr" "$0}' >> "${2}" < "${1}"
+ elif [[ -z "${IPV4_ADDRESS}" && -n "${IPV6_ADDRESS}" ]];then
+ # Only IPv6
+ awk -v ipv6addr="$IPV6_ADDRESS" '{sub(/\r$/,""); print ipv6addr" "$0}' >> "${2}" < "${1}"
+ elif [[ -z "${IPV4_ADDRESS}" && -z "${IPV6_ADDRESS}" ]];then
+ echo "::: No IP Values found! Please run 'pihole -r' and choose reconfigure to restore values"
+ exit 1
+ fi
+}
+
+gravity_hostFormatLocal() {
# Format domain list as "192.168.x.x domain.com"
- echo -n "::: Formatting domains into a HOSTS file..."
if [[ -f /etc/hostname ]]; then
hostname=$( ${localList}
- # Both IPv4 and IPv6
- cat ${piholeDir}/${eventHorizon} | awk -v ipv4addr="$IPV4_ADDRESS" -v ipv6addr="$IPV6_ADDRESS" '{sub(/\r$/,""); print ipv4addr" "$0"\n"ipv6addr" "$0}' >> ${piholeDir}/${accretionDisc}
-
- elif [[ -n "${IPV4_ADDRESS}" && -z "${IPV6_ADDRESS}" ]];then
-
- echo -e "${IPV4_ADDRESS} ${hostname}\n${IPV4_ADDRESS} pi.hole" > ${localList}
- # Only IPv4
- cat ${piholeDir}/${eventHorizon} | awk -v ipv4addr="$IPV4_ADDRESS" '{sub(/\r$/,""); print ipv4addr" "$0}' >> ${piholeDir}/${accretionDisc}
-
- elif [[ -z "${IPV4_ADDRESS}" && -n "${IPV6_ADDRESS}" ]];then
-
- echo -e "${IPV6_ADDRESS} ${hostname}\n${IPV6_ADDRESS} pi.hole" > ${localList}
- # Only IPv6
- cat ${piholeDir}/${eventHorizon} | awk -v ipv6addr="$IPV6_ADDRESS" '{sub(/\r$/,""); print ipv6addr" "$0}' >> ${piholeDir}/${accretionDisc}
-
- elif [[ -z "${IPV4_ADDRESS}" && -z "${IPV6_ADDRESS}" ]];then
- echo "::: No IP Values found! Please run 'pihole -r' and choose reconfigure to restore values"
- exit 1
- fi
+ echo -e "${hostname}\npi.hole" > "${localList}.tmp"
+ # Copy the file over as /etc/pihole/local.list so dnsmasq can use it
+ rm "${localList}"
+ gravity_doHostFormat "${localList}.tmp" "${localList}"
+ rm "${localList}.tmp"
+}
+gravity_hostFormatGravity() {
+ # Format domain list as "192.168.x.x domain.com"
+ echo "" > "${piholeDir}/${accretionDisc}"
+ gravity_doHostFormat "${piholeDir}/${eventHorizon}" "${piholeDir}/${accretionDisc}"
# Copy the file over as /etc/pihole/gravity.list so dnsmasq can use it
- cp ${piholeDir}/${accretionDisc} ${adList}
- echo " done!"
+ mv "${piholeDir}/${accretionDisc}" "${adList}"
+}
+
+gravity_hostFormatBlack() {
+ if [[ -f "${blacklistFile}" ]]; then
+ numBlacklisted=$(wc -l < "${blacklistFile}")
+ # Format domain list as "192.168.x.x domain.com"
+ gravity_doHostFormat "${blacklistFile}" "${blackList}.tmp"
+ # Copy the file over as /etc/pihole/black.list so dnsmasq can use it
+ mv "${blackList}.tmp" "${blackList}"
+ else
+ echo "::: Nothing to blacklist!"
+ fi
}
# blackbody - remove any remnant files from script processes
@@ -377,11 +391,6 @@ gravity_advanced() {
}
gravity_reload() {
- #Clear no longer needed files...
- echo ":::"
- echo -n "::: Cleaning up un-needed files..."
- rm ${piholeDir}/pihole.*.txt
- echo " done!"
# Reload hosts file
echo ":::"
@@ -402,6 +411,7 @@ for var in "$@"; do
"-f" | "--force" ) forceGrav=true;;
"-h" | "--help" ) helpFunc;;
"-sd" | "--skip-download" ) skipDownload=true;;
+ "-b" | "--blacklist-only" ) blackListOnly=true;;
esac
done
@@ -411,22 +421,39 @@ if [[ "${forceGrav}" == true ]]; then
echo " done!"
fi
-gravity_collapse
-gravity_spinup
-if [[ "${skipDownload}" == false ]]; then
+if [[ ! "${blackListOnly}" == true ]]; then
+ gravity_collapse
+ gravity_spinup
+ if [[ "${skipDownload}" == false ]]; then
gravity_Schwarzchild
gravity_advanced
-else
+ else
echo "::: Using cached Event Horizon list..."
numberOf=$(wc -l < ${piholeDir}/${preEventHorizon})
- echo "::: $numberOf unique domains trapped in the event horizon."
+ echo "::: $numberOf unique domains trapped in the event horizon."
+ fi
+ gravity_Whitelist
fi
-gravity_Whitelist
gravity_Blacklist
gravity_Wildcard
-gravity_hostFormat
+echo -n "::: Formatting domains into a HOSTS file..."
+if [[ ! "${blackListOnly}" == true ]]; then
+ gravity_hostFormatLocal
+ gravity_hostFormatGravity
+fi
+gravity_hostFormatBlack
+echo " done!"
+
gravity_blackbody
+if [[ ! "${blackListOnly}" == true ]]; then
+ #Clear no longer needed files...
+ echo ":::"
+ echo -n "::: Cleaning up un-needed files..."
+ rm ${piholeDir}/pihole.*.txt
+ echo " done!"
+fi
+
gravity_reload
"${PIHOLE_COMMAND}" status
diff --git a/pihole b/pihole
index 83e13000..055d6bce 100755
--- a/pihole
+++ b/pihole
@@ -9,11 +9,11 @@
# Please see LICENSE file for your rights under this license.
readonly PI_HOLE_SCRIPT_DIR="/opt/pihole"
-
readonly wildcardlist="/etc/dnsmasq.d/03-pihole-wildcard.conf"
+
# Must be root to use this tool
if [[ ! $EUID -eq 0 ]];then
- if [ -x "$(command -v sudo)" ];then
+ if [[ -x "$(command -v sudo)" ]]; then
exec sudo bash "$0" "$@"
exit $?
else
@@ -61,7 +61,7 @@ debugFunc() {
}
flushFunc() {
- "${PI_HOLE_SCRIPT_DIR}"/piholeLogFlush.sh
+ "${PI_HOLE_SCRIPT_DIR}"/piholeLogFlush.sh "$@"
exit 0
}
@@ -163,16 +163,16 @@ versionFunc() {
restartDNS() {
dnsmasqPid=$(pidof dnsmasq)
- if [[ ${dnsmasqPid} ]]; then
- # service already running - reload config
- if [ -x "$(command -v systemctl)" ]; then
+ if [[ "${dnsmasqPid}" ]]; then
+ # Service already running - reload config
+ if [[ -x "$(command -v systemctl)" ]]; then
systemctl restart dnsmasq
else
service dnsmasq restart
fi
else
- # service not running, start it up
- if [ -x "$(command -v systemctl)" ]; then
+ # Service not running, start it up
+ if [[ -x "$(command -v systemctl)" ]]; then
systemctl start dnsmasq
else
service dnsmasq start
@@ -181,16 +181,29 @@ restartDNS() {
}
piholeEnable() {
- if [[ "${1}" == "0" ]] ; then
- #Disable Pihole
+ if [[ "${2}" == "-h" ]] || [[ "${2}" == "--help" ]]; then
+ echo "Usage: pihole disable [time]
+Example: 'pihole disable', or 'pihole disable 5m'
+Disable Pi-hole subsystems
+
+Time:
+ #s Disable Pi-hole functionality for # second(s)
+ #m Disable Pi-hole functionality for # minute(s)"
+ exit 0
+ elif [[ "${1}" == "0" ]]; then
+ # Disable Pi-hole
sed -i 's/^addn-hosts=\/etc\/pihole\/gravity.list/#addn-hosts=\/etc\/pihole\/gravity.list/' /etc/dnsmasq.d/01-pihole.conf
+ sed -i 's/^addn-hosts=\/etc\/pihole\/black.list/#addn-hosts=\/etc\/pihole\/black.list/' /etc/dnsmasq.d/01-pihole.conf
+ if [[ -e "$wildcardlist" ]]; then
+ mv "$wildcardlist" "/etc/pihole/wildcard.list"
+ fi
echo "::: Blocking has been disabled!"
- if [[ $# > 1 ]] ; then
- if [[ ${2} == *"s"* ]] ; then
+ if [[ $# > 1 ]]; then
+ if [[ "${2}" == *"s"* ]]; then
tt=${2%"s"}
echo "::: Blocking will be re-enabled in ${tt} seconds"
nohup bash -c "sleep ${tt}; pihole enable" /dev/null &
- elif [[ ${2} == *"m"* ]] ; then
+ elif [[ "${2}" == *"m"* ]]; then
tt=${2%"m"}
echo "::: Blocking will be re-enabled in ${tt} minutes"
tt=$((${tt}*60))
@@ -204,24 +217,35 @@ piholeEnable() {
fi
fi
else
- #Enable pihole
+ # Enable Pi-hole
echo "::: Blocking has been enabled!"
sed -i 's/^#addn-hosts/addn-hosts/' /etc/dnsmasq.d/01-pihole.conf
+ if [[ -e "/etc/pihole/wildcard.list" ]]; then
+ mv "/etc/pihole/wildcard.list" "$wildcardlist"
+ fi
fi
restartDNS
}
piholeLogging() {
shift
+ if [[ "${1}" == "-h" ]] || [[ "${1}" == "--help" ]]; then
+ echo "Usage: pihole logging [options]
+Example: 'pihole logging on'
+Specify whether the Pi-hole log should be used
- if [[ "${1}" == "off" ]] ; then
- #Disable Logging
+Options:
+ on Enable the Pi-hole log at /var/log/pihole.log
+ off Disable the Pi-hole log at /var/log/pihole.log"
+ exit 0
+ elif [[ "${1}" == "off" ]]; then
+ # Disable logging
sed -i 's/^log-queries/#log-queries/' /etc/dnsmasq.d/01-pihole.conf
sed -i 's/^QUERY_LOGGING=true/QUERY_LOGGING=false/' /etc/pihole/setupVars.conf
pihole -f
echo "::: Logging has been disabled!"
- elif [[ "${1}" == "on" ]] ; then
- #Enable logging
+ elif [[ "${1}" == "on" ]]; then
+ # Enable logging
sed -i 's/^#log-queries/log-queries/' /etc/dnsmasq.d/01-pihole.conf
sed -i 's/^QUERY_LOGGING=false/QUERY_LOGGING=true/' /etc/pihole/setupVars.conf
echo "::: Logging has been enabled!"
@@ -233,12 +257,12 @@ piholeLogging() {
}
piholeStatus() {
- if [[ $(netstat -plnt | grep -c ':53 ') > 0 ]]; then
- if [[ "${1}" != "web" ]] ; then
+ if [[ "$(netstat -plnt | grep -c ':53 ')" -gt "0" ]]; then
+ if [[ "${1}" != "web" ]]; then
echo "::: DNS service is running"
fi
else
- if [[ "${1}" == "web" ]] ; then
+ if [[ "${1}" == "web" ]]; then
echo "-1";
else
echo "::: DNS service is NOT running"
@@ -246,28 +270,28 @@ piholeStatus() {
return
fi
- if [[ $(grep -i "^#addn-hosts=/" /etc/dnsmasq.d/01-pihole.conf) ]] ; then
- #list is commented out
- if [[ "${1}" == "web" ]] ; then
+ if [[ "$(grep -i "^#addn-hosts=/" /etc/dnsmasq.d/01-pihole.conf)" ]]; then
+ # List is commented out
+ if [[ "${1}" == "web" ]]; then
echo 0;
else
echo "::: Pi-hole blocking is Disabled";
fi
- elif [[ $(grep -i "^addn-hosts=/" /etc/dnsmasq.d/01-pihole.conf) ]] ; then
- #list set
- if [[ "${1}" == "web" ]] ; then
+ elif [[ "$(grep -i "^addn-hosts=/" /etc/dnsmasq.d/01-pihole.conf)" ]]; then
+ # List set
+ if [[ "${1}" == "web" ]]; then
echo 1;
else
echo "::: Pi-hole blocking is Enabled";
fi
else
- #addn-host not found
- if [[ "${1}" == "web" ]] ; then
+ # Addn-host not found
+ if [[ "${1}" == "web" ]]; then
echo 99
else
echo "::: No hosts file linked to dnsmasq, adding it in enabled state"
fi
- #add addn-host= to dnsmasq
+ # Add addn-host= to dnsmasq
echo "addn-hosts=/etc/pihole/gravity.list" >> /etc/dnsmasq.d/01-pihole.conf
restartDNS
fi
@@ -280,46 +304,96 @@ tailFunc() {
}
piholeCheckoutFunc() {
+ if [[ "$2" == "-h" ]] || [[ "$2" == "--help" ]]; then
+ echo "Usage: pihole checkout [repo] [branch]
+Example: 'pihole checkout master' or 'pihole checkout core dev'
+Switch Pi-hole subsystems to a different Github branch
+
+Repositories:
+ core [branch] Change the branch of Pi-hole's core subsystem
+ web [branch] Change the branch of Admin Console subsystem
+
+Branches:
+ master Update subsystems to the latest stable release
+ dev Update subsystems to the latest development release"
+ exit 0
+ fi
+
source "${PI_HOLE_SCRIPT_DIR}"/piholeCheckout.sh
shift
checkout "$@"
}
+tricorderFunc() {
+ if [[ ! -p "/dev/stdin" ]]; then
+ echo "Please do not call Tricorder directly."
+ exit 1
+ fi
+
+ if ! timeout 2 nc -z tricorder.pi-hole.net 9998 &> /dev/null; then
+ echo "Unable to connect to Pi-hole's Tricorder server."
+ exit 1
+ fi
+
+ if command -v openssl &> /dev/null; then
+ openssl s_client -quiet -connect tricorder.pi-hole.net:9998 2> /dev/null < /dev/stdin
+ exit "$?"
+ else
+ echo "Your debug log will be transmitted unencrypted via plain-text"
+ echo "There is a possibility that this could be intercepted by a third party"
+ echo "If you wish to cancel, press Ctrl-C to exit within 10 seconds"
+ secs="10"
+ while [[ "$secs" -gt "0" ]]; do
+ echo -ne "."
+ sleep 1
+ : $((secs--))
+ done
+ echo " "
+ nc tricorder.pi-hole.net 9999 < /dev/stdin
+ exit "$?"
+ fi
+}
+
helpFunc() {
- cat << EOM
-::: Control all Pi-hole specific functions
-:::
-::: Usage: pihole [options]
-::: Add -h after -w (whitelist), -b (blacklist), -c (chronometer), or -a (admin) for more information on usage
-:::
-::: Options:
-::: -w, whitelist Whitelist domain(s)
-::: -b, blacklist Blacklist domain(s) (exact match)
-::: -wild, wildcard Blacklist whole domain(s) (wildcard)
-::: -d, debug Start a debugging session
-::: Automated debugging can be enabled with '-a'.
-::: 'pihole -d -a'
-::: -f, flush Flush the 'pihole.log' file
-::: -t, tail Output the last lines of the 'pihole.log' file. Lines are appended as the file grows
-::: -up, updatePihole Update Pi-hole components
-::: -r, reconfigure Reconfigure or Repair Pi-hole
-::: -g, updateGravity Update the list of ad-serving domains
-::: -c, chronometer Calculates stats and displays to an LCD
-::: -h, help Show this help dialog
-::: -v, version Show installed versions of Pi-hole and Web-Admin
-::: -q, query Query the adlists for a specific domain
-::: 'pihole -q domain -exact' shows exact matches only
-::: -l, logging Enable or Disable logging (pass 'on' or 'off')
-::: -a, admin Admin webpage options
-::: uninstall Uninstall Pi-hole from your system! :(
-::: status Display if Pi-hole is Enabled or Disabled
-::: enable Enable Pi-hole DNS Blocking
-::: disable Disable Pi-hole DNS Blocking
-::: Blocking can also be disabled only temporarily, e.g.,
-::: 'pihole disable 5m' - will disable blocking for 5 minutes
-::: restartdns Restart dnsmasq
-::: checkout Check out different branches
-EOM
+ echo "Usage: pihole [options]
+Example: 'pihole -w -h'
+Add '-h' after specific commands for more information on usage
+
+Whitelist/Blacklist Options:
+ -w, whitelist Whitelist domain(s)
+ -b, blacklist Blacklist domain(s)
+ -wild, wildcard Blacklist domain(s), and all its subdomains
+ Add '-h' for more info on whitelist/blacklist usage
+
+Debugging Options:
+ -d, debug Start a debugging session
+ Add '-a' to enable automated debugging
+ -f, flush Flush the Pi-hole log
+ -r, reconfigure Reconfigure or Repair Pi-hole subsystems
+ -t, tail View the live output of the Pi-hole log
+
+Options:
+ -a, admin Admin Console options
+ Add '-h' for more info on admin console usage
+ -c, chronometer Calculates stats and displays to an LCD
+ Add '-h' for more info on chronometer usage
+ -g, updateGravity Update the list of ad-serving domains
+ -h, --help, help Show this help dialog
+ -l, logging Specify whether the Pi-hole log should be used
+ Add '-h' for more info on logging usage
+ -q, query Query the adlists for a specified domain
+ Add '-exact' AFTER a specified domain for exact match
+ -up, updatePihole Update Pi-hole subsystems
+ -v, version Show installed versions of Pi-hole, Admin Console & FTL
+ Add '-h' for more info on version usage
+ uninstall Uninstall Pi-hole from your system
+ status Display the running status of Pi-hole subsystems
+ enable Enable Pi-hole subsystems
+ disable Disable Pi-hole subsystems
+ Add '-h' for more info on disable usage
+ restartdns Restart Pi-hole subsystems
+ checkout Switch Pi-hole subsystems to a different Github branch
+ Add '-h' for more info on checkout usage";
exit 0
}
@@ -333,7 +407,7 @@ case "${1}" in
"-b" | "blacklist" ) blacklistFunc "$@";;
"-wild" | "wildcard" ) wildcardFunc "$@";;
"-d" | "debug" ) debugFunc "$@";;
- "-f" | "flush" ) flushFunc;;
+ "-f" | "flush" ) flushFunc "$@";;
"-up" | "updatePihole" ) updatePiholeFunc;;
"-r" | "reconfigure" ) reconfigurePiholeFunc;;
"-g" | "updateGravity" ) updateGravityFunc "$@";;
@@ -344,11 +418,12 @@ case "${1}" in
"-l" | "logging" ) piholeLogging "$@";;
"uninstall" ) uninstallFunc;;
"enable" ) piholeEnable 1;;
- "disable" ) piholeEnable 0 $2;;
+ "disable" ) piholeEnable 0 "$2";;
"status" ) piholeStatus "$2";;
"restartdns" ) restartDNS;;
"-a" | "admin" ) webpageFunc "$@";;
"-t" | "tail" ) tailFunc;;
"checkout" ) piholeCheckoutFunc "$@";;
+ "tricorder" ) tricorderFunc;;
* ) helpFunc;;
esac
diff --git a/test/test_automated_install.py b/test/test_automated_install.py
index 8e36fc96..60772625 100644
--- a/test/test_automated_install.py
+++ b/test/test_automated_install.py
@@ -402,6 +402,61 @@ def test_FTL_binary_installed_and_responsive_no_errors(Pihole):
# assert '644 /run/pihole-FTL.pid' in support_files.stdout
# assert '644 /var/log/pihole-FTL.log' in support_files.stdout
+def test_IPv6_only_link_local(Pihole):
+ ''' confirms IPv6 blocking is disabled for Link-local address '''
+ # mock ip -6 address to return Link-local address
+ mock_command_2('ip', {'-6 address':('inet6 fe80::d210:52fa:fe00:7ad7/64 scope link', '0')}, Pihole)
+ detectPlatform = Pihole.run('''
+ source /opt/pihole/basic-install.sh
+ useIPv6dialog
+ ''')
+ expected_stdout = 'Found neither IPv6 ULA nor GUA address, blocking IPv6 ads will not be enabled'
+ assert expected_stdout in detectPlatform.stdout
+
+def test_IPv6_only_ULA(Pihole):
+ ''' confirms IPv6 blocking is enabled for ULA addresses '''
+ # mock ip -6 address to return ULA address
+ mock_command_2('ip', {'-6 address':('inet6 fda2:2001:5555:0:d210:52fa:fe00:7ad7/64 scope global', '0')}, Pihole)
+ detectPlatform = Pihole.run('''
+ source /opt/pihole/basic-install.sh
+ useIPv6dialog
+ ''')
+ expected_stdout = 'Found IPv6 ULA address, using it for blocking IPv6 ads'
+ assert expected_stdout in detectPlatform.stdout
+
+def test_IPv6_only_GUA(Pihole):
+ ''' confirms IPv6 blocking is enabled for GUA addresses '''
+ # mock ip -6 address to return GUA address
+ mock_command_2('ip', {'-6 address':('inet6 2003:12:1e43:301:d210:52fa:fe00:7ad7/64 scope global', '0')}, Pihole)
+ detectPlatform = Pihole.run('''
+ source /opt/pihole/basic-install.sh
+ useIPv6dialog
+ ''')
+ expected_stdout = 'Found IPv6 GUA address, using it for blocking IPv6 ads'
+ assert expected_stdout in detectPlatform.stdout
+
+def test_IPv6_GUA_ULA_test(Pihole):
+ ''' confirms IPv6 blocking is enabled for GUA and ULA addresses '''
+ # mock ip -6 address to return GUA and ULA addresses
+ mock_command_2('ip', {'-6 address':('inet6 2003:12:1e43:301:d210:52fa:fe00:7ad7/64 scope global\ninet6 fda2:2001:5555:0:d210:52fa:fe00:7ad7/64 scope global', '0')}, Pihole)
+ detectPlatform = Pihole.run('''
+ source /opt/pihole/basic-install.sh
+ useIPv6dialog
+ ''')
+ expected_stdout = 'Found IPv6 ULA address, using it for blocking IPv6 ads'
+ assert expected_stdout in detectPlatform.stdout
+
+def test_IPv6_ULA_GUA_test(Pihole):
+ ''' confirms IPv6 blocking is enabled for GUA and ULA addresses '''
+ # mock ip -6 address to return ULA and GUA addresses
+ mock_command_2('ip', {'-6 address':('inet6 fda2:2001:5555:0:d210:52fa:fe00:7ad7/64 scope global\ninet6 2003:12:1e43:301:d210:52fa:fe00:7ad7/64 scope global', '0')}, Pihole)
+ detectPlatform = Pihole.run('''
+ source /opt/pihole/basic-install.sh
+ useIPv6dialog
+ ''')
+ expected_stdout = 'Found IPv6 ULA address, using it for blocking IPv6 ads'
+ assert expected_stdout in detectPlatform.stdout
+
# Helper functions
def mock_command(script, args, container):
''' Allows for setup of commands we don't really want to have to run for real in unit tests '''
@@ -424,6 +479,27 @@ def mock_command(script, args, container):
chmod +x {script}
rm -f /var/log/{scriptlog}'''.format(script=full_script_path, content=mock_script, scriptlog=script))
+def mock_command_2(script, args, container):
+ ''' Allows for setup of commands we don't really want to have to run for real in unit tests '''
+ full_script_path = '/usr/local/bin/{}'.format(script)
+ mock_script = dedent('''\
+ #!/bin/bash -e
+ echo "\$0 \$@" >> /var/log/{script}
+ case "\$1 \$2" in'''.format(script=script))
+ for k, v in args.iteritems():
+ case = dedent('''
+ \"{arg}\")
+ echo \"{res}\"
+ exit {retcode}
+ ;;'''.format(arg=k, res=v[0], retcode=v[1]))
+ mock_script += case
+ mock_script += dedent('''
+ esac''')
+ container.run('''
+ cat < {script}\n{content}\nEOF
+ chmod +x {script}
+ rm -f /var/log/{scriptlog}'''.format(script=full_script_path, content=mock_script, scriptlog=script))
+
def run_script(Pihole, script):
result = Pihole.run(script)
assert result.rc == 0
From 536585b8460defd5de88cec786808e26c410408e Mon Sep 17 00:00:00 2001
From: Adam Warner
Date: Wed, 21 Jun 2017 12:49:05 +0100
Subject: [PATCH 095/162] Colourise Core Output Text (#1471)
* Define colours within COL_TABLE
* Do not output colours for non-terminal instances
* Removed ":::"
* Fixed indenting & spacing
* Made output consistent throughout project
* Reworded text to fit on standard 80 char wide Terminal screen
* Made 'sudo raspi-config' warning (insufficient disk space) only show on RPi
* Make "Installation/Update Complete" the final msg
* Remove redundant messages
* Simplify update available message
* Confirm user would like to begin uninstall
* If "git pull" string says "Already up-to-date.", place [i] before it
* Colour Temp/Interface output
* Made `pihole disable 5z` invalid
* Added error fallback if invalid argument (not s/m) is detected
* Quoted "$2" for consistency
* Updated help text
* L185/286: Replaced echo with redirect
* User agents for adblock.mahakala.is/adaway.org unnecessary
* Print newline on confirmation of repository reset
* Add output to admin-related dnsmasq restarts
* Return error message for "pihole -q"
* Imply default checkout behaviour with y/N
* Fix uninstall failing to remove pihole user
* Print checkout 'git remote show origin' STDERR on new line
* Replaced checkout "AdminLTE" wording with "Web Admin"
---
advanced/Scripts/COL_TABLE | 28 ++
advanced/Scripts/list.sh | 112 +++---
advanced/Scripts/piholeCheckout.sh | 135 ++++---
advanced/Scripts/piholeLogFlush.sh | 7 +-
advanced/Scripts/update.sh | 92 ++---
advanced/Scripts/webpage.sh | 37 +-
automated install/basic-install.sh | 537 +++++++++++++++------------
automated install/uninstall.sh | 138 ++++---
gravity.sh | 565 +++++++++++++++--------------
pihole | 107 ++++--
test/test_automated_install.py | 110 ++++--
11 files changed, 1076 insertions(+), 792 deletions(-)
create mode 100644 advanced/Scripts/COL_TABLE
diff --git a/advanced/Scripts/COL_TABLE b/advanced/Scripts/COL_TABLE
new file mode 100644
index 00000000..20dd98b0
--- /dev/null
+++ b/advanced/Scripts/COL_TABLE
@@ -0,0 +1,28 @@
+if [[ -t 1 ]] && [[ $(tput colors) -ge 8 ]]; then
+ COL_NC='[0m'
+ COL_WHITE='[1;37m'
+ COL_BLACK='[0;30m'
+ COL_BLUE='[0;34m'
+ COL_LIGHT_BLUE='[1;34m'
+ COL_GREEN='[0;32m'
+ COL_LIGHT_GREEN='[1;32m'
+ COL_CYAN='[0;36m'
+ COL_LIGHT_CYAN='[1;36m'
+ COL_RED='[0;31m'
+ COL_LIGHT_RED='[1;31m'
+ COL_URG_RED='[39;41m'
+ COL_PURPLE='[0;35m'
+ COL_LIGHT_PURPLE='[1;35m'
+ COL_BROWN='[0;33m'
+ COL_YELLOW='[1;33m'
+ COL_GRAY='[0;30m'
+ COL_LIGHT_GRAY='[0;37m'
+ COL_DARK_GRAY='[1;30m'
+fi
+
+TICK="[${COL_LIGHT_GREEN}✓${COL_NC}]"
+CROSS="[${COL_LIGHT_RED}✗${COL_NC}]"
+INFO="[i]"
+QST="[?]"
+DONE="${COL_LIGHT_GREEN} done!${COL_NC}"
+OVER="\r\033[K"
diff --git a/advanced/Scripts/list.sh b/advanced/Scripts/list.sh
index 308e1f5e..9d587296 100755
--- a/advanced/Scripts/list.sh
+++ b/advanced/Scripts/list.sh
@@ -24,6 +24,10 @@ domToRemoveList=()
listMain=""
listAlt=""
+colfile="/opt/pihole/COL_TABLE"
+source ${colfile}
+
+
helpFunc() {
if [[ "${listMain}" == "${whitelist}" ]]; then
param="w"
@@ -64,8 +68,9 @@ HandleOther() {
# Check validity of domain
validDomain=$(echo "${domain}" | perl -lne 'print if /(?!.*[^a-z0-9-\.].*)^((?=[a-z0-9-]{1,63}\.)(xn--)?[a-z0-9-]+\.)*[a-z]{2,63}/')
if [[ -z "${validDomain}" ]]; then
- echo "::: $1 is not a valid argument or domain name"
+ echo -e " ${CROSS} $1 is not a valid argument or domain name!"
else
+ echo -e " ${TICK} $1 is a valid domain name!"
domList=("${domList[@]}" ${validDomain})
fi
}
@@ -93,6 +98,10 @@ PoplistFile() {
AddDomain() {
list="$2"
domain=$(EscapeRegexp "$1")
+
+ [[ "${list}" == "${whitelist}" ]] && listname="whitelist"
+ [[ "${list}" == "${blacklist}" ]] && listname="blacklist"
+ [[ "${list}" == "${wildcardlist}" ]] && listname="wildcard blacklist"
if [[ "${list}" == "${whitelist}" || "${list}" == "${blacklist}" ]]; then
bool=true
@@ -102,14 +111,14 @@ AddDomain() {
if [[ "${bool}" == false ]]; then
# Domain not found in the whitelist file, add it!
if [[ "${verbose}" == true ]]; then
- echo "::: Adding $1 to $list..."
+ echo -e " ${INFO} Adding $1 to $listname..."
fi
reload=true
# Add it to the list we want to add it to
echo "$1" >> "${list}"
else
if [[ "${verbose}" == true ]]; then
- echo "::: ${1} already exists in ${list}, no need to add!"
+ echo -e " ${INFO} ${1} already exists in ${listname}, no need to add!"
fi
fi
elif [[ "${list}" == "${wildcardlist}" ]]; then
@@ -124,7 +133,7 @@ AddDomain() {
if [[ "${bool}" == false ]]; then
if [[ "${verbose}" == true ]]; then
- echo "::: Adding $1 to wildcard blacklist..."
+ echo -e " ${INFO} Adding $1 to wildcard blacklist..."
fi
reload=true
echo "address=/$1/${IPV4_ADDRESS}" >> "${wildcardlist}"
@@ -133,67 +142,78 @@ AddDomain() {
fi
else
if [[ "${verbose}" == true ]]; then
- echo "::: ${1} already exists in wildcard blacklist, no need to add!"
+ echo -e " ${INFO} ${1} already exists in wildcard blacklist, no need to add!"
fi
fi
fi
}
RemoveDomain() {
- list="$2"
- domain=$(EscapeRegexp "$1")
+ list="$2"
+ domain=$(EscapeRegexp "$1")
+
+ [[ "${list}" == "${whitelist}" ]] && listname="whitelist"
+ [[ "${list}" == "${blacklist}" ]] && listname="blacklist"
+ [[ "${list}" == "${wildcardlist}" ]] && listname="wildcard blacklist"
- if [[ "${list}" == "${whitelist}" || "${list}" == "${blacklist}" ]]; then
- bool=true
- # Is it in the list? Logic follows that if its whitelisted it should not be blacklisted and vice versa
- grep -Ex -q "${domain}" "${list}" > /dev/null 2>&1 || bool=false
- if [[ "${bool}" == true ]]; then
- # Remove it from the other one
- echo "::: Removing $1 from $list..."
- # /I flag: search case-insensitive
- sed -i "/${domain}/Id" "${list}"
- reload=true
- else
- if [[ "${verbose}" == true ]]; then
- echo "::: ${1} does not exist in ${list}, no need to remove!"
- fi
- fi
- elif [[ "${list}" == "${wildcardlist}" ]]; then
- bool=true
- # Is it in the list?
- grep -e "address=\/${domain}\/" "${wildcardlist}" > /dev/null 2>&1 || bool=false
- if [[ "${bool}" == true ]]; then
- # Remove it from the other one
- echo "::: Removing $1 from $list..."
- # /I flag: search case-insensitive
- sed -i "/address=\/${domain}/Id" "${list}"
- reload=true
- else
- if [[ "${verbose}" == true ]]; then
- echo "::: ${1} does not exist in ${list}, no need to remove!"
- fi
+ if [[ "${list}" == "${whitelist}" || "${list}" == "${blacklist}" ]]; then
+ bool=true
+ # Is it in the list? Logic follows that if its whitelisted it should not be blacklisted and vice versa
+ grep -Ex -q "${domain}" "${list}" > /dev/null 2>&1 || bool=false
+ if [[ "${bool}" == true ]]; then
+ # Remove it from the other one
+ echo -e " ${INFO} Removing $1 from $listname..."
+ # /I flag: search case-insensitive
+ sed -i "/${domain}/Id" "${list}"
+ reload=true
+ else
+ if [[ "${verbose}" == true ]]; then
+ echo -e " ${INFO} ${1} does not exist in ${listname}, no need to remove!"
fi
fi
+ elif [[ "${list}" == "${wildcardlist}" ]]; then
+ bool=true
+ # Is it in the list?
+ grep -e "address=\/${domain}\/" "${wildcardlist}" > /dev/null 2>&1 || bool=false
+ if [[ "${bool}" == true ]]; then
+ # Remove it from the other one
+ echo -e " ${INFO} Removing $1 from $listname..."
+ # /I flag: search case-insensitive
+ sed -i "/address=\/${domain}/Id" "${list}"
+ reload=true
+ else
+ if [[ "${verbose}" == true ]]; then
+ echo -e " ${INFO} ${1} does not exist in ${listname}, no need to remove!"
+ fi
+ fi
+ fi
}
Reload() {
# Reload hosts file
+ echo ""
+ echo -e " ${INFO} Updating gravity..."
+ echo ""
pihole -g -sd
}
Displaylist() {
- if [[ "${listMain}" == "${whitelist}" ]]; then
- string="gravity resistant domains"
+ if [[ -f ${listMain} ]]; then
+ if [[ "${listMain}" == "${whitelist}" ]]; then
+ string="gravity resistant domains"
+ else
+ string="domains caught in the sinkhole"
+ fi
+ verbose=false
+ echo -e "Displaying $string:\n"
+ count=1
+ while IFS= read -r RD; do
+ echo " ${count}: ${RD}"
+ count=$((count+1))
+ done < "${listMain}"
else
- string="domains caught in the sinkhole"
+ echo -e " ${COL_LIGHT_RED}${listMain} does not exist!${COL_NC}"
fi
- verbose=false
- echo -e "Displaying $string:\n"
- count=1
- while IFS= read -r RD; do
- echo "${count}: ${RD}"
- count=$((count+1))
- done < "${listMain}"
exit 0;
}
diff --git a/advanced/Scripts/piholeCheckout.sh b/advanced/Scripts/piholeCheckout.sh
index e2c0ab11..102db2ba 100644
--- a/advanced/Scripts/piholeCheckout.sh
+++ b/advanced/Scripts/piholeCheckout.sh
@@ -9,7 +9,8 @@
# Please see LICENSE file for your rights under this license.
readonly PI_HOLE_FILES_DIR="/etc/.pihole"
-PH_TEST="true" source "${PI_HOLE_FILES_DIR}/automated install/basic-install.sh"
+PH_TEST="true"
+source "${PI_HOLE_FILES_DIR}/automated install/basic-install.sh"
# webInterfaceGitUrl set in basic-install.sh
# webInterfaceDir set in basic-install.sh
@@ -20,9 +21,8 @@ PH_TEST="true" source "${PI_HOLE_FILES_DIR}/automated install/basic-install.sh"
source "${setupVars}"
update="false"
-# Colour codes
-red="\e[1;31m"
-def="\e[0m"
+coltable="/opt/pihole/COL_TABLE"
+source ${coltable}
fully_fetch_repo() {
# Add upstream branches to shallow clone
@@ -41,10 +41,12 @@ fully_fetch_repo() {
get_available_branches() {
# Return available branches
local directory="${1}"
+ local output
cd "${directory}" || return 1
- # Get reachable remote branches
- git remote show origin | grep 'tracked' | sed 's/tracked//;s/ //g'
+ # Get reachable remote branches, but store STDERR as STDOUT variable
+ output=$( { git remote show origin | grep 'tracked' | sed 's/tracked//;s/ //g'; } 2>&1 )
+ echo "$output"
return
}
@@ -72,29 +74,36 @@ checkout_pull_branch() {
cd "${directory}" || return 1
oldbranch="$(git symbolic-ref HEAD)"
-
+
git checkout "${branch}" || return 1
- if [ "$(git diff "${oldbranch}" | grep -c "^")" -gt "0" ]; then
+ if [[ "$(git diff "${oldbranch}" | grep -c "^")" -gt "0" ]]; then
update="true"
fi
- git pull || return 1
+ git_pull=$(git pull || return 1)
+
+ if [[ "$git_pull" == *"up-to-date"* ]]; then
+ echo -e "\n ${INFO} $(git pull)"
+ else
+ echo -e "$git_pull\n"
+ fi
+
return 0
}
warning1() {
echo " Please note that changing branches severely alters your Pi-hole subsystems"
echo " Features that work on the master branch, may not on a development branch"
- echo -e " ${red}This feature is NOT supported unless a Pi-hole developer explicitly asks!${def}"
+ echo -e " ${COL_LIGHT_RED}This feature is NOT supported unless a Pi-hole developer explicitly asks!${COL_NC}"
read -r -p " Have you read and understood this? [y/N] " response
case ${response} in
[yY][eE][sS]|[yY])
- echo "::: Continuing with branch change."
+ echo ""
return 0
;;
*)
- echo "::: Branch change has been cancelled."
+ echo -e "\n ${INFO} Branch change has been cancelled"
return 1
;;
esac
@@ -107,24 +116,23 @@ checkout() {
# Avoid globbing
set -f
- #This is unlikely
+ # This is unlikely
if ! is_repo "${PI_HOLE_FILES_DIR}" ; then
- echo "::: Critical Error: Core Pi-hole repo is missing from system!"
- echo "::: Please re-run install script from https://github.com/pi-hole/pi-hole"
+ echo -e " ${COL_LIGHT_RED}Error: Core Pi-hole repo is missing from system!
+ Please re-run install script from https://github.com/pi-hole/pi-hole${COL_NC}"
exit 1;
fi
if [[ ${INSTALL_WEB} == "true" ]]; then
if ! is_repo "${webInterfaceDir}" ; then
- echo "::: Critical Error: Web Admin repo is missing from system!"
- echo "::: Please re-run install script from https://github.com/pi-hole/pi-hole"
+ echo -e " ${COL_LIGHT_RED}Error: Web Admin repo is missing from system!
+ Please re-run install script from https://github.com/pi-hole/pi-hole${COL_NC}"
exit 1;
fi
fi
if [[ -z "${1}" ]]; then
- echo "::: No option detected. Please use 'pihole checkout '."
- echo "::: Or enter the repository and branch you would like to check out:"
- echo "::: 'pihole checkout '"
+ echo -e " ${COL_LIGHT_RED}Invalid option${COL_NC}
+ Try 'pihole checkout --help' for more information."
exit 1
fi
@@ -134,72 +142,91 @@ checkout() {
if [[ "${1}" == "dev" ]] ; then
# Shortcut to check out development branches
- echo "::: Shortcut \"dev\" detected - checking out development / devel branches ..."
- echo "::: Pi-hole core"
- fetch_checkout_pull_branch "${PI_HOLE_FILES_DIR}" "development" || { echo "Unable to pull Core developement branch"; exit 1; }
+ echo -e " ${INFO} Shortcut \"dev\" detected - checking out development / devel branches..."
+ echo -e " ${INFO} Pi-hole core"
+ fetch_checkout_pull_branch "${PI_HOLE_FILES_DIR}" "development" || { echo " ${CROSS} Unable to pull Core developement branch"; exit 1; }
if [[ ${INSTALL_WEB} == "true" ]]; then
- echo "::: Web interface"
- fetch_checkout_pull_branch "${webInterfaceDir}" "devel" || { echo "Unable to pull Web development branch"; exit 1; }
+ echo -e " ${INFO} Web interface"
+ fetch_checkout_pull_branch "${webInterfaceDir}" "devel" || { echo " ${CROSS} Unable to pull Web development branch"; exit 1; }
fi
- echo "::: done!"
+ echo -e " ${TICK} Pi-hole core"
elif [[ "${1}" == "master" ]] ; then
# Shortcut to check out master branches
- echo "::: Shortcut \"master\" detected - checking out master branches ..."
- echo "::: Pi-hole core"
- fetch_checkout_pull_branch "${PI_HOLE_FILES_DIR}" "master" || { echo "Unable to pull Core master branch"; exit 1; }
+ echo -e " ${INFO} Shortcut \"master\" detected - checking out master branches..."
+ echo -e " ${INFO} Pi-hole core"
+ fetch_checkout_pull_branch "${PI_HOLE_FILES_DIR}" "master" || { echo " ${CROSS} Unable to pull Core master branch"; exit 1; }
if [[ ${INSTALL_WEB} == "true" ]]; then
- echo "::: Web interface"
- fetch_checkout_pull_branch "${webInterfaceDir}" "master" || { echo "Unable to pull web master branch"; exit 1; }
+ echo -e " ${INFO} Web interface"
+ fetch_checkout_pull_branch "${webInterfaceDir}" "master" || { echo " ${CROSS} Unable to pull Web master branch"; exit 1; }
fi
- echo "::: done!"
+ echo -e " ${TICK} Web interface"
+
elif [[ "${1}" == "core" ]] ; then
- echo -n "::: Fetching remote branches for Pi-hole core from ${piholeGitUrl} ... "
+ str="Fetching branches from ${piholeGitUrl}"
+ echo -ne " ${INFO} $str"
if ! fully_fetch_repo "${PI_HOLE_FILES_DIR}" ; then
- echo "::: Fetching all branches for Pi-hole core repo failed!"
+ echo -e " ${CROSS} $str"
exit 1
fi
corebranches=($(get_available_branches "${PI_HOLE_FILES_DIR}"))
- echo " done!"
- echo "::: ${#corebranches[@]} branches available"
- echo ":::"
- # Have to user chosing the branch he wants
+
+ if [[ "${corebranches[@]}" == *"master"* ]]; then
+ echo -e "${OVER} ${TICK} $str
+ ${INFO} ${#corebranches[@]} branches available for Pi-hole Core"
+ else
+ # Print STDERR output from get_available_branches
+ echo -e "${OVER} ${CROSS} $str\n\n${corebranches[*]}"
+ exit 1
+ fi
+
+ echo ""
+ # Have the user choose the branch they want
if ! (for e in "${corebranches[@]}"; do [[ "$e" == "${2}" ]] && exit 0; done); then
- echo "::: Requested branch \"${2}\" is not available!"
- echo "::: Available branches for core are:"
- for e in "${corebranches[@]}"; do echo "::: $e"; done
+ echo -e " ${INFO} Requested branch \"${2}\" is not available"
+ echo -e " ${INFO} Available branches for Core are:"
+ for e in "${corebranches[@]}"; do echo " - $e"; done
exit 1
fi
checkout_pull_branch "${PI_HOLE_FILES_DIR}" "${2}"
- elif [[ "${1}" == "web" && "${INSTALL_WEB}" == "true" ]] ; then
- echo -n "::: Fetching remote branches for the web interface from ${webInterfaceGitUrl} ... "
+ elif [[ "${1}" == "web" ]] && [[ "${INSTALL_WEB}" == "true" ]] ; then
+ str="Fetching branches from ${webInterfaceGitUrl}"
+ echo -ne " ${INFO} $str"
if ! fully_fetch_repo "${webInterfaceDir}" ; then
- echo "::: Fetching all branches for Pi-hole web interface repo failed!"
+ echo -e " ${CROSS} $str"
exit 1
fi
webbranches=($(get_available_branches "${webInterfaceDir}"))
- echo " done!"
- echo "::: ${#webbranches[@]} branches available"
- echo ":::"
- # Have to user chosing the branch he wants
+
+ if [[ "${corebranches[@]}" == *"master"* ]]; then
+ echo -e "${OVER} ${TICK} $str
+ ${INFO} ${#webbranches[@]} branches available for Web Admin"
+ else
+ # Print STDERR output from get_available_branches
+ echo -e "${OVER} ${CROSS} $str\n\n${corebranches[*]}"
+ exit 1
+ fi
+
+ echo ""
+ # Have the user choose the branch they want
if ! (for e in "${webbranches[@]}"; do [[ "$e" == "${2}" ]] && exit 0; done); then
- echo "::: Requested branch \"${2}\" is not available!"
- echo "::: Available branches for web are:"
- for e in "${webbranches[@]}"; do echo "::: $e"; done
+ echo -e " ${INFO} Requested branch \"${2}\" is not available"
+ echo -e " ${INFO} Available branches for Web Admin are:"
+ for e in "${webbranches[@]}"; do echo " - $e"; done
exit 1
fi
checkout_pull_branch "${webInterfaceDir}" "${2}"
else
- echo "::: Requested option \"${1}\" is not available!"
+ echo -e " ${INFO} Requested option \"${1}\" is not available"
exit 1
fi
# Force updating everything
if [[ ! "${1}" == "web" && "${update}" == "true" ]]; then
- echo "::: Running installer to upgrade your installation"
+ echo -e " ${INFO} Running installer to upgrade your installation"
if "${PI_HOLE_FILES_DIR}/automated install/basic-install.sh" --unattended; then
exit 0
else
- echo "Unable to complete update, contact Pi-hole"
+ echo -e " ${COL_LIGHT_RED} Error: Unable to complete update, please contact support${COL_NC}"
exit 1
fi
fi
diff --git a/advanced/Scripts/piholeLogFlush.sh b/advanced/Scripts/piholeLogFlush.sh
index cc553b32..2187f3ac 100755
--- a/advanced/Scripts/piholeLogFlush.sh
+++ b/advanced/Scripts/piholeLogFlush.sh
@@ -8,8 +8,11 @@
# This file is copyright under the latest version of the EUPL.
# Please see LICENSE file for your rights under this license.
+colfile="/opt/pihole/COL_TABLE"
+source ${colfile}
+
if [[ "$@" != *"quiet"* ]]; then
- echo -n "::: Flushing /var/log/pihole.log ..."
+ echo -ne " ${INFO} Flushing /var/log/pihole.log ..."
fi
if [[ "$@" == *"once"* ]]; then
# Nightly logrotation
@@ -41,5 +44,5 @@ else
fi
if [[ "$@" != *"quiet"* ]]; then
- echo "... done!"
+ echo -e "${OVER} ${TICK} Flushed /var/log/pihole.log"
fi
diff --git a/advanced/Scripts/update.sh b/advanced/Scripts/update.sh
index 6aef183b..e8155f1a 100755
--- a/advanced/Scripts/update.sh
+++ b/advanced/Scripts/update.sh
@@ -22,6 +22,10 @@ readonly PI_HOLE_FILES_DIR="/etc/.pihole"
PH_TEST=true
source ${PI_HOLE_FILES_DIR}/automated\ install/basic-install.sh
+colfile="/opt/pihole/COL_TABLE"
+source ${colfile}
+
+
# is_repo() sourced from basic-install.sh
# make_repo() sourced from basic-install.sh
# update_repo() source from basic-install.sh
@@ -49,14 +53,14 @@ GitCheckUpdateAvail() {
REMOTE="$(git rev-parse @{upstream})"
if [[ ${#LOCAL} == 0 ]]; then
- echo "::: Error: Local revision could not be obtained, ask Pi-hole support."
- echo "::: Additional debugging output:"
+ echo -e " ${COL_LIGHT_RED}Error: Local revision could not be obtained, ask Pi-hole support."
+ echo -e " Additional debugging output:${COL_NC}"
git status
exit
fi
if [[ ${#REMOTE} == 0 ]]; then
- echo "::: Error: Remote revision could not be obtained, ask Pi-hole support."
- echo "::: Additional debugging output:"
+ echo -e " ${COL_LIGHT_RED}Error: Remote revision could not be obtained, ask Pi-hole support."
+ echo -e " Additional debugging output:${COL_NC}"
git status
exit
fi
@@ -94,52 +98,52 @@ main() {
#This is unlikely
if ! is_repo "${PI_HOLE_FILES_DIR}" ; then
- echo "::: Critical Error: Core Pi-hole repo is missing from system!"
- echo "::: Please re-run install script from https://github.com/pi-hole/pi-hole"
+ echo -e " ${COL_LIGHT_RED}Critical Error: Core Pi-hole repo is missing from system!"
+ echo -e " Please re-run install script from https://github.com/pi-hole/pi-hole${COL_NC}"
exit 1;
fi
- echo "::: Checking for updates..."
+ echo -e " ${INFO} Checking for updates..."
if GitCheckUpdateAvail "${PI_HOLE_FILES_DIR}" ; then
core_update=true
- echo "::: Pi-hole Core: update available"
+ echo -e " ${INFO} Pi-hole Core:\t${COL_YELLOW}update available${COL_NC}"
else
core_update=false
- echo "::: Pi-hole Core: up to date"
+ echo -e " ${INFO} Pi-hole Core:\t${COL_LIGHT_GREEN}up to date${COL_NC}"
fi
if FTLcheckUpdate ; then
FTL_update=true
- echo "::: FTL: update available"
+ echo -e " ${INFO} FTL:\t\t${COL_YELLOW}update available${COL_NC}"
else
FTL_update=false
- echo "::: FTL: up to date"
+ echo -e " ${INFO} FTL:\t\t${COL_LIGHT_GREEN}up to date${COL_NC}"
fi
-
+
# Logic: Don't update FTL when there is a core update available
# since the core update will run the installer which will itself
# re-install (i.e. update) FTL
if ${FTL_update} && ! ${core_update}; then
- echo ":::"
- echo "::: FTL out of date"
+ echo ""
+ echo -e " ${INFO} FTL out of date"
FTLdetect
- echo ":::"
+ echo ""
fi
if [[ ${INSTALL_WEB} == true ]]; then
if ! is_repo "${ADMIN_INTERFACE_DIR}" ; then
- echo "::: Critical Error: Web Admin repo is missing from system!"
- echo "::: Please re-run install script from https://github.com/pi-hole/pi-hole"
+ echo -e " ${COL_LIGHT_RED}Critical Error: Web Admin repo is missing from system!"
+ echo -e " Please re-run install script from https://github.com/pi-hole/pi-hole${COL_NC}"
exit 1;
fi
if GitCheckUpdateAvail "${ADMIN_INTERFACE_DIR}" ; then
web_update=true
- echo "::: Web Interface: update available"
+ echo -e " ${INFO} Web Interface:\t${COL_YELLOW}update available${COL_NC}"
else
web_update=false
- echo "::: Web Interface: up to date"
+ echo -e " ${INFO} Web Interface:\t${COL_LIGHT_GREEN}up to date${COL_NC}"
fi
# Logic
@@ -154,64 +158,64 @@ main() {
if ! ${core_update} && ! ${web_update} ; then
if ! ${FTL_update} ; then
- echo ":::"
- echo "::: Everything is up to date!"
+ echo ""
+ echo -e " ${TICK} Everything is up to date!"
exit 0
fi
elif ! ${core_update} && ${web_update} ; then
- echo ":::"
- echo "::: Pi-hole Web Admin files out of date"
+ echo ""
+ echo -e " ${INFO} Pi-hole Web Admin files out of date"
getGitFiles "${ADMIN_INTERFACE_DIR}" "${ADMIN_INTERFACE_GIT_URL}"
elif ${core_update} && ! ${web_update} ; then
- echo ":::"
- echo "::: Pi-hole core files out of date"
+ echo ""
+ echo -e " ${INFO} Pi-hole core files out of date"
getGitFiles "${PI_HOLE_FILES_DIR}" "${PI_HOLE_GIT_URL}"
- ${PI_HOLE_FILES_DIR}/automated\ install/basic-install.sh --reconfigure --unattended || echo "Unable to complete update, contact Pi-hole" && exit 1
+ ${PI_HOLE_FILES_DIR}/automated\ install/basic-install.sh --reconfigure --unattended || echo -e " ${COL_LIGHT_RED}Unable to complete update, contact Pi-hole${COL_NC}" && exit 1
elif ${core_update} && ${web_update} ; then
- echo ":::"
- echo "::: Updating Pi-hole core and web admin files"
+ echo ""
+ echo -e " ${INFO} Updating Pi-hole core and web admin files"
getGitFiles "${PI_HOLE_FILES_DIR}" "${PI_HOLE_GIT_URL}"
- ${PI_HOLE_FILES_DIR}/automated\ install/basic-install.sh --unattended || echo "Unable to complete update, contact Pi-hole" && exit 1
+ ${PI_HOLE_FILES_DIR}/automated\ install/basic-install.sh --unattended || echo -e " ${COL_LIGHT_RED}Unable to complete update, contact Pi-hole${COL_NC}" && exit 1
else
- echo "*** Update script has malfunctioned, fallthrough reached. Please contact support"
+ echo -e " ${COL_LIGHT_RED}Update script has malfunctioned, fallthrough reached. Please contact support${COL_NC}"
exit 1
fi
else # Web Admin not installed, so only verify if core is up to date
if ! ${core_update}; then
if ! ${FTL_update} ; then
- echo ":::"
- echo "::: Everything is up to date!"
+ echo ""
+ echo -e " ${INFO} Everything is up to date!"
exit 0
fi
else
- echo ":::"
- echo "::: Pi-hole core files out of date"
+ echo ""
+ echo -e " ${INFO} Pi-hole core files out of date"
getGitFiles "${PI_HOLE_FILES_DIR}" "${PI_HOLE_GIT_URL}"
- ${PI_HOLE_FILES_DIR}/automated\ install/basic-install.sh --reconfigure --unattended || echo "Unable to complete update, contact Pi-hole" && exit 1
+ ${PI_HOLE_FILES_DIR}/automated\ install/basic-install.sh --reconfigure --unattended || echo -e " ${COL_LIGHT_RED}Unable to complete update, contact Pi-hole${COL_NC}" && exit 1
fi
fi
if [[ "${web_update}" == true ]]; then
web_version_current="$(/usr/local/bin/pihole version --admin --current)"
- echo ":::"
- echo "::: Web Admin version is now at ${web_version_current/* v/v}}"
- echo "::: If you had made any changes in '/var/www/html/admin/', they have been stashed using 'git stash'"
+ echo ""
+ echo -e " ${INFO} Web Admin version is now at ${web_version_current/* v/v}"
+ echo -e " ${INFO} If you had made any changes in '/var/www/html/admin/', they have been stashed using 'git stash'"
fi
if [[ "${core_update}" == true ]]; then
pihole_version_current="$(/usr/local/bin/pihole version --pihole --current)"
- echo ":::"
- echo "::: Pi-hole version is now at ${pihole_version_current/* v/v}}"
- echo "::: If you had made any changes in '/etc/.pihole/', they have been stashed using 'git stash'"
+ echo ""
+ echo -e " ${INFO} Pi-hole version is now at ${pihole_version_current/* v/v}"
+ echo -e " ${INFO} If you had made any changes in '/etc/.pihole/', they have been stashed using 'git stash'"
fi
if [[ ${FTL_update} == true ]]; then
- FTL_version_current="$(/usr/local/bin/pihole version --ftl --current)"
- echo ":::"
- echo "::: FTL version is now at ${FTL_version_current/* v/v}}"
+ FTL_version_current="$(/usr/bin/pihole-FTL tag)"
+ echo ""
+ echo -e " ${INFO} FTL version is now at ${FTL_version_current/* v/v}"
start_service pihole-FTL
enable_service pihole-FTL
fi
diff --git a/advanced/Scripts/webpage.sh b/advanced/Scripts/webpage.sh
index 8419aa8d..b05cdbfb 100755
--- a/advanced/Scripts/webpage.sh
+++ b/advanced/Scripts/webpage.sh
@@ -14,13 +14,17 @@ readonly dhcpconfig="/etc/dnsmasq.d/02-pihole-dhcp.conf"
# 03 -> wildcards
readonly dhcpstaticconfig="/etc/dnsmasq.d/04-pihole-static-dhcp.conf"
+coltable="/opt/pihole/COL_TABLE"
+if [[ -f ${coltable} ]]; then
+ source ${coltable}
+fi
+
helpFunc() {
echo "Usage: pihole -a [options]
Example: pihole -a -p password
Set options for the Admin Console
Options:
- -f, flush Flush the Pi-hole log
-p, password Set Admin Console password
-c, celsius Set Celsius as preferred temperature unit
-f, fahrenheit Set Fahrenheit as preferred temperature unit
@@ -58,6 +62,7 @@ delete_dnsmasq_setting() {
SetTemperatureUnit() {
change_setting "TEMPERATUREUNIT" "${unit}"
+ echo -e " ${TICK} Set temperature unit to ${unit}"
}
HashPassword() {
@@ -89,7 +94,7 @@ SetWebPassword() {
if [ "${PASSWORD}" == "" ]; then
change_setting "WEBPASSWORD" ""
- echo "Password Removed"
+ echo -e " ${TICK} Password Removed"
exit 0
fi
@@ -101,9 +106,9 @@ SetWebPassword() {
hash=$(HashPassword ${PASSWORD})
# Save hash to file
change_setting "WEBPASSWORD" "${hash}"
- echo "New password set"
+ echo -e " ${TICK} New password set"
else
- echo "Passwords don't match. Your password has not been changed"
+ echo -e " ${CROSS} Passwords don't match. Your password has not been changed"
exit 1
fi
}
@@ -213,11 +218,19 @@ Reboot() {
}
RestartDNS() {
- if [ -x "$(command -v systemctl)" ]; then
- systemctl restart dnsmasq &> /dev/null
- else
- service dnsmasq restart &> /dev/null
- fi
+ local str="Restarting dnsmasq"
+ echo -ne " ${INFO} ${str}..."
+ if [[ -x "$(command -v systemctl)" ]]; then
+ systemctl restart dnsmasq
+ else
+ service dnsmasq restart
+ fi
+
+ if [[ "$?" == 0 ]]; then
+ echo -e "${OVER} ${TICK} ${str}"
+ else
+ echo -e "${OVER} ${CROSS} ${str}"
+ fi
}
SetQueryLogOptions() {
@@ -404,13 +417,13 @@ Interfaces:
fi
if [[ "${args[2]}" == "all" ]]; then
- echo "Listening on all interfaces, permiting all origins, hope you have a firewall!"
+ echo -e " ${INFO} Listening on all interfaces, permiting all origins. Please use a firewall!"
change_setting "DNSMASQ_LISTENING" "all"
elif [[ "${args[2]}" == "local" ]]; then
- echo "Listening on all interfaces, permitting only origins that are at most one hop away (local devices)"
+ echo -e " ${INFO} Listening on all interfaces, permiting origins from one hop away (LAN)"
change_setting "DNSMASQ_LISTENING" "local"
else
- echo "Listening only on interface ${PIHOLE_INTERFACE}"
+ echo -e " ${INFO} Listening only on interface ${PIHOLE_INTERFACE}"
change_setting "DNSMASQ_LISTENING" "single"
fi
diff --git a/automated install/basic-install.sh b/automated install/basic-install.sh
index 053e04ba..10ad7aff 100755
--- a/automated install/basic-install.sh
+++ b/automated install/basic-install.sh
@@ -22,6 +22,7 @@ tmpLog=/tmp/pihole-install.log
instalLogLoc=/etc/pihole/install.log
setupVars=/etc/pihole/setupVars.conf
lighttpdConfig=/etc/lighttpd/lighttpd.conf
+coltable=/opt/pihole/COL_TABLE
webInterfaceGitUrl="https://github.com/pi-hole/AdminLTE.git"
webInterfaceDir="/var/www/html/admin"
@@ -54,15 +55,29 @@ skipSpaceCheck=false
reconfigure=false
runUnattended=false
+if [[ -f ${coltable} ]]; then
+ source ${coltable}
+else
+ COL_NC='\e[0m' # No Color
+ COL_LIGHT_GREEN='\e[1;32m'
+ COL_LIGHT_RED='\e[1;31m'
+ TICK="[${COL_LIGHT_GREEN}✓${COL_NC}]"
+ CROSS="[${COL_LIGHT_RED}✗${COL_NC}]"
+ INFO="[i]"
+ DONE="${COL_LIGHT_GREEN} done!${COL_NC}"
+ OVER="\r\033[K"
+fi
+
+
show_ascii_berry() {
- echo "
- .;;,.
+ echo -e "
+ ${COL_LIGHT_GREEN}.;;,.
.ccccc:,.
:cccclll:. ..,,
:ccccclll. ;ooodc
'ccll:;ll .oooodc
.;cll.;;looo:.
- .. ','.
+ ${COL_LIGHT_RED}.. ','.
.',,,,,,'.
.',,,,,,,,,,.
.',,,,,,,,,,,,....
@@ -75,7 +90,7 @@ show_ascii_berry() {
....',,,,,,,,,,,,.
.',,,,,,,,,'.
.',,,,,,'.
- ..'''.
+ ..'''.${COL_NC}
"
}
@@ -148,7 +163,7 @@ elif command -v rpm &> /dev/null; then
DNSMASQ_USER="nobody"
else
- echo "OS distribution not supported"
+ echo -e " ${CROSS} OS distribution not supported"
exit
fi
}
@@ -176,14 +191,14 @@ is_repo() {
make_repo() {
local directory="${1}"
local remoteRepo="${2}"
-
- echo -n "::: Cloning ${remoteRepo} into ${directory}..."
+ str="Clone ${remoteRepo} into ${directory}"
+ echo -ne " ${INFO} ${str}..."
# Clean out the directory if it exists for git to clone into
if [[ -d "${directory}" ]]; then
rm -rf "${directory}"
fi
git clone -q --depth 1 "${remoteRepo}" "${directory}" &> /dev/null || return $?
- echo " done!"
+ echo -e "${OVER} ${TICK} ${str}"
return 0
}
@@ -191,14 +206,15 @@ update_repo() {
local directory="${1}"
local curdir
+ local str="Update repo in ${1}"
curdir="${PWD}"
cd "${directory}" &> /dev/null || return 1
# Pull the latest commits
- echo -n "::: Updating repo in ${1}..."
+ echo -ne " ${INFO} ${str}..."
git stash --all --quiet &> /dev/null || true # Okay for stash failure
git clean --force -d || true # Okay for already clean directory
git pull --quiet &> /dev/null || return $?
- echo " done!"
+ echo -e "${OVER} ${TICK} ${str}"
cd "${curdir}" &> /dev/null || return 1
return 0
}
@@ -208,15 +224,16 @@ getGitFiles() {
# as arguments 1 and 2
local directory="${1}"
local remoteRepo="${2}"
- echo ":::"
- echo "::: Checking for existing repository..."
+ local str="Check for existing repository in ${1}"
+ echo -ne " ${INFO} ${str}..."
if is_repo "${directory}"; then
- update_repo "${directory}" || { echo "*** Error: Could not update local repository. Contact support."; exit 1; }
- echo " done!"
+ echo -e "${OVER} ${TICK} ${str}"
+ update_repo "${directory}" || { echo -e "\n ${COL_LIGHT_RED}Error: Could not update local repository. Contact support.${COL_NC}"; exit 1; }
else
- make_repo "${directory}" "${remoteRepo}" || { echo "Unable to clone repository, please contact support"; exit 1; }
- echo " done!"
+ echo -e "${OVER} ${CROSS} ${str}"
+ make_repo "${directory}" "${remoteRepo}" || { echo -e "\n ${COL_LIGHT_RED}Error: Could not update local repository. Contact support.${COL_NC}"; exit 1; }
fi
+ echo ""
return 0
}
@@ -224,9 +241,10 @@ resetRepo() {
local directory="${1}"
cd "${directory}" &> /dev/null || return 1
- echo -n "::: Resetting repo in ${1}..."
+ str="Resetting repository within ${1}..."
+ echo -ne " ${INFO} ${str}"
git reset --hard &> /dev/null || return $?
- echo " done!"
+ echo -e "${OVER} ${TICK} ${str}"
return 0
}
@@ -263,29 +281,35 @@ verifyFreeDiskSpace() {
# 50MB is the minimum space needed (45MB install (includes web admin bootstrap/jquery libraries etc) + 5MB one day of logs.)
# - Fourdee: Local ensures the variable is only created, and accessible within this function/void. Generally considered a "good" coding practice for non-global variables.
- echo "::: Verifying free disk space..."
+ local str="Disk space check"
local required_free_kilobytes=51200
local existing_free_kilobytes=$(df -Pk | grep -m1 '\/$' | awk '{print $4}')
# - Unknown free disk space , not a integer
if ! [[ "${existing_free_kilobytes}" =~ ^([0-9])+$ ]]; then
- echo "::: Unknown free disk space!"
- echo "::: We were unable to determine available free disk space on this system."
- echo "::: You may override this check and force the installation, however, it is not recommended"
- echo "::: To do so, pass the argument '--i_do_not_follow_recommendations' to the install script"
- echo "::: eg. curl -L https://install.pi-hole.net | bash /dev/stdin --i_do_not_follow_recommendations"
+ echo -e " ${CROSS} ${str}
+ Unknown free disk space!
+ We were unable to determine available free disk space on this system.
+ You may override this check, however, it is not recommended
+ The option '${COL_LIGHT_RED}--i_do_not_follow_recommendations${COL_NC}' can override this
+ e.g: curl -L https://install.pi-hole.net | bash /dev/stdin ${COL_LIGHT_RED}${COL_NC}"
exit 1
# - Insufficient free disk space
elif [[ ${existing_free_kilobytes} -lt ${required_free_kilobytes} ]]; then
- echo "::: Insufficient Disk Space!"
- echo "::: Your system appears to be low on disk space. Pi-hole recommends a minimum of $required_free_kilobytes KiloBytes."
- echo "::: You only have ${existing_free_kilobytes} KiloBytes free."
- echo "::: If this is a new install you may need to expand your disk."
- echo "::: Try running 'sudo raspi-config', and choose the 'expand file system option'"
- echo "::: After rebooting, run this installation again. (curl -L https://install.pi-hole.net | bash)"
+ echo -e " ${CROSS} ${str}
+ Your system disk appears to only have ${existing_free_kilobytes} KB free
+ It is recommended to have a minimum of ${required_free_kilobytes} KB to run the Pi-hole"
+ if command -v vcgencmd &> /dev/null; then
+ echo " If this is a new install you may need to expand your disk
+ Run 'sudo raspi-config', and choose the 'expand file system' option
+ After rebooting, run this installation again
+ e.g: curl -L https://install.pi-hole.net | bash"
+ fi
- echo "Insufficient free space, exiting..."
+ echo -e "\n ${COL_LIGHT_RED}Insufficient free space, exiting...${COL_NC}"
exit 1
+ else
+ echo -e " ${TICK} ${str}"
fi
}
@@ -319,10 +343,10 @@ chooseInterface() {
chooseInterfaceCmd=(whiptail --separate-output --radiolist "Choose An Interface (press space to select)" ${r} ${c} ${interfaceCount})
chooseInterfaceOptions=$("${chooseInterfaceCmd[@]}" "${interfacesArray[@]}" 2>&1 >/dev/tty) || \
- { echo "::: Cancel selected. Exiting"; exit 1; }
+ { echo -e " ${COL_LIGHT_RED}Cancel was selected, exiting installer${COL_NC}"; exit 1; }
for desiredInterface in ${chooseInterfaceOptions}; do
PIHOLE_INTERFACE=${desiredInterface}
- echo "::: Using interface: $PIHOLE_INTERFACE"
+ echo -e " ${INFO} Using interface: $PIHOLE_INTERFACE"
done
fi
}
@@ -372,7 +396,7 @@ use4andor6() {
cmd=(whiptail --separate-output --checklist "Select Protocols (press space to select)" ${r} ${c} 2)
options=(IPv4 "Block ads over IPv4" on
IPv6 "Block ads over IPv6" on)
- choices=$("${cmd[@]}" "${options[@]}" 2>&1 >/dev/tty) || { echo "::: Cancel selected. Exiting"; exit 1; }
+ choices=$("${cmd[@]}" "${options[@]}" 2>&1 >/dev/tty) || { echo -e " ${COL_LIGHT_RED}Cancel was selected, exiting installer${COL_NC}"; exit 1; }
for choice in ${choices}
do
case ${choice} in
@@ -388,11 +412,10 @@ use4andor6() {
if [[ ${useIPv6} ]]; then
useIPv6dialog
fi
- echo "::: IPv4 address: ${IPV4_ADDRESS}"
- echo "::: IPv6 address: ${IPV6_ADDRESS}"
+ echo -e " ${INFO} IPv4 address: ${IPV4_ADDRESS}"
+ echo -e " ${INFO} IPv6 address: ${IPV6_ADDRESS}"
if [ ! ${useIPv4} ] && [ ! ${useIPv6} ]; then
- echo "::: Cannot continue, neither IPv4 or IPv6 selected"
- echo "::: Exiting"
+ echo -e " ${COL_LIGHT_RED}Error: Neither IPv4 or IPv6 selected${COL_NC}"
exit 1
fi
}
@@ -417,19 +440,19 @@ It is also possible to use a DHCP reservation, but if you are going to do that,
# Ask for the IPv4 address
IPV4_ADDRESS=$(whiptail --backtitle "Calibrating network interface" --title "IPv4 address" --inputbox "Enter your desired IPv4 address" ${r} ${c} "${IPV4_ADDRESS}" 3>&1 1>&2 2>&3) || \
# Cancelling IPv4 settings window
- { ipSettingsCorrect=False; echo "::: Cancel selected. Exiting..."; exit 1; }
- echo "::: Your static IPv4 address: ${IPV4_ADDRESS}"
+ { ipSettingsCorrect=False; echo -e " ${COL_LIGHT_RED}Cancel was selected, exiting installer${COL_NC}"; exit 1; }
+ echo -e " ${INFO} Your static IPv4 address: ${IPV4_ADDRESS}"
# Ask for the gateway
IPv4gw=$(whiptail --backtitle "Calibrating network interface" --title "IPv4 gateway (router)" --inputbox "Enter your desired IPv4 default gateway" ${r} ${c} "${IPv4gw}" 3>&1 1>&2 2>&3) || \
# Cancelling gateway settings window
- { ipSettingsCorrect=False; echo "::: Cancel selected. Exiting..."; exit 1; }
- echo "::: Your static IPv4 gateway: ${IPv4gw}"
+ { ipSettingsCorrect=False; echo -e " ${COL_LIGHT_RED}Cancel was selected, exiting installer${COL_NC}"; exit 1; }
+ echo -e " ${INFO} Your static IPv4 gateway: ${IPv4gw}"
# Give the user a chance to review their settings before moving on
if whiptail --backtitle "Calibrating network interface" --title "Static IP Address" --yesno "Are these settings correct?
- IP address: ${IPV4_ADDRESS}
- Gateway: ${IPv4gw}" ${r} ${c}; then
+ IP address: ${IPV4_ADDRESS}
+ Gateway: ${IPv4gw}" ${r} ${c}; then
# After that's done, the loop ends and we move on
ipSettingsCorrect=True
else
@@ -456,19 +479,18 @@ setStaticIPv4() {
if [[ -f /etc/dhcpcd.conf ]]; then
# Debian Family
if grep -q "${IPV4_ADDRESS}" /etc/dhcpcd.conf; then
- echo "::: Static IP already configured"
+ echo -e " ${INFO} Static IP already configured"
else
setDHCPCD
ip addr replace dev "${PIHOLE_INTERFACE}" "${IPV4_ADDRESS}"
- echo ":::"
- echo "::: Setting IP to ${IPV4_ADDRESS}. You may need to restart after the install is complete."
- echo ":::"
+ echo -e " ${TICK} Set IP address to ${IPV4_ADDRESS%/*}
+ You may need to restart after the install is complete"
fi
elif [[ -f /etc/sysconfig/network-scripts/ifcfg-${PIHOLE_INTERFACE} ]];then
# Fedora Family
IFCFG_FILE=/etc/sysconfig/network-scripts/ifcfg-${PIHOLE_INTERFACE}
if grep -q "${IPV4_ADDRESS}" "${IFCFG_FILE}"; then
- echo "::: Static IP already configured"
+ echo -e " ${INFO} Static IP already configured"
else
IPADDR=$(echo "${IPV4_ADDRESS}" | cut -f1 -d/)
CIDR=$(echo "${IPV4_ADDRESS}" | cut -f2 -d/)
@@ -492,12 +514,11 @@ setStaticIPv4() {
# Tell NetworkManager to read our new sysconfig file
nmcli con load "${IFCFG_FILE}" > /dev/null
fi
- echo ":::"
- echo "::: Setting IP to ${IPV4_ADDRESS}. You may need to restart after the install is complete."
- echo ":::"
+ echo -e " ${TICK} Set IP address to ${IPV4_ADDRESS%/*}
+ You may need to restart after the install is complete"
fi
else
- echo "::: Warning: Unable to locate configuration file to set static IPv4 address!"
+ echo -e " ${INFO} Warning: Unable to locate configuration file to set static IPv4 address"
exit 1
fi
}
@@ -530,35 +551,37 @@ setDNS() {
Custom "")
DNSchoices=$(whiptail --separate-output --menu "Select Upstream DNS Provider. To use your own, select Custom." ${r} ${c} 6 \
"${DNSChooseOptions[@]}" 2>&1 >/dev/tty) || \
- { echo "::: Cancel selected. Exiting"; exit 1; }
+ { echo -e " ${COL_LIGHT_RED}Cancel was selected, exiting installer${COL_NC}"; exit 1; }
+
+ echo -ne " ${INFO} Using "
case ${DNSchoices} in
Google)
- echo "::: Using Google DNS servers."
+ echo "Google DNS servers"
PIHOLE_DNS_1="8.8.8.8"
PIHOLE_DNS_2="8.8.4.4"
;;
OpenDNS)
- echo "::: Using OpenDNS servers."
+ echo "OpenDNS servers"
PIHOLE_DNS_1="208.67.222.222"
PIHOLE_DNS_2="208.67.220.220"
;;
Level3)
- echo "::: Using Level3 servers."
+ echo "Level3 servers"
PIHOLE_DNS_1="4.2.2.1"
PIHOLE_DNS_2="4.2.2.2"
;;
Norton)
- echo "::: Using Norton ConnectSafe servers."
+ echo "Norton ConnectSafe servers"
PIHOLE_DNS_1="199.85.126.10"
PIHOLE_DNS_2="199.85.127.10"
;;
Comodo)
- echo "::: Using Comodo Secure servers."
+ echo "Comodo Secure servers"
PIHOLE_DNS_1="8.26.56.26"
PIHOLE_DNS_2="8.20.247.20"
;;
DNSWatch)
- echo "::: Using DNS.WATCH servers."
+ echo "DNS.WATCH servers"
PIHOLE_DNS_1="84.200.69.80"
PIHOLE_DNS_2="84.200.70.40"
;;
@@ -578,7 +601,7 @@ setDNS() {
fi
piholeDNS=$(whiptail --backtitle "Specify Upstream DNS Provider(s)" --inputbox "Enter your desired upstream DNS provider(s), seperated by a comma.\n\nFor example '8.8.8.8, 8.8.4.4'" ${r} ${c} "${prePopulate}" 3>&1 1>&2 2>&3) || \
- { echo "::: Cancel selected. Exiting"; exit 1; }
+ { echo -e " ${COL_LIGHT_RED}Cancel was selected, exiting installer${COL_NC}"; exit 1; }
PIHOLE_DNS_1=$(echo "${piholeDNS}" | sed 's/[, \t]\+/,/g' | awk -F, '{print$1}')
PIHOLE_DNS_2=$(echo "${piholeDNS}" | sed 's/[, \t]\+/,/g' | awk -F, '{print$2}')
if ! valid_ip "${PIHOLE_DNS_1}" || [ ! "${PIHOLE_DNS_1}" ]; then
@@ -617,14 +640,14 @@ setLogging() {
LogToggleCommand=(whiptail --separate-output --radiolist "Do you want to log queries?\n (Disabling will render graphs on the Admin page useless):" ${r} ${c} 6)
LogChooseOptions=("On (Recommended)" "" on
Off "" off)
- LogChoices=$("${LogToggleCommand[@]}" "${LogChooseOptions[@]}" 2>&1 >/dev/tty) || (echo "::: Cancel selected. Exiting..." && exit 1)
+ LogChoices=$("${LogToggleCommand[@]}" "${LogChooseOptions[@]}" 2>&1 >/dev/tty) || (echo -e " ${COL_LIGHT_RED}Cancel was selected, exiting installer${COL_NC}" && exit 1)
case ${LogChoices} in
"On (Recommended)")
- echo "::: Logging On."
+ echo -e " ${INFO} Logging On."
QUERY_LOGGING=true
;;
Off)
- echo "::: Logging Off."
+ echo -e " ${INFO} Logging Off."
QUERY_LOGGING=false
;;
esac
@@ -638,14 +661,14 @@ setAdminFlag() {
WebToggleCommand=(whiptail --separate-output --radiolist "Do you wish to install the web admin interface?" ${r} ${c} 6)
WebChooseOptions=("On (Recommended)" "" on
Off "" off)
- WebChoices=$("${WebToggleCommand[@]}" "${WebChooseOptions[@]}" 2>&1 >/dev/tty) || (echo "::: Cancel selected. Exiting..." && exit 1)
+ WebChoices=$("${WebToggleCommand[@]}" "${WebChooseOptions[@]}" 2>&1 >/dev/tty) || (echo -e " ${COL_LIGHT_RED}Cancel was selected, exiting installer${COL_NC}" && exit 1)
case ${WebChoices} in
"On (Recommended)")
- echo "::: Web Interface On."
+ echo -e " ${INFO} Web Interface On."
INSTALL_WEB=true
;;
Off)
- echo "::: Web Interface off."
+ echo -e " ${INFO} Web Interface off."
INSTALL_WEB=false
;;
esac
@@ -662,27 +685,27 @@ version_check_dnsmasq() {
local dnsmasq_pihole_01_location="/etc/dnsmasq.d/01-pihole.conf"
if [ -f ${dnsmasq_conf} ]; then
- echo -n "::: Existing dnsmasq.conf found..."
+ echo -ne " ${INFO} Existing dnsmasq.conf found..."
if grep -q ${dnsmasq_pihole_id_string} ${dnsmasq_conf}; then
echo " it is from a previous Pi-hole install."
- echo -n "::: Backing up dnsmasq.conf to dnsmasq.conf.orig..."
+ echo -ne " ${INFO} Backing up dnsmasq.conf to dnsmasq.conf.orig..."
mv -f ${dnsmasq_conf} ${dnsmasq_conf_orig}
- echo " done."
- echo -n "::: Restoring default dnsmasq.conf..."
+ echo -e "${OVER} ${TICK} Backing up dnsmasq.conf to dnsmasq.conf.orig..."
+ echo -ne " ${INFO} Restoring default dnsmasq.conf..."
cp ${dnsmasq_original_config} ${dnsmasq_conf}
- echo " done."
+ echo -e "${OVER} ${TICK} Restoring default dnsmasq.conf..."
else
echo " it is not a Pi-hole file, leaving alone!"
fi
else
- echo -n "::: No dnsmasq.conf found.. restoring default dnsmasq.conf..."
+ echo -ne " ${INFO} No dnsmasq.conf found... restoring default dnsmasq.conf..."
cp ${dnsmasq_original_config} ${dnsmasq_conf}
- echo " done."
+ echo -e "${OVER} ${TICK} No dnsmasq.conf found... restoring default dnsmasq.conf..."
fi
- echo -n "::: Copying 01-pihole.conf to /etc/dnsmasq.d/01-pihole.conf..."
+ echo -en " ${INFO} Copying 01-pihole.conf to /etc/dnsmasq.d/01-pihole.conf..."
cp ${dnsmasq_pihole_01_snippet} ${dnsmasq_pihole_01_location}
- echo " done."
+ echo -e "${OVER} ${TICK} Copying 01-pihole.conf to /etc/dnsmasq.d/01-pihole.conf"
sed -i "s/@INT@/$PIHOLE_INTERFACE/" ${dnsmasq_pihole_01_location}
if [[ "${PIHOLE_DNS_1}" != "" ]]; then
sed -i "s/@DNS1@/$PIHOLE_DNS_1/" ${dnsmasq_pihole_01_location}
@@ -720,9 +743,8 @@ clean_existing() {
installScripts() {
# Install the scripts from repository to their various locations
-
- echo ":::"
- echo -n "::: Installing scripts from ${PI_HOLE_LOCAL_REPO}..."
+ local str="Installing scripts from ${PI_HOLE_LOCAL_REPO}"
+ echo -ne " ${INFO} ${str}..."
# Clear out script files from Pi-hole scripts directory.
clean_existing "${PI_HOLE_INSTALL_DIR}" "${PI_HOLE_FILES[@]}"
@@ -734,19 +756,21 @@ installScripts() {
install -o "${USER}" -Dm755 -t "${PI_HOLE_INSTALL_DIR}" gravity.sh
install -o "${USER}" -Dm755 -t "${PI_HOLE_INSTALL_DIR}" ./advanced/Scripts/*.sh
install -o "${USER}" -Dm755 -t "${PI_HOLE_INSTALL_DIR}" ./automated\ install/uninstall.sh
+ install -o "${USER}" -Dm755 -t "${PI_HOLE_INSTALL_DIR}" ./advanced/Scripts/COL_TABLE
install -o "${USER}" -Dm755 -t /usr/local/bin/ pihole
install -Dm644 ./advanced/bash-completion/pihole /etc/bash_completion.d/pihole
- echo " done."
+ echo -e "${OVER} ${TICK} ${str}"
else
- echo " *** ERROR: Local repo ${PI_HOLE_LOCAL_REPO} not found, exiting."
+ echo -e "${OVER} ${CROSS} ${str}"
+ echo -e " ${COL_LIGHT_RED}Error: Local repo ${PI_HOLE_LOCAL_REPO} not found, exiting installer${COL_NC}"
exit 1
fi
}
installConfigs() {
# Install the configs from PI_HOLE_LOCAL_REPO to their various locations
- echo ":::"
- echo "::: Installing configs from ${PI_HOLE_LOCAL_REPO}..."
+ echo ""
+ echo -e " ${INFO} Installing configs from ${PI_HOLE_LOCAL_REPO}..."
version_check_dnsmasq
#Only mess with lighttpd configs if user has chosen to install web interface
@@ -770,39 +794,42 @@ installConfigs() {
stop_service() {
# Stop service passed in as argument.
# Can softfail, as process may not be installed when this is called
- echo ":::"
- echo -n "::: Stopping ${1} service..."
+ local str="Stopping ${1} service"
+ echo ""
+ echo -ne " ${INFO} ${str}..."
if command -v systemctl &> /dev/null; then
systemctl stop "${1}" &> /dev/null || true
else
service "${1}" stop &> /dev/null || true
fi
- echo " done."
+ echo -e "${OVER} ${TICK} ${str}..."
}
start_service() {
# Start/Restart service passed in as argument
# This should not fail, it's an error if it does
- echo ":::"
- echo -n "::: Starting ${1} service..."
+ local str="Starting ${1} service"
+ echo ""
+ echo -ne " ${INFO} ${str}..."
if command -v systemctl &> /dev/null; then
systemctl restart "${1}" &> /dev/null
else
service "${1}" restart &> /dev/null
fi
- echo " done."
+ echo -e "${OVER} ${TICK} ${str}"
}
enable_service() {
# Enable service so that it will start with next reboot
- echo ":::"
- echo -n "::: Enabling ${1} service to start on reboot..."
+ local str="Enabling ${1} service to start on reboot"
+ echo ""
+ echo -ne " ${INFO} ${str}..."
if command -v systemctl &> /dev/null; then
systemctl enable "${1}" &> /dev/null
else
update-rc.d "${1}" defaults &> /dev/null
fi
- echo " done."
+ echo -e "${OVER} ${TICK} ${str}"
}
update_package_cache() {
@@ -812,12 +839,14 @@ update_package_cache() {
#Update package cache on apt based OSes. Do this every time since
#it's quick and packages can be updated at any time.
- echo ":::"
- echo -n "::: Updating local cache of available packages..."
+ local str="Update local cache of available packages"
+ echo ""
+ echo -ne " ${INFO} ${str}..."
if eval "${UPDATE_PKG_CACHE}" &> /dev/null; then
- echo " done!"
+ echo -e "${OVER} ${TICK} ${str}"
else
- echo -en "\n!!! ERROR - Unable to update package cache. Please try \"${UPDATE_PKG_CACHE}\""
+ echo -e "${OVER} ${CROSS} ${str}"
+ echo -ne " ${COL_LIGHT_RED}Error: Unable to update package cache. Please try \"${UPDATE_PKG_CACHE}\"${COL_NC}"
return 1
fi
}
@@ -825,25 +854,37 @@ update_package_cache() {
notify_package_updates_available() {
# Let user know if they have outdated packages on their system and
# advise them to run a package update at soonest possible.
- echo ":::"
- echo -n "::: Checking ${PKG_MANAGER} for upgraded packages...."
+ local str="Checking ${PKG_MANAGER} for upgraded packages"
+ echo ""
+ echo -ne " ${INFO} ${str}..."
updatesToInstall=$(eval "${PKG_COUNT}")
- echo " done!"
- echo ":::"
+ #echo -e "\r\033[K ${TICK} ${str}"
+ #echo ""
if [[ -d "/lib/modules/$(uname -r)" ]]; then
if [[ ${updatesToInstall} -eq "0" ]]; then
- echo "::: Your system is up to date! Continuing with Pi-hole installation..."
+ echo -e "${OVER} ${TICK} ${str}... up to date!"
+ echo ""
else
- echo "::: There are ${updatesToInstall} updates available for your system!"
- echo "::: We recommend you update your OS after installing Pi-hole! "
- echo ":::"
+ echo -e "${OVER} ${TICK} ${str}... ${updatesToInstall} updates available"
+ echo -e " ${INFO} ${COL_LIGHT_GREEN}It is recommended to update your OS after installing the Pi-hole! ${COL_NC}"
+ echo ""
fi
else
- echo "::: Kernel update detected, please reboot your system and try again if your installation fails."
+ echo -e "${OVER} ${CROSS} ${str}
+ Kernel update detected. If the install fails, please reboot and try again"
+ echo ""
fi
}
+counter=0
install_dependent_packages() {
+ counter=$((counter+1))
+ if [ ${counter} == 1 ]; then
+ echo -e " ${INFO} Installer Dependency checks..."
+ else
+ echo -e " ${INFO} Main Dependency checks..."
+ fi
+
# Install packages passed in via argument array
# No spinner - conflicts with set -e
declare -a argArray1=("${!1}")
@@ -856,11 +897,11 @@ install_dependent_packages() {
# installed by us, and remove only the installed packages, and not the entire list.
if command -v debconf-apt-progress &> /dev/null; then
for i in "${argArray1[@]}"; do
- echo -n "::: Checking for $i..."
+ echo -ne " ${INFO} Checking for $i..."
if dpkg-query -W -f='${Status}' "${i}" 2>/dev/null | grep "ok installed" &> /dev/null; then
- echo " installed!"
+ echo -e "${OVER} ${TICK} Checking for $i"
else
- echo " added to install list!"
+ echo -e "${OVER} ${CROSS} Checking for $i (will be installed)"
installArray+=("${i}")
fi
done
@@ -869,16 +910,17 @@ install_dependent_packages() {
debconf-apt-progress -- "${PKG_INSTALL[@]}" "${installArray[@]}"
return
fi
+ echo ""
return 0
fi
#Fedora/CentOS
for i in "${argArray1[@]}"; do
- echo -n "::: Checking for $i..."
+ echo -ne " ${INFO} Checking for $i..."
if ${PKG_MANAGER} -q list installed "${i}" &> /dev/null; then
- echo " installed!"
+ echo -e "${OVER} ${TICK} Checking for $i"
else
- echo " added to install list!"
+ echo -e "${OVER} ${CROSS} Checking for $i (will be installed)"
installArray+=("${i}")
fi
done
@@ -886,67 +928,82 @@ install_dependent_packages() {
"${PKG_INSTALL[@]}" "${installArray[@]}" &> /dev/null
return
fi
+ echo ""
return 0
}
CreateLogFile() {
# Create logfiles if necessary
- echo ":::"
- echo -n "::: Creating log file and changing owner to dnsmasq..."
+ local str="Creating log and changing owner to dnsmasq"
+ echo ""
+ echo -ne " ${INFO} ${str}..."
if [ ! -f /var/log/pihole.log ]; then
touch /var/log/pihole.log
chmod 644 /var/log/pihole.log
chown "${DNSMASQ_USER}":root /var/log/pihole.log
- echo " done!"
+ echo -e "${OVER} ${TICK} ${str}"
else
- echo " already exists!"
+ echo -e " ${COL_LIGHT_GREEN}log already exists!${COL_NC}"
fi
}
installPiholeWeb() {
# Install the web interface
- echo ":::"
- echo "::: Installing pihole custom index page..."
+
+ echo ""
+ echo " ${INFO} Installing blocking page..."
if [ -d "/var/www/html/pihole" ]; then
+
+ local str="Installing index.php"
+ echo -ne " ${INFO} ${str}..."
if [ -f "/var/www/html/pihole/index.php" ]; then
- echo "::: Existing index.php detected, not overwriting"
+ echo -e " ${COL_LIGHT_GREEN}detected index.php, not overwriting${COL_NC}"
else
- echo -n "::: index.php missing, replacing... "
cp ${PI_HOLE_LOCAL_REPO}/advanced/index.php /var/www/html/pihole/
- echo " done!"
+ echo -e "${OVER} ${TICK} ${str}"
fi
+ local str="Installing index.js"
+ echo -ne " ${INFO} ${str}..."
if [ -f "/var/www/html/pihole/index.js" ]; then
- echo "::: Existing index.js detected, not overwriting"
+ echo -e " ${COL_LIGHT_GREEN}detected index.js, not overwriting${COL_NC}"
else
- echo -n "::: index.js missing, replacing... "
cp ${PI_HOLE_LOCAL_REPO}/advanced/index.js /var/www/html/pihole/
- echo " done!"
+ echo -e "${OVER} ${TICK} ${str}"
fi
+ local str="Installing blockingpage.css"
+ echo -ne " ${INFO} ${str}..."
if [ -f "/var/www/html/pihole/blockingpage.css" ]; then
- echo "::: Existing blockingpage.css detected, not overwriting"
+ echo -e " ${COL_LIGHT_GREEN}detected blockingpage.css, not overwriting${COL_NC}"
else
- echo -n "::: blockingpage.css missing, replacing... "
cp ${PI_HOLE_LOCAL_REPO}/advanced/blockingpage.css /var/www/html/pihole
- echo " done!"
+ echo -e "${OVER} ${TICK} ${str}"
fi
else
- echo "::: Creating directory for blocking page"
+ local str="Creating directory for blocking page, and copying files"
+ echo -ne " ${INFO} ${str}..."
install -d /var/www/html/pihole
install -D ${PI_HOLE_LOCAL_REPO}/advanced/{index,blockingpage}.* /var/www/html/pihole/
+ echo -e "${OVER} ${TICK} ${str}"
+
+ local str="Backing up index.lighttpd.html"
+ echo -ne " ${INFO} ${str}..."
if [ -f /var/www/html/index.lighttpd.html ]; then
mv /var/www/html/index.lighttpd.html /var/www/html/index.lighttpd.orig
+ echo -e "${OVER} ${TICK} ${str}"
else
- printf "\n:::\tNo default index.lighttpd.html file found... not backing up"
+ echo -e "${OVER} ${CROSS} ${str}"
+ echo -e " No default index.lighttpd.html file found... not backing up"
fi
- echo " done!"
+
fi
# Install Sudoer file
- echo ":::"
- echo -n "::: Installing sudoer file..."
+ echo ""
+ local str="Installing sudoer file"
+ echo -ne " ${INFO} ${str}..."
mkdir -p /etc/sudoers.d/
cp ${PI_HOLE_LOCAL_REPO}/advanced/pihole.sudo /etc/sudoers.d/pihole
# Add lighttpd user (OS dependent) to sudoers file
@@ -959,50 +1016,56 @@ installPiholeWeb() {
fi
chmod 0440 /etc/sudoers.d/pihole
- echo " done!"
+ echo -e "${OVER} ${TICK} ${str}"
}
installCron() {
# Install the cron job
- echo ":::"
- echo -n "::: Installing latest Cron script..."
+ local str="Installing latest Cron script"
+ echo ""
+ echo -ne " ${INFO} ${str}..."
cp ${PI_HOLE_LOCAL_REPO}/advanced/pihole.cron /etc/cron.d/pihole
- echo " done!"
+ echo -e "${OVER} ${TICK} ${str}"
}
runGravity() {
# Run gravity.sh to build blacklists
- echo ":::"
- echo "::: Preparing to run gravity.sh to refresh hosts..."
+ echo ""
+ echo -e " ${INFO} Preparing to run gravity.sh to refresh hosts..."
if ls /etc/pihole/list* 1> /dev/null 2>&1; then
- echo "::: Cleaning up previous install (preserving whitelist/blacklist)"
+ echo -e " ${INFO} Cleaning up previous install (preserving whitelist/blacklist)"
rm /etc/pihole/list.*
fi
# Test if /etc/pihole/adlists.default exists
if [[ ! -e /etc/pihole/adlists.default ]]; then
cp ${PI_HOLE_LOCAL_REPO}/adlists.default /etc/pihole/adlists.default
fi
- echo "::: Running gravity.sh"
+ echo -e " ${INFO} Running gravity.sh"
{ /opt/pihole/gravity.sh; }
}
create_pihole_user() {
# Check if user pihole exists and create if not
- echo "::: Checking if user 'pihole' exists..."
+ local str="Checking for user 'pihole'"
+ echo -ne " ${INFO} ${str}..."
if id -u pihole &> /dev/null; then
- echo "::: User 'pihole' already exists"
+ echo -ne "${OVER} ${TICK} ${str}"
else
- echo "::: User 'pihole' doesn't exist. Creating..."
+ echo -ne "${OVER} ${CROSS} ${str}"
+ local str="Creating user 'pihole'"
+ echo -ne " ${INFO} ${str}..."
useradd -r -s /usr/sbin/nologin pihole
+ echo -ne "${OVER} ${TICK} ${str}"
fi
}
configureFirewall() {
# Allow HTTP and DNS traffic
+ echo ""
if firewall-cmd --state &> /dev/null; then
whiptail --title "Firewall in use" --yesno "We have detected a running firewall\n\nPi-hole currently requires HTTP and DNS port access.\n\n\n\nInstall Pi-hole default firewall rules?" ${r} ${c} || \
- { echo -e ":::\n::: Not installing firewall rulesets."; return 0; }
- echo -e ":::\n:::\n Configuring FirewallD for httpd and dnsmasq."
+ { echo -e " ${INFO} Not installing firewall rulesets."; return 0; }
+ echo -e " ${TICK} Configuring FirewallD for httpd and dnsmasq."
firewall-cmd --permanent --add-service=http --add-service=dns
firewall-cmd --reload
return 0
@@ -1012,8 +1075,8 @@ configureFirewall() {
# then check and insert our Rules above the DROP/REJECT Rule.
if iptables -S INPUT | head -n1 | grep -qv '^-P.*ACCEPT$' || iptables -S INPUT | tail -n1 | grep -qv '^-\(A\|P\).*ACCEPT$'; then
whiptail --title "Firewall in use" --yesno "We have detected a running firewall\n\nPi-hole currently requires HTTP and DNS port access.\n\n\n\nInstall Pi-hole default firewall rules?" ${r} ${c} || \
- { echo -e ":::\n::: Not installing firewall rulesets."; return 0; }
- echo -e ":::\n::: Installing new IPTables firewall rulesets."
+ { echo -e " ${INFO} Not installing firewall rulesets."; return 0; }
+ echo -e " ${TICK} Installing new IPTables firewall rulesets."
# Check chain first, otherwise a new rule will duplicate old ones
iptables -C INPUT -p tcp -m tcp --dport 80 -j ACCEPT &> /dev/null || iptables -I INPUT 1 -p tcp -m tcp --dport 80 -j ACCEPT
iptables -C INPUT -p tcp -m tcp --dport 53 -j ACCEPT &> /dev/null || iptables -I INPUT 1 -p tcp -m tcp --dport 53 -j ACCEPT
@@ -1022,10 +1085,10 @@ configureFirewall() {
return 0
fi
else
- echo -e ":::\n::: No active firewall detected.. skipping firewall configuration."
+ echo -e " ${INFO} No active firewall detected.. skipping firewall configuration."
return 0
fi
- echo -e ":::\n::: Skipping firewall configuration."
+ echo -e " ${INFO} Skipping firewall configuration."
}
finalExports() {
@@ -1069,8 +1132,9 @@ finalExports() {
installLogrotate() {
# Install the logrotate script
- echo ":::"
- echo -n "::: Installing latest logrotate script..."
+ local str="Installing latest logrotate script"
+ echo ""
+ echo -ne " ${INFO} ${str}..."
cp ${PI_HOLE_LOCAL_REPO}/advanced/logrotate /etc/pihole/logrotate
# Different operating systems have different user / group
# settings for logrotate that makes it impossible to create
@@ -1082,7 +1146,7 @@ installLogrotate() {
if [[ ! -z $logusergroup ]]; then
sed -i "s/# su #/su ${logusergroup}/g;" /etc/pihole/logrotate
fi
- echo " done!"
+ echo -e "${OVER} ${TICK} ${str}"
}
installPihole() {
@@ -1099,7 +1163,8 @@ installPihole() {
if [ -x "$(command -v lighty-enable-mod)" ]; then
lighty-enable-mod fastcgi fastcgi-php > /dev/null || true
else
- printf "\n:::\tWarning: 'lighty-enable-mod' utility not found. Please ensure fastcgi is enabled if you experience issues.\n"
+ echo -e " ${INFO} Warning: 'lighty-enable-mod' utility not found
+ Please ensure fastcgi is enabled if you experience issues\n"
fi
fi
installScripts
@@ -1110,7 +1175,7 @@ installPihole() {
fi
installCron
installLogrotate
- FTLdetect || echo "::: FTL Engine not installed."
+ FTLdetect || echo -e " ${CROSS} FTL Engine not installed."
configureFirewall
finalExports
#runGravity
@@ -1142,7 +1207,7 @@ updatePihole() {
fi
installCron
installLogrotate
- FTLdetect || echo "::: FTL Engine not installed."
+ FTLdetect || echo -e " ${CROSS} FTL Engine not installed."
finalExports #re-export setupVars.conf to account for any new vars added in new versions
#runGravity
}
@@ -1151,16 +1216,16 @@ updatePihole() {
checkSelinux() {
if command -v getenforce &> /dev/null; then
- echo ":::"
- echo -n "::: SELinux Support Detected... Mode: "
+ echo ""
+ echo -ne " ${INFO} SELinux Support Detected... Mode: "
enforceMode=$(getenforce)
echo "${enforceMode}"
if [[ "${enforceMode}" == "Enforcing" ]]; then
whiptail --title "SELinux Enforcing Detected" --yesno "SELinux is being Enforced on your system!\n\nPi-hole currently does not support SELinux, but you may still continue with the installation.\n\nNote: Admin UI Will not function fully without setting your policies correctly\n\nContinue installing Pi-hole?" ${r} ${c} || \
- { echo ":::"; echo "::: Not continuing install after SELinux Enforcing detected."; exit 1; }
- echo ":::"
- echo "::: Continuing installation with SELinux Enforcing."
- echo "::: Please refer to official SELinux documentation to create a custom policy."
+ { echo ""; echo -e " ${COL_LIGHT_RED}SELinux Enforcing detected, exiting installer${COL_NC}"; exit 1; }
+ echo ""
+ echo -e " ${INFO} Continuing installation with SELinux Enforcing"
+ echo -e " ${INFO} Please refer to official SELinux documentation to create a custom policy"
fi
fi
}
@@ -1211,15 +1276,15 @@ update_dialogs() {
UpdateCmd=$(whiptail --title "Existing Install Detected!" --menu "\n\nWe have detected an existing install.\n\nPlease choose from the following options: \n($strAdd)" ${r} ${c} 2 \
"${opt1a}" "${opt1b}" \
"${opt2a}" "${opt2b}" 3>&2 2>&1 1>&3) || \
- { echo "::: Cancel selected. Exiting"; exit 1; }
+ { echo -e " ${COL_LIGHT_RED}Cancel was selected, exiting installer${COL_NC}"; exit 1; }
case ${UpdateCmd} in
${opt1a})
- echo "::: ${opt1a} option selected."
+ echo -e " ${INFO} ${opt1a} option selected."
useUpdateVars=true
;;
${opt2a})
- echo "::: ${opt2a} option selected"
+ echo -e " ${INFO} ${opt2a} option selected"
useUpdateVars=false
;;
esac
@@ -1227,14 +1292,14 @@ update_dialogs() {
clone_or_update_repos() {
if [[ "${reconfigure}" == true ]]; then
- echo "::: --reconfigure passed to install script. Resetting changes to local repos"
+ echo " ${INFO} Performing reconfiguration, skipping download of local repos"
resetRepo ${PI_HOLE_LOCAL_REPO} || \
- { echo "!!! Unable to reset ${PI_HOLE_LOCAL_REPO}, unable to continue."; \
+ { echo -e " ${COL_LIGHT_RED}Unable to reset ${PI_HOLE_LOCAL_REPO}, exiting installer${COL_NC}"; \
exit 1; \
}
if [[ ${INSTALL_WEB} == true ]]; then
resetRepo ${webInterfaceDir} || \
- { echo "!!! Unable to reset ${webInterfaceDir}, unable to continue."; \
+ { echo -e " ${COL_LIGHT_RED}Unable to reset ${webInterfaceDir}, exiting installer${COL_NC}"; \
exit 1; \
}
fi
@@ -1245,12 +1310,12 @@ clone_or_update_repos() {
exit 1; \
}
- if [[ ${INSTALL_WEB} == true ]]; then
- getGitFiles ${webInterfaceDir} ${webInterfaceGitUrl} || \
- { echo "!!! Unable to clone ${webInterfaceGitUrl} into ${webInterfaceDir}, unable to continue."; \
- exit 1; \
- }
- fi
+ if [[ ${INSTALL_WEB} == true ]]; then
+ getGitFiles ${webInterfaceDir} ${webInterfaceGitUrl} || \
+ { echo -e " ${COL_LIGHT_RED}Unable to clone ${webInterfaceGitUrl} into ${webInterfaceDir}, exiting installer${COL_NC}"; \
+ exit 1; \
+ }
+ fi
fi
}
@@ -1259,13 +1324,15 @@ FTLinstall() {
local binary="${1}"
local latesttag
local orig_dir
- echo -n "::: Installing FTL... "
+ local str="Installing FTL"
+ echo -ne " ${INFO} ${str}..."
orig_dir="${PWD}"
latesttag=$(curl -sI https://github.com/pi-hole/FTL/releases/latest | grep "Location" | awk -F '/' '{print $NF}')
# Tags should always start with v, check for that.
if [[ ! "${latesttag}" == v* ]]; then
- echo "failed (error in getting latest release location from GitHub)"
+ echo -e "${OVER} ${CROSS} ${str}"
+ echo -e " ${COL_LIGHT_RED}Error: Unable to get latest release location from GitHub${COL_NC}"
return 1
fi
if curl -sSL --fail "https://github.com/pi-hole/FTL/releases/download/${latesttag%$'\r'}/${binary}" -o "/tmp/${binary}"; then
@@ -1280,60 +1347,64 @@ FTLinstall() {
rm /tmp/${binary} /tmp/${binary}.sha1
cd "${orig_dir}"
install -T -m 0755 "${PI_HOLE_LOCAL_REPO}/advanced/pihole-FTL.service" "/etc/init.d/pihole-FTL"
- echo "done."
+ echo -e "${OVER} ${TICK} ${str}"
return 0
else
- echo "failed (download of binary from Github failed)"
+ echo -e "${OVER} ${CROSS} ${str}"
+ echo -e " ${COL_LIGHT_RED}Error: Download of binary from Github failed${COL_NC}"
cd "${orig_dir}"
return 1
fi
else
cd "${orig_dir}"
- echo "failed (URL not found.)"
+ echo -e "${OVER} ${CROSS} ${str}"
+ echo -e " ${COL_LIGHT_RED}Error: URL not found${COL_NC}"
fi
}
FTLdetect() {
# Detect suitable FTL binary platform
- echo ":::"
- echo "::: Downloading latest version of FTL..."
+ echo ""
+ echo -e " ${INFO} Downloading latest version of FTL..."
local machine
local binary
machine=$(uname -m)
- if [[ $machine == arm* || $machine == *aarch* ]]; then
+ local str="Detecting architecture"
+ echo -ne " ${INFO} ${str}..."
+ if [[ ${machine} == arm* || ${machine} == *aarch* ]]; then
# ARM
local rev=$(uname -m | sed "s/[^0-9]//g;")
local lib=$(ldd /bin/ls | grep -E '^\s*/lib' | awk '{ print $1 }')
if [[ "$lib" == "/lib/ld-linux-aarch64.so.1" ]]; then
- echo "::: Detected ARM-aarch64 architecture"
+ echo -e "${OVER} ${TICK} Detected ARM-aarch64 architecture"
binary="pihole-FTL-aarch64-linux-gnu"
elif [[ "$lib" == "/lib/ld-linux-armhf.so.3" ]]; then
if [ "$rev" -gt "6" ]; then
- echo "::: Detected ARM-hf architecture (armv7+)"
+ echo -e "${OVER} ${TICK} Detected ARM-hf architecture (armv7+)"
binary="pihole-FTL-arm-linux-gnueabihf"
else
- echo "::: Detected ARM-hf architecture (armv6 or lower)"
- echo "::: Using ARM binary"
+ echo -e "${OVER} ${TICK} Detected ARM-hf architecture (armv6 or lower) Using ARM binary"
binary="pihole-FTL-arm-linux-gnueabi"
fi
else
- echo "::: Detected ARM architecture"
+ echo -e "${OVER} ${TICK} Detected ARM architecture"
binary="pihole-FTL-arm-linux-gnueabi"
fi
- elif [[ $machine == x86_64 ]]; then
+ elif [[ ${machine} == x86_64 ]]; then
# 64bit
- echo "::: Detected x86_64 architecture"
+ echo -e "${OVER} ${TICK} Detected x86_64 architecture"
binary="pihole-FTL-linux-x86_64"
else
# Something else - we try to use 32bit executable and warn the user
- if [[ ! $machine == i686 ]]; then
- echo "::: Not able to detect architecture (unknown: ${machine}), trying 32bit executable"
- echo "::: Contact Pi-hole support if you experience problems (like FTL not running)"
+ if [[ ! ${machine} == i686 ]]; then
+ echo -e "${OVER} ${CROSS} ${str}...
+ ${COL_LIGHT_RED}Not able to detect architecture (unknown: ${machine}), trying 32bit executable
+ Contact support if you experience issues (e.g: FTL not running)${COL_NC}"
else
- echo "::: Detected 32bit (i686) architecture"
+ echo -e "${OVER} ${TICK} Detected 32bit (i686) architecture"
fi
binary="pihole-FTL-linux-x86_32"
fi
@@ -1347,22 +1418,28 @@ main() {
######## FIRST CHECK ########
# Must be root to install
show_ascii_berry
- echo ":::"
+ local str="Root user check"
+ echo ""
+
if [[ ${EUID} -eq 0 ]]; then
- echo "::: You are root."
+ echo -e " ${TICK} ${str}"
else
- echo "::: Script called with non-root privileges. The Pi-hole installs server packages and configures"
- echo "::: system networking, it requires elevated rights. Please check the contents of the script for"
- echo "::: any concerns with this requirement. Please be sure to download this script from a trusted source."
- echo ":::"
- echo "::: Detecting the presence of the sudo utility for continuation of this install..."
+ echo -e " ${CROSS} ${str}
+ Script called with non-root privileges
+ The Pi-hole requires elevated privleges to install and run
+ Please check the installer for any concerns regarding this requirement
+ Make sure to download this script from a trusted source"
+ echo ""
+ echo -ne " ${INFO} Sudo utility check"
if command -v sudo &> /dev/null; then
- echo "::: Utility sudo located."
+ echo -e "${OVER} ${TICK} Sudo utility check"
exec curl -sSL https://raw.githubusercontent.com/pi-hole/pi-hole/master/automated%20install/basic-install.sh | sudo bash "$@"
exit $?
else
- echo "::: sudo is needed for the Web interface to run pihole commands. Please run this script as root and it will be automatically installed."
+ echo -e "${OVER} ${CROSS} Sudo utility check
+ Sudo is needed for the Web Interface to run pihole commands\n
+ ${COL_LIGHT_RED}Please re-run this installer as root${COL_NC}"
exit 1
fi
fi
@@ -1373,15 +1450,15 @@ main() {
# Check arguments for the undocumented flags
for var in "$@"; do
case "$var" in
- "--reconfigure" ) reconfigure=true;;
- "--i_do_not_follow_recommendations" ) skipSpaceCheck=false;;
- "--unattended" ) runUnattended=true;;
+ "--reconfigure" ) reconfigure=true;;
+ "--i_do_not_follow_recommendations" ) skipSpaceCheck=false;;
+ "--unattended" ) runUnattended=true;;
esac
done
if [[ -f ${setupVars} ]]; then
if [[ "${runUnattended}" == true ]]; then
- echo "::: --unattended passed to install script, no whiptail dialogs will be displayed"
+ echo -e " ${INFO} Performing unattended setup, no whiptail dialogs will be displayed"
useUpdateVars=true
else
update_dialogs
@@ -1391,7 +1468,7 @@ main() {
# Start the installer
# Verify there is enough disk space for the install
if [[ "${skipSpaceCheck}" == true ]]; then
- echo "::: --i_do_not_follow_recommendations passed to script, skipping free disk space verification!"
+ echo -e " ${INFO} Skipping free disk space verification"
else
verifyFreeDiskSpace
fi
@@ -1414,7 +1491,7 @@ main() {
welcomeDialogs
# Create directory for Pi-hole storage
mkdir -p /etc/pihole/
-
+
stop_service dnsmasq
if [[ ${INSTALL_WEB} == true ]]; then
stop_service lighttpd
@@ -1476,7 +1553,7 @@ main() {
fi
fi
- echo "::: Restarting services..."
+ echo -e " ${INFO} Restarting services..."
# Start services
start_service dnsmasq
enable_service dnsmasq
@@ -1491,40 +1568,34 @@ main() {
start_service pihole-FTL
enable_service pihole-FTL
- echo "::: done."
-
if [[ "${useUpdateVars}" == false ]]; then
displayFinalMessage "${pw}"
fi
-
- echo ":::"
- if [[ "${useUpdateVars}" == false ]]; then
- echo "::: Installation Complete! Configure your devices to use the Pi-hole as their DNS server using:"
- echo "::: ${IPV4_ADDRESS%/*}"
- echo "::: ${IPV6_ADDRESS}"
- echo ":::"
- echo "::: If you set a new IP address, you should restart the Pi."
- if [[ ${INSTALL_WEB} == true ]]; then
- echo "::: View the web interface at http://pi.hole/admin or http://${IPV4_ADDRESS%/*}/admin"
- fi
- else
- echo "::: Update complete!"
- fi
-
+
if [[ ${INSTALL_WEB} == true ]]; then
if (( ${#pw} > 0 )) ; then
- echo ":::"
- echo "::: Note: As security measure a password has been installed for your web interface"
- echo "::: The currently set password is"
- echo "::: ${pw}"
- echo ":::"
- echo "::: You can always change it using"
- echo "::: pihole -a -p"
+ echo -e " ${INFO} Web Interface password: ${COL_LIGHT_GREEN}${pw}${COL_NC}
+ This can be changed using 'pihole -a -p'"
+ echo ""
fi
fi
- echo ":::"
- echo "::: The install log is located at: /etc/pihole/install.log"
+ if [[ "${useUpdateVars}" == false ]]; then
+ if [[ ${INSTALL_WEB} == true ]]; then
+ echo -e " View the web interface at http://pi.hole/admin or http://${IPV4_ADDRESS%/*}/admin"
+ echo ""
+ fi
+ echo " You may now configure your devices to use the Pi-hole as their DNS server"
+ [[ -n "${IPV4_ADDRESS%/*}" ]] && echo -e " ${INFO} Pi-hole DNS (IPv4): ${IPV4_ADDRESS%/*}"
+ [[ -n "${IPV6_ADDRESS}" ]] && echo -e " ${INFO} Pi-hole DNS (IPv6): ${IPV6_ADDRESS}"
+ echo -e " If you set a new IP address, please restart the server running the Pi-hole"
+ INSTALL_TYPE="Installation"
+ else
+ INSTALL_TYPE="Update"
+ fi
+
+ echo -e "\n ${INFO} The install log is located at: /etc/pihole/install.log
+ ${COL_LIGHT_GREEN}${INSTALL_TYPE} Complete! ${COL_NC}"
}
if [[ "${PH_TEST}" != true ]] ; then
diff --git a/automated install/uninstall.sh b/automated install/uninstall.sh
index ed768c38..336bb953 100755
--- a/automated install/uninstall.sh
+++ b/automated install/uninstall.sh
@@ -8,19 +8,30 @@
# This file is copyright under the latest version of the EUPL.
# Please see LICENSE file for your rights under this license.
+source "/opt/pihole/COL_TABLE"
+while true; do
+ read -rp " ${QST} Are you sure you would like to remove ${COL_WHITE}Pi-hole${COL_NC}? [y/N] " yn
+ case ${yn} in
+ [Yy]* ) break;;
+ [Nn]* ) echo -e "\n ${COL_LIGHT_GREEN}Uninstall has been cancelled${COL_NC}"; exit 0;;
+ * ) echo -e "\n ${COL_LIGHT_GREEN}Uninstall has been cancelled${COL_NC}"; exit 0;;
+ esac
+done
# Must be root to uninstall
+str="Root user check"
if [[ ${EUID} -eq 0 ]]; then
- echo "::: You are root."
+ echo -e " ${TICK} ${str}"
else
- echo "::: Sudo will be used for the uninstall."
- # Check if it is actually installed
- # If it isn't, exit because the unnstall cannot complete
+ # Check if sudo is actually installed
+ # If it isn't, exit because the uninstall can not complete
if [ -x "$(command -v sudo)" ]; then
export SUDO="sudo"
else
- echo "::: Please install sudo or run this as root."
+ echo -e " ${CROSS} ${str}
+ Script called with non-root privileges
+ The Pi-hole requires elevated privleges to uninstall"
exit 1
fi
fi
@@ -54,59 +65,48 @@ elif [ -x "$(command -v apt-get)" ]; then
${SUDO} ${PKG_MANAGER} -y autoclean
}
else
- echo "OS distribution not supported"
- exit
+ echo -e " ${CROSS} OS distribution not supported"
+ exit 1
fi
-spinner() {
- local pid=$1
- local delay=0.50
- local spinstr='/-\|'
- while [ "$(ps a | awk '{print $1}' | grep "${pid}")" ]; do
- local temp=${spinstr#?}
- printf " [%c] " "${spinstr}"
- local spinstr=${temp}${spinstr%"$temp}"}
- sleep ${delay}
- printf "\b\b\b\b\b\b"
- done
- printf " \b\b\b\b"
-}
-
removeAndPurge() {
# Purge dependencies
- echo ":::"
+ echo ""
for i in "${PIHOLE_DEPS[@]}"; do
package_check ${i} > /dev/null
- if [ $? -eq 0 ]; then
+ if [[ "$?" -eq 0 ]]; then
while true; do
- read -rp "::: Do you wish to remove ${i} from your system? [y/n]: " yn
+ read -rp " ${QST} Do you wish to remove ${COL_WHITE}${i}${COL_NC} from your system? [Y/N] " yn
case ${yn} in
- [Yy]* ) printf ":::\tRemoving %s..." "${i}"; ${SUDO} ${PKG_REMOVE} "${i}" &> /dev/null & spinner $!; printf "done!\n"; break;;
- [Nn]* ) printf ":::\tSkipping %s\n" "${i}"; break;;
- * ) printf "::: You must answer yes or no!\n";;
+ [Yy]* )
+ echo -ne " ${INFO} Removing ${i}...";
+ ${SUDO} ${PKG_REMOVE} "${i}" &> /dev/null;
+ echo -e "${OVER} ${INFO} Removed ${i}";
+ break;;
+ [Nn]* ) echo -e " ${INFO} Skipped ${i}"; break;;
esac
done
else
- printf ":::\tPackage %s not installed... Not removing.\n" "${i}"
+ echo -e " ${INFO} Package ${i} not installed"
fi
done
- # Remove dependency config files
- echo "::: Removing dnsmasq config files..."
+ # Remove dnsmasq config files
${SUDO} rm /etc/dnsmasq.conf /etc/dnsmasq.conf.orig /etc/dnsmasq.d/01-pihole.conf &> /dev/null
-
+ echo -e " ${TICK} Removing dnsmasq config files"
+
# Take care of any additional package cleaning
- printf "::: Auto removing & cleaning remaining dependencies..."
- package_cleanup &> /dev/null & spinner $!; printf "done!\n";
-
- # Call removeNoPurge to remove PiHole specific files
+ echo -ne " ${INFO} Removing & cleaning remaining dependencies..."
+ package_cleanup &> /dev/null
+ echo -e "${OVER} ${TICK} Removed & cleaned up remaining dependencies"
+
+ # Call removeNoPurge to remove Pi-hole specific files
removeNoPurge
}
removeNoPurge() {
- echo ":::"
- # Only web directories/files that are created by pihole should be removed.
- echo "::: Removing the Pi-hole Web server files..."
+ # Only web directories/files that are created by Pi-hole should be removed
+ echo -ne " ${INFO} Removing Web Interface..."
${SUDO} rm -rf /var/www/html/admin &> /dev/null
${SUDO} rm -rf /var/www/html/pihole &> /dev/null
${SUDO} rm /var/www/html/index.lighttpd.orig &> /dev/null
@@ -117,34 +117,35 @@ removeNoPurge() {
${SUDO} rm -rf /var/www/html &> /dev/null
fi
fi
+ echo -e "${OVER} ${TICK} Removed Web Interface"
# Attempt to preserve backwards compatibility with older versions
# to guarantee no additional changes were made to /etc/crontab after
# the installation of pihole, /etc/crontab.pihole should be permanently
# preserved.
if [[ -f /etc/crontab.orig ]]; then
- echo "::: Initial Pi-hole cron detected. Restoring the default system cron..."
${SUDO} mv /etc/crontab /etc/crontab.pihole
${SUDO} mv /etc/crontab.orig /etc/crontab
${SUDO} service cron restart
+ echo -e " ${TICK} Restored the default system cron"
fi
# Attempt to preserve backwards compatibility with older versions
if [[ -f /etc/cron.d/pihole ]];then
- echo "::: Removing cron.d/pihole..."
${SUDO} rm /etc/cron.d/pihole &> /dev/null
+ echo -e " ${TICK} Removed /etc/cron.d/pihole"
fi
- echo "::: Removing config files and scripts..."
package_check lighttpd > /dev/null
- if [ $? -eq 1 ]; then
+ if [[ $? -eq 1 ]]; then
${SUDO} rm -rf /etc/lighttpd/ &> /dev/null
+ echo -e " ${TICK} Removed lighttpd"
else
if [ -f /etc/lighttpd/lighttpd.conf.orig ]; then
${SUDO} mv /etc/lighttpd/lighttpd.conf.orig /etc/lighttpd/lighttpd.conf
fi
fi
-
+
${SUDO} rm /etc/dnsmasq.d/adList.conf &> /dev/null
${SUDO} rm /etc/dnsmasq.d/01-pihole.conf &> /dev/null
${SUDO} rm -rf /var/log/*pihole* &> /dev/null
@@ -154,28 +155,53 @@ removeNoPurge() {
${SUDO} rm /usr/local/bin/pihole &> /dev/null
${SUDO} rm /etc/bash_completion.d/pihole &> /dev/null
${SUDO} rm /etc/sudoers.d/pihole &> /dev/null
-
+ echo -e " ${TICK} Removed config files"
+
+ # Remove FTL
+ if command -v pihole-FTL &> /dev/null; then
+ echo -ne " ${INFO} Removing pihole-FTL..."
+
+ if [[ -x "$(command -v systemctl)" ]]; then
+ systemctl stop pihole-FTL
+ else
+ service pihole-FTL stop
+ fi
+
+ ${SUDO} rm /etc/init.d/pihole-FTL
+ ${SUDO} rm /usr/bin/pihole-FTL
+
+ echo -e "${OVER} ${TICK} Removed pihole-FTL"
+ fi
+
# If the pihole user exists, then remove
- if id "pihole" >/dev/null 2>&1; then
- echo "::: Removing pihole user..."
- ${SUDO} userdel -r pihole
+ if id "pihole" &> /dev/null; then
+ ${SUDO} userdel -r pihole 2> /dev/null
+ if [[ "$?" -eq 0 ]]; then
+ echo -e " ${TICK} Removed 'pihole' user"
+ else
+ echo -e " ${CROSS} Unable to remove 'pihole' user"
+ fi
fi
- echo ":::"
- printf "::: Finished removing PiHole from your system. Sorry to see you go!\n"
- printf "::: Reach out to us at https://github.com/pi-hole/pi-hole/issues if you need help\n"
- printf "::: Reinstall by simpling running\n:::\n:::\tcurl -sSL https://install.pi-hole.net | bash\n:::\n::: at any time!\n:::\n"
- printf "::: PLEASE RESET YOUR DNS ON YOUR ROUTER/CLIENTS TO RESTORE INTERNET CONNECTIVITY!\n"
+ echo -e "\n We're sorry to see you go, but thanks for checking out Pi-hole!
+ If you need help, reach out to us on Github, Discourse, Reddit or Twitter
+ Reinstall at any time: ${COL_WHITE}curl -sSL https://install.pi-hole.net | bash${COL_NC}
+
+ ${COL_LIGHT_RED}Please reset the DNS on your router/clients to restore internet connectivity
+ ${COL_LIGHT_GREEN}Uninstallation Complete! ${COL_NC}"
}
######### SCRIPT ###########
-echo "::: Preparing to remove packages, be sure that each may be safely removed depending on your operating system."
-echo "::: (SAFE TO REMOVE ALL ON RASPBIAN)"
+if command -v vcgencmd &> /dev/null; then
+ echo -e " ${INFO} All dependencies are safe to remove on Raspbian"
+else
+ echo -e " ${INFO} Be sure to confirm if any dependencies should not be removed"
+fi
while true; do
- read -rp "::: Do you wish to purge PiHole's dependencies from your OS? (You will be prompted for each package) [y/n]: " yn
+ read -rp " ${QST} Do you wish to go through each dependency for removal? [Y/n] " yn
case ${yn} in
[Yy]* ) removeAndPurge; break;;
-
[Nn]* ) removeNoPurge; break;;
+ * ) removeAndPurge; break;;
esac
done
diff --git a/gravity.sh b/gravity.sh
index 285ce5c3..bc7637e3 100755
--- a/gravity.sh
+++ b/gravity.sh
@@ -8,45 +8,42 @@
# This file is copyright under the latest version of the EUPL.
# Please see LICENSE file for your rights under this license.
-
-
# Run this script as root or under sudo
-echo ":::"
+
+coltable="/opt/pihole/COL_TABLE"
+source ${coltable}
helpFunc() {
- cat << EOM
-::: Pull in domains from adlists
-:::
-::: Usage: pihole -g
-:::
-::: Options:
-::: -f, --force Force lists to be downloaded, even if they don't need updating.
-::: -h, --help Show this help dialog
-EOM
- exit 0
+ echo "Usage: pihole -g
+Update domains from blocklists specified in adlists.list
+
+Options:
+ -f, --force Force the download of all specified blocklists
+ -h, --help Show this help dialog"
+ exit 0
}
PIHOLE_COMMAND="/usr/local/bin/pihole"
adListFile=/etc/pihole/adlists.list
-adListDefault=/etc/pihole/adlists.default #being deprecated
+adListDefault=/etc/pihole/adlists.default # Deprecated
adListRepoDefault=/etc/.pihole/adlists.default
whitelistScript="${PIHOLE_COMMAND} -w"
whitelistFile=/etc/pihole/whitelist.txt
blacklistFile=/etc/pihole/blacklist.txt
readonly wildcardlist="/etc/dnsmasq.d/03-pihole-wildcard.conf"
-#Source the setupVars from install script for the IP
+# Source the setupVars from install script for the IP
setupVars=/etc/pihole/setupVars.conf
-if [[ -f ${setupVars} ]];then
- . /etc/pihole/setupVars.conf
+if [[ -f "${setupVars}" ]];then
+ . /etc/pihole/setupVars.conf
else
- echo "::: WARNING: /etc/pihole/setupVars.conf missing. Possible installation failure."
- echo "::: Please run 'pihole -r', and choose the 'reconfigure' option to reconfigure."
- exit 1
+ echo -e " ${COL_LIGHT_RED}Error: /etc/pihole/setupVars.conf missing. Possible installation failure.${COL_NC}
+ Please run 'pihole -r', and choose the 'reconfigure' option to reconfigure."
+ exit 1
fi
-#Remove the /* from the end of the IPv4addr.
+# Remove the /* from the end of the IPv4addr.
IPV4_ADDRESS=${IPV4_ADDRESS%/*}
IPV6_ADDRESS=${IPV6_ADDRESS}
@@ -65,13 +62,13 @@ accretionDisc=${basename}.3.accretionDisc.txt
skipDownload=false
-# Warn users still using pihole.conf that it no longer has any effect (I imagine about 2 people use it)
+# Warn users still using pihole.conf that it no longer has any effect
if [[ -r ${piholeDir}/pihole.conf ]]; then
- echo "::: pihole.conf file no longer supported. Over-rides in this file are ignored."
+echo -e " ${COL_LIGHT_RED}pihole.conf file no longer supported. Overrides in this file are ignored.${COL_NC}"
fi
###########################
-# collapse - begin formation of pihole
+# Collapse - begin formation of pihole
gravity_collapse() {
#New Logic:
@@ -79,266 +76,276 @@ gravity_collapse() {
# If not, cp /etc/.pihole/adlists.default /etc/pihole/adlists.list
# Read from adlists.list
- #The following two blocks will sort out any missing adlists in the /etc/pihole directory, and remove legacy adlists.default
- if [ -f ${adListDefault} ] && [ -f ${adListFile} ]; then
- rm ${adListDefault}
+ # The following two blocks will sort out any missing adlists in the /etc/pihole directory, and remove legacy adlists.default
+ if [[ -f "${adListDefault}" ]] && [[ -f "${adListFile}" ]]; then
+ rm "${adListDefault}"
fi
- if [ ! -f ${adListFile} ]; then
- cp ${adListRepoDefault} ${adListFile}
+ if [ ! -f "${adListFile}" ]; then
+ cp "${adListRepoDefault}" "${adListFile}"
fi
- echo "::: Neutrino emissions detected..."
- echo ":::"
- echo -n "::: Pulling source lists into range..."
+ echo -e " ${INFO} Neutrino emissions detected..."
+ echo ""
+ local str="Pulling source lists into range"
+ echo -ne " ${INFO} ${str}..."
+
sources=()
while IFS= read -r line || [[ -n "$line" ]]; do
- #Do not read commented out or blank lines
+ # Do not read commented out or blank lines
if [[ ${line} = \#* ]] || [[ ! ${line} ]]; then
echo "" > /dev/null
else
sources+=(${line})
fi
done < ${adListFile}
- echo " done!"
+
+ echo -e "${OVER} ${TICK} ${str}"
}
# patternCheck - check to see if curl downloaded any new files.
gravity_patternCheck() {
- patternBuffer=$1
- success=$2
- error=$3
- if [ $success = true ]; then
- # check if download was successful but list has not been modified
- if [ "${error}" == "304" ]; then
- echo "::: No changes detected, transport skipped!"
- # check if the patternbuffer is a non-zero length file
- elif [[ -s "${patternBuffer}" ]]; then
- # Some of the blocklists are copyright, they need to be downloaded
- # and stored as is. They can be processed for content after they
- # have been saved.
- mv "${patternBuffer}" "${saveLocation}"
- echo "::: List updated, transport successful!"
- else
- # Empty file -> use previously downloaded list
- echo "::: Received empty file, using cached one (list not updated!)"
- fi
- else
- # check if cached list exists
- if [[ -r "${saveLocation}" ]]; then
- echo "::: List download failed, using cached list (list not updated!)"
- else
- echo "::: Download failed and no cached list available (list will not be considered)"
- fi
- fi
+ patternBuffer=$1
+ success=$2
+ error=$3
+ if [[ "${success}" = true ]]; then
+ # Check if download was successful but list has not been modified
+ if [[ "${error}" == "304" ]]; then
+ echo -e " ${TICK} No changes detected, transport skipped!"
+ # Check if the patternbuffer is a non-zero length file
+ elif [[ -s "${patternBuffer}" ]]; then
+ # Some blocklists are copyright, they need to be downloaded and stored
+ # as is. They can be processed for content after they have been saved.
+ mv "${patternBuffer}" "${saveLocation}"
+ echo -e " ${TICK} List updated, transport successful!"
+ else
+ # Empty file -> use previously downloaded list
+ echo -e " ${INFO} Received empty file, ${COL_LIGHT_GREEN}using cached one${COL_NC} (list not updated!)"
+ fi
+ else
+ # Check if cached list exists
+ if [[ -r "${saveLocation}" ]]; then
+ echo -e " ${CROSS} List download failed, using cached list (list not updated!)"
+ else
+ echo -e " ${CROSS} Download failed and no cached list available (list will not be considered)"
+ fi
+ fi
}
# transport - curl the specified url with any needed command extentions
gravity_transport() {
- url=$1
- cmd_ext=$2
- agent=$3
+ url=$1
+ cmd_ext=$2
+ agent=$3
- # tmp file, so we don't have to store the (long!) lists in RAM
- patternBuffer=$(mktemp)
- heisenbergCompensator=""
- if [[ -r ${saveLocation} ]]; then
- # if domain has been saved, add file for date check to only download newer
- heisenbergCompensator="-z ${saveLocation}"
- fi
+ # tmp file, so we don't have to store the (long!) lists in RAM
+ patternBuffer=$(mktemp)
+ heisenbergCompensator=""
+ if [[ -r ${saveLocation} ]]; then
+ # If domain has been saved, add file for date check to only download newer
+ heisenbergCompensator="-z ${saveLocation}"
+ fi
- # Silently curl url
- err=$(curl -s -L ${cmd_ext} ${heisenbergCompensator} -w %{http_code} -A "${agent}" ${url} -o ${patternBuffer})
+ # Silently curl url
+ echo -e "${OVER} ${TICK} ${str}"
+ local str="Status:"
+ echo -ne " ${INFO} ${str} Pending"
+ err=$(curl -s -L ${cmd_ext} ${heisenbergCompensator} -w %{http_code} -A "${agent}" ${url} -o ${patternBuffer})
- echo " done"
- # Analyze http response
- echo -n "::: Status: "
- case "$err" in
- "200" ) echo "Success (OK)"; success=true;;
- "304" ) echo "Not modified"; success=true;;
- "403" ) echo "Forbidden"; success=false;;
- "404" ) echo "Not found"; success=false;;
- "408" ) echo "Time-out"; success=false;;
- "451" ) echo "Unavailable For Legal Reasons"; success=false;;
- "521" ) echo "Web Server Is Down (Cloudflare)"; success=false;;
- "522" ) echo "Connection Timed Out (Cloudflare)"; success=false;;
- "500" ) echo "Internal Server Error"; success=false;;
- * ) echo "Status $err"; success=false;;
- esac
+ # Analyze http response
+ case "$err" in
+ "200" ) echo -e "${OVER} ${TICK} ${str} Success (OK)"; success=true;;
+ "304" ) echo -e "${OVER} ${TICK} ${str} Not modified"; success=true;;
+ "403" ) echo -e "${OVER} ${CROSS} ${str} Forbidden"; success=false;;
+ "404" ) echo -e "${OVER} ${CROSS} ${str} Not found"; success=false;;
+ "408" ) echo -e "${OVER} ${CROSS} ${str} Time-out"; success=false;;
+ "451" ) echo -e "${OVER} ${CROSS} ${str} Unavailable For Legal Reasons"; success=false;;
+ "521" ) echo -e "${OVER} ${CROSS} ${str} Web Server Is Down (Cloudflare)"; success=false;;
+ "522" ) echo -e "${OVER} ${CROSS} ${str} Connection Timed Out (Cloudflare)"; success=false;;
+ "500" ) echo -e "${OVER} ${CROSS} ${str} Internal Server Error"; success=false;;
+ * ) echo -e "${OVER} ${CROSS} ${str} Status $err"; success=false;;
+ esac
- # Process result
- gravity_patternCheck "${patternBuffer}" ${success} "${err}"
+ # Process result
+ gravity_patternCheck "${patternBuffer}" "${success}" "${err}"
- # Delete temp file if it hasn't been moved
- if [[ -f "${patternBuffer}" ]]; then
- rm "${patternBuffer}"
- fi
+ # Delete temp file if it hasn't been moved
+ if [[ -f "${patternBuffer}" ]]; then
+ rm "${patternBuffer}"
+ fi
}
# spinup - main gravity function
gravity_spinup() {
- echo ":::"
- # Loop through domain list. Download each one and remove commented lines (lines beginning with '# 'or '/') and # blank lines
- for ((i = 0; i < "${#sources[@]}"; i++)); do
- url=${sources[$i]}
- # Get just the domain from the URL
- domain=$(echo "${url}" | cut -d'/' -f3)
+ echo ""
+ # Loop through domain list. Download each one and remove commented lines (lines beginning with '# 'or '/') and # blank lines
+ for ((i = 0; i < "${#sources[@]}"; i++)); do
+ url=${sources[$i]}
+ # Get just the domain from the URL
+ domain=$(cut -d'/' -f3 <<< "${url}")
- # Save the file as list.#.domain
- saveLocation=${piholeDir}/list.${i}.${domain}.${justDomainsExtension}
- activeDomains[$i]=${saveLocation}
+ # Save the file as list.#.domain
+ saveLocation=${piholeDir}/list.${i}.${domain}.${justDomainsExtension}
+ activeDomains[$i]=${saveLocation}
- agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2227.0 Safari/537.36"
+ agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2227.0 Safari/537.36"
- # Use a case statement to download lists that need special cURL commands
- # to complete properly and reset the user agent when required
- case "${domain}" in
- "adblock.mahakala.is")
- agent='Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36'
- cmd_ext="-e http://forum.xda-developers.com/"
- ;;
+ # Use a case statement to download lists that need special cURL commands
+ # to complete properly and reset the user agent when required
+ case "${domain}" in
+ "pgl.yoyo.org")
+ cmd_ext="-d mimetype=plaintext -d hostformat=hosts"
+ ;;
- "adaway.org")
- agent='Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36'
- ;;
+ # Default is a simple request
+ *) cmd_ext=""
+ esac
- "pgl.yoyo.org")
- cmd_ext="-d mimetype=plaintext -d hostformat=hosts"
- ;;
+ if [[ "${skipDownload}" == false ]]; then
+ local str="Aiming tractor beam at $domain"
+ echo -ne " ${INFO} ${str}..."
- # Default is a simple request
- *) cmd_ext=""
- esac
- if [[ "${skipDownload}" == false ]]; then
- echo -n "::: Getting $domain list..."
- gravity_transport "$url" "$cmd_ext" "$agent"
- fi
- done
+ gravity_transport "$url" "$cmd_ext" "$agent" "$str"
+ echo ""
+ fi
+ done
}
# Schwarzchild - aggregate domains to one list and add blacklisted domains
gravity_Schwarzchild() {
- echo "::: "
- # Find all active domains and compile them into one file and remove CRs
- echo -n "::: Aggregating list of domains..."
- truncate -s 0 ${piholeDir}/${matterAndLight}
- for i in "${activeDomains[@]}"; do
- # Only assimilate list if it is available (download might have faild permanently)
- if [[ -r "${i}" ]]; then
- cat "${i}" | tr -d '\r' >> ${piholeDir}/${matterAndLight}
- fi
- done
- echo " done!"
+ echo ""
+ # Find all active domains and compile them into one file and remove CRs
+ local str="Aggregating list of domains"
+ echo -ne " ${INFO} ${str}..."
+
+ truncate -s 0 ${piholeDir}/${matterAndLight}
+ for i in "${activeDomains[@]}"; do
+ # Only assimilate list if it is available (download might have failed permanently)
+ if [[ -r "${i}" ]]; then
+ cat "${i}" | tr -d '\r' >> ${piholeDir}/${matterAndLight}
+ fi
+ done
+
+ echo -e "${OVER} ${TICK} ${str}"
}
gravity_Blacklist() {
- # Append blacklist entries to eventHorizon if they exist
- if [[ -f "${blacklistFile}" ]]; then
- numBlacklisted=$(wc -l < "${blacklistFile}")
- plural=; [[ "$numBlacklisted" != "1" ]] && plural=s
- echo "::: Exact blocked domain${plural}: $numBlacklisted"
- else
- echo "::: Nothing to blacklist!"
- fi
-
+ # Append blacklist entries to eventHorizon if they exist
+ if [[ -f "${blacklistFile}" ]]; then
+ numBlacklisted=$(wc -l < "${blacklistFile}")
+ plural=; [[ "$numBlacklisted" != "1" ]] && plural=s
+ local str="Exact blocked domain${plural}: $numBlacklisted"
+ echo -e " ${INFO} ${str}"
+ else
+ echo -e " ${INFO} Nothing to blacklist!"
+ fi
}
gravity_Wildcard() {
- # Return number of wildcards in output - don't actually handle wildcards
- if [[ -f "${wildcardlist}" ]]; then
- numWildcards=$(grep -c ^ "${wildcardlist}")
- if [[ -n "${IPV4_ADDRESS}" && -n "${IPV6_ADDRESS}" ]];then
- let numWildcards/=2
- fi
- plural=; [[ "$numWildcards" != "1" ]] && plural=s
- echo "::: Wildcard blocked domain${plural}: $numWildcards"
- else
- echo "::: No wildcards used!"
- fi
+ # Return number of wildcards in output - don't actually handle wildcards
+ if [[ -f "${wildcardlist}" ]]; then
+ numWildcards=$(grep -c ^ "${wildcardlist}")
+ if [[ -n "${IPV4_ADDRESS}" ]] && [[ -n "${IPV6_ADDRESS}" ]];then
+ let numWildcards/=2
+ fi
+ plural=; [[ "$numWildcards" != "1" ]] && plural=s
+ echo -e " ${INFO} Wildcard blocked domain${plural}: $numWildcards"
+ else
+ echo -e " ${INFO} No wildcards used!"
+ fi
}
gravity_Whitelist() {
- #${piholeDir}/${eventHorizon})
- echo ":::"
- # Prevent our sources from being pulled into the hole
- plural=; [[ "${sources[@]}" != "1" ]] && plural=s
- echo -n "::: Adding adlist source${plural} to the whitelist..."
+ echo ""
+ # Prevent our sources from being pulled into the hole
+ plural=; [[ "${sources[@]}" != "1" ]] && plural=s
+ local str="Adding adlist source${plural} to the whitelist"
+ echo -ne " ${INFO} ${str}..."
- urls=()
- for url in "${sources[@]}"; do
- tmp=$(echo "${url}" | awk -F '/' '{print $3}')
- urls=("${urls[@]}" ${tmp})
- done
- echo " done!"
+ urls=()
+ for url in "${sources[@]}"; do
+ tmp=$(awk -F '/' '{print $3}' <<< "${url}")
+ urls=("${urls[@]}" ${tmp})
+ done
- # Ensure adlist domains are in whitelist.txt
- ${whitelistScript} -nr -q "${urls[@]}" > /dev/null
+ echo -e "${OVER} ${TICK} ${str}"
- # Check whitelist.txt exists.
- if [[ -f "${whitelistFile}" ]]; then
- # Remove anything in whitelist.txt from the Event Horizon
- numWhitelisted=$(wc -l < "${whitelistFile}")
- plural=; [[ "$numWhitelisted" != "1" ]] && plural=s
- echo -n "::: Whitelisting $numWhitelisted domain${plural}..."
- #print everything from preEventHorizon into eventHorizon EXCEPT domains in whitelist.txt
- grep -F -x -v -f ${whitelistFile} ${piholeDir}/${preEventHorizon} > ${piholeDir}/${eventHorizon}
- echo " done!"
- else
- echo "::: Nothing to whitelist!"
- fi
+ # Ensure adlist domains are in whitelist.txt
+ ${whitelistScript} -nr -q "${urls[@]}" > /dev/null
+
+ # Check whitelist.txt exists.
+ if [[ -f "${whitelistFile}" ]]; then
+ # Remove anything in whitelist.txt from the Event Horizon
+ numWhitelisted=$(wc -l < "${whitelistFile}")
+ plural=; [[ "$numWhitelisted" != "1" ]] && plural=s
+ local str="Whitelisting $numWhitelisted domain${plural}"
+ echo -ne " ${INFO} ${str}..."
+
+ # Print everything from preEventHorizon into eventHorizon EXCEPT domains in whitelist.txt
+ grep -F -x -v -f ${whitelistFile} ${piholeDir}/${preEventHorizon} > ${piholeDir}/${eventHorizon}
+
+ echo -e "${OVER} ${TICK} ${str}"
+ else
+ echo -e " ${INFO} Nothing to whitelist!"
+ fi
}
gravity_unique() {
- # Sort and remove duplicates
- echo -n "::: Removing duplicate domains...."
- sort -u ${piholeDir}/${supernova} > ${piholeDir}/${preEventHorizon}
- echo " done!"
- numberOf=$(wc -l < ${piholeDir}/${preEventHorizon})
- echo "::: $numberOf unique domains trapped in the event horizon."
+ # Sort and remove duplicates
+ local str="Removing duplicate domains"
+ echo -ne " ${INFO} ${str}..."
+
+ sort -u ${piholeDir}/${supernova} > ${piholeDir}/${preEventHorizon}
+
+ echo -e "${OVER} ${TICK} ${str}"
+ numberOf=$(wc -l < ${piholeDir}/${preEventHorizon})
+ echo -e " ${INFO} ${COL_LIGHT_BLUE}${numberOf}${COL_NC} unique domains trapped in the event horizon."
}
gravity_doHostFormat() {
# Check vars from setupVars.conf to see if we're using IPv4, IPv6, Or both.
- if [[ -n "${IPV4_ADDRESS}" && -n "${IPV6_ADDRESS}" ]];then
- # Both IPv4 and IPv6
- awk -v ipv4addr="$IPV4_ADDRESS" -v ipv6addr="$IPV6_ADDRESS" '{sub(/\r$/,""); print ipv4addr" "$0"\n"ipv6addr" "$0}' >> "${2}" < "${1}"
- elif [[ -n "${IPV4_ADDRESS}" && -z "${IPV6_ADDRESS}" ]];then
- # Only IPv4
- awk -v ipv4addr="$IPV4_ADDRESS" '{sub(/\r$/,""); print ipv4addr" "$0}' >> "${2}" < "${1}"
- elif [[ -z "${IPV4_ADDRESS}" && -n "${IPV6_ADDRESS}" ]];then
- # Only IPv6
- awk -v ipv6addr="$IPV6_ADDRESS" '{sub(/\r$/,""); print ipv6addr" "$0}' >> "${2}" < "${1}"
- elif [[ -z "${IPV4_ADDRESS}" && -z "${IPV6_ADDRESS}" ]];then
- echo "::: No IP Values found! Please run 'pihole -r' and choose reconfigure to restore values"
- exit 1
+ if [[ -n "${IPV4_ADDRESS}" ]] && [[ -n "${IPV6_ADDRESS}" ]];then
+ # Both IPv4 and IPv6
+ awk -v ipv4addr="$IPV4_ADDRESS" -v ipv6addr="$IPV6_ADDRESS" '{sub(/\r$/,""); print ipv4addr" "$0"\n"ipv6addr" "$0}' >> "${2}" < "${1}"
+ elif [[ -n "${IPV4_ADDRESS}" ]] && [[ -z "${IPV6_ADDRESS}" ]];then
+ # Only IPv4
+ awk -v ipv4addr="$IPV4_ADDRESS" '{sub(/\r$/,""); print ipv4addr" "$0}' >> "${2}" < "${1}"
+ elif [[ -z "${IPV4_ADDRESS}" ]] && [[ -n "${IPV6_ADDRESS}" ]];then
+ # Only IPv6
+ awk -v ipv6addr="$IPV6_ADDRESS" '{sub(/\r$/,""); print ipv6addr" "$0}' >> "${2}" < "${1}"
+ elif [[ -z "${IPV4_ADDRESS}" ]] &&[[ -z "${IPV6_ADDRESS}" ]];then
+ echo -e "${OVER} ${CROSS} ${str}"
+ echo -e " ${COL_LIGHT_RED}No IP Values found! Please run 'pihole -r' and choose reconfigure to restore values${COL_NC}"
+ exit 1
fi
}
gravity_hostFormatLocal() {
- # Format domain list as "192.168.x.x domain.com"
+ # Format domain list as "192.168.x.x domain.com"
- if [[ -f /etc/hostname ]]; then
- hostname=$( "${localList}.tmp"
- # Copy the file over as /etc/pihole/local.list so dnsmasq can use it
- rm "${localList}"
- gravity_doHostFormat "${localList}.tmp" "${localList}"
- rm "${localList}.tmp"
+ echo -e "${hostname}\npi.hole" > "${localList}.tmp"
+ # Copy the file over as /etc/pihole/local.list so dnsmasq can use it
+ rm "${localList}"
+ gravity_doHostFormat "${localList}.tmp" "${localList}"
+ rm "${localList}.tmp"
}
gravity_hostFormatGravity() {
- # Format domain list as "192.168.x.x domain.com"
- echo "" > "${piholeDir}/${accretionDisc}"
- gravity_doHostFormat "${piholeDir}/${eventHorizon}" "${piholeDir}/${accretionDisc}"
- # Copy the file over as /etc/pihole/gravity.list so dnsmasq can use it
- mv "${piholeDir}/${accretionDisc}" "${adList}"
+ # Format domain list as "192.168.x.x domain.com"
+ echo "" > "${piholeDir}/${accretionDisc}"
+ gravity_doHostFormat "${piholeDir}/${eventHorizon}" "${piholeDir}/${accretionDisc}"
+ # Copy the file over as /etc/pihole/gravity.list so dnsmasq can use it
+ mv "${piholeDir}/${accretionDisc}" "${adList}"
+
}
gravity_hostFormatBlack() {
@@ -349,76 +356,83 @@ gravity_hostFormatBlack() {
# Copy the file over as /etc/pihole/black.list so dnsmasq can use it
mv "${blackList}.tmp" "${blackList}"
else
- echo "::: Nothing to blacklist!"
+ echo -e " ${INFO} Nothing to blacklist!"
fi
}
# blackbody - remove any remnant files from script processes
gravity_blackbody() {
- # Loop through list files
- for file in ${piholeDir}/*.${justDomainsExtension}; do
- # If list is in active array then leave it (noop) else rm the list
- if [[ " ${activeDomains[@]} " =~ ${file} ]]; then
- :
- else
- rm -f "${file}"
- fi
- done
+ # Loop through list files
+ for file in ${piholeDir}/*.${justDomainsExtension}; do
+ # If list is in active array then leave it (noop) else rm the list
+ if [[ " ${activeDomains[@]} " =~ ${file} ]]; then
+ :
+ else
+ rm -f "${file}"
+ fi
+ done
}
gravity_advanced() {
- # Remove comments and print only the domain name
- # Most of the lists downloaded are already in hosts file format but the spacing/formating is not contigious
- # This helps with that and makes it easier to read
- # It also helps with debugging so each stage of the script can be researched more in depth
- echo -n "::: Formatting list of domains to remove comments...."
- #awk '($1 !~ /^#/) { if (NF>1) {print $2} else {print $1}}' ${piholeDir}/${matterAndLight} | sed -nr -e 's/\.{2,}/./g' -e '/\./p' > ${piholeDir}/${supernova}
- #Above line does not correctly grab domains where comment is on the same line (e.g 'addomain.com #comment')
- #Awk -F splits on given IFS, we grab the right hand side (chops trailing #coments and /'s to grab the domain only.
- #Last awk command takes non-commented lines and if they have 2 fields, take the left field (the domain) and leave
- #+ the right (IP address), otherwise grab the single field.
- cat ${piholeDir}/${matterAndLight} | \
- awk -F '#' '{print $1}' | \
- awk -F '/' '{print $1}' | \
- awk '($1 !~ /^#/) { if (NF>1) {print $2} else {print $1}}' | \
- sed -nr -e 's/\.{2,}/./g' -e '/\./p' > ${piholeDir}/${supernova}
- echo " done!"
+ # Remove comments and print only the domain name
+ # Most of the lists downloaded are already in hosts file format but the spacing/formating is not contigious
+ # This helps with that and makes it easier to read
+ # It also helps with debugging so each stage of the script can be researched more in depth
+ local str="Formatting list of domains to remove comments"
+ echo -ne " ${INFO} ${str}..."
- numberOf=$(wc -l < ${piholeDir}/${supernova})
- echo "::: ${numberOf} domains being pulled in by gravity..."
+ #awk '($1 !~ /^#/) { if (NF>1) {print $2} else {print $1}}' ${piholeDir}/${matterAndLight} | sed -nr -e 's/\.{2,}/./g' -e '/\./p' > ${piholeDir}/${supernova}
+ #Above line does not correctly grab domains where comment is on the same line (e.g 'addomain.com #comment')
+ #Awk -F splits on given IFS, we grab the right hand side (chops trailing #coments and /'s to grab the domain only.
+ #Last awk command takes non-commented lines and if they have 2 fields, take the left field (the domain) and leave
+ #+ the right (IP address), otherwise grab the single field.
+ cat ${piholeDir}/${matterAndLight} | \
+ awk -F '#' '{print $1}' | \
+ awk -F '/' '{print $1}' | \
+ awk '($1 !~ /^#/) { if (NF>1) {print $2} else {print $1}}' | \
+ sed -nr -e 's/\.{2,}/./g' -e '/\./p' > ${piholeDir}/${supernova}
- gravity_unique
+ echo -e "${OVER} ${TICK} ${str}"
+
+ numberOf=$(wc -l < ${piholeDir}/${supernova})
+ echo -e " ${INFO} ${COL_LIGHT_BLUE}${numberOf}${COL_NC} domains being pulled in by gravity"
+
+ gravity_unique
}
gravity_reload() {
+ # Reload hosts file
+ echo ""
+ local str="Refreshing lists in dnsmasq"
+ echo -e " ${INFO} ${str}..."
- # Reload hosts file
- echo ":::"
- echo -n "::: Refresh lists in dnsmasq..."
+ # Ensure /etc/dnsmasq.d/01-pihole.conf is pointing at the correct list!
+ # First escape forward slashes in the path:
+ adList=${adList//\//\\\/}
+ # Now replace the line in dnsmasq file
+ # sed -i "s/^addn-hosts.*/addn-hosts=$adList/" /etc/dnsmasq.d/01-pihole.conf
- #ensure /etc/dnsmasq.d/01-pihole.conf is pointing at the correct list!
- #First escape forward slashes in the path:
- adList=${adList//\//\\\/}
- #Now replace the line in dnsmasq file
-# sed -i "s/^addn-hosts.*/addn-hosts=$adList/" /etc/dnsmasq.d/01-pihole.conf
-
- "${PIHOLE_COMMAND}" restartdns
- echo " done!"
+ "${PIHOLE_COMMAND}" restartdns
}
for var in "$@"; do
- case "${var}" in
- "-f" | "--force" ) forceGrav=true;;
- "-h" | "--help" ) helpFunc;;
- "-sd" | "--skip-download" ) skipDownload=true;;
- "-b" | "--blacklist-only" ) blackListOnly=true;;
- esac
+ case "${var}" in
+ "-f" | "--force" ) forceGrav=true;;
+ "-h" | "--help" ) helpFunc;;
+ "-sd" | "--skip-download" ) skipDownload=true;;
+ "-b" | "--blacklist-only" ) blackListOnly=true;;
+ esac
done
if [[ "${forceGrav}" == true ]]; then
- echo -n "::: Deleting exising list cache..."
- rm /etc/pihole/list.*
- echo " done!"
+ str="Deleting exising list cache"
+ echo -ne "${INFO} ${str}..."
+
+ if rm /etc/pihole/list.* 2> /dev/null; then
+ echo -e "${OVER} ${TICK} ${str}"
+ else
+ echo -e "${OVER} ${CROSS} ${str}"
+ fi
fi
if [[ ! "${blackListOnly}" == true ]]; then
@@ -428,31 +442,34 @@ if [[ ! "${blackListOnly}" == true ]]; then
gravity_Schwarzchild
gravity_advanced
else
- echo "::: Using cached Event Horizon list..."
+ echo -e " ${INFO} Using cached Event Horizon list..."
numberOf=$(wc -l < ${piholeDir}/${preEventHorizon})
- echo "::: $numberOf unique domains trapped in the event horizon."
+ echo -e " ${INFO} ${COL_LIGHT_BLUE}$numberOf${COL_NC} unique domains trapped in the event horizon."
fi
gravity_Whitelist
fi
gravity_Blacklist
gravity_Wildcard
-echo -n "::: Formatting domains into a HOSTS file..."
+str="Formatting domains into a HOSTS file"
+echo -ne " ${INFO} ${str}..."
if [[ ! "${blackListOnly}" == true ]]; then
gravity_hostFormatLocal
gravity_hostFormatGravity
fi
gravity_hostFormatBlack
-echo " done!"
+echo -e "${OVER} ${TICK} ${str}"
gravity_blackbody
if [[ ! "${blackListOnly}" == true ]]; then
- #Clear no longer needed files...
- echo ":::"
- echo -n "::: Cleaning up un-needed files..."
- rm ${piholeDir}/pihole.*.txt
- echo " done!"
+ # Clear no longer needed files...
+ str="Cleaning up un-needed files"
+ echo -ne " ${INFO} ${str}..."
+
+ rm ${piholeDir}/pihole.*.txt 2> /dev/null
+
+ echo -e "${OVER} ${TICK} ${str}"
fi
gravity_reload
diff --git a/pihole b/pihole
index 055d6bce..93b35393 100755
--- a/pihole
+++ b/pihole
@@ -8,6 +8,9 @@
# This file is copyright under the latest version of the EUPL.
# Please see LICENSE file for your rights under this license.
+colfile="/opt/pihole/COL_TABLE"
+source ${colfile}
+
readonly PI_HOLE_SCRIPT_DIR="/opt/pihole"
readonly wildcardlist="/etc/dnsmasq.d/03-pihole-wildcard.conf"
@@ -17,7 +20,7 @@ if [[ ! $EUID -eq 0 ]];then
exec sudo bash "$0" "$@"
exit $?
else
- echo "::: sudo is needed to run pihole commands. Please run this script as root or install sudo."
+ echo -e " ${CROSS} sudo is needed to run pihole commands. Please run this script as root or install sudo."
exit 1
fi
fi
@@ -108,6 +111,13 @@ processWildcards() {
queryFunc() {
domain="${2}"
+
+ if [[ -z "${domain}" ]]; then
+ echo -e " ${COL_LIGHT_RED}Invalid option${COL_NC}
+ Try 'pihole query --help' for more information."
+ exit 1
+ fi
+
method="${3}"
lists=( /etc/pihole/list.* /etc/pihole/blacklist.txt)
for list in ${lists[@]}; do
@@ -115,13 +125,13 @@ queryFunc() {
result=$(scanList ${domain} ${list} ${method})
# Remove empty lines before couting number of results
count=$(sed '/^\s*$/d' <<< "$result" | wc -l)
- echo "::: ${list} (${count} results)"
+ echo "${list} (${count} results)"
if [[ ${count} > 0 ]]; then
echo "${result}"
fi
echo ""
else
- echo "::: ${list} does not exist"
+ echo -e " ${CROSS} List does not exist"
echo ""
fi
done
@@ -134,7 +144,7 @@ queryFunc() {
# Remove empty lines before couting number of results
count=$(sed '/^\s*$/d' <<< "$result" | wc -l)
if [[ ${count} > 0 ]]; then
- echo "::: Wildcard blocking ${domain} (${count} results)"
+ echo -e " ${TICK} Wildcard blocking ${domain} (${count} results)"
echo "${result}"
echo ""
fi
@@ -165,18 +175,22 @@ restartDNS() {
dnsmasqPid=$(pidof dnsmasq)
if [[ "${dnsmasqPid}" ]]; then
# Service already running - reload config
+ echo -ne " ${INFO} Restarting dnsmasq"
if [[ -x "$(command -v systemctl)" ]]; then
systemctl restart dnsmasq
else
service dnsmasq restart
fi
+ [[ "$?" == 0 ]] && echo -e "${OVER} ${TICK} Restarted dnsmasq" || echo -e "${OVER} ${CROSS} Failed to restart dnsmasq"
else
# Service not running, start it up
+ echo -ne " ${INFO} Starting dnsmasq"
if [[ -x "$(command -v systemctl)" ]]; then
systemctl start dnsmasq
else
service dnsmasq start
fi
+ [[ "$?" == 0 ]] && echo -e "${OVER} ${TICK} Restarted dnsmasq" || echo -e "${OVER} ${CROSS} Failed to restart dnsmasq"
fi
}
@@ -190,6 +204,7 @@ Time:
#s Disable Pi-hole functionality for # second(s)
#m Disable Pi-hole functionality for # minute(s)"
exit 0
+
elif [[ "${1}" == "0" ]]; then
# Disable Pi-hole
sed -i 's/^addn-hosts=\/etc\/pihole\/gravity.list/#addn-hosts=\/etc\/pihole\/gravity.list/' /etc/dnsmasq.d/01-pihole.conf
@@ -197,34 +212,57 @@ Time:
if [[ -e "$wildcardlist" ]]; then
mv "$wildcardlist" "/etc/pihole/wildcard.list"
fi
- echo "::: Blocking has been disabled!"
if [[ $# > 1 ]]; then
- if [[ "${2}" == *"s"* ]]; then
+ local error=false
+ if [[ "${2}" == *"s" ]]; then
tt=${2%"s"}
- echo "::: Blocking will be re-enabled in ${tt} seconds"
- nohup bash -c "sleep ${tt}; pihole enable" /dev/null &
- elif [[ "${2}" == *"m"* ]]; then
+ if [[ "${tt}" =~ ^-?[0-9]+$ ]];then
+ local str="Disabling blocking for ${tt} seconds"
+ echo -e " ${INFO} ${str}..."
+ local str="Blocking will be re-enabled in ${tt} seconds"
+ nohup bash -c "sleep ${tt}; pihole enable" /dev/null &
+ else
+ local error=true
+ fi
+ elif [[ "${2}" == *"m" ]]; then
tt=${2%"m"}
- echo "::: Blocking will be re-enabled in ${tt} minutes"
- tt=$((${tt}*60))
- nohup bash -c "sleep ${tt}; pihole enable" /dev/null &
+ if [[ "${tt}" =~ ^-?[0-9]+$ ]];then
+ local str="Disabling blocking for ${tt} minutes"
+ echo -e " ${INFO} ${str}..."
+ local str="Blocking will be re-enabled in ${tt} minutes"
+ tt=$((${tt}*60))
+ nohup bash -c "sleep ${tt}; pihole enable" /dev/null &
+ else
+ local error=true
+ fi
+ elif [[ -n "${2}" ]]; then
+ local error=true
else
- echo "::: Unknown format for delayed reactivation of the blocking!"
- echo "::: Example:"
- echo "::: pihole disable 5s - will disable blocking for 5 seconds"
- echo "::: pihole disable 7m - will disable blocking for 7 minutes"
- echo "::: Blocking will not automatically be re-enabled!"
+ echo -e " ${INFO} Disabling blocking"
fi
+
+ if [[ ${error} == true ]];then
+ echo -e " ${COL_LIGHT_RED}Unknown format for delayed reactivation of the blocking!${COL_NC}"
+ echo -e " Try 'pihole disable --help' for more information."
+ exit 1
+ fi
+
+ local str="Pi-hole Disabled"
fi
else
# Enable Pi-hole
- echo "::: Blocking has been enabled!"
+ echo -e " ${INFO} Enabling blocking"
+ local str="Pi-hole Enabled"
+
sed -i 's/^#addn-hosts/addn-hosts/' /etc/dnsmasq.d/01-pihole.conf
if [[ -e "/etc/pihole/wildcard.list" ]]; then
mv "/etc/pihole/wildcard.list" "$wildcardlist"
fi
fi
+
restartDNS
+
+ echo -e "${OVER} ${TICK} ${str}"
}
piholeLogging() {
@@ -243,29 +281,33 @@ Options:
sed -i 's/^log-queries/#log-queries/' /etc/dnsmasq.d/01-pihole.conf
sed -i 's/^QUERY_LOGGING=true/QUERY_LOGGING=false/' /etc/pihole/setupVars.conf
pihole -f
- echo "::: Logging has been disabled!"
+ echo -e " ${INFO} Disabling logging..."
+ local str="Logging has been disabled!"
elif [[ "${1}" == "on" ]]; then
# Enable logging
sed -i 's/^#log-queries/log-queries/' /etc/dnsmasq.d/01-pihole.conf
sed -i 's/^QUERY_LOGGING=false/QUERY_LOGGING=true/' /etc/pihole/setupVars.conf
- echo "::: Logging has been enabled!"
+ echo -e " ${INFO} Enabling logging..."
+ local str="Logging has been enabled!"
else
- echo "::: Invalid option passed, please pass 'on' or 'off'"
+ echo -e " ${COL_LIGHT_RED}Invalid option${COL_NC}
+ Try 'pihole logging --help' for more information."
exit 1
fi
restartDNS
+ echo -e "${OVER} ${TICK} ${str}"
}
piholeStatus() {
if [[ "$(netstat -plnt | grep -c ':53 ')" -gt "0" ]]; then
if [[ "${1}" != "web" ]]; then
- echo "::: DNS service is running"
+ echo -e " ${TICK} DNS service is running"
fi
else
if [[ "${1}" == "web" ]]; then
echo "-1";
else
- echo "::: DNS service is NOT running"
+ echo -e " ${CROSS} DNS service is NOT running"
fi
return
fi
@@ -275,21 +317,21 @@ piholeStatus() {
if [[ "${1}" == "web" ]]; then
echo 0;
else
- echo "::: Pi-hole blocking is Disabled";
+ echo -e " ${CROSS} Pi-hole blocking is Disabled";
fi
elif [[ "$(grep -i "^addn-hosts=/" /etc/dnsmasq.d/01-pihole.conf)" ]]; then
# List set
if [[ "${1}" == "web" ]]; then
echo 1;
else
- echo "::: Pi-hole blocking is Enabled";
+ echo -e " ${TICK} Pi-hole blocking is Enabled";
fi
else
# Addn-host not found
if [[ "${1}" == "web" ]]; then
echo 99
else
- echo "::: No hosts file linked to dnsmasq, adding it in enabled state"
+ echo -e " ${INFO} No hosts file linked to dnsmasq, adding it in enabled state"
fi
# Add addn-host= to dnsmasq
echo "addn-hosts=/etc/pihole/gravity.list" >> /etc/dnsmasq.d/01-pihole.conf
@@ -298,7 +340,7 @@ piholeStatus() {
}
tailFunc() {
- echo "Press Ctrl-C to exit"
+ echo -e " ${INFO} Press Ctrl-C to exit"
tail -F /var/log/pihole.log
exit 0
}
@@ -326,12 +368,12 @@ Branches:
tricorderFunc() {
if [[ ! -p "/dev/stdin" ]]; then
- echo "Please do not call Tricorder directly."
+ echo -e " ${INFO} Please do not call Tricorder directly"
exit 1
fi
if ! timeout 2 nc -z tricorder.pi-hole.net 9998 &> /dev/null; then
- echo "Unable to connect to Pi-hole's Tricorder server."
+ echo -e " ${CROSS} Unable to connect to Pi-hole's Tricorder server"
exit 1
fi
@@ -339,9 +381,10 @@ tricorderFunc() {
openssl s_client -quiet -connect tricorder.pi-hole.net:9998 2> /dev/null < /dev/stdin
exit "$?"
else
- echo "Your debug log will be transmitted unencrypted via plain-text"
- echo "There is a possibility that this could be intercepted by a third party"
- echo "If you wish to cancel, press Ctrl-C to exit within 10 seconds"
+ echo -e " ${INFO} ${COL_YELLOW}Security Notice${COL_NC}: ${COL_WHITE}openssl${COL_NC} is not installed
+ Your debug log will be transmitted unencrypted via plain-text
+ There is a possibility that this could be intercepted by a third party
+ If you wish to cancel, press Ctrl-C to exit within 10 seconds"
secs="10"
while [[ "$secs" -gt "0" ]]; do
echo -ne "."
diff --git a/test/test_automated_install.py b/test/test_automated_install.py
index 60772625..60b9dbb8 100644
--- a/test/test_automated_install.py
+++ b/test/test_automated_install.py
@@ -9,6 +9,10 @@ SETUPVARS = {
'PIHOLE_DNS_2' : '4.2.2.2'
}
+tick_box="[\x1b[1;32m\xe2\x9c\x93\x1b[0m]".decode("utf-8")
+cross_box="[\x1b[1;31m\xe2\x9c\x97\x1b[0m]".decode("utf-8")
+info_box="[i]".decode("utf-8")
+
def test_setupVars_are_sourced_to_global_scope(Pihole):
''' currently update_dialogs sources setupVars with a dot,
then various other functions use the variables.
@@ -173,8 +177,11 @@ def test_installPiholeWeb_fresh_install_no_errors(Pihole):
source /opt/pihole/basic-install.sh
installPiholeWeb
''')
- assert 'Installing pihole custom index page...' in installWeb.stdout
+ assert info_box + ' Installing blocking page...' in installWeb.stdout
+ assert tick_box + ' Creating directory for blocking page, and copying files' in installWeb.stdout
+ assert cross_box + ' Backing up index.lighttpd.html' in installWeb.stdout
assert 'No default index.lighttpd.html file found... not backing up' in installWeb.stdout
+ assert tick_box + ' Installing sudoer file' in installWeb.stdout
web_directory = Pihole.run('ls -r /var/www/html/pihole').stdout
assert 'index.php' in web_directory
assert 'index.js' in web_directory
@@ -187,11 +194,12 @@ def test_installPiholeWeb_empty_directory_no_errors(Pihole):
mkdir -p /var/www/html/pihole
installPiholeWeb
''')
- assert 'Installing pihole custom index page...' in installWeb.stdout
+ assert info_box + ' Installing blocking page...' in installWeb.stdout
+ assert info_box + ' Installing index.php' in installWeb.stdout
+ assert info_box + ' Installing index.js' in installWeb.stdout
+ assert info_box + ' Installing blockingpage.css' in installWeb.stdout
assert 'No default index.lighttpd.html file found... not backing up' not in installWeb.stdout
- assert 'index.php missing, replacing...' in installWeb.stdout
- assert 'index.js missing, replacing...' in installWeb.stdout
- assert 'blockingpage.css missing, replacing...' in installWeb.stdout
+ assert tick_box + ' Installing sudoer file' in installWeb.stdout
web_directory = Pihole.run('ls -r /var/www/html/pihole').stdout
assert 'index.php' in web_directory
assert 'index.js' in web_directory
@@ -205,11 +213,13 @@ def test_installPiholeWeb_index_php_no_errors(Pihole):
touch /var/www/html/pihole/index.php
installPiholeWeb
''')
- assert 'Installing pihole custom index page...' in installWeb.stdout
+ assert info_box + ' Installing blocking page...' in installWeb.stdout
+ assert info_box + ' Installing index.php' in installWeb.stdout
+ assert 'detected index.php, not overwriting' in installWeb.stdout
+ assert info_box + ' Installing index.js' in installWeb.stdout
+ assert info_box + ' Installing blockingpage.css' in installWeb.stdout
assert 'No default index.lighttpd.html file found... not backing up' not in installWeb.stdout
- assert 'Existing index.php detected, not overwriting' in installWeb.stdout
- assert 'index.js missing, replacing...' in installWeb.stdout
- assert 'blockingpage.css missing, replacing...' in installWeb.stdout
+ assert tick_box + ' Installing sudoer file' in installWeb.stdout
web_directory = Pihole.run('ls -r /var/www/html/pihole').stdout
assert 'index.php' in web_directory
assert 'index.js' in web_directory
@@ -223,11 +233,13 @@ def test_installPiholeWeb_index_js_no_errors(Pihole):
touch /var/www/html/pihole/index.js
installPiholeWeb
''')
- assert 'Installing pihole custom index page...' in installWeb.stdout
+ assert info_box + ' Installing blocking page...' in installWeb.stdout
+ assert info_box + ' Installing index.php' in installWeb.stdout
+ assert info_box + ' Installing index.js' in installWeb.stdout
+ assert 'detected index.js, not overwriting' in installWeb.stdout
+ assert info_box + ' Installing blockingpage.css' in installWeb.stdout
assert 'No default index.lighttpd.html file found... not backing up' not in installWeb.stdout
- assert 'index.php missing, replacing...' in installWeb.stdout
- assert 'Existing index.js detected, not overwriting' in installWeb.stdout
- assert 'blockingpage.css missing, replacing...' in installWeb.stdout
+ assert tick_box + ' Installing sudoer file' in installWeb.stdout
web_directory = Pihole.run('ls -r /var/www/html/pihole').stdout
assert 'index.php' in web_directory
assert 'index.js' in web_directory
@@ -241,11 +253,13 @@ def test_installPiholeWeb_blockingpage_css_no_errors(Pihole):
touch /var/www/html/pihole/blockingpage.css
installPiholeWeb
''')
- assert 'Installing pihole custom index page...' in installWeb.stdout
+ assert info_box + ' Installing blocking page...' in installWeb.stdout
+ assert info_box + ' Installing index.php' in installWeb.stdout
+ assert info_box + ' Installing index.js' in installWeb.stdout
+ assert info_box + ' Installing blockingpage.css' in installWeb.stdout
+ assert 'detected blockingpage.css, not overwriting' in installWeb.stdout
assert 'No default index.lighttpd.html file found... not backing up' not in installWeb.stdout
- assert 'index.php missing, replacing...' in installWeb.stdout
- assert 'index.js missing, replacing...' in installWeb.stdout
- assert 'Existing blockingpage.css detected, not overwriting' in installWeb.stdout
+ assert tick_box + ' Installing sudoer file' in installWeb.stdout
web_directory = Pihole.run('ls -r /var/www/html/pihole').stdout
assert 'index.php' in web_directory
assert 'index.js' in web_directory
@@ -261,14 +275,14 @@ def test_installPiholeWeb_already_populated_no_errors(Pihole):
touch /var/www/html/pihole/blockingpage.css
installPiholeWeb
''')
- assert 'Installing pihole custom index page...' in installWeb.stdout
- assert 'No default index.lighttpd.html file found... not backing up' not in installWeb.stdout
- assert 'Existing index.php detected, not overwriting' in installWeb.stdout
- assert 'index.php missing, replacing...' not in installWeb.stdout
- assert 'Existing index.js detected, not overwriting' in installWeb.stdout
- assert 'index.js missing, replacing...' not in installWeb.stdout
- assert 'Existing blockingpage.css detected, not overwriting' in installWeb.stdout
- assert 'blockingpage.css missing, replacing... ' not in installWeb.stdout
+ assert info_box + ' Installing blocking page...' in installWeb.stdout
+ assert info_box + ' Installing index.php' in installWeb.stdout
+ assert 'detected index.php, not overwriting' in installWeb.stdout
+ assert info_box + ' Installing index.js' in installWeb.stdout
+ assert 'detected index.js, not overwriting' in installWeb.stdout
+ assert info_box + ' Installing blockingpage.css' in installWeb.stdout
+ assert 'detected blockingpage.css, not overwriting' in installWeb.stdout
+ assert tick_box + ' Installing sudoer file' in installWeb.stdout
web_directory = Pihole.run('ls -r /var/www/html/pihole').stdout
assert 'index.php' in web_directory
assert 'index.js' in web_directory
@@ -281,9 +295,8 @@ def test_update_package_cache_success_no_errors(Pihole):
distro_check
update_package_cache
''')
- assert 'Updating local cache of available packages...' in updateCache.stdout
- assert 'ERROR' not in updateCache.stdout
- assert 'done!' in updateCache.stdout
+ assert tick_box + ' Update local cache of available packages' in updateCache.stdout
+ assert 'Error: Unable to update package cache.' not in updateCache.stdout
def test_update_package_cache_failure_no_errors(Pihole):
''' confirms package cache was not updated'''
@@ -293,9 +306,8 @@ def test_update_package_cache_failure_no_errors(Pihole):
distro_check
update_package_cache
''')
- assert 'Updating local cache of available packages...' in updateCache.stdout
- assert 'ERROR' in updateCache.stdout
- assert 'done!' not in updateCache.stdout
+ assert cross_box + ' Update local cache of available packages' in updateCache.stdout
+ assert 'Error: Unable to update package cache.' in updateCache.stdout
def test_FTL_detect_aarch64_no_errors(Pihole):
''' confirms only aarch64 package is downloaded for FTL engine '''
@@ -307,7 +319,11 @@ def test_FTL_detect_aarch64_no_errors(Pihole):
source /opt/pihole/basic-install.sh
FTLdetect
''')
- expected_stdout = 'Detected ARM-aarch64 architecture'
+ expected_stdout = info_box + ' Downloading latest version of FTL...'
+ assert expected_stdout in detectPlatform.stdout
+ expected_stdout = tick_box + ' Detected ARM-aarch64 architecture'
+ assert expected_stdout in detectPlatform.stdout
+ expected_stdout = tick_box + ' Installing FTL'
assert expected_stdout in detectPlatform.stdout
def test_FTL_detect_armv6l_no_errors(Pihole):
@@ -320,7 +336,11 @@ def test_FTL_detect_armv6l_no_errors(Pihole):
source /opt/pihole/basic-install.sh
FTLdetect
''')
- expected_stdout = 'Detected ARM-hf architecture (armv6 or lower)'
+ expected_stdout = info_box + ' Downloading latest version of FTL...'
+ assert expected_stdout in detectPlatform.stdout
+ expected_stdout = tick_box + ' Detected ARM-hf architecture (armv6 or lower)'
+ assert expected_stdout in detectPlatform.stdout
+ expected_stdout = tick_box + ' Installing FTL'
assert expected_stdout in detectPlatform.stdout
def test_FTL_detect_armv7l_no_errors(Pihole):
@@ -333,7 +353,11 @@ def test_FTL_detect_armv7l_no_errors(Pihole):
source /opt/pihole/basic-install.sh
FTLdetect
''')
- expected_stdout = 'Detected ARM-hf architecture (armv7+)'
+ expected_stdout = info_box + ' Downloading latest version of FTL...'
+ assert expected_stdout in detectPlatform.stdout
+ expected_stdout = tick_box + ' Detected ARM-hf architecture (armv7+)'
+ assert expected_stdout in detectPlatform.stdout
+ expected_stdout = tick_box + ' Installing FTL'
assert expected_stdout in detectPlatform.stdout
def test_FTL_detect_x86_64_no_errors(Pihole):
@@ -342,7 +366,11 @@ def test_FTL_detect_x86_64_no_errors(Pihole):
source /opt/pihole/basic-install.sh
FTLdetect
''')
- expected_stdout = 'Detected x86_64 architecture'
+ expected_stdout = info_box + ' Downloading latest version of FTL...'
+ assert expected_stdout in detectPlatform.stdout
+ expected_stdout = tick_box + ' Detected x86_64 architecture'
+ assert expected_stdout in detectPlatform.stdout
+ expected_stdout = tick_box + ' Installing FTL'
assert expected_stdout in detectPlatform.stdout
def test_FTL_detect_unknown_no_errors(Pihole):
@@ -363,9 +391,12 @@ def test_FTL_download_aarch64_no_errors(Pihole):
source /opt/pihole/basic-install.sh
FTLinstall pihole-FTL-aarch64-linux-gnu
''')
- expected_stdout = 'done'
+ expected_stdout = tick_box + ' Installing FTL'
assert expected_stdout in download_binary.stdout
- assert 'failed' not in download_binary.stdout
+ error = 'Error: Download of binary from Github failed'
+ assert error not in download_binary.stdout
+ error = 'Error: URL not found'
+ assert error not in download_binary.stdout
def test_FTL_download_unknown_fails_no_errors(Pihole):
''' confirms unknown binary is not downloaded for FTL engine '''
@@ -374,9 +405,10 @@ def test_FTL_download_unknown_fails_no_errors(Pihole):
source /opt/pihole/basic-install.sh
FTLinstall pihole-FTL-mips
''')
- expected_stdout = 'failed'
+ expected_stdout = cross_box + ' Installing FTL'
assert expected_stdout in download_binary.stdout
- assert 'done' not in download_binary.stdout
+ error = 'Error: URL not found'
+ assert error in download_binary.stdout
def test_FTL_binary_installed_and_responsive_no_errors(Pihole):
''' confirms FTL binary is copied and functional in installed location '''
From c85a6034917e642e57bcb983c06badac51be1cc1 Mon Sep 17 00:00:00 2001
From: Dan Schaper
Date: Wed, 21 Jun 2017 08:19:19 -0700
Subject: [PATCH 096/162] Update PULL_REQUEST_TEMPLATE.md
---
.github/PULL_REQUEST_TEMPLATE.md | 19 +++++++++----------
1 file changed, 9 insertions(+), 10 deletions(-)
diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md
index 424bbc78..2a75bca4 100644
--- a/.github/PULL_REQUEST_TEMPLATE.md
+++ b/.github/PULL_REQUEST_TEMPLATE.md
@@ -3,17 +3,16 @@
***Please submit all pull requests against the `development` branch. Failure to do so will delay or deny your request***
- [] I have read and understood the [contributors guide](https://github.com/pi-hole/pi-hole/blob/master/CONTRIBUTING.md).
-- [] I have checked that [another pull request](https://github.com/pi-hole/pi-hole/pulls) for this purpose does not exist.
-- [] I have considered, and confirmed that this submission will be valuable to others.
-- [] I accept that this submission may not be used, and the pull request closed at the will of the maintainer.
-- [] I give this submission freely, and claim no ownership to its content.
+- [] I have written tests and verified that they fail without my change
+- [] I have squashed any insignificant commits
+- [] This change has comments for package types, values, functions, and non-obvious lines of code
+- [] I am willing to help maintain this change if there are issues with it later
+- [] I give this submission freely, and claim no ownership to its content. And I have Signed Off all commits.
-**How familiar are you with the codebase?:**
+***Please explain what you have done and wish to accomplish with this Pull Request***
-_{replace this text with a number from 1 to 10, with 1 being not familiar, and 10 being very familiar}_
+1. What does this change do, exactly?
----
-_{replace this line with your pull request content}_
+2. Please link to the relevant issues.
-
-_This template was created based on the work of [`udemy-dl`](https://github.com/nishad/udemy-dl/blob/master/LICENSE)._
+3. Which documentation changes (if any) need to be made because of this PR?
From a4650c62264b9fd455c3b74fd4484c524e4b1930 Mon Sep 17 00:00:00 2001
From: Dan Schaper
Date: Wed, 21 Jun 2017 08:26:59 -0700
Subject: [PATCH 097/162] Update PULL_REQUEST_TEMPLATE.md
---
.github/PULL_REQUEST_TEMPLATE.md | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md
index 2a75bca4..ae241fdf 100644
--- a/.github/PULL_REQUEST_TEMPLATE.md
+++ b/.github/PULL_REQUEST_TEMPLATE.md
@@ -7,7 +7,8 @@
- [] I have squashed any insignificant commits
- [] This change has comments for package types, values, functions, and non-obvious lines of code
- [] I am willing to help maintain this change if there are issues with it later
-- [] I give this submission freely, and claim no ownership to its content. And I have Signed Off all commits.
+- [] I give this submission freely, and claim no ownership to its content
+- [] I have Signed Off all commits.
***Please explain what you have done and wish to accomplish with this Pull Request***
From 06d5ea9d51ee765730dc1204139a633a072c3029 Mon Sep 17 00:00:00 2001
From: Dan Schaper
Date: Thu, 22 Jun 2017 12:59:07 -0700
Subject: [PATCH 098/162] Grammar and signoff instructions.
Signed-off-by: Dan Schaper
---
.github/PULL_REQUEST_TEMPLATE.md | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md
index ae241fdf..8583806b 100644
--- a/.github/PULL_REQUEST_TEMPLATE.md
+++ b/.github/PULL_REQUEST_TEMPLATE.md
@@ -3,12 +3,12 @@
***Please submit all pull requests against the `development` branch. Failure to do so will delay or deny your request***
- [] I have read and understood the [contributors guide](https://github.com/pi-hole/pi-hole/blob/master/CONTRIBUTING.md).
-- [] I have written tests and verified that they fail without my change
-- [] I have squashed any insignificant commits
-- [] This change has comments for package types, values, functions, and non-obvious lines of code
-- [] I am willing to help maintain this change if there are issues with it later
-- [] I give this submission freely, and claim no ownership to its content
-- [] I have Signed Off all commits.
+- [] I have written tests and verified that they fail without my change.
+- [] I have squashed any insignificant commits.
+- [] This change has comments for package types, values, functions, and non-obvious lines of code.
+- [] I am willing to help maintain this change if there are issues with it later.
+- [] I give this submission freely and claim no ownership. It is compatible with the EUPL 1.2 license.
+- [] I have Signed Off all commits. (`git commit --signoff`)
***Please explain what you have done and wish to accomplish with this Pull Request***
From cb09e0bc9af11625729c7976cf50c771b44c0299 Mon Sep 17 00:00:00 2001
From: Mcat12
Date: Sat, 24 Jun 2017 11:14:23 -0400
Subject: [PATCH 099/162] Strip `/*` from the end of the IPv6 address
Fixes #1536
---
advanced/Scripts/list.sh | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/advanced/Scripts/list.sh b/advanced/Scripts/list.sh
index 9d587296..e7151cf6 100755
--- a/advanced/Scripts/list.sh
+++ b/advanced/Scripts/list.sh
@@ -123,9 +123,9 @@ AddDomain() {
fi
elif [[ "${list}" == "${wildcardlist}" ]]; then
source "${piholeDir}/setupVars.conf"
- # Remove the /* from the end of the IPv4addr.
+ # Remove the /* from the end of the IP addresses
IPV4_ADDRESS=${IPV4_ADDRESS%/*}
- IPV6_ADDRESS=${IPV6_ADDRESS}
+ IPV6_ADDRESS=${IPV6_ADDRESS%/*}
bool=true
# Is the domain in the list?
From 0c2827e1308df7cb703391a20cc01b0e92795632 Mon Sep 17 00:00:00 2001
From: Dan Schaper
Date: Sat, 24 Jun 2017 15:49:16 -0700
Subject: [PATCH 100/162] Test exclusion for sourced files SC1090.
Signed-off-by: Dan Schaper
---
test/test_shellcheck.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/test/test_shellcheck.py b/test/test_shellcheck.py
index fa342027..9c4f141b 100644
--- a/test/test_shellcheck.py
+++ b/test/test_shellcheck.py
@@ -7,7 +7,7 @@ run_local = testinfra.get_backend(
def test_scripts_pass_shellcheck():
''' Make sure shellcheck does not find anything wrong with our shell scripts '''
- shellcheck = "find . -type f \( -name 'update.sh' -o -name 'piholeDebug.sh' \) | while read file; do shellcheck \"$file\"; done;"
+ shellcheck = "find . -type f \( -name 'update.sh' -o -name 'piholeDebug.sh' \) | while read file; do shellcheck \"$file\" -e SC1090; done;"
results = run_local(shellcheck)
print results.stdout
assert '' == results.stdout
From bc46694ea709175c22c7f92531511f1dc8381d3e Mon Sep 17 00:00:00 2001
From: Mcat12
Date: Sun, 25 Jun 2017 12:18:09 -0400
Subject: [PATCH 101/162] Move local.list after the ad blocking lists
Fixes the bug found by [Reddit](https://www.reddit.com/r/pihole/comments/6j3az9/urls_in_my_blacklist_are_showing_up_as_my_default/)
---
advanced/01-pihole.conf | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/advanced/01-pihole.conf b/advanced/01-pihole.conf
index 79735c15..8b772ae8 100644
--- a/advanced/01-pihole.conf
+++ b/advanced/01-pihole.conf
@@ -21,8 +21,8 @@
###############################################################################
addn-hosts=/etc/pihole/gravity.list
-addn-hosts=/etc/pihole/local.list
addn-hosts=/etc/pihole/black.list
+addn-hosts=/etc/pihole/local.list
domain-needed
From 07fc047dd8ce195bd5216e6a52d32348b9a70561 Mon Sep 17 00:00:00 2001
From: Dan Schaper
Date: Sun, 25 Jun 2017 12:26:16 -0700
Subject: [PATCH 102/162] Remove testing for `debug` as this is getting a
re-write by Jacob.
Signed-off-by: Dan Schaper
---
test/test_shellcheck.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/test/test_shellcheck.py b/test/test_shellcheck.py
index 9c4f141b..1b6b35a7 100644
--- a/test/test_shellcheck.py
+++ b/test/test_shellcheck.py
@@ -7,7 +7,7 @@ run_local = testinfra.get_backend(
def test_scripts_pass_shellcheck():
''' Make sure shellcheck does not find anything wrong with our shell scripts '''
- shellcheck = "find . -type f \( -name 'update.sh' -o -name 'piholeDebug.sh' \) | while read file; do shellcheck \"$file\" -e SC1090; done;"
+ shellcheck = "find . -type f -name 'update.sh' | while read file; do shellcheck \"$file\" -e SC1090; done;"
results = run_local(shellcheck)
print results.stdout
assert '' == results.stdout
From c29c4ceb0f179f6e0ba0775edd265bdd7029987a Mon Sep 17 00:00:00 2001
From: Dan Schaper
Date: Sun, 25 Jun 2017 14:21:41 -0700
Subject: [PATCH 103/162] Integrate DL's update.sh fixes.
`shellcheck -x` for following files.
Do not test for included files SC1091
Signed-off-by: Dan Schaper
---
advanced/Scripts/update.sh | 25 +++++++++++++++----------
test/test_shellcheck.py | 2 +-
2 files changed, 16 insertions(+), 11 deletions(-)
diff --git a/advanced/Scripts/update.sh b/advanced/Scripts/update.sh
index e8155f1a..779f6c8d 100755
--- a/advanced/Scripts/update.sh
+++ b/advanced/Scripts/update.sh
@@ -19,12 +19,14 @@ readonly ADMIN_INTERFACE_DIR="/var/www/html/admin"
readonly PI_HOLE_GIT_URL="https://github.com/pi-hole/pi-hole.git"
readonly PI_HOLE_FILES_DIR="/etc/.pihole"
+# shellcheck disable=SC2034
PH_TEST=true
-source ${PI_HOLE_FILES_DIR}/automated\ install/basic-install.sh
-colfile="/opt/pihole/COL_TABLE"
-source ${colfile}
+# Have to ignore the following rule as spaces in paths are not supported by ShellCheck
+#shellcheck disable=SC1090
+source "${PI_HOLE_FILES_DIR}/automated install/basic-install.sh"
+source "/opt/pihole/COL_TABLE"
# is_repo() sourced from basic-install.sh
# make_repo() sourced from basic-install.sh
@@ -34,14 +36,14 @@ source ${colfile}
GitCheckUpdateAvail() {
local directory="${1}"
curdir=$PWD
- cd "${directory}"
+ cd "${directory}" || return
# Fetch latest changes in this repo
git fetch --quiet origin
# @ alone is a shortcut for HEAD. Older versions of git
# need @{0}
- LOCAL="$(git rev-parse @{0})"
+ LOCAL="$("git rev-parse @{0}")"
# The suffix @{upstream} to a branchname
# (short form @{u}) refers
@@ -50,7 +52,7 @@ GitCheckUpdateAvail() {
# (configured with branch..remote and
# branch..merge). A missing branchname
# defaults to the current one.
- REMOTE="$(git rev-parse @{upstream})"
+ REMOTE="$("git rev-parse @{upstream}")"
if [[ ${#LOCAL} == 0 ]]; then
echo -e " ${COL_LIGHT_RED}Error: Local revision could not be obtained, ask Pi-hole support."
@@ -66,7 +68,7 @@ GitCheckUpdateAvail() {
fi
# Change back to original directory
- cd "${curdir}"
+ cd "${curdir}" || exit
if [[ "${LOCAL}" != "${REMOTE}" ]]; then
# Local branch is behind remote branch -> Update
@@ -81,8 +83,10 @@ GitCheckUpdateAvail() {
FTLcheckUpdate() {
- local FTLversion=$(/usr/bin/pihole-FTL tag)
- local FTLlatesttag=$(curl -sI https://github.com/pi-hole/FTL/releases/latest | grep 'Location' | awk -F '/' '{print $NF}' | tr -d '\r\n')
+ local FTLversion
+ FTLversion=$(/usr/bin/pihole-FTL tag)
+ local FTLlatesttag
+ FTLlatesttag=$(curl -sI https://github.com/pi-hole/FTL/releases/latest | grep 'Location' | awk -F '/' '{print $NF}' | tr -d '\r\n')
if [[ "${FTLversion}" != "${FTLlatesttag}" ]]; then
return 0
@@ -94,6 +98,7 @@ FTLcheckUpdate() {
main() {
local pihole_version_current
local web_version_current
+ #shellcheck disable=1090,2154
source "${setupVars}"
#This is unlikely
@@ -120,7 +125,7 @@ main() {
FTL_update=false
echo -e " ${INFO} FTL:\t\t${COL_LIGHT_GREEN}up to date${COL_NC}"
fi
-
+
# Logic: Don't update FTL when there is a core update available
# since the core update will run the installer which will itself
# re-install (i.e. update) FTL
diff --git a/test/test_shellcheck.py b/test/test_shellcheck.py
index 1b6b35a7..5b1a8961 100644
--- a/test/test_shellcheck.py
+++ b/test/test_shellcheck.py
@@ -7,7 +7,7 @@ run_local = testinfra.get_backend(
def test_scripts_pass_shellcheck():
''' Make sure shellcheck does not find anything wrong with our shell scripts '''
- shellcheck = "find . -type f -name 'update.sh' | while read file; do shellcheck \"$file\" -e SC1090; done;"
+ shellcheck = "find . -type f -name 'update.sh' | while read file; do shellcheck -x \"$file\" -e SC1090,SC1091; done;"
results = run_local(shellcheck)
print results.stdout
assert '' == results.stdout
From 1e31fa89aa722ed4290755356c88a9629f99cd3e Mon Sep 17 00:00:00 2001
From: Mcat12
Date: Mon, 26 Jun 2017 09:51:21 -0400
Subject: [PATCH 104/162] Remove /* from IPv6 as well as IPv4
Fixes Discourse issue: https://discourse.pi-hole.net/t/ipv6-aaaa-dns-issue/3830
---
gravity.sh | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/gravity.sh b/gravity.sh
index bc7637e3..168a4350 100755
--- a/gravity.sh
+++ b/gravity.sh
@@ -43,9 +43,9 @@ else
exit 1
fi
-# Remove the /* from the end of the IPv4addr.
+# Remove the /* from the end of the IP addresses
IPV4_ADDRESS=${IPV4_ADDRESS%/*}
-IPV6_ADDRESS=${IPV6_ADDRESS}
+IPV6_ADDRESS=${IPV6_ADDRESS%/*}
# Variables for various stages of downloading and formatting the list
basename=pihole
From 5f00347019d2341cfa1a3f9e130b4ce92ae8acb9 Mon Sep 17 00:00:00 2001
From: Jacob Salmela
Date: Mon, 26 Jun 2017 21:34:39 -0500
Subject: [PATCH 105/162] appease shellcheck by removing two unneccesary
functions and making some if/else blocks
---
advanced/Scripts/piholeDebug.sh | 44 +++++++++------------------------
1 file changed, 12 insertions(+), 32 deletions(-)
diff --git a/advanced/Scripts/piholeDebug.sh b/advanced/Scripts/piholeDebug.sh
index d6526d9c..59029eb0 100755
--- a/advanced/Scripts/piholeDebug.sh
+++ b/advanced/Scripts/piholeDebug.sh
@@ -131,6 +131,7 @@ ${WEB_GIT_DIRECTORY}
${BLOCK_PAGE_DIRECTORY})
# Store the required directories in an array so it can be parsed through
+mapfile -t array <<< "$var"
REQUIRED_FILES=(${PIHOLE_CRON_FILE}
${PIHOLE_DNS_CONFIG_FILE}
${PIHOLE_DHCP_CONFIG_FILE}
@@ -190,20 +191,6 @@ copy_to_debug_log() {
cat /proc/$$/fd/3 >> "${PIHOLE_DEBUG_LOG}"
}
-echo_succes_or_fail() {
- # If the command was successful (a zero),
- if [[ $? -eq 0 ]]; then
- # Set the first argument passed to this function as a named variable for better readability
- local message="${1}"
- # show success
- log_write "${TICK} ${message}"
- else
- local message="${1}"
- # Otherwise, show a error
- log_write "${CROSS} ${message}"
- fi
-}
-
initiate_debug() {
# Clear the screen so the debug log is readable
clear
@@ -235,19 +222,6 @@ if_file_exists() {
fi
}
-if_directory_exists() {
- # Set the first argument passed to tihs function as a named variable for better readability
- local directory_to_test="${1}"
- # If the file is readable
- if [[ -d "${directory_to_test}" ]]; then
- # Return success
- return 0
- else
- # Otherwise, return a failure
- return 1
- fi
-}
-
compare_local_version_to_git_version() {
# The git directory to check
local git_dir="${1}"
@@ -266,18 +240,21 @@ compare_local_version_to_git_version() {
# Store the error message in a variable in case we want to change and/or reuse it
local error_msg="git status failed"
# If the pihole git directory exists,
- if_directory_exists "${git_dir}" && \
+ if [[ -d "${git_dir}" ]]; then
# move into it
cd "${git_dir}" || \
# If not, show an error
log_write "${COL_LIGHT_RED}Could not cd into ${git_dir}$COL_NC"
if git status &> /dev/null; then
# The current version the user is on
- local remote_version=$(git describe --tags --abbrev=0);
+ local remote_version
+ remote_version=$(git describe --tags --abbrev=0);
# What branch they are on
- local remote_branch=$(git rev-parse --abbrev-ref HEAD);
+ local remote_branch
+ remote_branch=$(git rev-parse --abbrev-ref HEAD);
# The commit they are on
- local remote_commit=$(git describe --long --dirty --tags --always)
+ local remote_commit
+ remote_commit=$(git describe --long --dirty --tags --always)
# echo this information out to the user in a nice format
# If the current version matches what pihole -v produces, the user is up-to-date
if [[ "${remote_version}" == "$(pihole -v | awk '/${search_term}/ {print $6}' | cut -d ')' -f1)" ]]; then
@@ -307,6 +284,9 @@ compare_local_version_to_git_version() {
# and exit with a non zero code
return 1
fi
+ else
+ :
+ fi
}
check_ftl_version() {
@@ -874,7 +854,7 @@ dir_check() {
# do nothing
: || \
# Otherwise, show an error
- echo_succes_or_fail "${COL_LIGHT_RED}${directory} does not exist.${COL_NC}"
+ log_write "${COL_LIGHT_RED}${directory} does not exist.${COL_NC}"
done
}
From b6a2a4ad5a8c67c9f214aa38e69337036417bd23 Mon Sep 17 00:00:00 2001
From: Jacob Salmela
Date: Mon, 26 Jun 2017 21:51:41 -0500
Subject: [PATCH 106/162] more shellcheck fixes
---
advanced/Scripts/piholeDebug.sh | 16 ++++++++++------
1 file changed, 10 insertions(+), 6 deletions(-)
diff --git a/advanced/Scripts/piholeDebug.sh b/advanced/Scripts/piholeDebug.sh
index 59029eb0..2b45eb72 100755
--- a/advanced/Scripts/piholeDebug.sh
+++ b/advanced/Scripts/piholeDebug.sh
@@ -372,7 +372,7 @@ get_distro_attributes() {
OLD_IFS="$IFS"
# Store the distro info in an array and make it global since the OS won't change,
# but we'll keep it within the function for better unit testing
- IFS=$'\r\n' command eval 'distro_info=( $(cat /etc/*release) )'
+ IFS=$'\r\n' command eval "distro_info=( $(cat /etc/*release) )"
# Set a named variable for better readability
local distro_attribute
@@ -402,11 +402,13 @@ diagnose_operating_system() {
echo_current_diagnostic "Operating system"
# If there is a /etc/*release file, it's probably a supported operating system, so we can
- if_file_exists /etc/*release && \
+ if [[ -r /etc/*release ]]; then
# display the attributes to the user from the function made earlier
- get_distro_attributes || \
+ get_distro_attributes
+ else
# If it doesn't exist, it's not a system we currently support and link to FAQ
log_write "${CROSS} ${COL_LIGHT_RED}${error_msg}${COL_NC} (${FAQ_HARDWARE_REQUIREMENTS})"
+ fi
}
processor_check() {
@@ -440,11 +442,13 @@ processor_check() {
parse_setup_vars() {
echo_current_diagnostic "Setup variables"
# If the file exists,
- if_file_exists "${PIHOLE_SETUP_VARS_FILE}" && \
+ if [[ -r "${PIHOLE_SETUP_VARS_FILE}" ]]; then
# parse it
- parse_file "${PIHOLE_SETUP_VARS_FILE}" || \
+ parse_file "${PIHOLE_SETUP_VARS_FILE}"
+ else
# If not, show an error
log_write "${CROSS} ${COL_LIGHT_RED}Could not read ${PIHOLE_SETUP_VARS_FILE}.${COL_NC}"
+ fi
}
does_ip_match_setup_vars() {
@@ -453,7 +457,7 @@ does_ip_match_setup_vars() {
# IP address to check for
local ip_address="${2}"
# See what IP is in the setupVars.conf file
- local setup_vars_ip=$(cat ${PIHOLE_SETUP_VARS_FILE} | grep IPV${protocol}_ADDRESS | cut -d '=' -f2)
+ local setup_vars_ip=$(< ${PIHOLE_SETUP_VARS_FILE} | grep IPV${protocol}_ADDRESS | cut -d '=' -f2)
# If it's an IPv6 address
if [[ "${protocol}" == "6" ]]; then
# Strip off the / (CIDR notation)
From 22fac5e1e0bfed3a0df3964969e3b7f4ed889c0d Mon Sep 17 00:00:00 2001
From: Jacob Salmela
Date: Mon, 26 Jun 2017 22:03:45 -0500
Subject: [PATCH 107/162] additional shellcheck fixes
---
advanced/Scripts/piholeDebug.sh | 64 ++++++++++++++++-----------------
1 file changed, 30 insertions(+), 34 deletions(-)
diff --git a/advanced/Scripts/piholeDebug.sh b/advanced/Scripts/piholeDebug.sh
index 2b45eb72..cdeea52c 100755
--- a/advanced/Scripts/piholeDebug.sh
+++ b/advanced/Scripts/piholeDebug.sh
@@ -162,12 +162,14 @@ source_setup_variables() {
# Display the current test that is running
log_write "\n${COL_LIGHT_PURPLE}*** [ INITIALIZING ]${COL_NC} Sourcing setup variables"
# If the variable file exists,
- if_file_exists "${PIHOLE_SETUP_VARS_FILE}" && \
+ if ls "${PIHOLE_SETUP_VARS_FILE}" 1> /dev/null 2>&1; then
log_write "${INFO} Sourcing ${PIHOLE_SETUP_VARS_FILE}...";
# source it
- source ${PIHOLE_SETUP_VARS_FILE} || \
+ source ${PIHOLE_SETUP_VARS_FILE}
+ else
# If it can't, show an error
log_write "${PIHOLE_SETUP_VARS_FILE} ${COL_LIGHT_RED}does not exist or cannot be read.${COL_NC}"
+ fi
}
make_temporary_log() {
@@ -209,19 +211,6 @@ echo_current_diagnostic() {
log_write "\n${COL_LIGHT_PURPLE}*** [ DIAGNOSING ]:${COL_NC} ${1}"
}
-if_file_exists() {
- # Set the first argument passed to tihs function as a named variable for better readability
- local file_to_test="${1}"
- # If the file is readable
- if [[ -r "${file_to_test}" ]]; then
- # Return success
- return 0
- else
- # Otherwise, return a failure
- return 1
- fi
-}
-
compare_local_version_to_git_version() {
# The git directory to check
local git_dir="${1}"
@@ -372,7 +361,7 @@ get_distro_attributes() {
OLD_IFS="$IFS"
# Store the distro info in an array and make it global since the OS won't change,
# but we'll keep it within the function for better unit testing
- IFS=$'\r\n' command eval "distro_info=( $(cat /etc/*release) )"
+ IFS=$'\r\n' command eval 'distro_info=( $(cat /etc/*release) )'
# Set a named variable for better readability
local distro_attribute
@@ -402,7 +391,7 @@ diagnose_operating_system() {
echo_current_diagnostic "Operating system"
# If there is a /etc/*release file, it's probably a supported operating system, so we can
- if [[ -r /etc/*release ]]; then
+ if ls /etc/*release 1> /dev/null 2>&1; then
# display the attributes to the user from the function made earlier
get_distro_attributes
else
@@ -457,7 +446,7 @@ does_ip_match_setup_vars() {
# IP address to check for
local ip_address="${2}"
# See what IP is in the setupVars.conf file
- local setup_vars_ip=$(< ${PIHOLE_SETUP_VARS_FILE} | grep IPV${protocol}_ADDRESS | cut -d '=' -f2)
+ local setup_vars_ip=$(cat ${PIHOLE_SETUP_VARS_FILE} | grep IPV${protocol}_ADDRESS | cut -d '=' -f2)
# If it's an IPv6 address
if [[ "${protocol}" == "6" ]]; then
# Strip off the / (CIDR notation)
@@ -613,10 +602,12 @@ check_required_ports() {
done < <( lsof -i -P -n | awk -F' ' '/LISTEN/ {print $9, $1}' | sort -n | uniq | cut -d':' -f2 )
# Now that we have the values stored,
- for i in ${!ports_in_use[@]}; do
+ for i in "${!ports_in_use[@]}"; do
# loop through them and assign some local variables
- local port_number="$(echo "${ports_in_use[$i]}" | awk '{print $1}')"
- local service_name=$(echo "${ports_in_use[$i]}" | awk '{print $2}')
+ local port_number
+ port_number="$(echo "${ports_in_use[$i]}" | awk '{print $1}')"
+ local service_name
+ service_name=$(echo "${ports_in_use[$i]}" | awk '{print $2}')
# Use a case statement to determine if the right services are using the right ports
case "${port_number}" in
53) compare_port_to_service_assigned "${resolver}"
@@ -647,14 +638,18 @@ 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=$(curl -Is localhost | awk '/X-Pi-hole/' | tr -d '\r')
+ 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 dashboard=$(curl -Is localhost/admin/ | awk '/X-Pi-hole/' | tr -d '\r')
+ local dashboard
+ dashboard=$(curl -Is localhost/admin/ | awk '/X-Pi-hole/' | tr -d '\r')
# Store what the X-Header shoud be in variables for comparision later
- local block_page_working="X-Pi-hole: A black hole for Internet advertisements."
- local dashboard_working="X-Pi-hole: The Pi-hole Web interface is working!"
+ 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!"
# If the X-header found by curl matches what is should be,
- if [[ $block_page == $block_page_working ]]; then
+ if [[ $block_page == "$block_page_working" ]]; then
# display a success message
log_write "$TICK ${COL_LIGHT_GREEN}${block_page}${COL_NC}"
else
@@ -663,7 +658,7 @@ check_x_headers() {
fi
# Same logic applies to the dashbord as above, if the X-Header matches what a working system shoud have,
- if [[ $dashboard == $dashboard_working ]]; then
+ if [[ $dashboard == "$dashboard_working" ]]; then
# then we can show a success
log_write "$TICK ${COL_LIGHT_GREEN}${dashboard}${COL_NC}"
else
@@ -682,7 +677,6 @@ dig_at() {
echo_current_diagnostic "Name resolution (IPv${protocol}) using a random blocked domain and a known ad-serving domain"
# Set more local variables
# We need to test name resolution locally, via Pi-hole, and via a public resolver
- local url
local local_dig
local pihole_dig
local remote_dig
@@ -852,13 +846,15 @@ dir_check() {
# Display the current test that is running
echo_current_diagnostic "contents of ${COL_CYAN}${directory}${COL_NC}"
# For each file in the directory,
- for filename in "${directory}"; do
+ for filename in ${directory}; do
# check if exists first; if it does,
- if_file_exists "${filename}" && \
- # do nothing
- : || \
- # Otherwise, show an error
- log_write "${COL_LIGHT_RED}${directory} does not exist.${COL_NC}"
+ if ls "${filename}" 1> /dev/null 2>&1; then
+ # do nothing
+ :
+ else
+ # Otherwise, show an error
+ log_write "${COL_LIGHT_RED}${directory} does not exist.${COL_NC}"
+ fi
done
}
From e9d81fc883c6ce6aa5739d0f5538b8400fd18520 Mon Sep 17 00:00:00 2001
From: DL6ER
Date: Tue, 27 Jun 2017 10:53:24 +0200
Subject: [PATCH 108/162] Backend additions for aufit log feature (#1399)
---
advanced/Scripts/webpage.sh | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/advanced/Scripts/webpage.sh b/advanced/Scripts/webpage.sh
index b05cdbfb..a49d5283 100755
--- a/advanced/Scripts/webpage.sh
+++ b/advanced/Scripts/webpage.sh
@@ -441,6 +441,11 @@ Teleporter() {
php /var/www/html/admin/scripts/pi-hole/php/teleporter.php > "pi-hole-teleporter_${datetimestamp}.zip"
}
+audit()
+{
+ echo "${args[2]}" >> /etc/pihole/auditlog.list
+}
+
main() {
args=("$@")
@@ -467,6 +472,7 @@ main() {
"-i" | "interface" ) SetListeningMode "$@";;
"-t" | "teleporter" ) Teleporter;;
"adlist" ) CustomizeAdLists;;
+ "audit" ) audit;;
* ) helpFunc;;
esac
From 98afb0e9980a716666031206d9955830e9f727f5 Mon Sep 17 00:00:00 2001
From: DL6ER
Date: Tue, 27 Jun 2017 14:28:05 +0200
Subject: [PATCH 109/162] pihole checkout ftl
---
advanced/Scripts/piholeCheckout.sh | 125 +++++++++++++++++++++++++++--
1 file changed, 118 insertions(+), 7 deletions(-)
diff --git a/advanced/Scripts/piholeCheckout.sh b/advanced/Scripts/piholeCheckout.sh
index 102db2ba..d4a85e8a 100644
--- a/advanced/Scripts/piholeCheckout.sh
+++ b/advanced/Scripts/piholeCheckout.sh
@@ -24,6 +24,93 @@ update="false"
coltable="/opt/pihole/COL_TABLE"
source ${coltable}
+check_download_exists() {
+ status=$(curl --head --silent "https://ftl.pi-hole.net/${1}" | head -n 1)
+ if echo "$status" | grep -q "404"; then
+ return 1
+ else
+ return 0
+ fi
+}
+
+FTLinstall() {
+ # Download and install FTL binary
+ local binary="${1}"
+ local path="${2}"
+ local str="Installing FTL"
+ echo -ne " ${INFO} ${str}..."
+
+ if curl -sSL --fail "https://ftl.pi-hole.net/${path}" -o "/tmp/${binary}"; then
+ # Get sha1 of the binary we just downloaded for verification.
+ curl -sSL --fail "https://ftl.pi-hole.net/${path}.sha1" -o "/tmp/${binary}.sha1"
+ # Check if we just downloaded text, or a binary file.
+ cd /tmp
+ if sha1sum --status --quiet -c "${binary}".sha1; then
+ echo -n "transferred... "
+ stop_service pihole-FTL &> /dev/null
+ install -T -m 0755 "/tmp/${binary}" "/usr/bin/pihole-FTL"
+ rm "/tmp/${binary}" "/tmp/${binary}.sha1"
+ start_service pihole-FTL &> /dev/null
+ echo -e "${OVER} ${TICK} ${str}"
+ return 0
+ else
+ echo -e "${OVER} ${CROSS} ${str}"
+ echo -e " ${COL_LIGHT_RED}Error: Download of binary from ftl.pi-hole.net failed${COL_NC}"
+ return 1
+ fi
+ else
+ echo -e "${OVER} ${CROSS} ${str}"
+ echo -e " ${COL_LIGHT_RED}Error: URL not found${COL_NC}"
+ fi
+}
+
+get_binary_name() {
+ local machine
+
+ machine=$(uname -m)
+
+ local str="Detecting architecture"
+ echo -ne " ${INFO} ${str}..."
+ if [[ ${machine} == arm* || ${machine} == *aarch* ]]; then
+ # ARM
+ local rev=$(uname -m | sed "s/[^0-9]//g;")
+ local lib=$(ldd /bin/ls | grep -E '^\s*/lib' | awk '{ print $1 }')
+ if [[ "$lib" == "/lib/ld-linux-aarch64.so.1" ]]; then
+ echo -e "${OVER} ${TICK} Detected ARM-aarch64 architecture"
+ binary="pihole-FTL-aarch64-linux-gnu"
+ elif [[ "$lib" == "/lib/ld-linux-armhf.so.3" ]]; then
+ if [ "$rev" -gt "6" ]; then
+ echo -e "${OVER} ${TICK} Detected ARM-hf architecture (armv7+)"
+ binary="pihole-FTL-arm-linux-gnueabihf"
+ else
+ echo -e "${OVER} ${TICK} Detected ARM-hf architecture (armv6 or lower) Using ARM binary"
+ binary="pihole-FTL-arm-linux-gnueabi"
+ fi
+ else
+ echo -e "${OVER} ${TICK} Detected ARM architecture"
+ binary="pihole-FTL-arm-linux-gnueabi"
+ fi
+ elif [[ $machine == ppc ]]; then
+ # PowerPC
+ echo "::: Detected PowerPC architecture"
+ binary="pihole-FTL-powerpc-linux-gnu"
+ elif [[ ${machine} == x86_64 ]]; then
+ # 64bit
+ echo -e "${OVER} ${TICK} Detected x86_64 architecture"
+ binary="pihole-FTL-linux-x86_64"
+ else
+ # Something else - we try to use 32bit executable and warn the user
+ if [[ ! ${machine} == i686 ]]; then
+ echo -e "${OVER} ${CROSS} ${str}...
+ ${COL_LIGHT_RED}Not able to detect architecture (unknown: ${machine}), trying 32bit executable
+ Contact support if you experience issues (e.g: FTL not running)${COL_NC}"
+ else
+ echo -e "${OVER} ${TICK} Detected 32bit (i686) architecture"
+ fi
+ binary="pihole-FTL-linux-x86_32"
+ fi
+}
+
fully_fetch_repo() {
# Add upstream branches to shallow clone
local directory="${1}"
@@ -50,7 +137,6 @@ get_available_branches() {
return
}
-
fetch_checkout_pull_branch() {
# Check out specified branch
local directory="${1}"
@@ -74,7 +160,7 @@ checkout_pull_branch() {
cd "${directory}" || return 1
oldbranch="$(git symbolic-ref HEAD)"
-
+
git checkout "${branch}" || return 1
if [[ "$(git diff "${oldbranch}" | grep -c "^")" -gt "0" ]]; then
@@ -82,13 +168,13 @@ checkout_pull_branch() {
fi
git_pull=$(git pull || return 1)
-
+
if [[ "$git_pull" == *"up-to-date"* ]]; then
echo -e "\n ${INFO} $(git pull)"
else
echo -e "$git_pull\n"
fi
-
+
return 0
}
@@ -150,6 +236,12 @@ checkout() {
fetch_checkout_pull_branch "${webInterfaceDir}" "devel" || { echo " ${CROSS} Unable to pull Web development branch"; exit 1; }
fi
echo -e " ${TICK} Pi-hole core"
+
+ get_binary_name
+ local path
+ path="development/${binary}"
+ FTLinstall "${binary}" "${path}"
+
elif [[ "${1}" == "master" ]] ; then
# Shortcut to check out master branches
echo -e " ${INFO} Shortcut \"master\" detected - checking out master branches..."
@@ -160,7 +252,12 @@ checkout() {
fetch_checkout_pull_branch "${webInterfaceDir}" "master" || { echo " ${CROSS} Unable to pull Web master branch"; exit 1; }
fi
echo -e " ${TICK} Web interface"
-
+
+ get_binary_name
+ local path
+ path="master/${binary}"
+ FTLinstall "${binary}" "${path}"
+
elif [[ "${1}" == "core" ]] ; then
str="Fetching branches from ${piholeGitUrl}"
echo -ne " ${INFO} $str"
@@ -196,7 +293,7 @@ checkout() {
exit 1
fi
webbranches=($(get_available_branches "${webInterfaceDir}"))
-
+
if [[ "${corebranches[@]}" == *"master"* ]]; then
echo -e "${OVER} ${TICK} $str
${INFO} ${#webbranches[@]} branches available for Web Admin"
@@ -215,13 +312,27 @@ checkout() {
exit 1
fi
checkout_pull_branch "${webInterfaceDir}" "${2}"
+ elif [[ "${1}" == "ftl" ]] ; then
+
+ get_binary_name
+ local path
+ path="${2}/${binary}"
+
+ if check_download_exists "$path"; then
+ echo " ${TICK} Branch ${2} exists"
+ else
+ echo " ${CROSS} Branch ${2} doesn't exist"
+ fi
+
+ FTLinstall "${binary}" "${path}"
+
else
echo -e " ${INFO} Requested option \"${1}\" is not available"
exit 1
fi
# Force updating everything
- if [[ ! "${1}" == "web" && "${update}" == "true" ]]; then
+ if [[ ( ! "${1}" == "web" && ! "${1}" == "ftl" ) && "${update}" == "true" ]]; then
echo -e " ${INFO} Running installer to upgrade your installation"
if "${PI_HOLE_FILES_DIR}/automated install/basic-install.sh" --unattended; then
exit 0
From ab1a6d8829b2d9d86f1bc48dd2fd034dba28736d Mon Sep 17 00:00:00 2001
From: Adam Warner
Date: Thu, 29 Jun 2017 02:18:52 +0100
Subject: [PATCH 110/162] Fix install script using IPv6 CIDR notation (#1570)
---
automated install/basic-install.sh | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/automated install/basic-install.sh b/automated install/basic-install.sh
index 0878dc30..ee6a1d56 100755
--- a/automated install/basic-install.sh
+++ b/automated install/basic-install.sh
@@ -368,8 +368,8 @@ useIPv6dialog() {
# Determine type of found IPv6 addresses
for i in "${IPV6_ADDRESSES[@]}"; do
result=$(testIPv6 "$i")
- [[ "${result}" == "ULA" ]] && ULA_ADDRESS="$i"
- [[ "${result}" == "GUA" ]] && GUA_ADDRESS="$i"
+ [[ "${result}" == "ULA" ]] && ULA_ADDRESS="${i%/*}"
+ [[ "${result}" == "GUA" ]] && GUA_ADDRESS="${i%/*}"
done
# Determine which address to be used: Prefer ULA over GUA or don't use any if none found
@@ -1495,7 +1495,7 @@ main() {
welcomeDialogs
# Create directory for Pi-hole storage
mkdir -p /etc/pihole/
-
+
stop_service dnsmasq
if [[ ${INSTALL_WEB} == true ]]; then
stop_service lighttpd
@@ -1575,7 +1575,7 @@ main() {
if [[ "${useUpdateVars}" == false ]]; then
displayFinalMessage "${pw}"
fi
-
+
if [[ ${INSTALL_WEB} == true ]]; then
if (( ${#pw} > 0 )) ; then
echo -e " ${INFO} Web Interface password: ${COL_LIGHT_GREEN}${pw}${COL_NC}
@@ -1597,7 +1597,7 @@ main() {
else
INSTALL_TYPE="Update"
fi
-
+
echo -e "\n ${INFO} The install log is located at: /etc/pihole/install.log
${COL_LIGHT_GREEN}${INSTALL_TYPE} Complete! ${COL_NC}"
}
From 04cef25addfbb4a43299ffe775e4b4f5b9559a0a Mon Sep 17 00:00:00 2001
From: Jacob Salmela
Date: Thu, 29 Jun 2017 11:17:19 -0500
Subject: [PATCH 111/162] remove color character codes before uploading so the
log is more readable on our plaintext tricorder server
---
advanced/Scripts/piholeDebug.sh | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/advanced/Scripts/piholeDebug.sh b/advanced/Scripts/piholeDebug.sh
index cdeea52c..49c4cd5c 100755
--- a/advanced/Scripts/piholeDebug.sh
+++ b/advanced/Scripts/piholeDebug.sh
@@ -103,6 +103,7 @@ FTL_PORT="${RUN_DIRECTORY}/pihole-FTL.port"
PIHOLE_LOG="${LOG_DIRECTORY}/pihole.log"
PIHOLE_LOG_GZIPS=${LOG_DIRECTORY}/pihole.log.[0-9].*
PIHOLE_DEBUG_LOG="${LOG_DIRECTORY}/pihole_debug.log"
+PIHOLE_DEBUG_LOG_SANITIZED="${LOG_DIRECTORY}/pihole_debug-sanitized.log"
PIHOLE_FTL_LOG="${LOG_DIRECTORY}/pihole-FTL.log"
PIHOLE_WEB_SERVER_ACCESS_LOG_FILE="${WEB_SERVER_LOG_DIRECTORY}/access.log"
@@ -190,7 +191,8 @@ log_write() {
copy_to_debug_log() {
# Copy the contents of file descriptor 3 into the debug log so it can be uploaded to tricorder
- cat /proc/$$/fd/3 >> "${PIHOLE_DEBUG_LOG}"
+ cat /proc/$$/fd/3 > "${PIHOLE_DEBUG_LOG}"
+ sed 's/\[[0-9;]\{1,5\}m//g' > "${PIHOLE_DEBUG_LOG_SANITIZED}" <<< cat "${PIHOLE_DEBUG_LOG}"
}
initiate_debug() {
@@ -976,13 +978,13 @@ tricorder_use_nc_or_ssl() {
# If the command exists,
log_write " * Using ${COL_LIGHT_GREEN}openssl${COL_NC} for transmission."
# encrypt and transmit the log and store the token returned in a variable
- tricorder_token=$(cat ${PIHOLE_DEBUG_LOG} | openssl s_client -quiet -connect tricorder.pi-hole.net:${TRICORDER_SSL_PORT_NUMBER} 2> /dev/null)
+ tricorder_token=$(cat ${PIHOLE_DEBUG_LOG_SANITIZED} | openssl s_client -quiet -connect tricorder.pi-hole.net:${TRICORDER_SSL_PORT_NUMBER} 2> /dev/null)
# Otherwise,
else
# use net cat
log_write "${INFO} Using ${COL_YELLOW}netcat${COL_NC} for transmission."
# Save the token returned by our server in a variable
- tricorder_token=$(cat ${PIHOLE_DEBUG_LOG} | nc tricorder.pi-hole.net ${TRICORDER_NC_PORT_NUMBER})
+ tricorder_token=$(cat ${PIHOLE_DEBUG_LOG_SANITIZED} | nc tricorder.pi-hole.net ${TRICORDER_NC_PORT_NUMBER})
fi
}
@@ -1054,7 +1056,7 @@ upload_to_tricorder() {
log_write " * Please try again or contact the Pi-hole team for assistance."
fi
# Finally, show where the log file is no matter the outcome of the function so users can look at it
- log_write " * A local copy of the debug log can be found at: ${COL_CYAN}${PIHOLE_DEBUG_LOG}${COL_NC}\n"
+ log_write " * A local copy of the debug log can be found at: ${COL_CYAN}${PIHOLE_DEBUG_LOG_SANITIZED}${COL_NC}\n"
}
# Run through all the functions we made
From 1957b002bc12fed57526d0ff51ac7d0c7777cf49 Mon Sep 17 00:00:00 2001
From: Jacob Salmela
Date: Thu, 29 Jun 2017 11:37:58 -0500
Subject: [PATCH 112/162] add comments about X-Headers and further explain the
file descriptor cod.
---
advanced/Scripts/piholeDebug.sh | 15 ++++++++++++---
1 file changed, 12 insertions(+), 3 deletions(-)
diff --git a/advanced/Scripts/piholeDebug.sh b/advanced/Scripts/piholeDebug.sh
index 49c4cd5c..d42e3517 100755
--- a/advanced/Scripts/piholeDebug.sh
+++ b/advanced/Scripts/piholeDebug.sh
@@ -180,7 +180,8 @@ make_temporary_log() {
# https://stackoverflow.com/questions/18460186/writing-outputs-to-log-file-and-console
exec 3>"$TEMPLOG"
# Delete templog, but allow for addressing via file handle
- # This lets us write to the log without having a temporary file on the drive
+ # This lets us write to the log without having a temporary file on the drive, which
+ # is meant to be a security measure so there is not a lingering file on the drive during the debug process
rm "$TEMPLOG"
}
@@ -190,8 +191,12 @@ log_write() {
}
copy_to_debug_log() {
- # Copy the contents of file descriptor 3 into the debug log so it can be uploaded to tricorder
+ # Copy the contents of file descriptor 3 into the debug log
cat /proc/$$/fd/3 > "${PIHOLE_DEBUG_LOG}"
+ # Since we use color codes such as '\e[1;33m', they should be removed before being
+ # uploaded to our server, since it can't properly display in color
+ # This is accomplished by use sed to remove characters matching that patter
+ # The entire file is then copied over to a sanitized version of the log
sed 's/\[[0-9;]\{1,5\}m//g' > "${PIHOLE_DEBUG_LOG_SANITIZED}" <<< cat "${PIHOLE_DEBUG_LOG}"
}
@@ -637,6 +642,10 @@ check_networking() {
check_x_headers() {
# The X-Headers allow us to determine from the command line if the Web
+ # lighttpd.conf has a directive to show "X-Pi-hole: A black hole for Internet advertisements."
+ # in the header of any Pi-holed domain
+ # Similarly, it will show "X-Pi-hole: The Pi-hole Web interface is working!" if you view the header returned
+ # when accessing the dashboard (i.e curl -I pi.hole/admin/)
# 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
@@ -1061,9 +1070,9 @@ upload_to_tricorder() {
# Run through all the functions we made
make_temporary_log
+initiate_debug
# setupVars.conf needs to be sourced before the networking so the values are
# available to the other functions
-initiate_debug
source_setup_variables
check_component_versions
check_critical_program_versions
From 05a724afaeb0bfd59829d5b5603c2acba4ea6fc4 Mon Sep 17 00:00:00 2001
From: Jacob Salmela
Date: Thu, 29 Jun 2017 11:49:28 -0500
Subject: [PATCH 113/162] codacy appeasement: remove useless cats
---
advanced/Scripts/piholeDebug.sh | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/advanced/Scripts/piholeDebug.sh b/advanced/Scripts/piholeDebug.sh
index d42e3517..f98d986a 100755
--- a/advanced/Scripts/piholeDebug.sh
+++ b/advanced/Scripts/piholeDebug.sh
@@ -987,13 +987,13 @@ tricorder_use_nc_or_ssl() {
# If the command exists,
log_write " * Using ${COL_LIGHT_GREEN}openssl${COL_NC} for transmission."
# encrypt and transmit the log and store the token returned in a variable
- tricorder_token=$(cat ${PIHOLE_DEBUG_LOG_SANITIZED} | openssl s_client -quiet -connect tricorder.pi-hole.net:${TRICORDER_SSL_PORT_NUMBER} 2> /dev/null)
+ tricorder_token=$(< ${PIHOLE_DEBUG_LOG_SANITIZED} openssl s_client -quiet -connect tricorder.pi-hole.net:${TRICORDER_SSL_PORT_NUMBER} 2> /dev/null)
# Otherwise,
else
# use net cat
log_write "${INFO} Using ${COL_YELLOW}netcat${COL_NC} for transmission."
# Save the token returned by our server in a variable
- tricorder_token=$(cat ${PIHOLE_DEBUG_LOG_SANITIZED} | nc tricorder.pi-hole.net ${TRICORDER_NC_PORT_NUMBER})
+ tricorder_token=$(< ${PIHOLE_DEBUG_LOG_SANITIZED} nc tricorder.pi-hole.net ${TRICORDER_NC_PORT_NUMBER})
fi
}
From ec4e9780ed0eb1dca0436d365b2b09b345117ab4 Mon Sep 17 00:00:00 2001
From: DL6ER
Date: Fri, 30 Jun 2017 14:52:33 +0200
Subject: [PATCH 114/162] Accept underscores when validating domain names
(#1571)
---
advanced/Scripts/list.sh | 13 ++++++++-----
1 file changed, 8 insertions(+), 5 deletions(-)
diff --git a/advanced/Scripts/list.sh b/advanced/Scripts/list.sh
index e7151cf6..86589083 100755
--- a/advanced/Scripts/list.sh
+++ b/advanced/Scripts/list.sh
@@ -62,11 +62,14 @@ EscapeRegexp() {
}
HandleOther() {
- # First, convert everything to lowercase
- domain=$(sed -e "y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/" <<< "$1")
+ # Convert to lowercase
+ domain="${1,,}"
# Check validity of domain
- validDomain=$(echo "${domain}" | perl -lne 'print if /(?!.*[^a-z0-9-\.].*)^((?=[a-z0-9-]{1,63}\.)(xn--)?[a-z0-9-]+\.)*[a-z]{2,63}/')
+ validDomain=$(perl -lne 'print if /^((-|_)*[a-z\d]((-|_)*[a-z\d])*(-|_)*)(\.(-|_)*([a-z\d]((-|_)*[a-z\d])*))*$/' <<< "${domain}") # Valid chars check
+ validDomain=$(perl -lne 'print if /^.{1,253}$/' <<< "${validDomain}") # Overall length check
+ validDomain=$(perl -lne 'print if /^[^\.]{1,63}(\.[^\.]{1,63})*$/' <<< "${validDomain}") # Length of each label
+
if [[ -z "${validDomain}" ]]; then
echo -e " ${CROSS} $1 is not a valid argument or domain name!"
else
@@ -98,7 +101,7 @@ PoplistFile() {
AddDomain() {
list="$2"
domain=$(EscapeRegexp "$1")
-
+
[[ "${list}" == "${whitelist}" ]] && listname="whitelist"
[[ "${list}" == "${blacklist}" ]] && listname="blacklist"
[[ "${list}" == "${wildcardlist}" ]] && listname="wildcard blacklist"
@@ -151,7 +154,7 @@ AddDomain() {
RemoveDomain() {
list="$2"
domain=$(EscapeRegexp "$1")
-
+
[[ "${list}" == "${whitelist}" ]] && listname="whitelist"
[[ "${list}" == "${blacklist}" ]] && listname="blacklist"
[[ "${list}" == "${wildcardlist}" ]] && listname="wildcard blacklist"
From b3eb5c4f0e09506e30ce09b21c19c8c29bd21f4b Mon Sep 17 00:00:00 2001
From: Adam Warner
Date: Sat, 1 Jul 2017 13:08:17 +0100
Subject: [PATCH 115/162] Colour Tweaks (#1549)
---
advanced/Scripts/piholeCheckout.sh | 26 ++++++++++++++------------
advanced/Scripts/update.sh | 6 +-----
automated install/basic-install.sh | 2 +-
3 files changed, 16 insertions(+), 18 deletions(-)
diff --git a/advanced/Scripts/piholeCheckout.sh b/advanced/Scripts/piholeCheckout.sh
index 102db2ba..093c958e 100644
--- a/advanced/Scripts/piholeCheckout.sh
+++ b/advanced/Scripts/piholeCheckout.sh
@@ -3,7 +3,7 @@
# (c) 2017 Pi-hole, LLC (https://pi-hole.net)
# Network-wide ad blocking via your own hardware.
#
-# Switch Pi-hole subsystems to a different Github branch
+# Switch Pi-hole subsystems to a different Github branch.
#
# This file is copyright under the latest version of the EUPL.
# Please see LICENSE file for your rights under this license.
@@ -60,7 +60,7 @@ fetch_checkout_pull_branch() {
cd "${directory}"
git remote set-branches origin "${branch}" || return 1
git stash --all --quiet &> /dev/null || true
- git clean --force -d || true
+ git clean --quiet --force -d || true
git fetch --quiet || return 1
checkout_pull_branch "${directory}" "${branch}" || return 1
}
@@ -74,21 +74,21 @@ checkout_pull_branch() {
cd "${directory}" || return 1
oldbranch="$(git symbolic-ref HEAD)"
-
- git checkout "${branch}" || return 1
+
+ git checkout "${branch}" --quiet || return 1
if [[ "$(git diff "${oldbranch}" | grep -c "^")" -gt "0" ]]; then
update="true"
fi
git_pull=$(git pull || return 1)
-
+
if [[ "$git_pull" == *"up-to-date"* ]]; then
- echo -e "\n ${INFO} $(git pull)"
+ echo -e " ${INFO} $(git pull)"
else
echo -e "$git_pull\n"
fi
-
+
return 0
}
@@ -143,13 +143,15 @@ checkout() {
if [[ "${1}" == "dev" ]] ; then
# Shortcut to check out development branches
echo -e " ${INFO} Shortcut \"dev\" detected - checking out development / devel branches..."
- echo -e " ${INFO} Pi-hole core"
+ echo ""
+ echo -e " ${INFO} Pi-hole Core"
fetch_checkout_pull_branch "${PI_HOLE_FILES_DIR}" "development" || { echo " ${CROSS} Unable to pull Core developement branch"; exit 1; }
if [[ ${INSTALL_WEB} == "true" ]]; then
+ echo ""
echo -e " ${INFO} Web interface"
fetch_checkout_pull_branch "${webInterfaceDir}" "devel" || { echo " ${CROSS} Unable to pull Web development branch"; exit 1; }
fi
- echo -e " ${TICK} Pi-hole core"
+ #echo -e " ${TICK} Pi-hole Core"
elif [[ "${1}" == "master" ]] ; then
# Shortcut to check out master branches
echo -e " ${INFO} Shortcut \"master\" detected - checking out master branches..."
@@ -159,8 +161,8 @@ checkout() {
echo -e " ${INFO} Web interface"
fetch_checkout_pull_branch "${webInterfaceDir}" "master" || { echo " ${CROSS} Unable to pull Web master branch"; exit 1; }
fi
- echo -e " ${TICK} Web interface"
-
+ #echo -e " ${TICK} Web Interface"
+
elif [[ "${1}" == "core" ]] ; then
str="Fetching branches from ${piholeGitUrl}"
echo -ne " ${INFO} $str"
@@ -196,7 +198,7 @@ checkout() {
exit 1
fi
webbranches=($(get_available_branches "${webInterfaceDir}"))
-
+
if [[ "${corebranches[@]}" == *"master"* ]]; then
echo -e "${OVER} ${TICK} $str
${INFO} ${#webbranches[@]} branches available for Web Admin"
diff --git a/advanced/Scripts/update.sh b/advanced/Scripts/update.sh
index 779f6c8d..d4919d08 100755
--- a/advanced/Scripts/update.sh
+++ b/advanced/Scripts/update.sh
@@ -10,10 +10,7 @@
# This file is copyright under the latest version of the EUPL.
# Please see LICENSE file for your rights under this license.
-
-
# Variables
-
readonly ADMIN_INTERFACE_GIT_URL="https://github.com/pi-hole/AdminLTE.git"
readonly ADMIN_INTERFACE_DIR="/var/www/html/admin"
readonly PI_HOLE_GIT_URL="https://github.com/pi-hole/pi-hole.git"
@@ -82,7 +79,6 @@ GitCheckUpdateAvail() {
}
FTLcheckUpdate() {
-
local FTLversion
FTLversion=$(/usr/bin/pihole-FTL tag)
local FTLlatesttag
@@ -131,7 +127,7 @@ main() {
# re-install (i.e. update) FTL
if ${FTL_update} && ! ${core_update}; then
echo ""
- echo -e " ${INFO} FTL out of date"
+ echo -e " ${INFO} FTL out of date"
FTLdetect
echo ""
fi
diff --git a/automated install/basic-install.sh b/automated install/basic-install.sh
index ee6a1d56..3c6b77af 100755
--- a/automated install/basic-install.sh
+++ b/automated install/basic-install.sh
@@ -212,7 +212,7 @@ update_repo() {
# Pull the latest commits
echo -ne " ${INFO} ${str}..."
git stash --all --quiet &> /dev/null || true # Okay for stash failure
- git clean --force -d || true # Okay for already clean directory
+ git clean --quiet --force -d || true # Okay for already clean directory
git pull --quiet &> /dev/null || return $?
echo -e "${OVER} ${TICK} ${str}"
cd "${curdir}" &> /dev/null || return 1
From 6ce79ae1d0372a05fc129f39aa8b871ac8f8b314 Mon Sep 17 00:00:00 2001
From: DL6ER
Date: Sat, 1 Jul 2017 23:52:10 +0200
Subject: [PATCH 116/162] Fix git commands (#1577)
---
advanced/Scripts/update.sh | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/advanced/Scripts/update.sh b/advanced/Scripts/update.sh
index d4919d08..71b7cecd 100755
--- a/advanced/Scripts/update.sh
+++ b/advanced/Scripts/update.sh
@@ -40,7 +40,7 @@ GitCheckUpdateAvail() {
# @ alone is a shortcut for HEAD. Older versions of git
# need @{0}
- LOCAL="$("git rev-parse @{0}")"
+ LOCAL="$(git rev-parse "@{0}")"
# The suffix @{upstream} to a branchname
# (short form @{u}) refers
@@ -49,7 +49,7 @@ GitCheckUpdateAvail() {
# (configured with branch..remote and
# branch..merge). A missing branchname
# defaults to the current one.
- REMOTE="$("git rev-parse @{upstream}")"
+ REMOTE="$(git rev-parse "@{upstream}")"
if [[ ${#LOCAL} == 0 ]]; then
echo -e " ${COL_LIGHT_RED}Error: Local revision could not be obtained, ask Pi-hole support."
From 209fbf82c403c495867bae77b5ef585c1a76b986 Mon Sep 17 00:00:00 2001
From: WaLLy3K
Date: Sun, 2 Jul 2017 23:21:00 +1000
Subject: [PATCH 117/162] Colourise tailFunc (#1550)
* Colourise tailFunc
* Strip month, day number and dnsmasq[PID]
* Blocked domains show as light red
* Queries show as standard colour
* Everything else as dark gray
* Change tailFunc highlighted lines
* Highlight Blocked/Blacklist/Wildcard lines as red
* Make DHCP lines default colour
* Make sure tailFunc doesn't match on domain names
---
pihole | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/pihole b/pihole
index 93b35393..3c321b93 100755
--- a/pihole
+++ b/pihole
@@ -340,8 +340,13 @@ piholeStatus() {
}
tailFunc() {
+ date=$(date +'%b %d ')
echo -e " ${INFO} Press Ctrl-C to exit"
- tail -F /var/log/pihole.log
+ tail -f /var/log/pihole.log | sed \
+ -e "s,\(${date}\| dnsmasq\[.*[0-9]]\),,g" \
+ -e "s,\(.*\(gravity.list\|black.list\| config \).* is \(${IPV4_ADDRESS%/*}\|${IPV6_ADDRESS:-NULL}\).*\),${COL_LIGHT_RED}&${COL_NC}," \
+ -e "s,.*\(query\[A\|DHCP\).*,${COL_NC}&${COL_NC}," \
+ -e "s,.*,${COL_DARK_GRAY}&${COL_NC},"
exit 0
}
From 1bebcef2658527a3159911fe824c0d92e759233d Mon Sep 17 00:00:00 2001
From: WaLLy3K
Date: Tue, 4 Jul 2017 13:52:51 +1000
Subject: [PATCH 118/162] Make Chronometer usable on smaller screens (#1518)
---
advanced/Scripts/chronometer.sh | 493 ++++++++++++++++++++------------
1 file changed, 313 insertions(+), 180 deletions(-)
diff --git a/advanced/Scripts/chronometer.sh b/advanced/Scripts/chronometer.sh
index d9b7d05b..d9b01fc0 100755
--- a/advanced/Scripts/chronometer.sh
+++ b/advanced/Scripts/chronometer.sh
@@ -7,6 +7,7 @@
#
# This file is copyright under the latest version of the EUPL.
# Please see LICENSE file for your rights under this license.
+LC_NUMERIC=C
# Retrieve stats from FTL engine
pihole-FTL() {
@@ -32,43 +33,74 @@ pihole-FTL() {
exec 3<&-
fi
else
- echo -e "${COL_LIGHT_RED}FTL offline${COL_NC}"
+ echo "0"
fi
}
-# Print spaces to align right-side content
+# Print spaces to align right-side additional text
printFunc() {
- txt_len="${#2}"
-
- # Reduce string length when using colour code
- [ "${2:0:1}" == "" ] && txt_len=$((txt_len-7))
-
- if [[ "$3" == "last" ]]; then
- # Prevent final line from printing trailing newline
- scr_size=( $(stty size 2>/dev/null || echo 24 80) )
- scr_width="${scr_size[1]}"
-
- title_len="${#1}"
- spc_num=$(( (scr_width - title_len) - txt_len ))
- [[ "$spc_num" -lt 0 ]] && spc_num="0"
- spc=$(printf "%${spc_num}s")
-
- printf "%s%s$spc" "$1" "$2"
- else
- # Determine number of spaces for padding
- spc_num=$(( 20 - txt_len ))
- [[ "$spc_num" -lt 0 ]] && spc_num="0"
- spc=$(printf "%${spc_num}s")
+ local text_last
- # Print string (Max 20 characters, prevents overflow)
- printf "%s%s$spc" "$1" "${2:0:20}"
+ title="$1"
+ title_len="${#title}"
+
+ text_main="$2"
+ text_main_nocol="$text_main"
+ if [[ "${text_main:0:1}" == "" ]]; then
+ text_main_nocol=$(sed 's/\[[0-9;]\{1,5\}m//g' <<< "$text_main")
+ fi
+ text_main_len="${#text_main_nocol}"
+
+ text_addn="$3"
+ if [[ "$text_addn" == "last" ]]; then
+ text_addn=""
+ text_last="true"
+ fi
+
+ # If there is additional text, define max length of text_main
+ if [[ -n "$text_addn" ]]; then
+ case "$scr_cols" in
+ [0-9]|1[0-9]|2[0-9]|3[0-9]|4[0-4]) text_main_max_len="9";;
+ 4[5-9]) text_main_max_len="14";;
+ *) text_main_max_len="19";;
+ esac
+ fi
+
+ [[ -z "$text_addn" ]] && text_main_max_len="$(( scr_cols - title_len ))"
+
+ # Remove excess characters from main text
+ if [[ "$text_main_len" -gt "$text_main_max_len" ]]; then
+ # Trim text without colours
+ text_main_trim="${text_main_nocol:0:$text_main_max_len}"
+ # Replace with trimmed text
+ text_main="${text_main/$text_main_nocol/$text_main_trim}"
+ fi
+
+ # Determine amount of spaces for each line
+ if [[ -n "$text_last" ]]; then
+ # Move cursor to end of screen
+ spc_num=$(( scr_cols - ( title_len + text_main_len ) ))
+ else
+ spc_num=$(( text_main_max_len - text_main_len ))
+ fi
+
+ [[ "$spc_num" -le 0 ]] && spc_num="0"
+ spc=$(printf "%${spc_num}s")
+ #spc="${spc// /.}" # Debug: Visualise spaces
+
+ printf "%s%s$spc" "$title" "$text_main"
+
+ if [[ -n "$text_addn" ]]; then
+ printf "%s(%s)%s\n" "$COL_NC$COL_DARK_GRAY" "$text_addn" "$COL_NC"
+ else
+ # Do not print trailing newline on final line
+ [[ -z "$text_last" ]] && printf "%s\n" "$COL_NC"
fi
}
# Perform on first Chrono run (not for JSON formatted string)
get_init_stats() {
- LC_NUMERIC=C
- calcFunc(){ awk "BEGIN {print $*}"; }
+ calcFunc(){ awk "BEGIN {print $*}" 2> /dev/null; }
# Convert bytes to human-readable format
hrBytes() {
@@ -90,33 +122,53 @@ get_init_stats() {
# Convert seconds to human-readable format
hrSecs() {
- day=$(( $1/60/60/24 )); hrs=$(( $1/3600%24 )); mins=$(( ($1%3600)/60 )); secs=$(( $1%60 ))
+ day=$(( $1/60/60/24 )); hrs=$(( $1/3600%24 ))
+ mins=$(( ($1%3600)/60 )); secs=$(( $1%60 ))
[[ "$day" -ge "2" ]] && plu="s"
[[ "$day" -ge "1" ]] && days="$day day${plu}, " || days=""
printf "%s%02d:%02d:%02d\n" "$days" "$hrs" "$mins" "$secs"
- }
+ }
# Set Colour Codes
coltable="/opt/pihole/COL_TABLE"
if [[ -f "${coltable}" ]]; then
source ${coltable}
else
- COL_NC='[0m'
- COL_DARK_GRAY='[1;30m'
- COL_LIGHT_GREEN='[1;32m'
- COL_LIGHT_BLUE='[1;34m'
- COL_LIGHT_RED='[1;31m'
- COL_YELLOW='[1;33m'
- COL_LIGHT_RED='[1;31m'
- COL_URG_RED='[39;41m'
+ COL_NC="[0m"
+ COL_DARK_GRAY="[1;30m"
+ COL_LIGHT_GREEN="[1;32m"
+ COL_LIGHT_BLUE="[1;34m"
+ COL_LIGHT_RED="[1;31m"
+ COL_YELLOW="[1;33m"
+ COL_LIGHT_RED="[1;31m"
+ COL_URG_RED="[39;41m"
fi
- # Get RPi model number, or OS distro info
+ # Get RPi throttle state (RPi 3B only) & model number, or OS distro info
if command -v vcgencmd &> /dev/null; then
- sys_rev=$(awk '/Revision/ {print $3}' < /proc/cpuinfo)
- case "$sys_rev" in
+ local sys_throttle_raw
+ local sys_rev_raw
+
+ sys_throttle_raw=$(vgt=$(sudo vcgencmd get_throttled); echo "${vgt##*x}")
+
+ # Active Throttle Notice: http://bit.ly/2gnunOo
+ if [[ "$sys_throttle_raw" != "0" ]]; then
+ case "$sys_throttle_raw" in
+ *0001) thr_type="${COL_YELLOW}Under Voltage";;
+ *0002) thr_type="${COL_LIGHT_BLUE}Arm Freq Cap";;
+ *0003) thr_type="${COL_YELLOW}UV${COL_DARK_GRAY},${COL_NC} ${COL_LIGHT_BLUE}AFC";;
+ *0004) thr_type="${COL_LIGHT_RED}Throttled";;
+ *0005) thr_type="${COL_YELLOW}UV${COL_DARK_GRAY},${COL_NC} ${COL_LIGHT_RED}TT";;
+ *0006) thr_type="${COL_LIGHT_BLUE}AFC${COL_DARK_GRAY},${COL_NC} ${COL_LIGHT_RED}TT";;
+ *0007) thr_type="${COL_YELLOW}UV${COL_DARK_GRAY},${COL_NC} ${COL_LIGHT_BLUE}AFC${COL_DARK_GRAY},${COL_NC} ${COL_LIGHT_RED}TT";;
+ esac
+ [[ -n "$thr_type" ]] && sys_throttle="$thr_type${COL_DARK_GRAY}"
+ fi
+
+ sys_rev_raw=$(awk '/Revision/ {print $3}' < /proc/cpuinfo)
+ case "$sys_rev_raw" in
000[2-6]) sys_model=" 1, Model B";; # 256MB
- 000[7-9]) sys_model=" 1, Model A" ;; # 256MB
+ 000[7-9]) sys_model=" 1, Model A";; # 256MB
000d|000e|000f) sys_model=" 1, Model B";; # 512MB
0010|0013) sys_model=" 1, Model B+";; # 512MB
0012|0015) sys_model=" 1, Model A+";; # 256MB
@@ -126,7 +178,7 @@ get_init_stats() {
90009[2-3]|920093) sys_model=" Zero";; # 512MB
9000c1) sys_model=" Zero W";; # 512MB
a02082|a[2-3]2082) sys_model=" 3, Model B";; # 1GB
- *) sys_model="" ;;
+ *) sys_model="";;
esac
sys_type="Raspberry Pi$sys_model"
else
@@ -137,7 +189,6 @@ get_init_stats() {
# Get core count
sys_cores=$(grep -c "^processor" /proc/cpuinfo)
- [[ "$sys_cores" -ne 1 ]] && sys_cores_plu="cores" || sys_cores_plu="core"
# Test existence of clock speed file for ARM CPU
if [[ -f "/sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq" ]]; then
@@ -168,80 +219,95 @@ get_sys_stats() {
# Update every 12 refreshes (Def: every 60s)
count=$((count+1))
if [[ "$count" == "1" ]] || (( "$count" % 12 == 0 )); then
+ # Do not source setupVars if file does not exist
[[ -n "$setupVars" ]] && source "$setupVars"
-
-
- ph_ver_raw=($(pihole -v -c 2> /dev/null | sed -n 's/^.* v/v/p'))
+
+ mapfile -t ph_ver_raw < <(pihole -v -c 2> /dev/null | sed -n 's/^.* v/v/p')
if [[ -n "${ph_ver_raw[0]}" ]]; then
ph_core_ver="${ph_ver_raw[0]}"
ph_lte_ver="${ph_ver_raw[1]}"
ph_ftl_ver="${ph_ver_raw[2]}"
else
- ph_core_ver="${COL_LIGHT_RED}API unavailable${COL_NC}"
+ ph_core_ver="-1"
fi
-
+
sys_name=$(hostname)
-
+
[[ -n "$TEMPERATUREUNIT" ]] && temp_unit="$TEMPERATUREUNIT" || temp_unit="c"
-
+
# Get storage stats for partition mounted on /
- disk_raw=($(df -B1 / 2> /dev/null | awk 'END{ print $3,$2,$5 }'))
+ read -r -a disk_raw <<< "$(df -B1 / 2> /dev/null | awk 'END{ print $3,$2,$5 }')"
disk_used="${disk_raw[0]}"
disk_total="${disk_raw[1]}"
disk_perc="${disk_raw[2]}"
-
+
net_gateway=$(route -n | awk '$4 == "UG" {print $2;exit}')
-
+
# Get DHCP stats, if feature is enabled
if [[ "$DHCP_ACTIVE" == "true" ]]; then
- ph_dhcp_eip="${DHCP_END##*.}"
ph_dhcp_max=$(( ${DHCP_END##*.} - ${DHCP_START##*.} + 1 ))
fi
-
- # Get alt DNS server, or print total count of alt DNS servers
- if [[ -z "${PIHOLE_DNS_3}" ]]; then
- ph_alts="${PIHOLE_DNS_2}"
- else
- dns_count="0"
- [[ -n "${PIHOLE_DNS_2}" ]] && dns_count=$((dns_count+1))
- [[ -n "${PIHOLE_DNS_3}" ]] && dns_count=$((dns_count+1))
- [[ -n "${PIHOLE_DNS_4}" ]] && dns_count=$((dns_count+1))
- [[ -n "${PIHOLE_DNS_5}" ]] && dns_count=$((dns_count+1))
- [[ -n "${PIHOLE_DNS_6}" ]] && dns_count=$((dns_count+1))
- [[ -n "${PIHOLE_DNS_7}" ]] && dns_count=$((dns_count+1))
- [[ -n "${PIHOLE_DNS_8}" ]] && dns_count=$((dns_count+1))
- [[ -n "${PIHOLE_DNS_9}" ]] && dns_count="$dns_count+"
- ph_alts="${dns_count} others"
- fi
+
+ # Get DNS server count
+ dns_count="0"
+ [[ -n "${PIHOLE_DNS_1}" ]] && dns_count=$((dns_count+1))
+ [[ -n "${PIHOLE_DNS_2}" ]] && dns_count=$((dns_count+1))
+ [[ -n "${PIHOLE_DNS_3}" ]] && dns_count=$((dns_count+1))
+ [[ -n "${PIHOLE_DNS_4}" ]] && dns_count=$((dns_count+1))
+ [[ -n "${PIHOLE_DNS_5}" ]] && dns_count=$((dns_count+1))
+ [[ -n "${PIHOLE_DNS_6}" ]] && dns_count=$((dns_count+1))
+ [[ -n "${PIHOLE_DNS_7}" ]] && dns_count=$((dns_count+1))
+ [[ -n "${PIHOLE_DNS_8}" ]] && dns_count=$((dns_count+1))
+ [[ -n "${PIHOLE_DNS_9}" ]] && dns_count="$dns_count+"
fi
-
+
+ # Get screen size
+ read -r -a scr_size <<< "$(stty size 2>/dev/null || echo 24 80)"
+ scr_lines="${scr_size[0]}"
+ scr_cols="${scr_size[1]}"
+
+ # Determine Chronometer size behaviour
+ if [[ "$scr_cols" -ge 58 ]]; then
+ chrono_width="large"
+ elif [[ "$scr_cols" -gt 40 ]]; then
+ chrono_width="medium"
+ else
+ chrono_width="small"
+ fi
+
+ # Determine max length of divider string
+ scr_line_len=$(( scr_cols - 2 ))
+ [[ "$scr_line_len" -ge 58 ]] && scr_line_len="58"
+ scr_line_str=$(printf "%${scr_line_len}s")
+ scr_line_str="${scr_line_str// /—}"
+
sys_uptime=$(hrSecs "$(cut -d. -f1 /proc/uptime)")
sys_loadavg=$(cut -d " " -f1,2,3 /proc/loadavg)
-
- # Get CPU usage, only counting processes over 1% CPU as active
+
+ # Get CPU usage, only counting processes over 1% as active
cpu_raw=$(ps -eo pcpu,rss --no-headers | grep -E -v " 0")
cpu_tasks=$(wc -l <<< "$cpu_raw")
cpu_taskact=$(sed -r "/(^ 0.)/d" <<< "$cpu_raw" | wc -l)
cpu_perc=$(awk '{sum+=$1} END {printf "%.0f\n", sum/'"$sys_cores"'}' <<< "$cpu_raw")
-
+
# Get CPU clock speed
if [[ -n "$scaling_freq_file" ]]; then
cpu_mhz=$(( $(< /sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq) / 1000 ))
else
- cpu_mhz=$(lscpu | awk -F "[ .]+" '/MHz/ {print $4;exit}')
+ cpu_mhz=$(lscpu | awk -F ":" '/MHz/ {print $2;exit}')
+ cpu_mhz=$(printf "%.0f" "${cpu_mhz//[[:space:]]/}")
fi
-
- # Determine correct string format for CPU clock speed
+
+ # Determine whether to display CPU clock speed as MHz or GHz
if [[ -n "$cpu_mhz" ]]; then
- [[ "$cpu_mhz" -le "999" ]] && cpu_freq="$cpu_mhz MHz" || cpu_freq="$(calcFunc "$cpu_mhz"/1000) Ghz"
- [[ -n "$cpu_freq" ]] && cpu_freq_str=" @ $cpu_freq" || cpu_freq_str=""
+ [[ "$cpu_mhz" -le "999" ]] && cpu_freq="$cpu_mhz MHz" || cpu_freq="$(calcFunc "$cpu_mhz"/1000) GHz"
fi
-
+
# Determine colour for temperature
if [[ -n "$temp_file" ]]; then
if [[ "$temp_unit" == "C" ]]; then
- cpu_temp=$(printf "%'.0fc\n" "$(calcFunc "$(< $temp_file) / 1000")")
-
+ cpu_temp=$(printf "%.0fc\n" "$(calcFunc "$(< $temp_file) / 1000")")
+
case "${cpu_temp::-1}" in
-*|[0-9]|[1-3][0-9]) cpu_col="$COL_LIGHT_BLUE";;
4[0-9]) cpu_col="";;
@@ -249,13 +315,13 @@ get_sys_stats() {
6[0-9]) cpu_col="$COL_LIGHT_RED";;
*) cpu_col="$COL_URG_RED";;
esac
-
+
# $COL_NC$COL_DARK_GRAY is needed for $COL_URG_RED
- cpu_temp_str=", $cpu_col$cpu_temp$COL_NC$COL_DARK_GRAY"
-
+ cpu_temp_str=" @ $cpu_col$cpu_temp$COL_NC$COL_DARK_GRAY"
+
elif [[ "$temp_unit" == "F" ]]; then
- cpu_temp=$(printf "%'.0ff\n" "$(calcFunc "($(< $temp_file) / 1000) * 9 / 5 + 32")")
-
+ cpu_temp=$(printf "%.0ff\n" "$(calcFunc "($(< $temp_file) / 1000) * 9 / 5 + 32")")
+
case "${cpu_temp::-1}" in
-*|[0-9]|[0-9][0-9]) cpu_col="$COL_LIGHT_BLUE";;
1[0-1][0-9]) cpu_col="";;
@@ -263,132 +329,199 @@ get_sys_stats() {
1[4-5][0-9]) cpu_col="$COL_LIGHT_RED";;
*) cpu_col="$COL_URG_RED";;
esac
-
- cpu_temp_str=", $cpu_col$cpu_temp$COL_NC$COL_DARK_GRAY"
-
+
+ cpu_temp_str=" @ $cpu_col$cpu_temp$COL_NC$COL_DARK_GRAY"
+
else
- cpu_temp_str=$(printf ", %'.0fk\n" "$(calcFunc "($(< $temp_file) / 1000) + 273.15")")
+ cpu_temp_str=$(printf " @ %.0fk\n" "$(calcFunc "($(< $temp_file) / 1000) + 273.15")")
fi
else
cpu_temp_str=""
fi
-
- ram_raw=($(awk '/MemTotal:/{total=$2} /MemFree:/{free=$2} /Buffers:/{buffers=$2} /^Cached:/{cached=$2} END {printf "%.0f %.0f %.0f", (total-free-buffers-cached)*100/total, (total-free-buffers-cached)*1024, total*1024}' /proc/meminfo))
+
+ read -r -a ram_raw <<< "$(awk '/MemTotal:/{total=$2} /MemFree:/{free=$2} /Buffers:/{buffers=$2} /^Cached:/{cached=$2} END {printf "%.0f %.0f %.0f", (total-free-buffers-cached)*100/total, (total-free-buffers-cached)*1024, total*1024}' /proc/meminfo)"
ram_perc="${ram_raw[0]}"
ram_used="${ram_raw[1]}"
ram_total="${ram_raw[2]}"
-
+
if [[ "$(pihole status web 2> /dev/null)" == "1" ]]; then
ph_status="${COL_LIGHT_GREEN}Active"
else
- ph_status="${COL_LIGHT_RED}Inactive"
+ ph_status="${COL_LIGHT_RED}Offline"
fi
-
+
if [[ "$DHCP_ACTIVE" == "true" ]]; then
- ph_dhcp_num=$(wc -l 2> /dev/null < "/etc/pihole/dhcp.leases")
+ local ph_dhcp_range
+
+ ph_dhcp_range=$(seq -s "|" -f "${DHCP_START%.*}.%g" "${DHCP_START##*.}" "${DHCP_END##*.}")
+
+ # Count dynamic leases from available range, and not static leases
+ ph_dhcp_num=$(grep -cE "$ph_dhcp_range" "/etc/pihole/dhcp.leases")
+ ph_dhcp_percent=$(( ph_dhcp_num * 100 / ph_dhcp_max ))
fi
}
get_ftl_stats() {
local stats_raw
-
- stats_raw=($(pihole-FTL "stats"))
- domains_being_blocked_raw="${stats_raw[1]}"
- dns_queries_today_raw="${stats_raw[3]}"
- ads_blocked_today_raw="${stats_raw[5]}"
- ads_percentage_today_raw="${stats_raw[7]}"
+
+ mapfile -t stats_raw < <(pihole-FTL "stats")
+ domains_being_blocked_raw="${stats_raw[1]#* }"
+ dns_queries_today_raw="${stats_raw[3]#* }"
+ ads_blocked_today_raw="${stats_raw[5]#* }"
+ ads_percentage_today_raw="${stats_raw[7]#* }"
+ queries_forwarded_raw="${stats_raw[11]#* }"
+ queries_cached_raw="${stats_raw[13]#* }"
# Only retrieve these stats when not called from jsonFunc
if [[ -z "$1" ]]; then
- local recent_blocked_raw
local top_ad_raw
local top_domain_raw
local top_client_raw
-
- domains_being_blocked=$(printf "%'.0f\n" "${domains_being_blocked_raw}")
- dns_queries_today=$(printf "%'.0f\n" "${dns_queries_today_raw}")
- ads_blocked_today=$(printf "%'.0f\n" "${ads_blocked_today_raw}")
+
+ domains_being_blocked=$(printf "%.0f\n" "${domains_being_blocked_raw}")
+ dns_queries_today=$(printf "%.0f\n" "${dns_queries_today_raw}")
+ ads_blocked_today=$(printf "%.0f\n" "${ads_blocked_today_raw}")
ads_percentage_today=$(printf "%'.0f\n" "${ads_percentage_today_raw}")
-
- recent_blocked_raw=$(pihole-FTL recentBlocked)
- top_ad_raw=($(pihole-FTL "top-ads (1)"))
- top_domain_raw=($(pihole-FTL "top-domains (1)"))
- top_client_raw=($(pihole-FTL "top-clients (1)"))
-
- # Limit strings to 40 characters to prevent overflow
- recent_blocked="${recent_blocked_raw:0:40}"
- top_ad="${top_ad_raw[2]:0:40}"
- top_domain="${top_domain_raw[2]:0:40}"
- [[ "${top_client_raw[3]}" ]] && top_client="${top_client_raw[3]:0:40}" || top_client="${top_client_raw[2]:0:40}"
+ queries_cached_percentage=$(printf "%.0f\n" "$(calcFunc "$queries_cached_raw * 100 / ( $queries_forwarded_raw + $queries_cached_raw )")")
+ recent_blocked=$(pihole-FTL recentBlocked)
+ read -r -a top_ad_raw <<< "$(pihole-FTL "top-ads (1)")"
+ read -r -a top_domain_raw <<< "$(pihole-FTL "top-domains (1)")"
+ read -r -a top_client_raw <<< "$(pihole-FTL "top-clients (1)")"
+
+ top_ad="${top_ad_raw[2]}"
+ top_domain="${top_domain_raw[2]}"
+ if [[ "${top_client_raw[3]}" ]]; then
+ top_client="${top_client_raw[3]}"
+ else
+ top_client="${top_client_raw[2]}"
+ fi
fi
}
+get_strings() {
+ # Expand or contract strings depending on screen size
+ if [[ "$chrono_width" == "large" ]]; then
+ phc_str=" ${COL_DARK_GRAY}Pi-hole"
+ lte_str=" ${COL_DARK_GRAY}Admin"
+ ftl_str=" ${COL_DARK_GRAY}FTL"
+ api_str="${COL_LIGHT_RED}API Offline"
+
+ host_info="$sys_type"
+ sys_info="$sys_throttle"
+ sys_info2="Active: $cpu_taskact of $cpu_tasks tasks"
+ used_str="Used: "
+ leased_str="Leased: "
+ domains_being_blocked=$(printf "%'.0f" "$domains_being_blocked")
+ ph_info="Blocking: $domains_being_blocked sites"
+ total_str="Total: "
+ else
+ phc_str=" ${COL_DARK_GRAY}PH"
+ lte_str=" ${COL_DARK_GRAY}Web"
+ ftl_str=" ${COL_DARK_GRAY}FTL"
+ api_str="${COL_LIGHT_RED}API Down"
+ ph_info="$domains_being_blocked blocked"
+ fi
+
+ [[ "$sys_cores" -ne 1 ]] && sys_cores_txt="${sys_cores}x "
+ cpu_info="$sys_cores_txt$cpu_freq$cpu_temp_str"
+ ram_info="$used_str$(hrBytes "$ram_used") of $(hrBytes "$ram_total")"
+ disk_info="$used_str$(hrBytes "$disk_used") of $(hrBytes "$disk_total")"
+
+ lan_info="Gateway: $net_gateway"
+ dhcp_info="$leased_str$ph_dhcp_num of $ph_dhcp_max"
+
+ ads_info="$total_str$ads_blocked_today of $dns_queries_today"
+ dns_info="$dns_count DNS servers"
+
+ [[ "$recent_blocked" == "0" ]] && recent_blocked="${COL_LIGHT_RED}FTL offline${COL_NC}"
+}
+
chronoFunc() {
get_init_stats
-
+
for (( ; ; )); do
get_sys_stats
get_ftl_stats
-
- # Do not print LTE/FTL strings if API is unavailable
- ph_core_str=" ${COL_DARK_GRAY}Pi-hole: $ph_core_ver${COL_NC}"
- if [[ -n "$ph_lte_ver" ]]; then
- ph_lte_str=" ${COL_DARK_GRAY}AdminLTE: $ph_lte_ver${COL_NC}"
- ph_ftl_str=" ${COL_DARK_GRAY}FTL: $ph_ftl_ver${COL_NC}"
- fi
-
- clear
-
- echo -e "[0;1;31;91m|¯[0;1;33;93m¯[0;1;32;92m¯[0;1;32;92m(¯[0;1;36;96m)_[0;1;34;94m_[0;1;35;95m|[0;1;33;93m¯[0;1;31;91m|_ [0;1;32;92m__[0;1;36;96m_|[0;1;31;91m¯[0;1;34;94m|[0;1;35;95m__[0;1;31;91m_[0m$ph_core_str
-[0;1;33;93m| ¯[0;1;32;92m_[0;1;36;96m/¯[0;1;34;94m|_[0;1;35;95m_[0;1;31;91m| [0;1;33;93m' [0;1;32;92m\/ [0;1;36;96m_ [0;1;34;94m\ [0;1;35;95m/ [0;1;31;91m-[0;1;33;93m_)[0m$ph_lte_str
-[0;1;32;92m|_[0;1;36;96m| [0;1;34;94m|_[0;1;35;95m| [0;1;33;93m|_[0;1;32;92m||[0;1;36;96m_\[0;1;34;94m__[0;1;35;95m_/[0;1;31;91m_\[0;1;33;93m__[0;1;32;92m_|[0m$ph_ftl_str
- ${COL_DARK_GRAY}——————————————————————————————————————————————————————————${COL_NC}"
+ get_strings
- printFunc " Hostname: " "$sys_name"
- [ -n "$sys_type" ] && printf "%s(%s)%s\n" "$COL_DARK_GRAY" "$sys_type" "$COL_NC" || printf "\n"
-
- printf "%s\n" " Uptime: $sys_uptime"
-
- printFunc " Task Load: " "$sys_loadavg"
- printf "%s(%s)%s\n" "$COL_DARK_GRAY" "Active: $cpu_taskact of $cpu_tasks tasks" "$COL_NC"
-
- printFunc " CPU usage: " "$cpu_perc%"
- printf "%s(%s)%s\n" "$COL_DARK_GRAY" "$sys_cores $sys_cores_plu$cpu_freq_str$cpu_temp_str" "$COL_NC"
-
- printFunc " RAM usage: " "$ram_perc%"
- printf "%s(%s)%s\n" "$COL_DARK_GRAY" "Used: $(hrBytes "$ram_used") of $(hrBytes "$ram_total")" "$COL_NC"
-
- printFunc " HDD usage: " "$disk_perc"
- printf "%s(%s)%s\n" "$COL_DARK_GRAY" "Used: $(hrBytes "$disk_used") of $(hrBytes "$disk_total")" "$COL_NC"
-
- printFunc " LAN addr: " "${IPV4_ADDRESS/\/*/}"
- printf "%s(%s)%s\n" "$COL_DARK_GRAY" "Gateway: $net_gateway" "$COL_NC"
-
- if [[ "$DHCP_ACTIVE" == "true" ]]; then
- printFunc " DHCP: " "$DHCP_START to $ph_dhcp_eip"
- printf "%s(%s)%s\n" "$COL_DARK_GRAY" "Leased: $ph_dhcp_num of $ph_dhcp_max" "$COL_NC"
+ # Strip excess development version numbers
+ if [[ "$ph_core_ver" != "-1" ]]; then
+ phc_ver_str="$phc_str: ${ph_core_ver%-*}${COL_NC}"
+ lte_ver_str="$lte_str: ${ph_lte_ver%-*}${COL_NC}"
+ ftl_ver_str="$ftl_str: ${ph_ftl_ver%-*}${COL_NC}"
+ else
+ phc_ver_str="$phc_str: $api_str${COL_NC}"
fi
-
- printFunc " Pi-hole: " "$ph_status"
- printf "%s(%s)%s\n" "$COL_DARK_GRAY" "Blocking: $domains_being_blocked sites" "$COL_NC"
-
- printFunc " Ads Today: " "$ads_percentage_today%"
- printf "%s(%s)%s\n" "$COL_DARK_GRAY" "$ads_blocked_today of $dns_queries_today queries" "$COL_NC"
-
- printFunc " Fwd DNS: " "$PIHOLE_DNS_1"
- printf "%s(%s)%s\n" "$COL_DARK_GRAY" "Alt DNS: $ph_alts" "$COL_NC"
-
- echo -e " ${COL_DARK_GRAY}——————————————————————————————————————————————————————————${COL_NC}"
- echo " Recently blocked: $recent_blocked"
- echo " Top Advertiser: $top_ad"
- echo " Top Domain: $top_domain"
- printFunc " Top Client: " "$top_client" "last"
-
- if [[ "$1" == "exit" ]]; then
+
+ # Get refresh number
+ if [[ "$*" == *"-r"* ]]; then
+ num="$*"
+ num="${num/*-r /}"
+ num="${num/ */}"
+ num_str="Refresh set for every $num seconds"
+ else
+ num_str=""
+ fi
+
+ clear
+
+ # Remove exit message heading on third refresh
+ if [[ "$count" -le 2 ]] && [[ "$*" != *"-e"* ]]; then
+ echo -e " ${COL_LIGHT_GREEN}Pi-hole Chronometer${COL_NC}
+ $num_str
+ ${COL_LIGHT_RED}Press Ctrl-C to exit${COL_NC}
+ ${COL_DARK_GRAY}$scr_line_str${COL_NC}"
+ else
+ echo -e "[0;1;31;91m|¯[0;1;33;93m¯[0;1;32;92m¯[0;1;32;92m(¯[0;1;36;96m)[0;1;34;94m_[0;1;35;95m|[0;1;33;93m¯[0;1;31;91m|_ [0;1;32;92m__[0;1;36;96m_|[0;1;31;91m¯[0;1;34;94m|[0;1;35;95m__[0;1;31;91m_[0m$phc_ver_str
+[0;1;33;93m| ¯[0;1;32;92m_[0;1;36;96m/¯[0;1;34;94m|[0;1;35;95m_[0;1;31;91m| [0;1;33;93m' [0;1;32;92m\/ [0;1;36;96m_ [0;1;34;94m\ [0;1;35;95m/ [0;1;31;91m-[0;1;33;93m_)[0m$lte_ver_str
+[0;1;32;92m|_[0;1;36;96m| [0;1;34;94m|_[0;1;35;95m| [0;1;33;93m|_[0;1;32;92m||[0;1;36;96m_\[0;1;34;94m__[0;1;35;95m_/[0;1;31;91m_\[0;1;33;93m__[0;1;32;92m_|[0m$ftl_ver_str
+ ${COL_DARK_GRAY}$scr_line_str${COL_NC}"
+ fi
+
+ printFunc " Hostname: " "$sys_name" "$host_info"
+ printFunc " Uptime: " "$sys_uptime" "$sys_info"
+ printFunc " Task Load: " "$sys_loadavg" "$sys_info2"
+ printFunc " CPU usage: " "$cpu_perc%" "$cpu_info"
+ printFunc " RAM usage: " "$ram_perc%" "$ram_info"
+ printFunc " HDD usage: " "$disk_perc" "$disk_info"
+
+ if [[ "$scr_lines" -gt 17 ]] && [[ "$chrono_width" != "small" ]]; then
+ printFunc " LAN addr: " "${IPV4_ADDRESS/\/*/}" "$lan_info"
+ fi
+
+ if [[ "$DHCP_ACTIVE" == "true" ]]; then
+ printFunc "DHCP usage: " "$ph_dhcp_percent%" "$dhcp_info"
+ fi
+
+ printFunc " Pi-hole: " "$ph_status" "$ph_info"
+ printFunc " Ads Today: " "$ads_percentage_today%" "$ads_info"
+ printFunc "Local Qrys: " "$queries_cached_percentage%" "$dns_info"
+
+ printFunc " Blocked: " "$recent_blocked"
+ printFunc "Top Advert: " "$top_ad"
+
+ # Provide more stats on screens with more lines
+ if [[ "$scr_lines" -eq 17 ]]; then
+ if [[ "$DHCP_ACTIVE" == "true" ]]; then
+ printFunc "Top Domain: " "$top_domain" "last"
+ else
+ print_client="true"
+ fi
+ else
+ print_client="true"
+ fi
+
+ if [[ -n "$print_client" ]]; then
+ printFunc "Top Domain: " "$top_domain"
+ printFunc "Top Client: " "$top_client" "last"
+ fi
+
+ # Handle exit/refresh options
+ if [[ "$*" == *"-e"* ]]; then
exit 0
else
- if [[ -n "$1" ]]; then
- sleep "${1}"
+ if [[ "$*" == *"-r"* ]]; then
+ sleep "$num"
else
sleep 5
fi
@@ -409,14 +542,14 @@ helpFunc() {
echo "Usage: pihole -c [options]
Example: 'pihole -c -j'
Calculates stats and displays to an LCD
-
+
Options:
-j, --json Output stats as JSON formatted string
-r, --refresh Set update frequency (in seconds)
-e, --exit Output stats and exit witout refreshing
-h, --help Display this help text"
fi
-
+
exit 0
}
@@ -428,8 +561,8 @@ for var in "$@"; do
case "$var" in
"-j" | "--json" ) jsonFunc;;
"-h" | "--help" ) helpFunc;;
- "-r" | "--refresh" ) chronoFunc "$2";;
- "-e" | "--exit" ) chronoFunc "exit";;
+ "-r" | "--refresh" ) chronoFunc "$@";;
+ "-e" | "--exit" ) chronoFunc "$@";;
* ) helpFunc "?";;
esac
done
From 70fd94edb3ebcfaf16ea9d453e7ca10d7318c9ed Mon Sep 17 00:00:00 2001
From: DL6ER
Date: Wed, 5 Jul 2017 19:30:05 +0200
Subject: [PATCH 119/162] Edit message when requested branch of FTL is not
available
---
advanced/Scripts/piholeCheckout.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/advanced/Scripts/piholeCheckout.sh b/advanced/Scripts/piholeCheckout.sh
index d4a85e8a..7a84f588 100644
--- a/advanced/Scripts/piholeCheckout.sh
+++ b/advanced/Scripts/piholeCheckout.sh
@@ -321,7 +321,7 @@ checkout() {
if check_download_exists "$path"; then
echo " ${TICK} Branch ${2} exists"
else
- echo " ${CROSS} Branch ${2} doesn't exist"
+ echo " ${CROSS} Requested branch \"${2}\" is not available"
fi
FTLinstall "${binary}" "${path}"
From bb8a263d70766863d73d077578ebe041f10793d1 Mon Sep 17 00:00:00 2001
From: DL6ER
Date: Wed, 5 Jul 2017 19:34:20 +0200
Subject: [PATCH 120/162] ShellCheck
---
advanced/Scripts/piholeCheckout.sh | 38 +++++++++++++++++++-----------
1 file changed, 24 insertions(+), 14 deletions(-)
diff --git a/advanced/Scripts/piholeCheckout.sh b/advanced/Scripts/piholeCheckout.sh
index 7a84f588..657bde83 100644
--- a/advanced/Scripts/piholeCheckout.sh
+++ b/advanced/Scripts/piholeCheckout.sh
@@ -35,16 +35,19 @@ check_download_exists() {
FTLinstall() {
# Download and install FTL binary
- local binary="${1}"
- local path="${2}"
- local str="Installing FTL"
+ local binary
+ binary="${1}"
+ local path
+ path="${2}"
+ local str
+ str="Installing FTL"
echo -ne " ${INFO} ${str}..."
if curl -sSL --fail "https://ftl.pi-hole.net/${path}" -o "/tmp/${binary}"; then
# Get sha1 of the binary we just downloaded for verification.
curl -sSL --fail "https://ftl.pi-hole.net/${path}.sha1" -o "/tmp/${binary}.sha1"
# Check if we just downloaded text, or a binary file.
- cd /tmp
+ cd /tmp || return 1
if sha1sum --status --quiet -c "${binary}".sha1; then
echo -n "transferred... "
stop_service pihole-FTL &> /dev/null
@@ -66,15 +69,17 @@ FTLinstall() {
get_binary_name() {
local machine
-
machine=$(uname -m)
- local str="Detecting architecture"
+ local str
+ str="Detecting architecture"
echo -ne " ${INFO} ${str}..."
if [[ ${machine} == arm* || ${machine} == *aarch* ]]; then
# ARM
- local rev=$(uname -m | sed "s/[^0-9]//g;")
- local lib=$(ldd /bin/ls | grep -E '^\s*/lib' | awk '{ print $1 }')
+ local rev
+ rev=$(uname -m | sed "s/[^0-9]//g;")
+ local lib
+ lib=$(ldd /bin/ls | grep -E '^\s*/lib' | awk '{ print $1 }')
if [[ "$lib" == "/lib/ld-linux-aarch64.so.1" ]]; then
echo -e "${OVER} ${TICK} Detected ARM-aarch64 architecture"
binary="pihole-FTL-aarch64-linux-gnu"
@@ -127,7 +132,8 @@ fully_fetch_repo() {
get_available_branches() {
# Return available branches
- local directory="${1}"
+ local directory
+ directory="${1}"
local output
cd "${directory}" || return 1
@@ -139,11 +145,13 @@ get_available_branches() {
fetch_checkout_pull_branch() {
# Check out specified branch
- local directory="${1}"
- local branch="${2}"
+ local directory
+ directory="${1}"
+ local branch
+ branch="${2}"
# Set the reference for the requested branch, fetch, check it put and pull it
- cd "${directory}"
+ cd "${directory}" || return 1
git remote set-branches origin "${branch}" || return 1
git stash --all --quiet &> /dev/null || true
git clean --force -d || true
@@ -153,8 +161,10 @@ fetch_checkout_pull_branch() {
checkout_pull_branch() {
# Check out specified branch
- local directory="${1}"
- local branch="${2}"
+ local directory
+ directory="${1}"
+ local branch
+ branch="${2}"
local oldbranch
cd "${directory}" || return 1
From aad39c5ffc9ed879c3327224e1bf79d121615290 Mon Sep 17 00:00:00 2001
From: Jacob Salmela
Date: Thu, 6 Jul 2017 19:25:56 -0500
Subject: [PATCH 121/162] add comments for nearly every line of code.
---
automated install/basic-install.sh | 690 +++++++++++++++++++++++++----
1 file changed, 597 insertions(+), 93 deletions(-)
diff --git a/automated install/basic-install.sh b/automated install/basic-install.sh
index 3c6b77af..4a30461b 100755
--- a/automated install/basic-install.sh
+++ b/automated install/basic-install.sh
@@ -12,28 +12,49 @@
# pi-hole.net/donate
#
-# Install with this command (from your Pi):
+# Install with this command (from your Linux machine):
#
# curl -L install.pi-hole.net | bash
+
+# -e option instructs bash to immediately exit if any command [1] has a non-zero exit status
+# We do not want users to end up with a partially working install, so we exit the script
+# instead of continuing the installation with something broken
set -e
+
######## VARIABLES #########
+# For better maintainability, we store as much information that can change in variables
+# This allows us to make a change in one place that can propogate to all instances of the variable
+# These variables should all be GLOBAL variables, written in CAPS
+# Local variables will be in lowercase and will exist only within functions
+# It's still a work in progress, so you may see some variance in this guideline until it is complete
+
+# We write to a temporary file before moving the log to the pihole folder
tmpLog=/tmp/pihole-install.log
instalLogLoc=/etc/pihole/install.log
+# This is an important file as it contains information specific to the machine it's being installed on
setupVars=/etc/pihole/setupVars.conf
+# Pi-hole uses lighttpd as a Web server, and this is the config file for it
lighttpdConfig=/etc/lighttpd/lighttpd.conf
+# This is a file used for the colorized output
coltable=/opt/pihole/COL_TABLE
+# We store several other folders and
webInterfaceGitUrl="https://github.com/pi-hole/AdminLTE.git"
webInterfaceDir="/var/www/html/admin"
piholeGitUrl="https://github.com/pi-hole/pi-hole.git"
PI_HOLE_LOCAL_REPO="/etc/.pihole"
+# These are the names of piholes files, stored in an array
PI_HOLE_FILES=(chronometer list piholeDebug piholeLogFlush setupLCD update version gravity uninstall webpage)
+# This folder is where the Pi-hole scripts will be installed
PI_HOLE_INSTALL_DIR="/opt/pihole"
useUpdateVars=false
+# Pi-hole needs an IP address; to begin, these variables are empty since we don't know what the IP is until
+# this script can run
IPV4_ADDRESS=""
IPV6_ADDRESS=""
+# By default, query logging is enabled and the dashboard is set to be installed
QUERY_LOGGING=true
INSTALL_WEB=true
@@ -51,13 +72,19 @@ r=$(( r < 20 ? 20 : r ))
c=$(( c < 70 ? 70 : c ))
######## Undocumented Flags. Shhh ########
+# These are undocumented flags; some of which we can use when repairing an installation
+# The runUnattended flag is one example of this
skipSpaceCheck=false
reconfigure=false
runUnattended=false
+# If the color table file exists,
if [[ -f ${coltable} ]]; then
+ # source it
source ${coltable}
+# Othwerise,
else
+ # Set these values so the installer can still run in color
COL_NC='\e[0m' # No Color
COL_LIGHT_GREEN='\e[1;32m'
COL_LIGHT_RED='\e[1;31m'
@@ -68,7 +95,8 @@ else
OVER="\r\033[K"
fi
-
+# A simple function that just echoes out our logo in ASCII format
+# This lets users know that it is a Pi-hole, LLC product
show_ascii_berry() {
echo -e "
${COL_LIGHT_GREEN}.;;,.
@@ -97,41 +125,63 @@ show_ascii_berry() {
# Compatibility
distro_check() {
+# If apt-get is isntalled, then we know it's part of the Debian family
if command -v apt-get &> /dev/null; then
- #Debian Family
- #############################################
+ # Set some global variables here
+ # We don't set them earlier since the family might be Red Hat, so these values would be different
PKG_MANAGER="apt-get"
+ # A variable to store the command used to update the package cache
UPDATE_PKG_CACHE="${PKG_MANAGER} update"
+ # An array for something...
PKG_INSTALL=(${PKG_MANAGER} --yes --no-install-recommends install)
# grep -c will return 1 retVal on 0 matches, block this throwing the set -e with an OR TRUE
PKG_COUNT="${PKG_MANAGER} -s -o Debug::NoLocking=true upgrade | grep -c ^Inst || true"
- # #########################################
- # fixes for dependency differences
- # Debian 7 doesn't have iproute2 use iproute
+ # Some distros vary slightly so these fixes for dependencies may apply
+ # Debian 7 doesn't have iproute2 so if the dry run install is successful,
if ${PKG_MANAGER} install --dry-run iproute2 > /dev/null 2>&1; then
+ # we can install it
iproute_pkg="iproute2"
+ # Otherwise,
else
+ # use iproute
iproute_pkg="iproute"
fi
- # Prefer the php metapackage if it's there, fall back on the php5 packages
+ # We prefer the php metapackage if it's there
if ${PKG_MANAGER} install --dry-run php > /dev/null 2>&1; then
phpVer="php"
+ # If not,
else
+ # fall back on the php5 packages
phpVer="php5"
fi
- # #########################################
+
+ # Since our instal script is so large, we need several other programs to successfuly get a machine provisioned
+ # These programs are stored in an array so they can be looped through later
INSTALLER_DEPS=(apt-utils dialog debconf dhcpcd5 git ${iproute_pkg} whiptail)
+ # Pi-hole itself has several dependencies that also need to be installed
PIHOLE_DEPS=(bc cron curl dnsmasq dnsutils iputils-ping lsof netcat sudo unzip wget)
+ # The Web dashboard has some that also need to be installed
+ # It's useful to separate the two since our repos are also setup as "Core" code and "Web" code
PIHOLE_WEB_DEPS=(lighttpd ${phpVer}-common ${phpVer}-cgi)
+ # The Web server user,
LIGHTTPD_USER="www-data"
+ # group,
LIGHTTPD_GROUP="www-data"
+ # and config file
LIGHTTPD_CFG="lighttpd.conf.debian"
+ # The DNS server user
DNSMASQ_USER="dnsmasq"
- test_dpkg_lock() {
+# A function to check...
+test_dpkg_lock() {
+ # An iterator used for counting loop iterations
i=0
+ # fuser is a program to show which processes use the named files, sockets, or filesystems
+ # So while the command is true
while fuser /var/lib/dpkg/lock >/dev/null 2>&1 ; do
+ # Wait half a second
sleep 0.5
+ # and increase the iterator
((i=i+1))
done
# Always return success, since we only return if there is no
@@ -139,15 +189,16 @@ if command -v apt-get &> /dev/null; then
return 0
}
+# If apt-get is not found, check for rpm to see if it's a Red Hat family OS
elif command -v rpm &> /dev/null; then
- # Fedora Family
+ # Then check if dnf or yum is the package manager
if command -v dnf &> /dev/null; then
PKG_MANAGER="dnf"
else
PKG_MANAGER="yum"
fi
-# Fedora and family update cache on every PKG_INSTALL call, no need for a separate update.
+ # Fedora and family update cache on every PKG_INSTALL call, no need for a separate update.
UPDATE_PKG_CACHE=":"
PKG_INSTALL=(${PKG_MANAGER} install -y)
PKG_COUNT="${PKG_MANAGER} check-update | egrep '(.i686|.x86|.noarch|.arm|.src)' | wc -l"
@@ -162,113 +213,176 @@ elif command -v rpm &> /dev/null; then
LIGHTTPD_CFG="lighttpd.conf.fedora"
DNSMASQ_USER="nobody"
+# If neither apt-get or rmp/dnf are not found
else
+ # it's not an OS we can support,
echo -e " ${CROSS} OS distribution not supported"
+ # so exit the installer
exit
fi
}
+# A function for checking if a folder is a git repository
is_repo() {
- # Use git to check if directory is currently under VCS, return the value 128
- # if directory is not a repo. Return 1 if directory does not exist.
+ # Use a named, local variable instead of the vague $1, which is the first arguement passed to this function
+ # These local variables should always be lowercase
local directory="${1}"
+ # A local variabled for the current directory
local curdir
+ # A variable to store the return code
local rc
-
+ # Assign the current directory variable by using pwd
curdir="${PWD}"
+ # If the first argument passed to this function is a directory,
if [[ -d "${directory}" ]]; then
- # git -C is not used here to support git versions older than 1.8.4
+ # move into the directory
cd "${directory}"
+ # Use git to check if the folder is a repo
+ # git -C is not used here to support git versions older than 1.8.4
git status --short &> /dev/null || rc=$?
+ # If the command was not successful,
else
- # non-zero return code if directory does not exist
+ # Set a non-zero return code if directory does not exist
rc=1
fi
+ # Move back into the directory the user started in
cd "${curdir}"
+ # Return the code; if one is not set, return 0
return "${rc:-0}"
}
+# A function to clone a repo
make_repo() {
+ # Set named variables for better readability
local directory="${1}"
local remoteRepo="${2}"
+ # The message to display when this function is running
str="Clone ${remoteRepo} into ${directory}"
+ # Display the message and use the color table to preface the message with an "info" indicator
echo -ne " ${INFO} ${str}..."
- # Clean out the directory if it exists for git to clone into
+ # If the directory exists,
if [[ -d "${directory}" ]]; then
+ # delete everything in it so git can clone into it
rm -rf "${directory}"
fi
+ # Clone the repo and return the return code from this command
git clone -q --depth 1 "${remoteRepo}" "${directory}" &> /dev/null || return $?
+ # Show a colored message showing it's status
echo -e "${OVER} ${TICK} ${str}"
+ # Always return 0? Not sure this is correct
return 0
}
+# We need to make sure the repos are up-to-date so we can effectively install Clean out the directory if it exists for git to clone into
update_repo() {
+ # Use named, local variables
+ # As you can see, these are the same variable names used in the last function,
+ # but since they are local, their scope does not go beyond this function
+ # This helps prevent the wrong value from being assigned if you were to set the variable as a GLOBAL one
local directory="${1}"
local curdir
+ # A variable to store the message we want to display;
+ # Again, it's useful to store these in variables in case we need to reuse or change the message;
+ # we only need to make one change here
local str="Update repo in ${1}"
+
+ # Make sure we know what directory we are in so we can move back into it
curdir="${PWD}"
+ # Move into the directory that was passed as an argument
cd "${directory}" &> /dev/null || return 1
- # Pull the latest commits
+ # Let the user know what's happening
echo -ne " ${INFO} ${str}..."
+ # Stash any local commits as they conflict with our working code
git stash --all --quiet &> /dev/null || true # Okay for stash failure
git clean --quiet --force -d || true # Okay for already clean directory
+ # Pull the latest commits
git pull --quiet &> /dev/null || return $?
+ # Show a completion message
echo -e "${OVER} ${TICK} ${str}"
+ # Move back into the oiginal directory
cd "${curdir}" &> /dev/null || return 1
return 0
}
+# A function that combines the functions previously made
getGitFiles() {
- # Setup git repos for directory and repository passed
- # as arguments 1 and 2
+ # Setup named variables for the git repos
+ # We need the directory
local directory="${1}"
+ # as well as the repo URL
local remoteRepo="${2}"
+ # A local varible containing the message to be displayed
local str="Check for existing repository in ${1}"
+ # Show the message
echo -ne " ${INFO} ${str}..."
+ # Check if the directory is a repository
if is_repo "${directory}"; then
+ # Show that we're checking it
echo -e "${OVER} ${TICK} ${str}"
+ # Update the repo, returning an error message on failure
update_repo "${directory}" || { echo -e "\n ${COL_LIGHT_RED}Error: Could not update local repository. Contact support.${COL_NC}"; exit 1; }
+ # If it's not a .git repo,
else
+ # Show an error
echo -e "${OVER} ${CROSS} ${str}"
+ # Attempt to make the repository, showing an error on falure
make_repo "${directory}" "${remoteRepo}" || { echo -e "\n ${COL_LIGHT_RED}Error: Could not update local repository. Contact support.${COL_NC}"; exit 1; }
fi
+ # echo a blank line
echo ""
+ # and return success?
return 0
}
+# Reset a repo to get rid of any local changed
resetRepo() {
+ # Use named varibles for arguments
local directory="${1}"
-
+ # Move into the directory
cd "${directory}" &> /dev/null || return 1
+ # Store the message in a varible
str="Resetting repository within ${1}..."
+ # Show the message
echo -ne " ${INFO} ${str}"
+ # Use git to remove the local changes
git reset --hard &> /dev/null || return $?
+ # And show the status
echo -e "${OVER} ${TICK} ${str}"
+ # Returning success anyway?
return 0
}
+# We need to know the IPv4 information so we can effectively setup the DNS server
+# Without this information, we won't know where to Pi-hole will be found
find_IPv4_information() {
+ # Named, local variables
local route
- # Find IP used to route to outside world
+ # Find IP used to route to outside world by checking the the route to Google's public DNS server
route=$(ip route get 8.8.8.8)
+ # Use awk to strip out just the interface device as it is used in future commands
IPv4dev=$(awk '{for (i=1; i<=NF; i++) if ($i~/dev/) print $(i+1)}' <<< "${route}")
+ # Get just the IP address
IPv4bare=$(awk '{print $7}' <<< "${route}")
+ # Append the CIDR notation to the IP address
IPV4_ADDRESS=$(ip -o -f inet addr show | grep "${IPv4bare}" | awk '{print $4}' | awk 'END {print}')
+ # Get the default gateway (the way to reach the Internet)
IPv4gw=$(awk '{print $3}' <<< "${route}")
}
+# Get available interfaces that are UP
get_available_interfaces() {
- # Get available UP interfaces.
+ # There may be more than one so it's all stored in a variable
availableInterfaces=$(ip --oneline link show up | grep -v "lo" | awk '{print $2}' | cut -d':' -f1 | cut -d'@' -f1)
}
+# A function for displaying the dialogs the user sees when first running the installer
welcomeDialogs() {
- # Display the welcome dialog
+ # Display the welcome dialog using an approriately sized window via the calculation conducted earlier in the script
whiptail --msgbox --backtitle "Welcome" --title "Pi-hole automated installer" "\n\nThis installer will transform your device into a network-wide ad blocker!" ${r} ${c}
- # Support for a part-time dev
+ # Request that users donate if they enjoy the software since we all work on it in our free time
whiptail --msgbox --backtitle "Plea" --title "Free and open source" "\n\nThe Pi-hole is free, but powered by your donations: http://pi-hole.net/donate" ${r} ${c}
# Explain the need for a static address
@@ -277,43 +391,54 @@ welcomeDialogs() {
In the next section, you can choose to use your current network settings (DHCP) or to manually edit them." ${r} ${c}
}
+# We need to make sure there is enough space before installing, so there is a function to check this
verifyFreeDiskSpace() {
# 50MB is the minimum space needed (45MB install (includes web admin bootstrap/jquery libraries etc) + 5MB one day of logs.)
# - Fourdee: Local ensures the variable is only created, and accessible within this function/void. Generally considered a "good" coding practice for non-global variables.
local str="Disk space check"
+ # Reqired space in KB
local required_free_kilobytes=51200
+ # Calculate existing free space on this machine
local existing_free_kilobytes=$(df -Pk | grep -m1 '\/$' | awk '{print $4}')
- # - Unknown free disk space , not a integer
+ # If the existing space is not an integer,
if ! [[ "${existing_free_kilobytes}" =~ ^([0-9])+$ ]]; then
+ # show an error that we can't determine the free space
echo -e " ${CROSS} ${str}
Unknown free disk space!
We were unable to determine available free disk space on this system.
You may override this check, however, it is not recommended
The option '${COL_LIGHT_RED}--i_do_not_follow_recommendations${COL_NC}' can override this
e.g: curl -L https://install.pi-hole.net | bash /dev/stdin ${COL_LIGHT_RED}${COL_NC}"
+ # exit with an error code
exit 1
- # - Insufficient free disk space
+ # If there is insufficient free disk space,
elif [[ ${existing_free_kilobytes} -lt ${required_free_kilobytes} ]]; then
+ # show an error message
echo -e " ${CROSS} ${str}
Your system disk appears to only have ${existing_free_kilobytes} KB free
It is recommended to have a minimum of ${required_free_kilobytes} KB to run the Pi-hole"
+ # if the vcgencmd command exists,
if command -v vcgencmd &> /dev/null; then
+ # it's probably a Raspbian install, so show a message about expanding the filesystem
echo " If this is a new install you may need to expand your disk
Run 'sudo raspi-config', and choose the 'expand file system' option
After rebooting, run this installation again
e.g: curl -L https://install.pi-hole.net | bash"
fi
-
+ # Show there is not enough free space
echo -e "\n ${COL_LIGHT_RED}Insufficient free space, exiting...${COL_NC}"
+ # and exit with an error
exit 1
+ # Otherwise,
else
+ # Show that we're running a disk space check
echo -e " ${TICK} ${str}"
fi
}
-
+# A function that let's the user pick an interface to use with Pi-hole
chooseInterface() {
# Turn the available interfaces into an array so it can be used with a whiptail dialog
local interfacesArray=()
@@ -329,100 +454,156 @@ chooseInterface() {
# Find out how many interfaces are available to choose from
interfaceCount=$(echo "${availableInterfaces}" | wc -l)
+ # If there is one interface,
if [[ ${interfaceCount} -eq 1 ]]; then
+ # Set it as the interface to use since there is no other option
PIHOLE_INTERFACE="${availableInterfaces}"
+ # Otherwise,
else
+ # While reading through the available interfaces
while read -r line; do
+ # use a variable to set the option as OFF to begin with
mode="OFF"
+ # If it's the first loop,
if [[ ${firstLoop} -eq 1 ]]; then
+ # set this as the interface to use (ON)
firstLoop=0
mode="ON"
fi
+ # Put all these interfaces into an array
interfacesArray+=("${line}" "available" "${mode}")
+ # Feed the available interfaces into this while loop
done <<< "${availableInterfaces}"
-
+ # The whiptail command that will be run, stored in a variable
chooseInterfaceCmd=(whiptail --separate-output --radiolist "Choose An Interface (press space to select)" ${r} ${c} ${interfaceCount})
+ # Now run the command using the interfaces saved into the array
chooseInterfaceOptions=$("${chooseInterfaceCmd[@]}" "${interfacesArray[@]}" 2>&1 >/dev/tty) || \
+ # If the user chooses Canel, exit
{ echo -e " ${COL_LIGHT_RED}Cancel was selected, exiting installer${COL_NC}"; exit 1; }
+ # For each interface
for desiredInterface in ${chooseInterfaceOptions}; do
+ # Set the one the user selected as the interface to use
PIHOLE_INTERFACE=${desiredInterface}
+ # and show this information to the user
echo -e " ${INFO} Using interface: $PIHOLE_INTERFACE"
done
fi
}
+# This lets us prefer ULA addresses over GUA
+# This caused problems for some users when their ISP changed their IPv6 addresses
# See https://github.com/pi-hole/pi-hole/issues/1473#issuecomment-301745953
testIPv6() {
+ # first will contain fda2 (ULA)
first="$(cut -f1 -d":" <<< "$1")"
+ # value1 will contain 253 which is the decimal value corresponding to 0xfd
value1=$(((0x$first)/256))
+ # will contain 162 which is the decimal value corresponding to 0xa2
value2=$(((0x$first)%256))
+ # the ULA test is testing for fc00::/7 according to RFC 4193
((($value1&254)==252)) && echo "ULA" || true
+ # the GUA test is testing for 2000::/3 according to RFC 4291
((($value1&112)==32)) && echo "GUA" || true
+ # the LL test is testing for fe80::/10 according to RFC 4193
((($value1==254) && (($value2&192)==128))) && echo "Link-local" || true
}
+# A dialog for showing the user about IPv6 blocking
useIPv6dialog() {
# Determine the IPv6 address used for blocking
IPV6_ADDRESSES=($(ip -6 address | grep 'scope global' | awk '{print $2}'))
- # Determine type of found IPv6 addresses
+ # For each address in the array above, determine the type of IPv6 address it is
for i in "${IPV6_ADDRESSES[@]}"; do
+ # Check if it's ULA, GUA, or LL by using the function created earlier
result=$(testIPv6 "$i")
+ # If it's a ULA address, use it and store it as a global variable
[[ "${result}" == "ULA" ]] && ULA_ADDRESS="${i%/*}"
+ # If it's a GUA address, we can still use it si store it as a global variable
[[ "${result}" == "GUA" ]] && GUA_ADDRESS="${i%/*}"
done
# Determine which address to be used: Prefer ULA over GUA or don't use any if none found
+ # If the ULA_ADDRESS contains a value,
if [[ ! -z "${ULA_ADDRESS}" ]]; then
+ # set the IPv6 address to the ULA address
IPV6_ADDRESS="${ULA_ADDRESS}"
+ # Show this info to the user
echo "::: Found IPv6 ULA address, using it for blocking IPv6 ads"
+ # Otherwise, if the GUA_ADDRESS has a value,
elif [[ ! -z "${GUA_ADDRESS}" ]]; then
+ # Let the user know
echo "::: Found IPv6 GUA address, using it for blocking IPv6 ads"
+ # And assign it to the global variable
IPV6_ADDRESS="${GUA_ADDRESS}"
+ # If none of those work,
else
+ # explain that IPv6 blocking will not be used
echo "::: Found neither IPv6 ULA nor GUA address, blocking IPv6 ads will not be enabled"
+ # So set the variable to be empty
IPV6_ADDRESS=""
fi
+ # If the IPV6_ADDRESS contains a value
if [[ ! -z "${IPV6_ADDRESS}" ]]; then
+ # Display that IPv6 is supported and will be used
whiptail --msgbox --backtitle "IPv6..." --title "IPv6 Supported" "$IPV6_ADDRESS will be used to block ads." ${r} ${c}
fi
}
+# A function to check if we should use IPv4 and/or IPv6 for blocking ads
use4andor6() {
+ # Named local variables
local useIPv4
local useIPv6
- # Let use select IPv4 and/or IPv6
+ # Let use select IPv4 and/or IPv6 via a checklist
cmd=(whiptail --separate-output --checklist "Select Protocols (press space to select)" ${r} ${c} 2)
+ # In an array, show the options available:
+ # IPv4 (on by default)
options=(IPv4 "Block ads over IPv4" on
+ # or IPv6 (on by default if available)
IPv6 "Block ads over IPv6" on)
+ # In a variable, show the choices available; exit if Cancel is selected
choices=$("${cmd[@]}" "${options[@]}" 2>&1 >/dev/tty) || { echo -e " ${COL_LIGHT_RED}Cancel was selected, exiting installer${COL_NC}"; exit 1; }
+ # For each choice available,
for choice in ${choices}
do
+ # Set the values to true
case ${choice} in
IPv4 ) useIPv4=true;;
IPv6 ) useIPv6=true;;
esac
done
+ # If IPv4 is to be used,
if [[ ${useIPv4} ]]; then
+ # Run our function to get the information we need
find_IPv4_information
getStaticIPv4Settings
setStaticIPv4
fi
+ # If IPv6 is to be used,
if [[ ${useIPv6} ]]; then
+ # Run our function to get this information
useIPv6dialog
fi
+ # Echo the information to the user
echo -e " ${INFO} IPv4 address: ${IPV4_ADDRESS}"
echo -e " ${INFO} IPv6 address: ${IPV6_ADDRESS}"
+ # If neither protocol is selected,
if [ ! ${useIPv4} ] && [ ! ${useIPv6} ]; then
+ # Show an error in red
echo -e " ${COL_LIGHT_RED}Error: Neither IPv4 or IPv6 selected${COL_NC}"
+ # and exit with an error
exit 1
fi
}
+#
getStaticIPv4Settings() {
+ # Local, named variables
local ipSettingsCorrect
# Ask if the user wants to use DHCP settings as their static IP
+ # This is useful for users that are using DHCP reservations; then we can just use the information gathered via our functions
if whiptail --backtitle "Calibrating network interface" --title "Static IP Address" --yesno "Do you want to use your current network settings as a static address?
IP address: ${IPV4_ADDRESS}
Gateway: ${IPv4gw}" ${r} ${c}; then
@@ -430,7 +611,7 @@ getStaticIPv4Settings() {
whiptail --msgbox --backtitle "IP information" --title "FYI: IP Conflict" "It is possible your router could still try to assign this IP to a device, which would cause a conflict. But in most cases the router is smart enough to not do that.
If you are worried, either manually set the address, or modify the DHCP reservation pool so it does not include the IP you want.
It is also possible to use a DHCP reservation, but if you are going to do that, you might as well set a static address." ${r} ${c}
- # Nothing else to do since the variables are already set above
+ # Nothing else to do since the variables are already set above
else
# Otherwise, we need to ask the user to input their desired settings.
# Start by getting the IPv4 address (pre-filling it with info gathered from DHCP)
@@ -464,8 +645,9 @@ It is also possible to use a DHCP reservation, but if you are going to do that,
fi
}
+# dhcpcd is very annoying,
setDHCPCD() {
- # Append these lines to dhcpcd.conf to enable a static IP
+ # but we cab append these lines to dhcpcd.conf to enable a static IP
echo "interface ${PIHOLE_INTERFACE}
static ip_address=${IPV4_ADDRESS}
static routers=${IPv4gw}
@@ -473,30 +655,40 @@ setDHCPCD() {
}
setStaticIPv4() {
+ # Local, named variables
local IFCFG_FILE
local IPADDR
local CIDR
+ # For the Debian family, if dhcpcd.conf exists,
if [[ -f /etc/dhcpcd.conf ]]; then
- # Debian Family
+ # check if the IP is already in the file
if grep -q "${IPV4_ADDRESS}" /etc/dhcpcd.conf; then
echo -e " ${INFO} Static IP already configured"
+ # If it's not,
else
+ # set it using our function
setDHCPCD
+ # Then use the ip command to immediately set the new address
ip addr replace dev "${PIHOLE_INTERFACE}" "${IPV4_ADDRESS}"
+ # Also give a warning that the user may need to reboot their system
echo -e " ${TICK} Set IP address to ${IPV4_ADDRESS%/*}
You may need to restart after the install is complete"
fi
+ # If it's not Debian, check if it's the Fedora family by checking for the file below
elif [[ -f /etc/sysconfig/network-scripts/ifcfg-${PIHOLE_INTERFACE} ]];then
- # Fedora Family
+ # If it exists,
IFCFG_FILE=/etc/sysconfig/network-scripts/ifcfg-${PIHOLE_INTERFACE}
+ # check if the desired IP is already set
if grep -q "${IPV4_ADDRESS}" "${IFCFG_FILE}"; then
echo -e " ${INFO} Static IP already configured"
+ # Otherwise,
else
+ # Put the IP in variables without the CIDR notation
IPADDR=$(echo "${IPV4_ADDRESS}" | cut -f1 -d/)
CIDR=$(echo "${IPV4_ADDRESS}" | cut -f2 -d/)
# Backup existing interface configuration:
cp "${IFCFG_FILE}" "${IFCFG_FILE}".pihole.orig
- # Build Interface configuration file:
+ # Build Interface configuration file using the GLOBAL variables we have
{
echo "# Configured via Pi-hole installer"
echo "DEVICE=$PIHOLE_INTERFACE"
@@ -509,39 +701,57 @@ setStaticIPv4() {
echo "DNS2=$PIHOLE_DNS_2"
echo "USERCTL=no"
}> "${IFCFG_FILE}"
+ # Use ip to immediately set the new address
ip addr replace dev "${PIHOLE_INTERFACE}" "${IPV4_ADDRESS}"
+ # If NetworkMangler command line interface exists,
if command -v nmcli &> /dev/null;then
- # Tell NetworkManager to read our new sysconfig file
+ # Tell NetworkManagler to read our new sysconfig file
nmcli con load "${IFCFG_FILE}" > /dev/null
fi
+ # Show a warning that the user may need to restart
echo -e " ${TICK} Set IP address to ${IPV4_ADDRESS%/*}
You may need to restart after the install is complete"
fi
+ # If all that fails,
else
+ # show an error and exit
echo -e " ${INFO} Warning: Unable to locate configuration file to set static IPv4 address"
exit 1
fi
}
+# Check an IP address to see if it is a valid one
valid_ip() {
+ # Local, named variables
local ip=${1}
local stat=1
+ # If the IP matches the format xxx.xxx.xxx.xxx,
if [[ ${ip} =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then
+ # Save the old Interfal Field Separator in a variable
OIFS=$IFS
+ # and set the new one to a dot (period)
IFS='.'
+ # Put the IP into an array
ip=(${ip})
+ # Restore the IFS to what it was
IFS=${OIFS}
+ ## Evaluate each octet by checking if it's less than or equal to 255 (the max for each octet)
[[ ${ip[0]} -le 255 && ${ip[1]} -le 255 \
&& ${ip[2]} -le 255 && ${ip[3]} -le 255 ]]
+ # Save the exit code
stat=$?
fi
+ # Return the exit code
return ${stat}
}
+# A function to choose the upstream DNS provider(s)
setDNS() {
+ # Local, named variables
local DNSSettingsCorrect
+ # In an array, list the available upstream providers
DNSChooseOptions=(Google ""
OpenDNS ""
Level3 ""
@@ -549,11 +759,15 @@ setDNS() {
Comodo ""
DNSWatch ""
Custom "")
+ # In a whiptail dialog, show the options
DNSchoices=$(whiptail --separate-output --menu "Select Upstream DNS Provider. To use your own, select Custom." ${r} ${c} 6 \
"${DNSChooseOptions[@]}" 2>&1 >/dev/tty) || \
+ # exit if Cancel is selected
{ echo -e " ${COL_LIGHT_RED}Cancel was selected, exiting installer${COL_NC}"; exit 1; }
+ # Display the selection
echo -ne " ${INFO} Using "
+ # Depending on the user's choice, set the GLOBAl variables to the IP of the respective provider
case ${DNSchoices} in
Google)
echo "Google DNS servers"
@@ -586,44 +800,68 @@ setDNS() {
PIHOLE_DNS_2="84.200.70.40"
;;
Custom)
+ # Until the DNS settings are selected,
until [[ ${DNSSettingsCorrect} = True ]]; do
+ #
strInvalid="Invalid"
+ # If the first
if [ ! ${PIHOLE_DNS_1} ]; then
+ # and second upstream servers do not exist
if [ ! ${PIHOLE_DNS_2} ]; then
+ #
prePopulate=""
+ # Otherwise,
else
+ #
prePopulate=", ${PIHOLE_DNS_2}"
fi
+ #
elif [ ${PIHOLE_DNS_1} ] && [ ! ${PIHOLE_DNS_2} ]; then
+ #
prePopulate="${PIHOLE_DNS_1}"
+ #
elif [ ${PIHOLE_DNS_1} ] && [ ${PIHOLE_DNS_2} ]; then
+ #
prePopulate="${PIHOLE_DNS_1}, ${PIHOLE_DNS_2}"
fi
+ # Dialog for the user to enter custom upstream servers
piholeDNS=$(whiptail --backtitle "Specify Upstream DNS Provider(s)" --inputbox "Enter your desired upstream DNS provider(s), seperated by a comma.\n\nFor example '8.8.8.8, 8.8.4.4'" ${r} ${c} "${prePopulate}" 3>&1 1>&2 2>&3) || \
{ echo -e " ${COL_LIGHT_RED}Cancel was selected, exiting installer${COL_NC}"; exit 1; }
+ #
PIHOLE_DNS_1=$(echo "${piholeDNS}" | sed 's/[, \t]\+/,/g' | awk -F, '{print$1}')
PIHOLE_DNS_2=$(echo "${piholeDNS}" | sed 's/[, \t]\+/,/g' | awk -F, '{print$2}')
+ # If the IP is valid,
if ! valid_ip "${PIHOLE_DNS_1}" || [ ! "${PIHOLE_DNS_1}" ]; then
+ # store it in the variable so we can use it
PIHOLE_DNS_1=${strInvalid}
fi
+ # Do the same for the secondary server
if ! valid_ip "${PIHOLE_DNS_2}" && [ "${PIHOLE_DNS_2}" ]; then
PIHOLE_DNS_2=${strInvalid}
fi
+ # If either of the DNS servers are invalid,
if [[ ${PIHOLE_DNS_1} == "${strInvalid}" ]] || [[ ${PIHOLE_DNS_2} == "${strInvalid}" ]]; then
+ # explain this to the user
whiptail --msgbox --backtitle "Invalid IP" --title "Invalid IP" "One or both entered IP addresses were invalid. Please try again.\n\n DNS Server 1: $PIHOLE_DNS_1\n DNS Server 2: ${PIHOLE_DNS_2}" ${r} ${c}
+ # and set the variables back to nothing
if [[ ${PIHOLE_DNS_1} == "${strInvalid}" ]]; then
PIHOLE_DNS_1=""
fi
if [[ ${PIHOLE_DNS_2} == "${strInvalid}" ]]; then
PIHOLE_DNS_2=""
fi
+ # Since the settings will not work, stay in the loop
DNSSettingsCorrect=False
+ # Othwerise,
else
+ # Show the settings
if (whiptail --backtitle "Specify Upstream DNS Provider(s)" --title "Upstream DNS Provider(s)" --yesno "Are these settings correct?\n DNS Server 1: $PIHOLE_DNS_1\n DNS Server 2: ${PIHOLE_DNS_2}" ${r} ${c}); then
+ # and break from the loop since the servers are vaid
DNSSettingsCorrect=True
+ # Otherwise,
else
- # If the settings are wrong, the loop continues
+ # If the settings are wrong, the loop continues
DNSSettingsCorrect=False
fi
fi
@@ -632,51 +870,67 @@ setDNS() {
esac
}
+# Allow the user to enable/disable logging
setLogging() {
+ # Local, named variables
local LogToggleCommand
local LogChooseOptions
local LogChoices
+ # Ask if the user wants to log queries
LogToggleCommand=(whiptail --separate-output --radiolist "Do you want to log queries?\n (Disabling will render graphs on the Admin page useless):" ${r} ${c} 6)
+ # The default selection is on
LogChooseOptions=("On (Recommended)" "" on
Off "" off)
+ # Get the user's choice
LogChoices=$("${LogToggleCommand[@]}" "${LogChooseOptions[@]}" 2>&1 >/dev/tty) || (echo -e " ${COL_LIGHT_RED}Cancel was selected, exiting installer${COL_NC}" && exit 1)
case ${LogChoices} in
+ # If it's on
"On (Recommended)")
echo -e " ${INFO} Logging On."
+ # Set the GLOBAL variable to true so we know what they selected
QUERY_LOGGING=true
;;
+ # Othwerise, it's off,
Off)
echo -e " ${INFO} Logging Off."
+ # So set it to false
QUERY_LOGGING=false
;;
esac
}
+# Funtion to ask the user if they want to install the dashboard
setAdminFlag() {
+ # Local, named variables
local WebToggleCommand
local WebChooseOptions
local WebChoices
+ # Similar to the logging function, ask what the user wants
WebToggleCommand=(whiptail --separate-output --radiolist "Do you wish to install the web admin interface?" ${r} ${c} 6)
+ # with the default being enabled
WebChooseOptions=("On (Recommended)" "" on
Off "" off)
WebChoices=$("${WebToggleCommand[@]}" "${WebChooseOptions[@]}" 2>&1 >/dev/tty) || (echo -e " ${COL_LIGHT_RED}Cancel was selected, exiting installer${COL_NC}" && exit 1)
+ # Depending on their choice
case ${WebChoices} in
"On (Recommended)")
echo -e " ${INFO} Web Interface On."
+ # Set it to true
INSTALL_WEB=true
;;
Off)
echo -e " ${INFO} Web Interface off."
+ # or false
INSTALL_WEB=false
;;
esac
}
-
+# Check if /etc/dnsmasq.conf is from pihole. If so replace with an original and install new in .d directory
version_check_dnsmasq() {
- # Check if /etc/dnsmasq.conf is from pihole. If so replace with an original and install new in .d directory
+ # Local, named variables
local dnsmasq_conf="/etc/dnsmasq.conf"
local dnsmasq_conf_orig="/etc/dnsmasq.conf.orig"
local dnsmasq_pihole_id_string="addn-hosts=/etc/pihole/gravity.list"
@@ -684,65 +938,89 @@ version_check_dnsmasq() {
local dnsmasq_pihole_01_snippet="${PI_HOLE_LOCAL_REPO}/advanced/01-pihole.conf"
local dnsmasq_pihole_01_location="/etc/dnsmasq.d/01-pihole.conf"
+ # If the dnsmasq config file exists
if [ -f ${dnsmasq_conf} ]; then
echo -ne " ${INFO} Existing dnsmasq.conf found..."
+ # If gravity.list is found within this file, we presume it's from older versions on Pi-hole,
if grep -q ${dnsmasq_pihole_id_string} ${dnsmasq_conf}; then
echo " it is from a previous Pi-hole install."
echo -ne " ${INFO} Backing up dnsmasq.conf to dnsmasq.conf.orig..."
+ # so backup the original file
mv -f ${dnsmasq_conf} ${dnsmasq_conf_orig}
echo -e "${OVER} ${TICK} Backing up dnsmasq.conf to dnsmasq.conf.orig..."
echo -ne " ${INFO} Restoring default dnsmasq.conf..."
+ # and replace it with the default
cp ${dnsmasq_original_config} ${dnsmasq_conf}
echo -e "${OVER} ${TICK} Restoring default dnsmasq.conf..."
+ # Otherwise,
else
+ # Don't to anything
echo " it is not a Pi-hole file, leaving alone!"
fi
else
+ # If a file cannot be found,
echo -ne " ${INFO} No dnsmasq.conf found... restoring default dnsmasq.conf..."
+ # restore the default one
cp ${dnsmasq_original_config} ${dnsmasq_conf}
echo -e "${OVER} ${TICK} No dnsmasq.conf found... restoring default dnsmasq.conf..."
fi
echo -en " ${INFO} Copying 01-pihole.conf to /etc/dnsmasq.d/01-pihole.conf..."
+ # Copy the new Pi-hole DNS config file into the dnsmasq.d directory
cp ${dnsmasq_pihole_01_snippet} ${dnsmasq_pihole_01_location}
echo -e "${OVER} ${TICK} Copying 01-pihole.conf to /etc/dnsmasq.d/01-pihole.conf"
+ # Replace our placeholder values with the GLOBAL DNS variables that we populated earlier
+ # First, swap in the interface to listen on
sed -i "s/@INT@/$PIHOLE_INTERFACE/" ${dnsmasq_pihole_01_location}
if [[ "${PIHOLE_DNS_1}" != "" ]]; then
+ # Then swap in the primary DNS server
sed -i "s/@DNS1@/$PIHOLE_DNS_1/" ${dnsmasq_pihole_01_location}
else
+ #
sed -i '/^server=@DNS1@/d' ${dnsmasq_pihole_01_location}
fi
if [[ "${PIHOLE_DNS_2}" != "" ]]; then
+ # Then swap in the primary DNS server
sed -i "s/@DNS2@/$PIHOLE_DNS_2/" ${dnsmasq_pihole_01_location}
else
+ #
sed -i '/^server=@DNS2@/d' ${dnsmasq_pihole_01_location}
fi
+ #
sed -i 's/^#conf-dir=\/etc\/dnsmasq.d$/conf-dir=\/etc\/dnsmasq.d/' ${dnsmasq_conf}
+ # If the user does not want to enable logging,
if [[ "${QUERY_LOGGING}" == false ]] ; then
- #Disable Logging
+ # Disable it by commenting out the directive in the DNS config file
sed -i 's/^log-queries/#log-queries/' ${dnsmasq_pihole_01_location}
+ # Otherwise,
else
- #Enable Logging
+ # enable it by uncommenting the directive in the DNS config file
sed -i 's/^#log-queries/log-queries/' ${dnsmasq_pihole_01_location}
fi
}
+# Clean an exiting installation to prepare for upgrade/reinstall
clean_existing() {
- # Clean an exiting installation to prepare for upgrade/reinstall
- # ${1} Directory to clean; ${2} Array of files to remove
+ # Local, named variables
+ # ${1} Directory to clean
local clean_directory="${1}"
+ # Make ${2} the new one?
shift
+ # ${2} Array of files to remove
local old_files=( "$@" )
+ # For each script found in the old files array
for script in "${old_files[@]}"; do
+ # Remove them
rm -f "${clean_directory}/${script}.sh"
done
}
+# Install the scripts from repository to their various locations
installScripts() {
- # Install the scripts from repository to their various locations
+ # Local, named variables
local str="Installing scripts from ${PI_HOLE_LOCAL_REPO}"
echo -ne " ${INFO} ${str}..."
@@ -751,8 +1029,15 @@ installScripts() {
# Install files from local core repository
if is_repo "${PI_HOLE_LOCAL_REPO}"; then
+ # move into the directory
cd "${PI_HOLE_LOCAL_REPO}"
+ # Install the scripts by:
+ # -o setting the owner to the user
+ # -Dm755 create all leading components of destiantion except the last, then copy the source to the destiantion and setting the permissions to 755
+ #
+ # This first one is the directory
install -o "${USER}" -Dm755 -d "${PI_HOLE_INSTALL_DIR}"
+ # The rest are the scripts Pi-hole needs
install -o "${USER}" -Dm755 -t "${PI_HOLE_INSTALL_DIR}" gravity.sh
install -o "${USER}" -Dm755 -t "${PI_HOLE_INSTALL_DIR}" ./advanced/Scripts/*.sh
install -o "${USER}" -Dm755 -t "${PI_HOLE_INSTALL_DIR}" ./automated\ install/uninstall.sh
@@ -760,28 +1045,38 @@ installScripts() {
install -o "${USER}" -Dm755 -t /usr/local/bin/ pihole
install -Dm644 ./advanced/bash-completion/pihole /etc/bash_completion.d/pihole
echo -e "${OVER} ${TICK} ${str}"
+ # Otherwise,
else
+ # Show an error and exit
echo -e "${OVER} ${CROSS} ${str}"
echo -e " ${COL_LIGHT_RED}Error: Local repo ${PI_HOLE_LOCAL_REPO} not found, exiting installer${COL_NC}"
exit 1
fi
}
+# Install the configs from PI_HOLE_LOCAL_REPO to their various locations
installConfigs() {
- # Install the configs from PI_HOLE_LOCAL_REPO to their various locations
echo ""
echo -e " ${INFO} Installing configs from ${PI_HOLE_LOCAL_REPO}..."
+ # Make sure Pi-hole's config files are in place
version_check_dnsmasq
- #Only mess with lighttpd configs if user has chosen to install web interface
+ # If the user chose to install the dashboard,
if [[ ${INSTALL_WEB} == true ]]; then
+ # and if the Web server conf directory does not exist,
if [ ! -d "/etc/lighttpd" ]; then
+ # make it
mkdir /etc/lighttpd
+ # and set the owners
chown "${USER}":root /etc/lighttpd
+ # Otherwise, if the config file already exists
elif [ -f "/etc/lighttpd/lighttpd.conf" ]; then
+ # back up the original
mv /etc/lighttpd/lighttpd.conf /etc/lighttpd/lighttpd.conf.orig
fi
+ # and copy in the config file Pi-hole needs
cp ${PI_HOLE_LOCAL_REPO}/advanced/${LIGHTTPD_CFG} /etc/lighttpd/lighttpd.conf
+ # Make the directories if they do not exist and set the owners
mkdir -p /var/run/lighttpd
chown ${LIGHTTPD_USER}:${LIGHTTPD_GROUP} /var/run/lighttpd
mkdir -p /var/cache/lighttpd/compress
@@ -805,83 +1100,110 @@ stop_service() {
echo -e "${OVER} ${TICK} ${str}..."
}
+# Start/Restart service passed in as argument
start_service() {
- # Start/Restart service passed in as argument
- # This should not fail, it's an error if it does
+ # Local, named variables
local str="Starting ${1} service"
echo ""
echo -ne " ${INFO} ${str}..."
+ # If systemctl exists,
if command -v systemctl &> /dev/null; then
+ # use that to restart the service
systemctl restart "${1}" &> /dev/null
+ # Otherwise,
else
+ # fall back to the service command
service "${1}" restart &> /dev/null
fi
echo -e "${OVER} ${TICK} ${str}"
}
+# Enable service so that it will start with next reboot
enable_service() {
- # Enable service so that it will start with next reboot
+ # Local, named variables
local str="Enabling ${1} service to start on reboot"
echo ""
echo -ne " ${INFO} ${str}..."
+ # If systemctl exists,
if command -v systemctl &> /dev/null; then
+ # use that to enable the service
systemctl enable "${1}" &> /dev/null
+ # Othwerwise,
else
+ # use update-rc.d to accomplish this
update-rc.d "${1}" defaults &> /dev/null
fi
echo -e "${OVER} ${TICK} ${str}"
}
update_package_cache() {
- #Running apt-get update/upgrade with minimal output can cause some issues with
- #requiring user input (e.g password for phpmyadmin see #218)
+ # Running apt-get update/upgrade with minimal output can cause some issues with
+ # requiring user input (e.g password for phpmyadmin see #218)
- #Update package cache on apt based OSes. Do this every time since
- #it's quick and packages can be updated at any time.
+ # Update package cache on apt based OSes. Do this every time since
+ # it's quick and packages can be updated at any time.
+ # Local, named variables
local str="Update local cache of available packages"
echo ""
echo -ne " ${INFO} ${str}..."
+ # Create a command from the package cache variable
if eval "${UPDATE_PKG_CACHE}" &> /dev/null; then
echo -e "${OVER} ${TICK} ${str}"
+ # Otherwise,
else
+ # show an error and exit
echo -e "${OVER} ${CROSS} ${str}"
echo -ne " ${COL_LIGHT_RED}Error: Unable to update package cache. Please try \"${UPDATE_PKG_CACHE}\"${COL_NC}"
return 1
fi
}
+# Let user know if they have outdated packages on their system and
+# advise them to run a package update at soonest possible.
notify_package_updates_available() {
- # Let user know if they have outdated packages on their system and
- # advise them to run a package update at soonest possible.
+ # Local, named variables
local str="Checking ${PKG_MANAGER} for upgraded packages"
echo ""
echo -ne " ${INFO} ${str}..."
+ # Store the list of packages in a variable
updatesToInstall=$(eval "${PKG_COUNT}")
#echo -e "\r\033[K ${TICK} ${str}"
#echo ""
+ #
if [[ -d "/lib/modules/$(uname -r)" ]]; then
+ #
if [[ ${updatesToInstall} -eq "0" ]]; then
+ #
echo -e "${OVER} ${TICK} ${str}... up to date!"
echo ""
else
+ #
echo -e "${OVER} ${TICK} ${str}... ${updatesToInstall} updates available"
echo -e " ${INFO} ${COL_LIGHT_GREEN}It is recommended to update your OS after installing the Pi-hole! ${COL_NC}"
echo ""
fi
else
+ #
echo -e "${OVER} ${CROSS} ${str}
Kernel update detected. If the install fails, please reboot and try again"
echo ""
fi
}
+# What's this doing outside of a function in the middle of nowhere?
counter=0
+
install_dependent_packages() {
+ # Local, named variables should be used here, especially for an iterator
+ # Add one to the counter
counter=$((counter+1))
+ # If it equals 1,
if [ ${counter} == 1 ]; then
+ #
echo -e " ${INFO} Installer Dependency checks..."
else
+ #
echo -e " ${INFO} Main Dependency checks..."
fi
@@ -895,36 +1217,49 @@ install_dependent_packages() {
# amount of download traffic.
# NOTE: We may be able to use this installArray in the future to create a list of package that were
# installed by us, and remove only the installed packages, and not the entire list.
- if command -v debconf-apt-progress &> /dev/null; then
+ if command -v debconf-apt-progress &> /dev/null;
+ # For each package,
for i in "${argArray1[@]}"; do
echo -ne " ${INFO} Checking for $i..."
+ #
if dpkg-query -W -f='${Status}' "${i}" 2>/dev/null | grep "ok installed" &> /dev/null; then
+ #
echo -e "${OVER} ${TICK} Checking for $i"
else
+ #
echo -e "${OVER} ${CROSS} Checking for $i (will be installed)"
+ #
installArray+=("${i}")
fi
done
+ #
if [[ ${#installArray[@]} -gt 0 ]]; then
+ #
test_dpkg_lock
+ #
debconf-apt-progress -- "${PKG_INSTALL[@]}" "${installArray[@]}"
return
fi
echo ""
+ #
return 0
fi
- #Fedora/CentOS
+ # Install Fedora/CentOS packages
for i in "${argArray1[@]}"; do
echo -ne " ${INFO} Checking for $i..."
+ #
if ${PKG_MANAGER} -q list installed "${i}" &> /dev/null; then
echo -e "${OVER} ${TICK} Checking for $i"
else
echo -e "${OVER} ${CROSS} Checking for $i (will be installed)"
+ #
installArray+=("${i}")
fi
done
+ #
if [[ ${#installArray[@]} -gt 0 ]]; then
+ #
"${PKG_INSTALL[@]}" "${installArray[@]}" &> /dev/null
return
fi
@@ -932,141 +1267,180 @@ install_dependent_packages() {
return 0
}
+# Create logfiles if necessary
CreateLogFile() {
- # Create logfiles if necessary
local str="Creating log and changing owner to dnsmasq"
echo ""
echo -ne " ${INFO} ${str}..."
+ # If the pihole log does not exist,
if [ ! -f /var/log/pihole.log ]; then
+ # Make it,
touch /var/log/pihole.log
+ # set the permissions,
chmod 644 /var/log/pihole.log
+ # and owners
chown "${DNSMASQ_USER}":root /var/log/pihole.log
echo -e "${OVER} ${TICK} ${str}"
+ # Otherwise,
else
+ # the file should already exist
echo -e " ${COL_LIGHT_GREEN}log already exists!${COL_NC}"
fi
}
+# Install the Web interface dashboard
installPiholeWeb() {
- # Install the web interface
-
echo ""
echo " ${INFO} Installing blocking page..."
+ # If the pihole Web directory exists,
if [ -d "/var/www/html/pihole" ]; then
-
local str="Installing index.php"
echo -ne " ${INFO} ${str}..."
+ # and if the index file exists,
if [ -f "/var/www/html/pihole/index.php" ]; then
+ # do not overwrite it,
echo -e " ${COL_LIGHT_GREEN}detected index.php, not overwriting${COL_NC}"
+ # if it doesn't exist
else
+ # install it by copying it from the repo
cp ${PI_HOLE_LOCAL_REPO}/advanced/index.php /var/www/html/pihole/
echo -e "${OVER} ${TICK} ${str}"
fi
local str="Installing index.js"
echo -ne " ${INFO} ${str}..."
+ # and if the index file exists,
if [ -f "/var/www/html/pihole/index.js" ]; then
+ # do not overwrite it,
echo -e " ${COL_LIGHT_GREEN}detected index.js, not overwriting${COL_NC}"
else
+ # install it by copying it from the repo
cp ${PI_HOLE_LOCAL_REPO}/advanced/index.js /var/www/html/pihole/
echo -e "${OVER} ${TICK} ${str}"
fi
local str="Installing blockingpage.css"
echo -ne " ${INFO} ${str}..."
+ # and if the index file exists,
if [ -f "/var/www/html/pihole/blockingpage.css" ]; then
+ # do not overwrite it,
echo -e " ${COL_LIGHT_GREEN}detected blockingpage.css, not overwriting${COL_NC}"
else
+ # install it by copying it from the repo
cp ${PI_HOLE_LOCAL_REPO}/advanced/blockingpage.css /var/www/html/pihole
echo -e "${OVER} ${TICK} ${str}"
fi
-
+ # If the pihole Web directory does not exist,
else
local str="Creating directory for blocking page, and copying files"
echo -ne " ${INFO} ${str}..."
+ # Install the directory
install -d /var/www/html/pihole
+ # and the blockpage
install -D ${PI_HOLE_LOCAL_REPO}/advanced/{index,blockingpage}.* /var/www/html/pihole/
echo -e "${OVER} ${TICK} ${str}"
local str="Backing up index.lighttpd.html"
echo -ne " ${INFO} ${str}..."
+ # If the default index file exists,
if [ -f /var/www/html/index.lighttpd.html ]; then
+ # back it up
mv /var/www/html/index.lighttpd.html /var/www/html/index.lighttpd.orig
echo -e "${OVER} ${TICK} ${str}"
+ # Othwerwise,
else
+ # don't do anything
echo -e "${OVER} ${CROSS} ${str}"
echo -e " No default index.lighttpd.html file found... not backing up"
fi
fi
- # Install Sudoer file
+ # Install Sudoers file
echo ""
local str="Installing sudoer file"
echo -ne " ${INFO} ${str}..."
+ # Make the .d directory if it doesn't exist
mkdir -p /etc/sudoers.d/
+ # and copy in the pihole sudoers file
cp ${PI_HOLE_LOCAL_REPO}/advanced/pihole.sudo /etc/sudoers.d/pihole
# Add lighttpd user (OS dependent) to sudoers file
echo "${LIGHTTPD_USER} ALL=NOPASSWD: /usr/local/bin/pihole" >> /etc/sudoers.d/pihole
+ # If the Web server user is lighttpd,
if [[ "$LIGHTTPD_USER" == "lighttpd" ]]; then
# Allow executing pihole via sudo with Fedora
# Usually /usr/local/bin is not permitted as directory for sudoable programms
echo "Defaults secure_path = /sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin" >> /etc/sudoers.d/pihole
fi
-
+ # Set the strict permissions on the file
chmod 0440 /etc/sudoers.d/pihole
echo -e "${OVER} ${TICK} ${str}"
}
+# Installs a cron file
installCron() {
# Install the cron job
local str="Installing latest Cron script"
echo ""
echo -ne " ${INFO} ${str}..."
+ # Copy the cron file over from the local repo
cp ${PI_HOLE_LOCAL_REPO}/advanced/pihole.cron /etc/cron.d/pihole
echo -e "${OVER} ${TICK} ${str}"
}
+# Gravity is a very important script as it aggregates all of the domains into a single HOSTS formatted list,
+# which is what Pi-hole needs to begin blocking ads
runGravity() {
- # Run gravity.sh to build blacklists
echo ""
echo -e " ${INFO} Preparing to run gravity.sh to refresh hosts..."
+ # If cached lists exist,
if ls /etc/pihole/list* 1> /dev/null 2>&1; then
echo -e " ${INFO} Cleaning up previous install (preserving whitelist/blacklist)"
+ # remove them
rm /etc/pihole/list.*
fi
- # Test if /etc/pihole/adlists.default exists
+ # If the default ad lists file exists,
if [[ ! -e /etc/pihole/adlists.default ]]; then
+ # copy it over from the local repo
cp ${PI_HOLE_LOCAL_REPO}/adlists.default /etc/pihole/adlists.default
fi
echo -e " ${INFO} Running gravity.sh"
+ # Run gravity in the current shell
{ /opt/pihole/gravity.sh; }
}
+# Check if the pihole user exists and create if it does not
create_pihole_user() {
- # Check if user pihole exists and create if not
local str="Checking for user 'pihole'"
echo -ne " ${INFO} ${str}..."
+ # If the user pihole exists,
if id -u pihole &> /dev/null; then
+ # just show a success
echo -ne "${OVER} ${TICK} ${str}"
+ # Othwerwise,
else
echo -ne "${OVER} ${CROSS} ${str}"
local str="Creating user 'pihole'"
echo -ne " ${INFO} ${str}..."
+ # create her with the useradd command
useradd -r -s /usr/sbin/nologin pihole
echo -ne "${OVER} ${TICK} ${str}"
fi
}
+# Allow HTTP and DNS traffic
configureFirewall() {
- # Allow HTTP and DNS traffic
echo ""
+ # If a firewall is running,
if firewall-cmd --state &> /dev/null; then
+ # ask if the user wants to install Pi-hole's default firwall rules
whiptail --title "Firewall in use" --yesno "We have detected a running firewall\n\nPi-hole currently requires HTTP and DNS port access.\n\n\n\nInstall Pi-hole default firewall rules?" ${r} ${c} || \
{ echo -e " ${INFO} Not installing firewall rulesets."; return 0; }
echo -e " ${TICK} Configuring FirewallD for httpd and dnsmasq."
+ # Allow HTTP and DNS traffice
firewall-cmd --permanent --add-service=http --add-service=dns
+ # Reload the firewall to apply these changes
firewall-cmd --reload
return 0
# Check for proper kernel modules to prevent failure
@@ -1084,29 +1458,37 @@ configureFirewall() {
iptables -C INPUT -p tcp -m tcp --dport 4711:4720 -i lo -j ACCEPT &> /dev/null || iptables -I INPUT 1 -p tcp -m tcp --dport 4711:4720 -i lo -j ACCEPT
return 0
fi
+ # Othwerwise,
else
+ # no firewall is running
echo -e " ${INFO} No active firewall detected.. skipping firewall configuration."
+ # so just exit
return 0
fi
echo -e " ${INFO} Skipping firewall configuration."
}
+#
finalExports() {
-
+ # If the Web interface is not set to be installed,
if [[ ${INSTALL_WEB} == false ]]; then
- #No web interface installed, and therefore no block page set IPV4/6 to 0.0.0.0 and ::/0
+ # and if there is not an IPv4 address,
if [ ${IPV4_ADDRESS} ]; then
+ # there is no block page, so set IPv4 to 0.0.0.0 (all IP addresses)
IPV4_ADDRESS="0.0.0.0"
fi
if [ ${IPV6_ADDRESS} ]; then
+ # and IPv6 to ::/0
IPV6_ADDRESS="::/0"
fi
fi
- # Update variables in setupVars.conf file
+ # If the setup variable file exists,
if [ -e "${setupVars}" ]; then
+ # update the variables in the file
sed -i.update.bak '/PIHOLE_INTERFACE/d;/IPV4_ADDRESS/d;/IPV6_ADDRESS/d;/PIHOLE_DNS_1/d;/PIHOLE_DNS_2/d;/QUERY_LOGGING/d;/INSTALL_WEB/d;' "${setupVars}"
fi
+ # echo the information to the user
{
echo "PIHOLE_INTERFACE=${PIHOLE_INTERFACE}"
echo "IPV4_ADDRESS=${IPV4_ADDRESS}"
@@ -1119,22 +1501,29 @@ finalExports() {
# Look for DNS server settings which would have to be reapplied
source "${setupVars}"
+ #
source "${PI_HOLE_LOCAL_REPO}/advanced/Scripts/webpage.sh"
+ #
if [[ "${DNS_FQDN_REQUIRED}" != "" ]] ; then
+ #
ProcessDNSSettings
fi
+ #
if [[ "${DHCP_ACTIVE}" != "" ]] ; then
+ #
ProcessDHCPSettings
fi
}
+# Install the logrotate script
installLogrotate() {
- # Install the logrotate script
+
local str="Installing latest logrotate script"
echo ""
echo -ne " ${INFO} ${str}..."
+ # Copy the file over from the local repo
cp ${PI_HOLE_LOCAL_REPO}/advanced/logrotate /etc/pihole/logrotate
# Different operating systems have different user / group
# settings for logrotate that makes it impossible to create
@@ -1143,49 +1532,67 @@ installLogrotate() {
# customize the logrotate script here in order to reflect
# the local properties of the /var/log directory
logusergroup="$(stat -c '%U %G' /var/log)"
+ # If the variable has a value,
if [[ ! -z $logusergroup ]]; then
+ #
sed -i "s/# su #/su ${logusergroup}/g;" /etc/pihole/logrotate
fi
echo -e "${OVER} ${TICK} ${str}"
}
+# Install base files and web interface
installPihole() {
- # Install base files and web interface
+ # Create the pihole user
create_pihole_user
+ # If the user wants to install the Web interface,
if [[ ${INSTALL_WEB} == true ]]; then
if [ ! -d "/var/www/html" ]; then
+ # make the Web directory if necessary
mkdir -p /var/www/html
fi
+ # Set the owner and permissions
chown ${LIGHTTPD_USER}:${LIGHTTPD_GROUP} /var/www/html
chmod 775 /var/www/html
+ # Give pihole access to the Web server group
usermod -a -G ${LIGHTTPD_GROUP} pihole
+ # If the lighttpd command is executable,
if [ -x "$(command -v lighty-enable-mod)" ]; then
+ # enable fastcgi and fastcgi-php
lighty-enable-mod fastcgi fastcgi-php > /dev/null || true
else
+ # Othweise, show info about installing them
echo -e " ${INFO} Warning: 'lighty-enable-mod' utility not found
Please ensure fastcgi is enabled if you experience issues\n"
fi
fi
+ # Install scripts,
installScripts
+ # configs,
installConfigs
+ # and create the log file
CreateLogFile
+ # If the user wants to install the dashboard,
if [[ ${INSTALL_WEB} == true ]]; then
+ # do so
installPiholeWeb
fi
+ # Install the cron file
installCron
+ # Install the logrotate file
installLogrotate
+ # Check if FTL is installed
FTLdetect || echo -e " ${CROSS} FTL Engine not installed."
+ # Configure the firewall
configureFirewall
+ # Run the final exports
finalExports
#runGravity
}
+# At some point in the future this list can be pruned, for now we'll need it to ensure updates don't break.
+# Refactoring of install script has changed the name of a couple of variables. Sort them out here.
accountForRefactor() {
- # At some point in the future this list can be pruned, for now we'll need it to ensure updates don't break.
-
- # Refactoring of install script has changed the name of a couple of variables. Sort them out here.
-
sed -i 's/piholeInterface/PIHOLE_INTERFACE/g' ${setupVars}
sed -i 's/IPv4_address/IPV4_ADDRESS/g' ${setupVars}
sed -i 's/IPv4addr/IPV4_ADDRESS/g' ${setupVars}
@@ -1193,34 +1600,44 @@ accountForRefactor() {
sed -i 's/piholeIPv6/IPV6_ADDRESS/g' ${setupVars}
sed -i 's/piholeDNS1/PIHOLE_DNS_1/g' ${setupVars}
sed -i 's/piholeDNS2/PIHOLE_DNS_2/g' ${setupVars}
-
}
updatePihole() {
accountForRefactor
# Install base files and web interface
installScripts
+ # Install config files
installConfigs
+ # Create the log file
CreateLogFile
+ # If the user wants to install the dasboard,
if [[ ${INSTALL_WEB} == true ]]; then
+ # do so
installPiholeWeb
fi
+ # Install the cron file
installCron
+ # Install logrotate
installLogrotate
+ # Detect if FTL is installed
FTLdetect || echo -e " ${CROSS} FTL Engine not installed."
finalExports #re-export setupVars.conf to account for any new vars added in new versions
#runGravity
}
-
+# SELinux
checkSelinux() {
+ # If the getenforce command exists,
if command -v getenforce &> /dev/null; then
echo ""
echo -ne " ${INFO} SELinux Support Detected... Mode: "
+ # Store the current mode in a variable
enforceMode=$(getenforce)
echo "${enforceMode}"
+ # If it's enforcing,
if [[ "${enforceMode}" == "Enforcing" ]]; then
+ # Explain Pi-hole does not support it yet
whiptail --title "SELinux Enforcing Detected" --yesno "SELinux is being Enforced on your system!\n\nPi-hole currently does not support SELinux, but you may still continue with the installation.\n\nNote: Admin UI Will not function fully without setting your policies correctly\n\nContinue installing Pi-hole?" ${r} ${c} || \
{ echo ""; echo -e " ${COL_LIGHT_RED}SELinux Enforcing detected, exiting installer${COL_NC}"; exit 1; }
echo ""
@@ -1230,17 +1647,22 @@ checkSelinux() {
fi
}
+# Installation complete message with instructions for the user
displayFinalMessage() {
-
+ # If
if [[ ${#1} -gt 0 ]] ; then
pwstring="$1"
+ # else, if the dashboard password in the setup variables exists,
elif [[ $(grep 'WEBPASSWORD' -c /etc/pihole/setupVars.conf) -gt 0 ]]; then
+ # set a variable for evaluation later
pwstring="unchanged"
else
+ # set a variable for evaluation later
pwstring="NOT SET"
fi
-
+ # If the user wants to install the dashboard,
if [[ ${INSTALL_WEB} == true ]]; then
+ # Store a message in a variable and display it
additional="View the web interface at http://pi.hole/admin or http://${IPV4_ADDRESS%/*}/admin
Your Admin Webpage login password is ${pwstring}"
@@ -1260,12 +1682,15 @@ ${additional}" ${r} ${c}
}
update_dialogs() {
- # reconfigure
+ # If pihole -r "reconfigure" option was selected,
if [ "${reconfigure}" = true ]; then
+ # set some variables that will be used
opt1a="Repair"
opt1b="This will retain existing settings"
strAdd="You will remain on the same version"
+ # Othweise,
else
+ # set some variables with different values
opt1a="Update"
opt1b="This will retain existing settings."
strAdd="You will be updated to the latest version."
@@ -1273,16 +1698,20 @@ update_dialogs() {
opt2a="Reconfigure"
opt2b="This will allow you to enter new settings"
+ # Display the information to the user
UpdateCmd=$(whiptail --title "Existing Install Detected!" --menu "\n\nWe have detected an existing install.\n\nPlease choose from the following options: \n($strAdd)" ${r} ${c} 2 \
"${opt1a}" "${opt1b}" \
"${opt2a}" "${opt2b}" 3>&2 2>&1 1>&3) || \
{ echo -e " ${COL_LIGHT_RED}Cancel was selected, exiting installer${COL_NC}"; exit 1; }
+ # Set the variable based on if the user user chooses
case ${UpdateCmd} in
+ # repair, or
${opt1a})
echo -e " ${INFO} ${opt1a} option selected."
useUpdateVars=true
;;
+ # recongigure,
${opt2a})
echo -e " ${INFO} ${opt2a} option selected"
useUpdateVars=false
@@ -1290,27 +1719,34 @@ update_dialogs() {
esac
}
+
clone_or_update_repos() {
+ # If the user wants to reconfigure,
if [[ "${reconfigure}" == true ]]; then
echo " ${INFO} Performing reconfiguration, skipping download of local repos"
+ # Reset the Core repo
resetRepo ${PI_HOLE_LOCAL_REPO} || \
{ echo -e " ${COL_LIGHT_RED}Unable to reset ${PI_HOLE_LOCAL_REPO}, exiting installer${COL_NC}"; \
exit 1; \
}
+ # If the Web interface was installed,
if [[ ${INSTALL_WEB} == true ]]; then
+ # reset it's repo
resetRepo ${webInterfaceDir} || \
{ echo -e " ${COL_LIGHT_RED}Unable to reset ${webInterfaceDir}, exiting installer${COL_NC}"; \
exit 1; \
}
fi
+ # Otherwise, a repair is happening
else
- # Get Git files for Core and Admin
+ # so get git files for Core
getGitFiles ${PI_HOLE_LOCAL_REPO} ${piholeGitUrl} || \
{ echo "!!! Unable to clone ${piholeGitUrl} into ${PI_HOLE_LOCAL_REPO}, unable to continue."; \
exit 1; \
}
-
+ # If the Web interface was installed,
if [[ ${INSTALL_WEB} == true ]]; then
+ # get the Web git files
getGitFiles ${webInterfaceDir} ${webInterfaceGitUrl} || \
{ echo -e " ${COL_LIGHT_RED}Unable to clone ${webInterfaceGitUrl} into ${webInterfaceDir}, exiting installer${COL_NC}"; \
exit 1; \
@@ -1319,15 +1755,18 @@ clone_or_update_repos() {
fi
}
+# Download and install FTL binary
FTLinstall() {
- # Download and install FTL binary
+ # Local, named variables
local binary="${1}"
local latesttag
local orig_dir
local str="Installing FTL"
echo -ne " ${INFO} ${str}..."
+ # Get the current working directory
orig_dir="${PWD}"
+ # Find the latest version tag for FTL
latesttag=$(curl -sI https://github.com/pi-hole/FTL/releases/latest | grep "Location" | awk -F '/' '{print $NF}')
# Tags should always start with v, check for that.
if [[ ! "${latesttag}" == v* ]]; then
@@ -1335,71 +1774,98 @@ FTLinstall() {
echo -e " ${COL_LIGHT_RED}Error: Unable to get latest release location from GitHub${COL_NC}"
return 1
fi
+ # If the download worked,
if curl -sSL --fail "https://github.com/pi-hole/FTL/releases/download/${latesttag%$'\r'}/${binary}" -o "/tmp/${binary}"; then
- # Get sha1 of the binary we just downloaded for verification.
+ # get sha1 of the binary we just downloaded for verification.
curl -sSL --fail "https://github.com/pi-hole/FTL/releases/download/${latesttag%$'\r'}/${binary}.sha1" -o "/tmp/${binary}.sha1"
- # Check if we just downloaded text, or a binary file.
+
+ # Move into the temp directory
cd /tmp
+ # If we downloaded binary file (as opposed to text),
if sha1sum --status --quiet -c "${binary}".sha1; then
echo -n "transferred... "
+ # Stop FTL
stop_service pihole-FTL &> /dev/null
+ # Install the new version with the correct permissions
install -T -m 0755 /tmp/${binary} /usr/bin/pihole-FTL
+ # Remove the tempoary file
rm /tmp/${binary} /tmp/${binary}.sha1
+ # Move back into the original directory the user was in
cd "${orig_dir}"
+ # Install the FTL service
install -T -m 0755 "${PI_HOLE_LOCAL_REPO}/advanced/pihole-FTL.service" "/etc/init.d/pihole-FTL"
echo -e "${OVER} ${TICK} ${str}"
return 0
+ # Otherise,
else
echo -e "${OVER} ${CROSS} ${str}"
echo -e " ${COL_LIGHT_RED}Error: Download of binary from Github failed${COL_NC}"
+ # the download failed, so just go back to the original directory
cd "${orig_dir}"
return 1
fi
+ # Otherwise,
else
cd "${orig_dir}"
echo -e "${OVER} ${CROSS} ${str}"
+ # The URL could not be found
echo -e " ${COL_LIGHT_RED}Error: URL not found${COL_NC}"
fi
}
+# Detect suitable FTL binary platform
FTLdetect() {
- # Detect suitable FTL binary platform
echo ""
echo -e " ${INFO} Downloading latest version of FTL..."
+ # Local, named variables
local machine
local binary
+ # Store architecture in a variable
machine=$(uname -m)
local str="Detecting architecture"
echo -ne " ${INFO} ${str}..."
+ # If the machine is arm or aarch
if [[ ${machine} == arm* || ${machine} == *aarch* ]]; then
# ARM
+ #
local rev=$(uname -m | sed "s/[^0-9]//g;")
+ #
local lib=$(ldd /bin/ls | grep -E '^\s*/lib' | awk '{ print $1 }')
+ #
if [[ "$lib" == "/lib/ld-linux-aarch64.so.1" ]]; then
echo -e "${OVER} ${TICK} Detected ARM-aarch64 architecture"
+ # set the binary to be used
binary="pihole-FTL-aarch64-linux-gnu"
+ #
elif [[ "$lib" == "/lib/ld-linux-armhf.so.3" ]]; then
+ #
if [ "$rev" -gt "6" ]; then
echo -e "${OVER} ${TICK} Detected ARM-hf architecture (armv7+)"
+ # set the binary to be used
binary="pihole-FTL-arm-linux-gnueabihf"
+ # Otherwise,
else
echo -e "${OVER} ${TICK} Detected ARM-hf architecture (armv6 or lower) Using ARM binary"
+ # set the binary to be used
binary="pihole-FTL-arm-linux-gnueabi"
fi
else
echo -e "${OVER} ${TICK} Detected ARM architecture"
+ # set the binary to be used
binary="pihole-FTL-arm-linux-gnueabi"
fi
elif [[ $machine == ppc ]]; then
# PowerPC
echo "::: Detected PowerPC architecture"
+ # set the binary to be used
binary="pihole-FTL-powerpc-linux-gnu"
elif [[ ${machine} == x86_64 ]]; then
# 64bit
echo -e "${OVER} ${TICK} Detected x86_64 architecture"
+ # set the binary to be used
binary="pihole-FTL-linux-x86_64"
else
# Something else - we try to use 32bit executable and warn the user
@@ -1413,6 +1879,7 @@ FTLdetect() {
binary="pihole-FTL-linux-x86_32"
fi
+ # Install FTL
FTLinstall "${binary}" || return 1
}
@@ -1420,14 +1887,19 @@ FTLdetect() {
main() {
######## FIRST CHECK ########
- # Must be root to install
+ # Show the Pi-hole logo so people know it's genuine since the logo and name are trademarked
show_ascii_berry
+ # Must be root to install
local str="Root user check"
echo ""
+ # If the user's id is zero,
if [[ ${EUID} -eq 0 ]]; then
+ # they are root and all is good
echo -e " ${TICK} ${str}"
+ # Otherwise,
else
+ # They do not have enough privileges, so let the user know
echo -e " ${CROSS} ${str}
Script called with non-root privileges
The Pi-hole requires elevated privleges to install and run
@@ -1436,11 +1908,15 @@ main() {
echo ""
echo -ne " ${INFO} Sudo utility check"
+ # If the sudo command exists,
if command -v sudo &> /dev/null; then
echo -e "${OVER} ${TICK} Sudo utility check"
+ # Download the install script and run it with admin rights
exec curl -sSL https://raw.githubusercontent.com/pi-hole/pi-hole/master/automated%20install/basic-install.sh | sudo bash "$@"
exit $?
+ # Otherwise,
else
+ # Let them know they need to run it as root
echo -e "${OVER} ${CROSS} Sudo utility check
Sudo is needed for the Web Interface to run pihole commands\n
${COL_LIGHT_RED}Please re-run this installer as root${COL_NC}"
@@ -1460,11 +1936,16 @@ main() {
esac
done
+ # If the setup variable file exists,
if [[ -f ${setupVars} ]]; then
+ # if it's running unattended,
if [[ "${runUnattended}" == true ]]; then
echo -e " ${INFO} Performing unattended setup, no whiptail dialogs will be displayed"
+ # Use the setup variables
useUpdateVars=true
+ # Otherwise,
else
+ # show the available options (repair/reconfigure)
update_dialogs
fi
fi
@@ -1515,10 +1996,13 @@ main() {
# Clone/Update the repos
clone_or_update_repos
- # Install packages used by the Pi-hole
+ # Install packages used by the Pi-hole
if [[ ${INSTALL_WEB} == true ]]; then
+ # Install the Web dependencies
DEPS=("${PIHOLE_DEPS[@]}" "${PIHOLE_WEB_DEPS[@]}")
+ # Otherwise,
else
+ # just install the Core dependencies
DEPS=("${PIHOLE_DEPS[@]}")
fi
install_dependent_packages DEPS[@]
@@ -1535,8 +2019,11 @@ main() {
# Install packages used by the Pi-hole
if [[ ${INSTALL_WEB} == true ]]; then
+ # Install the Web dependencies
DEPS=("${PIHOLE_DEPS[@]}" "${PIHOLE_WEB_DEPS[@]}")
+ # Otherwise,
else
+ # just install the Core dependencies
DEPS=("${PIHOLE_DEPS[@]}")
fi
install_dependent_packages DEPS[@]
@@ -1550,7 +2037,9 @@ main() {
if [[ ${INSTALL_WEB} == true ]]; then
# Add password to web UI if there is none
pw=""
+ # If no password is set,
if [[ $(grep 'WEBPASSWORD' -c /etc/pihole/setupVars.conf) == 0 ]] ; then
+ # generate a random password
pw=$(tr -dc _A-Z-a-z-0-9 < /dev/urandom | head -c 8)
. /opt/pihole/webpage.sh
echo "WEBPASSWORD=$(HashPassword ${pw})" >> ${setupVars}
@@ -1562,46 +2051,61 @@ main() {
start_service dnsmasq
enable_service dnsmasq
+ # If the Web server was installed,
if [[ ${INSTALL_WEB} == true ]]; then
+ # enable it
start_service lighttpd
enable_service lighttpd
fi
+ # Download and compile the aggregated block list
runGravity
+ # Enable FTL
start_service pihole-FTL
enable_service pihole-FTL
+ #
if [[ "${useUpdateVars}" == false ]]; then
displayFinalMessage "${pw}"
fi
+ # If the Web interface was installed,
if [[ ${INSTALL_WEB} == true ]]; then
+ # If there is a password,
if (( ${#pw} > 0 )) ; then
+ # display the password
echo -e " ${INFO} Web Interface password: ${COL_LIGHT_GREEN}${pw}${COL_NC}
This can be changed using 'pihole -a -p'"
echo ""
fi
fi
+ #
if [[ "${useUpdateVars}" == false ]]; then
+ # If the Web interface was installed,
if [[ ${INSTALL_WEB} == true ]]; then
echo -e " View the web interface at http://pi.hole/admin or http://${IPV4_ADDRESS%/*}/admin"
echo ""
fi
+ # Explain to the user how to use Pi-hole as their DNS server
echo " You may now configure your devices to use the Pi-hole as their DNS server"
[[ -n "${IPV4_ADDRESS%/*}" ]] && echo -e " ${INFO} Pi-hole DNS (IPv4): ${IPV4_ADDRESS%/*}"
[[ -n "${IPV6_ADDRESS}" ]] && echo -e " ${INFO} Pi-hole DNS (IPv6): ${IPV6_ADDRESS}"
echo -e " If you set a new IP address, please restart the server running the Pi-hole"
+ #
INSTALL_TYPE="Installation"
else
+ #
INSTALL_TYPE="Update"
fi
+ # Display where the log file is
echo -e "\n ${INFO} The install log is located at: /etc/pihole/install.log
${COL_LIGHT_GREEN}${INSTALL_TYPE} Complete! ${COL_NC}"
}
+#
if [[ "${PH_TEST}" != true ]] ; then
main "$@"
fi
From 042dcf795c4c18b5e62dcea0d72f7ff275d7e3c3 Mon Sep 17 00:00:00 2001
From: Jacob Salmela
Date: Thu, 6 Jul 2017 20:44:40 -0500
Subject: [PATCH 122/162] fixes #1430
---
advanced/Scripts/webpage.sh | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)
diff --git a/advanced/Scripts/webpage.sh b/advanced/Scripts/webpage.sh
index a49d5283..c8a31f82 100755
--- a/advanced/Scripts/webpage.sh
+++ b/advanced/Scripts/webpage.sh
@@ -31,7 +31,7 @@ Options:
-k, kelvin Set Kelvin as preferred temperature unit
-h, --help Show this help dialog
-i, interface Specify dnsmasq's interface listening behavior
- Add '-h' for more info on interface usage"
+ Add '-h' for more info on interface usage"
exit 0
}
@@ -89,6 +89,9 @@ SetWebPassword() {
readonly PASSWORD="${args[2]}"
readonly CONFIRM="${PASSWORD}"
else
+ # Prevnts a bug if the user presses Ctrl+C and it continues to hide the text typed.
+ # So we reset the terminal via stty if the user does press Ctrl+C
+ trap '{ echo "No password will be set" ; stty sane ; exit 1; }' INT
read -s -p "Enter New Password (Blank for no password): " PASSWORD
echo ""
@@ -225,7 +228,7 @@ RestartDNS() {
else
service dnsmasq restart
fi
-
+
if [[ "$?" == 0 ]]; then
echo -e "${OVER} ${TICK} ${str}"
else
@@ -402,7 +405,7 @@ SetHostRecord() {
SetListeningMode() {
source "${setupVars}"
-
+
if [[ "$3" == "-h" ]] || [[ "$3" == "--help" ]]; then
echo "Usage: pihole -a -i [interface]
Example: 'pihole -a -i local'
@@ -415,7 +418,7 @@ Interfaces:
all Listen on all interfaces, permit all origins"
exit 0
fi
-
+
if [[ "${args[2]}" == "all" ]]; then
echo -e " ${INFO} Listening on all interfaces, permiting all origins. Please use a firewall!"
change_setting "DNSMASQ_LISTENING" "all"
From fb66fb12c569987f19edf1cc0df1805131577584 Mon Sep 17 00:00:00 2001
From: Jacob Salmela
Date: Thu, 6 Jul 2017 20:54:09 -0500
Subject: [PATCH 123/162] put "no password will be set" on a newline.
---
advanced/Scripts/webpage.sh | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/advanced/Scripts/webpage.sh b/advanced/Scripts/webpage.sh
index c8a31f82..5aae18f7 100755
--- a/advanced/Scripts/webpage.sh
+++ b/advanced/Scripts/webpage.sh
@@ -89,9 +89,9 @@ SetWebPassword() {
readonly PASSWORD="${args[2]}"
readonly CONFIRM="${PASSWORD}"
else
- # Prevnts a bug if the user presses Ctrl+C and it continues to hide the text typed.
+ # Prevents a bug if the user presses Ctrl+C and it continues to hide the text typed.
# So we reset the terminal via stty if the user does press Ctrl+C
- trap '{ echo "No password will be set" ; stty sane ; exit 1; }' INT
+ trap '{ echo -e "\nNo password will be set" ; stty sane ; exit 1; }' INT
read -s -p "Enter New Password (Blank for no password): " PASSWORD
echo ""
From 2f939d8c56318ef71a4c8a2c62bc72369a4fce59 Mon Sep 17 00:00:00 2001
From: Jacob Salmela
Date: Fri, 7 Jul 2017 09:05:19 -0500
Subject: [PATCH 124/162] fix two spelling errors
---
automated install/basic-install.sh | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/automated install/basic-install.sh b/automated install/basic-install.sh
index 4a30461b..1d523214 100755
--- a/automated install/basic-install.sh
+++ b/automated install/basic-install.sh
@@ -125,7 +125,7 @@ show_ascii_berry() {
# Compatibility
distro_check() {
-# If apt-get is isntalled, then we know it's part of the Debian family
+# If apt-get is installed, then we know it's part of the Debian family
if command -v apt-get &> /dev/null; then
# Set some global variables here
# We don't set them earlier since the family might be Red Hat, so these values would be different
@@ -647,7 +647,7 @@ It is also possible to use a DHCP reservation, but if you are going to do that,
# dhcpcd is very annoying,
setDHCPCD() {
- # but we cab append these lines to dhcpcd.conf to enable a static IP
+ # but we can append these lines to dhcpcd.conf to enable a static IP
echo "interface ${PIHOLE_INTERFACE}
static ip_address=${IPV4_ADDRESS}
static routers=${IPv4gw}
From e7ad972783a99839378344be6ac82b307d4f4dfb Mon Sep 17 00:00:00 2001
From: Jacob Salmela
Date: Mon, 10 Jul 2017 14:12:30 -0500
Subject: [PATCH 125/162] fix thre spelling errors
---
automated install/basic-install.sh | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/automated install/basic-install.sh b/automated install/basic-install.sh
index 1d523214..419ad10e 100755
--- a/automated install/basic-install.sh
+++ b/automated install/basic-install.sh
@@ -155,7 +155,7 @@ if command -v apt-get &> /dev/null; then
phpVer="php5"
fi
- # Since our instal script is so large, we need several other programs to successfuly get a machine provisioned
+ # Since our install script is so large, we need several other programs to successfuly get a machine provisioned
# These programs are stored in an array so they can be looped through later
INSTALLER_DEPS=(apt-utils dialog debconf dhcpcd5 git ${iproute_pkg} whiptail)
# Pi-hole itself has several dependencies that also need to be installed
@@ -227,7 +227,7 @@ is_repo() {
# Use a named, local variable instead of the vague $1, which is the first arguement passed to this function
# These local variables should always be lowercase
local directory="${1}"
- # A local variabled for the current directory
+ # A local variable for the current directory
local curdir
# A variable to store the return code
local rc
@@ -1001,7 +1001,7 @@ version_check_dnsmasq() {
fi
}
-# Clean an exiting installation to prepare for upgrade/reinstall
+# Clean an existing installation to prepare for upgrade/reinstall
clean_existing() {
# Local, named variables
# ${1} Directory to clean
From 613f2d3b867c5efb580ba7c4e78c1bc96967d34f Mon Sep 17 00:00:00 2001
From: Jacob Salmela
Date: Tue, 11 Jul 2017 22:51:20 -0500
Subject: [PATCH 126/162] =?UTF-8?q?Pi-hole=20is=20now=20a=20registered=20t?=
=?UTF-8?q?rademark:=20replace=20=E2=84=A2=20with=20=C2=AE?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: Jacob Salmela
---
README.md | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/README.md b/README.md
index 6f8813fa..b2f3908f 100644
--- a/README.md
+++ b/README.md
@@ -8,9 +8,9 @@
-## The multi-platform, network-wide ad blocker
+## Pi-hole®: The multi-platform, network-wide ad blocker
-Block ads for **all** your devices _without_ the need to install client-side software. The Pi-hole™ blocks ads at the DNS-level, so all your devices are protected.
+Block ads for **all** your devices _without_ the need to install client-side software. The Pi-hole blocks ads at the DNS-level, so all your devices are protected.
- Web Browsers
- Cell Phones
@@ -53,9 +53,9 @@ wget -O basic-install.sh https://install.pi-hole.net
bash basic-install.sh
```
-Once installed, [configure your router to have **DHCP clients use the Pi as their DNS server**](https://discourse.pi-hole.net/t/how-do-i-configure-my-devices-to-use-pi-hole-as-their-dns-server/245) and then any device that connects to your network will have ads blocked without any further configuration. Alternatively, you can manually set each device to use Pi-hole™ as their DNS server.
+Once installed, [configure your router to have **DHCP clients use the Pi as their DNS server**](https://discourse.pi-hole.net/t/how-do-i-configure-my-devices-to-use-pi-hole-as-their-dns-server/245) and then any device that connects to your network will have ads blocked without any further configuration. Alternatively, you can manually set each device to use Pi-hole as their DNS server.
-## What is Pi-hole™ and how do I install it?
+## What is Pi-hole and how do I install it?
@@ -73,7 +73,7 @@ Once installed, [configure your router to have **DHCP clients use the Pi as thei
## Technical Details
-The Pi-hole™ is an **advertising-aware DNS/Web server**. If an ad domain is queried, a small Web page or GIF is delivered in place of the advertisement.
+The Pi-hole is an **advertising-aware DNS/Web server**. If an ad domain is queried, a small Web page or GIF is delivered in place of the advertisement.
### Gravity
@@ -102,7 +102,7 @@ Domains can be whitelisted and blacklisted using either the web interface or the
### Settings
-The settings page lets you control and configure your Pi-hole™. You can do things like:
+The settings page lets you control and configure your Pi-hole. You can do things like:
- enable Pi-hole's built-in DHCP server
- exclude domains from the graphs
@@ -113,7 +113,7 @@ The settings page lets you control and configure your Pi-hole™. You can do th
#### Built-in DHCP Server
-Pi-hole™ ships with a built-in DHCP server. This allows you to let your network devices use Pi-hole™ as their DNS server if your router does not let you adjust the DHCP options.
+Pi-hole ships with a built-in DHCP server. This allows you to let your network devices use Pi-hole as their DNS server if your router does not let you adjust the DHCP options.
@@ -137,7 +137,7 @@ The same output can be achieved on the CLI by running `chronometer.sh -j`
You can view [real-time stats](https://discourse.pi-hole.net/t/how-do-i-view-my-pi-holes-stats-over-ssh-or-on-an-lcd-using-chronometer/240) via `ssh` or on an [2.8" LCD screen](http://amzn.to/1P0q1Fj). This is accomplished via [`chronometer.sh`](https://github.com/pi-hole/pi-hole/blob/master/advanced/Scripts/chronometer.sh). ![Pi-hole LCD](http://i.imgur.com/nBEqycp.jpg)
-## Pi-hole™ Projects
+## Pi-hole Projects
- [An ad blocking Magic Mirror](https://zonksec.com/blog/magic-mirror-dns-filtering/#dnssoftware)
- [Pi-hole stats in your Mac's menu bar](https://getbitbar.com/plugins/Network/pi-hole.1m.py)
From 38d213ee6cdb02cc8667c4dd5c1f3a3cd6db7f24 Mon Sep 17 00:00:00 2001
From: Jacob Salmela
Date: Tue, 11 Jul 2017 22:55:50 -0500
Subject: [PATCH 127/162] add section about additional ways to support us
Signed-off-by: Jacob Salmela
---
README.md | 3 +++
1 file changed, 3 insertions(+)
diff --git a/README.md b/README.md
index b2f3908f..a1d69a78 100644
--- a/README.md
+++ b/README.md
@@ -29,6 +29,9 @@ Digital Ocean helps with our infrastructure, but our developers are all voluntee
- ![Paypal](https://assets.pi-hole.net/static/paypal.png) [Donate via PayPal](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=3J2L3Z4DHW9UY)
- ![Bitcoin](https://assets.pi-hole.net/static/Bitcoin.png) Bitcoin Address: 1GKnevUnVaQM2pQieMyeHkpr8DXfkpfAtL
+### Other Ways To Support Us
+If you're not the type to give away money, there are [other ways support us](https://pi-hole.net/donate): you can sign up for services through our affiliate links, which will also help us offset some of the costs associated with keeping Pi-hole operational.
+
### One-Step Automated Install
1. Install a [supported operating system](https://discourse.pi-hole.net/t/hardware-software-requirements/273/1)
2. Run the command below (it downloads [this script](https://github.com/pi-hole/pi-hole/blob/master/automated%20install/basic-install.sh) in case you want to read over it first!)
From 527fe2f5e176e0c185f01996d38e6568c97f7b2d Mon Sep 17 00:00:00 2001
From: Jacob Salmela
Date: Tue, 11 Jul 2017 23:06:42 -0500
Subject: [PATCH 128/162] wordsmithing using Pi-hole as your DNS server,
gravity, and additional blocklists.
Signed-off-by: Jacob Salmela
---
README.md | 14 +++++++++++---
1 file changed, 11 insertions(+), 3 deletions(-)
diff --git a/README.md b/README.md
index a1d69a78..d4744972 100644
--- a/README.md
+++ b/README.md
@@ -56,7 +56,11 @@ wget -O basic-install.sh https://install.pi-hole.net
bash basic-install.sh
```
-Once installed, [configure your router to have **DHCP clients use the Pi as their DNS server**](https://discourse.pi-hole.net/t/how-do-i-configure-my-devices-to-use-pi-hole-as-their-dns-server/245) and then any device that connects to your network will have ads blocked without any further configuration. Alternatively, you can manually set each device to use Pi-hole as their DNS server.
+Once installed, [configure your router to have **DHCP clients use the Pi-hole as their DNS server**](https://discourse.pi-hole.net/t/how-do-i-configure-my-devices-to-use-pi-hole-as-their-dns-server/245) and then any device that connects to your network will have ads blocked without any further configuration.
+
+If your router does not support setting the DNS server, you can [use Pi-hole's built in DHCP server](https://discourse.pi-hole.net/t/how-do-i-use-pi-holes-built-in-dhcp-server-and-why-would-i-want-to/3026); just be sure to disable DHCP on your router first.
+
+Alternatively, you can manually set each device to use Pi-hole as their DNS server.
## What is Pi-hole and how do I install it?
@@ -68,6 +72,7 @@ Once installed, [configure your router to have **DHCP clients use the Pi as thei
- [Users Forum](https://discourse.pi-hole.net/)
- [FAQs](https://discourse.pi-hole.net/c/faqs)
+- [Feature requests](https://discourse.pi-hole.net/c/feature-requests?order=votes)
- [Wiki](https://github.com/pi-hole/pi-hole/wiki)
- ![Twitter](https://assets.pi-hole.net/static/twitter.png) [Tweet @The_Pi_Hole](https://twitter.com/The_Pi_Hole)
- ![Reddit](https://assets.pi-hole.net/static/reddit.png) [Reddit /r/pihole](https://www.reddit.com/r/pihole/)
@@ -78,9 +83,12 @@ Once installed, [configure your router to have **DHCP clients use the Pi as thei
The Pi-hole is an **advertising-aware DNS/Web server**. If an ad domain is queried, a small Web page or GIF is delivered in place of the advertisement.
-### Gravity
+### Gravity: Finding Ads To Block
-The [gravity.sh](https://github.com/pi-hole/pi-hole/blob/master/gravity.sh) does most of the magic. The script pulls in ad domains from many sources and compiles them into a single list of [over 1.6 million entries](http://jacobsalmela.com/block-millions-ads-network-wide-with-a-raspberry-pi-hole-2-0) (if you decide to use the [mahakala list](https://github.com/pi-hole/pi-hole/commit/963eacfe0537a7abddf30441c754c67ca1e40965)). This script is controlled by the `pihole` command. Please run `pihole -h` to see what commands can be run via `pihole`.
+The [gravity.sh](https://github.com/pi-hole/pi-hole/blob/master/gravity.sh) script does most of the magic. The script pulls in over 100,000 known ad-serving domains from many sources and aggregates them into a single list.
+
+#### Additional Blocklists
+You can also use Pi-hole to block additional domains beyond the defaults. It can even be used to block malware or phising domains. [The Big Blocklist Collection](https://wally3k.github.io/) is a good resource for finding additional domains to block.
From e5e26413e98c106eee52fcca4134e280b03bb39c Mon Sep 17 00:00:00 2001
From: Jacob Salmela
Date: Tue, 11 Jul 2017 23:28:47 -0500
Subject: [PATCH 129/162] new executive summary above the fold
Signed-off-by: Jacob Salmela
---
README.md | 22 +++++++++++++++-------
1 file changed, 15 insertions(+), 7 deletions(-)
diff --git a/README.md b/README.md
index d4744972..7782dc54 100644
--- a/README.md
+++ b/README.md
@@ -10,18 +10,26 @@
## Pi-hole®: The multi-platform, network-wide ad blocker
-Block ads for **all** your devices _without_ the need to install client-side software. The Pi-hole blocks ads at the DNS-level, so all your devices are protected.
-
-- Web Browsers
-- Cell Phones
-- Smart TV's
-- Internet-connected home automation
-- Anything that communicates with the Internet
+Block ads for **all** your devices _without_ the need to install client-side software.
+## Executive Summary
+The Pi-hole blocks ads at the DNS-level, so all your devices are protected.
+
+- **Easy-to-install** - our intelligent installer walks you through the process with no additional software needed on client devices
+- **Universal** - ads are blocked in _non-browser locations_ such as ad-supported mobile apps and smart TVs
+- **Quick** - installation takes less than ten minutes and it [_really_ is _that easy_](https://discourse.pi-hole.net/t/new-pi-hole-questions/3971/5?u=jacob.salmela)
+- **Informative** - an administrative Web interface shows ad-blocking statistics
+- **Lightweight** - designed to run on [minimal resources](https://discourse.pi-hole.net/t/hardware-software-requirements/273)
+- **Scalable** - even in large environments, [Pi-hole can handle hundreds of millions of queries](https://pi-hole.net/2017/05/24/how-much-traffic-can-pi-hole-handle/) (with the right hardware specs)
+- **Powerful** - advertisements are blocked over IPv4 _and_ IPv6
+- **Fast** - it speeds up high-cost, high-latency networks by caching DNS queries and saves bandwidth by not downloading advertisement elements
+- **Versatile** - Pi-hole can function also function as a DHCP server
+
+
## Your Support Still Matters
Digital Ocean helps with our infrastructure, but our developers are all volunteers so *your donations help keep us innovating*. Sending a donation using our links below helps us offset a portion of our monthly costs.
From fbd55dd74058a385edd881133672469b99dbc811 Mon Sep 17 00:00:00 2001
From: Jacob Salmela
Date: Tue, 11 Jul 2017 23:33:49 -0500
Subject: [PATCH 130/162] tweaks to donation verbiage
Signed-off-by: Jacob Salmela
---
README.md | 19 +++++++++----------
1 file changed, 9 insertions(+), 10 deletions(-)
diff --git a/README.md b/README.md
index 7782dc54..5199e534 100644
--- a/README.md
+++ b/README.md
@@ -29,27 +29,26 @@ The Pi-hole blocks ads at the DNS-level, so all your devices are protected.
- **Fast** - it speeds up high-cost, high-latency networks by caching DNS queries and saves bandwidth by not downloading advertisement elements
- **Versatile** - Pi-hole can function also function as a DHCP server
+# Pi-hole Is Free, But Powered By Your Donations
-## Your Support Still Matters
-
-Digital Ocean helps with our infrastructure, but our developers are all volunteers so *your donations help keep us innovating*. Sending a donation using our links below helps us offset a portion of our monthly costs.
+[Digital Ocean](http://www.digitalocean.com/?refcode=344d234950e1) helps with our infrastructure, but [our developers](https://github.com/orgs/pi-hole/people) are all volunteers so *your donations help keep us innovating*.
- ![Paypal](https://assets.pi-hole.net/static/paypal.png) [Donate via PayPal](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=3J2L3Z4DHW9UY)
- ![Bitcoin](https://assets.pi-hole.net/static/Bitcoin.png) Bitcoin Address: 1GKnevUnVaQM2pQieMyeHkpr8DXfkpfAtL
-### Other Ways To Support Us
-If you're not the type to give away money, there are [other ways support us](https://pi-hole.net/donate): you can sign up for services through our affiliate links, which will also help us offset some of the costs associated with keeping Pi-hole operational.
+## Other Ways To Support Us
+If you'd rather not send money, there are [other ways to support us](https://pi-hole.net/donate): you can sign up for services through our affiliate links, which will also help us offset some of the costs associated with keeping Pi-hole operational.
-### One-Step Automated Install
+# One-Step Automated Install
1. Install a [supported operating system](https://discourse.pi-hole.net/t/hardware-software-requirements/273/1)
2. Run the command below (it downloads [this script](https://github.com/pi-hole/pi-hole/blob/master/automated%20install/basic-install.sh) in case you want to read over it first!)
-### `curl -sSL https://install.pi-hole.net | bash`
+#### `curl -sSL https://install.pi-hole.net | bash`
-#### Alternative Semi-Automated Install Methods
+## Alternative Semi-Automated Install Methods
_If you wish to read over the script before running it, run `nano basic-install.sh` to open the file in a text viewer._
-##### Clone our repository and run the automated installer from your device.
+### Clone our repository and run the automated installer from your device.
```
git clone --depth 1 https://github.com/pi-hole/pi-hole.git Pi-hole
@@ -70,7 +69,7 @@ If your router does not support setting the DNS server, you can [use Pi-hole's b
Alternatively, you can manually set each device to use Pi-hole as their DNS server.
-## What is Pi-hole and how do I install it?
+# What is Pi-hole and how do I install it?
From 9348a8ab15f5dcd0c1b7d927ee70cbcbdb77d7bd Mon Sep 17 00:00:00 2001
From: Jacob Salmela
Date: Tue, 11 Jul 2017 23:36:40 -0500
Subject: [PATCH 131/162] move technical details to the bottom of the page in
light of showing off Pi-holes features first.
Signed-off-by: Jacob Salmela
---
README.md | 60 ++++++++++++++++++++++++++++---------------------------
1 file changed, 31 insertions(+), 29 deletions(-)
diff --git a/README.md b/README.md
index 5199e534..7a4c58dd 100644
--- a/README.md
+++ b/README.md
@@ -74,36 +74,9 @@ Alternatively, you can manually set each device to use Pi-hole as their DNS serv
+# Overview Of Features
-## Get Help Or Connect With Us On The Web
-
-- [Users Forum](https://discourse.pi-hole.net/)
-- [FAQs](https://discourse.pi-hole.net/c/faqs)
-- [Feature requests](https://discourse.pi-hole.net/c/feature-requests?order=votes)
-- [Wiki](https://github.com/pi-hole/pi-hole/wiki)
-- ![Twitter](https://assets.pi-hole.net/static/twitter.png) [Tweet @The_Pi_Hole](https://twitter.com/The_Pi_Hole)
-- ![Reddit](https://assets.pi-hole.net/static/reddit.png) [Reddit /r/pihole](https://www.reddit.com/r/pihole/)
-- ![YouTube](https://assets.pi-hole.net/static/youtube.png) [Pi-hole channel](https://www.youtube.com/channel/UCT5kq9w0wSjogzJb81C9U0w)
-- [![Join the chat at https://gitter.im/pi-hole/pi-hole](https://badges.gitter.im/pi-hole/pi-hole.svg)](https://gitter.im/pi-hole/pi-hole?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
-
-## Technical Details
-
-The Pi-hole is an **advertising-aware DNS/Web server**. If an ad domain is queried, a small Web page or GIF is delivered in place of the advertisement.
-
-### Gravity: Finding Ads To Block
-
-The [gravity.sh](https://github.com/pi-hole/pi-hole/blob/master/gravity.sh) script does most of the magic. The script pulls in over 100,000 known ad-serving domains from many sources and aggregates them into a single list.
-
-#### Additional Blocklists
-You can also use Pi-hole to block additional domains beyond the defaults. It can even be used to block malware or phising domains. [The Big Blocklist Collection](https://wally3k.github.io/) is a good resource for finding additional domains to block.
-
-
-
-#### Other Operating Systems
-
-The automated install is only for a clean install of a Debian family or Fedora based system, such as the Raspberry Pi. However, this script will work for most UNIX-like systems, some with some slight **modifications** that we can help you work through. If you can install `dnsmasq` and a web server, it should work OK. If there are other platforms you'd like supported, let us know.
-
-### Web Interface
+## The Dashboard (Web Interface)
The [Web interface](https://github.com/pi-hole/AdminLTE#pi-hole-admin-dashboard) will be installed automatically so you can view stats and change settings. You can find it at:
@@ -155,6 +128,35 @@ The same output can be achieved on the CLI by running `chronometer.sh -j`
You can view [real-time stats](https://discourse.pi-hole.net/t/how-do-i-view-my-pi-holes-stats-over-ssh-or-on-an-lcd-using-chronometer/240) via `ssh` or on an [2.8" LCD screen](http://amzn.to/1P0q1Fj). This is accomplished via [`chronometer.sh`](https://github.com/pi-hole/pi-hole/blob/master/advanced/Scripts/chronometer.sh). ![Pi-hole LCD](http://i.imgur.com/nBEqycp.jpg)
+## Get Help Or Connect With Us On The Web
+
+- [Users Forum](https://discourse.pi-hole.net/)
+- [FAQs](https://discourse.pi-hole.net/c/faqs)
+- [Feature requests](https://discourse.pi-hole.net/c/feature-requests?order=votes)
+- [Wiki](https://github.com/pi-hole/pi-hole/wiki)
+- ![Twitter](https://assets.pi-hole.net/static/twitter.png) [Tweet @The_Pi_Hole](https://twitter.com/The_Pi_Hole)
+- ![Reddit](https://assets.pi-hole.net/static/reddit.png) [Reddit /r/pihole](https://www.reddit.com/r/pihole/)
+- ![YouTube](https://assets.pi-hole.net/static/youtube.png) [Pi-hole channel](https://www.youtube.com/channel/UCT5kq9w0wSjogzJb81C9U0w)
+- [![Join the chat at https://gitter.im/pi-hole/pi-hole](https://badges.gitter.im/pi-hole/pi-hole.svg)](https://gitter.im/pi-hole/pi-hole?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
+
+## Technical Details
+
+The Pi-hole is an **advertising-aware DNS/Web server**. If an ad domain is queried, a small Web page or GIF is delivered in place of the advertisement.
+
+### Gravity: Finding Ads To Block
+
+The [gravity.sh](https://github.com/pi-hole/pi-hole/blob/master/gravity.sh) script does most of the magic. The script pulls in over 100,000 known ad-serving domains from many sources and aggregates them into a single list.
+
+#### Additional Blocklists
+You can also use Pi-hole to block additional domains beyond the defaults. It can even be used to block malware or phising domains. [The Big Blocklist Collection](https://wally3k.github.io/) is a good resource for finding additional domains to block.
+
+
+
+#### Other Operating Systems
+
+The automated install is only for a clean install of a Debian family or Fedora based system, such as the Raspberry Pi. However, this script will work for most UNIX-like systems, some with some slight **modifications** that we can help you work through. If you can install `dnsmasq` and a web server, it should work OK. If there are other platforms you'd like supported, let us know.
+
+
## Pi-hole Projects
- [An ad blocking Magic Mirror](https://zonksec.com/blog/magic-mirror-dns-filtering/#dnssoftware)
From 24df5f5208b1b55e94406ff8d3fac2af65e07acf Mon Sep 17 00:00:00 2001
From: Jacob Salmela
Date: Wed, 12 Jul 2017 00:36:12 -0500
Subject: [PATCH 132/162] describe settings page in the order they appear on
the dashboard--also add screenshots
Signed-off-by: Jacob Salmela
---
README.md | 100 ++++++++++++++++++++++++++++++++++++++++++++++--------
1 file changed, 86 insertions(+), 14 deletions(-)
diff --git a/README.md b/README.md
index 7a4c58dd..6b14b40b 100644
--- a/README.md
+++ b/README.md
@@ -78,31 +78,108 @@ Alternatively, you can manually set each device to use Pi-hole as their DNS serv
## The Dashboard (Web Interface)
-The [Web interface](https://github.com/pi-hole/AdminLTE#pi-hole-admin-dashboard) will be installed automatically so you can view stats and change settings. You can find it at:
+The [dashboard](https://github.com/pi-hole/AdminLTE#pi-hole-admin-dashboard) will (by default) be enabled during installation so you can view stats, change settings, and configure your Pi-hole.
-`http://192.168.1.x/admin/index.php` or `http://pi.hole/admin`
+![Pi-hole Dashboard](https://assets.pi-hole.net/static/dashboard.png)
-![Pi-hole Advanced Stats Dashboard](https://assets.pi-hole.net/static/dashboard212.png)
+There are several ways to [access the dashboard](https://discourse.pi-hole.net/t/how-do-i-access-pi-holes-dashboard-admin-interface/3168):
-### Whitelist and blacklist
+1. `http:///admin/`
+2. `http:/pi.hole/admin/` (when using Pi-hole as your DNS server)
+3. `http://pi.hole/` (when using Pi-hole as your DNS server)
+
+### The Query Log
+
+If enabled, the query log will show all of the DNS queries requested by clients using Pi-hole as their DNS server. Forwarded domains will show in green, and blocked (_Pi-holed_) domains will show in red. You can also white or black list domains from within this section.
-Domains can be whitelisted and blacklisted using either the web interface or the command line. See [the wiki page](https://github.com/pi-hole/pi-hole/wiki/Whitelisting-and-Blacklisting) for more details
-
+
+#### Long-term Statistics
+Using our Faster-Than-Light Engine ([FTL](https://github.com/pi-hole/FTL)), Pi-hole can store all of the domains queried in a database for retrieval or analysis later on. You can view this data as a graph, individual queries, or top clients/advertisers.
+
+
+
+
+
+### Whitelist And Blacklist
+
+Domains can be [whitelisted](https://discourse.pi-hole.net/t/commonly-whitelisted-domains/212) and/or [blacklisted](https://discourse.pi-hole.net/t/commonly-blacklisted-domains/305) using either the dashboard or [the `pihole` command](https://discourse.pi-hole.net/t/the-pihole-command-with-examples/738).
+
+
+
+
+
+#### Additional Blocklists
+By default, Pi-hole blocks over 100,000 known ad-serving domains. You can expand the blocking power of your Pi-hole by [adding additional lists](https://discourse.pi-hole.net/t/how-do-i-add-additional-block-lists-to-pi-hole/259) such as the ones found on [The Big Blocklist Collection](https://wally3k.github.io/).
+
+
+
+
+
+### Enable And Disable Pi-hole
+Sometimes you may want to stop using Pi-hole or turn it back on. You can trigger this via the dashboard or command line.
+
+
+
+
+
+### Tools
+
+
+
+
+
+
+#### Update Ad Lists
+This runs `gravity` to download any newly-added domains from your source lists.
+
+#### Query Ad Lists
+You can find out what list a certain domain was on. This is useful for troubleshooting sites that may not work properly due to a blocked domain.
+
+#### `tail`ing Log Files
+You can watch the log files in real time to help debug any issues, or just see what's happening with your Pi-hole.
+
+#### Pi-hole Debugger
+If you are having trouble with your Pi-hole, this is the place to go. You can run the debugger and it will attempt to diagnose any issues and then link to an FAQ with instructions on rectifying the problem.
+
+
+
+
+
+If run [via the command line](https://discourse.pi-hole.net/t/the-pihole-command-with-examples/738#debug), you will see red/yellow/green text, which makes it easy to identify any problems.
+
+
+
+
+
+
+After the debugger has finished, you have the option to upload it to our secure server for 48 hours. All you need to do then is provide one of our developers the unique token generated by the debugger (this is usually done via [our forums](https://discourse.pi-hole.net/c/bugs-problems-issues)).
+
+
+
+
+
+However, most of the time, you will be able to solve any issues without any intervention from us. But if you can't, we're always around to help out.
+
### Settings
The settings page lets you control and configure your Pi-hole. You can do things like:
+- view networking information
+- flush logs or disable the logging of queries
- enable Pi-hole's built-in DHCP server
-- exclude domains from the graphs
+- manage block lists
+- exclude domains from the graphs and enable privacy options
- configure upstream DNS servers
+- restart Pi-hole's services
+- back up some of Pi-hole's important files
- and more!
-![Settings page](https://assets.pi-hole.net/static/settings212.png)
+![Settings page](https://assets.pi-hole.net/static/settings-page.png)
-#### Built-in DHCP Server
+## Built-in DHCP Server
Pi-hole ships with a built-in DHCP server. This allows you to let your network devices use Pi-hole as their DNS server if your router does not let you adjust the DHCP options.
@@ -147,11 +224,6 @@ The Pi-hole is an **advertising-aware DNS/Web server**. If an ad domain is queri
The [gravity.sh](https://github.com/pi-hole/pi-hole/blob/master/gravity.sh) script does most of the magic. The script pulls in over 100,000 known ad-serving domains from many sources and aggregates them into a single list.
-#### Additional Blocklists
-You can also use Pi-hole to block additional domains beyond the defaults. It can even be used to block malware or phising domains. [The Big Blocklist Collection](https://wally3k.github.io/) is a good resource for finding additional domains to block.
-
-
-
#### Other Operating Systems
The automated install is only for a clean install of a Debian family or Fedora based system, such as the Raspberry Pi. However, this script will work for most UNIX-like systems, some with some slight **modifications** that we can help you work through. If you can install `dnsmasq` and a web server, it should work OK. If there are other platforms you'd like supported, let us know.
From 03387391def4e473faf670e85f67752e617627aa Mon Sep 17 00:00:00 2001
From: Jacob Salmela
Date: Wed, 12 Jul 2017 00:53:14 -0500
Subject: [PATCH 133/162] wordsmith DHCP server section, API section, and
chronometer2 section. Also add more images
Signed-off-by: Jacob Salmela
---
README.md | 64 ++++++++++++++++++++++++++++++++++++++++++++-----------
1 file changed, 51 insertions(+), 13 deletions(-)
diff --git a/README.md b/README.md
index 6b14b40b..36fc5312 100644
--- a/README.md
+++ b/README.md
@@ -181,31 +181,69 @@ The settings page lets you control and configure your Pi-hole. You can do thing
## Built-in DHCP Server
-Pi-hole ships with a built-in DHCP server. This allows you to let your network devices use Pi-hole as their DNS server if your router does not let you adjust the DHCP options.
+Pi-hole ships with a [built-in DHCP server](https://discourse.pi-hole.net/t/how-do-i-use-pi-holes-built-in-dhcp-server-and-why-would-i-want-to/3026). This allows you to let your network devices use Pi-hole as their DNS server if your router does not let you adjust the DHCP options.
+
+One nice feature of using Pi-hole's DHCP server if you can set hostnames and DHCP reservations so you'll [see hostnames in the query log instead of IP addresses](https://discourse.pi-hole.net/t/how-do-i-show-hostnames-instead-of-ip-addresses-in-the-dashboard/3530). You can still do this without using Pi-hole's DHCP server; it just takes a little more work. If you do plan to use Pi-hole's DHCP server, be sure to disable DHCP on your router first.
+
-
+
-## API
-
-A basic read-only API can be accessed at `/admin/api.php`. It returns the following JSON:
+## The FTL Engine: Our API
+A read-only API can be accessed at `admin/api.php`. It returns the following JSON:
``` json
{
- "domains_being_blocked": "136708",
- "dns_queries_today": "18108",
- "ads_blocked_today": "14648",
- "ads_percentage_today": "80.89"
-}
+ "domains_being_blocked":111175,
+ "dns_queries_today":15669,
+ "ads_blocked_today":1752,
+ "ads_percentage_today":11.181314,
+ "unique_domains":1178,
+ "queries_forwarded":9177,
+ "queries_cached":4740,
+ "unique_clients":18
+ }
```
+More details on the API can be found [here](https://discourse.pi-hole.net/t/pi-hole-api/1863) and on [the repo itself](https://github.com/pi-hole/FTL).
The same output can be achieved on the CLI by running `chronometer.sh -j`
-## Real-time Statistics
+### Real-time Statistics, Courtesy Of The Time Cops
-You can view [real-time stats](https://discourse.pi-hole.net/t/how-do-i-view-my-pi-holes-stats-over-ssh-or-on-an-lcd-using-chronometer/240) via `ssh` or on an [2.8" LCD screen](http://amzn.to/1P0q1Fj). This is accomplished via [`chronometer.sh`](https://github.com/pi-hole/pi-hole/blob/master/advanced/Scripts/chronometer.sh). ![Pi-hole LCD](http://i.imgur.com/nBEqycp.jpg)
+Using [chronometer2](https://github.com/pi-hole/pi-hole/blob/master/advanced/Scripts/chronometer.sh), you can view [real-time stats](https://discourse.pi-hole.net/t/how-do-i-view-my-pi-holes-stats-over-ssh-or-on-an-lcd-using-chronometer/240) via `ssh` or on an LCD screen such as the [2.8" LCD screen from Adafruit](http://amzn.to/1P0q1Fj).
-## Get Help Or Connect With Us On The Web
+Simply run `pihole -c` for some detailed information.
+```
+|¯¯¯(¯)__|¯|_ ___|¯|___ Pi-hole: v3.2
+| ¯_/¯|__| ' \/ _ \ / -_) AdminLTE: v3.2
+|_| |_| |_||_\___/_\___| FTL: v2.10
+ ——————————————————————————————————————————————————————————
+ Hostname: pihole (Raspberry Pi 1, Model B)
+ Uptime: 11 days, 12:55:01
+ Task Load: 0.35 0.16 0.15 (Active: 5 of 33 tasks)
+ CPU usage: 48% (1 core @ 700 MHz, 47c)
+ RAM usage: 12% (Used: 54 MB of 434 MB)
+ HDD usage: 20% (Used: 1 GB of 7 GB)
+ LAN addr: 192.168.1.100 (Gateway: 192.168.1.1)
+ Pi-hole: Active (Blocking: 111175 sites)
+ Ads Today: 11% (1759 of 15812 queries)
+ Fwd DNS: 208.67.222.222 (Alt DNS: 3 others)
+ ——————————————————————————————————————————————————————————
+ Recently blocked: www.google-analytics.com
+ Top Advertiser: www.example.org
+ Top Domain: www.example.org
+ Top Client: somehost
+```
+
+
+
+
+
+
+
+
+
+# Get Help Or Connect With Us On The Web
- [Users Forum](https://discourse.pi-hole.net/)
- [FAQs](https://discourse.pi-hole.net/c/faqs)
From f4c7d389e5926903c90652d3adc3654fc1f1ef71 Mon Sep 17 00:00:00 2001
From: Jacob Salmela
Date: Wed, 12 Jul 2017 01:03:09 -0500
Subject: [PATCH 134/162] more wordsmithing and updating links
Signed-off-by: Jacob Salmela
---
README.md | 32 ++++++++++++++------------------
1 file changed, 14 insertions(+), 18 deletions(-)
diff --git a/README.md b/README.md
index 36fc5312..2c95e0b3 100644
--- a/README.md
+++ b/README.md
@@ -169,15 +169,18 @@ The settings page lets you control and configure your Pi-hole. You can do thing
- view networking information
- flush logs or disable the logging of queries
-- enable Pi-hole's built-in DHCP server
-- manage block lists
+- [enable Pi-hole's built-in DHCP server](https://discourse.pi-hole.net/t/how-do-i-use-pi-holes-built-in-dhcp-server-and-why-would-i-want-to/3026)
+- [manage block lists](https://discourse.pi-hole.net/t/how-do-i-add-additional-block-lists-to-pi-hole/259)
- exclude domains from the graphs and enable privacy options
- configure upstream DNS servers
- restart Pi-hole's services
- back up some of Pi-hole's important files
- and more!
-![Settings page](https://assets.pi-hole.net/static/settings-page.png)
+
+
+
+
## Built-in DHCP Server
@@ -191,7 +194,9 @@ One nice feature of using Pi-hole's DHCP server if you can set hostnames and DHC
## The FTL Engine: Our API
-A read-only API can be accessed at `admin/api.php`. It returns the following JSON:
+A read-only API can be accessed at `admin/api.php` (the same output can be achieved on the CLI by running `pihole -c -j`).
+
+It returns the following JSON:
``` json
{
"domains_being_blocked":111175,
@@ -204,9 +209,8 @@ A read-only API can be accessed at `admin/api.php`. It returns the following JSO
"unique_clients":18
}
```
-More details on the API can be found [here](https://discourse.pi-hole.net/t/pi-hole-api/1863) and on [the repo itself](https://github.com/pi-hole/FTL).
-The same output can be achieved on the CLI by running `chronometer.sh -j`
+More details on the API can be found [here](https://discourse.pi-hole.net/t/pi-hole-api/1863) and on [the repo itself](https://github.com/pi-hole/FTL).
### Real-time Statistics, Courtesy Of The Time Cops
@@ -254,20 +258,12 @@ Simply run `pihole -c` for some detailed information.
- ![YouTube](https://assets.pi-hole.net/static/youtube.png) [Pi-hole channel](https://www.youtube.com/channel/UCT5kq9w0wSjogzJb81C9U0w)
- [![Join the chat at https://gitter.im/pi-hole/pi-hole](https://badges.gitter.im/pi-hole/pi-hole.svg)](https://gitter.im/pi-hole/pi-hole?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
-## Technical Details
+# Technical Details
-The Pi-hole is an **advertising-aware DNS/Web server**. If an ad domain is queried, a small Web page or GIF is delivered in place of the advertisement.
-
-### Gravity: Finding Ads To Block
-
-The [gravity.sh](https://github.com/pi-hole/pi-hole/blob/master/gravity.sh) script does most of the magic. The script pulls in over 100,000 known ad-serving domains from many sources and aggregates them into a single list.
-
-#### Other Operating Systems
-
-The automated install is only for a clean install of a Debian family or Fedora based system, such as the Raspberry Pi. However, this script will work for most UNIX-like systems, some with some slight **modifications** that we can help you work through. If you can install `dnsmasq` and a web server, it should work OK. If there are other platforms you'd like supported, let us know.
+To summarize into a short sentence, the Pi-hole is an **advertising-aware DNS/Web server**. And while quite outdated at this point, [this original blog post about Pi-hole](https://jacobsalmela.com/2015/06/16/block-millions-ads-network-wide-with-a-raspberry-pi-hole-2-0/) goes into **great detail** about how it was setup and how it works. Syntactically, it's no longer accurate, but the same basic principles and logic still apply to Pi-hole's current state.
-## Pi-hole Projects
+# Pi-hole Projects
- [An ad blocking Magic Mirror](https://zonksec.com/blog/magic-mirror-dns-filtering/#dnssoftware)
- [Pi-hole stats in your Mac's menu bar](https://getbitbar.com/plugins/Network/pi-hole.1m.py)
@@ -288,7 +284,7 @@ The automated install is only for a clean install of a Debian family or Fedora b
- [Pi-hole Droid - open source Android client](https://github.com/friimaind/pi-hole-droid)
- [Windows DNS Swapper](https://github.com/roots84/DNS-Swapper), see [#1400](https://github.com/pi-hole/pi-hole/issues/1400)
-## Coverage
+# Coverage
- [Adafruit livestream install](https://www.youtube.com/watch?v=eg4u2j1HYlI)
- [TekThing: 5 fun, easy projects for a Raspberry Pi](https://youtu.be/QwrKlyC2kdM?t=1m42s)
From bc1065a7fc83c2b0a4e93b50e7c1a1eb264f8454 Mon Sep 17 00:00:00 2001
From: Jacob Salmela
Date: Wed, 12 Jul 2017 01:18:50 -0500
Subject: [PATCH 135/162] reorganize sections. install instructions first. also
added more wordsmithing and links to interesting pi-hole.net articles
Signed-off-by: Jacob Salmela
---
README.md | 37 ++++++++++++++++++++++++++-----------
1 file changed, 26 insertions(+), 11 deletions(-)
diff --git a/README.md b/README.md
index 2c95e0b3..980a9d93 100644
--- a/README.md
+++ b/README.md
@@ -29,16 +29,6 @@ The Pi-hole blocks ads at the DNS-level, so all your devices are protected.
- **Fast** - it speeds up high-cost, high-latency networks by caching DNS queries and saves bandwidth by not downloading advertisement elements
- **Versatile** - Pi-hole can function also function as a DHCP server
-# Pi-hole Is Free, But Powered By Your Donations
-
-[Digital Ocean](http://www.digitalocean.com/?refcode=344d234950e1) helps with our infrastructure, but [our developers](https://github.com/orgs/pi-hole/people) are all volunteers so *your donations help keep us innovating*.
-
-- ![Paypal](https://assets.pi-hole.net/static/paypal.png) [Donate via PayPal](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=3J2L3Z4DHW9UY)
-- ![Bitcoin](https://assets.pi-hole.net/static/Bitcoin.png) Bitcoin Address: 1GKnevUnVaQM2pQieMyeHkpr8DXfkpfAtL
-
-## Other Ways To Support Us
-If you'd rather not send money, there are [other ways to support us](https://pi-hole.net/donate): you can sign up for services through our affiliate links, which will also help us offset some of the costs associated with keeping Pi-hole operational.
-
# One-Step Automated Install
1. Install a [supported operating system](https://discourse.pi-hole.net/t/hardware-software-requirements/273/1)
2. Run the command below (it downloads [this script](https://github.com/pi-hole/pi-hole/blob/master/automated%20install/basic-install.sh) in case you want to read over it first!)
@@ -74,6 +64,29 @@ Alternatively, you can manually set each device to use Pi-hole as their DNS serv
+# Pi-hole Is Free, But Powered By Your Donations
+
+[Digital Ocean](http://www.digitalocean.com/?refcode=344d234950e1) helps with our infrastructure, but [our developers](https://github.com/orgs/pi-hole/people) are all volunteers so *your donations help keep us innovating*.
+
+- ![Paypal](https://assets.pi-hole.net/static/paypal.png) [Donate via PayPal](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=3J2L3Z4DHW9UY)
+- ![Bitcoin](https://assets.pi-hole.net/static/Bitcoin.png) Bitcoin Address: 1GKnevUnVaQM2pQieMyeHkpr8DXfkpfAtL
+
+## Other Ways To Support Us
+### Affiliate Links
+If you'd rather not send money, there are [other ways to support us](https://pi-hole.net/donate): you can sign up for services through our affiliate links, which will also help us offset some of the costs associated with keeping Pi-hole operational; or you can support us in some non-tangible ways as listed below.
+
+### Contributing Code Via Pull Requests
+
+We don't work on Pi-hole for monetary reasons; we work on it because we think it's fun and we think our software is important in today's world. To that end, we welcome all contributors--from novices to masters.
+
+If you feel you have some code to contribute, we're happy to take a look. Just make sure to fill out our template when submitting a pull request. We're all volunteers on the project and without all the information in the template, it's very difficult for us to quickly get the code merged in.
+
+You'll find that the [install script](https://github.com/pi-hole/pi-hole/blob/master/automated%20install/basic-install.sh) and the [debug script](https://github.com/pi-hole/pi-hole/blob/master/advanced/Scripts/piholeDebug.sh) have an abundance of comments. These are two important scripts but we think they can also be a valuable resource to those who want to learn how to write scripts or code a program, which is why they are fully commented. So we encourage anyone who likes to tinker to read through it and submit a PR for us to review.
+
+### Presenting About Pi-hole
+
+Word-of-mouth has immensely helped our project grow. If you are going to be presenting about Pi-hole at a conference, meetup, or even for a school project, [get a hold of us for some free swag](https://pi-hole.net/2017/05/17/giving-a-presentation-on-pi-hole-contact-us-first-for-some-goodies-and-support/) to hand out to your audience.
+
# Overview Of Features
## The Dashboard (Web Interface)
@@ -96,6 +109,8 @@ If enabled, the query log will show all of the DNS queries requested by clients
+The query log and graphs are what have helped people [discover what sort of traffic is traversing their networks](https://pi-hole.net/2017/07/06/round-3-what-really-happens-on-your-network/).
+
#### Long-term Statistics
Using our Faster-Than-Light Engine ([FTL](https://github.com/pi-hole/FTL)), Pi-hole can store all of the domains queried in a database for retrieval or analysis later on. You can view this data as a graph, individual queries, or top clients/advertisers.
@@ -139,7 +154,7 @@ This runs `gravity` to download any newly-added domains from your source lists.
You can find out what list a certain domain was on. This is useful for troubleshooting sites that may not work properly due to a blocked domain.
#### `tail`ing Log Files
-You can watch the log files in real time to help debug any issues, or just see what's happening with your Pi-hole.
+You can [watch the log files](https://discourse.pi-hole.net/t/how-do-i-watch-and-interpret-the-pihole-log-file/276) in real time to help debug any issues, or just see what's happening with your Pi-hole.
#### Pi-hole Debugger
If you are having trouble with your Pi-hole, this is the place to go. You can run the debugger and it will attempt to diagnose any issues and then link to an FAQ with instructions on rectifying the problem.
From ea8927e1da9ab21a0b2fcadcee0d11151be186b3 Mon Sep 17 00:00:00 2001
From: Jacob Salmela
Date: Wed, 12 Jul 2017 01:21:47 -0500
Subject: [PATCH 136/162] add facebook page to contact info
Signed-off-by: Jacob Salmela
---
README.md | 1 +
1 file changed, 1 insertion(+)
diff --git a/README.md b/README.md
index 980a9d93..0ba43d7c 100644
--- a/README.md
+++ b/README.md
@@ -268,6 +268,7 @@ Simply run `pihole -c` for some detailed information.
- [FAQs](https://discourse.pi-hole.net/c/faqs)
- [Feature requests](https://discourse.pi-hole.net/c/feature-requests?order=votes)
- [Wiki](https://github.com/pi-hole/pi-hole/wiki)
+- [Facebook](https://www.facebook.com/ThePiHole/)
- ![Twitter](https://assets.pi-hole.net/static/twitter.png) [Tweet @The_Pi_Hole](https://twitter.com/The_Pi_Hole)
- ![Reddit](https://assets.pi-hole.net/static/reddit.png) [Reddit /r/pihole](https://www.reddit.com/r/pihole/)
- ![YouTube](https://assets.pi-hole.net/static/youtube.png) [Pi-hole channel](https://www.youtube.com/channel/UCT5kq9w0wSjogzJb81C9U0w)
From 2778d88e8acfdb40d4ad885903e5f9b54c56ac25 Mon Sep 17 00:00:00 2001
From: Dan Schaper
Date: Wed, 12 Jul 2017 00:12:54 -0700
Subject: [PATCH 137/162] Fix missing `then` clause
---
automated install/basic-install.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/automated install/basic-install.sh b/automated install/basic-install.sh
index 419ad10e..74e2a61d 100755
--- a/automated install/basic-install.sh
+++ b/automated install/basic-install.sh
@@ -1217,7 +1217,7 @@ install_dependent_packages() {
# amount of download traffic.
# NOTE: We may be able to use this installArray in the future to create a list of package that were
# installed by us, and remove only the installed packages, and not the entire list.
- if command -v debconf-apt-progress &> /dev/null;
+ if command -v debconf-apt-progress &> /dev/null; then
# For each package,
for i in "${argArray1[@]}"; do
echo -ne " ${INFO} Checking for $i..."
From 93d40b083e1c77b011c182f5214e1e058eaf3db4 Mon Sep 17 00:00:00 2001
From: Dan Schaper
Date: Wed, 12 Jul 2017 11:40:18 -0700
Subject: [PATCH 138/162] Fix extentions of the JPG images
Some images are jpg and not png.
---
README.md | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/README.md b/README.md
index 0ba43d7c..4a6a86c6 100644
--- a/README.md
+++ b/README.md
@@ -255,11 +255,11 @@ Simply run `pihole -c` for some detailed information.
```
-
+
-
+
# Get Help Or Connect With Us On The Web
From 74b912a0b71c1fd2027f4cc0c194fdf636d07dbb Mon Sep 17 00:00:00 2001
From: Adam Warner
Date: Wed, 12 Jul 2017 22:02:07 +0100
Subject: [PATCH 139/162] Check if FTL is already installed, do not download if
it is detected, and the sha1sum matches the remote This will probably break
some tests. I'll work that out in a bit Signed-off-by: Adam Warner
Signed-off-by: Adam Warner
---
automated install/basic-install.sh | 24 +++++++++++++++++++++---
1 file changed, 21 insertions(+), 3 deletions(-)
diff --git a/automated install/basic-install.sh b/automated install/basic-install.sh
index 74e2a61d..8c026442 100755
--- a/automated install/basic-install.sh
+++ b/automated install/basic-install.sh
@@ -1761,7 +1761,7 @@ FTLinstall() {
local binary="${1}"
local latesttag
local orig_dir
- local str="Installing FTL"
+ local str="Downloading and Installing FTL"
echo -ne " ${INFO} ${str}..."
# Get the current working directory
@@ -1774,6 +1774,7 @@ FTLinstall() {
echo -e " ${COL_LIGHT_RED}Error: Unable to get latest release location from GitHub${COL_NC}"
return 1
fi
+
# If the download worked,
if curl -sSL --fail "https://github.com/pi-hole/FTL/releases/download/${latesttag%$'\r'}/${binary}" -o "/tmp/${binary}"; then
# get sha1 of the binary we just downloaded for verification.
@@ -1879,9 +1880,26 @@ FTLdetect() {
binary="pihole-FTL-linux-x86_32"
fi
- # Install FTL
- FTLinstall "${binary}" || return 1
+ #In the next section we check to see if FTL is already installed (in case of pihole -r).
+ #If the installed version matches the latest version, then check the installed sha1sum of the binary vs the remote sha1sum. If they do not match, then download
+ local FTLversion=$(/usr/bin/pihole-FTL tag)
+ local FTLlatesttag=$(curl -sI https://github.com/pi-hole/FTL/releases/latest | grep 'Location' | awk -F '/' '{print $NF}' | tr -d '\r\n')
+ if [[ "${FTLversion}" != "${FTLlatesttag}" ]]; then
+ # Install FTL
+ FTLinstall "${binary}" || return 1
+ else
+ local remoteSha1=$(curl -sSL --fail "https://github.com/pi-hole/FTL/releases/download/${FTLversion%$'\r'}/${binary}.sha1" | cut -d ' ' -f 1)
+ local localSha1=$(sha1sum "$(which pihole-FTL)" | cut -d ' ' -f 1)
+
+ echo -e " ${INFO} Existing FTL Binary detected. Checking sha1sum..."
+ if [[ "${remoteSha1}" != "${localSha1}" ]]; then
+ echo -e " ${INFO} Corruption detected..."
+ FTLinstall "${binary}" || return 1
+ else
+ echo -e " ${INFO} sha1sums match. No need to download!"
+ fi
+ fi
}
main() {
From bf70c2c6605e15caf433bf5830a7e6a474b22f3a Mon Sep 17 00:00:00 2001
From: Adam Warner
Date: Wed, 12 Jul 2017 22:52:03 +0100
Subject: [PATCH 140/162] initial changes to tests to take into account changes
to strings
Signed-off-by: Adam Warner
---
automated install/basic-install.sh | 2 +-
test/test_automated_install.py | 20 ++++++++++----------
2 files changed, 11 insertions(+), 11 deletions(-)
diff --git a/automated install/basic-install.sh b/automated install/basic-install.sh
index 8c026442..3a53fca5 100755
--- a/automated install/basic-install.sh
+++ b/automated install/basic-install.sh
@@ -1817,7 +1817,7 @@ FTLinstall() {
# Detect suitable FTL binary platform
FTLdetect() {
echo ""
- echo -e " ${INFO} Downloading latest version of FTL..."
+ echo -e " ${INFO} FTL Checks..."
# Local, named variables
local machine
diff --git a/test/test_automated_install.py b/test/test_automated_install.py
index 60b9dbb8..4a4f72aa 100644
--- a/test/test_automated_install.py
+++ b/test/test_automated_install.py
@@ -319,11 +319,11 @@ def test_FTL_detect_aarch64_no_errors(Pihole):
source /opt/pihole/basic-install.sh
FTLdetect
''')
- expected_stdout = info_box + ' Downloading latest version of FTL...'
+ expected_stdout = info_box + ' FTL Checks...'
assert expected_stdout in detectPlatform.stdout
expected_stdout = tick_box + ' Detected ARM-aarch64 architecture'
assert expected_stdout in detectPlatform.stdout
- expected_stdout = tick_box + ' Installing FTL'
+ expected_stdout = tick_box + ' Downloading and Installing FTL'
assert expected_stdout in detectPlatform.stdout
def test_FTL_detect_armv6l_no_errors(Pihole):
@@ -336,11 +336,11 @@ def test_FTL_detect_armv6l_no_errors(Pihole):
source /opt/pihole/basic-install.sh
FTLdetect
''')
- expected_stdout = info_box + ' Downloading latest version of FTL...'
+ expected_stdout = info_box + ' FTL Checks...'
assert expected_stdout in detectPlatform.stdout
expected_stdout = tick_box + ' Detected ARM-hf architecture (armv6 or lower)'
assert expected_stdout in detectPlatform.stdout
- expected_stdout = tick_box + ' Installing FTL'
+ expected_stdout = tick_box + ' Downloading and Installing FTL'
assert expected_stdout in detectPlatform.stdout
def test_FTL_detect_armv7l_no_errors(Pihole):
@@ -353,11 +353,11 @@ def test_FTL_detect_armv7l_no_errors(Pihole):
source /opt/pihole/basic-install.sh
FTLdetect
''')
- expected_stdout = info_box + ' Downloading latest version of FTL...'
+ expected_stdout = info_box + ' FTL Checks...'
assert expected_stdout in detectPlatform.stdout
expected_stdout = tick_box + ' Detected ARM-hf architecture (armv7+)'
assert expected_stdout in detectPlatform.stdout
- expected_stdout = tick_box + ' Installing FTL'
+ expected_stdout = tick_box + ' Downloading and Installing FTL'
assert expected_stdout in detectPlatform.stdout
def test_FTL_detect_x86_64_no_errors(Pihole):
@@ -366,11 +366,11 @@ def test_FTL_detect_x86_64_no_errors(Pihole):
source /opt/pihole/basic-install.sh
FTLdetect
''')
- expected_stdout = info_box + ' Downloading latest version of FTL...'
+ expected_stdout = info_box + ' FTL Checks...'
assert expected_stdout in detectPlatform.stdout
expected_stdout = tick_box + ' Detected x86_64 architecture'
assert expected_stdout in detectPlatform.stdout
- expected_stdout = tick_box + ' Installing FTL'
+ expected_stdout = tick_box + ' Downloading and Installing FTL'
assert expected_stdout in detectPlatform.stdout
def test_FTL_detect_unknown_no_errors(Pihole):
@@ -391,7 +391,7 @@ def test_FTL_download_aarch64_no_errors(Pihole):
source /opt/pihole/basic-install.sh
FTLinstall pihole-FTL-aarch64-linux-gnu
''')
- expected_stdout = tick_box + ' Installing FTL'
+ expected_stdout = tick_box + ' Downloading and Installing FTL'
assert expected_stdout in download_binary.stdout
error = 'Error: Download of binary from Github failed'
assert error not in download_binary.stdout
@@ -405,7 +405,7 @@ def test_FTL_download_unknown_fails_no_errors(Pihole):
source /opt/pihole/basic-install.sh
FTLinstall pihole-FTL-mips
''')
- expected_stdout = cross_box + ' Installing FTL'
+ expected_stdout = cross_box + ' Downloading and Installing FTL'
assert expected_stdout in download_binary.stdout
error = 'Error: URL not found'
assert error in download_binary.stdout
From e1f818ffb7edc8d7257f40f85d39007a804c7d8c Mon Sep 17 00:00:00 2001
From: Jacob Salmela <4aad0716@opayq.com>
Date: Fri, 14 Jul 2017 10:53:45 -0500
Subject: [PATCH 141/162] Tweak/debug improvements (#1585)
* check for CIDR notation when comparing IPv6 address to that found in setupVars.conf
* highlight bad address entries in pihole.log and reference a corresponding FAQ
* show header output if Pi-holes x-header does not match
* fix automated mode when running from the dashboard. It would previously not automatically upload and generate a token.
* show disclaimer message
* undocumented feature for now: obfuscate domains in pihole.log so they are not visible when sent to the Pi-hole developers. We need to make an additonal flag for this in the pihole command. if the variable OBFUSCATE has a value, it will replace the domain in the log with a placeholder value
* fix small typo in the disclaimer
---
advanced/Scripts/piholeDebug.sh | 68 ++++++++++++++++++++++++++-------
1 file changed, 55 insertions(+), 13 deletions(-)
diff --git a/advanced/Scripts/piholeDebug.sh b/advanced/Scripts/piholeDebug.sh
index f98d986a..60b04b73 100755
--- a/advanced/Scripts/piholeDebug.sh
+++ b/advanced/Scripts/piholeDebug.sh
@@ -39,6 +39,8 @@ else
OVER="\r\033[K"
fi
+OBFUSCATED_PLACEHOLDER=""
+
# FAQ URLs for use in showing the debug log
FAQ_UPDATE_PI_HOLE="${COL_CYAN}https://discourse.pi-hole.net/t/how-do-i-update-pi-hole/249${COL_NC}"
FAQ_CHECKOUT_COMMAND="${COL_CYAN}https://discourse.pi-hole.net/t/the-pihole-command-with-examples/738#checkout${COL_NC}"
@@ -47,6 +49,7 @@ FAQ_HARDWARE_REQUIREMENTS_PORTS="${COL_CYAN}https://discourse.pi-hole.net/t/hard
FAQ_GATEWAY="${COL_CYAN}https://discourse.pi-hole.net/t/why-is-a-default-gateway-important-for-pi-hole/3546${COL_NC}"
FAQ_ULA="${COL_CYAN}https://discourse.pi-hole.net/t/use-ipv6-ula-addresses-for-pi-hole/2127${COL_NC}"
FAQ_FTL_COMPATIBILITY="${COL_CYAN}https://github.com/pi-hole/FTL#compatibility-list${COL_NC}"
+FAQ_BAD_ADDRESS="${COL_CYAN}https://discourse.pi-hole.net/t/why-do-i-see-bad-address-at-in-pihole-log/3972${COL_NC}"
# Other URLs we may use
FORUMS_URL="${COL_CYAN}https://discourse.pi-hole.net${COL_NC}"
@@ -159,6 +162,17 @@ ${PIHOLE_FTL_LOG}
${PIHOLE_WEB_SERVER_ACCESS_LOG_FILE}
${PIHOLE_WEB_SERVER_ERROR_LOG_FILE})
+DISCLAIMER="This process collects information from your Pi-hole, and optionally uploads it to a unique and random directory on tricorder.pi-hole.net.
+
+The intent of this script is to allow users to self-diagnose their installations. This is accomplished by running tests against our software and providing the user with links to FAQ articles when a problem is detected. Since we are a small team and Pi-hole has been growing steadily, it is our hope that this will help us spend more time on development.
+
+NOTE: All log files auto-delete after 48 hours and ONLY the Pi-hole developers can access your data via the given token. We have taken these extra steps to secure your data and will work to further reduce any personal information gathered.
+"
+
+show_disclaimer(){
+ log_write "${DISCLAIMER}"
+}
+
source_setup_variables() {
# Display the current test that is running
log_write "\n${COL_LIGHT_PURPLE}*** [ INITIALIZING ]${COL_NC} Sourcing setup variables"
@@ -203,6 +217,7 @@ copy_to_debug_log() {
initiate_debug() {
# Clear the screen so the debug log is readable
clear
+ show_disclaimer
# Display that the debug process is beginning
log_write "${COL_LIGHT_PURPLE}*** [ INITIALIZING ]${COL_NC}"
# Timestamp the start of the log
@@ -457,7 +472,7 @@ does_ip_match_setup_vars() {
# If it's an IPv6 address
if [[ "${protocol}" == "6" ]]; then
# Strip off the / (CIDR notation)
- if [[ "${ip_address%/*}" == "${setup_vars_ip}" ]]; then
+ if [[ "${ip_address%/*}" == "${setup_vars_ip%/*}" ]]; then
# if it matches, show it in green
log_write " ${COL_LIGHT_GREEN}${ip_address%/*}${COL_NC} matches the IP found in ${PIHOLE_SETUP_VARS_FILE}"
else
@@ -659,6 +674,10 @@ check_x_headers() {
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
@@ -666,6 +685,7 @@ check_x_headers() {
else
# Otherwise, show an error
log_write "$CROSS ${COL_LIGHT_RED}X-Header does not match or could not be retrieved.${COL_NC}"
+ log_write "${COL_LIGHT_RED}${full_curl_output_block_page}${COL_NC}"
fi
# Same logic applies to the dashbord as above, if the X-Header matches what a working system shoud have,
@@ -675,6 +695,7 @@ check_x_headers() {
else
# Othewise, it's a failure since the X-Headers either don't exist or have been modified in some way
log_write "$CROSS ${COL_LIGHT_RED}X-Header does not match or could not be retrieved.${COL_NC}"
+ log_write "${COL_LIGHT_RED}${full_curl_output_dashboard}${COL_NC}"
fi
}
@@ -972,8 +993,39 @@ analyze_pihole_log() {
local pihole_log_head=()
pihole_log_head=( $(head -n 20 ${PIHOLE_LOG}) )
log_write " ${COL_CYAN}-----head of $(basename ${PIHOLE_LOG})------${COL_NC}"
+ local error_to_check_for
+ local line_to_obfuscate
+ local obfuscated_line
for head_line in "${pihole_log_head[@]}"; do
- log_write " ${head_line}"
+ # A common error in the pihole.log is when there is a non-hosts formatted file
+ # that the DNS server is attempting to read. Since it's not formatted
+ # correctly, there will be an entry for "bad address at line n"
+ # So we can check for that here and highlight it in red so the user can see it easily
+ error_to_check_for=$(echo ${head_line} | grep 'bad address at')
+ # Some users may not want to have the domains they visit sent to us
+ # To that end, we check for lines in the log that would contain a domain name
+ line_to_obfuscate=$(echo ${head_line} | grep ': query\|: forwarded\|: reply')
+ # If the variable contains a value, it found an error in the log
+ if [[ -n ${error_to_check_for} ]]; then
+ # So we can print it in red to make it visible to the user
+ log_write " ${CROSS} ${COL_LIGHT_RED}${head_line}${COL_NC} (${FAQ_BAD_ADDRESS})"
+ else
+ # If the variable does not a value (the current default behavior), so do not obfuscate anything
+ if [[ -z ${OBFUSCATE} ]]; then
+ log_write " ${head_line}"
+ # Othwerise, a flag was passed to this command to obfuscate domains in the log
+ else
+ # So first check if there are domains in the log that should be obfuscated
+ if [[ -n ${line_to_obfuscate} ]]; then
+ # If there are, we need to use awk to replace only the domain name (the 6th field in the log)
+ # so we substitue the domain for the placeholder value
+ obfuscated_line=$(echo ${line_to_obfuscate} | awk -v placeholder="${OBFUSCATED_PLACEHOLDER}" '{sub($6,placeholder); print $0}')
+ log_write " ${obfuscated_line}"
+ else
+ log_write " ${head_line}"
+ fi
+ fi
+ fi
done
log_write ""
# Set the IFS back to what it was
@@ -1019,17 +1071,7 @@ upload_to_tricorder() {
# let the user know
log_write "${INFO} Debug script running in automated mode"
# and then decide again which tool to use to submit it
- if command -v openssl &> /dev/null; then
- # If openssl is available, use it
- log_write "${INFO} Using ${COL_LIGHT_GREEN}openssl${COL_NC} for transmission."
- # Save the token returned by our server in a variable
- tricorder_token=$(openssl s_client -quiet -connect tricorder.pi-hole.net:${TRICORDER_SSL_PORT_NUMBER} 2> /dev/null < /dev/stdin)
- else
- # Otherwise, fallback to netcat
- log_write "${INFO} Using ${COL_YELLOW}netcat${COL_NC} for transmission."
- # Save the token returned by our server in a variable
- tricorder_token=$(nc tricorder.pi-hole.net ${TRICORDER_NC_PORT_NUMBER} < /dev/stdin)
- fi
+ tricorder_use_nc_or_ssl
# If we're not running in automated mode,
else
echo ""
From 7d56e2a9371e952b5ffea24a298615a73e098b11 Mon Sep 17 00:00:00 2001
From: Adam Warner
Date: Fri, 14 Jul 2017 20:54:41 +0100
Subject: [PATCH 142/162] `FTL` has an `L` in it, innit?
Signed-off-by: Adam Warner
---
advanced/Scripts/piholeDebug.sh | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/advanced/Scripts/piholeDebug.sh b/advanced/Scripts/piholeDebug.sh
index 60b04b73..ea387b5a 100755
--- a/advanced/Scripts/piholeDebug.sh
+++ b/advanced/Scripts/piholeDebug.sh
@@ -598,7 +598,7 @@ compare_port_to_service_assigned() {
# The programs we use may change at some point, so they are in a varible here
local resolver="dnsmasq"
local web_server="lighttpd"
- local ftl="pihole-FT"
+ local ftl="pihole-FTL"
if [[ "${service_name}" == "${resolver}" ]] || [[ "${service_name}" == "${web_server}" ]] || [[ "${service_name}" == "${ftl}" ]]; then
# if port 53 is dnsmasq, show it in green as it's standard
log_write "[${COL_LIGHT_GREEN}${port_number}${COL_NC}] is in use by ${COL_LIGHT_GREEN}${service_name}${COL_NC}"
@@ -615,7 +615,7 @@ check_required_ports() {
# so we can detect any issues
local resolver="dnsmasq"
local web_server="lighttpd"
- local ftl="pihole-FT"
+ local ftl="pihole-FTL"
# Create an array for these ports in use
ports_in_use=()
# Sort the addresses and remove duplicates
From 9464b71a6e37a4067932362fd57f367ef7872d2b Mon Sep 17 00:00:00 2001
From: Mcat12
Date: Mon, 26 Jun 2017 09:51:21 -0400
Subject: [PATCH 143/162] Remove /* from IPv6 as well as IPv4
Fixes Discourse issue: https://discourse.pi-hole.net/t/ipv6-aaaa-dns-issue/3830
Signed-off-by: Adam Warner
# Conflicts:
# gravity.sh
---
gravity.sh | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/gravity.sh b/gravity.sh
index 285ce5c3..41e3c68a 100755
--- a/gravity.sh
+++ b/gravity.sh
@@ -46,9 +46,9 @@ else
exit 1
fi
-#Remove the /* from the end of the IPv4addr.
+#Remove the /* from the end of the IP addresses
IPV4_ADDRESS=${IPV4_ADDRESS%/*}
-IPV6_ADDRESS=${IPV6_ADDRESS}
+IPV6_ADDRESS=${IPV6_ADDRESS%/*}
# Variables for various stages of downloading and formatting the list
basename=pihole
From edb594461d3ac683934eb9b256d93946f92823ad Mon Sep 17 00:00:00 2001
From: Adam Warner
Date: Wed, 28 Jun 2017 22:54:02 +0100
Subject: [PATCH 144/162] Remove CIDR from IPv6 address when detecting it in
the install script
Signed-off-by: Adam Warner
# Conflicts:
# automated install/basic-install.sh
---
automated install/basic-install.sh | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/automated install/basic-install.sh b/automated install/basic-install.sh
index 053e04ba..2cf2c61d 100755
--- a/automated install/basic-install.sh
+++ b/automated install/basic-install.sh
@@ -344,8 +344,8 @@ useIPv6dialog() {
# Determine type of found IPv6 addresses
for i in "${IPV6_ADDRESSES[@]}"; do
result=$(testIPv6 "$i")
- [[ "${result}" == "ULA" ]] && ULA_ADDRESS="$i"
- [[ "${result}" == "GUA" ]] && GUA_ADDRESS="$i"
+ [[ "${result}" == "ULA" ]] && ULA_ADDRESS="${i%/*}"
+ [[ "${result}" == "GUA" ]] && GUA_ADDRESS="${i%/*}"
done
# Determine which address to be used: Prefer ULA over GUA or don't use any if none found
@@ -1510,10 +1510,9 @@ main() {
else
echo "::: Update complete!"
fi
-
if [[ ${INSTALL_WEB} == true ]]; then
if (( ${#pw} > 0 )) ; then
- echo ":::"
+ echo ":::"
echo "::: Note: As security measure a password has been installed for your web interface"
echo "::: The currently set password is"
echo "::: ${pw}"
@@ -1524,7 +1523,8 @@ main() {
fi
echo ":::"
- echo "::: The install log is located at: /etc/pihole/install.log"
+ echo "::: The install log is located at: /etc/pihole/install.log
+ "
}
if [[ "${PH_TEST}" != true ]] ; then
From 9101916719a86ab9478496bf18e4e0baa42ab3ab Mon Sep 17 00:00:00 2001
From: Dan Schaper
Date: Sat, 24 Jun 2017 15:49:16 -0700
Subject: [PATCH 145/162] Test exclusion for sourced files SC1090.
Signed-off-by: Dan Schaper
---
test/test_shellcheck.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/test/test_shellcheck.py b/test/test_shellcheck.py
index fa342027..9c4f141b 100644
--- a/test/test_shellcheck.py
+++ b/test/test_shellcheck.py
@@ -7,7 +7,7 @@ run_local = testinfra.get_backend(
def test_scripts_pass_shellcheck():
''' Make sure shellcheck does not find anything wrong with our shell scripts '''
- shellcheck = "find . -type f \( -name 'update.sh' -o -name 'piholeDebug.sh' \) | while read file; do shellcheck \"$file\"; done;"
+ shellcheck = "find . -type f \( -name 'update.sh' -o -name 'piholeDebug.sh' \) | while read file; do shellcheck \"$file\" -e SC1090; done;"
results = run_local(shellcheck)
print results.stdout
assert '' == results.stdout
From 66f32b7601d52266e7f244cda3f9334f06d5e6ce Mon Sep 17 00:00:00 2001
From: Dan Schaper
Date: Sun, 25 Jun 2017 12:26:16 -0700
Subject: [PATCH 146/162] Remove testing for `debug` as this is getting a
re-write by Jacob.
Signed-off-by: Dan Schaper
---
test/test_shellcheck.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/test/test_shellcheck.py b/test/test_shellcheck.py
index 9c4f141b..1b6b35a7 100644
--- a/test/test_shellcheck.py
+++ b/test/test_shellcheck.py
@@ -7,7 +7,7 @@ run_local = testinfra.get_backend(
def test_scripts_pass_shellcheck():
''' Make sure shellcheck does not find anything wrong with our shell scripts '''
- shellcheck = "find . -type f \( -name 'update.sh' -o -name 'piholeDebug.sh' \) | while read file; do shellcheck \"$file\" -e SC1090; done;"
+ shellcheck = "find . -type f -name 'update.sh' | while read file; do shellcheck \"$file\" -e SC1090; done;"
results = run_local(shellcheck)
print results.stdout
assert '' == results.stdout
From 05c8687041be34065724fd2e33783a47feae10ff Mon Sep 17 00:00:00 2001
From: Dan Schaper
Date: Sun, 25 Jun 2017 14:21:41 -0700
Subject: [PATCH 147/162] Integrate DL's update.sh fixes.
`shellcheck -x` for following files.
Do not test for included files SC1091
Signed-off-by: Dan Schaper
Signed-off-by: Adam Warner
# Conflicts:
# advanced/Scripts/update.sh
---
advanced/Scripts/update.sh | 23 ++++++++++++++++-------
test/test_shellcheck.py | 2 +-
2 files changed, 17 insertions(+), 8 deletions(-)
diff --git a/advanced/Scripts/update.sh b/advanced/Scripts/update.sh
index 6aef183b..e3a7f8fd 100755
--- a/advanced/Scripts/update.sh
+++ b/advanced/Scripts/update.sh
@@ -19,8 +19,14 @@ readonly ADMIN_INTERFACE_DIR="/var/www/html/admin"
readonly PI_HOLE_GIT_URL="https://github.com/pi-hole/pi-hole.git"
readonly PI_HOLE_FILES_DIR="/etc/.pihole"
+# shellcheck disable=SC2034
PH_TEST=true
-source ${PI_HOLE_FILES_DIR}/automated\ install/basic-install.sh
+
+# Have to ignore the following rule as spaces in paths are not supported by ShellCheck
+#shellcheck disable=SC1090
+source "${PI_HOLE_FILES_DIR}/automated install/basic-install.sh"
+
+source "/opt/pihole/COL_TABLE"
# is_repo() sourced from basic-install.sh
# make_repo() sourced from basic-install.sh
@@ -30,14 +36,14 @@ source ${PI_HOLE_FILES_DIR}/automated\ install/basic-install.sh
GitCheckUpdateAvail() {
local directory="${1}"
curdir=$PWD
- cd "${directory}"
+ cd "${directory}" || return
# Fetch latest changes in this repo
git fetch --quiet origin
# @ alone is a shortcut for HEAD. Older versions of git
# need @{0}
- LOCAL="$(git rev-parse @{0})"
+ LOCAL="$("git rev-parse @{0}")"
# The suffix @{upstream} to a branchname
# (short form @{u}) refers
@@ -46,7 +52,7 @@ GitCheckUpdateAvail() {
# (configured with branch..remote and
# branch..merge). A missing branchname
# defaults to the current one.
- REMOTE="$(git rev-parse @{upstream})"
+ REMOTE="$("git rev-parse @{upstream}")"
if [[ ${#LOCAL} == 0 ]]; then
echo "::: Error: Local revision could not be obtained, ask Pi-hole support."
@@ -62,7 +68,7 @@ GitCheckUpdateAvail() {
fi
# Change back to original directory
- cd "${curdir}"
+ cd "${curdir}" || exit
if [[ "${LOCAL}" != "${REMOTE}" ]]; then
# Local branch is behind remote branch -> Update
@@ -77,8 +83,10 @@ GitCheckUpdateAvail() {
FTLcheckUpdate() {
- local FTLversion=$(/usr/bin/pihole-FTL tag)
- local FTLlatesttag=$(curl -sI https://github.com/pi-hole/FTL/releases/latest | grep 'Location' | awk -F '/' '{print $NF}' | tr -d '\r\n')
+ local FTLversion
+ FTLversion=$(/usr/bin/pihole-FTL tag)
+ local FTLlatesttag
+ FTLlatesttag=$(curl -sI https://github.com/pi-hole/FTL/releases/latest | grep 'Location' | awk -F '/' '{print $NF}' | tr -d '\r\n')
if [[ "${FTLversion}" != "${FTLlatesttag}" ]]; then
return 0
@@ -90,6 +98,7 @@ FTLcheckUpdate() {
main() {
local pihole_version_current
local web_version_current
+ #shellcheck disable=1090,2154
source "${setupVars}"
#This is unlikely
diff --git a/test/test_shellcheck.py b/test/test_shellcheck.py
index 1b6b35a7..5b1a8961 100644
--- a/test/test_shellcheck.py
+++ b/test/test_shellcheck.py
@@ -7,7 +7,7 @@ run_local = testinfra.get_backend(
def test_scripts_pass_shellcheck():
''' Make sure shellcheck does not find anything wrong with our shell scripts '''
- shellcheck = "find . -type f -name 'update.sh' | while read file; do shellcheck \"$file\" -e SC1090; done;"
+ shellcheck = "find . -type f -name 'update.sh' | while read file; do shellcheck -x \"$file\" -e SC1090,SC1091; done;"
results = run_local(shellcheck)
print results.stdout
assert '' == results.stdout
From 3631d1349ebe06ad804df8ca4ba008ca1b917433 Mon Sep 17 00:00:00 2001
From: WaLLy3K
Date: Sat, 15 Jul 2017 20:11:06 +1000
Subject: [PATCH 148/162] Prevent Web Admin from printing restartdns colour
codes (#1575)
* Prevent Web Admin from printing unnecessary msgs
* Make DNS restart behaviour consistent
---
advanced/Scripts/webpage.sh | 17 +++++++++--------
pihole | 24 ++++++++++++++++--------
2 files changed, 25 insertions(+), 16 deletions(-)
diff --git a/advanced/Scripts/webpage.sh b/advanced/Scripts/webpage.sh
index 5aae18f7..42272122 100755
--- a/advanced/Scripts/webpage.sh
+++ b/advanced/Scripts/webpage.sh
@@ -221,18 +221,19 @@ Reboot() {
}
RestartDNS() {
- local str="Restarting dnsmasq"
- echo -ne " ${INFO} ${str}..."
- if [[ -x "$(command -v systemctl)" ]]; then
- systemctl restart dnsmasq
+ local str="Restarting DNS service"
+ [[ -t 1 ]] && echo -ne " ${INFO} ${str}"
+ if command -v systemctl &> /dev/null; then
+ output=$( { systemctl restart dnsmasq; } 2>&1 )
else
- service dnsmasq restart
+ output=$( { service dnsmasq restart; } 2>&1 )
fi
- if [[ "$?" == 0 ]]; then
- echo -e "${OVER} ${TICK} ${str}"
+ if [[ -z "${output}" ]]; then
+ [[ -t 1 ]] && echo -e "${OVER} ${TICK} ${str}"
else
- echo -e "${OVER} ${CROSS} ${str}"
+ [[ ! -t 1 ]] && OVER=""
+ echo -e "${OVER} ${CROSS} ${output}"
fi
}
diff --git a/pihole b/pihole
index 3c321b93..b4b5e886 100755
--- a/pihole
+++ b/pihole
@@ -173,24 +173,32 @@ versionFunc() {
restartDNS() {
dnsmasqPid=$(pidof dnsmasq)
+ local str="Restarting DNS service"
+ echo -ne " ${INFO} ${str}"
if [[ "${dnsmasqPid}" ]]; then
# Service already running - reload config
- echo -ne " ${INFO} Restarting dnsmasq"
if [[ -x "$(command -v systemctl)" ]]; then
- systemctl restart dnsmasq
+ output=$( { systemctl restart dnsmasq; } 2>&1 )
else
- service dnsmasq restart
+ output=$( { service dnsmasq restart; } 2>&1 )
+ fi
+ if [[ -z "${output}" ]]; then
+ echo -e "${OVER} ${TICK} ${str}"
+ else
+ echo -e "${OVER} ${CROSS} ${output}"
fi
- [[ "$?" == 0 ]] && echo -e "${OVER} ${TICK} Restarted dnsmasq" || echo -e "${OVER} ${CROSS} Failed to restart dnsmasq"
else
# Service not running, start it up
- echo -ne " ${INFO} Starting dnsmasq"
if [[ -x "$(command -v systemctl)" ]]; then
- systemctl start dnsmasq
+ output=$( { systemctl start dnsmasq; } 2>&1 )
else
- service dnsmasq start
+ output=$( { service dnsmasq start; } 2>&1 )
+ fi
+ if [[ -z "${output}" ]]; then
+ echo -e "${OVER} ${TICK} ${str}"
+ else
+ echo -e "${OVER} ${CROSS} ${output}"
fi
- [[ "$?" == 0 ]] && echo -e "${OVER} ${TICK} Restarted dnsmasq" || echo -e "${OVER} ${CROSS} Failed to restart dnsmasq"
fi
}
From 3a50b91722ed438e7db86e2b0a147b91642116c8 Mon Sep 17 00:00:00 2001
From: WaLLy3K
Date: Sat, 15 Jul 2017 20:56:40 +1000
Subject: [PATCH 149/162] User-friendly queryFunc() output (#1483)
* User-friendly queryFunc() output
* Silence grep errors
* Provide 'pihole -q -h' help output
* Rewrite option handling
* Loop through grep stdout to make query output user friendly
* Add -adlist option to show block list URL instead of internal file name
* Limit general searches to 10 matches per block list
* Add -all option to override 10 match limit
* Fixed 'pihole -h' wording
* Further query optimisations
* Optimised scanList() output by switching folder
* Re-added processWildcards() function
* Added "-bp" exact matching option for use with block page
* Standardised query output
* Separated wildcard search from blacklist/whitelist search
* Optimised sorting by sorting glob output and not scanList() output
* Fixed result skipping
* Add text for wildcard result on exact query
* Fix wildcard result output
* Multiple wildcard matches on exact query could cause unexpected output
* Remove unnecessary replacement
* Make grep only output matching text
* HOSTS format lists will also output the IP address
* That substitution was necessary
* Remove IP address from HOSTS format lists
* Filter unwanted content
* Add /dev/null to grep, to always print file name (even when searching only one block list)
* Use three seds to remove unwanted content from block lists
* Merge with development
* Simplify queryFunc code
---
pihole | 244 ++++++++++++++++++++++++++++++++++++++++++++++++---------
1 file changed, 206 insertions(+), 38 deletions(-)
diff --git a/pihole b/pihole
index b4b5e886..1bd35dbb 100755
--- a/pihole
+++ b/pihole
@@ -87,10 +87,14 @@ scanList(){
domain="${1}"
list="${2}"
method="${3}"
- if [[ ${method} == "-exact" ]] ; then
- grep -i -E "(^|\s)${domain}($|\s)" "${list}"
+
+ # Switch folder, preventing grep from printing file path
+ cd "/etc/pihole" || return 1
+
+ if [[ -n "${method}" ]]; then
+ grep -i -E -l "(^|\s|\/)${domain}($|\s|\/)" ${list} /dev/null 2> /dev/null
else
- grep -i "${domain}" "${list}"
+ grep -i "${domain}" ${list} /dev/null 2> /dev/null
fi
}
@@ -110,46 +114,210 @@ processWildcards() {
}
queryFunc() {
- domain="${2}"
-
- if [[ -z "${domain}" ]]; then
- echo -e " ${COL_LIGHT_RED}Invalid option${COL_NC}
- Try 'pihole query --help' for more information."
+ options="$*"
+ options="${options/-q /}"
+
+ if [[ "${options}" == "-h" ]] || [[ "${options}" == "--help" ]]; then
+ echo "Usage: pihole -q [option]
+Example: 'pihole -q -exact domain.com'
+Query the adlists for a specified domain
+
+Options:
+ -adlist Print the name of the block list URL
+ -exact Search the block lists for exact domain matches
+ -all Return all query matches within a block list
+ -h, --help Show this help dialog"
+ exit 0
+ fi
+
+ if [[ "${options}" == *"-exact"* ]]; then
+ method="exact"
+ exact=true
+ fi
+
+ if [[ "${options}" == *"-adlist"* ]]; then
+ adlist=true
+ fi
+
+ if [[ "${options}" == *"-bp"* ]]; then
+ method="exact"
+ blockpage=true
+ fi
+
+ if [[ "${options}" == *"-all"* ]]; then
+ all=true
+ fi
+
+ # Strip valid options, leaving only the domain and invalid options
+ options=$(sed 's/ \?-\(exact\|adlist\|bp\|all\) \?//g' <<< "$options")
+
+ # Handle errors
+ if [[ "${options}" == *" "* ]]; then
+ error=true
+ str="Unknown option specified"
+ elif [[ "${options}" == "-q" ]]; then
+ error=true
+ str="No domain specified"
+ fi
+
+ if [[ -n "${error}" ]]; then
+ echo -e " ${COL_LIGHT_RED}${str}${COL_NC}
+ Try 'pihole -q --help' for more information."
exit 1
fi
-
- method="${3}"
- lists=( /etc/pihole/list.* /etc/pihole/blacklist.txt)
- for list in ${lists[@]}; do
- if [ -e "${list}" ]; then
- result=$(scanList ${domain} ${list} ${method})
- # Remove empty lines before couting number of results
- count=$(sed '/^\s*$/d' <<< "$result" | wc -l)
- echo "${list} (${count} results)"
- if [[ ${count} > 0 ]]; then
- echo "${result}"
- fi
- echo ""
- else
- echo -e " ${CROSS} List does not exist"
- echo ""
- fi
- done
- # Scan for possible wildcard matches
- if [ -e "${wildcardlist}" ]; then
- local wildcards=($(processWildcards "${domain}"))
- for domain in ${wildcards[@]}; do
- result=$(scanList "\/${domain}\/" ${wildcardlist})
- # Remove empty lines before couting number of results
- count=$(sed '/^\s*$/d' <<< "$result" | wc -l)
- if [[ ${count} > 0 ]]; then
- echo -e " ${TICK} Wildcard blocking ${domain} (${count} results)"
- echo "${result}"
- echo ""
+ # If domain contains non ASCII characters, convert domain to punycode if python is available
+ # Cr: https://serverfault.com/a/335079
+ if [[ "$options" = *[![:ascii:]]* ]]; then
+ if command -v python &> /dev/null; then
+ query=$(python -c 'import sys;print sys.argv[1].decode("utf-8").encode("idna")' "${options}")
+ fi
+ else
+ query="${options}"
+ fi
+
+ # Scan Whitelist and Blacklist
+ lists="whitelist.txt blacklist.txt"
+ results=($(scanList "${query}" "${lists}" "${method}"))
+
+ if [[ -n "${results[*]}" ]]; then
+ # Loop through each scanList line to print appropriate title
+ for result in "${results[@]}"; do
+ filename="${result/:*/}"
+ if [[ -n "$exact" ]]; then
+ printf " Exact result in %s\n" "${filename}"
+ elif [[ -n "$blockpage" ]]; then
+ printf " [i] %s\n" "${filename}"
+ else
+ domain="${result/*:/}"
+ if [[ ! "${filename}" == "${filename_prev:-}" ]]; then
+ printf " Result from %s\n" "${filename}"
+ fi
+ printf " %s\n" "${domain}"
+ filename_prev="${filename}"
fi
done
fi
+
+ # Scan Wildcards
+ if [[ -e "${wildcardlist}" ]]; then
+ wildcards=($(processWildcards "${query}"))
+
+ for match in "${wildcards[@]}"; do
+ results=($(scanList "\/${match}\/" ${wildcardlist}))
+
+ if [[ -n "${results[*]}" ]]; then
+ # Remove empty lines before couting number of results
+ count=$(sed '/^\s*$/d' <<< "${results[@]}" | wc -l)
+ if [[ "${count}" -ge 0 ]]; then
+ blResult=true
+ if [[ -z "${blockpage}" ]]; then
+ printf " Wildcard result in %s\n" "${wildcardlist/*dnsmasq.d\/}"
+ fi
+
+ if [[ -n "${blockpage}" ]]; then
+ echo " ${INFO} ${match}"
+ else
+ echo " *.${match}"
+ fi
+ fi
+ fi
+ done
+
+ [[ -n "${blResult}" ]] && [[ -n "${blockpage}" ]] && exit 0
+ fi
+
+ # Glob *.domains file names, remove file paths and sort by list number
+ lists_raw=(/etc/pihole/*.domains)
+ IFS_OLD=$IFS
+ IFS=$'\n'
+ lists=$(sort -t . -k 2 -g <<< "${lists_raw[*]//\/etc\/pihole\//}")
+
+ # Scan Domains files
+ results=($(scanList "${query}" "${lists}" "${method}"))
+
+ # Handle notices
+ if [[ -z "${blResult}" ]] && [[ -z "${results[*]}" ]]; then
+ notice=true
+ str="No ${method/t/t }results found for ${query} found within block lists"
+ elif [[ -z "${all}" ]] && [[ "${#results[*]}" -ge 16000 ]]; then
+ # 16000 chars is 15 chars X 1000 lines worth of results
+ notice=true
+ str="Hundreds of ${method/t/t }results found for ${query}
+ This can be overriden using the -all option"
+ fi
+
+ if [[ -n "${notice}" ]]; then
+ echo -e " ${INFO} ${str}"
+ exit
+ fi
+
+ # Remove unwanted content from results
+ if [[ -z "${method}" ]]; then
+ results=($(sed "/:#/d" <<< "${results[*]}")) # Lines starting with comments
+ results=($(sed "s/[ \t]#.*//g" <<< "${results[*]}")) # Comments after domain
+ results=($(sed "s/:.*[ \t]/:/g" <<< "${results[*]}")) # IP address
+ fi
+ IFS=$IFS_OLD
+
+ # Get adlist content as array
+ if [[ -n "${adlist}" ]] || [[ -n "${blockpage}" ]]; then
+ if [[ -f "/etc/pihole/adlists.list" ]]; then
+ for url in $(< /etc/pihole/adlists.list); do
+ if [[ "${url:0:4}" == "http" ]] || [[ "${url:0:3}" == "www" ]]; then
+ adlists+=("$url")
+ fi
+ done
+ else
+ echo -e " ${COL_LIGHT_RED}The file '/etc/pihole/adlists.list' was not found${COL_NC}"
+ exit 1
+ fi
+ fi
+
+ if [[ -n "${results[*]}" ]]; then
+ if [[ -n "${exact}" ]]; then
+ echo " Exact result(s) for ${query} found in:"
+ fi
+
+ for result in "${results[@]}"; do
+ filename="${result/:*/}"
+
+ # Convert file name to URL name for -adlist or -bp options
+ if [[ -n "${adlist}" ]] || [[ -n "${blockpage}" ]]; then
+ filenum=("${filename/list./}")
+ filenum=("${filenum/.*/}")
+ filename="${adlists[$filenum]}"
+ fi
+
+ if [[ -n "${exact}" ]]; then
+ printf " %s\n" "${filename}"
+ elif [[ -n "${blockpage}" ]]; then
+ printf " [%s] %s\n" "${filenum}" "${filename}"
+ else # Standard query output
+
+ # Print filename heading once per file, not for every match
+ if [[ ! "${filename}" == "${filename_prev:-}" ]]; then
+ unset count
+ printf " Result from %s\n" "${filename}"
+ else
+ let count++
+ fi
+
+ # Print matching domain if $max_count has not been reached
+ [[ -z "${all}" ]] && max_count="20"
+ if [[ -z "${all}" ]] && [[ "${count}" -eq "${max_count}" ]]; then
+ echo " Over $count results found, skipping rest of file"
+ elif [[ -z "${all}" ]] && [[ "${count}" -gt "${max_count}" ]]; then
+ continue
+ else
+ domain="${result/*:/}"
+ printf " %s\n" "${domain}"
+ fi
+ filename_prev="${filename}"
+ fi
+ done
+ fi
+
exit 0
}
@@ -438,7 +606,7 @@ Options:
-l, logging Specify whether the Pi-hole log should be used
Add '-h' for more info on logging usage
-q, query Query the adlists for a specified domain
- Add '-exact' AFTER a specified domain for exact match
+ Add '-h' for more info on query usage
-up, updatePihole Update Pi-hole subsystems
-v, version Show installed versions of Pi-hole, Admin Console & FTL
Add '-h' for more info on version usage
From 8af9853b9a516367031178ba836246f196e1ef55 Mon Sep 17 00:00:00 2001
From: WaLLy3K
Date: Sun, 16 Jul 2017 22:32:34 +1000
Subject: [PATCH 150/162] Fixed minor formatting issues
* Removed useless echo
* Quoted and braced conditionals
* Explicit escaping of newline
* Fixed arrays implicitly concatenating (SC2199)
* Fixed incorrect variable used in checkout web
---
advanced/Scripts/piholeCheckout.sh | 39 +++++++++++++++---------------
1 file changed, 19 insertions(+), 20 deletions(-)
diff --git a/advanced/Scripts/piholeCheckout.sh b/advanced/Scripts/piholeCheckout.sh
index f9add489..44058111 100644
--- a/advanced/Scripts/piholeCheckout.sh
+++ b/advanced/Scripts/piholeCheckout.sh
@@ -26,7 +26,7 @@ source ${coltable}
check_download_exists() {
status=$(curl --head --silent "https://ftl.pi-hole.net/${1}" | head -n 1)
- if echo "$status" | grep -q "404"; then
+ if grep -q "404" <<< "$status"; then
return 1
else
return 0
@@ -74,17 +74,17 @@ get_binary_name() {
local str
str="Detecting architecture"
echo -ne " ${INFO} ${str}..."
- if [[ ${machine} == arm* || ${machine} == *aarch* ]]; then
+ if [[ "${machine}" == "arm"* || "${machine}" == *"aarch"* ]]; then
# ARM
local rev
rev=$(uname -m | sed "s/[^0-9]//g;")
local lib
lib=$(ldd /bin/ls | grep -E '^\s*/lib' | awk '{ print $1 }')
- if [[ "$lib" == "/lib/ld-linux-aarch64.so.1" ]]; then
+ if [[ "${lib}" == "/lib/ld-linux-aarch64.so.1" ]]; then
echo -e "${OVER} ${TICK} Detected ARM-aarch64 architecture"
binary="pihole-FTL-aarch64-linux-gnu"
- elif [[ "$lib" == "/lib/ld-linux-armhf.so.3" ]]; then
- if [ "$rev" -gt "6" ]; then
+ elif [[ "${lib}" == "/lib/ld-linux-armhf.so.3" ]]; then
+ if [[ "$rev" -gt "6" ]]; then
echo -e "${OVER} ${TICK} Detected ARM-hf architecture (armv7+)"
binary="pihole-FTL-arm-linux-gnueabihf"
else
@@ -95,17 +95,17 @@ get_binary_name() {
echo -e "${OVER} ${TICK} Detected ARM architecture"
binary="pihole-FTL-arm-linux-gnueabi"
fi
- elif [[ $machine == ppc ]]; then
+ elif [[ "${machine}" == "ppc" ]]; then
# PowerPC
- echo "::: Detected PowerPC architecture"
+ echo -e "${OVER} ${TICK} Detected PowerPC architecture"
binary="pihole-FTL-powerpc-linux-gnu"
- elif [[ ${machine} == x86_64 ]]; then
+ elif [[ "${machine}" == "x86_64" ]]; then
# 64bit
echo -e "${OVER} ${TICK} Detected x86_64 architecture"
binary="pihole-FTL-linux-x86_64"
else
# Something else - we try to use 32bit executable and warn the user
- if [[ ! ${machine} == i686 ]]; then
+ if [[ ! "${machine}" == "i686" ]]; then
echo -e "${OVER} ${CROSS} ${str}...
${COL_LIGHT_RED}Not able to detect architecture (unknown: ${machine}), trying 32bit executable
Contact support if you experience issues (e.g: FTL not running)${COL_NC}"
@@ -182,7 +182,7 @@ checkout_pull_branch() {
if [[ "$git_pull" == *"up-to-date"* ]]; then
echo -e " ${INFO} $(git pull)"
else
- echo -e "$git_pull\n"
+ echo -e "$git_pull\\n"
fi
return 0
@@ -193,13 +193,13 @@ warning1() {
echo " Features that work on the master branch, may not on a development branch"
echo -e " ${COL_LIGHT_RED}This feature is NOT supported unless a Pi-hole developer explicitly asks!${COL_NC}"
read -r -p " Have you read and understood this? [y/N] " response
- case ${response} in
+ case "${response}" in
[yY][eE][sS]|[yY])
echo ""
return 0
;;
*)
- echo -e "\n ${INFO} Branch change has been cancelled"
+ echo -e "\\n ${INFO} Branch change has been cancelled"
return 1
;;
esac
@@ -218,7 +218,7 @@ checkout() {
Please re-run install script from https://github.com/pi-hole/pi-hole${COL_NC}"
exit 1;
fi
- if [[ ${INSTALL_WEB} == "true" ]]; then
+ if [[ "${INSTALL_WEB}" == "true" ]]; then
if ! is_repo "${webInterfaceDir}" ; then
echo -e " ${COL_LIGHT_RED}Error: Web Admin repo is missing from system!
Please re-run install script from https://github.com/pi-hole/pi-hole${COL_NC}"
@@ -242,7 +242,7 @@ checkout() {
echo ""
echo -e " ${INFO} Pi-hole Core"
fetch_checkout_pull_branch "${PI_HOLE_FILES_DIR}" "development" || { echo " ${CROSS} Unable to pull Core developement branch"; exit 1; }
- if [[ ${INSTALL_WEB} == "true" ]]; then
+ if [[ "${INSTALL_WEB}" == "true" ]]; then
echo ""
echo -e " ${INFO} Web interface"
fetch_checkout_pull_branch "${webInterfaceDir}" "devel" || { echo " ${CROSS} Unable to pull Web development branch"; exit 1; }
@@ -263,7 +263,7 @@ checkout() {
fetch_checkout_pull_branch "${webInterfaceDir}" "master" || { echo " ${CROSS} Unable to pull Web master branch"; exit 1; }
fi
#echo -e " ${TICK} Web Interface"
- get_binary_name
+ get_binary_name
local path
path="master/${binary}"
FTLinstall "${binary}" "${path}"
@@ -276,12 +276,12 @@ checkout() {
fi
corebranches=($(get_available_branches "${PI_HOLE_FILES_DIR}"))
- if [[ "${corebranches[@]}" == *"master"* ]]; then
+ if [[ "${corebranches[*]}" == *"master"* ]]; then
echo -e "${OVER} ${TICK} $str
${INFO} ${#corebranches[@]} branches available for Pi-hole Core"
else
# Print STDERR output from get_available_branches
- echo -e "${OVER} ${CROSS} $str\n\n${corebranches[*]}"
+ echo -e "${OVER} ${CROSS} $str\\n\\n${corebranches[*]}"
exit 1
fi
@@ -303,12 +303,12 @@ checkout() {
fi
webbranches=($(get_available_branches "${webInterfaceDir}"))
- if [[ "${corebranches[@]}" == *"master"* ]]; then
+ if [[ "${webbranches[*]}" == *"master"* ]]; then
echo -e "${OVER} ${TICK} $str
${INFO} ${#webbranches[@]} branches available for Web Admin"
else
# Print STDERR output from get_available_branches
- echo -e "${OVER} ${CROSS} $str\n\n${corebranches[*]}"
+ echo -e "${OVER} ${CROSS} $str\\n\\n${webbranches[*]}"
exit 1
fi
@@ -322,7 +322,6 @@ checkout() {
fi
checkout_pull_branch "${webInterfaceDir}" "${2}"
elif [[ "${1}" == "ftl" ]] ; then
-
get_binary_name
local path
path="${2}/${binary}"
From f2e9d585f79f757302eaf7417f6e7209bc848352 Mon Sep 17 00:00:00 2001
From: Adam Warner
Date: Sun, 16 Jul 2017 13:22:59 +0100
Subject: [PATCH 151/162] * Add helptext for `pihole checkout ftl` * Only
attempt to install FTL if branch was found * ~~corebranches~~ webbranches
(web branches now actually listed)
Signed-off-by: Adam Warner
---
advanced/Scripts/piholeCheckout.sh | 7 +++----
pihole | 7 ++++---
2 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/advanced/Scripts/piholeCheckout.sh b/advanced/Scripts/piholeCheckout.sh
index f9add489..b786ba0c 100644
--- a/advanced/Scripts/piholeCheckout.sh
+++ b/advanced/Scripts/piholeCheckout.sh
@@ -303,12 +303,12 @@ checkout() {
fi
webbranches=($(get_available_branches "${webInterfaceDir}"))
- if [[ "${corebranches[@]}" == *"master"* ]]; then
+ if [[ "${webbranches[@]}" == *"master"* ]]; then
echo -e "${OVER} ${TICK} $str
${INFO} ${#webbranches[@]} branches available for Web Admin"
else
# Print STDERR output from get_available_branches
- echo -e "${OVER} ${CROSS} $str\n\n${corebranches[*]}"
+ echo -e "${OVER} ${CROSS} $str\n\n${webbranches[*]}"
exit 1
fi
@@ -329,12 +329,11 @@ checkout() {
if check_download_exists "$path"; then
echo " ${TICK} Branch ${2} exists"
+ FTLinstall "${binary}" "${path}"
else
echo " ${CROSS} Requested branch \"${2}\" is not available"
fi
- FTLinstall "${binary}" "${path}"
-
else
echo -e " ${INFO} Requested option \"${1}\" is not available"
exit 1
diff --git a/pihole b/pihole
index 1bd35dbb..8da911d8 100755
--- a/pihole
+++ b/pihole
@@ -429,15 +429,15 @@ Time:
# Enable Pi-hole
echo -e " ${INFO} Enabling blocking"
local str="Pi-hole Enabled"
-
+
sed -i 's/^#addn-hosts/addn-hosts/' /etc/dnsmasq.d/01-pihole.conf
if [[ -e "/etc/pihole/wildcard.list" ]]; then
mv "/etc/pihole/wildcard.list" "$wildcardlist"
fi
fi
-
+
restartDNS
-
+
echo -e "${OVER} ${TICK} ${str}"
}
@@ -535,6 +535,7 @@ Switch Pi-hole subsystems to a different Github branch
Repositories:
core [branch] Change the branch of Pi-hole's core subsystem
web [branch] Change the branch of Admin Console subsystem
+ ftl [branch] Change the branch of Pi-hole's FTL subsystem
Branches:
master Update subsystems to the latest stable release
From 247d3ed7299822cad1c3a71a9c999ffd6ff6e8dc Mon Sep 17 00:00:00 2001
From: Adam Warner
Date: Sun, 16 Jul 2017 13:54:23 +0100
Subject: [PATCH 152/162] list availible branches for FTL
Signed-off-by: Adam Warner
---
advanced/Scripts/piholeCheckout.sh | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/advanced/Scripts/piholeCheckout.sh b/advanced/Scripts/piholeCheckout.sh
index c6f55dd9..f214d2ce 100644
--- a/advanced/Scripts/piholeCheckout.sh
+++ b/advanced/Scripts/piholeCheckout.sh
@@ -331,6 +331,10 @@ checkout() {
FTLinstall "${binary}" "${path}"
else
echo " ${CROSS} Requested branch \"${2}\" is not available"
+ ftlbranches=( $(git ls-remote https://github.com/pi-hole/ftl | grep 'heads' | sed 's/refs\/heads\///;s/ //g' | awk '{print $2}') )
+ echo -e " ${INFO} Available branches for FTL are:"
+ for e in "${ftlbranches[@]}"; do echo " - $e"; done
+ exit 1
fi
else
From c9a98b68c8eff21e997c10f3282686ae820f833f Mon Sep 17 00:00:00 2001
From: WaLLy3K
Date: Mon, 17 Jul 2017 01:44:14 +1000
Subject: [PATCH 153/162] Avoid reactivating a deactivated lighttpd service
(#1485)
* Do not activate disabled lighttpd upon update
* Fixes #1362
* Use systemctl when available
* Move `finalexports` to the very end of the install script
set value of LIGHTTPD_ENABLED to 1 or 0 depending on whether or not lighttpd is enabled or disabled.
actually save LIGHTTPD_ENABLED value to setupvars.conf
Signed-off-by: Adam Warner
* add [[ -z "${LIGHTTPD_ENABLED}" ]] back in!
Signed-off-by: Adam Warner
* Ensure "Loaded:" is the line being checked
* Colourise disabled lighttpd message
* Prevent disabled lighttpd triggering error
* change of plan, don't need that [[ -z "${LIGHTTPD_ENABLED}" ]]
Signed-off-by: Adam Warner
---
automated install/basic-install.sh | 35 ++++++++++++++++++++----------
1 file changed, 24 insertions(+), 11 deletions(-)
diff --git a/automated install/basic-install.sh b/automated install/basic-install.sh
index 74e2a61d..a3c41b11 100755
--- a/automated install/basic-install.sh
+++ b/automated install/basic-install.sh
@@ -1485,8 +1485,7 @@ finalExports() {
# If the setup variable file exists,
if [ -e "${setupVars}" ]; then
- # update the variables in the file
- sed -i.update.bak '/PIHOLE_INTERFACE/d;/IPV4_ADDRESS/d;/IPV6_ADDRESS/d;/PIHOLE_DNS_1/d;/PIHOLE_DNS_2/d;/QUERY_LOGGING/d;/INSTALL_WEB/d;' "${setupVars}"
+ sed -i.update.bak '/PIHOLE_INTERFACE/d;/IPV4_ADDRESS/d;/IPV6_ADDRESS/d;/PIHOLE_DNS_1/d;/PIHOLE_DNS_2/d;/QUERY_LOGGING/d;/INSTALL_WEB/d;/LIGHTTPD_ENABLED/d;' "${setupVars}"
fi
# echo the information to the user
{
@@ -1497,6 +1496,7 @@ finalExports() {
echo "PIHOLE_DNS_2=${PIHOLE_DNS_2}"
echo "QUERY_LOGGING=${QUERY_LOGGING}"
echo "INSTALL_WEB=${INSTALL_WEB}"
+ echo "LIGHTTPD_ENABLED=${LIGHTTPD_ENABLED}"
}>> "${setupVars}"
# Look for DNS server settings which would have to be reapplied
@@ -1585,9 +1585,6 @@ installPihole() {
FTLdetect || echo -e " ${CROSS} FTL Engine not installed."
# Configure the firewall
configureFirewall
- # Run the final exports
- finalExports
- #runGravity
}
# At some point in the future this list can be pruned, for now we'll need it to ensure updates don't break.
@@ -1621,8 +1618,8 @@ updatePihole() {
installLogrotate
# Detect if FTL is installed
FTLdetect || echo -e " ${CROSS} FTL Engine not installed."
- finalExports #re-export setupVars.conf to account for any new vars added in new versions
- #runGravity
+
+
}
@@ -2052,10 +2049,24 @@ main() {
enable_service dnsmasq
# If the Web server was installed,
- if [[ ${INSTALL_WEB} == true ]]; then
- # enable it
- start_service lighttpd
- enable_service lighttpd
+ if [[ "${INSTALL_WEB}" == true ]]; then
+ # Check to see if lighttpd was already set to run on reboot
+ if [[ "${useUpdateVars}" == true ]]; then
+ if [[ -x "$(command -v systemctl)" ]]; then
+ # Value will either be 1, if true, or 0
+ LIGHTTPD_ENABLED=$(systemctl is-enabled lighttpd | grep -c 'enabled' || true)
+ else
+ # Value will either be 1, if true, or 0
+ LIGHTTPD_ENABLED=$(service lighttpd status | awk '/Loaded:/ {print $0}' | grep -c 'enabled' || true)
+ fi
+ fi
+
+ if [[ "${LIGHTTPD_ENABLED}" == "1" ]]; then
+ start_service lighttpd
+ enable_service lighttpd
+ else
+ echo -e " ${INFO} Lighttpd is disabled, skipping service restart"
+ fi
fi
# Download and compile the aggregated block list
@@ -2103,6 +2114,8 @@ main() {
# Display where the log file is
echo -e "\n ${INFO} The install log is located at: /etc/pihole/install.log
${COL_LIGHT_GREEN}${INSTALL_TYPE} Complete! ${COL_NC}"
+ #update setupvars.conf with any variables that may or may not have been changed during the install
+ finalExports
}
#
From 70fb733fea71858494f441d429513d6a77674b21 Mon Sep 17 00:00:00 2001
From: Adam Warner
Date: Mon, 17 Jul 2017 10:53:49 +0100
Subject: [PATCH 154/162] col_table does not exist yet, will break the install
if pushed as hotfix. Not sure why these additional "'s were put in, they
break the update command, too.
Signed-off-by: Adam Warner
---
advanced/Scripts/update.sh | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/advanced/Scripts/update.sh b/advanced/Scripts/update.sh
index e3a7f8fd..2ef136a9 100755
--- a/advanced/Scripts/update.sh
+++ b/advanced/Scripts/update.sh
@@ -26,8 +26,6 @@ PH_TEST=true
#shellcheck disable=SC1090
source "${PI_HOLE_FILES_DIR}/automated install/basic-install.sh"
-source "/opt/pihole/COL_TABLE"
-
# is_repo() sourced from basic-install.sh
# make_repo() sourced from basic-install.sh
# update_repo() source from basic-install.sh
@@ -43,7 +41,7 @@ GitCheckUpdateAvail() {
# @ alone is a shortcut for HEAD. Older versions of git
# need @{0}
- LOCAL="$("git rev-parse @{0}")"
+ LOCAL="$(git rev-parse @{0})"
# The suffix @{upstream} to a branchname
# (short form @{u}) refers
@@ -52,7 +50,7 @@ GitCheckUpdateAvail() {
# (configured with branch..remote and
# branch..merge). A missing branchname
# defaults to the current one.
- REMOTE="$("git rev-parse @{upstream}")"
+ REMOTE="$(git rev-parse @{upstream})"
if [[ ${#LOCAL} == 0 ]]; then
echo "::: Error: Local revision could not be obtained, ask Pi-hole support."
From 83592a5e70a627ea1ba5ab1fce6c99112e9e8f6b Mon Sep 17 00:00:00 2001
From: Adam Warner
Date: Mon, 17 Jul 2017 11:14:02 +0100
Subject: [PATCH 155/162] Put '"'s in the right place
Signed-off-by: Adam Warner
---
advanced/Scripts/update.sh | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/advanced/Scripts/update.sh b/advanced/Scripts/update.sh
index 2ef136a9..4281d69f 100755
--- a/advanced/Scripts/update.sh
+++ b/advanced/Scripts/update.sh
@@ -41,7 +41,7 @@ GitCheckUpdateAvail() {
# @ alone is a shortcut for HEAD. Older versions of git
# need @{0}
- LOCAL="$(git rev-parse @{0})"
+ LOCAL="$(git rev-parse "@{0}")"
# The suffix @{upstream} to a branchname
# (short form @{u}) refers
@@ -50,7 +50,7 @@ GitCheckUpdateAvail() {
# (configured with branch..remote and
# branch..merge). A missing branchname
# defaults to the current one.
- REMOTE="$(git rev-parse @{upstream})"
+ REMOTE="$(git rev-parse "@{upstream}")"
if [[ ${#LOCAL} == 0 ]]; then
echo "::: Error: Local revision could not be obtained, ask Pi-hole support."
From 1c93868ae1b1bc673f26ae4c5a9d235897ca99aa Mon Sep 17 00:00:00 2001
From: Adam Warner
Date: Mon, 24 Jul 2017 23:22:04 +0100
Subject: [PATCH 156/162] Adjust wording of echos
Signed-off-by: Adam Warner
---
automated install/basic-install.sh | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/automated install/basic-install.sh b/automated install/basic-install.sh
index 3a53fca5..f0d6018f 100755
--- a/automated install/basic-install.sh
+++ b/automated install/basic-install.sh
@@ -1882,6 +1882,7 @@ FTLdetect() {
#In the next section we check to see if FTL is already installed (in case of pihole -r).
#If the installed version matches the latest version, then check the installed sha1sum of the binary vs the remote sha1sum. If they do not match, then download
+ echo -e " ${INFO} Checking for existing FTL binary..."
local FTLversion=$(/usr/bin/pihole-FTL tag)
local FTLlatesttag=$(curl -sI https://github.com/pi-hole/FTL/releases/latest | grep 'Location' | awk -F '/' '{print $NF}' | tr -d '\r\n')
@@ -1889,15 +1890,16 @@ FTLdetect() {
# Install FTL
FTLinstall "${binary}" || return 1
else
+ echo -e " ${INFO} Latest FTL Binary already installed (${FTLlatesttag}). Confirming Checksum..."
+
local remoteSha1=$(curl -sSL --fail "https://github.com/pi-hole/FTL/releases/download/${FTLversion%$'\r'}/${binary}.sha1" | cut -d ' ' -f 1)
local localSha1=$(sha1sum "$(which pihole-FTL)" | cut -d ' ' -f 1)
- echo -e " ${INFO} Existing FTL Binary detected. Checking sha1sum..."
if [[ "${remoteSha1}" != "${localSha1}" ]]; then
echo -e " ${INFO} Corruption detected..."
FTLinstall "${binary}" || return 1
else
- echo -e " ${INFO} sha1sums match. No need to download!"
+ echo -e " ${INFO} Checksum correct. No need to download!"
fi
fi
}
From a293b5a3718f3381f9f9fd2cc955127d062e1a99 Mon Sep 17 00:00:00 2001
From: Adam Warner
Date: Tue, 25 Jul 2017 22:49:06 +0100
Subject: [PATCH 157/162] prevent `./automated install/basic-install.sh: line
1886: /usr/bin/pihole-FTL: No such file or directory` on new install, or if
pihole-FTL is missing for whatever reason.
Signed-off-by: Adam Warner
---
automated install/basic-install.sh | 38 +++++++++++++++++++-----------
1 file changed, 24 insertions(+), 14 deletions(-)
diff --git a/automated install/basic-install.sh b/automated install/basic-install.sh
index f0d6018f..170754f2 100755
--- a/automated install/basic-install.sh
+++ b/automated install/basic-install.sh
@@ -1883,25 +1883,35 @@ FTLdetect() {
#In the next section we check to see if FTL is already installed (in case of pihole -r).
#If the installed version matches the latest version, then check the installed sha1sum of the binary vs the remote sha1sum. If they do not match, then download
echo -e " ${INFO} Checking for existing FTL binary..."
- local FTLversion=$(/usr/bin/pihole-FTL tag)
- local FTLlatesttag=$(curl -sI https://github.com/pi-hole/FTL/releases/latest | grep 'Location' | awk -F '/' '{print $NF}' | tr -d '\r\n')
- if [[ "${FTLversion}" != "${FTLlatesttag}" ]]; then
- # Install FTL
- FTLinstall "${binary}" || return 1
- else
- echo -e " ${INFO} Latest FTL Binary already installed (${FTLlatesttag}). Confirming Checksum..."
+ local ftlLoc=$(which pihole-FTL)
- local remoteSha1=$(curl -sSL --fail "https://github.com/pi-hole/FTL/releases/download/${FTLversion%$'\r'}/${binary}.sha1" | cut -d ' ' -f 1)
- local localSha1=$(sha1sum "$(which pihole-FTL)" | cut -d ' ' -f 1)
+ if [[ ${ftlLoc} ]]; then
+ local FTLversion=$(/usr/bin/pihole-FTL tag)
+ local FTLlatesttag=$(curl -sI https://github.com/pi-hole/FTL/releases/latest | grep 'Location' | awk -F '/' '{print $NF}' | tr -d '\r\n')
- if [[ "${remoteSha1}" != "${localSha1}" ]]; then
- echo -e " ${INFO} Corruption detected..."
- FTLinstall "${binary}" || return 1
+ if [[ "${FTLversion}" != "${FTLlatesttag}" ]]; then
+ # Install FTL
+ FTLinstall "${binary}" || return 1
else
- echo -e " ${INFO} Checksum correct. No need to download!"
+ echo -e " ${INFO} Latest FTL Binary already installed (${FTLlatesttag}). Confirming Checksum..."
+
+ local remoteSha1=$(curl -sSL --fail "https://github.com/pi-hole/FTL/releases/download/${FTLversion%$'\r'}/${binary}.sha1" | cut -d ' ' -f 1)
+ local localSha1=$(sha1sum "$(which pihole-FTL)" | cut -d ' ' -f 1)
+
+ if [[ "${remoteSha1}" != "${localSha1}" ]]; then
+ echo -e " ${INFO} Corruption detected..."
+ FTLinstall "${binary}" || return 1
+ else
+ echo -e " ${INFO} Checksum correct. No need to download!"
+ fi
fi
- fi
+ else
+ # Install FTL
+ FTLinstall "${binary}" || return 1
+ fi
+
+
}
main() {
From 714fd93292880e999706419480f4c59a0defb77f Mon Sep 17 00:00:00 2001
From: WaLLy3K
Date: Wed, 26 Jul 2017 08:03:23 +1000
Subject: [PATCH 158/162] Provide correct FTL stats (#1619)
* Provide correct FTL stats
* Use the correct lines in the array when displaying FTL stats
* Treat ads_blocked_today/dns_queries_today as currency, like domains_being_blocked is on large screens
* Chronometer Shellcheck validation
* Remove unnecessary \ from CPU usage readout
---
advanced/Scripts/chronometer.sh | 42 ++++++++++++++++++---------------
1 file changed, 23 insertions(+), 19 deletions(-)
diff --git a/advanced/Scripts/chronometer.sh b/advanced/Scripts/chronometer.sh
index d9b01fc0..a9ccf900 100755
--- a/advanced/Scripts/chronometer.sh
+++ b/advanced/Scripts/chronometer.sh
@@ -1,4 +1,5 @@
#!/usr/bin/env bash
+# shellcheck disable=SC1090,SC1091
# 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.
@@ -91,10 +92,10 @@ printFunc() {
printf "%s%s$spc" "$title" "$text_main"
if [[ -n "$text_addn" ]]; then
- printf "%s(%s)%s\n" "$COL_NC$COL_DARK_GRAY" "$text_addn" "$COL_NC"
+ printf "%s(%s)%s\\n" "$COL_NC$COL_DARK_GRAY" "$text_addn" "$COL_NC"
else
# Do not print trailing newline on final line
- [[ -z "$text_last" ]] && printf "%s\n" "$COL_NC"
+ [[ -z "$text_last" ]] && printf "%s\\n" "$COL_NC"
fi
}
@@ -126,7 +127,7 @@ get_init_stats() {
mins=$(( ($1%3600)/60 )); secs=$(( $1%60 ))
[[ "$day" -ge "2" ]] && plu="s"
[[ "$day" -ge "1" ]] && days="$day day${plu}, " || days=""
- printf "%s%02d:%02d:%02d\n" "$days" "$hrs" "$mins" "$secs"
+ printf "%s%02d:%02d:%02d\\n" "$days" "$hrs" "$mins" "$secs"
}
# Set Colour Codes
@@ -285,6 +286,7 @@ get_sys_stats() {
sys_loadavg=$(cut -d " " -f1,2,3 /proc/loadavg)
# Get CPU usage, only counting processes over 1% as active
+ # shellcheck disable=SC2009
cpu_raw=$(ps -eo pcpu,rss --no-headers | grep -E -v " 0")
cpu_tasks=$(wc -l <<< "$cpu_raw")
cpu_taskact=$(sed -r "/(^ 0.)/d" <<< "$cpu_raw" | wc -l)
@@ -306,7 +308,7 @@ get_sys_stats() {
# Determine colour for temperature
if [[ -n "$temp_file" ]]; then
if [[ "$temp_unit" == "C" ]]; then
- cpu_temp=$(printf "%.0fc\n" "$(calcFunc "$(< $temp_file) / 1000")")
+ cpu_temp=$(printf "%.0fc\\n" "$(calcFunc "$(< $temp_file) / 1000")")
case "${cpu_temp::-1}" in
-*|[0-9]|[1-3][0-9]) cpu_col="$COL_LIGHT_BLUE";;
@@ -320,7 +322,7 @@ get_sys_stats() {
cpu_temp_str=" @ $cpu_col$cpu_temp$COL_NC$COL_DARK_GRAY"
elif [[ "$temp_unit" == "F" ]]; then
- cpu_temp=$(printf "%.0ff\n" "$(calcFunc "($(< $temp_file) / 1000) * 9 / 5 + 32")")
+ cpu_temp=$(printf "%.0ff\\n" "$(calcFunc "($(< $temp_file) / 1000) * 9 / 5 + 32")")
case "${cpu_temp::-1}" in
-*|[0-9]|[0-9][0-9]) cpu_col="$COL_LIGHT_BLUE";;
@@ -333,7 +335,7 @@ get_sys_stats() {
cpu_temp_str=" @ $cpu_col$cpu_temp$COL_NC$COL_DARK_GRAY"
else
- cpu_temp_str=$(printf " @ %.0fk\n" "$(calcFunc "($(< $temp_file) / 1000) + 273.15")")
+ cpu_temp_str=$(printf " @ %.0fk\\n" "$(calcFunc "($(< $temp_file) / 1000) + 273.15")")
fi
else
cpu_temp_str=""
@@ -365,12 +367,12 @@ get_ftl_stats() {
local stats_raw
mapfile -t stats_raw < <(pihole-FTL "stats")
- domains_being_blocked_raw="${stats_raw[1]#* }"
- dns_queries_today_raw="${stats_raw[3]#* }"
- ads_blocked_today_raw="${stats_raw[5]#* }"
- ads_percentage_today_raw="${stats_raw[7]#* }"
- queries_forwarded_raw="${stats_raw[11]#* }"
- queries_cached_raw="${stats_raw[13]#* }"
+ domains_being_blocked_raw="${stats_raw[0]#* }"
+ dns_queries_today_raw="${stats_raw[1]#* }"
+ ads_blocked_today_raw="${stats_raw[2]#* }"
+ ads_percentage_today_raw="${stats_raw[3]#* }"
+ queries_forwarded_raw="${stats_raw[5]#* }"
+ queries_cached_raw="${stats_raw[6]#* }"
# Only retrieve these stats when not called from jsonFunc
if [[ -z "$1" ]]; then
@@ -378,11 +380,11 @@ get_ftl_stats() {
local top_domain_raw
local top_client_raw
- domains_being_blocked=$(printf "%.0f\n" "${domains_being_blocked_raw}")
- dns_queries_today=$(printf "%.0f\n" "${dns_queries_today_raw}")
- ads_blocked_today=$(printf "%.0f\n" "${ads_blocked_today_raw}")
- ads_percentage_today=$(printf "%'.0f\n" "${ads_percentage_today_raw}")
- queries_cached_percentage=$(printf "%.0f\n" "$(calcFunc "$queries_cached_raw * 100 / ( $queries_forwarded_raw + $queries_cached_raw )")")
+ domains_being_blocked=$(printf "%.0f\\n" "${domains_being_blocked_raw}")
+ dns_queries_today=$(printf "%.0f\\n" "${dns_queries_today_raw}")
+ ads_blocked_today=$(printf "%.0f\\n" "${ads_blocked_today_raw}")
+ ads_percentage_today=$(printf "%'.0f\\n" "${ads_percentage_today_raw}")
+ queries_cached_percentage=$(printf "%.0f\\n" "$(calcFunc "$queries_cached_raw * 100 / ( $queries_forwarded_raw + $queries_cached_raw )")")
recent_blocked=$(pihole-FTL recentBlocked)
read -r -a top_ad_raw <<< "$(pihole-FTL "top-ads (1)")"
read -r -a top_domain_raw <<< "$(pihole-FTL "top-domains (1)")"
@@ -412,6 +414,8 @@ get_strings() {
used_str="Used: "
leased_str="Leased: "
domains_being_blocked=$(printf "%'.0f" "$domains_being_blocked")
+ ads_blocked_today=$(printf "%'.0f" "$ads_blocked_today")
+ dns_queries_today=$(printf "%'.0f" "$dns_queries_today")
ph_info="Blocking: $domains_being_blocked sites"
total_str="Total: "
else
@@ -473,8 +477,8 @@ chronoFunc() {
${COL_DARK_GRAY}$scr_line_str${COL_NC}"
else
echo -e "[0;1;31;91m|¯[0;1;33;93m¯[0;1;32;92m¯[0;1;32;92m(¯[0;1;36;96m)[0;1;34;94m_[0;1;35;95m|[0;1;33;93m¯[0;1;31;91m|_ [0;1;32;92m__[0;1;36;96m_|[0;1;31;91m¯[0;1;34;94m|[0;1;35;95m__[0;1;31;91m_[0m$phc_ver_str
-[0;1;33;93m| ¯[0;1;32;92m_[0;1;36;96m/¯[0;1;34;94m|[0;1;35;95m_[0;1;31;91m| [0;1;33;93m' [0;1;32;92m\/ [0;1;36;96m_ [0;1;34;94m\ [0;1;35;95m/ [0;1;31;91m-[0;1;33;93m_)[0m$lte_ver_str
-[0;1;32;92m|_[0;1;36;96m| [0;1;34;94m|_[0;1;35;95m| [0;1;33;93m|_[0;1;32;92m||[0;1;36;96m_\[0;1;34;94m__[0;1;35;95m_/[0;1;31;91m_\[0;1;33;93m__[0;1;32;92m_|[0m$ftl_ver_str
+[0;1;33;93m| ¯[0;1;32;92m_[0;1;36;96m/¯[0;1;34;94m|[0;1;35;95m_[0;1;31;91m| [0;1;33;93m' [0;1;32;92m\\/ [0;1;36;96m_ [0;1;34;94m\\ [0;1;35;95m/ [0;1;31;91m-[0;1;33;93m_)[0m$lte_ver_str
+[0;1;32;92m|_[0;1;36;96m| [0;1;34;94m|_[0;1;35;95m| [0;1;33;93m|_[0;1;32;92m||[0;1;36;96m_\\[0;1;34;94m__[0;1;35;95m_/[0;1;31;91m_\\[0;1;33;93m__[0;1;32;92m_|[0m$ftl_ver_str
${COL_DARK_GRAY}$scr_line_str${COL_NC}"
fi
From e0eb5eb2b1bb5fc5772aac479f71d4dfb77237ac Mon Sep 17 00:00:00 2001
From: WaLLy3K
Date: Wed, 26 Jul 2017 08:07:06 +1000
Subject: [PATCH 159/162] Fix queryFunc if adlists URLs have been removed
(#1618)
* Fix queryFunc if adlists URLs have been removed
* Allow for -adlists command line switch (where the "s" is a typo)
* Add error message when unable to find associated adlists URL
* Provide PR fix on current dev version
* Add blResult variable for white/black match
* Supporting Block Page queryFunc fixes
* Re-add unmerged lines
---
pihole | 15 +++++++++++----
1 file changed, 11 insertions(+), 4 deletions(-)
diff --git a/pihole b/pihole
index 8da911d8..61ed6cd6 100755
--- a/pihole
+++ b/pihole
@@ -149,7 +149,7 @@ Options:
fi
# Strip valid options, leaving only the domain and invalid options
- options=$(sed 's/ \?-\(exact\|adlist\|bp\|all\) \?//g' <<< "$options")
+ options=$(sed 's/ \?-\(exact\|adlist\(s\)\?\|bp\|all\) \?//g' <<< "$options")
# Handle errors
if [[ "${options}" == *" "* ]]; then
@@ -181,13 +181,14 @@ Options:
results=($(scanList "${query}" "${lists}" "${method}"))
if [[ -n "${results[*]}" ]]; then
+ blResult=true
# Loop through each scanList line to print appropriate title
for result in "${results[@]}"; do
filename="${result/:*/}"
if [[ -n "$exact" ]]; then
printf " Exact result in %s\n" "${filename}"
elif [[ -n "$blockpage" ]]; then
- printf " [i] %s\n" "${filename}"
+ printf "π %s\n" "${filename}"
else
domain="${result/*:/}"
if [[ ! "${filename}" == "${filename_prev:-}" ]]; then
@@ -216,7 +217,7 @@ Options:
fi
if [[ -n "${blockpage}" ]]; then
- echo " ${INFO} ${match}"
+ echo "π ${wildcardlist/*\/}"
else
echo " *.${match}"
fi
@@ -287,12 +288,18 @@ Options:
filenum=("${filename/list./}")
filenum=("${filenum/.*/}")
filename="${adlists[$filenum]}"
+
+ # If gravity has generated associated .domains files
+ # but adlists.list has been modified since
+ if [[ -z "${filename}" ]]; then
+ filename="${COL_LIGHT_RED}Error: no associated adlists URL found${COL_NC}"
+ fi
fi
if [[ -n "${exact}" ]]; then
printf " %s\n" "${filename}"
elif [[ -n "${blockpage}" ]]; then
- printf " [%s] %s\n" "${filenum}" "${filename}"
+ printf "%s %s\n" "${filenum}" "${filename}"
else # Standard query output
# Print filename heading once per file, not for every match
From c02a24cf7176f73c8ec8d1abf28a807e69611c17 Mon Sep 17 00:00:00 2001
From: Adam Warner
Date: Wed, 26 Jul 2017 14:34:40 +0100
Subject: [PATCH 160/162] Fix/unbreak development (#1635)
* Always process DNS and DHCP settings in installer
* change where finalExports is called and where LIGHTTPD_ENABLED is set.
Signed-off-by: Adam Warner
* this may or may not work. If it does, can be functionised to reduce code duping
Signed-off-by: Adam Warner
* This will fix the tests, but break the patch
Signed-off-by: Adam Warner
---
automated install/basic-install.sh | 43 +++++++++++++++++-------------
1 file changed, 25 insertions(+), 18 deletions(-)
diff --git a/automated install/basic-install.sh b/automated install/basic-install.sh
index 4330637d..e37282a7 100755
--- a/automated install/basic-install.sh
+++ b/automated install/basic-install.sh
@@ -1499,22 +1499,20 @@ finalExports() {
echo "LIGHTTPD_ENABLED=${LIGHTTPD_ENABLED}"
}>> "${setupVars}"
- # Look for DNS server settings which would have to be reapplied
+ # Bring in the current settings and the functions to manipulate them
source "${setupVars}"
- #
source "${PI_HOLE_LOCAL_REPO}/advanced/Scripts/webpage.sh"
- #
if [[ "${DNS_FQDN_REQUIRED}" != "" ]] ; then
- #
+ # Look for DNS server settings which would have to be reapplied
ProcessDNSSettings
fi
- #
if [[ "${DHCP_ACTIVE}" != "" ]] ; then
- #
+ # Look for DHCP server settings which would have to be reapplied
ProcessDHCPSettings
fi
+
}
# Install the logrotate script
@@ -1585,6 +1583,9 @@ installPihole() {
FTLdetect || echo -e " ${CROSS} FTL Engine not installed."
# Configure the firewall
configureFirewall
+
+ #update setupvars.conf with any variables that may or may not have been changed during the install
+ finalExports
}
# At some point in the future this list can be pruned, for now we'll need it to ensure updates don't break.
@@ -1619,6 +1620,8 @@ updatePihole() {
# Detect if FTL is installed
FTLdetect || echo -e " ${CROSS} FTL Engine not installed."
+ #update setupvars.conf with any variables that may or may not have been changed during the install
+ finalExports
}
@@ -2034,6 +2037,13 @@ main() {
fi
install_dependent_packages DEPS[@]
+ if [[ -x "$(command -v systemctl)" ]]; then
+ # Value will either be 1, if true, or 0
+ LIGHTTPD_ENABLED=$(systemctl is-enabled lighttpd | grep -c 'enabled' || true)
+ else
+ # Value will either be 1, if true, or 0
+ LIGHTTPD_ENABLED=$(service lighttpd status | awk '/Loaded:/ {print $0}' | grep -c 'enabled' || true)
+ fi
# Install and log everything to a file
installPihole | tee ${tmpLog}
@@ -2055,6 +2065,14 @@ main() {
fi
install_dependent_packages DEPS[@]
+ if [[ -x "$(command -v systemctl)" ]]; then
+ # Value will either be 1, if true, or 0
+ LIGHTTPD_ENABLED=$(systemctl is-enabled lighttpd | grep -c 'enabled' || true)
+ else
+ # Value will either be 1, if true, or 0
+ LIGHTTPD_ENABLED=$(service lighttpd status | awk '/Loaded:/ {print $0}' | grep -c 'enabled' || true)
+ fi
+
updatePihole | tee ${tmpLog}
fi
@@ -2080,16 +2098,6 @@ main() {
# If the Web server was installed,
if [[ "${INSTALL_WEB}" == true ]]; then
- # Check to see if lighttpd was already set to run on reboot
- if [[ "${useUpdateVars}" == true ]]; then
- if [[ -x "$(command -v systemctl)" ]]; then
- # Value will either be 1, if true, or 0
- LIGHTTPD_ENABLED=$(systemctl is-enabled lighttpd | grep -c 'enabled' || true)
- else
- # Value will either be 1, if true, or 0
- LIGHTTPD_ENABLED=$(service lighttpd status | awk '/Loaded:/ {print $0}' | grep -c 'enabled' || true)
- fi
- fi
if [[ "${LIGHTTPD_ENABLED}" == "1" ]]; then
start_service lighttpd
@@ -2144,8 +2152,7 @@ main() {
# Display where the log file is
echo -e "\n ${INFO} The install log is located at: /etc/pihole/install.log
${COL_LIGHT_GREEN}${INSTALL_TYPE} Complete! ${COL_NC}"
- #update setupvars.conf with any variables that may or may not have been changed during the install
- finalExports
+
}
#
From b09c660833b322eec21a1f84e1044557c274478a Mon Sep 17 00:00:00 2001
From: Mcat12
Date: Wed, 26 Jul 2017 12:15:23 -0400
Subject: [PATCH 161/162] Always process DNS and DHCP settings in installer
(#1630)
* Always process DNS and DHCP settings in installer
* Make sure dnsmasq config exists before modifying it
Signed-off-by: Mcat12
* Make sure the dnsmasq config directory exists
Signed-off-by: Mcat12
* Only remove the DHCP config if it exists (fixes tests, hopefully)
Signed-off-by: Mcat12
---
advanced/Scripts/webpage.sh | 4 +++-
automated install/basic-install.sh | 11 +++--------
test/test_automated_install.py | 2 ++
3 files changed, 8 insertions(+), 9 deletions(-)
diff --git a/advanced/Scripts/webpage.sh b/advanced/Scripts/webpage.sh
index 42272122..b887a2b8 100755
--- a/advanced/Scripts/webpage.sh
+++ b/advanced/Scripts/webpage.sh
@@ -292,7 +292,9 @@ ra-param=*,0,0
fi
else
- rm "${dhcpconfig}" &> /dev/null
+ if [[ -f "${dhcpconfig}" ]]; then
+ rm "${dhcpconfig}" &> /dev/null
+ fi
fi
}
diff --git a/automated install/basic-install.sh b/automated install/basic-install.sh
index e37282a7..9d264846 100755
--- a/automated install/basic-install.sh
+++ b/automated install/basic-install.sh
@@ -1503,16 +1503,11 @@ finalExports() {
source "${setupVars}"
source "${PI_HOLE_LOCAL_REPO}/advanced/Scripts/webpage.sh"
- if [[ "${DNS_FQDN_REQUIRED}" != "" ]] ; then
# Look for DNS server settings which would have to be reapplied
- ProcessDNSSettings
- fi
-
- if [[ "${DHCP_ACTIVE}" != "" ]] ; then
- # Look for DHCP server settings which would have to be reapplied
- ProcessDHCPSettings
- fi
+ ProcessDNSSettings
+ # Look for DHCP server settings which would have to be reapplied
+ ProcessDHCPSettings
}
# Install the logrotate script
diff --git a/test/test_automated_install.py b/test/test_automated_install.py
index 4a4f72aa..9129c314 100644
--- a/test/test_automated_install.py
+++ b/test/test_automated_install.py
@@ -59,6 +59,8 @@ def test_setupVars_saved_to_file(Pihole):
TERM=xterm
source /opt/pihole/basic-install.sh
{}
+ mkdir -p /etc/dnsmasq.d
+ version_check_dnsmasq
finalExports
cat /etc/pihole/setupVars.conf
'''.format(set_setup_vars))
From fdf2649f2fef8981176735fb856997e4856fc13b Mon Sep 17 00:00:00 2001
From: WaLLy3K
Date: Thu, 27 Jul 2017 03:00:08 +1000
Subject: [PATCH 162/162] Clean up known remaining colour output issues (#1613)
* Print newline on error message
* Output last three lines of error if update fails
* Consistent error messages & housekeeping
* Add shellcheck directive to ignore COL_TABLE
* Quoted and braced variables for codebase consistency
* Escaped newlines correctly
* Made error messages consistent (indenting and wording)
* Removed consecutive echos
* Conditional formatting consistency
* Braced, quoted and used [[ on conditionals
* Fix specific ShellCheck issues
* Fixed issues that could be safely changed without extensive testing
* Update SELinux whiptail behaviour & more
* Colourised some strings
* Fixed multiple line string indenting
* Made output consistent with existing codebase
* Removed sequential echos
* Make SELinux whiptail use "--defaultno", and change text wording
* Add help text for hostrecord, and colourise output
* this should fix the tests...
Signed-off-by: Adam Warner
* revert changes to `update_package_cache()` to prove tests
Signed-off-by: Adam Warner
---
advanced/Scripts/update.sh | 76 ++++----
advanced/Scripts/webpage.sh | 20 +-
automated install/basic-install.sh | 283 ++++++++++++++---------------
test/test_automated_install.py | 6 +-
4 files changed, 194 insertions(+), 191 deletions(-)
diff --git a/advanced/Scripts/update.sh b/advanced/Scripts/update.sh
index 71b7cecd..a4ada4c8 100755
--- a/advanced/Scripts/update.sh
+++ b/advanced/Scripts/update.sh
@@ -19,10 +19,9 @@ readonly PI_HOLE_FILES_DIR="/etc/.pihole"
# shellcheck disable=SC2034
PH_TEST=true
-# Have to ignore the following rule as spaces in paths are not supported by ShellCheck
-#shellcheck disable=SC1090
+# shellcheck disable=SC1090
source "${PI_HOLE_FILES_DIR}/automated install/basic-install.sh"
-
+# shellcheck disable=SC1091
source "/opt/pihole/COL_TABLE"
# is_repo() sourced from basic-install.sh
@@ -51,15 +50,15 @@ GitCheckUpdateAvail() {
# defaults to the current one.
REMOTE="$(git rev-parse "@{upstream}")"
- if [[ ${#LOCAL} == 0 ]]; then
- echo -e " ${COL_LIGHT_RED}Error: Local revision could not be obtained, ask Pi-hole support."
- echo -e " Additional debugging output:${COL_NC}"
+ if [[ "${#LOCAL}" == 0 ]]; then
+ echo -e "\\n ${COL_LIGHT_RED}Error: Local revision could not be obtained, please contact Pi-hole Support
+ Additional debugging output:${COL_NC}"
git status
exit
fi
- if [[ ${#REMOTE} == 0 ]]; then
- echo -e " ${COL_LIGHT_RED}Error: Remote revision could not be obtained, ask Pi-hole support."
- echo -e " Additional debugging output:${COL_NC}"
+ if [[ "${#REMOTE}" == 0 ]]; then
+ echo -e "\\n ${COL_LIGHT_RED}Error: Remote revision could not be obtained, please contact Pi-hole Support
+ Additional debugging output:${COL_NC}"
git status
exit
fi
@@ -94,13 +93,15 @@ FTLcheckUpdate() {
main() {
local pihole_version_current
local web_version_current
- #shellcheck disable=1090,2154
+ local basicError="\\n ${COL_LIGHT_RED}Unable to complete update, please contact Pi-hole Support${COL_NC}"
+
+ # shellcheck disable=1090,2154
source "${setupVars}"
- #This is unlikely
+ # This is unlikely
if ! is_repo "${PI_HOLE_FILES_DIR}" ; then
- echo -e " ${COL_LIGHT_RED}Critical Error: Core Pi-hole repo is missing from system!"
- echo -e " Please re-run install script from https://github.com/pi-hole/pi-hole${COL_NC}"
+ echo -e "\\n ${COL_LIGHT_RED}Error: Core Pi-hole repo is missing from system!
+ Please re-run install script from https://pi-hole.net${COL_NC}"
exit 1;
fi
@@ -108,18 +109,18 @@ main() {
if GitCheckUpdateAvail "${PI_HOLE_FILES_DIR}" ; then
core_update=true
- echo -e " ${INFO} Pi-hole Core:\t${COL_YELLOW}update available${COL_NC}"
+ echo -e " ${INFO} Pi-hole Core:\\t${COL_YELLOW}update available${COL_NC}"
else
core_update=false
- echo -e " ${INFO} Pi-hole Core:\t${COL_LIGHT_GREEN}up to date${COL_NC}"
+ echo -e " ${INFO} Pi-hole Core:\\t${COL_LIGHT_GREEN}up to date${COL_NC}"
fi
if FTLcheckUpdate ; then
FTL_update=true
- echo -e " ${INFO} FTL:\t\t${COL_YELLOW}update available${COL_NC}"
+ echo -e " ${INFO} FTL:\\t\\t${COL_YELLOW}update available${COL_NC}"
else
FTL_update=false
- echo -e " ${INFO} FTL:\t\t${COL_LIGHT_GREEN}up to date${COL_NC}"
+ echo -e " ${INFO} FTL:\\t\\t${COL_LIGHT_GREEN}up to date${COL_NC}"
fi
# Logic: Don't update FTL when there is a core update available
@@ -132,19 +133,19 @@ main() {
echo ""
fi
- if [[ ${INSTALL_WEB} == true ]]; then
+ if [[ "${INSTALL_WEB}" == true ]]; then
if ! is_repo "${ADMIN_INTERFACE_DIR}" ; then
- echo -e " ${COL_LIGHT_RED}Critical Error: Web Admin repo is missing from system!"
- echo -e " Please re-run install script from https://github.com/pi-hole/pi-hole${COL_NC}"
+ echo -e "\\n ${COL_LIGHT_RED}Error: Web Admin repo is missing from system!
+ Please re-run install script from https://pi-hole.net${COL_NC}"
exit 1;
fi
if GitCheckUpdateAvail "${ADMIN_INTERFACE_DIR}" ; then
web_update=true
- echo -e " ${INFO} Web Interface:\t${COL_YELLOW}update available${COL_NC}"
+ echo -e " ${INFO} Web Interface:\\t${COL_YELLOW}update available${COL_NC}"
else
web_update=false
- echo -e " ${INFO} Web Interface:\t${COL_LIGHT_GREEN}up to date${COL_NC}"
+ echo -e " ${INFO} Web Interface:\\t${COL_LIGHT_GREEN}up to date${COL_NC}"
fi
# Logic
@@ -163,25 +164,24 @@ main() {
echo -e " ${TICK} Everything is up to date!"
exit 0
fi
-
elif ! ${core_update} && ${web_update} ; then
echo ""
echo -e " ${INFO} Pi-hole Web Admin files out of date"
getGitFiles "${ADMIN_INTERFACE_DIR}" "${ADMIN_INTERFACE_GIT_URL}"
-
elif ${core_update} && ! ${web_update} ; then
echo ""
echo -e " ${INFO} Pi-hole core files out of date"
getGitFiles "${PI_HOLE_FILES_DIR}" "${PI_HOLE_GIT_URL}"
- ${PI_HOLE_FILES_DIR}/automated\ install/basic-install.sh --reconfigure --unattended || echo -e " ${COL_LIGHT_RED}Unable to complete update, contact Pi-hole${COL_NC}" && exit 1
-
+ ${PI_HOLE_FILES_DIR}/automated\ install/basic-install.sh --reconfigure --unattended || \
+ echo -e "${basicError}" && exit 1
elif ${core_update} && ${web_update} ; then
echo ""
echo -e " ${INFO} Updating Pi-hole core and web admin files"
getGitFiles "${PI_HOLE_FILES_DIR}" "${PI_HOLE_GIT_URL}"
- ${PI_HOLE_FILES_DIR}/automated\ install/basic-install.sh --unattended || echo -e " ${COL_LIGHT_RED}Unable to complete update, contact Pi-hole${COL_NC}" && exit 1
+ ${PI_HOLE_FILES_DIR}/automated\ install/basic-install.sh --unattended || \
+ echo -e "${basicError}" && exit 1
else
- echo -e " ${COL_LIGHT_RED}Update script has malfunctioned, fallthrough reached. Please contact support${COL_NC}"
+ echo -e " ${COL_LIGHT_RED}Update script has malfunctioned, please contact Pi-hole Support${COL_NC}"
exit 1
fi
else # Web Admin not installed, so only verify if core is up to date
@@ -193,38 +193,36 @@ main() {
fi
else
echo ""
- echo -e " ${INFO} Pi-hole core files out of date"
+ echo -e " ${INFO} Pi-hole Core files out of date"
getGitFiles "${PI_HOLE_FILES_DIR}" "${PI_HOLE_GIT_URL}"
- ${PI_HOLE_FILES_DIR}/automated\ install/basic-install.sh --reconfigure --unattended || echo -e " ${COL_LIGHT_RED}Unable to complete update, contact Pi-hole${COL_NC}" && exit 1
+ ${PI_HOLE_FILES_DIR}/automated\ install/basic-install.sh --reconfigure --unattended || \
+ echo -e "${basicError}" && exit 1
fi
fi
if [[ "${web_update}" == true ]]; then
web_version_current="$(/usr/local/bin/pihole version --admin --current)"
echo ""
- echo -e " ${INFO} Web Admin version is now at ${web_version_current/* v/v}"
- echo -e " ${INFO} If you had made any changes in '/var/www/html/admin/', they have been stashed using 'git stash'"
+ echo -e " ${INFO} Web Admin version is now at ${web_version_current/* v/v}
+ ${INFO} If you had made any changes in '/var/www/html/admin/', they have been stashed using 'git stash'"
fi
if [[ "${core_update}" == true ]]; then
pihole_version_current="$(/usr/local/bin/pihole version --pihole --current)"
echo ""
- echo -e " ${INFO} Pi-hole version is now at ${pihole_version_current/* v/v}"
- echo -e " ${INFO} If you had made any changes in '/etc/.pihole/', they have been stashed using 'git stash'"
+ echo -e " ${INFO} Pi-hole version is now at ${pihole_version_current/* v/v}
+ ${INFO} If you had made any changes in '/etc/.pihole/', they have been stashed using 'git stash'"
fi
- if [[ ${FTL_update} == true ]]; then
+ if [[ "${FTL_update}" == true ]]; then
FTL_version_current="$(/usr/bin/pihole-FTL tag)"
- echo ""
- echo -e " ${INFO} FTL version is now at ${FTL_version_current/* v/v}"
+ echo -e "\\n ${INFO} FTL version is now at ${FTL_version_current/* v/v}"
start_service pihole-FTL
enable_service pihole-FTL
fi
-
echo ""
exit 0
-
}
main
diff --git a/advanced/Scripts/webpage.sh b/advanced/Scripts/webpage.sh
index b887a2b8..9d101482 100755
--- a/advanced/Scripts/webpage.sh
+++ b/advanced/Scripts/webpage.sh
@@ -29,6 +29,7 @@ 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
+ -r, hostrecord Add a name to the DNS associated to an IPv4/IPv6 address
-h, --help Show this help dialog
-i, interface Specify dnsmasq's interface listening behavior
Add '-h' for more info on interface usage"
@@ -392,12 +393,23 @@ RemoveDHCPStaticAddress() {
}
SetHostRecord() {
- if [ -n "${args[3]}" ]; then
+ if [[ "${1}" == "-h" ]] || [[ "${1}" == "--help" ]]; then
+ echo "Usage: pihole -a hostrecord [IPv4-address],[IPv6-address]
+Example: 'pihole -a hostrecord home.domain.com 192.168.1.1,2001:db8:a0b:12f0::1'
+Add a name to the DNS associated to an IPv4/IPv6 address
+
+Options:
+ \"\" Empty: Remove host record
+ -h, --help Show this help dialog"
+ exit 0
+ fi
+
+ if [[ -n "${args[3]}" ]]; then
change_setting "HOSTRECORD" "${args[2]},${args[3]}"
- echo "Setting host record for ${args[2]} -> ${args[3]}"
+ echo -e " ${TICK} Setting host record for ${args[2]} to ${args[3]}"
else
change_setting "HOSTRECORD" ""
- echo "Removing host record"
+ echo -e " ${TICK} Removing host record"
fi
ProcessDNSSettings
@@ -474,7 +486,7 @@ main() {
"resolve" ) ResolutionSettings;;
"addstaticdhcp" ) AddDHCPStaticAddress;;
"removestaticdhcp" ) RemoveDHCPStaticAddress;;
- "hostrecord" ) SetHostRecord;;
+ "-r" | "hostrecord" ) SetHostRecord "$3";;
"-i" | "interface" ) SetListeningMode "$@";;
"-t" | "teleporter" ) Teleporter;;
"adlist" ) CustomizeAdLists;;
diff --git a/automated install/basic-install.sh b/automated install/basic-install.sh
index 9d264846..4047502b 100755
--- a/automated install/basic-install.sh
+++ b/automated install/basic-install.sh
@@ -1,22 +1,21 @@
#!/usr/bin/env bash
+# shellcheck disable=SC1090
+
# 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.
#
-# Installs Pi-hole
+# Installs and Updates Pi-hole
#
# This file is copyright under the latest version of the EUPL.
# Please see LICENSE file for your rights under this license.
-
-
# pi-hole.net/donate
#
# Install with this command (from your Linux machine):
#
# curl -L install.pi-hole.net | bash
-
# -e option instructs bash to immediately exit if any command [1] has a non-zero exit status
# We do not want users to end up with a partially working install, so we exit the script
# instead of continuing the installation with something broken
@@ -35,6 +34,7 @@ instalLogLoc=/etc/pihole/install.log
# This is an important file as it contains information specific to the machine it's being installed on
setupVars=/etc/pihole/setupVars.conf
# Pi-hole uses lighttpd as a Web server, and this is the config file for it
+# shellcheck disable=SC2034
lighttpdConfig=/etc/lighttpd/lighttpd.conf
# This is a file used for the colorized output
coltable=/opt/pihole/COL_TABLE
@@ -79,7 +79,7 @@ reconfigure=false
runUnattended=false
# If the color table file exists,
-if [[ -f ${coltable} ]]; then
+if [[ -f "${coltable}" ]]; then
# source it
source ${coltable}
# Othwerise,
@@ -91,8 +91,9 @@ else
TICK="[${COL_LIGHT_GREEN}✓${COL_NC}]"
CROSS="[${COL_LIGHT_RED}✗${COL_NC}]"
INFO="[i]"
+ # shellcheck disable=SC2034
DONE="${COL_LIGHT_GREEN} done!${COL_NC}"
- OVER="\r\033[K"
+ OVER="\\r\\033[K"
fi
# A simple function that just echoes out our logo in ASCII format
@@ -122,7 +123,6 @@ show_ascii_berry() {
"
}
-
# Compatibility
distro_check() {
# If apt-get is installed, then we know it's part of the Debian family
@@ -321,13 +321,13 @@ getGitFiles() {
# Show that we're checking it
echo -e "${OVER} ${TICK} ${str}"
# Update the repo, returning an error message on failure
- update_repo "${directory}" || { echo -e "\n ${COL_LIGHT_RED}Error: Could not update local repository. Contact support.${COL_NC}"; exit 1; }
+ update_repo "${directory}" || { echo -e "\\n ${COL_LIGHT_RED}Error: Could not update local repository. Contact support.${COL_NC}"; exit 1; }
# If it's not a .git repo,
else
# Show an error
echo -e "${OVER} ${CROSS} ${str}"
# Attempt to make the repository, showing an error on falure
- make_repo "${directory}" "${remoteRepo}" || { echo -e "\n ${COL_LIGHT_RED}Error: Could not update local repository. Contact support.${COL_NC}"; exit 1; }
+ make_repo "${directory}" "${remoteRepo}" || { echo -e "\\n ${COL_LIGHT_RED}Error: Could not update local repository. Contact support.${COL_NC}"; exit 1; }
fi
# echo a blank line
echo ""
@@ -380,13 +380,13 @@ get_available_interfaces() {
# A function for displaying the dialogs the user sees when first running the installer
welcomeDialogs() {
# Display the welcome dialog using an approriately sized window via the calculation conducted earlier in the script
- whiptail --msgbox --backtitle "Welcome" --title "Pi-hole automated installer" "\n\nThis installer will transform your device into a network-wide ad blocker!" ${r} ${c}
+ whiptail --msgbox --backtitle "Welcome" --title "Pi-hole automated installer" "\\n\\nThis installer will transform your device into a network-wide ad blocker!" ${r} ${c}
# Request that users donate if they enjoy the software since we all work on it in our free time
- whiptail --msgbox --backtitle "Plea" --title "Free and open source" "\n\nThe Pi-hole is free, but powered by your donations: http://pi-hole.net/donate" ${r} ${c}
+ whiptail --msgbox --backtitle "Plea" --title "Free and open source" "\\n\\nThe Pi-hole is free, but powered by your donations: http://pi-hole.net/donate" ${r} ${c}
# Explain the need for a static address
- whiptail --msgbox --backtitle "Initiating network interface" --title "Static IP Needed" "\n\nThe Pi-hole is a SERVER so it needs a STATIC IP ADDRESS to function properly.
+ whiptail --msgbox --backtitle "Initiating network interface" --title "Static IP Needed" "\\n\\nThe Pi-hole is a SERVER so it needs a STATIC IP ADDRESS to function properly.
In the next section, you can choose to use your current network settings (DHCP) or to manually edit them." ${r} ${c}
}
@@ -400,7 +400,8 @@ verifyFreeDiskSpace() {
# Reqired space in KB
local required_free_kilobytes=51200
# Calculate existing free space on this machine
- local existing_free_kilobytes=$(df -Pk | grep -m1 '\/$' | awk '{print $4}')
+ local existing_free_kilobytes
+ existing_free_kilobytes=$(df -Pk | grep -m1 '\/$' | awk '{print $4}')
# If the existing space is not an integer,
if ! [[ "${existing_free_kilobytes}" =~ ^([0-9])+$ ]]; then
@@ -414,7 +415,7 @@ verifyFreeDiskSpace() {
# exit with an error code
exit 1
# If there is insufficient free disk space,
- elif [[ ${existing_free_kilobytes} -lt ${required_free_kilobytes} ]]; then
+ elif [[ "${existing_free_kilobytes}" -lt "${required_free_kilobytes}" ]]; then
# show an error message
echo -e " ${CROSS} ${str}
Your system disk appears to only have ${existing_free_kilobytes} KB free
@@ -428,7 +429,7 @@ verifyFreeDiskSpace() {
e.g: curl -L https://install.pi-hole.net | bash"
fi
# Show there is not enough free space
- echo -e "\n ${COL_LIGHT_RED}Insufficient free space, exiting...${COL_NC}"
+ echo -e "\\n ${COL_LIGHT_RED}Insufficient free space, exiting...${COL_NC}"
# and exit with an error
exit 1
# Otherwise,
@@ -455,7 +456,7 @@ chooseInterface() {
interfaceCount=$(echo "${availableInterfaces}" | wc -l)
# If there is one interface,
- if [[ ${interfaceCount} -eq 1 ]]; then
+ if [[ "${interfaceCount}" -eq 1 ]]; then
# Set it as the interface to use since there is no other option
PIHOLE_INTERFACE="${availableInterfaces}"
# Otherwise,
@@ -465,7 +466,7 @@ chooseInterface() {
# use a variable to set the option as OFF to begin with
mode="OFF"
# If it's the first loop,
- if [[ ${firstLoop} -eq 1 ]]; then
+ if [[ "${firstLoop}" -eq 1 ]]; then
# set this as the interface to use (ON)
firstLoop=0
mode="ON"
@@ -501,11 +502,11 @@ testIPv6() {
# will contain 162 which is the decimal value corresponding to 0xa2
value2=$(((0x$first)%256))
# the ULA test is testing for fc00::/7 according to RFC 4193
- ((($value1&254)==252)) && echo "ULA" || true
+ (((value1&254)==252)) && echo "ULA" || true
# the GUA test is testing for 2000::/3 according to RFC 4291
- ((($value1&112)==32)) && echo "GUA" || true
+ (((value1&112)==32)) && echo "GUA" || true
# the LL test is testing for fe80::/10 according to RFC 4193
- ((($value1==254) && (($value2&192)==128))) && echo "Link-local" || true
+ (((value1==254) && ((value2&192)==128))) && echo "Link-local" || true
}
# A dialog for showing the user about IPv6 blocking
@@ -529,17 +530,17 @@ useIPv6dialog() {
# set the IPv6 address to the ULA address
IPV6_ADDRESS="${ULA_ADDRESS}"
# Show this info to the user
- echo "::: Found IPv6 ULA address, using it for blocking IPv6 ads"
+ echo -e " ${INFO} Found IPv6 ULA address, using it for blocking IPv6 ads"
# Otherwise, if the GUA_ADDRESS has a value,
elif [[ ! -z "${GUA_ADDRESS}" ]]; then
# Let the user know
- echo "::: Found IPv6 GUA address, using it for blocking IPv6 ads"
+ echo -e " ${INFO} Found IPv6 GUA address, using it for blocking IPv6 ads"
# And assign it to the global variable
IPV6_ADDRESS="${GUA_ADDRESS}"
# If none of those work,
else
# explain that IPv6 blocking will not be used
- echo "::: Found neither IPv6 ULA nor GUA address, blocking IPv6 ads will not be enabled"
+ echo -e " ${INFO} Unable to find IPv6 ULA/GUA address, IPv6 adblocking will not be enabled"
# So set the variable to be empty
IPV6_ADDRESS=""
fi
@@ -575,14 +576,14 @@ use4andor6() {
esac
done
# If IPv4 is to be used,
- if [[ ${useIPv4} ]]; then
+ if [[ "${useIPv4}" ]]; then
# Run our function to get the information we need
find_IPv4_information
getStaticIPv4Settings
setStaticIPv4
fi
# If IPv6 is to be used,
- if [[ ${useIPv6} ]]; then
+ if [[ "${useIPv6}" ]]; then
# Run our function to get this information
useIPv6dialog
fi
@@ -590,7 +591,7 @@ use4andor6() {
echo -e " ${INFO} IPv4 address: ${IPV4_ADDRESS}"
echo -e " ${INFO} IPv6 address: ${IPV6_ADDRESS}"
# If neither protocol is selected,
- if [ ! ${useIPv4} ] && [ ! ${useIPv6} ]; then
+ if [[ ! "${useIPv4}" ]] && [[ ! "${useIPv6}" ]]; then
# Show an error in red
echo -e " ${COL_LIGHT_RED}Error: Neither IPv4 or IPv6 selected${COL_NC}"
# and exit with an error
@@ -616,7 +617,7 @@ It is also possible to use a DHCP reservation, but if you are going to do that,
# Otherwise, we need to ask the user to input their desired settings.
# Start by getting the IPv4 address (pre-filling it with info gathered from DHCP)
# Start a loop to let the user enter their information with the chance to go back and edit it if necessary
- until [[ ${ipSettingsCorrect} = True ]]; do
+ until [[ "${ipSettingsCorrect}" = True ]]; do
# Ask for the IPv4 address
IPV4_ADDRESS=$(whiptail --backtitle "Calibrating network interface" --title "IPv4 address" --inputbox "Enter your desired IPv4 address" ${r} ${c} "${IPV4_ADDRESS}" 3>&1 1>&2 2>&3) || \
@@ -660,7 +661,7 @@ setStaticIPv4() {
local IPADDR
local CIDR
# For the Debian family, if dhcpcd.conf exists,
- if [[ -f /etc/dhcpcd.conf ]]; then
+ if [[ -f "/etc/dhcpcd.conf" ]]; then
# check if the IP is already in the file
if grep -q "${IPV4_ADDRESS}" /etc/dhcpcd.conf; then
echo -e " ${INFO} Static IP already configured"
@@ -672,10 +673,10 @@ setStaticIPv4() {
ip addr replace dev "${PIHOLE_INTERFACE}" "${IPV4_ADDRESS}"
# Also give a warning that the user may need to reboot their system
echo -e " ${TICK} Set IP address to ${IPV4_ADDRESS%/*}
- You may need to restart after the install is complete"
+ You may need to restart after the install is complete"
fi
# If it's not Debian, check if it's the Fedora family by checking for the file below
- elif [[ -f /etc/sysconfig/network-scripts/ifcfg-${PIHOLE_INTERFACE} ]];then
+ elif [[ -f "/etc/sysconfig/network-scripts/ifcfg-${PIHOLE_INTERFACE}" ]];then
# If it exists,
IFCFG_FILE=/etc/sysconfig/network-scripts/ifcfg-${PIHOLE_INTERFACE}
# check if the desired IP is already set
@@ -710,7 +711,7 @@ setStaticIPv4() {
fi
# Show a warning that the user may need to restart
echo -e " ${TICK} Set IP address to ${IPV4_ADDRESS%/*}
- You may need to restart after the install is complete"
+ You may need to restart after the install is complete"
fi
# If all that fails,
else
@@ -727,7 +728,7 @@ valid_ip() {
local stat=1
# If the IP matches the format xxx.xxx.xxx.xxx,
- if [[ ${ip} =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then
+ if [[ "${ip}" =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then
# Save the old Interfal Field Separator in a variable
OIFS=$IFS
# and set the new one to a dot (period)
@@ -737,8 +738,8 @@ valid_ip() {
# Restore the IFS to what it was
IFS=${OIFS}
## Evaluate each octet by checking if it's less than or equal to 255 (the max for each octet)
- [[ ${ip[0]} -le 255 && ${ip[1]} -le 255 \
- && ${ip[2]} -le 255 && ${ip[3]} -le 255 ]]
+ [[ "${ip[0]}" -le 255 && "${ip[1]}" -le 255 \
+ && "${ip[2]}" -le 255 && "${ip[3]}" -le 255 ]]
# Save the exit code
stat=$?
fi
@@ -801,13 +802,13 @@ setDNS() {
;;
Custom)
# Until the DNS settings are selected,
- until [[ ${DNSSettingsCorrect} = True ]]; do
+ until [[ "${DNSSettingsCorrect}" = True ]]; do
#
strInvalid="Invalid"
# If the first
- if [ ! ${PIHOLE_DNS_1} ]; then
+ if [[ ! "${PIHOLE_DNS_1}" ]]; then
# and second upstream servers do not exist
- if [ ! ${PIHOLE_DNS_2} ]; then
+ if [[ ! "${PIHOLE_DNS_2}" ]]; then
#
prePopulate=""
# Otherwise,
@@ -816,39 +817,39 @@ setDNS() {
prePopulate=", ${PIHOLE_DNS_2}"
fi
#
- elif [ ${PIHOLE_DNS_1} ] && [ ! ${PIHOLE_DNS_2} ]; then
+ elif [[ "${PIHOLE_DNS_1}" ]] && [[ ! "${PIHOLE_DNS_2}" ]]; then
#
prePopulate="${PIHOLE_DNS_1}"
#
- elif [ ${PIHOLE_DNS_1} ] && [ ${PIHOLE_DNS_2} ]; then
+ elif [[ "${PIHOLE_DNS_1}" ]] && [[ "${PIHOLE_DNS_2}" ]]; then
#
prePopulate="${PIHOLE_DNS_1}, ${PIHOLE_DNS_2}"
fi
# Dialog for the user to enter custom upstream servers
- piholeDNS=$(whiptail --backtitle "Specify Upstream DNS Provider(s)" --inputbox "Enter your desired upstream DNS provider(s), seperated by a comma.\n\nFor example '8.8.8.8, 8.8.4.4'" ${r} ${c} "${prePopulate}" 3>&1 1>&2 2>&3) || \
+ piholeDNS=$(whiptail --backtitle "Specify Upstream DNS Provider(s)" --inputbox "Enter your desired upstream DNS provider(s), seperated by a comma.\\n\\nFor example '8.8.8.8, 8.8.4.4'" ${r} ${c} "${prePopulate}" 3>&1 1>&2 2>&3) || \
{ echo -e " ${COL_LIGHT_RED}Cancel was selected, exiting installer${COL_NC}"; exit 1; }
#
PIHOLE_DNS_1=$(echo "${piholeDNS}" | sed 's/[, \t]\+/,/g' | awk -F, '{print$1}')
PIHOLE_DNS_2=$(echo "${piholeDNS}" | sed 's/[, \t]\+/,/g' | awk -F, '{print$2}')
# If the IP is valid,
- if ! valid_ip "${PIHOLE_DNS_1}" || [ ! "${PIHOLE_DNS_1}" ]; then
+ if ! valid_ip "${PIHOLE_DNS_1}" || [[ ! "${PIHOLE_DNS_1}" ]]; then
# store it in the variable so we can use it
PIHOLE_DNS_1=${strInvalid}
fi
# Do the same for the secondary server
- if ! valid_ip "${PIHOLE_DNS_2}" && [ "${PIHOLE_DNS_2}" ]; then
+ if ! valid_ip "${PIHOLE_DNS_2}" && [[ "${PIHOLE_DNS_2}" ]]; then
PIHOLE_DNS_2=${strInvalid}
fi
# If either of the DNS servers are invalid,
- if [[ ${PIHOLE_DNS_1} == "${strInvalid}" ]] || [[ ${PIHOLE_DNS_2} == "${strInvalid}" ]]; then
+ if [[ "${PIHOLE_DNS_1}" == "${strInvalid}" ]] || [[ "${PIHOLE_DNS_2}" == "${strInvalid}" ]]; then
# explain this to the user
- whiptail --msgbox --backtitle "Invalid IP" --title "Invalid IP" "One or both entered IP addresses were invalid. Please try again.\n\n DNS Server 1: $PIHOLE_DNS_1\n DNS Server 2: ${PIHOLE_DNS_2}" ${r} ${c}
+ whiptail --msgbox --backtitle "Invalid IP" --title "Invalid IP" "One or both entered IP addresses were invalid. Please try again.\\n\\n DNS Server 1: $PIHOLE_DNS_1\\n DNS Server 2: ${PIHOLE_DNS_2}" ${r} ${c}
# and set the variables back to nothing
- if [[ ${PIHOLE_DNS_1} == "${strInvalid}" ]]; then
+ if [[ "${PIHOLE_DNS_1}" == "${strInvalid}" ]]; then
PIHOLE_DNS_1=""
fi
- if [[ ${PIHOLE_DNS_2} == "${strInvalid}" ]]; then
+ if [[ "${PIHOLE_DNS_2}" == "${strInvalid}" ]]; then
PIHOLE_DNS_2=""
fi
# Since the settings will not work, stay in the loop
@@ -856,7 +857,7 @@ setDNS() {
# Othwerise,
else
# Show the settings
- if (whiptail --backtitle "Specify Upstream DNS Provider(s)" --title "Upstream DNS Provider(s)" --yesno "Are these settings correct?\n DNS Server 1: $PIHOLE_DNS_1\n DNS Server 2: ${PIHOLE_DNS_2}" ${r} ${c}); then
+ if (whiptail --backtitle "Specify Upstream DNS Provider(s)" --title "Upstream DNS Provider(s)" --yesno "Are these settings correct?\\n DNS Server 1: $PIHOLE_DNS_1\\n DNS Server 2: ${PIHOLE_DNS_2}" ${r} ${c}); then
# and break from the loop since the servers are vaid
DNSSettingsCorrect=True
# Otherwise,
@@ -878,7 +879,7 @@ setLogging() {
local LogChoices
# Ask if the user wants to log queries
- LogToggleCommand=(whiptail --separate-output --radiolist "Do you want to log queries?\n (Disabling will render graphs on the Admin page useless):" ${r} ${c} 6)
+ LogToggleCommand=(whiptail --separate-output --radiolist "Do you want to log queries?\\n (Disabling will render graphs on the Admin page useless):" ${r} ${c} 6)
# The default selection is on
LogChooseOptions=("On (Recommended)" "" on
Off "" off)
@@ -916,12 +917,12 @@ setAdminFlag() {
# Depending on their choice
case ${WebChoices} in
"On (Recommended)")
- echo -e " ${INFO} Web Interface On."
+ echo -e " ${INFO} Web Interface On"
# Set it to true
INSTALL_WEB=true
;;
Off)
- echo -e " ${INFO} Web Interface off."
+ echo -e " ${INFO} Web Interface Off"
# or false
INSTALL_WEB=false
;;
@@ -939,7 +940,7 @@ version_check_dnsmasq() {
local dnsmasq_pihole_01_location="/etc/dnsmasq.d/01-pihole.conf"
# If the dnsmasq config file exists
- if [ -f ${dnsmasq_conf} ]; then
+ if [[ -f "${dnsmasq_conf}" ]]; then
echo -ne " ${INFO} Existing dnsmasq.conf found..."
# If gravity.list is found within this file, we presume it's from older versions on Pi-hole,
if grep -q ${dnsmasq_pihole_id_string} ${dnsmasq_conf}; then
@@ -1048,8 +1049,8 @@ installScripts() {
# Otherwise,
else
# Show an error and exit
- echo -e "${OVER} ${CROSS} ${str}"
- echo -e " ${COL_LIGHT_RED}Error: Local repo ${PI_HOLE_LOCAL_REPO} not found, exiting installer${COL_NC}"
+ echo -e "${OVER} ${CROSS} ${str}
+ ${COL_LIGHT_RED}Error: Local repo ${PI_HOLE_LOCAL_REPO} not found, exiting installer${COL_NC}"
exit 1
fi
}
@@ -1062,15 +1063,15 @@ installConfigs() {
version_check_dnsmasq
# If the user chose to install the dashboard,
- if [[ ${INSTALL_WEB} == true ]]; then
+ if [[ "${INSTALL_WEB}" == true ]]; then
# and if the Web server conf directory does not exist,
- if [ ! -d "/etc/lighttpd" ]; then
+ if [[ ! -d "/etc/lighttpd" ]]; then
# make it
mkdir /etc/lighttpd
# and set the owners
chown "${USER}":root /etc/lighttpd
# Otherwise, if the config file already exists
- elif [ -f "/etc/lighttpd/lighttpd.conf" ]; then
+ elif [[ -f "/etc/lighttpd/lighttpd.conf" ]]; then
# back up the original
mv /etc/lighttpd/lighttpd.conf /etc/lighttpd/lighttpd.conf.orig
fi
@@ -1164,16 +1165,13 @@ update_package_cache() {
notify_package_updates_available() {
# Local, named variables
local str="Checking ${PKG_MANAGER} for upgraded packages"
- echo ""
- echo -ne " ${INFO} ${str}..."
+ echo -ne "\\n ${INFO} ${str}..."
# Store the list of packages in a variable
updatesToInstall=$(eval "${PKG_COUNT}")
- #echo -e "\r\033[K ${TICK} ${str}"
- #echo ""
- #
+
if [[ -d "/lib/modules/$(uname -r)" ]]; then
#
- if [[ ${updatesToInstall} -eq "0" ]]; then
+ if [[ "${updatesToInstall}" -eq 0 ]]; then
#
echo -e "${OVER} ${TICK} ${str}... up to date!"
echo ""
@@ -1184,10 +1182,8 @@ notify_package_updates_available() {
echo ""
fi
else
- #
echo -e "${OVER} ${CROSS} ${str}
- Kernel update detected. If the install fails, please reboot and try again"
- echo ""
+ Kernel update detected. If the install fails, please reboot and try again\\n"
fi
}
@@ -1199,7 +1195,7 @@ install_dependent_packages() {
# Add one to the counter
counter=$((counter+1))
# If it equals 1,
- if [ ${counter} == 1 ]; then
+ if [[ "${counter}" == 1 ]]; then
#
echo -e " ${INFO} Installer Dependency checks..."
else
@@ -1233,7 +1229,7 @@ install_dependent_packages() {
fi
done
#
- if [[ ${#installArray[@]} -gt 0 ]]; then
+ if [[ "${#installArray[@]}" -gt 0 ]]; then
#
test_dpkg_lock
#
@@ -1258,7 +1254,7 @@ install_dependent_packages() {
fi
done
#
- if [[ ${#installArray[@]} -gt 0 ]]; then
+ if [[ "${#installArray[@]}" -gt 0 ]]; then
#
"${PKG_INSTALL[@]}" "${installArray[@]}" &> /dev/null
return
@@ -1273,7 +1269,7 @@ CreateLogFile() {
echo ""
echo -ne " ${INFO} ${str}..."
# If the pihole log does not exist,
- if [ ! -f /var/log/pihole.log ]; then
+ if [[ ! -f "/var/log/pihole.log" ]]; then
# Make it,
touch /var/log/pihole.log
# set the permissions,
@@ -1293,11 +1289,11 @@ installPiholeWeb() {
echo ""
echo " ${INFO} Installing blocking page..."
# If the pihole Web directory exists,
- if [ -d "/var/www/html/pihole" ]; then
+ if [[ -d "/var/www/html/pihole" ]]; then
local str="Installing index.php"
echo -ne " ${INFO} ${str}..."
# and if the index file exists,
- if [ -f "/var/www/html/pihole/index.php" ]; then
+ if [[ -f "/var/www/html/pihole/index.php" ]]; then
# do not overwrite it,
echo -e " ${COL_LIGHT_GREEN}detected index.php, not overwriting${COL_NC}"
# if it doesn't exist
@@ -1310,7 +1306,7 @@ installPiholeWeb() {
local str="Installing index.js"
echo -ne " ${INFO} ${str}..."
# and if the index file exists,
- if [ -f "/var/www/html/pihole/index.js" ]; then
+ if [[ -f "/var/www/html/pihole/index.js" ]]; then
# do not overwrite it,
echo -e " ${COL_LIGHT_GREEN}detected index.js, not overwriting${COL_NC}"
else
@@ -1322,7 +1318,7 @@ installPiholeWeb() {
local str="Installing blockingpage.css"
echo -ne " ${INFO} ${str}..."
# and if the index file exists,
- if [ -f "/var/www/html/pihole/blockingpage.css" ]; then
+ if [[ -f "/var/www/html/pihole/blockingpage.css" ]]; then
# do not overwrite it,
echo -e " ${COL_LIGHT_GREEN}detected blockingpage.css, not overwriting${COL_NC}"
else
@@ -1343,15 +1339,15 @@ installPiholeWeb() {
local str="Backing up index.lighttpd.html"
echo -ne " ${INFO} ${str}..."
# If the default index file exists,
- if [ -f /var/www/html/index.lighttpd.html ]; then
+ if [[ -f "/var/www/html/index.lighttpd.html" ]]; then
# back it up
mv /var/www/html/index.lighttpd.html /var/www/html/index.lighttpd.orig
echo -e "${OVER} ${TICK} ${str}"
# Othwerwise,
else
# don't do anything
- echo -e "${OVER} ${CROSS} ${str}"
- echo -e " No default index.lighttpd.html file found... not backing up"
+ echo -e "${OVER} ${CROSS} ${str}
+ No default index.lighttpd.html file found... not backing up"
fi
fi
@@ -1435,9 +1431,9 @@ configureFirewall() {
# If a firewall is running,
if firewall-cmd --state &> /dev/null; then
# ask if the user wants to install Pi-hole's default firwall rules
- whiptail --title "Firewall in use" --yesno "We have detected a running firewall\n\nPi-hole currently requires HTTP and DNS port access.\n\n\n\nInstall Pi-hole default firewall rules?" ${r} ${c} || \
+ whiptail --title "Firewall in use" --yesno "We have detected a running firewall\\n\\nPi-hole currently requires HTTP and DNS port access.\\n\\n\\n\\nInstall Pi-hole default firewall rules?" ${r} ${c} || \
{ echo -e " ${INFO} Not installing firewall rulesets."; return 0; }
- echo -e " ${TICK} Configuring FirewallD for httpd and dnsmasq."
+ echo -e " ${TICK} Configuring FirewallD for httpd and dnsmasq"
# Allow HTTP and DNS traffice
firewall-cmd --permanent --add-service=http --add-service=dns
# Reload the firewall to apply these changes
@@ -1448,9 +1444,9 @@ configureFirewall() {
# If chain Policy is not ACCEPT or last Rule is not ACCEPT
# then check and insert our Rules above the DROP/REJECT Rule.
if iptables -S INPUT | head -n1 | grep -qv '^-P.*ACCEPT$' || iptables -S INPUT | tail -n1 | grep -qv '^-\(A\|P\).*ACCEPT$'; then
- whiptail --title "Firewall in use" --yesno "We have detected a running firewall\n\nPi-hole currently requires HTTP and DNS port access.\n\n\n\nInstall Pi-hole default firewall rules?" ${r} ${c} || \
+ whiptail --title "Firewall in use" --yesno "We have detected a running firewall\\n\\nPi-hole currently requires HTTP and DNS port access.\\n\\n\\n\\nInstall Pi-hole default firewall rules?" ${r} ${c} || \
{ echo -e " ${INFO} Not installing firewall rulesets."; return 0; }
- echo -e " ${TICK} Installing new IPTables firewall rulesets."
+ echo -e " ${TICK} Installing new IPTables firewall rulesets"
# Check chain first, otherwise a new rule will duplicate old ones
iptables -C INPUT -p tcp -m tcp --dport 80 -j ACCEPT &> /dev/null || iptables -I INPUT 1 -p tcp -m tcp --dport 80 -j ACCEPT
iptables -C INPUT -p tcp -m tcp --dport 53 -j ACCEPT &> /dev/null || iptables -I INPUT 1 -p tcp -m tcp --dport 53 -j ACCEPT
@@ -1461,31 +1457,32 @@ configureFirewall() {
# Othwerwise,
else
# no firewall is running
- echo -e " ${INFO} No active firewall detected.. skipping firewall configuration."
+ echo -e " ${INFO} No active firewall detected.. skipping firewall configuration"
# so just exit
return 0
fi
- echo -e " ${INFO} Skipping firewall configuration."
+ echo -e " ${INFO} Skipping firewall configuration"
}
#
finalExports() {
# If the Web interface is not set to be installed,
- if [[ ${INSTALL_WEB} == false ]]; then
+ if [[ "${INSTALL_WEB}" == false ]]; then
# and if there is not an IPv4 address,
- if [ ${IPV4_ADDRESS} ]; then
+ if [[ "${IPV4_ADDRESS}" ]]; then
# there is no block page, so set IPv4 to 0.0.0.0 (all IP addresses)
IPV4_ADDRESS="0.0.0.0"
fi
- if [ ${IPV6_ADDRESS} ]; then
+ if [[ "${IPV6_ADDRESS}" ]]; then
# and IPv6 to ::/0
IPV6_ADDRESS="::/0"
fi
fi
# If the setup variable file exists,
- if [ -e "${setupVars}" ]; then
- sed -i.update.bak '/PIHOLE_INTERFACE/d;/IPV4_ADDRESS/d;/IPV6_ADDRESS/d;/PIHOLE_DNS_1/d;/PIHOLE_DNS_2/d;/QUERY_LOGGING/d;/INSTALL_WEB/d;/LIGHTTPD_ENABLED/d;' "${setupVars}"
+ if [[ -e "${setupVars}" ]]; then
+ # update the variables in the file
+ sed -i.update.bak '/PIHOLE_INTERFACE/d;/IPV4_ADDRESS/d;/IPV6_ADDRESS/d;/PIHOLE_DNS_1/d;/PIHOLE_DNS_2/d;/QUERY_LOGGING/d;/INSTALL_WEB/d;' "${setupVars}"
fi
# echo the information to the user
{
@@ -1526,7 +1523,7 @@ installLogrotate() {
# the local properties of the /var/log directory
logusergroup="$(stat -c '%U %G' /var/log)"
# If the variable has a value,
- if [[ ! -z $logusergroup ]]; then
+ if [[ ! -z "${logusergroup}" ]]; then
#
sed -i "s/# su #/su ${logusergroup}/g;" /etc/pihole/logrotate
fi
@@ -1539,8 +1536,8 @@ installPihole() {
create_pihole_user
# If the user wants to install the Web interface,
- if [[ ${INSTALL_WEB} == true ]]; then
- if [ ! -d "/var/www/html" ]; then
+ if [[ "${INSTALL_WEB}" == true ]]; then
+ if [[ ! -d "/var/www/html" ]]; then
# make the Web directory if necessary
mkdir -p /var/www/html
fi
@@ -1550,13 +1547,13 @@ installPihole() {
# Give pihole access to the Web server group
usermod -a -G ${LIGHTTPD_GROUP} pihole
# If the lighttpd command is executable,
- if [ -x "$(command -v lighty-enable-mod)" ]; then
+ if [[ -x "$(command -v lighty-enable-mod)" ]]; then
# enable fastcgi and fastcgi-php
lighty-enable-mod fastcgi fastcgi-php > /dev/null || true
else
# Othweise, show info about installing them
echo -e " ${INFO} Warning: 'lighty-enable-mod' utility not found
- Please ensure fastcgi is enabled if you experience issues\n"
+ Please ensure fastcgi is enabled if you experience issues\\n"
fi
fi
# Install scripts,
@@ -1566,7 +1563,7 @@ installPihole() {
# and create the log file
CreateLogFile
# If the user wants to install the dashboard,
- if [[ ${INSTALL_WEB} == true ]]; then
+ if [[ "${INSTALL_WEB}" == true ]]; then
# do so
installPiholeWeb
fi
@@ -1575,7 +1572,7 @@ installPihole() {
# Install the logrotate file
installLogrotate
# Check if FTL is installed
- FTLdetect || echo -e " ${CROSS} FTL Engine not installed."
+ FTLdetect || echo -e " ${CROSS} FTL Engine not installed"
# Configure the firewall
configureFirewall
@@ -1604,7 +1601,7 @@ updatePihole() {
# Create the log file
CreateLogFile
# If the user wants to install the dasboard,
- if [[ ${INSTALL_WEB} == true ]]; then
+ if [[ "${INSTALL_WEB}" == true ]]; then
# do so
installPiholeWeb
fi
@@ -1625,19 +1622,17 @@ updatePihole() {
checkSelinux() {
# If the getenforce command exists,
if command -v getenforce &> /dev/null; then
- echo ""
- echo -ne " ${INFO} SELinux Support Detected... Mode: "
# Store the current mode in a variable
enforceMode=$(getenforce)
- echo "${enforceMode}"
+ echo -e "\\n ${INFO} SELinux mode detected: ${enforceMode}"
+
# If it's enforcing,
if [[ "${enforceMode}" == "Enforcing" ]]; then
# Explain Pi-hole does not support it yet
- whiptail --title "SELinux Enforcing Detected" --yesno "SELinux is being Enforced on your system!\n\nPi-hole currently does not support SELinux, but you may still continue with the installation.\n\nNote: Admin UI Will not function fully without setting your policies correctly\n\nContinue installing Pi-hole?" ${r} ${c} || \
- { echo ""; echo -e " ${COL_LIGHT_RED}SELinux Enforcing detected, exiting installer${COL_NC}"; exit 1; }
- echo ""
- echo -e " ${INFO} Continuing installation with SELinux Enforcing"
- echo -e " ${INFO} Please refer to official SELinux documentation to create a custom policy"
+ whiptail --defaultno --title "SELinux Enforcing Detected" --yesno "SELinux is being ENFORCED on your system! \\n\\nPi-hole currently does not support SELinux, but you may still continue with the installation.\\n\\nNote: Web Admin will not be fully functional unless you set your policies correctly\\n\\nContinue installing Pi-hole?" ${r} ${c} || \
+ { echo -e "\\n ${COL_LIGHT_RED}SELinux Enforcing detected, exiting installer${COL_NC}"; exit 1; }
+ echo -e " ${INFO} Continuing installation with SELinux Enforcing
+ ${INFO} Please refer to official SELinux documentation to create a custom policy"
fi
fi
}
@@ -1645,7 +1640,7 @@ checkSelinux() {
# Installation complete message with instructions for the user
displayFinalMessage() {
# If
- if [[ ${#1} -gt 0 ]] ; then
+ if [[ "${#1}" -gt 0 ]] ; then
pwstring="$1"
# else, if the dashboard password in the setup variables exists,
elif [[ $(grep 'WEBPASSWORD' -c /etc/pihole/setupVars.conf) -gt 0 ]]; then
@@ -1656,7 +1651,7 @@ displayFinalMessage() {
pwstring="NOT SET"
fi
# If the user wants to install the dashboard,
- if [[ ${INSTALL_WEB} == true ]]; then
+ if [[ "${INSTALL_WEB}" == true ]]; then
# Store a message in a variable and display it
additional="View the web interface at http://pi.hole/admin or http://${IPV4_ADDRESS%/*}/admin
@@ -1678,7 +1673,7 @@ ${additional}" ${r} ${c}
update_dialogs() {
# If pihole -r "reconfigure" option was selected,
- if [ "${reconfigure}" = true ]; then
+ if [[ "${reconfigure}" = true ]]; then
# set some variables that will be used
opt1a="Repair"
opt1b="This will retain existing settings"
@@ -1694,7 +1689,7 @@ update_dialogs() {
opt2b="This will allow you to enter new settings"
# Display the information to the user
- UpdateCmd=$(whiptail --title "Existing Install Detected!" --menu "\n\nWe have detected an existing install.\n\nPlease choose from the following options: \n($strAdd)" ${r} ${c} 2 \
+ UpdateCmd=$(whiptail --title "Existing Install Detected!" --menu "\\n\\nWe have detected an existing install.\\n\\nPlease choose from the following options: \\n($strAdd)" ${r} ${c} 2 \
"${opt1a}" "${opt1b}" \
"${opt2a}" "${opt2b}" 3>&2 2>&1 1>&3) || \
{ echo -e " ${COL_LIGHT_RED}Cancel was selected, exiting installer${COL_NC}"; exit 1; }
@@ -1703,7 +1698,7 @@ update_dialogs() {
case ${UpdateCmd} in
# repair, or
${opt1a})
- echo -e " ${INFO} ${opt1a} option selected."
+ echo -e " ${INFO} ${opt1a} option selected"
useUpdateVars=true
;;
# recongigure,
@@ -1714,7 +1709,6 @@ update_dialogs() {
esac
}
-
clone_or_update_repos() {
# If the user wants to reconfigure,
if [[ "${reconfigure}" == true ]]; then
@@ -1725,7 +1719,7 @@ clone_or_update_repos() {
exit 1; \
}
# If the Web interface was installed,
- if [[ ${INSTALL_WEB} == true ]]; then
+ if [[ "${INSTALL_WEB}" == true ]]; then
# reset it's repo
resetRepo ${webInterfaceDir} || \
{ echo -e " ${COL_LIGHT_RED}Unable to reset ${webInterfaceDir}, exiting installer${COL_NC}"; \
@@ -1736,11 +1730,11 @@ clone_or_update_repos() {
else
# so get git files for Core
getGitFiles ${PI_HOLE_LOCAL_REPO} ${piholeGitUrl} || \
- { echo "!!! Unable to clone ${piholeGitUrl} into ${PI_HOLE_LOCAL_REPO}, unable to continue."; \
+ { echo -e " ${COL_LIGHT_RED}Unable to clone ${piholeGitUrl} into ${PI_HOLE_LOCAL_REPO}, unable to continue${COL_NC}"; \
exit 1; \
}
# If the Web interface was installed,
- if [[ ${INSTALL_WEB} == true ]]; then
+ if [[ "${INSTALL_WEB}" == true ]]; then
# get the Web git files
getGitFiles ${webInterfaceDir} ${webInterfaceGitUrl} || \
{ echo -e " ${COL_LIGHT_RED}Unable to clone ${webInterfaceGitUrl} into ${webInterfaceDir}, exiting installer${COL_NC}"; \
@@ -1824,21 +1818,23 @@ FTLdetect() {
local str="Detecting architecture"
echo -ne " ${INFO} ${str}..."
# If the machine is arm or aarch
- if [[ ${machine} == arm* || ${machine} == *aarch* ]]; then
+ if [[ "${machine}" == "arm"* || "${machine}" == *"aarch"* ]]; then
# ARM
#
- local rev=$(uname -m | sed "s/[^0-9]//g;")
+ local rev
+ rev=$(uname -m | sed "s/[^0-9]//g;")
#
- local lib=$(ldd /bin/ls | grep -E '^\s*/lib' | awk '{ print $1 }')
+ local lib
+ lib=$(ldd /bin/ls | grep -E '^\s*/lib' | awk '{ print $1 }')
#
- if [[ "$lib" == "/lib/ld-linux-aarch64.so.1" ]]; then
+ if [[ "${lib}" == "/lib/ld-linux-aarch64.so.1" ]]; then
echo -e "${OVER} ${TICK} Detected ARM-aarch64 architecture"
# set the binary to be used
binary="pihole-FTL-aarch64-linux-gnu"
#
- elif [[ "$lib" == "/lib/ld-linux-armhf.so.3" ]]; then
+ elif [[ "${lib}" == "/lib/ld-linux-armhf.so.3" ]]; then
#
- if [ "$rev" -gt "6" ]; then
+ if [[ "${rev}" -gt 6 ]]; then
echo -e "${OVER} ${TICK} Detected ARM-hf architecture (armv7+)"
# set the binary to be used
binary="pihole-FTL-arm-linux-gnueabihf"
@@ -1853,22 +1849,22 @@ FTLdetect() {
# set the binary to be used
binary="pihole-FTL-arm-linux-gnueabi"
fi
- elif [[ $machine == ppc ]]; then
+ elif [[ "${machine}" == "ppc" ]]; then
# PowerPC
- echo "::: Detected PowerPC architecture"
+ echo -e "${OVER} ${TICK} Detected PowerPC architecture"
# set the binary to be used
binary="pihole-FTL-powerpc-linux-gnu"
- elif [[ ${machine} == x86_64 ]]; then
+ elif [[ "${machine}" == "x86_64" ]]; then
# 64bit
echo -e "${OVER} ${TICK} Detected x86_64 architecture"
# set the binary to be used
binary="pihole-FTL-linux-x86_64"
else
# Something else - we try to use 32bit executable and warn the user
- if [[ ! ${machine} == i686 ]]; then
+ if [[ ! "${machine}" == "i686" ]]; then
echo -e "${OVER} ${CROSS} ${str}...
- ${COL_LIGHT_RED}Not able to detect architecture (unknown: ${machine}), trying 32bit executable
- Contact support if you experience issues (e.g: FTL not running)${COL_NC}"
+ ${COL_LIGHT_RED}Not able to detect architecture (unknown: ${machine}), trying 32bit executable${COL_NC}
+ Contact Pi-hole Support if you experience issues (e.g: FTL not running)"
else
echo -e "${OVER} ${TICK} Detected 32bit (i686) architecture"
fi
@@ -1910,7 +1906,6 @@ FTLdetect() {
}
main() {
-
######## FIRST CHECK ########
# Show the Pi-hole logo so people know it's genuine since the logo and name are trademarked
show_ascii_berry
@@ -1919,18 +1914,17 @@ main() {
echo ""
# If the user's id is zero,
- if [[ ${EUID} -eq 0 ]]; then
+ if [[ "${EUID}" -eq 0 ]]; then
# they are root and all is good
echo -e " ${TICK} ${str}"
# Otherwise,
else
# They do not have enough privileges, so let the user know
echo -e " ${CROSS} ${str}
- Script called with non-root privileges
- The Pi-hole requires elevated privleges to install and run
- Please check the installer for any concerns regarding this requirement
- Make sure to download this script from a trusted source"
- echo ""
+ ${COL_LIGHT_RED}Script called with non-root privileges${COL_NC}
+ The Pi-hole requires elevated privleges to install and run
+ Please check the installer for any concerns regarding this requirement
+ Make sure to download this script from a trusted source\\n"
echo -ne " ${INFO} Sudo utility check"
# If the sudo command exists,
@@ -1943,7 +1937,7 @@ main() {
else
# Let them know they need to run it as root
echo -e "${OVER} ${CROSS} Sudo utility check
- Sudo is needed for the Web Interface to run pihole commands\n
+ Sudo is needed for the Web Interface to run pihole commands\\n
${COL_LIGHT_RED}Please re-run this installer as root${COL_NC}"
exit 1
fi
@@ -1962,7 +1956,7 @@ main() {
done
# If the setup variable file exists,
- if [[ -f ${setupVars} ]]; then
+ if [[ -f "${setupVars}" ]]; then
# if it's running unattended,
if [[ "${runUnattended}" == true ]]; then
echo -e " ${INFO} Performing unattended setup, no whiptail dialogs will be displayed"
@@ -1995,15 +1989,14 @@ main() {
# Check if SELinux is Enforcing
checkSelinux
-
- if [[ ${useUpdateVars} == false ]]; then
+ if [[ "${useUpdateVars}" == false ]]; then
# Display welcome dialogs
welcomeDialogs
# Create directory for Pi-hole storage
mkdir -p /etc/pihole/
stop_service dnsmasq
- if [[ ${INSTALL_WEB} == true ]]; then
+ if [[ "${INSTALL_WEB}" == true ]]; then
stop_service lighttpd
fi
# Determine available interfaces
@@ -2022,7 +2015,7 @@ main() {
clone_or_update_repos
# Install packages used by the Pi-hole
- if [[ ${INSTALL_WEB} == true ]]; then
+ if [[ "${INSTALL_WEB}" == true ]]; then
# Install the Web dependencies
DEPS=("${PIHOLE_DEPS[@]}" "${PIHOLE_WEB_DEPS[@]}")
# Otherwise,
@@ -2046,11 +2039,11 @@ main() {
# Clone/Update the repos
clone_or_update_repos
- # Source ${setupVars} for use in the rest of the functions.
+ # Source ${setupVars} for use in the rest of the functions
source ${setupVars}
# Install packages used by the Pi-hole
- if [[ ${INSTALL_WEB} == true ]]; then
+ if [[ "${INSTALL_WEB}" == true ]]; then
# Install the Web dependencies
DEPS=("${PIHOLE_DEPS[@]}" "${PIHOLE_WEB_DEPS[@]}")
# Otherwise,
@@ -2074,13 +2067,14 @@ main() {
# Move the log file into /etc/pihole for storage
mv ${tmpLog} ${instalLogLoc}
- if [[ ${INSTALL_WEB} == true ]]; then
+ if [[ "${INSTALL_WEB}" == true ]]; then
# Add password to web UI if there is none
pw=""
# If no password is set,
if [[ $(grep 'WEBPASSWORD' -c /etc/pihole/setupVars.conf) == 0 ]] ; then
# generate a random password
pw=$(tr -dc _A-Z-a-z-0-9 < /dev/urandom | head -c 8)
+ # shellcheck disable=SC1091
. /opt/pihole/webpage.sh
echo "WEBPASSWORD=$(HashPassword ${pw})" >> ${setupVars}
fi
@@ -2115,20 +2109,19 @@ main() {
fi
# If the Web interface was installed,
- if [[ ${INSTALL_WEB} == true ]]; then
+ if [[ "${INSTALL_WEB}" == true ]]; then
# If there is a password,
if (( ${#pw} > 0 )) ; then
# display the password
echo -e " ${INFO} Web Interface password: ${COL_LIGHT_GREEN}${pw}${COL_NC}
- This can be changed using 'pihole -a -p'"
- echo ""
+ This can be changed using 'pihole -a -p'\\n"
fi
fi
#
if [[ "${useUpdateVars}" == false ]]; then
# If the Web interface was installed,
- if [[ ${INSTALL_WEB} == true ]]; then
+ if [[ "${INSTALL_WEB}" == true ]]; then
echo -e " View the web interface at http://pi.hole/admin or http://${IPV4_ADDRESS%/*}/admin"
echo ""
fi
@@ -2145,7 +2138,7 @@ main() {
fi
# Display where the log file is
- echo -e "\n ${INFO} The install log is located at: /etc/pihole/install.log
+ echo -e "\\n ${INFO} The install log is located at: /etc/pihole/install.log
${COL_LIGHT_GREEN}${INSTALL_TYPE} Complete! ${COL_NC}"
}
diff --git a/test/test_automated_install.py b/test/test_automated_install.py
index 9129c314..7f1a86a1 100644
--- a/test/test_automated_install.py
+++ b/test/test_automated_install.py
@@ -80,7 +80,7 @@ def test_configureFirewall_firewalld_running_no_errors(Pihole):
source /opt/pihole/basic-install.sh
configureFirewall
''')
- expected_stdout = 'Configuring FirewallD for httpd and dnsmasq.'
+ expected_stdout = 'Configuring FirewallD for httpd and dnsmasq'
assert expected_stdout in configureFirewall.stdout
firewall_calls = Pihole.run('cat /var/log/firewall-cmd').stdout
assert 'firewall-cmd --state' in firewall_calls
@@ -95,7 +95,7 @@ def test_configureFirewall_firewalld_disabled_no_errors(Pihole):
source /opt/pihole/basic-install.sh
configureFirewall
''')
- expected_stdout = 'No active firewall detected.. skipping firewall configuration.'
+ expected_stdout = 'No active firewall detected.. skipping firewall configuration'
assert expected_stdout in configureFirewall.stdout
def test_configureFirewall_firewalld_enabled_declined_no_errors(Pihole):
@@ -444,7 +444,7 @@ def test_IPv6_only_link_local(Pihole):
source /opt/pihole/basic-install.sh
useIPv6dialog
''')
- expected_stdout = 'Found neither IPv6 ULA nor GUA address, blocking IPv6 ads will not be enabled'
+ expected_stdout = 'Unable to find IPv6 ULA/GUA address, IPv6 adblocking will not be enabled'
assert expected_stdout in detectPlatform.stdout
def test_IPv6_only_ULA(Pihole):