Merge branch 'development' into development

This commit is contained in:
WaLLy3K 2017-05-16 10:18:32 +10:00 committed by GitHub
commit 7d17c652f3
21 changed files with 833 additions and 685 deletions

38
.editorconfig Normal file
View file

@ -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

View file

@ -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?:**

View file

@ -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

View file

@ -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.

View file

@ -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

View file

@ -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

View file

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

View file

@ -8,7 +8,7 @@
# 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"
@ -82,16 +82,13 @@ normalChrono() {
} }
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
::: -h, --help display this help text
EOM
exit 0 exit 0
} }

View file

@ -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,33 +25,33 @@ listMain=""
listAlt="" listAlt=""
helpFunc() { helpFunc() {
if [[ "${listMain}" == "${whitelist}" ]]; then
if [[ ${listMain} == ${whitelist} ]]; then
param="w" param="w"
word="white" type="white"
elif [[ ${listMain} == ${wildcardlist} ]]; then elif [[ "${listMain}" == "${wildcardlist}" ]]; then
param="wild" param="wild"
word="wildcard" type="wildcard black"
else else
param="b" param="b"
word="black" type="black"
fi fi
cat << EOM echo "Usage: pihole -${param} [options] <domain> <domain2 ...>
::: Immediately add one or more domains to the ${word}list Example: 'pihole -${param} site.com', or 'pihole -${param} site1.com site2.com'
::: ${type^}list one or more domains
::: Usage: pihole -${param} domain1 [domain2 ...]
::: Options:"
::: Options:
::: -d, --delmode Remove domains from the ${word}list if [[ "${listMain}" == "${wildcardlist}" ]]; then
::: -nr, --noreload Update ${word}list without refreshing dnsmasq echo " -wild, --wildcard Block all subdomains of specified domain"
::: -q, --quiet Output is less verbose
::: -h, --help Show this help dialog
::: -l, --list Display domains on the ${word}list
EOM
if [[ "${param}" == "wild" ]]; then
echo "::: -wild, --wildcard Add wildcard entry (only blacklist)"
fi fi
echo " -d, --delmode Remove domain(s) from the ${type}list
-nr, --noreload Update ${type}list without refreshing dnsmasq
-q, --quiet Make output less verbose
-h, --help Show this help dialog
-l, --list Display all your ${type}listed domains"
exit 0 exit 0
} }
@ -68,9 +66,9 @@ 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})
@ -78,16 +76,19 @@ HandleOther(){
} }
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 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 # Logic: If addmode then add to desired list and remove from the other; if delmode then remove from desired list but do not add to the other
if ${addmode}; then if ${addmode}; then
AddDomain "${dom}" "${listMain}" AddDomain "${dom}" "${listMain}"
RemoveDomain "${dom}" "${listAlt}" RemoveDomain "${dom}" "${listAlt}"
if [[ "${listMain}" == "${whitelist}" || "${listMain}" == "${blacklist}" ]]; then
RemoveDomain "${dom}" "${wildcardlist}" RemoveDomain "${dom}" "${wildcardlist}"
fi
else else
RemoveDomain "${dom}" "${listMain}" RemoveDomain "${dom}" "${listMain}"
fi fi
@ -99,13 +100,12 @@ AddDomain() {
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
@ -117,9 +117,7 @@ AddDomain() {
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 elif [[ "${list}" == "${wildcardlist}" ]]; then
source "${piholeDir}/setupVars.conf" source "${piholeDir}/setupVars.conf"
# Remove the /* from the end of the IPv4addr. # Remove the /* from the end of the IPv4addr.
IPV4_ADDRESS=${IPV4_ADDRESS%/*} IPV4_ADDRESS=${IPV4_ADDRESS%/*}
@ -135,7 +133,7 @@ AddDomain() {
fi fi
reload=true reload=true
echo "address=/$1/${IPV4_ADDRESS}" >> "${wildcardlist}" echo "address=/$1/${IPV4_ADDRESS}" >> "${wildcardlist}"
if [[ ${#IPV6_ADDRESS} > 0 ]] ; then if [[ "${#IPV6_ADDRESS}" > 0 ]]; then
echo "address=/$1/${IPV6_ADDRESS}" >> "${wildcardlist}" echo "address=/$1/${IPV6_ADDRESS}" >> "${wildcardlist}"
fi fi
else else
@ -151,7 +149,6 @@ 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
@ -166,9 +163,7 @@ RemoveDomain() {
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
@ -192,13 +187,13 @@ Reload() {
} }
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}"

View file

@ -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}"
@ -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
@ -199,4 +204,3 @@ checkout()
fi fi
fi fi
} }

View file

@ -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 ###

View file

@ -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!"

View file

@ -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

View file

@ -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:]]._-')
#WEBHASHLATEST=$(curl -s https://api.github.com/repos/pi-hole/AdminLTE/commits/master | \ [[ "$2" == "-c" ]] || [[ "$2" == "--current" ]] || [[ -z "$2" ]] && current=$(getLocalVersion $GITDIR)
# grep sha | \ [[ "$2" == "-l" ]] || [[ "$2" == "--latest" ]] || [[ -z "$2" ]] && latest=$(getRemoteVersion "$1")
# head -n1 | \ if [[ "$2" == "-h" ]] || [[ "$2" == "--hash" ]]; then
# awk -F ' ' '{ print $2 }' | \ [[ "$3" == "-c" ]] || [[ "$3" == "--current" ]] || [[ -z "$3" ]] && curHash=$(getLocalHash "$GITDIR")
# tr -cd '[[:alnum:]]._-') [[ "$3" == "-l" ]] || [[ "$3" == "--latest" ]] || [[ -z "$3" ]] && latHash=$(getRemoteHash "$1" "$(cd "$GITDIR" 2> /dev/null && git rev-parse --abbrev-ref HEAD)")
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 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

View file

@ -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
} }
@ -62,13 +57,17 @@ delete_dnsmasq_setting() {
} }
SetTemperatureUnit() { SetTemperatureUnit() {
change_setting "TEMPERATUREUNIT" "${unit}" change_setting "TEMPERATUREUNIT" "${unit}"
}
HashPassword() {
# Compute password hash twice to avoid rainbow table vulnerability
return=$(echo -n ${1} | sha256sum | sed 's/\s.*$//')
return=$(echo -n ${return} | sha256sum | sed 's/\s.*$//')
echo ${return}
} }
SetWebPassword() { 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
# Compute password hash twice to avoid rainbow table vulnerability readonly PASSWORD="${args[2]}"
hash=$(echo -n ${args[2]} | sha256sum | sed 's/\s.*$//') readonly CONFIRM="${PASSWORD}"
hash=$(echo -n ${hash} | sha256sum | sed 's/\s.*$//') else
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() {
@ -156,7 +168,6 @@ 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,49 +198,36 @@ 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
@ -282,7 +280,6 @@ ra-param=*,0,0
} }
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]}"
@ -301,7 +298,6 @@ EnableDHCP(){
} }
DisableDHCP() { DisableDHCP() {
change_setting "DHCP_ACTIVE" "false" change_setting "DHCP_ACTIVE" "false"
# Remove possible old setting from file # Remove possible old setting from file
@ -314,23 +310,36 @@ DisableDHCP(){
} }
SetWebUILayout() { SetWebUILayout() {
change_setting "WEBUIBOXEDLAYOUT" "${args[2]}" change_setting "WEBUIBOXEDLAYOUT" "${args[2]}"
}
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
} }
SetPrivacyMode() { SetPrivacyMode() {
if [[ "${args[2]}" == "true" ]]; then 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,13 +385,24 @@ SetHostRecord(){
# Restart dnsmasq to load new configuration # Restart dnsmasq to load new configuration
RestartDNS RestartDNS
} }
SetListeningMode() { SetListeningMode() {
source "${setupVars}" source "${setupVars}"
if [[ "$3" == "-h" ]] || [[ "$3" == "--help" ]]; then
echo "Usage: pihole -a -i [interface]
Example: 'pihole -a -i local'
Specify dnsmasq's network interface listening behavior
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 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"
@ -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
} }

View file

@ -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) {

View file

@ -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
;; ;;

View file

@ -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

View file

@ -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,12 +72,24 @@ 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
#custom file found, use this instead of default
echo -n "::: Custom adList file detected. Reading..."
sources=() sources=()
while IFS= read -r line || [[ -n "$line" ]]; do while IFS= read -r line || [[ -n "$line" ]]; do
#Do not read commented out or blank lines #Do not read commented out or blank lines
@ -86,20 +100,6 @@ gravity_collapse() {
fi fi
done < ${adListFile} done < ${adListFile}
echo " done!" 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,7 +187,7 @@ 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
@ -193,6 +197,10 @@ gravity_spinup() {
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"
;; ;;
@ -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

224
pihole
View file

@ -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
@ -84,62 +84,45 @@ scanList(){
domain="${1}" domain="${1}"
list="${2}" list="${2}"
method="${3}" method="${3}"
if [[ ${method} == "-exact" ]] ; then
grep -i -E "(^|\s)${domain}($|\s)" "${list}"
else
grep -i "${domain}" "${list}"
fi
}
processWildcards() { if [[ "${method}" == "-exact" ]]; then
IFS="." read -r -a array <<< "${1}" grep -i -E -l "(^|\s|\/)${domain}($|\s|\/)" ${list}
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 else
ar="${array[$j]}.${ar}" grep -i "${domain}" ${list}
fi 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 [ -e "${list}" ]; then
result=$(scanList ${domain} ${list} ${method})
# Remove empty lines before couting number of results
count=$(sed '/^\s*$/d' <<< "$result" | wc -l)
echo "::: ${list} (${count} results)"
if [[ ${count} > 0 ]]; then
echo "${result}"
fi
echo ""
else
echo "::: ${list} does not exist"
echo ""
fi
done
# Scan for possible wildcard matches # If domain contains non ASCII characters, convert domain to punycode if python exists
if [ -e "${wildcardlist}" ]; then # Cr: https://serverfault.com/a/335079
local wildcards=($(processWildcards "${domain}")) if [[ -z "${2}" ]]; then
for domain in ${wildcards[@]}; do echo "::: No domain specified"
result=$(scanList "\/${domain}\/" ${wildcardlist}) exit 1
# Remove empty lines before couting number of results elif [[ "${2}" = *[![:ascii:]]* ]]; then
count=$(sed '/^\s*$/d' <<< "$result" | wc -l) [[ "$(which python)" ]] && domain=$(python -c 'import sys;print sys.argv[1].decode("utf-8").encode("idna")' "${2}")
if [[ ${count} > 0 ]]; then else
echo "::: Wildcard blocking ${domain} (${count} results)" domain="${2}"
echo "${result}"
echo ""
fi fi
done
# Scan Whitelist, Blacklist and Wildcards
lists="/etc/pihole/whitelist.txt /etc/pihole/blacklist.txt $wildcardlist"
result=$(scanList ${domain} "${lists}" ${method})
if [[ -n "$result" ]]; then
echo "$result"
[[ ! -t 1 ]] && exit 0
fi 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,9 +205,17 @@ piholeEnable() {
piholeLogging() { piholeLogging() {
shift shift
if [[ "${1}" == "-h" ]] || [[ "${1}" == "--help" ]]; then
echo "Usage: pihole logging [options]
Example: 'pihole logging on'
Specify whether the Pi-hole log should be used
if [[ "${1}" == "off" ]] ; then Options:
#Disable Logging 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
@ -233,7 +233,7 @@ 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
@ -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 "$@";;

View file

@ -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):