Merge branch 'development' into development

pull/1317/head
WaLLy3K 7 years ago committed by GitHub
commit 7d17c652f3

@ -0,0 +1,38 @@
# EditorConfig is awesome: http://EditorConfig.org
# top-most EditorConfig file
root = true
# Unix-style newlines with a newline ending every file
[*]
end_of_line = lf
insert_final_newline = true
indent_style = space
indent_size = tab
tab_width = 2
charset = utf-8
trim_trailing_whitespace = true
# Matches multiple files with brace expansion notation
# Set default charset
[*.{js,py}]
charset = utf-8
# 4 space indentation
[*.py]
indent_style = space
indent_size = 4
# Tab indentation (no size specified)
[Makefile]
indent_style = tab
# Indentation override for all JS under lib directory
[scripts/**.js]
indent_style = space
indent_size = 2
# Matches the exact files either package.json or .travis.yml
[{package.json,.travis.yml}]
indent_style = space
indent_size = 2

@ -2,7 +2,7 @@
- [] I have read and understood the [contributors guide](https://github.com/pi-hole/pi-hole/blob/master/CONTRIBUTING.md). - [] I have read and understood the [contributors guide](https://github.com/pi-hole/pi-hole/blob/master/CONTRIBUTING.md).
- [] The issue I am reporting can be *replicated* - [] The issue I am reporting can be *replicated*
- [] The issue I'm reporting isn't a duplicate (see [FAQs](https://github.com/pi-hole/pi-hole/wiki/FAQs), [closed issues](https://github.com/pi-hole/pi-hole/issues?utf8=%E2%9C%93&q=is%3Aissue%20is%3Aclosed%20), and [open issues](https://github.com/pi-hole/pi-hole/issues)). - [] The issue I am reporting isn't a duplicate (see [FAQs](https://github.com/pi-hole/pi-hole/wiki/FAQs), [closed issues](https://github.com/pi-hole/pi-hole/issues?utf8=%E2%9C%93&q=is%3Aissue%20is%3Aclosed%20), and [open issues](https://github.com/pi-hole/pi-hole/issues)).
**How familiar are you with the codebase?:** **How familiar are you with the codebase?:**

@ -10,7 +10,7 @@ group_defaults:
reset_on_push: reset_on_push:
enabled: true enabled: true
reject_value: -2 reject_value: -2
approve_regex: '^(Approved|:shipit:|:\+1:|Engage)' approve_regex: '^(Approved|:shipit:|:\+1:|Engage|:taco:)'
reject_regex: '^(Rejected|:-1:|Borg)' reject_regex: '^(Rejected|:-1:|Borg)'
author_approval: author_approval:
auto: true auto: true

@ -35,4 +35,5 @@ When requesting or submitting new features, first consider whether it might be u
- Before Submitting your Pull Request, merge `development` with your new branch and fix any conflicts. (Make sure you don't break anything in development!) - Before Submitting your Pull Request, merge `development` with your new branch and fix any conflicts. (Make sure you don't break anything in development!)
- Please use the [Google Style Guide for Shell](https://google.github.io/styleguide/shell.xml) for your code submission styles. - Please use the [Google Style Guide for Shell](https://google.github.io/styleguide/shell.xml) for your code submission styles.
- Commit Unix line endings. - Commit Unix line endings.
- Please use the Pi-hole brand: **Pi-hole** (Take a special look at the capitalized 'P' and a low 'h' with a hyphen)
- (Optional fun) keep to the theme of Star Trek/black holes/gravity. - (Optional fun) keep to the theme of Star Trek/black holes/gravity.

@ -5,12 +5,12 @@
</p> </p>
<p align="center"> <p align="center">
<a href=https://discourse.pi-hole.net><img src="https://assets.pi-hole.net/static/Vortex_text.png" width=210></a> <a href=https://discourse.pi-hole.net><img src="https://assets.pi-hole.net/static/Vortex_with_text_and_TM.png" width=210></a>
</p> </p>
## The multi-platform, network-wide ad blocker ## 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 - Web Browsers
- Cell Phones - Cell Phones
@ -53,9 +53,9 @@ wget -O basic-install.sh https://install.pi-hole.net
bash basic-install.sh 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?
<p align="center"> <p align="center">
<a href=https://www.youtube.com/watch?v=vKWjx1AQYgs><img src="https://assets.pi-hole.net/static/video-explainer.png"></a> <a href=https://www.youtube.com/watch?v=vKWjx1AQYgs><img src="https://assets.pi-hole.net/static/video-explainer.png"></a>
</p> </p>
@ -73,7 +73,7 @@ Once installed, [configure your router to have **DHCP clients use the Pi as thei
## 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. 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
@ -83,7 +83,7 @@ The [gravity.sh](https://github.com/pi-hole/pi-hole/blob/master/gravity.sh) does
#### Other Operating Systems #### 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 Webserver, it should work OK. If there are other platforms you'd like supported, let us know. 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 ### Web Interface
@ -102,7 +102,7 @@ Domains can be whitelisted and blacklisted using either the web interface or the
### Settings ### 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 - enable Pi-hole's built-in DHCP server
- exclude domains from the graphs - exclude domains from the graphs
@ -113,7 +113,7 @@ The settings page lets you control and configure your Pi-hole. You can do thing
#### 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. 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.
<p align="center"> <p align="center">
<a href=hhttps://discourse.pi-hole.net/t/how-do-i-configure-my-devices-to-use-pi-hole-as-their-dns-server/245><img src="https://assets.pi-hole.net/static/piholedhcpserver.png"></a> <a href=hhttps://discourse.pi-hole.net/t/how-do-i-configure-my-devices-to-use-pi-hole-as-their-dns-server/245><img src="https://assets.pi-hole.net/static/piholedhcpserver.png"></a>
</p> </p>
@ -137,14 +137,14 @@ 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) 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) - [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) - [Pi-hole stats in your Mac's menu bar](https://getbitbar.com/plugins/Network/pi-hole.1m.py)
- [Get LED alerts for each blocked ad](http://thetimmy.silvernight.org/pages/endisbutton/) - [Get LED alerts for each blocked ad](http://thetimmy.silvernight.org/pages/endisbutton/)
- [Pi-hole on Ubuntu 14.04 on VirtualBox](http://hbalagtas.blogspot.com/2016/02/adblocking-with-pi-hole-and-ubuntu-1404.html) - [Pi-hole on Ubuntu 14.04 on VirtualBox](http://hbalagtas.blogspot.com/2016/02/adblocking-with-pi-hole-and-ubuntu-1404.html)
- [Docker Pi-hole container (x86 and ARM)](https://hub.docker.com/r/diginc/pi-hole/) - [Docker Pi-hole container (x86 and ARM)](https://hub.docker.com/r/diginc/pi-hole/)
- [Splunk: Pi-hole Visualizser](https://splunkbase.splunk.com/app/3023/) - [Splunk: Pi-hole Visualiser](https://splunkbase.splunk.com/app/3023/)
- [Pi-hole Chrome extension](https://chrome.google.com/webstore/detail/pi-hole-list-editor/hlnoeoejkllgkjbnnnhfolapllcnaglh) ([open source](https://github.com/packtloss/pihole-extension)) - [Pi-hole Chrome extension](https://chrome.google.com/webstore/detail/pi-hole-list-editor/hlnoeoejkllgkjbnnnhfolapllcnaglh) ([open source](https://github.com/packtloss/pihole-extension))
- [Go Bananas for CHiP-hole ad blocking](https://www.hackster.io/jacobsalmela/chip-hole-network-wide-ad-blocker-98e037) - [Go Bananas for CHiP-hole ad blocking](https://www.hackster.io/jacobsalmela/chip-hole-network-wide-ad-blocker-98e037)
- [Sky-Hole](http://dlaa.me/blog/post/skyhole) - [Sky-Hole](http://dlaa.me/blog/post/skyhole)
@ -154,7 +154,7 @@ You can view [real-time stats](https://discourse.pi-hole.net/t/how-do-i-view-my-
- [Minibian Pi-hole](http://munkjensen.net/wiki/index.php/See_my_Pi-Hole#Minibian_Pi-hole) - [Minibian Pi-hole](http://munkjensen.net/wiki/index.php/See_my_Pi-Hole#Minibian_Pi-hole)
- [Windows Tray Stat Application](https://github.com/goldbattle/copernicus) - [Windows Tray Stat Application](https://github.com/goldbattle/copernicus)
- [Let your blink1 device blink when Pi-hole filters ads](https://gist.github.com/elpatron68/ec0b4c582e5abf604885ac1e068d233f) - [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 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) - [Pi-hole Droid - open source Android client](https://github.com/friimaind/pi-hole-droid)
## Coverage ## Coverage

@ -1,53 +1,23 @@
## Pi-hole ad-list default sources. Updated 29/10/2016 #########################
# #
# To make changes to this file: #
# 1. run `cp /etc/pihole/adlists.default /etc/pihole/adlists.list` #
# 2. run `nano /etc/pihole/adlists.list` #
# 3. Uncomment or comment any of the below lists #
# #
# Know of any other lists? Feel free to let us know about them, or add them #
# to this file! #
################################################################################
# The below list amalgamates several lists we used previously. # The below list amalgamates several lists we used previously.
# See `https://github.com/StevenBlack/hosts` for details # See `https://github.com/StevenBlack/hosts` for details
##StevenBlack's list
https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts
# Other lists we consider safe: ##MalwareDomains
https://mirror1.malwaredomains.com/files/justdomains https://mirror1.malwaredomains.com/files/justdomains
##Cameleon
http://sysctl.org/cameleon/hosts http://sysctl.org/cameleon/hosts
##Zeustracker
https://zeustracker.abuse.ch/blocklist.php?download=domainblocklist https://zeustracker.abuse.ch/blocklist.php?download=domainblocklist
##Disconnect.me Tracking
https://s3.amazonaws.com/lists.disconnect.me/simple_tracking.txt https://s3.amazonaws.com/lists.disconnect.me/simple_tracking.txt
##Disconnect.me Ads
https://s3.amazonaws.com/lists.disconnect.me/simple_ad.txt https://s3.amazonaws.com/lists.disconnect.me/simple_ad.txt
# hosts-file.net list. Updated frequently, but has been known to block legitimate sites. ##Hosts-file.net
https://hosts-file.net/ad_servers.txt https://hosts-file.net/ad_servers.txt
# Mahakala list. Has been known to block legitimate domains including the entire .com range.
# Warning: Due to the sheer size of this list, the web admin console will be unresponsive.
#https://adblock.mahakala.is/
# ADZHOSTS list. Has been known to block legitimate domains
#http://pilotfiber.dl.sourceforge.net/project/adzhosts/HOSTS.txt
# Windows 10 telemetry list
#https://raw.githubusercontent.com/crazy-max/WindowsSpyBlocker/master/data/hosts/win10/spy.txt
# Securemecca.com list - Also blocks "adult" sites (pornography/gambling etc)
#http://securemecca.com/Downloads/hosts.txt
# Quidsup's tracker list
#https://raw.githubusercontent.com/quidsup/notrack/master/trackers.txt
# Block the BBC News website Breaking News banner
#https://raw.githubusercontent.com/BreakingTheNews/BreakingTheNews.github.io/master/hosts
# Untested Lists:
#https://raw.githubusercontent.com/reek/anti-adblock-killer/master/anti-adblock-killer-filters.txt
#https://raw.githubusercontent.com/Dawsey21/Lists/master/main-blacklist.txt
#http://malwaredomains.lehigh.edu/files/domains.txt
# Following two lists should be used simultaneously: (readme https://github.com/notracking/hosts-blocklists/)
#https://raw.github.com/notracking/hosts-blocklists/master/hostnames.txt
#https://raw.github.com/notracking/hosts-blocklists/master/domains.txt
# Combination of several host files on the internet (warning some facebook domains are also blocked but you can go to facebook.com). See https://github.com/mat1th/Dns-add-block for more information.
#https://raw.githubusercontent.com/mat1th/Dns-add-block/master/hosts

@ -25,6 +25,8 @@ addn-hosts=/etc/pihole/local.list
domain-needed domain-needed
localise-queries
bogus-priv bogus-priv
no-resolv no-resolv

@ -8,101 +8,98 @@
# This file is copyright under the latest version of the EUPL. # This file is copyright under the latest version of the EUPL.
# Please see LICENSE file for your rights under this license. # Please see LICENSE file for your rights under this license.
#Functions############################################################################################################## # Functions
piLog="/var/log/pihole.log" piLog="/var/log/pihole.log"
gravity="/etc/pihole/gravity.list" gravity="/etc/pihole/gravity.list"
. /etc/pihole/setupVars.conf . /etc/pihole/setupVars.conf
function GetFTLData { function GetFTLData {
# Open connection to FTL # Open connection to FTL
exec 3<>/dev/tcp/localhost/"$(cat /var/run/pihole-FTL.port)" exec 3<>/dev/tcp/localhost/"$(cat /var/run/pihole-FTL.port)"
# Test if connection is open # Test if connection is open
if { >&3; } 2> /dev/null; then if { >&3; } 2> /dev/null; then
# Send command to FTL # Send command to FTL
echo -e ">$1" >&3 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 read -r -t 1 LINE <&3
until [ ! $? ] || [[ "$LINE" == *"EOM"* ]]; do done
echo "$LINE" >&1
read -r -t 1 LINE <&3
done
# Close connection # Close connection
exec 3>&- exec 3>&-
exec 3<&- exec 3<&-
fi fi
} }
outputJSON() { outputJSON() {
get_summary_data 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}}" 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() { get_summary_data() {
local summary=$(GetFTLData "stats") local summary=$(GetFTLData "stats")
domains_being_blocked_raw=$(grep "domains_being_blocked" <<< "${summary}" | grep -Eo "[0-9]+$") domains_being_blocked_raw=$(grep "domains_being_blocked" <<< "${summary}" | grep -Eo "[0-9]+$")
domains_being_blocked=$(printf "%'.f" ${domains_being_blocked_raw}) 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_raw=$(grep "dns_queries_today" <<< "$summary" | grep -Eo "[0-9]+$")
dns_queries_today=$(printf "%'.f" ${dns_queries_today_raw}) 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_raw=$(grep "ads_blocked_today" <<< "$summary" | grep -Eo "[0-9]+$")
ads_blocked_today=$(printf "%'.f" ${ads_blocked_today_raw}) ads_blocked_today=$(printf "%'.f" ${ads_blocked_today_raw})
ads_percentage_today_raw=$(grep "ads_percentage_today" <<< "$summary" | grep -Eo "[0-9.]+$") 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}) LC_NUMERIC=C ads_percentage_today=$(printf "%'.f" ${ads_percentage_today_raw})
} }
normalChrono() { normalChrono() {
for (( ; ; )); do for (( ; ; )); do
get_summary_data get_summary_data
domain=$(GetFTLData recentBlocked) domain=$(GetFTLData recentBlocked)
clear clear
# Displays a colorful Pi-hole logo # Displays a colorful Pi-hole logo
echo " ___ _ _ _" echo " ___ _ _ _"
echo "| _ (_)___| |_ ___| |___" echo "| _ (_)___| |_ ___| |___"
echo "| _/ |___| ' \/ _ \ / -_)" echo "| _/ |___| ' \/ _ \ / -_)"
echo "|_| |_| |_||_\___/_\___|" echo "|_| |_| |_||_\___/_\___|"
echo "" echo ""
echo " ${IPV4_ADDRESS}" echo " ${IPV4_ADDRESS}"
echo "" echo ""
uptime | cut -d' ' -f11- uptime | cut -d' ' -f11-
#uptime -p #Doesn't work on all versions of uptime #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."}' 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 "-------------------------------"
echo "Recently blocked:" echo "Recently blocked:"
echo " $domain" echo " $domain"
echo "Blocking: ${domains_being_blocked}" echo "Blocking: ${domains_being_blocked}"
echo "Queries: ${dns_queries_today}" echo "Queries: ${dns_queries_today}"
echo "Pi-holed: ${ads_blocked_today} (${ads_percentage_today}%)" echo "Pi-holed: ${ads_blocked_today} (${ads_percentage_today}%)"
sleep 5 sleep 5
done done
} }
displayHelp() { displayHelp() {
cat << EOM echo "Usage: pihole -c [options]
::: Displays stats about your piHole! Example: 'pihole -c -j'
::: Calculates stats and displays to an LCD
::: 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
::: Options: -h, --help Display this help text"
::: -j, --json output stats as JSON formatted string exit 0
::: -h, --help display this help text
EOM
exit 0
} }
if [[ $# = 0 ]]; then if [[ $# = 0 ]]; then
normalChrono normalChrono
fi fi
for var in "$@"; do for var in "$@"; do
case "$var" in case "$var" in
"-j" | "--json" ) outputJSON;; "-j" | "--json" ) outputJSON;;
"-h" | "--help" ) displayHelp;; "-h" | "--help" ) displayHelp;;
* ) exit 1;; * ) exit 1;;
esac esac
done done

@ -3,14 +3,12 @@
# (c) 2017 Pi-hole, LLC (https://pi-hole.net) # (c) 2017 Pi-hole, LLC (https://pi-hole.net)
# Network-wide ad blocking via your own hardware. # 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. # This file is copyright under the latest version of the EUPL.
# Please see LICENSE file for your rights under this license. # Please see LICENSE file for your rights under this license.
# Globals
#globals
basename=pihole basename=pihole
piholeDir=/etc/${basename} piholeDir=/etc/${basename}
whitelist=${piholeDir}/whitelist.txt whitelist=${piholeDir}/whitelist.txt
@ -27,123 +25,123 @@ listMain=""
listAlt="" listAlt=""
helpFunc() { helpFunc() {
if [[ "${listMain}" == "${whitelist}" ]]; then
if [[ ${listMain} == ${whitelist} ]]; then param="w"
param="w" type="white"
word="white" elif [[ "${listMain}" == "${wildcardlist}" ]]; then
elif [[ ${listMain} == ${wildcardlist} ]]; then param="wild"
param="wild" type="wildcard black"
word="wildcard" else
else param="b"
param="b" type="black"
word="black" fi
fi
echo "Usage: pihole -${param} [options] <domain> <domain2 ...>
cat << EOM Example: 'pihole -${param} site.com', or 'pihole -${param} site1.com site2.com'
::: Immediately add one or more domains to the ${word}list ${type^}list one or more domains
:::
::: Usage: pihole -${param} domain1 [domain2 ...] Options:"
:::
::: Options: if [[ "${listMain}" == "${wildcardlist}" ]]; then
::: -d, --delmode Remove domains from the ${word}list echo " -wild, --wildcard Block all subdomains of specified domain"
::: -nr, --noreload Update ${word}list without refreshing dnsmasq fi
::: -q, --quiet Output is less verbose
::: -h, --help Show this help dialog echo " -d, --delmode Remove domain(s) from the ${type}list
::: -l, --list Display domains on the ${word}list -nr, --noreload Update ${type}list without refreshing dnsmasq
EOM -q, --quiet Make output less verbose
if [[ "${param}" == "wild" ]]; then -h, --help Show this help dialog
echo "::: -wild, --wildcard Add wildcard entry (only blacklist)" -l, --list Display all your ${type}listed domains"
fi
exit 0 exit 0
} }
EscapeRegexp() { EscapeRegexp() {
# This way we may safely insert an arbitrary # This way we may safely insert an arbitrary
# string in our regular expressions # string in our regular expressions
# Also remove leading "." if present # Also remove leading "." if present
echo $* | sed 's/^\.*//' | sed "s/[]\.|$(){}?+*^]/\\\\&/g" | sed "s/\\//\\\\\//g" echo $* | sed 's/^\.*//' | sed "s/[]\.|$(){}?+*^]/\\\\&/g" | sed "s/\\//\\\\\//g"
} }
HandleOther(){ HandleOther() {
# First, convert everything to lowercase # First, convert everything to lowercase
domain=$(sed -e "y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/" <<< "$1") domain=$(sed -e "y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/" <<< "$1")
#check validity of domain # 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=$(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 if [[ -z "${validDomain}" ]]; then
echo "::: $1 is not a valid argument or domain name" echo "::: $1 is not a valid argument or domain name"
else else
domList=("${domList[@]}" ${validDomain}) domList=("${domList[@]}" ${validDomain})
fi fi
} }
PoplistFile() { PoplistFile() {
#check whitelist file exists, and if not, create it # Check whitelist file exists, and if not, create it
if [[ ! -f ${whitelist} ]]; then if [[ ! -f ${whitelist} ]]; then
touch ${whitelist} touch ${whitelist}
fi 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 for dom in "${domList[@]}"; do
if ${addmode}; then # 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
AddDomain "${dom}" "${listMain}" if ${addmode}; then
RemoveDomain "${dom}" "${listAlt}" AddDomain "${dom}" "${listMain}"
RemoveDomain "${dom}" "${wildcardlist}" RemoveDomain "${dom}" "${listAlt}"
else if [[ "${listMain}" == "${whitelist}" || "${listMain}" == "${blacklist}" ]]; then
RemoveDomain "${dom}" "${listMain}" RemoveDomain "${dom}" "${wildcardlist}"
fi fi
done else
RemoveDomain "${dom}" "${listMain}"
fi
done
} }
AddDomain() { AddDomain() {
list="$2" list="$2"
domain=$(EscapeRegexp "$1") domain=$(EscapeRegexp "$1")
if [[ "${list}" == "${whitelist}" || "${list}" == "${blacklist}" ]]; then if [[ "${list}" == "${whitelist}" || "${list}" == "${blacklist}" ]]; then
bool=true
bool=true # Is the domain in the list we want to add it to?
#Is the domain in the list we want to add it to? grep -Ex -q "${domain}" "${list}" > /dev/null 2>&1 || bool=false
grep -Ex -q "${domain}" "${list}" > /dev/null 2>&1 || bool=false
if [[ "${bool}" == false ]]; then
if [[ "${bool}" == false ]]; then # Domain not found in the whitelist file, add it!
#domain not found in the whitelist file, add it! if [[ "${verbose}" == true ]]; then
if [[ "${verbose}" == true ]]; then echo "::: Adding $1 to $list..."
echo "::: Adding $1 to $list..." fi
fi reload=true
reload=true # Add it to the list we want to add it to
# Add it to the list we want to add it to echo "$1" >> "${list}"
echo "$1" >> "${list}" else
else if [[ "${verbose}" == true ]]; then
if [[ "${verbose}" == true ]]; then echo "::: ${1} already exists in ${list}, no need to add!"
echo "::: ${1} already exists in ${list}, no need to add!" fi
fi fi
fi elif [[ "${list}" == "${wildcardlist}" ]]; then
source "${piholeDir}/setupVars.conf"
elif [[ "${list}" == "${wildcardlist}" ]]; then # Remove the /* from the end of the IPv4addr.
IPV4_ADDRESS=${IPV4_ADDRESS%/*}
source "${piholeDir}/setupVars.conf" IPV6_ADDRESS=${IPV6_ADDRESS}
#Remove the /* from the end of the IPv4addr.
IPV4_ADDRESS=${IPV4_ADDRESS%/*} bool=true
IPV6_ADDRESS=${IPV6_ADDRESS} # Is the domain in the list?
grep -e "address=\/${domain}\/" "${wildcardlist}" > /dev/null 2>&1 || bool=false
bool=true
#Is the domain in the list? if [[ "${bool}" == false ]]; then
grep -e "address=\/${domain}\/" "${wildcardlist}" > /dev/null 2>&1 || bool=false if [[ "${verbose}" == true ]]; then
echo "::: Adding $1 to wildcard blacklist..."
if [[ "${bool}" == false ]]; then fi
if [[ "${verbose}" == true ]]; then reload=true
echo "::: Adding $1 to wildcard blacklist..." echo "address=/$1/${IPV4_ADDRESS}" >> "${wildcardlist}"
fi if [[ "${#IPV6_ADDRESS}" > 0 ]]; then
reload=true echo "address=/$1/${IPV6_ADDRESS}" >> "${wildcardlist}"
echo "address=/$1/${IPV4_ADDRESS}" >> "${wildcardlist}" fi
if [[ ${#IPV6_ADDRESS} > 0 ]] ; then else
echo "address=/$1/${IPV6_ADDRESS}" >> "${wildcardlist}" if [[ "${verbose}" == true ]]; then
fi echo "::: ${1} already exists in wildcard blacklist, no need to add!"
else fi
if [[ "${verbose}" == true ]]; then fi
echo "::: ${1} already exists in wildcard blacklist, no need to add!" fi
fi
fi
fi
} }
RemoveDomain() { RemoveDomain() {
@ -151,85 +149,82 @@ RemoveDomain() {
domain=$(EscapeRegexp "$1") domain=$(EscapeRegexp "$1")
if [[ "${list}" == "${whitelist}" || "${list}" == "${blacklist}" ]]; then if [[ "${list}" == "${whitelist}" || "${list}" == "${blacklist}" ]]; then
bool=true
bool=true # Is it in the list? Logic follows that if its whitelisted it should not be blacklisted and vice versa
#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
grep -Ex -q "${domain}" "${list}" > /dev/null 2>&1 || bool=false if [[ "${bool}" == true ]]; then
if [[ "${bool}" == true ]]; then # Remove it from the other one
# Remove it from the other one echo "::: Removing $1 from $list..."
echo "::: Removing $1 from $list..." # /I flag: search case-insensitive
# /I flag: search case-insensitive sed -i "/${domain}/Id" "${list}"
sed -i "/${domain}/Id" "${list}" reload=true
reload=true else
else if [[ "${verbose}" == true ]]; then
if [[ "${verbose}" == true ]]; then echo "::: ${1} does not exist in ${list}, no need to remove!"
echo "::: ${1} does not exist in ${list}, no need to remove!"
fi
fi fi
fi
elif [[ "${list}" == "${wildcardlist}" ]]; then elif [[ "${list}" == "${wildcardlist}" ]]; then
bool=true
bool=true # Is it in the list?
#Is it in the list? grep -e "address=\/${domain}\/" "${wildcardlist}" > /dev/null 2>&1 || bool=false
grep -e "address=\/${domain}\/" "${wildcardlist}" > /dev/null 2>&1 || bool=false if [[ "${bool}" == true ]]; then
if [[ "${bool}" == true ]]; then # Remove it from the other one
# Remove it from the other one echo "::: Removing $1 from $list..."
echo "::: Removing $1 from $list..." # /I flag: search case-insensitive
# /I flag: search case-insensitive sed -i "/address=\/${domain}/Id" "${list}"
sed -i "/address=\/${domain}/Id" "${list}" reload=true
reload=true else
else if [[ "${verbose}" == true ]]; then
if [[ "${verbose}" == true ]]; then echo "::: ${1} does not exist in ${list}, no need to remove!"
echo "::: ${1} does not exist in ${list}, no need to remove!"
fi
fi fi
fi
fi fi
} }
Reload() { Reload() {
# Reload hosts file # Reload hosts file
pihole -g -sd pihole -g -sd
} }
Displaylist() { Displaylist() {
if [[ ${listMain} == ${whitelist} ]]; then if [[ "${listMain}" == "${whitelist}" ]]; then
string="gravity resistant domains" string="gravity resistant domains"
else else
string="domains caught in the sinkhole" string="domains caught in the sinkhole"
fi fi
verbose=false verbose=false
echo -e " Displaying $string \n" echo -e "Displaying $string:\n"
count=1 count=1
while IFS= read -r RD; do while IFS= read -r RD; do
echo "${count}: ${RD}" echo "${count}: ${RD}"
count=$((count+1)) count=$((count+1))
done < "${listMain}" done < "${listMain}"
exit 0; exit 0;
} }
for var in "$@"; do for var in "$@"; do
case "${var}" in case "${var}" in
"-w" | "whitelist" ) listMain="${whitelist}"; listAlt="${blacklist}";; "-w" | "whitelist" ) listMain="${whitelist}"; listAlt="${blacklist}";;
"-b" | "blacklist" ) listMain="${blacklist}"; listAlt="${whitelist}";; "-b" | "blacklist" ) listMain="${blacklist}"; listAlt="${whitelist}";;
"-wild" | "wildcard" ) listMain="${wildcardlist}";; "-wild" | "wildcard" ) listMain="${wildcardlist}";;
"-nr"| "--noreload" ) reload=false;; "-nr"| "--noreload" ) reload=false;;
"-d" | "--delmode" ) addmode=false;; "-d" | "--delmode" ) addmode=false;;
"-f" | "--force" ) force=true;; "-f" | "--force" ) force=true;;
"-q" | "--quiet" ) verbose=false;; "-q" | "--quiet" ) verbose=false;;
"-h" | "--help" ) helpFunc;; "-h" | "--help" ) helpFunc;;
"-l" | "--list" ) Displaylist;; "-l" | "--list" ) Displaylist;;
* ) HandleOther "${var}";; * ) HandleOther "${var}";;
esac esac
done done
shift shift
if [[ $# = 0 ]]; then if [[ $# = 0 ]]; then
helpFunc helpFunc
fi fi
PoplistFile PoplistFile
if ${reload}; then if ${reload}; then
Reload Reload
fi fi

@ -3,7 +3,7 @@
# (c) 2017 Pi-hole, LLC (https://pi-hole.net) # (c) 2017 Pi-hole, LLC (https://pi-hole.net)
# Network-wide ad blocking via your own hardware. # 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. # This file is copyright under the latest version of the EUPL.
# Please see LICENSE file for your rights under this license. # 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 # setupVars set in basic-install.sh
source "${setupVars}" source "${setupVars}"
update="false" update="false"
# Colour codes
red="\e[1;31m"
def="\e[0m"
fully_fetch_repo() { fully_fetch_repo() {
# Add upstream branches to shallow clone # Add upstream branches to shallow clone
local directory="${1}" local directory="${1}"
@ -35,7 +38,7 @@ fully_fetch_repo() {
return 0 return 0
} }
get_available_branches(){ get_available_branches() {
# Return available branches # Return available branches
local directory="${1}" 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 # Set the reference for the requested branch, fetch, check it put and pull it
cd "${directory}" cd "${directory}"
git remote set-branches origin "${branch}" || return 1 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 git fetch --quiet || return 1
checkout_pull_branch "${directory}" "${branch}" || return 1 checkout_pull_branch "${directory}" "${branch}" || return 1
} }
@ -79,23 +84,23 @@ checkout_pull_branch() {
} }
warning1() { warning1() {
echo "::: Note that changing the branch is a severe change of your Pi-hole system." echo " Please note that changing branches severely alters your Pi-hole subsystems"
echo "::: This is not supported unless one of the developers explicitly asks you to do this!" echo " Features that work on the master branch, may not on a development branch"
read -r -p "::: Have you read and understood this? [y/N] " response 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 case ${response} in
[yY][eE][sS]|[yY]) [yY][eE][sS]|[yY])
echo "::: Continuing." echo "::: Continuing with branch change."
return 0 return 0
;; ;;
*) *)
echo "::: Aborting." echo "::: Branch change has been cancelled."
return 1 return 1
;; ;;
esac esac
} }
checkout() checkout() {
{
local corebranches local corebranches
local webbranches local webbranches
@ -104,7 +109,7 @@ checkout()
#This is unlikely #This is unlikely
if ! is_repo "${PI_HOLE_FILES_DIR}" ; then if ! is_repo "${PI_HOLE_FILES_DIR}" ; then
echo "::: Critical Error: Core Pi-Hole repo is missing from system!" 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 "::: Please re-run install script from https://github.com/pi-hole/pi-hole"
exit 1; exit 1;
fi fi
@ -192,11 +197,10 @@ checkout()
if [[ ! "${1}" == "web" && "${update}" == "true" ]]; then if [[ ! "${1}" == "web" && "${update}" == "true" ]]; then
echo "::: Running installer to upgrade your installation" echo "::: Running installer to upgrade your installation"
if "${PI_HOLE_FILES_DIR}/automated install/basic-install.sh" --unattended; then if "${PI_HOLE_FILES_DIR}/automated install/basic-install.sh" --unattended; then
exit 0 exit 0
else else
echo "Unable to complete update, contact Pi-hole" echo "Unable to complete update, contact Pi-hole"
exit 1 exit 1
fi fi
fi fi
} }

@ -27,6 +27,7 @@ PIHOLELOG="/var/log/pihole.log"
PIHOLEGITDIR="/etc/.pihole/" PIHOLEGITDIR="/etc/.pihole/"
ADMINGITDIR="/var/www/html/admin/" ADMINGITDIR="/var/www/html/admin/"
WHITELISTMATCHES="/tmp/whitelistmatches.list" WHITELISTMATCHES="/tmp/whitelistmatches.list"
readonly FTLLOG="/var/log/pihole-FTL.log"
TIMEOUT=60 TIMEOUT=60
# Header info and introduction # Header info and introduction
@ -43,16 +44,11 @@ cat << EOM
::: Please read and note any issues, and follow any directions advised during this process. ::: Please read and note any issues, and follow any directions advised during this process.
EOM EOM
# Ensure the file exists, create if not, clear if exists.
truncate --size=0 "${DEBUG_LOG}"
chmod 644 ${DEBUG_LOG}
chown "$USER":pihole ${DEBUG_LOG}
source ${VARSFILE} source ${VARSFILE}
### Private functions exist here ### ### Private functions exist here ###
log_write() { log_write() {
echo "${1}" >> "${DEBUG_LOG}" echo "${@}" >&3
} }
log_echo() { log_echo() {
@ -77,14 +73,14 @@ log_echo() {
header_write() { header_write() {
log_echo "" log_echo ""
log_echo "${1}" log_echo "---= ${1}"
log_write "" log_write ""
} }
file_parse() { file_parse() {
while read -r line; do while read -r line; do
if [ ! -z "${line}" ]; then if [ ! -z "${line}" ]; then
[[ "${line}" =~ ^#.*$ || ! "${line}" ]] && continue [[ "${line}" =~ ^#.*$ || ! "${line}" || "${line}" == "WEBPASSWORD="* ]] && continue
log_write "${line}" log_write "${line}"
fi fi
done < "${1}" done < "${1}"
@ -231,6 +227,7 @@ ipv6_check() {
ip_check() { ip_check() {
local protocol=${1} local protocol=${1}
local gravity=${2} 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) }')" 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 if [[ -n ${ip_addr_list} ]]; then
@ -263,18 +260,18 @@ ip_ping_check() {
if [[ -n ${ip_def_gateway} ]]; then if [[ -n ${ip_def_gateway} ]]; then
echo -n "::: Pinging default IPv${protocol} gateway: " 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 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 return 1
else else
echo "Gateway responded." log_echo "Gateway responded."
log_write "${ping_gateway}" log_write "${ping_gateway}"
fi fi
echo -n "::: Pinging Internet via IPv${protocol}: " 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 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 return 1
else else
echo "Query responded." log_echo "Query responded."
log_write "${ping_inet}" log_write "${ping_inet}"
fi fi
else else
@ -363,9 +360,9 @@ testChaos(){
log_write "Pi-hole dnsmasq specific records lookups" log_write "Pi-hole dnsmasq specific records lookups"
log_write "Cache Size:" log_write "Cache Size:"
dig +short chaos txt cachesize.bind >> ${DEBUG_LOG} log_write $(dig +short chaos txt cachesize.bind)
log_write "Upstream Servers:" log_write "Upstream Servers:"
dig +short chaos txt servers.bind >> ${DEBUG_LOG} log_write $(dig +short chaos txt servers.bind)
log_write "" log_write ""
} }
@ -375,10 +372,8 @@ checkProcesses() {
echo "::: Logging status of lighttpd, dnsmasq and pihole-FTL..." echo "::: Logging status of lighttpd, dnsmasq and pihole-FTL..."
PROCESSES=( lighttpd dnsmasq pihole-FTL ) PROCESSES=( lighttpd dnsmasq pihole-FTL )
for i in "${PROCESSES[@]}"; do for i in "${PROCESSES[@]}"; do
log_write "" log_write "Status for ${i} daemon:"
log_write "${i}" log_write $(systemctl is-active "${i}")
log_write " processes status:"
systemctl -l status "${i}" >> "${DEBUG_LOG}"
done done
log_write "" log_write ""
} }
@ -417,7 +412,7 @@ dumpPiHoleLog() {
if [ -e "${PIHOLELOG}" ]; then if [ -e "${PIHOLELOG}" ]; then
# Dummy process to use for flagging down tail to terminate # Dummy process to use for flagging down tail to terminate
countdown & countdown &
tail -n0 -f --pid=$! "${PIHOLELOG}" >> ${DEBUG_LOG} tail -n0 -f --pid=$! "${PIHOLELOG}" >&4
else else
log_write "No pihole.log file found!" log_write "No pihole.log file found!"
printf ":::\tNo pihole.log file found!\n" printf ":::\tNo pihole.log file found!\n"
@ -428,6 +423,16 @@ dumpPiHoleLog() {
finalWork() { finalWork() {
local tricorder local tricorder
echo "::: Finshed debugging!" 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." echo "::: The debug log can be uploaded to tricorder.pi-hole.net for sharing with developers only."
if [[ "${AUTOMATED}" ]]; then if [[ "${AUTOMATED}" ]]; then
echo "::: Debug script running in automated mode, uploading log to tricorder..." echo "::: Debug script running in automated mode, uploading log to tricorder..."
@ -456,6 +461,17 @@ finalWork() {
} }
### END FUNCTIONS ### ### 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 # Gather version of required packages / repositories
version_check || echo "REQUIRED FILES MISSING" version_check || echo "REQUIRED FILES MISSING"
@ -508,6 +524,18 @@ header_write "Analyzing pihole.log"
&& log_write "${PIHOLELOG} is ${pihole_size}." \ && log_write "${PIHOLELOG} is ${pihole_size}." \
|| log_echo "Warning: No pihole.log file found!" || 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 trap finalWork EXIT
### Method calls for additional logging ### ### Method calls for additional logging ###

@ -3,18 +3,22 @@
# (c) 2017 Pi-hole, LLC (https://pi-hole.net) # (c) 2017 Pi-hole, LLC (https://pi-hole.net)
# Network-wide ad blocking via your own hardware. # Network-wide ad blocking via your own hardware.
# #
# Flushes /var/log/pihole.log # Flushes Pi-hole's log file
# #
# This file is copyright under the latest version of the EUPL. # This file is copyright under the latest version of the EUPL.
# Please see LICENSE file for your rights under this license. # Please see LICENSE file for your rights under this license.
echo -n "::: Flushing /var/log/pihole.log ..." echo -n "::: Flushing /var/log/pihole.log ..."
# Test if logrotate is available on this system # Test if logrotate is available on this system
if command -v /usr/sbin/logrotate &> /dev/null; then 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 /usr/sbin/logrotate --force /etc/pihole/logrotate
else else
# Flush both pihole.log and pihole.log.1 (if existing)
echo " " > /var/log/pihole.log echo " " > /var/log/pihole.log
if [ -f /var/log/pihole.log.1 ]; then
echo " " > /var/log/pihole.log.1
fi
fi fi
echo "... done!" echo "... done!"

@ -90,10 +90,11 @@ FTLcheckUpdate() {
main() { main() {
local pihole_version_current local pihole_version_current
local web_version_current local web_version_current
source "${setupVars}"
#This is unlikely #This is unlikely
if ! is_repo "${PI_HOLE_FILES_DIR}" ; then if ! is_repo "${PI_HOLE_FILES_DIR}" ; then
echo "::: Critical Error: Core Pi-Hole repo is missing from system!" 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 "::: Please re-run install script from https://github.com/pi-hole/pi-hole"
exit 1; exit 1;
fi fi

@ -3,24 +3,29 @@
# (c) 2017 Pi-hole, LLC (https://pi-hole.net) # (c) 2017 Pi-hole, LLC (https://pi-hole.net)
# Network-wide ad blocking via your own hardware. # 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. # This file is copyright under the latest version of the EUPL.
# Please see LICENSE file for your rights under this license. # Please see LICENSE file for your rights under this license.
# Variables # Variables
DEFAULT="-1" DEFAULT="-1"
PHGITDIR="/etc/.pihole/" COREGITDIR="/etc/.pihole/"
WEBGITDIR="/var/www/html/admin/" WEBGITDIR="/var/www/html/admin/"
getLocalVersion() { getLocalVersion() {
# FTL requires a different method
if [[ "$1" == "FTL" ]]; then
pihole-FTL version
return 0
fi
# Get the tagged version of the local repository # Get the tagged version of the local repository
local directory="${1}" local directory="${1}"
local version local version
cd "${directory}" || { echo "${DEFAULT}"; return 1; } cd "${directory}" 2> /dev/null || { echo "${DEFAULT}"; return 1; }
version=$(git describe --tags --always || \ version=$(git describe --tags --always || echo "$DEFAULT")
echo "${DEFAULT}")
if [[ "${version}" =~ ^v ]]; then if [[ "${version}" =~ ^v ]]; then
echo "${version}" echo "${version}"
elif [[ "${version}" == "${DEFAULT}" ]]; then elif [[ "${version}" == "${DEFAULT}" ]]; then
@ -33,13 +38,18 @@ getLocalVersion() {
} }
getLocalHash() { 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 # Get the short hash of the local repository
local directory="${1}" local directory="${1}"
local hash local hash
cd "${directory}" || { echo "${DEFAULT}"; return 1; } cd "${directory}" 2> /dev/null || { echo "${DEFAULT}"; return 1; }
hash=$(git rev-parse --short HEAD || \ hash=$(git rev-parse --short HEAD || echo "$DEFAULT")
echo "${DEFAULT}")
if [[ "${hash}" == "${DEFAULT}" ]]; then if [[ "${hash}" == "${DEFAULT}" ]]; then
echo "ERROR" echo "ERROR"
return 1 return 1
@ -49,12 +59,33 @@ getLocalHash() {
return 0 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(){ getRemoteVersion(){
# Get the version from the remote origin # Get the version from the remote origin
local daemon="${1}" local daemon="${1}"
local version 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 }' | \ awk -F: '$1 ~/tag_name/ { print $2 }' | \
tr -cd '[[:alnum:]]._-') tr -cd '[[:alnum:]]._-')
if [[ "${version}" =~ ^v ]]; then if [[ "${version}" =~ ^v ]]; then
@ -66,72 +97,72 @@ getRemoteVersion(){
return 0 return 0
} }
#PHHASHLATEST=$(curl -s https://api.github.com/repos/pi-hole/pi-hole/commits/master | \ versionOutput() {
# grep sha | \ [[ "$1" == "pi-hole" ]] && GITDIR=$COREGITDIR
# head -n1 | \ [[ "$1" == "AdminLTE" ]] && GITDIR=$WEBGITDIR
# awk -F ' ' '{ print $2 }' | \ [[ "$1" == "FTL" ]] && GITDIR="FTL"
# tr -cd '[[:alnum:]]._-')
[[ "$2" == "-c" ]] || [[ "$2" == "--current" ]] || [[ -z "$2" ]] && current=$(getLocalVersion $GITDIR)
#WEBHASHLATEST=$(curl -s https://api.github.com/repos/pi-hole/AdminLTE/commits/master | \ [[ "$2" == "-l" ]] || [[ "$2" == "--latest" ]] || [[ -z "$2" ]] && latest=$(getRemoteVersion "$1")
# grep sha | \ if [[ "$2" == "-h" ]] || [[ "$2" == "--hash" ]]; then
# head -n1 | \ [[ "$3" == "-c" ]] || [[ "$3" == "--current" ]] || [[ -z "$3" ]] && curHash=$(getLocalHash "$GITDIR")
# awk -F ' ' '{ print $2 }' | \ [[ "$3" == "-l" ]] || [[ "$3" == "--latest" ]] || [[ -z "$3" ]] && latHash=$(getRemoteHash "$1" "$(cd "$GITDIR" 2> /dev/null && git rev-parse --abbrev-ref HEAD)")
# tr -cd '[[:alnum:]]._-') fi
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 [[ -n "$current" ]] && [[ -n "$latest" ]]; then
if [ -d "${WEBGITDIR}" ]; then output="${1^} version is $current (Latest: $latest)"
case "${1}" in elif [[ -n "$current" ]] && [[ -z "$latest" ]]; then
"-l" | "--latest" ) echo $(getRemoteVersion AdminLTE);; output="Current ${1^} version is $current"
"-c" | "--current" ) echo $(getLocalVersion "${WEBGITDIR}");; elif [[ -z "$current" ]] && [[ -n "$latest" ]]; then
"-h" | "--hash" ) echo $(getLocalHash "${WEBGITDIR}");; output="Latest ${1^} version is $latest"
* ) echo "::: Invalid Option!"; exit 1; elif [[ "$curHash" == "N/A" ]] || [[ "$latHash" == "N/A" ]]; then
esac 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 else
echo "::: Web interface not installed!"; exit 1; errorOutput
fi fi
[[ -n "$output" ]] && echo " $output"
} }
coreOutput() { errorOutput() {
case "${1}" in echo " Invalid Option! Try 'pihole -v --help' for more information."
"-l" | "--latest" ) echo $(getRemoteVersion pi-hole);; exit 1
"-c" | "--current" ) echo $(getLocalVersion "${PHGITDIR}");; }
"-h" | "--hash" ) echo $(getLocalHash "${PHGITDIR}");;
* ) echo "::: Invalid Option!"; exit 1; defaultOutput() {
esac versionOutput "pi-hole" "$@"
versionOutput "AdminLTE" "$@"
versionOutput "FTL" "$@"
} }
helpFunc() { helpFunc() {
cat << EOM echo "Usage: pihole -v [repo | option] [option]
::: Example: 'pihole -v -p -l'
::: Show Pi-hole/Web Admin versions Show Pi-hole, Admin Console & FTL versions
:::
::: Usage: pihole -v [ -a | -p ] [ -l | -c ] Repositories:
::: -p, --pihole Only retrieve info regarding Pi-hole repository
::: Options: -a, --admin Only retrieve info regarding AdminLTE repository
::: -a, --admin Show both current and latest versions of web admin -f, --ftl Only retrieve info regarding FTL repository
::: -p, --pihole Show both current and latest versions of Pi-hole core files
::: -l, --latest (Only after -a | -p) Return only latest version Options:
::: -c, --current (Only after -a | -p) Return only current version -c, --current Return the current version
::: -h, --help Show this help dialog -l, --latest Return the latest version
::: --hash Return the Github hash from your local repositories
EOM -h, --help Show this help dialog"
exit 0 exit 0
} }
if [[ $# = 0 ]]; then
normalOutput
fi
case "${1}" in case "${1}" in
"-a" | "--admin" ) shift; webOutput "$@";; "-p" | "--pihole" ) shift; versionOutput "pi-hole" "$@";;
"-p" | "--pihole" ) shift; coreOutput "$@" ;; "-a" | "--admin" ) shift; versionOutput "AdminLTE" "$@";;
"-f" | "--ftl" ) shift; versionOutput "FTL" "$@";;
"-h" | "--help" ) helpFunc;; "-h" | "--help" ) helpFunc;;
* ) defaultOutput "$@";;
esac esac

@ -8,7 +8,6 @@
# This file is copyright under the latest version of the EUPL. # This file is copyright under the latest version of the EUPL.
# Please see LICENSE file for your rights under this license. # Please see LICENSE file for your rights under this license.
readonly setupVars="/etc/pihole/setupVars.conf" readonly setupVars="/etc/pihole/setupVars.conf"
readonly dnsmasqconfig="/etc/dnsmasq.d/01-pihole.conf" readonly dnsmasqconfig="/etc/dnsmasq.d/01-pihole.conf"
readonly dhcpconfig="/etc/dnsmasq.d/02-pihole-dhcp.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" readonly dhcpstaticconfig="/etc/dnsmasq.d/04-pihole-static-dhcp.conf"
helpFunc() { helpFunc() {
cat << EOM echo "Usage: pihole -a [options]
::: Set admin options for the web interface of pihole Example: pihole -a -p password
::: Set options for the Admin Console
::: Usage: pihole -a [options]
::: Options:
::: Options: -f, flush Flush the Pi-hole log
::: -p, password Set web interface password, an empty input will remove any previously set password -p, password Set Admin Console password
::: -c, celsius Set Celsius temperature unit -c, celsius Set Celsius as preferred temperature unit
::: -f, fahrenheit Set Fahrenheit temperature unit -f, fahrenheit Set Fahrenheit as preferred temperature unit
::: -k, kelvin Set Kelvin temperature unit -k, kelvin Set Kelvin as preferred temperature unit
::: -h, --help Show this help dialog -h, --help Show this help dialog
::: -i, interface Setup interface listening behavior of dnsmasq -i, interface Specify dnsmasq's interface listening behavior
::: pihole -a -i local : Listen on all interfaces, but allow only queries from Add '-h' for more info on interface usage"
::: 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
exit 0 exit 0
} }
@ -61,14 +56,18 @@ delete_dnsmasq_setting() {
sed -i "/${1}/d" "${dnsmasqconfig}" sed -i "/${1}/d" "${dnsmasqconfig}"
} }
SetTemperatureUnit(){ SetTemperatureUnit() {
change_setting "TEMPERATUREUNIT" "${unit}" change_setting "TEMPERATUREUNIT" "${unit}"
} }
SetWebPassword(){ 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() {
if [ "${SUDO_USER}" == "www-data" ]; then if [ "${SUDO_USER}" == "www-data" ]; then
echo "Security measure: user www-data is not allowed to change webUI password!" echo "Security measure: user www-data is not allowed to change webUI password!"
echo "Exiting" echo "Exiting"
@ -81,19 +80,32 @@ SetWebPassword(){
exit 1 exit 1
fi fi
# Set password only if there is one to be set if (( ${#args[2]} > 0 )) ; then
if (( ${#args[2]} > 0 )) ; then readonly PASSWORD="${args[2]}"
# Compute password hash twice to avoid rainbow table vulnerability readonly CONFIRM="${PASSWORD}"
hash=$(echo -n ${args[2]} | sha256sum | sed 's/\s.*$//') else
hash=$(echo -n ${hash} | sha256sum | sed 's/\s.*$//') read -s -p "Enter New Password (Blank for no password): " PASSWORD
echo ""
if [ "${PASSWORD}" == "" ]; then
change_setting "WEBPASSWORD" ""
echo "Password Removed"
exit 0
fi
read -s -p "Confirm Password: " CONFIRM
echo ""
fi
if [ "${PASSWORD}" == "${CONFIRM}" ] ; then
hash=$(HashPassword ${PASSWORD})
# Save hash to file # Save hash to file
change_setting "WEBPASSWORD" "${hash}" change_setting "WEBPASSWORD" "${hash}"
echo "New password set" echo "New password set"
else else
change_setting "WEBPASSWORD" "" echo "Passwords don't match. Your password has not been changed"
echo "Password removed" exit 1
fi fi
} }
ProcessDNSSettings() { ProcessDNSSettings() {
@ -155,8 +167,7 @@ trust-anchor=.,19036,8,2,49AAC11D7B6F6446702E54A1607371607A1A41855200FD2CE1CDDE3
} }
SetDNSServers(){ SetDNSServers() {
# Save setting to file # Save setting to file
delete_setting "PIHOLE_DNS" delete_setting "PIHOLE_DNS"
IFS=',' read -r -a array <<< "${args[2]}" IFS=',' read -r -a array <<< "${args[2]}"
@ -187,72 +198,59 @@ SetDNSServers(){
# Restart dnsmasq to load new configuration # Restart dnsmasq to load new configuration
RestartDNS RestartDNS
} }
SetExcludeDomains(){ SetExcludeDomains() {
change_setting "API_EXCLUDE_DOMAINS" "${args[2]}" change_setting "API_EXCLUDE_DOMAINS" "${args[2]}"
} }
SetExcludeClients(){ SetExcludeClients() {
change_setting "API_EXCLUDE_CLIENTS" "${args[2]}" change_setting "API_EXCLUDE_CLIENTS" "${args[2]}"
} }
Reboot(){ Reboot() {
nohup bash -c "sleep 5; reboot" &> /dev/null </dev/null & nohup bash -c "sleep 5; reboot" &> /dev/null </dev/null &
} }
RestartDNS(){ RestartDNS() {
if [ -x "$(command -v systemctl)" ]; then if [ -x "$(command -v systemctl)" ]; then
systemctl restart dnsmasq &> /dev/null systemctl restart dnsmasq &> /dev/null
else else
service dnsmasq restart &> /dev/null service dnsmasq restart &> /dev/null
fi fi
} }
SetQueryLogOptions(){ SetQueryLogOptions() {
change_setting "API_QUERY_LOG_SHOW" "${args[2]}" change_setting "API_QUERY_LOG_SHOW" "${args[2]}"
} }
ProcessDHCPSettings() { ProcessDHCPSettings() {
source "${setupVars}" source "${setupVars}"
if [[ "${DHCP_ACTIVE}" == "true" ]]; then 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
# Use eth0 as fallback interface if [ -z ${interface} ]; then
if [ -z ${interface} ]; then interface="eth0"
interface="eth0" fi
fi
if [[ "${PIHOLE_DOMAIN}" == "" ]]; then
if [[ "${PIHOLE_DOMAIN}" == "" ]]; then PIHOLE_DOMAIN="local"
PIHOLE_DOMAIN="local" change_setting "PIHOLE_DOMAIN" "${PIHOLE_DOMAIN}"
change_setting "PIHOLE_DOMAIN" "${PIHOLE_DOMAIN}" fi
fi
if [[ "${DHCP_LEASETIME}" == "0" ]]; then
if [[ "${DHCP_LEASETIME}" == "0" ]]; then leasetime="infinite"
leasetime="infinite" elif [[ "${DHCP_LEASETIME}" == "" ]]; then
elif [[ "${DHCP_LEASETIME}" == "" ]]; then leasetime="24h"
leasetime="24h" change_setting "DHCP_LEASETIME" "${leasetime}"
change_setting "DHCP_LEASETIME" "${leasetime}" else
else leasetime="${DHCP_LEASETIME}h"
leasetime="${DHCP_LEASETIME}h" fi
fi
# Write settings to file
# Write settings to file echo "###############################################################################
echo "###############################################################################
# DHCP SERVER CONFIG FILE AUTOMATICALLY POPULATED BY PI-HOLE WEB INTERFACE. # # DHCP SERVER CONFIG FILE AUTOMATICALLY POPULATED BY PI-HOLE WEB INTERFACE. #
# ANY CHANGES MADE TO THIS FILE WILL BE LOST ON CHANGE # # ANY CHANGES MADE TO THIS FILE WILL BE LOST ON CHANGE #
############################################################################### ###############################################################################
@ -263,26 +261,25 @@ dhcp-leasefile=/etc/pihole/dhcp.leases
#quiet-dhcp #quiet-dhcp
" > "${dhcpconfig}" " > "${dhcpconfig}"
if [[ "${PIHOLE_DOMAIN}" != "none" ]]; then if [[ "${PIHOLE_DOMAIN}" != "none" ]]; then
echo "domain=${PIHOLE_DOMAIN}" >> "${dhcpconfig}" echo "domain=${PIHOLE_DOMAIN}" >> "${dhcpconfig}"
fi fi
if [[ "${DHCP_IPv6}" == "true" ]]; then if [[ "${DHCP_IPv6}" == "true" ]]; then
echo "#quiet-dhcp6 echo "#quiet-dhcp6
#enable-ra #enable-ra
dhcp-option=option6:dns-server,[::] dhcp-option=option6:dns-server,[::]
dhcp-range=::100,::1ff,constructor:${interface},ra-names,slaac,${leasetime} dhcp-range=::100,::1ff,constructor:${interface},ra-names,slaac,${leasetime}
ra-param=*,0,0 ra-param=*,0,0
" >> "${dhcpconfig}" " >> "${dhcpconfig}"
fi fi
else else
rm "${dhcpconfig}" &> /dev/null rm "${dhcpconfig}" &> /dev/null
fi fi
} }
EnableDHCP(){ EnableDHCP() {
change_setting "DHCP_ACTIVE" "true" change_setting "DHCP_ACTIVE" "true"
change_setting "DHCP_START" "${args[2]}" change_setting "DHCP_START" "${args[2]}"
change_setting "DHCP_END" "${args[3]}" change_setting "DHCP_END" "${args[3]}"
@ -300,8 +297,7 @@ EnableDHCP(){
RestartDNS RestartDNS
} }
DisableDHCP(){ DisableDHCP() {
change_setting "DHCP_ACTIVE" "false" change_setting "DHCP_ACTIVE" "false"
# Remove possible old setting from file # Remove possible old setting from file
@ -313,24 +309,37 @@ DisableDHCP(){
RestartDNS RestartDNS
} }
SetWebUILayout(){ SetWebUILayout() {
change_setting "WEBUIBOXEDLAYOUT" "${args[2]}" change_setting "WEBUIBOXEDLAYOUT" "${args[2]}"
} }
SetPrivacyMode(){ CustomizeAdLists() {
list="/etc/pihole/adlists.list"
if [[ "${args[2]}" == "enable" ]]; then
sed -i "\\@${args[3]}@s/^#http/http/g" "${list}"
elif [[ "${args[2]}" == "disable" ]]; then
sed -i "\\@${args[3]}@s/^http/#http/g" "${list}"
elif [[ "${args[2]}" == "add" ]]; then
echo "${args[3]}" >> ${list}
elif [[ "${args[2]}" == "del" ]]; then
var=$(echo "${args[3]}" | sed 's/\//\\\//g')
sed -i "/${var}/Id" "${list}"
else
echo "Not permitted"
return 1
fi
}
if [[ "${args[2]}" == "true" ]] ; then SetPrivacyMode() {
if [[ "${args[2]}" == "true" ]]; then
change_setting "API_PRIVACY_MODE" "true" change_setting "API_PRIVACY_MODE" "true"
else else
change_setting "API_PRIVACY_MODE" "false" change_setting "API_PRIVACY_MODE" "false"
fi fi
} }
ResolutionSettings() { ResolutionSettings() {
typ="${args[2]}" typ="${args[2]}"
state="${args[3]}" state="${args[3]}"
@ -339,11 +348,9 @@ ResolutionSettings() {
elif [[ "${typ}" == "clients" ]]; then elif [[ "${typ}" == "clients" ]]; then
change_setting "API_GET_CLIENT_HOSTNAME" "${state}" change_setting "API_GET_CLIENT_HOSTNAME" "${state}"
fi fi
} }
AddDHCPStaticAddress() { AddDHCPStaticAddress() {
mac="${args[2]}" mac="${args[2]}"
ip="${args[3]}" ip="${args[3]}"
host="${args[4]}" host="${args[4]}"
@ -358,18 +365,14 @@ AddDHCPStaticAddress() {
# Full info given # Full info given
echo "dhcp-host=${mac},${ip},${host}" >> "${dhcpstaticconfig}" echo "dhcp-host=${mac},${ip},${host}" >> "${dhcpstaticconfig}"
fi fi
} }
RemoveDHCPStaticAddress() { RemoveDHCPStaticAddress() {
mac="${args[2]}" mac="${args[2]}"
sed -i "/dhcp-host=${mac}.*/d" "${dhcpstaticconfig}" sed -i "/dhcp-host=${mac}.*/d" "${dhcpstaticconfig}"
} }
SetHostRecord(){ SetHostRecord() {
if [ -n "${args[3]}" ]; then if [ -n "${args[3]}" ]; then
change_setting "HOSTRECORD" "${args[2]},${args[3]}" change_setting "HOSTRECORD" "${args[2]},${args[3]}"
echo "Setting host record for ${args[2]} -> ${args[3]}" echo "Setting host record for ${args[2]} -> ${args[3]}"
@ -382,17 +385,28 @@ SetHostRecord(){
# Restart dnsmasq to load new configuration # Restart dnsmasq to load new configuration
RestartDNS RestartDNS
} }
SetListeningMode(){ SetListeningMode() {
source "${setupVars}" source "${setupVars}"
if [[ "${args[2]}" == "all" ]] ; 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
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!" echo "Listening on all interfaces, permiting all origins, hope you have a firewall!"
change_setting "DNSMASQ_LISTENING" "all" 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)" echo "Listening on all interfaces, permitting only origins that are at most one hop away (local devices)"
change_setting "DNSMASQ_LISTENING" "local" change_setting "DNSMASQ_LISTENING" "local"
else else
@ -407,17 +421,14 @@ SetListeningMode(){
# Restart dnsmasq to load new configuration # Restart dnsmasq to load new configuration
RestartDNS RestartDNS
fi fi
} }
Teleporter() Teleporter() {
{
local datetimestamp=$(date "+%Y-%m-%d_%H-%M-%S") 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" php /var/www/html/admin/scripts/pi-hole/php/teleporter.php > "pi-hole-teleporter_${datetimestamp}.zip"
} }
main() { main() {
args=("$@") args=("$@")
case "${args[1]}" in case "${args[1]}" in
@ -440,8 +451,9 @@ main() {
"addstaticdhcp" ) AddDHCPStaticAddress;; "addstaticdhcp" ) AddDHCPStaticAddress;;
"removestaticdhcp" ) RemoveDHCPStaticAddress;; "removestaticdhcp" ) RemoveDHCPStaticAddress;;
"hostrecord" ) SetHostRecord;; "hostrecord" ) SetHostRecord;;
"-i" | "interface" ) SetListeningMode;; "-i" | "interface" ) SetListeningMode "$@";;
"-t" | "teleporter" ) Teleporter;; "-t" | "teleporter" ) Teleporter;;
"adlist" ) CustomizeAdLists;;
* ) helpFunc;; * ) helpFunc;;
esac esac
@ -450,5 +462,4 @@ main() {
if [[ $# = 0 ]]; then if [[ $# = 0 ]]; then
helpFunc helpFunc
fi fi
} }

@ -1,15 +1,55 @@
<?php <?php
/* Detailed Pi-Hole Block Page: Show "Website Blocked" if user browses to site, but not to image/file requests based on the work of WaLLy3K for DietPi & Pi-Hole */ /* Detailed Pi-hole Block Page: Show "Website Blocked" if user browses to site, but not to image/file requests based on the work of WaLLy3K for DietPi & Pi-Hole */
function validIP($address){
if (preg_match('/[.:0]/', $address) && !preg_match('/[1-9a-f]/', $address)) {
// Test if address contains either `:` or `0` but not 1-9 or a-f
return false;
}
return !filter_var($address, FILTER_VALIDATE_IP) === false;
}
$uri = escapeshellcmd($_SERVER['REQUEST_URI']); $uri = escapeshellcmd($_SERVER['REQUEST_URI']);
$serverName = escapeshellcmd($_SERVER['SERVER_NAME']); $serverName = escapeshellcmd($_SERVER['SERVER_NAME']);
// If the server name is 'pi.hole', it's likely a user trying to get to the admin panel.
// Let's be nice and redirect them.
if ($serverName === 'pi.hole')
{
header('HTTP/1.1 301 Moved Permanently');
header("Location: /admin/");
}
// Retrieve server URI extension (EG: jpg, exe, php) // Retrieve server URI extension (EG: jpg, exe, php)
ini_set('pcre.recursion_limit',100);
$uriExt = pathinfo($uri, PATHINFO_EXTENSION); $uriExt = pathinfo($uri, PATHINFO_EXTENSION);
// Define which URL extensions get rendered as "Website Blocked" // Define which URL extensions get rendered as "Website Blocked"
$webExt = array('asp', 'htm', 'html', 'php', 'rss', 'xml'); $webExt = array('asp', 'htm', 'html', 'php', 'rss', 'xml');
// Get IPv4 and IPv6 addresses from setupVars.conf (if available)
$setupVars = parse_ini_file("/etc/pihole/setupVars.conf");
$ipv4 = isset($setupVars["IPV4_ADDRESS"]) ? explode("/", $setupVars["IPV4_ADDRESS"])[0] : $_SERVER['SERVER_ADDR'];
$ipv6 = isset($setupVars["IPV6_ADDRESS"]) ? explode("/", $setupVars["IPV6_ADDRESS"])[0] : $_SERVER['SERVER_ADDR'];
$AUTHORIZED_HOSTNAMES = array(
$ipv4,
$ipv6,
str_replace(array("[","]"), array("",""), $_SERVER["SERVER_ADDR"]),
"pi.hole",
"localhost");
// Allow user set virtual hostnames
$virtual_host = getenv('VIRTUAL_HOST');
if (!empty($virtual_host))
array_push($AUTHORIZED_HOSTNAMES, $virtual_host);
// Immediately quit since we didn't block this page (the IP address or pi.hole is explicitly requested)
if(validIP($serverName) || in_array($serverName,$AUTHORIZED_HOSTNAMES))
{
http_response_code(404);
die();
}
if(in_array($uriExt, $webExt) || empty($uriExt)) if(in_array($uriExt, $webExt) || empty($uriExt))
{ {
// Requested resource has an extension listed in $webExt // Requested resource has an extension listed in $webExt
@ -37,7 +77,7 @@ if (!$showPage)
die(); die();
} }
// Get Pi-Hole version // Get Pi-hole version
$piHoleVersion = exec('cd /etc/.pihole/ && git describe --tags --abbrev=0'); $piHoleVersion = exec('cd /etc/.pihole/ && git describe --tags --abbrev=0');
// Don't show the URI if it is the root directory // Don't show the URI if it is the root directory
@ -48,6 +88,7 @@ if($uri == "/")
?> ?>
<!DOCTYPE html> <!DOCTYPE html>
<html>
<head> <head>
<meta charset='UTF-8'/> <meta charset='UTF-8'/>
<title>Website Blocked</title> <title>Website Blocked</title>
@ -144,7 +185,7 @@ function add() {
} }
$.ajax({ $.ajax({
url: "admin/scripts/pi-hole/php/add.php", url: "/admin/scripts/pi-hole/php/add.php",
method: "post", method: "post",
data: {"domain":domain.val(), "list":"white", "pw":pw.val()}, data: {"domain":domain.val(), "list":"white", "pw":pw.val()},
success: function(response) { success: function(response) {

@ -13,11 +13,11 @@ FTLUSER=pihole
PIDFILE=/var/run/pihole-FTL.pid PIDFILE=/var/run/pihole-FTL.pid
get_pid() { get_pid() {
cat "$PIDFILE" pidof "pihole-FTL"
} }
is_running() { is_running() {
[ -f "$PIDFILE" ] && ps $(get_pid) > /dev/null 2>&1 ps "$(get_pid)" > /dev/null 2>&1
} }
# Start the service # Start the service
@ -36,8 +36,8 @@ start() {
# Stop the service # Stop the service
stop() { stop() {
if is_running; then if is_running; then
kill $(get_pid) kill "$(get_pid)"
for i in {1..10}; do for i in {1..5}; do
if ! is_running; then if ! is_running; then
break break
fi fi
@ -48,7 +48,8 @@ stop() {
echo echo
if is_running; then if is_running; then
echo "Not stopped; may still be shutting down or shutdown may have failed" echo "Not stopped; may still be shutting down or shutdown may have failed, killing now"
kill -9 "$(get_pid)"
exit 1 exit 1
else else
echo "Stopped" echo "Stopped"
@ -61,16 +62,13 @@ stop() {
### main logic ### ### main logic ###
case "$1" in case "$1" in
start)
start
;;
stop) stop)
stop stop
;; ;;
status) status)
status pihole-FTL status pihole-FTL
;; ;;
restart|reload|condrestart) start|restart|reload|condrestart)
stop stop
start start
;; ;;

@ -86,7 +86,7 @@ if command -v apt-get &> /dev/null; then
#Debian Family #Debian Family
############################################# #############################################
PKG_MANAGER="apt-get" 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) 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 # 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" PKG_COUNT="${PKG_MANAGER} -s -o Debug::NoLocking=true upgrade | grep -c ^Inst || true"
@ -105,7 +105,7 @@ if command -v apt-get &> /dev/null; then
phpVer="php5" phpVer="php5"
fi fi
# ######################################### # #########################################
INSTALLER_DEPS=(apt-utils debconf dhcpcd5 git ${iproute_pkg} whiptail) INSTALLER_DEPS=(apt-utils dialog debconf dhcpcd5 git ${iproute_pkg} whiptail)
PIHOLE_DEPS=(bc cron curl dnsmasq dnsutils iputils-ping lsof netcat sudo unzip wget) PIHOLE_DEPS=(bc cron curl dnsmasq dnsutils iputils-ping lsof netcat sudo unzip wget)
PIHOLE_WEB_DEPS=(lighttpd ${phpVer}-common ${phpVer}-cgi) PIHOLE_WEB_DEPS=(lighttpd ${phpVer}-common ${phpVer}-cgi)
LIGHTTPD_USER="www-data" LIGHTTPD_USER="www-data"
@ -136,7 +136,7 @@ elif command -v rpm &> /dev/null; then
UPDATE_PKG_CACHE=":" UPDATE_PKG_CACHE=":"
PKG_INSTALL=(${PKG_MANAGER} install -y) PKG_INSTALL=(${PKG_MANAGER} install -y)
PKG_COUNT="${PKG_MANAGER} check-update | egrep '(.i686|.x86|.noarch|.arm|.src)' | wc -l" PKG_COUNT="${PKG_MANAGER} check-update | egrep '(.i686|.x86|.noarch|.arm|.src)' | wc -l"
INSTALLER_DEPS=(git iproute net-tools newt procps-ng) INSTALLER_DEPS=(dialog git iproute net-tools newt procps-ng)
PIHOLE_DEPS=(bc bind-utils cronie curl dnsmasq findutils nmap-ncat sudo unzip wget) PIHOLE_DEPS=(bc bind-utils cronie curl dnsmasq findutils nmap-ncat sudo unzip wget)
PIHOLE_WEB_DEPS=(lighttpd lighttpd-fastcgi php php-common php-cli) PIHOLE_WEB_DEPS=(lighttpd lighttpd-fastcgi php php-common php-cli)
if ! grep -q 'Fedora' /etc/redhat-release; then if ! grep -q 'Fedora' /etc/redhat-release; then
@ -233,7 +233,7 @@ find_IPv4_information() {
get_available_interfaces() { get_available_interfaces() {
# Get available UP interfaces. # Get available UP interfaces.
availableInterfaces=$(ip -o link | grep -v "state DOWN\|lo" | awk '{print $2}' | cut -d':' -f1 | cut -d'@' -f1) availableInterfaces=$(ip --oneline link show up | grep -v "lo" | awk '{print $2}' | cut -d':' -f1 | cut -d'@' -f1)
} }
welcomeDialogs() { welcomeDialogs() {
@ -268,7 +268,7 @@ verifyFreeDiskSpace() {
# - Insufficient free disk space # - Insufficient free disk space
elif [[ ${existing_free_kilobytes} -lt ${required_free_kilobytes} ]]; then elif [[ ${existing_free_kilobytes} -lt ${required_free_kilobytes} ]]; then
echo "::: Insufficient Disk Space!" 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 "::: 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 "::: You only have ${existing_free_kilobytes} KiloBytes free."
echo "::: If this is a new install you may need to expand your disk." 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 "::: Try running 'sudo raspi-config', and choose the 'expand file system option'"
@ -408,7 +408,7 @@ setDHCPCD() {
echo "interface ${PIHOLE_INTERFACE} echo "interface ${PIHOLE_INTERFACE}
static ip_address=${IPV4_ADDRESS} static ip_address=${IPV4_ADDRESS}
static routers=${IPv4gw} 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() { setStaticIPv4() {
@ -438,7 +438,7 @@ setStaticIPv4() {
cp "${IFCFG_FILE}" "${IFCFG_FILE}".pihole.orig cp "${IFCFG_FILE}" "${IFCFG_FILE}".pihole.orig
# Build Interface configuration file: # Build Interface configuration file:
{ {
echo "# Configured via Pi-Hole installer" echo "# Configured via Pi-hole installer"
echo "DEVICE=$PIHOLE_INTERFACE" echo "DEVICE=$PIHOLE_INTERFACE"
echo "BOOTPROTO=none" echo "BOOTPROTO=none"
echo "ONBOOT=yes" echo "ONBOOT=yes"
@ -619,14 +619,14 @@ version_check_dnsmasq() {
local dnsmasq_conf="/etc/dnsmasq.conf" local dnsmasq_conf="/etc/dnsmasq.conf"
local dnsmasq_conf_orig="/etc/dnsmasq.conf.orig" local dnsmasq_conf_orig="/etc/dnsmasq.conf.orig"
local dnsmasq_pihole_id_string="addn-hosts=/etc/pihole/gravity.list" local dnsmasq_pihole_id_string="addn-hosts=/etc/pihole/gravity.list"
local dnsmasq_original_config="/etc/.pihole/advanced/dnsmasq.conf.original" local dnsmasq_original_config="${PI_HOLE_LOCAL_REPO}/advanced/dnsmasq.conf.original"
local dnsmasq_pihole_01_snippet="/etc/.pihole/advanced/01-pihole.conf" local dnsmasq_pihole_01_snippet="${PI_HOLE_LOCAL_REPO}/advanced/01-pihole.conf"
local dnsmasq_pihole_01_location="/etc/dnsmasq.d/01-pihole.conf" local dnsmasq_pihole_01_location="/etc/dnsmasq.d/01-pihole.conf"
if [ -f ${dnsmasq_conf} ]; then if [ -f ${dnsmasq_conf} ]; then
echo -n "::: Existing dnsmasq.conf found..." echo -n "::: Existing dnsmasq.conf found..."
if grep -q ${dnsmasq_pihole_id_string} ${dnsmasq_conf}; then if grep -q ${dnsmasq_pihole_id_string} ${dnsmasq_conf}; then
echo " it is from a previous pi-hole install." echo " it is from a previous Pi-hole install."
echo -n "::: Backing up dnsmasq.conf to dnsmasq.conf.orig..." echo -n "::: Backing up dnsmasq.conf to dnsmasq.conf.orig..."
mv -f ${dnsmasq_conf} ${dnsmasq_conf_orig} mv -f ${dnsmasq_conf} ${dnsmasq_conf_orig}
echo " done." echo " done."
@ -634,7 +634,7 @@ version_check_dnsmasq() {
cp ${dnsmasq_original_config} ${dnsmasq_conf} cp ${dnsmasq_original_config} ${dnsmasq_conf}
echo " done." echo " done."
else else
echo " it is not a pi-hole file, leaving alone!" echo " it is not a Pi-hole file, leaving alone!"
fi fi
else else
echo -n "::: No dnsmasq.conf found.. restoring default dnsmasq.conf..." echo -n "::: No dnsmasq.conf found.. restoring default dnsmasq.conf..."
@ -706,9 +706,9 @@ installScripts() {
} }
installConfigs() { installConfigs() {
# Install the configs from /etc/.pihole to their various locations # Install the configs from PI_HOLE_LOCAL_REPO to their various locations
echo ":::" echo ":::"
echo "::: Installing configs..." echo "::: Installing configs from ${PI_HOLE_LOCAL_REPO}..."
version_check_dnsmasq version_check_dnsmasq
#Only mess with lighttpd configs if user has chosen to install web interface #Only mess with lighttpd configs if user has chosen to install web interface
@ -719,7 +719,7 @@ installConfigs() {
elif [ -f "/etc/lighttpd/lighttpd.conf" ]; then elif [ -f "/etc/lighttpd/lighttpd.conf" ]; then
mv /etc/lighttpd/lighttpd.conf /etc/lighttpd/lighttpd.conf.orig mv /etc/lighttpd/lighttpd.conf /etc/lighttpd/lighttpd.conf.orig
fi fi
cp /etc/.pihole/advanced/${LIGHTTPD_CFG} /etc/lighttpd/lighttpd.conf cp ${PI_HOLE_LOCAL_REPO}/advanced/${LIGHTTPD_CFG} /etc/lighttpd/lighttpd.conf
mkdir -p /var/run/lighttpd mkdir -p /var/run/lighttpd
chown ${LIGHTTPD_USER}:${LIGHTTPD_GROUP} /var/run/lighttpd chown ${LIGHTTPD_USER}:${LIGHTTPD_GROUP} /var/run/lighttpd
mkdir -p /var/cache/lighttpd/compress mkdir -p /var/cache/lighttpd/compress
@ -797,7 +797,7 @@ notify_package_updates_available() {
echo "::: Your system is up to date! Continuing with Pi-hole installation..." echo "::: Your system is up to date! Continuing with Pi-hole installation..."
else else
echo "::: There are ${updatesToInstall} updates available for your system!" echo "::: There are ${updatesToInstall} updates available for your system!"
echo "::: We recommend you update your OS after installing Pi-Hole! " echo "::: We recommend you update your OS after installing Pi-hole! "
echo ":::" echo ":::"
fi fi
else else
@ -874,7 +874,7 @@ installPiholeWeb() {
echo "::: Existing index.php detected, not overwriting" echo "::: Existing index.php detected, not overwriting"
else else
echo -n "::: index.php missing, replacing... " echo -n "::: index.php missing, replacing... "
cp /etc/.pihole/advanced/index.php /var/www/html/pihole/ cp ${PI_HOLE_LOCAL_REPO}/advanced/index.php /var/www/html/pihole/
echo " done!" echo " done!"
fi fi
@ -882,7 +882,7 @@ installPiholeWeb() {
echo "::: Existing index.js detected, not overwriting" echo "::: Existing index.js detected, not overwriting"
else else
echo -n "::: index.js missing, replacing... " echo -n "::: index.js missing, replacing... "
cp /etc/.pihole/advanced/index.js /var/www/html/pihole/ cp ${PI_HOLE_LOCAL_REPO}/advanced/index.js /var/www/html/pihole/
echo " done!" echo " done!"
fi fi
@ -890,14 +890,14 @@ installPiholeWeb() {
echo "::: Existing blockingpage.css detected, not overwriting" echo "::: Existing blockingpage.css detected, not overwriting"
else else
echo -n "::: blockingpage.css missing, replacing... " echo -n "::: blockingpage.css missing, replacing... "
cp /etc/.pihole/advanced/blockingpage.css /var/www/html/pihole cp ${PI_HOLE_LOCAL_REPO}/advanced/blockingpage.css /var/www/html/pihole
echo " done!" echo " done!"
fi fi
else else
echo "::: Creating directory for blocking page" echo "::: Creating directory for blocking page"
install -d /var/www/html/pihole install -d /var/www/html/pihole
install -D /etc/.pihole/advanced/{index,blockingpage}.* /var/www/html/pihole/ install -D ${PI_HOLE_LOCAL_REPO}/advanced/{index,blockingpage}.* /var/www/html/pihole/
if [ -f /var/www/html/index.lighttpd.html ]; then if [ -f /var/www/html/index.lighttpd.html ]; then
mv /var/www/html/index.lighttpd.html /var/www/html/index.lighttpd.orig mv /var/www/html/index.lighttpd.html /var/www/html/index.lighttpd.orig
else else
@ -910,7 +910,7 @@ installPiholeWeb() {
echo ":::" echo ":::"
echo -n "::: Installing sudoer file..." echo -n "::: Installing sudoer file..."
mkdir -p /etc/sudoers.d/ mkdir -p /etc/sudoers.d/
cp /etc/.pihole/advanced/pihole.sudo /etc/sudoers.d/pihole cp ${PI_HOLE_LOCAL_REPO}/advanced/pihole.sudo /etc/sudoers.d/pihole
# Add lighttpd user (OS dependent) to sudoers file # Add lighttpd user (OS dependent) to sudoers file
echo "${LIGHTTPD_USER} ALL=NOPASSWD: /usr/local/bin/pihole" >> /etc/sudoers.d/pihole echo "${LIGHTTPD_USER} ALL=NOPASSWD: /usr/local/bin/pihole" >> /etc/sudoers.d/pihole
@ -928,7 +928,7 @@ installCron() {
# Install the cron job # Install the cron job
echo ":::" echo ":::"
echo -n "::: Installing latest Cron script..." echo -n "::: Installing latest Cron script..."
cp /etc/.pihole/advanced/pihole.cron /etc/cron.d/pihole cp ${PI_HOLE_LOCAL_REPO}/advanced/pihole.cron /etc/cron.d/pihole
echo " done!" echo " done!"
} }
@ -942,7 +942,7 @@ runGravity() {
fi fi
# Test if /etc/pihole/adlists.default exists # Test if /etc/pihole/adlists.default exists
if [[ ! -e /etc/pihole/adlists.default ]]; then if [[ ! -e /etc/pihole/adlists.default ]]; then
cp /etc/.pihole/adlists.default /etc/pihole/adlists.default cp ${PI_HOLE_LOCAL_REPO}/adlists.default /etc/pihole/adlists.default
fi fi
echo "::: Running gravity.sh" echo "::: Running gravity.sh"
{ /opt/pihole/gravity.sh; } { /opt/pihole/gravity.sh; }
@ -965,7 +965,7 @@ configureFirewall() {
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 ":::\n::: Not installing firewall rulesets."; return 0; } { echo -e ":::\n::: Not installing firewall rulesets."; return 0; }
echo -e ":::\n:::\n Configuring FirewallD for httpd and dnsmasq." echo -e ":::\n:::\n Configuring FirewallD for httpd and dnsmasq."
firewall-cmd --permanent --add-port=80/tcp --add-port=53/tcp --add-port=53/udp firewall-cmd --permanent --add-service=http --add-service=dns
firewall-cmd --reload firewall-cmd --reload
return 0 return 0
# Check for proper kernel modules to prevent failure # Check for proper kernel modules to prevent failure
@ -1017,7 +1017,7 @@ finalExports() {
# Look for DNS server settings which would have to be reapplied # Look for DNS server settings which would have to be reapplied
source "${setupVars}" source "${setupVars}"
source "/etc/.pihole/advanced/Scripts/webpage.sh" source "${PI_HOLE_LOCAL_REPO}/advanced/Scripts/webpage.sh"
if [[ "${DNS_FQDN_REQUIRED}" != "" ]] ; then if [[ "${DNS_FQDN_REQUIRED}" != "" ]] ; then
ProcessDNSSettings ProcessDNSSettings
@ -1032,7 +1032,7 @@ installLogrotate() {
# Install the logrotate script # Install the logrotate script
echo ":::" echo ":::"
echo -n "::: Installing latest logrotate script..." echo -n "::: Installing latest logrotate script..."
cp /etc/.pihole/advanced/logrotate /etc/pihole/logrotate cp ${PI_HOLE_LOCAL_REPO}/advanced/logrotate /etc/pihole/logrotate
# Different operating systems have different user / group # Different operating systems have different user / group
# settings for logrotate that makes it impossible to create # settings for logrotate that makes it impossible to create
# a static logrotate file that will work with e.g. # a static logrotate file that will work with e.g.
@ -1221,7 +1221,7 @@ FTLinstall() {
stop_service pihole-FTL &> /dev/null stop_service pihole-FTL &> /dev/null
install -T -m 0755 /tmp/${binary} /usr/bin/pihole-FTL install -T -m 0755 /tmp/${binary} /usr/bin/pihole-FTL
cd "${orig_dir}" cd "${orig_dir}"
install -T -m 0755 "/etc/.pihole/advanced/pihole-FTL.service" "/etc/init.d/pihole-FTL" install -T -m 0755 "${PI_HOLE_LOCAL_REPO}/advanced/pihole-FTL.service" "/etc/init.d/pihole-FTL"
echo "done." echo "done."
return 0 return 0
else else
@ -1413,7 +1413,8 @@ main() {
pw="" pw=""
if [[ $(grep 'WEBPASSWORD' -c /etc/pihole/setupVars.conf) == 0 ]] ; then if [[ $(grep 'WEBPASSWORD' -c /etc/pihole/setupVars.conf) == 0 ]] ; then
pw=$(tr -dc _A-Z-a-z-0-9 < /dev/urandom | head -c 8) pw=$(tr -dc _A-Z-a-z-0-9 < /dev/urandom | head -c 8)
/usr/local/bin/pihole -a -p "${pw}" . /opt/pihole/webpage.sh
echo "WEBPASSWORD=$(HashPassword ${pw})" >> ${setupVars}
fi fi
fi fi
@ -1460,7 +1461,7 @@ main() {
echo "::: ${pw}" echo "::: ${pw}"
echo ":::" echo ":::"
echo "::: You can always change it using" echo "::: You can always change it using"
echo "::: pihole -a -p new_password" echo "::: pihole -a -p"
fi fi
fi fi

@ -26,10 +26,12 @@ EOM
exit 0 exit 0
} }
PIHOLE_COMMAND="/usr/local/bin/pihole"
adListFile=/etc/pihole/adlists.list adListFile=/etc/pihole/adlists.list
adListDefault=/etc/pihole/adlists.default adListDefault=/etc/pihole/adlists.default #being deprecated
whitelistScript="pihole -w" adListRepoDefault=/etc/.pihole/adlists.default
whitelistScript="${PIHOLE_COMMAND} -w"
whitelistFile=/etc/pihole/whitelist.txt whitelistFile=/etc/pihole/whitelist.txt
blacklistFile=/etc/pihole/blacklist.txt blacklistFile=/etc/pihole/blacklist.txt
readonly wildcardlist="/etc/dnsmasq.d/03-pihole-wildcard.conf" readonly wildcardlist="/etc/dnsmasq.d/03-pihole-wildcard.conf"
@ -70,36 +72,34 @@ fi
########################### ###########################
# collapse - begin formation of pihole # collapse - begin formation of pihole
gravity_collapse() { gravity_collapse() {
#New Logic:
# Does /etc/pihole/adlists.list exist? If so leave it alone
# 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}
fi
if [ ! -f ${adListFile} ]; then
cp ${adListRepoDefault} ${adListFile}
fi
echo "::: Neutrino emissions detected..." echo "::: Neutrino emissions detected..."
echo ":::" echo ":::"
#Decide if we're using a custom ad block list, or defaults. echo -n "::: Pulling source lists into range..."
if [ -f ${adListFile} ]; then sources=()
#custom file found, use this instead of default while IFS= read -r line || [[ -n "$line" ]]; do
echo -n "::: Custom adList file detected. Reading..." #Do not read commented out or blank lines
sources=() if [[ ${line} = \#* ]] || [[ ! ${line} ]]; then
while IFS= read -r line || [[ -n "$line" ]]; do echo "" > /dev/null
#Do not read commented out or blank lines else
if [[ ${line} = \#* ]] || [[ ! ${line} ]]; then sources+=(${line})
echo "" > /dev/null fi
else done < ${adListFile}
sources+=(${line}) echo " done!"
fi
done < ${adListFile}
echo " done!"
else
#no custom file found, use defaults!
echo -n "::: No custom adlist file detected, reading from default file..."
sources=()
while IFS= read -r line || [[ -n "$line" ]]; do
#Do not read commented out or blank lines
if [[ ${line} = \#* ]] || [[ ! ${line} ]]; then
echo "" > /dev/null
else
sources+=(${line})
fi
done < ${adListDefault}
echo " done!"
fi
} }
# patternCheck - check to see if curl downloaded any new files. # patternCheck - check to see if curl downloaded any new files.
@ -168,6 +168,10 @@ gravity_transport() {
# Process result # Process result
gravity_patternCheck "${patternBuffer}" ${success} "${err}" gravity_patternCheck "${patternBuffer}" ${success} "${err}"
# Delete temp file if it hasn't been moved
if [[ -f "${patternBuffer}" ]]; then
rm "${patternBuffer}"
fi
} }
# spinup - main gravity function # spinup - main gravity function
@ -183,22 +187,26 @@ gravity_spinup() {
saveLocation=${piholeDir}/list.${i}.${domain}.${justDomainsExtension} saveLocation=${piholeDir}/list.${i}.${domain}.${justDomainsExtension}
activeDomains[$i]=${saveLocation} activeDomains[$i]=${saveLocation}
agent="Mozilla/10.0" 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 # Use a case statement to download lists that need special cURL commands
# to complete properly and reset the user agent when required # to complete properly and reset the user agent when required
case "${domain}" in case "${domain}" in
"adblock.mahakala.is") "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' 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/" cmd_ext="-e http://forum.xda-developers.com/"
;; ;;
"adaway.org")
agent='Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36'
;;
"pgl.yoyo.org") "pgl.yoyo.org")
cmd_ext="-d mimetype=plaintext -d hostformat=hosts" cmd_ext="-d mimetype=plaintext -d hostformat=hosts"
;; ;;
# Default is a simple request # Default is a simple request
*) cmd_ext="" *) cmd_ext=""
esac esac
if [[ "${skipDownload}" == false ]]; then if [[ "${skipDownload}" == false ]]; then
echo -n "::: Getting $domain list..." echo -n "::: Getting $domain list..."
@ -385,7 +393,7 @@ gravity_reload() {
#Now replace the line in dnsmasq file #Now replace the line in dnsmasq file
# sed -i "s/^addn-hosts.*/addn-hosts=$adList/" /etc/dnsmasq.d/01-pihole.conf # sed -i "s/^addn-hosts.*/addn-hosts=$adList/" /etc/dnsmasq.d/01-pihole.conf
pihole restartdns "${PIHOLE_COMMAND}" restartdns
echo " done!" echo " done!"
} }
@ -403,8 +411,6 @@ if [[ "${forceGrav}" == true ]]; then
echo " done!" echo " done!"
fi fi
#Overwrite adlists.default from /etc/.pihole in case any changes have been made. Changes should be saved in /etc/adlists.list
cp /etc/.pihole/adlists.default /etc/pihole/adlists.default
gravity_collapse gravity_collapse
gravity_spinup gravity_spinup
if [[ "${skipDownload}" == false ]]; then if [[ "${skipDownload}" == false ]]; then
@ -423,4 +429,4 @@ gravity_hostFormat
gravity_blackbody gravity_blackbody
gravity_reload gravity_reload
pihole status "${PIHOLE_COMMAND}" status

250
pihole

@ -9,11 +9,11 @@
# Please see LICENSE file for your rights under this license. # Please see LICENSE file for your rights under this license.
readonly PI_HOLE_SCRIPT_DIR="/opt/pihole" readonly PI_HOLE_SCRIPT_DIR="/opt/pihole"
readonly wildcardlist="/etc/dnsmasq.d/03-pihole-wildcard.conf" readonly wildcardlist="/etc/dnsmasq.d/03-pihole-wildcard.conf"
# Must be root to use this tool # Must be root to use this tool
if [[ ! $EUID -eq 0 ]];then if [[ ! $EUID -eq 0 ]];then
if [ -x "$(command -v sudo)" ];then if [[ -x "$(command -v sudo)" ]]; then
exec sudo bash "$0" "$@" exec sudo bash "$0" "$@"
exit $? exit $?
else else
@ -80,66 +80,49 @@ updateGravityFunc() {
exit 0 exit 0
} }
scanList(){ scanList() {
domain="${1}" domain="${1}"
list="${2}" list="${2}"
method="${3}" method="${3}"
if [[ ${method} == "-exact" ]] ; then
grep -i -E "(^|\s)${domain}($|\s)" "${list}" if [[ "${method}" == "-exact" ]]; then
grep -i -E -l "(^|\s|\/)${domain}($|\s|\/)" ${list}
else else
grep -i "${domain}" "${list}" grep -i "${domain}" ${list}
fi 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() { queryFunc() {
domain="${2}"
method="${3}" method="${3}"
lists=( /etc/pihole/list.* /etc/pihole/blacklist.txt)
for list in ${lists[@]}; do # If domain contains non ASCII characters, convert domain to punycode if python exists
if [ -e "${list}" ]; then # Cr: https://serverfault.com/a/335079
result=$(scanList ${domain} ${list} ${method}) if [[ -z "${2}" ]]; then
# Remove empty lines before couting number of results echo "::: No domain specified"
count=$(sed '/^\s*$/d' <<< "$result" | wc -l) exit 1
echo "::: ${list} (${count} results)" elif [[ "${2}" = *[![:ascii:]]* ]]; then
if [[ ${count} > 0 ]]; then [[ "$(which python)" ]] && domain=$(python -c 'import sys;print sys.argv[1].decode("utf-8").encode("idna")' "${2}")
echo "${result}" else
fi domain="${2}"
echo "" fi
else
echo "::: ${list} does not exist" # Scan Whitelist, Blacklist and Wildcards
echo "" lists="/etc/pihole/whitelist.txt /etc/pihole/blacklist.txt $wildcardlist"
fi result=$(scanList ${domain} "${lists}" ${method})
done if [[ -n "$result" ]]; then
echo "$result"
# Scan for possible wildcard matches [[ ! -t 1 ]] && exit 0
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 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 exit 0
} }
@ -163,16 +146,16 @@ versionFunc() {
restartDNS() { restartDNS() {
dnsmasqPid=$(pidof dnsmasq) dnsmasqPid=$(pidof dnsmasq)
if [[ ${dnsmasqPid} ]]; then if [[ "${dnsmasqPid}" ]]; then
# service already running - reload config # Service already running - reload config
if [ -x "$(command -v systemctl)" ]; then if [[ -x "$(command -v systemctl)" ]]; then
systemctl restart dnsmasq systemctl restart dnsmasq
else else
service dnsmasq restart service dnsmasq restart
fi fi
else else
# service not running, start it up # Service not running, start it up
if [ -x "$(command -v systemctl)" ]; then if [[ -x "$(command -v systemctl)" ]]; then
systemctl start dnsmasq systemctl start dnsmasq
else else
service dnsmasq start service dnsmasq start
@ -181,16 +164,25 @@ restartDNS() {
} }
piholeEnable() { piholeEnable() {
if [[ "${1}" == "0" ]] ; then if [[ "${2}" == "-h" ]] || [[ "${2}" == "--help" ]]; then
#Disable Pihole 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\/gravity.list/#addn-hosts=\/etc\/pihole\/gravity.list/' /etc/dnsmasq.d/01-pihole.conf
echo "::: Blocking has been disabled!" echo "::: Blocking has been disabled!"
if [[ $# > 1 ]] ; then if [[ $# > 1 ]]; then
if [[ ${2} == *"s"* ]] ; then if [[ "${2}" == *"s"* ]]; then
tt=${2%"s"} tt=${2%"s"}
echo "::: Blocking will be re-enabled in ${tt} seconds" echo "::: Blocking will be re-enabled in ${tt} seconds"
nohup bash -c "sleep ${tt}; pihole enable" </dev/null &>/dev/null & nohup bash -c "sleep ${tt}; pihole enable" </dev/null &>/dev/null &
elif [[ ${2} == *"m"* ]] ; then elif [[ "${2}" == *"m"* ]]; then
tt=${2%"m"} tt=${2%"m"}
echo "::: Blocking will be re-enabled in ${tt} minutes" echo "::: Blocking will be re-enabled in ${tt} minutes"
tt=$((${tt}*60)) tt=$((${tt}*60))
@ -204,7 +196,7 @@ piholeEnable() {
fi fi
fi fi
else else
#Enable pihole # Enable Pi-hole
echo "::: Blocking has been enabled!" echo "::: Blocking has been enabled!"
sed -i 's/^#addn-hosts/addn-hosts/' /etc/dnsmasq.d/01-pihole.conf sed -i 's/^#addn-hosts/addn-hosts/' /etc/dnsmasq.d/01-pihole.conf
fi fi
@ -213,15 +205,23 @@ piholeEnable() {
piholeLogging() { piholeLogging() {
shift shift
if [[ "${1}" == "-h" ]] || [[ "${1}" == "--help" ]]; then
if [[ "${1}" == "off" ]] ; then echo "Usage: pihole logging [options]
#Disable Logging Example: 'pihole logging on'
Specify whether the Pi-hole log should be used
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/^log-queries/#log-queries/' /etc/dnsmasq.d/01-pihole.conf
sed -i 's/^QUERY_LOGGING=true/QUERY_LOGGING=false/' /etc/pihole/setupVars.conf sed -i 's/^QUERY_LOGGING=true/QUERY_LOGGING=false/' /etc/pihole/setupVars.conf
pihole -f pihole -f
echo "::: Logging has been disabled!" echo "::: Logging has been disabled!"
elif [[ "${1}" == "on" ]] ; then elif [[ "${1}" == "on" ]]; then
#Enable logging # Enable logging
sed -i 's/^#log-queries/log-queries/' /etc/dnsmasq.d/01-pihole.conf 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 sed -i 's/^QUERY_LOGGING=false/QUERY_LOGGING=true/' /etc/pihole/setupVars.conf
echo "::: Logging has been enabled!" echo "::: Logging has been enabled!"
@ -233,12 +233,12 @@ piholeLogging() {
} }
piholeStatus() { piholeStatus() {
if [[ $(netstat -plnt | grep -c ':53 ') > 0 ]]; then if [[ "$(netstat -plnt | grep -c ':53 ')" -gt "0" ]]; then
if [[ "${1}" != "web" ]] ; then if [[ "${1}" != "web" ]]; then
echo "::: DNS service is running" echo "::: DNS service is running"
fi fi
else else
if [[ "${1}" == "web" ]] ; then if [[ "${1}" == "web" ]]; then
echo "-1"; echo "-1";
else else
echo "::: DNS service is NOT running" echo "::: DNS service is NOT running"
@ -246,28 +246,28 @@ piholeStatus() {
return return
fi fi
if [[ $(grep -i "^#addn-hosts=/" /etc/dnsmasq.d/01-pihole.conf) ]] ; then if [[ "$(grep -i "^#addn-hosts=/" /etc/dnsmasq.d/01-pihole.conf)" ]]; then
#list is commented out # List is commented out
if [[ "${1}" == "web" ]] ; then if [[ "${1}" == "web" ]]; then
echo 0; echo 0;
else else
echo "::: Pi-hole blocking is Disabled"; echo "::: Pi-hole blocking is Disabled";
fi fi
elif [[ $(grep -i "^addn-hosts=/" /etc/dnsmasq.d/01-pihole.conf) ]] ; then elif [[ "$(grep -i "^addn-hosts=/" /etc/dnsmasq.d/01-pihole.conf)" ]]; then
#list set # List set
if [[ "${1}" == "web" ]] ; then if [[ "${1}" == "web" ]]; then
echo 1; echo 1;
else else
echo "::: Pi-hole blocking is Enabled"; echo "::: Pi-hole blocking is Enabled";
fi fi
else else
#addn-host not found # Addn-host not found
if [[ "${1}" == "web" ]] ; then if [[ "${1}" == "web" ]]; then
echo 99 echo 99
else else
echo "::: No hosts file linked to dnsmasq, adding it in enabled state" echo "::: No hosts file linked to dnsmasq, adding it in enabled state"
fi fi
#add addn-host= to dnsmasq # Add addn-host= to dnsmasq
echo "addn-hosts=/etc/pihole/gravity.list" >> /etc/dnsmasq.d/01-pihole.conf echo "addn-hosts=/etc/pihole/gravity.list" >> /etc/dnsmasq.d/01-pihole.conf
restartDNS restartDNS
fi fi
@ -280,46 +280,66 @@ tailFunc() {
} }
piholeCheckoutFunc() { 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 source "${PI_HOLE_SCRIPT_DIR}"/piholeCheckout.sh
shift shift
checkout "$@" checkout "$@"
} }
helpFunc() { helpFunc() {
cat << EOM echo "Usage: pihole [options]
::: Control all PiHole specific functions! Example: 'pihole -w -h'
::: Add '-h' after specific commands for more information on usage
::: Usage: pihole [options]
::: Add -h after -w (whitelist), -b (blacklist), -c (chronometer), or -a (admin) for more information on usage Whitelist/Blacklist Options:
::: -w, whitelist Whitelist domain(s)
::: Options: -b, blacklist Blacklist domain(s)
::: -w, whitelist Whitelist domain(s) -wild, wildcard Blacklist domain(s), and all its subdomains
::: -b, blacklist Blacklist domain(s) (exact match) Add '-h' for more info on whitelist/blacklist usage
::: -wild, wildcard Blacklist whole domain(s) (wildcard)
::: -d, debug Start a debugging session Debugging Options:
::: Automated debugging can be enabled with `-a`. -d, debug Start a debugging session
::: 'pihole -d -a' Add '-a' to enable automated debugging
::: -f, flush Flush the 'pihole.log' file -f, flush Flush the Pi-hole log
::: -t, tail Output the last lines of the 'pihole.log' file. Lines are appended as the file grows -r, reconfigure Reconfigure or Repair Pi-hole subsystems
::: -up, updatePihole Update Pi-hole components -t, tail View the live output of the Pi-hole log
::: -r, reconfigure Reconfigure or Repair Pi-hole
::: -g, updateGravity Update the list of ad-serving domains Options:
::: -c, chronometer Calculates stats and displays to an LCD -a, admin Admin Console options
::: -h, help Show this help dialog Add '-h' for more info on admin console usage
::: -v, version Show installed versions of Pi-Hole and Web-Admin -c, chronometer Calculates stats and displays to an LCD
::: -q, query Query the adlists for a specific domain Add '-h' for more info on chronometer usage
::: 'pihole -q domain -exact' shows exact matches only -g, updateGravity Update the list of ad-serving domains
::: -l, logging Enable or Disable logging (pass 'on' or 'off') -h, --help, help Show this help dialog
::: -a, admin Admin webpage options -l, logging Specify whether the Pi-hole log should be used
::: uninstall Uninstall Pi-Hole from your system :(! Add '-h' for more info on logging usage
::: status Is Pi-Hole Enabled or Disabled -q, query Query the adlists for a specified domain
::: enable Enable Pi-Hole DNS Blocking Add '-exact' AFTER a specified domain for exact match
::: disable Disable Pi-Hole DNS Blocking -up, updatePihole Update Pi-hole subsystems
::: Blocking can also be disabled only temporarily, e.g., -v, version Show installed versions of Pi-hole, Admin Console & FTL
::: 'pihole disable 5m' - will disable blocking for 5 minutes Add '-h' for more info on version usage
::: restartdns Restart dnsmasq uninstall Uninstall Pi-hole from your system
::: checkout Check out different branches status Display the running status of Pi-hole subsystems
EOM 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 exit 0
} }
@ -344,7 +364,7 @@ case "${1}" in
"-l" | "logging" ) piholeLogging "$@";; "-l" | "logging" ) piholeLogging "$@";;
"uninstall" ) uninstallFunc;; "uninstall" ) uninstallFunc;;
"enable" ) piholeEnable 1;; "enable" ) piholeEnable 1;;
"disable" ) piholeEnable 0 $2;; "disable" ) piholeEnable 0 "$2";;
"status" ) piholeStatus "$2";; "status" ) piholeStatus "$2";;
"restartdns" ) restartDNS;; "restartdns" ) restartDNS;;
"-a" | "admin" ) webpageFunc "$@";; "-a" | "admin" ) webpageFunc "$@";;

@ -78,7 +78,7 @@ def test_configureFirewall_firewalld_running_no_errors(Pihole):
assert expected_stdout in configureFirewall.stdout assert expected_stdout in configureFirewall.stdout
firewall_calls = Pihole.run('cat /var/log/firewall-cmd').stdout firewall_calls = Pihole.run('cat /var/log/firewall-cmd').stdout
assert 'firewall-cmd --state' in firewall_calls assert 'firewall-cmd --state' in firewall_calls
assert 'firewall-cmd --permanent --add-port=80/tcp --add-port=53/tcp --add-port=53/udp' in firewall_calls assert 'firewall-cmd --permanent --add-service=http --add-service=dns' in firewall_calls
assert 'firewall-cmd --reload' in firewall_calls assert 'firewall-cmd --reload' in firewall_calls
def test_configureFirewall_firewalld_disabled_no_errors(Pihole): def test_configureFirewall_firewalld_disabled_no_errors(Pihole):

Loading…
Cancel
Save