From a03caea549c033796de8720e5ed45dd8384a12f2 Mon Sep 17 00:00:00 2001
From: diginc
Date: Mon, 10 Oct 2016 23:14:39 -0500
Subject: [PATCH 001/228] setupVar tests passing for debian & centos
---
.gitignore | 4 ++
automated install/basic-install.sh | 4 +-
autotest | 1 +
test/__init__.py | 0
test/centos.Dockerfile | 14 ++++++
test/conftest.py | 46 ++++++++++++++++++
test/debian.Dockerfile | 15 ++++++
test/test_000_build_containers.py | 18 +++++++
test/test_automated_install.py | 77 ++++++++++++++++++++++++++++++
9 files changed, 178 insertions(+), 1 deletion(-)
create mode 100755 autotest
create mode 100644 test/__init__.py
create mode 100644 test/centos.Dockerfile
create mode 100644 test/conftest.py
create mode 100644 test/debian.Dockerfile
create mode 100644 test/test_000_build_containers.py
create mode 100644 test/test_automated_install.py
diff --git a/.gitignore b/.gitignore
index e43b0f98..0e0d4b99 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1,5 @@
.DS_Store
+*.pyc
+*.swp
+__pycache__
+.cache
diff --git a/automated install/basic-install.sh b/automated install/basic-install.sh
index 945fa1e1..13e546ba 100755
--- a/automated install/basic-install.sh
+++ b/automated install/basic-install.sh
@@ -971,4 +971,6 @@ echo "::: The install log is located at: /etc/pihole/install.log"
echo "::: View the web interface at http://pi.hole/admin or http://${IPv4_address%/*}/admin"
}
-main "$@"
+if [[ -z "$PHTEST" ]] ; then
+ main "$@"
+fi
diff --git a/autotest b/autotest
new file mode 100755
index 00000000..3747cc0b
--- /dev/null
+++ b/autotest
@@ -0,0 +1 @@
+py.test -v -f test/
diff --git a/test/__init__.py b/test/__init__.py
new file mode 100644
index 00000000..e69de29b
diff --git a/test/centos.Dockerfile b/test/centos.Dockerfile
new file mode 100644
index 00000000..9af7eb4d
--- /dev/null
+++ b/test/centos.Dockerfile
@@ -0,0 +1,14 @@
+FROM centos:7
+
+ENV GITDIR /etc/.pihole
+ENV SCRIPTDIR /opt/pihole
+
+RUN mkdir -p $GITDIR $SCRIPTDIR /etc/pihole
+ADD . $GITDIR
+RUN cp $GITDIR/advanced/Scripts/*.sh $GITDIR/gravity.sh $GITDIR/pihole $GITDIR/automated\ install/*.sh $SCRIPTDIR/
+ENV PATH /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:$SCRIPTDIR
+
+RUN true && \
+ chmod +x $SCRIPTDIR/*
+
+#sed '/# Start the installer/Q' /opt/pihole/basic-install.sh > /opt/pihole/stub_basic-install.sh && \
diff --git a/test/conftest.py b/test/conftest.py
new file mode 100644
index 00000000..407d00dc
--- /dev/null
+++ b/test/conftest.py
@@ -0,0 +1,46 @@
+import pytest
+import testinfra
+
+check_output = testinfra.get_backend(
+ "local://"
+).get_module("Command").check_output
+
+@pytest.fixture
+def Pihole(Docker):
+ ''' used to contain some script stubbing, now pretty much an alias '''
+ return Docker
+
+@pytest.fixture
+def Docker(request, args, image, cmd):
+ ''' combine our fixtures into a docker run command and setup finalizer to cleanup '''
+ assert 'docker' in check_output('id'), "Are you in the docker group?"
+ docker_run = "docker run {} {} {}".format(args, image, cmd)
+ docker_id = check_output(docker_run)
+
+ def teardown():
+ check_output("docker rm -f %s", docker_id)
+ request.addfinalizer(teardown)
+
+ docker_container = testinfra.get_backend("docker://" + docker_id)
+ docker_container.id = docker_id
+ return docker_container
+
+@pytest.fixture
+def args(request):
+ ''' -t became required when tput began being used '''
+ return '-t -d'
+
+@pytest.fixture(params=['debian', 'centos'])
+def tag(request):
+ ''' consumed by image to make the test matrix '''
+ return request.param
+
+@pytest.fixture()
+def image(request, tag):
+ ''' built by test_000_build_containers.py '''
+ return 'pytest_pihole:{}'.format(tag)
+
+@pytest.fixture()
+def cmd(request):
+ ''' default to doing nothing by tailing null, but don't exit '''
+ return 'tail -f /dev/null'
diff --git a/test/debian.Dockerfile b/test/debian.Dockerfile
new file mode 100644
index 00000000..b80d6155
--- /dev/null
+++ b/test/debian.Dockerfile
@@ -0,0 +1,15 @@
+FROM debian:jessie
+
+ENV GITDIR /etc/.pihole
+ENV SCRIPTDIR /opt/pihole
+
+RUN mkdir -p $GITDIR $SCRIPTDIR /etc/pihole
+ADD . $GITDIR
+RUN cp $GITDIR/advanced/Scripts/*.sh $GITDIR/gravity.sh $GITDIR/pihole $GITDIR/automated\ install/*.sh $SCRIPTDIR/
+ENV PATH /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:$SCRIPTDIR
+
+
+RUN true && \
+ chmod +x $SCRIPTDIR/*
+
+#sed '/# Start the installer/Q' /opt/pihole/basic-install.sh > /opt/pihole/stub_basic-install.sh && \
diff --git a/test/test_000_build_containers.py b/test/test_000_build_containers.py
new file mode 100644
index 00000000..c617f3ae
--- /dev/null
+++ b/test/test_000_build_containers.py
@@ -0,0 +1,18 @@
+''' This file starts with 000 to make it run first '''
+import pytest
+import testinfra
+
+run_local = testinfra.get_backend(
+ "local://"
+).get_module("Command").run
+
+@pytest.mark.parametrize("image,tag", [
+ ( 'test/debian.Dockerfile', 'pytest_pihole:debian' ),
+ ( 'test/centos.Dockerfile', 'pytest_pihole:centos' ),
+])
+def test_build_pihole_image(image, tag):
+ build_cmd = run_local('docker build -f {} -t {} .'.format(image, tag))
+ if build_cmd.rc != 0:
+ print build_cmd.stdout
+ print build_cmd.stderr
+ assert build_cmd.rc == 0
diff --git a/test/test_automated_install.py b/test/test_automated_install.py
new file mode 100644
index 00000000..1605fdb6
--- /dev/null
+++ b/test/test_automated_install.py
@@ -0,0 +1,77 @@
+import pytest
+from textwrap import dedent
+
+SETUPVARS = {
+ 'piholeInterface' : 'eth99',
+ 'IPv4_address' : '1.1.1.1',
+ 'IPv6_address' : '2:2:2:2:2:2',
+ 'piholeDNS1' : '4.2.2.1',
+ 'piholeDNS2' : '4.2.2.2'
+}
+
+def test_setupVars_are_sourced_to_global_scope(Pihole):
+ ''' currently update_dialogs sources setupVars with a dot,
+ then various other functions use the variables '''
+ setup_var_file = 'cat < /etc/pihole/setupVars.conf\n'
+ for k,v in SETUPVARS.iteritems():
+ setup_var_file += "{}={}\n".format(k, v)
+ setup_var_file += "EOF\n"
+ Pihole.run(setup_var_file)
+
+ script = dedent('''\
+ #!/bin/bash -e
+ printSetupVars() {
+ # Currently debug test function only
+ echo "Outputting sourced variables"
+ echo "piholeInterface=\${piholeInterface}"
+ echo "IPv4_address=\${IPv4_address}"
+ echo "IPv6_address=\${IPv6_address}"
+ echo "piholeDNS1=\${piholeDNS1}"
+ echo "piholeDNS2=\${piholeDNS2}"
+ }
+ update_dialogs() {
+ . /etc/pihole/setupVars.conf
+ }
+ update_dialogs
+ printSetupVars
+ ''')
+
+ output = run_script(Pihole, script).stdout
+
+ for k,v in SETUPVARS.iteritems():
+ assert "{}={}".format(k, v) in output
+
+def test_setupVars_saved_to_file(Pihole):
+ ''' confirm saved settings are written to a file for future updates to re-use '''
+ set_setup_vars = '\n' # dedent works better with this and padding matching script below
+ for k,v in SETUPVARS.iteritems():
+ set_setup_vars += " {}={}\n".format(k, v)
+ Pihole.run(set_setup_vars).stdout
+
+ script = dedent('''\
+ #!/bin/bash -e
+ echo start
+ TERM=xterm
+ PHTEST=TRUE
+ source /opt/pihole/basic-install.sh
+ {}
+ finalExports
+ cat /etc/pihole/setupVars.conf
+ '''.format(set_setup_vars))
+
+ output = run_script(Pihole, script).stdout
+
+ for k,v in SETUPVARS.iteritems():
+ assert "{}={}".format(k, v) in output
+
+def run_script(Pihole, script, file="/test.sh"):
+ _write_test_script(Pihole, script, file=file)
+ result = Pihole.run(file)
+ assert result.rc == 0
+ return result
+
+def _write_test_script(Pihole, script, file):
+ ''' Running the test script blocks directly can behave differently with regard to global vars '''
+ ''' this is a cheap work around to that until all functions no longer rely on global variables '''
+ Pihole.run('cat < {file}\n{script}\nEOF'.format(file=file, script=script))
+ Pihole.run('chmod +x {}'.format(file))
From 97c44042e19858137b7e010800263d7a5490e714 Mon Sep 17 00:00:00 2001
From: diginc
Date: Mon, 10 Oct 2016 23:18:05 -0500
Subject: [PATCH 002/228] Adding failing shellcheck test and results
Should be useful for showing others why other changes were made in the next commit.
---
test/shellcheck_failing_output.txt | 140 +++++++++++++++++++++++++++++
test/test_shellcheck.py | 13 +++
2 files changed, 153 insertions(+)
create mode 100644 test/shellcheck_failing_output.txt
create mode 100644 test/test_shellcheck.py
diff --git a/test/shellcheck_failing_output.txt b/test/shellcheck_failing_output.txt
new file mode 100644
index 00000000..65b79560
--- /dev/null
+++ b/test/shellcheck_failing_output.txt
@@ -0,0 +1,140 @@
+============================= test session starts ==============================
+platform linux2 -- Python 2.7.6, pytest-2.9.2, py-1.4.31, pluggy-0.3.1 -- /usr/bin/python
+cachedir: .cache
+rootdir: /home/a/opensource/pi-hole, inifile:
+plugins: cov-2.3.0, bdd-2.17.0, xdist-1.14, testinfra-1.4.0
+collecting ... collected 7 items
+
+test/test_000_build_containers.py::test_build_pihole_image[test/debian.Dockerfile-pytest_pihole:debian] PASSED
+test/test_000_build_containers.py::test_build_pihole_image[test/centos.Dockerfile-pytest_pihole:centos] PASSED
+test/test_automated_install.py::test_setupVars_are_sourced_to_global_scope[debian] PASSED
+test/test_automated_install.py::test_setupVars_are_sourced_to_global_scope[centos] PASSED
+test/test_automated_install.py::test_setupVars_saved_to_file[debian] PASSED
+test/test_automated_install.py::test_setupVars_saved_to_file[centos] PASSED
+test/test_shellcheck.py::test_scripts_pass_shellcheck FAILED
+
+=================================== FAILURES ===================================
+_________________________ test_scripts_pass_shellcheck _________________________
+
+ def test_scripts_pass_shellcheck():
+ ''' Make sure shellcheck does not find anything wrong with our shell scripts '''
+ shellcheck = "find . -name 'basic-install.sh' | while read file; do shellcheck \"$file\"; done;"
+ results = run_local(shellcheck)
+ print results.stdout
+> assert '' == results.stdout
+E assert '' == '\nIn ./automated install/bas...C may run when A is true.\n\n'
+E +
+E + In ./automated install/basic-install.sh line 79:
+E + INSTALLER_DEPS=( apt-utils whiptail git dhcpcd5)
+E + ^-- SC2034: INSTALLER_DEPS appears unused. Verify it or export it.
+E +
+E +
+E + In ./automated install/basic-install.sh line 80:
+E + PIHOLE_DEPS=( dnsutils bc dnsmasq lighttpd ${phpVer}-common ${phpVer}-cgi curl unzip wget sudo netcat cron iproute2 )
+E + ^-- SC2034: PIHOLE_DEPS appears unused. Verify it or export it.
+E Detailed information truncated (91 more lines), use "-vv" to show
+
+test/test_shellcheck.py:13: AssertionError
+----------------------------- Captured stdout call -----------------------------
+
+In ./automated install/basic-install.sh line 79:
+ INSTALLER_DEPS=( apt-utils whiptail git dhcpcd5)
+ ^-- SC2034: INSTALLER_DEPS appears unused. Verify it or export it.
+
+
+In ./automated install/basic-install.sh line 80:
+ PIHOLE_DEPS=( dnsutils bc dnsmasq lighttpd ${phpVer}-common ${phpVer}-cgi curl unzip wget sudo netcat cron iproute2 )
+ ^-- SC2034: PIHOLE_DEPS appears unused. Verify it or export it.
+
+
+In ./automated install/basic-install.sh line 86:
+ dpkg-query -W -f='${Status}' "$1" 2>/dev/null | grep -c "ok installed" || ${PKG_INSTALL} "$1"
+ ^-- SC2016: Expressions don't expand in single quotes, use double quotes for that.
+
+
+In ./automated install/basic-install.sh line 100:
+ INSTALLER_DEPS=( iproute net-tools procps-ng newt git )
+ ^-- SC2034: INSTALLER_DEPS appears unused. Verify it or export it.
+
+
+In ./automated install/basic-install.sh line 101:
+ PIHOLE_DEPS=( epel-release bind-utils bc dnsmasq lighttpd lighttpd-fastcgi php-common php-cli php curl unzip wget findutils cronie sudo nmap-ncat )
+ ^-- SC2034: PIHOLE_DEPS appears unused. Verify it or export it.
+
+
+In ./automated install/basic-install.sh line 120:
+ while [ "$(ps a | awk '{print $1}' | grep "$pid")" ]; do
+ ^-- SC2143: Instead of [ -n $(foo | grep bar) ], use foo | grep -q bar .
+
+
+In ./automated install/basic-install.sh line 214:
+ chooseInterfaceOptions=$("${chooseInterfaceCmd[@]}" "${interfacesArray[@]}" 2>&1 >/dev/tty)
+ ^-- SC2069: The order of the 2>&1 and the redirect matters. The 2>&1 has to be last.
+
+
+In ./automated install/basic-install.sh line 241:
+ choices=$("${cmd[@]}" "${options[@]}" 2>&1 >/dev/tty)
+ ^-- SC2069: The order of the 2>&1 and the redirect matters. The 2>&1 has to be last.
+
+
+In ./automated install/basic-install.sh line 354:
+ cp "${IFCFG_FILE}" "${IFCFG_FILE}".backup-"$(date +%Y-%m-%d-%H%M%S)"
+ ^-- SC2140: The double quotes around this do nothing. Remove or escape them.
+
+
+In ./automated install/basic-install.sh line 408:
+ DNSchoices=$("${DNSChooseCmd[@]}" "${DNSChooseOptions[@]}" 2>&1 >/dev/tty)
+ ^-- SC2069: The order of the 2>&1 and the redirect matters. The 2>&1 has to be last.
+
+
+In ./automated install/basic-install.sh line 585:
+ systemctl stop "${1}" &> /dev/null & spinner $! || true
+ ^-- SC2086: Double quote to prevent globbing and word splitting.
+
+
+In ./automated install/basic-install.sh line 587:
+ service "${1}" stop &> /dev/null & spinner $! || true
+ ^-- SC2086: Double quote to prevent globbing and word splitting.
+
+
+In ./automated install/basic-install.sh line 598:
+ systemctl restart "${1}" &> /dev/null & spinner $!
+ ^-- SC2086: Double quote to prevent globbing and word splitting.
+
+
+In ./automated install/basic-install.sh line 600:
+ service "${1}" restart &> /dev/null & spinner $!
+ ^-- SC2086: Double quote to prevent globbing and word splitting.
+
+
+In ./automated install/basic-install.sh line 610:
+ systemctl enable "${1}" &> /dev/null & spinner $!
+ ^-- SC2086: Double quote to prevent globbing and word splitting.
+
+
+In ./automated install/basic-install.sh line 612:
+ update-rc.d "${1}" defaults &> /dev/null & spinner $!
+ ^-- SC2086: Double quote to prevent globbing and word splitting.
+
+
+In ./automated install/basic-install.sh line 631:
+ ${UPDATE_PKG_CACHE} &> /dev/null & spinner $!
+ ^-- SC2086: Double quote to prevent globbing and word splitting.
+
+
+In ./automated install/basic-install.sh line 688:
+ git clone -q --depth 1 "${2}" "${1}" > /dev/null & spinner $!
+ ^-- SC2086: Double quote to prevent globbing and word splitting.
+
+
+In ./automated install/basic-install.sh line 696:
+ git pull -q > /dev/null & spinner $!
+ ^-- SC2086: Double quote to prevent globbing and word splitting.
+
+
+In ./automated install/basic-install.sh line 761:
+ id -u pihole &> /dev/null && echo "::: User 'pihole' already exists" || (echo "::: User 'pihole' doesn't exist. Creating..." && useradd -r -s /usr/sbin/nologin pihole)
+ ^-- SC2015: Note that A && B || C is not if-then-else. C may run when A is true.
+
+
+===================== 1 failed, 6 passed in 20.79 seconds ======================
diff --git a/test/test_shellcheck.py b/test/test_shellcheck.py
new file mode 100644
index 00000000..7f777caf
--- /dev/null
+++ b/test/test_shellcheck.py
@@ -0,0 +1,13 @@
+import pytest
+import testinfra
+
+run_local = testinfra.get_backend(
+ "local://"
+).get_module("Command").run
+
+def test_scripts_pass_shellcheck():
+ ''' Make sure shellcheck does not find anything wrong with our shell scripts '''
+ shellcheck = "find . -name 'basic-install.sh' | while read file; do shellcheck \"$file\"; done;"
+ results = run_local(shellcheck)
+ print results.stdout
+ assert '' == results.stdout
From 3a4fe3e391392e81bd00e05f2d0762aae63ca7b9 Mon Sep 17 00:00:00 2001
From: Eric Warnke
Date: Wed, 26 Oct 2016 14:47:29 -0400
Subject: [PATCH 003/228] Wheezy install fix by selecting appropriate deps,
made the php check the same
---
automated install/basic-install.sh | 12 ++++++++----
1 file changed, 8 insertions(+), 4 deletions(-)
diff --git a/automated install/basic-install.sh b/automated install/basic-install.sh
index ae3a4529..d8023637 100755
--- a/automated install/basic-install.sh
+++ b/automated install/basic-install.sh
@@ -75,9 +75,6 @@ fi
if [ -x "$(command -v apt-get)" ]; then
#Debian Family
- #Decide if php should be `php5` or just `php` (Fixes issues with Ubuntu 16.04 LTS)
- phpVer="php5"
- apt-get install --dry-run php5 > /dev/null 2>&1 || phpVer="php"
#############################################
PKG_MANAGER="apt-get"
PKG_CACHE="/var/lib/apt/lists/"
@@ -86,8 +83,15 @@ if [ -x "$(command -v apt-get)" ]; then
PKG_INSTALL="${PKG_MANAGER} --yes --fix-missing install"
# grep -c will return 1 retVal on 0 matches, block this throwing the set -e with an OR TRUE
PKG_COUNT="${PKG_MANAGER} -s -o Debug::NoLocking=true upgrade | grep -c ^Inst || true"
+ # #########################################
+ # fixes for dependancy differences
+ # Debian 7 doesn't have iproute2 use iproute
+ ${PKG_MANAGER} install --dry-run iproute2 > /dev/null 2>&1 && IPROUTE_PKG="iproute2" || IPROUTE_PKG="iproute"
+ # Ubuntu 16.04 LTS php / php5 fix
+ ${PKG_MANAGER} install --dry-run php5 > /dev/null 2>&1 && phpVer="php5" || phpVer="php"
+ # #########################################
INSTALLER_DEPS=( apt-utils whiptail git dhcpcd5)
- PIHOLE_DEPS=( dnsutils bc dnsmasq lighttpd ${phpVer}-common ${phpVer}-cgi curl unzip wget sudo netcat cron iproute2 )
+ PIHOLE_DEPS=( dnsutils bc dnsmasq lighttpd ${phpVer}-common ${phpVer}-cgi curl unzip wget sudo netcat cron ${IPROUTE_PKG} )
LIGHTTPD_USER="www-data"
LIGHTTPD_GROUP="www-data"
LIGHTTPD_CFG="lighttpd.conf.debian"
From 05c8406fca53a47b3e13d7f55d8e4391919c8266 Mon Sep 17 00:00:00 2001
From: Dan Schaper
Date: Sun, 30 Oct 2016 06:37:36 -0700
Subject: [PATCH 004/228] Update last modified date for adlist
---
adlists.default | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/adlists.default b/adlists.default
index 20b48008..57860b3f 100644
--- a/adlists.default
+++ b/adlists.default
@@ -1,4 +1,4 @@
-## Pi-hole ad-list default sources. Updated 22/05/2016 #########################
+## 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` #
From fa36fdeb033a113e93a5fc6eb0d587083310c1e7 Mon Sep 17 00:00:00 2001
From: Dan Schaper
Date: Sun, 30 Oct 2016 07:06:27 -0700
Subject: [PATCH 005/228] Update README
Add discourse links, remove last of Optimal, bring Other Devices up to the top, update alternate install instructions.
---
README.md | 27 +++++++++++++--------------
1 file changed, 13 insertions(+), 14 deletions(-)
diff --git a/README.md b/README.md
index 7257ba4e..a8cdf268 100644
--- a/README.md
+++ b/README.md
@@ -8,17 +8,15 @@ Works on most Debian and CentOS/RHEL based distributions!
1. Install Raspbian
2. Run the command below (downloads [this script](https://github.com/pi-hole/pi-hole/blob/master/automated%20install/basic-install.sh) in case you want to read over it first!)
-## `curl -L https://install.pi-hole.net | bash`
+## `curl -sSL https://install.pi-hole.net | bash`
### Alternative Semi-Automated install
```bash
wget -O basic-install.sh https://install.pi-hole.net
-chmod +x basic-install.sh
-./basic-install.sh
+cat basic-install.sh | bash
```
-
-If you wish to read over the script before running it, then after the `wget` command, do `nano basic-install.sh` to open a text viewer
+If you wish to read over the script before running it, then after the `wget` command, do `nano basic-install.sh` to open a text viewer.
Once installed, [configure your router to have **DHCP clients use the Pi as their DNS server**](http://pi-hole.net/faq/can-i-set-the-pi-hole-to-be-the-dns-server-at-my-router-so-i-dont-have-to-change-settings-for-my-devices/) 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 the Raspberry Pi as its DNS server](http://pi-hole.net/faq/how-do-i-use-the-pi-hole-as-my-dns-server/).
@@ -34,7 +32,7 @@ Once installed, [configure your router to have **DHCP clients use the Pi as thei
## Pi-hole Is Free, But Powered By Your Donations
-Send a one-time donation or sign up for Optimal.com's service using our link below to provide us with a small portion of the monthly fee.
+Send a one-time donation using our link below to provide us with a small portion of the monthly fee.
- ![Paypal](http://i.imgur.com/3muNfxu.png) : [Donate](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=3J2L3Z4DHW9UY)
- ![Flattr](http://i.imgur.com/ZFceFRu.png) : [Donate](https://flattr.com/submit/auto?user_id=jacobsalmela&url=https://github.com/pi-hole/pi-hole)
@@ -43,19 +41,24 @@ Send a one-time donation or sign up for Optimal.com's service using our link bel
## Get Help Or Connect With Us On The Web
- [@The_Pi_Hole](https://twitter.com/The_Pi_Hole)
+- [Discourse](https://discourse.pi-hole.net/)
- [/r/pihole](https://www.reddit.com/r/pihole/)
- [Pi-hole YouTube channel](https://www.youtube.com/channel/UCT5kq9w0wSjogzJb81C9U0w)
- [Wiki](https://github.com/pi-hole/pi-hole/wiki/Customization)
-- [FAQs](https://pi-hole.net/help/)
+- [FAQs](https://discourse.pi-hole.net/c/faqs)
- [![Join the chat at https://gitter.im/pi-hole/pi-hole](https://badges.gitter.im/pi-hole/pi-hole.svg)](https://gitter.im/pi-hole/pi-hole?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
## Technical Details
The Pi-hole is an **advertising-aware DNS/Web server**. If an ad domain is queried, a small Web page or GIF is delivered in place of the advertisement. You can also [replace ads with any image you want](http://pi-hole.net/faq/is-it-possible-to-change-the-blank-page-that-takes-place-of-the-ads-to-something-else/) since it is just a simple Webpage taking place of the ads.
+#### Other Operating Systems
+
+This script will work for other UNIX-like systems with some slight **modifications**. As long as you can install `dnsmasq` and a Webserver, it should work OK. The automated install is only for a clean install of a Debian family or Fedora based system, such as the Raspberry Pi. If there are other platforms you'd like supported, let us know.
+
### Gravity
-The [gravity.sh](https://github.com/pi-hole/pi-hole/blob/master/gravity.sh) does most of the magic. The script pulls in ad domains from many sources and compiles them into a single list of [over 1.6 million entries](http://jacobsalmela.com/block-millions-ads-network-wide-with-a-raspberry-pi-hole-2-0) (if you decide to use the [mahakala list](https://github.com/pi-hole/pi-hole/commit/963eacfe0537a7abddf30441c754c67ca1e40965)).
+The [gravity.sh](https://github.com/pi-hole/pi-hole/blob/master/gravity.sh) does most of the magic. The script pulls in ad domains from many sources and compiles them into a single list of [over 1.6 million entries](http://jacobsalmela.com/block-millions-ads-network-wide-with-a-raspberry-pi-hole-2-0) (if you decide to use the [mahakala list](https://github.com/pi-hole/pi-hole/commit/963eacfe0537a7abddf30441c754c67ca1e40965)). This script is controlled by the `pihole` command. Please run `pihole -h` to see what commands can be run via `pihole`.
## Web Interface
@@ -67,13 +70,13 @@ The [Web interface](https://github.com/jacobsalmela/AdminLTE#pi-hole-admin-dashb
### Whitelist and blacklist
-Domains can be whitelisted and blacklisted using two pre-installed scripts. See [the wiki page](https://github.com/pi-hole/pi-hole/wiki/Whitelisting-and-Blacklisting) for more details ![Whitelist editor in the Web interface](http://i.imgur.com/ogu2ewg.png)
+Domains can be whitelisted and blacklisted using either the web interface or the command line. See [the wiki page](https://github.com/pi-hole/pi-hole/wiki/Whitelisting-and-Blacklisting) for more details ![Whitelist editor in the Web interface](http://i.imgur.com/ogu2ewg.png)
## API
A basic read-only API can be accessed at `/admin/api.php`. It returns the following JSON:
-```json
+``` json
{
"domains_being_blocked": "136708",
"dns_queries_today": "18108",
@@ -119,7 +122,3 @@ You can view [real-time stats](http://pi-hole.net/faq/install-the-real-time-lcd-
- [Foolish Tech Show](https://youtu.be/bYyena0I9yc?t=2m4s)
- [Pi-hole on Ubuntu](http://www.boyter.org/2015/12/pi-hole-ubuntu-14-04/)
- [Catchpoint: iOS 9 Ad Blocking](http://blog.catchpoint.com/2015/09/14/ad-blocking-apple/)
-
-## Other Operating Systems
-
-This script will work for other UNIX-like systems with some slight **modifications**. As long as you can install `dnsmasq` and a Webserver, it should work OK. The automated install is only for a clean install of a Debian based system, such as the Raspberry Pi.
From 7920fcbb5ea14981bf6acaa7b9575321d49ced6b Mon Sep 17 00:00:00 2001
From: Dan Schaper
Date: Sun, 30 Oct 2016 07:09:03 -0700
Subject: [PATCH 006/228] Add linux.die.net links
Add links for online manpages.
---
README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/README.md b/README.md
index a8cdf268..3d2b285f 100644
--- a/README.md
+++ b/README.md
@@ -16,7 +16,7 @@ Works on most Debian and CentOS/RHEL based distributions!
wget -O basic-install.sh https://install.pi-hole.net
cat basic-install.sh | bash
```
-If you wish to read over the script before running it, then after the `wget` command, do `nano basic-install.sh` to open a text viewer.
+If you wish to read over the script before running it, then after the [`wget`](https://linux.die.net/man/1/wget) command, run `nano basic-install.sh` to open the file in a text viewer.
Once installed, [configure your router to have **DHCP clients use the Pi as their DNS server**](http://pi-hole.net/faq/can-i-set-the-pi-hole-to-be-the-dns-server-at-my-router-so-i-dont-have-to-change-settings-for-my-devices/) 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 the Raspberry Pi as its DNS server](http://pi-hole.net/faq/how-do-i-use-the-pi-hole-as-my-dns-server/).
From ef13e67572e77fb0e4577d93f21f20d8a7db870e Mon Sep 17 00:00:00 2001
From: Dan Schaper
Date: Sun, 30 Oct 2016 07:11:34 -0700
Subject: [PATCH 007/228] Update README.md
---
README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/README.md b/README.md
index 3d2b285f..b28b3f3e 100644
--- a/README.md
+++ b/README.md
@@ -8,7 +8,7 @@ Works on most Debian and CentOS/RHEL based distributions!
1. Install Raspbian
2. Run the command below (downloads [this script](https://github.com/pi-hole/pi-hole/blob/master/automated%20install/basic-install.sh) in case you want to read over it first!)
-## `curl -sSL https://install.pi-hole.net | bash`
+### `curl -sSL https://install.pi-hole.net | bash`
### Alternative Semi-Automated install
From 126f275e189bdb9dc3b9f36fc7d50b647dc0c3cc Mon Sep 17 00:00:00 2001
From: Adam Warner
Date: Sun, 30 Oct 2016 17:15:35 +0000
Subject: [PATCH 008/228] Update pullapprove into master
Requires approval of ALL members of the `admin` team.
---
.pullapprove.yml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/.pullapprove.yml b/.pullapprove.yml
index 68b9acfc..3b421dd2 100644
--- a/.pullapprove.yml
+++ b/.pullapprove.yml
@@ -33,6 +33,6 @@ groups:
conditions:
branches:
- master
- required: 3
+ required: -1
teams:
- - gravity
+ - admin
From 4e7ca51bebc7cc44e466a6b78fd143588fce2dc2 Mon Sep 17 00:00:00 2001
From: Eric Warnke
Date: Mon, 31 Oct 2016 21:24:57 -0400
Subject: [PATCH 009/228] Added dependancy for ping and lsof used in debug
scripts
---
automated install/basic-install.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/automated install/basic-install.sh b/automated install/basic-install.sh
index 6489a5fc..93974211 100755
--- a/automated install/basic-install.sh
+++ b/automated install/basic-install.sh
@@ -91,7 +91,7 @@ if [ -x "$(command -v apt-get)" ]; then
${PKG_MANAGER} install --dry-run php5 > /dev/null 2>&1 && phpVer="php5" || phpVer="php"
# #########################################
INSTALLER_DEPS=( apt-utils whiptail git dhcpcd5)
- PIHOLE_DEPS=( dnsutils bc dnsmasq lighttpd ${phpVer}-common ${phpVer}-cgi curl unzip wget sudo netcat cron ${IPROUTE_PKG} )
+ PIHOLE_DEPS=( iputils-ping lsof dnsutils bc dnsmasq lighttpd ${phpVer}-common ${phpVer}-cgi curl unzip wget sudo netcat cron ${IPROUTE_PKG} )
LIGHTTPD_USER="www-data"
LIGHTTPD_GROUP="www-data"
LIGHTTPD_CFG="lighttpd.conf.debian"
From fb5ac6d6d74e00843c53e07ab188635d6aba9e7e Mon Sep 17 00:00:00 2001
From: Eric Warnke
Date: Mon, 31 Oct 2016 21:31:13 -0400
Subject: [PATCH 010/228] We should prefer the php metapackage if it's there,
falling back on php5 if it's not
---
automated install/basic-install.sh | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/automated install/basic-install.sh b/automated install/basic-install.sh
index 93974211..c8312a01 100755
--- a/automated install/basic-install.sh
+++ b/automated install/basic-install.sh
@@ -87,8 +87,8 @@ if [ -x "$(command -v apt-get)" ]; then
# fixes for dependancy differences
# Debian 7 doesn't have iproute2 use iproute
${PKG_MANAGER} install --dry-run iproute2 > /dev/null 2>&1 && IPROUTE_PKG="iproute2" || IPROUTE_PKG="iproute"
- # Ubuntu 16.04 LTS php / php5 fix
- ${PKG_MANAGER} install --dry-run php5 > /dev/null 2>&1 && phpVer="php5" || phpVer="php"
+ # Prefer the php metapackage if it's there, fall back on the php5 pacakges
+ ${PKG_MANAGER} install --dry-run php > /dev/null 2>&1 && phpVer="php" || phpVer="php5"
# #########################################
INSTALLER_DEPS=( apt-utils whiptail git dhcpcd5)
PIHOLE_DEPS=( iputils-ping lsof dnsutils bc dnsmasq lighttpd ${phpVer}-common ${phpVer}-cgi curl unzip wget sudo netcat cron ${IPROUTE_PKG} )
From f1efc97357695a7e1fc1c1b6eab23891051e23e8 Mon Sep 17 00:00:00 2001
From: Dan Schaper
Date: Tue, 1 Nov 2016 11:04:33 -0700
Subject: [PATCH 011/228] Clairfy condition to make sure they operate as per
the specs of the logic flow layout.
---
advanced/Scripts/update.sh | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/advanced/Scripts/update.sh b/advanced/Scripts/update.sh
index a2220d57..a743b549 100644
--- a/advanced/Scripts/update.sh
+++ b/advanced/Scripts/update.sh
@@ -104,12 +104,12 @@ echo ":::"
-if [[ ${piholeVersion} == ${piholeVersionLatest} && ${webVersion} == ${webVersionLatest} ]]; then
+if [[ ${piholeVersion} == ${piholeVersionLatest} ]] && [[ ${webVersion} == ${webVersionLatest} ]]; then
echo "::: Everything is up to date!"
echo ""
exit 0
-elif [[ ${piholeVersion} == ${piholeVersionLatest} && ${webVersion} != ${webVersionLatest} ]]; then
+elif [[ ${piholeVersion} == ${piholeVersionLatest} ]] && [[ ${webVersion} != ${webVersionLatest} ]]; then
echo "::: Pi-hole Web Admin files out of date"
getGitFiles ${webInterfaceDir} ${webInterfaceGitUrl}
echo ":::"
@@ -117,7 +117,7 @@ elif [[ ${piholeVersion} == ${piholeVersionLatest} && ${webVersion} != ${webVers
echo "::: Web Admin version is now at ${webVersion}"
echo "::: If you had made any changes in '/var/www/html/admin', they have been stashed using 'git stash'"
echo ""
-elif [[ ${piholeVersion} != ${piholeVersionLatest} && ${webVersion} == ${webVersionLatest} ]]; then
+elif [[ ${piholeVersion} != ${piholeVersionLatest} ]] && [[ ${webVersion} == ${webVersionLatest} ]]; then
echo "::: Pi-hole core files out of date"
getGitFiles ${piholeFilesDir} ${piholeGitUrl}
/etc/.pihole/automated\ install/basic-install.sh --reconfigure --unattended
@@ -126,7 +126,7 @@ elif [[ ${piholeVersion} != ${piholeVersionLatest} && ${webVersion} == ${webVers
echo "::: Pi-hole version is now at ${piholeVersion}"
echo "::: If you had made any changes in '/etc/.pihole', they have been stashed using 'git stash'"
echo ""
-elif [[ ${piholeVersion} != ${piholeVersionLatest} && ${webVersion} != ${webVersionLatest} ]]; then
+elif [[ ${piholeVersion} != ${piholeVersionLatest} ]] && [[ ${webVersion} != ${webVersionLatest} ]]; then
echo "::: Updating Everything"
getGitFiles ${piholeFilesDir} ${piholeGitUrl}
/etc/.pihole/automated\ install/basic-install.sh --unattended
From 1e7e5230cca66f000883e7fd25d027b4b06c6f2c Mon Sep 17 00:00:00 2001
From: Dan Schaper
Date: Tue, 1 Nov 2016 11:15:21 -0700
Subject: [PATCH 012/228] Clarify what exactly is being called and the expected
returned value format
---
advanced/Scripts/update.sh | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/advanced/Scripts/update.sh b/advanced/Scripts/update.sh
index a743b549..afccd10e 100644
--- a/advanced/Scripts/update.sh
+++ b/advanced/Scripts/update.sh
@@ -79,10 +79,14 @@ if [ ! -d "/var/www/html/admin" ]; then #This is unlikely
fi
echo "::: Checking for updates..."
+# Checks Pi-hole version > pihole only > current local git repo version : returns string in format vX.X.X
piholeVersion=$(pihole -v -p -c)
+# Checks Pi-hole version > pihole only > remote upstream repo version : returns string in format vX.X.X
piholeVersionLatest=$(pihole -v -p -l)
+# Checks Pi-hole version > admin only > current local git repo version : returns string in format vX.X.X
webVersion=$(pihole -v -a -c)
+# Checks Pi-hole version > admin only > remote upstream repo version : returns string in format vX.X.X
webVersionLatest=$(pihole -v -a -l)
echo ":::"
@@ -104,7 +108,7 @@ echo ":::"
-if [[ ${piholeVersion} == ${piholeVersionLatest} ]] && [[ ${webVersion} == ${webVersionLatest} ]]; then
+if [[ ${piholeVersion} == ${piholeVersionLatest} ]] && [[ "${webVersion}" == "${webVersionLatest}" ]]; then
echo "::: Everything is up to date!"
echo ""
exit 0
From 0c9520d7e35f032fa6a0b3a30f9b98061893d85c Mon Sep 17 00:00:00 2001
From: Dan Schaper
Date: Tue, 1 Nov 2016 11:18:41 -0700
Subject: [PATCH 013/228] Protect against unexepcted return values (GitHub not
responding as we'd expect.) And make sure bash doesn't maul the variables and
cause firing of unattended reinstall of application when values returned
aren't as expected.
---
advanced/Scripts/update.sh | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)
diff --git a/advanced/Scripts/update.sh b/advanced/Scripts/update.sh
index afccd10e..cbbf804f 100644
--- a/advanced/Scripts/update.sh
+++ b/advanced/Scripts/update.sh
@@ -108,12 +108,12 @@ echo ":::"
-if [[ ${piholeVersion} == ${piholeVersionLatest} ]] && [[ "${webVersion}" == "${webVersionLatest}" ]]; then
+if [[ "${piholeVersion}" == "${piholeVersionLatest}" ]] && [[ "${webVersion}" == "${webVersionLatest}" ]]; then
echo "::: Everything is up to date!"
echo ""
exit 0
-elif [[ ${piholeVersion} == ${piholeVersionLatest} ]] && [[ ${webVersion} != ${webVersionLatest} ]]; then
+elif [[ "${piholeVersion} == ${piholeVersionLatest}" ]] && [[ "${webVersion}" != "${webVersionLatest}" ]]; then
echo "::: Pi-hole Web Admin files out of date"
getGitFiles ${webInterfaceDir} ${webInterfaceGitUrl}
echo ":::"
@@ -121,7 +121,7 @@ elif [[ ${piholeVersion} == ${piholeVersionLatest} ]] && [[ ${webVersion} != ${w
echo "::: Web Admin version is now at ${webVersion}"
echo "::: If you had made any changes in '/var/www/html/admin', they have been stashed using 'git stash'"
echo ""
-elif [[ ${piholeVersion} != ${piholeVersionLatest} ]] && [[ ${webVersion} == ${webVersionLatest} ]]; then
+elif [[ "${piholeVersion}" != "${piholeVersionLatest}" ]] && [[ "${webVersion}" == "${webVersionLatest}" ]]; then
echo "::: Pi-hole core files out of date"
getGitFiles ${piholeFilesDir} ${piholeGitUrl}
/etc/.pihole/automated\ install/basic-install.sh --reconfigure --unattended
@@ -130,11 +130,14 @@ elif [[ ${piholeVersion} != ${piholeVersionLatest} ]] && [[ ${webVersion} == ${w
echo "::: Pi-hole version is now at ${piholeVersion}"
echo "::: If you had made any changes in '/etc/.pihole', they have been stashed using 'git stash'"
echo ""
-elif [[ ${piholeVersion} != ${piholeVersionLatest} ]] && [[ ${webVersion} != ${webVersionLatest} ]]; then
+elif [[ "${piholeVersion}" != "${piholeVersionLatest}" ]] && [[ "${webVersion}" != "${webVersionLatest}" ]]; then
echo "::: Updating Everything"
getGitFiles ${piholeFilesDir} ${piholeGitUrl}
/etc/.pihole/automated\ install/basic-install.sh --unattended
+
+ # Checks Pi-hole version > admin only > current local git repo version : returns string in format vX.X.X
webVersion=$(pihole -v -a -c)
+ # Checks Pi-hole version > admin only > current local git repo version : returns string in format vX.X.X
piholeVersion=$(pihole -v -p -c)
echo ":::"
echo "::: Pi-hole version is now at ${piholeVersion}"
From c3e2bce956d032b5dabf6dbf0d1bb0704535c157 Mon Sep 17 00:00:00 2001
From: Dan Schaper
Date: Tue, 1 Nov 2016 11:26:57 -0700
Subject: [PATCH 014/228] Variables declared as strings, make sure they are
strings when we use them in functions.
---
advanced/Scripts/update.sh | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/advanced/Scripts/update.sh b/advanced/Scripts/update.sh
index cbbf804f..d682f265 100644
--- a/advanced/Scripts/update.sh
+++ b/advanced/Scripts/update.sh
@@ -115,7 +115,7 @@ if [[ "${piholeVersion}" == "${piholeVersionLatest}" ]] && [[ "${webVersion}" ==
elif [[ "${piholeVersion} == ${piholeVersionLatest}" ]] && [[ "${webVersion}" != "${webVersionLatest}" ]]; then
echo "::: Pi-hole Web Admin files out of date"
- getGitFiles ${webInterfaceDir} ${webInterfaceGitUrl}
+ getGitFiles "${webInterfaceDir}" "${webInterfaceGitUrl}"
echo ":::"
webVersion=$(pihole -v -a -c)
echo "::: Web Admin version is now at ${webVersion}"
@@ -123,7 +123,7 @@ elif [[ "${piholeVersion} == ${piholeVersionLatest}" ]] && [[ "${webVersion}" !=
echo ""
elif [[ "${piholeVersion}" != "${piholeVersionLatest}" ]] && [[ "${webVersion}" == "${webVersionLatest}" ]]; then
echo "::: Pi-hole core files out of date"
- getGitFiles ${piholeFilesDir} ${piholeGitUrl}
+ getGitFiles "${piholeFilesDir}" "${piholeGitUrl}"
/etc/.pihole/automated\ install/basic-install.sh --reconfigure --unattended
echo ":::"
piholeVersion=$(pihole -v -p -c)
@@ -132,7 +132,7 @@ elif [[ "${piholeVersion}" != "${piholeVersionLatest}" ]] && [[ "${webVersion}"
echo ""
elif [[ "${piholeVersion}" != "${piholeVersionLatest}" ]] && [[ "${webVersion}" != "${webVersionLatest}" ]]; then
echo "::: Updating Everything"
- getGitFiles ${piholeFilesDir} ${piholeGitUrl}
+ getGitFiles "${piholeFilesDir}" "${piholeGitUrl}"
/etc/.pihole/automated\ install/basic-install.sh --unattended
# Checks Pi-hole version > admin only > current local git repo version : returns string in format vX.X.X
From ffbfadbccf082657a67210ce2050c7bdfde8f2a4 Mon Sep 17 00:00:00 2001
From: Dan Schaper
Date: Tue, 1 Nov 2016 11:33:04 -0700
Subject: [PATCH 015/228] Detail what the script does.
---
advanced/Scripts/update.sh | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/advanced/Scripts/update.sh b/advanced/Scripts/update.sh
index d682f265..41748717 100644
--- a/advanced/Scripts/update.sh
+++ b/advanced/Scripts/update.sh
@@ -3,7 +3,9 @@
# (c) 2015, 2016 by Jacob Salmela
# Network-wide ad blocking via your Raspberry Pi
# http://pi-hole.net
-# Whitelists domains
+# Check Pi-hole core and admin pages versions and determine what
+# upgrade (if any) is required. Automatically updates and reinstalls
+# application if update is detected.
#
# Pi-hole is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
From 1991ee7a7d992f4d33fbaafbf9d72dc1932716c3 Mon Sep 17 00:00:00 2001
From: Dan Schaper
Date: Tue, 1 Nov 2016 11:36:44 -0700
Subject: [PATCH 016/228] Google Style Guide. `readonly` and cap constants.
---
advanced/Scripts/update.sh | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/advanced/Scripts/update.sh b/advanced/Scripts/update.sh
index 41748717..2feecd54 100644
--- a/advanced/Scripts/update.sh
+++ b/advanced/Scripts/update.sh
@@ -14,10 +14,10 @@
# Variables
-webInterfaceGitUrl="https://github.com/pi-hole/AdminLTE.git"
-webInterfaceDir="/var/www/html/admin"
-piholeGitUrl="https://github.com/pi-hole/pi-hole.git"
-piholeFilesDir="/etc/.pihole"
+readonly WEBINTERFACEGITURL="https://github.com/pi-hole/AdminLTE.git"
+readonly WEBINTERFACEDIR="/var/www/html/admin"
+readonly PIHOLEGITURL="https://github.com/pi-hole/pi-hole.git"
+readonly PIHOLEFILESDIR="/etc/.pihole"
spinner() {
local pid=${1}
@@ -117,7 +117,7 @@ if [[ "${piholeVersion}" == "${piholeVersionLatest}" ]] && [[ "${webVersion}" ==
elif [[ "${piholeVersion} == ${piholeVersionLatest}" ]] && [[ "${webVersion}" != "${webVersionLatest}" ]]; then
echo "::: Pi-hole Web Admin files out of date"
- getGitFiles "${webInterfaceDir}" "${webInterfaceGitUrl}"
+ getGitFiles "${WEBINTERFACEDIR}" "${WEBINTERFACEGITURL}"
echo ":::"
webVersion=$(pihole -v -a -c)
echo "::: Web Admin version is now at ${webVersion}"
@@ -125,7 +125,7 @@ elif [[ "${piholeVersion} == ${piholeVersionLatest}" ]] && [[ "${webVersion}" !=
echo ""
elif [[ "${piholeVersion}" != "${piholeVersionLatest}" ]] && [[ "${webVersion}" == "${webVersionLatest}" ]]; then
echo "::: Pi-hole core files out of date"
- getGitFiles "${piholeFilesDir}" "${piholeGitUrl}"
+ getGitFiles "${PIHOLEFILESDIR}" "${PIHOLEGITURL}"
/etc/.pihole/automated\ install/basic-install.sh --reconfigure --unattended
echo ":::"
piholeVersion=$(pihole -v -p -c)
@@ -134,7 +134,7 @@ elif [[ "${piholeVersion}" != "${piholeVersionLatest}" ]] && [[ "${webVersion}"
echo ""
elif [[ "${piholeVersion}" != "${piholeVersionLatest}" ]] && [[ "${webVersion}" != "${webVersionLatest}" ]]; then
echo "::: Updating Everything"
- getGitFiles "${piholeFilesDir}" "${piholeGitUrl}"
+ getGitFiles "${PIHOLEFILESDIR}" "${PIHOLEGITURL}"
/etc/.pihole/automated\ install/basic-install.sh --unattended
# Checks Pi-hole version > admin only > current local git repo version : returns string in format vX.X.X
From fbc800e55621d93315de6b666410ed1febd08c86 Mon Sep 17 00:00:00 2001
From: Dan Schaper
Date: Tue, 1 Nov 2016 11:42:18 -0700
Subject: [PATCH 017/228] If unattened reinstall fails, notify user and exit
script immediately.
---
advanced/Scripts/update.sh | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/advanced/Scripts/update.sh b/advanced/Scripts/update.sh
index 2feecd54..5ecb6a6f 100644
--- a/advanced/Scripts/update.sh
+++ b/advanced/Scripts/update.sh
@@ -135,7 +135,8 @@ elif [[ "${piholeVersion}" != "${piholeVersionLatest}" ]] && [[ "${webVersion}"
elif [[ "${piholeVersion}" != "${piholeVersionLatest}" ]] && [[ "${webVersion}" != "${webVersionLatest}" ]]; then
echo "::: Updating Everything"
getGitFiles "${PIHOLEFILESDIR}" "${PIHOLEGITURL}"
- /etc/.pihole/automated\ install/basic-install.sh --unattended
+
+ /etc/.pihole/automated\ install/basic-install.sh --unattended || echo "Unable to complete update, contact Pi-hole" && exit 1
# Checks Pi-hole version > admin only > current local git repo version : returns string in format vX.X.X
webVersion=$(pihole -v -a -c)
From 807b60b0e61412bfb97fe035582ca5ac3a10fa79 Mon Sep 17 00:00:00 2001
From: Dan Schaper
Date: Tue, 1 Nov 2016 11:44:16 -0700
Subject: [PATCH 018/228] Missed the second reinstaller....
---
advanced/Scripts/update.sh | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/advanced/Scripts/update.sh b/advanced/Scripts/update.sh
index 5ecb6a6f..783ae625 100644
--- a/advanced/Scripts/update.sh
+++ b/advanced/Scripts/update.sh
@@ -126,7 +126,9 @@ elif [[ "${piholeVersion} == ${piholeVersionLatest}" ]] && [[ "${webVersion}" !=
elif [[ "${piholeVersion}" != "${piholeVersionLatest}" ]] && [[ "${webVersion}" == "${webVersionLatest}" ]]; then
echo "::: Pi-hole core files out of date"
getGitFiles "${PIHOLEFILESDIR}" "${PIHOLEGITURL}"
- /etc/.pihole/automated\ install/basic-install.sh --reconfigure --unattended
+
+ /etc/.pihole/automated\ install/basic-install.sh --reconfigure --unattended || echo "Unable to complete update, contact Pi-hole" && exit 1
+
echo ":::"
piholeVersion=$(pihole -v -p -c)
echo "::: Pi-hole version is now at ${piholeVersion}"
From 5fef5f1ed49fc5eb50f849132759ce874167d4de Mon Sep 17 00:00:00 2001
From: Dan Schaper
Date: Tue, 1 Nov 2016 11:54:14 -0700
Subject: [PATCH 019/228] Break down `is_repo` to make sure it does what is
expected.
---
advanced/Scripts/update.sh | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/advanced/Scripts/update.sh b/advanced/Scripts/update.sh
index 783ae625..2af64738 100644
--- a/advanced/Scripts/update.sh
+++ b/advanced/Scripts/update.sh
@@ -49,7 +49,13 @@ is_repo() {
# Use git to check if directory is currently under VCS
echo -n "::: Checking $1 is a repo..."
cd "${1}" &> /dev/null || return 1
- git status &> /dev/null && echo " OK!"; return 0 || echo " not found!"; return 1
+ if [[ $(git status --short) ]]; then
+ echo " OK!"
+ return 0
+ else
+ echo " not found!"
+ return 1
+ fi
}
make_repo() {
From 114bc13c2369a7c6936742dbe85363ed70514b26 Mon Sep 17 00:00:00 2001
From: Dan Schaper
Date: Tue, 1 Nov 2016 12:03:26 -0700
Subject: [PATCH 020/228] Specify path, cron may not know where the files are
located.
---
advanced/Scripts/update.sh | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/advanced/Scripts/update.sh b/advanced/Scripts/update.sh
index 2af64738..e682e837 100644
--- a/advanced/Scripts/update.sh
+++ b/advanced/Scripts/update.sh
@@ -88,14 +88,14 @@ fi
echo "::: Checking for updates..."
# Checks Pi-hole version > pihole only > current local git repo version : returns string in format vX.X.X
-piholeVersion=$(pihole -v -p -c)
+piholeVersion=$(/usr/local/bin/pihole -v -p -c)
# Checks Pi-hole version > pihole only > remote upstream repo version : returns string in format vX.X.X
-piholeVersionLatest=$(pihole -v -p -l)
+piholeVersionLatest=$(/usr/local/bin/pihole -v -p -l)
# Checks Pi-hole version > admin only > current local git repo version : returns string in format vX.X.X
-webVersion=$(pihole -v -a -c)
+webVersion=$(/usr/local/bin/pihole -v -a -c)
# Checks Pi-hole version > admin only > remote upstream repo version : returns string in format vX.X.X
-webVersionLatest=$(pihole -v -a -l)
+webVersionLatest=$(/usr/local/bin/pihole -v -a -l)
echo ":::"
echo "::: Pi-hole version is $piholeVersion (Latest version is $piholeVersionLatest)"
@@ -125,7 +125,7 @@ elif [[ "${piholeVersion} == ${piholeVersionLatest}" ]] && [[ "${webVersion}" !=
echo "::: Pi-hole Web Admin files out of date"
getGitFiles "${WEBINTERFACEDIR}" "${WEBINTERFACEGITURL}"
echo ":::"
- webVersion=$(pihole -v -a -c)
+ webVersion=$(/usr/local/bin/pihole -v -a -c)
echo "::: Web Admin version is now at ${webVersion}"
echo "::: If you had made any changes in '/var/www/html/admin', they have been stashed using 'git stash'"
echo ""
@@ -136,7 +136,7 @@ elif [[ "${piholeVersion}" != "${piholeVersionLatest}" ]] && [[ "${webVersion}"
/etc/.pihole/automated\ install/basic-install.sh --reconfigure --unattended || echo "Unable to complete update, contact Pi-hole" && exit 1
echo ":::"
- piholeVersion=$(pihole -v -p -c)
+ piholeVersion=$(/usr/local/bin/pihole -v -p -c)
echo "::: Pi-hole version is now at ${piholeVersion}"
echo "::: If you had made any changes in '/etc/.pihole', they have been stashed using 'git stash'"
echo ""
@@ -147,9 +147,9 @@ elif [[ "${piholeVersion}" != "${piholeVersionLatest}" ]] && [[ "${webVersion}"
/etc/.pihole/automated\ install/basic-install.sh --unattended || echo "Unable to complete update, contact Pi-hole" && exit 1
# Checks Pi-hole version > admin only > current local git repo version : returns string in format vX.X.X
- webVersion=$(pihole -v -a -c)
+ webVersion=$(/usr/local/bin/pihole -v -a -c)
# Checks Pi-hole version > admin only > current local git repo version : returns string in format vX.X.X
- piholeVersion=$(pihole -v -p -c)
+ piholeVersion=$(/usr/local/bin/pihole -v -p -c)
echo ":::"
echo "::: Pi-hole version is now at ${piholeVersion}"
echo "::: If you had made any changes in '/etc/.pihole', they have been stashed using 'git stash'"
From 85b8676b8e817b38179ab93870b6b9b41413f295 Mon Sep 17 00:00:00 2001
From: Dan Schaper
Date: Tue, 1 Nov 2016 12:16:46 -0700
Subject: [PATCH 021/228] Remove spinner, no functions here should last that
long, and it masks a few potential exit avenues.
---
advanced/Scripts/update.sh | 18 ++----------------
1 file changed, 2 insertions(+), 16 deletions(-)
diff --git a/advanced/Scripts/update.sh b/advanced/Scripts/update.sh
index e682e837..e5e8766d 100644
--- a/advanced/Scripts/update.sh
+++ b/advanced/Scripts/update.sh
@@ -19,20 +19,6 @@ readonly WEBINTERFACEDIR="/var/www/html/admin"
readonly PIHOLEGITURL="https://github.com/pi-hole/pi-hole.git"
readonly PIHOLEFILESDIR="/etc/.pihole"
-spinner() {
- local pid=${1}
- local delay=0.50
- local spinstr='/-\|'
- while [ "$(ps a | awk '{print $1}' | grep "${pid}")" ]; do
- local temp=${spinstr#?}
- printf " [%c] " "${spinstr}"
- local spinstr=${temp}${spinstr%"$temp"}
- sleep ${delay}
- printf "\b\b\b\b\b\b"
- done
- printf " \b\b\b\b"
-}
-
getGitFiles() {
# Setup git repos for directory and repository passed
# as arguments 1 and 2
@@ -70,8 +56,8 @@ update_repo() {
# Pull the latest commits
echo -n "::: Updating repo in $1..."
cd "${1}" || exit 1
- git stash -q > /dev/null & spinner $!
- git pull -q > /dev/null & spinner $!
+ git stash -q > /dev/null || exit 1
+ git pull -q > /dev/null || exit 1
echo " done!"
}
From 04da292df999b51dfd21496802b9a7ac58e51802 Mon Sep 17 00:00:00 2001
From: Dan Schaper
Date: Tue, 1 Nov 2016 12:17:38 -0700
Subject: [PATCH 022/228] Missed one spinner, updated and exit script if github
is unreachable.
---
advanced/Scripts/update.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/advanced/Scripts/update.sh b/advanced/Scripts/update.sh
index e5e8766d..71b0a6ad 100644
--- a/advanced/Scripts/update.sh
+++ b/advanced/Scripts/update.sh
@@ -48,7 +48,7 @@ make_repo() {
# Remove the non-repod interface and clone the interface
echo -n "::: Cloning $2 into $1..."
rm -rf "${1}"
- git clone -q --depth 1 "${2}" "${1}" > /dev/null & spinner $!
+ git clone -q --depth 1 "${2}" "${1}" > /dev/null || exit 1
echo " done!"
}
From bdd240ecb66d8acafe60c166c7c962ce9b3bbe04 Mon Sep 17 00:00:00 2001
From: Dan Schaper
Date: Tue, 1 Nov 2016 15:36:27 -0700
Subject: [PATCH 023/228] Shellcheck catch for always true expansion.
---
advanced/Scripts/update.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/advanced/Scripts/update.sh b/advanced/Scripts/update.sh
index 71b0a6ad..90b82ce3 100644
--- a/advanced/Scripts/update.sh
+++ b/advanced/Scripts/update.sh
@@ -107,7 +107,7 @@ if [[ "${piholeVersion}" == "${piholeVersionLatest}" ]] && [[ "${webVersion}" ==
echo ""
exit 0
-elif [[ "${piholeVersion} == ${piholeVersionLatest}" ]] && [[ "${webVersion}" != "${webVersionLatest}" ]]; then
+elif [[ "${piholeVersion}" == "${piholeVersionLatest}" ]] && [[ "${webVersion}" != "${webVersionLatest}" ]]; then
echo "::: Pi-hole Web Admin files out of date"
getGitFiles "${WEBINTERFACEDIR}" "${WEBINTERFACEGITURL}"
echo ":::"
From 884363bd0535f4582b9f4425f671c7d7e4c82955 Mon Sep 17 00:00:00 2001
From: Jacob Salmela
Date: Tue, 1 Nov 2016 19:01:28 -0500
Subject: [PATCH 024/228] remove ipv6 check since it's already in setupVars
---
advanced/Scripts/chronometer.sh | 8 --------
1 file changed, 8 deletions(-)
diff --git a/advanced/Scripts/chronometer.sh b/advanced/Scripts/chronometer.sh
index 2c305d53..7ed20417 100755
--- a/advanced/Scripts/chronometer.sh
+++ b/advanced/Scripts/chronometer.sh
@@ -61,14 +61,6 @@ CalcPercentBlockedToday() {
fi
}
-CheckIPv6() {
- piholeIPv6file="/etc/pihole/.useIPv6"
- if [[ -f ${piholeIPv6file} ]];then
- # If the file exists, then the user previously chose to use IPv6 in the automated installer
- piholeIPv6=$(ip -6 route get 2001:4860:4860::8888 | awk -F " " '{ for(i=1;i<=NF;i++) if ($i == "src") print $(i+1) }')
- fi
-}
-
outputJSON() {
CalcQueriesToday
CalcblockedToday
From f8e97269223dc06b58aef15f2c25a6ff3fbd8504 Mon Sep 17 00:00:00 2001
From: Jacob Salmela
Date: Tue, 1 Nov 2016 19:01:48 -0500
Subject: [PATCH 025/228] source setupVars and check for the correct variable
---
advanced/Scripts/chronometer.sh | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/advanced/Scripts/chronometer.sh b/advanced/Scripts/chronometer.sh
index 7ed20417..bd755453 100755
--- a/advanced/Scripts/chronometer.sh
+++ b/advanced/Scripts/chronometer.sh
@@ -17,11 +17,12 @@ gravity="/etc/pihole/gravity.list"
today=$(date "+%b %e")
+. /etc/pihole/setupVars.conf
+
CalcBlockedDomains() {
- CheckIPv6
if [ -e "${gravity}" ]; then
#Are we IPV6 or IPV4?
- if [[ -n ${piholeIPv6} ]]; then
+ if [[ -n "${IPv6_address}" ]]; then
#We are IPV6
blockedDomainsTotal=$(wc -l /etc/pihole/gravity.list | awk '{print $1/2}')
else
From 72015b0226e31bae8b349f4896562bb175bbd696 Mon Sep 17 00:00:00 2001
From: diginc
Date: Tue, 1 Nov 2016 23:00:14 -0500
Subject: [PATCH 026/228] reduce complexity and un needed cat
---
README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/README.md b/README.md
index b28b3f3e..496816fb 100644
--- a/README.md
+++ b/README.md
@@ -14,7 +14,7 @@ Works on most Debian and CentOS/RHEL based distributions!
```bash
wget -O basic-install.sh https://install.pi-hole.net
-cat basic-install.sh | bash
+bash basic-install.sh
```
If you wish to read over the script before running it, then after the [`wget`](https://linux.die.net/man/1/wget) command, run `nano basic-install.sh` to open the file in a text viewer.
From a8fa061f2e89c24d3123687a89951e979030669b Mon Sep 17 00:00:00 2001
From: diginc
Date: Tue, 1 Nov 2016 23:02:06 -0500
Subject: [PATCH 027/228] quote all the assignments prevent accidental glob
splitting
---
advanced/Scripts/update.sh | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/advanced/Scripts/update.sh b/advanced/Scripts/update.sh
index 71b0a6ad..c28e4249 100644
--- a/advanced/Scripts/update.sh
+++ b/advanced/Scripts/update.sh
@@ -74,14 +74,14 @@ fi
echo "::: Checking for updates..."
# Checks Pi-hole version > pihole only > current local git repo version : returns string in format vX.X.X
-piholeVersion=$(/usr/local/bin/pihole -v -p -c)
+piholeVersion="$(/usr/local/bin/pihole -v -p -c)"
# Checks Pi-hole version > pihole only > remote upstream repo version : returns string in format vX.X.X
-piholeVersionLatest=$(/usr/local/bin/pihole -v -p -l)
+piholeVersionLatest="$(/usr/local/bin/pihole -v -p -l)"
# Checks Pi-hole version > admin only > current local git repo version : returns string in format vX.X.X
-webVersion=$(/usr/local/bin/pihole -v -a -c)
+webVersion="$(/usr/local/bin/pihole -v -a -c)"
# Checks Pi-hole version > admin only > remote upstream repo version : returns string in format vX.X.X
-webVersionLatest=$(/usr/local/bin/pihole -v -a -l)
+webVersionLatest="$(/usr/local/bin/pihole -v -a -l)"
echo ":::"
echo "::: Pi-hole version is $piholeVersion (Latest version is $piholeVersionLatest)"
@@ -111,7 +111,7 @@ elif [[ "${piholeVersion} == ${piholeVersionLatest}" ]] && [[ "${webVersion}" !=
echo "::: Pi-hole Web Admin files out of date"
getGitFiles "${WEBINTERFACEDIR}" "${WEBINTERFACEGITURL}"
echo ":::"
- webVersion=$(/usr/local/bin/pihole -v -a -c)
+ webVersion="$(/usr/local/bin/pihole -v -a -c)"
echo "::: Web Admin version is now at ${webVersion}"
echo "::: If you had made any changes in '/var/www/html/admin', they have been stashed using 'git stash'"
echo ""
@@ -122,7 +122,7 @@ elif [[ "${piholeVersion}" != "${piholeVersionLatest}" ]] && [[ "${webVersion}"
/etc/.pihole/automated\ install/basic-install.sh --reconfigure --unattended || echo "Unable to complete update, contact Pi-hole" && exit 1
echo ":::"
- piholeVersion=$(/usr/local/bin/pihole -v -p -c)
+ piholeVersion="$(/usr/local/bin/pihole -v -p -c)"
echo "::: Pi-hole version is now at ${piholeVersion}"
echo "::: If you had made any changes in '/etc/.pihole', they have been stashed using 'git stash'"
echo ""
@@ -133,9 +133,9 @@ elif [[ "${piholeVersion}" != "${piholeVersionLatest}" ]] && [[ "${webVersion}"
/etc/.pihole/automated\ install/basic-install.sh --unattended || echo "Unable to complete update, contact Pi-hole" && exit 1
# Checks Pi-hole version > admin only > current local git repo version : returns string in format vX.X.X
- webVersion=$(/usr/local/bin/pihole -v -a -c)
+ webVersion="$(/usr/local/bin/pihole -v -a -c)"
# Checks Pi-hole version > admin only > current local git repo version : returns string in format vX.X.X
- piholeVersion=$(/usr/local/bin/pihole -v -p -c)
+ piholeVersion="$(/usr/local/bin/pihole -v -p -c)"
echo ":::"
echo "::: Pi-hole version is now at ${piholeVersion}"
echo "::: If you had made any changes in '/etc/.pihole', they have been stashed using 'git stash'"
From d986746ef9e1fa565f319adef025bfd168a14435 Mon Sep 17 00:00:00 2001
From: diginc
Date: Tue, 1 Nov 2016 23:02:50 -0500
Subject: [PATCH 028/228] missing quote added
---
advanced/Scripts/update.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/advanced/Scripts/update.sh b/advanced/Scripts/update.sh
index c28e4249..7b08179d 100644
--- a/advanced/Scripts/update.sh
+++ b/advanced/Scripts/update.sh
@@ -107,7 +107,7 @@ if [[ "${piholeVersion}" == "${piholeVersionLatest}" ]] && [[ "${webVersion}" ==
echo ""
exit 0
-elif [[ "${piholeVersion} == ${piholeVersionLatest}" ]] && [[ "${webVersion}" != "${webVersionLatest}" ]]; then
+elif [[ "${piholeVersion}" == "${piholeVersionLatest}" ]] && [[ "${webVersion}" != "${webVersionLatest}" ]]; then
echo "::: Pi-hole Web Admin files out of date"
getGitFiles "${WEBINTERFACEDIR}" "${WEBINTERFACEGITURL}"
echo ":::"
From c30478bf4a594084375c9e5bd766b722e2b96852 Mon Sep 17 00:00:00 2001
From: diginc
Date: Tue, 1 Nov 2016 23:21:50 -0500
Subject: [PATCH 029/228] cleanup and use sentintel in is_repo
---
advanced/Scripts/update.sh | 20 +++++++++++---------
1 file changed, 11 insertions(+), 9 deletions(-)
diff --git a/advanced/Scripts/update.sh b/advanced/Scripts/update.sh
index 7b08179d..0e36c2a2 100644
--- a/advanced/Scripts/update.sh
+++ b/advanced/Scripts/update.sh
@@ -33,15 +33,17 @@ getGitFiles() {
is_repo() {
# Use git to check if directory is currently under VCS
- echo -n "::: Checking $1 is a repo..."
- cd "${1}" &> /dev/null || return 1
- if [[ $(git status --short) ]]; then
- echo " OK!"
- return 0
- else
- echo " not found!"
- return 1
- fi
+ local directory="${1}"
+ local gitRepo=0
+ echo -n "::: Checking if ${directory} is a repo... "
+ cd "${directory}" &> /dev/null || return 1
+ if [[ $(git status --short > /dev/null) ]]; then
+ echo "OK"
+ else
+ echo "not found!"
+ gitRepo=1
+ fi;
+ return ${gitRepo}
}
make_repo() {
From 26789f9b3670a1390e0bcd948900f4c1e6fcb243 Mon Sep 17 00:00:00 2001
From: diginc
Date: Tue, 1 Nov 2016 23:53:11 -0500
Subject: [PATCH 030/228] add travis and python requirements
---
.travis.yml | 10 ++++++++++
requirements.txt | 5 +++++
2 files changed, 15 insertions(+)
create mode 100644 .travis.yml
create mode 100644 requirements.txt
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 00000000..2ca3b2d2
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,10 @@
+sudo: required
+services:
+ - docker
+language: python
+python:
+ - "2.7"
+install:
+ - pip install -r requirements.txt
+
+script: py.test -vv
diff --git a/requirements.txt b/requirements.txt
new file mode 100644
index 00000000..53737ca5
--- /dev/null
+++ b/requirements.txt
@@ -0,0 +1,5 @@
+docker-compose
+pytest
+pytest-xdist
+pytest-cov
+testinfra
From 7548d9a8fe935320a564da5e3ae77b4147edc3a5 Mon Sep 17 00:00:00 2001
From: diginc
Date: Tue, 1 Nov 2016 23:56:46 -0500
Subject: [PATCH 031/228] point shellcheck at update.sh instead
---
test/shellcheck_failing_output.txt | 128 ++++++++---------------------
test/test_shellcheck.py | 2 +-
2 files changed, 33 insertions(+), 97 deletions(-)
diff --git a/test/shellcheck_failing_output.txt b/test/shellcheck_failing_output.txt
index 65b79560..c741a8e9 100644
--- a/test/shellcheck_failing_output.txt
+++ b/test/shellcheck_failing_output.txt
@@ -18,123 +18,59 @@ _________________________ test_scripts_pass_shellcheck _________________________
def test_scripts_pass_shellcheck():
''' Make sure shellcheck does not find anything wrong with our shell scripts '''
- shellcheck = "find . -name 'basic-install.sh' | while read file; do shellcheck \"$file\"; done;"
+ shellcheck = "find . -name 'update.sh' | while read file; do shellcheck \"$file\"; done;"
results = run_local(shellcheck)
print results.stdout
> assert '' == results.stdout
-E assert '' == '\nIn ./automated install/bas...C may run when A is true.\n\n'
+E assert '' == '\nIn ./advanced/Scripts/upda...vent glob interpretation.\n\n'
E +
-E + In ./automated install/basic-install.sh line 79:
-E + INSTALLER_DEPS=( apt-utils whiptail git dhcpcd5)
-E + ^-- SC2034: INSTALLER_DEPS appears unused. Verify it or export it.
+E + In ./advanced/Scripts/update.sh line 24:
+E + while [ "$(ps a | awk '{print $1}' | grep "${pid}")" ]; do
+E + ^-- SC2143: Instead of [ -n $(foo | grep bar) ], use foo | grep -q bar .
E +
E +
-E + In ./automated install/basic-install.sh line 80:
-E + PIHOLE_DEPS=( dnsutils bc dnsmasq lighttpd ${phpVer}-common ${phpVer}-cgi curl unzip wget sudo netcat cron iproute2 )
-E + ^-- SC2034: PIHOLE_DEPS appears unused. Verify it or export it.
-E Detailed information truncated (91 more lines), use "-vv" to show
+E + In ./advanced/Scripts/update.sh line 57:
+E + git clone -q --depth 1 "${2}" "${1}" > /dev/null & spinner $!
+E + ^-- SC2086: Double quote to prevent globbing and word splitting.
+E Detailed information truncated (27 more lines), use "-vv" to show
test/test_shellcheck.py:13: AssertionError
----------------------------- Captured stdout call -----------------------------
-In ./automated install/basic-install.sh line 79:
- INSTALLER_DEPS=( apt-utils whiptail git dhcpcd5)
- ^-- SC2034: INSTALLER_DEPS appears unused. Verify it or export it.
+In ./advanced/Scripts/update.sh line 24:
+ while [ "$(ps a | awk '{print $1}' | grep "${pid}")" ]; do
+ ^-- SC2143: Instead of [ -n $(foo | grep bar) ], use foo | grep -q bar .
-In ./automated install/basic-install.sh line 80:
- PIHOLE_DEPS=( dnsutils bc dnsmasq lighttpd ${phpVer}-common ${phpVer}-cgi curl unzip wget sudo netcat cron iproute2 )
- ^-- SC2034: PIHOLE_DEPS appears unused. Verify it or export it.
+In ./advanced/Scripts/update.sh line 57:
+ git clone -q --depth 1 "${2}" "${1}" > /dev/null & spinner $!
+ ^-- SC2086: Double quote to prevent globbing and word splitting.
-In ./automated install/basic-install.sh line 86:
- dpkg-query -W -f='${Status}' "$1" 2>/dev/null | grep -c "ok installed" || ${PKG_INSTALL} "$1"
- ^-- SC2016: Expressions don't expand in single quotes, use double quotes for that.
+In ./advanced/Scripts/update.sh line 65:
+ git stash -q > /dev/null & spinner $!
+ ^-- SC2086: Double quote to prevent globbing and word splitting.
-In ./automated install/basic-install.sh line 100:
- INSTALLER_DEPS=( iproute net-tools procps-ng newt git )
- ^-- SC2034: INSTALLER_DEPS appears unused. Verify it or export it.
+In ./advanced/Scripts/update.sh line 66:
+ git pull -q > /dev/null & spinner $!
+ ^-- SC2086: Double quote to prevent globbing and word splitting.
-In ./automated install/basic-install.sh line 101:
- PIHOLE_DEPS=( epel-release bind-utils bc dnsmasq lighttpd lighttpd-fastcgi php-common php-cli php curl unzip wget findutils cronie sudo nmap-ncat )
- ^-- SC2034: PIHOLE_DEPS appears unused. Verify it or export it.
+In ./advanced/Scripts/update.sh line 107:
+if [[ ${piholeVersion} == ${piholeVersionLatest} && ${webVersion} == ${webVersionLatest} ]]; then
+ ^-- SC2053: Quote the rhs of = in [[ ]] to prevent glob interpretation.
+ ^-- SC2053: Quote the rhs of = in [[ ]] to prevent glob interpretation.
-In ./automated install/basic-install.sh line 120:
- while [ "$(ps a | awk '{print $1}' | grep "$pid")" ]; do
- ^-- SC2143: Instead of [ -n $(foo | grep bar) ], use foo | grep -q bar .
+In ./advanced/Scripts/update.sh line 112:
+elif [[ ${piholeVersion} == ${piholeVersionLatest} && ${webVersion} != ${webVersionLatest} ]]; then
+ ^-- SC2053: Quote the rhs of = in [[ ]] to prevent glob interpretation.
-In ./automated install/basic-install.sh line 214:
- chooseInterfaceOptions=$("${chooseInterfaceCmd[@]}" "${interfacesArray[@]}" 2>&1 >/dev/tty)
- ^-- SC2069: The order of the 2>&1 and the redirect matters. The 2>&1 has to be last.
+In ./advanced/Scripts/update.sh line 120:
+elif [[ ${piholeVersion} != ${piholeVersionLatest} && ${webVersion} == ${webVersionLatest} ]]; then
+ ^-- SC2053: Quote the rhs of = in [[ ]] to prevent glob interpretation.
-In ./automated install/basic-install.sh line 241:
- choices=$("${cmd[@]}" "${options[@]}" 2>&1 >/dev/tty)
- ^-- SC2069: The order of the 2>&1 and the redirect matters. The 2>&1 has to be last.
-
-
-In ./automated install/basic-install.sh line 354:
- cp "${IFCFG_FILE}" "${IFCFG_FILE}".backup-"$(date +%Y-%m-%d-%H%M%S)"
- ^-- SC2140: The double quotes around this do nothing. Remove or escape them.
-
-
-In ./automated install/basic-install.sh line 408:
- DNSchoices=$("${DNSChooseCmd[@]}" "${DNSChooseOptions[@]}" 2>&1 >/dev/tty)
- ^-- SC2069: The order of the 2>&1 and the redirect matters. The 2>&1 has to be last.
-
-
-In ./automated install/basic-install.sh line 585:
- systemctl stop "${1}" &> /dev/null & spinner $! || true
- ^-- SC2086: Double quote to prevent globbing and word splitting.
-
-
-In ./automated install/basic-install.sh line 587:
- service "${1}" stop &> /dev/null & spinner $! || true
- ^-- SC2086: Double quote to prevent globbing and word splitting.
-
-
-In ./automated install/basic-install.sh line 598:
- systemctl restart "${1}" &> /dev/null & spinner $!
- ^-- SC2086: Double quote to prevent globbing and word splitting.
-
-
-In ./automated install/basic-install.sh line 600:
- service "${1}" restart &> /dev/null & spinner $!
- ^-- SC2086: Double quote to prevent globbing and word splitting.
-
-
-In ./automated install/basic-install.sh line 610:
- systemctl enable "${1}" &> /dev/null & spinner $!
- ^-- SC2086: Double quote to prevent globbing and word splitting.
-
-
-In ./automated install/basic-install.sh line 612:
- update-rc.d "${1}" defaults &> /dev/null & spinner $!
- ^-- SC2086: Double quote to prevent globbing and word splitting.
-
-
-In ./automated install/basic-install.sh line 631:
- ${UPDATE_PKG_CACHE} &> /dev/null & spinner $!
- ^-- SC2086: Double quote to prevent globbing and word splitting.
-
-
-In ./automated install/basic-install.sh line 688:
- git clone -q --depth 1 "${2}" "${1}" > /dev/null & spinner $!
- ^-- SC2086: Double quote to prevent globbing and word splitting.
-
-
-In ./automated install/basic-install.sh line 696:
- git pull -q > /dev/null & spinner $!
- ^-- SC2086: Double quote to prevent globbing and word splitting.
-
-
-In ./automated install/basic-install.sh line 761:
- id -u pihole &> /dev/null && echo "::: User 'pihole' already exists" || (echo "::: User 'pihole' doesn't exist. Creating..." && useradd -r -s /usr/sbin/nologin pihole)
- ^-- SC2015: Note that A && B || C is not if-then-else. C may run when A is true.
-
-
-===================== 1 failed, 6 passed in 20.79 seconds ======================
+===================== 1 failed, 6 passed in 24.01 seconds ======================
diff --git a/test/test_shellcheck.py b/test/test_shellcheck.py
index 7f777caf..43b27164 100644
--- a/test/test_shellcheck.py
+++ b/test/test_shellcheck.py
@@ -7,7 +7,7 @@ run_local = testinfra.get_backend(
def test_scripts_pass_shellcheck():
''' Make sure shellcheck does not find anything wrong with our shell scripts '''
- shellcheck = "find . -name 'basic-install.sh' | while read file; do shellcheck \"$file\"; done;"
+ shellcheck = "find . -name 'update.sh' | while read file; do shellcheck \"$file\"; done;"
results = run_local(shellcheck)
print results.stdout
assert '' == results.stdout
From 7a2247178761a00cb52d81242df7cdcab5ae3d48 Mon Sep 17 00:00:00 2001
From: Dan Schaper
Date: Tue, 1 Nov 2016 22:19:40 -0700
Subject: [PATCH 032/228] New naming convention, and reorder functions as bash
would prefer them to be.
---
advanced/Scripts/update.sh | 38 +++++++++++++++---------------
automated install/basic-install.sh | 32 ++++++++++++-------------
2 files changed, 35 insertions(+), 35 deletions(-)
diff --git a/advanced/Scripts/update.sh b/advanced/Scripts/update.sh
index 90b82ce3..b14b9bcd 100644
--- a/advanced/Scripts/update.sh
+++ b/advanced/Scripts/update.sh
@@ -14,22 +14,10 @@
# Variables
-readonly WEBINTERFACEGITURL="https://github.com/pi-hole/AdminLTE.git"
-readonly WEBINTERFACEDIR="/var/www/html/admin"
-readonly PIHOLEGITURL="https://github.com/pi-hole/pi-hole.git"
-readonly PIHOLEFILESDIR="/etc/.pihole"
-
-getGitFiles() {
- # Setup git repos for directory and repository passed
- # as arguments 1 and 2
- echo ":::"
- echo "::: Checking for existing repository..."
- if is_repo "${1}"; then
- update_repo "${1}"
- else
- make_repo "${1}" "${2}"
- fi
-}
+readonly ADMIN_INTERFACE_GIT_URL="https://github.com/pi-hole/AdminLTE.git"
+readonly ADMIN_INTERFACE_DIR="/var/www/html/admin"
+readonly PI_HOLE_GIT_URL="https://github.com/pi-hole/pi-hole.git"
+readonly PI_HOLE_FILES_DIR="/etc/.pihole"
is_repo() {
# Use git to check if directory is currently under VCS
@@ -61,6 +49,18 @@ update_repo() {
echo " done!"
}
+getGitFiles() {
+ # Setup git repos for directory and repository passed
+ # as arguments 1 and 2
+ echo ":::"
+ echo "::: Checking for existing repository..."
+ if is_repo "${1}"; then
+ update_repo "${1}"
+ else
+ make_repo "${1}" "${2}"
+ fi
+}
+
if [ ! -d "/etc/.pihole" ]; then #This is unlikely
echo "::: Critical Error: Pi-Hole repo missing from system!"
echo "::: Please re-run install script from https://github.com/pi-hole/pi-hole"
@@ -109,7 +109,7 @@ if [[ "${piholeVersion}" == "${piholeVersionLatest}" ]] && [[ "${webVersion}" ==
elif [[ "${piholeVersion}" == "${piholeVersionLatest}" ]] && [[ "${webVersion}" != "${webVersionLatest}" ]]; then
echo "::: Pi-hole Web Admin files out of date"
- getGitFiles "${WEBINTERFACEDIR}" "${WEBINTERFACEGITURL}"
+ getGitFiles "${ADMIN_INTERFACE_DIR}" "${ADMIN_INTERFACE_GIT_URL}"
echo ":::"
webVersion=$(/usr/local/bin/pihole -v -a -c)
echo "::: Web Admin version is now at ${webVersion}"
@@ -117,7 +117,7 @@ elif [[ "${piholeVersion}" == "${piholeVersionLatest}" ]] && [[ "${webVersion}"
echo ""
elif [[ "${piholeVersion}" != "${piholeVersionLatest}" ]] && [[ "${webVersion}" == "${webVersionLatest}" ]]; then
echo "::: Pi-hole core files out of date"
- getGitFiles "${PIHOLEFILESDIR}" "${PIHOLEGITURL}"
+ getGitFiles "${PI_HOLE_FILES_DIR}" "${PI_HOLE_GIT_URL}"
/etc/.pihole/automated\ install/basic-install.sh --reconfigure --unattended || echo "Unable to complete update, contact Pi-hole" && exit 1
@@ -128,7 +128,7 @@ elif [[ "${piholeVersion}" != "${piholeVersionLatest}" ]] && [[ "${webVersion}"
echo ""
elif [[ "${piholeVersion}" != "${piholeVersionLatest}" ]] && [[ "${webVersion}" != "${webVersionLatest}" ]]; then
echo "::: Updating Everything"
- getGitFiles "${PIHOLEFILESDIR}" "${PIHOLEGITURL}"
+ getGitFiles "${PI_HOLE_FILES_DIR}" "${PI_HOLE_GIT_URL}"
/etc/.pihole/automated\ install/basic-install.sh --unattended || echo "Unable to complete update, contact Pi-hole" && exit 1
diff --git a/automated install/basic-install.sh b/automated install/basic-install.sh
index 6489a5fc..921b0ffa 100755
--- a/automated install/basic-install.sh
+++ b/automated install/basic-install.sh
@@ -712,6 +712,22 @@ install_dependent_packages() {
done
}
+make_repo() {
+ # Remove the non-repod interface and clone the interface
+ echo -n "::: Cloning $2 into $1..."
+ rm -rf "${1}"
+ git clone -q --depth 1 "${2}" "${1}" > /dev/null & spinner $!
+ echo " done!"
+}
+
+update_repo() {
+ # Pull the latest commits
+ echo -n "::: Updating repo in $1..."
+ cd "${1}" || exit 1
+ git stash -q > /dev/null & spinner $!
+ git pull -q > /dev/null & spinner $!
+ echo " done!"
+}
getGitFiles() {
# Setup git repos for directory and repository passed
# as arguments 1 and 2
@@ -731,22 +747,6 @@ is_repo() {
git status &> /dev/null && echo " OK!"; return 0 || echo " not found!"; return 1
}
-make_repo() {
- # Remove the non-repod interface and clone the interface
- echo -n "::: Cloning $2 into $1..."
- rm -rf "${1}"
- git clone -q --depth 1 "${2}" "${1}" > /dev/null & spinner $!
- echo " done!"
-}
-
-update_repo() {
- # Pull the latest commits
- echo -n "::: Updating repo in $1..."
- cd "${1}" || exit 1
- git stash -q > /dev/null & spinner $!
- git pull -q > /dev/null & spinner $!
- echo " done!"
-}
CreateLogFile() {
# Create logfiles if necessary
From db0f3307e07a5b4d40b2b7a032556eb3efeef580 Mon Sep 17 00:00:00 2001
From: Dan Schaper
Date: Tue, 1 Nov 2016 22:48:30 -0700
Subject: [PATCH 033/228] Only take out scripts in the directory, don't remove
the directory as a whole. Need this for the future installs.
---
automated install/basic-install.sh | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/automated install/basic-install.sh b/automated install/basic-install.sh
index 921b0ffa..a9a5d47d 100755
--- a/automated install/basic-install.sh
+++ b/automated install/basic-install.sh
@@ -593,8 +593,7 @@ installScripts() {
echo ":::"
echo -n "::: Installing scripts to /opt/pihole..."
#clear out /opt/pihole and recreate it. This allows us to remove scripts from future installs
- rm -rf /opt/pihole
- install -o "${USER}" -m755 -d /opt/pihole
+ rm -f /opt/pihole/*.sh
cd /etc/.pihole/
From 12f5f8ba00b2f3c31517c1f18905b349119a902c Mon Sep 17 00:00:00 2001
From: Dan Schaper
Date: Wed, 2 Nov 2016 00:14:25 -0700
Subject: [PATCH 034/228] Begin to bring code up to Pi-hole conventions. Block
installScripts and begin factoring out redundant code.
---
automated install/basic-install.sh | 122 +++++++++++++++++------------
1 file changed, 70 insertions(+), 52 deletions(-)
diff --git a/automated install/basic-install.sh b/automated install/basic-install.sh
index a9a5d47d..ea1fb8d9 100755
--- a/automated install/basic-install.sh
+++ b/automated install/basic-install.sh
@@ -25,8 +25,8 @@ setupVars=/etc/pihole/setupVars.conf
webInterfaceGitUrl="https://github.com/pi-hole/AdminLTE.git"
webInterfaceDir="/var/www/html/admin"
piholeGitUrl="https://github.com/pi-hole/pi-hole.git"
-piholeFilesDir="/etc/.pihole"
-
+PI_HOLE_LOCAL_REPO="/etc/.pihole"
+PI_HOLE_FILES=(chronometer list piholeDebug piholeLogFlush setupLCD update version)
useUpdateVars=false
IPv4_address=""
@@ -144,6 +144,42 @@ spinner() {
printf " \b\b\b\b"
}
+is_repo() {
+ # Use git to check if directory is currently under VCS
+ echo -n "::: Checking $1 is a repo..."
+ cd "${1}" &> /dev/null || return 1
+ git status &> /dev/null && echo " OK!"; return 0 || echo " not found!"; return 1
+}
+
+make_repo() {
+ # Remove the non-repod interface and clone the interface
+ echo -n "::: Cloning $2 into $1..."
+ rm -rf "${1}"
+ git clone -q --depth 1 "${2}" "${1}" > /dev/null & spinner $!
+ echo " done!"
+}
+
+update_repo() {
+ # Pull the latest commits
+ echo -n "::: Updating repo in $1..."
+ cd "${1}" || exit 1
+ git stash -q > /dev/null & spinner $!
+ git pull -q > /dev/null & spinner $!
+ echo " done!"
+}
+
+getGitFiles() {
+ # Setup git repos for directory and repository passed
+ # as arguments 1 and 2
+ echo ":::"
+ echo "::: Checking for existing repository..."
+ if is_repo "${1}"; then
+ update_repo "${1}"
+ else
+ make_repo "${1}" "${2}"
+ fi
+}
+
find_IPv4_information() {
# Find IP used to route to outside world
IPv4dev=$(ip route get 8.8.8.8 | awk '{for(i=1;i<=NF;i++)if($i~/dev/)print $(i+1)}')
@@ -169,7 +205,6 @@ welcomeDialogs() {
In the next section, you can choose to use your current network settings (DHCP) or to manually edit them." ${r} ${c}
}
-
verifyFreeDiskSpace() {
# 50MB is the minimum space needed (45MB install (includes web admin bootstrap/jquery libraries etc) + 5MB one day of logs.)
@@ -588,22 +623,41 @@ remove_legacy_scripts() {
done
}
+clean_existing() {
+ # Clean an exiting installation to prepare for upgrade/reinstall
+ # ${1} Directory to clean; ${2} Array of files to remove
+ local clean_directory="${1}"
+ local old_files=${2}
+
+ for script in "${old_files[@]}"; do
+ rm -f "${clean_directory}${script}.sh"
+ done
+
+}
+
installScripts() {
- # Install the scripts from /etc/.pihole to their various locations
+ # Install the scripts from repository to their various locations
+ readonly install_dir="/opt/pihole/"
+
echo ":::"
- echo -n "::: Installing scripts to /opt/pihole..."
- #clear out /opt/pihole and recreate it. This allows us to remove scripts from future installs
- rm -f /opt/pihole/*.sh
+ echo -n "::: Installing scripts to ${PI_HOLE_LOCAL_REPO}..."
- cd /etc/.pihole/
+ # Clear out script files from Pi-hole scripts directory.
+ clean_existing "${install_dir}" "${PI_HOLE_FILES}"
- install -o "${USER}" -Dm755 -t /opt/pihole/ gravity.sh
- install -o "${USER}" -Dm755 -t /opt/pihole/ ./advanced/Scripts/*.sh
- install -o "${USER}" -Dm755 -t /opt/pihole/ ./automated\ install/uninstall.sh
- install -o "${USER}" -Dm755 -t /usr/local/bin/ pihole
-
- install -Dm644 ./advanced/bash-completion/pihole /etc/bash_completion.d/pihole
- echo " done."
+ # Install files from local core repository
+ if [[ $(is_repo "${PI_HOLE_LOCAL_REPO}") ]]; then
+ cd "${PI_HOLE_LOCAL_REPO}"
+ install -o "${USER}" -Dm755 -t /opt/pihole/ gravity.sh
+ install -o "${USER}" -Dm755 -t /opt/pihole/ ./advanced/Scripts/*.sh
+ install -o "${USER}" -Dm755 -t /opt/pihole/ ./automated\ install/uninstall.sh
+ install -o "${USER}" -Dm755 -t /usr/local/bin/ pihole
+ install -Dm644 ./advanced/bash-completion/pihole /etc/bash_completion.d/pihole
+ echo " done."
+ else
+ echo " *** ERROR: Local repo ${core_repo} not found, exiting."
+ exit 1
+ fi
}
installConfigs() {
@@ -711,42 +765,6 @@ install_dependent_packages() {
done
}
-make_repo() {
- # Remove the non-repod interface and clone the interface
- echo -n "::: Cloning $2 into $1..."
- rm -rf "${1}"
- git clone -q --depth 1 "${2}" "${1}" > /dev/null & spinner $!
- echo " done!"
-}
-
-update_repo() {
- # Pull the latest commits
- echo -n "::: Updating repo in $1..."
- cd "${1}" || exit 1
- git stash -q > /dev/null & spinner $!
- git pull -q > /dev/null & spinner $!
- echo " done!"
-}
-getGitFiles() {
- # Setup git repos for directory and repository passed
- # as arguments 1 and 2
- echo ":::"
- echo "::: Checking for existing repository..."
- if is_repo "${1}"; then
- update_repo "${1}"
- else
- make_repo "${1}" "${2}"
- fi
-}
-
-is_repo() {
- # Use git to check if directory is currently under VCS
- echo -n "::: Checking $1 is a repo..."
- cd "${1}" &> /dev/null || return 1
- git status &> /dev/null && echo " OK!"; return 0 || echo " not found!"; return 1
-}
-
-
CreateLogFile() {
# Create logfiles if necessary
echo ":::"
@@ -994,7 +1012,7 @@ main() {
echo "::: --reconfigure passed to install script. Not downloading/updating local repos"
else
# Get Git files for Core and Admin
- getGitFiles ${piholeFilesDir} ${piholeGitUrl}
+ getGitFiles ${PI_HOLE_LOCAL_REPO} ${piholeGitUrl}
getGitFiles ${webInterfaceDir} ${webInterfaceGitUrl}
fi
From d9528dfd0967cb947f42ef6ab0e3d6721c9f71d1 Mon Sep 17 00:00:00 2001
From: Dan Schaper
Date: Wed, 2 Nov 2016 00:51:38 -0700
Subject: [PATCH 035/228] Bash is funny with returns.
---
advanced/Scripts/update.sh | 10 +++++++---
automated install/basic-install.sh | 6 +++---
2 files changed, 10 insertions(+), 6 deletions(-)
diff --git a/advanced/Scripts/update.sh b/advanced/Scripts/update.sh
index fd67a484..8531dc2c 100644
--- a/advanced/Scripts/update.sh
+++ b/advanced/Scripts/update.sh
@@ -25,7 +25,7 @@ is_repo() {
local gitRepo=0
echo -n "::: Checking if ${directory} is a repo... "
cd "${directory}" &> /dev/null || return 1
- if [[ $(git status --short > /dev/null) ]]; then
+ if [[ $(git status --short &> /dev/null) ]]; then
echo "OK"
else
echo "not found!"
@@ -63,12 +63,16 @@ getGitFiles() {
fi
}
-if [ ! -d "/etc/.pihole" ]; then #This is unlikely
+
+is_repo "${PI_HOLE_FILES_DIR}" &> /dev/null
+if [[ $? -eq 1 ]]; then #This is unlikely
echo "::: Critical Error: Pi-Hole repo missing from system!"
echo "::: Please re-run install script from https://github.com/pi-hole/pi-hole"
exit 1;
fi
-if [ ! -d "/var/www/html/admin" ]; then #This is unlikely
+
+is_repo "${ADMIN_INTERFACE_DIR}" &> /dev/null
+if [[ $? -eq 1 ]]; then #This is unlikely
echo "::: Critical Error: Pi-Hole repo missing from system!"
echo "::: Please re-run install script from https://github.com/pi-hole/pi-hole"
exit 1;
diff --git a/automated install/basic-install.sh b/automated install/basic-install.sh
index ea1fb8d9..49329f5a 100755
--- a/automated install/basic-install.sh
+++ b/automated install/basic-install.sh
@@ -73,7 +73,7 @@ fi
# Compatibility
-if [ -x "$(command -v apt-get)" ]; then
+if [[ $(command -v apt-get) ]]; then
#Debian Family
#############################################
PKG_MANAGER="apt-get"
@@ -99,9 +99,9 @@ if [ -x "$(command -v apt-get)" ]; then
package_check_install() {
dpkg-query -W -f='${Status}' "${1}" 2>/dev/null | grep -c "ok installed" || ${PKG_INSTALL} "${1}"
}
-elif [ -x "$(command -v rpm)" ]; then
+elif [ $(command -v rpm) ]; then
# Fedora Family
- if [ -x "$(command -v dnf)" ]; then
+ if [ $(command -v dnf) ]; then
PKG_MANAGER="dnf"
else
PKG_MANAGER="yum"
From 7d414b5628690cadc63acdac3071c3ae118530b4 Mon Sep 17 00:00:00 2001
From: Dan Schaper
Date: Wed, 2 Nov 2016 01:12:02 -0700
Subject: [PATCH 036/228] Move version messages to main function, check for
repos.
---
advanced/Scripts/update.sh | 149 ++++++++++++++++++-------------------
1 file changed, 74 insertions(+), 75 deletions(-)
diff --git a/advanced/Scripts/update.sh b/advanced/Scripts/update.sh
index 8531dc2c..dfabccb0 100644
--- a/advanced/Scripts/update.sh
+++ b/advanced/Scripts/update.sh
@@ -63,90 +63,89 @@ getGitFiles() {
fi
}
+main() {
-is_repo "${PI_HOLE_FILES_DIR}" &> /dev/null
-if [[ $? -eq 1 ]]; then #This is unlikely
- echo "::: Critical Error: Pi-Hole repo missing from system!"
- echo "::: Please re-run install script from https://github.com/pi-hole/pi-hole"
- exit 1;
-fi
+ is_repo "${PI_HOLE_FILES_DIR}" &> /dev/null
+ if [[ $? -eq 1 ]]; then #This is unlikely
+ echo "::: Critical Error: Pi-Hole repo missing from system!"
+ echo "::: Please re-run install script from https://github.com/pi-hole/pi-hole"
+ exit 1;
+ fi
-is_repo "${ADMIN_INTERFACE_DIR}" &> /dev/null
-if [[ $? -eq 1 ]]; then #This is unlikely
- echo "::: Critical Error: Pi-Hole repo missing from system!"
- echo "::: Please re-run install script from https://github.com/pi-hole/pi-hole"
- exit 1;
-fi
+ is_repo "${ADMIN_INTERFACE_DIR}" &> /dev/null
+ if [[ $? -eq 1 ]]; then #This is unlikely
+ echo "::: Critical Error: Pi-Hole repo missing from system!"
+ echo "::: Please re-run install script from https://github.com/pi-hole/pi-hole"
+ exit 1;
+ fi
-echo "::: Checking for updates..."
-# Checks Pi-hole version > pihole only > current local git repo version : returns string in format vX.X.X
-piholeVersion="$(/usr/local/bin/pihole -v -p -c)"
-# Checks Pi-hole version > pihole only > remote upstream repo version : returns string in format vX.X.X
-piholeVersionLatest="$(/usr/local/bin/pihole -v -p -l)"
+ echo "::: Checking for updates..."
+ # Checks Pi-hole version > pihole only > current local git repo version : returns string in format vX.X.X
+ local -r pihole_version_current="$(/usr/local/bin/pihole -v -p -c)"
+ # Checks Pi-hole version > pihole only > remote upstream repo version : returns string in format vX.X.X
+ local -r pihole_version_latest="$(/usr/local/bin/pihole -v -p -l)"
-# Checks Pi-hole version > admin only > current local git repo version : returns string in format vX.X.X
-webVersion="$(/usr/local/bin/pihole -v -a -c)"
-# Checks Pi-hole version > admin only > remote upstream repo version : returns string in format vX.X.X
-webVersionLatest="$(/usr/local/bin/pihole -v -a -l)"
+ # Checks Pi-hole version > admin only > current local git repo version : returns string in format vX.X.X
+ local -r web_version_current="$(/usr/local/bin/pihole -v -a -c)"
+ # Checks Pi-hole version > admin only > remote upstream repo version : returns string in format vX.X.X
+ local -r web_version_latest="$(/usr/local/bin/pihole -v -a -l)"
-echo ":::"
-echo "::: Pi-hole version is $piholeVersion (Latest version is $piholeVersionLatest)"
-echo "::: Web Admin version is $webVersion (Latest version is $webVersionLatest)"
-echo ":::"
+ # Logic
+ # If latest versions are blank - we've probably hit Github rate limit (stop running `pihole -up so often!):
+ # Update anyway
+ # If Core up to date AND web up to date:
+ # Do nothing
+ # If Core up to date AND web NOT up to date:
+ # Pull web repo
+ # If Core NOT up to date AND web up to date:
+ # pull pihole repo, run install --unattended -- reconfigure
+ # if Core NOT up to date AND web NOT up to date:
+ # pull pihole repo run install --unattended
-# Logic
-# If latest versions are blank - we've probably hit Github rate limit (stop running `pihole -up so often!):
-# Update anyway
-# If Core up to date AND web up to date:
-# Do nothing
-# If Core up to date AND web NOT up to date:
-# Pull web repo
-# If Core NOT up to date AND web up to date:
-# pull pihole repo, run install --unattended -- reconfigure
-# if Core NOT up to date AND web NOT up to date:
-# pull pihole repo run install --unattended
+ if [[ "${pihole_version_current}" == "${pihole_version_latest}" ]] && [[ "${web_version_current}" == "${web_version_latest}" ]]; then
+ echo "::: Pi-hole version is $pihole_version_current"
+ echo "::: Web Admin version is $web_version_current"
+ echo "::: Everything is up to date!"
+ echo ""
+ exit 0
+ elif [[ "${pihole_version_current}" == "${pihole_version_latest}" ]] && [[ "${web_version_current}" != "${web_version_latest}" ]]; then
+ echo "::: Pi-hole Web Admin files out of date"
+ getGitFiles "${ADMIN_INTERFACE_DIR}" "${ADMIN_INTERFACE_GIT_URL}"
+ echo ":::"
+ web_version_current="$(/usr/local/bin/pihole -v -a -c)"
+ echo "::: Web Admin version is now at ${web_version_current}"
+ echo "::: If you had made any changes in '/var/www/html/admin', they have been stashed using 'git stash'"
+ echo ""
+ elif [[ "${pihole_version_current}" != "${pihole_version_latest}" ]] && [[ "${web_version_current}" == "${web_version_latest}" ]]; then
+ echo "::: Pi-hole core files out of date"
+ getGitFiles "${PI_HOLE_FILES_DIR}" "${PI_HOLE_GIT_URL}"
+ /etc/.pihole/automated\ install/basic-install.sh --reconfigure --unattended || echo "Unable to complete update, contact Pi-hole" && exit 1
-if [[ "${piholeVersion}" == "${piholeVersionLatest}" ]] && [[ "${webVersion}" == "${webVersionLatest}" ]]; then
- echo "::: Everything is up to date!"
- echo ""
- exit 0
+ echo ":::"
+ pihole_version_current="$(/usr/local/bin/pihole -v -p -c)"
+ echo "::: Pi-hole version is now at ${pihole_version_current}"
+ echo "::: If you had made any changes in '/etc/.pihole', they have been stashed using 'git stash'"
+ echo ""
+ elif [[ "${pihole_version_current}" != "${pihole_version_latest}" ]] && [[ "${web_version_current}" != "${web_version_latest}" ]]; then
+ echo "::: Updating Everything"
+ getGitFiles "${PI_HOLE_FILES_DIR}" "${PI_HOLE_GIT_URL}"
-elif [[ "${piholeVersion}" == "${piholeVersionLatest}" ]] && [[ "${webVersion}" != "${webVersionLatest}" ]]; then
- echo "::: Pi-hole Web Admin files out of date"
- getGitFiles "${ADMIN_INTERFACE_DIR}" "${ADMIN_INTERFACE_GIT_URL}"
- echo ":::"
- webVersion="$(/usr/local/bin/pihole -v -a -c)"
- echo "::: Web Admin version is now at ${webVersion}"
- echo "::: If you had made any changes in '/var/www/html/admin', they have been stashed using 'git stash'"
- echo ""
-elif [[ "${piholeVersion}" != "${piholeVersionLatest}" ]] && [[ "${webVersion}" == "${webVersionLatest}" ]]; then
- echo "::: Pi-hole core files out of date"
- getGitFiles "${PI_HOLE_FILES_DIR}" "${PI_HOLE_GIT_URL}"
+ /etc/.pihole/automated\ install/basic-install.sh --unattended || echo "Unable to complete update, contact Pi-hole" && exit 1
- /etc/.pihole/automated\ install/basic-install.sh --reconfigure --unattended || echo "Unable to complete update, contact Pi-hole" && exit 1
+ # Checks Pi-hole version > admin only > current local git repo version : returns string in format vX.X.X
+ web_version_current="$(/usr/local/bin/pihole -v -a -c)"
+ # Checks Pi-hole version > admin only > current local git repo version : returns string in format vX.X.X
+ pihole_version_current="$(/usr/local/bin/pihole -v -p -c)"
+ echo ":::"
+ echo "::: Pi-hole version is now at ${pihole_version_current}"
+ echo "::: If you had made any changes in '/etc/.pihole', they have been stashed using 'git stash'"
+ echo ":::"
+ echo "::: Pi-hole version is now at ${pihole_version_current}"
+ echo "::: If you had made any changes in '/etc/.pihole', they have been stashed using 'git stash'"
+ echo ""
+ fi
+}
- echo ":::"
- piholeVersion="$(/usr/local/bin/pihole -v -p -c)"
- echo "::: Pi-hole version is now at ${piholeVersion}"
- echo "::: If you had made any changes in '/etc/.pihole', they have been stashed using 'git stash'"
- echo ""
-elif [[ "${piholeVersion}" != "${piholeVersionLatest}" ]] && [[ "${webVersion}" != "${webVersionLatest}" ]]; then
- echo "::: Updating Everything"
- getGitFiles "${PI_HOLE_FILES_DIR}" "${PI_HOLE_GIT_URL}"
-
- /etc/.pihole/automated\ install/basic-install.sh --unattended || echo "Unable to complete update, contact Pi-hole" && exit 1
-
- # Checks Pi-hole version > admin only > current local git repo version : returns string in format vX.X.X
- webVersion="$(/usr/local/bin/pihole -v -a -c)"
- # Checks Pi-hole version > admin only > current local git repo version : returns string in format vX.X.X
- piholeVersion="$(/usr/local/bin/pihole -v -p -c)"
- echo ":::"
- echo "::: Pi-hole version is now at ${piholeVersion}"
- echo "::: If you had made any changes in '/etc/.pihole', they have been stashed using 'git stash'"
- echo ":::"
- echo "::: Pi-hole version is now at ${piholeVersion}"
- echo "::: If you had made any changes in '/etc/.pihole', they have been stashed using 'git stash'"
- echo ""
-fi
+main
From 34482c5ed62e711e40deec5c71467c8ac2c09970 Mon Sep 17 00:00:00 2001
From: Dan Schaper
Date: Wed, 2 Nov 2016 03:09:59 -0700
Subject: [PATCH 037/228] Modified `is_repo`
---
advanced/Scripts/update.sh | 11 +++++------
1 file changed, 5 insertions(+), 6 deletions(-)
diff --git a/advanced/Scripts/update.sh b/advanced/Scripts/update.sh
index dfabccb0..b8514c1c 100644
--- a/advanced/Scripts/update.sh
+++ b/advanced/Scripts/update.sh
@@ -22,16 +22,15 @@ readonly PI_HOLE_FILES_DIR="/etc/.pihole"
is_repo() {
# Use git to check if directory is currently under VCS
local directory="${1}"
- local gitRepo=0
echo -n "::: Checking if ${directory} is a repo... "
- cd "${directory}" &> /dev/null || return 1
- if [[ $(git status --short &> /dev/null) ]]; then
+ cd "${directory}" &> /dev/null || false
+ if [[ $(git status --short &> /dev/null) -eq 0 ]]; then
echo "OK"
+ true
else
echo "not found!"
- gitRepo=1
+ false
fi;
- return ${gitRepo}
}
make_repo() {
@@ -65,7 +64,7 @@ getGitFiles() {
main() {
- is_repo "${PI_HOLE_FILES_DIR}" &> /dev/null
+ is_repo "${PI_HOLE_FILES_DIR}"
if [[ $? -eq 1 ]]; then #This is unlikely
echo "::: Critical Error: Pi-Hole repo missing from system!"
echo "::: Please re-run install script from https://github.com/pi-hole/pi-hole"
From 9ec5bbd5605f3a5c1982e2f7eaf6bd1bc565ba17 Mon Sep 17 00:00:00 2001
From: Dan Schaper
Date: Wed, 2 Nov 2016 03:38:35 -0700
Subject: [PATCH 038/228] Actually get `is_repo` to return a value and have it
expected.
---
advanced/Scripts/update.sh | 16 +++++-----------
1 file changed, 5 insertions(+), 11 deletions(-)
diff --git a/advanced/Scripts/update.sh b/advanced/Scripts/update.sh
index b8514c1c..1fce075f 100644
--- a/advanced/Scripts/update.sh
+++ b/advanced/Scripts/update.sh
@@ -22,18 +22,12 @@ readonly PI_HOLE_FILES_DIR="/etc/.pihole"
is_repo() {
# Use git to check if directory is currently under VCS
local directory="${1}"
- echo -n "::: Checking if ${directory} is a repo... "
cd "${directory}" &> /dev/null || false
- if [[ $(git status --short &> /dev/null) -eq 0 ]]; then
- echo "OK"
- true
- else
- echo "not found!"
- false
- fi;
+ $(git status --short &> /dev/null)
+ return
}
-make_repo() {
+ make_repo() {
# Remove the non-repod interface and clone the interface
echo -n "::: Cloning $2 into $1..."
rm -rf "${1}"
@@ -65,14 +59,14 @@ getGitFiles() {
main() {
is_repo "${PI_HOLE_FILES_DIR}"
- if [[ $? -eq 1 ]]; then #This is unlikely
+ if [[ $? -ne 0 ]]; then #This is unlikely
echo "::: Critical Error: Pi-Hole repo missing from system!"
echo "::: Please re-run install script from https://github.com/pi-hole/pi-hole"
exit 1;
fi
is_repo "${ADMIN_INTERFACE_DIR}" &> /dev/null
- if [[ $? -eq 1 ]]; then #This is unlikely
+ if [[ $? -ne 0 ]]; then #This is unlikely
echo "::: Critical Error: Pi-Hole repo missing from system!"
echo "::: Please re-run install script from https://github.com/pi-hole/pi-hole"
exit 1;
From 035e4bf727e14961b0b45de78d7b1ebe5cc1f81e Mon Sep 17 00:00:00 2001
From: Dan Schaper
Date: Wed, 2 Nov 2016 03:55:04 -0700
Subject: [PATCH 039/228] Move value checks to `if` calls.
---
advanced/Scripts/update.sh | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/advanced/Scripts/update.sh b/advanced/Scripts/update.sh
index 1fce075f..74bd2e54 100644
--- a/advanced/Scripts/update.sh
+++ b/advanced/Scripts/update.sh
@@ -58,15 +58,13 @@ getGitFiles() {
main() {
- is_repo "${PI_HOLE_FILES_DIR}"
- if [[ $? -ne 0 ]]; then #This is unlikely
+ if ! is_repo "${PI_HOLE_FILES_DIR}"; then #This is unlikely
echo "::: Critical Error: Pi-Hole repo missing from system!"
echo "::: Please re-run install script from https://github.com/pi-hole/pi-hole"
exit 1;
fi
- is_repo "${ADMIN_INTERFACE_DIR}" &> /dev/null
- if [[ $? -ne 0 ]]; then #This is unlikely
+ if ! $(is_repo "${ADMIN_INTERFACE_DIR}"); then #This is unlikely
echo "::: Critical Error: Pi-Hole repo missing from system!"
echo "::: Please re-run install script from https://github.com/pi-hole/pi-hole"
exit 1;
From d4dccfdb2d33953290ffb01968d901410888ea1f Mon Sep 17 00:00:00 2001
From: Promofaux
Date: Mon, 31 Oct 2016 21:38:48 +0000
Subject: [PATCH 040/228] Cherry pick 229439c
---
automated install/basic-install.sh | 38 ++++++++++++++++++++++++++++++
1 file changed, 38 insertions(+)
diff --git a/automated install/basic-install.sh b/automated install/basic-install.sh
index 49329f5a..b3b34757 100755
--- a/automated install/basic-install.sh
+++ b/automated install/basic-install.sh
@@ -537,6 +537,29 @@ setDNS() {
fi
}
+setLogging() {
+ LogToggleCommand=(whiptail --separate-output --radiolist "Select Logging mode:" ${r} ${c} 6)
+ DNSChooseOptions=("On (Reccomended)" "" on
+ Off "" off)
+ DNSchoices=$("${DNSChooseCmd[@]}" "${DNSChooseOptions[@]}" 2>&1 >/dev/tty)
+ if [[ $? = 0 ]];then
+ case ${DNSchoices} in
+ "On (Reccomended)")
+ echo "::: Logging On."
+ queryLogging=true
+ ;;
+ Off)
+ echo "::: Logging Off."
+ queryLogging=false
+ ;;
+ esac
+ else
+ echo "::: Cancel selected. Exiting..."
+ exit 1
+ fi
+}
+
+
version_check_dnsmasq() {
# Check if /etc/dnsmasq.conf is from pihole. If so replace with an original and install new in .d directory
local dnsmasq_conf="/etc/dnsmasq.conf"
@@ -611,6 +634,14 @@ version_check_dnsmasq() {
fi
sed -i 's/^#conf-dir=\/etc\/dnsmasq.d$/conf-dir=\/etc\/dnsmasq.d/' ${dnsmasq_conf}
+
+ if [[ "${queryLogging}" == false ]] ; then
+ #Disable Logging
+ sed -i 's/^log-queries/#log-queries/' ${dnsmasq_pihole_01_location}
+ else
+ #Enable Logging
+ sed -i 's/^#log-queries/log-queries/' ${dnsmasq_pihole_01_location}
+ fi
}
remove_legacy_scripts() {
@@ -855,6 +886,7 @@ finalExports() {
echo "IPv6_address=${IPv6_address}"
echo "piholeDNS1=${piholeDNS1}"
echo "piholeDNS2=${piholeDNS2}"
+ echo "queryLogging=${queryLogging}"
}>> "${setupVars}"
}
@@ -1034,6 +1066,12 @@ main() {
use4andor6
# Decide what upstream DNS Servers to use
setDNS
+ # Let the user decide if they want query logging enabled...
+ setLogging
+
+ # Install packages used by the Pi-hole
+ install_dependent_packages PIHOLE_DEPS[@]
+
# Install and log everything to a file
installPihole | tee ${tmpLog}
else
From 617a1477069e6cc2b806d801450ebf8ac0744bc4 Mon Sep 17 00:00:00 2001
From: Promofaux
Date: Mon, 31 Oct 2016 21:40:20 +0000
Subject: [PATCH 041/228] Wording adjustment
---
automated install/basic-install.sh | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/automated install/basic-install.sh b/automated install/basic-install.sh
index b3b34757..6d66fb89 100755
--- a/automated install/basic-install.sh
+++ b/automated install/basic-install.sh
@@ -538,13 +538,13 @@ setDNS() {
}
setLogging() {
- LogToggleCommand=(whiptail --separate-output --radiolist "Select Logging mode:" ${r} ${c} 6)
+ LogToggleCommand=(whiptail --separate-output --radiolist "Do you want to log queries?\n (Disabling will render graphs on the Admin page useless):" ${r} ${c} 6)
DNSChooseOptions=("On (Reccomended)" "" on
Off "" off)
DNSchoices=$("${DNSChooseCmd[@]}" "${DNSChooseOptions[@]}" 2>&1 >/dev/tty)
if [[ $? = 0 ]];then
case ${DNSchoices} in
- "On (Reccomended)")
+ "On (Recommended)")
echo "::: Logging On."
queryLogging=true
;;
From 1d21b0da9a83fd288741857c0704ac8618661e5d Mon Sep 17 00:00:00 2001
From: Promofaux
Date: Mon, 31 Oct 2016 22:02:20 +0000
Subject: [PATCH 042/228] enable or disable logging from pihole command
---
pihole | 23 +++++++++++++++++++++++
1 file changed, 23 insertions(+)
diff --git a/pihole b/pihole
index 4b197d12..55d82569 100755
--- a/pihole
+++ b/pihole
@@ -125,6 +125,27 @@ piholeEnable() {
restartDNS
}
+piholeLogging() {
+
+ shift
+
+ if [[ "${1}" == "off" ]] ; then
+ #Disable Logging
+ sed -i 's/^log-queries/#log-queries/' /etc/dnsmasq.d/01-pihole.conf
+ sed -i 's/^queryLogging=true/queryLogging=false/' /etc/pihole/setupVars.conf
+ echo "::: Logging has been disabled!"
+ elif [[ "${1}" == "on" ]] ; then
+ #Enable logging
+ sed -i 's/^#log-queries/log-queries/' /etc/dnsmasq.d/01-pihole.conf
+ sed -i 's/^queryLogging=false/queryLogging=true/' /etc/pihole/setupVars.conf
+ echo "::: Logging has been enabled!"
+ else
+ echo "::: Invalid option passed, please pass 'on' or 'off'"
+ exit 1
+ fi
+ restartDNS
+}
+
piholeStatus() {
if [[ $(cat /etc/dnsmasq.d/01-pihole.conf | grep "#addn-hosts=/") ]] ; then
#list is commented out
@@ -173,6 +194,7 @@ helpFunc() {
::: -h, help Show this help dialog
::: -v, version Show current versions
::: -q, query Query the adlists for a specific domain
+::: -l, logging Enable or Disable logging (pass 'on' or 'off')
::: uninstall Uninstall Pi-Hole from your system :(!
::: status Is Pi-Hole Enabled or Disabled
::: enable Enable Pi-Hole DNS Blocking
@@ -200,6 +222,7 @@ case "${1}" in
"-h" | "help" ) helpFunc;;
"-v" | "version" ) versionFunc "$@";;
"-q" | "query" ) queryFunc "$@";;
+ "-l" | "logging" ) piholeLogging "$@";;
"uninstall" ) uninstallFunc;;
"enable" ) piholeEnable 1;;
"disable" ) piholeEnable 0;;
From bbc09ed31347dbf1a58487d6df9befadb33c1e92 Mon Sep 17 00:00:00 2001
From: Dan Schaper
Date: Mon, 31 Oct 2016 16:48:02 -0700
Subject: [PATCH 043/228] Swap variable names.
---
automated install/basic-install.sh | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/automated install/basic-install.sh b/automated install/basic-install.sh
index 6d66fb89..3abaca7c 100755
--- a/automated install/basic-install.sh
+++ b/automated install/basic-install.sh
@@ -539,11 +539,11 @@ setDNS() {
setLogging() {
LogToggleCommand=(whiptail --separate-output --radiolist "Do you want to log queries?\n (Disabling will render graphs on the Admin page useless):" ${r} ${c} 6)
- DNSChooseOptions=("On (Reccomended)" "" on
+ LogChooseOptions=("On (Reccomended)" "" on
Off "" off)
- DNSchoices=$("${DNSChooseCmd[@]}" "${DNSChooseOptions[@]}" 2>&1 >/dev/tty)
+ LogChoices=$("${LogToggleCommand[@]}" "${LogChooseOptions[@]}" 2>&1 >/dev/tty)
if [[ $? = 0 ]];then
- case ${DNSchoices} in
+ case ${LogChoices} in
"On (Recommended)")
echo "::: Logging On."
queryLogging=true
@@ -554,6 +554,7 @@ setLogging() {
;;
esac
else
+ # Well never see this, `set -e` kicked in already and dropped us.
echo "::: Cancel selected. Exiting..."
exit 1
fi
From d695c5972f0c84046281bf7c9b051984a4744cd4 Mon Sep 17 00:00:00 2001
From: Dan Schaper
Date: Mon, 31 Oct 2016 16:48:58 -0700
Subject: [PATCH 044/228] `local` variables just to be safe and make sure they
stay in this function.
---
automated install/basic-install.sh | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/automated install/basic-install.sh b/automated install/basic-install.sh
index 3abaca7c..0ee45e77 100755
--- a/automated install/basic-install.sh
+++ b/automated install/basic-install.sh
@@ -538,6 +538,10 @@ setDNS() {
}
setLogging() {
+ local LogToggleCommand
+ local LogChooseOptions
+ local LogChoices
+
LogToggleCommand=(whiptail --separate-output --radiolist "Do you want to log queries?\n (Disabling will render graphs on the Admin page useless):" ${r} ${c} 6)
LogChooseOptions=("On (Reccomended)" "" on
Off "" off)
From c07d7165ab31b612bb6de34ef8ac4ebffa51f215 Mon Sep 17 00:00:00 2001
From: Dan Schaper
Date: Mon, 31 Oct 2016 16:49:40 -0700
Subject: [PATCH 045/228] Global variables CAP'ed
---
automated install/basic-install.sh | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/automated install/basic-install.sh b/automated install/basic-install.sh
index 0ee45e77..028e20a4 100755
--- a/automated install/basic-install.sh
+++ b/automated install/basic-install.sh
@@ -550,11 +550,11 @@ setLogging() {
case ${LogChoices} in
"On (Recommended)")
echo "::: Logging On."
- queryLogging=true
+ QUERYLOGGING=true
;;
Off)
echo "::: Logging Off."
- queryLogging=false
+ QUERYLOGGING=false
;;
esac
else
@@ -640,7 +640,7 @@ version_check_dnsmasq() {
sed -i 's/^#conf-dir=\/etc\/dnsmasq.d$/conf-dir=\/etc\/dnsmasq.d/' ${dnsmasq_conf}
- if [[ "${queryLogging}" == false ]] ; then
+ if [[ "${QUERYLOGGING}" == false ]] ; then
#Disable Logging
sed -i 's/^log-queries/#log-queries/' ${dnsmasq_pihole_01_location}
else
@@ -891,7 +891,7 @@ finalExports() {
echo "IPv6_address=${IPv6_address}"
echo "piholeDNS1=${piholeDNS1}"
echo "piholeDNS2=${piholeDNS2}"
- echo "queryLogging=${queryLogging}"
+ echo "queryLogging=${QUERYLOGGING}"
}>> "${setupVars}"
}
From 9a1876571b11a55ac4c387d5c1a890f940548b3d Mon Sep 17 00:00:00 2001
From: Dan Schaper
Date: Mon, 31 Oct 2016 16:55:10 -0700
Subject: [PATCH 046/228] Prototype `whiptails` so they don't fall to shell.
Need to do this to all functions.
---
automated install/basic-install.sh | 8 +-------
1 file changed, 1 insertion(+), 7 deletions(-)
diff --git a/automated install/basic-install.sh b/automated install/basic-install.sh
index 028e20a4..ddb83e3b 100755
--- a/automated install/basic-install.sh
+++ b/automated install/basic-install.sh
@@ -545,8 +545,7 @@ setLogging() {
LogToggleCommand=(whiptail --separate-output --radiolist "Do you want to log queries?\n (Disabling will render graphs on the Admin page useless):" ${r} ${c} 6)
LogChooseOptions=("On (Reccomended)" "" on
Off "" off)
- LogChoices=$("${LogToggleCommand[@]}" "${LogChooseOptions[@]}" 2>&1 >/dev/tty)
- if [[ $? = 0 ]];then
+ LogChoices=$("${LogToggleCommand[@]}" "${LogChooseOptions[@]}" 2>&1 >/dev/tty) || (echo "::: Cancel selected. Exiting..." && exit 1)
case ${LogChoices} in
"On (Recommended)")
echo "::: Logging On."
@@ -557,11 +556,6 @@ setLogging() {
QUERYLOGGING=false
;;
esac
- else
- # Well never see this, `set -e` kicked in already and dropped us.
- echo "::: Cancel selected. Exiting..."
- exit 1
- fi
}
From a2903b6e6345d71d6b95734459cfaab02c845e58 Mon Sep 17 00:00:00 2001
From: Adam Warner
Date: Tue, 1 Nov 2016 09:32:57 +0000
Subject: [PATCH 047/228] Consistency
---
automated install/basic-install.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/automated install/basic-install.sh b/automated install/basic-install.sh
index ddb83e3b..c649d448 100755
--- a/automated install/basic-install.sh
+++ b/automated install/basic-install.sh
@@ -885,7 +885,7 @@ finalExports() {
echo "IPv6_address=${IPv6_address}"
echo "piholeDNS1=${piholeDNS1}"
echo "piholeDNS2=${piholeDNS2}"
- echo "queryLogging=${QUERYLOGGING}"
+ echo "QUERYLOGGING=${QUERYLOGGING}"
}>> "${setupVars}"
}
From b723714c0c1f4e7f536c4ed0c5be72ee3c2530e2 Mon Sep 17 00:00:00 2001
From: Adam Warner
Date: Tue, 1 Nov 2016 09:33:39 +0000
Subject: [PATCH 048/228] Convention :
https://google.github.io/styleguide/shell.xml?showone=Constants_and_Environment_Variable_Names#Constants_and_Environment_Variable_Names
---
automated install/basic-install.sh | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/automated install/basic-install.sh b/automated install/basic-install.sh
index c649d448..19c71818 100755
--- a/automated install/basic-install.sh
+++ b/automated install/basic-install.sh
@@ -549,11 +549,11 @@ setLogging() {
case ${LogChoices} in
"On (Recommended)")
echo "::: Logging On."
- QUERYLOGGING=true
+ QUERY_LOGGING=true
;;
Off)
echo "::: Logging Off."
- QUERYLOGGING=false
+ QUERY_LOGGING=false
;;
esac
}
@@ -634,7 +634,7 @@ version_check_dnsmasq() {
sed -i 's/^#conf-dir=\/etc\/dnsmasq.d$/conf-dir=\/etc\/dnsmasq.d/' ${dnsmasq_conf}
- if [[ "${QUERYLOGGING}" == false ]] ; then
+ if [[ "${QUERY_LOGGING}" == false ]] ; then
#Disable Logging
sed -i 's/^log-queries/#log-queries/' ${dnsmasq_pihole_01_location}
else
@@ -885,7 +885,7 @@ finalExports() {
echo "IPv6_address=${IPv6_address}"
echo "piholeDNS1=${piholeDNS1}"
echo "piholeDNS2=${piholeDNS2}"
- echo "QUERYLOGGING=${QUERYLOGGING}"
+ echo "QUERY_LOGGING=${QUERY_LOGGING}"
}>> "${setupVars}"
}
From 82e7de2aaad483d22c2dab6750d1cc04c049d3ed Mon Sep 17 00:00:00 2001
From: Adam Warner
Date: Tue, 1 Nov 2016 09:36:59 +0000
Subject: [PATCH 049/228] Account for variable name changes
---
automated install/basic-install.sh | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/automated install/basic-install.sh b/automated install/basic-install.sh
index 19c71818..77f14dc4 100755
--- a/automated install/basic-install.sh
+++ b/automated install/basic-install.sh
@@ -914,10 +914,16 @@ installPihole() {
runGravity
}
-updatePihole() {
+accountForRefactor() {
+ # At some point in the future this list can be pruned, for now we'll need it to ensure updates don't break.
# Refactoring of install script has changed the name of a couple of variables. Sort them out here.
sed -i 's/IPv4addr/IPv4_address/g' ${setupVars}
sed -i 's/piholeIPv6/IPv6_address/g' ${setupVars}
+
+}
+
+updatePihole() {
+ accountForRefactor
# Source ${setupVars} for use in the rest of the functions.
. ${setupVars}
# Install base files and web interface
From edd00e8e708419e43b6fbf545615532658b9c30c Mon Sep 17 00:00:00 2001
From: Adam Warner
Date: Tue, 1 Nov 2016 09:45:22 +0000
Subject: [PATCH 050/228] consistency
---
automated install/basic-install.sh | 164 +++++++++++++++--------------
1 file changed, 86 insertions(+), 78 deletions(-)
diff --git a/automated install/basic-install.sh b/automated install/basic-install.sh
index 77f14dc4..7020eeff 100755
--- a/automated install/basic-install.sh
+++ b/automated install/basic-install.sh
@@ -29,8 +29,8 @@ PI_HOLE_LOCAL_REPO="/etc/.pihole"
PI_HOLE_FILES=(chronometer list piholeDebug piholeLogFlush setupLCD update version)
useUpdateVars=false
-IPv4_address=""
-IPv6_address=""
+IPV4_ADDRESS=""
+IPV6_ADDRESS=""
# Find the rows and columns will default to 80x24 is it can not be detected
screen_size=$(stty size 2>/dev/null || echo 24 80)
@@ -183,7 +183,7 @@ getGitFiles() {
find_IPv4_information() {
# Find IP used to route to outside world
IPv4dev=$(ip route get 8.8.8.8 | awk '{for(i=1;i<=NF;i++)if($i~/dev/)print $(i+1)}')
- IPv4_address=$(ip -o -f inet addr show dev "$IPv4dev" | awk '{print $4}' | awk 'END {print}')
+ IPV4_ADDRESS=$(ip -o -f inet addr show dev "$IPv4dev" | awk '{print $4}' | awk 'END {print}')
IPv4gw=$(ip route get 8.8.8.8 | awk '{print $3}')
}
@@ -265,8 +265,8 @@ chooseInterface() {
chooseInterfaceOptions=$("${chooseInterfaceCmd[@]}" "${interfacesArray[@]}" 2>&1 >/dev/tty)
if [[ $? = 0 ]]; then
for desiredInterface in ${chooseInterfaceOptions}; do
- piholeInterface=${desiredInterface}
- echo "::: Using interface: $piholeInterface"
+ PIHOLE_INTERFACE=${desiredInterface}
+ echo "::: Using interface: $PIHOLE_INTERFACE"
done
else
echo "::: Cancel selected, exiting...."
@@ -276,8 +276,8 @@ chooseInterface() {
useIPv6dialog() {
# Show the IPv6 address used for blocking
- IPv6_address=$(ip -6 route get 2001:4860:4860::8888 | awk -F " " '{ for(i=1;i<=NF;i++) if ($i == "src") print $(i+1) }')
- whiptail --msgbox --backtitle "IPv6..." --title "IPv6 Supported" "$IPv6_address will be used to block ads." ${r} ${c}
+ IPV6_ADDRESS=$(ip -6 route get 2001:4860:4860::8888 | awk -F " " '{ for(i=1;i<=NF;i++) if ($i == "src") print $(i+1) }')
+ whiptail --msgbox --backtitle "IPv6..." --title "IPv6 Supported" "$IPV6_ADDRESS will be used to block ads." ${r} ${c}
}
@@ -305,8 +305,8 @@ use4andor6() {
if [[ ${useIPv6} ]]; then
useIPv6dialog
fi
- echo "::: IPv4 address: ${IPv4_address}"
- echo "::: IPv6 address: ${IPv6_address}"
+ echo "::: IPv4 address: ${IPV4_ADDRESS}"
+ echo "::: IPv6 address: ${IPV6_ADDRESS}"
if [ ! ${useIPv4} ] && [ ! ${useIPv6} ]; then
echo "::: Cannot continue, neither IPv4 or IPv6 selected"
echo "::: Exiting"
@@ -321,7 +321,7 @@ use4andor6() {
getStaticIPv4Settings() {
# Ask if the user wants to use DHCP settings as their static IP
if (whiptail --backtitle "Calibrating network interface" --title "Static IP Address" --yesno "Do you want to use your current network settings as a static address?
- IP address: ${IPv4_address}
+ IP address: ${IPV4_ADDRESS}
Gateway: ${IPv4gw}" ${r} ${c}); then
# If they choose yes, let the user know that the IP address will not be available via DHCP and may cause a conflict.
whiptail --msgbox --backtitle "IP information" --title "FYI: IP Conflict" "It is possible your router could still try to assign this IP to a device, which would cause a conflict. But in most cases the router is smart enough to not do that.
@@ -334,16 +334,16 @@ It is also possible to use a DHCP reservation, but if you are going to do that,
# Start a loop to let the user enter their information with the chance to go back and edit it if necessary
until [[ ${ipSettingsCorrect} = True ]]; do
# Ask for the IPv4 address
- IPv4_address=$(whiptail --backtitle "Calibrating network interface" --title "IPv4 address" --inputbox "Enter your desired IPv4 address" ${r} ${c} "${IPv4_address}" 3>&1 1>&2 2>&3)
+ IPV4_ADDRESS=$(whiptail --backtitle "Calibrating network interface" --title "IPv4 address" --inputbox "Enter your desired IPv4 address" ${r} ${c} "${IPV4_ADDRESS}" 3>&1 1>&2 2>&3)
if [[ $? = 0 ]]; then
- echo "::: Your static IPv4 address: ${IPv4_address}"
+ echo "::: Your static IPv4 address: ${IPV4_ADDRESS}"
# Ask for the gateway
IPv4gw=$(whiptail --backtitle "Calibrating network interface" --title "IPv4 gateway (router)" --inputbox "Enter your desired IPv4 default gateway" ${r} ${c} "${IPv4gw}" 3>&1 1>&2 2>&3)
if [[ $? = 0 ]]; then
echo "::: Your static IPv4 gateway: ${IPv4gw}"
# Give the user a chance to review their settings before moving on
if (whiptail --backtitle "Calibrating network interface" --title "Static IP Address" --yesno "Are these settings correct?
- IP address: ${IPv4_address}
+ IP address: ${IPV4_ADDRESS}
Gateway: ${IPv4gw}" ${r} ${c}); then
# After that's done, the loop ends and we move on
ipSettingsCorrect=True
@@ -370,8 +370,8 @@ It is also possible to use a DHCP reservation, but if you are going to do that,
setDHCPCD() {
# Append these lines to dhcpcd.conf to enable a static IP
- echo "## interface ${piholeInterface}
- static ip_address=${IPv4_address}
+ echo "## interface ${PIHOLE_INTERFACE}
+ static ip_address=${IPV4_ADDRESS}
static routers=${IPv4gw}
static domain_name_servers=${IPv4gw}" | tee -a /etc/dhcpcd.conf >/dev/null
}
@@ -382,45 +382,45 @@ setStaticIPv4() {
local CIDR
if [[ -f /etc/dhcpcd.conf ]]; then
# Debian Family
- if grep -q "${IPv4_address}" /etc/dhcpcd.conf; then
+ if grep -q "${IPV4_ADDRESS}" /etc/dhcpcd.conf; then
echo "::: Static IP already configured"
else
setDHCPCD
- ip addr replace dev "${piholeInterface}" "${IPv4_address}"
+ ip addr replace dev "${PIHOLE_INTERFACE}" "${IPV4_ADDRESS}"
echo ":::"
- echo "::: Setting IP to ${IPv4_address}. You may need to restart after the install is complete."
+ echo "::: Setting IP to ${IPV4_ADDRESS}. You may need to restart after the install is complete."
echo ":::"
fi
- elif [[ -f /etc/sysconfig/network-scripts/ifcfg-${piholeInterface} ]];then
+ elif [[ -f /etc/sysconfig/network-scripts/ifcfg-${PIHOLE_INTERFACE} ]];then
# Fedora Family
- IFCFG_FILE=/etc/sysconfig/network-scripts/ifcfg-${piholeInterface}
- if grep -q "${IPv4_address}" "${IFCFG_FILE}"; then
+ IFCFG_FILE=/etc/sysconfig/network-scripts/ifcfg-${PIHOLE_INTERFACE}
+ if grep -q "${IPV4_ADDRESS}" "${IFCFG_FILE}"; then
echo "::: Static IP already configured"
else
- IPADDR=$(echo "${IPv4_address}" | cut -f1 -d/)
- CIDR=$(echo "${IPv4_address}" | cut -f2 -d/)
+ IPADDR=$(echo "${IPV4_ADDRESS}" | cut -f1 -d/)
+ CIDR=$(echo "${IPV4_ADDRESS}" | cut -f2 -d/)
# Backup existing interface configuration:
cp "${IFCFG_FILE}" "${IFCFG_FILE}".pihole.orig
# Build Interface configuration file:
{
echo "# Configured via Pi-Hole installer"
- echo "DEVICE=$piholeInterface"
+ echo "DEVICE=$PIHOLE_INTERFACE"
echo "BOOTPROTO=none"
echo "ONBOOT=yes"
echo "IPADDR=$IPADDR"
echo "PREFIX=$CIDR"
echo "GATEWAY=$IPv4gw"
- echo "DNS1=$piholeDNS1"
- echo "DNS2=$piholeDNS2"
+ echo "DNS1=$PIHOLE_DNS_1"
+ echo "DNS2=$PIHOLE_DNS_2"
echo "USERCTL=no"
}>> "${IFCFG_FILE}"
- ip addr replace dev "${piholeInterface}" "${IPv4_address}"
+ ip addr replace dev "${PIHOLE_INTERFACE}" "${IPV4_ADDRESS}"
if [ -x "$(command -v nmcli)" ];then
# Tell NetworkManager to read our new sysconfig file
nmcli con load "${IFCFG_FILE}" > /dev/null
fi
echo ":::"
- echo "::: Setting IP to ${IPv4_address}. You may need to restart after the install is complete."
+ echo "::: Setting IP to ${IPV4_ADDRESS}. You may need to restart after the install is complete."
echo ":::"
fi
else
@@ -458,70 +458,70 @@ setDNS() {
case ${DNSchoices} in
Google)
echo "::: Using Google DNS servers."
- piholeDNS1="8.8.8.8"
- piholeDNS2="8.8.4.4"
+ PIHOLE_DNS_1="8.8.8.8"
+ PIHOLE_DNS_2="8.8.4.4"
;;
OpenDNS)
echo "::: Using OpenDNS servers."
- piholeDNS1="208.67.222.222"
- piholeDNS2="208.67.220.220"
+ PIHOLE_DNS_1="208.67.222.222"
+ PIHOLE_DNS_2="208.67.220.220"
;;
Level3)
echo "::: Using Level3 servers."
- piholeDNS1="4.2.2.1"
- piholeDNS2="4.2.2.2"
+ PIHOLE_DNS_1="4.2.2.1"
+ PIHOLE_DNS_2="4.2.2.2"
;;
Norton)
echo "::: Using Norton ConnectSafe servers."
- piholeDNS1="199.85.126.10"
- piholeDNS2="199.85.127.10"
+ PIHOLE_DNS_1="199.85.126.10"
+ PIHOLE_DNS_2="199.85.127.10"
;;
Comodo)
echo "::: Using Comodo Secure servers."
- piholeDNS1="8.26.56.26"
- piholeDNS2="8.20.247.20"
+ PIHOLE_DNS_1="8.26.56.26"
+ PIHOLE_DNS_2="8.20.247.20"
;;
Custom)
until [[ ${DNSSettingsCorrect} = True ]]; do
strInvalid="Invalid"
- if [ ! ${piholeDNS1} ]; then
- if [ ! ${piholeDNS2} ]; then
+ if [ ! ${PIHOLE_DNS_1} ]; then
+ if [ ! ${PIHOLE_DNS_2} ]; then
prePopulate=""
else
- prePopulate=", ${piholeDNS2}"
+ prePopulate=", ${PIHOLE_DNS_2}"
fi
- elif [ ${piholeDNS1} ] && [ ! ${piholeDNS2} ]; then
- prePopulate="${piholeDNS1}"
- elif [ ${piholeDNS1} ] && [ ${piholeDNS2} ]; then
- prePopulate="${piholeDNS1}, ${piholeDNS2}"
+ elif [ ${PIHOLE_DNS_1} ] && [ ! ${PIHOLE_DNS_2} ]; then
+ prePopulate="${PIHOLE_DNS_1}"
+ elif [ ${PIHOLE_DNS_1} ] && [ ${PIHOLE_DNS_2} ]; then
+ prePopulate="${PIHOLE_DNS_1}, ${PIHOLE_DNS_2}"
fi
piholeDNS=$(whiptail --backtitle "Specify Upstream DNS Provider(s)" --inputbox "Enter your desired upstream DNS provider(s), seperated by a comma.\n\nFor example '8.8.8.8, 8.8.4.4'" ${r} ${c} "${prePopulate}" 3>&1 1>&2 2>&3)
if [[ $? = 0 ]]; then
- piholeDNS1=$(echo "${piholeDNS}" | sed 's/[, \t]\+/,/g' | awk -F, '{print$1}')
- piholeDNS2=$(echo "${piholeDNS}" | sed 's/[, \t]\+/,/g' | awk -F, '{print$2}')
- if ! valid_ip "${piholeDNS1}" || [ ! "${piholeDNS1}" ]; then
- piholeDNS1=${strInvalid}
+ PIHOLE_DNS_1=$(echo "${piholeDNS}" | sed 's/[, \t]\+/,/g' | awk -F, '{print$1}')
+ PIHOLE_DNS_2=$(echo "${piholeDNS}" | sed 's/[, \t]\+/,/g' | awk -F, '{print$2}')
+ if ! valid_ip "${PIHOLE_DNS_1}" || [ ! "${PIHOLE_DNS_1}" ]; then
+ PIHOLE_DNS_1=${strInvalid}
fi
- if ! valid_ip "${piholeDNS2}" && [ "${piholeDNS2}" ]; then
- piholeDNS2=${strInvalid}
+ if ! valid_ip "${PIHOLE_DNS_2}" && [ "${PIHOLE_DNS_2}" ]; then
+ PIHOLE_DNS_2=${strInvalid}
fi
else
echo "::: Cancel selected, exiting...."
exit 1
fi
- if [[ ${piholeDNS1} == "${strInvalid}" ]] || [[ ${piholeDNS2} == "${strInvalid}" ]]; then
- whiptail --msgbox --backtitle "Invalid IP" --title "Invalid IP" "One or both entered IP addresses were invalid. Please try again.\n\n DNS Server 1: $piholeDNS1\n DNS Server 2: ${piholeDNS2}" ${r} ${c}
- if [[ ${piholeDNS1} == "${strInvalid}" ]]; then
- piholeDNS1=""
+ if [[ ${PIHOLE_DNS_1} == "${strInvalid}" ]] || [[ ${PIHOLE_DNS_2} == "${strInvalid}" ]]; then
+ whiptail --msgbox --backtitle "Invalid IP" --title "Invalid IP" "One or both entered IP addresses were invalid. Please try again.\n\n DNS Server 1: $PIHOLE_DNS_1\n DNS Server 2: ${PIHOLE_DNS_2}" ${r} ${c}
+ if [[ ${PIHOLE_DNS_1} == "${strInvalid}" ]]; then
+ PIHOLE_DNS_1=""
fi
- if [[ ${piholeDNS2} == "${strInvalid}" ]]; then
- piholeDNS2=""
+ if [[ ${PIHOLE_DNS_2} == "${strInvalid}" ]]; then
+ PIHOLE_DNS_2=""
fi
DNSSettingsCorrect=False
else
- if (whiptail --backtitle "Specify Upstream DNS Provider(s)" --title "Upstream DNS Provider(s)" --yesno "Are these settings correct?\n DNS Server 1: $piholeDNS1\n DNS Server 2: ${piholeDNS2}" ${r} ${c}); then
+ if (whiptail --backtitle "Specify Upstream DNS Provider(s)" --title "Upstream DNS Provider(s)" --yesno "Are these settings correct?\n DNS Server 1: $PIHOLE_DNS_1\n DNS Server 2: ${PIHOLE_DNS_2}" ${r} ${c}); then
DNSSettingsCorrect=True
else
# If the settings are wrong, the loop continues
@@ -590,14 +590,14 @@ version_check_dnsmasq() {
echo -n "::: Copying 01-pihole.conf to /etc/dnsmasq.d/01-pihole.conf..."
cp ${dnsmasq_pihole_01_snippet} ${dnsmasq_pihole_01_location}
echo " done."
- sed -i "s/@INT@/$piholeInterface/" ${dnsmasq_pihole_01_location}
- if [[ "${piholeDNS1}" != "" ]]; then
- sed -i "s/@DNS1@/$piholeDNS1/" ${dnsmasq_pihole_01_location}
+ sed -i "s/@INT@/$PIHOLE_INTERFACE/" ${dnsmasq_pihole_01_location}
+ if [[ "${PIHOLE_DNS_1}" != "" ]]; then
+ sed -i "s/@DNS1@/$PIHOLE_DNS_1/" ${dnsmasq_pihole_01_location}
else
sed -i '/^server=@DNS1@/d' ${dnsmasq_pihole_01_location}
fi
- if [[ "${piholeDNS2}" != "" ]]; then
- sed -i "s/@DNS2@/$piholeDNS2/" ${dnsmasq_pihole_01_location}
+ if [[ "${PIHOLE_DNS_2}" != "" ]]; then
+ sed -i "s/@DNS2@/$PIHOLE_DNS_2/" ${dnsmasq_pihole_01_location}
else
sed -i '/^server=@DNS2@/d' ${dnsmasq_pihole_01_location}
fi
@@ -611,16 +611,16 @@ version_check_dnsmasq() {
fi
#Replace IPv4 and IPv6 tokens in 01-pihole.conf for pi.hole resolution.
- if [[ "${IPv4_address}" != "" ]]; then
- tmp=${IPv4_address%/*}
+ if [[ "${IPV4_ADDRESS}" != "" ]]; then
+ tmp=${IPV4_ADDRESS%/*}
sed -i "s/@IPv4@/$tmp/" ${dnsmasq_pihole_01_location}
else
sed -i '/^address=\/pi.hole\/@IPv4@/d' ${dnsmasq_pihole_01_location}
sed -i '/^address=\/@HOSTNAME@\/@IPv4@/d' ${dnsmasq_pihole_01_location}
fi
- if [[ "${IPv6_address}" != "" ]]; then
- sed -i "s/@IPv6@/$IPv6_address/" ${dnsmasq_pihole_01_location}
+ if [[ "${IPV6_ADDRESS}" != "" ]]; then
+ sed -i "s/@IPv6@/$IPV6_ADDRESS/" ${dnsmasq_pihole_01_location}
else
sed -i '/^address=\/pi.hole\/@IPv6@/d' ${dnsmasq_pihole_01_location}
sed -i '/^address=\/@HOSTNAME@\/@IPv6@/d' ${dnsmasq_pihole_01_location}
@@ -880,11 +880,11 @@ finalExports() {
rm ${setupVars}
fi
{
- echo "piholeInterface=${piholeInterface}"
- echo "IPv4_address=${IPv4_address}"
- echo "IPv6_address=${IPv6_address}"
- echo "piholeDNS1=${piholeDNS1}"
- echo "piholeDNS2=${piholeDNS2}"
+ echo "PIHOLE_INTERFACE=${PIHOLE_INTERFACE}"
+ echo "IPV4_ADDRESS=${IPV4_ADDRESS}"
+ echo "IPV6_ADDRESS=${IPV6_ADDRESS}"
+ echo "PIHOLE_DNS_1=${PIHOLE_DNS_1}"
+ echo "PIHOLE_DNS_2=${PIHOLE_DNS_2}"
echo "QUERY_LOGGING=${QUERY_LOGGING}"
}>> "${setupVars}"
}
@@ -916,10 +916,18 @@ installPihole() {
accountForRefactor() {
# At some point in the future this list can be pruned, for now we'll need it to ensure updates don't break.
+
# Refactoring of install script has changed the name of a couple of variables. Sort them out here.
sed -i 's/IPv4addr/IPv4_address/g' ${setupVars}
sed -i 's/piholeIPv6/IPv6_address/g' ${setupVars}
+ # Account for renaming of global variables.
+ sed -i 's/piholeInterface/PIHOLE_INTERFACE/g' ${setupVars}
+ sed -i 's/IPv4_address/IPV4_ADDRESS/g' ${setupVars}
+ sed -i 's/IPv6_address/IPV6_ADDRESS/g' ${setupVars}
+ sed -i 's/piholeDNS1/PIHOLE_DNS_1/g' ${setupVars}
+ sed -i 's/piholeDNS2/PIHOLE_DNS_2/g' ${setupVars}
+
}
updatePihole() {
@@ -961,13 +969,13 @@ displayFinalMessage() {
# Final completion message to user
whiptail --msgbox --backtitle "Make it so." --title "Installation Complete!" "Configure your devices to use the Pi-hole as their DNS server using:
-IPv4: ${IPv4_address%/*}
-IPv6: ${IPv6_address}
+IPv4: ${IPV4_ADDRESS%/*}
+IPv6: ${IPV6_ADDRESS}
If you set a new IP address, you should restart the Pi.
The install log is in /etc/pihole.
-View the web interface at http://pi.hole/admin or http://${IPv4_address%/*}/admin" ${r} ${c}
+View the web interface at http://pi.hole/admin or http://${IPV4_ADDRESS%/*}/admin" ${r} ${c}
}
update_dialogs() {
@@ -1101,8 +1109,8 @@ main() {
echo ":::"
if [[ "${useUpdateVars}" == false ]]; then
echo "::: Installation Complete! Configure your devices to use the Pi-hole as their DNS server using:"
- echo "::: ${IPv4_address%/*}"
- echo "::: ${IPv6_address}"
+ echo "::: ${IPV4_ADDRESS%/*}"
+ echo "::: ${IPV6_ADDRESS}"
echo ":::"
echo "::: If you set a new IP address, you should restart the Pi."
else
@@ -1111,7 +1119,7 @@ main() {
echo ":::"
echo "::: The install log is located at: /etc/pihole/install.log"
- echo "::: View the web interface at http://pi.hole/admin or http://${IPv4_address%/*}/admin"
+ echo "::: View the web interface at http://pi.hole/admin or http://${IPV4_ADDRESS%/*}/admin"
}
main "$@"
From c47c5e466f27b0bb14b88edcd6784ee1fc484971 Mon Sep 17 00:00:00 2001
From: Adam Warner
Date: Tue, 1 Nov 2016 09:48:21 +0000
Subject: [PATCH 051/228] consistency
---
pihole | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/pihole b/pihole
index 55d82569..478d995e 100755
--- a/pihole
+++ b/pihole
@@ -132,12 +132,12 @@ piholeLogging() {
if [[ "${1}" == "off" ]] ; then
#Disable Logging
sed -i 's/^log-queries/#log-queries/' /etc/dnsmasq.d/01-pihole.conf
- sed -i 's/^queryLogging=true/queryLogging=false/' /etc/pihole/setupVars.conf
+ sed -i 's/^QUERY_LOGGING=true/QUERY_LOGGING=false/' /etc/pihole/setupVars.conf
echo "::: Logging has been disabled!"
elif [[ "${1}" == "on" ]] ; then
#Enable logging
sed -i 's/^#log-queries/log-queries/' /etc/dnsmasq.d/01-pihole.conf
- sed -i 's/^queryLogging=false/queryLogging=true/' /etc/pihole/setupVars.conf
+ sed -i 's/^QUERY_LOGGING=false/QUERY_LOGGING=true/' /etc/pihole/setupVars.conf
echo "::: Logging has been enabled!"
else
echo "::: Invalid option passed, please pass 'on' or 'off'"
From 99057ed859cc973b4bd9fb4329ada73ee29289e5 Mon Sep 17 00:00:00 2001
From: Adam Warner
Date: Tue, 1 Nov 2016 09:47:31 +0000
Subject: [PATCH 052/228] Update var names from setupVars.conf in gravity.sh
---
gravity.sh | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/gravity.sh b/gravity.sh
index 112b42b6..15e157f6 100755
--- a/gravity.sh
+++ b/gravity.sh
@@ -44,7 +44,7 @@ else
fi
#Remove the /* from the end of the IPv4addr.
-IPv4_address=${IPv4_address%/*}
+IPV4_ADDRESS=${IPV4_ADDRESS%/*}
# Variables for various stages of downloading and formatting the list
basename=pihole
@@ -242,22 +242,22 @@ gravity_hostFormat() {
# Format domain list as "192.168.x.x domain.com"
echo "::: Formatting domains into a HOSTS file..."
# Check vars from setupVars.conf to see if we're using IPv4, IPv6, Or both.
- if [[ -n "${IPv4_address}" && -n "${IPv6_address}" ]];then
+ if [[ -n "${IPV4_ADDRESS}" && -n "${IPV6_ADDRESS}" ]];then
# Both IPv4 and IPv6
- cat ${piholeDir}/${eventHorizon} | awk -v ipv4addr="$IPv4_address" -v ipv6addr="$IPv6_address" '{sub(/\r$/,""); print ipv4addr" "$0"\n"ipv6addr" "$0}' >> ${piholeDir}/${accretionDisc}
+ cat ${piholeDir}/${eventHorizon} | awk -v ipv4addr="$IPV4_ADDRESS" -v ipv6addr="$IPV6_ADDRESS" '{sub(/\r$/,""); print ipv4addr" "$0"\n"ipv6addr" "$0}' >> ${piholeDir}/${accretionDisc}
- elif [[ -n "${IPv4_address}" && -z "${IPv6_address}" ]];then
+ elif [[ -n "${IPV4_ADDRESS}" && -z "${IPV6_ADDRESS}" ]];then
# Only IPv4
- cat ${piholeDir}/${eventHorizon} | awk -v ipv4addr="$IPv4_address" '{sub(/\r$/,""); print ipv4addr" "$0}' >> ${piholeDir}/${accretionDisc}
+ cat ${piholeDir}/${eventHorizon} | awk -v ipv4addr="$IPV4_ADDRESS" '{sub(/\r$/,""); print ipv4addr" "$0}' >> ${piholeDir}/${accretionDisc}
- elif [[ -z "${IPv4_address}" && -n "${IPv6_address}" ]];then
+ elif [[ -z "${IPV4_ADDRESS}" && -n "${IPV6_ADDRESS}" ]];then
# Only IPv6
- cat ${piholeDir}/${eventHorizon} | awk -v ipv6addr="$IPv6_address" '{sub(/\r$/,""); print ipv6addr" "$0}' >> ${piholeDir}/${accretionDisc}
+ cat ${piholeDir}/${eventHorizon} | awk -v ipv6addr="$IPV6_ADDRESS" '{sub(/\r$/,""); print ipv6addr" "$0}' >> ${piholeDir}/${accretionDisc}
- elif [[ -z "${IPv4_address}" && -z "${IPv6_address}" ]];then
+ elif [[ -z "${IPV4_ADDRESS}" && -z "${IPV6_ADDRESS}" ]];then
echo "::: No IP Values found! Please run 'pihole -r' and choose reconfigure to restore values"
exit 1
fi
From 354309fcad1be97f175bd87efab6c3329c8e5cae Mon Sep 17 00:00:00 2001
From: Adam Warner
Date: Tue, 1 Nov 2016 16:46:54 +0000
Subject: [PATCH 053/228] set QUERY_LOGGING default to true
---
automated install/basic-install.sh | 1 +
1 file changed, 1 insertion(+)
diff --git a/automated install/basic-install.sh b/automated install/basic-install.sh
index 7020eeff..79b823b1 100755
--- a/automated install/basic-install.sh
+++ b/automated install/basic-install.sh
@@ -31,6 +31,7 @@ useUpdateVars=false
IPV4_ADDRESS=""
IPV6_ADDRESS=""
+QUERY_LOGGING=true
# Find the rows and columns will default to 80x24 is it can not be detected
screen_size=$(stty size 2>/dev/null || echo 24 80)
From 3df2ef8587df0f3ca5381f9dc9a083681fe2e7b8 Mon Sep 17 00:00:00 2001
From: Adam Warner
Date: Wed, 2 Nov 2016 09:33:17 +0000
Subject: [PATCH 054/228] Cherry picking f6f6f6d, conflict fix
---
automated install/basic-install.sh | 25 +++++++++++++------------
1 file changed, 13 insertions(+), 12 deletions(-)
diff --git a/automated install/basic-install.sh b/automated install/basic-install.sh
index 79b823b1..c068fb39 100755
--- a/automated install/basic-install.sh
+++ b/automated install/basic-install.sh
@@ -932,18 +932,19 @@ accountForRefactor() {
}
updatePihole() {
- accountForRefactor
- # Source ${setupVars} for use in the rest of the functions.
- . ${setupVars}
- # Install base files and web interface
- installScripts
- installConfigs
- CreateLogFile
- configureSelinux
- installPiholeWeb
- installCron
- configureFirewall
- runGravity
+ accountForRefactor
+ # Source ${setupVars} for use in the rest of the functions.
+ . ${setupVars}
+ # Install base files and web interface
+ installScripts
+ installConfigs
+ CreateLogFile
+ configureSelinux
+ installPiholeWeb
+ installCron
+ configureFirewall
+ finalExports #re-export setupVars.conf to account for any new vars added in new versions
+ runGravity
}
configureSelinux() {
From f36e4ba336432e480d19e335db6846ef259fa275 Mon Sep 17 00:00:00 2001
From: Adam Warner
Date: Wed, 2 Nov 2016 09:35:48 +0000
Subject: [PATCH 055/228] Cherry picking 3f049fa79, conflict fix
---
pihole | 34 +++++++++++++++++-----------------
1 file changed, 17 insertions(+), 17 deletions(-)
diff --git a/pihole b/pihole
index 478d995e..ace0d9a9 100755
--- a/pihole
+++ b/pihole
@@ -126,24 +126,24 @@ piholeEnable() {
}
piholeLogging() {
+ shift
- shift
-
- if [[ "${1}" == "off" ]] ; then
- #Disable Logging
- sed -i 's/^log-queries/#log-queries/' /etc/dnsmasq.d/01-pihole.conf
- sed -i 's/^QUERY_LOGGING=true/QUERY_LOGGING=false/' /etc/pihole/setupVars.conf
- echo "::: Logging has been disabled!"
- elif [[ "${1}" == "on" ]] ; then
- #Enable logging
- sed -i 's/^#log-queries/log-queries/' /etc/dnsmasq.d/01-pihole.conf
- sed -i 's/^QUERY_LOGGING=false/QUERY_LOGGING=true/' /etc/pihole/setupVars.conf
- echo "::: Logging has been enabled!"
- else
- echo "::: Invalid option passed, please pass 'on' or 'off'"
- exit 1
- fi
- restartDNS
+ if [[ "${1}" == "off" ]] ; then
+ #Disable Logging
+ sed -i 's/^log-queries/#log-queries/' /etc/dnsmasq.d/01-pihole.conf
+ sed -i 's/^QUERY_LOGGING=true/QUERY_LOGGING=false/' /etc/pihole/setupVars.conf
+ pihole -f
+ echo "::: Logging has been disabled!"
+ elif [[ "${1}" == "on" ]] ; then
+ #Enable logging
+ sed -i 's/^#log-queries/log-queries/' /etc/dnsmasq.d/01-pihole.conf
+ sed -i 's/^QUERY_LOGGING=false/QUERY_LOGGING=true/' /etc/pihole/setupVars.conf
+ echo "::: Logging has been enabled!"
+ else
+ echo "::: Invalid option passed, please pass 'on' or 'off'"
+ exit 1
+ fi
+ restartDNS
}
piholeStatus() {
From 7740e4268c0dbbca9a5fa7f676322fe6ea3bae68 Mon Sep 17 00:00:00 2001
From: Dan Schaper
Date: Wed, 2 Nov 2016 05:17:28 -0700
Subject: [PATCH 056/228] Consistency and standards basic-install start.
---
automated install/basic-install.sh | 184 +++++++++++++++--------------
1 file changed, 94 insertions(+), 90 deletions(-)
diff --git a/automated install/basic-install.sh b/automated install/basic-install.sh
index 49329f5a..017ea8f1 100755
--- a/automated install/basic-install.sh
+++ b/automated install/basic-install.sh
@@ -33,7 +33,7 @@ IPv4_address=""
IPv6_address=""
# Find the rows and columns will default to 80x24 is it can not be detected
-screen_size=$(stty size 2>/dev/null || echo 24 80)
+screen_size=$(stty size 2>/dev/null || echo 24 80)
rows=$(echo $screen_size | awk '{print $1}')
columns=$(echo $screen_size | awk '{print $2}')
@@ -53,119 +53,123 @@ runUnattended=false
# Must be root to install
echo ":::"
if [[ ${EUID} -eq 0 ]]; then
- echo "::: You are root."
+ echo "::: You are root."
else
- echo "::: Script called with non-root privileges. The Pi-hole installs server packages and configures"
- echo "::: system networking, it requires elevated rights. Please check the contents of the script for"
- echo "::: any concerns with this requirement. Please be sure to download this script from a trusted source."
- echo ":::"
- echo "::: Detecting the presence of the sudo utility for continuation of this install..."
+ echo "::: Script called with non-root privileges. The Pi-hole installs server packages and configures"
+ echo "::: system networking, it requires elevated rights. Please check the contents of the script for"
+ echo "::: any concerns with this requirement. Please be sure to download this script from a trusted source."
+ echo ":::"
+ echo "::: Detecting the presence of the sudo utility for continuation of this install..."
- if [ -x "$(command -v sudo)" ]; then
- echo "::: Utility sudo located."
- exec curl -sSL https://install.pi-hole.net | sudo bash "$@"
- exit $?
- else
- echo "::: sudo is needed for the Web interface to run pihole commands. Please run this script as root and it will be automatically installed."
- exit 1
- fi
+ if [ -x "$(command -v sudo)" ]; then
+ echo "::: Utility sudo located."
+ exec curl -sSL https://install.pi-hole.net | sudo bash "$@"
+ exit $?
+ else
+ echo "::: sudo is needed for the Web interface to run pihole commands. Please run this script as root and it will be automatically installed."
+ exit 1
+ fi
fi
# Compatibility
if [[ $(command -v apt-get) ]]; then
- #Debian Family
- #############################################
- PKG_MANAGER="apt-get"
- PKG_CACHE="/var/lib/apt/lists/"
- UPDATE_PKG_CACHE="${PKG_MANAGER} update"
- PKG_UPDATE="${PKG_MANAGER} upgrade"
- PKG_INSTALL="${PKG_MANAGER} --yes --fix-missing install"
- # grep -c will return 1 retVal on 0 matches, block this throwing the set -e with an OR TRUE
- PKG_COUNT="${PKG_MANAGER} -s -o Debug::NoLocking=true upgrade | grep -c ^Inst || true"
- # #########################################
- # fixes for dependancy differences
- # Debian 7 doesn't have iproute2 use iproute
- ${PKG_MANAGER} install --dry-run iproute2 > /dev/null 2>&1 && IPROUTE_PKG="iproute2" || IPROUTE_PKG="iproute"
- # Ubuntu 16.04 LTS php / php5 fix
- ${PKG_MANAGER} install --dry-run php5 > /dev/null 2>&1 && phpVer="php5" || phpVer="php"
- # #########################################
- INSTALLER_DEPS=( apt-utils whiptail git dhcpcd5)
- PIHOLE_DEPS=( dnsutils bc dnsmasq lighttpd ${phpVer}-common ${phpVer}-cgi curl unzip wget sudo netcat cron ${IPROUTE_PKG} )
- LIGHTTPD_USER="www-data"
- LIGHTTPD_GROUP="www-data"
- LIGHTTPD_CFG="lighttpd.conf.debian"
- DNSMASQ_USER="dnsmasq"
- package_check_install() {
- dpkg-query -W -f='${Status}' "${1}" 2>/dev/null | grep -c "ok installed" || ${PKG_INSTALL} "${1}"
- }
+ #Debian Family
+ #############################################
+ PKG_MANAGER="apt-get"
+ PKG_CACHE="/var/lib/apt/lists/"
+ UPDATE_PKG_CACHE="${PKG_MANAGER} update"
+ PKG_UPDATE="${PKG_MANAGER} upgrade"
+ PKG_INSTALL="${PKG_MANAGER} --yes --fix-missing install"
+ # grep -c will return 1 retVal on 0 matches, block this throwing the set -e with an OR TRUE
+ PKG_COUNT="${PKG_MANAGER} -s -o Debug::NoLocking=true upgrade | grep -c ^Inst || true"
+ # #########################################
+ # fixes for dependancy differences
+ # Debian 7 doesn't have iproute2 use iproute
+ ${PKG_MANAGER} install --dry-run iproute2 > /dev/null 2>&1 && IPROUTE_PKG="iproute2" || IPROUTE_PKG="iproute"
+ # Ubuntu 16.04 LTS php / php5 fix
+ ${PKG_MANAGER} install --dry-run php5 > /dev/null 2>&1 && phpVer="php5" || phpVer="php"
+ # #########################################
+ INSTALLER_DEPS=( apt-utils whiptail git dhcpcd5)
+ PIHOLE_DEPS=( dnsutils bc dnsmasq lighttpd ${phpVer}-common ${phpVer}-cgi curl unzip wget sudo netcat cron ${IPROUTE_PKG} )
+ LIGHTTPD_USER="www-data"
+ LIGHTTPD_GROUP="www-data"
+ LIGHTTPD_CFG="lighttpd.conf.debian"
+ DNSMASQ_USER="dnsmasq"
+
+ package_check_install() {
+ dpkg-query -W -f='${Status}' "${1}" 2>/dev/null | grep -c "ok installed" || ${PKG_INSTALL} "${1}"
+ }
elif [ $(command -v rpm) ]; then
- # Fedora Family
- if [ $(command -v dnf) ]; then
- PKG_MANAGER="dnf"
- else
- PKG_MANAGER="yum"
- fi
- PKG_CACHE="/var/cache/${PKG_MANAGER}"
- UPDATE_PKG_CACHE="${PKG_MANAGER} check-update"
- PKG_UPDATE="${PKG_MANAGER} update -y"
- PKG_INSTALL="${PKG_MANAGER} install -y"
- PKG_COUNT="${PKG_MANAGER} check-update | egrep '(.i686|.x86|.noarch|.arm|.src)' | wc -l"
- INSTALLER_DEPS=( iproute net-tools procps-ng newt git )
- PIHOLE_DEPS=( epel-release bind-utils bc dnsmasq lighttpd lighttpd-fastcgi php-common php-cli php curl unzip wget findutils cronie sudo nmap-ncat )
- if grep -q 'Fedora' /etc/redhat-release; then
- remove_deps=(epel-release);
- PIHOLE_DEPS=( ${PIHOLE_DEPS[@]/$remove_deps} );
- fi
- LIGHTTPD_USER="lighttpd"
- LIGHTTPD_GROUP="lighttpd"
- LIGHTTPD_CFG="lighttpd.conf.fedora"
- DNSMASQ_USER="nobody"
- package_check_install() {
- rpm -qa | grep ^"${1}"- > /dev/null || ${PKG_INSTALL} "${1}"
- }
+ # Fedora Family
+ if [ $(command -v dnf) ]; then
+ PKG_MANAGER="dnf"
+ else
+ PKG_MANAGER="yum"
+ fi
+ PKG_CACHE="/var/cache/${PKG_MANAGER}"
+ UPDATE_PKG_CACHE="${PKG_MANAGER} check-update"
+ PKG_UPDATE="${PKG_MANAGER} update -y"
+ PKG_INSTALL="${PKG_MANAGER} install -y"
+ PKG_COUNT="${PKG_MANAGER} check-update | egrep '(.i686|.x86|.noarch|.arm|.src)' | wc -l"
+ INSTALLER_DEPS=( iproute net-tools procps-ng newt git )
+ PIHOLE_DEPS=( epel-release bind-utils bc dnsmasq lighttpd lighttpd-fastcgi php-common php-cli php curl unzip wget findutils cronie sudo nmap-ncat )
+
+ if grep -q 'Fedora' /etc/redhat-release; then
+ remove_deps=(epel-release);
+ PIHOLE_DEPS=( ${PIHOLE_DEPS[@]/$remove_deps} );
+ fi
+ LIGHTTPD_USER="lighttpd"
+ LIGHTTPD_GROUP="lighttpd"
+ LIGHTTPD_CFG="lighttpd.conf.fedora"
+ DNSMASQ_USER="nobody"
+
+ package_check_install() {
+ rpm -qa | grep ^"${1}"- > /dev/null || ${PKG_INSTALL} "${1}"
+ }
else
- echo "OS distribution not supported"
- exit
+ echo "OS distribution not supported"
+ exit
fi
####### FUNCTIONS ##########
spinner() {
- local pid=$1
- local delay=0.50
- local spinstr='/-\|'
- while [ "$(ps a | awk '{print $1}' | grep "${pid}")" ]; do
- local temp=${spinstr#?}
- printf " [%c] " "${spinstr}"
- local spinstr=${temp}${spinstr%"$temp"}
- sleep ${delay}
- printf "\b\b\b\b\b\b"
- done
- printf " \b\b\b\b"
+ local pid=$1
+ local delay=0.50
+ local spinstr='/-\|'
+
+ while [ "$(ps a | awk '{print $1}' | grep "${pid}")" ]; do
+ local temp=${spinstr#?}
+ printf " [%c] " "${spinstr}"
+ local spinstr=${temp}${spinstr%"$temp"}
+ sleep ${delay}
+ printf "\b\b\b\b\b\b"
+ done
+ printf " \b\b\b\b"
}
is_repo() {
# Use git to check if directory is currently under VCS
echo -n "::: Checking $1 is a repo..."
cd "${1}" &> /dev/null || return 1
- git status &> /dev/null && echo " OK!"; return 0 || echo " not found!"; return 1
+ git status &> /dev/null && (echo " OK!"; true) || (echo " not found!"; false)
}
make_repo() {
- # Remove the non-repod interface and clone the interface
- echo -n "::: Cloning $2 into $1..."
- rm -rf "${1}"
- git clone -q --depth 1 "${2}" "${1}" > /dev/null & spinner $!
- echo " done!"
+ # Remove the non-repod interface and clone the interface
+ echo -n "::: Cloning $2 into $1..."
+ rm -rf "${1}"
+ git clone -q --depth 1 "${2}" "${1}" > /dev/null & spinner $!
+ echo " done!"
}
update_repo() {
- # Pull the latest commits
- echo -n "::: Updating repo in $1..."
- cd "${1}" || exit 1
- git stash -q > /dev/null & spinner $!
- git pull -q > /dev/null & spinner $!
- echo " done!"
+ # Pull the latest commits
+ echo -n "::: Updating repo in $1..."
+ cd "${1}" || exit 1
+ git stash -q > /dev/null & spinner $!
+ git pull -q > /dev/null & spinner $!
+ echo " done!"
}
getGitFiles() {
@@ -1035,7 +1039,7 @@ main() {
# Decide what upstream DNS Servers to use
setDNS
# Install and log everything to a file
- installPihole | tee ${tmpLog}
+ installPihole | tee ${tmpLog}
else
updatePihole | tee ${tmpLog}
fi
From a0d9a1133cac1da095ffa1b01525b5f6ef630963 Mon Sep 17 00:00:00 2001
From: Dan Schaper
Date: Wed, 2 Nov 2016 05:34:39 -0700
Subject: [PATCH 057/228] Factoring and combining functions
---
advanced/Scripts/update.sh | 33 ++++++++++++++++++---------------
1 file changed, 18 insertions(+), 15 deletions(-)
diff --git a/advanced/Scripts/update.sh b/advanced/Scripts/update.sh
index 74bd2e54..c27d837b 100644
--- a/advanced/Scripts/update.sh
+++ b/advanced/Scripts/update.sh
@@ -23,16 +23,25 @@ is_repo() {
# Use git to check if directory is currently under VCS
local directory="${1}"
cd "${directory}" &> /dev/null || false
- $(git status --short &> /dev/null)
+ git status --short &> /dev/null
return
}
- make_repo() {
- # Remove the non-repod interface and clone the interface
- echo -n "::: Cloning $2 into $1..."
- rm -rf "${1}"
- git clone -q --depth 1 "${2}" "${1}" > /dev/null || exit 1
- echo " done!"
+prep_dirs() {
+ # Prepare directory for local repository building
+ local dir_to_clean="${1}"
+ cd "${dir_to_clean}" &> /dev/null || (echo "Unable to prepare directory, please contact support"; exit false)
+ rm -rf "${dir_to_clean}" &> /dev/null || (echo "Unable to prepare directory, please contact support"; exit false)
+}
+
+make_repo() {
+ # Remove the non-repod interface and clone the interface
+ local source_repo="${2}"
+ local dest_dir="${1}"
+ echo -n "::: Cloning ${source_repo} into ${dest_dir}..."
+ rm -rf "${dest_dir}"
+ git clone -q --depth 1 "${2}" "${1}" > /dev/null || exit 1
+ echo " done!"
}
update_repo() {
@@ -58,14 +67,8 @@ getGitFiles() {
main() {
- if ! is_repo "${PI_HOLE_FILES_DIR}"; then #This is unlikely
- echo "::: Critical Error: Pi-Hole repo missing from system!"
- echo "::: Please re-run install script from https://github.com/pi-hole/pi-hole"
- exit 1;
- fi
-
- if ! $(is_repo "${ADMIN_INTERFACE_DIR}"); then #This is unlikely
- echo "::: Critical Error: Pi-Hole repo missing from system!"
+ if ! is_repo "${PI_HOLE_FILES_DIR}" && ! is_repo "${ADMIN_INTERFACE_DIR}" ; then #This is unlikely
+ echo "::: Critical Error: One or more Pi-Hole repos are missing from system!"
echo "::: Please re-run install script from https://github.com/pi-hole/pi-hole"
exit 1;
fi
From 8dc9143b34d9ffeb47c61753c36feba6f3767296 Mon Sep 17 00:00:00 2001
From: Dan Schaper
Date: Wed, 2 Nov 2016 05:45:29 -0700
Subject: [PATCH 058/228] Just delete, no need to cd there first.
---
advanced/Scripts/update.sh | 17 +++++++++--------
1 file changed, 9 insertions(+), 8 deletions(-)
diff --git a/advanced/Scripts/update.sh b/advanced/Scripts/update.sh
index c27d837b..0c5e625c 100644
--- a/advanced/Scripts/update.sh
+++ b/advanced/Scripts/update.sh
@@ -20,9 +20,9 @@ readonly PI_HOLE_GIT_URL="https://github.com/pi-hole/pi-hole.git"
readonly PI_HOLE_FILES_DIR="/etc/.pihole"
is_repo() {
- # Use git to check if directory is currently under VCS
- local directory="${1}"
- cd "${directory}" &> /dev/null || false
+ # Use git to check if directory is currently under VCS, do not exit if failed
+ local directory="${1}"
+ cd "${directory}" &> /dev/null || false
git status --short &> /dev/null
return
}
@@ -30,17 +30,18 @@ is_repo() {
prep_dirs() {
# Prepare directory for local repository building
local dir_to_clean="${1}"
- cd "${dir_to_clean}" &> /dev/null || (echo "Unable to prepare directory, please contact support"; exit false)
- rm -rf "${dir_to_clean}" &> /dev/null || (echo "Unable to prepare directory, please contact support"; exit false)
+ rm -rf "${dir_to_clean}" &> /dev/null
}
make_repo() {
# Remove the non-repod interface and clone the interface
local source_repo="${2}"
local dest_dir="${1}"
+
echo -n "::: Cloning ${source_repo} into ${dest_dir}..."
- rm -rf "${dest_dir}"
- git clone -q --depth 1 "${2}" "${1}" > /dev/null || exit 1
+ prep_dirs "${dest_dir}"
+ git clone -q --depth 1 "${source_repo}" "${dest_dir}" > /dev/null \
+ || (echo "Unable to clone directory, please contact support"; exit false)
echo " done!"
}
@@ -67,7 +68,7 @@ getGitFiles() {
main() {
- if ! is_repo "${PI_HOLE_FILES_DIR}" && ! is_repo "${ADMIN_INTERFACE_DIR}" ; then #This is unlikely
+ if ! is_repo "${PI_HOLE_FILES_DIR}" || ! is_repo "${ADMIN_INTERFACE_DIR}" ; then #This is unlikely
echo "::: Critical Error: One or more Pi-Hole repos are missing from system!"
echo "::: Please re-run install script from https://github.com/pi-hole/pi-hole"
exit 1;
From 93d91353a1615aaea530c0bcce818df94cabab96 Mon Sep 17 00:00:00 2001
From: Dan Schaper
Date: Wed, 2 Nov 2016 05:49:33 -0700
Subject: [PATCH 059/228] All tabs now spaced
---
advanced/Scripts/update.sh | 32 ++++++++++++++++----------------
1 file changed, 16 insertions(+), 16 deletions(-)
diff --git a/advanced/Scripts/update.sh b/advanced/Scripts/update.sh
index 0c5e625c..ea04dc2e 100644
--- a/advanced/Scripts/update.sh
+++ b/advanced/Scripts/update.sh
@@ -20,7 +20,7 @@ readonly PI_HOLE_GIT_URL="https://github.com/pi-hole/pi-hole.git"
readonly PI_HOLE_FILES_DIR="/etc/.pihole"
is_repo() {
- # Use git to check if directory is currently under VCS, do not exit if failed
+ # Use git to check if directory is currently under VCS, do not exit if failed
local directory="${1}"
cd "${directory}" &> /dev/null || false
git status --short &> /dev/null
@@ -46,24 +46,24 @@ make_repo() {
}
update_repo() {
-# Pull the latest commits
- echo -n "::: Updating repo in $1..."
- cd "${1}" || exit 1
- git stash -q > /dev/null || exit 1
- git pull -q > /dev/null || exit 1
- echo " done!"
+ # Pull the latest commits
+ echo -n "::: Updating repo in $1..."
+ cd "${1}" || exit 1
+ git stash -q > /dev/null || exit 1
+ git pull -q > /dev/null || exit 1
+ echo " done!"
}
getGitFiles() {
- # Setup git repos for directory and repository passed
- # as arguments 1 and 2
- echo ":::"
- echo "::: Checking for existing repository..."
- if is_repo "${1}"; then
- update_repo "${1}"
- else
- make_repo "${1}" "${2}"
- fi
+ # Setup git repos for directory and repository passed
+ # as arguments 1 and 2
+ echo ":::"
+ echo "::: Checking for existing repository..."
+ if is_repo "${1}"; then
+ update_repo "${1}"
+ else
+ make_repo "${1}" "${2}"
+ fi
}
main() {
From 50bd8b4a09078f0410d1561ab7304dd385543b25 Mon Sep 17 00:00:00 2001
From: Adam Warner
Date: Wed, 2 Nov 2016 13:34:57 +0000
Subject: [PATCH 060/228] Further tweaks to local repo handling
---
advanced/Scripts/update.sh | 35 +++++++++++++++++-------------
automated install/basic-install.sh | 31 +++++++++++++++-----------
2 files changed, 38 insertions(+), 28 deletions(-)
diff --git a/advanced/Scripts/update.sh b/advanced/Scripts/update.sh
index 74bd2e54..b4c9728a 100644
--- a/advanced/Scripts/update.sh
+++ b/advanced/Scripts/update.sh
@@ -20,39 +20,44 @@ readonly PI_HOLE_GIT_URL="https://github.com/pi-hole/pi-hole.git"
readonly PI_HOLE_FILES_DIR="/etc/.pihole"
is_repo() {
- # Use git to check if directory is currently under VCS
- local directory="${1}"
- cd "${directory}" &> /dev/null || false
- $(git status --short &> /dev/null)
+ # Use git to check if directory is currently under VCS, return the value
+ local directory="${1}"
+ git -C "${directory}" status --short &> /dev/null
return
}
- make_repo() {
+make_repo() {
+ local directory="${1}"
+ local remoteRepo="{$2}"
# Remove the non-repod interface and clone the interface
- echo -n "::: Cloning $2 into $1..."
- rm -rf "${1}"
- git clone -q --depth 1 "${2}" "${1}" > /dev/null || exit 1
+ echo -n "::: Cloning $remoteRepo into $directory..."
+ rm -rf "${directory}"
+ git clone -q --depth 1 "${remoteRepo}" "${directory}" > /dev/null
echo " done!"
}
update_repo() {
-# Pull the latest commits
+echo "update" && exit 1
+ local directory="${1}"
+ # Pull the latest commits
echo -n "::: Updating repo in $1..."
- cd "${1}" || exit 1
- git stash -q > /dev/null || exit 1
- git pull -q > /dev/null || exit 1
+ cd "${directory}" || exit 1
+ git stash -q > /dev/null
+ git pull -q > /dev/null
echo " done!"
}
getGitFiles() {
# Setup git repos for directory and repository passed
# as arguments 1 and 2
+ local directory="${1}"
+ local remoteRepo="{$2}"
echo ":::"
echo "::: Checking for existing repository..."
- if is_repo "${1}"; then
- update_repo "${1}"
+ if is_repo "${directory}"; then
+ update_repo "${directory}"
else
- make_repo "${1}" "${2}"
+ make_repo "${directory}" "${remoteRepo}"
fi
}
diff --git a/automated install/basic-install.sh b/automated install/basic-install.sh
index c068fb39..8e797a20 100755
--- a/automated install/basic-install.sh
+++ b/automated install/basic-install.sh
@@ -146,24 +146,27 @@ spinner() {
}
is_repo() {
- # Use git to check if directory is currently under VCS
- echo -n "::: Checking $1 is a repo..."
- cd "${1}" &> /dev/null || return 1
- git status &> /dev/null && echo " OK!"; return 0 || echo " not found!"; return 1
+ # Use git to check if directory is currently under VCS, return the value
+ local directory="${1}"
+ git -C "${directory}" status --short &> /dev/null
+ return
}
make_repo() {
+ local directory="${1}"
+ local remoteRepo="${2}"
# Remove the non-repod interface and clone the interface
- echo -n "::: Cloning $2 into $1..."
- rm -rf "${1}"
- git clone -q --depth 1 "${2}" "${1}" > /dev/null & spinner $!
+ echo -n "::: Cloning $remoteRepo into $directory..."
+ rm -rf "${directory}"
+ git clone -q --depth 1 "${remoteRepo}" "${directory}" > /dev/null & spinner $!
echo " done!"
}
update_repo() {
+ local directory="${1}"
# Pull the latest commits
echo -n "::: Updating repo in $1..."
- cd "${1}" || exit 1
+ cd "${directory}" || exit 1
git stash -q > /dev/null & spinner $!
git pull -q > /dev/null & spinner $!
echo " done!"
@@ -172,12 +175,14 @@ update_repo() {
getGitFiles() {
# Setup git repos for directory and repository passed
# as arguments 1 and 2
+ local directory="${1}"
+ local remoteRepo="${2}"
echo ":::"
echo "::: Checking for existing repository..."
- if is_repo "${1}"; then
- update_repo "${1}"
+ if is_repo "${directory}"; then
+ update_repo "${directory}"
else
- make_repo "${1}" "${2}"
+ make_repo "${directory}" "${remoteRepo}"
fi
}
@@ -671,13 +676,13 @@ installScripts() {
readonly install_dir="/opt/pihole/"
echo ":::"
- echo -n "::: Installing scripts to ${PI_HOLE_LOCAL_REPO}..."
+ echo -n "::: Installing scripts from ${PI_HOLE_LOCAL_REPO}..."
# Clear out script files from Pi-hole scripts directory.
clean_existing "${install_dir}" "${PI_HOLE_FILES}"
# Install files from local core repository
- if [[ $(is_repo "${PI_HOLE_LOCAL_REPO}") ]]; then
+ if is_repo "${PI_HOLE_LOCAL_REPO}"; then
cd "${PI_HOLE_LOCAL_REPO}"
install -o "${USER}" -Dm755 -t /opt/pihole/ gravity.sh
install -o "${USER}" -Dm755 -t /opt/pihole/ ./advanced/Scripts/*.sh
From ece1667fb0c2853fb597d4ee3c2e3b3be16c7d90 Mon Sep 17 00:00:00 2001
From: Dan Schaper
Date: Wed, 2 Nov 2016 06:41:51 -0700
Subject: [PATCH 061/228] Refactor and move some bits.
---
advanced/Scripts/update.sh | 52 +++++++++++++++-----------------------
1 file changed, 21 insertions(+), 31 deletions(-)
diff --git a/advanced/Scripts/update.sh b/advanced/Scripts/update.sh
index ea04dc2e..dbad17f8 100644
--- a/advanced/Scripts/update.sh
+++ b/advanced/Scripts/update.sh
@@ -20,10 +20,9 @@ readonly PI_HOLE_GIT_URL="https://github.com/pi-hole/pi-hole.git"
readonly PI_HOLE_FILES_DIR="/etc/.pihole"
is_repo() {
- # Use git to check if directory is currently under VCS, do not exit if failed
+ # Use git to check if directory is currently under VCS, return the value
local directory="${1}"
- cd "${directory}" &> /dev/null || false
- git status --short &> /dev/null
+ git -C "${directory}" status --short &> /dev/null
return
}
@@ -31,6 +30,7 @@ prep_dirs() {
# Prepare directory for local repository building
local dir_to_clean="${1}"
rm -rf "${dir_to_clean}" &> /dev/null
+ return
}
make_repo() {
@@ -39,18 +39,18 @@ make_repo() {
local dest_dir="${1}"
echo -n "::: Cloning ${source_repo} into ${dest_dir}..."
- prep_dirs "${dest_dir}"
- git clone -q --depth 1 "${source_repo}" "${dest_dir}" > /dev/null \
- || (echo "Unable to clone directory, please contact support"; exit false)
- echo " done!"
+ if (prep_dirs "${dest_dir}" && git clone -q --depth 1 "${source_repo}" "${dest_dir}" > /dev/null); then \
+ echo " done!" || (echo "Unable to clone repository, please contact support"; exit false)
+ fi
}
update_repo() {
+ local dest_dir="${1}"
# Pull the latest commits
- echo -n "::: Updating repo in $1..."
+ echo -n "::: Updating repository in ${dest_dir}..."
cd "${1}" || exit 1
- git stash -q > /dev/null || exit 1
- git pull -q > /dev/null || exit 1
+ git stash -q > /dev/null || exit $?
+ git pull -q > /dev/null || exit $?
echo " done!"
}
@@ -98,49 +98,39 @@ main() {
# pull pihole repo run install --unattended
if [[ "${pihole_version_current}" == "${pihole_version_latest}" ]] && [[ "${web_version_current}" == "${web_version_latest}" ]]; then
- echo "::: Pi-hole version is $pihole_version_current"
- echo "::: Web Admin version is $web_version_current"
echo "::: Everything is up to date!"
- echo ""
- exit 0
elif [[ "${pihole_version_current}" == "${pihole_version_latest}" ]] && [[ "${web_version_current}" != "${web_version_latest}" ]]; then
echo "::: Pi-hole Web Admin files out of date"
getGitFiles "${ADMIN_INTERFACE_DIR}" "${ADMIN_INTERFACE_GIT_URL}"
echo ":::"
web_version_current="$(/usr/local/bin/pihole -v -a -c)"
- echo "::: Web Admin version is now at ${web_version_current}"
- echo "::: If you had made any changes in '/var/www/html/admin', they have been stashed using 'git stash'"
- echo ""
+
elif [[ "${pihole_version_current}" != "${pihole_version_latest}" ]] && [[ "${web_version_current}" == "${web_version_latest}" ]]; then
echo "::: Pi-hole core files out of date"
getGitFiles "${PI_HOLE_FILES_DIR}" "${PI_HOLE_GIT_URL}"
-
/etc/.pihole/automated\ install/basic-install.sh --reconfigure --unattended || echo "Unable to complete update, contact Pi-hole" && exit 1
-
echo ":::"
pihole_version_current="$(/usr/local/bin/pihole -v -p -c)"
- echo "::: Pi-hole version is now at ${pihole_version_current}"
- echo "::: If you had made any changes in '/etc/.pihole', they have been stashed using 'git stash'"
- echo ""
+
+
elif [[ "${pihole_version_current}" != "${pihole_version_latest}" ]] && [[ "${web_version_current}" != "${web_version_latest}" ]]; then
echo "::: Updating Everything"
getGitFiles "${PI_HOLE_FILES_DIR}" "${PI_HOLE_GIT_URL}"
-
/etc/.pihole/automated\ install/basic-install.sh --unattended || echo "Unable to complete update, contact Pi-hole" && exit 1
-
# Checks Pi-hole version > admin only > current local git repo version : returns string in format vX.X.X
web_version_current="$(/usr/local/bin/pihole -v -a -c)"
# Checks Pi-hole version > admin only > current local git repo version : returns string in format vX.X.X
pihole_version_current="$(/usr/local/bin/pihole -v -p -c)"
- echo ":::"
- echo "::: Pi-hole version is now at ${pihole_version_current}"
- echo "::: If you had made any changes in '/etc/.pihole', they have been stashed using 'git stash'"
- echo ":::"
- echo "::: Pi-hole version is now at ${pihole_version_current}"
- echo "::: If you had made any changes in '/etc/.pihole', they have been stashed using 'git stash'"
- echo ""
fi
+ echo ":::"
+ echo "::: Pi-hole version is now at ${pihole_version_current}"
+ echo "::: If you had made any changes in '/etc/.pihole/', they have been stashed using 'git stash'"
+ echo ":::"
+ echo "::: Web Admin version is now at ${web_version_current}"
+ echo "::: If you had made any changes in '/var/www/html/admin/', they have been stashed using 'git stash'"
+ echo ""
+ exit 0
}
main
From b636c1e1f8221dc6f9a7ce62970148e2b608bc5d Mon Sep 17 00:00:00 2001
From: Dan Schaper
Date: Wed, 2 Nov 2016 07:00:43 -0700
Subject: [PATCH 062/228] Whitespace.
---
advanced/Scripts/update.sh | 22 +++++++++++-----------
1 file changed, 11 insertions(+), 11 deletions(-)
diff --git a/advanced/Scripts/update.sh b/advanced/Scripts/update.sh
index 7d05efd8..c29c6b70 100644
--- a/advanced/Scripts/update.sh
+++ b/advanced/Scripts/update.sh
@@ -55,17 +55,17 @@ update_repo() {
}
getGitFiles() {
- # Setup git repos for directory and repository passed
- # as arguments 1 and 2
- local directory="${1}"
- local remoteRepo="{$2}"
- echo ":::"
- echo "::: Checking for existing repository..."
- if is_repo "${directory}"; then
- update_repo "${directory}"
- else
- make_repo "${directory}" "${remoteRepo}"
- fi
+ # Setup git repos for directory and repository passed
+ # as arguments 1 and 2
+ local directory="${1}"
+ local remoteRepo="{$2}"
+ echo ":::"
+ echo "::: Checking for existing repository..."
+ if is_repo "${directory}"; then
+ update_repo "${directory}"
+ else
+ make_repo "${directory}" "${remoteRepo}"
+ fi
}
main() {
From ee37c37cab37a5faa9f53aeb09eb5fb6fff168a9 Mon Sep 17 00:00:00 2001
From: Adam Warner
Date: Wed, 2 Nov 2016 14:29:20 +0000
Subject: [PATCH 063/228] fix update output logic. version number variables
should not be read only!
---
advanced/Scripts/update.sh | 40 ++++++++++++++++++++++++++------------
1 file changed, 28 insertions(+), 12 deletions(-)
diff --git a/advanced/Scripts/update.sh b/advanced/Scripts/update.sh
index 7d05efd8..1a12dfc1 100644
--- a/advanced/Scripts/update.sh
+++ b/advanced/Scripts/update.sh
@@ -78,14 +78,14 @@ main() {
echo "::: Checking for updates..."
# Checks Pi-hole version > pihole only > current local git repo version : returns string in format vX.X.X
- local -r pihole_version_current="$(/usr/local/bin/pihole -v -p -c)"
+ local pihole_version_current="$(/usr/local/bin/pihole -v -p -c)"
# Checks Pi-hole version > pihole only > remote upstream repo version : returns string in format vX.X.X
- local -r pihole_version_latest="$(/usr/local/bin/pihole -v -p -l)"
+ local pihole_version_latest="$(/usr/local/bin/pihole -v -p -l)"
# Checks Pi-hole version > admin only > current local git repo version : returns string in format vX.X.X
- local -r web_version_current="$(/usr/local/bin/pihole -v -a -c)"
+ local web_version_current="$(/usr/local/bin/pihole -v -a -c)"
# Checks Pi-hole version > admin only > remote upstream repo version : returns string in format vX.X.X
- local -r web_version_latest="$(/usr/local/bin/pihole -v -a -l)"
+ local web_version_latest="$(/usr/local/bin/pihole -v -a -l)"
# Logic
# If latest versions are blank - we've probably hit Github rate limit (stop running `pihole -up so often!):
@@ -100,21 +100,27 @@ main() {
# pull pihole repo run install --unattended
if [[ "${pihole_version_current}" == "${pihole_version_latest}" ]] && [[ "${web_version_current}" == "${web_version_latest}" ]]; then
+ echo ":::"
+ echo "::: Pi-hole version is $pihole_version_current"
+ echo "::: Web Admin version is $web_version_current"
+ echo ":::"
echo "::: Everything is up to date!"
+ exit 0
elif [[ "${pihole_version_current}" == "${pihole_version_latest}" ]] && [[ "${web_version_current}" != "${web_version_latest}" ]]; then
+ echo ":::"
echo "::: Pi-hole Web Admin files out of date"
getGitFiles "${ADMIN_INTERFACE_DIR}" "${ADMIN_INTERFACE_GIT_URL}"
- echo ":::"
+
web_version_current="$(/usr/local/bin/pihole -v -a -c)"
+ web_updated=true
elif [[ "${pihole_version_current}" != "${pihole_version_latest}" ]] && [[ "${web_version_current}" == "${web_version_latest}" ]]; then
echo "::: Pi-hole core files out of date"
getGitFiles "${PI_HOLE_FILES_DIR}" "${PI_HOLE_GIT_URL}"
/etc/.pihole/automated\ install/basic-install.sh --reconfigure --unattended || echo "Unable to complete update, contact Pi-hole" && exit 1
- echo ":::"
pihole_version_current="$(/usr/local/bin/pihole -v -p -c)"
-
+ core_updated=true
elif [[ "${pihole_version_current}" != "${pihole_version_latest}" ]] && [[ "${web_version_current}" != "${web_version_latest}" ]]; then
echo "::: Updating Everything"
@@ -124,15 +130,25 @@ main() {
web_version_current="$(/usr/local/bin/pihole -v -a -c)"
# Checks Pi-hole version > admin only > current local git repo version : returns string in format vX.X.X
pihole_version_current="$(/usr/local/bin/pihole -v -p -c)"
+ web_updated=true
+ core_updated=true
fi
- echo ":::"
- echo "::: Pi-hole version is now at ${pihole_version_current}"
- echo "::: If you had made any changes in '/etc/.pihole/', they have been stashed using 'git stash'"
+
+ if [[ "${web_updated}" == true ]]; then
echo ":::"
echo "::: Web Admin version is now at ${web_version_current}"
echo "::: If you had made any changes in '/var/www/html/admin/', they have been stashed using 'git stash'"
- echo ""
- exit 0
+ fi
+
+ if [[ "${core_updated}" == true ]]; then
+ echo ":::"
+ echo "::: Pi-hole version is now at ${pihole_version_current}"
+ echo "::: If you had made any changes in '/etc/.pihole/', they have been stashed using 'git stash'"
+ fi
+
+ echo ""
+ exit 0
+
}
main
From fef9ab674e2d853b970bb73200d69c0286fef9e5 Mon Sep 17 00:00:00 2001
From: Dan Schaper
Date: Wed, 2 Nov 2016 07:53:02 -0700
Subject: [PATCH 064/228] Pi-hole CORE installer variables are being changed to
standardize scripts.
---
test/test_automated_install.py | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/test/test_automated_install.py b/test/test_automated_install.py
index 1605fdb6..b09eabd6 100644
--- a/test/test_automated_install.py
+++ b/test/test_automated_install.py
@@ -23,11 +23,11 @@ def test_setupVars_are_sourced_to_global_scope(Pihole):
printSetupVars() {
# Currently debug test function only
echo "Outputting sourced variables"
- echo "piholeInterface=\${piholeInterface}"
- echo "IPv4_address=\${IPv4_address}"
- echo "IPv6_address=\${IPv6_address}"
- echo "piholeDNS1=\${piholeDNS1}"
- echo "piholeDNS2=\${piholeDNS2}"
+ echo "PIHOLE_INTERFAC=\${piholeInterface}"
+ echo "IPv4_ADDRESS=\${IPv4_address}"
+ echo "IPv6_ADDRESS=\${IPv6_address}"
+ echo "PIHOLE_DNS1=\${piholeDNS1}"
+ echo "PIHOLE_DNS2=\${piholeDNS2}"
}
update_dialogs() {
. /etc/pihole/setupVars.conf
From e99ef9c093666434898eb641129685c97ed4793a Mon Sep 17 00:00:00 2001
From: Dan Schaper
Date: Wed, 2 Nov 2016 08:22:45 -0700
Subject: [PATCH 065/228] Cap the variables and echo out the proper
environment.
---
test/test_automated_install.py | 20 ++++++++++----------
1 file changed, 10 insertions(+), 10 deletions(-)
diff --git a/test/test_automated_install.py b/test/test_automated_install.py
index b09eabd6..44bdacb2 100644
--- a/test/test_automated_install.py
+++ b/test/test_automated_install.py
@@ -2,11 +2,11 @@ import pytest
from textwrap import dedent
SETUPVARS = {
- 'piholeInterface' : 'eth99',
- 'IPv4_address' : '1.1.1.1',
- 'IPv6_address' : '2:2:2:2:2:2',
- 'piholeDNS1' : '4.2.2.1',
- 'piholeDNS2' : '4.2.2.2'
+ 'PIHOLE_INTERFACE' : 'eth99',
+ 'IPV4_ADDRESS' : '1.1.1.1',
+ 'IPV6_ADDRESS' : 'FE80::240:D0FF:FE48:4672',
+ 'PIHOLE_DNS1' : '4.2.2.1',
+ 'PIHOLE_DNS2' : '4.2.2.2'
}
def test_setupVars_are_sourced_to_global_scope(Pihole):
@@ -23,11 +23,11 @@ def test_setupVars_are_sourced_to_global_scope(Pihole):
printSetupVars() {
# Currently debug test function only
echo "Outputting sourced variables"
- echo "PIHOLE_INTERFAC=\${piholeInterface}"
- echo "IPv4_ADDRESS=\${IPv4_address}"
- echo "IPv6_ADDRESS=\${IPv6_address}"
- echo "PIHOLE_DNS1=\${piholeDNS1}"
- echo "PIHOLE_DNS2=\${piholeDNS2}"
+ echo "PIHOLE_INTERFACE=\${PIHOLE_INTERFACE}"
+ echo "IPv4_ADDRESS=\${IPv4_ADDRESS}"
+ echo "IPv6_ADDRESS=\${IPv6_ADDRESS}"
+ echo "PIHOLE_DNS1=\${PIHOLE_DNS1}"
+ echo "PIHOLE_DNS2=\${PIHOLE_DNS2}"
}
update_dialogs() {
. /etc/pihole/setupVars.conf
From 07029f93e36c0a03ccefa6b1b5f352e3d72bce00 Mon Sep 17 00:00:00 2001
From: Dan Schaper
Date: Wed, 2 Nov 2016 08:34:56 -0700
Subject: [PATCH 066/228] Match team convention in naming.
---
test/test_automated_install.py | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/test/test_automated_install.py b/test/test_automated_install.py
index 44bdacb2..b9b05708 100644
--- a/test/test_automated_install.py
+++ b/test/test_automated_install.py
@@ -24,8 +24,8 @@ def test_setupVars_are_sourced_to_global_scope(Pihole):
# Currently debug test function only
echo "Outputting sourced variables"
echo "PIHOLE_INTERFACE=\${PIHOLE_INTERFACE}"
- echo "IPv4_ADDRESS=\${IPv4_ADDRESS}"
- echo "IPv6_ADDRESS=\${IPv6_ADDRESS}"
+ echo "IPV4_ADDRESS=\${IPV4_ADDRESS}"
+ echo "IPV6_ADDRESS=\${IPV6_ADDRESS}"
echo "PIHOLE_DNS1=\${PIHOLE_DNS1}"
echo "PIHOLE_DNS2=\${PIHOLE_DNS2}"
}
From a1a9a7fa9e0cfe49a4e8e1cec28b40573204b9aa Mon Sep 17 00:00:00 2001
From: Dan Schaper
Date: Wed, 2 Nov 2016 08:52:23 -0700
Subject: [PATCH 067/228] Clarify which DNS entry we are modifying.
---
test/test_automated_install.py | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/test/test_automated_install.py b/test/test_automated_install.py
index b9b05708..458536eb 100644
--- a/test/test_automated_install.py
+++ b/test/test_automated_install.py
@@ -5,8 +5,8 @@ SETUPVARS = {
'PIHOLE_INTERFACE' : 'eth99',
'IPV4_ADDRESS' : '1.1.1.1',
'IPV6_ADDRESS' : 'FE80::240:D0FF:FE48:4672',
- 'PIHOLE_DNS1' : '4.2.2.1',
- 'PIHOLE_DNS2' : '4.2.2.2'
+ 'PIHOLE_DNS_1' : '4.2.2.1',
+ 'PIHOLE_DNS_2' : '4.2.2.2'
}
def test_setupVars_are_sourced_to_global_scope(Pihole):
@@ -26,8 +26,8 @@ def test_setupVars_are_sourced_to_global_scope(Pihole):
echo "PIHOLE_INTERFACE=\${PIHOLE_INTERFACE}"
echo "IPV4_ADDRESS=\${IPV4_ADDRESS}"
echo "IPV6_ADDRESS=\${IPV6_ADDRESS}"
- echo "PIHOLE_DNS1=\${PIHOLE_DNS1}"
- echo "PIHOLE_DNS2=\${PIHOLE_DNS2}"
+ echo "PIHOLE_DNS_1=\${PIHOLE_DNS_1}"
+ echo "PIHOLE_DNS_2=\${PIHOLE_DNS_2}"
}
update_dialogs() {
. /etc/pihole/setupVars.conf
From fe18d69b659a5f00e0155ba039d7c809fa886edd Mon Sep 17 00:00:00 2001
From: Dan Schaper
Date: Wed, 2 Nov 2016 09:25:32 -0700
Subject: [PATCH 068/228] Grep should start at the beginning of line to make
sure it doesn't fire on `#` beginning lines.
---
pihole | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/pihole b/pihole
index ace0d9a9..199c0a68 100755
--- a/pihole
+++ b/pihole
@@ -154,7 +154,7 @@ piholeStatus() {
else
echo "::: Pi-hole blocking is Disabled";
fi
- elif [[ $(cat /etc/dnsmasq.d/01-pihole.conf | grep "addn-hosts=/") ]] ; then
+ elif [[ $(cat /etc/dnsmasq.d/01-pihole.conf | grep "^addn-hosts=/") ]] ; then
#list set
if [[ "${1}" == "web" ]] ; then
echo 1;
From e42a037b7db3a99bc84bda809b9d80e5a0008482 Mon Sep 17 00:00:00 2001
From: Dan Schaper
Date: Wed, 2 Nov 2016 09:28:00 -0700
Subject: [PATCH 069/228] Grep -i instead of cat.
---
pihole | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/pihole b/pihole
index 199c0a68..25805b7f 100755
--- a/pihole
+++ b/pihole
@@ -147,14 +147,14 @@ piholeLogging() {
}
piholeStatus() {
- if [[ $(cat /etc/dnsmasq.d/01-pihole.conf | grep "#addn-hosts=/") ]] ; then
+ if [[ $(grep -i "^#addn-hosts=/" /etc/dnsmasq.d/01-pihole.conf) ]] ; then
#list is commented out
if [[ "${1}" == "web" ]] ; then
echo 0;
else
echo "::: Pi-hole blocking is Disabled";
fi
- elif [[ $(cat /etc/dnsmasq.d/01-pihole.conf | grep "^addn-hosts=/") ]] ; then
+ elif [[ $(grep -i "^addn-hosts=/" /etc/dnsmasq.d/01-pihole.conf) ]] ; then
#list set
if [[ "${1}" == "web" ]] ; then
echo 1;
From 0ef8832b041b61383f4d029857790701757bc049 Mon Sep 17 00:00:00 2001
From: Dan Schaper
Date: Wed, 2 Nov 2016 09:36:30 -0700
Subject: [PATCH 070/228] whitespace
---
pihole | 125 ++++++++++++++++++++++++++++-----------------------------
1 file changed, 62 insertions(+), 63 deletions(-)
diff --git a/pihole b/pihole
index 25805b7f..a1c03420 100755
--- a/pihole
+++ b/pihole
@@ -12,85 +12,84 @@
# Must be root to use this tool
if [[ ! $EUID -eq 0 ]];then
- if [ -x "$(command -v sudo)" ];then
- exec sudo bash "$0" "$@"
- exit $?
- else
- echo "::: sudo is needed to run pihole commands. Please run this script as root or install sudo."
- exit 1
- fi
+ if [ -x "$(command -v sudo)" ];then
+ exec sudo bash "$0" "$@"
+ exit $?
+ else
+ echo "::: sudo is needed to run pihole commands. Please run this script as root or install sudo."
+ exit 1
+ fi
fi
whitelistFunc() {
- /opt/pihole/list.sh "$@"
- exit 0
+ /opt/pihole/list.sh "$@"
+ exit 0
}
blacklistFunc() {
- /opt/pihole/list.sh "$@"
- exit 0
+ /opt/pihole/list.sh "$@"
+ exit 0
}
debugFunc() {
- /opt/pihole/piholeDebug.sh
- exit 0
+ /opt/pihole/piholeDebug.sh
+ exit 0
}
flushFunc() {
- /opt/pihole/piholeLogFlush.sh
- exit 0
+ /opt/pihole/piholeLogFlush.sh
+ exit 0
}
-
updatePiholeFunc() {
- /opt/pihole/update.sh
- exit 0
+ /opt/pihole/update.sh
+ exit 0
}
reconfigurePiholeFunc() {
- /etc/.pihole/automated\ install/basic-install.sh --reconfigure
- exit 0;
+ /etc/.pihole/automated\ install/basic-install.sh --reconfigure
+ exit 0;
}
updateGravityFunc() {
- /opt/pihole/gravity.sh "$@"
- exit 0
+ /opt/pihole/gravity.sh "$@"
+ exit 0
}
setupLCDFunction() {
- /opt/pihole/setupLCD.sh
- exit 0
+ /opt/pihole/setupLCD.sh
+ exit 0
}
queryFunc() {
- domain=$2
- for list in /etc/pihole/list.*; do
- count=$(grep ${domain} $list | wc -l)
- echo "::: ${list} (${count} results)"
- if [[ ${count} > 0 ]]; then
- grep ${domain} ${list}
- fi
- echo ""
- done
- exit 0
+ domain=$2
+ for list in /etc/pihole/list.*; do
+ count=$(grep ${domain} $list | wc -l)
+ echo "::: ${list} (${count} results)"
+ if [[ ${count} > 0 ]]; then
+ grep ${domain} ${list}
+ fi
+ echo ""
+ done
+ exit 0
}
chronometerFunc() {
- shift
- /opt/pihole/chronometer.sh "$@"
- exit 0
+ shift
+ /opt/pihole/chronometer.sh "$@"
+ exit 0
}
uninstallFunc() {
- /opt/pihole/uninstall.sh
- exit 0
+ /opt/pihole/uninstall.sh
+ exit 0
}
versionFunc() {
- shift
- /opt/pihole/version.sh "$@"
- exit 0
+ shift
+ /opt/pihole/version.sh "$@"
+ exit 0
}
restartDNS() {
@@ -201,32 +200,32 @@ helpFunc() {
::: disable Disable Pi-Hole DNS Blocking
::: restartdns Restart dnsmasq
EOM
- exit 1
+ exit 1
}
if [[ $# = 0 ]]; then
- helpFunc
+ helpFunc
fi
# Handle redirecting to specific functions based on arguments
case "${1}" in
- "-w" | "whitelist" ) whitelistFunc "$@";;
- "-b" | "blacklist" ) blacklistFunc "$@";;
- "-d" | "debug" ) debugFunc;;
- "-f" | "flush" ) flushFunc;;
- "-up" | "updatePihole" ) updatePiholeFunc;;
- "-r" | "reconfigure" ) reconfigurePiholeFunc;;
- "-g" | "updateGravity" ) updateGravityFunc "$@";;
- "-s" | "setupLCD" ) setupLCDFunction;;
- "-c" | "chronometer" ) chronometerFunc "$@";;
- "-h" | "help" ) helpFunc;;
- "-v" | "version" ) versionFunc "$@";;
- "-q" | "query" ) queryFunc "$@";;
- "-l" | "logging" ) piholeLogging "$@";;
- "uninstall" ) uninstallFunc;;
- "enable" ) piholeEnable 1;;
- "disable" ) piholeEnable 0;;
- "status" ) piholeStatus "$2";;
- "restartdns" ) restartDNS;;
- * ) helpFunc;;
+ "-w" | "whitelist" ) whitelistFunc "$@";;
+ "-b" | "blacklist" ) blacklistFunc "$@";;
+ "-d" | "debug" ) debugFunc;;
+ "-f" | "flush" ) flushFunc;;
+ "-up" | "updatePihole" ) updatePiholeFunc;;
+ "-r" | "reconfigure" ) reconfigurePiholeFunc;;
+ "-g" | "updateGravity" ) updateGravityFunc "$@";;
+ "-s" | "setupLCD" ) setupLCDFunction;;
+ "-c" | "chronometer" ) chronometerFunc "$@";;
+ "-h" | "help" ) helpFunc;;
+ "-v" | "version" ) versionFunc "$@";;
+ "-q" | "query" ) queryFunc "$@";;
+ "-l" | "logging" ) piholeLogging "$@";;
+ "uninstall" ) uninstallFunc;;
+ "enable" ) piholeEnable 1;;
+ "disable" ) piholeEnable 0;;
+ "status" ) piholeStatus "$2";;
+ "restartdns" ) restartDNS;;
+ * ) helpFunc;;
esac
From dfb4ac03653f6b83a168dcb1b0976535921b18de Mon Sep 17 00:00:00 2001
From: Dan Schaper
Date: Wed, 2 Nov 2016 09:52:15 -0700
Subject: [PATCH 071/228] Keep .yml's from going to user local repos.
---
.gitignore | 1 +
pihole | 2 +-
2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/.gitignore b/.gitignore
index 0e0d4b99..19b458d3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,3 +3,4 @@
*.swp
__pycache__
.cache
+*.yml
diff --git a/pihole b/pihole
index a1c03420..758aa660 100755
--- a/pihole
+++ b/pihole
@@ -62,7 +62,7 @@ setupLCDFunction() {
}
queryFunc() {
- domain=$2
+ domain="${2}"
for list in /etc/pihole/list.*; do
count=$(grep ${domain} $list | wc -l)
echo "::: ${list} (${count} results)"
From 1d64ad1ccd13c485c7def7d0fa27acf5a1979e63 Mon Sep 17 00:00:00 2001
From: Dan Schaper
Date: Wed, 2 Nov 2016 10:39:27 -0700
Subject: [PATCH 072/228] Stash all changed files, clean directory and pull
updates.
---
advanced/Scripts/update.sh | 16 ++++++++++------
pihole | 21 +++++++++++----------
2 files changed, 21 insertions(+), 16 deletions(-)
diff --git a/advanced/Scripts/update.sh b/advanced/Scripts/update.sh
index 549e5176..c12248a9 100644
--- a/advanced/Scripts/update.sh
+++ b/advanced/Scripts/update.sh
@@ -28,8 +28,8 @@ is_repo() {
prep_dirs() {
# Prepare directory for local repository building
- local dir_to_clean="${1}"
- rm -rf "${dir_to_clean}" &> /dev/null
+ local directory="${1}"
+ rm -rf "${directory}" &> /dev/null
return
}
@@ -48,9 +48,13 @@ update_repo() {
local dest_dir="${1}"
# Pull the latest commits
echo -n "::: Updating repository in ${dest_dir}..."
- cd "${1}" || exit 1
- git stash -q > /dev/null || exit $?
- git pull -q > /dev/null || exit $?
+
+ # Stash all files not tracked for later retrieval
+ git -C "${dest_dir}" stash --all --quiet &> /dev/null || false
+ # Force a clean working directory for cloning
+ git -C "${dest_dir}" clean --force -d &> /dev/null || false
+ # Fetch latest changes and apply
+ git -C "${dest_dir}" pull --quiet &> /dev/null || false
echo " done!"
}
@@ -62,7 +66,7 @@ getGitFiles() {
echo ":::"
echo "::: Checking for existing repository..."
if is_repo "${directory}"; then
- update_repo "${directory}"
+ update_repo "${directory}" || (echo "*** Error: Could not update local repository. Contact support."; exit 1)
else
make_repo "${directory}" "${remoteRepo}"
fi
diff --git a/pihole b/pihole
index 758aa660..83046675 100755
--- a/pihole
+++ b/pihole
@@ -10,6 +10,7 @@
# the Free Software Foundation, either version 2 of the License, or
# (at your option) any later version.
+PI_HOLE_SCRIPT_DIR="/opt/pihole"
# Must be root to use this tool
if [[ ! $EUID -eq 0 ]];then
if [ -x "$(command -v sudo)" ];then
@@ -22,27 +23,27 @@ if [[ ! $EUID -eq 0 ]];then
fi
whitelistFunc() {
- /opt/pihole/list.sh "$@"
+ "${PI_HOLE_SCRIPT_DIR}"/list.sh "$@"
exit 0
}
blacklistFunc() {
- /opt/pihole/list.sh "$@"
+ "${PI_HOLE_SCRIPT_DIR}"/list.sh "$@"
exit 0
}
debugFunc() {
- /opt/pihole/piholeDebug.sh
+ "${PI_HOLE_SCRIPT_DIR}"/piholeDebug.sh
exit 0
}
flushFunc() {
- /opt/pihole/piholeLogFlush.sh
+ "${PI_HOLE_SCRIPT_DIR}"/piholeLogFlush.sh
exit 0
}
updatePiholeFunc() {
- /opt/pihole/update.sh
+ "${PI_HOLE_SCRIPT_DIR}"/update.sh
exit 0
}
@@ -52,12 +53,12 @@ reconfigurePiholeFunc() {
}
updateGravityFunc() {
- /opt/pihole/gravity.sh "$@"
+ "${PI_HOLE_SCRIPT_DIR}"/gravity.sh "$@"
exit 0
}
setupLCDFunction() {
- /opt/pihole/setupLCD.sh
+ "${PI_HOLE_SCRIPT_DIR}"/setupLCD.sh
exit 0
}
@@ -76,19 +77,19 @@ queryFunc() {
chronometerFunc() {
shift
- /opt/pihole/chronometer.sh "$@"
+ "${PI_HOLE_SCRIPT_DIR}"/chronometer.sh "$@"
exit 0
}
uninstallFunc() {
- /opt/pihole/uninstall.sh
+ "${PI_HOLE_SCRIPT_DIR}"/uninstall.sh
exit 0
}
versionFunc() {
shift
- /opt/pihole/version.sh "$@"
+ "${PI_HOLE_SCRIPT_DIR}"/version.sh "$@"
exit 0
}
From 34be601dd7f8f6c84304ba3b138f457ca56431ed Mon Sep 17 00:00:00 2001
From: Dan Schaper
Date: Wed, 2 Nov 2016 10:42:05 -0700
Subject: [PATCH 073/228] Test for lexicographically less than tag version.
---
advanced/Scripts/update.sh | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/advanced/Scripts/update.sh b/advanced/Scripts/update.sh
index c12248a9..c20357e9 100644
--- a/advanced/Scripts/update.sh
+++ b/advanced/Scripts/update.sh
@@ -111,7 +111,7 @@ main() {
echo "::: Everything is up to date!"
exit 0
- elif [[ "${pihole_version_current}" == "${pihole_version_latest}" ]] && [[ "${web_version_current}" != "${web_version_latest}" ]]; then
+ elif [[ "${pihole_version_current}" == "${pihole_version_latest}" ]] && [[ "${web_version_current}" < "${web_version_latest}" ]]; then
echo ":::"
echo "::: Pi-hole Web Admin files out of date"
getGitFiles "${ADMIN_INTERFACE_DIR}" "${ADMIN_INTERFACE_GIT_URL}"
@@ -119,14 +119,14 @@ main() {
web_version_current="$(/usr/local/bin/pihole -v -a -c)"
web_updated=true
- elif [[ "${pihole_version_current}" != "${pihole_version_latest}" ]] && [[ "${web_version_current}" == "${web_version_latest}" ]]; then
+ elif [[ "${pihole_version_current}" < "${pihole_version_latest}" ]] && [[ "${web_version_current}" == "${web_version_latest}" ]]; then
echo "::: Pi-hole core files out of date"
getGitFiles "${PI_HOLE_FILES_DIR}" "${PI_HOLE_GIT_URL}"
/etc/.pihole/automated\ install/basic-install.sh --reconfigure --unattended || echo "Unable to complete update, contact Pi-hole" && exit 1
pihole_version_current="$(/usr/local/bin/pihole -v -p -c)"
core_updated=true
- elif [[ "${pihole_version_current}" != "${pihole_version_latest}" ]] && [[ "${web_version_current}" != "${web_version_latest}" ]]; then
+ elif [[ "${pihole_version_current}" < "${pihole_version_latest}" ]] && [[ "${web_version_current}" < "${web_version_latest}" ]]; then
echo "::: Updating Everything"
getGitFiles "${PI_HOLE_FILES_DIR}" "${PI_HOLE_GIT_URL}"
/etc/.pihole/automated\ install/basic-install.sh --unattended || echo "Unable to complete update, contact Pi-hole" && exit 1
From b8a5ed710ea9c2c3e8bce927d328fed438ce8410 Mon Sep 17 00:00:00 2001
From: Dan Schaper
Date: Wed, 2 Nov 2016 10:51:09 -0700
Subject: [PATCH 074/228] Take echos out of utility functions and move up a
level.
---
advanced/Scripts/update.sh | 15 +++++++++------
1 file changed, 9 insertions(+), 6 deletions(-)
diff --git a/advanced/Scripts/update.sh b/advanced/Scripts/update.sh
index c20357e9..089cad5f 100644
--- a/advanced/Scripts/update.sh
+++ b/advanced/Scripts/update.sh
@@ -22,6 +22,7 @@ readonly PI_HOLE_FILES_DIR="/etc/.pihole"
is_repo() {
# Use git to check if directory is currently under VCS, return the value
local directory="${1}"
+
git -C "${directory}" status --short &> /dev/null
return
}
@@ -29,18 +30,18 @@ is_repo() {
prep_dirs() {
# Prepare directory for local repository building
local directory="${1}"
+
rm -rf "${directory}" &> /dev/null
return
}
make_repo() {
# Remove the non-repod interface and clone the interface
- local source_repo="${2}"
- local dest_dir="${1}"
+ local remoteRepo="${2}"
+ local directory="${1}"
- echo -n "::: Cloning ${source_repo} into ${dest_dir}..."
- if (prep_dirs "${dest_dir}" && git clone -q --depth 1 "${source_repo}" "${dest_dir}" > /dev/null); then \
- echo " done!" || (echo "Unable to clone repository, please contact support"; exit false)
+ if ! (prep_dirs "${directory}" && git clone -q --depth 1 "${remoteRepo}" "${directory}" > /dev/null); then \
+ return false
fi
}
@@ -68,7 +69,9 @@ getGitFiles() {
if is_repo "${directory}"; then
update_repo "${directory}" || (echo "*** Error: Could not update local repository. Contact support."; exit 1)
else
- make_repo "${directory}" "${remoteRepo}"
+ echo -n "::: Cloning ${remoteRepo} into ${directory}..."
+ make_repo "${directory}" "${remoteRepo}" || (echo "Unable to clone repository, please contact support"; exit 1)
+ echo " done!"
fi
}
From bd68db51e061ac7dd76a50f3a3162d1f298b7833 Mon Sep 17 00:00:00 2001
From: Dan Schaper
Date: Wed, 2 Nov 2016 11:01:50 -0700
Subject: [PATCH 075/228] ShellCheck split local declaration and assignment.
---
advanced/Scripts/update.sh | 19 +++++++++++--------
1 file changed, 11 insertions(+), 8 deletions(-)
diff --git a/advanced/Scripts/update.sh b/advanced/Scripts/update.sh
index 089cad5f..30f03e2e 100644
--- a/advanced/Scripts/update.sh
+++ b/advanced/Scripts/update.sh
@@ -40,9 +40,8 @@ make_repo() {
local remoteRepo="${2}"
local directory="${1}"
- if ! (prep_dirs "${directory}" && git clone -q --depth 1 "${remoteRepo}" "${directory}" > /dev/null); then \
- return false
- fi
+ (prep_dirs "${directory}" && git clone -q --depth 1 "${remoteRepo}" "${directory}" > /dev/null)
+ return
}
update_repo() {
@@ -63,7 +62,7 @@ getGitFiles() {
# Setup git repos for directory and repository passed
# as arguments 1 and 2
local directory="${1}"
- local remoteRepo="{$2}"
+ local remoteRepo="${2}"
echo ":::"
echo "::: Checking for existing repository..."
if is_repo "${directory}"; then
@@ -76,6 +75,10 @@ getGitFiles() {
}
main() {
+ local pihole_version_current
+ local pihole_version_latest
+ local web_version_current
+ local web_version_latest
if ! is_repo "${PI_HOLE_FILES_DIR}" || ! is_repo "${ADMIN_INTERFACE_DIR}" ; then #This is unlikely
echo "::: Critical Error: One or more Pi-Hole repos are missing from system!"
@@ -85,14 +88,14 @@ main() {
echo "::: Checking for updates..."
# Checks Pi-hole version > pihole only > current local git repo version : returns string in format vX.X.X
- local pihole_version_current="$(/usr/local/bin/pihole -v -p -c)"
+ pihole_version_current="$(/usr/local/bin/pihole -v -p -c)"
# Checks Pi-hole version > pihole only > remote upstream repo version : returns string in format vX.X.X
- local pihole_version_latest="$(/usr/local/bin/pihole -v -p -l)"
+ pihole_version_latest="$(/usr/local/bin/pihole -v -p -l)"
# Checks Pi-hole version > admin only > current local git repo version : returns string in format vX.X.X
- local web_version_current="$(/usr/local/bin/pihole -v -a -c)"
+ web_version_current="$(/usr/local/bin/pihole -v -a -c)"
# Checks Pi-hole version > admin only > remote upstream repo version : returns string in format vX.X.X
- local web_version_latest="$(/usr/local/bin/pihole -v -a -l)"
+ web_version_latest="$(/usr/local/bin/pihole -v -a -l)"
# Logic
# If latest versions are blank - we've probably hit Github rate limit (stop running `pihole -up so often!):
From 3f61aea7fcb808a2b616650653ce996f1d1b2475 Mon Sep 17 00:00:00 2001
From: Dan Schaper
Date: Wed, 2 Nov 2016 11:09:53 -0700
Subject: [PATCH 076/228] Utility functions fully quiet now. Calling functions
have the echos.
---
advanced/Scripts/update.sh | 14 ++++++++------
1 file changed, 8 insertions(+), 6 deletions(-)
diff --git a/advanced/Scripts/update.sh b/advanced/Scripts/update.sh
index 30f03e2e..de9db399 100644
--- a/advanced/Scripts/update.sh
+++ b/advanced/Scripts/update.sh
@@ -45,17 +45,17 @@ make_repo() {
}
update_repo() {
- local dest_dir="${1}"
+ local directory="${1}"
+ local retVal=0
# Pull the latest commits
- echo -n "::: Updating repository in ${dest_dir}..."
# Stash all files not tracked for later retrieval
- git -C "${dest_dir}" stash --all --quiet &> /dev/null || false
+ git -C "${directory}" stash --all --quiet &> /dev/null || ${retVal}=1
# Force a clean working directory for cloning
- git -C "${dest_dir}" clean --force -d &> /dev/null || false
+ git -C "${directory}" clean --force -d &> /dev/null || ${retVal}=1
# Fetch latest changes and apply
- git -C "${dest_dir}" pull --quiet &> /dev/null || false
- echo " done!"
+ git -C "${directory}" pull --quiet &> /dev/null || ${retVal}=1
+ return ${retVal}
}
getGitFiles() {
@@ -66,7 +66,9 @@ getGitFiles() {
echo ":::"
echo "::: Checking for existing repository..."
if is_repo "${directory}"; then
+ echo -n "::: Updating repository in ${directory}..."
update_repo "${directory}" || (echo "*** Error: Could not update local repository. Contact support."; exit 1)
+ echo " done!"
else
echo -n "::: Cloning ${remoteRepo} into ${directory}..."
make_repo "${directory}" "${remoteRepo}" || (echo "Unable to clone repository, please contact support"; exit 1)
From c1a3f003e802f778ec2dfe102808a1324ed74f91 Mon Sep 17 00:00:00 2001
From: Dan Schaper
Date: Wed, 2 Nov 2016 11:18:13 -0700
Subject: [PATCH 077/228] Rename the only utilty function left that didn't say
`repo`
---
advanced/Scripts/update.sh | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/advanced/Scripts/update.sh b/advanced/Scripts/update.sh
index de9db399..da88127f 100644
--- a/advanced/Scripts/update.sh
+++ b/advanced/Scripts/update.sh
@@ -27,7 +27,7 @@ is_repo() {
return
}
-prep_dirs() {
+prep_repo() {
# Prepare directory for local repository building
local directory="${1}"
@@ -40,7 +40,7 @@ make_repo() {
local remoteRepo="${2}"
local directory="${1}"
- (prep_dirs "${directory}" && git clone -q --depth 1 "${remoteRepo}" "${directory}" > /dev/null)
+ (prep_repo "${directory}" && git clone -q --depth 1 "${remoteRepo}" "${directory}" > /dev/null)
return
}
From 3cf6a65da9ecb880f65785014849c7f7bd6a7639 Mon Sep 17 00:00:00 2001
From: Dan Schaper
Date: Wed, 2 Nov 2016 11:32:53 -0700
Subject: [PATCH 078/228] Remove *.yml ignoring
Travis YAML might not be good to ignore.
---
.gitignore | 1 -
1 file changed, 1 deletion(-)
diff --git a/.gitignore b/.gitignore
index 19b458d3..0e0d4b99 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,4 +3,3 @@
*.swp
__pycache__
.cache
-*.yml
From 3d43e1568cb6d88a139cf09a2dbb5aba68bed43b Mon Sep 17 00:00:00 2001
From: Dan Schaper
Date: Wed, 2 Nov 2016 11:39:22 -0700
Subject: [PATCH 079/228] Use explicit calls for function to self-document
---
.gitignore | 3 ++-
advanced/Scripts/update.sh | 14 +++++---------
2 files changed, 7 insertions(+), 10 deletions(-)
diff --git a/.gitignore b/.gitignore
index 19b458d3..c4b497a0 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,4 +3,5 @@
*.swp
__pycache__
.cache
-*.yml
+.pullapprove.yml
+
diff --git a/advanced/Scripts/update.sh b/advanced/Scripts/update.sh
index da88127f..0b26ac7a 100644
--- a/advanced/Scripts/update.sh
+++ b/advanced/Scripts/update.sh
@@ -89,15 +89,11 @@ main() {
fi
echo "::: Checking for updates..."
- # Checks Pi-hole version > pihole only > current local git repo version : returns string in format vX.X.X
- pihole_version_current="$(/usr/local/bin/pihole -v -p -c)"
- # Checks Pi-hole version > pihole only > remote upstream repo version : returns string in format vX.X.X
- pihole_version_latest="$(/usr/local/bin/pihole -v -p -l)"
-
- # Checks Pi-hole version > admin only > current local git repo version : returns string in format vX.X.X
- web_version_current="$(/usr/local/bin/pihole -v -a -c)"
- # Checks Pi-hole version > admin only > remote upstream repo version : returns string in format vX.X.X
- web_version_latest="$(/usr/local/bin/pihole -v -a -l)"
+ # Checks Pi-hole version string in format vX.X.X
+ pihole_version_current="$(/usr/local/bin/pihole version --pihole --current)"
+ pihole_version_latest="$(/usr/local/bin/pihole version --pihole --latest)"
+ web_version_current="$(/usr/local/bin/pihole version --admin --current)"
+ web_version_latest="$(/usr/local/bin/pihole version --admin --latest)"
# Logic
# If latest versions are blank - we've probably hit Github rate limit (stop running `pihole -up so often!):
From f7266ef4c8280b8e332790d4278301c6bcabefcf Mon Sep 17 00:00:00 2001
From: Dan Schaper
Date: Wed, 2 Nov 2016 12:07:59 -0700
Subject: [PATCH 080/228] Version remote check returns -1 on failure to detect
curl silent failing. Update detects loss of contact to GitHub or fallthrough
condition and reports to user.
---
advanced/Scripts/update.sh | 26 +++++++++++++++-----------
advanced/Scripts/version.sh | 4 ++--
2 files changed, 17 insertions(+), 13 deletions(-)
diff --git a/advanced/Scripts/update.sh b/advanced/Scripts/update.sh
index 0b26ac7a..9b17168b 100644
--- a/advanced/Scripts/update.sh
+++ b/advanced/Scripts/update.sh
@@ -82,11 +82,11 @@ main() {
local web_version_current
local web_version_latest
- if ! is_repo "${PI_HOLE_FILES_DIR}" || ! is_repo "${ADMIN_INTERFACE_DIR}" ; then #This is unlikely
- echo "::: Critical Error: One or more Pi-Hole repos are missing from system!"
- echo "::: Please re-run install script from https://github.com/pi-hole/pi-hole"
- exit 1;
- fi
+# if ! is_repo "${PI_HOLE_FILES_DIR}" || ! is_repo "${ADMIN_INTERFACE_DIR}" ; then #This is unlikely
+# echo "::: Critical Error: One or more Pi-Hole repos are missing from system!"
+# echo "::: Please re-run install script from https://github.com/pi-hole/pi-hole"
+# exit 1;
+# fi
echo "::: Checking for updates..."
# Checks Pi-hole version string in format vX.X.X
@@ -95,6 +95,11 @@ main() {
web_version_current="$(/usr/local/bin/pihole version --admin --current)"
web_version_latest="$(/usr/local/bin/pihole version --admin --latest)"
+ if [[ "${pihole_version_latest}" -eq "-1" || "${web_version_latest}" -eq -1 ]]; then
+ echo "*** Unable to contact GitHub for latest version. Please try again later, contact support if this continues."
+ exit 1
+ fi
+
# Logic
# If latest versions are blank - we've probably hit Github rate limit (stop running `pihole -up so often!):
# Update anyway
@@ -120,35 +125,34 @@ main() {
echo "::: Pi-hole Web Admin files out of date"
getGitFiles "${ADMIN_INTERFACE_DIR}" "${ADMIN_INTERFACE_GIT_URL}"
- web_version_current="$(/usr/local/bin/pihole -v -a -c)"
web_updated=true
elif [[ "${pihole_version_current}" < "${pihole_version_latest}" ]] && [[ "${web_version_current}" == "${web_version_latest}" ]]; then
echo "::: Pi-hole core files out of date"
getGitFiles "${PI_HOLE_FILES_DIR}" "${PI_HOLE_GIT_URL}"
/etc/.pihole/automated\ install/basic-install.sh --reconfigure --unattended || echo "Unable to complete update, contact Pi-hole" && exit 1
- pihole_version_current="$(/usr/local/bin/pihole -v -p -c)"
core_updated=true
elif [[ "${pihole_version_current}" < "${pihole_version_latest}" ]] && [[ "${web_version_current}" < "${web_version_latest}" ]]; then
echo "::: Updating Everything"
getGitFiles "${PI_HOLE_FILES_DIR}" "${PI_HOLE_GIT_URL}"
/etc/.pihole/automated\ install/basic-install.sh --unattended || echo "Unable to complete update, contact Pi-hole" && exit 1
- # Checks Pi-hole version > admin only > current local git repo version : returns string in format vX.X.X
- web_version_current="$(/usr/local/bin/pihole -v -a -c)"
- # Checks Pi-hole version > admin only > current local git repo version : returns string in format vX.X.X
- pihole_version_current="$(/usr/local/bin/pihole -v -p -c)"
web_updated=true
core_updated=true
+ else
+ echo "*** Update script has malfunctioned, fallthrough reached. Please contact support"
+ exit 1
fi
if [[ "${web_updated}" == true ]]; then
+ web_version_current="$(/usr/local/bin/pihole version --admin --current)"
echo ":::"
echo "::: Web Admin version is now at ${web_version_current}"
echo "::: If you had made any changes in '/var/www/html/admin/', they have been stashed using 'git stash'"
fi
if [[ "${core_updated}" == true ]]; then
+ pihole_version_current="$(/usr/local/bin/pihole version --pihole --current)"
echo ":::"
echo "::: Pi-hole version is now at ${pihole_version_current}"
echo "::: If you had made any changes in '/etc/.pihole/', they have been stashed using 'git stash'"
diff --git a/advanced/Scripts/version.sh b/advanced/Scripts/version.sh
index ca78032a..86375415 100644
--- a/advanced/Scripts/version.sh
+++ b/advanced/Scripts/version.sh
@@ -58,10 +58,10 @@ coreOutput() {
if [[ "${latest}" == true && "${current}" == false ]]; then
piholeVersionLatest=$(curl -s https://api.github.com/repos/pi-hole/pi-hole/releases/latest | grep -Po '"tag_name":.*?[^\\]",' | perl -pe 's/"tag_name": "//; s/^"//; s/",$//')
- echo ${piholeVersionLatest}
+ echo ${piholeVersionLatest:-"-1"}
elif [[ "${latest}" == false && "${current}" == true ]]; then
piholeVersion=$(cd /etc/.pihole/ && git describe --tags --abbrev=0)
- echo ${piholeVersion}
+ echo ${piholeVersion:-"-1"}
else
piholeVersion=$(cd /etc/.pihole/ && git describe --tags --abbrev=0)
piholeVersionLatest=$(curl -s https://api.github.com/repos/pi-hole/pi-hole/releases/latest | grep -Po '"tag_name":.*?[^\\]",' | perl -pe 's/"tag_name": "//; s/^"//; s/",$//')
From 603ec997baa355396ea2d7b0bf358126891e5b26 Mon Sep 17 00:00:00 2001
From: Dan Schaper
Date: Wed, 2 Nov 2016 12:09:33 -0700
Subject: [PATCH 081/228] Remove testing block.
---
advanced/Scripts/update.sh | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/advanced/Scripts/update.sh b/advanced/Scripts/update.sh
index 9b17168b..008f257f 100644
--- a/advanced/Scripts/update.sh
+++ b/advanced/Scripts/update.sh
@@ -82,11 +82,11 @@ main() {
local web_version_current
local web_version_latest
-# if ! is_repo "${PI_HOLE_FILES_DIR}" || ! is_repo "${ADMIN_INTERFACE_DIR}" ; then #This is unlikely
-# echo "::: Critical Error: One or more Pi-Hole repos are missing from system!"
-# echo "::: Please re-run install script from https://github.com/pi-hole/pi-hole"
-# exit 1;
-# fi
+ if ! is_repo "${PI_HOLE_FILES_DIR}" || ! is_repo "${ADMIN_INTERFACE_DIR}" ; then #This is unlikely
+ echo "::: Critical Error: One or more Pi-Hole repos are missing from system!"
+ echo "::: Please re-run install script from https://github.com/pi-hole/pi-hole"
+ exit 1;
+ fi
echo "::: Checking for updates..."
# Checks Pi-hole version string in format vX.X.X
From f7d0de53bb6ac7e1e9c6e27f8a4c05b1c906514d Mon Sep 17 00:00:00 2001
From: Dan Schaper
Date: Wed, 2 Nov 2016 12:11:34 -0700
Subject: [PATCH 082/228] Compare string to string.
---
advanced/Scripts/update.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/advanced/Scripts/update.sh b/advanced/Scripts/update.sh
index 008f257f..556270b2 100644
--- a/advanced/Scripts/update.sh
+++ b/advanced/Scripts/update.sh
@@ -95,7 +95,7 @@ main() {
web_version_current="$(/usr/local/bin/pihole version --admin --current)"
web_version_latest="$(/usr/local/bin/pihole version --admin --latest)"
- if [[ "${pihole_version_latest}" -eq "-1" || "${web_version_latest}" -eq -1 ]]; then
+ if [[ "${pihole_version_latest}" -eq "-1" || "${web_version_latest}" -eq "-1" ]]; then
echo "*** Unable to contact GitHub for latest version. Please try again later, contact support if this continues."
exit 1
fi
From 4b7b859db91befd53493f9257ff61e72d44910d2 Mon Sep 17 00:00:00 2001
From: Dan Schaper
Date: Wed, 2 Nov 2016 12:29:55 -0700
Subject: [PATCH 083/228] Gotta catch 'em all...'
---
advanced/Scripts/version.sh | 18 ++++++++++--------
1 file changed, 10 insertions(+), 8 deletions(-)
diff --git a/advanced/Scripts/version.sh b/advanced/Scripts/version.sh
index 86375415..fc74f8a0 100644
--- a/advanced/Scripts/version.sh
+++ b/advanced/Scripts/version.sh
@@ -14,6 +14,8 @@
latest=false
current=false
+DEFAULT="-1"
+
normalOutput() {
piholeVersion=$(cd /etc/.pihole/ && git describe --tags --abbrev=0)
webVersion=$(cd /var/www/html/admin/ && git describe --tags --abbrev=0)
@@ -21,8 +23,8 @@ normalOutput() {
piholeVersionLatest=$(curl -s https://api.github.com/repos/pi-hole/pi-hole/releases/latest | grep -Po '"tag_name":.*?[^\\]",' | perl -pe 's/"tag_name": "//; s/^"//; s/",$//')
webVersionLatest=$(curl -s https://api.github.com/repos/pi-hole/AdminLTE/releases/latest | grep -Po '"tag_name":.*?[^\\]",' | perl -pe 's/"tag_name": "//; s/^"//; s/",$//')
- echo "::: Pi-hole version is ${piholeVersion} (Latest version is ${piholeVersionLatest})"
- echo "::: Web-Admin version is ${webVersion} (Latest version is ${webVersionLatest})"
+ echo "::: Pi-hole version is ${piholeVersion} (Latest version is ${piholeVersionLatest:-${DEFAULT}})"
+ echo "::: Web-Admin version is ${webVersion} (Latest version is ${webVersionLatest:-${DEFAULT}})"
}
webOutput() {
@@ -36,14 +38,14 @@ webOutput() {
if [[ "${latest}" == true && "${current}" == false ]]; then
webVersionLatest=$(curl -s https://api.github.com/repos/pi-hole/AdminLTE/releases/latest | grep -Po '"tag_name":.*?[^\\]",' | perl -pe 's/"tag_name": "//; s/^"//; s/",$//')
- echo ${webVersionLatest}
+ echo "${webVersionLatest:--1}"
elif [[ "${latest}" == false && "${current}" == true ]]; then
webVersion=$(cd /var/www/html/admin/ && git describe --tags --abbrev=0)
- echo ${webVersion}
+ echo "${webVersion}"
else
webVersion=$(cd /var/www/html/admin/ && git describe --tags --abbrev=0)
webVersionLatest=$(curl -s https://api.github.com/repos/pi-hole/AdminLTE/releases/latest | grep -Po '"tag_name":.*?[^\\]",' | perl -pe 's/"tag_name": "//; s/^"//; s/",$//')
- echo "::: Web-Admin version is $webVersion (Latest version is $webVersionLatest)"
+ echo "::: Web-Admin version is ${webVersion} (Latest version is ${webVersionLatest:-${DEFAULT}})"
fi
}
@@ -58,14 +60,14 @@ coreOutput() {
if [[ "${latest}" == true && "${current}" == false ]]; then
piholeVersionLatest=$(curl -s https://api.github.com/repos/pi-hole/pi-hole/releases/latest | grep -Po '"tag_name":.*?[^\\]",' | perl -pe 's/"tag_name": "//; s/^"//; s/",$//')
- echo ${piholeVersionLatest:-"-1"}
+ echo "${piholeVersionLatest:--1}"
elif [[ "${latest}" == false && "${current}" == true ]]; then
piholeVersion=$(cd /etc/.pihole/ && git describe --tags --abbrev=0)
- echo ${piholeVersion:-"-1"}
+ echo "${piholeVersion}"
else
piholeVersion=$(cd /etc/.pihole/ && git describe --tags --abbrev=0)
piholeVersionLatest=$(curl -s https://api.github.com/repos/pi-hole/pi-hole/releases/latest | grep -Po '"tag_name":.*?[^\\]",' | perl -pe 's/"tag_name": "//; s/^"//; s/",$//')
- echo "::: Pi-hole version is $piholeVersion (Latest version is $piholeVersionLatest)"
+ echo "::: Pi-hole version is ${piholeVersion} (Latest version is ${piholeVersionLatest:-${DEFAULT}})"
fi
}
From 2f976504e829680b4b7ded53561297bd2fc6a330 Mon Sep 17 00:00:00 2001
From: Promofaux
Date: Wed, 2 Nov 2016 20:06:21 +0000
Subject: [PATCH 084/228] switch out -eq for ==
---
advanced/Scripts/update.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/advanced/Scripts/update.sh b/advanced/Scripts/update.sh
index 556270b2..10728cd8 100644
--- a/advanced/Scripts/update.sh
+++ b/advanced/Scripts/update.sh
@@ -95,7 +95,7 @@ main() {
web_version_current="$(/usr/local/bin/pihole version --admin --current)"
web_version_latest="$(/usr/local/bin/pihole version --admin --latest)"
- if [[ "${pihole_version_latest}" -eq "-1" || "${web_version_latest}" -eq "-1" ]]; then
+ if [[ "${pihole_version_latest}" == "-1" || "${web_version_latest}" == "-1" ]]; then
echo "*** Unable to contact GitHub for latest version. Please try again later, contact support if this continues."
exit 1
fi
From b429e890add80798222bcdae83c66ef50e627e1e Mon Sep 17 00:00:00 2001
From: Promofaux
Date: Wed, 2 Nov 2016 20:16:36 +0000
Subject: [PATCH 085/228] move web interface message inside "if not update"
block. Check for pi-hole deps AFTER whiptails
---
.idea/codeStyleSettings.xml | 22 ++++++++++++++++++++++
automated install/basic-install.sh | 10 +++++-----
2 files changed, 27 insertions(+), 5 deletions(-)
create mode 100644 .idea/codeStyleSettings.xml
diff --git a/.idea/codeStyleSettings.xml b/.idea/codeStyleSettings.xml
new file mode 100644
index 00000000..a571e63f
--- /dev/null
+++ b/.idea/codeStyleSettings.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/automated install/basic-install.sh b/automated install/basic-install.sh
index fb048ec2..2e8ae77d 100755
--- a/automated install/basic-install.sh
+++ b/automated install/basic-install.sh
@@ -1061,9 +1061,6 @@ main() {
# Install packages used by this installation script
install_dependent_packages INSTALLER_DEPS[@]
- # Install packages used by the Pi-hole
- install_dependent_packages PIHOLE_DEPS[@]
-
if [[ "${reconfigure}" == true ]]; then
echo "::: --reconfigure passed to install script. Not downloading/updating local repos"
else
@@ -1094,11 +1091,14 @@ main() {
setLogging
# Install packages used by the Pi-hole
- install_dependent_packages PIHOLE_DEPS[@]
+ install_dependent_packages PIHOLE_DEPS[@]
# Install and log everything to a file
installPihole | tee ${tmpLog}
else
+ # update packages used by the Pi-hole
+ install_dependent_packages PIHOLE_DEPS[@]
+
updatePihole | tee ${tmpLog}
fi
@@ -1124,13 +1124,13 @@ main() {
echo "::: ${IPV6_ADDRESS}"
echo ":::"
echo "::: If you set a new IP address, you should restart the Pi."
+ echo "::: View the web interface at http://pi.hole/admin or http://${IPV4_ADDRESS%/*}/admin"
else
echo "::: Update complete!"
fi
echo ":::"
echo "::: The install log is located at: /etc/pihole/install.log"
- echo "::: View the web interface at http://pi.hole/admin or http://${IPV4_ADDRESS%/*}/admin"
}
if [[ -z "$PHTEST" ]] ; then
From d273b4b48b0d6f44e3be63c6be8a8b88ba1e7ba8 Mon Sep 17 00:00:00 2001
From: Promofaux
Date: Wed, 2 Nov 2016 20:57:56 +0000
Subject: [PATCH 086/228] Check for missing index.html, replace if missing.
---
automated install/basic-install.sh | 19 +++++++++++++++++--
1 file changed, 17 insertions(+), 2 deletions(-)
diff --git a/automated install/basic-install.sh b/automated install/basic-install.sh
index 2e8ae77d..aef1b443 100755
--- a/automated install/basic-install.sh
+++ b/automated install/basic-install.sh
@@ -822,9 +822,24 @@ CreateLogFile() {
installPiholeWeb() {
# Install the web interface
echo ":::"
- echo -n "::: Installing pihole custom index page..."
+ echo "::: Installing pihole custom index page..."
if [ -d "/var/www/html/pihole" ]; then
- echo " Existing page detected, not overwriting"
+ if [ -f "/var/www/html/pihole/index.html" ]; then
+ echo "::: Existing index.html detected, not overwriting"
+ else
+ echo -n "::: index.html missing, replacing... "
+ cp /etc/.pihole/advanced/index.html /var/www/html/pihole/
+ echo " done!"
+ fi
+
+ if [ -f "/var/www/html/pihole/index.js" ]; then
+ echo "::: Existing index.js detected, not overwriting"
+ else
+ echo -n "::: index.html missing, replacing... "
+ cp /etc/.pihole/advanced/index.js /var/www/html/pihole/
+ echo " done!"
+ fi
+
else
mkdir /var/www/html/pihole
if [ -f /var/www/html/index.lighttpd.html ]; then
From a182a208dca31ec1d28280ecd2a8835ef0fc1181 Mon Sep 17 00:00:00 2001
From: Promofaux
Date: Wed, 2 Nov 2016 21:06:12 +0000
Subject: [PATCH 087/228] Tidy up output
---
automated install/basic-install.sh | 1 +
1 file changed, 1 insertion(+)
diff --git a/automated install/basic-install.sh b/automated install/basic-install.sh
index aef1b443..aa6e6dda 100755
--- a/automated install/basic-install.sh
+++ b/automated install/basic-install.sh
@@ -851,6 +851,7 @@ installPiholeWeb() {
echo " done!"
fi
# Install Sudoer file
+ echo ":::"
echo -n "::: Installing sudoer file..."
mkdir -p /etc/sudoers.d/
cp /etc/.pihole/advanced/pihole.sudo /etc/sudoers.d/pihole
From c452a4569e2fc55f6bc3067a458aa538df3cc28d Mon Sep 17 00:00:00 2001
From: Promofaux
Date: Wed, 2 Nov 2016 21:17:00 +0000
Subject: [PATCH 088/228] .js
---
automated install/basic-install.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/automated install/basic-install.sh b/automated install/basic-install.sh
index aa6e6dda..14d271ef 100755
--- a/automated install/basic-install.sh
+++ b/automated install/basic-install.sh
@@ -835,7 +835,7 @@ installPiholeWeb() {
if [ -f "/var/www/html/pihole/index.js" ]; then
echo "::: Existing index.js detected, not overwriting"
else
- echo -n "::: index.html missing, replacing... "
+ echo -n "::: index.js missing, replacing... "
cp /etc/.pihole/advanced/index.js /var/www/html/pihole/
echo " done!"
fi
From d7d6d6f99107f355a9da8827d8a4de3be50fa271 Mon Sep 17 00:00:00 2001
From: Promofaux
Date: Wed, 2 Nov 2016 21:46:30 +0000
Subject: [PATCH 089/228] Update to use new Var name
---
advanced/Scripts/chronometer.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/advanced/Scripts/chronometer.sh b/advanced/Scripts/chronometer.sh
index bd755453..16ff6fb6 100755
--- a/advanced/Scripts/chronometer.sh
+++ b/advanced/Scripts/chronometer.sh
@@ -22,7 +22,7 @@ today=$(date "+%b %e")
CalcBlockedDomains() {
if [ -e "${gravity}" ]; then
#Are we IPV6 or IPV4?
- if [[ -n "${IPv6_address}" ]]; then
+ if [[ -n "${IPV6_ADDRESS}" ]]; then
#We are IPV6
blockedDomainsTotal=$(wc -l /etc/pihole/gravity.list | awk '{print $1/2}')
else
From a4aeb9a1dd6693b8f6d98bbfafdf4faec58dc4e3 Mon Sep 17 00:00:00 2001
From: Dan Schaper
Date: Wed, 2 Nov 2016 20:07:51 -0700
Subject: [PATCH 090/228] Update README.md
---
README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/README.md b/README.md
index 496816fb..e8c6e55c 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-[![Bountysource](https://www.bountysource.com/badge/tracker?tracker_id=3011939)](https://www.bountysource.com/trackers/3011939-pi-hole-pi-hole?utm_source=3011939&utm_medium=shield&utm_campaign=TRACKER_BADGE) [![Code Climate](https://codeclimate.com/github/pi-hole/pi-hole/badges/gpa.svg)](https://codeclimate.com/github/pi-hole/pi-hole)
+[![Bountysource](https://www.bountysource.com/badge/tracker?tracker_id=3011939)](https://www.bountysource.com/trackers/3011939-pi-hole-pi-hole?utm_source=3011939&utm_medium=shield&utm_campaign=TRACKER_BADGE) [![Code Climate](https://codeclimate.com/github/pi-hole/pi-hole/badges/gpa.svg)](https://codeclimate.com/github/pi-hole/pi-hole) [![Build Status](https://travis-ci.org/pi-hole/pi-hole.svg?branch=development)](https://travis-ci.org/pi-hole/pi-hole)
# Automated Install
From 633095aee1704cc6cced1dc78ea897dac32417f2 Mon Sep 17 00:00:00 2001
From: diginc
Date: Wed, 2 Nov 2016 22:13:05 -0500
Subject: [PATCH 091/228] switch to consistent style
---
automated install/basic-install.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/automated install/basic-install.sh b/automated install/basic-install.sh
index 14d271ef..534b194d 100755
--- a/automated install/basic-install.sh
+++ b/automated install/basic-install.sh
@@ -1149,6 +1149,6 @@ main() {
echo "::: The install log is located at: /etc/pihole/install.log"
}
-if [[ -z "$PHTEST" ]] ; then
+if [[ "${PHTEST}" != "TRUE" ]] ; then
main "$@"
fi
From 0d7e06a141ac0bde23f478f878be21e8b7d6cebd Mon Sep 17 00:00:00 2001
From: diginc
Date: Wed, 2 Nov 2016 22:13:39 -0500
Subject: [PATCH 092/228] remove old pytest output file
---
test/shellcheck_failing_output.txt | 76 ------------------------------
1 file changed, 76 deletions(-)
delete mode 100644 test/shellcheck_failing_output.txt
diff --git a/test/shellcheck_failing_output.txt b/test/shellcheck_failing_output.txt
deleted file mode 100644
index c741a8e9..00000000
--- a/test/shellcheck_failing_output.txt
+++ /dev/null
@@ -1,76 +0,0 @@
-============================= test session starts ==============================
-platform linux2 -- Python 2.7.6, pytest-2.9.2, py-1.4.31, pluggy-0.3.1 -- /usr/bin/python
-cachedir: .cache
-rootdir: /home/a/opensource/pi-hole, inifile:
-plugins: cov-2.3.0, bdd-2.17.0, xdist-1.14, testinfra-1.4.0
-collecting ... collected 7 items
-
-test/test_000_build_containers.py::test_build_pihole_image[test/debian.Dockerfile-pytest_pihole:debian] PASSED
-test/test_000_build_containers.py::test_build_pihole_image[test/centos.Dockerfile-pytest_pihole:centos] PASSED
-test/test_automated_install.py::test_setupVars_are_sourced_to_global_scope[debian] PASSED
-test/test_automated_install.py::test_setupVars_are_sourced_to_global_scope[centos] PASSED
-test/test_automated_install.py::test_setupVars_saved_to_file[debian] PASSED
-test/test_automated_install.py::test_setupVars_saved_to_file[centos] PASSED
-test/test_shellcheck.py::test_scripts_pass_shellcheck FAILED
-
-=================================== FAILURES ===================================
-_________________________ test_scripts_pass_shellcheck _________________________
-
- def test_scripts_pass_shellcheck():
- ''' Make sure shellcheck does not find anything wrong with our shell scripts '''
- shellcheck = "find . -name 'update.sh' | while read file; do shellcheck \"$file\"; done;"
- results = run_local(shellcheck)
- print results.stdout
-> assert '' == results.stdout
-E assert '' == '\nIn ./advanced/Scripts/upda...vent glob interpretation.\n\n'
-E +
-E + In ./advanced/Scripts/update.sh line 24:
-E + while [ "$(ps a | awk '{print $1}' | grep "${pid}")" ]; do
-E + ^-- SC2143: Instead of [ -n $(foo | grep bar) ], use foo | grep -q bar .
-E +
-E +
-E + In ./advanced/Scripts/update.sh line 57:
-E + git clone -q --depth 1 "${2}" "${1}" > /dev/null & spinner $!
-E + ^-- SC2086: Double quote to prevent globbing and word splitting.
-E Detailed information truncated (27 more lines), use "-vv" to show
-
-test/test_shellcheck.py:13: AssertionError
------------------------------ Captured stdout call -----------------------------
-
-In ./advanced/Scripts/update.sh line 24:
- while [ "$(ps a | awk '{print $1}' | grep "${pid}")" ]; do
- ^-- SC2143: Instead of [ -n $(foo | grep bar) ], use foo | grep -q bar .
-
-
-In ./advanced/Scripts/update.sh line 57:
- git clone -q --depth 1 "${2}" "${1}" > /dev/null & spinner $!
- ^-- SC2086: Double quote to prevent globbing and word splitting.
-
-
-In ./advanced/Scripts/update.sh line 65:
- git stash -q > /dev/null & spinner $!
- ^-- SC2086: Double quote to prevent globbing and word splitting.
-
-
-In ./advanced/Scripts/update.sh line 66:
- git pull -q > /dev/null & spinner $!
- ^-- SC2086: Double quote to prevent globbing and word splitting.
-
-
-In ./advanced/Scripts/update.sh line 107:
-if [[ ${piholeVersion} == ${piholeVersionLatest} && ${webVersion} == ${webVersionLatest} ]]; then
- ^-- SC2053: Quote the rhs of = in [[ ]] to prevent glob interpretation.
- ^-- SC2053: Quote the rhs of = in [[ ]] to prevent glob interpretation.
-
-
-In ./advanced/Scripts/update.sh line 112:
-elif [[ ${piholeVersion} == ${piholeVersionLatest} && ${webVersion} != ${webVersionLatest} ]]; then
- ^-- SC2053: Quote the rhs of = in [[ ]] to prevent glob interpretation.
-
-
-In ./advanced/Scripts/update.sh line 120:
-elif [[ ${piholeVersion} != ${piholeVersionLatest} && ${webVersion} == ${webVersionLatest} ]]; then
- ^-- SC2053: Quote the rhs of = in [[ ]] to prevent glob interpretation.
-
-
-===================== 1 failed, 6 passed in 24.01 seconds ======================
From d958b3ff65d5cf8de6a9df2c52d37271afefb5ba Mon Sep 17 00:00:00 2001
From: Dan Schaper
Date: Wed, 2 Nov 2016 20:14:04 -0700
Subject: [PATCH 093/228] Remove CodeClimate yaml, Travis new ShellChecker
---
.codeclimate.yml | 3 ---
1 file changed, 3 deletions(-)
delete mode 100644 .codeclimate.yml
diff --git a/.codeclimate.yml b/.codeclimate.yml
deleted file mode 100644
index e1cb3b50..00000000
--- a/.codeclimate.yml
+++ /dev/null
@@ -1,3 +0,0 @@
-engines:
- shellcheck:
- enabled: true
From 05e114173db93f9395866995c004138d1a9e56db Mon Sep 17 00:00:00 2001
From: diginc
Date: Wed, 2 Nov 2016 23:25:13 -0500
Subject: [PATCH 094/228] update comments, add configureFirewall test
* Comments to clarify some of the existing tests
* mock_command to allow recording of calls and mocking return calls in bash
* new configureFirewall test (only the first one of it's many paths)
---
test/test_automated_install.py | 41 ++++++++++++++++++++++++++++++++--
1 file changed, 39 insertions(+), 2 deletions(-)
diff --git a/test/test_automated_install.py b/test/test_automated_install.py
index 458536eb..b720b94d 100644
--- a/test/test_automated_install.py
+++ b/test/test_automated_install.py
@@ -10,8 +10,9 @@ SETUPVARS = {
}
def test_setupVars_are_sourced_to_global_scope(Pihole):
- ''' currently update_dialogs sources setupVars with a dot,
- then various other functions use the variables '''
+ ''' currently update_dialogs sources setupVars with a dot,
+ then various other functions use the variables.
+ This confirms the sourced variables are in scope between functions '''
setup_var_file = 'cat < /etc/pihole/setupVars.conf\n'
for k,v in SETUPVARS.iteritems():
setup_var_file += "{}={}\n".format(k, v)
@@ -64,6 +65,42 @@ def test_setupVars_saved_to_file(Pihole):
for k,v in SETUPVARS.iteritems():
assert "{}={}".format(k, v) in output
+def test_configureFirewall_firewalld_no_errors(Pihole):
+ ''' confirms firewalld rules are applied when appopriate '''
+ mock_command('firewall-cmd', '0', Pihole)
+ configureFirewall = Pihole.run('''
+ bash -c "
+ PHTEST=TRUE
+ source /opt/pihole/basic-install.sh
+ configureFirewall
+ " ''')
+ expected_stdout = '::: Configuring firewalld for httpd and dnsmasq.'
+ assert expected_stdout in configureFirewall.stdout
+ firewall_calls = Pihole.run('cat /var/log/firewall-cmd').stdout
+ assert 'firewall-cmd --state' in firewall_calls
+ assert 'firewall-cmd --permanent --add-port=80/tcp' in firewall_calls
+ assert 'firewall-cmd --permanent --add-port=53/tcp' in firewall_calls
+ assert 'firewall-cmd --permanent --add-port=53/udp' in firewall_calls
+ assert 'firewall-cmd --reload' in firewall_calls
+
+
+# Helper functions
+def mock_command(script, result, container):
+ ''' Allows for setup of commands we don't really want to have to run for real in unit tests '''
+ ''' TODO: support array of results that enable the results to change over multiple executions of a command '''
+ full_script_path = '/usr/local/bin/{}'.format(script)
+ mock_script = dedent('''\
+ #!/bin/bash -e
+ echo "\$0 \$@" >> /var/log/{script}
+ exit {retcode}
+ '''.format(script=script, retcode=result))
+ container.run('''
+ cat < {script}\n{content}\nEOF
+ chmod +x {script}
+ '''.format(script=full_script_path, content=mock_script))
+ print container.run('cat {}'.format(full_script_path)).stdout
+
+
def run_script(Pihole, script, file="/test.sh"):
_write_test_script(Pihole, script, file=file)
result = Pihole.run(file)
From 699e29934521587066f001800f09e76badc0a1d4 Mon Sep 17 00:00:00 2001
From: diginc
Date: Wed, 2 Nov 2016 23:40:50 -0500
Subject: [PATCH 095/228] add a comment about bash vs dash. future refact
needed
---
test/test_automated_install.py | 3 +++
1 file changed, 3 insertions(+)
diff --git a/test/test_automated_install.py b/test/test_automated_install.py
index b720b94d..6a3daf60 100644
--- a/test/test_automated_install.py
+++ b/test/test_automated_install.py
@@ -110,5 +110,8 @@ def run_script(Pihole, script, file="/test.sh"):
def _write_test_script(Pihole, script, file):
''' Running the test script blocks directly can behave differently with regard to global vars '''
''' this is a cheap work around to that until all functions no longer rely on global variables '''
+ ''' found out why, dash: is the default in testinfra run() for Docker
+ Should try and convert the tests using this to firewalld style test
+ or override the run() function to use bash instead '''
Pihole.run('cat < {file}\n{script}\nEOF'.format(file=file, script=script))
Pihole.run('chmod +x {}'.format(file))
From a5a067d50fb15c5d1d03f6d0c70bb587c21c11db Mon Sep 17 00:00:00 2001
From: diginc
Date: Wed, 2 Nov 2016 23:58:54 -0500
Subject: [PATCH 096/228] switching testinfra's Docker run from dash to bash
---
test/conftest.py | 14 ++++++++++++++
test/test_automated_install.py | 3 +--
2 files changed, 15 insertions(+), 2 deletions(-)
diff --git a/test/conftest.py b/test/conftest.py
index 407d00dc..e99e47a3 100644
--- a/test/conftest.py
+++ b/test/conftest.py
@@ -8,6 +8,20 @@ check_output = testinfra.get_backend(
@pytest.fixture
def Pihole(Docker):
''' used to contain some script stubbing, now pretty much an alias '''
+ def run_bash(self, command, *args, **kwargs):
+ cmd = self.get_command(command, *args)
+ if self.user is not None:
+ out = self.run_local(
+ "docker exec -u %s %s /bin/bash -c %s",
+ self.user, self.name, cmd)
+ else:
+ out = self.run_local(
+ "docker exec %s /bin/bash -c %s", self.name, cmd)
+ out.command = self.encode(cmd)
+ return out
+
+ funcType = type(Docker.run)
+ Docker.run = funcType(run_bash, Docker, testinfra.backend.docker.DockerBackend)
return Docker
@pytest.fixture
diff --git a/test/test_automated_install.py b/test/test_automated_install.py
index 6a3daf60..45fecfd0 100644
--- a/test/test_automated_install.py
+++ b/test/test_automated_install.py
@@ -69,11 +69,10 @@ def test_configureFirewall_firewalld_no_errors(Pihole):
''' confirms firewalld rules are applied when appopriate '''
mock_command('firewall-cmd', '0', Pihole)
configureFirewall = Pihole.run('''
- bash -c "
PHTEST=TRUE
source /opt/pihole/basic-install.sh
configureFirewall
- " ''')
+ ''')
expected_stdout = '::: Configuring firewalld for httpd and dnsmasq.'
assert expected_stdout in configureFirewall.stdout
firewall_calls = Pihole.run('cat /var/log/firewall-cmd').stdout
From d2f815bba7c122d22bdfaf70e2ad2e4272e39fe6 Mon Sep 17 00:00:00 2001
From: diginc
Date: Thu, 3 Nov 2016 00:02:28 -0500
Subject: [PATCH 097/228] no longer need to write bash test scripts
---
test/test_automated_install.py | 28 +++++++++-------------------
1 file changed, 9 insertions(+), 19 deletions(-)
diff --git a/test/test_automated_install.py b/test/test_automated_install.py
index 45fecfd0..19d87fe8 100644
--- a/test/test_automated_install.py
+++ b/test/test_automated_install.py
@@ -20,15 +20,15 @@ def test_setupVars_are_sourced_to_global_scope(Pihole):
Pihole.run(setup_var_file)
script = dedent('''\
- #!/bin/bash -e
+ set -e
printSetupVars() {
# Currently debug test function only
echo "Outputting sourced variables"
- echo "PIHOLE_INTERFACE=\${PIHOLE_INTERFACE}"
- echo "IPV4_ADDRESS=\${IPV4_ADDRESS}"
- echo "IPV6_ADDRESS=\${IPV6_ADDRESS}"
- echo "PIHOLE_DNS_1=\${PIHOLE_DNS_1}"
- echo "PIHOLE_DNS_2=\${PIHOLE_DNS_2}"
+ echo "PIHOLE_INTERFACE=${PIHOLE_INTERFACE}"
+ echo "IPV4_ADDRESS=${IPV4_ADDRESS}"
+ echo "IPV6_ADDRESS=${IPV6_ADDRESS}"
+ echo "PIHOLE_DNS_1=${PIHOLE_DNS_1}"
+ echo "PIHOLE_DNS_2=${PIHOLE_DNS_2}"
}
update_dialogs() {
. /etc/pihole/setupVars.conf
@@ -50,7 +50,7 @@ def test_setupVars_saved_to_file(Pihole):
Pihole.run(set_setup_vars).stdout
script = dedent('''\
- #!/bin/bash -e
+ set -e
echo start
TERM=xterm
PHTEST=TRUE
@@ -100,17 +100,7 @@ def mock_command(script, result, container):
print container.run('cat {}'.format(full_script_path)).stdout
-def run_script(Pihole, script, file="/test.sh"):
- _write_test_script(Pihole, script, file=file)
- result = Pihole.run(file)
+def run_script(Pihole, script):
+ result = Pihole.run(script)
assert result.rc == 0
return result
-
-def _write_test_script(Pihole, script, file):
- ''' Running the test script blocks directly can behave differently with regard to global vars '''
- ''' this is a cheap work around to that until all functions no longer rely on global variables '''
- ''' found out why, dash: is the default in testinfra run() for Docker
- Should try and convert the tests using this to firewalld style test
- or override the run() function to use bash instead '''
- Pihole.run('cat < {file}\n{script}\nEOF'.format(file=file, script=script))
- Pihole.run('chmod +x {}'.format(file))
From 5b54b9cb11173a0ffcab78d089da47c65236d77b Mon Sep 17 00:00:00 2001
From: diginc
Date: Thu, 3 Nov 2016 00:05:19 -0500
Subject: [PATCH 098/228] update Pihole fixture comment
---
test/conftest.py | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/test/conftest.py b/test/conftest.py
index e99e47a3..5960cc24 100644
--- a/test/conftest.py
+++ b/test/conftest.py
@@ -7,7 +7,8 @@ check_output = testinfra.get_backend(
@pytest.fixture
def Pihole(Docker):
- ''' used to contain some script stubbing, now pretty much an alias '''
+ ''' used to contain some script stubbing, now pretty much an alias.
+ Also provides bash as the default run function shell '''
def run_bash(self, command, *args, **kwargs):
cmd = self.get_command(command, *args)
if self.user is not None:
From 43007592873b31538e1ed816c83d8b3dd8b1792a Mon Sep 17 00:00:00 2001
From: Adam Warner
Date: Thu, 3 Nov 2016 08:01:25 +0000
Subject: [PATCH 099/228] Fix logic. If both v6 and v4 divide by two, else
dont.
---
advanced/Scripts/chronometer.sh | 9 +++------
1 file changed, 3 insertions(+), 6 deletions(-)
diff --git a/advanced/Scripts/chronometer.sh b/advanced/Scripts/chronometer.sh
index 16ff6fb6..2e6cabda 100755
--- a/advanced/Scripts/chronometer.sh
+++ b/advanced/Scripts/chronometer.sh
@@ -21,12 +21,11 @@ today=$(date "+%b %e")
CalcBlockedDomains() {
if [ -e "${gravity}" ]; then
- #Are we IPV6 or IPV4?
- if [[ -n "${IPV6_ADDRESS}" ]]; then
- #We are IPV6
+ # if BOTH IPV4 and IPV6 are in use, then we need to divide total domains by 2.
+ if [[ -n "${IPV4_ADDRESS}" && -n "${IPV6_ADDRESS}" ]]; then
blockedDomainsTotal=$(wc -l /etc/pihole/gravity.list | awk '{print $1/2}')
else
- #We are IPV4
+ # only one is set.
blockedDomainsTotal=$(wc -l /etc/pihole/gravity.list | awk '{print $1}')
fi
else
@@ -104,8 +103,6 @@ normalChrono() {
CalcBlockedDomains
echo "Blocking: ${blockedDomainsTotal}"
- #below commented line does not add up to todaysQueryCount
- #echo "Queries: $todaysQueryCountV4 / $todaysQueryCountV6"
echo "Queries: ${queriesToday}" #same total calculation as dashboard
echo "Pi-holed: ${blockedToday} (${percentBlockedToday}%)"
From c2930b0ca5fff156924d19ff71e6fc2ea76fd3bc Mon Sep 17 00:00:00 2001
From: Adam Hill
Date: Thu, 3 Nov 2016 08:34:44 -0500
Subject: [PATCH 100/228] remove the debug print in mock_command
---
test/test_automated_install.py | 2 --
1 file changed, 2 deletions(-)
diff --git a/test/test_automated_install.py b/test/test_automated_install.py
index 19d87fe8..a3c80666 100644
--- a/test/test_automated_install.py
+++ b/test/test_automated_install.py
@@ -97,8 +97,6 @@ def mock_command(script, result, container):
cat < {script}\n{content}\nEOF
chmod +x {script}
'''.format(script=full_script_path, content=mock_script))
- print container.run('cat {}'.format(full_script_path)).stdout
-
def run_script(Pihole, script):
result = Pihole.run(script)
From b9f3493dbc13dffb72172118abb5bf8f8312dd04 Mon Sep 17 00:00:00 2001
From: diginc
Date: Thu, 3 Nov 2016 22:34:04 -0500
Subject: [PATCH 101/228] move PH_TRUE to Dockerfiles to DRY
---
automated install/basic-install.sh | 2 +-
test/centos.Dockerfile | 2 ++
test/debian.Dockerfile | 3 ++-
test/test_automated_install.py | 2 --
4 files changed, 5 insertions(+), 4 deletions(-)
diff --git a/automated install/basic-install.sh b/automated install/basic-install.sh
index 534b194d..491f7b6d 100755
--- a/automated install/basic-install.sh
+++ b/automated install/basic-install.sh
@@ -1149,6 +1149,6 @@ main() {
echo "::: The install log is located at: /etc/pihole/install.log"
}
-if [[ "${PHTEST}" != "TRUE" ]] ; then
+if [[ "${PH_TEST}" != true ]] ; then
main "$@"
fi
diff --git a/test/centos.Dockerfile b/test/centos.Dockerfile
index 9af7eb4d..00543b67 100644
--- a/test/centos.Dockerfile
+++ b/test/centos.Dockerfile
@@ -11,4 +11,6 @@ ENV PATH /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:$SCRIPTDIR
RUN true && \
chmod +x $SCRIPTDIR/*
+ENV PH_TEST true
+
#sed '/# Start the installer/Q' /opt/pihole/basic-install.sh > /opt/pihole/stub_basic-install.sh && \
diff --git a/test/debian.Dockerfile b/test/debian.Dockerfile
index b80d6155..931c0ba7 100644
--- a/test/debian.Dockerfile
+++ b/test/debian.Dockerfile
@@ -8,8 +8,9 @@ ADD . $GITDIR
RUN cp $GITDIR/advanced/Scripts/*.sh $GITDIR/gravity.sh $GITDIR/pihole $GITDIR/automated\ install/*.sh $SCRIPTDIR/
ENV PATH /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:$SCRIPTDIR
-
RUN true && \
chmod +x $SCRIPTDIR/*
+ENV PH_TEST true
+
#sed '/# Start the installer/Q' /opt/pihole/basic-install.sh > /opt/pihole/stub_basic-install.sh && \
diff --git a/test/test_automated_install.py b/test/test_automated_install.py
index a3c80666..ee3beeee 100644
--- a/test/test_automated_install.py
+++ b/test/test_automated_install.py
@@ -53,7 +53,6 @@ def test_setupVars_saved_to_file(Pihole):
set -e
echo start
TERM=xterm
- PHTEST=TRUE
source /opt/pihole/basic-install.sh
{}
finalExports
@@ -69,7 +68,6 @@ def test_configureFirewall_firewalld_no_errors(Pihole):
''' confirms firewalld rules are applied when appopriate '''
mock_command('firewall-cmd', '0', Pihole)
configureFirewall = Pihole.run('''
- PHTEST=TRUE
source /opt/pihole/basic-install.sh
configureFirewall
''')
From c755b3c49ef82c50d429a5e834a9c64060b3ab47 Mon Sep 17 00:00:00 2001
From: Markus Busche
Date: Fri, 4 Nov 2016 21:56:14 +0100
Subject: [PATCH 102/228] Added Link to blink1_pi-hole.py
---
README.md | 1 +
1 file changed, 1 insertion(+)
diff --git a/README.md b/README.md
index 7257ba4e..a8995566 100644
--- a/README.md
+++ b/README.md
@@ -103,6 +103,7 @@ You can view [real-time stats](http://pi-hole.net/faq/install-the-real-time-lcd-
- [Pi-hole on/off button](http://thetimmy.silvernight.org/pages/endisbutton/)
- [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)
+- [Let your blink1 device blink when Pi-hole filters ads](https://gist.github.com/elpatron68/ec0b4c582e5abf604885ac1e068d233f)
## Coverage
From 563696e291a66eda9f5d149b064f58b9de9b4345 Mon Sep 17 00:00:00 2001
From: Dan Schaper
Date: Fri, 4 Nov 2016 14:01:01 -0700
Subject: [PATCH 103/228] PR against Development guide
PA will tag PR to Master with -1 approval in the next release. That will deny any PR's against Master from users and changing branches after the PR is started does not appear to modify the PA actions.
---
.github/PULL_REQUEST_TEMPLATE.md | 2 ++
1 file changed, 2 insertions(+)
diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md
index 7291be41..3882215d 100644
--- a/.github/PULL_REQUEST_TEMPLATE.md
+++ b/.github/PULL_REQUEST_TEMPLATE.md
@@ -1,5 +1,7 @@
**By submitting this pull request, I confirm the following (please check boxes, eg [X])Failure to fill the template will close your PR:**
+***Please submit all pull requests against the `development` branch. Failure to do so will delay or deny your request***
+
- [] I have read and understood the [contributors guide](https://github.com/pi-hole/pi-hole/blob/master/CONTRIBUTING.md).
- [] I have checked that [another pull request](https://github.com/pi-hole/pi-hole/pulls) for this purpose does not exist.
- [] I have considered, and confirmed that this submission will be valuable to others.
From e5cc38a210185b882ddc74e46d9e03c64046ff66 Mon Sep 17 00:00:00 2001
From: Jacob Salmela
Date: Sun, 6 Nov 2016 08:08:58 -0600
Subject: [PATCH 104/228] Direct users to Discourse for FRs
It's a better platform for it because users can vote and we can have
easier discussions for it.
---
.github/ISSUE_TEMPLATE.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md
index 53f5b429..7994f9d2 100644
--- a/.github/ISSUE_TEMPLATE.md
+++ b/.github/ISSUE_TEMPLATE.md
@@ -20,7 +20,7 @@
---
**[FEATURE REQUEST | QUESTION | OTHER]:**
-_{replace this section with your content or delete if not a FEATURE REQUEST/QUESTION/OTHER}_
+Please [submit your feature request here](https://discourse.pi-hole.net/c/feature-requests), so it is votable by the community. It's also easier for us to track.
**[BUG | ISSUE] Expected Behaviour:**
From a0f0dff88ec7e0dde30aa278bf42f5e5556258ba Mon Sep 17 00:00:00 2001
From: Jacob Salmela
Date: Sun, 6 Nov 2016 08:18:57 -0600
Subject: [PATCH 105/228] replace hardcoded interface with var
setupVars.conf is already sourced, so we just need to replace the
hardcoded value with the variable name.
---
advanced/Scripts/chronometer.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/advanced/Scripts/chronometer.sh b/advanced/Scripts/chronometer.sh
index 2e6cabda..46051a20 100755
--- a/advanced/Scripts/chronometer.sh
+++ b/advanced/Scripts/chronometer.sh
@@ -80,7 +80,7 @@ normalChrono() {
echo "[0;1;33;93m|[0m [0;1;32;92m_[0;1;36;96m/[0m [0;1;34;94m|_[0;1;35;95m__[0;1;31;91m|[0m [0;1;33;93m'[0m [0;1;32;92m\/[0m [0;1;36;96m_[0m [0;1;34;94m\[0m [0;1;35;95m/[0m [0;1;31;91m-[0;1;33;93m_)[0m"
echo "[0;1;32;92m|_[0;1;36;96m|[0m [0;1;34;94m|_[0;1;35;95m|[0m [0;1;33;93m|_[0;1;32;92m||[0;1;36;96m_\[0;1;34;94m__[0;1;35;95m_/[0;1;31;91m_\[0;1;33;93m__[0;1;32;92m_|[0m"
echo ""
- echo " $(ifconfig eth0 | awk '/inet addr/ {print $2}' | cut -d':' -f2)"
+ echo " $(ifconfig ${PIHOLE_INTERFACE} | awk '/inet addr/ {print $2}' | cut -d':' -f2)"
echo ""
uptime | cut -d' ' -f11-
#uptime -p #Doesn't work on all versions of uptime
From ca56ca5bd85fec8f7c89b1956f14e4c4ad59a1a6 Mon Sep 17 00:00:00 2001
From: Jacob Salmela
Date: Sun, 6 Nov 2016 11:16:48 -0600
Subject: [PATCH 106/228] promo-tweak
Better logic introduced by @PromoFaux
---
advanced/Scripts/chronometer.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/advanced/Scripts/chronometer.sh b/advanced/Scripts/chronometer.sh
index 46051a20..7f2c764a 100755
--- a/advanced/Scripts/chronometer.sh
+++ b/advanced/Scripts/chronometer.sh
@@ -80,7 +80,7 @@ normalChrono() {
echo "[0;1;33;93m|[0m [0;1;32;92m_[0;1;36;96m/[0m [0;1;34;94m|_[0;1;35;95m__[0;1;31;91m|[0m [0;1;33;93m'[0m [0;1;32;92m\/[0m [0;1;36;96m_[0m [0;1;34;94m\[0m [0;1;35;95m/[0m [0;1;31;91m-[0;1;33;93m_)[0m"
echo "[0;1;32;92m|_[0;1;36;96m|[0m [0;1;34;94m|_[0;1;35;95m|[0m [0;1;33;93m|_[0;1;32;92m||[0;1;36;96m_\[0;1;34;94m__[0;1;35;95m_/[0;1;31;91m_\[0;1;33;93m__[0;1;32;92m_|[0m"
echo ""
- echo " $(ifconfig ${PIHOLE_INTERFACE} | awk '/inet addr/ {print $2}' | cut -d':' -f2)"
+ echo " ${IPV4_ADDRESS}"
echo ""
uptime | cut -d' ' -f11-
#uptime -p #Doesn't work on all versions of uptime
From 0caa44e9797dab02397c1fa0afd06d82cc69a56f Mon Sep 17 00:00:00 2001
From: bcambl
Date: Mon, 7 Nov 2016 12:54:31 -0600
Subject: [PATCH 107/228] write ifcfg instead of appending
---
automated install/basic-install.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/automated install/basic-install.sh b/automated install/basic-install.sh
index 14d271ef..abeb7fbe 100755
--- a/automated install/basic-install.sh
+++ b/automated install/basic-install.sh
@@ -423,7 +423,7 @@ setStaticIPv4() {
echo "DNS1=$PIHOLE_DNS_1"
echo "DNS2=$PIHOLE_DNS_2"
echo "USERCTL=no"
- }>> "${IFCFG_FILE}"
+ }> "${IFCFG_FILE}"
ip addr replace dev "${PIHOLE_INTERFACE}" "${IPV4_ADDRESS}"
if [ -x "$(command -v nmcli)" ];then
# Tell NetworkManager to read our new sysconfig file
From fd7e4f2268eaea02f338ea1dd8056e80be811d03 Mon Sep 17 00:00:00 2001
From: Nicolas Lamirault
Date: Tue, 15 Nov 2016 09:27:16 +0100
Subject: [PATCH 108/228] Add Pi-Hole Prometheus exporter project
---
README.md | 1 +
1 file changed, 1 insertion(+)
diff --git a/README.md b/README.md
index ed75d742..666fe863 100644
--- a/README.md
+++ b/README.md
@@ -107,6 +107,7 @@ You can view [real-time stats](http://pi-hole.net/faq/install-the-real-time-lcd-
- [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)
- [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
## Coverage
From 86d3ca48ae086c3833db345e24a545ab89cb7e56 Mon Sep 17 00:00:00 2001
From: Hayden Knowles
Date: Tue, 15 Nov 2016 22:40:57 +1300
Subject: [PATCH 109/228] moved newline to correct place
---
automated install/uninstall.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/automated install/uninstall.sh b/automated install/uninstall.sh
index abba88a5..6ed429aa 100755
--- a/automated install/uninstall.sh
+++ b/automated install/uninstall.sh
@@ -82,7 +82,7 @@ removeAndPurge() {
read -rp "::: Do you wish to remove ${i} from your system? [y/n]: " yn
case ${yn} in
[Yy]* ) printf ":::\tRemoving %s..." "${i}"; ${SUDO} ${PKG_REMOVE} "${i}" &> /dev/null & spinner $!; printf "done!\n"; break;;
- [Nn]* ) printf ":::\tSkipping %s" "${i}\n"; break;;
+ [Nn]* ) printf ":::\tSkipping %s\n" "${i}"; break;;
* ) printf "::: You must answer yes or no!\n";;
esac
done
From b191cd73a7810ee744e963d11e77f678b16ab616 Mon Sep 17 00:00:00 2001
From: Adam Warner
Date: Tue, 15 Nov 2016 13:28:18 +0000
Subject: [PATCH 110/228] Update piholeDebug.sh
wording
---
advanced/Scripts/piholeDebug.sh | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/advanced/Scripts/piholeDebug.sh b/advanced/Scripts/piholeDebug.sh
index 6768a8ea..fd4b475d 100755
--- a/advanced/Scripts/piholeDebug.sh
+++ b/advanced/Scripts/piholeDebug.sh
@@ -384,10 +384,13 @@ finalWork() {
# Check if tricorder.pi-hole.net is reachable and provide token.
if [ -n "${tricorder}" ]; then
echo "::: Your debug token is : ${tricorder}"
- echo "::: Please contact the Pi-hole team with your token to being assistance."
+ echo "::: Please contact the Pi-hole team with your token for assistance."
echo "::: Thank you."
+ else
+ echo "::: There was an error uploading your debug log."
+ echo "::: Please try again or contact the Pi-hole team for assistance."
fi
- echo "::: Debug log can be found at : /var/log/pihole_debug.log"
+ echo "::: A local copy of the Debug log can be found at : /var/log/pihole_debug.log"
}
trap finalWork EXIT
From db278d81e41e9cba378238a192c7682e0c668b26 Mon Sep 17 00:00:00 2001
From: DL6ER
Date: Wed, 16 Nov 2016 21:34:43 +0100
Subject: [PATCH 111/228] Added webpage.sh
---
advanced/Scripts/webpage.sh | 72 +++++++++++++++++++++++++++++++++++++
pihole | 9 ++++-
2 files changed, 80 insertions(+), 1 deletion(-)
create mode 100755 advanced/Scripts/webpage.sh
diff --git a/advanced/Scripts/webpage.sh b/advanced/Scripts/webpage.sh
new file mode 100755
index 00000000..9ebe7dd4
--- /dev/null
+++ b/advanced/Scripts/webpage.sh
@@ -0,0 +1,72 @@
+#!/usr/bin/env bash
+# Pi-hole: A black hole for Internet advertisements
+# (c) 2015, 2016 by Jacob Salmela
+# Network-wide ad blocking via your Raspberry Pi
+# http://pi-hole.net
+# Whitelists and blacklists domains
+#
+# Pi-hole is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 2 of the License, or
+# (at your option) any later version.
+
+#globals
+basename=pihole
+piholeDir=/etc/${basename}
+
+helpFunc() {
+ cat << EOM
+::: Set options for the web interface of pihole
+:::
+::: Usage: pihole -web [options]
+:::
+::: Options:
+::: -p, password Set web interface password
+::: -c, celsius Set Celcius temperature unit
+::: -f, fahrenheit Set Fahrenheit temperature unit
+::: -h, --help Show this help dialog
+EOM
+ exit 1
+}
+
+args=("$@")
+
+SetTemperatureUnit(){
+
+ # Remove setting from file (create backup setupVars.conf.bak)
+ sed -i.bak '/temperatureunit/d' /etc/pihole/setupVars.conf
+ # Save setting to file
+ if [[ $unit == "F" ]] ; then
+ echo "temperatureunit=F" >> /etc/pihole/setupVars.conf
+ else
+ echo "temperatureunit=C" >> /etc/pihole/setupVars.conf
+ fi
+
+}
+
+SetWebPassword(){
+
+ # Remove password from file (create backup setupVars.conf.bak)
+ sed -i.bak '/webpassword/d' /etc/pihole/setupVars.conf
+ # Compute password hash
+ hash=$(echo -n ${args[2]} | sha256sum | sed 's/\s.*$//')
+ # Save hash to file
+ echo "webpassword=${hash}" >> /etc/pihole/setupVars.conf
+
+}
+
+for var in "$@"; do
+ case "${var}" in
+ "-p" | "password" ) SetWebPassword;;
+ "-c" | "celsius" ) unit="C"; SetTemperatureUnit;;
+ "-f" | "fahrenheit" ) unit="F"; SetTemperatureUnit;;
+ "-h" | "--help" ) helpFunc;;
+ esac
+done
+
+shift
+
+if [[ $# = 0 ]]; then
+ helpFunc
+fi
+
diff --git a/pihole b/pihole
index 83046675..98b1850b 100755
--- a/pihole
+++ b/pihole
@@ -22,6 +22,11 @@ if [[ ! $EUID -eq 0 ]];then
fi
fi
+webpageFunc() {
+ /opt/pihole/webpage.sh "$@"
+ exit 0
+}
+
whitelistFunc() {
"${PI_HOLE_SCRIPT_DIR}"/list.sh "$@"
exit 0
@@ -180,7 +185,7 @@ helpFunc() {
::: Control all PiHole specific functions!
:::
::: Usage: pihole [options]
-::: Add -h after -w (whitelist), -b (blacklist), or -c (chronometer) for more information on usage
+::: Add -h after -w (whitelist), -b (blacklist), -c (chronometer), or -web (webpage) for more information on usage
:::
::: Options:
::: -w, whitelist Whitelist domains
@@ -195,6 +200,7 @@ helpFunc() {
::: -v, version Show current versions
::: -q, query Query the adlists for a specific domain
::: -l, logging Enable or Disable logging (pass 'on' or 'off')
+::: -web, webpage Webpage options
::: uninstall Uninstall Pi-Hole from your system :(!
::: status Is Pi-Hole Enabled or Disabled
::: enable Enable Pi-Hole DNS Blocking
@@ -228,5 +234,6 @@ case "${1}" in
"disable" ) piholeEnable 0;;
"status" ) piholeStatus "$2";;
"restartdns" ) restartDNS;;
+ "-web" | "webpage" ) webpageFunc "$@";;
* ) helpFunc;;
esac
From 9193c71cff31e69c74ad4cd884f376fbc4866e81 Mon Sep 17 00:00:00 2001
From: DL6ER
Date: Wed, 16 Nov 2016 21:36:19 +0100
Subject: [PATCH 112/228] Minor change
---
advanced/Scripts/webpage.sh | 6 +-----
1 file changed, 1 insertion(+), 5 deletions(-)
diff --git a/advanced/Scripts/webpage.sh b/advanced/Scripts/webpage.sh
index 9ebe7dd4..07fbec4c 100755
--- a/advanced/Scripts/webpage.sh
+++ b/advanced/Scripts/webpage.sh
@@ -10,9 +10,7 @@
# the Free Software Foundation, either version 2 of the License, or
# (at your option) any later version.
-#globals
-basename=pihole
-piholeDir=/etc/${basename}
+args=("$@")
helpFunc() {
cat << EOM
@@ -29,8 +27,6 @@ EOM
exit 1
}
-args=("$@")
-
SetTemperatureUnit(){
# Remove setting from file (create backup setupVars.conf.bak)
From 01bf1ae92d5a51b299aa7a675cb3ffa250149ebf Mon Sep 17 00:00:00 2001
From: DL6ER
Date: Wed, 16 Nov 2016 22:13:47 +0100
Subject: [PATCH 113/228] Compute double hashes to avoid rainbow table
vulnerability
---
advanced/Scripts/webpage.sh | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/advanced/Scripts/webpage.sh b/advanced/Scripts/webpage.sh
index 07fbec4c..dc1e2644 100755
--- a/advanced/Scripts/webpage.sh
+++ b/advanced/Scripts/webpage.sh
@@ -1,9 +1,8 @@
#!/usr/bin/env bash
# Pi-hole: A black hole for Internet advertisements
-# (c) 2015, 2016 by Jacob Salmela
# Network-wide ad blocking via your Raspberry Pi
# http://pi-hole.net
-# Whitelists and blacklists domains
+# Web interface settings
#
# Pi-hole is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -44,8 +43,9 @@ SetWebPassword(){
# Remove password from file (create backup setupVars.conf.bak)
sed -i.bak '/webpassword/d' /etc/pihole/setupVars.conf
- # Compute password hash
+ # Compute password hash twice to avoid rainbow table vulnerability
hash=$(echo -n ${args[2]} | sha256sum | sed 's/\s.*$//')
+ hash=$(echo -n ${hash} | sha256sum | sed 's/\s.*$//')
# Save hash to file
echo "webpassword=${hash}" >> /etc/pihole/setupVars.conf
From 88c161769de113ecac7944ec27b18d2cec1d38a8 Mon Sep 17 00:00:00 2001
From: DL6ER
Date: Wed, 16 Nov 2016 22:33:28 +0100
Subject: [PATCH 114/228] Capitalized variable names.
---
advanced/Scripts/webpage.sh | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/advanced/Scripts/webpage.sh b/advanced/Scripts/webpage.sh
index dc1e2644..6d2975ba 100755
--- a/advanced/Scripts/webpage.sh
+++ b/advanced/Scripts/webpage.sh
@@ -29,12 +29,12 @@ EOM
SetTemperatureUnit(){
# Remove setting from file (create backup setupVars.conf.bak)
- sed -i.bak '/temperatureunit/d' /etc/pihole/setupVars.conf
+ sed -i.bak '/TEMPERATUREUNIT/d' /etc/pihole/setupVars.conf
# Save setting to file
if [[ $unit == "F" ]] ; then
- echo "temperatureunit=F" >> /etc/pihole/setupVars.conf
+ echo "TEMPERATUREUNIT=F" >> /etc/pihole/setupVars.conf
else
- echo "temperatureunit=C" >> /etc/pihole/setupVars.conf
+ echo "TEMPERATUREUNIT=C" >> /etc/pihole/setupVars.conf
fi
}
@@ -42,12 +42,12 @@ SetTemperatureUnit(){
SetWebPassword(){
# Remove password from file (create backup setupVars.conf.bak)
- sed -i.bak '/webpassword/d' /etc/pihole/setupVars.conf
+ sed -i.bak '/WEBPASSWORD/d' /etc/pihole/setupVars.conf
# Compute password hash twice to avoid rainbow table vulnerability
hash=$(echo -n ${args[2]} | sha256sum | sed 's/\s.*$//')
hash=$(echo -n ${hash} | sha256sum | sed 's/\s.*$//')
# Save hash to file
- echo "webpassword=${hash}" >> /etc/pihole/setupVars.conf
+ echo "WEBPASSWORD=${hash}" >> /etc/pihole/setupVars.conf
}
From fd0dd9f54cc31ea4fb280ccff07d2c24823546cb Mon Sep 17 00:00:00 2001
From: Dan Schaper
Date: Wed, 16 Nov 2016 13:55:29 -0800
Subject: [PATCH 115/228] Add GSG/Shell link
---
CONTRIBUTING.md | 1 +
1 file changed, 1 insertion(+)
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 539f55d5..d342a8b5 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -33,5 +33,6 @@ When requesting or submitting new features, first consider whether it might be u
- Submit Pull Requests to the **development branch only**.
- 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.
- Commit Unix line endings.
- (Optional fun) keep to the theme of Star Trek/black holes/gravity.
From cac9c633259ec92d9c1c022f7c5330faa8a87028 Mon Sep 17 00:00:00 2001
From: zbholman
Date: Wed, 16 Nov 2016 17:06:30 -0500
Subject: [PATCH 116/228] Added removal of pihole user to the uninstall.sh
Not sure if I should have created a variable for the username or if the echo is necessary. And this is my first time doing a pull request, hopefully it works out lol.
---
automated install/uninstall.sh | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/automated install/uninstall.sh b/automated install/uninstall.sh
index abba88a5..b3ce5c7e 100755
--- a/automated install/uninstall.sh
+++ b/automated install/uninstall.sh
@@ -154,6 +154,12 @@ removeNoPurge() {
${SUDO} rm /usr/local/bin/pihole &> /dev/null
${SUDO} rm /etc/bash_completion.d/pihole &> /dev/null
${SUDO} rm /etc/sudoers.d/pihole &> /dev/null
+
+ # If the pihole user exists, then remove
+ if id "pihole" >/dev/null 2>&1; then
+ echo "::: Removing pihole user..."
+ ${SUDO} userdel -r pihole
+ fi
echo ":::"
printf "::: Finished removing PiHole from your system. Sorry to see you go!\n"
From 9bce5a09f35dd92b08c42ff0cc8f8f8ba1e61f47 Mon Sep 17 00:00:00 2001
From: Dan Schaper
Date: Wed, 16 Nov 2016 21:42:54 -0800
Subject: [PATCH 117/228] Small change in template
Just a space, and italicize
---
.github/PULL_REQUEST_TEMPLATE.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md
index 3882215d..9d6310d0 100644
--- a/.github/PULL_REQUEST_TEMPLATE.md
+++ b/.github/PULL_REQUEST_TEMPLATE.md
@@ -1,4 +1,4 @@
-**By submitting this pull request, I confirm the following (please check boxes, eg [X])Failure to fill the template will close your PR:**
+**By submitting this pull request, I confirm the following (please check boxes, eg [X]) _Failure to fill the template will close your PR_:**
***Please submit all pull requests against the `development` branch. Failure to do so will delay or deny your request***
From 808503d526a9f9b78296f2fb14713d92bbc7f870 Mon Sep 17 00:00:00 2001
From: Dan Schaper
Date: Thu, 17 Nov 2016 10:28:51 -0800
Subject: [PATCH 118/228] Add piholeDebug to tests
---
test/test_shellcheck.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/test/test_shellcheck.py b/test/test_shellcheck.py
index 43b27164..fa342027 100644
--- a/test/test_shellcheck.py
+++ b/test/test_shellcheck.py
@@ -7,7 +7,7 @@ run_local = testinfra.get_backend(
def test_scripts_pass_shellcheck():
''' Make sure shellcheck does not find anything wrong with our shell scripts '''
- shellcheck = "find . -name 'update.sh' | while read file; do shellcheck \"$file\"; done;"
+ shellcheck = "find . -type f \( -name 'update.sh' -o -name 'piholeDebug.sh' \) | while read file; do shellcheck \"$file\"; done;"
results = run_local(shellcheck)
print results.stdout
assert '' == results.stdout
From a95ce11ca68c7e9e0decdc0ed451a6fbc0384c1f Mon Sep 17 00:00:00 2001
From: Dan Schaper
Date: Thu, 17 Nov 2016 10:39:51 -0800
Subject: [PATCH 119/228] Add debug timeoute
---
advanced/Scripts/piholeDebug.sh | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/advanced/Scripts/piholeDebug.sh b/advanced/Scripts/piholeDebug.sh
index fd4b475d..375fb927 100755
--- a/advanced/Scripts/piholeDebug.sh
+++ b/advanced/Scripts/piholeDebug.sh
@@ -27,7 +27,7 @@ PIHOLELOG="/var/log/pihole.log"
WHITELISTMATCHES="/tmp/whitelistmatches.list"
IPV6_READY=false
-
+TIMEOUT=60
# Header info and introduction
cat << EOM
::: Beginning Pi-hole debug at $(date)!
@@ -356,9 +356,10 @@ dumpPiHoleLog() {
echo -e "::: Try loading a site that you are having trouble with now from a client web browser.. \n:::\t(Press CTRL+C to finish logging.)"
header_write "pihole.log"
if [ -e "${PIHOLELOG}" ]; then
+ # Dummy process to use for flagging down tail to terminate
+ sleep ${TIMEOUT} &
while true; do
- tail -f "${PIHOLELOG}" >> ${DEBUG_LOG}
- log_write ""
+ tail -n0 -f --pid=$! "${PIHOLELOG}" >> ${DEBUG_LOG}
done
else
log_write "No pihole.log file found!"
From 6d2c5b23122dc7ffc4be5981cb5ceaa95561836d Mon Sep 17 00:00:00 2001
From: Dan Schaper
Date: Thu, 17 Nov 2016 10:58:58 -0800
Subject: [PATCH 120/228] Add debug timeoute
---
advanced/Scripts/piholeDebug.sh | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/advanced/Scripts/piholeDebug.sh b/advanced/Scripts/piholeDebug.sh
index 375fb927..b39d038c 100755
--- a/advanced/Scripts/piholeDebug.sh
+++ b/advanced/Scripts/piholeDebug.sh
@@ -27,7 +27,7 @@ PIHOLELOG="/var/log/pihole.log"
WHITELISTMATCHES="/tmp/whitelistmatches.list"
IPV6_READY=false
-TIMEOUT=60
+TIMEOUT=15
# Header info and introduction
cat << EOM
::: Beginning Pi-hole debug at $(date)!
@@ -358,9 +358,7 @@ dumpPiHoleLog() {
if [ -e "${PIHOLELOG}" ]; then
# Dummy process to use for flagging down tail to terminate
sleep ${TIMEOUT} &
- while true; do
- tail -n0 -f --pid=$! "${PIHOLELOG}" >> ${DEBUG_LOG}
- done
+ tail -n0 -f --pid=$! "${PIHOLELOG}" >> ${DEBUG_LOG}
else
log_write "No pihole.log file found!"
printf ":::\tNo pihole.log file found!\n"
From 0f4c8d4923a2d55d357e89aefaed802ed4d537f3 Mon Sep 17 00:00:00 2001
From: Dan Schaper
Date: Thu, 17 Nov 2016 11:00:11 -0800
Subject: [PATCH 121/228] Set default timeout to 60 seconds
---
advanced/Scripts/piholeDebug.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/advanced/Scripts/piholeDebug.sh b/advanced/Scripts/piholeDebug.sh
index b39d038c..c91edf2a 100755
--- a/advanced/Scripts/piholeDebug.sh
+++ b/advanced/Scripts/piholeDebug.sh
@@ -27,7 +27,7 @@ PIHOLELOG="/var/log/pihole.log"
WHITELISTMATCHES="/tmp/whitelistmatches.list"
IPV6_READY=false
-TIMEOUT=15
+TIMEOUT=60
# Header info and introduction
cat << EOM
::: Beginning Pi-hole debug at $(date)!
From f667298b64e082ce06979a59572ee8694fd31725 Mon Sep 17 00:00:00 2001
From: DL6ER
Date: Thu, 17 Nov 2016 22:58:00 +0100
Subject: [PATCH 122/228] Added possiblity for delayed reactivation of blocking
---
pihole | 30 ++++++++++++++++++++++++++++--
1 file changed, 28 insertions(+), 2 deletions(-)
diff --git a/pihole b/pihole
index 83046675..310efb7e 100755
--- a/pihole
+++ b/pihole
@@ -117,6 +117,32 @@ piholeEnable() {
#Disable Pihole
sed -i 's/^addn-hosts/#addn-hosts/' /etc/dnsmasq.d/01-pihole.conf
echo "::: Blocking has been disabled!"
+ if [[ $# > 1 ]] ; then
+ if [ -x "$(command -v nohup)" ]; then
+ if [[ ${2} == *"s"* ]] ; then
+ echo "Seconds"
+ tt=${2%"s"}
+ echo "::: Blocking will be reenabled in ${tt} seconds"
+ echo "sleep ${tt}; pihole enable"
+ nohup bash -c "sleep ${tt}; pihole enable" /dev/null &
+ elif [[ ${2} == *"m"* ]] ; then
+ tt=${2%"m"}
+ echo "::: Blocking will be reenabled in ${tt} minutes"
+ tt=$((${tt}*60))
+ echo "sleep ${tt}; pihole enable"
+ nohup bash -c "sleep ${tt}; pihole enable" /dev/null &
+ else
+ echo "::: Unknown format for delayed reactivation of the blocking!"
+ echo "::: Example:"
+ echo "::: pihole disable 5s - will disable blocking for 5 seconds"
+ echo "::: pihole disable 7m - will disable blocking for 7 minutes"
+ echo "::: Blocking will not automatically be reenabled!"
+ fi
+ else
+ echo "::: Command 'nohup' has to be available for this feature."
+ echo "::: Blocking will not automatically be reenabled!"
+ fi
+ fi
else
#Enable pihole
echo "::: Blocking has been enabled!"
@@ -224,8 +250,8 @@ case "${1}" in
"-q" | "query" ) queryFunc "$@";;
"-l" | "logging" ) piholeLogging "$@";;
"uninstall" ) uninstallFunc;;
- "enable" ) piholeEnable 1;;
- "disable" ) piholeEnable 0;;
+ "enable" ) piholeEnable 1 $2;;
+ "disable" ) piholeEnable 0 $2;;
"status" ) piholeStatus "$2";;
"restartdns" ) restartDNS;;
* ) helpFunc;;
From 3aba1607b248baa1cd241a2ca2583e736cf70259 Mon Sep 17 00:00:00 2001
From: DL6ER
Date: Thu, 17 Nov 2016 23:04:46 +0100
Subject: [PATCH 123/228] Removed debug echos
---
pihole | 3 ---
1 file changed, 3 deletions(-)
diff --git a/pihole b/pihole
index 310efb7e..fca1ed63 100755
--- a/pihole
+++ b/pihole
@@ -120,16 +120,13 @@ piholeEnable() {
if [[ $# > 1 ]] ; then
if [ -x "$(command -v nohup)" ]; then
if [[ ${2} == *"s"* ]] ; then
- echo "Seconds"
tt=${2%"s"}
echo "::: Blocking will be reenabled in ${tt} seconds"
- echo "sleep ${tt}; pihole enable"
nohup bash -c "sleep ${tt}; pihole enable" /dev/null &
elif [[ ${2} == *"m"* ]] ; then
tt=${2%"m"}
echo "::: Blocking will be reenabled in ${tt} minutes"
tt=$((${tt}*60))
- echo "sleep ${tt}; pihole enable"
nohup bash -c "sleep ${tt}; pihole enable" /dev/null &
else
echo "::: Unknown format for delayed reactivation of the blocking!"
From c6857501aa854502b06dd89f065459238aecaff4 Mon Sep 17 00:00:00 2001
From: DL6ER
Date: Thu, 17 Nov 2016 23:31:11 +0100
Subject: [PATCH 124/228] Removed check for availability of nohup
---
pihole | 33 ++++++++++++++-------------------
1 file changed, 14 insertions(+), 19 deletions(-)
diff --git a/pihole b/pihole
index fca1ed63..02a64827 100755
--- a/pihole
+++ b/pihole
@@ -118,25 +118,20 @@ piholeEnable() {
sed -i 's/^addn-hosts/#addn-hosts/' /etc/dnsmasq.d/01-pihole.conf
echo "::: Blocking has been disabled!"
if [[ $# > 1 ]] ; then
- if [ -x "$(command -v nohup)" ]; then
- if [[ ${2} == *"s"* ]] ; then
- tt=${2%"s"}
- echo "::: Blocking will be reenabled in ${tt} seconds"
- nohup bash -c "sleep ${tt}; pihole enable" /dev/null &
- elif [[ ${2} == *"m"* ]] ; then
- tt=${2%"m"}
- echo "::: Blocking will be reenabled in ${tt} minutes"
- tt=$((${tt}*60))
- nohup bash -c "sleep ${tt}; pihole enable" /dev/null &
- else
- echo "::: Unknown format for delayed reactivation of the blocking!"
- echo "::: Example:"
- echo "::: pihole disable 5s - will disable blocking for 5 seconds"
- echo "::: pihole disable 7m - will disable blocking for 7 minutes"
- echo "::: Blocking will not automatically be reenabled!"
- fi
+ if [[ ${2} == *"s"* ]] ; then
+ tt=${2%"s"}
+ echo "::: Blocking will be reenabled in ${tt} seconds"
+ nohup bash -c "sleep ${tt}; pihole enable" /dev/null &
+ elif [[ ${2} == *"m"* ]] ; then
+ tt=${2%"m"}
+ echo "::: Blocking will be reenabled in ${tt} minutes"
+ tt=$((${tt}*60))
+ nohup bash -c "sleep ${tt}; pihole enable" /dev/null &
else
- echo "::: Command 'nohup' has to be available for this feature."
+ echo "::: Unknown format for delayed reactivation of the blocking!"
+ echo "::: Example:"
+ echo "::: pihole disable 5s - will disable blocking for 5 seconds"
+ echo "::: pihole disable 7m - will disable blocking for 7 minutes"
echo "::: Blocking will not automatically be reenabled!"
fi
fi
@@ -247,7 +242,7 @@ case "${1}" in
"-q" | "query" ) queryFunc "$@";;
"-l" | "logging" ) piholeLogging "$@";;
"uninstall" ) uninstallFunc;;
- "enable" ) piholeEnable 1 $2;;
+ "enable" ) piholeEnable 1;;
"disable" ) piholeEnable 0 $2;;
"status" ) piholeStatus "$2";;
"restartdns" ) restartDNS;;
From 96f2aa18036b06e71768cd20affa0bc37d5a82f3 Mon Sep 17 00:00:00 2001
From: DL6ER
Date: Thu, 17 Nov 2016 23:36:53 +0100
Subject: [PATCH 125/228] fixed typo
---
pihole | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/pihole b/pihole
index 02a64827..56953b03 100755
--- a/pihole
+++ b/pihole
@@ -132,7 +132,7 @@ piholeEnable() {
echo "::: Example:"
echo "::: pihole disable 5s - will disable blocking for 5 seconds"
echo "::: pihole disable 7m - will disable blocking for 7 minutes"
- echo "::: Blocking will not automatically be reenabled!"
+ echo "::: Blocking will not automatically be re-enabled!"
fi
fi
else
From 291ca0874a4479b047dd56bbc8646833dbce29a6 Mon Sep 17 00:00:00 2001
From: DL6ER
Date: Fri, 18 Nov 2016 12:16:10 +0100
Subject: [PATCH 126/228] Fixed two more typos
---
pihole | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/pihole b/pihole
index 56953b03..017bdaec 100755
--- a/pihole
+++ b/pihole
@@ -120,11 +120,11 @@ piholeEnable() {
if [[ $# > 1 ]] ; then
if [[ ${2} == *"s"* ]] ; then
tt=${2%"s"}
- echo "::: Blocking will be reenabled in ${tt} seconds"
+ echo "::: Blocking will be re-enabled in ${tt} seconds"
nohup bash -c "sleep ${tt}; pihole enable" /dev/null &
elif [[ ${2} == *"m"* ]] ; then
tt=${2%"m"}
- echo "::: Blocking will be reenabled in ${tt} minutes"
+ echo "::: Blocking will be re-enabled in ${tt} minutes"
tt=$((${tt}*60))
nohup bash -c "sleep ${tt}; pihole enable" /dev/null &
else
From 27e5f2798d4a584c2655458ba646baedd8a38cfb Mon Sep 17 00:00:00 2001
From: DL6ER
Date: Fri, 18 Nov 2016 17:33:46 +0100
Subject: [PATCH 127/228] Added missing "done." output
---
gravity.sh | 1 +
1 file changed, 1 insertion(+)
mode change 100755 => 100644 gravity.sh
diff --git a/gravity.sh b/gravity.sh
old mode 100755
new mode 100644
index 15e157f6..4f9c2910
--- a/gravity.sh
+++ b/gravity.sh
@@ -264,6 +264,7 @@ gravity_hostFormat() {
# Copy the file over as /etc/pihole/gravity.list so dnsmasq can use it
cp ${piholeDir}/${accretionDisc} ${adList}
+ echo " done!"
}
# blackbody - remove any remnant files from script processes
From 3fa05293fc466865a00140eaf65babae682b32f1 Mon Sep 17 00:00:00 2001
From: DL6ER
Date: Fri, 18 Nov 2016 17:37:13 +0100
Subject: [PATCH 128/228] Fixed file permissions
---
gravity.sh | 0
1 file changed, 0 insertions(+), 0 deletions(-)
mode change 100644 => 100755 gravity.sh
diff --git a/gravity.sh b/gravity.sh
old mode 100644
new mode 100755
From 4945f33254755effa6a11c95787cb5804406dc0e Mon Sep 17 00:00:00 2001
From: DL6ER
Date: Fri, 18 Nov 2016 17:39:34 +0100
Subject: [PATCH 129/228] Added "-n" to first echo call
---
gravity.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/gravity.sh b/gravity.sh
index 4f9c2910..8ca2a3da 100755
--- a/gravity.sh
+++ b/gravity.sh
@@ -240,7 +240,7 @@ gravity_unique() {
gravity_hostFormat() {
# Format domain list as "192.168.x.x domain.com"
- echo "::: Formatting domains into a HOSTS file..."
+ echo -n "::: Formatting domains into a HOSTS file..."
# Check vars from setupVars.conf to see if we're using IPv4, IPv6, Or both.
if [[ -n "${IPV4_ADDRESS}" && -n "${IPV6_ADDRESS}" ]];then
From 68cb0782c05c1ba6701a8bc02f3332ab6260ee56 Mon Sep 17 00:00:00 2001
From: Dan Schaper
Date: Fri, 18 Nov 2016 13:27:06 -0800
Subject: [PATCH 130/228] Add countdown timer
---
advanced/Scripts/piholeDebug.sh | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)
diff --git a/advanced/Scripts/piholeDebug.sh b/advanced/Scripts/piholeDebug.sh
index c91edf2a..d0e60177 100755
--- a/advanced/Scripts/piholeDebug.sh
+++ b/advanced/Scripts/piholeDebug.sh
@@ -316,6 +316,16 @@ debugLighttpd() {
echo ":::"
}
+countdown() {
+ tuvix=${TIMEOUT}
+ printf "::: Logging will automatically teminate in ${TIMEOUT} seconds\n"
+ while [ $tuvix -ge 1 ]
+ do
+ printf ":::\t${tuvix} seconds left. \r"
+ sleep 5
+ tuvix=$(( tuvix - 5 ))
+ done
+}
### END FUNCTIONS ###
# Gather version of required packages / repositories
@@ -357,7 +367,7 @@ dumpPiHoleLog() {
header_write "pihole.log"
if [ -e "${PIHOLELOG}" ]; then
# Dummy process to use for flagging down tail to terminate
- sleep ${TIMEOUT} &
+ countdown &
tail -n0 -f --pid=$! "${PIHOLELOG}" >> ${DEBUG_LOG}
else
log_write "No pihole.log file found!"
From 08e7b7e0ad8ca94aafacf82158bbe75aeda02361 Mon Sep 17 00:00:00 2001
From: Mcat12
Date: Sat, 19 Nov 2016 14:00:56 -0500
Subject: [PATCH 131/228] Fix typo
---
gravity.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/gravity.sh b/gravity.sh
index 8ca2a3da..4d440a4a 100755
--- a/gravity.sh
+++ b/gravity.sh
@@ -189,7 +189,7 @@ gravity_Blacklist() {
if [[ -f "${blacklistFile}" ]]; then
numBlacklisted=$(wc -l < "${blacklistFile}")
plural=; [[ "$numBlacklisted" != "1" ]] && plural=s
- echo -n "::: BlackListing $numBlacklisted domain${plural}..."
+ echo -n "::: Blacklisting $numBlacklisted domain${plural}..."
cat ${blacklistFile} >> ${piholeDir}/${eventHorizon}
echo " done!"
else
From 733919be4a0d22cfb4f93dbaaf3f30e03ed4ce84 Mon Sep 17 00:00:00 2001
From: DL6ER
Date: Sat, 19 Nov 2016 21:50:15 +0100
Subject: [PATCH 132/228] Implement possibility to remove password using
"pihole -web -p"
---
advanced/Scripts/webpage.sh | 16 +++++++++++-----
1 file changed, 11 insertions(+), 5 deletions(-)
diff --git a/advanced/Scripts/webpage.sh b/advanced/Scripts/webpage.sh
index 6d2975ba..0a66bc62 100755
--- a/advanced/Scripts/webpage.sh
+++ b/advanced/Scripts/webpage.sh
@@ -43,11 +43,17 @@ SetWebPassword(){
# Remove password from file (create backup setupVars.conf.bak)
sed -i.bak '/WEBPASSWORD/d' /etc/pihole/setupVars.conf
- # Compute password hash twice to avoid rainbow table vulnerability
- hash=$(echo -n ${args[2]} | sha256sum | sed 's/\s.*$//')
- hash=$(echo -n ${hash} | sha256sum | sed 's/\s.*$//')
- # Save hash to file
- echo "WEBPASSWORD=${hash}" >> /etc/pihole/setupVars.conf
+ # Set password only if there is one to be set
+ if (( ${#args[2]} > 0 )) ; then
+ # Compute password hash twice to avoid rainbow table vulnerability
+ hash=$(echo -n ${args[2]} | sha256sum | sed 's/\s.*$//')
+ hash=$(echo -n ${hash} | sha256sum | sed 's/\s.*$//')
+ # Save hash to file
+ echo "WEBPASSWORD=${hash}" >> /etc/pihole/setupVars.conf
+ echo "New password set"
+ else
+ echo "Password removed"
+ fi
}
From 33b6fe72dabdf24ffa3494d71f0b4068382a0ac8 Mon Sep 17 00:00:00 2001
From: DL6ER
Date: Sat, 19 Nov 2016 21:57:42 +0100
Subject: [PATCH 133/228] Extended help text
---
advanced/Scripts/webpage.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/advanced/Scripts/webpage.sh b/advanced/Scripts/webpage.sh
index 0a66bc62..68be534f 100755
--- a/advanced/Scripts/webpage.sh
+++ b/advanced/Scripts/webpage.sh
@@ -18,7 +18,7 @@ helpFunc() {
::: Usage: pihole -web [options]
:::
::: Options:
-::: -p, password Set web interface password
+::: -p, password Set web interface password, an empty input will remove any previously set password
::: -c, celsius Set Celcius temperature unit
::: -f, fahrenheit Set Fahrenheit temperature unit
::: -h, --help Show this help dialog
From bb7f8ae69dc67861a1dd5a087e1250c860fa5ad1 Mon Sep 17 00:00:00 2001
From: Dan Schaper
Date: Fri, 4 Nov 2016 18:43:54 -0700
Subject: [PATCH 134/228] Add git clone method to installers
---
.idea/codeStyleSettings.xml | 3 +++
README.md | 15 +++++++++++++--
2 files changed, 16 insertions(+), 2 deletions(-)
diff --git a/.idea/codeStyleSettings.xml b/.idea/codeStyleSettings.xml
index a571e63f..1028340e 100644
--- a/.idea/codeStyleSettings.xml
+++ b/.idea/codeStyleSettings.xml
@@ -15,6 +15,9 @@
+
+
+
diff --git a/README.md b/README.md
index 666fe863..c027c465 100644
--- a/README.md
+++ b/README.md
@@ -10,13 +10,24 @@ Works on most Debian and CentOS/RHEL based distributions!
### `curl -sSL https://install.pi-hole.net | bash`
-### Alternative Semi-Automated install
+### Alternative Semi-Automated Install Methods
+Clone our repository and run the automated installer from your device.
+
+```
+git clone --depth 1 https://github.com/pi-hole/pi-hole.git Pi-hole
+cd Pi-hole/automated_installer/
+(Optionally nano|vi|vim|cat the basic-install.sh file to verify the actions it will take)
+bash basic-install.sh
+```
+
+Or
+
+If you wish to read over the script before running it, then after the [`wget`](https://linux.die.net/man/1/wget) command, run `nano basic-install.sh` to open the file in a text viewer.
```bash
wget -O basic-install.sh https://install.pi-hole.net
bash basic-install.sh
```
-If you wish to read over the script before running it, then after the [`wget`](https://linux.die.net/man/1/wget) command, run `nano basic-install.sh` to open the file in a text viewer.
Once installed, [configure your router to have **DHCP clients use the Pi as their DNS server**](http://pi-hole.net/faq/can-i-set-the-pi-hole-to-be-the-dns-server-at-my-router-so-i-dont-have-to-change-settings-for-my-devices/) 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 the Raspberry Pi as its DNS server](http://pi-hole.net/faq/how-do-i-use-the-pi-hole-as-my-dns-server/).
From e863a200e8609d6ba6eb0583587b7d61f6c69b04 Mon Sep 17 00:00:00 2001
From: Dan Schaper
Date: Fri, 4 Nov 2016 18:44:21 -0700
Subject: [PATCH 135/228] Remove CC badge
---
README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/README.md b/README.md
index c027c465..f0862141 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-[![Bountysource](https://www.bountysource.com/badge/tracker?tracker_id=3011939)](https://www.bountysource.com/trackers/3011939-pi-hole-pi-hole?utm_source=3011939&utm_medium=shield&utm_campaign=TRACKER_BADGE) [![Code Climate](https://codeclimate.com/github/pi-hole/pi-hole/badges/gpa.svg)](https://codeclimate.com/github/pi-hole/pi-hole) [![Build Status](https://travis-ci.org/pi-hole/pi-hole.svg?branch=development)](https://travis-ci.org/pi-hole/pi-hole)
+[![Bountysource](https://www.bountysource.com/badge/tracker?tracker_id=3011939)](https://www.bountysource.com/trackers/3011939-pi-hole-pi-hole?utm_source=3011939&utm_medium=shield&utm_campaign=TRACKER_BADGE) [![Build Status](https://travis-ci.org/pi-hole/pi-hole.svg?branch=development)](https://travis-ci.org/pi-hole/pi-hole)
# Automated Install
From 924f499303407f79b4f57ce5948abcd13e82e1fd Mon Sep 17 00:00:00 2001
From: Dan Schaper
Date: Tue, 8 Nov 2016 00:18:26 -0800
Subject: [PATCH 136/228] Add DO Slug and Copy to README
---
README.md | 2 ++
1 file changed, 2 insertions(+)
diff --git a/README.md b/README.md
index f0862141..2bbb4346 100644
--- a/README.md
+++ b/README.md
@@ -59,6 +59,8 @@ Send a one-time donation using our link below to provide us with a small portion
- [FAQs](https://discourse.pi-hole.net/c/faqs)
- [![Join the chat at https://gitter.im/pi-hole/pi-hole](https://badges.gitter.im/pi-hole/pi-hole.svg)](https://gitter.im/pi-hole/pi-hole?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
+ [![Digital Ocean](https://gitlab.pi-hole.net/Pi-hole/assets/raw/master/DOHostingSlug.png)](http://www.digitalocean.com/?refcode=344d234950e)
+
## 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. You can also [replace ads with any image you want](http://pi-hole.net/faq/is-it-possible-to-change-the-blank-page-that-takes-place-of-the-ads-to-something-else/) since it is just a simple Webpage taking place of the ads.
From aacddb745b8a468ac43bfac7deb178ba2c14d088 Mon Sep 17 00:00:00 2001
From: Dan Schaper
Date: Tue, 8 Nov 2016 00:38:48 -0800
Subject: [PATCH 137/228] Swap Global Image
Global image, no berry, no overlay
---
README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/README.md b/README.md
index 2bbb4346..a2969c1d 100644
--- a/README.md
+++ b/README.md
@@ -33,7 +33,7 @@ Once installed, [configure your router to have **DHCP clients use the Pi as thei
## How To Install Pi-hole
-[![60-second install tutorial](http://i.imgur.com/5TEc3a6.png)](https://www.youtube.com/watch?v=TzFLJqUeirA)
+[![60-second install tutorial](https://gitlab.pi-hole.net/Pi-hole/assets/raw/master/Global.PNG)](https://www.youtube.com/watch?v=TzFLJqUeirA)
## How It Works
From 486a4929dae59ffd4224f092c15e98229e5f828b Mon Sep 17 00:00:00 2001
From: Dan Schaper
Date: Tue, 8 Nov 2016 00:52:15 -0800
Subject: [PATCH 138/228] Add click instructions
---
README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/README.md b/README.md
index a2969c1d..270c7f02 100644
--- a/README.md
+++ b/README.md
@@ -31,7 +31,7 @@ bash basic-install.sh
Once installed, [configure your router to have **DHCP clients use the Pi as their DNS server**](http://pi-hole.net/faq/can-i-set-the-pi-hole-to-be-the-dns-server-at-my-router-so-i-dont-have-to-change-settings-for-my-devices/) 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 the Raspberry Pi as its DNS server](http://pi-hole.net/faq/how-do-i-use-the-pi-hole-as-my-dns-server/).
-## How To Install Pi-hole
+## How To Install Pi-hole (Click to Watch!)
[![60-second install tutorial](https://gitlab.pi-hole.net/Pi-hole/assets/raw/master/Global.PNG)](https://www.youtube.com/watch?v=TzFLJqUeirA)
From d7154714266610d64eeb9594e008020e1966544f Mon Sep 17 00:00:00 2001
From: Dan Schaper
Date: Tue, 8 Nov 2016 01:17:40 -0800
Subject: [PATCH 139/228] Center Global
---
README.md | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/README.md b/README.md
index 270c7f02..64f169ac 100644
--- a/README.md
+++ b/README.md
@@ -32,8 +32,9 @@ bash basic-install.sh
Once installed, [configure your router to have **DHCP clients use the Pi as their DNS server**](http://pi-hole.net/faq/can-i-set-the-pi-hole-to-be-the-dns-server-at-my-router-so-i-dont-have-to-change-settings-for-my-devices/) 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 the Raspberry Pi as its DNS server](http://pi-hole.net/faq/how-do-i-use-the-pi-hole-as-my-dns-server/).
## How To Install Pi-hole (Click to Watch!)
-
-[![60-second install tutorial](https://gitlab.pi-hole.net/Pi-hole/assets/raw/master/Global.PNG)](https://www.youtube.com/watch?v=TzFLJqUeirA)
+
+
+
## How It Works
From 3ed08b5c39d1c0882eaf2047fb16026e4868d2f4 Mon Sep 17 00:00:00 2001
From: Dan Schaper
Date: Tue, 8 Nov 2016 01:28:02 -0800
Subject: [PATCH 140/228] Add New Logo and other changes
Remove extra break
Center Badges and move DO Slug
Bump Vortex up a bit.
Last change for now.
Move things around a bit.
Pull overlay off black hole image
---
README.md | 28 ++++++++++++++++++----------
1 file changed, 18 insertions(+), 10 deletions(-)
diff --git a/README.md b/README.md
index 64f169ac..2a7df29e 100644
--- a/README.md
+++ b/README.md
@@ -1,10 +1,16 @@
-[![Bountysource](https://www.bountysource.com/badge/tracker?tracker_id=3011939)](https://www.bountysource.com/trackers/3011939-pi-hole-pi-hole?utm_source=3011939&utm_medium=shield&utm_campaign=TRACKER_BADGE) [![Build Status](https://travis-ci.org/pi-hole/pi-hole.svg?branch=development)](https://travis-ci.org/pi-hole/pi-hole)
+
+
+
+
+
-# Automated Install
+
+
+
-Designed For Raspberry Pi A+, B, B+, 2, 3B, and Zero (with an Ethernet/Wi-Fi adapter)
-Works on most Debian and CentOS/RHEL based distributions!
+## Originally Designed For the Raspberry Pi Family of Products. Now Works on most Debian and Fedora based distributions on the x86_64 Platform!
+### Automated Install
1. Install Raspbian
2. Run the command below (downloads [this script](https://github.com/pi-hole/pi-hole/blob/master/automated%20install/basic-install.sh) in case you want to read over it first!)
@@ -36,18 +42,22 @@ Once installed, [configure your router to have **DHCP clients use the Pi as thei
+
+
+
+
## How It Works
**Watch the 60-second video below to get a quick overview**
-
-[![Pi-hole exlplained](http://i.imgur.com/pG1m937.png)](https://youtu.be/9Eti3xibiho)
+
+
+
## Pi-hole Is Free, But Powered By Your Donations
-Send a one-time donation using our link below to provide us with a small portion of the monthly fee.
+Send a one-time donation using our links below to help us with a small portion of our monthly costs.
- ![Paypal](http://i.imgur.com/3muNfxu.png) : [Donate](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=3J2L3Z4DHW9UY)
-- ![Flattr](http://i.imgur.com/ZFceFRu.png) : [Donate](https://flattr.com/submit/auto?user_id=jacobsalmela&url=https://github.com/pi-hole/pi-hole)
- ![Bitcoin](http://i.imgur.com/FIlmOMG.png) : 1GKnevUnVaQM2pQieMyeHkpr8DXfkpfAtL
## Get Help Or Connect With Us On The Web
@@ -60,8 +70,6 @@ Send a one-time donation using our link below to provide us with a small portion
- [FAQs](https://discourse.pi-hole.net/c/faqs)
- [![Join the chat at https://gitter.im/pi-hole/pi-hole](https://badges.gitter.im/pi-hole/pi-hole.svg)](https://gitter.im/pi-hole/pi-hole?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
- [![Digital Ocean](https://gitlab.pi-hole.net/Pi-hole/assets/raw/master/DOHostingSlug.png)](http://www.digitalocean.com/?refcode=344d234950e)
-
## 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. You can also [replace ads with any image you want](http://pi-hole.net/faq/is-it-possible-to-change-the-blank-page-that-takes-place-of-the-ads-to-something-else/) since it is just a simple Webpage taking place of the ads.
From 4d9fb57e22d191cb323aa186d6d4ce4571140ae1 Mon Sep 17 00:00:00 2001
From: Jacob Salmela
Date: Tue, 8 Nov 2016 06:49:50 -0600
Subject: [PATCH 141/228] above the fold verbage
Try to let the user know in two sentences what Pi-hole can do for them.
Also, linked to Discourse hw/sw requirements.
fixed DO referral code.
---
README.md | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/README.md b/README.md
index 2a7df29e..a18e1446 100644
--- a/README.md
+++ b/README.md
@@ -8,10 +8,12 @@
-## Originally Designed For the Raspberry Pi Family of Products. Now Works on most Debian and Fedora based distributions on the x86_64 Platform!
+## The multi-platform, network-wide ad blocker
+
+Block ads for **all** your devices _without_ the need to install client-side software. Because Pi-hole blocks ads the DNS-level, ads can be blocked in non-traditional places such as in apps or on smart TVs.
### Automated Install
-1. Install Raspbian
+1. Install a [supported operating system](https://discourse.pi-hole.net/t/hardware-software-requirements/273/1)
2. Run the command below (downloads [this script](https://github.com/pi-hole/pi-hole/blob/master/automated%20install/basic-install.sh) in case you want to read over it first!)
### `curl -sSL https://install.pi-hole.net | bash`
@@ -43,7 +45,7 @@ Once installed, [configure your router to have **DHCP clients use the Pi as thei
-
+
## How It Works
From df55b2c516e6a1c77fcd836f31c7f368b3d053fd Mon Sep 17 00:00:00 2001
From: Jacob Salmela
Date: Tue, 8 Nov 2016 06:56:20 -0600
Subject: [PATCH 142/228] relocate and wordsmith donations
---
README.md | 22 +++++++++++-----------
1 file changed, 11 insertions(+), 11 deletions(-)
diff --git a/README.md b/README.md
index a18e1446..f81574c0 100644
--- a/README.md
+++ b/README.md
@@ -12,6 +12,17 @@
Block ads for **all** your devices _without_ the need to install client-side software. Because Pi-hole blocks ads the DNS-level, ads can be blocked in non-traditional places such as in apps or on smart TVs.
+
+
+
+
+## Your Support Still Matters
+
+Digital Ocean helps with our infrastructure, but our developers are all volunteers, so *your donations are what help keep us motivated* to keep working on the project. Send a one-time donation using our links below to help us with a small portion of our monthly costs.
+
+- ![Paypal](http://i.imgur.com/3muNfxu.png) : [Donate](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=3J2L3Z4DHW9UY)
+- ![Bitcoin](http://i.imgur.com/FIlmOMG.png) : 1GKnevUnVaQM2pQieMyeHkpr8DXfkpfAtL
+
### Automated Install
1. Install a [supported operating system](https://discourse.pi-hole.net/t/hardware-software-requirements/273/1)
2. Run the command below (downloads [this script](https://github.com/pi-hole/pi-hole/blob/master/automated%20install/basic-install.sh) in case you want to read over it first!)
@@ -44,10 +55,6 @@ Once installed, [configure your router to have **DHCP clients use the Pi as thei
-
-
-
-
## How It Works
**Watch the 60-second video below to get a quick overview**
@@ -55,13 +62,6 @@ Once installed, [configure your router to have **DHCP clients use the Pi as thei
-## Pi-hole Is Free, But Powered By Your Donations
-
-Send a one-time donation using our links below to help us with a small portion of our monthly costs.
-
-- ![Paypal](http://i.imgur.com/3muNfxu.png) : [Donate](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=3J2L3Z4DHW9UY)
-- ![Bitcoin](http://i.imgur.com/FIlmOMG.png) : 1GKnevUnVaQM2pQieMyeHkpr8DXfkpfAtL
-
## Get Help Or Connect With Us On The Web
- [@The_Pi_Hole](https://twitter.com/The_Pi_Hole)
From fc3d4b3defbe00ad1e198c89920a0893fb49bc5b Mon Sep 17 00:00:00 2001
From: Mcat12
Date: Tue, 8 Nov 2016 15:03:19 -0500
Subject: [PATCH 143/228] Update README.md
---
README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/README.md b/README.md
index f81574c0..b7a90a96 100644
--- a/README.md
+++ b/README.md
@@ -25,7 +25,7 @@ Digital Ocean helps with our infrastructure, but our developers are all voluntee
### Automated Install
1. Install a [supported operating system](https://discourse.pi-hole.net/t/hardware-software-requirements/273/1)
-2. Run the command below (downloads [this script](https://github.com/pi-hole/pi-hole/blob/master/automated%20install/basic-install.sh) in case you want to read over it first!)
+2. Run the command below (it downloads [this script](https://github.com/pi-hole/pi-hole/blob/master/automated%20install/basic-install.sh) in case you want to read over it first!)
### `curl -sSL https://install.pi-hole.net | bash`
From 6e54cfd2ac4488f3ffd7b0f6576e684e745dd5ac Mon Sep 17 00:00:00 2001
From: Dan Schaper
Date: Tue, 8 Nov 2016 15:29:30 -0800
Subject: [PATCH 144/228] Further refinements.
Trying to find a good flow for information and layout.
---
README.md | 24 +++++++++++++++---------
1 file changed, 15 insertions(+), 9 deletions(-)
diff --git a/README.md b/README.md
index b7a90a96..b8e1f045 100644
--- a/README.md
+++ b/README.md
@@ -10,7 +10,13 @@
## The multi-platform, network-wide ad blocker
-Block ads for **all** your devices _without_ the need to install client-side software. Because Pi-hole blocks ads the DNS-level, ads can be blocked in non-traditional places such as in apps or on smart TVs.
+Block ads for **all** your devices _without_ the need to install client-side software. The Pi-hole blocks ads the DNS-level, so all your devices are protected.
+
+- Web Browsers
+- Cell Phones
+- Smart TV's
+- Internet-connected home automation
+- Anything that communicates with the Internet
@@ -50,22 +56,26 @@ bash basic-install.sh
Once installed, [configure your router to have **DHCP clients use the Pi as their DNS server**](http://pi-hole.net/faq/can-i-set-the-pi-hole-to-be-the-dns-server-at-my-router-so-i-dont-have-to-change-settings-for-my-devices/) 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 the Raspberry Pi as its DNS server](http://pi-hole.net/faq/how-do-i-use-the-pi-hole-as-my-dns-server/).
-## How To Install Pi-hole (Click to Watch!)
+## Installing the Pi-hole (Click to Watch!)
-## How It Works
+## How does it work?
**Watch the 60-second video below to get a quick overview**
+### Gravity
+
+The [gravity.sh](https://github.com/pi-hole/pi-hole/blob/master/gravity.sh) does most of the magic. The script pulls in ad domains from many sources and compiles them into a single list of [over 1.6 million entries](http://jacobsalmela.com/block-millions-ads-network-wide-with-a-raspberry-pi-hole-2-0) (if you decide to use the [mahakala list](https://github.com/pi-hole/pi-hole/commit/963eacfe0537a7abddf30441c754c67ca1e40965)). This script is controlled by the `pihole` command. Please run `pihole -h` to see what commands can be run via `pihole`.
+
## Get Help Or Connect With Us On The Web
-- [@The_Pi_Hole](https://twitter.com/The_Pi_Hole)
- [Discourse](https://discourse.pi-hole.net/)
+- [@The_Pi_Hole](https://twitter.com/The_Pi_Hole)
- [/r/pihole](https://www.reddit.com/r/pihole/)
- [Pi-hole YouTube channel](https://www.youtube.com/channel/UCT5kq9w0wSjogzJb81C9U0w)
- [Wiki](https://github.com/pi-hole/pi-hole/wiki/Customization)
@@ -78,11 +88,7 @@ The Pi-hole is an **advertising-aware DNS/Web server**. If an ad domain is queri
#### Other Operating Systems
-This script will work for other UNIX-like systems with some slight **modifications**. As long as you can install `dnsmasq` and a Webserver, it should work OK. The automated install is only for a clean install of a Debian family or Fedora based system, such as the Raspberry Pi. If there are other platforms you'd like supported, let us know.
-
-### Gravity
-
-The [gravity.sh](https://github.com/pi-hole/pi-hole/blob/master/gravity.sh) does most of the magic. The script pulls in ad domains from many sources and compiles them into a single list of [over 1.6 million entries](http://jacobsalmela.com/block-millions-ads-network-wide-with-a-raspberry-pi-hole-2-0) (if you decide to use the [mahakala list](https://github.com/pi-hole/pi-hole/commit/963eacfe0537a7abddf30441c754c67ca1e40965)). This script is controlled by the `pihole` command. Please run `pihole -h` to see what commands can be run via `pihole`.
+The 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.
## Web Interface
From ddbcbe5458245a519641a0dba228dc4dc9ac3509 Mon Sep 17 00:00:00 2001
From: Dan Schaper
Date: Wed, 9 Nov 2016 12:49:18 -0800
Subject: [PATCH 145/228] Merge in git method instructions from other branch.
Move some bits around.
Start adding in logos to media links
More logos
Add BC logo
Change static images to use Asset server
Add and center control panel image
---
README.md | 54 +++++++++++++++++++++++++++++-------------------------
1 file changed, 29 insertions(+), 25 deletions(-)
diff --git a/README.md b/README.md
index b8e1f045..bcf3af43 100644
--- a/README.md
+++ b/README.md
@@ -5,7 +5,7 @@
-
+
## The multi-platform, network-wide ad blocker
@@ -19,36 +19,35 @@ Block ads for **all** your devices _without_ the need to install client-side sof
- Anything that communicates with the Internet
-
+
## Your Support Still Matters
-Digital Ocean helps with our infrastructure, but our developers are all volunteers, so *your donations are what help keep us motivated* to keep working on the project. Send a one-time donation using our links below to help us with a small portion of our monthly costs.
+Digital Ocean helps with our infrastructure, but our developers are all volunteers so *your donations help keep us innovating*. Sending a donation using our links below helps us offset a portion of our monthly costs.
-- ![Paypal](http://i.imgur.com/3muNfxu.png) : [Donate](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=3J2L3Z4DHW9UY)
-- ![Bitcoin](http://i.imgur.com/FIlmOMG.png) : 1GKnevUnVaQM2pQieMyeHkpr8DXfkpfAtL
+- ![Paypal](https://assets.pi-hole.net/static/paypal.png) [Donate via PayPal](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=3J2L3Z4DHW9UY)
+- ![Bitcoin](https://assets.pi-hole.net/static/Bitcoin.png) Bitcoin Address: 1GKnevUnVaQM2pQieMyeHkpr8DXfkpfAtL
-### Automated Install
+### One-Step Automated Install
1. Install a [supported operating system](https://discourse.pi-hole.net/t/hardware-software-requirements/273/1)
2. Run the command below (it downloads [this script](https://github.com/pi-hole/pi-hole/blob/master/automated%20install/basic-install.sh) in case you want to read over it first!)
### `curl -sSL https://install.pi-hole.net | bash`
-### Alternative Semi-Automated Install Methods
+#### Alternative Semi-Automated Install Methods
+_If you wish to read over the script before running it, run `nano basic-install.sh` to open the file in a text viewer._
-Clone our repository and run the automated installer from your device.
+##### Clone our repository and run the automated installer from your device.
```
git clone --depth 1 https://github.com/pi-hole/pi-hole.git Pi-hole
cd Pi-hole/automated_installer/
-(Optionally nano|vi|vim|cat the basic-install.sh file to verify the actions it will take)
bash basic-install.sh
```
-Or
+##### Or
-If you wish to read over the script before running it, then after the [`wget`](https://linux.die.net/man/1/wget) command, run `nano basic-install.sh` to open the file in a text viewer.
```bash
wget -O basic-install.sh https://install.pi-hole.net
bash basic-install.sh
@@ -58,39 +57,41 @@ Once installed, [configure your router to have **DHCP clients use the Pi as thei
## Installing the Pi-hole (Click to Watch!)
-
+
-## How does it work?
+## Would you like to know more?
**Watch the 60-second video below to get a quick overview**
-
+
-### Gravity
-
-The [gravity.sh](https://github.com/pi-hole/pi-hole/blob/master/gravity.sh) does most of the magic. The script pulls in ad domains from many sources and compiles them into a single list of [over 1.6 million entries](http://jacobsalmela.com/block-millions-ads-network-wide-with-a-raspberry-pi-hole-2-0) (if you decide to use the [mahakala list](https://github.com/pi-hole/pi-hole/commit/963eacfe0537a7abddf30441c754c67ca1e40965)). This script is controlled by the `pihole` command. Please run `pihole -h` to see what commands can be run via `pihole`.
-
## Get Help Or Connect With Us On The Web
-- [Discourse](https://discourse.pi-hole.net/)
-- [@The_Pi_Hole](https://twitter.com/The_Pi_Hole)
-- [/r/pihole](https://www.reddit.com/r/pihole/)
-- [Pi-hole YouTube channel](https://www.youtube.com/channel/UCT5kq9w0wSjogzJb81C9U0w)
-- [Wiki](https://github.com/pi-hole/pi-hole/wiki/Customization)
+- [Users Forum](https://discourse.pi-hole.net/)
- [FAQs](https://discourse.pi-hole.net/c/faqs)
+- [Wiki](https://github.com/pi-hole/pi-hole/wiki/Customization)
+- ![Twitter](https://assets.pi-hole.net/static/twitter.png) [Tweet @The_Pi_Hole](https://twitter.com/The_Pi_Hole)
+- ![Reddit](https://assets.pi-hole.net/static/reddit.png) [Reddit /r/pihole](https://www.reddit.com/r/pihole/)
+- ![YouTube](https://assets.pi-hole.net/static/youtube.png) [Pi-hole channel](https://www.youtube.com/channel/UCT5kq9w0wSjogzJb81C9U0w)
- [![Join the chat at https://gitter.im/pi-hole/pi-hole](https://badges.gitter.im/pi-hole/pi-hole.svg)](https://gitter.im/pi-hole/pi-hole?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
## Technical Details
The Pi-hole is an **advertising-aware DNS/Web server**. If an ad domain is queried, a small Web page or GIF is delivered in place of the advertisement. You can also [replace ads with any image you want](http://pi-hole.net/faq/is-it-possible-to-change-the-blank-page-that-takes-place-of-the-ads-to-something-else/) since it is just a simple Webpage taking place of the ads.
+### Gravity
+
+The [gravity.sh](https://github.com/pi-hole/pi-hole/blob/master/gravity.sh) does most of the magic. The script pulls in ad domains from many sources and compiles them into a single list of [over 1.6 million entries](http://jacobsalmela.com/block-millions-ads-network-wide-with-a-raspberry-pi-hole-2-0) (if you decide to use the [mahakala list](https://github.com/pi-hole/pi-hole/commit/963eacfe0537a7abddf30441c754c67ca1e40965)). This script is controlled by the `pihole` command. Please run `pihole -h` to see what commands can be run via `pihole`.
+
+
+
#### 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.
-## Web Interface
+### Web Interface
The [Web interface](https://github.com/jacobsalmela/AdminLTE#pi-hole-admin-dashboard) will be installed automatically so you can view stats and change settings. You can find it at:
@@ -100,7 +101,10 @@ The [Web interface](https://github.com/jacobsalmela/AdminLTE#pi-hole-admin-dashb
### Whitelist and blacklist
-Domains can be whitelisted and blacklisted using either the web interface or the command line. See [the wiki page](https://github.com/pi-hole/pi-hole/wiki/Whitelisting-and-Blacklisting) for more details ![Whitelist editor in the Web interface](http://i.imgur.com/ogu2ewg.png)
+Domains can be whitelisted and blacklisted using either the web interface or the command line. See [the wiki page](https://github.com/pi-hole/pi-hole/wiki/Whitelisting-and-Blacklisting) for more details
+
+
+
## API
From eb22ca24673a8516db98185ef183f5df039f53a0 Mon Sep 17 00:00:00 2001
From: Dan Schaper
Date: Fri, 11 Nov 2016 11:55:28 -0800
Subject: [PATCH 146/228] Reset Code Stylings to group defalut
---
.idea/codeStyleSettings.xml | 5 +----
1 file changed, 1 insertion(+), 4 deletions(-)
diff --git a/.idea/codeStyleSettings.xml b/.idea/codeStyleSettings.xml
index 1028340e..8de25c7c 100644
--- a/.idea/codeStyleSettings.xml
+++ b/.idea/codeStyleSettings.xml
@@ -15,11 +15,8 @@
-
-
-
-
\ No newline at end of file
+
From 7424a2996010dfdb90fb4c95003f6a9ebde0a292 Mon Sep 17 00:00:00 2001
From: Mcat12
Date: Sat, 19 Nov 2016 16:53:11 -0500
Subject: [PATCH 147/228] Update wiki link
---
README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/README.md b/README.md
index bcf3af43..35d1649a 100644
--- a/README.md
+++ b/README.md
@@ -71,7 +71,7 @@ Once installed, [configure your router to have **DHCP clients use the Pi as thei
- [Users Forum](https://discourse.pi-hole.net/)
- [FAQs](https://discourse.pi-hole.net/c/faqs)
-- [Wiki](https://github.com/pi-hole/pi-hole/wiki/Customization)
+- [Wiki](https://github.com/pi-hole/pi-hole/wiki)
- ![Twitter](https://assets.pi-hole.net/static/twitter.png) [Tweet @The_Pi_Hole](https://twitter.com/The_Pi_Hole)
- ![Reddit](https://assets.pi-hole.net/static/reddit.png) [Reddit /r/pihole](https://www.reddit.com/r/pihole/)
- ![YouTube](https://assets.pi-hole.net/static/youtube.png) [Pi-hole channel](https://www.youtube.com/channel/UCT5kq9w0wSjogzJb81C9U0w)
From 5dbbf91917171a51a10e36116114c0511daf8b49 Mon Sep 17 00:00:00 2001
From: Dan Schaper
Date: Sat, 19 Nov 2016 15:08:35 -0800
Subject: [PATCH 148/228] Link to AdminLTE
---
README.md | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/README.md b/README.md
index 35d1649a..66e0c250 100644
--- a/README.md
+++ b/README.md
@@ -93,11 +93,11 @@ The automated install is only for a clean install of a Debian family or Fedora b
### Web Interface
-The [Web interface](https://github.com/jacobsalmela/AdminLTE#pi-hole-admin-dashboard) will be installed automatically so you can view stats and change settings. You can find it at:
+The [Web interface](https://github.com/pi-hole/AdminLTE#pi-hole-admin-dashboard) will be installed automatically so you can view stats and change settings. You can find it at:
`http://192.168.1.x/admin/index.php` or `http://pi.hole/admin`
-![Pi-hole Advanced Stats Dashboard](http://i.imgur.com/gTq2GbS.png)
+![Pi-hole Advanced Stats Dashboard](https://assets.pi-hole.net/static/dashboard.png)
### Whitelist and blacklist
From f50cbe74cb4a974ebd9125c3edeb06a9f8b3efad Mon Sep 17 00:00:00 2001
From: DL6ER
Date: Sun, 20 Nov 2016 15:15:27 +0100
Subject: [PATCH 149/228] Changed -web (webpage) to -a (admin)
---
advanced/Scripts/webpage.sh | 4 ++--
pihole | 6 +++---
2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/advanced/Scripts/webpage.sh b/advanced/Scripts/webpage.sh
index 68be534f..bcb45a14 100755
--- a/advanced/Scripts/webpage.sh
+++ b/advanced/Scripts/webpage.sh
@@ -13,9 +13,9 @@ args=("$@")
helpFunc() {
cat << EOM
-::: Set options for the web interface of pihole
+::: Set admin options for the web interface of pihole
:::
-::: Usage: pihole -web [options]
+::: Usage: pihole -a [options]
:::
::: Options:
::: -p, password Set web interface password, an empty input will remove any previously set password
diff --git a/pihole b/pihole
index 98b1850b..530dac8d 100755
--- a/pihole
+++ b/pihole
@@ -185,7 +185,7 @@ helpFunc() {
::: Control all PiHole specific functions!
:::
::: Usage: pihole [options]
-::: Add -h after -w (whitelist), -b (blacklist), -c (chronometer), or -web (webpage) for more information on usage
+::: Add -h after -w (whitelist), -b (blacklist), -c (chronometer), or -a (admin) for more information on usage
:::
::: Options:
::: -w, whitelist Whitelist domains
@@ -200,7 +200,7 @@ helpFunc() {
::: -v, version Show current versions
::: -q, query Query the adlists for a specific domain
::: -l, logging Enable or Disable logging (pass 'on' or 'off')
-::: -web, webpage Webpage options
+::: -a, admin Admin webpage options
::: uninstall Uninstall Pi-Hole from your system :(!
::: status Is Pi-Hole Enabled or Disabled
::: enable Enable Pi-Hole DNS Blocking
@@ -234,6 +234,6 @@ case "${1}" in
"disable" ) piholeEnable 0;;
"status" ) piholeStatus "$2";;
"restartdns" ) restartDNS;;
- "-web" | "webpage" ) webpageFunc "$@";;
+ "-a" | "admin" ) webpageFunc "$@";;
* ) helpFunc;;
esac
From e5a1afaa26c480708d5dc1babd548e9b4e84174b Mon Sep 17 00:00:00 2001
From: DL6ER
Date: Sun, 20 Nov 2016 17:31:27 +0100
Subject: [PATCH 150/228] Added another missing "done"
---
gravity.sh | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/gravity.sh b/gravity.sh
index 4d440a4a..22749463 100755
--- a/gravity.sh
+++ b/gravity.sh
@@ -307,7 +307,7 @@ gravity_reload() {
# Reload hosts file
echo ":::"
- echo "::: Refresh lists in dnsmasq..."
+ echo -n "::: Refresh lists in dnsmasq..."
#ensure /etc/dnsmasq.d/01-pihole.conf is pointing at the correct list!
#First escape forward slashes in the path:
@@ -315,7 +315,8 @@ gravity_reload() {
#Now replace the line in dnsmasq file
# sed -i "s/^addn-hosts.*/addn-hosts=$adList/" /etc/dnsmasq.d/01-pihole.conf
- pihole restartdns
+ pihole restartdns
+ echo "done."
}
for var in "$@"; do
From cdee6d55d368ccec3e15c5d6b5d92cf4cf11c22b Mon Sep 17 00:00:00 2001
From: DL6ER
Date: Sun, 20 Nov 2016 17:40:22 +0100
Subject: [PATCH 151/228] Minor change
---
gravity.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/gravity.sh b/gravity.sh
index 22749463..d05dddea 100755
--- a/gravity.sh
+++ b/gravity.sh
@@ -316,7 +316,7 @@ gravity_reload() {
# sed -i "s/^addn-hosts.*/addn-hosts=$adList/" /etc/dnsmasq.d/01-pihole.conf
pihole restartdns
- echo "done."
+ echo " done!"
}
for var in "$@"; do
From 41bb53a29f1edf2612609905b6359596a1610d98 Mon Sep 17 00:00:00 2001
From: Dan Schaper
Date: Sun, 20 Nov 2016 09:42:45 -0800
Subject: [PATCH 152/228] Remove CC Badge, Link Vortex to Discourse
---
README.md | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/README.md b/README.md
index 66e0c250..88e37552 100644
--- a/README.md
+++ b/README.md
@@ -1,11 +1,10 @@
-
-
+
## The multi-platform, network-wide ad blocker
From 0fc8ac8d4d1f7ca5835972f9547b587593174dd6 Mon Sep 17 00:00:00 2001
From: Dan Schaper
Date: Sun, 20 Nov 2016 09:44:39 -0800
Subject: [PATCH 153/228] Codacy Badge for Master
---
README.md | 1 +
1 file changed, 1 insertion(+)
diff --git a/README.md b/README.md
index 88e37552..24edd34c 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,6 @@
+
From 7bf0985a5750d29450c24a6a0ab9b5191e4266e9 Mon Sep 17 00:00:00 2001
From: DL6ER
Date: Mon, 21 Nov 2016 11:30:34 +0100
Subject: [PATCH 154/228] Extended help text of main pihole command
---
pihole | 2 ++
1 file changed, 2 insertions(+)
diff --git a/pihole b/pihole
index 017bdaec..406bc2d8 100755
--- a/pihole
+++ b/pihole
@@ -217,6 +217,8 @@ helpFunc() {
::: status Is Pi-Hole Enabled or Disabled
::: enable Enable Pi-Hole DNS Blocking
::: disable Disable Pi-Hole DNS Blocking
+::: Blocking can also be disabled only temporarily, e.g.,
+::: pihole disable 5m - will disable blocking for 5 minutes
::: restartdns Restart dnsmasq
EOM
exit 1
From 907995a2216ca5ecc9b91c528a5026f3507bda28 Mon Sep 17 00:00:00 2001
From: Adam Warner
Date: Mon, 21 Nov 2016 13:13:39 +0000
Subject: [PATCH 155/228] Update .pullapprove.yml
reflect new approvers team
---
.pullapprove.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.pullapprove.yml b/.pullapprove.yml
index 3b421dd2..f9d10062 100644
--- a/.pullapprove.yml
+++ b/.pullapprove.yml
@@ -25,7 +25,7 @@ groups:
- development
required: 2
teams:
- - gravity
+ - approvers
master:
approve_by_comment:
From 4c10634d85fd25a44cb6c688927abd6278453a7e Mon Sep 17 00:00:00 2001
From: DL6ER
Date: Mon, 21 Nov 2016 15:49:11 +0100
Subject: [PATCH 156/228] Convert domain names to lower case before checking
validity of the domain
---
advanced/Scripts/list.sh | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
mode change 100644 => 100755 advanced/Scripts/list.sh
diff --git a/advanced/Scripts/list.sh b/advanced/Scripts/list.sh
old mode 100644
new mode 100755
index 24f6d055..cfcea424
--- a/advanced/Scripts/list.sh
+++ b/advanced/Scripts/list.sh
@@ -51,8 +51,11 @@ EOM
}
HandleOther(){
- #check validity of domain
- validDomain=$(echo "$1" | perl -ne'print if /\b((?=[a-z0-9-]{1,63}\.)(xn--)?[a-z0-9]+(-[a-z0-9]+)*\.)+[a-z]{2,63}\b/')
+ # First, convert everything to lowercase
+ domain=$(sed -e "y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/" <<< "$1")
+
+ #check validity of domain
+ validDomain=$(echo "$domain" | perl -ne'print if /\b((?=[a-z0-9-]{1,63}\.)(xn--)?[a-z0-9]+(-[a-z0-9]+)*\.)+[a-z]{2,63}\b/')
if [ -z "${validDomain}" ]; then
echo "::: $1 is not a valid argument or domain name"
else
From 7b26b308ad393aae6977073c5d564c6210fb0ca3 Mon Sep 17 00:00:00 2001
From: DL6ER
Date: Mon, 21 Nov 2016 15:50:05 +0100
Subject: [PATCH 157/228] No need for echo and pipe here!
---
advanced/Scripts/list.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/advanced/Scripts/list.sh b/advanced/Scripts/list.sh
index cfcea424..35f2ceaa 100755
--- a/advanced/Scripts/list.sh
+++ b/advanced/Scripts/list.sh
@@ -55,7 +55,7 @@ HandleOther(){
domain=$(sed -e "y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/" <<< "$1")
#check validity of domain
- validDomain=$(echo "$domain" | perl -ne'print if /\b((?=[a-z0-9-]{1,63}\.)(xn--)?[a-z0-9]+(-[a-z0-9]+)*\.)+[a-z]{2,63}\b/')
+ validDomain=$(perl -ne "print if /\b((?=[a-z0-9-]{1,63}\.)(xn--)?[a-z0-9]+(-[a-z0-9]+)*\.)+[a-z]{2,63}\b/" <<< "$domain")
if [ -z "${validDomain}" ]; then
echo "::: $1 is not a valid argument or domain name"
else
From c97cfde9f991a9ddebb920d17ce015ef9f1f612f Mon Sep 17 00:00:00 2001
From: Adam Warner
Date: Mon, 21 Nov 2016 22:51:59 +0000
Subject: [PATCH 158/228] Update gravity.sh
Only include domain part of lines that contain `/` e.g `www.fakenewswatch.com/megynkelly`
---
gravity.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/gravity.sh b/gravity.sh
index d05dddea..d9bd0521 100755
--- a/gravity.sh
+++ b/gravity.sh
@@ -289,7 +289,7 @@ gravity_advanced() {
#awk '($1 !~ /^#/) { if (NF>1) {print $2} else {print $1}}' ${piholeDir}/${matterAndLight} | sed -nr -e 's/\.{2,}/./g' -e '/\./p' > ${piholeDir}/${supernova}
#Above line does not correctly grab domains where comment is on the same line (e.g 'addomain.com #comment')
#Add additional awk command to read all lines up to a '#', and then continue as we were
- cat ${piholeDir}/${matterAndLight} | awk -F'#' '{print $1}' | awk '($1 !~ /^#/) { if (NF>1) {print $2} else {print $1}}' | sed -nr -e 's/\.{2,}/./g' -e '/\./p' > ${piholeDir}/${supernova}
+ cat ${piholeDir}/${matterAndLight} | awk -F'#' '{print $1}' | awk -F'/' '{print $1}' | awk '($1 !~ /^#/) { if (NF>1) {print $2} else {print $1}}' | sed -nr -e 's/\.{2,}/./g' -e '/\./p' > ${piholeDir}/${supernova}
echo " done!"
numberOf=$(wc -l < ${piholeDir}/${supernova})
From 80c19cbf7d876473fbec031d4fe6702bd772807d Mon Sep 17 00:00:00 2001
From: Dan Schaper
Date: Tue, 22 Nov 2016 12:05:19 -0800
Subject: [PATCH 159/228] Update ISSUE_TEMPLATE.md
---
.github/ISSUE_TEMPLATE.md | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md
index 7994f9d2..07fc4352 100644
--- a/.github/ISSUE_TEMPLATE.md
+++ b/.github/ISSUE_TEMPLATE.md
@@ -35,8 +35,8 @@ Please [submit your feature request here](https://discourse.pi-hole.net/c/featur
-
-
-**(Optional) Debug Log generated by `pihole -d`:**
+**(Optional) Debug token generated by `pihole -d`:**
-`http://termbin.com/`
+``
_This template was created based on the work of [`udemy-dl`](https://github.com/nishad/udemy-dl/blob/master/LICENSE)._
From 2ec4acfe5285db3fdcdc5961c6a7a7d526b43779 Mon Sep 17 00:00:00 2001
From: Dan Schaper
Date: Thu, 1 Dec 2016 12:21:08 -0800
Subject: [PATCH 160/228] Begin fixing exit values.
Signed-off-by: Dan Schaper
---
advanced/Scripts/list.sh | 2 +-
automated install/basic-install.sh | 10 +++++-----
gravity.sh | 2 +-
pihole | 2 +-
4 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/advanced/Scripts/list.sh b/advanced/Scripts/list.sh
index 24f6d055..5cee8b56 100644
--- a/advanced/Scripts/list.sh
+++ b/advanced/Scripts/list.sh
@@ -47,7 +47,7 @@ helpFunc() {
::: -h, --help Show this help dialog
::: -l, --list Display your ${word}listed domains
EOM
- exit 1
+ exit 0
}
HandleOther(){
diff --git a/automated install/basic-install.sh b/automated install/basic-install.sh
index d79f05b2..d481c135 100755
--- a/automated install/basic-install.sh
+++ b/automated install/basic-install.sh
@@ -113,12 +113,12 @@ elif [ $(command -v rpm) ]; then
PKG_UPDATE="${PKG_MANAGER} update -y"
PKG_INSTALL="${PKG_MANAGER} install -y"
PKG_COUNT="${PKG_MANAGER} check-update | egrep '(.i686|.x86|.noarch|.arm|.src)' | wc -l"
- INSTALLER_DEPS=( iproute net-tools procps-ng newt git )
- PIHOLE_DEPS=( epel-release bind-utils bc dnsmasq lighttpd lighttpd-fastcgi php-common php-cli php curl unzip wget findutils cronie sudo nmap-ncat )
+ INSTALLER_DEPS=(iproute net-tools procps-ng newt git)
+ PIHOLE_DEPS=(bind-utils bc dnsmasq lighttpd lighttpd-fastcgi php-common php-cli php curl unzip wget findutils cronie sudo nmap-ncat)
- if grep -q 'Fedora' /etc/redhat-release; then
- remove_deps=(epel-release);
- PIHOLE_DEPS=( ${PIHOLE_DEPS[@]/$remove_deps} );
+ if ! grep -q 'Fedora' /etc/redhat-release; then
+ add_deps=(epel-release);
+ PIHOLE_DEPS=( "${add_deps[@]}" "${PIHOLE_DEPS[@]}" );
fi
LIGHTTPD_USER="lighttpd"
LIGHTTPD_GROUP="lighttpd"
diff --git a/gravity.sh b/gravity.sh
index d05dddea..d6b7106b 100755
--- a/gravity.sh
+++ b/gravity.sh
@@ -23,7 +23,7 @@ helpFunc() {
::: -f, --force Force lists to be downloaded, even if they don't need updating.
::: -h, --help Show this help dialog
EOM
- exit 1
+ exit 0
}
diff --git a/pihole b/pihole
index 771ab4c3..d8217fed 100755
--- a/pihole
+++ b/pihole
@@ -227,7 +227,7 @@ helpFunc() {
::: pihole disable 5m - will disable blocking for 5 minutes
::: restartdns Restart dnsmasq
EOM
- exit 1
+ exit 0
}
if [[ $# = 0 ]]; then
From cb52ad3ba307fc2eb4a303052e3ce72af32eff8b Mon Sep 17 00:00:00 2001
From: Dan Schaper
Date: Thu, 1 Dec 2016 13:31:35 -0800
Subject: [PATCH 161/228] Revert other branch chages.
Signed-off-by: Dan Schaper
---
automated install/basic-install.sh | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/automated install/basic-install.sh b/automated install/basic-install.sh
index d481c135..d79f05b2 100755
--- a/automated install/basic-install.sh
+++ b/automated install/basic-install.sh
@@ -113,12 +113,12 @@ elif [ $(command -v rpm) ]; then
PKG_UPDATE="${PKG_MANAGER} update -y"
PKG_INSTALL="${PKG_MANAGER} install -y"
PKG_COUNT="${PKG_MANAGER} check-update | egrep '(.i686|.x86|.noarch|.arm|.src)' | wc -l"
- INSTALLER_DEPS=(iproute net-tools procps-ng newt git)
- PIHOLE_DEPS=(bind-utils bc dnsmasq lighttpd lighttpd-fastcgi php-common php-cli php curl unzip wget findutils cronie sudo nmap-ncat)
+ INSTALLER_DEPS=( iproute net-tools procps-ng newt git )
+ PIHOLE_DEPS=( epel-release bind-utils bc dnsmasq lighttpd lighttpd-fastcgi php-common php-cli php curl unzip wget findutils cronie sudo nmap-ncat )
- if ! grep -q 'Fedora' /etc/redhat-release; then
- add_deps=(epel-release);
- PIHOLE_DEPS=( "${add_deps[@]}" "${PIHOLE_DEPS[@]}" );
+ if grep -q 'Fedora' /etc/redhat-release; then
+ remove_deps=(epel-release);
+ PIHOLE_DEPS=( ${PIHOLE_DEPS[@]/$remove_deps} );
fi
LIGHTTPD_USER="lighttpd"
LIGHTTPD_GROUP="lighttpd"
From c9fe62a691a6e5bd0b60d48865c801f90eefa422 Mon Sep 17 00:00:00 2001
From: Dan Schaper
Date: Thu, 1 Dec 2016 13:53:40 -0800
Subject: [PATCH 162/228] Clarify what the command is doing.
Signed-off-by: Dan Schaper
---
gravity.sh | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/gravity.sh b/gravity.sh
index d9bd0521..3f73b524 100755
--- a/gravity.sh
+++ b/gravity.sh
@@ -288,8 +288,14 @@ gravity_advanced() {
echo -n "::: Formatting list of domains to remove comments...."
#awk '($1 !~ /^#/) { if (NF>1) {print $2} else {print $1}}' ${piholeDir}/${matterAndLight} | sed -nr -e 's/\.{2,}/./g' -e '/\./p' > ${piholeDir}/${supernova}
#Above line does not correctly grab domains where comment is on the same line (e.g 'addomain.com #comment')
- #Add additional awk command to read all lines up to a '#', and then continue as we were
- cat ${piholeDir}/${matterAndLight} | awk -F'#' '{print $1}' | awk -F'/' '{print $1}' | awk '($1 !~ /^#/) { if (NF>1) {print $2} else {print $1}}' | sed -nr -e 's/\.{2,}/./g' -e '/\./p' > ${piholeDir}/${supernova}
+ #Awk -F splits on given IFS, we grab the right hand side (chops trailing #coments and /'s to grab the domain only.
+ #Last awk command takes non-commented lines and if they have 2 fields, take the left field (the domain) and leave
+ #+ and leave the right (IP address), otherwise grab the single field.
+ cat ${piholeDir}/${matterAndLight} | \
+ awk -F '#' '{print $1}' | \
+ awk -F '/' '{print $1}' | \
+ awk '($1 !~ /^#/) { if (NF>1) {print $2} else {print $1}}' | \
+ sed -nr -e 's/\.{2,}/./g' -e '/\./p' > ${piholeDir}/${supernova}
echo " done!"
numberOf=$(wc -l < ${piholeDir}/${supernova})
From d92646324cd5ca370ce6e714c00f114ae77ae03d Mon Sep 17 00:00:00 2001
From: Dan Schaper
Date: Thu, 1 Dec 2016 13:59:58 -0800
Subject: [PATCH 163/228] Double worded
Signed-off-by: Dan Schaper
---
gravity.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/gravity.sh b/gravity.sh
index 3f73b524..bfe82dce 100755
--- a/gravity.sh
+++ b/gravity.sh
@@ -290,7 +290,7 @@ gravity_advanced() {
#Above line does not correctly grab domains where comment is on the same line (e.g 'addomain.com #comment')
#Awk -F splits on given IFS, we grab the right hand side (chops trailing #coments and /'s to grab the domain only.
#Last awk command takes non-commented lines and if they have 2 fields, take the left field (the domain) and leave
- #+ and leave the right (IP address), otherwise grab the single field.
+ #+ the right (IP address), otherwise grab the single field.
cat ${piholeDir}/${matterAndLight} | \
awk -F '#' '{print $1}' | \
awk -F '/' '{print $1}' | \
From 925c80edd45e962cc824b48693603075e62fa7eb Mon Sep 17 00:00:00 2001
From: Dan Schaper
Date: Thu, 1 Dec 2016 15:10:06 -0800
Subject: [PATCH 164/228] Catch more 1's
Signed-off-by: Dan Schaper
---
advanced/Scripts/chronometer.sh | 2 +-
advanced/Scripts/version.sh | 2 +-
advanced/Scripts/webpage.sh | 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/advanced/Scripts/chronometer.sh b/advanced/Scripts/chronometer.sh
index 7f2c764a..c4b3d865 100755
--- a/advanced/Scripts/chronometer.sh
+++ b/advanced/Scripts/chronometer.sh
@@ -121,7 +121,7 @@ displayHelp() {
::: -j, --json output stats as JSON formatted string
::: -h, --help display this help text
EOM
- exit 1
+ exit 0
}
if [[ $# = 0 ]]; then
diff --git a/advanced/Scripts/version.sh b/advanced/Scripts/version.sh
index fc74f8a0..42bd96ce 100644
--- a/advanced/Scripts/version.sh
+++ b/advanced/Scripts/version.sh
@@ -86,7 +86,7 @@ helpFunc() {
::: -h, --help Show this help dialog
:::
EOM
- exit 1
+ exit 0
}
if [[ $# = 0 ]]; then
diff --git a/advanced/Scripts/webpage.sh b/advanced/Scripts/webpage.sh
index bcb45a14..0a79d853 100755
--- a/advanced/Scripts/webpage.sh
+++ b/advanced/Scripts/webpage.sh
@@ -23,7 +23,7 @@ helpFunc() {
::: -f, fahrenheit Set Fahrenheit temperature unit
::: -h, --help Show this help dialog
EOM
- exit 1
+ exit 0
}
SetTemperatureUnit(){
From c8ad6f23a88f1e292796f508dd3cafc99c5765de Mon Sep 17 00:00:00 2001
From: DL6ER
Date: Fri, 2 Dec 2016 12:57:04 +0100
Subject: [PATCH 165/228] Properly escape any special characters before using
them in regexp manner
---
advanced/Scripts/list.sh | 18 +++++++++++++-----
1 file changed, 13 insertions(+), 5 deletions(-)
diff --git a/advanced/Scripts/list.sh b/advanced/Scripts/list.sh
index 35f2ceaa..82f11fa7 100755
--- a/advanced/Scripts/list.sh
+++ b/advanced/Scripts/list.sh
@@ -50,6 +50,12 @@ EOM
exit 1
}
+EscapeRegexp() {
+ # This way we may safely insert an arbitrary
+ # string in our regular expressions
+ echo $* | sed 's/[]\.|$(){}?+*^]/\\&/g' | sed 's/\//\\\//g'
+}
+
HandleOther(){
# First, convert everything to lowercase
domain=$(sed -e "y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/" <<< "$1")
@@ -80,12 +86,12 @@ PoplistFile() {
}
AddDomain() {
-
list="$2"
+ domain=$(EscapeRegexp "$1")
bool=true
#Is the domain in the list we want to add it to?
- grep -Ex -q "$1" ${list} > /dev/null 2>&1 || bool=false
+ grep -Ex -q "${domain}" ${list} > /dev/null 2>&1 || bool=false
if [[ "${bool}" == false ]]; then
#domain not found in the whitelist file, add it!
@@ -104,14 +110,16 @@ AddDomain() {
RemoveDomain() {
list="$2"
+ domain=$(EscapeRegexp "$1")
bool=true
- #Is it in the other list? Logic follows that if its whitelisted it should not be blacklisted and vice versa
- grep -Ex -q "$1" ${list} > /dev/null 2>&1 || bool=false
+ #Is it in the list? Logic follows that if its whitelisted it should not be blacklisted and vice versa
+ grep -Ex -q "${domain}" ${list} > /dev/null 2>&1 || bool=false
if [[ "${bool}" == true ]]; then
# Remove it from the other one
echo "::: Removing $1 from $list..."
- echo "$1" | sed 's/\./\\./g' | xargs -I {} perl -i -ne'print unless /'{}'(?!.)/;' ${list}
+ # /I flag: search case-insensitive
+ sed -i "/${domain}/Id" ${list}
reload=true
else
if [[ "${verbose}" == true ]]; then
From 629ca970a11ee6ff6f6b56f8c998f3005cafc719 Mon Sep 17 00:00:00 2001
From: DL6ER
Date: Fri, 2 Dec 2016 14:08:54 +0100
Subject: [PATCH 166/228] Changed from single quoted filter expression to
double quotes as reqeusted by codacy
---
advanced/Scripts/list.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/advanced/Scripts/list.sh b/advanced/Scripts/list.sh
index 82f11fa7..32e7e877 100755
--- a/advanced/Scripts/list.sh
+++ b/advanced/Scripts/list.sh
@@ -53,7 +53,7 @@ EOM
EscapeRegexp() {
# This way we may safely insert an arbitrary
# string in our regular expressions
- echo $* | sed 's/[]\.|$(){}?+*^]/\\&/g' | sed 's/\//\\\//g'
+ echo $* | sed "s/[]\\.|$(){}?+*^]/\\\\&/g"
}
HandleOther(){
From 2061daa902f9dc0f56daccfb024eeaca3ea1398d Mon Sep 17 00:00:00 2001
From: DL6ER
Date: Fri, 2 Dec 2016 14:11:17 +0100
Subject: [PATCH 167/228] Don't forget to escape also the slash "/"
---
advanced/Scripts/list.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/advanced/Scripts/list.sh b/advanced/Scripts/list.sh
index 32e7e877..37a17a0f 100755
--- a/advanced/Scripts/list.sh
+++ b/advanced/Scripts/list.sh
@@ -53,7 +53,7 @@ EOM
EscapeRegexp() {
# This way we may safely insert an arbitrary
# string in our regular expressions
- echo $* | sed "s/[]\\.|$(){}?+*^]/\\\\&/g"
+ echo $* | sed "s/[]\\.|$(){}?+*^]/\\\\&/g" | sed "s/\\//\\\\\//g"
}
HandleOther(){
From 509cfd15f27f07f4e6d99fd431b821024be86280 Mon Sep 17 00:00:00 2001
From: DL6ER
Date: Fri, 2 Dec 2016 14:17:34 +0100
Subject: [PATCH 168/228] Simplified EscapeRegexp()
---
advanced/Scripts/list.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/advanced/Scripts/list.sh b/advanced/Scripts/list.sh
index 37a17a0f..ca038ef3 100755
--- a/advanced/Scripts/list.sh
+++ b/advanced/Scripts/list.sh
@@ -53,7 +53,7 @@ EOM
EscapeRegexp() {
# This way we may safely insert an arbitrary
# string in our regular expressions
- echo $* | sed "s/[]\\.|$(){}?+*^]/\\\\&/g" | sed "s/\\//\\\\\//g"
+ echo $* | sed "s/[]\\.|$(){}?+*^]\\//\\\\&/g"
}
HandleOther(){
From 870454330d96ddae71f62fb2c44ee735aec20999 Mon Sep 17 00:00:00 2001
From: trinapicot
Date: Fri, 2 Dec 2016 13:54:11 -0700
Subject: [PATCH 169/228] Add check for lighty.conf before trying to move it
---
automated install/basic-install.sh | 1 +
1 file changed, 1 insertion(+)
diff --git a/automated install/basic-install.sh b/automated install/basic-install.sh
index d79f05b2..33444873 100755
--- a/automated install/basic-install.sh
+++ b/automated install/basic-install.sh
@@ -708,6 +708,7 @@ installConfigs() {
if [ ! -d "/etc/lighttpd" ]; then
mkdir /etc/lighttpd
chown "${USER}":root /etc/lighttpd
+ elif [ -f "/etc/lighttpd/lighttpd.conf" ]; then
mv /etc/lighttpd/lighttpd.conf /etc/lighttpd/lighttpd.conf.orig
fi
cp /etc/.pihole/advanced/${LIGHTTPD_CFG} /etc/lighttpd/lighttpd.conf
From 78cb43d0dc014dcf6d470f81bde188e795807491 Mon Sep 17 00:00:00 2001
From: DL6ER
Date: Sat, 3 Dec 2016 00:32:37 +0100
Subject: [PATCH 170/228] Revert "Simplified EscapeRegexp()"
This reverts commit 509cfd15f27f07f4e6d99fd431b821024be86280.
---
advanced/Scripts/list.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/advanced/Scripts/list.sh b/advanced/Scripts/list.sh
index ca038ef3..37a17a0f 100755
--- a/advanced/Scripts/list.sh
+++ b/advanced/Scripts/list.sh
@@ -53,7 +53,7 @@ EOM
EscapeRegexp() {
# This way we may safely insert an arbitrary
# string in our regular expressions
- echo $* | sed "s/[]\\.|$(){}?+*^]\\//\\\\&/g"
+ echo $* | sed "s/[]\\.|$(){}?+*^]/\\\\&/g" | sed "s/\\//\\\\\//g"
}
HandleOther(){
From b4e5358145f8c20805bc8a55ec3006ed378b51b1 Mon Sep 17 00:00:00 2001
From: Christos Koutsiaris
Date: Sun, 4 Dec 2016 18:40:01 +0000
Subject: [PATCH 171/228] Ad blocker with armbian and orange pi
---
README.md | 1 +
1 file changed, 1 insertion(+)
diff --git a/README.md b/README.md
index 24edd34c..c982354c 100644
--- a/README.md
+++ b/README.md
@@ -158,3 +158,4 @@ You can view [real-time stats](http://pi-hole.net/faq/install-the-real-time-lcd-
- [Foolish Tech Show](https://youtu.be/bYyena0I9yc?t=2m4s)
- [Pi-hole on Ubuntu](http://www.boyter.org/2015/12/pi-hole-ubuntu-14-04/)
- [Catchpoint: iOS 9 Ad Blocking](http://blog.catchpoint.com/2015/09/14/ad-blocking-apple/)
+- [Build an Ad-Blocker for less than 10$ with Orange-Pi](http://www.devacron.com/orangepi-zero-as-an-ad-block-server-with-pi-hole/)
From eb63e75379854d53971733cd35dc1a33dbe84d9b Mon Sep 17 00:00:00 2001
From: DL6ER
Date: Mon, 5 Dec 2016 17:06:20 +0100
Subject: [PATCH 172/228] No need for pipe here
---
pihole | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/pihole b/pihole
index d8217fed..45cd0af0 100755
--- a/pihole
+++ b/pihole
@@ -70,7 +70,7 @@ setupLCDFunction() {
queryFunc() {
domain="${2}"
for list in /etc/pihole/list.*; do
- count=$(grep ${domain} $list | wc -l)
+ count=$(grep -c ${domain} $list)
echo "::: ${list} (${count} results)"
if [[ ${count} > 0 ]]; then
grep ${domain} ${list}
From 6cd3c9347282dd21602c59d35ef9873316edea56 Mon Sep 17 00:00:00 2001
From: DL6ER
Date: Mon, 5 Dec 2016 17:09:49 +0100
Subject: [PATCH 173/228] Also query white- and blacklist
---
pihole | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/pihole b/pihole
index 45cd0af0..5abdc01c 100755
--- a/pihole
+++ b/pihole
@@ -69,7 +69,8 @@ setupLCDFunction() {
queryFunc() {
domain="${2}"
- for list in /etc/pihole/list.*; do
+ lists=( /etc/pihole/list.* /etc/pihole/whitelist.txt /etc/pihole/blacklist.txt)
+ for list in ${lists[@]}; do
count=$(grep -c ${domain} $list)
echo "::: ${list} (${count} results)"
if [[ ${count} > 0 ]]; then
From 74cb79252cf22109b863bf8d022afa52f87da2c5 Mon Sep 17 00:00:00 2001
From: DL6ER
Date: Mon, 5 Dec 2016 17:12:28 +0100
Subject: [PATCH 174/228] Only looking for blocking entries (do not scan
whitelist.txt)
---
pihole | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/pihole b/pihole
index 5abdc01c..8adb15ed 100755
--- a/pihole
+++ b/pihole
@@ -69,7 +69,7 @@ setupLCDFunction() {
queryFunc() {
domain="${2}"
- lists=( /etc/pihole/list.* /etc/pihole/whitelist.txt /etc/pihole/blacklist.txt)
+ lists=( /etc/pihole/list.* /etc/pihole/blacklist.txt)
for list in ${lists[@]}; do
count=$(grep -c ${domain} $list)
echo "::: ${list} (${count} results)"
From fb72ac9904818e72ce486eede6c9b10ae89011ab Mon Sep 17 00:00:00 2001
From: DL6ER
Date: Tue, 6 Dec 2016 08:18:49 +0100
Subject: [PATCH 175/228] Show only exact matches for pihole -q
---
pihole | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/pihole b/pihole
index 8adb15ed..e1210dc8 100755
--- a/pihole
+++ b/pihole
@@ -71,10 +71,10 @@ queryFunc() {
domain="${2}"
lists=( /etc/pihole/list.* /etc/pihole/blacklist.txt)
for list in ${lists[@]}; do
- count=$(grep -c ${domain} $list)
+ count=$(grep -c -E "(^|\s)${domain}($|\s)" $list)
echo "::: ${list} (${count} results)"
if [[ ${count} > 0 ]]; then
- grep ${domain} ${list}
+ grep -E "(^|\s)${domain}($|\s)" ${list}
fi
echo ""
done
From 294df8690cd9bf7ef4560d76e9fffb6578814c4a Mon Sep 17 00:00:00 2001
From: DL6ER
Date: Tue, 6 Dec 2016 09:55:17 +0100
Subject: [PATCH 176/228] Do only one grep on each of the lists and count the
number of non-empty lines in the result. Improves speed by factor of 2x
---
pihole | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/pihole b/pihole
index e1210dc8..a59bbc3c 100755
--- a/pihole
+++ b/pihole
@@ -67,14 +67,20 @@ setupLCDFunction() {
exit 0
}
+scanList(){
+ grep -E "(^|\s)${domain}($|\s)" "$1"
+}
+
queryFunc() {
domain="${2}"
lists=( /etc/pihole/list.* /etc/pihole/blacklist.txt)
for list in ${lists[@]}; do
- count=$(grep -c -E "(^|\s)${domain}($|\s)" $list)
+ result=$(scanList $list)
+ # Remove empty lines before couting number of results
+ count=$(sed '/^\s*$/d' <<< "$result" | wc -l)
echo "::: ${list} (${count} results)"
if [[ ${count} > 0 ]]; then
- grep -E "(^|\s)${domain}($|\s)" ${list}
+ echo $result
fi
echo ""
done
From c0886cb5c699d30149d71a0e1d33355234cc0f3d Mon Sep 17 00:00:00 2001
From: DL6ER
Date: Tue, 6 Dec 2016 13:18:01 +0100
Subject: [PATCH 177/228] pihole -q is partial matching (as before),
pihole -q -exact is exact matching (new behavior)
---
pihole | 15 ++++++++++++---
1 file changed, 12 insertions(+), 3 deletions(-)
diff --git a/pihole b/pihole
index a59bbc3c..40d45e6a 100755
--- a/pihole
+++ b/pihole
@@ -68,19 +68,27 @@ setupLCDFunction() {
}
scanList(){
- grep -E "(^|\s)${domain}($|\s)" "$1"
+ domain="${1}"
+ list="${2}"
+ method="${3}"
+ if [[ ${method} == "-exact" ]] ; then
+ grep -E "(^|\s)${domain}($|\s)" "${list}"
+ else
+ grep "${domain}" "${list}"
+ fi
}
queryFunc() {
domain="${2}"
+ method="${3}"
lists=( /etc/pihole/list.* /etc/pihole/blacklist.txt)
for list in ${lists[@]}; do
- result=$(scanList $list)
+ 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
+ echo "${result}"
fi
echo ""
done
@@ -224,6 +232,7 @@ helpFunc() {
::: -h, help Show this help dialog
::: -v, version Show current versions
::: -q, query Query the adlists for a specific domain
+::: Use pihole -q domain -exact if you want to see exact matches only
::: -l, logging Enable or Disable logging (pass 'on' or 'off')
::: -a, admin Admin webpage options
::: uninstall Uninstall Pi-Hole from your system :(!
From 0a423ffd40bed3719b532c638d2439760b3abc6a Mon Sep 17 00:00:00 2001
From: trinapicot
Date: Wed, 7 Dec 2016 20:31:34 -0700
Subject: [PATCH 178/228] Fix check for lighttpd install before configuration
directory removal
---
automated install/uninstall.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/automated install/uninstall.sh b/automated install/uninstall.sh
index 49ab197d..2bc4dd25 100755
--- a/automated install/uninstall.sh
+++ b/automated install/uninstall.sh
@@ -136,7 +136,7 @@ removeNoPurge() {
fi
echo "::: Removing config files and scripts..."
- package_check ${i} > /dev/null
+ package_check lighttpd > /dev/null
if [ $? -eq 1 ]; then
${SUDO} rm -rf /etc/lighttpd/ &> /dev/null
else
From 5120d9ec33a570fe4ad07e5619c27cc18c21b4ea Mon Sep 17 00:00:00 2001
From: DL6ER
Date: Thu, 8 Dec 2016 21:15:03 +0100
Subject: [PATCH 179/228] Add tail option
---
pihole | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/pihole b/pihole
index 8adb15ed..9e727809 100755
--- a/pihole
+++ b/pihole
@@ -198,6 +198,10 @@ piholeStatus() {
fi
}
+tailFunc() {
+ tail -F /var/log/pihole.log
+ exit 0
+}
helpFunc() {
cat << EOM
@@ -211,6 +215,7 @@ helpFunc() {
::: -b, blacklist Blacklist domains
::: -d, debug Start a debugging session if having trouble
::: -f, flush Flush the pihole.log file
+::: -t, tail Output the last lines of the pihole.log file. Lines are appended as the file grows
::: -up, updatePihole Update Pi-hole
::: -g, updateGravity Update the list of ad-serving domains
::: -s, setupLCD Automatically configures the Pi to use the 2.8 LCD screen to display stats on it
@@ -256,5 +261,6 @@ case "${1}" in
"status" ) piholeStatus "$2";;
"restartdns" ) restartDNS;;
"-a" | "admin" ) webpageFunc "$@";;
+ "-t" | "tail" ) tailFunc;;
* ) helpFunc;;
esac
From b9e0e88fe91aa0a2efb06165640a084117a9efd4 Mon Sep 17 00:00:00 2001
From: Mcat12
Date: Thu, 8 Dec 2016 15:47:30 -0500
Subject: [PATCH 180/228] Update pihole
---
pihole | 1 +
1 file changed, 1 insertion(+)
diff --git a/pihole b/pihole
index 8adb15ed..6c99895b 100755
--- a/pihole
+++ b/pihole
@@ -212,6 +212,7 @@ helpFunc() {
::: -d, debug Start a debugging session if having trouble
::: -f, flush Flush the pihole.log file
::: -up, updatePihole Update Pi-hole
+::: -r, reconfigure Reconfigure or Repair Pi-hole
::: -g, updateGravity Update the list of ad-serving domains
::: -s, setupLCD Automatically configures the Pi to use the 2.8 LCD screen to display stats on it
::: -c, chronometer Calculates stats and displays to an LCD
From b591df55b0c44540ced89561ae53a9846b636236 Mon Sep 17 00:00:00 2001
From: Mcat12
Date: Thu, 8 Dec 2016 16:35:50 -0500
Subject: [PATCH 181/228] Tell user how to exit tail command
---
pihole | 1 +
1 file changed, 1 insertion(+)
diff --git a/pihole b/pihole
index 9e727809..2ab51c05 100755
--- a/pihole
+++ b/pihole
@@ -199,6 +199,7 @@ piholeStatus() {
}
tailFunc() {
+ echo "Press Ctrl-C to exit"
tail -F /var/log/pihole.log
exit 0
}
From bf867bd9fdc4e3e6374d80c92d4db936fd7b456f Mon Sep 17 00:00:00 2001
From: DL6ER
Date: Sun, 11 Dec 2016 16:54:27 +0100
Subject: [PATCH 182/228] Set DNS servers from web UI
---
advanced/Scripts/webpage.sh | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/advanced/Scripts/webpage.sh b/advanced/Scripts/webpage.sh
index 0a79d853..839f6e6d 100755
--- a/advanced/Scripts/webpage.sh
+++ b/advanced/Scripts/webpage.sh
@@ -57,11 +57,22 @@ SetWebPassword(){
}
+SetDNSServers(){
+
+ # Remove setting from file (create backup setupVars.conf.bak)
+ sed -i.bak '/PIHOLE_DNS_1/d;/PIHOLE_DNS_2/d;' /etc/pihole/setupVars.conf
+ # Save setting to file
+ echo "PIHOLE_DNS_1=${args[2]}" >> /etc/pihole/setupVars.conf
+ echo "PIHOLE_DNS_2=${args[3]}" >> /etc/pihole/setupVars.conf
+
+}
+
for var in "$@"; do
case "${var}" in
"-p" | "password" ) SetWebPassword;;
"-c" | "celsius" ) unit="C"; SetTemperatureUnit;;
"-f" | "fahrenheit" ) unit="F"; SetTemperatureUnit;;
+ "setdns" ) SetDNSServers;;
"-h" | "--help" ) helpFunc;;
esac
done
From 9ac378ae09a5c484b891963bb78a9b657a518116 Mon Sep 17 00:00:00 2001
From: DL6ER
Date: Sun, 11 Dec 2016 19:30:04 +0100
Subject: [PATCH 183/228] Set domains and clients which are excluded by the API
---
advanced/Scripts/webpage.sh | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
diff --git a/advanced/Scripts/webpage.sh b/advanced/Scripts/webpage.sh
index 839f6e6d..35ba6875 100755
--- a/advanced/Scripts/webpage.sh
+++ b/advanced/Scripts/webpage.sh
@@ -67,12 +67,30 @@ SetDNSServers(){
}
+SetExcludeDomains(){
+
+ # Remove setting from file (create backup setupVars.conf.bak)
+ sed -i.bak '/API_EXCLUDE_DOMAINS/d;' /etc/pihole/setupVars.conf
+ # Save setting to file
+ echo "API_EXCLUDE_DOMAINS=${args[2]}" >> /etc/pihole/setupVars.conf
+}
+
+SetExcludeClients(){
+
+ # Remove setting from file (create backup setupVars.conf.bak)
+ sed -i.bak '/API_EXCLUDE_CLIENTS/d;' /etc/pihole/setupVars.conf
+ # Save setting to file
+ echo "API_EXCLUDE_CLIENTS=${args[2]}" >> /etc/pihole/setupVars.conf
+}
+
for var in "$@"; do
case "${var}" in
"-p" | "password" ) SetWebPassword;;
"-c" | "celsius" ) unit="C"; SetTemperatureUnit;;
"-f" | "fahrenheit" ) unit="F"; SetTemperatureUnit;;
"setdns" ) SetDNSServers;;
+ "setexcludedomains" ) SetExcludeDomains;;
+ "setexcludeclients" ) SetExcludeClients;;
"-h" | "--help" ) helpFunc;;
esac
done
From 2bafa2f2ac685798d120ab1393940354978d4e75 Mon Sep 17 00:00:00 2001
From: DL6ER
Date: Sun, 11 Dec 2016 22:33:27 +0100
Subject: [PATCH 184/228] Add reboot option
---
advanced/Scripts/webpage.sh | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/advanced/Scripts/webpage.sh b/advanced/Scripts/webpage.sh
index 35ba6875..bdd3a17f 100755
--- a/advanced/Scripts/webpage.sh
+++ b/advanced/Scripts/webpage.sh
@@ -83,6 +83,12 @@ SetExcludeClients(){
echo "API_EXCLUDE_CLIENTS=${args[2]}" >> /etc/pihole/setupVars.conf
}
+Reboot(){
+
+ reboot
+
+}
+
for var in "$@"; do
case "${var}" in
"-p" | "password" ) SetWebPassword;;
@@ -91,6 +97,7 @@ for var in "$@"; do
"setdns" ) SetDNSServers;;
"setexcludedomains" ) SetExcludeDomains;;
"setexcludeclients" ) SetExcludeClients;;
+ "reboot" ) Reboot;;
"-h" | "--help" ) helpFunc;;
esac
done
From aaab3306a87c7e8384bbe0c4e46cb0c6e56acc03 Mon Sep 17 00:00:00 2001
From: DL6ER
Date: Mon, 12 Dec 2016 10:38:21 +0100
Subject: [PATCH 185/228] Add restart DNS capability
---
advanced/Scripts/webpage.sh | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/advanced/Scripts/webpage.sh b/advanced/Scripts/webpage.sh
index bdd3a17f..a7a76161 100755
--- a/advanced/Scripts/webpage.sh
+++ b/advanced/Scripts/webpage.sh
@@ -89,6 +89,16 @@ Reboot(){
}
+RestartDNS(){
+
+ if [ -x "$(command -v systemctl)" ]; then
+ systemctl restart dnsmasq &> /dev/null
+ else
+ service dnsmasq restart &> /dev/null
+ fi
+
+}
+
for var in "$@"; do
case "${var}" in
"-p" | "password" ) SetWebPassword;;
@@ -98,6 +108,7 @@ for var in "$@"; do
"setexcludedomains" ) SetExcludeDomains;;
"setexcludeclients" ) SetExcludeClients;;
"reboot" ) Reboot;;
+ "restartdns" ) RestartDNS;;
"-h" | "--help" ) helpFunc;;
esac
done
From d4f83cb1d4792283fd0d7f844518fc02a33c5c24 Mon Sep 17 00:00:00 2001
From: DL6ER
Date: Mon, 12 Dec 2016 13:15:07 +0100
Subject: [PATCH 186/228] Be able to set API_QUERY_LOG_SHOW
---
advanced/Scripts/webpage.sh | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/advanced/Scripts/webpage.sh b/advanced/Scripts/webpage.sh
index a7a76161..4df11f38 100755
--- a/advanced/Scripts/webpage.sh
+++ b/advanced/Scripts/webpage.sh
@@ -99,6 +99,14 @@ RestartDNS(){
}
+SetQueryLogOptions(){
+
+ # Remove setting from file (create backup setupVars.conf.bak)
+ sed -i.bak '/API_QUERY_LOG_SHOW/d;' /etc/pihole/setupVars.conf
+ # Save setting to file
+ echo "API_QUERY_LOG_SHOW=${args[2]}" >> /etc/pihole/setupVars.conf
+}
+
for var in "$@"; do
case "${var}" in
"-p" | "password" ) SetWebPassword;;
@@ -109,6 +117,7 @@ for var in "$@"; do
"setexcludeclients" ) SetExcludeClients;;
"reboot" ) Reboot;;
"restartdns" ) RestartDNS;;
+ "setquerylog" ) SetQueryLogOptions;;
"-h" | "--help" ) helpFunc;;
esac
done
From 2f4b7ce3dd3749acc5513ab63214cdd38f265609 Mon Sep 17 00:00:00 2001
From: DL6ER
Date: Mon, 12 Dec 2016 14:16:13 +0100
Subject: [PATCH 187/228] Update dnsmasq file when changing upstream DNS
servers and restart the service to get it active
---
advanced/Scripts/webpage.sh | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/advanced/Scripts/webpage.sh b/advanced/Scripts/webpage.sh
index 4df11f38..6ae2c327 100755
--- a/advanced/Scripts/webpage.sh
+++ b/advanced/Scripts/webpage.sh
@@ -65,6 +65,14 @@ SetDNSServers(){
echo "PIHOLE_DNS_1=${args[2]}" >> /etc/pihole/setupVars.conf
echo "PIHOLE_DNS_2=${args[3]}" >> /etc/pihole/setupVars.conf
+ # Replace within actual dnsmasq config file
+ sed -i '/server=/d;' /etc/dnsmasq.d/01-pihole.conf
+ echo "server=${args[2]}" >> /etc/dnsmasq.d/01-pihole.conf
+ echo "server=${args[3]}" >> /etc/dnsmasq.d/01-pihole.conf
+
+ # Restart dnsmasq to load new configuration
+ RestartDNS
+
}
SetExcludeDomains(){
From 8dc0dc4d694a3873134c8cbf3d75d3b0fe18f815 Mon Sep 17 00:00:00 2001
From: DL6ER
Date: Mon, 12 Dec 2016 15:34:05 +0100
Subject: [PATCH 188/228] Add DHCP-Server backend
---
advanced/Scripts/webpage.sh | 36 ++++++++++++++++++++++++++++++++++++
1 file changed, 36 insertions(+)
diff --git a/advanced/Scripts/webpage.sh b/advanced/Scripts/webpage.sh
index 6ae2c327..a930856f 100755
--- a/advanced/Scripts/webpage.sh
+++ b/advanced/Scripts/webpage.sh
@@ -115,6 +115,40 @@ SetQueryLogOptions(){
echo "API_QUERY_LOG_SHOW=${args[2]}" >> /etc/pihole/setupVars.conf
}
+EnableDHCP(){
+
+ # Remove setting from file (create backup setupVars.conf.bak)
+ sed -i.bak '/DHCP_/d;' /etc/pihole/setupVars.conf
+ echo "DHCP_ACTIVE=true" >> /etc/pihole/setupVars.conf
+ echo "DHCP_START=${args[2]}" >> /etc/pihole/setupVars.conf
+ echo "DHCP_END=${args[3]}" >> /etc/pihole/setupVars.conf
+ echo "DHCP_ROUTER=${args[4]}" >> /etc/pihole/setupVars.conf
+
+ # Remove setting from file
+ sed -i '/dhcp-/d;' /etc/dnsmasq.d/01-pihole.conf
+ # Save setting to file
+ echo "dhcp-range=${args[2]},${args[3]},infinite" >> /etc/dnsmasq.d/01-pihole.conf
+ echo "dhcp-option=option:router,${args[4]}" >> /etc/dnsmasq.d/01-pihole.conf
+ # Changes the behaviour from strict RFC compliance so that DHCP requests on unknown leases from unknown hosts are not ignored. This allows new hosts to get a lease without a tedious timeout under all circumstances. It also allows dnsmasq to rebuild its lease database without each client needing to reacquire a lease, if the database is lost.
+ echo "dhcp-authoritative" >> /etc/dnsmasq.d/01-pihole.conf
+ # Use the specified file to store DHCP lease information
+ echo "dhcp-leasefile=/etc/pihole/dhcp.leases" >> /etc/dnsmasq.d/01-pihole.conf
+
+ RestartDNS
+}
+
+DisableDHCP(){
+
+ # Remove setting from file (create backup setupVars.conf.bak)
+ sed -i.bak '/DHCP_ACTIVE/d;' /etc/pihole/setupVars.conf
+ echo "DHCP_ACTIVE=false" >> /etc/pihole/setupVars.conf
+
+ # Remove setting from file
+ sed -i '/dhcp-/d;' /etc/dnsmasq.d/01-pihole.conf
+
+ RestartDNS
+}
+
for var in "$@"; do
case "${var}" in
"-p" | "password" ) SetWebPassword;;
@@ -126,6 +160,8 @@ for var in "$@"; do
"reboot" ) Reboot;;
"restartdns" ) RestartDNS;;
"setquerylog" ) SetQueryLogOptions;;
+ "enabledhcp" ) EnableDHCP;;
+ "disabledhcp" ) DisableDHCP;;
"-h" | "--help" ) helpFunc;;
esac
done
From a00034a6a7a12f0fe587b59b34466e063d79912e Mon Sep 17 00:00:00 2001
From: DL6ER
Date: Mon, 12 Dec 2016 17:03:53 +0100
Subject: [PATCH 189/228] Add password to webUI after update if there is none
---
automated install/basic-install.sh | 23 ++++++++++++++++++++++-
1 file changed, 22 insertions(+), 1 deletion(-)
diff --git a/automated install/basic-install.sh b/automated install/basic-install.sh
index 33444873..08963637 100755
--- a/automated install/basic-install.sh
+++ b/automated install/basic-install.sh
@@ -994,6 +994,11 @@ configureSelinux() {
}
displayFinalMessage() {
+ if [ ! -z $pw ]; then
+ pwstring="Note: As security measure a password has been installed for your web interface\n The currently set password is\n ${pw}\n\n You can always change it using\n pihole -a -p new_password"
+ else
+ pswsting=""
+ fi
# Final completion message to user
whiptail --msgbox --backtitle "Make it so." --title "Installation Complete!" "Configure your devices to use the Pi-hole as their DNS server using:
@@ -1003,7 +1008,8 @@ IPv6: ${IPV6_ADDRESS}
If you set a new IP address, you should restart the Pi.
The install log is in /etc/pihole.
-View the web interface at http://pi.hole/admin or http://${IPV4_ADDRESS%/*}/admin" ${r} ${c}
+View the web interface at http://pi.hole/admin or http://${IPV4_ADDRESS%/*}/admin
+${string}" ${r} ${c}
}
update_dialogs() {
@@ -1122,6 +1128,12 @@ main() {
# Move the log file into /etc/pihole for storage
mv ${tmpLog} ${instalLogLoc}
+ # Add password to web UI if there is none
+ if [[ $(grep 'WEBPASSWORD' -c /etc/pihole/setupVars.conf) == 0 ]] ; then
+ pw=$(tr -dc _A-Z-a-z-0-9 < /dev/urandom | head -c 8)
+ pihole -a -p ${pw}
+ fi
+
if [[ "${useUpdateVars}" == false ]]; then
displayFinalMessage
fi
@@ -1144,6 +1156,15 @@ main() {
echo "::: View the web interface at http://pi.hole/admin or http://${IPV4_ADDRESS%/*}/admin"
else
echo "::: Update complete!"
+ if [ ! -z $pw ]; then
+ echo ":::"
+ echo "::: Note: As security measure a password has been installed for your web interface"
+ echo "::: The currently set password is"
+ echo "::: ${pw}"
+ echo ":::"
+ echo "::: You can always change it using"
+ echo "::: pihole -a -p new_password"
+ fi
fi
echo ":::"
From bc91716082fbd7dc139f434e7326a31216e811fe Mon Sep 17 00:00:00 2001
From: DL6ER
Date: Mon, 12 Dec 2016 17:14:52 +0100
Subject: [PATCH 190/228] Suppress logging of DHCP actions to
/var/log/pihole.log
---
advanced/Scripts/webpage.sh | 3 +++
1 file changed, 3 insertions(+)
diff --git a/advanced/Scripts/webpage.sh b/advanced/Scripts/webpage.sh
index a930856f..21de7067 100755
--- a/advanced/Scripts/webpage.sh
+++ b/advanced/Scripts/webpage.sh
@@ -133,6 +133,9 @@ EnableDHCP(){
echo "dhcp-authoritative" >> /etc/dnsmasq.d/01-pihole.conf
# Use the specified file to store DHCP lease information
echo "dhcp-leasefile=/etc/pihole/dhcp.leases" >> /etc/dnsmasq.d/01-pihole.conf
+ # Suppress logging of the routine operation of these protocols. Errors and problems will still be logged, though.
+ echo "quiet-dhcp" >> /etc/dnsmasq.d/01-pihole.conf
+ echo "quiet-dhcp6" >> /etc/dnsmasq.d/01-pihole.conf
RestartDNS
}
From 8a2ee95e4ac9dc07a7bec69e0048721a25e83b58 Mon Sep 17 00:00:00 2001
From: Mcat12
Date: Mon, 12 Dec 2016 15:30:47 -0500
Subject: [PATCH 191/228] Update ADZHOSTS list
---
adlists.default | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/adlists.default b/adlists.default
index 57860b3f..92422db7 100644
--- a/adlists.default
+++ b/adlists.default
@@ -28,7 +28,7 @@ https://hosts-file.net/ad_servers.txt
#http://adblock.mahakala.is/
# ADZHOSTS list. Has been known to block legitimate domains
-#http://optimate.dl.sourceforge.net/project/adzhosts/HOSTS.txt
+#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
From b8d2bfc890c36c9418e5e8d066e45b6fc65810f1 Mon Sep 17 00:00:00 2001
From: DL6ER
Date: Tue, 13 Dec 2016 12:42:40 +0100
Subject: [PATCH 192/228] Wait 5 seconds before rebooting so the web UI can
finish loading before being unreachable due to the reboot
---
advanced/Scripts/webpage.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/advanced/Scripts/webpage.sh b/advanced/Scripts/webpage.sh
index 21de7067..4730118d 100755
--- a/advanced/Scripts/webpage.sh
+++ b/advanced/Scripts/webpage.sh
@@ -93,7 +93,7 @@ SetExcludeClients(){
Reboot(){
- reboot
+ nohup bash -c "sleep 5; reboot" &> /dev/null
Date: Tue, 13 Dec 2016 14:59:52 +0100
Subject: [PATCH 193/228] Add "Interface appearence" option
---
advanced/Scripts/webpage.sh | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/advanced/Scripts/webpage.sh b/advanced/Scripts/webpage.sh
index 4730118d..5863d2dc 100755
--- a/advanced/Scripts/webpage.sh
+++ b/advanced/Scripts/webpage.sh
@@ -152,6 +152,14 @@ DisableDHCP(){
RestartDNS
}
+SetWebUILayout(){
+
+ # Remove setting from file (create backup setupVars.conf.bak)
+ sed -i.bak '/WEBUIBOXEDLAYOUT/d;' /etc/pihole/setupVars.conf
+ echo "WEBUIBOXEDLAYOUT=${args[2]}" >> /etc/pihole/setupVars.conf
+
+}
+
for var in "$@"; do
case "${var}" in
"-p" | "password" ) SetWebPassword;;
@@ -165,6 +173,7 @@ for var in "$@"; do
"setquerylog" ) SetQueryLogOptions;;
"enabledhcp" ) EnableDHCP;;
"disabledhcp" ) DisableDHCP;;
+ "layout" ) SetWebUILayout;;
"-h" | "--help" ) helpFunc;;
esac
done
From 004ba283789d38cbad4054f7d0824f2850e03e20 Mon Sep 17 00:00:00 2001
From: DL6ER
Date: Tue, 13 Dec 2016 15:52:28 +0100
Subject: [PATCH 194/228] Prevent web UI password change by web user
---
advanced/Scripts/webpage.sh | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/advanced/Scripts/webpage.sh b/advanced/Scripts/webpage.sh
index 0a79d853..db7d2026 100755
--- a/advanced/Scripts/webpage.sh
+++ b/advanced/Scripts/webpage.sh
@@ -41,6 +41,18 @@ SetTemperatureUnit(){
SetWebPassword(){
+ if[ "$SUDO_USER" == "www-data" ]; then
+ echo "Security measure: user www-data is not allowed to change webUI password!"
+ echo "Exiting"
+ exit 1
+ fi
+
+ if[ "$SUDO_USER" == "lighttpd" ]; then
+ echo "Security measure: user lighttpd is not allowed to change webUI password!"
+ echo "Exiting"
+ exit 1
+ fi
+
# Remove password from file (create backup setupVars.conf.bak)
sed -i.bak '/WEBPASSWORD/d' /etc/pihole/setupVars.conf
# Set password only if there is one to be set
From 207422f83a4deccb0e932f78fbd0db02707810b6 Mon Sep 17 00:00:00 2001
From: DL6ER
Date: Tue, 13 Dec 2016 15:54:41 +0100
Subject: [PATCH 195/228] Added a missing space
---
advanced/Scripts/webpage.sh | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/advanced/Scripts/webpage.sh b/advanced/Scripts/webpage.sh
index db7d2026..0beb688f 100755
--- a/advanced/Scripts/webpage.sh
+++ b/advanced/Scripts/webpage.sh
@@ -41,13 +41,13 @@ SetTemperatureUnit(){
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 "Exiting"
exit 1
fi
- if[ "$SUDO_USER" == "lighttpd" ]; then
+ if [ "${SUDO_USER}" == "lighttpd" ]; then
echo "Security measure: user lighttpd is not allowed to change webUI password!"
echo "Exiting"
exit 1
From 1556adb678a11e1f2c66474330d515b6eb62aa99 Mon Sep 17 00:00:00 2001
From: DL6ER
Date: Wed, 14 Dec 2016 12:12:36 +0100
Subject: [PATCH 196/228] Also remove quiet-dhcp setting when
disabling/enabling the Pi-Hole DHCP server
---
advanced/Scripts/webpage.sh | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/advanced/Scripts/webpage.sh b/advanced/Scripts/webpage.sh
index 179580b4..1ee41b15 100755
--- a/advanced/Scripts/webpage.sh
+++ b/advanced/Scripts/webpage.sh
@@ -137,7 +137,7 @@ EnableDHCP(){
echo "DHCP_ROUTER=${args[4]}" >> /etc/pihole/setupVars.conf
# Remove setting from file
- sed -i '/dhcp-/d;' /etc/dnsmasq.d/01-pihole.conf
+ sed -i '/dhcp-/d;/quiet-dhcp/d;' /etc/dnsmasq.d/01-pihole.conf
# Save setting to file
echo "dhcp-range=${args[2]},${args[3]},infinite" >> /etc/dnsmasq.d/01-pihole.conf
echo "dhcp-option=option:router,${args[4]}" >> /etc/dnsmasq.d/01-pihole.conf
@@ -159,7 +159,7 @@ DisableDHCP(){
echo "DHCP_ACTIVE=false" >> /etc/pihole/setupVars.conf
# Remove setting from file
- sed -i '/dhcp-/d;' /etc/dnsmasq.d/01-pihole.conf
+ sed -i '/dhcp-/d;/quiet-dhcp/d;' /etc/dnsmasq.d/01-pihole.conf
RestartDNS
}
From ba015c191845fe279ef8b5943c3b213d5dbf0f88 Mon Sep 17 00:00:00 2001
From: DL6ER
Date: Wed, 14 Dec 2016 14:24:09 +0100
Subject: [PATCH 197/228] Set domain name via Settings page
---
advanced/Scripts/webpage.sh | 50 ++++++++++++++++++++++++-------------
1 file changed, 33 insertions(+), 17 deletions(-)
diff --git a/advanced/Scripts/webpage.sh b/advanced/Scripts/webpage.sh
index 1ee41b15..4f7fa43b 100755
--- a/advanced/Scripts/webpage.sh
+++ b/advanced/Scripts/webpage.sh
@@ -172,23 +172,39 @@ SetWebUILayout(){
}
-for var in "$@"; do
- case "${var}" in
- "-p" | "password" ) SetWebPassword;;
- "-c" | "celsius" ) unit="C"; SetTemperatureUnit;;
- "-f" | "fahrenheit" ) unit="F"; SetTemperatureUnit;;
- "setdns" ) SetDNSServers;;
- "setexcludedomains" ) SetExcludeDomains;;
- "setexcludeclients" ) SetExcludeClients;;
- "reboot" ) Reboot;;
- "restartdns" ) RestartDNS;;
- "setquerylog" ) SetQueryLogOptions;;
- "enabledhcp" ) EnableDHCP;;
- "disabledhcp" ) DisableDHCP;;
- "layout" ) SetWebUILayout;;
- "-h" | "--help" ) helpFunc;;
- esac
-done
+SetDNSDomainName(){
+
+ # Remove setting from file (create backup setupVars.conf.bak)
+ sed -i.bak '/PIHOLE_DOMAIN/d;' /etc/pihole/setupVars.conf
+ # Save setting to file
+ echo "PIHOLE_DOMAIN=${args[2]}" >> /etc/pihole/setupVars.conf
+
+ # Replace within actual dnsmasq config file
+ sed -i '/domain=/d;' /etc/dnsmasq.d/01-pihole.conf
+ echo "domain=${args[2]}" >> /etc/dnsmasq.d/01-pihole.conf
+
+ # Restart dnsmasq to load new configuration
+ RestartDNS
+
+}
+
+case "${args[1]}" in
+ "-p" | "password" ) SetWebPassword;;
+ "-c" | "celsius" ) unit="C"; SetTemperatureUnit;;
+ "-f" | "fahrenheit" ) unit="F"; SetTemperatureUnit;;
+ "setdns" ) SetDNSServers;;
+ "setexcludedomains" ) SetExcludeDomains;;
+ "setexcludeclients" ) SetExcludeClients;;
+ "reboot" ) Reboot;;
+ "restartdns" ) RestartDNS;;
+ "setquerylog" ) SetQueryLogOptions;;
+ "enabledhcp" ) EnableDHCP;;
+ "disabledhcp" ) DisableDHCP;;
+ "layout" ) SetWebUILayout;;
+ "-h" | "--help" ) helpFunc;;
+ "domainname" ) SetDNSDomainName;;
+ * ) helpFunc;;
+esac
shift
From 85e3f37503f0da4e85099614ea01ff5f7516051f Mon Sep 17 00:00:00 2001
From: DL6ER
Date: Wed, 14 Dec 2016 16:09:57 +0100
Subject: [PATCH 198/228] dnsmasq "domain-needed" property
---
advanced/Scripts/webpage.sh | 14 +++++++++++++-
1 file changed, 13 insertions(+), 1 deletion(-)
diff --git a/advanced/Scripts/webpage.sh b/advanced/Scripts/webpage.sh
index 4f7fa43b..3309fc99 100755
--- a/advanced/Scripts/webpage.sh
+++ b/advanced/Scripts/webpage.sh
@@ -72,7 +72,7 @@ SetWebPassword(){
SetDNSServers(){
# Remove setting from file (create backup setupVars.conf.bak)
- sed -i.bak '/PIHOLE_DNS_1/d;/PIHOLE_DNS_2/d;' /etc/pihole/setupVars.conf
+ sed -i.bak '/PIHOLE_DNS_1/d;/PIHOLE_DNS_2/d;/DNS_FQDN_REQUIRED/d;' /etc/pihole/setupVars.conf
# Save setting to file
echo "PIHOLE_DNS_1=${args[2]}" >> /etc/pihole/setupVars.conf
echo "PIHOLE_DNS_2=${args[3]}" >> /etc/pihole/setupVars.conf
@@ -82,6 +82,18 @@ SetDNSServers(){
echo "server=${args[2]}" >> /etc/dnsmasq.d/01-pihole.conf
echo "server=${args[3]}" >> /etc/dnsmasq.d/01-pihole.conf
+ # Remove domain-needed entry
+ sed -i '/domain-needed/d;' /etc/dnsmasq.d/01-pihole.conf
+
+ # Readd it if required
+ if [[ "${args[4]}" == "domain-needed" ]]; then
+ echo "domain-needed" >> /etc/dnsmasq.d/01-pihole.conf
+ echo "DNS_FQDN_REQUIRED=true" >> /etc/pihole/setupVars.conf
+ else
+ echo "DNS_FQDN_REQUIRED=false" >> /etc/pihole/setupVars.conf
+ fi
+ # Leave it deleted if not wanted
+
# Restart dnsmasq to load new configuration
RestartDNS
From 2977168da139d0f547d898fa7baba181a653fef8 Mon Sep 17 00:00:00 2001
From: DL6ER
Date: Wed, 14 Dec 2016 16:16:25 +0100
Subject: [PATCH 199/228] dnsmasq "bogus-priv" property
---
advanced/Scripts/webpage.sh | 14 +++++++++++++-
1 file changed, 13 insertions(+), 1 deletion(-)
diff --git a/advanced/Scripts/webpage.sh b/advanced/Scripts/webpage.sh
index 3309fc99..d07e5c94 100755
--- a/advanced/Scripts/webpage.sh
+++ b/advanced/Scripts/webpage.sh
@@ -90,9 +90,21 @@ SetDNSServers(){
echo "domain-needed" >> /etc/dnsmasq.d/01-pihole.conf
echo "DNS_FQDN_REQUIRED=true" >> /etc/pihole/setupVars.conf
else
+ # Leave it deleted if not wanted
echo "DNS_FQDN_REQUIRED=false" >> /etc/pihole/setupVars.conf
fi
- # Leave it deleted if not wanted
+
+ # Remove bogus-priv entry
+ sed -i '/bogus-priv/d;' /etc/dnsmasq.d/01-pihole.conf
+
+ # Readd it if required
+ if [[ "${args[5]}" == "bogus-priv" ]]; then
+ echo "bogus-priv" >> /etc/dnsmasq.d/01-pihole.conf
+ echo "DNS_BOGUS_PRIV=true" >> /etc/pihole/setupVars.conf
+ else
+ # Leave it deleted if not wanted
+ echo "DNS_BOGUS_PRIV=false" >> /etc/pihole/setupVars.conf
+ fi
# Restart dnsmasq to load new configuration
RestartDNS
From 9a2ffabc33d09277025da20c37b3d7dc3e89a84b Mon Sep 17 00:00:00 2001
From: DL6ER
Date: Wed, 14 Dec 2016 17:33:20 +0100
Subject: [PATCH 200/228] Fix missing path information
---
advanced/pihole.cron | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/advanced/pihole.cron b/advanced/pihole.cron
index 77b7c1ca..8311acfb 100644
--- a/advanced/pihole.cron
+++ b/advanced/pihole.cron
@@ -8,7 +8,7 @@
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 2 of the License, or
# (at your option) any later version.
-#
+#
# This file is under source-control of the Pi-hole installation and update
# scripts, any changes made to this file will be overwritten when the softare
# is updated or re-installed. Please make any changes to the appropriate crontab
@@ -16,11 +16,11 @@
# Pi-hole: Update the ad sources once a week on Sunday at 01:59
# Download any updates from the adlists
-59 1 * * 7 root /usr/local/bin/pihole updateGravity
+59 1 * * 7 root PATH="$PATH:/usr/local/bin/" pihole updateGravity
# Pi-hole: Update Pi-hole! Uncomment to enable auto update
-#30 2 * * 7 root /usr/local/bin/pihole updatePihole
+#30 2 * * 7 root PATH="$PATH:/usr/local/bin/" pihole updatePihole
# Pi-hole: Flush the log daily at 00:00 so it doesn't get out of control
# Stats will be viewable in the Web interface thanks to the cron job above
-00 00 * * * root /usr/local/bin/pihole flush
+00 00 * * * root PATH="$PATH:/usr/local/bin/" pihole flush
From 92f48248846af59b372404896163fba217d4372f Mon Sep 17 00:00:00 2001
From: Mcat12
Date: Wed, 14 Dec 2016 13:52:14 -0500
Subject: [PATCH 201/228] Automatically enable IPv6
---
automated install/basic-install.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/automated install/basic-install.sh b/automated install/basic-install.sh
index 33444873..afa44701 100755
--- a/automated install/basic-install.sh
+++ b/automated install/basic-install.sh
@@ -297,7 +297,7 @@ use4andor6() {
# Let use select IPv4 and/or IPv6
cmd=(whiptail --separate-output --checklist "Select Protocols (press space to select)" ${r} ${c} 2)
options=(IPv4 "Block ads over IPv4" on
- IPv6 "Block ads over IPv6" off)
+ IPv6 "Block ads over IPv6" on)
choices=$("${cmd[@]}" "${options[@]}" 2>&1 >/dev/tty)
if [[ $? = 0 ]];then
for choice in ${choices}
From db89fa9881f0a2047311e6e058c1e8d32904dfbd Mon Sep 17 00:00:00 2001
From: Promofaux
Date: Wed, 14 Dec 2016 19:26:55 +0000
Subject: [PATCH 202/228] initial support for additional hosts file
---
gravity.sh | 41 +++++++++++++++++++++++++++--------------
1 file changed, 27 insertions(+), 14 deletions(-)
diff --git a/gravity.sh b/gravity.sh
index 0184f193..1c1c397f 100755
--- a/gravity.sh
+++ b/gravity.sh
@@ -45,11 +45,13 @@ fi
#Remove the /* from the end of the IPv4addr.
IPV4_ADDRESS=${IPV4_ADDRESS%/*}
+IPV6_ADDRESS=${IPV6_ADDRESS}
# Variables for various stages of downloading and formatting the list
basename=pihole
piholeDir=/etc/${basename}
adList=${piholeDir}/gravity.list
+localList=${piholeDir}/local.list
justDomainsExtension=domains
matterAndLight=${basename}.0.matterandlight.txt
supernova=${basename}.1.supernova.txt
@@ -241,26 +243,37 @@ gravity_unique() {
gravity_hostFormat() {
# Format domain list as "192.168.x.x domain.com"
echo -n "::: Formatting domains into a HOSTS file..."
- # Check vars from setupVars.conf to see if we're using IPv4, IPv6, Or both.
- if [[ -n "${IPV4_ADDRESS}" && -n "${IPV6_ADDRESS}" ]];then
+ rm ${localList}
+ if [[ -f /etc/hostname ]]; then
+ hostname=$(> ${piholeDir}/${accretionDisc}
+ echo -e "${IPV4_ADDRESS} ${hostname}\n${IPV6_ADDRESS} ${hostname}\n${IPV4_ADDRESS} pi.hole\n${IPV6_ADDRESS} pi.hole" > ${localList}
+ # Both IPv4 and IPv6
+ cat ${piholeDir}/${eventHorizon} | awk -v ipv4addr="$IPV4_ADDRESS" -v ipv6addr="$IPV6_ADDRESS" '{sub(/\r$/,""); print ipv4addr" "$0"\n"ipv6addr" "$0}' >> ${piholeDir}/${accretionDisc}
- elif [[ -n "${IPV4_ADDRESS}" && -z "${IPV6_ADDRESS}" ]];then
+ elif [[ -n "${IPV4_ADDRESS}" && -z "${IPV6_ADDRESS}" ]];then
- # Only IPv4
- cat ${piholeDir}/${eventHorizon} | awk -v ipv4addr="$IPV4_ADDRESS" '{sub(/\r$/,""); print ipv4addr" "$0}' >> ${piholeDir}/${accretionDisc}
+ echo -e "${IPV4_ADDRESS} ${hostname}\n${IPV4_ADDRESS} pi.hole" > ${localList}
+ # Only IPv4
+ cat ${piholeDir}/${eventHorizon} | awk -v ipv4addr="$IPV4_ADDRESS" '{sub(/\r$/,""); print ipv4addr" "$0}' >> ${piholeDir}/${accretionDisc}
- elif [[ -z "${IPV4_ADDRESS}" && -n "${IPV6_ADDRESS}" ]];then
+ elif [[ -z "${IPV4_ADDRESS}" && -n "${IPV6_ADDRESS}" ]];then
- # Only IPv6
- cat ${piholeDir}/${eventHorizon} | awk -v ipv6addr="$IPV6_ADDRESS" '{sub(/\r$/,""); print ipv6addr" "$0}' >> ${piholeDir}/${accretionDisc}
+ echo -e "${IPV6_ADDRESS} ${hostname}\n${IPV6_ADDRESS} pi.hole" > ${localList}
+ # Only IPv6
+ cat ${piholeDir}/${eventHorizon} | awk -v ipv6addr="$IPV6_ADDRESS" '{sub(/\r$/,""); print ipv6addr" "$0}' >> ${piholeDir}/${accretionDisc}
- elif [[ -z "${IPV4_ADDRESS}" && -z "${IPV6_ADDRESS}" ]];then
- echo "::: No IP Values found! Please run 'pihole -r' and choose reconfigure to restore values"
- exit 1
- fi
+ elif [[ -z "${IPV4_ADDRESS}" && -z "${IPV6_ADDRESS}" ]];then
+ echo "::: No IP Values found! Please run 'pihole -r' and choose reconfigure to restore values"
+ exit 1
+ fi
# Copy the file over as /etc/pihole/gravity.list so dnsmasq can use it
cp ${piholeDir}/${accretionDisc} ${adList}
From 684ac98c8ed6c365ec94f0a0894b0a1ef58e3602 Mon Sep 17 00:00:00 2001
From: Promofaux
Date: Wed, 14 Dec 2016 19:28:01 +0000
Subject: [PATCH 203/228] Remove hostname and pi.hole entries, move to
/etc/pihole/local.list
---
advanced/01-pihole.conf | 7 +------
1 file changed, 1 insertion(+), 6 deletions(-)
diff --git a/advanced/01-pihole.conf b/advanced/01-pihole.conf
index f4707ef4..0ddf1caa 100644
--- a/advanced/01-pihole.conf
+++ b/advanced/01-pihole.conf
@@ -20,13 +20,8 @@
# OR IN /etc/dnsmasq.conf #
###############################################################################
-address=/pi.hole/@IPv4@
-address=/pi.hole/@IPv6@
-
-address=/@HOSTNAME@/@IPv4@
-address=/@HOSTNAME@/@IPv6@
-
addn-hosts=/etc/pihole/gravity.list
+addn-hosts=/etc/pihole/local.list
domain-needed
From c10ec5548f0ce1c45052e80235e825120b9dde40 Mon Sep 17 00:00:00 2001
From: Promofaux
Date: Wed, 14 Dec 2016 19:29:44 +0000
Subject: [PATCH 204/228] remove code that replaces tokens in 01-pihole.conf
---
automated install/basic-install.sh | 30 ------------------------------
1 file changed, 30 deletions(-)
diff --git a/automated install/basic-install.sh b/automated install/basic-install.sh
index afa44701..9464d03b 100755
--- a/automated install/basic-install.sh
+++ b/automated install/basic-install.sh
@@ -612,36 +612,6 @@ version_check_dnsmasq() {
sed -i '/^server=@DNS2@/d' ${dnsmasq_pihole_01_location}
fi
- #sed -i "s/@HOSTNAME@/$hostname/" ${dnsmasq_pihole_01_location}
-
- if [[ -f /etc/hostname ]]; then
- hostname=$(
Date: Wed, 14 Dec 2016 19:31:57 +0000
Subject: [PATCH 205/228] check for list before removing it
---
gravity.sh | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/gravity.sh b/gravity.sh
index 1c1c397f..9ddd7beb 100755
--- a/gravity.sh
+++ b/gravity.sh
@@ -243,7 +243,11 @@ gravity_unique() {
gravity_hostFormat() {
# Format domain list as "192.168.x.x domain.com"
echo -n "::: Formatting domains into a HOSTS file..."
- rm ${localList}
+
+ if [[ -f ${localList} ]]; then
+ rm ${localList}
+ fi
+
if [[ -f /etc/hostname ]]; then
hostname=$(
Date: Wed, 14 Dec 2016 19:33:15 +0000
Subject: [PATCH 206/228] no need to remove list, because of echo >
---
gravity.sh | 4 ----
1 file changed, 4 deletions(-)
diff --git a/gravity.sh b/gravity.sh
index 9ddd7beb..58d0eef9 100755
--- a/gravity.sh
+++ b/gravity.sh
@@ -244,10 +244,6 @@ gravity_hostFormat() {
# Format domain list as "192.168.x.x domain.com"
echo -n "::: Formatting domains into a HOSTS file..."
- if [[ -f ${localList} ]]; then
- rm ${localList}
- fi
-
if [[ -f /etc/hostname ]]; then
hostname=$(
Date: Wed, 14 Dec 2016 19:42:20 +0000
Subject: [PATCH 207/228] specifically comment out gravity.list addn-host
---
pihole | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/pihole b/pihole
index 6d5f8c9d..5509df47 100755
--- a/pihole
+++ b/pihole
@@ -135,7 +135,7 @@ restartDNS() {
piholeEnable() {
if [[ "${1}" == "0" ]] ; then
#Disable Pihole
- sed -i 's/^addn-hosts/#addn-hosts/' /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!"
if [[ $# > 1 ]] ; then
if [[ ${2} == *"s"* ]] ; then
From e7713a9028fce828cfb02406bc972fa42c4bcc17 Mon Sep 17 00:00:00 2001
From: Promofaux
Date: Wed, 14 Dec 2016 19:53:40 +0000
Subject: [PATCH 208/228] add missing pihole autocomplete commands
---
advanced/bash-completion/pihole | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/advanced/bash-completion/pihole b/advanced/bash-completion/pihole
index dd3f050d..05baa820 100644
--- a/advanced/bash-completion/pihole
+++ b/advanced/bash-completion/pihole
@@ -3,7 +3,7 @@ _pihole() {
COMPREPLY=()
cur="${COMP_WORDS[COMP_CWORD]}"
prev="${COMP_WORDS[COMP_CWORD-1]}"
- opts="blacklist chronometer debug flush help query reconfigure setupLCD uninstall updateGravity updatePihole version whitelist"
+ opts="admin blacklist chronometer debug disable enable flush help logging query reconfigure restartdns setupLCD status tail uninstall updateGravity updatePihole version whitelist"
COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
return 0
From f81dadc5d08c647ca4ddbd72caf1e5c310ea4ac7 Mon Sep 17 00:00:00 2001
From: DL6ER
Date: Thu, 15 Dec 2016 14:10:55 +0100
Subject: [PATCH 209/228] Fix final message
---
automated install/basic-install.sh | 27 ++++++++++++++++++++-------
1 file changed, 20 insertions(+), 7 deletions(-)
diff --git a/automated install/basic-install.sh b/automated install/basic-install.sh
index 08963637..b8f0c2dc 100755
--- a/automated install/basic-install.sh
+++ b/automated install/basic-install.sh
@@ -994,11 +994,7 @@ configureSelinux() {
}
displayFinalMessage() {
- if [ ! -z $pw ]; then
- pwstring="Note: As security measure a password has been installed for your web interface\n The currently set password is\n ${pw}\n\n You can always change it using\n pihole -a -p new_password"
- else
- pswsting=""
- fi
+ if (( ${#1} > 0 )) ; then
# Final completion message to user
whiptail --msgbox --backtitle "Make it so." --title "Installation Complete!" "Configure your devices to use the Pi-hole as their DNS server using:
@@ -1009,7 +1005,23 @@ If you set a new IP address, you should restart the Pi.
The install log is in /etc/pihole.
View the web interface at http://pi.hole/admin or http://${IPV4_ADDRESS%/*}/admin
-${string}" ${r} ${c}
+
+Note: As security measure a password has been installed for your web interface
+The currently set password is
+ ${1}
+You can always change it using
+ pihole -a -p new_password" ${r} ${c}
+ else
+ whiptail --msgbox --backtitle "Make it so." --title "Installation Complete!" "Configure your devices to use the Pi-hole as their DNS server using:
+
+IPv4: ${IPV4_ADDRESS%/*}
+IPv6: ${IPV6_ADDRESS}
+
+If you set a new IP address, you should restart the Pi.
+
+The install log is in /etc/pihole.
+View the web interface at http://pi.hole/admin or http://${IPV4_ADDRESS%/*}/admin" ${r} ${c}
+ fi
}
update_dialogs() {
@@ -1129,13 +1141,14 @@ main() {
mv ${tmpLog} ${instalLogLoc}
# Add password to web UI if there is none
+ pw=""
if [[ $(grep 'WEBPASSWORD' -c /etc/pihole/setupVars.conf) == 0 ]] ; then
pw=$(tr -dc _A-Z-a-z-0-9 < /dev/urandom | head -c 8)
pihole -a -p ${pw}
fi
if [[ "${useUpdateVars}" == false ]]; then
- displayFinalMessage
+ displayFinalMessage ${pw}
fi
echo "::: Restarting services..."
From e2898217d21b09d2b5a00f7125cf54dce211d140 Mon Sep 17 00:00:00 2001
From: DL6ER
Date: Thu, 15 Dec 2016 15:20:41 +0100
Subject: [PATCH 210/228] Made message shorter
---
automated install/basic-install.sh | 9 ++-------
1 file changed, 2 insertions(+), 7 deletions(-)
diff --git a/automated install/basic-install.sh b/automated install/basic-install.sh
index b8f0c2dc..23d57cff 100755
--- a/automated install/basic-install.sh
+++ b/automated install/basic-install.sh
@@ -1005,12 +1005,7 @@ If you set a new IP address, you should restart the Pi.
The install log is in /etc/pihole.
View the web interface at http://pi.hole/admin or http://${IPV4_ADDRESS%/*}/admin
-
-Note: As security measure a password has been installed for your web interface
-The currently set password is
- ${1}
-You can always change it using
- pihole -a -p new_password" ${r} ${c}
+The currently set password is ${1}" ${r} ${c}
else
whiptail --msgbox --backtitle "Make it so." --title "Installation Complete!" "Configure your devices to use the Pi-hole as their DNS server using:
@@ -1169,7 +1164,7 @@ main() {
echo "::: View the web interface at http://pi.hole/admin or http://${IPV4_ADDRESS%/*}/admin"
else
echo "::: Update complete!"
- if [ ! -z $pw ]; then
+ if (( ${#pw} > 0 )) ; then
echo ":::"
echo "::: Note: As security measure a password has been installed for your web interface"
echo "::: The currently set password is"
From 1eeaa012347e5e7ed76eda6e4e4f92402e58b490 Mon Sep 17 00:00:00 2001
From: DL6ER
Date: Thu, 15 Dec 2016 15:22:18 +0100
Subject: [PATCH 211/228] Always put the information that we added a password
if we did (not only on update but also on fresh install)
---
automated install/basic-install.sh | 19 ++++++++++---------
1 file changed, 10 insertions(+), 9 deletions(-)
diff --git a/automated install/basic-install.sh b/automated install/basic-install.sh
index 23d57cff..d96c7eb4 100755
--- a/automated install/basic-install.sh
+++ b/automated install/basic-install.sh
@@ -1164,15 +1164,16 @@ main() {
echo "::: View the web interface at http://pi.hole/admin or http://${IPV4_ADDRESS%/*}/admin"
else
echo "::: Update complete!"
- if (( ${#pw} > 0 )) ; then
- echo ":::"
- echo "::: Note: As security measure a password has been installed for your web interface"
- echo "::: The currently set password is"
- echo "::: ${pw}"
- echo ":::"
- echo "::: You can always change it using"
- echo "::: pihole -a -p new_password"
- fi
+ fi
+
+ if (( ${#pw} > 0 )) ; then
+ echo ":::"
+ echo "::: Note: As security measure a password has been installed for your web interface"
+ echo "::: The currently set password is"
+ echo "::: ${pw}"
+ echo ":::"
+ echo "::: You can always change it using"
+ echo "::: pihole -a -p new_password"
fi
echo ":::"
From ec8c848106841c0e7900d7772025c99c30364d3f Mon Sep 17 00:00:00 2001
From: DL6ER
Date: Fri, 16 Dec 2016 12:53:00 +0100
Subject: [PATCH 212/228] Don't kill already existing setupVars.conf on update
(and fresh install)
---
automated install/basic-install.sh | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/automated install/basic-install.sh b/automated install/basic-install.sh
index 9464d03b..4744d7d5 100755
--- a/automated install/basic-install.sh
+++ b/automated install/basic-install.sh
@@ -872,10 +872,8 @@ configureFirewall() {
}
finalExports() {
- #If it already exists, lets overwrite it with the new values.
- if [[ -f ${setupVars} ]]; then
- rm ${setupVars}
- fi
+ # Update variables in setupVars.conf file
+ sed -i.update.bak '/PIHOLE_DOMAIN/d;/IPV4_ADDRESS/d;/IPV6_ADDRESS/d;/PIHOLE_DNS_1/d;/PIHOLE_DNS_2/d;/QUERY_LOGGING/d;' "${setupVars}"
{
echo "PIHOLE_INTERFACE=${PIHOLE_INTERFACE}"
echo "IPV4_ADDRESS=${IPV4_ADDRESS}"
From 7872f68a45145b713971bab9af6cc56860a8fbf6 Mon Sep 17 00:00:00 2001
From: DL6ER
Date: Fri, 16 Dec 2016 13:13:35 +0100
Subject: [PATCH 213/228] Only try to remove parts inthe file if the file
already exists
---
automated install/basic-install.sh | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/automated install/basic-install.sh b/automated install/basic-install.sh
index 4744d7d5..0e82cb31 100755
--- a/automated install/basic-install.sh
+++ b/automated install/basic-install.sh
@@ -873,7 +873,9 @@ configureFirewall() {
finalExports() {
# Update variables in setupVars.conf file
- sed -i.update.bak '/PIHOLE_DOMAIN/d;/IPV4_ADDRESS/d;/IPV6_ADDRESS/d;/PIHOLE_DNS_1/d;/PIHOLE_DNS_2/d;/QUERY_LOGGING/d;' "${setupVars}"
+ if [ -e "${setupVars}" ]; then
+ sed -i.update.bak '/PIHOLE_DOMAIN/d;/IPV4_ADDRESS/d;/IPV6_ADDRESS/d;/PIHOLE_DNS_1/d;/PIHOLE_DNS_2/d;/QUERY_LOGGING/d;' "${setupVars}"
+ fi
{
echo "PIHOLE_INTERFACE=${PIHOLE_INTERFACE}"
echo "IPV4_ADDRESS=${IPV4_ADDRESS}"
From d4c378ed5d1b0c21af598c12b2013547469b97f7 Mon Sep 17 00:00:00 2001
From: DL6ER
Date: Fri, 16 Dec 2016 13:20:25 +0100
Subject: [PATCH 214/228] Remove PIHOLE_INTERFACE if already set (not
PIHOLE_DOMAIN)
---
automated install/basic-install.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/automated install/basic-install.sh b/automated install/basic-install.sh
index 0e82cb31..4671f49e 100755
--- a/automated install/basic-install.sh
+++ b/automated install/basic-install.sh
@@ -874,7 +874,7 @@ configureFirewall() {
finalExports() {
# Update variables in setupVars.conf file
if [ -e "${setupVars}" ]; then
- sed -i.update.bak '/PIHOLE_DOMAIN/d;/IPV4_ADDRESS/d;/IPV6_ADDRESS/d;/PIHOLE_DNS_1/d;/PIHOLE_DNS_2/d;/QUERY_LOGGING/d;' "${setupVars}"
+ sed -i.update.bak '/PIHOLE_INTERFACE/d;/IPV4_ADDRESS/d;/IPV6_ADDRESS/d;/PIHOLE_DNS_1/d;/PIHOLE_DNS_2/d;/QUERY_LOGGING/d;' "${setupVars}"
fi
{
echo "PIHOLE_INTERFACE=${PIHOLE_INTERFACE}"
From 8cb01cdd294584372a94cebb20ebfd6fea0adf0f Mon Sep 17 00:00:00 2001
From: Dan Schaper
Date: Fri, 16 Dec 2016 15:08:30 -0800
Subject: [PATCH 215/228] One step to rename variables.
Signed-off-by: Dan Schaper
---
automated install/basic-install.sh | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/automated install/basic-install.sh b/automated install/basic-install.sh
index 8abf9af8..a04cac3f 100755
--- a/automated install/basic-install.sh
+++ b/automated install/basic-install.sh
@@ -915,13 +915,12 @@ accountForRefactor() {
# At some point in the future this list can be pruned, for now we'll need it to ensure updates don't break.
# Refactoring of install script has changed the name of a couple of variables. Sort them out here.
- sed -i 's/IPv4addr/IPv4_address/g' ${setupVars}
- sed -i 's/piholeIPv6/IPv6_address/g' ${setupVars}
- # Account for renaming of global variables.
sed -i 's/piholeInterface/PIHOLE_INTERFACE/g' ${setupVars}
sed -i 's/IPv4_address/IPV4_ADDRESS/g' ${setupVars}
+ sed -i 's/IPv4addr/IPV4_ADDRESS/g' ${setupVars}
sed -i 's/IPv6_address/IPV6_ADDRESS/g' ${setupVars}
+ sed -i 's/piholeIPv6/IPV6_ADDRESS/g' ${setupVars}
sed -i 's/piholeDNS1/PIHOLE_DNS_1/g' ${setupVars}
sed -i 's/piholeDNS2/PIHOLE_DNS_2/g' ${setupVars}
From 715838cf892f9718b4a9afc94210a872b3c268ef Mon Sep 17 00:00:00 2001
From: DL6ER
Date: Mon, 19 Dec 2016 13:42:42 +0100
Subject: [PATCH 216/228] Allow disabling second DNS server
---
advanced/Scripts/webpage.sh | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/advanced/Scripts/webpage.sh b/advanced/Scripts/webpage.sh
index d07e5c94..6251b158 100755
--- a/advanced/Scripts/webpage.sh
+++ b/advanced/Scripts/webpage.sh
@@ -75,12 +75,18 @@ SetDNSServers(){
sed -i.bak '/PIHOLE_DNS_1/d;/PIHOLE_DNS_2/d;/DNS_FQDN_REQUIRED/d;' /etc/pihole/setupVars.conf
# Save setting to file
echo "PIHOLE_DNS_1=${args[2]}" >> /etc/pihole/setupVars.conf
- echo "PIHOLE_DNS_2=${args[3]}" >> /etc/pihole/setupVars.conf
+ if [[ "${args[3]}" != "none" ]]; then
+ echo "PIHOLE_DNS_2=${args[3]}" >> /etc/pihole/setupVars.conf
+ else
+ echo "PIHOLE_DNS_2=" >> /etc/pihole/setupVars.conf
+ fi
# Replace within actual dnsmasq config file
sed -i '/server=/d;' /etc/dnsmasq.d/01-pihole.conf
echo "server=${args[2]}" >> /etc/dnsmasq.d/01-pihole.conf
- echo "server=${args[3]}" >> /etc/dnsmasq.d/01-pihole.conf
+ if [[ "${args[3]}" != "none" ]]; then
+ echo "server=${args[3]}" >> /etc/dnsmasq.d/01-pihole.conf
+ fi
# Remove domain-needed entry
sed -i '/domain-needed/d;' /etc/dnsmasq.d/01-pihole.conf
From da363070c7770f738c18c13120828edf722f149c Mon Sep 17 00:00:00 2001
From: DL6ER
Date: Tue, 20 Dec 2016 12:21:08 +0100
Subject: [PATCH 217/228] Added Kelvin
---
advanced/Scripts/webpage.sh | 7 ++-----
1 file changed, 2 insertions(+), 5 deletions(-)
diff --git a/advanced/Scripts/webpage.sh b/advanced/Scripts/webpage.sh
index 6251b158..6b54abb7 100755
--- a/advanced/Scripts/webpage.sh
+++ b/advanced/Scripts/webpage.sh
@@ -31,11 +31,7 @@ SetTemperatureUnit(){
# Remove setting from file (create backup setupVars.conf.bak)
sed -i.bak '/TEMPERATUREUNIT/d' /etc/pihole/setupVars.conf
# Save setting to file
- if [[ $unit == "F" ]] ; then
- echo "TEMPERATUREUNIT=F" >> /etc/pihole/setupVars.conf
- else
- echo "TEMPERATUREUNIT=C" >> /etc/pihole/setupVars.conf
- fi
+ echo "TEMPERATUREUNIT=${unit}" >> /etc/pihole/setupVars.conf
}
@@ -222,6 +218,7 @@ case "${args[1]}" in
"-p" | "password" ) SetWebPassword;;
"-c" | "celsius" ) unit="C"; SetTemperatureUnit;;
"-f" | "fahrenheit" ) unit="F"; SetTemperatureUnit;;
+ "-k" | "kelvin" ) unit="K"; SetTemperatureUnit;;
"setdns" ) SetDNSServers;;
"setexcludedomains" ) SetExcludeDomains;;
"setexcludeclients" ) SetExcludeClients;;
From ee8f29d178ef18d68057564af71f4ab1da45a3cc Mon Sep 17 00:00:00 2001
From: DL6ER
Date: Tue, 20 Dec 2016 16:28:28 +0100
Subject: [PATCH 218/228] Fixed typo, extended help text
---
advanced/Scripts/webpage.sh | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/advanced/Scripts/webpage.sh b/advanced/Scripts/webpage.sh
index 6b54abb7..07706346 100755
--- a/advanced/Scripts/webpage.sh
+++ b/advanced/Scripts/webpage.sh
@@ -19,8 +19,9 @@ helpFunc() {
:::
::: Options:
::: -p, password Set web interface password, an empty input will remove any previously set password
-::: -c, celsius Set Celcius temperature unit
+::: -c, celsius Set Celsius temperature unit
::: -f, fahrenheit Set Fahrenheit temperature unit
+::: -k, kelvin Set Kelvin temperature unit
::: -h, --help Show this help dialog
EOM
exit 0
From d0e3c546f80c86f2eef82df82bcfab88cd137417 Mon Sep 17 00:00:00 2001
From: Dan Schaper
Date: Tue, 20 Dec 2016 15:00:37 -0800
Subject: [PATCH 219/228] CRLF to CR (Win to Unix line endings)
Signed-off-by: Dan Schaper
---
automated install/basic-install.sh | 1155 +---------------------------
1 file changed, 1 insertion(+), 1154 deletions(-)
diff --git a/automated install/basic-install.sh b/automated install/basic-install.sh
index a04cac3f..96c8ece3 100755
--- a/automated install/basic-install.sh
+++ b/automated install/basic-install.sh
@@ -1,1154 +1 @@
-#!/usr/bin/env bash
-# Pi-hole: A black hole for Internet advertisements
-# (c) 2015, 2016 by Jacob Salmela
-# Network-wide ad blocking via your Raspberry Pi
-# http://pi-hole.net
-# Installs Pi-hole
-#
-# Pi-hole is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 2 of the License, or
-# (at your option) any later version.
-
-# pi-hole.net/donate
-#
-# Install with this command (from your Pi):
-#
-# curl -L install.pi-hole.net | bash
-
-set -e
-######## VARIABLES #########
-tmpLog=/tmp/pihole-install.log
-instalLogLoc=/etc/pihole/install.log
-setupVars=/etc/pihole/setupVars.conf
-
-webInterfaceGitUrl="https://github.com/pi-hole/AdminLTE.git"
-webInterfaceDir="/var/www/html/admin"
-piholeGitUrl="https://github.com/pi-hole/pi-hole.git"
-PI_HOLE_LOCAL_REPO="/etc/.pihole"
-PI_HOLE_FILES=(chronometer list piholeDebug piholeLogFlush setupLCD update version)
-useUpdateVars=false
-
-IPV4_ADDRESS=""
-IPV6_ADDRESS=""
-QUERY_LOGGING=true
-
-# Find the rows and columns will default to 80x24 is it can not be detected
-screen_size=$(stty size 2>/dev/null || echo 24 80)
-rows=$(echo $screen_size | awk '{print $1}')
-columns=$(echo $screen_size | awk '{print $2}')
-
-# Divide by two so the dialogs take up half of the screen, which looks nice.
-r=$(( rows / 2 ))
-c=$(( columns / 2 ))
-# Unless the screen is tiny
-r=$(( r < 20 ? 20 : r ))
-c=$(( c < 70 ? 70 : c ))
-
-######## Undocumented Flags. Shhh ########
-skipSpaceCheck=false
-reconfigure=false
-runUnattended=false
-
-######## FIRST CHECK ########
-# Must be root to install
-echo ":::"
-if [[ ${EUID} -eq 0 ]]; then
- echo "::: You are root."
-else
- echo "::: Script called with non-root privileges. The Pi-hole installs server packages and configures"
- echo "::: system networking, it requires elevated rights. Please check the contents of the script for"
- echo "::: any concerns with this requirement. Please be sure to download this script from a trusted source."
- echo ":::"
- echo "::: Detecting the presence of the sudo utility for continuation of this install..."
-
- if [ -x "$(command -v sudo)" ]; then
- echo "::: Utility sudo located."
- exec curl -sSL https://install.pi-hole.net | sudo bash "$@"
- exit $?
- else
- echo "::: sudo is needed for the Web interface to run pihole commands. Please run this script as root and it will be automatically installed."
- exit 1
- fi
-fi
-
-# Compatibility
-
-if [[ $(command -v apt-get) ]]; then
- #Debian Family
- #############################################
- PKG_MANAGER="apt-get"
- PKG_CACHE="/var/lib/apt/lists/"
- UPDATE_PKG_CACHE="${PKG_MANAGER} update"
- PKG_UPDATE="${PKG_MANAGER} upgrade"
- PKG_INSTALL="${PKG_MANAGER} --yes --fix-missing install"
- # grep -c will return 1 retVal on 0 matches, block this throwing the set -e with an OR TRUE
- PKG_COUNT="${PKG_MANAGER} -s -o Debug::NoLocking=true upgrade | grep -c ^Inst || true"
- # #########################################
- # fixes for dependancy differences
- # Debian 7 doesn't have iproute2 use iproute
- ${PKG_MANAGER} install --dry-run iproute2 > /dev/null 2>&1 && IPROUTE_PKG="iproute2" || IPROUTE_PKG="iproute"
- # Prefer the php metapackage if it's there, fall back on the php5 pacakges
- ${PKG_MANAGER} install --dry-run php > /dev/null 2>&1 && phpVer="php" || phpVer="php5"
- # #########################################
- INSTALLER_DEPS=( apt-utils whiptail git dhcpcd5)
- PIHOLE_DEPS=( iputils-ping lsof dnsutils bc dnsmasq lighttpd ${phpVer}-common ${phpVer}-cgi curl unzip wget sudo netcat cron ${IPROUTE_PKG} )
- LIGHTTPD_USER="www-data"
- LIGHTTPD_GROUP="www-data"
- LIGHTTPD_CFG="lighttpd.conf.debian"
- DNSMASQ_USER="dnsmasq"
-
- package_check_install() {
- dpkg-query -W -f='${Status}' "${1}" 2>/dev/null | grep -c "ok installed" || ${PKG_INSTALL} "${1}"
- }
-elif [ $(command -v rpm) ]; then
- # Fedora Family
- if [ $(command -v dnf) ]; then
- PKG_MANAGER="dnf"
- else
- PKG_MANAGER="yum"
- fi
- PKG_CACHE="/var/cache/${PKG_MANAGER}"
- UPDATE_PKG_CACHE="${PKG_MANAGER} check-update"
- PKG_UPDATE="${PKG_MANAGER} update -y"
- PKG_INSTALL="${PKG_MANAGER} install -y"
- PKG_COUNT="${PKG_MANAGER} check-update | egrep '(.i686|.x86|.noarch|.arm|.src)' | wc -l"
- INSTALLER_DEPS=( iproute net-tools procps-ng newt git )
- PIHOLE_DEPS=( epel-release bind-utils bc dnsmasq lighttpd lighttpd-fastcgi php-common php-cli php curl unzip wget findutils cronie sudo nmap-ncat )
-
- if grep -q 'Fedora' /etc/redhat-release; then
- remove_deps=(epel-release);
- PIHOLE_DEPS=( ${PIHOLE_DEPS[@]/$remove_deps} );
- fi
- LIGHTTPD_USER="lighttpd"
- LIGHTTPD_GROUP="lighttpd"
- LIGHTTPD_CFG="lighttpd.conf.fedora"
- DNSMASQ_USER="nobody"
-
- package_check_install() {
- rpm -qa | grep ^"${1}"- > /dev/null || ${PKG_INSTALL} "${1}"
- }
-else
- echo "OS distribution not supported"
- exit
-fi
-
-####### FUNCTIONS ##########
-spinner() {
- local pid=$1
- local delay=0.50
- local spinstr='/-\|'
-
- while [ "$(ps a | awk '{print $1}' | grep "${pid}")" ]; do
- local temp=${spinstr#?}
- printf " [%c] " "${spinstr}"
- local spinstr=${temp}${spinstr%"$temp"}
- sleep ${delay}
- printf "\b\b\b\b\b\b"
- done
- printf " \b\b\b\b"
-}
-
-is_repo() {
- # Use git to check if directory is currently under VCS, return the value
- local directory="${1}"
- git -C "${directory}" status --short &> /dev/null
- return
-}
-
-make_repo() {
- local directory="${1}"
- local remoteRepo="${2}"
- # Remove the non-repod interface and clone the interface
- echo -n "::: Cloning $remoteRepo into $directory..."
- rm -rf "${directory}"
- git clone -q --depth 1 "${remoteRepo}" "${directory}" > /dev/null & spinner $!
- echo " done!"
-}
-
-update_repo() {
- local directory="${1}"
- # Pull the latest commits
- echo -n "::: Updating repo in $1..."
- cd "${directory}" || exit 1
- git stash -q > /dev/null & spinner $!
- git pull -q > /dev/null & spinner $!
- echo " done!"
-}
-
-getGitFiles() {
- # Setup git repos for directory and repository passed
- # as arguments 1 and 2
- local directory="${1}"
- local remoteRepo="${2}"
- echo ":::"
- echo "::: Checking for existing repository..."
- if is_repo "${directory}"; then
- update_repo "${directory}"
- else
- make_repo "${directory}" "${remoteRepo}"
- fi
-}
-
-find_IPv4_information() {
- # Find IP used to route to outside world
- IPv4dev=$(ip route get 8.8.8.8 | awk '{for(i=1;i<=NF;i++)if($i~/dev/)print $(i+1)}')
- IPV4_ADDRESS=$(ip -o -f inet addr show dev "$IPv4dev" | awk '{print $4}' | awk 'END {print}')
- IPv4gw=$(ip route get 8.8.8.8 | awk '{print $3}')
-}
-
-get_available_interfaces() {
- # Get available interfaces. Consider only getting UP interfaces in the future, and leaving DOWN interfaces out of list.
- availableInterfaces=$(ip -o link | awk '{print $2}' | grep -v "lo" | cut -d':' -f1 | cut -d'@' -f1)
-}
-
-welcomeDialogs() {
- # Display the welcome dialog
- whiptail --msgbox --backtitle "Welcome" --title "Pi-hole automated installer" "\n\nThis installer will transform your device into a network-wide ad blocker!" ${r} ${c}
-
- # Support for a part-time dev
- whiptail --msgbox --backtitle "Plea" --title "Free and open source" "\n\nThe Pi-hole is free, but powered by your donations: http://pi-hole.net/donate" ${r} ${c}
-
- # Explain the need for a static address
- whiptail --msgbox --backtitle "Initiating network interface" --title "Static IP Needed" "\n\nThe Pi-hole is a SERVER so it needs a STATIC IP ADDRESS to function properly.
-
-In the next section, you can choose to use your current network settings (DHCP) or to manually edit them." ${r} ${c}
-}
-
-verifyFreeDiskSpace() {
-
- # 50MB is the minimum space needed (45MB install (includes web admin bootstrap/jquery libraries etc) + 5MB one day of logs.)
- # - Fourdee: Local ensures the variable is only created, and accessible within this function/void. Generally considered a "good" coding practice for non-global variables.
- echo "::: Verifying free disk space..."
- local required_free_kilobytes=51200
- local existing_free_kilobytes=$(df -Pk | grep -m1 '\/$' | awk '{print $4}')
-
- # - Unknown free disk space , not a integer
- if ! [[ "${existing_free_kilobytes}" =~ ^([0-9])+$ ]]; then
- echo "::: Unknown free disk space!"
- echo "::: We were unable to determine available free disk space on this system."
- echo "::: You may override this check and force the installation, however, it is not recommended"
- echo "::: To do so, pass the argument '--i_do_not_follow_recommendations' to the install script"
- echo "::: eg. curl -L https://install.pi-hole.net | bash /dev/stdin --i_do_not_follow_recommendations"
- exit 1
- # - Insufficient free disk space
- elif [[ ${existing_free_kilobytes} -lt ${required_free_kilobytes} ]]; then
- echo "::: Insufficient Disk Space!"
- echo "::: Your system appears to be low on disk space. pi-hole recommends a minimum of $required_free_kilobytes KiloBytes."
- echo "::: You only have ${existing_free_kilobytes} KiloBytes free."
- echo "::: If this is a new install you may need to expand your disk."
- echo "::: Try running 'sudo raspi-config', and choose the 'expand file system option'"
- echo "::: After rebooting, run this installation again. (curl -L https://install.pi-hole.net | bash)"
-
- echo "Insufficient free space, exiting..."
- exit 1
-
- fi
-
-}
-
-
-chooseInterface() {
- # Turn the available interfaces into an array so it can be used with a whiptail dialog
- local interfacesArray=()
- # Number of available interfaces
- local interfaceCount
- # Whiptail variable storage
- local chooseInterfaceCmd
- # Temporary Whiptail options storage
- local chooseInterfaceOptions
- # Loop sentinel variable
- local firstLoop=1
-
- while read -r line; do
- mode="OFF"
- if [[ ${firstLoop} -eq 1 ]]; then
- firstLoop=0
- mode="ON"
- fi
- interfacesArray+=("${line}" "available" "${mode}")
- done <<< "${availableInterfaces}"
-
- # Find out how many interfaces are available to choose from
- interfaceCount=$(echo "${availableInterfaces}" | wc -l)
- chooseInterfaceCmd=(whiptail --separate-output --radiolist "Choose An Interface (press space to select)" ${r} ${c} ${interfaceCount})
- chooseInterfaceOptions=$("${chooseInterfaceCmd[@]}" "${interfacesArray[@]}" 2>&1 >/dev/tty)
- if [[ $? = 0 ]]; then
- for desiredInterface in ${chooseInterfaceOptions}; do
- PIHOLE_INTERFACE=${desiredInterface}
- echo "::: Using interface: $PIHOLE_INTERFACE"
- done
- else
- echo "::: Cancel selected, exiting...."
- exit 1
- fi
-}
-
-useIPv6dialog() {
- # Show the IPv6 address used for blocking
- IPV6_ADDRESS=$(ip -6 route get 2001:4860:4860::8888 | awk -F " " '{ for(i=1;i<=NF;i++) if ($i == "src") print $(i+1) }')
- whiptail --msgbox --backtitle "IPv6..." --title "IPv6 Supported" "$IPV6_ADDRESS will be used to block ads." ${r} ${c}
-}
-
-
-use4andor6() {
- local useIPv4
- local useIPv6
- # Let use select IPv4 and/or IPv6
- cmd=(whiptail --separate-output --checklist "Select Protocols (press space to select)" ${r} ${c} 2)
- options=(IPv4 "Block ads over IPv4" on
- IPv6 "Block ads over IPv6" on)
- choices=$("${cmd[@]}" "${options[@]}" 2>&1 >/dev/tty)
- if [[ $? = 0 ]];then
- for choice in ${choices}
- do
- case ${choice} in
- IPv4 ) useIPv4=true;;
- IPv6 ) useIPv6=true;;
- esac
- done
- if [[ ${useIPv4} ]]; then
- find_IPv4_information
- getStaticIPv4Settings
- setStaticIPv4
- fi
- if [[ ${useIPv6} ]]; then
- useIPv6dialog
- fi
- echo "::: IPv4 address: ${IPV4_ADDRESS}"
- echo "::: IPv6 address: ${IPV6_ADDRESS}"
- if [ ! ${useIPv4} ] && [ ! ${useIPv6} ]; then
- echo "::: Cannot continue, neither IPv4 or IPv6 selected"
- echo "::: Exiting"
- exit 1
- fi
- else
- echo "::: Cancel selected. Exiting..."
- exit 1
- fi
-}
-
-getStaticIPv4Settings() {
- # Ask if the user wants to use DHCP settings as their static IP
- if (whiptail --backtitle "Calibrating network interface" --title "Static IP Address" --yesno "Do you want to use your current network settings as a static address?
- IP address: ${IPV4_ADDRESS}
- Gateway: ${IPv4gw}" ${r} ${c}); then
- # If they choose yes, let the user know that the IP address will not be available via DHCP and may cause a conflict.
- whiptail --msgbox --backtitle "IP information" --title "FYI: IP Conflict" "It is possible your router could still try to assign this IP to a device, which would cause a conflict. But in most cases the router is smart enough to not do that.
-If you are worried, either manually set the address, or modify the DHCP reservation pool so it does not include the IP you want.
-It is also possible to use a DHCP reservation, but if you are going to do that, you might as well set a static address." ${r} ${c}
- # Nothing else to do since the variables are already set above
- else
- # Otherwise, we need to ask the user to input their desired settings.
- # Start by getting the IPv4 address (pre-filling it with info gathered from DHCP)
- # Start a loop to let the user enter their information with the chance to go back and edit it if necessary
- until [[ ${ipSettingsCorrect} = True ]]; do
- # Ask for the IPv4 address
- IPV4_ADDRESS=$(whiptail --backtitle "Calibrating network interface" --title "IPv4 address" --inputbox "Enter your desired IPv4 address" ${r} ${c} "${IPV4_ADDRESS}" 3>&1 1>&2 2>&3)
- if [[ $? = 0 ]]; then
- echo "::: Your static IPv4 address: ${IPV4_ADDRESS}"
- # Ask for the gateway
- IPv4gw=$(whiptail --backtitle "Calibrating network interface" --title "IPv4 gateway (router)" --inputbox "Enter your desired IPv4 default gateway" ${r} ${c} "${IPv4gw}" 3>&1 1>&2 2>&3)
- if [[ $? = 0 ]]; then
- echo "::: Your static IPv4 gateway: ${IPv4gw}"
- # Give the user a chance to review their settings before moving on
- if (whiptail --backtitle "Calibrating network interface" --title "Static IP Address" --yesno "Are these settings correct?
- IP address: ${IPV4_ADDRESS}
- Gateway: ${IPv4gw}" ${r} ${c}); then
- # After that's done, the loop ends and we move on
- ipSettingsCorrect=True
- else
- # If the settings are wrong, the loop continues
- ipSettingsCorrect=False
- fi
- else
- # Cancelling gateway settings window
- ipSettingsCorrect=False
- echo "::: Cancel selected. Exiting..."
- exit 1
- fi
- else
- # Cancelling IPv4 settings window
- ipSettingsCorrect=False
- echo "::: Cancel selected. Exiting..."
- exit 1
- fi
- done
- # End the if statement for DHCP vs. static
- fi
-}
-
-setDHCPCD() {
- # Append these lines to dhcpcd.conf to enable a static IP
- echo "## interface ${PIHOLE_INTERFACE}
- static ip_address=${IPV4_ADDRESS}
- static routers=${IPv4gw}
- static domain_name_servers=${IPv4gw}" | tee -a /etc/dhcpcd.conf >/dev/null
-}
-
-setStaticIPv4() {
- local IFCFG_FILE
- local IPADDR
- local CIDR
- if [[ -f /etc/dhcpcd.conf ]]; then
- # Debian Family
- if grep -q "${IPV4_ADDRESS}" /etc/dhcpcd.conf; then
- echo "::: Static IP already configured"
- else
- setDHCPCD
- ip addr replace dev "${PIHOLE_INTERFACE}" "${IPV4_ADDRESS}"
- echo ":::"
- echo "::: Setting IP to ${IPV4_ADDRESS}. You may need to restart after the install is complete."
- echo ":::"
- fi
- elif [[ -f /etc/sysconfig/network-scripts/ifcfg-${PIHOLE_INTERFACE} ]];then
- # Fedora Family
- IFCFG_FILE=/etc/sysconfig/network-scripts/ifcfg-${PIHOLE_INTERFACE}
- if grep -q "${IPV4_ADDRESS}" "${IFCFG_FILE}"; then
- echo "::: Static IP already configured"
- else
- IPADDR=$(echo "${IPV4_ADDRESS}" | cut -f1 -d/)
- CIDR=$(echo "${IPV4_ADDRESS}" | cut -f2 -d/)
- # Backup existing interface configuration:
- cp "${IFCFG_FILE}" "${IFCFG_FILE}".pihole.orig
- # Build Interface configuration file:
- {
- echo "# Configured via Pi-Hole installer"
- echo "DEVICE=$PIHOLE_INTERFACE"
- echo "BOOTPROTO=none"
- echo "ONBOOT=yes"
- echo "IPADDR=$IPADDR"
- echo "PREFIX=$CIDR"
- echo "GATEWAY=$IPv4gw"
- echo "DNS1=$PIHOLE_DNS_1"
- echo "DNS2=$PIHOLE_DNS_2"
- echo "USERCTL=no"
- }> "${IFCFG_FILE}"
- ip addr replace dev "${PIHOLE_INTERFACE}" "${IPV4_ADDRESS}"
- if [ -x "$(command -v nmcli)" ];then
- # Tell NetworkManager to read our new sysconfig file
- nmcli con load "${IFCFG_FILE}" > /dev/null
- fi
- echo ":::"
- echo "::: Setting IP to ${IPV4_ADDRESS}. You may need to restart after the install is complete."
- echo ":::"
- fi
- else
- echo "::: Warning: Unable to locate configuration file to set static IPv4 address!"
- exit 1
- fi
-}
-
-valid_ip() {
- local ip=${1}
- local stat=1
-
- if [[ ${ip} =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then
- OIFS=$IFS
- IFS='.'
- ip=(${ip})
- IFS=${OIFS}
- [[ ${ip[0]} -le 255 && ${ip[1]} -le 255 \
- && ${ip[2]} -le 255 && ${ip[3]} -le 255 ]]
- stat=$?
- fi
- return ${stat}
-}
-
-setDNS() {
- DNSChooseCmd=(whiptail --separate-output --radiolist "Select Upstream DNS Provider. To use your own, select Custom." ${r} ${c} 6)
- DNSChooseOptions=(Google "" on
- OpenDNS "" off
- Level3 "" off
- Norton "" off
- Comodo "" off
- Custom "" off)
- DNSchoices=$("${DNSChooseCmd[@]}" "${DNSChooseOptions[@]}" 2>&1 >/dev/tty)
- if [[ $? = 0 ]];then
- case ${DNSchoices} in
- Google)
- echo "::: Using Google DNS servers."
- PIHOLE_DNS_1="8.8.8.8"
- PIHOLE_DNS_2="8.8.4.4"
- ;;
- OpenDNS)
- echo "::: Using OpenDNS servers."
- PIHOLE_DNS_1="208.67.222.222"
- PIHOLE_DNS_2="208.67.220.220"
- ;;
- Level3)
- echo "::: Using Level3 servers."
- PIHOLE_DNS_1="4.2.2.1"
- PIHOLE_DNS_2="4.2.2.2"
- ;;
- Norton)
- echo "::: Using Norton ConnectSafe servers."
- PIHOLE_DNS_1="199.85.126.10"
- PIHOLE_DNS_2="199.85.127.10"
- ;;
- Comodo)
- echo "::: Using Comodo Secure servers."
- PIHOLE_DNS_1="8.26.56.26"
- PIHOLE_DNS_2="8.20.247.20"
- ;;
- Custom)
- until [[ ${DNSSettingsCorrect} = True ]]; do
- strInvalid="Invalid"
- if [ ! ${PIHOLE_DNS_1} ]; then
- if [ ! ${PIHOLE_DNS_2} ]; then
- prePopulate=""
- else
- prePopulate=", ${PIHOLE_DNS_2}"
- fi
- elif [ ${PIHOLE_DNS_1} ] && [ ! ${PIHOLE_DNS_2} ]; then
- prePopulate="${PIHOLE_DNS_1}"
- elif [ ${PIHOLE_DNS_1} ] && [ ${PIHOLE_DNS_2} ]; then
- prePopulate="${PIHOLE_DNS_1}, ${PIHOLE_DNS_2}"
- fi
-
- piholeDNS=$(whiptail --backtitle "Specify Upstream DNS Provider(s)" --inputbox "Enter your desired upstream DNS provider(s), seperated by a comma.\n\nFor example '8.8.8.8, 8.8.4.4'" ${r} ${c} "${prePopulate}" 3>&1 1>&2 2>&3)
-
- if [[ $? = 0 ]]; then
- PIHOLE_DNS_1=$(echo "${piholeDNS}" | sed 's/[, \t]\+/,/g' | awk -F, '{print$1}')
- PIHOLE_DNS_2=$(echo "${piholeDNS}" | sed 's/[, \t]\+/,/g' | awk -F, '{print$2}')
- if ! valid_ip "${PIHOLE_DNS_1}" || [ ! "${PIHOLE_DNS_1}" ]; then
- PIHOLE_DNS_1=${strInvalid}
- fi
- if ! valid_ip "${PIHOLE_DNS_2}" && [ "${PIHOLE_DNS_2}" ]; then
- PIHOLE_DNS_2=${strInvalid}
- fi
- else
- echo "::: Cancel selected, exiting...."
- exit 1
- fi
- if [[ ${PIHOLE_DNS_1} == "${strInvalid}" ]] || [[ ${PIHOLE_DNS_2} == "${strInvalid}" ]]; then
- whiptail --msgbox --backtitle "Invalid IP" --title "Invalid IP" "One or both entered IP addresses were invalid. Please try again.\n\n DNS Server 1: $PIHOLE_DNS_1\n DNS Server 2: ${PIHOLE_DNS_2}" ${r} ${c}
- if [[ ${PIHOLE_DNS_1} == "${strInvalid}" ]]; then
- PIHOLE_DNS_1=""
- fi
- if [[ ${PIHOLE_DNS_2} == "${strInvalid}" ]]; then
- PIHOLE_DNS_2=""
- fi
- DNSSettingsCorrect=False
- else
- if (whiptail --backtitle "Specify Upstream DNS Provider(s)" --title "Upstream DNS Provider(s)" --yesno "Are these settings correct?\n DNS Server 1: $PIHOLE_DNS_1\n DNS Server 2: ${PIHOLE_DNS_2}" ${r} ${c}); then
- DNSSettingsCorrect=True
- else
- # If the settings are wrong, the loop continues
- DNSSettingsCorrect=False
- fi
- fi
- done
- ;;
- esac
- else
- echo "::: Cancel selected. Exiting..."
- exit 1
- fi
-}
-
-setLogging() {
- local LogToggleCommand
- local LogChooseOptions
- local LogChoices
-
- LogToggleCommand=(whiptail --separate-output --radiolist "Do you want to log queries?\n (Disabling will render graphs on the Admin page useless):" ${r} ${c} 6)
- LogChooseOptions=("On (Reccomended)" "" on
- Off "" off)
- LogChoices=$("${LogToggleCommand[@]}" "${LogChooseOptions[@]}" 2>&1 >/dev/tty) || (echo "::: Cancel selected. Exiting..." && exit 1)
- case ${LogChoices} in
- "On (Recommended)")
- echo "::: Logging On."
- QUERY_LOGGING=true
- ;;
- Off)
- echo "::: Logging Off."
- QUERY_LOGGING=false
- ;;
- esac
-}
-
-
-version_check_dnsmasq() {
- # Check if /etc/dnsmasq.conf is from pihole. If so replace with an original and install new in .d directory
- local dnsmasq_conf="/etc/dnsmasq.conf"
- local dnsmasq_conf_orig="/etc/dnsmasq.conf.orig"
- local dnsmasq_pihole_id_string="addn-hosts=/etc/pihole/gravity.list"
- local dnsmasq_original_config="/etc/.pihole/advanced/dnsmasq.conf.original"
- local dnsmasq_pihole_01_snippet="/etc/.pihole/advanced/01-pihole.conf"
- local dnsmasq_pihole_01_location="/etc/dnsmasq.d/01-pihole.conf"
-
- if [ -f ${dnsmasq_conf} ]; then
- echo -n "::: Existing dnsmasq.conf found..."
- if grep -q ${dnsmasq_pihole_id_string} ${dnsmasq_conf}; then
- echo " it is from a previous pi-hole install."
- echo -n "::: Backing up dnsmasq.conf to dnsmasq.conf.orig..."
- mv -f ${dnsmasq_conf} ${dnsmasq_conf_orig}
- echo " done."
- echo -n "::: Restoring default dnsmasq.conf..."
- cp ${dnsmasq_original_config} ${dnsmasq_conf}
- echo " done."
- else
- echo " it is not a pi-hole file, leaving alone!"
- fi
- else
- echo -n "::: No dnsmasq.conf found.. restoring default dnsmasq.conf..."
- cp ${dnsmasq_original_config} ${dnsmasq_conf}
- echo " done."
- fi
-
- echo -n "::: Copying 01-pihole.conf to /etc/dnsmasq.d/01-pihole.conf..."
- cp ${dnsmasq_pihole_01_snippet} ${dnsmasq_pihole_01_location}
- echo " done."
- sed -i "s/@INT@/$PIHOLE_INTERFACE/" ${dnsmasq_pihole_01_location}
- if [[ "${PIHOLE_DNS_1}" != "" ]]; then
- sed -i "s/@DNS1@/$PIHOLE_DNS_1/" ${dnsmasq_pihole_01_location}
- else
- sed -i '/^server=@DNS1@/d' ${dnsmasq_pihole_01_location}
- fi
- if [[ "${PIHOLE_DNS_2}" != "" ]]; then
- sed -i "s/@DNS2@/$PIHOLE_DNS_2/" ${dnsmasq_pihole_01_location}
- else
- sed -i '/^server=@DNS2@/d' ${dnsmasq_pihole_01_location}
- fi
-
- sed -i 's/^#conf-dir=\/etc\/dnsmasq.d$/conf-dir=\/etc\/dnsmasq.d/' ${dnsmasq_conf}
-
- if [[ "${QUERY_LOGGING}" == false ]] ; then
- #Disable Logging
- sed -i 's/^log-queries/#log-queries/' ${dnsmasq_pihole_01_location}
- else
- #Enable Logging
- sed -i 's/^#log-queries/log-queries/' ${dnsmasq_pihole_01_location}
- fi
-}
-
-remove_legacy_scripts() {
- #Tidy up /usr/local/bin directory if installing over previous install.
- oldFiles=( gravity chronometer whitelist blacklist piholeLogFlush updateDashboard uninstall setupLCD piholeDebug)
- for i in "${oldFiles[@]}"; do
- if [ -f "/usr/local/bin/$i.sh" ]; then
- rm /usr/local/bin/"$i".sh
- fi
- done
-}
-
-clean_existing() {
- # Clean an exiting installation to prepare for upgrade/reinstall
- # ${1} Directory to clean; ${2} Array of files to remove
- local clean_directory="${1}"
- local old_files=${2}
-
- for script in "${old_files[@]}"; do
- rm -f "${clean_directory}${script}.sh"
- done
-
-}
-
-installScripts() {
- # Install the scripts from repository to their various locations
- readonly install_dir="/opt/pihole/"
-
- echo ":::"
- echo -n "::: Installing scripts from ${PI_HOLE_LOCAL_REPO}..."
-
- # Clear out script files from Pi-hole scripts directory.
- clean_existing "${install_dir}" "${PI_HOLE_FILES}"
-
- # Install files from local core repository
- if is_repo "${PI_HOLE_LOCAL_REPO}"; then
- cd "${PI_HOLE_LOCAL_REPO}"
- install -o "${USER}" -Dm755 -t /opt/pihole/ gravity.sh
- install -o "${USER}" -Dm755 -t /opt/pihole/ ./advanced/Scripts/*.sh
- install -o "${USER}" -Dm755 -t /opt/pihole/ ./automated\ install/uninstall.sh
- install -o "${USER}" -Dm755 -t /usr/local/bin/ pihole
- install -Dm644 ./advanced/bash-completion/pihole /etc/bash_completion.d/pihole
- echo " done."
- else
- echo " *** ERROR: Local repo ${core_repo} not found, exiting."
- exit 1
- fi
-}
-
-installConfigs() {
- # Install the configs from /etc/.pihole to their various locations
- echo ":::"
- echo "::: Installing configs..."
- version_check_dnsmasq
- if [ ! -d "/etc/lighttpd" ]; then
- mkdir /etc/lighttpd
- chown "${USER}":root /etc/lighttpd
- elif [ -f "/etc/lighttpd/lighttpd.conf" ]; then
- mv /etc/lighttpd/lighttpd.conf /etc/lighttpd/lighttpd.conf.orig
- fi
- cp /etc/.pihole/advanced/${LIGHTTPD_CFG} /etc/lighttpd/lighttpd.conf
- mkdir -p /var/run/lighttpd
- chown ${LIGHTTPD_USER}:${LIGHTTPD_GROUP} /var/run/lighttpd
- mkdir -p /var/cache/lighttpd/compress
- chown ${LIGHTTPD_USER}:${LIGHTTPD_GROUP} /var/cache/lighttpd/compress
- mkdir -p /var/cache/lighttpd/uploads
- chown ${LIGHTTPD_USER}:${LIGHTTPD_GROUP} /var/cache/lighttpd/uploads
-}
-
-stop_service() {
- # Stop service passed in as argument.
- # Can softfail, as process may not be installed when this is called
- echo ":::"
- echo -n "::: Stopping ${1} service..."
- if [ -x "$(command -v systemctl)" ]; then
- systemctl stop "${1}" &> /dev/null & spinner $! || true
- else
- service "${1}" stop &> /dev/null & spinner $! || true
- fi
- echo " done."
-}
-
-start_service() {
- # Start/Restart service passed in as argument
- # This should not fail, it's an error if it does
- echo ":::"
- echo -n "::: Starting ${1} service..."
- if [ -x "$(command -v systemctl)" ]; then
- systemctl restart "${1}" &> /dev/null & spinner $!
- else
- service "${1}" restart &> /dev/null & spinner $!
- fi
- echo " done."
-}
-
-enable_service() {
- # Enable service so that it will start with next reboot
- echo ":::"
- echo -n "::: Enabling ${1} service to start on reboot..."
- if [ -x "$(command -v systemctl)" ]; then
- systemctl enable "${1}" &> /dev/null & spinner $!
- else
- update-rc.d "${1}" defaults &> /dev/null & spinner $!
- fi
- echo " done."
-}
-
-update_pacakge_cache() {
- #Running apt-get update/upgrade with minimal output can cause some issues with
- #requiring user input (e.g password for phpmyadmin see #218)
-
- #Check to see if apt-get update has already been run today
- #it needs to have been run at least once on new installs!
- timestamp=$(stat -c %Y ${PKG_CACHE})
- timestampAsDate=$(date -d @"${timestamp}" "+%b %e")
- today=$(date "+%b %e")
-
- if [ ! "${today}" == "${timestampAsDate}" ]; then
- #update package lists
- echo ":::"
- echo -n "::: ${PKG_MANAGER} update has not been run today. Running now..."
- ${UPDATE_PKG_CACHE} &> /dev/null & spinner $!
- echo " done!"
- fi
-}
-
-notify_package_updates_available() {
- # Let user know if they have outdated packages on their system and
- # advise them to run a package update at soonest possible.
- echo ":::"
- echo -n "::: Checking ${PKG_MANAGER} for upgraded packages...."
- updatesToInstall=$(eval "${PKG_COUNT}")
- echo " done!"
- echo ":::"
- if [[ ${updatesToInstall} -eq "0" ]]; then
- echo "::: Your system is up to date! Continuing with Pi-hole installation..."
- else
- echo "::: There are ${updatesToInstall} updates available for your system!"
- echo "::: We recommend you run '${PKG_UPDATE}' after installing Pi-Hole! "
- echo ":::"
- fi
-}
-
-install_dependent_packages() {
- # Install packages passed in via argument array
- # No spinner - conflicts with set -e
- declare -a argArray1=("${!1}")
-
- for i in "${argArray1[@]}"; do
- echo -n "::: Checking for $i..."
- package_check_install "${i}" &> /dev/null
- echo " installed!"
- done
-}
-
-CreateLogFile() {
- # Create logfiles if necessary
- echo ":::"
- echo -n "::: Creating log file and changing owner to dnsmasq..."
- if [ ! -f /var/log/pihole.log ]; then
- touch /var/log/pihole.log
- chmod 644 /var/log/pihole.log
- chown "${DNSMASQ_USER}":root /var/log/pihole.log
- echo " done!"
- else
- echo " already exists!"
- fi
-}
-
-installPiholeWeb() {
- # Install the web interface
- echo ":::"
- echo "::: Installing pihole custom index page..."
- if [ -d "/var/www/html/pihole" ]; then
- if [ -f "/var/www/html/pihole/index.html" ]; then
- echo "::: Existing index.html detected, not overwriting"
- else
- echo -n "::: index.html missing, replacing... "
- cp /etc/.pihole/advanced/index.html /var/www/html/pihole/
- echo " done!"
- fi
-
- if [ -f "/var/www/html/pihole/index.js" ]; then
- echo "::: Existing index.js detected, not overwriting"
- else
- echo -n "::: index.js missing, replacing... "
- cp /etc/.pihole/advanced/index.js /var/www/html/pihole/
- echo " done!"
- fi
-
- else
- mkdir /var/www/html/pihole
- if [ -f /var/www/html/index.lighttpd.html ]; then
- mv /var/www/html/index.lighttpd.html /var/www/html/index.lighttpd.orig
- else
- printf "\n:::\tNo default index.lighttpd.html file found... not backing up"
- fi
- cp /etc/.pihole/advanced/index.* /var/www/html/pihole/.
- echo " done!"
- fi
- # Install Sudoer file
- echo ":::"
- echo -n "::: Installing sudoer file..."
- mkdir -p /etc/sudoers.d/
- cp /etc/.pihole/advanced/pihole.sudo /etc/sudoers.d/pihole
- chmod 0440 /etc/sudoers.d/pihole
- echo " done!"
-}
-
-installCron() {
- # Install the cron job
- echo ":::"
- echo -n "::: Installing latest Cron script..."
- cp /etc/.pihole/advanced/pihole.cron /etc/cron.d/pihole
- echo " done!"
-}
-
-runGravity() {
- # Run gravity.sh to build blacklists
- echo ":::"
- echo "::: Preparing to run gravity.sh to refresh hosts..."
- if ls /etc/pihole/list* 1> /dev/null 2>&1; then
- echo "::: Cleaning up previous install (preserving whitelist/blacklist)"
- rm /etc/pihole/list.*
- fi
- echo "::: Running gravity.sh"
- /opt/pihole/gravity.sh
-}
-
-create_pihole_user() {
- # Check if user pihole exists and create if not
- echo "::: Checking if user 'pihole' exists..."
- id -u pihole &> /dev/null && echo "::: User 'pihole' already exists" || (echo "::: User 'pihole' doesn't exist. Creating..." && useradd -r -s /usr/sbin/nologin pihole)
-}
-
-configureFirewall() {
- # Allow HTTP and DNS traffic
- if [ -x "$(command -v firewall-cmd)" ]; then
- firewall-cmd --state &> /dev/null && ( echo "::: Configuring firewalld for httpd and dnsmasq.." && firewall-cmd --permanent --add-port=80/tcp && firewall-cmd --permanent --add-port=53/tcp \
- && firewall-cmd --permanent --add-port=53/udp && firewall-cmd --reload) || echo "::: FirewallD not enabled"
- elif [ -x "$(command -v iptables)" ]; then
- echo "::: Configuring iptables for httpd and dnsmasq.."
- iptables -A INPUT -p tcp -m tcp --dport 80 -j ACCEPT
- iptables -A INPUT -p tcp -m tcp --dport 53 -j ACCEPT
- iptables -A INPUT -p udp -m udp --dport 53 -j ACCEPT
- else
- echo "::: No firewall detected.. skipping firewall configuration."
- fi
-}
-
-finalExports() {
- # Update variables in setupVars.conf file
- if [ -e "${setupVars}" ]; then
- sed -i.update.bak '/PIHOLE_INTERFACE/d;/IPV4_ADDRESS/d;/IPV6_ADDRESS/d;/PIHOLE_DNS_1/d;/PIHOLE_DNS_2/d;/QUERY_LOGGING/d;' "${setupVars}"
- fi
- {
- echo "PIHOLE_INTERFACE=${PIHOLE_INTERFACE}"
- echo "IPV4_ADDRESS=${IPV4_ADDRESS}"
- echo "IPV6_ADDRESS=${IPV6_ADDRESS}"
- echo "PIHOLE_DNS_1=${PIHOLE_DNS_1}"
- echo "PIHOLE_DNS_2=${PIHOLE_DNS_2}"
- echo "QUERY_LOGGING=${QUERY_LOGGING}"
- }>> "${setupVars}"
-}
-
-installPihole() {
- # Install base files and web interface
- create_pihole_user
- if [ ! -d "/var/www/html" ]; then
- mkdir -p /var/www/html
- fi
- chown ${LIGHTTPD_USER}:${LIGHTTPD_GROUP} /var/www/html
- chmod 775 /var/www/html
- usermod -a -G ${LIGHTTPD_GROUP} pihole
- if [ -x "$(command -v lighty-enable-mod)" ]; then
- lighty-enable-mod fastcgi fastcgi-php > /dev/null || true
- else
- printf "\n:::\tWarning: 'lighty-enable-mod' utility not found. Please ensure fastcgi is enabled if you experience issues.\n"
- fi
- installScripts
- installConfigs
- CreateLogFile
- configureSelinux
- installPiholeWeb
- installCron
- configureFirewall
- finalExports
- runGravity
-}
-
-accountForRefactor() {
- # At some point in the future this list can be pruned, for now we'll need it to ensure updates don't break.
-
- # Refactoring of install script has changed the name of a couple of variables. Sort them out here.
-
- sed -i 's/piholeInterface/PIHOLE_INTERFACE/g' ${setupVars}
- sed -i 's/IPv4_address/IPV4_ADDRESS/g' ${setupVars}
- sed -i 's/IPv4addr/IPV4_ADDRESS/g' ${setupVars}
- sed -i 's/IPv6_address/IPV6_ADDRESS/g' ${setupVars}
- sed -i 's/piholeIPv6/IPV6_ADDRESS/g' ${setupVars}
- sed -i 's/piholeDNS1/PIHOLE_DNS_1/g' ${setupVars}
- sed -i 's/piholeDNS2/PIHOLE_DNS_2/g' ${setupVars}
-
-}
-
-updatePihole() {
- accountForRefactor
- # Source ${setupVars} for use in the rest of the functions.
- . ${setupVars}
- # Install base files and web interface
- installScripts
- installConfigs
- CreateLogFile
- configureSelinux
- installPiholeWeb
- installCron
- configureFirewall
- finalExports #re-export setupVars.conf to account for any new vars added in new versions
- runGravity
-}
-
-configureSelinux() {
- if [ -x "$(command -v getenforce)" ]; then
- printf "\n::: SELinux Detected\n"
- printf ":::\tChecking for SELinux policy development packages..."
- package_check_install "selinux-policy-devel" > /dev/null
- echo " installed!"
- printf ":::\tEnabling httpd server side includes (SSI).. "
- setsebool -P httpd_ssi_exec on &> /dev/null && echo "Success" || echo "SELinux not enabled"
- printf "\n:::\tCompiling Pi-Hole SELinux policy..\n"
- if ! [ -x "$(command -v systemctl)" ]; then
- sed -i.bak '/systemd/d' /etc/.pihole/advanced/selinux/pihole.te
- fi
- checkmodule -M -m -o /etc/pihole/pihole.mod /etc/.pihole/advanced/selinux/pihole.te
- semodule_package -o /etc/pihole/pihole.pp -m /etc/pihole/pihole.mod
- semodule -i /etc/pihole/pihole.pp
- rm -f /etc/pihole/pihole.mod
- semodule -l | grep pihole &> /dev/null && echo "::: Installed Pi-Hole SELinux policy" || echo "::: Warning: Pi-Hole SELinux policy did not install."
- fi
-}
-
-displayFinalMessage() {
- if (( ${#1} > 0 )) ; then
- # Final completion message to user
- whiptail --msgbox --backtitle "Make it so." --title "Installation Complete!" "Configure your devices to use the Pi-hole as their DNS server using:
-
-IPv4: ${IPV4_ADDRESS%/*}
-IPv6: ${IPV6_ADDRESS}
-
-If you set a new IP address, you should restart the Pi.
-
-The install log is in /etc/pihole.
-View the web interface at http://pi.hole/admin or http://${IPV4_ADDRESS%/*}/admin
-The currently set password is ${1}" ${r} ${c}
- else
- whiptail --msgbox --backtitle "Make it so." --title "Installation Complete!" "Configure your devices to use the Pi-hole as their DNS server using:
-
-IPv4: ${IPV4_ADDRESS%/*}
-IPv6: ${IPV6_ADDRESS}
-
-If you set a new IP address, you should restart the Pi.
-
-The install log is in /etc/pihole.
-View the web interface at http://pi.hole/admin or http://${IPV4_ADDRESS%/*}/admin" ${r} ${c}
- fi
-}
-
-update_dialogs() {
- # reconfigure
- if [ "${reconfigure}" = true ]; then
- opt1a="Repair"
- opt1b="This will retain existing settings"
- strAdd="You will remain on the same version"
- else
- opt1a="Update"
- opt1b="This will retain existing settings."
- strAdd="You will be updated to the latest version."
- fi
- opt2a="Reconfigure"
- opt2b="This will allow you to enter new settings"
-
- UpdateCmd=$(whiptail --title "Existing Install Detected!" --menu "\n\nWe have detected an existing install.\n\nPlease choose from the following options: \n($strAdd)" ${r} ${c} 2 \
- "${opt1a}" "${opt1b}" \
- "${opt2a}" "${opt2b}" 3>&2 2>&1 1>&3)
-
- if [[ $? = 0 ]];then
- case ${UpdateCmd} in
- ${opt1a})
- echo "::: ${opt1a} option selected."
- useUpdateVars=true
- ;;
- ${opt2a})
- echo "::: ${opt2a} option selected"
- useUpdateVars=false
- ;;
- esac
- else
- echo "::: Cancel selected. Exiting..."
- exit 1
- fi
-
-}
-
-main() {
-# Check arguments for the undocumented flags
- for var in "$@"; do
- case "$var" in
- "--reconfigure" ) reconfigure=true;;
- "--i_do_not_follow_recommendations" ) skipSpaceCheck=false;;
- "--unattended" ) runUnattended=true;;
- esac
- done
-
- if [[ -f ${setupVars} ]]; then
- if [[ "${runUnattended}" == true ]]; then
- echo "::: --unattended passed to install script, no whiptail dialogs will be displayed"
- useUpdateVars=true
- else
- update_dialogs
- fi
- fi
-
- # Start the installer
- # Verify there is enough disk space for the install
- if [[ "${skipSpaceCheck}" == true ]]; then
- echo "::: --i_do_not_follow_recommendations passed to script, skipping free disk space verification!"
- else
- verifyFreeDiskSpace
- fi
-
- # Update package cache
- update_pacakge_cache
-
- # Notify user of package availability
- notify_package_updates_available
-
- # Install packages used by this installation script
- install_dependent_packages INSTALLER_DEPS[@]
-
- if [[ "${reconfigure}" == true ]]; then
- echo "::: --reconfigure passed to install script. Not downloading/updating local repos"
- else
- # Get Git files for Core and Admin
- getGitFiles ${PI_HOLE_LOCAL_REPO} ${piholeGitUrl}
- getGitFiles ${webInterfaceDir} ${webInterfaceGitUrl}
- fi
-
- if [[ ${useUpdateVars} == false ]]; then
- # Display welcome dialogs
- welcomeDialogs
- # Create directory for Pi-hole storage
- mkdir -p /etc/pihole/
- # Remove legacy scripts from previous storage location
- remove_legacy_scripts
- # Stop resolver and webserver while installing proceses
- stop_service dnsmasq
- stop_service lighttpd
- # Determine available interfaces
- get_available_interfaces
- # Find interfaces and let the user choose one
- chooseInterface
- # Let the user decide if they want to block ads over IPv4 and/or IPv6
- use4andor6
- # Decide what upstream DNS Servers to use
- setDNS
- # Let the user decide if they want query logging enabled...
- setLogging
-
- # Install packages used by the Pi-hole
- install_dependent_packages PIHOLE_DEPS[@]
-
- # Install and log everything to a file
- installPihole | tee ${tmpLog}
- else
- # update packages used by the Pi-hole
- install_dependent_packages PIHOLE_DEPS[@]
-
- updatePihole | tee ${tmpLog}
- fi
-
- # Move the log file into /etc/pihole for storage
- mv ${tmpLog} ${instalLogLoc}
-
- # Add password to web UI if there is none
- pw=""
- if [[ $(grep 'WEBPASSWORD' -c /etc/pihole/setupVars.conf) == 0 ]] ; then
- pw=$(tr -dc _A-Z-a-z-0-9 < /dev/urandom | head -c 8)
- pihole -a -p ${pw}
- fi
-
- if [[ "${useUpdateVars}" == false ]]; then
- displayFinalMessage ${pw}
- fi
-
- echo "::: Restarting services..."
- # Start services
- start_service dnsmasq
- enable_service dnsmasq
- start_service lighttpd
- enable_service lighttpd
- echo "::: done."
-
- echo ":::"
- if [[ "${useUpdateVars}" == false ]]; then
- echo "::: Installation Complete! Configure your devices to use the Pi-hole as their DNS server using:"
- echo "::: ${IPV4_ADDRESS%/*}"
- echo "::: ${IPV6_ADDRESS}"
- echo ":::"
- echo "::: If you set a new IP address, you should restart the Pi."
- echo "::: View the web interface at http://pi.hole/admin or http://${IPV4_ADDRESS%/*}/admin"
- else
- echo "::: Update complete!"
- fi
-
- if (( ${#pw} > 0 )) ; then
- echo ":::"
- echo "::: Note: As security measure a password has been installed for your web interface"
- echo "::: The currently set password is"
- echo "::: ${pw}"
- echo ":::"
- echo "::: You can always change it using"
- echo "::: pihole -a -p new_password"
- fi
-
- echo ":::"
- echo "::: The install log is located at: /etc/pihole/install.log"
-}
-
-if [[ "${PH_TEST}" != true ]] ; then
- main "$@"
-fi
+#!/usr/bin/env bash
# Pi-hole: A black hole for Internet advertisements
# (c) 2015, 2016 by Jacob Salmela
# Network-wide ad blocking via your Raspberry Pi
# http://pi-hole.net
# Installs Pi-hole
#
# Pi-hole is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 2 of the License, or
# (at your option) any later version.
# pi-hole.net/donate
#
# Install with this command (from your Pi):
#
# curl -L install.pi-hole.net | bash
set -e
######## VARIABLES #########
tmpLog=/tmp/pihole-install.log
instalLogLoc=/etc/pihole/install.log
setupVars=/etc/pihole/setupVars.conf
webInterfaceGitUrl="https://github.com/pi-hole/AdminLTE.git"
webInterfaceDir="/var/www/html/admin"
piholeGitUrl="https://github.com/pi-hole/pi-hole.git"
PI_HOLE_LOCAL_REPO="/etc/.pihole"
PI_HOLE_FILES=(chronometer list piholeDebug piholeLogFlush setupLCD update version)
useUpdateVars=false
IPV4_ADDRESS=""
IPV6_ADDRESS=""
QUERY_LOGGING=true
# Find the rows and columns will default to 80x24 is it can not be detected
screen_size=$(stty size 2>/dev/null || echo 24 80)
rows=$(echo $screen_size | awk '{print $1}')
columns=$(echo $screen_size | awk '{print $2}')
# Divide by two so the dialogs take up half of the screen, which looks nice.
r=$(( rows / 2 ))
c=$(( columns / 2 ))
# Unless the screen is tiny
r=$(( r < 20 ? 20 : r ))
c=$(( c < 70 ? 70 : c ))
######## Undocumented Flags. Shhh ########
skipSpaceCheck=false
reconfigure=false
runUnattended=false
######## FIRST CHECK ########
# Must be root to install
echo ":::"
if [[ ${EUID} -eq 0 ]]; then
echo "::: You are root."
else
echo "::: Script called with non-root privileges. The Pi-hole installs server packages and configures"
echo "::: system networking, it requires elevated rights. Please check the contents of the script for"
echo "::: any concerns with this requirement. Please be sure to download this script from a trusted source."
echo ":::"
echo "::: Detecting the presence of the sudo utility for continuation of this install..."
if [ -x "$(command -v sudo)" ]; then
echo "::: Utility sudo located."
exec curl -sSL https://install.pi-hole.net | sudo bash "$@"
exit $?
else
echo "::: sudo is needed for the Web interface to run pihole commands. Please run this script as root and it will be automatically installed."
exit 1
fi
fi
# Compatibility
if [[ $(command -v apt-get) ]]; then
#Debian Family
#############################################
PKG_MANAGER="apt-get"
PKG_CACHE="/var/lib/apt/lists/"
UPDATE_PKG_CACHE="${PKG_MANAGER} update"
PKG_UPDATE="${PKG_MANAGER} upgrade"
PKG_INSTALL="${PKG_MANAGER} --yes --fix-missing install"
# grep -c will return 1 retVal on 0 matches, block this throwing the set -e with an OR TRUE
PKG_COUNT="${PKG_MANAGER} -s -o Debug::NoLocking=true upgrade | grep -c ^Inst || true"
# #########################################
# fixes for dependancy differences
# Debian 7 doesn't have iproute2 use iproute
${PKG_MANAGER} install --dry-run iproute2 > /dev/null 2>&1 && IPROUTE_PKG="iproute2" || IPROUTE_PKG="iproute"
# Prefer the php metapackage if it's there, fall back on the php5 pacakges
${PKG_MANAGER} install --dry-run php > /dev/null 2>&1 && phpVer="php" || phpVer="php5"
# #########################################
INSTALLER_DEPS=( apt-utils whiptail git dhcpcd5)
PIHOLE_DEPS=( iputils-ping lsof dnsutils bc dnsmasq lighttpd ${phpVer}-common ${phpVer}-cgi curl unzip wget sudo netcat cron ${IPROUTE_PKG} )
LIGHTTPD_USER="www-data"
LIGHTTPD_GROUP="www-data"
LIGHTTPD_CFG="lighttpd.conf.debian"
DNSMASQ_USER="dnsmasq"
package_check_install() {
dpkg-query -W -f='${Status}' "${1}" 2>/dev/null | grep -c "ok installed" || ${PKG_INSTALL} "${1}"
}
elif [ $(command -v rpm) ]; then
# Fedora Family
if [ $(command -v dnf) ]; then
PKG_MANAGER="dnf"
else
PKG_MANAGER="yum"
fi
PKG_CACHE="/var/cache/${PKG_MANAGER}"
UPDATE_PKG_CACHE="${PKG_MANAGER} check-update"
PKG_UPDATE="${PKG_MANAGER} update -y"
PKG_INSTALL="${PKG_MANAGER} install -y"
PKG_COUNT="${PKG_MANAGER} check-update | egrep '(.i686|.x86|.noarch|.arm|.src)' | wc -l"
INSTALLER_DEPS=( iproute net-tools procps-ng newt git )
PIHOLE_DEPS=( epel-release bind-utils bc dnsmasq lighttpd lighttpd-fastcgi php-common php-cli php curl unzip wget findutils cronie sudo nmap-ncat )
if grep -q 'Fedora' /etc/redhat-release; then
remove_deps=(epel-release);
PIHOLE_DEPS=( ${PIHOLE_DEPS[@]/$remove_deps} );
fi
LIGHTTPD_USER="lighttpd"
LIGHTTPD_GROUP="lighttpd"
LIGHTTPD_CFG="lighttpd.conf.fedora"
DNSMASQ_USER="nobody"
package_check_install() {
rpm -qa | grep ^"${1}"- > /dev/null || ${PKG_INSTALL} "${1}"
}
else
echo "OS distribution not supported"
exit
fi
####### FUNCTIONS ##########
spinner() {
local pid=$1
local delay=0.50
local spinstr='/-\|'
while [ "$(ps a | awk '{print $1}' | grep "${pid}")" ]; do
local temp=${spinstr#?}
printf " [%c] " "${spinstr}"
local spinstr=${temp}${spinstr%"$temp"}
sleep ${delay}
printf "\b\b\b\b\b\b"
done
printf " \b\b\b\b"
}
is_repo() {
# Use git to check if directory is currently under VCS, return the value
local directory="${1}"
git -C "${directory}" status --short &> /dev/null
return
}
make_repo() {
local directory="${1}"
local remoteRepo="${2}"
# Remove the non-repod interface and clone the interface
echo -n "::: Cloning $remoteRepo into $directory..."
rm -rf "${directory}"
git clone -q --depth 1 "${remoteRepo}" "${directory}" > /dev/null & spinner $!
echo " done!"
}
update_repo() {
local directory="${1}"
# Pull the latest commits
echo -n "::: Updating repo in $1..."
cd "${directory}" || exit 1
git stash -q > /dev/null & spinner $!
git pull -q > /dev/null & spinner $!
echo " done!"
}
getGitFiles() {
# Setup git repos for directory and repository passed
# as arguments 1 and 2
local directory="${1}"
local remoteRepo="${2}"
echo ":::"
echo "::: Checking for existing repository..."
if is_repo "${directory}"; then
update_repo "${directory}"
else
make_repo "${directory}" "${remoteRepo}"
fi
}
find_IPv4_information() {
# Find IP used to route to outside world
IPv4dev=$(ip route get 8.8.8.8 | awk '{for(i=1;i<=NF;i++)if($i~/dev/)print $(i+1)}')
IPV4_ADDRESS=$(ip -o -f inet addr show dev "$IPv4dev" | awk '{print $4}' | awk 'END {print}')
IPv4gw=$(ip route get 8.8.8.8 | awk '{print $3}')
}
get_available_interfaces() {
# Get available interfaces. Consider only getting UP interfaces in the future, and leaving DOWN interfaces out of list.
availableInterfaces=$(ip -o link | awk '{print $2}' | grep -v "lo" | cut -d':' -f1 | cut -d'@' -f1)
}
welcomeDialogs() {
# Display the welcome dialog
whiptail --msgbox --backtitle "Welcome" --title "Pi-hole automated installer" "\n\nThis installer will transform your device into a network-wide ad blocker!" ${r} ${c}
# Support for a part-time dev
whiptail --msgbox --backtitle "Plea" --title "Free and open source" "\n\nThe Pi-hole is free, but powered by your donations: http://pi-hole.net/donate" ${r} ${c}
# Explain the need for a static address
whiptail --msgbox --backtitle "Initiating network interface" --title "Static IP Needed" "\n\nThe Pi-hole is a SERVER so it needs a STATIC IP ADDRESS to function properly.
In the next section, you can choose to use your current network settings (DHCP) or to manually edit them." ${r} ${c}
}
verifyFreeDiskSpace() {
# 50MB is the minimum space needed (45MB install (includes web admin bootstrap/jquery libraries etc) + 5MB one day of logs.)
# - Fourdee: Local ensures the variable is only created, and accessible within this function/void. Generally considered a "good" coding practice for non-global variables.
echo "::: Verifying free disk space..."
local required_free_kilobytes=51200
local existing_free_kilobytes=$(df -Pk | grep -m1 '\/$' | awk '{print $4}')
# - Unknown free disk space , not a integer
if ! [[ "${existing_free_kilobytes}" =~ ^([0-9])+$ ]]; then
echo "::: Unknown free disk space!"
echo "::: We were unable to determine available free disk space on this system."
echo "::: You may override this check and force the installation, however, it is not recommended"
echo "::: To do so, pass the argument '--i_do_not_follow_recommendations' to the install script"
echo "::: eg. curl -L https://install.pi-hole.net | bash /dev/stdin --i_do_not_follow_recommendations"
exit 1
# - Insufficient free disk space
elif [[ ${existing_free_kilobytes} -lt ${required_free_kilobytes} ]]; then
echo "::: Insufficient Disk Space!"
echo "::: Your system appears to be low on disk space. pi-hole recommends a minimum of $required_free_kilobytes KiloBytes."
echo "::: You only have ${existing_free_kilobytes} KiloBytes free."
echo "::: If this is a new install you may need to expand your disk."
echo "::: Try running 'sudo raspi-config', and choose the 'expand file system option'"
echo "::: After rebooting, run this installation again. (curl -L https://install.pi-hole.net | bash)"
echo "Insufficient free space, exiting..."
exit 1
fi
}
chooseInterface() {
# Turn the available interfaces into an array so it can be used with a whiptail dialog
local interfacesArray=()
# Number of available interfaces
local interfaceCount
# Whiptail variable storage
local chooseInterfaceCmd
# Temporary Whiptail options storage
local chooseInterfaceOptions
# Loop sentinel variable
local firstLoop=1
while read -r line; do
mode="OFF"
if [[ ${firstLoop} -eq 1 ]]; then
firstLoop=0
mode="ON"
fi
interfacesArray+=("${line}" "available" "${mode}")
done <<< "${availableInterfaces}"
# Find out how many interfaces are available to choose from
interfaceCount=$(echo "${availableInterfaces}" | wc -l)
chooseInterfaceCmd=(whiptail --separate-output --radiolist "Choose An Interface (press space to select)" ${r} ${c} ${interfaceCount})
chooseInterfaceOptions=$("${chooseInterfaceCmd[@]}" "${interfacesArray[@]}" 2>&1 >/dev/tty)
if [[ $? = 0 ]]; then
for desiredInterface in ${chooseInterfaceOptions}; do
PIHOLE_INTERFACE=${desiredInterface}
echo "::: Using interface: $PIHOLE_INTERFACE"
done
else
echo "::: Cancel selected, exiting...."
exit 1
fi
}
useIPv6dialog() {
# Show the IPv6 address used for blocking
IPV6_ADDRESS=$(ip -6 route get 2001:4860:4860::8888 | awk -F " " '{ for(i=1;i<=NF;i++) if ($i == "src") print $(i+1) }')
whiptail --msgbox --backtitle "IPv6..." --title "IPv6 Supported" "$IPV6_ADDRESS will be used to block ads." ${r} ${c}
}
use4andor6() {
local useIPv4
local useIPv6
# Let use select IPv4 and/or IPv6
cmd=(whiptail --separate-output --checklist "Select Protocols (press space to select)" ${r} ${c} 2)
options=(IPv4 "Block ads over IPv4" on
IPv6 "Block ads over IPv6" on)
choices=$("${cmd[@]}" "${options[@]}" 2>&1 >/dev/tty)
if [[ $? = 0 ]];then
for choice in ${choices}
do
case ${choice} in
IPv4 ) useIPv4=true;;
IPv6 ) useIPv6=true;;
esac
done
if [[ ${useIPv4} ]]; then
find_IPv4_information
getStaticIPv4Settings
setStaticIPv4
fi
if [[ ${useIPv6} ]]; then
useIPv6dialog
fi
echo "::: IPv4 address: ${IPV4_ADDRESS}"
echo "::: IPv6 address: ${IPV6_ADDRESS}"
if [ ! ${useIPv4} ] && [ ! ${useIPv6} ]; then
echo "::: Cannot continue, neither IPv4 or IPv6 selected"
echo "::: Exiting"
exit 1
fi
else
echo "::: Cancel selected. Exiting..."
exit 1
fi
}
getStaticIPv4Settings() {
# Ask if the user wants to use DHCP settings as their static IP
if (whiptail --backtitle "Calibrating network interface" --title "Static IP Address" --yesno "Do you want to use your current network settings as a static address?
IP address: ${IPV4_ADDRESS}
Gateway: ${IPv4gw}" ${r} ${c}); then
# If they choose yes, let the user know that the IP address will not be available via DHCP and may cause a conflict.
whiptail --msgbox --backtitle "IP information" --title "FYI: IP Conflict" "It is possible your router could still try to assign this IP to a device, which would cause a conflict. But in most cases the router is smart enough to not do that.
If you are worried, either manually set the address, or modify the DHCP reservation pool so it does not include the IP you want.
It is also possible to use a DHCP reservation, but if you are going to do that, you might as well set a static address." ${r} ${c}
# Nothing else to do since the variables are already set above
else
# Otherwise, we need to ask the user to input their desired settings.
# Start by getting the IPv4 address (pre-filling it with info gathered from DHCP)
# Start a loop to let the user enter their information with the chance to go back and edit it if necessary
until [[ ${ipSettingsCorrect} = True ]]; do
# Ask for the IPv4 address
IPV4_ADDRESS=$(whiptail --backtitle "Calibrating network interface" --title "IPv4 address" --inputbox "Enter your desired IPv4 address" ${r} ${c} "${IPV4_ADDRESS}" 3>&1 1>&2 2>&3)
if [[ $? = 0 ]]; then
echo "::: Your static IPv4 address: ${IPV4_ADDRESS}"
# Ask for the gateway
IPv4gw=$(whiptail --backtitle "Calibrating network interface" --title "IPv4 gateway (router)" --inputbox "Enter your desired IPv4 default gateway" ${r} ${c} "${IPv4gw}" 3>&1 1>&2 2>&3)
if [[ $? = 0 ]]; then
echo "::: Your static IPv4 gateway: ${IPv4gw}"
# Give the user a chance to review their settings before moving on
if (whiptail --backtitle "Calibrating network interface" --title "Static IP Address" --yesno "Are these settings correct?
IP address: ${IPV4_ADDRESS}
Gateway: ${IPv4gw}" ${r} ${c}); then
# After that's done, the loop ends and we move on
ipSettingsCorrect=True
else
# If the settings are wrong, the loop continues
ipSettingsCorrect=False
fi
else
# Cancelling gateway settings window
ipSettingsCorrect=False
echo "::: Cancel selected. Exiting..."
exit 1
fi
else
# Cancelling IPv4 settings window
ipSettingsCorrect=False
echo "::: Cancel selected. Exiting..."
exit 1
fi
done
# End the if statement for DHCP vs. static
fi
}
setDHCPCD() {
# Append these lines to dhcpcd.conf to enable a static IP
echo "## interface ${PIHOLE_INTERFACE}
static ip_address=${IPV4_ADDRESS}
static routers=${IPv4gw}
static domain_name_servers=${IPv4gw}" | tee -a /etc/dhcpcd.conf >/dev/null
}
setStaticIPv4() {
local IFCFG_FILE
local IPADDR
local CIDR
if [[ -f /etc/dhcpcd.conf ]]; then
# Debian Family
if grep -q "${IPV4_ADDRESS}" /etc/dhcpcd.conf; then
echo "::: Static IP already configured"
else
setDHCPCD
ip addr replace dev "${PIHOLE_INTERFACE}" "${IPV4_ADDRESS}"
echo ":::"
echo "::: Setting IP to ${IPV4_ADDRESS}. You may need to restart after the install is complete."
echo ":::"
fi
elif [[ -f /etc/sysconfig/network-scripts/ifcfg-${PIHOLE_INTERFACE} ]];then
# Fedora Family
IFCFG_FILE=/etc/sysconfig/network-scripts/ifcfg-${PIHOLE_INTERFACE}
if grep -q "${IPV4_ADDRESS}" "${IFCFG_FILE}"; then
echo "::: Static IP already configured"
else
IPADDR=$(echo "${IPV4_ADDRESS}" | cut -f1 -d/)
CIDR=$(echo "${IPV4_ADDRESS}" | cut -f2 -d/)
# Backup existing interface configuration:
cp "${IFCFG_FILE}" "${IFCFG_FILE}".pihole.orig
# Build Interface configuration file:
{
echo "# Configured via Pi-Hole installer"
echo "DEVICE=$PIHOLE_INTERFACE"
echo "BOOTPROTO=none"
echo "ONBOOT=yes"
echo "IPADDR=$IPADDR"
echo "PREFIX=$CIDR"
echo "GATEWAY=$IPv4gw"
echo "DNS1=$PIHOLE_DNS_1"
echo "DNS2=$PIHOLE_DNS_2"
echo "USERCTL=no"
}> "${IFCFG_FILE}"
ip addr replace dev "${PIHOLE_INTERFACE}" "${IPV4_ADDRESS}"
if [ -x "$(command -v nmcli)" ];then
# Tell NetworkManager to read our new sysconfig file
nmcli con load "${IFCFG_FILE}" > /dev/null
fi
echo ":::"
echo "::: Setting IP to ${IPV4_ADDRESS}. You may need to restart after the install is complete."
echo ":::"
fi
else
echo "::: Warning: Unable to locate configuration file to set static IPv4 address!"
exit 1
fi
}
valid_ip() {
local ip=${1}
local stat=1
if [[ ${ip} =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then
OIFS=$IFS
IFS='.'
ip=(${ip})
IFS=${OIFS}
[[ ${ip[0]} -le 255 && ${ip[1]} -le 255 \
&& ${ip[2]} -le 255 && ${ip[3]} -le 255 ]]
stat=$?
fi
return ${stat}
}
setDNS() {
DNSChooseCmd=(whiptail --separate-output --radiolist "Select Upstream DNS Provider. To use your own, select Custom." ${r} ${c} 6)
DNSChooseOptions=(Google "" on
OpenDNS "" off
Level3 "" off
Norton "" off
Comodo "" off
Custom "" off)
DNSchoices=$("${DNSChooseCmd[@]}" "${DNSChooseOptions[@]}" 2>&1 >/dev/tty)
if [[ $? = 0 ]];then
case ${DNSchoices} in
Google)
echo "::: Using Google DNS servers."
PIHOLE_DNS_1="8.8.8.8"
PIHOLE_DNS_2="8.8.4.4"
;;
OpenDNS)
echo "::: Using OpenDNS servers."
PIHOLE_DNS_1="208.67.222.222"
PIHOLE_DNS_2="208.67.220.220"
;;
Level3)
echo "::: Using Level3 servers."
PIHOLE_DNS_1="4.2.2.1"
PIHOLE_DNS_2="4.2.2.2"
;;
Norton)
echo "::: Using Norton ConnectSafe servers."
PIHOLE_DNS_1="199.85.126.10"
PIHOLE_DNS_2="199.85.127.10"
;;
Comodo)
echo "::: Using Comodo Secure servers."
PIHOLE_DNS_1="8.26.56.26"
PIHOLE_DNS_2="8.20.247.20"
;;
Custom)
until [[ ${DNSSettingsCorrect} = True ]]; do
strInvalid="Invalid"
if [ ! ${PIHOLE_DNS_1} ]; then
if [ ! ${PIHOLE_DNS_2} ]; then
prePopulate=""
else
prePopulate=", ${PIHOLE_DNS_2}"
fi
elif [ ${PIHOLE_DNS_1} ] && [ ! ${PIHOLE_DNS_2} ]; then
prePopulate="${PIHOLE_DNS_1}"
elif [ ${PIHOLE_DNS_1} ] && [ ${PIHOLE_DNS_2} ]; then
prePopulate="${PIHOLE_DNS_1}, ${PIHOLE_DNS_2}"
fi
piholeDNS=$(whiptail --backtitle "Specify Upstream DNS Provider(s)" --inputbox "Enter your desired upstream DNS provider(s), seperated by a comma.\n\nFor example '8.8.8.8, 8.8.4.4'" ${r} ${c} "${prePopulate}" 3>&1 1>&2 2>&3)
if [[ $? = 0 ]]; then
PIHOLE_DNS_1=$(echo "${piholeDNS}" | sed 's/[, \t]\+/,/g' | awk -F, '{print$1}')
PIHOLE_DNS_2=$(echo "${piholeDNS}" | sed 's/[, \t]\+/,/g' | awk -F, '{print$2}')
if ! valid_ip "${PIHOLE_DNS_1}" || [ ! "${PIHOLE_DNS_1}" ]; then
PIHOLE_DNS_1=${strInvalid}
fi
if ! valid_ip "${PIHOLE_DNS_2}" && [ "${PIHOLE_DNS_2}" ]; then
PIHOLE_DNS_2=${strInvalid}
fi
else
echo "::: Cancel selected, exiting...."
exit 1
fi
if [[ ${PIHOLE_DNS_1} == "${strInvalid}" ]] || [[ ${PIHOLE_DNS_2} == "${strInvalid}" ]]; then
whiptail --msgbox --backtitle "Invalid IP" --title "Invalid IP" "One or both entered IP addresses were invalid. Please try again.\n\n DNS Server 1: $PIHOLE_DNS_1\n DNS Server 2: ${PIHOLE_DNS_2}" ${r} ${c}
if [[ ${PIHOLE_DNS_1} == "${strInvalid}" ]]; then
PIHOLE_DNS_1=""
fi
if [[ ${PIHOLE_DNS_2} == "${strInvalid}" ]]; then
PIHOLE_DNS_2=""
fi
DNSSettingsCorrect=False
else
if (whiptail --backtitle "Specify Upstream DNS Provider(s)" --title "Upstream DNS Provider(s)" --yesno "Are these settings correct?\n DNS Server 1: $PIHOLE_DNS_1\n DNS Server 2: ${PIHOLE_DNS_2}" ${r} ${c}); then
DNSSettingsCorrect=True
else
# If the settings are wrong, the loop continues
DNSSettingsCorrect=False
fi
fi
done
;;
esac
else
echo "::: Cancel selected. Exiting..."
exit 1
fi
}
setLogging() {
local LogToggleCommand
local LogChooseOptions
local LogChoices
LogToggleCommand=(whiptail --separate-output --radiolist "Do you want to log queries?\n (Disabling will render graphs on the Admin page useless):" ${r} ${c} 6)
LogChooseOptions=("On (Reccomended)" "" on
Off "" off)
LogChoices=$("${LogToggleCommand[@]}" "${LogChooseOptions[@]}" 2>&1 >/dev/tty) || (echo "::: Cancel selected. Exiting..." && exit 1)
case ${LogChoices} in
"On (Recommended)")
echo "::: Logging On."
QUERY_LOGGING=true
;;
Off)
echo "::: Logging Off."
QUERY_LOGGING=false
;;
esac
}
version_check_dnsmasq() {
# Check if /etc/dnsmasq.conf is from pihole. If so replace with an original and install new in .d directory
local dnsmasq_conf="/etc/dnsmasq.conf"
local dnsmasq_conf_orig="/etc/dnsmasq.conf.orig"
local dnsmasq_pihole_id_string="addn-hosts=/etc/pihole/gravity.list"
local dnsmasq_original_config="/etc/.pihole/advanced/dnsmasq.conf.original"
local dnsmasq_pihole_01_snippet="/etc/.pihole/advanced/01-pihole.conf"
local dnsmasq_pihole_01_location="/etc/dnsmasq.d/01-pihole.conf"
if [ -f ${dnsmasq_conf} ]; then
echo -n "::: Existing dnsmasq.conf found..."
if grep -q ${dnsmasq_pihole_id_string} ${dnsmasq_conf}; then
echo " it is from a previous pi-hole install."
echo -n "::: Backing up dnsmasq.conf to dnsmasq.conf.orig..."
mv -f ${dnsmasq_conf} ${dnsmasq_conf_orig}
echo " done."
echo -n "::: Restoring default dnsmasq.conf..."
cp ${dnsmasq_original_config} ${dnsmasq_conf}
echo " done."
else
echo " it is not a pi-hole file, leaving alone!"
fi
else
echo -n "::: No dnsmasq.conf found.. restoring default dnsmasq.conf..."
cp ${dnsmasq_original_config} ${dnsmasq_conf}
echo " done."
fi
echo -n "::: Copying 01-pihole.conf to /etc/dnsmasq.d/01-pihole.conf..."
cp ${dnsmasq_pihole_01_snippet} ${dnsmasq_pihole_01_location}
echo " done."
sed -i "s/@INT@/$PIHOLE_INTERFACE/" ${dnsmasq_pihole_01_location}
if [[ "${PIHOLE_DNS_1}" != "" ]]; then
sed -i "s/@DNS1@/$PIHOLE_DNS_1/" ${dnsmasq_pihole_01_location}
else
sed -i '/^server=@DNS1@/d' ${dnsmasq_pihole_01_location}
fi
if [[ "${PIHOLE_DNS_2}" != "" ]]; then
sed -i "s/@DNS2@/$PIHOLE_DNS_2/" ${dnsmasq_pihole_01_location}
else
sed -i '/^server=@DNS2@/d' ${dnsmasq_pihole_01_location}
fi
sed -i 's/^#conf-dir=\/etc\/dnsmasq.d$/conf-dir=\/etc\/dnsmasq.d/' ${dnsmasq_conf}
if [[ "${QUERY_LOGGING}" == false ]] ; then
#Disable Logging
sed -i 's/^log-queries/#log-queries/' ${dnsmasq_pihole_01_location}
else
#Enable Logging
sed -i 's/^#log-queries/log-queries/' ${dnsmasq_pihole_01_location}
fi
}
remove_legacy_scripts() {
#Tidy up /usr/local/bin directory if installing over previous install.
oldFiles=( gravity chronometer whitelist blacklist piholeLogFlush updateDashboard uninstall setupLCD piholeDebug)
for i in "${oldFiles[@]}"; do
if [ -f "/usr/local/bin/$i.sh" ]; then
rm /usr/local/bin/"$i".sh
fi
done
}
clean_existing() {
# Clean an exiting installation to prepare for upgrade/reinstall
# ${1} Directory to clean; ${2} Array of files to remove
local clean_directory="${1}"
local old_files=${2}
for script in "${old_files[@]}"; do
rm -f "${clean_directory}${script}.sh"
done
}
installScripts() {
# Install the scripts from repository to their various locations
readonly install_dir="/opt/pihole/"
echo ":::"
echo -n "::: Installing scripts from ${PI_HOLE_LOCAL_REPO}..."
# Clear out script files from Pi-hole scripts directory.
clean_existing "${install_dir}" "${PI_HOLE_FILES}"
# Install files from local core repository
if is_repo "${PI_HOLE_LOCAL_REPO}"; then
cd "${PI_HOLE_LOCAL_REPO}"
install -o "${USER}" -Dm755 -t /opt/pihole/ gravity.sh
install -o "${USER}" -Dm755 -t /opt/pihole/ ./advanced/Scripts/*.sh
install -o "${USER}" -Dm755 -t /opt/pihole/ ./automated\ install/uninstall.sh
install -o "${USER}" -Dm755 -t /usr/local/bin/ pihole
install -Dm644 ./advanced/bash-completion/pihole /etc/bash_completion.d/pihole
echo " done."
else
echo " *** ERROR: Local repo ${core_repo} not found, exiting."
exit 1
fi
}
installConfigs() {
# Install the configs from /etc/.pihole to their various locations
echo ":::"
echo "::: Installing configs..."
version_check_dnsmasq
if [ ! -d "/etc/lighttpd" ]; then
mkdir /etc/lighttpd
chown "${USER}":root /etc/lighttpd
elif [ -f "/etc/lighttpd/lighttpd.conf" ]; then
mv /etc/lighttpd/lighttpd.conf /etc/lighttpd/lighttpd.conf.orig
fi
cp /etc/.pihole/advanced/${LIGHTTPD_CFG} /etc/lighttpd/lighttpd.conf
mkdir -p /var/run/lighttpd
chown ${LIGHTTPD_USER}:${LIGHTTPD_GROUP} /var/run/lighttpd
mkdir -p /var/cache/lighttpd/compress
chown ${LIGHTTPD_USER}:${LIGHTTPD_GROUP} /var/cache/lighttpd/compress
mkdir -p /var/cache/lighttpd/uploads
chown ${LIGHTTPD_USER}:${LIGHTTPD_GROUP} /var/cache/lighttpd/uploads
}
stop_service() {
# Stop service passed in as argument.
# Can softfail, as process may not be installed when this is called
echo ":::"
echo -n "::: Stopping ${1} service..."
if [ -x "$(command -v systemctl)" ]; then
systemctl stop "${1}" &> /dev/null & spinner $! || true
else
service "${1}" stop &> /dev/null & spinner $! || true
fi
echo " done."
}
start_service() {
# Start/Restart service passed in as argument
# This should not fail, it's an error if it does
echo ":::"
echo -n "::: Starting ${1} service..."
if [ -x "$(command -v systemctl)" ]; then
systemctl restart "${1}" &> /dev/null & spinner $!
else
service "${1}" restart &> /dev/null & spinner $!
fi
echo " done."
}
enable_service() {
# Enable service so that it will start with next reboot
echo ":::"
echo -n "::: Enabling ${1} service to start on reboot..."
if [ -x "$(command -v systemctl)" ]; then
systemctl enable "${1}" &> /dev/null & spinner $!
else
update-rc.d "${1}" defaults &> /dev/null & spinner $!
fi
echo " done."
}
update_pacakge_cache() {
#Running apt-get update/upgrade with minimal output can cause some issues with
#requiring user input (e.g password for phpmyadmin see #218)
#Check to see if apt-get update has already been run today
#it needs to have been run at least once on new installs!
timestamp=$(stat -c %Y ${PKG_CACHE})
timestampAsDate=$(date -d @"${timestamp}" "+%b %e")
today=$(date "+%b %e")
if [ ! "${today}" == "${timestampAsDate}" ]; then
#update package lists
echo ":::"
echo -n "::: ${PKG_MANAGER} update has not been run today. Running now..."
${UPDATE_PKG_CACHE} &> /dev/null & spinner $!
echo " done!"
fi
}
notify_package_updates_available() {
# Let user know if they have outdated packages on their system and
# advise them to run a package update at soonest possible.
echo ":::"
echo -n "::: Checking ${PKG_MANAGER} for upgraded packages...."
updatesToInstall=$(eval "${PKG_COUNT}")
echo " done!"
echo ":::"
if [[ ${updatesToInstall} -eq "0" ]]; then
echo "::: Your system is up to date! Continuing with Pi-hole installation..."
else
echo "::: There are ${updatesToInstall} updates available for your system!"
echo "::: We recommend you run '${PKG_UPDATE}' after installing Pi-Hole! "
echo ":::"
fi
}
install_dependent_packages() {
# Install packages passed in via argument array
# No spinner - conflicts with set -e
declare -a argArray1=("${!1}")
for i in "${argArray1[@]}"; do
echo -n "::: Checking for $i..."
package_check_install "${i}" &> /dev/null
echo " installed!"
done
}
CreateLogFile() {
# Create logfiles if necessary
echo ":::"
echo -n "::: Creating log file and changing owner to dnsmasq..."
if [ ! -f /var/log/pihole.log ]; then
touch /var/log/pihole.log
chmod 644 /var/log/pihole.log
chown "${DNSMASQ_USER}":root /var/log/pihole.log
echo " done!"
else
echo " already exists!"
fi
}
installPiholeWeb() {
# Install the web interface
echo ":::"
echo "::: Installing pihole custom index page..."
if [ -d "/var/www/html/pihole" ]; then
if [ -f "/var/www/html/pihole/index.html" ]; then
echo "::: Existing index.html detected, not overwriting"
else
echo -n "::: index.html missing, replacing... "
cp /etc/.pihole/advanced/index.html /var/www/html/pihole/
echo " done!"
fi
if [ -f "/var/www/html/pihole/index.js" ]; then
echo "::: Existing index.js detected, not overwriting"
else
echo -n "::: index.js missing, replacing... "
cp /etc/.pihole/advanced/index.js /var/www/html/pihole/
echo " done!"
fi
else
mkdir /var/www/html/pihole
if [ -f /var/www/html/index.lighttpd.html ]; then
mv /var/www/html/index.lighttpd.html /var/www/html/index.lighttpd.orig
else
printf "\n:::\tNo default index.lighttpd.html file found... not backing up"
fi
cp /etc/.pihole/advanced/index.* /var/www/html/pihole/.
echo " done!"
fi
# Install Sudoer file
echo ":::"
echo -n "::: Installing sudoer file..."
mkdir -p /etc/sudoers.d/
cp /etc/.pihole/advanced/pihole.sudo /etc/sudoers.d/pihole
chmod 0440 /etc/sudoers.d/pihole
echo " done!"
}
installCron() {
# Install the cron job
echo ":::"
echo -n "::: Installing latest Cron script..."
cp /etc/.pihole/advanced/pihole.cron /etc/cron.d/pihole
echo " done!"
}
runGravity() {
# Run gravity.sh to build blacklists
echo ":::"
echo "::: Preparing to run gravity.sh to refresh hosts..."
if ls /etc/pihole/list* 1> /dev/null 2>&1; then
echo "::: Cleaning up previous install (preserving whitelist/blacklist)"
rm /etc/pihole/list.*
fi
echo "::: Running gravity.sh"
/opt/pihole/gravity.sh
}
create_pihole_user() {
# Check if user pihole exists and create if not
echo "::: Checking if user 'pihole' exists..."
id -u pihole &> /dev/null && echo "::: User 'pihole' already exists" || (echo "::: User 'pihole' doesn't exist. Creating..." && useradd -r -s /usr/sbin/nologin pihole)
}
configureFirewall() {
# Allow HTTP and DNS traffic
if [ -x "$(command -v firewall-cmd)" ]; then
firewall-cmd --state &> /dev/null && ( echo "::: Configuring firewalld for httpd and dnsmasq.." && firewall-cmd --permanent --add-port=80/tcp && firewall-cmd --permanent --add-port=53/tcp \
&& firewall-cmd --permanent --add-port=53/udp && firewall-cmd --reload) || echo "::: FirewallD not enabled"
elif [ -x "$(command -v iptables)" ]; then
echo "::: Configuring iptables for httpd and dnsmasq.."
iptables -A INPUT -p tcp -m tcp --dport 80 -j ACCEPT
iptables -A INPUT -p tcp -m tcp --dport 53 -j ACCEPT
iptables -A INPUT -p udp -m udp --dport 53 -j ACCEPT
else
echo "::: No firewall detected.. skipping firewall configuration."
fi
}
finalExports() {
# Update variables in setupVars.conf file
if [ -e "${setupVars}" ]; then
sed -i.update.bak '/PIHOLE_INTERFACE/d;/IPV4_ADDRESS/d;/IPV6_ADDRESS/d;/PIHOLE_DNS_1/d;/PIHOLE_DNS_2/d;/QUERY_LOGGING/d;' "${setupVars}"
fi
{
echo "PIHOLE_INTERFACE=${PIHOLE_INTERFACE}"
echo "IPV4_ADDRESS=${IPV4_ADDRESS}"
echo "IPV6_ADDRESS=${IPV6_ADDRESS}"
echo "PIHOLE_DNS_1=${PIHOLE_DNS_1}"
echo "PIHOLE_DNS_2=${PIHOLE_DNS_2}"
echo "QUERY_LOGGING=${QUERY_LOGGING}"
}>> "${setupVars}"
}
installPihole() {
# Install base files and web interface
create_pihole_user
if [ ! -d "/var/www/html" ]; then
mkdir -p /var/www/html
fi
chown ${LIGHTTPD_USER}:${LIGHTTPD_GROUP} /var/www/html
chmod 775 /var/www/html
usermod -a -G ${LIGHTTPD_GROUP} pihole
if [ -x "$(command -v lighty-enable-mod)" ]; then
lighty-enable-mod fastcgi fastcgi-php > /dev/null || true
else
printf "\n:::\tWarning: 'lighty-enable-mod' utility not found. Please ensure fastcgi is enabled if you experience issues.\n"
fi
installScripts
installConfigs
CreateLogFile
configureSelinux
installPiholeWeb
installCron
configureFirewall
finalExports
runGravity
}
accountForRefactor() {
# At some point in the future this list can be pruned, for now we'll need it to ensure updates don't break.
# Refactoring of install script has changed the name of a couple of variables. Sort them out here.
sed -i 's/piholeInterface/PIHOLE_INTERFACE/g' ${setupVars}
sed -i 's/IPv4_address/IPV4_ADDRESS/g' ${setupVars}
sed -i 's/IPv4addr/IPV4_ADDRESS/g' ${setupVars}
sed -i 's/IPv6_address/IPV6_ADDRESS/g' ${setupVars}
sed -i 's/piholeIPv6/IPV6_ADDRESS/g' ${setupVars}
sed -i 's/piholeDNS1/PIHOLE_DNS_1/g' ${setupVars}
sed -i 's/piholeDNS2/PIHOLE_DNS_2/g' ${setupVars}
}
updatePihole() {
accountForRefactor
# Source ${setupVars} for use in the rest of the functions.
. ${setupVars}
# Install base files and web interface
installScripts
installConfigs
CreateLogFile
configureSelinux
installPiholeWeb
installCron
configureFirewall
finalExports #re-export setupVars.conf to account for any new vars added in new versions
runGravity
}
configureSelinux() {
if [ -x "$(command -v getenforce)" ]; then
printf "\n::: SELinux Detected\n"
printf ":::\tChecking for SELinux policy development packages..."
package_check_install "selinux-policy-devel" > /dev/null
echo " installed!"
printf ":::\tEnabling httpd server side includes (SSI).. "
setsebool -P httpd_ssi_exec on &> /dev/null && echo "Success" || echo "SELinux not enabled"
printf "\n:::\tCompiling Pi-Hole SELinux policy..\n"
if ! [ -x "$(command -v systemctl)" ]; then
sed -i.bak '/systemd/d' /etc/.pihole/advanced/selinux/pihole.te
fi
checkmodule -M -m -o /etc/pihole/pihole.mod /etc/.pihole/advanced/selinux/pihole.te
semodule_package -o /etc/pihole/pihole.pp -m /etc/pihole/pihole.mod
semodule -i /etc/pihole/pihole.pp
rm -f /etc/pihole/pihole.mod
semodule -l | grep pihole &> /dev/null && echo "::: Installed Pi-Hole SELinux policy" || echo "::: Warning: Pi-Hole SELinux policy did not install."
fi
}
displayFinalMessage() {
if (( ${#1} > 0 )) ; then
# Final completion message to user
whiptail --msgbox --backtitle "Make it so." --title "Installation Complete!" "Configure your devices to use the Pi-hole as their DNS server using:
IPv4: ${IPV4_ADDRESS%/*}
IPv6: ${IPV6_ADDRESS}
If you set a new IP address, you should restart the Pi.
The install log is in /etc/pihole.
View the web interface at http://pi.hole/admin or http://${IPV4_ADDRESS%/*}/admin
The currently set password is ${1}" ${r} ${c}
else
whiptail --msgbox --backtitle "Make it so." --title "Installation Complete!" "Configure your devices to use the Pi-hole as their DNS server using:
IPv4: ${IPV4_ADDRESS%/*}
IPv6: ${IPV6_ADDRESS}
If you set a new IP address, you should restart the Pi.
The install log is in /etc/pihole.
View the web interface at http://pi.hole/admin or http://${IPV4_ADDRESS%/*}/admin" ${r} ${c}
fi
}
update_dialogs() {
# reconfigure
if [ "${reconfigure}" = true ]; then
opt1a="Repair"
opt1b="This will retain existing settings"
strAdd="You will remain on the same version"
else
opt1a="Update"
opt1b="This will retain existing settings."
strAdd="You will be updated to the latest version."
fi
opt2a="Reconfigure"
opt2b="This will allow you to enter new settings"
UpdateCmd=$(whiptail --title "Existing Install Detected!" --menu "\n\nWe have detected an existing install.\n\nPlease choose from the following options: \n($strAdd)" ${r} ${c} 2 \
"${opt1a}" "${opt1b}" \
"${opt2a}" "${opt2b}" 3>&2 2>&1 1>&3)
if [[ $? = 0 ]];then
case ${UpdateCmd} in
${opt1a})
echo "::: ${opt1a} option selected."
useUpdateVars=true
;;
${opt2a})
echo "::: ${opt2a} option selected"
useUpdateVars=false
;;
esac
else
echo "::: Cancel selected. Exiting..."
exit 1
fi
}
main() {
# Check arguments for the undocumented flags
for var in "$@"; do
case "$var" in
"--reconfigure" ) reconfigure=true;;
"--i_do_not_follow_recommendations" ) skipSpaceCheck=false;;
"--unattended" ) runUnattended=true;;
esac
done
if [[ -f ${setupVars} ]]; then
if [[ "${runUnattended}" == true ]]; then
echo "::: --unattended passed to install script, no whiptail dialogs will be displayed"
useUpdateVars=true
else
update_dialogs
fi
fi
# Start the installer
# Verify there is enough disk space for the install
if [[ "${skipSpaceCheck}" == true ]]; then
echo "::: --i_do_not_follow_recommendations passed to script, skipping free disk space verification!"
else
verifyFreeDiskSpace
fi
# Update package cache
update_pacakge_cache
# Notify user of package availability
notify_package_updates_available
# Install packages used by this installation script
install_dependent_packages INSTALLER_DEPS[@]
if [[ "${reconfigure}" == true ]]; then
echo "::: --reconfigure passed to install script. Not downloading/updating local repos"
else
# Get Git files for Core and Admin
getGitFiles ${PI_HOLE_LOCAL_REPO} ${piholeGitUrl}
getGitFiles ${webInterfaceDir} ${webInterfaceGitUrl}
fi
if [[ ${useUpdateVars} == false ]]; then
# Display welcome dialogs
welcomeDialogs
# Create directory for Pi-hole storage
mkdir -p /etc/pihole/
# Remove legacy scripts from previous storage location
remove_legacy_scripts
# Stop resolver and webserver while installing proceses
stop_service dnsmasq
stop_service lighttpd
# Determine available interfaces
get_available_interfaces
# Find interfaces and let the user choose one
chooseInterface
# Let the user decide if they want to block ads over IPv4 and/or IPv6
use4andor6
# Decide what upstream DNS Servers to use
setDNS
# Let the user decide if they want query logging enabled...
setLogging
# Install packages used by the Pi-hole
install_dependent_packages PIHOLE_DEPS[@]
# Install and log everything to a file
installPihole | tee ${tmpLog}
else
# update packages used by the Pi-hole
install_dependent_packages PIHOLE_DEPS[@]
updatePihole | tee ${tmpLog}
fi
# Move the log file into /etc/pihole for storage
mv ${tmpLog} ${instalLogLoc}
# Add password to web UI if there is none
pw=""
if [[ $(grep 'WEBPASSWORD' -c /etc/pihole/setupVars.conf) == 0 ]] ; then
pw=$(tr -dc _A-Z-a-z-0-9 < /dev/urandom | head -c 8)
pihole -a -p ${pw}
fi
if [[ "${useUpdateVars}" == false ]]; then
displayFinalMessage ${pw}
fi
echo "::: Restarting services..."
# Start services
start_service dnsmasq
enable_service dnsmasq
start_service lighttpd
enable_service lighttpd
echo "::: done."
echo ":::"
if [[ "${useUpdateVars}" == false ]]; then
echo "::: Installation Complete! Configure your devices to use the Pi-hole as their DNS server using:"
echo "::: ${IPV4_ADDRESS%/*}"
echo "::: ${IPV6_ADDRESS}"
echo ":::"
echo "::: If you set a new IP address, you should restart the Pi."
echo "::: View the web interface at http://pi.hole/admin or http://${IPV4_ADDRESS%/*}/admin"
else
echo "::: Update complete!"
fi
if (( ${#pw} > 0 )) ; then
echo ":::"
echo "::: Note: As security measure a password has been installed for your web interface"
echo "::: The currently set password is"
echo "::: ${pw}"
echo ":::"
echo "::: You can always change it using"
echo "::: pihole -a -p new_password"
fi
echo ":::"
echo "::: The install log is located at: /etc/pihole/install.log"
}
if [[ "${PH_TEST}" != true ]] ; then
main "$@"
fi
\ No newline at end of file
From 5c43df66a8e94ca08709a322ae8b0dfcb4b9e7e3 Mon Sep 17 00:00:00 2001
From: Dan Schaper
Date: Tue, 20 Dec 2016 15:07:36 -0800
Subject: [PATCH 220/228] Remove spinner function, masked return values.
Signed-off-by: Dan Schaper
---
automated install/basic-install.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/automated install/basic-install.sh b/automated install/basic-install.sh
index 96c8ece3..d96c7547 100755
--- a/automated install/basic-install.sh
+++ b/automated install/basic-install.sh
@@ -1 +1 @@
-#!/usr/bin/env bash
# Pi-hole: A black hole for Internet advertisements
# (c) 2015, 2016 by Jacob Salmela
# Network-wide ad blocking via your Raspberry Pi
# http://pi-hole.net
# Installs Pi-hole
#
# Pi-hole is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 2 of the License, or
# (at your option) any later version.
# pi-hole.net/donate
#
# Install with this command (from your Pi):
#
# curl -L install.pi-hole.net | bash
set -e
######## VARIABLES #########
tmpLog=/tmp/pihole-install.log
instalLogLoc=/etc/pihole/install.log
setupVars=/etc/pihole/setupVars.conf
webInterfaceGitUrl="https://github.com/pi-hole/AdminLTE.git"
webInterfaceDir="/var/www/html/admin"
piholeGitUrl="https://github.com/pi-hole/pi-hole.git"
PI_HOLE_LOCAL_REPO="/etc/.pihole"
PI_HOLE_FILES=(chronometer list piholeDebug piholeLogFlush setupLCD update version)
useUpdateVars=false
IPV4_ADDRESS=""
IPV6_ADDRESS=""
QUERY_LOGGING=true
# Find the rows and columns will default to 80x24 is it can not be detected
screen_size=$(stty size 2>/dev/null || echo 24 80)
rows=$(echo $screen_size | awk '{print $1}')
columns=$(echo $screen_size | awk '{print $2}')
# Divide by two so the dialogs take up half of the screen, which looks nice.
r=$(( rows / 2 ))
c=$(( columns / 2 ))
# Unless the screen is tiny
r=$(( r < 20 ? 20 : r ))
c=$(( c < 70 ? 70 : c ))
######## Undocumented Flags. Shhh ########
skipSpaceCheck=false
reconfigure=false
runUnattended=false
######## FIRST CHECK ########
# Must be root to install
echo ":::"
if [[ ${EUID} -eq 0 ]]; then
echo "::: You are root."
else
echo "::: Script called with non-root privileges. The Pi-hole installs server packages and configures"
echo "::: system networking, it requires elevated rights. Please check the contents of the script for"
echo "::: any concerns with this requirement. Please be sure to download this script from a trusted source."
echo ":::"
echo "::: Detecting the presence of the sudo utility for continuation of this install..."
if [ -x "$(command -v sudo)" ]; then
echo "::: Utility sudo located."
exec curl -sSL https://install.pi-hole.net | sudo bash "$@"
exit $?
else
echo "::: sudo is needed for the Web interface to run pihole commands. Please run this script as root and it will be automatically installed."
exit 1
fi
fi
# Compatibility
if [[ $(command -v apt-get) ]]; then
#Debian Family
#############################################
PKG_MANAGER="apt-get"
PKG_CACHE="/var/lib/apt/lists/"
UPDATE_PKG_CACHE="${PKG_MANAGER} update"
PKG_UPDATE="${PKG_MANAGER} upgrade"
PKG_INSTALL="${PKG_MANAGER} --yes --fix-missing install"
# grep -c will return 1 retVal on 0 matches, block this throwing the set -e with an OR TRUE
PKG_COUNT="${PKG_MANAGER} -s -o Debug::NoLocking=true upgrade | grep -c ^Inst || true"
# #########################################
# fixes for dependancy differences
# Debian 7 doesn't have iproute2 use iproute
${PKG_MANAGER} install --dry-run iproute2 > /dev/null 2>&1 && IPROUTE_PKG="iproute2" || IPROUTE_PKG="iproute"
# Prefer the php metapackage if it's there, fall back on the php5 pacakges
${PKG_MANAGER} install --dry-run php > /dev/null 2>&1 && phpVer="php" || phpVer="php5"
# #########################################
INSTALLER_DEPS=( apt-utils whiptail git dhcpcd5)
PIHOLE_DEPS=( iputils-ping lsof dnsutils bc dnsmasq lighttpd ${phpVer}-common ${phpVer}-cgi curl unzip wget sudo netcat cron ${IPROUTE_PKG} )
LIGHTTPD_USER="www-data"
LIGHTTPD_GROUP="www-data"
LIGHTTPD_CFG="lighttpd.conf.debian"
DNSMASQ_USER="dnsmasq"
package_check_install() {
dpkg-query -W -f='${Status}' "${1}" 2>/dev/null | grep -c "ok installed" || ${PKG_INSTALL} "${1}"
}
elif [ $(command -v rpm) ]; then
# Fedora Family
if [ $(command -v dnf) ]; then
PKG_MANAGER="dnf"
else
PKG_MANAGER="yum"
fi
PKG_CACHE="/var/cache/${PKG_MANAGER}"
UPDATE_PKG_CACHE="${PKG_MANAGER} check-update"
PKG_UPDATE="${PKG_MANAGER} update -y"
PKG_INSTALL="${PKG_MANAGER} install -y"
PKG_COUNT="${PKG_MANAGER} check-update | egrep '(.i686|.x86|.noarch|.arm|.src)' | wc -l"
INSTALLER_DEPS=( iproute net-tools procps-ng newt git )
PIHOLE_DEPS=( epel-release bind-utils bc dnsmasq lighttpd lighttpd-fastcgi php-common php-cli php curl unzip wget findutils cronie sudo nmap-ncat )
if grep -q 'Fedora' /etc/redhat-release; then
remove_deps=(epel-release);
PIHOLE_DEPS=( ${PIHOLE_DEPS[@]/$remove_deps} );
fi
LIGHTTPD_USER="lighttpd"
LIGHTTPD_GROUP="lighttpd"
LIGHTTPD_CFG="lighttpd.conf.fedora"
DNSMASQ_USER="nobody"
package_check_install() {
rpm -qa | grep ^"${1}"- > /dev/null || ${PKG_INSTALL} "${1}"
}
else
echo "OS distribution not supported"
exit
fi
####### FUNCTIONS ##########
spinner() {
local pid=$1
local delay=0.50
local spinstr='/-\|'
while [ "$(ps a | awk '{print $1}' | grep "${pid}")" ]; do
local temp=${spinstr#?}
printf " [%c] " "${spinstr}"
local spinstr=${temp}${spinstr%"$temp"}
sleep ${delay}
printf "\b\b\b\b\b\b"
done
printf " \b\b\b\b"
}
is_repo() {
# Use git to check if directory is currently under VCS, return the value
local directory="${1}"
git -C "${directory}" status --short &> /dev/null
return
}
make_repo() {
local directory="${1}"
local remoteRepo="${2}"
# Remove the non-repod interface and clone the interface
echo -n "::: Cloning $remoteRepo into $directory..."
rm -rf "${directory}"
git clone -q --depth 1 "${remoteRepo}" "${directory}" > /dev/null & spinner $!
echo " done!"
}
update_repo() {
local directory="${1}"
# Pull the latest commits
echo -n "::: Updating repo in $1..."
cd "${directory}" || exit 1
git stash -q > /dev/null & spinner $!
git pull -q > /dev/null & spinner $!
echo " done!"
}
getGitFiles() {
# Setup git repos for directory and repository passed
# as arguments 1 and 2
local directory="${1}"
local remoteRepo="${2}"
echo ":::"
echo "::: Checking for existing repository..."
if is_repo "${directory}"; then
update_repo "${directory}"
else
make_repo "${directory}" "${remoteRepo}"
fi
}
find_IPv4_information() {
# Find IP used to route to outside world
IPv4dev=$(ip route get 8.8.8.8 | awk '{for(i=1;i<=NF;i++)if($i~/dev/)print $(i+1)}')
IPV4_ADDRESS=$(ip -o -f inet addr show dev "$IPv4dev" | awk '{print $4}' | awk 'END {print}')
IPv4gw=$(ip route get 8.8.8.8 | awk '{print $3}')
}
get_available_interfaces() {
# Get available interfaces. Consider only getting UP interfaces in the future, and leaving DOWN interfaces out of list.
availableInterfaces=$(ip -o link | awk '{print $2}' | grep -v "lo" | cut -d':' -f1 | cut -d'@' -f1)
}
welcomeDialogs() {
# Display the welcome dialog
whiptail --msgbox --backtitle "Welcome" --title "Pi-hole automated installer" "\n\nThis installer will transform your device into a network-wide ad blocker!" ${r} ${c}
# Support for a part-time dev
whiptail --msgbox --backtitle "Plea" --title "Free and open source" "\n\nThe Pi-hole is free, but powered by your donations: http://pi-hole.net/donate" ${r} ${c}
# Explain the need for a static address
whiptail --msgbox --backtitle "Initiating network interface" --title "Static IP Needed" "\n\nThe Pi-hole is a SERVER so it needs a STATIC IP ADDRESS to function properly.
In the next section, you can choose to use your current network settings (DHCP) or to manually edit them." ${r} ${c}
}
verifyFreeDiskSpace() {
# 50MB is the minimum space needed (45MB install (includes web admin bootstrap/jquery libraries etc) + 5MB one day of logs.)
# - Fourdee: Local ensures the variable is only created, and accessible within this function/void. Generally considered a "good" coding practice for non-global variables.
echo "::: Verifying free disk space..."
local required_free_kilobytes=51200
local existing_free_kilobytes=$(df -Pk | grep -m1 '\/$' | awk '{print $4}')
# - Unknown free disk space , not a integer
if ! [[ "${existing_free_kilobytes}" =~ ^([0-9])+$ ]]; then
echo "::: Unknown free disk space!"
echo "::: We were unable to determine available free disk space on this system."
echo "::: You may override this check and force the installation, however, it is not recommended"
echo "::: To do so, pass the argument '--i_do_not_follow_recommendations' to the install script"
echo "::: eg. curl -L https://install.pi-hole.net | bash /dev/stdin --i_do_not_follow_recommendations"
exit 1
# - Insufficient free disk space
elif [[ ${existing_free_kilobytes} -lt ${required_free_kilobytes} ]]; then
echo "::: Insufficient Disk Space!"
echo "::: Your system appears to be low on disk space. pi-hole recommends a minimum of $required_free_kilobytes KiloBytes."
echo "::: You only have ${existing_free_kilobytes} KiloBytes free."
echo "::: If this is a new install you may need to expand your disk."
echo "::: Try running 'sudo raspi-config', and choose the 'expand file system option'"
echo "::: After rebooting, run this installation again. (curl -L https://install.pi-hole.net | bash)"
echo "Insufficient free space, exiting..."
exit 1
fi
}
chooseInterface() {
# Turn the available interfaces into an array so it can be used with a whiptail dialog
local interfacesArray=()
# Number of available interfaces
local interfaceCount
# Whiptail variable storage
local chooseInterfaceCmd
# Temporary Whiptail options storage
local chooseInterfaceOptions
# Loop sentinel variable
local firstLoop=1
while read -r line; do
mode="OFF"
if [[ ${firstLoop} -eq 1 ]]; then
firstLoop=0
mode="ON"
fi
interfacesArray+=("${line}" "available" "${mode}")
done <<< "${availableInterfaces}"
# Find out how many interfaces are available to choose from
interfaceCount=$(echo "${availableInterfaces}" | wc -l)
chooseInterfaceCmd=(whiptail --separate-output --radiolist "Choose An Interface (press space to select)" ${r} ${c} ${interfaceCount})
chooseInterfaceOptions=$("${chooseInterfaceCmd[@]}" "${interfacesArray[@]}" 2>&1 >/dev/tty)
if [[ $? = 0 ]]; then
for desiredInterface in ${chooseInterfaceOptions}; do
PIHOLE_INTERFACE=${desiredInterface}
echo "::: Using interface: $PIHOLE_INTERFACE"
done
else
echo "::: Cancel selected, exiting...."
exit 1
fi
}
useIPv6dialog() {
# Show the IPv6 address used for blocking
IPV6_ADDRESS=$(ip -6 route get 2001:4860:4860::8888 | awk -F " " '{ for(i=1;i<=NF;i++) if ($i == "src") print $(i+1) }')
whiptail --msgbox --backtitle "IPv6..." --title "IPv6 Supported" "$IPV6_ADDRESS will be used to block ads." ${r} ${c}
}
use4andor6() {
local useIPv4
local useIPv6
# Let use select IPv4 and/or IPv6
cmd=(whiptail --separate-output --checklist "Select Protocols (press space to select)" ${r} ${c} 2)
options=(IPv4 "Block ads over IPv4" on
IPv6 "Block ads over IPv6" on)
choices=$("${cmd[@]}" "${options[@]}" 2>&1 >/dev/tty)
if [[ $? = 0 ]];then
for choice in ${choices}
do
case ${choice} in
IPv4 ) useIPv4=true;;
IPv6 ) useIPv6=true;;
esac
done
if [[ ${useIPv4} ]]; then
find_IPv4_information
getStaticIPv4Settings
setStaticIPv4
fi
if [[ ${useIPv6} ]]; then
useIPv6dialog
fi
echo "::: IPv4 address: ${IPV4_ADDRESS}"
echo "::: IPv6 address: ${IPV6_ADDRESS}"
if [ ! ${useIPv4} ] && [ ! ${useIPv6} ]; then
echo "::: Cannot continue, neither IPv4 or IPv6 selected"
echo "::: Exiting"
exit 1
fi
else
echo "::: Cancel selected. Exiting..."
exit 1
fi
}
getStaticIPv4Settings() {
# Ask if the user wants to use DHCP settings as their static IP
if (whiptail --backtitle "Calibrating network interface" --title "Static IP Address" --yesno "Do you want to use your current network settings as a static address?
IP address: ${IPV4_ADDRESS}
Gateway: ${IPv4gw}" ${r} ${c}); then
# If they choose yes, let the user know that the IP address will not be available via DHCP and may cause a conflict.
whiptail --msgbox --backtitle "IP information" --title "FYI: IP Conflict" "It is possible your router could still try to assign this IP to a device, which would cause a conflict. But in most cases the router is smart enough to not do that.
If you are worried, either manually set the address, or modify the DHCP reservation pool so it does not include the IP you want.
It is also possible to use a DHCP reservation, but if you are going to do that, you might as well set a static address." ${r} ${c}
# Nothing else to do since the variables are already set above
else
# Otherwise, we need to ask the user to input their desired settings.
# Start by getting the IPv4 address (pre-filling it with info gathered from DHCP)
# Start a loop to let the user enter their information with the chance to go back and edit it if necessary
until [[ ${ipSettingsCorrect} = True ]]; do
# Ask for the IPv4 address
IPV4_ADDRESS=$(whiptail --backtitle "Calibrating network interface" --title "IPv4 address" --inputbox "Enter your desired IPv4 address" ${r} ${c} "${IPV4_ADDRESS}" 3>&1 1>&2 2>&3)
if [[ $? = 0 ]]; then
echo "::: Your static IPv4 address: ${IPV4_ADDRESS}"
# Ask for the gateway
IPv4gw=$(whiptail --backtitle "Calibrating network interface" --title "IPv4 gateway (router)" --inputbox "Enter your desired IPv4 default gateway" ${r} ${c} "${IPv4gw}" 3>&1 1>&2 2>&3)
if [[ $? = 0 ]]; then
echo "::: Your static IPv4 gateway: ${IPv4gw}"
# Give the user a chance to review their settings before moving on
if (whiptail --backtitle "Calibrating network interface" --title "Static IP Address" --yesno "Are these settings correct?
IP address: ${IPV4_ADDRESS}
Gateway: ${IPv4gw}" ${r} ${c}); then
# After that's done, the loop ends and we move on
ipSettingsCorrect=True
else
# If the settings are wrong, the loop continues
ipSettingsCorrect=False
fi
else
# Cancelling gateway settings window
ipSettingsCorrect=False
echo "::: Cancel selected. Exiting..."
exit 1
fi
else
# Cancelling IPv4 settings window
ipSettingsCorrect=False
echo "::: Cancel selected. Exiting..."
exit 1
fi
done
# End the if statement for DHCP vs. static
fi
}
setDHCPCD() {
# Append these lines to dhcpcd.conf to enable a static IP
echo "## interface ${PIHOLE_INTERFACE}
static ip_address=${IPV4_ADDRESS}
static routers=${IPv4gw}
static domain_name_servers=${IPv4gw}" | tee -a /etc/dhcpcd.conf >/dev/null
}
setStaticIPv4() {
local IFCFG_FILE
local IPADDR
local CIDR
if [[ -f /etc/dhcpcd.conf ]]; then
# Debian Family
if grep -q "${IPV4_ADDRESS}" /etc/dhcpcd.conf; then
echo "::: Static IP already configured"
else
setDHCPCD
ip addr replace dev "${PIHOLE_INTERFACE}" "${IPV4_ADDRESS}"
echo ":::"
echo "::: Setting IP to ${IPV4_ADDRESS}. You may need to restart after the install is complete."
echo ":::"
fi
elif [[ -f /etc/sysconfig/network-scripts/ifcfg-${PIHOLE_INTERFACE} ]];then
# Fedora Family
IFCFG_FILE=/etc/sysconfig/network-scripts/ifcfg-${PIHOLE_INTERFACE}
if grep -q "${IPV4_ADDRESS}" "${IFCFG_FILE}"; then
echo "::: Static IP already configured"
else
IPADDR=$(echo "${IPV4_ADDRESS}" | cut -f1 -d/)
CIDR=$(echo "${IPV4_ADDRESS}" | cut -f2 -d/)
# Backup existing interface configuration:
cp "${IFCFG_FILE}" "${IFCFG_FILE}".pihole.orig
# Build Interface configuration file:
{
echo "# Configured via Pi-Hole installer"
echo "DEVICE=$PIHOLE_INTERFACE"
echo "BOOTPROTO=none"
echo "ONBOOT=yes"
echo "IPADDR=$IPADDR"
echo "PREFIX=$CIDR"
echo "GATEWAY=$IPv4gw"
echo "DNS1=$PIHOLE_DNS_1"
echo "DNS2=$PIHOLE_DNS_2"
echo "USERCTL=no"
}> "${IFCFG_FILE}"
ip addr replace dev "${PIHOLE_INTERFACE}" "${IPV4_ADDRESS}"
if [ -x "$(command -v nmcli)" ];then
# Tell NetworkManager to read our new sysconfig file
nmcli con load "${IFCFG_FILE}" > /dev/null
fi
echo ":::"
echo "::: Setting IP to ${IPV4_ADDRESS}. You may need to restart after the install is complete."
echo ":::"
fi
else
echo "::: Warning: Unable to locate configuration file to set static IPv4 address!"
exit 1
fi
}
valid_ip() {
local ip=${1}
local stat=1
if [[ ${ip} =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then
OIFS=$IFS
IFS='.'
ip=(${ip})
IFS=${OIFS}
[[ ${ip[0]} -le 255 && ${ip[1]} -le 255 \
&& ${ip[2]} -le 255 && ${ip[3]} -le 255 ]]
stat=$?
fi
return ${stat}
}
setDNS() {
DNSChooseCmd=(whiptail --separate-output --radiolist "Select Upstream DNS Provider. To use your own, select Custom." ${r} ${c} 6)
DNSChooseOptions=(Google "" on
OpenDNS "" off
Level3 "" off
Norton "" off
Comodo "" off
Custom "" off)
DNSchoices=$("${DNSChooseCmd[@]}" "${DNSChooseOptions[@]}" 2>&1 >/dev/tty)
if [[ $? = 0 ]];then
case ${DNSchoices} in
Google)
echo "::: Using Google DNS servers."
PIHOLE_DNS_1="8.8.8.8"
PIHOLE_DNS_2="8.8.4.4"
;;
OpenDNS)
echo "::: Using OpenDNS servers."
PIHOLE_DNS_1="208.67.222.222"
PIHOLE_DNS_2="208.67.220.220"
;;
Level3)
echo "::: Using Level3 servers."
PIHOLE_DNS_1="4.2.2.1"
PIHOLE_DNS_2="4.2.2.2"
;;
Norton)
echo "::: Using Norton ConnectSafe servers."
PIHOLE_DNS_1="199.85.126.10"
PIHOLE_DNS_2="199.85.127.10"
;;
Comodo)
echo "::: Using Comodo Secure servers."
PIHOLE_DNS_1="8.26.56.26"
PIHOLE_DNS_2="8.20.247.20"
;;
Custom)
until [[ ${DNSSettingsCorrect} = True ]]; do
strInvalid="Invalid"
if [ ! ${PIHOLE_DNS_1} ]; then
if [ ! ${PIHOLE_DNS_2} ]; then
prePopulate=""
else
prePopulate=", ${PIHOLE_DNS_2}"
fi
elif [ ${PIHOLE_DNS_1} ] && [ ! ${PIHOLE_DNS_2} ]; then
prePopulate="${PIHOLE_DNS_1}"
elif [ ${PIHOLE_DNS_1} ] && [ ${PIHOLE_DNS_2} ]; then
prePopulate="${PIHOLE_DNS_1}, ${PIHOLE_DNS_2}"
fi
piholeDNS=$(whiptail --backtitle "Specify Upstream DNS Provider(s)" --inputbox "Enter your desired upstream DNS provider(s), seperated by a comma.\n\nFor example '8.8.8.8, 8.8.4.4'" ${r} ${c} "${prePopulate}" 3>&1 1>&2 2>&3)
if [[ $? = 0 ]]; then
PIHOLE_DNS_1=$(echo "${piholeDNS}" | sed 's/[, \t]\+/,/g' | awk -F, '{print$1}')
PIHOLE_DNS_2=$(echo "${piholeDNS}" | sed 's/[, \t]\+/,/g' | awk -F, '{print$2}')
if ! valid_ip "${PIHOLE_DNS_1}" || [ ! "${PIHOLE_DNS_1}" ]; then
PIHOLE_DNS_1=${strInvalid}
fi
if ! valid_ip "${PIHOLE_DNS_2}" && [ "${PIHOLE_DNS_2}" ]; then
PIHOLE_DNS_2=${strInvalid}
fi
else
echo "::: Cancel selected, exiting...."
exit 1
fi
if [[ ${PIHOLE_DNS_1} == "${strInvalid}" ]] || [[ ${PIHOLE_DNS_2} == "${strInvalid}" ]]; then
whiptail --msgbox --backtitle "Invalid IP" --title "Invalid IP" "One or both entered IP addresses were invalid. Please try again.\n\n DNS Server 1: $PIHOLE_DNS_1\n DNS Server 2: ${PIHOLE_DNS_2}" ${r} ${c}
if [[ ${PIHOLE_DNS_1} == "${strInvalid}" ]]; then
PIHOLE_DNS_1=""
fi
if [[ ${PIHOLE_DNS_2} == "${strInvalid}" ]]; then
PIHOLE_DNS_2=""
fi
DNSSettingsCorrect=False
else
if (whiptail --backtitle "Specify Upstream DNS Provider(s)" --title "Upstream DNS Provider(s)" --yesno "Are these settings correct?\n DNS Server 1: $PIHOLE_DNS_1\n DNS Server 2: ${PIHOLE_DNS_2}" ${r} ${c}); then
DNSSettingsCorrect=True
else
# If the settings are wrong, the loop continues
DNSSettingsCorrect=False
fi
fi
done
;;
esac
else
echo "::: Cancel selected. Exiting..."
exit 1
fi
}
setLogging() {
local LogToggleCommand
local LogChooseOptions
local LogChoices
LogToggleCommand=(whiptail --separate-output --radiolist "Do you want to log queries?\n (Disabling will render graphs on the Admin page useless):" ${r} ${c} 6)
LogChooseOptions=("On (Reccomended)" "" on
Off "" off)
LogChoices=$("${LogToggleCommand[@]}" "${LogChooseOptions[@]}" 2>&1 >/dev/tty) || (echo "::: Cancel selected. Exiting..." && exit 1)
case ${LogChoices} in
"On (Recommended)")
echo "::: Logging On."
QUERY_LOGGING=true
;;
Off)
echo "::: Logging Off."
QUERY_LOGGING=false
;;
esac
}
version_check_dnsmasq() {
# Check if /etc/dnsmasq.conf is from pihole. If so replace with an original and install new in .d directory
local dnsmasq_conf="/etc/dnsmasq.conf"
local dnsmasq_conf_orig="/etc/dnsmasq.conf.orig"
local dnsmasq_pihole_id_string="addn-hosts=/etc/pihole/gravity.list"
local dnsmasq_original_config="/etc/.pihole/advanced/dnsmasq.conf.original"
local dnsmasq_pihole_01_snippet="/etc/.pihole/advanced/01-pihole.conf"
local dnsmasq_pihole_01_location="/etc/dnsmasq.d/01-pihole.conf"
if [ -f ${dnsmasq_conf} ]; then
echo -n "::: Existing dnsmasq.conf found..."
if grep -q ${dnsmasq_pihole_id_string} ${dnsmasq_conf}; then
echo " it is from a previous pi-hole install."
echo -n "::: Backing up dnsmasq.conf to dnsmasq.conf.orig..."
mv -f ${dnsmasq_conf} ${dnsmasq_conf_orig}
echo " done."
echo -n "::: Restoring default dnsmasq.conf..."
cp ${dnsmasq_original_config} ${dnsmasq_conf}
echo " done."
else
echo " it is not a pi-hole file, leaving alone!"
fi
else
echo -n "::: No dnsmasq.conf found.. restoring default dnsmasq.conf..."
cp ${dnsmasq_original_config} ${dnsmasq_conf}
echo " done."
fi
echo -n "::: Copying 01-pihole.conf to /etc/dnsmasq.d/01-pihole.conf..."
cp ${dnsmasq_pihole_01_snippet} ${dnsmasq_pihole_01_location}
echo " done."
sed -i "s/@INT@/$PIHOLE_INTERFACE/" ${dnsmasq_pihole_01_location}
if [[ "${PIHOLE_DNS_1}" != "" ]]; then
sed -i "s/@DNS1@/$PIHOLE_DNS_1/" ${dnsmasq_pihole_01_location}
else
sed -i '/^server=@DNS1@/d' ${dnsmasq_pihole_01_location}
fi
if [[ "${PIHOLE_DNS_2}" != "" ]]; then
sed -i "s/@DNS2@/$PIHOLE_DNS_2/" ${dnsmasq_pihole_01_location}
else
sed -i '/^server=@DNS2@/d' ${dnsmasq_pihole_01_location}
fi
sed -i 's/^#conf-dir=\/etc\/dnsmasq.d$/conf-dir=\/etc\/dnsmasq.d/' ${dnsmasq_conf}
if [[ "${QUERY_LOGGING}" == false ]] ; then
#Disable Logging
sed -i 's/^log-queries/#log-queries/' ${dnsmasq_pihole_01_location}
else
#Enable Logging
sed -i 's/^#log-queries/log-queries/' ${dnsmasq_pihole_01_location}
fi
}
remove_legacy_scripts() {
#Tidy up /usr/local/bin directory if installing over previous install.
oldFiles=( gravity chronometer whitelist blacklist piholeLogFlush updateDashboard uninstall setupLCD piholeDebug)
for i in "${oldFiles[@]}"; do
if [ -f "/usr/local/bin/$i.sh" ]; then
rm /usr/local/bin/"$i".sh
fi
done
}
clean_existing() {
# Clean an exiting installation to prepare for upgrade/reinstall
# ${1} Directory to clean; ${2} Array of files to remove
local clean_directory="${1}"
local old_files=${2}
for script in "${old_files[@]}"; do
rm -f "${clean_directory}${script}.sh"
done
}
installScripts() {
# Install the scripts from repository to their various locations
readonly install_dir="/opt/pihole/"
echo ":::"
echo -n "::: Installing scripts from ${PI_HOLE_LOCAL_REPO}..."
# Clear out script files from Pi-hole scripts directory.
clean_existing "${install_dir}" "${PI_HOLE_FILES}"
# Install files from local core repository
if is_repo "${PI_HOLE_LOCAL_REPO}"; then
cd "${PI_HOLE_LOCAL_REPO}"
install -o "${USER}" -Dm755 -t /opt/pihole/ gravity.sh
install -o "${USER}" -Dm755 -t /opt/pihole/ ./advanced/Scripts/*.sh
install -o "${USER}" -Dm755 -t /opt/pihole/ ./automated\ install/uninstall.sh
install -o "${USER}" -Dm755 -t /usr/local/bin/ pihole
install -Dm644 ./advanced/bash-completion/pihole /etc/bash_completion.d/pihole
echo " done."
else
echo " *** ERROR: Local repo ${core_repo} not found, exiting."
exit 1
fi
}
installConfigs() {
# Install the configs from /etc/.pihole to their various locations
echo ":::"
echo "::: Installing configs..."
version_check_dnsmasq
if [ ! -d "/etc/lighttpd" ]; then
mkdir /etc/lighttpd
chown "${USER}":root /etc/lighttpd
elif [ -f "/etc/lighttpd/lighttpd.conf" ]; then
mv /etc/lighttpd/lighttpd.conf /etc/lighttpd/lighttpd.conf.orig
fi
cp /etc/.pihole/advanced/${LIGHTTPD_CFG} /etc/lighttpd/lighttpd.conf
mkdir -p /var/run/lighttpd
chown ${LIGHTTPD_USER}:${LIGHTTPD_GROUP} /var/run/lighttpd
mkdir -p /var/cache/lighttpd/compress
chown ${LIGHTTPD_USER}:${LIGHTTPD_GROUP} /var/cache/lighttpd/compress
mkdir -p /var/cache/lighttpd/uploads
chown ${LIGHTTPD_USER}:${LIGHTTPD_GROUP} /var/cache/lighttpd/uploads
}
stop_service() {
# Stop service passed in as argument.
# Can softfail, as process may not be installed when this is called
echo ":::"
echo -n "::: Stopping ${1} service..."
if [ -x "$(command -v systemctl)" ]; then
systemctl stop "${1}" &> /dev/null & spinner $! || true
else
service "${1}" stop &> /dev/null & spinner $! || true
fi
echo " done."
}
start_service() {
# Start/Restart service passed in as argument
# This should not fail, it's an error if it does
echo ":::"
echo -n "::: Starting ${1} service..."
if [ -x "$(command -v systemctl)" ]; then
systemctl restart "${1}" &> /dev/null & spinner $!
else
service "${1}" restart &> /dev/null & spinner $!
fi
echo " done."
}
enable_service() {
# Enable service so that it will start with next reboot
echo ":::"
echo -n "::: Enabling ${1} service to start on reboot..."
if [ -x "$(command -v systemctl)" ]; then
systemctl enable "${1}" &> /dev/null & spinner $!
else
update-rc.d "${1}" defaults &> /dev/null & spinner $!
fi
echo " done."
}
update_pacakge_cache() {
#Running apt-get update/upgrade with minimal output can cause some issues with
#requiring user input (e.g password for phpmyadmin see #218)
#Check to see if apt-get update has already been run today
#it needs to have been run at least once on new installs!
timestamp=$(stat -c %Y ${PKG_CACHE})
timestampAsDate=$(date -d @"${timestamp}" "+%b %e")
today=$(date "+%b %e")
if [ ! "${today}" == "${timestampAsDate}" ]; then
#update package lists
echo ":::"
echo -n "::: ${PKG_MANAGER} update has not been run today. Running now..."
${UPDATE_PKG_CACHE} &> /dev/null & spinner $!
echo " done!"
fi
}
notify_package_updates_available() {
# Let user know if they have outdated packages on their system and
# advise them to run a package update at soonest possible.
echo ":::"
echo -n "::: Checking ${PKG_MANAGER} for upgraded packages...."
updatesToInstall=$(eval "${PKG_COUNT}")
echo " done!"
echo ":::"
if [[ ${updatesToInstall} -eq "0" ]]; then
echo "::: Your system is up to date! Continuing with Pi-hole installation..."
else
echo "::: There are ${updatesToInstall} updates available for your system!"
echo "::: We recommend you run '${PKG_UPDATE}' after installing Pi-Hole! "
echo ":::"
fi
}
install_dependent_packages() {
# Install packages passed in via argument array
# No spinner - conflicts with set -e
declare -a argArray1=("${!1}")
for i in "${argArray1[@]}"; do
echo -n "::: Checking for $i..."
package_check_install "${i}" &> /dev/null
echo " installed!"
done
}
CreateLogFile() {
# Create logfiles if necessary
echo ":::"
echo -n "::: Creating log file and changing owner to dnsmasq..."
if [ ! -f /var/log/pihole.log ]; then
touch /var/log/pihole.log
chmod 644 /var/log/pihole.log
chown "${DNSMASQ_USER}":root /var/log/pihole.log
echo " done!"
else
echo " already exists!"
fi
}
installPiholeWeb() {
# Install the web interface
echo ":::"
echo "::: Installing pihole custom index page..."
if [ -d "/var/www/html/pihole" ]; then
if [ -f "/var/www/html/pihole/index.html" ]; then
echo "::: Existing index.html detected, not overwriting"
else
echo -n "::: index.html missing, replacing... "
cp /etc/.pihole/advanced/index.html /var/www/html/pihole/
echo " done!"
fi
if [ -f "/var/www/html/pihole/index.js" ]; then
echo "::: Existing index.js detected, not overwriting"
else
echo -n "::: index.js missing, replacing... "
cp /etc/.pihole/advanced/index.js /var/www/html/pihole/
echo " done!"
fi
else
mkdir /var/www/html/pihole
if [ -f /var/www/html/index.lighttpd.html ]; then
mv /var/www/html/index.lighttpd.html /var/www/html/index.lighttpd.orig
else
printf "\n:::\tNo default index.lighttpd.html file found... not backing up"
fi
cp /etc/.pihole/advanced/index.* /var/www/html/pihole/.
echo " done!"
fi
# Install Sudoer file
echo ":::"
echo -n "::: Installing sudoer file..."
mkdir -p /etc/sudoers.d/
cp /etc/.pihole/advanced/pihole.sudo /etc/sudoers.d/pihole
chmod 0440 /etc/sudoers.d/pihole
echo " done!"
}
installCron() {
# Install the cron job
echo ":::"
echo -n "::: Installing latest Cron script..."
cp /etc/.pihole/advanced/pihole.cron /etc/cron.d/pihole
echo " done!"
}
runGravity() {
# Run gravity.sh to build blacklists
echo ":::"
echo "::: Preparing to run gravity.sh to refresh hosts..."
if ls /etc/pihole/list* 1> /dev/null 2>&1; then
echo "::: Cleaning up previous install (preserving whitelist/blacklist)"
rm /etc/pihole/list.*
fi
echo "::: Running gravity.sh"
/opt/pihole/gravity.sh
}
create_pihole_user() {
# Check if user pihole exists and create if not
echo "::: Checking if user 'pihole' exists..."
id -u pihole &> /dev/null && echo "::: User 'pihole' already exists" || (echo "::: User 'pihole' doesn't exist. Creating..." && useradd -r -s /usr/sbin/nologin pihole)
}
configureFirewall() {
# Allow HTTP and DNS traffic
if [ -x "$(command -v firewall-cmd)" ]; then
firewall-cmd --state &> /dev/null && ( echo "::: Configuring firewalld for httpd and dnsmasq.." && firewall-cmd --permanent --add-port=80/tcp && firewall-cmd --permanent --add-port=53/tcp \
&& firewall-cmd --permanent --add-port=53/udp && firewall-cmd --reload) || echo "::: FirewallD not enabled"
elif [ -x "$(command -v iptables)" ]; then
echo "::: Configuring iptables for httpd and dnsmasq.."
iptables -A INPUT -p tcp -m tcp --dport 80 -j ACCEPT
iptables -A INPUT -p tcp -m tcp --dport 53 -j ACCEPT
iptables -A INPUT -p udp -m udp --dport 53 -j ACCEPT
else
echo "::: No firewall detected.. skipping firewall configuration."
fi
}
finalExports() {
# Update variables in setupVars.conf file
if [ -e "${setupVars}" ]; then
sed -i.update.bak '/PIHOLE_INTERFACE/d;/IPV4_ADDRESS/d;/IPV6_ADDRESS/d;/PIHOLE_DNS_1/d;/PIHOLE_DNS_2/d;/QUERY_LOGGING/d;' "${setupVars}"
fi
{
echo "PIHOLE_INTERFACE=${PIHOLE_INTERFACE}"
echo "IPV4_ADDRESS=${IPV4_ADDRESS}"
echo "IPV6_ADDRESS=${IPV6_ADDRESS}"
echo "PIHOLE_DNS_1=${PIHOLE_DNS_1}"
echo "PIHOLE_DNS_2=${PIHOLE_DNS_2}"
echo "QUERY_LOGGING=${QUERY_LOGGING}"
}>> "${setupVars}"
}
installPihole() {
# Install base files and web interface
create_pihole_user
if [ ! -d "/var/www/html" ]; then
mkdir -p /var/www/html
fi
chown ${LIGHTTPD_USER}:${LIGHTTPD_GROUP} /var/www/html
chmod 775 /var/www/html
usermod -a -G ${LIGHTTPD_GROUP} pihole
if [ -x "$(command -v lighty-enable-mod)" ]; then
lighty-enable-mod fastcgi fastcgi-php > /dev/null || true
else
printf "\n:::\tWarning: 'lighty-enable-mod' utility not found. Please ensure fastcgi is enabled if you experience issues.\n"
fi
installScripts
installConfigs
CreateLogFile
configureSelinux
installPiholeWeb
installCron
configureFirewall
finalExports
runGravity
}
accountForRefactor() {
# At some point in the future this list can be pruned, for now we'll need it to ensure updates don't break.
# Refactoring of install script has changed the name of a couple of variables. Sort them out here.
sed -i 's/piholeInterface/PIHOLE_INTERFACE/g' ${setupVars}
sed -i 's/IPv4_address/IPV4_ADDRESS/g' ${setupVars}
sed -i 's/IPv4addr/IPV4_ADDRESS/g' ${setupVars}
sed -i 's/IPv6_address/IPV6_ADDRESS/g' ${setupVars}
sed -i 's/piholeIPv6/IPV6_ADDRESS/g' ${setupVars}
sed -i 's/piholeDNS1/PIHOLE_DNS_1/g' ${setupVars}
sed -i 's/piholeDNS2/PIHOLE_DNS_2/g' ${setupVars}
}
updatePihole() {
accountForRefactor
# Source ${setupVars} for use in the rest of the functions.
. ${setupVars}
# Install base files and web interface
installScripts
installConfigs
CreateLogFile
configureSelinux
installPiholeWeb
installCron
configureFirewall
finalExports #re-export setupVars.conf to account for any new vars added in new versions
runGravity
}
configureSelinux() {
if [ -x "$(command -v getenforce)" ]; then
printf "\n::: SELinux Detected\n"
printf ":::\tChecking for SELinux policy development packages..."
package_check_install "selinux-policy-devel" > /dev/null
echo " installed!"
printf ":::\tEnabling httpd server side includes (SSI).. "
setsebool -P httpd_ssi_exec on &> /dev/null && echo "Success" || echo "SELinux not enabled"
printf "\n:::\tCompiling Pi-Hole SELinux policy..\n"
if ! [ -x "$(command -v systemctl)" ]; then
sed -i.bak '/systemd/d' /etc/.pihole/advanced/selinux/pihole.te
fi
checkmodule -M -m -o /etc/pihole/pihole.mod /etc/.pihole/advanced/selinux/pihole.te
semodule_package -o /etc/pihole/pihole.pp -m /etc/pihole/pihole.mod
semodule -i /etc/pihole/pihole.pp
rm -f /etc/pihole/pihole.mod
semodule -l | grep pihole &> /dev/null && echo "::: Installed Pi-Hole SELinux policy" || echo "::: Warning: Pi-Hole SELinux policy did not install."
fi
}
displayFinalMessage() {
if (( ${#1} > 0 )) ; then
# Final completion message to user
whiptail --msgbox --backtitle "Make it so." --title "Installation Complete!" "Configure your devices to use the Pi-hole as their DNS server using:
IPv4: ${IPV4_ADDRESS%/*}
IPv6: ${IPV6_ADDRESS}
If you set a new IP address, you should restart the Pi.
The install log is in /etc/pihole.
View the web interface at http://pi.hole/admin or http://${IPV4_ADDRESS%/*}/admin
The currently set password is ${1}" ${r} ${c}
else
whiptail --msgbox --backtitle "Make it so." --title "Installation Complete!" "Configure your devices to use the Pi-hole as their DNS server using:
IPv4: ${IPV4_ADDRESS%/*}
IPv6: ${IPV6_ADDRESS}
If you set a new IP address, you should restart the Pi.
The install log is in /etc/pihole.
View the web interface at http://pi.hole/admin or http://${IPV4_ADDRESS%/*}/admin" ${r} ${c}
fi
}
update_dialogs() {
# reconfigure
if [ "${reconfigure}" = true ]; then
opt1a="Repair"
opt1b="This will retain existing settings"
strAdd="You will remain on the same version"
else
opt1a="Update"
opt1b="This will retain existing settings."
strAdd="You will be updated to the latest version."
fi
opt2a="Reconfigure"
opt2b="This will allow you to enter new settings"
UpdateCmd=$(whiptail --title "Existing Install Detected!" --menu "\n\nWe have detected an existing install.\n\nPlease choose from the following options: \n($strAdd)" ${r} ${c} 2 \
"${opt1a}" "${opt1b}" \
"${opt2a}" "${opt2b}" 3>&2 2>&1 1>&3)
if [[ $? = 0 ]];then
case ${UpdateCmd} in
${opt1a})
echo "::: ${opt1a} option selected."
useUpdateVars=true
;;
${opt2a})
echo "::: ${opt2a} option selected"
useUpdateVars=false
;;
esac
else
echo "::: Cancel selected. Exiting..."
exit 1
fi
}
main() {
# Check arguments for the undocumented flags
for var in "$@"; do
case "$var" in
"--reconfigure" ) reconfigure=true;;
"--i_do_not_follow_recommendations" ) skipSpaceCheck=false;;
"--unattended" ) runUnattended=true;;
esac
done
if [[ -f ${setupVars} ]]; then
if [[ "${runUnattended}" == true ]]; then
echo "::: --unattended passed to install script, no whiptail dialogs will be displayed"
useUpdateVars=true
else
update_dialogs
fi
fi
# Start the installer
# Verify there is enough disk space for the install
if [[ "${skipSpaceCheck}" == true ]]; then
echo "::: --i_do_not_follow_recommendations passed to script, skipping free disk space verification!"
else
verifyFreeDiskSpace
fi
# Update package cache
update_pacakge_cache
# Notify user of package availability
notify_package_updates_available
# Install packages used by this installation script
install_dependent_packages INSTALLER_DEPS[@]
if [[ "${reconfigure}" == true ]]; then
echo "::: --reconfigure passed to install script. Not downloading/updating local repos"
else
# Get Git files for Core and Admin
getGitFiles ${PI_HOLE_LOCAL_REPO} ${piholeGitUrl}
getGitFiles ${webInterfaceDir} ${webInterfaceGitUrl}
fi
if [[ ${useUpdateVars} == false ]]; then
# Display welcome dialogs
welcomeDialogs
# Create directory for Pi-hole storage
mkdir -p /etc/pihole/
# Remove legacy scripts from previous storage location
remove_legacy_scripts
# Stop resolver and webserver while installing proceses
stop_service dnsmasq
stop_service lighttpd
# Determine available interfaces
get_available_interfaces
# Find interfaces and let the user choose one
chooseInterface
# Let the user decide if they want to block ads over IPv4 and/or IPv6
use4andor6
# Decide what upstream DNS Servers to use
setDNS
# Let the user decide if they want query logging enabled...
setLogging
# Install packages used by the Pi-hole
install_dependent_packages PIHOLE_DEPS[@]
# Install and log everything to a file
installPihole | tee ${tmpLog}
else
# update packages used by the Pi-hole
install_dependent_packages PIHOLE_DEPS[@]
updatePihole | tee ${tmpLog}
fi
# Move the log file into /etc/pihole for storage
mv ${tmpLog} ${instalLogLoc}
# Add password to web UI if there is none
pw=""
if [[ $(grep 'WEBPASSWORD' -c /etc/pihole/setupVars.conf) == 0 ]] ; then
pw=$(tr -dc _A-Z-a-z-0-9 < /dev/urandom | head -c 8)
pihole -a -p ${pw}
fi
if [[ "${useUpdateVars}" == false ]]; then
displayFinalMessage ${pw}
fi
echo "::: Restarting services..."
# Start services
start_service dnsmasq
enable_service dnsmasq
start_service lighttpd
enable_service lighttpd
echo "::: done."
echo ":::"
if [[ "${useUpdateVars}" == false ]]; then
echo "::: Installation Complete! Configure your devices to use the Pi-hole as their DNS server using:"
echo "::: ${IPV4_ADDRESS%/*}"
echo "::: ${IPV6_ADDRESS}"
echo ":::"
echo "::: If you set a new IP address, you should restart the Pi."
echo "::: View the web interface at http://pi.hole/admin or http://${IPV4_ADDRESS%/*}/admin"
else
echo "::: Update complete!"
fi
if (( ${#pw} > 0 )) ; then
echo ":::"
echo "::: Note: As security measure a password has been installed for your web interface"
echo "::: The currently set password is"
echo "::: ${pw}"
echo ":::"
echo "::: You can always change it using"
echo "::: pihole -a -p new_password"
fi
echo ":::"
echo "::: The install log is located at: /etc/pihole/install.log"
}
if [[ "${PH_TEST}" != true ]] ; then
main "$@"
fi
\ No newline at end of file
+#!/usr/bin/env bash
# Pi-hole: A black hole for Internet advertisements
# (c) 2015, 2016 by Jacob Salmela
# Network-wide ad blocking via your Raspberry Pi
# http://pi-hole.net
# Installs Pi-hole
#
# Pi-hole is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 2 of the License, or
# (at your option) any later version.
# pi-hole.net/donate
#
# Install with this command (from your Pi):
#
# curl -L install.pi-hole.net | bash
set -e
######## VARIABLES #########
tmpLog=/tmp/pihole-install.log
instalLogLoc=/etc/pihole/install.log
setupVars=/etc/pihole/setupVars.conf
webInterfaceGitUrl="https://github.com/pi-hole/AdminLTE.git"
webInterfaceDir="/var/www/html/admin"
piholeGitUrl="https://github.com/pi-hole/pi-hole.git"
PI_HOLE_LOCAL_REPO="/etc/.pihole"
PI_HOLE_FILES=(chronometer list piholeDebug piholeLogFlush setupLCD update version)
useUpdateVars=false
IPV4_ADDRESS=""
IPV6_ADDRESS=""
QUERY_LOGGING=true
# Find the rows and columns will default to 80x24 is it can not be detected
screen_size=$(stty size 2>/dev/null || echo 24 80)
rows=$(echo $screen_size | awk '{print $1}')
columns=$(echo $screen_size | awk '{print $2}')
# Divide by two so the dialogs take up half of the screen, which looks nice.
r=$(( rows / 2 ))
c=$(( columns / 2 ))
# Unless the screen is tiny
r=$(( r < 20 ? 20 : r ))
c=$(( c < 70 ? 70 : c ))
######## Undocumented Flags. Shhh ########
skipSpaceCheck=false
reconfigure=false
runUnattended=false
######## FIRST CHECK ########
# Must be root to install
echo ":::"
if [[ ${EUID} -eq 0 ]]; then
echo "::: You are root."
else
echo "::: Script called with non-root privileges. The Pi-hole installs server packages and configures"
echo "::: system networking, it requires elevated rights. Please check the contents of the script for"
echo "::: any concerns with this requirement. Please be sure to download this script from a trusted source."
echo ":::"
echo "::: Detecting the presence of the sudo utility for continuation of this install..."
if [ -x "$(command -v sudo)" ]; then
echo "::: Utility sudo located."
exec curl -sSL https://install.pi-hole.net | sudo bash "$@"
exit $?
else
echo "::: sudo is needed for the Web interface to run pihole commands. Please run this script as root and it will be automatically installed."
exit 1
fi
fi
# Compatibility
if [[ $(command -v apt-get) ]]; then
#Debian Family
#############################################
PKG_MANAGER="apt-get"
PKG_CACHE="/var/lib/apt/lists/"
UPDATE_PKG_CACHE="${PKG_MANAGER} update"
PKG_UPDATE="${PKG_MANAGER} upgrade"
PKG_INSTALL="${PKG_MANAGER} --yes --fix-missing install"
# grep -c will return 1 retVal on 0 matches, block this throwing the set -e with an OR TRUE
PKG_COUNT="${PKG_MANAGER} -s -o Debug::NoLocking=true upgrade | grep -c ^Inst || true"
# #########################################
# fixes for dependancy differences
# Debian 7 doesn't have iproute2 use iproute
${PKG_MANAGER} install --dry-run iproute2 > /dev/null 2>&1 && IPROUTE_PKG="iproute2" || IPROUTE_PKG="iproute"
# Prefer the php metapackage if it's there, fall back on the php5 pacakges
${PKG_MANAGER} install --dry-run php > /dev/null 2>&1 && phpVer="php" || phpVer="php5"
# #########################################
INSTALLER_DEPS=(apt-utils whiptail git dhcpcd5)
PIHOLE_DEPS=(iputils-ping lsof dnsutils bc dnsmasq lighttpd ${phpVer}-common ${phpVer}-cgi curl unzip wget sudo netcat cron ${IPROUTE_PKG})
LIGHTTPD_USER="www-data"
LIGHTTPD_GROUP="www-data"
LIGHTTPD_CFG="lighttpd.conf.debian"
DNSMASQ_USER="dnsmasq"
package_check_install() {
dpkg-query -W -f='${Status}' "${1}" 2>/dev/null | grep -c "ok installed" || ${PKG_INSTALL} "${1}"
}
elif [ $(command -v rpm) ]; then
# Fedora Family
if [ $(command -v dnf) ]; then
PKG_MANAGER="dnf"
else
PKG_MANAGER="yum"
fi
PKG_CACHE="/var/cache/${PKG_MANAGER}"
UPDATE_PKG_CACHE="${PKG_MANAGER} check-update"
PKG_UPDATE="${PKG_MANAGER} update -y"
PKG_INSTALL="${PKG_MANAGER} install -y"
PKG_COUNT="${PKG_MANAGER} check-update | egrep '(.i686|.x86|.noarch|.arm|.src)' | wc -l"
INSTALLER_DEPS=(iproute net-tools procps-ng newt git)
PIHOLE_DEPS=(epel-release bind-utils bc dnsmasq lighttpd lighttpd-fastcgi php-common php-cli php curl unzip wget findutils cronie sudo nmap-ncat)
if grep -q 'Fedora' /etc/redhat-release; then
remove_deps=(epel-release);
PIHOLE_DEPS=( ${PIHOLE_DEPS[@]/$remove_deps} );
fi
LIGHTTPD_USER="lighttpd"
LIGHTTPD_GROUP="lighttpd"
LIGHTTPD_CFG="lighttpd.conf.fedora"
DNSMASQ_USER="nobody"
package_check_install() {
rpm -qa | grep ^"${1}"- > /dev/null || ${PKG_INSTALL} "${1}"
}
else
echo "OS distribution not supported"
exit
fi
####### FUNCTIONS ##########
is_repo() {
# Use git to check if directory is currently under VCS, return the value
local directory="${1}"
git -C "${directory}" status --short &> /dev/null
return
}
make_repo() {
local directory="${1}"
local remoteRepo="${2}"
# Remove the non-repod interface and clone the interface
echo -n "::: Cloning $remoteRepo into $directory..."
rm -rf "${directory}"
git clone -q --depth 1 "${remoteRepo}" "${directory}" &> /dev/null
echo " done!"
}
update_repo() {
local directory="${1}"
# Pull the latest commits
echo -n "::: Updating repo in $1..."
cd "${directory}" || exit 1
git stash -q &> /dev/null
git pull -q &> /dev/null
echo " done!"
}
getGitFiles() {
# Setup git repos for directory and repository passed
# as arguments 1 and 2
local directory="${1}"
local remoteRepo="${2}"
echo ":::"
echo "::: Checking for existing repository..."
if is_repo "${directory}"; then
update_repo "${directory}"
else
make_repo "${directory}" "${remoteRepo}"
fi
}
find_IPv4_information() {
# Find IP used to route to outside world
IPv4dev=$(ip route get 8.8.8.8 | awk '{for(i=1;i<=NF;i++)if($i~/dev/)print $(i+1)}')
IPV4_ADDRESS=$(ip -o -f inet addr show dev "$IPv4dev" | awk '{print $4}' | awk 'END {print}')
IPv4gw=$(ip route get 8.8.8.8 | awk '{print $3}')
}
get_available_interfaces() {
# Get available interfaces. Consider only getting UP interfaces in the future, and leaving DOWN interfaces out of list.
availableInterfaces=$(ip -o link | awk '{print $2}' | grep -v "lo" | cut -d':' -f1 | cut -d'@' -f1)
}
welcomeDialogs() {
# Display the welcome dialog
whiptail --msgbox --backtitle "Welcome" --title "Pi-hole automated installer" "\n\nThis installer will transform your device into a network-wide ad blocker!" ${r} ${c}
# Support for a part-time dev
whiptail --msgbox --backtitle "Plea" --title "Free and open source" "\n\nThe Pi-hole is free, but powered by your donations: http://pi-hole.net/donate" ${r} ${c}
# Explain the need for a static address
whiptail --msgbox --backtitle "Initiating network interface" --title "Static IP Needed" "\n\nThe Pi-hole is a SERVER so it needs a STATIC IP ADDRESS to function properly.
In the next section, you can choose to use your current network settings (DHCP) or to manually edit them." ${r} ${c}
}
verifyFreeDiskSpace() {
# 50MB is the minimum space needed (45MB install (includes web admin bootstrap/jquery libraries etc) + 5MB one day of logs.)
# - Fourdee: Local ensures the variable is only created, and accessible within this function/void. Generally considered a "good" coding practice for non-global variables.
echo "::: Verifying free disk space..."
local required_free_kilobytes=51200
local existing_free_kilobytes=$(df -Pk | grep -m1 '\/$' | awk '{print $4}')
# - Unknown free disk space , not a integer
if ! [[ "${existing_free_kilobytes}" =~ ^([0-9])+$ ]]; then
echo "::: Unknown free disk space!"
echo "::: We were unable to determine available free disk space on this system."
echo "::: You may override this check and force the installation, however, it is not recommended"
echo "::: To do so, pass the argument '--i_do_not_follow_recommendations' to the install script"
echo "::: eg. curl -L https://install.pi-hole.net | bash /dev/stdin --i_do_not_follow_recommendations"
exit 1
# - Insufficient free disk space
elif [[ ${existing_free_kilobytes} -lt ${required_free_kilobytes} ]]; then
echo "::: Insufficient Disk Space!"
echo "::: Your system appears to be low on disk space. pi-hole recommends a minimum of $required_free_kilobytes KiloBytes."
echo "::: You only have ${existing_free_kilobytes} KiloBytes free."
echo "::: If this is a new install you may need to expand your disk."
echo "::: Try running 'sudo raspi-config', and choose the 'expand file system option'"
echo "::: After rebooting, run this installation again. (curl -L https://install.pi-hole.net | bash)"
echo "Insufficient free space, exiting..."
exit 1
fi
}
chooseInterface() {
# Turn the available interfaces into an array so it can be used with a whiptail dialog
local interfacesArray=()
# Number of available interfaces
local interfaceCount
# Whiptail variable storage
local chooseInterfaceCmd
# Temporary Whiptail options storage
local chooseInterfaceOptions
# Loop sentinel variable
local firstLoop=1
while read -r line; do
mode="OFF"
if [[ ${firstLoop} -eq 1 ]]; then
firstLoop=0
mode="ON"
fi
interfacesArray+=("${line}" "available" "${mode}")
done <<< "${availableInterfaces}"
# Find out how many interfaces are available to choose from
interfaceCount=$(echo "${availableInterfaces}" | wc -l)
chooseInterfaceCmd=(whiptail --separate-output --radiolist "Choose An Interface (press space to select)" ${r} ${c} ${interfaceCount})
chooseInterfaceOptions=$("${chooseInterfaceCmd[@]}" "${interfacesArray[@]}" 2>&1 >/dev/tty)
if [[ $? = 0 ]]; then
for desiredInterface in ${chooseInterfaceOptions}; do
PIHOLE_INTERFACE=${desiredInterface}
echo "::: Using interface: $PIHOLE_INTERFACE"
done
else
echo "::: Cancel selected, exiting...."
exit 1
fi
}
useIPv6dialog() {
# Show the IPv6 address used for blocking
IPV6_ADDRESS=$(ip -6 route get 2001:4860:4860::8888 | awk -F " " '{ for(i=1;i<=NF;i++) if ($i == "src") print $(i+1) }')
whiptail --msgbox --backtitle "IPv6..." --title "IPv6 Supported" "$IPV6_ADDRESS will be used to block ads." ${r} ${c}
}
use4andor6() {
local useIPv4
local useIPv6
# Let use select IPv4 and/or IPv6
cmd=(whiptail --separate-output --checklist "Select Protocols (press space to select)" ${r} ${c} 2)
options=(IPv4 "Block ads over IPv4" on
IPv6 "Block ads over IPv6" on)
choices=$("${cmd[@]}" "${options[@]}" 2>&1 >/dev/tty)
if [[ $? = 0 ]];then
for choice in ${choices}
do
case ${choice} in
IPv4 ) useIPv4=true;;
IPv6 ) useIPv6=true;;
esac
done
if [[ ${useIPv4} ]]; then
find_IPv4_information
getStaticIPv4Settings
setStaticIPv4
fi
if [[ ${useIPv6} ]]; then
useIPv6dialog
fi
echo "::: IPv4 address: ${IPV4_ADDRESS}"
echo "::: IPv6 address: ${IPV6_ADDRESS}"
if [ ! ${useIPv4} ] && [ ! ${useIPv6} ]; then
echo "::: Cannot continue, neither IPv4 or IPv6 selected"
echo "::: Exiting"
exit 1
fi
else
echo "::: Cancel selected. Exiting..."
exit 1
fi
}
getStaticIPv4Settings() {
# Ask if the user wants to use DHCP settings as their static IP
if (whiptail --backtitle "Calibrating network interface" --title "Static IP Address" --yesno "Do you want to use your current network settings as a static address?
IP address: ${IPV4_ADDRESS}
Gateway: ${IPv4gw}" ${r} ${c}); then
# If they choose yes, let the user know that the IP address will not be available via DHCP and may cause a conflict.
whiptail --msgbox --backtitle "IP information" --title "FYI: IP Conflict" "It is possible your router could still try to assign this IP to a device, which would cause a conflict. But in most cases the router is smart enough to not do that.
If you are worried, either manually set the address, or modify the DHCP reservation pool so it does not include the IP you want.
It is also possible to use a DHCP reservation, but if you are going to do that, you might as well set a static address." ${r} ${c}
# Nothing else to do since the variables are already set above
else
# Otherwise, we need to ask the user to input their desired settings.
# Start by getting the IPv4 address (pre-filling it with info gathered from DHCP)
# Start a loop to let the user enter their information with the chance to go back and edit it if necessary
until [[ ${ipSettingsCorrect} = True ]]; do
# Ask for the IPv4 address
IPV4_ADDRESS=$(whiptail --backtitle "Calibrating network interface" --title "IPv4 address" --inputbox "Enter your desired IPv4 address" ${r} ${c} "${IPV4_ADDRESS}" 3>&1 1>&2 2>&3)
if [[ $? = 0 ]]; then
echo "::: Your static IPv4 address: ${IPV4_ADDRESS}"
# Ask for the gateway
IPv4gw=$(whiptail --backtitle "Calibrating network interface" --title "IPv4 gateway (router)" --inputbox "Enter your desired IPv4 default gateway" ${r} ${c} "${IPv4gw}" 3>&1 1>&2 2>&3)
if [[ $? = 0 ]]; then
echo "::: Your static IPv4 gateway: ${IPv4gw}"
# Give the user a chance to review their settings before moving on
if (whiptail --backtitle "Calibrating network interface" --title "Static IP Address" --yesno "Are these settings correct?
IP address: ${IPV4_ADDRESS}
Gateway: ${IPv4gw}" ${r} ${c}); then
# After that's done, the loop ends and we move on
ipSettingsCorrect=True
else
# If the settings are wrong, the loop continues
ipSettingsCorrect=False
fi
else
# Cancelling gateway settings window
ipSettingsCorrect=False
echo "::: Cancel selected. Exiting..."
exit 1
fi
else
# Cancelling IPv4 settings window
ipSettingsCorrect=False
echo "::: Cancel selected. Exiting..."
exit 1
fi
done
# End the if statement for DHCP vs. static
fi
}
setDHCPCD() {
# Append these lines to dhcpcd.conf to enable a static IP
echo "## interface ${PIHOLE_INTERFACE}
static ip_address=${IPV4_ADDRESS}
static routers=${IPv4gw}
static domain_name_servers=${IPv4gw}" | tee -a /etc/dhcpcd.conf >/dev/null
}
setStaticIPv4() {
local IFCFG_FILE
local IPADDR
local CIDR
if [[ -f /etc/dhcpcd.conf ]]; then
# Debian Family
if grep -q "${IPV4_ADDRESS}" /etc/dhcpcd.conf; then
echo "::: Static IP already configured"
else
setDHCPCD
ip addr replace dev "${PIHOLE_INTERFACE}" "${IPV4_ADDRESS}"
echo ":::"
echo "::: Setting IP to ${IPV4_ADDRESS}. You may need to restart after the install is complete."
echo ":::"
fi
elif [[ -f /etc/sysconfig/network-scripts/ifcfg-${PIHOLE_INTERFACE} ]];then
# Fedora Family
IFCFG_FILE=/etc/sysconfig/network-scripts/ifcfg-${PIHOLE_INTERFACE}
if grep -q "${IPV4_ADDRESS}" "${IFCFG_FILE}"; then
echo "::: Static IP already configured"
else
IPADDR=$(echo "${IPV4_ADDRESS}" | cut -f1 -d/)
CIDR=$(echo "${IPV4_ADDRESS}" | cut -f2 -d/)
# Backup existing interface configuration:
cp "${IFCFG_FILE}" "${IFCFG_FILE}".pihole.orig
# Build Interface configuration file:
{
echo "# Configured via Pi-Hole installer"
echo "DEVICE=$PIHOLE_INTERFACE"
echo "BOOTPROTO=none"
echo "ONBOOT=yes"
echo "IPADDR=$IPADDR"
echo "PREFIX=$CIDR"
echo "GATEWAY=$IPv4gw"
echo "DNS1=$PIHOLE_DNS_1"
echo "DNS2=$PIHOLE_DNS_2"
echo "USERCTL=no"
}> "${IFCFG_FILE}"
ip addr replace dev "${PIHOLE_INTERFACE}" "${IPV4_ADDRESS}"
if [ -x "$(command -v nmcli)" ];then
# Tell NetworkManager to read our new sysconfig file
nmcli con load "${IFCFG_FILE}" > /dev/null
fi
echo ":::"
echo "::: Setting IP to ${IPV4_ADDRESS}. You may need to restart after the install is complete."
echo ":::"
fi
else
echo "::: Warning: Unable to locate configuration file to set static IPv4 address!"
exit 1
fi
}
valid_ip() {
local ip=${1}
local stat=1
if [[ ${ip} =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then
OIFS=$IFS
IFS='.'
ip=(${ip})
IFS=${OIFS}
[[ ${ip[0]} -le 255 && ${ip[1]} -le 255 \
&& ${ip[2]} -le 255 && ${ip[3]} -le 255 ]]
stat=$?
fi
return ${stat}
}
setDNS() {
DNSChooseCmd=(whiptail --separate-output --radiolist "Select Upstream DNS Provider. To use your own, select Custom." ${r} ${c} 6)
DNSChooseOptions=(Google "" on
OpenDNS "" off
Level3 "" off
Norton "" off
Comodo "" off
Custom "" off)
DNSchoices=$("${DNSChooseCmd[@]}" "${DNSChooseOptions[@]}" 2>&1 >/dev/tty)
if [[ $? = 0 ]];then
case ${DNSchoices} in
Google)
echo "::: Using Google DNS servers."
PIHOLE_DNS_1="8.8.8.8"
PIHOLE_DNS_2="8.8.4.4"
;;
OpenDNS)
echo "::: Using OpenDNS servers."
PIHOLE_DNS_1="208.67.222.222"
PIHOLE_DNS_2="208.67.220.220"
;;
Level3)
echo "::: Using Level3 servers."
PIHOLE_DNS_1="4.2.2.1"
PIHOLE_DNS_2="4.2.2.2"
;;
Norton)
echo "::: Using Norton ConnectSafe servers."
PIHOLE_DNS_1="199.85.126.10"
PIHOLE_DNS_2="199.85.127.10"
;;
Comodo)
echo "::: Using Comodo Secure servers."
PIHOLE_DNS_1="8.26.56.26"
PIHOLE_DNS_2="8.20.247.20"
;;
Custom)
until [[ ${DNSSettingsCorrect} = True ]]; do
strInvalid="Invalid"
if [ ! ${PIHOLE_DNS_1} ]; then
if [ ! ${PIHOLE_DNS_2} ]; then
prePopulate=""
else
prePopulate=", ${PIHOLE_DNS_2}"
fi
elif [ ${PIHOLE_DNS_1} ] && [ ! ${PIHOLE_DNS_2} ]; then
prePopulate="${PIHOLE_DNS_1}"
elif [ ${PIHOLE_DNS_1} ] && [ ${PIHOLE_DNS_2} ]; then
prePopulate="${PIHOLE_DNS_1}, ${PIHOLE_DNS_2}"
fi
piholeDNS=$(whiptail --backtitle "Specify Upstream DNS Provider(s)" --inputbox "Enter your desired upstream DNS provider(s), seperated by a comma.\n\nFor example '8.8.8.8, 8.8.4.4'" ${r} ${c} "${prePopulate}" 3>&1 1>&2 2>&3)
if [[ $? = 0 ]]; then
PIHOLE_DNS_1=$(echo "${piholeDNS}" | sed 's/[, \t]\+/,/g' | awk -F, '{print$1}')
PIHOLE_DNS_2=$(echo "${piholeDNS}" | sed 's/[, \t]\+/,/g' | awk -F, '{print$2}')
if ! valid_ip "${PIHOLE_DNS_1}" || [ ! "${PIHOLE_DNS_1}" ]; then
PIHOLE_DNS_1=${strInvalid}
fi
if ! valid_ip "${PIHOLE_DNS_2}" && [ "${PIHOLE_DNS_2}" ]; then
PIHOLE_DNS_2=${strInvalid}
fi
else
echo "::: Cancel selected, exiting...."
exit 1
fi
if [[ ${PIHOLE_DNS_1} == "${strInvalid}" ]] || [[ ${PIHOLE_DNS_2} == "${strInvalid}" ]]; then
whiptail --msgbox --backtitle "Invalid IP" --title "Invalid IP" "One or both entered IP addresses were invalid. Please try again.\n\n DNS Server 1: $PIHOLE_DNS_1\n DNS Server 2: ${PIHOLE_DNS_2}" ${r} ${c}
if [[ ${PIHOLE_DNS_1} == "${strInvalid}" ]]; then
PIHOLE_DNS_1=""
fi
if [[ ${PIHOLE_DNS_2} == "${strInvalid}" ]]; then
PIHOLE_DNS_2=""
fi
DNSSettingsCorrect=False
else
if (whiptail --backtitle "Specify Upstream DNS Provider(s)" --title "Upstream DNS Provider(s)" --yesno "Are these settings correct?\n DNS Server 1: $PIHOLE_DNS_1\n DNS Server 2: ${PIHOLE_DNS_2}" ${r} ${c}); then
DNSSettingsCorrect=True
else
# If the settings are wrong, the loop continues
DNSSettingsCorrect=False
fi
fi
done
;;
esac
else
echo "::: Cancel selected. Exiting..."
exit 1
fi
}
setLogging() {
local LogToggleCommand
local LogChooseOptions
local LogChoices
LogToggleCommand=(whiptail --separate-output --radiolist "Do you want to log queries?\n (Disabling will render graphs on the Admin page useless):" ${r} ${c} 6)
LogChooseOptions=("On (Reccomended)" "" on
Off "" off)
LogChoices=$("${LogToggleCommand[@]}" "${LogChooseOptions[@]}" 2>&1 >/dev/tty) || (echo "::: Cancel selected. Exiting..." && exit 1)
case ${LogChoices} in
"On (Recommended)")
echo "::: Logging On."
QUERY_LOGGING=true
;;
Off)
echo "::: Logging Off."
QUERY_LOGGING=false
;;
esac
}
version_check_dnsmasq() {
# Check if /etc/dnsmasq.conf is from pihole. If so replace with an original and install new in .d directory
local dnsmasq_conf="/etc/dnsmasq.conf"
local dnsmasq_conf_orig="/etc/dnsmasq.conf.orig"
local dnsmasq_pihole_id_string="addn-hosts=/etc/pihole/gravity.list"
local dnsmasq_original_config="/etc/.pihole/advanced/dnsmasq.conf.original"
local dnsmasq_pihole_01_snippet="/etc/.pihole/advanced/01-pihole.conf"
local dnsmasq_pihole_01_location="/etc/dnsmasq.d/01-pihole.conf"
if [ -f ${dnsmasq_conf} ]; then
echo -n "::: Existing dnsmasq.conf found..."
if grep -q ${dnsmasq_pihole_id_string} ${dnsmasq_conf}; then
echo " it is from a previous pi-hole install."
echo -n "::: Backing up dnsmasq.conf to dnsmasq.conf.orig..."
mv -f ${dnsmasq_conf} ${dnsmasq_conf_orig}
echo " done."
echo -n "::: Restoring default dnsmasq.conf..."
cp ${dnsmasq_original_config} ${dnsmasq_conf}
echo " done."
else
echo " it is not a pi-hole file, leaving alone!"
fi
else
echo -n "::: No dnsmasq.conf found.. restoring default dnsmasq.conf..."
cp ${dnsmasq_original_config} ${dnsmasq_conf}
echo " done."
fi
echo -n "::: Copying 01-pihole.conf to /etc/dnsmasq.d/01-pihole.conf..."
cp ${dnsmasq_pihole_01_snippet} ${dnsmasq_pihole_01_location}
echo " done."
sed -i "s/@INT@/$PIHOLE_INTERFACE/" ${dnsmasq_pihole_01_location}
if [[ "${PIHOLE_DNS_1}" != "" ]]; then
sed -i "s/@DNS1@/$PIHOLE_DNS_1/" ${dnsmasq_pihole_01_location}
else
sed -i '/^server=@DNS1@/d' ${dnsmasq_pihole_01_location}
fi
if [[ "${PIHOLE_DNS_2}" != "" ]]; then
sed -i "s/@DNS2@/$PIHOLE_DNS_2/" ${dnsmasq_pihole_01_location}
else
sed -i '/^server=@DNS2@/d' ${dnsmasq_pihole_01_location}
fi
sed -i 's/^#conf-dir=\/etc\/dnsmasq.d$/conf-dir=\/etc\/dnsmasq.d/' ${dnsmasq_conf}
if [[ "${QUERY_LOGGING}" == false ]] ; then
#Disable Logging
sed -i 's/^log-queries/#log-queries/' ${dnsmasq_pihole_01_location}
else
#Enable Logging
sed -i 's/^#log-queries/log-queries/' ${dnsmasq_pihole_01_location}
fi
}
remove_legacy_scripts() {
#Tidy up /usr/local/bin directory if installing over previous install.
oldFiles=( gravity chronometer whitelist blacklist piholeLogFlush updateDashboard uninstall setupLCD piholeDebug)
for i in "${oldFiles[@]}"; do
if [ -f "/usr/local/bin/$i.sh" ]; then
rm /usr/local/bin/"$i".sh
fi
done
}
clean_existing() {
# Clean an exiting installation to prepare for upgrade/reinstall
# ${1} Directory to clean; ${2} Array of files to remove
local clean_directory="${1}"
local old_files=${2}
for script in "${old_files[@]}"; do
rm -f "${clean_directory}${script}.sh"
done
}
installScripts() {
# Install the scripts from repository to their various locations
readonly install_dir="/opt/pihole/"
echo ":::"
echo -n "::: Installing scripts from ${PI_HOLE_LOCAL_REPO}..."
# Clear out script files from Pi-hole scripts directory.
clean_existing "${install_dir}" "${PI_HOLE_FILES}"
# Install files from local core repository
if is_repo "${PI_HOLE_LOCAL_REPO}"; then
cd "${PI_HOLE_LOCAL_REPO}"
install -o "${USER}" -Dm755 -t /opt/pihole/ gravity.sh
install -o "${USER}" -Dm755 -t /opt/pihole/ ./advanced/Scripts/*.sh
install -o "${USER}" -Dm755 -t /opt/pihole/ ./automated\ install/uninstall.sh
install -o "${USER}" -Dm755 -t /usr/local/bin/ pihole
install -Dm644 ./advanced/bash-completion/pihole /etc/bash_completion.d/pihole
echo " done."
else
echo " *** ERROR: Local repo ${core_repo} not found, exiting."
exit 1
fi
}
installConfigs() {
# Install the configs from /etc/.pihole to their various locations
echo ":::"
echo "::: Installing configs..."
version_check_dnsmasq
if [ ! -d "/etc/lighttpd" ]; then
mkdir /etc/lighttpd
chown "${USER}":root /etc/lighttpd
elif [ -f "/etc/lighttpd/lighttpd.conf" ]; then
mv /etc/lighttpd/lighttpd.conf /etc/lighttpd/lighttpd.conf.orig
fi
cp /etc/.pihole/advanced/${LIGHTTPD_CFG} /etc/lighttpd/lighttpd.conf
mkdir -p /var/run/lighttpd
chown ${LIGHTTPD_USER}:${LIGHTTPD_GROUP} /var/run/lighttpd
mkdir -p /var/cache/lighttpd/compress
chown ${LIGHTTPD_USER}:${LIGHTTPD_GROUP} /var/cache/lighttpd/compress
mkdir -p /var/cache/lighttpd/uploads
chown ${LIGHTTPD_USER}:${LIGHTTPD_GROUP} /var/cache/lighttpd/uploads
}
stop_service() {
# Stop service passed in as argument.
# Can softfail, as process may not be installed when this is called
echo ":::"
echo -n "::: Stopping ${1} service..."
if [ -x "$(command -v systemctl)" ]; then
systemctl stop "${1}" &> /dev/null || true
else
service "${1}" stop &> /dev/null || true
fi
echo " done."
}
start_service() {
# Start/Restart service passed in as argument
# This should not fail, it's an error if it does
echo ":::"
echo -n "::: Starting ${1} service..."
if [ -x "$(command -v systemctl)" ]; then
systemctl restart "${1}" &> /dev/null
else
service "${1}" restart &> /dev/null
fi
echo " done."
}
enable_service() {
# Enable service so that it will start with next reboot
echo ":::"
echo -n "::: Enabling ${1} service to start on reboot..."
if [ -x "$(command -v systemctl)" ]; then
systemctl enable "${1}" &> /dev/null
else
update-rc.d "${1}" defaults &> /dev/null
fi
echo " done."
}
update_pacakge_cache() {
#Running apt-get update/upgrade with minimal output can cause some issues with
#requiring user input (e.g password for phpmyadmin see #218)
#Check to see if apt-get update has already been run today
#it needs to have been run at least once on new installs!
timestamp=$(stat -c %Y ${PKG_CACHE})
timestampAsDate=$(date -d @"${timestamp}" "+%b %e")
today=$(date "+%b %e")
if [ ! "${today}" == "${timestampAsDate}" ]; then
#update package lists
echo ":::"
echo -n "::: ${PKG_MANAGER} update has not been run today. Running now..."
${UPDATE_PKG_CACHE} &> /dev/null
echo " done!"
fi
}
notify_package_updates_available() {
# Let user know if they have outdated packages on their system and
# advise them to run a package update at soonest possible.
echo ":::"
echo -n "::: Checking ${PKG_MANAGER} for upgraded packages...."
updatesToInstall=$(eval "${PKG_COUNT}")
echo " done!"
echo ":::"
if [[ ${updatesToInstall} -eq "0" ]]; then
echo "::: Your system is up to date! Continuing with Pi-hole installation..."
else
echo "::: There are ${updatesToInstall} updates available for your system!"
echo "::: We recommend you run '${PKG_UPDATE}' after installing Pi-Hole! "
echo ":::"
fi
}
install_dependent_packages() {
# Install packages passed in via argument array
# No spinner - conflicts with set -e
declare -a argArray1=("${!1}")
for i in "${argArray1[@]}"; do
echo -n "::: Checking for $i..."
package_check_install "${i}" &> /dev/null
echo " installed!"
done
}
CreateLogFile() {
# Create logfiles if necessary
echo ":::"
echo -n "::: Creating log file and changing owner to dnsmasq..."
if [ ! -f /var/log/pihole.log ]; then
touch /var/log/pihole.log
chmod 644 /var/log/pihole.log
chown "${DNSMASQ_USER}":root /var/log/pihole.log
echo " done!"
else
echo " already exists!"
fi
}
installPiholeWeb() {
# Install the web interface
echo ":::"
echo "::: Installing pihole custom index page..."
if [ -d "/var/www/html/pihole" ]; then
if [ -f "/var/www/html/pihole/index.html" ]; then
echo "::: Existing index.html detected, not overwriting"
else
echo -n "::: index.html missing, replacing... "
cp /etc/.pihole/advanced/index.html /var/www/html/pihole/
echo " done!"
fi
if [ -f "/var/www/html/pihole/index.js" ]; then
echo "::: Existing index.js detected, not overwriting"
else
echo -n "::: index.js missing, replacing... "
cp /etc/.pihole/advanced/index.js /var/www/html/pihole/
echo " done!"
fi
else
mkdir /var/www/html/pihole
if [ -f /var/www/html/index.lighttpd.html ]; then
mv /var/www/html/index.lighttpd.html /var/www/html/index.lighttpd.orig
else
printf "\n:::\tNo default index.lighttpd.html file found... not backing up"
fi
cp /etc/.pihole/advanced/index.* /var/www/html/pihole/.
echo " done!"
fi
# Install Sudoer file
echo ":::"
echo -n "::: Installing sudoer file..."
mkdir -p /etc/sudoers.d/
cp /etc/.pihole/advanced/pihole.sudo /etc/sudoers.d/pihole
chmod 0440 /etc/sudoers.d/pihole
echo " done!"
}
installCron() {
# Install the cron job
echo ":::"
echo -n "::: Installing latest Cron script..."
cp /etc/.pihole/advanced/pihole.cron /etc/cron.d/pihole
echo " done!"
}
runGravity() {
# Run gravity.sh to build blacklists
echo ":::"
echo "::: Preparing to run gravity.sh to refresh hosts..."
if ls /etc/pihole/list* 1> /dev/null 2>&1; then
echo "::: Cleaning up previous install (preserving whitelist/blacklist)"
rm /etc/pihole/list.*
fi
echo "::: Running gravity.sh"
/opt/pihole/gravity.sh
}
create_pihole_user() {
# Check if user pihole exists and create if not
echo "::: Checking if user 'pihole' exists..."
id -u pihole &> /dev/null && echo "::: User 'pihole' already exists" || (echo "::: User 'pihole' doesn't exist. Creating..." && useradd -r -s /usr/sbin/nologin pihole)
}
configureFirewall() {
# Allow HTTP and DNS traffic
if [ -x "$(command -v firewall-cmd)" ]; then
firewall-cmd --state &> /dev/null && ( echo "::: Configuring firewalld for httpd and dnsmasq.." && firewall-cmd --permanent --add-port=80/tcp && firewall-cmd --permanent --add-port=53/tcp \
&& firewall-cmd --permanent --add-port=53/udp && firewall-cmd --reload) || echo "::: FirewallD not enabled"
elif [ -x "$(command -v iptables)" ]; then
echo "::: Configuring iptables for httpd and dnsmasq.."
iptables -A INPUT -p tcp -m tcp --dport 80 -j ACCEPT
iptables -A INPUT -p tcp -m tcp --dport 53 -j ACCEPT
iptables -A INPUT -p udp -m udp --dport 53 -j ACCEPT
else
echo "::: No firewall detected.. skipping firewall configuration."
fi
}
finalExports() {
# Update variables in setupVars.conf file
if [ -e "${setupVars}" ]; then
sed -i.update.bak '/PIHOLE_INTERFACE/d;/IPV4_ADDRESS/d;/IPV6_ADDRESS/d;/PIHOLE_DNS_1/d;/PIHOLE_DNS_2/d;/QUERY_LOGGING/d;' "${setupVars}"
fi
{
echo "PIHOLE_INTERFACE=${PIHOLE_INTERFACE}"
echo "IPV4_ADDRESS=${IPV4_ADDRESS}"
echo "IPV6_ADDRESS=${IPV6_ADDRESS}"
echo "PIHOLE_DNS_1=${PIHOLE_DNS_1}"
echo "PIHOLE_DNS_2=${PIHOLE_DNS_2}"
echo "QUERY_LOGGING=${QUERY_LOGGING}"
}>> "${setupVars}"
}
installPihole() {
# Install base files and web interface
create_pihole_user
if [ ! -d "/var/www/html" ]; then
mkdir -p /var/www/html
fi
chown ${LIGHTTPD_USER}:${LIGHTTPD_GROUP} /var/www/html
chmod 775 /var/www/html
usermod -a -G ${LIGHTTPD_GROUP} pihole
if [ -x "$(command -v lighty-enable-mod)" ]; then
lighty-enable-mod fastcgi fastcgi-php > /dev/null || true
else
printf "\n:::\tWarning: 'lighty-enable-mod' utility not found. Please ensure fastcgi is enabled if you experience issues.\n"
fi
installScripts
installConfigs
CreateLogFile
configureSelinux
installPiholeWeb
installCron
configureFirewall
finalExports
runGravity
}
accountForRefactor() {
# At some point in the future this list can be pruned, for now we'll need it to ensure updates don't break.
# Refactoring of install script has changed the name of a couple of variables. Sort them out here.
sed -i 's/piholeInterface/PIHOLE_INTERFACE/g' ${setupVars}
sed -i 's/IPv4_address/IPV4_ADDRESS/g' ${setupVars}
sed -i 's/IPv4addr/IPV4_ADDRESS/g' ${setupVars}
sed -i 's/IPv6_address/IPV6_ADDRESS/g' ${setupVars}
sed -i 's/piholeIPv6/IPV6_ADDRESS/g' ${setupVars}
sed -i 's/piholeDNS1/PIHOLE_DNS_1/g' ${setupVars}
sed -i 's/piholeDNS2/PIHOLE_DNS_2/g' ${setupVars}
}
updatePihole() {
accountForRefactor
# Source ${setupVars} for use in the rest of the functions.
. ${setupVars}
# Install base files and web interface
installScripts
installConfigs
CreateLogFile
configureSelinux
installPiholeWeb
installCron
configureFirewall
finalExports #re-export setupVars.conf to account for any new vars added in new versions
runGravity
}
configureSelinux() {
if [ -x "$(command -v getenforce)" ]; then
printf "\n::: SELinux Detected\n"
printf ":::\tChecking for SELinux policy development packages..."
package_check_install "selinux-policy-devel" > /dev/null
echo " installed!"
printf ":::\tEnabling httpd server side includes (SSI).. "
setsebool -P httpd_ssi_exec on &> /dev/null && echo "Success" || echo "SELinux not enabled"
printf "\n:::\tCompiling Pi-Hole SELinux policy..\n"
if ! [ -x "$(command -v systemctl)" ]; then
sed -i.bak '/systemd/d' /etc/.pihole/advanced/selinux/pihole.te
fi
checkmodule -M -m -o /etc/pihole/pihole.mod /etc/.pihole/advanced/selinux/pihole.te
semodule_package -o /etc/pihole/pihole.pp -m /etc/pihole/pihole.mod
semodule -i /etc/pihole/pihole.pp
rm -f /etc/pihole/pihole.mod
semodule -l | grep pihole &> /dev/null && echo "::: Installed Pi-Hole SELinux policy" || echo "::: Warning: Pi-Hole SELinux policy did not install."
fi
}
displayFinalMessage() {
if (( ${#1} > 0 )) ; then
# Final completion message to user
whiptail --msgbox --backtitle "Make it so." --title "Installation Complete!" "Configure your devices to use the Pi-hole as their DNS server using:
IPv4: ${IPV4_ADDRESS%/*}
IPv6: ${IPV6_ADDRESS}
If you set a new IP address, you should restart the Pi.
The install log is in /etc/pihole.
View the web interface at http://pi.hole/admin or http://${IPV4_ADDRESS%/*}/admin
The currently set password is ${1}" ${r} ${c}
else
whiptail --msgbox --backtitle "Make it so." --title "Installation Complete!" "Configure your devices to use the Pi-hole as their DNS server using:
IPv4: ${IPV4_ADDRESS%/*}
IPv6: ${IPV6_ADDRESS}
If you set a new IP address, you should restart the Pi.
The install log is in /etc/pihole.
View the web interface at http://pi.hole/admin or http://${IPV4_ADDRESS%/*}/admin" ${r} ${c}
fi
}
update_dialogs() {
# reconfigure
if [ "${reconfigure}" = true ]; then
opt1a="Repair"
opt1b="This will retain existing settings"
strAdd="You will remain on the same version"
else
opt1a="Update"
opt1b="This will retain existing settings."
strAdd="You will be updated to the latest version."
fi
opt2a="Reconfigure"
opt2b="This will allow you to enter new settings"
UpdateCmd=$(whiptail --title "Existing Install Detected!" --menu "\n\nWe have detected an existing install.\n\nPlease choose from the following options: \n($strAdd)" ${r} ${c} 2 \
"${opt1a}" "${opt1b}" \
"${opt2a}" "${opt2b}" 3>&2 2>&1 1>&3)
if [[ $? = 0 ]];then
case ${UpdateCmd} in
${opt1a})
echo "::: ${opt1a} option selected."
useUpdateVars=true
;;
${opt2a})
echo "::: ${opt2a} option selected"
useUpdateVars=false
;;
esac
else
echo "::: Cancel selected. Exiting..."
exit 1
fi
}
main() {
# Check arguments for the undocumented flags
for var in "$@"; do
case "$var" in
"--reconfigure" ) reconfigure=true;;
"--i_do_not_follow_recommendations" ) skipSpaceCheck=false;;
"--unattended" ) runUnattended=true;;
esac
done
if [[ -f ${setupVars} ]]; then
if [[ "${runUnattended}" == true ]]; then
echo "::: --unattended passed to install script, no whiptail dialogs will be displayed"
useUpdateVars=true
else
update_dialogs
fi
fi
# Start the installer
# Verify there is enough disk space for the install
if [[ "${skipSpaceCheck}" == true ]]; then
echo "::: --i_do_not_follow_recommendations passed to script, skipping free disk space verification!"
else
verifyFreeDiskSpace
fi
# Update package cache
update_pacakge_cache
# Notify user of package availability
notify_package_updates_available
# Install packages used by this installation script
install_dependent_packages INSTALLER_DEPS[@]
if [[ "${reconfigure}" == true ]]; then
echo "::: --reconfigure passed to install script. Not downloading/updating local repos"
else
# Get Git files for Core and Admin
getGitFiles ${PI_HOLE_LOCAL_REPO} ${piholeGitUrl}
getGitFiles ${webInterfaceDir} ${webInterfaceGitUrl}
fi
if [[ ${useUpdateVars} == false ]]; then
# Display welcome dialogs
welcomeDialogs
# Create directory for Pi-hole storage
mkdir -p /etc/pihole/
# Remove legacy scripts from previous storage location
remove_legacy_scripts
# Stop resolver and webserver while installing proceses
stop_service dnsmasq
stop_service lighttpd
# Determine available interfaces
get_available_interfaces
# Find interfaces and let the user choose one
chooseInterface
# Let the user decide if they want to block ads over IPv4 and/or IPv6
use4andor6
# Decide what upstream DNS Servers to use
setDNS
# Let the user decide if they want query logging enabled...
setLogging
# Install packages used by the Pi-hole
install_dependent_packages PIHOLE_DEPS[@]
# Install and log everything to a file
installPihole | tee ${tmpLog}
else
# update packages used by the Pi-hole
install_dependent_packages PIHOLE_DEPS[@]
updatePihole | tee ${tmpLog}
fi
# Move the log file into /etc/pihole for storage
mv ${tmpLog} ${instalLogLoc}
# Add password to web UI if there is none
pw=""
if [[ $(grep 'WEBPASSWORD' -c /etc/pihole/setupVars.conf) == 0 ]] ; then
pw=$(tr -dc _A-Z-a-z-0-9 < /dev/urandom | head -c 8)
pihole -a -p ${pw}
fi
if [[ "${useUpdateVars}" == false ]]; then
displayFinalMessage ${pw}
fi
echo "::: Restarting services..."
# Start services
start_service dnsmasq
enable_service dnsmasq
start_service lighttpd
enable_service lighttpd
echo "::: done."
echo ":::"
if [[ "${useUpdateVars}" == false ]]; then
echo "::: Installation Complete! Configure your devices to use the Pi-hole as their DNS server using:"
echo "::: ${IPV4_ADDRESS%/*}"
echo "::: ${IPV6_ADDRESS}"
echo ":::"
echo "::: If you set a new IP address, you should restart the Pi."
echo "::: View the web interface at http://pi.hole/admin or http://${IPV4_ADDRESS%/*}/admin"
else
echo "::: Update complete!"
fi
if (( ${#pw} > 0 )) ; then
echo ":::"
echo "::: Note: As security measure a password has been installed for your web interface"
echo "::: The currently set password is"
echo "::: ${pw}"
echo ":::"
echo "::: You can always change it using"
echo "::: pihole -a -p new_password"
fi
echo ":::"
echo "::: The install log is located at: /etc/pihole/install.log"
}
if [[ "${PH_TEST}" != true ]] ; then
main "$@"
fi
\ No newline at end of file
From 9a626948f8b0b72578a562d16bbbc84d13ea2466 Mon Sep 17 00:00:00 2001
From: Dan Schaper
Date: Tue, 20 Dec 2016 15:39:32 -0800
Subject: [PATCH 221/228] Use debconf for Deb/Ubu package installations.
Signed-off-by: Dan Schaper
Alphabetic sort of dependency names
Signed-off-by: Dan Schaper
---
automated install/basic-install.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/automated install/basic-install.sh b/automated install/basic-install.sh
index d96c7547..c64c3864 100755
--- a/automated install/basic-install.sh
+++ b/automated install/basic-install.sh
@@ -1 +1 @@
-#!/usr/bin/env bash
# Pi-hole: A black hole for Internet advertisements
# (c) 2015, 2016 by Jacob Salmela
# Network-wide ad blocking via your Raspberry Pi
# http://pi-hole.net
# Installs Pi-hole
#
# Pi-hole is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 2 of the License, or
# (at your option) any later version.
# pi-hole.net/donate
#
# Install with this command (from your Pi):
#
# curl -L install.pi-hole.net | bash
set -e
######## VARIABLES #########
tmpLog=/tmp/pihole-install.log
instalLogLoc=/etc/pihole/install.log
setupVars=/etc/pihole/setupVars.conf
webInterfaceGitUrl="https://github.com/pi-hole/AdminLTE.git"
webInterfaceDir="/var/www/html/admin"
piholeGitUrl="https://github.com/pi-hole/pi-hole.git"
PI_HOLE_LOCAL_REPO="/etc/.pihole"
PI_HOLE_FILES=(chronometer list piholeDebug piholeLogFlush setupLCD update version)
useUpdateVars=false
IPV4_ADDRESS=""
IPV6_ADDRESS=""
QUERY_LOGGING=true
# Find the rows and columns will default to 80x24 is it can not be detected
screen_size=$(stty size 2>/dev/null || echo 24 80)
rows=$(echo $screen_size | awk '{print $1}')
columns=$(echo $screen_size | awk '{print $2}')
# Divide by two so the dialogs take up half of the screen, which looks nice.
r=$(( rows / 2 ))
c=$(( columns / 2 ))
# Unless the screen is tiny
r=$(( r < 20 ? 20 : r ))
c=$(( c < 70 ? 70 : c ))
######## Undocumented Flags. Shhh ########
skipSpaceCheck=false
reconfigure=false
runUnattended=false
######## FIRST CHECK ########
# Must be root to install
echo ":::"
if [[ ${EUID} -eq 0 ]]; then
echo "::: You are root."
else
echo "::: Script called with non-root privileges. The Pi-hole installs server packages and configures"
echo "::: system networking, it requires elevated rights. Please check the contents of the script for"
echo "::: any concerns with this requirement. Please be sure to download this script from a trusted source."
echo ":::"
echo "::: Detecting the presence of the sudo utility for continuation of this install..."
if [ -x "$(command -v sudo)" ]; then
echo "::: Utility sudo located."
exec curl -sSL https://install.pi-hole.net | sudo bash "$@"
exit $?
else
echo "::: sudo is needed for the Web interface to run pihole commands. Please run this script as root and it will be automatically installed."
exit 1
fi
fi
# Compatibility
if [[ $(command -v apt-get) ]]; then
#Debian Family
#############################################
PKG_MANAGER="apt-get"
PKG_CACHE="/var/lib/apt/lists/"
UPDATE_PKG_CACHE="${PKG_MANAGER} update"
PKG_UPDATE="${PKG_MANAGER} upgrade"
PKG_INSTALL="${PKG_MANAGER} --yes --fix-missing install"
# grep -c will return 1 retVal on 0 matches, block this throwing the set -e with an OR TRUE
PKG_COUNT="${PKG_MANAGER} -s -o Debug::NoLocking=true upgrade | grep -c ^Inst || true"
# #########################################
# fixes for dependancy differences
# Debian 7 doesn't have iproute2 use iproute
${PKG_MANAGER} install --dry-run iproute2 > /dev/null 2>&1 && IPROUTE_PKG="iproute2" || IPROUTE_PKG="iproute"
# Prefer the php metapackage if it's there, fall back on the php5 pacakges
${PKG_MANAGER} install --dry-run php > /dev/null 2>&1 && phpVer="php" || phpVer="php5"
# #########################################
INSTALLER_DEPS=(apt-utils whiptail git dhcpcd5)
PIHOLE_DEPS=(iputils-ping lsof dnsutils bc dnsmasq lighttpd ${phpVer}-common ${phpVer}-cgi curl unzip wget sudo netcat cron ${IPROUTE_PKG})
LIGHTTPD_USER="www-data"
LIGHTTPD_GROUP="www-data"
LIGHTTPD_CFG="lighttpd.conf.debian"
DNSMASQ_USER="dnsmasq"
package_check_install() {
dpkg-query -W -f='${Status}' "${1}" 2>/dev/null | grep -c "ok installed" || ${PKG_INSTALL} "${1}"
}
elif [ $(command -v rpm) ]; then
# Fedora Family
if [ $(command -v dnf) ]; then
PKG_MANAGER="dnf"
else
PKG_MANAGER="yum"
fi
PKG_CACHE="/var/cache/${PKG_MANAGER}"
UPDATE_PKG_CACHE="${PKG_MANAGER} check-update"
PKG_UPDATE="${PKG_MANAGER} update -y"
PKG_INSTALL="${PKG_MANAGER} install -y"
PKG_COUNT="${PKG_MANAGER} check-update | egrep '(.i686|.x86|.noarch|.arm|.src)' | wc -l"
INSTALLER_DEPS=(iproute net-tools procps-ng newt git)
PIHOLE_DEPS=(epel-release bind-utils bc dnsmasq lighttpd lighttpd-fastcgi php-common php-cli php curl unzip wget findutils cronie sudo nmap-ncat)
if grep -q 'Fedora' /etc/redhat-release; then
remove_deps=(epel-release);
PIHOLE_DEPS=( ${PIHOLE_DEPS[@]/$remove_deps} );
fi
LIGHTTPD_USER="lighttpd"
LIGHTTPD_GROUP="lighttpd"
LIGHTTPD_CFG="lighttpd.conf.fedora"
DNSMASQ_USER="nobody"
package_check_install() {
rpm -qa | grep ^"${1}"- > /dev/null || ${PKG_INSTALL} "${1}"
}
else
echo "OS distribution not supported"
exit
fi
####### FUNCTIONS ##########
is_repo() {
# Use git to check if directory is currently under VCS, return the value
local directory="${1}"
git -C "${directory}" status --short &> /dev/null
return
}
make_repo() {
local directory="${1}"
local remoteRepo="${2}"
# Remove the non-repod interface and clone the interface
echo -n "::: Cloning $remoteRepo into $directory..."
rm -rf "${directory}"
git clone -q --depth 1 "${remoteRepo}" "${directory}" &> /dev/null
echo " done!"
}
update_repo() {
local directory="${1}"
# Pull the latest commits
echo -n "::: Updating repo in $1..."
cd "${directory}" || exit 1
git stash -q &> /dev/null
git pull -q &> /dev/null
echo " done!"
}
getGitFiles() {
# Setup git repos for directory and repository passed
# as arguments 1 and 2
local directory="${1}"
local remoteRepo="${2}"
echo ":::"
echo "::: Checking for existing repository..."
if is_repo "${directory}"; then
update_repo "${directory}"
else
make_repo "${directory}" "${remoteRepo}"
fi
}
find_IPv4_information() {
# Find IP used to route to outside world
IPv4dev=$(ip route get 8.8.8.8 | awk '{for(i=1;i<=NF;i++)if($i~/dev/)print $(i+1)}')
IPV4_ADDRESS=$(ip -o -f inet addr show dev "$IPv4dev" | awk '{print $4}' | awk 'END {print}')
IPv4gw=$(ip route get 8.8.8.8 | awk '{print $3}')
}
get_available_interfaces() {
# Get available interfaces. Consider only getting UP interfaces in the future, and leaving DOWN interfaces out of list.
availableInterfaces=$(ip -o link | awk '{print $2}' | grep -v "lo" | cut -d':' -f1 | cut -d'@' -f1)
}
welcomeDialogs() {
# Display the welcome dialog
whiptail --msgbox --backtitle "Welcome" --title "Pi-hole automated installer" "\n\nThis installer will transform your device into a network-wide ad blocker!" ${r} ${c}
# Support for a part-time dev
whiptail --msgbox --backtitle "Plea" --title "Free and open source" "\n\nThe Pi-hole is free, but powered by your donations: http://pi-hole.net/donate" ${r} ${c}
# Explain the need for a static address
whiptail --msgbox --backtitle "Initiating network interface" --title "Static IP Needed" "\n\nThe Pi-hole is a SERVER so it needs a STATIC IP ADDRESS to function properly.
In the next section, you can choose to use your current network settings (DHCP) or to manually edit them." ${r} ${c}
}
verifyFreeDiskSpace() {
# 50MB is the minimum space needed (45MB install (includes web admin bootstrap/jquery libraries etc) + 5MB one day of logs.)
# - Fourdee: Local ensures the variable is only created, and accessible within this function/void. Generally considered a "good" coding practice for non-global variables.
echo "::: Verifying free disk space..."
local required_free_kilobytes=51200
local existing_free_kilobytes=$(df -Pk | grep -m1 '\/$' | awk '{print $4}')
# - Unknown free disk space , not a integer
if ! [[ "${existing_free_kilobytes}" =~ ^([0-9])+$ ]]; then
echo "::: Unknown free disk space!"
echo "::: We were unable to determine available free disk space on this system."
echo "::: You may override this check and force the installation, however, it is not recommended"
echo "::: To do so, pass the argument '--i_do_not_follow_recommendations' to the install script"
echo "::: eg. curl -L https://install.pi-hole.net | bash /dev/stdin --i_do_not_follow_recommendations"
exit 1
# - Insufficient free disk space
elif [[ ${existing_free_kilobytes} -lt ${required_free_kilobytes} ]]; then
echo "::: Insufficient Disk Space!"
echo "::: Your system appears to be low on disk space. pi-hole recommends a minimum of $required_free_kilobytes KiloBytes."
echo "::: You only have ${existing_free_kilobytes} KiloBytes free."
echo "::: If this is a new install you may need to expand your disk."
echo "::: Try running 'sudo raspi-config', and choose the 'expand file system option'"
echo "::: After rebooting, run this installation again. (curl -L https://install.pi-hole.net | bash)"
echo "Insufficient free space, exiting..."
exit 1
fi
}
chooseInterface() {
# Turn the available interfaces into an array so it can be used with a whiptail dialog
local interfacesArray=()
# Number of available interfaces
local interfaceCount
# Whiptail variable storage
local chooseInterfaceCmd
# Temporary Whiptail options storage
local chooseInterfaceOptions
# Loop sentinel variable
local firstLoop=1
while read -r line; do
mode="OFF"
if [[ ${firstLoop} -eq 1 ]]; then
firstLoop=0
mode="ON"
fi
interfacesArray+=("${line}" "available" "${mode}")
done <<< "${availableInterfaces}"
# Find out how many interfaces are available to choose from
interfaceCount=$(echo "${availableInterfaces}" | wc -l)
chooseInterfaceCmd=(whiptail --separate-output --radiolist "Choose An Interface (press space to select)" ${r} ${c} ${interfaceCount})
chooseInterfaceOptions=$("${chooseInterfaceCmd[@]}" "${interfacesArray[@]}" 2>&1 >/dev/tty)
if [[ $? = 0 ]]; then
for desiredInterface in ${chooseInterfaceOptions}; do
PIHOLE_INTERFACE=${desiredInterface}
echo "::: Using interface: $PIHOLE_INTERFACE"
done
else
echo "::: Cancel selected, exiting...."
exit 1
fi
}
useIPv6dialog() {
# Show the IPv6 address used for blocking
IPV6_ADDRESS=$(ip -6 route get 2001:4860:4860::8888 | awk -F " " '{ for(i=1;i<=NF;i++) if ($i == "src") print $(i+1) }')
whiptail --msgbox --backtitle "IPv6..." --title "IPv6 Supported" "$IPV6_ADDRESS will be used to block ads." ${r} ${c}
}
use4andor6() {
local useIPv4
local useIPv6
# Let use select IPv4 and/or IPv6
cmd=(whiptail --separate-output --checklist "Select Protocols (press space to select)" ${r} ${c} 2)
options=(IPv4 "Block ads over IPv4" on
IPv6 "Block ads over IPv6" on)
choices=$("${cmd[@]}" "${options[@]}" 2>&1 >/dev/tty)
if [[ $? = 0 ]];then
for choice in ${choices}
do
case ${choice} in
IPv4 ) useIPv4=true;;
IPv6 ) useIPv6=true;;
esac
done
if [[ ${useIPv4} ]]; then
find_IPv4_information
getStaticIPv4Settings
setStaticIPv4
fi
if [[ ${useIPv6} ]]; then
useIPv6dialog
fi
echo "::: IPv4 address: ${IPV4_ADDRESS}"
echo "::: IPv6 address: ${IPV6_ADDRESS}"
if [ ! ${useIPv4} ] && [ ! ${useIPv6} ]; then
echo "::: Cannot continue, neither IPv4 or IPv6 selected"
echo "::: Exiting"
exit 1
fi
else
echo "::: Cancel selected. Exiting..."
exit 1
fi
}
getStaticIPv4Settings() {
# Ask if the user wants to use DHCP settings as their static IP
if (whiptail --backtitle "Calibrating network interface" --title "Static IP Address" --yesno "Do you want to use your current network settings as a static address?
IP address: ${IPV4_ADDRESS}
Gateway: ${IPv4gw}" ${r} ${c}); then
# If they choose yes, let the user know that the IP address will not be available via DHCP and may cause a conflict.
whiptail --msgbox --backtitle "IP information" --title "FYI: IP Conflict" "It is possible your router could still try to assign this IP to a device, which would cause a conflict. But in most cases the router is smart enough to not do that.
If you are worried, either manually set the address, or modify the DHCP reservation pool so it does not include the IP you want.
It is also possible to use a DHCP reservation, but if you are going to do that, you might as well set a static address." ${r} ${c}
# Nothing else to do since the variables are already set above
else
# Otherwise, we need to ask the user to input their desired settings.
# Start by getting the IPv4 address (pre-filling it with info gathered from DHCP)
# Start a loop to let the user enter their information with the chance to go back and edit it if necessary
until [[ ${ipSettingsCorrect} = True ]]; do
# Ask for the IPv4 address
IPV4_ADDRESS=$(whiptail --backtitle "Calibrating network interface" --title "IPv4 address" --inputbox "Enter your desired IPv4 address" ${r} ${c} "${IPV4_ADDRESS}" 3>&1 1>&2 2>&3)
if [[ $? = 0 ]]; then
echo "::: Your static IPv4 address: ${IPV4_ADDRESS}"
# Ask for the gateway
IPv4gw=$(whiptail --backtitle "Calibrating network interface" --title "IPv4 gateway (router)" --inputbox "Enter your desired IPv4 default gateway" ${r} ${c} "${IPv4gw}" 3>&1 1>&2 2>&3)
if [[ $? = 0 ]]; then
echo "::: Your static IPv4 gateway: ${IPv4gw}"
# Give the user a chance to review their settings before moving on
if (whiptail --backtitle "Calibrating network interface" --title "Static IP Address" --yesno "Are these settings correct?
IP address: ${IPV4_ADDRESS}
Gateway: ${IPv4gw}" ${r} ${c}); then
# After that's done, the loop ends and we move on
ipSettingsCorrect=True
else
# If the settings are wrong, the loop continues
ipSettingsCorrect=False
fi
else
# Cancelling gateway settings window
ipSettingsCorrect=False
echo "::: Cancel selected. Exiting..."
exit 1
fi
else
# Cancelling IPv4 settings window
ipSettingsCorrect=False
echo "::: Cancel selected. Exiting..."
exit 1
fi
done
# End the if statement for DHCP vs. static
fi
}
setDHCPCD() {
# Append these lines to dhcpcd.conf to enable a static IP
echo "## interface ${PIHOLE_INTERFACE}
static ip_address=${IPV4_ADDRESS}
static routers=${IPv4gw}
static domain_name_servers=${IPv4gw}" | tee -a /etc/dhcpcd.conf >/dev/null
}
setStaticIPv4() {
local IFCFG_FILE
local IPADDR
local CIDR
if [[ -f /etc/dhcpcd.conf ]]; then
# Debian Family
if grep -q "${IPV4_ADDRESS}" /etc/dhcpcd.conf; then
echo "::: Static IP already configured"
else
setDHCPCD
ip addr replace dev "${PIHOLE_INTERFACE}" "${IPV4_ADDRESS}"
echo ":::"
echo "::: Setting IP to ${IPV4_ADDRESS}. You may need to restart after the install is complete."
echo ":::"
fi
elif [[ -f /etc/sysconfig/network-scripts/ifcfg-${PIHOLE_INTERFACE} ]];then
# Fedora Family
IFCFG_FILE=/etc/sysconfig/network-scripts/ifcfg-${PIHOLE_INTERFACE}
if grep -q "${IPV4_ADDRESS}" "${IFCFG_FILE}"; then
echo "::: Static IP already configured"
else
IPADDR=$(echo "${IPV4_ADDRESS}" | cut -f1 -d/)
CIDR=$(echo "${IPV4_ADDRESS}" | cut -f2 -d/)
# Backup existing interface configuration:
cp "${IFCFG_FILE}" "${IFCFG_FILE}".pihole.orig
# Build Interface configuration file:
{
echo "# Configured via Pi-Hole installer"
echo "DEVICE=$PIHOLE_INTERFACE"
echo "BOOTPROTO=none"
echo "ONBOOT=yes"
echo "IPADDR=$IPADDR"
echo "PREFIX=$CIDR"
echo "GATEWAY=$IPv4gw"
echo "DNS1=$PIHOLE_DNS_1"
echo "DNS2=$PIHOLE_DNS_2"
echo "USERCTL=no"
}> "${IFCFG_FILE}"
ip addr replace dev "${PIHOLE_INTERFACE}" "${IPV4_ADDRESS}"
if [ -x "$(command -v nmcli)" ];then
# Tell NetworkManager to read our new sysconfig file
nmcli con load "${IFCFG_FILE}" > /dev/null
fi
echo ":::"
echo "::: Setting IP to ${IPV4_ADDRESS}. You may need to restart after the install is complete."
echo ":::"
fi
else
echo "::: Warning: Unable to locate configuration file to set static IPv4 address!"
exit 1
fi
}
valid_ip() {
local ip=${1}
local stat=1
if [[ ${ip} =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then
OIFS=$IFS
IFS='.'
ip=(${ip})
IFS=${OIFS}
[[ ${ip[0]} -le 255 && ${ip[1]} -le 255 \
&& ${ip[2]} -le 255 && ${ip[3]} -le 255 ]]
stat=$?
fi
return ${stat}
}
setDNS() {
DNSChooseCmd=(whiptail --separate-output --radiolist "Select Upstream DNS Provider. To use your own, select Custom." ${r} ${c} 6)
DNSChooseOptions=(Google "" on
OpenDNS "" off
Level3 "" off
Norton "" off
Comodo "" off
Custom "" off)
DNSchoices=$("${DNSChooseCmd[@]}" "${DNSChooseOptions[@]}" 2>&1 >/dev/tty)
if [[ $? = 0 ]];then
case ${DNSchoices} in
Google)
echo "::: Using Google DNS servers."
PIHOLE_DNS_1="8.8.8.8"
PIHOLE_DNS_2="8.8.4.4"
;;
OpenDNS)
echo "::: Using OpenDNS servers."
PIHOLE_DNS_1="208.67.222.222"
PIHOLE_DNS_2="208.67.220.220"
;;
Level3)
echo "::: Using Level3 servers."
PIHOLE_DNS_1="4.2.2.1"
PIHOLE_DNS_2="4.2.2.2"
;;
Norton)
echo "::: Using Norton ConnectSafe servers."
PIHOLE_DNS_1="199.85.126.10"
PIHOLE_DNS_2="199.85.127.10"
;;
Comodo)
echo "::: Using Comodo Secure servers."
PIHOLE_DNS_1="8.26.56.26"
PIHOLE_DNS_2="8.20.247.20"
;;
Custom)
until [[ ${DNSSettingsCorrect} = True ]]; do
strInvalid="Invalid"
if [ ! ${PIHOLE_DNS_1} ]; then
if [ ! ${PIHOLE_DNS_2} ]; then
prePopulate=""
else
prePopulate=", ${PIHOLE_DNS_2}"
fi
elif [ ${PIHOLE_DNS_1} ] && [ ! ${PIHOLE_DNS_2} ]; then
prePopulate="${PIHOLE_DNS_1}"
elif [ ${PIHOLE_DNS_1} ] && [ ${PIHOLE_DNS_2} ]; then
prePopulate="${PIHOLE_DNS_1}, ${PIHOLE_DNS_2}"
fi
piholeDNS=$(whiptail --backtitle "Specify Upstream DNS Provider(s)" --inputbox "Enter your desired upstream DNS provider(s), seperated by a comma.\n\nFor example '8.8.8.8, 8.8.4.4'" ${r} ${c} "${prePopulate}" 3>&1 1>&2 2>&3)
if [[ $? = 0 ]]; then
PIHOLE_DNS_1=$(echo "${piholeDNS}" | sed 's/[, \t]\+/,/g' | awk -F, '{print$1}')
PIHOLE_DNS_2=$(echo "${piholeDNS}" | sed 's/[, \t]\+/,/g' | awk -F, '{print$2}')
if ! valid_ip "${PIHOLE_DNS_1}" || [ ! "${PIHOLE_DNS_1}" ]; then
PIHOLE_DNS_1=${strInvalid}
fi
if ! valid_ip "${PIHOLE_DNS_2}" && [ "${PIHOLE_DNS_2}" ]; then
PIHOLE_DNS_2=${strInvalid}
fi
else
echo "::: Cancel selected, exiting...."
exit 1
fi
if [[ ${PIHOLE_DNS_1} == "${strInvalid}" ]] || [[ ${PIHOLE_DNS_2} == "${strInvalid}" ]]; then
whiptail --msgbox --backtitle "Invalid IP" --title "Invalid IP" "One or both entered IP addresses were invalid. Please try again.\n\n DNS Server 1: $PIHOLE_DNS_1\n DNS Server 2: ${PIHOLE_DNS_2}" ${r} ${c}
if [[ ${PIHOLE_DNS_1} == "${strInvalid}" ]]; then
PIHOLE_DNS_1=""
fi
if [[ ${PIHOLE_DNS_2} == "${strInvalid}" ]]; then
PIHOLE_DNS_2=""
fi
DNSSettingsCorrect=False
else
if (whiptail --backtitle "Specify Upstream DNS Provider(s)" --title "Upstream DNS Provider(s)" --yesno "Are these settings correct?\n DNS Server 1: $PIHOLE_DNS_1\n DNS Server 2: ${PIHOLE_DNS_2}" ${r} ${c}); then
DNSSettingsCorrect=True
else
# If the settings are wrong, the loop continues
DNSSettingsCorrect=False
fi
fi
done
;;
esac
else
echo "::: Cancel selected. Exiting..."
exit 1
fi
}
setLogging() {
local LogToggleCommand
local LogChooseOptions
local LogChoices
LogToggleCommand=(whiptail --separate-output --radiolist "Do you want to log queries?\n (Disabling will render graphs on the Admin page useless):" ${r} ${c} 6)
LogChooseOptions=("On (Reccomended)" "" on
Off "" off)
LogChoices=$("${LogToggleCommand[@]}" "${LogChooseOptions[@]}" 2>&1 >/dev/tty) || (echo "::: Cancel selected. Exiting..." && exit 1)
case ${LogChoices} in
"On (Recommended)")
echo "::: Logging On."
QUERY_LOGGING=true
;;
Off)
echo "::: Logging Off."
QUERY_LOGGING=false
;;
esac
}
version_check_dnsmasq() {
# Check if /etc/dnsmasq.conf is from pihole. If so replace with an original and install new in .d directory
local dnsmasq_conf="/etc/dnsmasq.conf"
local dnsmasq_conf_orig="/etc/dnsmasq.conf.orig"
local dnsmasq_pihole_id_string="addn-hosts=/etc/pihole/gravity.list"
local dnsmasq_original_config="/etc/.pihole/advanced/dnsmasq.conf.original"
local dnsmasq_pihole_01_snippet="/etc/.pihole/advanced/01-pihole.conf"
local dnsmasq_pihole_01_location="/etc/dnsmasq.d/01-pihole.conf"
if [ -f ${dnsmasq_conf} ]; then
echo -n "::: Existing dnsmasq.conf found..."
if grep -q ${dnsmasq_pihole_id_string} ${dnsmasq_conf}; then
echo " it is from a previous pi-hole install."
echo -n "::: Backing up dnsmasq.conf to dnsmasq.conf.orig..."
mv -f ${dnsmasq_conf} ${dnsmasq_conf_orig}
echo " done."
echo -n "::: Restoring default dnsmasq.conf..."
cp ${dnsmasq_original_config} ${dnsmasq_conf}
echo " done."
else
echo " it is not a pi-hole file, leaving alone!"
fi
else
echo -n "::: No dnsmasq.conf found.. restoring default dnsmasq.conf..."
cp ${dnsmasq_original_config} ${dnsmasq_conf}
echo " done."
fi
echo -n "::: Copying 01-pihole.conf to /etc/dnsmasq.d/01-pihole.conf..."
cp ${dnsmasq_pihole_01_snippet} ${dnsmasq_pihole_01_location}
echo " done."
sed -i "s/@INT@/$PIHOLE_INTERFACE/" ${dnsmasq_pihole_01_location}
if [[ "${PIHOLE_DNS_1}" != "" ]]; then
sed -i "s/@DNS1@/$PIHOLE_DNS_1/" ${dnsmasq_pihole_01_location}
else
sed -i '/^server=@DNS1@/d' ${dnsmasq_pihole_01_location}
fi
if [[ "${PIHOLE_DNS_2}" != "" ]]; then
sed -i "s/@DNS2@/$PIHOLE_DNS_2/" ${dnsmasq_pihole_01_location}
else
sed -i '/^server=@DNS2@/d' ${dnsmasq_pihole_01_location}
fi
sed -i 's/^#conf-dir=\/etc\/dnsmasq.d$/conf-dir=\/etc\/dnsmasq.d/' ${dnsmasq_conf}
if [[ "${QUERY_LOGGING}" == false ]] ; then
#Disable Logging
sed -i 's/^log-queries/#log-queries/' ${dnsmasq_pihole_01_location}
else
#Enable Logging
sed -i 's/^#log-queries/log-queries/' ${dnsmasq_pihole_01_location}
fi
}
remove_legacy_scripts() {
#Tidy up /usr/local/bin directory if installing over previous install.
oldFiles=( gravity chronometer whitelist blacklist piholeLogFlush updateDashboard uninstall setupLCD piholeDebug)
for i in "${oldFiles[@]}"; do
if [ -f "/usr/local/bin/$i.sh" ]; then
rm /usr/local/bin/"$i".sh
fi
done
}
clean_existing() {
# Clean an exiting installation to prepare for upgrade/reinstall
# ${1} Directory to clean; ${2} Array of files to remove
local clean_directory="${1}"
local old_files=${2}
for script in "${old_files[@]}"; do
rm -f "${clean_directory}${script}.sh"
done
}
installScripts() {
# Install the scripts from repository to their various locations
readonly install_dir="/opt/pihole/"
echo ":::"
echo -n "::: Installing scripts from ${PI_HOLE_LOCAL_REPO}..."
# Clear out script files from Pi-hole scripts directory.
clean_existing "${install_dir}" "${PI_HOLE_FILES}"
# Install files from local core repository
if is_repo "${PI_HOLE_LOCAL_REPO}"; then
cd "${PI_HOLE_LOCAL_REPO}"
install -o "${USER}" -Dm755 -t /opt/pihole/ gravity.sh
install -o "${USER}" -Dm755 -t /opt/pihole/ ./advanced/Scripts/*.sh
install -o "${USER}" -Dm755 -t /opt/pihole/ ./automated\ install/uninstall.sh
install -o "${USER}" -Dm755 -t /usr/local/bin/ pihole
install -Dm644 ./advanced/bash-completion/pihole /etc/bash_completion.d/pihole
echo " done."
else
echo " *** ERROR: Local repo ${core_repo} not found, exiting."
exit 1
fi
}
installConfigs() {
# Install the configs from /etc/.pihole to their various locations
echo ":::"
echo "::: Installing configs..."
version_check_dnsmasq
if [ ! -d "/etc/lighttpd" ]; then
mkdir /etc/lighttpd
chown "${USER}":root /etc/lighttpd
elif [ -f "/etc/lighttpd/lighttpd.conf" ]; then
mv /etc/lighttpd/lighttpd.conf /etc/lighttpd/lighttpd.conf.orig
fi
cp /etc/.pihole/advanced/${LIGHTTPD_CFG} /etc/lighttpd/lighttpd.conf
mkdir -p /var/run/lighttpd
chown ${LIGHTTPD_USER}:${LIGHTTPD_GROUP} /var/run/lighttpd
mkdir -p /var/cache/lighttpd/compress
chown ${LIGHTTPD_USER}:${LIGHTTPD_GROUP} /var/cache/lighttpd/compress
mkdir -p /var/cache/lighttpd/uploads
chown ${LIGHTTPD_USER}:${LIGHTTPD_GROUP} /var/cache/lighttpd/uploads
}
stop_service() {
# Stop service passed in as argument.
# Can softfail, as process may not be installed when this is called
echo ":::"
echo -n "::: Stopping ${1} service..."
if [ -x "$(command -v systemctl)" ]; then
systemctl stop "${1}" &> /dev/null || true
else
service "${1}" stop &> /dev/null || true
fi
echo " done."
}
start_service() {
# Start/Restart service passed in as argument
# This should not fail, it's an error if it does
echo ":::"
echo -n "::: Starting ${1} service..."
if [ -x "$(command -v systemctl)" ]; then
systemctl restart "${1}" &> /dev/null
else
service "${1}" restart &> /dev/null
fi
echo " done."
}
enable_service() {
# Enable service so that it will start with next reboot
echo ":::"
echo -n "::: Enabling ${1} service to start on reboot..."
if [ -x "$(command -v systemctl)" ]; then
systemctl enable "${1}" &> /dev/null
else
update-rc.d "${1}" defaults &> /dev/null
fi
echo " done."
}
update_pacakge_cache() {
#Running apt-get update/upgrade with minimal output can cause some issues with
#requiring user input (e.g password for phpmyadmin see #218)
#Check to see if apt-get update has already been run today
#it needs to have been run at least once on new installs!
timestamp=$(stat -c %Y ${PKG_CACHE})
timestampAsDate=$(date -d @"${timestamp}" "+%b %e")
today=$(date "+%b %e")
if [ ! "${today}" == "${timestampAsDate}" ]; then
#update package lists
echo ":::"
echo -n "::: ${PKG_MANAGER} update has not been run today. Running now..."
${UPDATE_PKG_CACHE} &> /dev/null
echo " done!"
fi
}
notify_package_updates_available() {
# Let user know if they have outdated packages on their system and
# advise them to run a package update at soonest possible.
echo ":::"
echo -n "::: Checking ${PKG_MANAGER} for upgraded packages...."
updatesToInstall=$(eval "${PKG_COUNT}")
echo " done!"
echo ":::"
if [[ ${updatesToInstall} -eq "0" ]]; then
echo "::: Your system is up to date! Continuing with Pi-hole installation..."
else
echo "::: There are ${updatesToInstall} updates available for your system!"
echo "::: We recommend you run '${PKG_UPDATE}' after installing Pi-Hole! "
echo ":::"
fi
}
install_dependent_packages() {
# Install packages passed in via argument array
# No spinner - conflicts with set -e
declare -a argArray1=("${!1}")
for i in "${argArray1[@]}"; do
echo -n "::: Checking for $i..."
package_check_install "${i}" &> /dev/null
echo " installed!"
done
}
CreateLogFile() {
# Create logfiles if necessary
echo ":::"
echo -n "::: Creating log file and changing owner to dnsmasq..."
if [ ! -f /var/log/pihole.log ]; then
touch /var/log/pihole.log
chmod 644 /var/log/pihole.log
chown "${DNSMASQ_USER}":root /var/log/pihole.log
echo " done!"
else
echo " already exists!"
fi
}
installPiholeWeb() {
# Install the web interface
echo ":::"
echo "::: Installing pihole custom index page..."
if [ -d "/var/www/html/pihole" ]; then
if [ -f "/var/www/html/pihole/index.html" ]; then
echo "::: Existing index.html detected, not overwriting"
else
echo -n "::: index.html missing, replacing... "
cp /etc/.pihole/advanced/index.html /var/www/html/pihole/
echo " done!"
fi
if [ -f "/var/www/html/pihole/index.js" ]; then
echo "::: Existing index.js detected, not overwriting"
else
echo -n "::: index.js missing, replacing... "
cp /etc/.pihole/advanced/index.js /var/www/html/pihole/
echo " done!"
fi
else
mkdir /var/www/html/pihole
if [ -f /var/www/html/index.lighttpd.html ]; then
mv /var/www/html/index.lighttpd.html /var/www/html/index.lighttpd.orig
else
printf "\n:::\tNo default index.lighttpd.html file found... not backing up"
fi
cp /etc/.pihole/advanced/index.* /var/www/html/pihole/.
echo " done!"
fi
# Install Sudoer file
echo ":::"
echo -n "::: Installing sudoer file..."
mkdir -p /etc/sudoers.d/
cp /etc/.pihole/advanced/pihole.sudo /etc/sudoers.d/pihole
chmod 0440 /etc/sudoers.d/pihole
echo " done!"
}
installCron() {
# Install the cron job
echo ":::"
echo -n "::: Installing latest Cron script..."
cp /etc/.pihole/advanced/pihole.cron /etc/cron.d/pihole
echo " done!"
}
runGravity() {
# Run gravity.sh to build blacklists
echo ":::"
echo "::: Preparing to run gravity.sh to refresh hosts..."
if ls /etc/pihole/list* 1> /dev/null 2>&1; then
echo "::: Cleaning up previous install (preserving whitelist/blacklist)"
rm /etc/pihole/list.*
fi
echo "::: Running gravity.sh"
/opt/pihole/gravity.sh
}
create_pihole_user() {
# Check if user pihole exists and create if not
echo "::: Checking if user 'pihole' exists..."
id -u pihole &> /dev/null && echo "::: User 'pihole' already exists" || (echo "::: User 'pihole' doesn't exist. Creating..." && useradd -r -s /usr/sbin/nologin pihole)
}
configureFirewall() {
# Allow HTTP and DNS traffic
if [ -x "$(command -v firewall-cmd)" ]; then
firewall-cmd --state &> /dev/null && ( echo "::: Configuring firewalld for httpd and dnsmasq.." && firewall-cmd --permanent --add-port=80/tcp && firewall-cmd --permanent --add-port=53/tcp \
&& firewall-cmd --permanent --add-port=53/udp && firewall-cmd --reload) || echo "::: FirewallD not enabled"
elif [ -x "$(command -v iptables)" ]; then
echo "::: Configuring iptables for httpd and dnsmasq.."
iptables -A INPUT -p tcp -m tcp --dport 80 -j ACCEPT
iptables -A INPUT -p tcp -m tcp --dport 53 -j ACCEPT
iptables -A INPUT -p udp -m udp --dport 53 -j ACCEPT
else
echo "::: No firewall detected.. skipping firewall configuration."
fi
}
finalExports() {
# Update variables in setupVars.conf file
if [ -e "${setupVars}" ]; then
sed -i.update.bak '/PIHOLE_INTERFACE/d;/IPV4_ADDRESS/d;/IPV6_ADDRESS/d;/PIHOLE_DNS_1/d;/PIHOLE_DNS_2/d;/QUERY_LOGGING/d;' "${setupVars}"
fi
{
echo "PIHOLE_INTERFACE=${PIHOLE_INTERFACE}"
echo "IPV4_ADDRESS=${IPV4_ADDRESS}"
echo "IPV6_ADDRESS=${IPV6_ADDRESS}"
echo "PIHOLE_DNS_1=${PIHOLE_DNS_1}"
echo "PIHOLE_DNS_2=${PIHOLE_DNS_2}"
echo "QUERY_LOGGING=${QUERY_LOGGING}"
}>> "${setupVars}"
}
installPihole() {
# Install base files and web interface
create_pihole_user
if [ ! -d "/var/www/html" ]; then
mkdir -p /var/www/html
fi
chown ${LIGHTTPD_USER}:${LIGHTTPD_GROUP} /var/www/html
chmod 775 /var/www/html
usermod -a -G ${LIGHTTPD_GROUP} pihole
if [ -x "$(command -v lighty-enable-mod)" ]; then
lighty-enable-mod fastcgi fastcgi-php > /dev/null || true
else
printf "\n:::\tWarning: 'lighty-enable-mod' utility not found. Please ensure fastcgi is enabled if you experience issues.\n"
fi
installScripts
installConfigs
CreateLogFile
configureSelinux
installPiholeWeb
installCron
configureFirewall
finalExports
runGravity
}
accountForRefactor() {
# At some point in the future this list can be pruned, for now we'll need it to ensure updates don't break.
# Refactoring of install script has changed the name of a couple of variables. Sort them out here.
sed -i 's/piholeInterface/PIHOLE_INTERFACE/g' ${setupVars}
sed -i 's/IPv4_address/IPV4_ADDRESS/g' ${setupVars}
sed -i 's/IPv4addr/IPV4_ADDRESS/g' ${setupVars}
sed -i 's/IPv6_address/IPV6_ADDRESS/g' ${setupVars}
sed -i 's/piholeIPv6/IPV6_ADDRESS/g' ${setupVars}
sed -i 's/piholeDNS1/PIHOLE_DNS_1/g' ${setupVars}
sed -i 's/piholeDNS2/PIHOLE_DNS_2/g' ${setupVars}
}
updatePihole() {
accountForRefactor
# Source ${setupVars} for use in the rest of the functions.
. ${setupVars}
# Install base files and web interface
installScripts
installConfigs
CreateLogFile
configureSelinux
installPiholeWeb
installCron
configureFirewall
finalExports #re-export setupVars.conf to account for any new vars added in new versions
runGravity
}
configureSelinux() {
if [ -x "$(command -v getenforce)" ]; then
printf "\n::: SELinux Detected\n"
printf ":::\tChecking for SELinux policy development packages..."
package_check_install "selinux-policy-devel" > /dev/null
echo " installed!"
printf ":::\tEnabling httpd server side includes (SSI).. "
setsebool -P httpd_ssi_exec on &> /dev/null && echo "Success" || echo "SELinux not enabled"
printf "\n:::\tCompiling Pi-Hole SELinux policy..\n"
if ! [ -x "$(command -v systemctl)" ]; then
sed -i.bak '/systemd/d' /etc/.pihole/advanced/selinux/pihole.te
fi
checkmodule -M -m -o /etc/pihole/pihole.mod /etc/.pihole/advanced/selinux/pihole.te
semodule_package -o /etc/pihole/pihole.pp -m /etc/pihole/pihole.mod
semodule -i /etc/pihole/pihole.pp
rm -f /etc/pihole/pihole.mod
semodule -l | grep pihole &> /dev/null && echo "::: Installed Pi-Hole SELinux policy" || echo "::: Warning: Pi-Hole SELinux policy did not install."
fi
}
displayFinalMessage() {
if (( ${#1} > 0 )) ; then
# Final completion message to user
whiptail --msgbox --backtitle "Make it so." --title "Installation Complete!" "Configure your devices to use the Pi-hole as their DNS server using:
IPv4: ${IPV4_ADDRESS%/*}
IPv6: ${IPV6_ADDRESS}
If you set a new IP address, you should restart the Pi.
The install log is in /etc/pihole.
View the web interface at http://pi.hole/admin or http://${IPV4_ADDRESS%/*}/admin
The currently set password is ${1}" ${r} ${c}
else
whiptail --msgbox --backtitle "Make it so." --title "Installation Complete!" "Configure your devices to use the Pi-hole as their DNS server using:
IPv4: ${IPV4_ADDRESS%/*}
IPv6: ${IPV6_ADDRESS}
If you set a new IP address, you should restart the Pi.
The install log is in /etc/pihole.
View the web interface at http://pi.hole/admin or http://${IPV4_ADDRESS%/*}/admin" ${r} ${c}
fi
}
update_dialogs() {
# reconfigure
if [ "${reconfigure}" = true ]; then
opt1a="Repair"
opt1b="This will retain existing settings"
strAdd="You will remain on the same version"
else
opt1a="Update"
opt1b="This will retain existing settings."
strAdd="You will be updated to the latest version."
fi
opt2a="Reconfigure"
opt2b="This will allow you to enter new settings"
UpdateCmd=$(whiptail --title "Existing Install Detected!" --menu "\n\nWe have detected an existing install.\n\nPlease choose from the following options: \n($strAdd)" ${r} ${c} 2 \
"${opt1a}" "${opt1b}" \
"${opt2a}" "${opt2b}" 3>&2 2>&1 1>&3)
if [[ $? = 0 ]];then
case ${UpdateCmd} in
${opt1a})
echo "::: ${opt1a} option selected."
useUpdateVars=true
;;
${opt2a})
echo "::: ${opt2a} option selected"
useUpdateVars=false
;;
esac
else
echo "::: Cancel selected. Exiting..."
exit 1
fi
}
main() {
# Check arguments for the undocumented flags
for var in "$@"; do
case "$var" in
"--reconfigure" ) reconfigure=true;;
"--i_do_not_follow_recommendations" ) skipSpaceCheck=false;;
"--unattended" ) runUnattended=true;;
esac
done
if [[ -f ${setupVars} ]]; then
if [[ "${runUnattended}" == true ]]; then
echo "::: --unattended passed to install script, no whiptail dialogs will be displayed"
useUpdateVars=true
else
update_dialogs
fi
fi
# Start the installer
# Verify there is enough disk space for the install
if [[ "${skipSpaceCheck}" == true ]]; then
echo "::: --i_do_not_follow_recommendations passed to script, skipping free disk space verification!"
else
verifyFreeDiskSpace
fi
# Update package cache
update_pacakge_cache
# Notify user of package availability
notify_package_updates_available
# Install packages used by this installation script
install_dependent_packages INSTALLER_DEPS[@]
if [[ "${reconfigure}" == true ]]; then
echo "::: --reconfigure passed to install script. Not downloading/updating local repos"
else
# Get Git files for Core and Admin
getGitFiles ${PI_HOLE_LOCAL_REPO} ${piholeGitUrl}
getGitFiles ${webInterfaceDir} ${webInterfaceGitUrl}
fi
if [[ ${useUpdateVars} == false ]]; then
# Display welcome dialogs
welcomeDialogs
# Create directory for Pi-hole storage
mkdir -p /etc/pihole/
# Remove legacy scripts from previous storage location
remove_legacy_scripts
# Stop resolver and webserver while installing proceses
stop_service dnsmasq
stop_service lighttpd
# Determine available interfaces
get_available_interfaces
# Find interfaces and let the user choose one
chooseInterface
# Let the user decide if they want to block ads over IPv4 and/or IPv6
use4andor6
# Decide what upstream DNS Servers to use
setDNS
# Let the user decide if they want query logging enabled...
setLogging
# Install packages used by the Pi-hole
install_dependent_packages PIHOLE_DEPS[@]
# Install and log everything to a file
installPihole | tee ${tmpLog}
else
# update packages used by the Pi-hole
install_dependent_packages PIHOLE_DEPS[@]
updatePihole | tee ${tmpLog}
fi
# Move the log file into /etc/pihole for storage
mv ${tmpLog} ${instalLogLoc}
# Add password to web UI if there is none
pw=""
if [[ $(grep 'WEBPASSWORD' -c /etc/pihole/setupVars.conf) == 0 ]] ; then
pw=$(tr -dc _A-Z-a-z-0-9 < /dev/urandom | head -c 8)
pihole -a -p ${pw}
fi
if [[ "${useUpdateVars}" == false ]]; then
displayFinalMessage ${pw}
fi
echo "::: Restarting services..."
# Start services
start_service dnsmasq
enable_service dnsmasq
start_service lighttpd
enable_service lighttpd
echo "::: done."
echo ":::"
if [[ "${useUpdateVars}" == false ]]; then
echo "::: Installation Complete! Configure your devices to use the Pi-hole as their DNS server using:"
echo "::: ${IPV4_ADDRESS%/*}"
echo "::: ${IPV6_ADDRESS}"
echo ":::"
echo "::: If you set a new IP address, you should restart the Pi."
echo "::: View the web interface at http://pi.hole/admin or http://${IPV4_ADDRESS%/*}/admin"
else
echo "::: Update complete!"
fi
if (( ${#pw} > 0 )) ; then
echo ":::"
echo "::: Note: As security measure a password has been installed for your web interface"
echo "::: The currently set password is"
echo "::: ${pw}"
echo ":::"
echo "::: You can always change it using"
echo "::: pihole -a -p new_password"
fi
echo ":::"
echo "::: The install log is located at: /etc/pihole/install.log"
}
if [[ "${PH_TEST}" != true ]] ; then
main "$@"
fi
\ No newline at end of file
+#!/usr/bin/env bash
# Pi-hole: A black hole for Internet advertisements
# (c) 2015, 2016 by Jacob Salmela
# Network-wide ad blocking via your Raspberry Pi
# http://pi-hole.net
# Installs Pi-hole
#
# Pi-hole is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 2 of the License, or
# (at your option) any later version.
# pi-hole.net/donate
#
# Install with this command (from your Pi):
#
# curl -L install.pi-hole.net | bash
set -e
######## VARIABLES #########
tmpLog=/tmp/pihole-install.log
instalLogLoc=/etc/pihole/install.log
setupVars=/etc/pihole/setupVars.conf
webInterfaceGitUrl="https://github.com/pi-hole/AdminLTE.git"
webInterfaceDir="/var/www/html/admin"
piholeGitUrl="https://github.com/pi-hole/pi-hole.git"
PI_HOLE_LOCAL_REPO="/etc/.pihole"
PI_HOLE_FILES=(chronometer list piholeDebug piholeLogFlush setupLCD update version)
useUpdateVars=false
IPV4_ADDRESS=""
IPV6_ADDRESS=""
QUERY_LOGGING=true
# Find the rows and columns will default to 80x24 is it can not be detected
screen_size=$(stty size 2>/dev/null || echo 24 80)
rows=$(echo $screen_size | awk '{print $1}')
columns=$(echo $screen_size | awk '{print $2}')
# Divide by two so the dialogs take up half of the screen, which looks nice.
r=$(( rows / 2 ))
c=$(( columns / 2 ))
# Unless the screen is tiny
r=$(( r < 20 ? 20 : r ))
c=$(( c < 70 ? 70 : c ))
######## Undocumented Flags. Shhh ########
skipSpaceCheck=false
reconfigure=false
runUnattended=false
######## FIRST CHECK ########
# Must be root to install
echo ":::"
if [[ ${EUID} -eq 0 ]]; then
echo "::: You are root."
else
echo "::: Script called with non-root privileges. The Pi-hole installs server packages and configures"
echo "::: system networking, it requires elevated rights. Please check the contents of the script for"
echo "::: any concerns with this requirement. Please be sure to download this script from a trusted source."
echo ":::"
echo "::: Detecting the presence of the sudo utility for continuation of this install..."
if [ -x "$(command -v sudo)" ]; then
echo "::: Utility sudo located."
exec curl -sSL https://install.pi-hole.net | sudo bash "$@"
exit $?
else
echo "::: sudo is needed for the Web interface to run pihole commands. Please run this script as root and it will be automatically installed."
exit 1
fi
fi
# Compatibility
if [[ $(command -v apt-get) ]]; then
#Debian Family
#############################################
PKG_MANAGER="apt-get"
PKG_CACHE="/var/lib/apt/lists/"
UPDATE_PKG_CACHE="${PKG_MANAGER} update"
PKG_UPDATE="${PKG_MANAGER} upgrade"
PKG_INSTALL="${PKG_MANAGER} --yes --fix-missing install"
# grep -c will return 1 retVal on 0 matches, block this throwing the set -e with an OR TRUE
PKG_COUNT="${PKG_MANAGER} -s -o Debug::NoLocking=true upgrade | grep -c ^Inst || true"
# #########################################
# fixes for dependancy differences
# Debian 7 doesn't have iproute2 use iproute
${PKG_MANAGER} install --dry-run iproute2 > /dev/null 2>&1 && IPROUTE_PKG="iproute2" || IPROUTE_PKG="iproute"
# Prefer the php metapackage if it's there, fall back on the php5 pacakges
${PKG_MANAGER} install --dry-run php > /dev/null 2>&1 && phpVer="php" || phpVer="php5"
# #########################################
INSTALLER_DEPS=(apt-utils debconf dhcpcd5 git whiptail)
PIHOLE_DEPS=(bc cron curl dnsmasq dnsutils ${IPROUTE_PKG} iputils-ping lighttpd lsof netcat ${phpVer}-common ${phpVer}-cgi sudo unzip wget)
LIGHTTPD_USER="www-data"
LIGHTTPD_GROUP="www-data"
LIGHTTPD_CFG="lighttpd.conf.debian"
DNSMASQ_USER="dnsmasq"
package_check_install() {
dpkg-query -W -f='${Status}' "${1}" 2>/dev/null | grep -c "ok installed" || ${PKG_INSTALL} "${1}"
}
elif [ $(command -v rpm) ]; then
# Fedora Family
if [ $(command -v dnf) ]; then
PKG_MANAGER="dnf"
else
PKG_MANAGER="yum"
fi
PKG_CACHE="/var/cache/${PKG_MANAGER}"
UPDATE_PKG_CACHE="${PKG_MANAGER} check-update"
PKG_UPDATE="${PKG_MANAGER} update -y"
PKG_INSTALL="${PKG_MANAGER} install -y"
PKG_COUNT="${PKG_MANAGER} check-update | egrep '(.i686|.x86|.noarch|.arm|.src)' | wc -l"
INSTALLER_DEPS=(git iproute net-tools newt procps-ng)
PIHOLE_DEPS=(bc bind-utils cronie curl dnsmasq epel-release findutils lighttpd lighttpd-fastcgi nmap-ncat php php-common php-cli sudo unzip wget)
if grep -q 'Fedora' /etc/redhat-release; then
remove_deps=(epel-release);
PIHOLE_DEPS=( ${PIHOLE_DEPS[@]/$remove_deps} );
fi
LIGHTTPD_USER="lighttpd"
LIGHTTPD_GROUP="lighttpd"
LIGHTTPD_CFG="lighttpd.conf.fedora"
DNSMASQ_USER="nobody"
package_check_install() {
rpm -qa | grep ^"${1}"- > /dev/null || ${PKG_INSTALL} "${1}"
}
else
echo "OS distribution not supported"
exit
fi
####### FUNCTIONS ##########
is_repo() {
# Use git to check if directory is currently under VCS, return the value
local directory="${1}"
git -C "${directory}" status --short &> /dev/null
return
}
make_repo() {
local directory="${1}"
local remoteRepo="${2}"
# Remove the non-repod interface and clone the interface
echo -n "::: Cloning $remoteRepo into $directory..."
rm -rf "${directory}"
git clone -q --depth 1 "${remoteRepo}" "${directory}" &> /dev/null
echo " done!"
}
update_repo() {
local directory="${1}"
# Pull the latest commits
echo -n "::: Updating repo in $1..."
cd "${directory}" || exit 1
git stash -q &> /dev/null
git pull -q &> /dev/null
echo " done!"
}
getGitFiles() {
# Setup git repos for directory and repository passed
# as arguments 1 and 2
local directory="${1}"
local remoteRepo="${2}"
echo ":::"
echo "::: Checking for existing repository..."
if is_repo "${directory}"; then
update_repo "${directory}"
else
make_repo "${directory}" "${remoteRepo}"
fi
}
find_IPv4_information() {
# Find IP used to route to outside world
IPv4dev=$(ip route get 8.8.8.8 | awk '{for(i=1;i<=NF;i++)if($i~/dev/)print $(i+1)}')
IPV4_ADDRESS=$(ip -o -f inet addr show dev "$IPv4dev" | awk '{print $4}' | awk 'END {print}')
IPv4gw=$(ip route get 8.8.8.8 | awk '{print $3}')
}
get_available_interfaces() {
# Get available interfaces. Consider only getting UP interfaces in the future, and leaving DOWN interfaces out of list.
availableInterfaces=$(ip -o link | awk '{print $2}' | grep -v "lo" | cut -d':' -f1 | cut -d'@' -f1)
}
welcomeDialogs() {
# Display the welcome dialog
whiptail --msgbox --backtitle "Welcome" --title "Pi-hole automated installer" "\n\nThis installer will transform your device into a network-wide ad blocker!" ${r} ${c}
# Support for a part-time dev
whiptail --msgbox --backtitle "Plea" --title "Free and open source" "\n\nThe Pi-hole is free, but powered by your donations: http://pi-hole.net/donate" ${r} ${c}
# Explain the need for a static address
whiptail --msgbox --backtitle "Initiating network interface" --title "Static IP Needed" "\n\nThe Pi-hole is a SERVER so it needs a STATIC IP ADDRESS to function properly.
In the next section, you can choose to use your current network settings (DHCP) or to manually edit them." ${r} ${c}
}
verifyFreeDiskSpace() {
# 50MB is the minimum space needed (45MB install (includes web admin bootstrap/jquery libraries etc) + 5MB one day of logs.)
# - Fourdee: Local ensures the variable is only created, and accessible within this function/void. Generally considered a "good" coding practice for non-global variables.
echo "::: Verifying free disk space..."
local required_free_kilobytes=51200
local existing_free_kilobytes=$(df -Pk | grep -m1 '\/$' | awk '{print $4}')
# - Unknown free disk space , not a integer
if ! [[ "${existing_free_kilobytes}" =~ ^([0-9])+$ ]]; then
echo "::: Unknown free disk space!"
echo "::: We were unable to determine available free disk space on this system."
echo "::: You may override this check and force the installation, however, it is not recommended"
echo "::: To do so, pass the argument '--i_do_not_follow_recommendations' to the install script"
echo "::: eg. curl -L https://install.pi-hole.net | bash /dev/stdin --i_do_not_follow_recommendations"
exit 1
# - Insufficient free disk space
elif [[ ${existing_free_kilobytes} -lt ${required_free_kilobytes} ]]; then
echo "::: Insufficient Disk Space!"
echo "::: Your system appears to be low on disk space. pi-hole recommends a minimum of $required_free_kilobytes KiloBytes."
echo "::: You only have ${existing_free_kilobytes} KiloBytes free."
echo "::: If this is a new install you may need to expand your disk."
echo "::: Try running 'sudo raspi-config', and choose the 'expand file system option'"
echo "::: After rebooting, run this installation again. (curl -L https://install.pi-hole.net | bash)"
echo "Insufficient free space, exiting..."
exit 1
fi
}
chooseInterface() {
# Turn the available interfaces into an array so it can be used with a whiptail dialog
local interfacesArray=()
# Number of available interfaces
local interfaceCount
# Whiptail variable storage
local chooseInterfaceCmd
# Temporary Whiptail options storage
local chooseInterfaceOptions
# Loop sentinel variable
local firstLoop=1
while read -r line; do
mode="OFF"
if [[ ${firstLoop} -eq 1 ]]; then
firstLoop=0
mode="ON"
fi
interfacesArray+=("${line}" "available" "${mode}")
done <<< "${availableInterfaces}"
# Find out how many interfaces are available to choose from
interfaceCount=$(echo "${availableInterfaces}" | wc -l)
chooseInterfaceCmd=(whiptail --separate-output --radiolist "Choose An Interface (press space to select)" ${r} ${c} ${interfaceCount})
chooseInterfaceOptions=$("${chooseInterfaceCmd[@]}" "${interfacesArray[@]}" 2>&1 >/dev/tty)
if [[ $? = 0 ]]; then
for desiredInterface in ${chooseInterfaceOptions}; do
PIHOLE_INTERFACE=${desiredInterface}
echo "::: Using interface: $PIHOLE_INTERFACE"
done
else
echo "::: Cancel selected, exiting...."
exit 1
fi
}
useIPv6dialog() {
# Show the IPv6 address used for blocking
IPV6_ADDRESS=$(ip -6 route get 2001:4860:4860::8888 | awk -F " " '{ for(i=1;i<=NF;i++) if ($i == "src") print $(i+1) }')
whiptail --msgbox --backtitle "IPv6..." --title "IPv6 Supported" "$IPV6_ADDRESS will be used to block ads." ${r} ${c}
}
use4andor6() {
local useIPv4
local useIPv6
# Let use select IPv4 and/or IPv6
cmd=(whiptail --separate-output --checklist "Select Protocols (press space to select)" ${r} ${c} 2)
options=(IPv4 "Block ads over IPv4" on
IPv6 "Block ads over IPv6" on)
choices=$("${cmd[@]}" "${options[@]}" 2>&1 >/dev/tty)
if [[ $? = 0 ]];then
for choice in ${choices}
do
case ${choice} in
IPv4 ) useIPv4=true;;
IPv6 ) useIPv6=true;;
esac
done
if [[ ${useIPv4} ]]; then
find_IPv4_information
getStaticIPv4Settings
setStaticIPv4
fi
if [[ ${useIPv6} ]]; then
useIPv6dialog
fi
echo "::: IPv4 address: ${IPV4_ADDRESS}"
echo "::: IPv6 address: ${IPV6_ADDRESS}"
if [ ! ${useIPv4} ] && [ ! ${useIPv6} ]; then
echo "::: Cannot continue, neither IPv4 or IPv6 selected"
echo "::: Exiting"
exit 1
fi
else
echo "::: Cancel selected. Exiting..."
exit 1
fi
}
getStaticIPv4Settings() {
# Ask if the user wants to use DHCP settings as their static IP
if (whiptail --backtitle "Calibrating network interface" --title "Static IP Address" --yesno "Do you want to use your current network settings as a static address?
IP address: ${IPV4_ADDRESS}
Gateway: ${IPv4gw}" ${r} ${c}); then
# If they choose yes, let the user know that the IP address will not be available via DHCP and may cause a conflict.
whiptail --msgbox --backtitle "IP information" --title "FYI: IP Conflict" "It is possible your router could still try to assign this IP to a device, which would cause a conflict. But in most cases the router is smart enough to not do that.
If you are worried, either manually set the address, or modify the DHCP reservation pool so it does not include the IP you want.
It is also possible to use a DHCP reservation, but if you are going to do that, you might as well set a static address." ${r} ${c}
# Nothing else to do since the variables are already set above
else
# Otherwise, we need to ask the user to input their desired settings.
# Start by getting the IPv4 address (pre-filling it with info gathered from DHCP)
# Start a loop to let the user enter their information with the chance to go back and edit it if necessary
until [[ ${ipSettingsCorrect} = True ]]; do
# Ask for the IPv4 address
IPV4_ADDRESS=$(whiptail --backtitle "Calibrating network interface" --title "IPv4 address" --inputbox "Enter your desired IPv4 address" ${r} ${c} "${IPV4_ADDRESS}" 3>&1 1>&2 2>&3)
if [[ $? = 0 ]]; then
echo "::: Your static IPv4 address: ${IPV4_ADDRESS}"
# Ask for the gateway
IPv4gw=$(whiptail --backtitle "Calibrating network interface" --title "IPv4 gateway (router)" --inputbox "Enter your desired IPv4 default gateway" ${r} ${c} "${IPv4gw}" 3>&1 1>&2 2>&3)
if [[ $? = 0 ]]; then
echo "::: Your static IPv4 gateway: ${IPv4gw}"
# Give the user a chance to review their settings before moving on
if (whiptail --backtitle "Calibrating network interface" --title "Static IP Address" --yesno "Are these settings correct?
IP address: ${IPV4_ADDRESS}
Gateway: ${IPv4gw}" ${r} ${c}); then
# After that's done, the loop ends and we move on
ipSettingsCorrect=True
else
# If the settings are wrong, the loop continues
ipSettingsCorrect=False
fi
else
# Cancelling gateway settings window
ipSettingsCorrect=False
echo "::: Cancel selected. Exiting..."
exit 1
fi
else
# Cancelling IPv4 settings window
ipSettingsCorrect=False
echo "::: Cancel selected. Exiting..."
exit 1
fi
done
# End the if statement for DHCP vs. static
fi
}
setDHCPCD() {
# Append these lines to dhcpcd.conf to enable a static IP
echo "## interface ${PIHOLE_INTERFACE}
static ip_address=${IPV4_ADDRESS}
static routers=${IPv4gw}
static domain_name_servers=${IPv4gw}" | tee -a /etc/dhcpcd.conf >/dev/null
}
setStaticIPv4() {
local IFCFG_FILE
local IPADDR
local CIDR
if [[ -f /etc/dhcpcd.conf ]]; then
# Debian Family
if grep -q "${IPV4_ADDRESS}" /etc/dhcpcd.conf; then
echo "::: Static IP already configured"
else
setDHCPCD
ip addr replace dev "${PIHOLE_INTERFACE}" "${IPV4_ADDRESS}"
echo ":::"
echo "::: Setting IP to ${IPV4_ADDRESS}. You may need to restart after the install is complete."
echo ":::"
fi
elif [[ -f /etc/sysconfig/network-scripts/ifcfg-${PIHOLE_INTERFACE} ]];then
# Fedora Family
IFCFG_FILE=/etc/sysconfig/network-scripts/ifcfg-${PIHOLE_INTERFACE}
if grep -q "${IPV4_ADDRESS}" "${IFCFG_FILE}"; then
echo "::: Static IP already configured"
else
IPADDR=$(echo "${IPV4_ADDRESS}" | cut -f1 -d/)
CIDR=$(echo "${IPV4_ADDRESS}" | cut -f2 -d/)
# Backup existing interface configuration:
cp "${IFCFG_FILE}" "${IFCFG_FILE}".pihole.orig
# Build Interface configuration file:
{
echo "# Configured via Pi-Hole installer"
echo "DEVICE=$PIHOLE_INTERFACE"
echo "BOOTPROTO=none"
echo "ONBOOT=yes"
echo "IPADDR=$IPADDR"
echo "PREFIX=$CIDR"
echo "GATEWAY=$IPv4gw"
echo "DNS1=$PIHOLE_DNS_1"
echo "DNS2=$PIHOLE_DNS_2"
echo "USERCTL=no"
}> "${IFCFG_FILE}"
ip addr replace dev "${PIHOLE_INTERFACE}" "${IPV4_ADDRESS}"
if [ -x "$(command -v nmcli)" ];then
# Tell NetworkManager to read our new sysconfig file
nmcli con load "${IFCFG_FILE}" > /dev/null
fi
echo ":::"
echo "::: Setting IP to ${IPV4_ADDRESS}. You may need to restart after the install is complete."
echo ":::"
fi
else
echo "::: Warning: Unable to locate configuration file to set static IPv4 address!"
exit 1
fi
}
valid_ip() {
local ip=${1}
local stat=1
if [[ ${ip} =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then
OIFS=$IFS
IFS='.'
ip=(${ip})
IFS=${OIFS}
[[ ${ip[0]} -le 255 && ${ip[1]} -le 255 \
&& ${ip[2]} -le 255 && ${ip[3]} -le 255 ]]
stat=$?
fi
return ${stat}
}
setDNS() {
DNSChooseCmd=(whiptail --separate-output --radiolist "Select Upstream DNS Provider. To use your own, select Custom." ${r} ${c} 6)
DNSChooseOptions=(Google "" on
OpenDNS "" off
Level3 "" off
Norton "" off
Comodo "" off
Custom "" off)
DNSchoices=$("${DNSChooseCmd[@]}" "${DNSChooseOptions[@]}" 2>&1 >/dev/tty)
if [[ $? = 0 ]];then
case ${DNSchoices} in
Google)
echo "::: Using Google DNS servers."
PIHOLE_DNS_1="8.8.8.8"
PIHOLE_DNS_2="8.8.4.4"
;;
OpenDNS)
echo "::: Using OpenDNS servers."
PIHOLE_DNS_1="208.67.222.222"
PIHOLE_DNS_2="208.67.220.220"
;;
Level3)
echo "::: Using Level3 servers."
PIHOLE_DNS_1="4.2.2.1"
PIHOLE_DNS_2="4.2.2.2"
;;
Norton)
echo "::: Using Norton ConnectSafe servers."
PIHOLE_DNS_1="199.85.126.10"
PIHOLE_DNS_2="199.85.127.10"
;;
Comodo)
echo "::: Using Comodo Secure servers."
PIHOLE_DNS_1="8.26.56.26"
PIHOLE_DNS_2="8.20.247.20"
;;
Custom)
until [[ ${DNSSettingsCorrect} = True ]]; do
strInvalid="Invalid"
if [ ! ${PIHOLE_DNS_1} ]; then
if [ ! ${PIHOLE_DNS_2} ]; then
prePopulate=""
else
prePopulate=", ${PIHOLE_DNS_2}"
fi
elif [ ${PIHOLE_DNS_1} ] && [ ! ${PIHOLE_DNS_2} ]; then
prePopulate="${PIHOLE_DNS_1}"
elif [ ${PIHOLE_DNS_1} ] && [ ${PIHOLE_DNS_2} ]; then
prePopulate="${PIHOLE_DNS_1}, ${PIHOLE_DNS_2}"
fi
piholeDNS=$(whiptail --backtitle "Specify Upstream DNS Provider(s)" --inputbox "Enter your desired upstream DNS provider(s), seperated by a comma.\n\nFor example '8.8.8.8, 8.8.4.4'" ${r} ${c} "${prePopulate}" 3>&1 1>&2 2>&3)
if [[ $? = 0 ]]; then
PIHOLE_DNS_1=$(echo "${piholeDNS}" | sed 's/[, \t]\+/,/g' | awk -F, '{print$1}')
PIHOLE_DNS_2=$(echo "${piholeDNS}" | sed 's/[, \t]\+/,/g' | awk -F, '{print$2}')
if ! valid_ip "${PIHOLE_DNS_1}" || [ ! "${PIHOLE_DNS_1}" ]; then
PIHOLE_DNS_1=${strInvalid}
fi
if ! valid_ip "${PIHOLE_DNS_2}" && [ "${PIHOLE_DNS_2}" ]; then
PIHOLE_DNS_2=${strInvalid}
fi
else
echo "::: Cancel selected, exiting...."
exit 1
fi
if [[ ${PIHOLE_DNS_1} == "${strInvalid}" ]] || [[ ${PIHOLE_DNS_2} == "${strInvalid}" ]]; then
whiptail --msgbox --backtitle "Invalid IP" --title "Invalid IP" "One or both entered IP addresses were invalid. Please try again.\n\n DNS Server 1: $PIHOLE_DNS_1\n DNS Server 2: ${PIHOLE_DNS_2}" ${r} ${c}
if [[ ${PIHOLE_DNS_1} == "${strInvalid}" ]]; then
PIHOLE_DNS_1=""
fi
if [[ ${PIHOLE_DNS_2} == "${strInvalid}" ]]; then
PIHOLE_DNS_2=""
fi
DNSSettingsCorrect=False
else
if (whiptail --backtitle "Specify Upstream DNS Provider(s)" --title "Upstream DNS Provider(s)" --yesno "Are these settings correct?\n DNS Server 1: $PIHOLE_DNS_1\n DNS Server 2: ${PIHOLE_DNS_2}" ${r} ${c}); then
DNSSettingsCorrect=True
else
# If the settings are wrong, the loop continues
DNSSettingsCorrect=False
fi
fi
done
;;
esac
else
echo "::: Cancel selected. Exiting..."
exit 1
fi
}
setLogging() {
local LogToggleCommand
local LogChooseOptions
local LogChoices
LogToggleCommand=(whiptail --separate-output --radiolist "Do you want to log queries?\n (Disabling will render graphs on the Admin page useless):" ${r} ${c} 6)
LogChooseOptions=("On (Reccomended)" "" on
Off "" off)
LogChoices=$("${LogToggleCommand[@]}" "${LogChooseOptions[@]}" 2>&1 >/dev/tty) || (echo "::: Cancel selected. Exiting..." && exit 1)
case ${LogChoices} in
"On (Recommended)")
echo "::: Logging On."
QUERY_LOGGING=true
;;
Off)
echo "::: Logging Off."
QUERY_LOGGING=false
;;
esac
}
version_check_dnsmasq() {
# Check if /etc/dnsmasq.conf is from pihole. If so replace with an original and install new in .d directory
local dnsmasq_conf="/etc/dnsmasq.conf"
local dnsmasq_conf_orig="/etc/dnsmasq.conf.orig"
local dnsmasq_pihole_id_string="addn-hosts=/etc/pihole/gravity.list"
local dnsmasq_original_config="/etc/.pihole/advanced/dnsmasq.conf.original"
local dnsmasq_pihole_01_snippet="/etc/.pihole/advanced/01-pihole.conf"
local dnsmasq_pihole_01_location="/etc/dnsmasq.d/01-pihole.conf"
if [ -f ${dnsmasq_conf} ]; then
echo -n "::: Existing dnsmasq.conf found..."
if grep -q ${dnsmasq_pihole_id_string} ${dnsmasq_conf}; then
echo " it is from a previous pi-hole install."
echo -n "::: Backing up dnsmasq.conf to dnsmasq.conf.orig..."
mv -f ${dnsmasq_conf} ${dnsmasq_conf_orig}
echo " done."
echo -n "::: Restoring default dnsmasq.conf..."
cp ${dnsmasq_original_config} ${dnsmasq_conf}
echo " done."
else
echo " it is not a pi-hole file, leaving alone!"
fi
else
echo -n "::: No dnsmasq.conf found.. restoring default dnsmasq.conf..."
cp ${dnsmasq_original_config} ${dnsmasq_conf}
echo " done."
fi
echo -n "::: Copying 01-pihole.conf to /etc/dnsmasq.d/01-pihole.conf..."
cp ${dnsmasq_pihole_01_snippet} ${dnsmasq_pihole_01_location}
echo " done."
sed -i "s/@INT@/$PIHOLE_INTERFACE/" ${dnsmasq_pihole_01_location}
if [[ "${PIHOLE_DNS_1}" != "" ]]; then
sed -i "s/@DNS1@/$PIHOLE_DNS_1/" ${dnsmasq_pihole_01_location}
else
sed -i '/^server=@DNS1@/d' ${dnsmasq_pihole_01_location}
fi
if [[ "${PIHOLE_DNS_2}" != "" ]]; then
sed -i "s/@DNS2@/$PIHOLE_DNS_2/" ${dnsmasq_pihole_01_location}
else
sed -i '/^server=@DNS2@/d' ${dnsmasq_pihole_01_location}
fi
sed -i 's/^#conf-dir=\/etc\/dnsmasq.d$/conf-dir=\/etc\/dnsmasq.d/' ${dnsmasq_conf}
if [[ "${QUERY_LOGGING}" == false ]] ; then
#Disable Logging
sed -i 's/^log-queries/#log-queries/' ${dnsmasq_pihole_01_location}
else
#Enable Logging
sed -i 's/^#log-queries/log-queries/' ${dnsmasq_pihole_01_location}
fi
}
remove_legacy_scripts() {
#Tidy up /usr/local/bin directory if installing over previous install.
oldFiles=( gravity chronometer whitelist blacklist piholeLogFlush updateDashboard uninstall setupLCD piholeDebug)
for i in "${oldFiles[@]}"; do
if [ -f "/usr/local/bin/$i.sh" ]; then
rm /usr/local/bin/"$i".sh
fi
done
}
clean_existing() {
# Clean an exiting installation to prepare for upgrade/reinstall
# ${1} Directory to clean; ${2} Array of files to remove
local clean_directory="${1}"
local old_files=${2}
for script in "${old_files[@]}"; do
rm -f "${clean_directory}${script}.sh"
done
}
installScripts() {
# Install the scripts from repository to their various locations
readonly install_dir="/opt/pihole/"
echo ":::"
echo -n "::: Installing scripts from ${PI_HOLE_LOCAL_REPO}..."
# Clear out script files from Pi-hole scripts directory.
clean_existing "${install_dir}" "${PI_HOLE_FILES}"
# Install files from local core repository
if is_repo "${PI_HOLE_LOCAL_REPO}"; then
cd "${PI_HOLE_LOCAL_REPO}"
install -o "${USER}" -Dm755 -t /opt/pihole/ gravity.sh
install -o "${USER}" -Dm755 -t /opt/pihole/ ./advanced/Scripts/*.sh
install -o "${USER}" -Dm755 -t /opt/pihole/ ./automated\ install/uninstall.sh
install -o "${USER}" -Dm755 -t /usr/local/bin/ pihole
install -Dm644 ./advanced/bash-completion/pihole /etc/bash_completion.d/pihole
echo " done."
else
echo " *** ERROR: Local repo ${core_repo} not found, exiting."
exit 1
fi
}
installConfigs() {
# Install the configs from /etc/.pihole to their various locations
echo ":::"
echo "::: Installing configs..."
version_check_dnsmasq
if [ ! -d "/etc/lighttpd" ]; then
mkdir /etc/lighttpd
chown "${USER}":root /etc/lighttpd
elif [ -f "/etc/lighttpd/lighttpd.conf" ]; then
mv /etc/lighttpd/lighttpd.conf /etc/lighttpd/lighttpd.conf.orig
fi
cp /etc/.pihole/advanced/${LIGHTTPD_CFG} /etc/lighttpd/lighttpd.conf
mkdir -p /var/run/lighttpd
chown ${LIGHTTPD_USER}:${LIGHTTPD_GROUP} /var/run/lighttpd
mkdir -p /var/cache/lighttpd/compress
chown ${LIGHTTPD_USER}:${LIGHTTPD_GROUP} /var/cache/lighttpd/compress
mkdir -p /var/cache/lighttpd/uploads
chown ${LIGHTTPD_USER}:${LIGHTTPD_GROUP} /var/cache/lighttpd/uploads
}
stop_service() {
# Stop service passed in as argument.
# Can softfail, as process may not be installed when this is called
echo ":::"
echo -n "::: Stopping ${1} service..."
if [ -x "$(command -v systemctl)" ]; then
systemctl stop "${1}" &> /dev/null || true
else
service "${1}" stop &> /dev/null || true
fi
echo " done."
}
start_service() {
# Start/Restart service passed in as argument
# This should not fail, it's an error if it does
echo ":::"
echo -n "::: Starting ${1} service..."
if [ -x "$(command -v systemctl)" ]; then
systemctl restart "${1}" &> /dev/null
else
service "${1}" restart &> /dev/null
fi
echo " done."
}
enable_service() {
# Enable service so that it will start with next reboot
echo ":::"
echo -n "::: Enabling ${1} service to start on reboot..."
if [ -x "$(command -v systemctl)" ]; then
systemctl enable "${1}" &> /dev/null
else
update-rc.d "${1}" defaults &> /dev/null
fi
echo " done."
}
update_pacakge_cache() {
#Running apt-get update/upgrade with minimal output can cause some issues with
#requiring user input (e.g password for phpmyadmin see #218)
#Check to see if apt-get update has already been run today
#it needs to have been run at least once on new installs!
timestamp=$(stat -c %Y ${PKG_CACHE})
timestampAsDate=$(date -d @"${timestamp}" "+%b %e")
today=$(date "+%b %e")
if [ ! "${today}" == "${timestampAsDate}" ]; then
#update package lists
echo ":::"
echo -n "::: ${PKG_MANAGER} update has not been run today. Running now..."
${UPDATE_PKG_CACHE} &> /dev/null
echo " done!"
fi
}
notify_package_updates_available() {
# Let user know if they have outdated packages on their system and
# advise them to run a package update at soonest possible.
echo ":::"
echo -n "::: Checking ${PKG_MANAGER} for upgraded packages...."
updatesToInstall=$(eval "${PKG_COUNT}")
echo " done!"
echo ":::"
if [[ ${updatesToInstall} -eq "0" ]]; then
echo "::: Your system is up to date! Continuing with Pi-hole installation..."
else
echo "::: There are ${updatesToInstall} updates available for your system!"
echo "::: We recommend you run '${PKG_UPDATE}' after installing Pi-Hole! "
echo ":::"
fi
}
install_dependent_packages() {
# Install packages passed in via argument array
# No spinner - conflicts with set -e
declare -a argArray1=("${!1}")
if command -v debconf-apt-progress &> /dev/null; then
debconf-apt-progress -- ${PKG_INSTALL} "${argArray1[@]}"
else
for i in "${argArray1[@]}"; do
echo -n "::: Checking for $i..."
package_check_install "${i}" &> /dev/null
echo " installed!"
done
fi
}
CreateLogFile() {
# Create logfiles if necessary
echo ":::"
echo -n "::: Creating log file and changing owner to dnsmasq..."
if [ ! -f /var/log/pihole.log ]; then
touch /var/log/pihole.log
chmod 644 /var/log/pihole.log
chown "${DNSMASQ_USER}":root /var/log/pihole.log
echo " done!"
else
echo " already exists!"
fi
}
installPiholeWeb() {
# Install the web interface
echo ":::"
echo "::: Installing pihole custom index page..."
if [ -d "/var/www/html/pihole" ]; then
if [ -f "/var/www/html/pihole/index.html" ]; then
echo "::: Existing index.html detected, not overwriting"
else
echo -n "::: index.html missing, replacing... "
cp /etc/.pihole/advanced/index.html /var/www/html/pihole/
echo " done!"
fi
if [ -f "/var/www/html/pihole/index.js" ]; then
echo "::: Existing index.js detected, not overwriting"
else
echo -n "::: index.js missing, replacing... "
cp /etc/.pihole/advanced/index.js /var/www/html/pihole/
echo " done!"
fi
else
mkdir /var/www/html/pihole
if [ -f /var/www/html/index.lighttpd.html ]; then
mv /var/www/html/index.lighttpd.html /var/www/html/index.lighttpd.orig
else
printf "\n:::\tNo default index.lighttpd.html file found... not backing up"
fi
cp /etc/.pihole/advanced/index.* /var/www/html/pihole/.
echo " done!"
fi
# Install Sudoer file
echo ":::"
echo -n "::: Installing sudoer file..."
mkdir -p /etc/sudoers.d/
cp /etc/.pihole/advanced/pihole.sudo /etc/sudoers.d/pihole
chmod 0440 /etc/sudoers.d/pihole
echo " done!"
}
installCron() {
# Install the cron job
echo ":::"
echo -n "::: Installing latest Cron script..."
cp /etc/.pihole/advanced/pihole.cron /etc/cron.d/pihole
echo " done!"
}
runGravity() {
# Run gravity.sh to build blacklists
echo ":::"
echo "::: Preparing to run gravity.sh to refresh hosts..."
if ls /etc/pihole/list* 1> /dev/null 2>&1; then
echo "::: Cleaning up previous install (preserving whitelist/blacklist)"
rm /etc/pihole/list.*
fi
echo "::: Running gravity.sh"
/opt/pihole/gravity.sh
}
create_pihole_user() {
# Check if user pihole exists and create if not
echo "::: Checking if user 'pihole' exists..."
id -u pihole &> /dev/null && echo "::: User 'pihole' already exists" || (echo "::: User 'pihole' doesn't exist. Creating..." && useradd -r -s /usr/sbin/nologin pihole)
}
configureFirewall() {
# Allow HTTP and DNS traffic
if [ -x "$(command -v firewall-cmd)" ]; then
firewall-cmd --state &> /dev/null && ( echo "::: Configuring firewalld for httpd and dnsmasq.." && firewall-cmd --permanent --add-port=80/tcp && firewall-cmd --permanent --add-port=53/tcp \
&& firewall-cmd --permanent --add-port=53/udp && firewall-cmd --reload) || echo "::: FirewallD not enabled"
elif [ -x "$(command -v iptables)" ]; then
echo "::: Configuring iptables for httpd and dnsmasq.."
iptables -A INPUT -p tcp -m tcp --dport 80 -j ACCEPT
iptables -A INPUT -p tcp -m tcp --dport 53 -j ACCEPT
iptables -A INPUT -p udp -m udp --dport 53 -j ACCEPT
else
echo "::: No firewall detected.. skipping firewall configuration."
fi
}
finalExports() {
# Update variables in setupVars.conf file
if [ -e "${setupVars}" ]; then
sed -i.update.bak '/PIHOLE_INTERFACE/d;/IPV4_ADDRESS/d;/IPV6_ADDRESS/d;/PIHOLE_DNS_1/d;/PIHOLE_DNS_2/d;/QUERY_LOGGING/d;' "${setupVars}"
fi
{
echo "PIHOLE_INTERFACE=${PIHOLE_INTERFACE}"
echo "IPV4_ADDRESS=${IPV4_ADDRESS}"
echo "IPV6_ADDRESS=${IPV6_ADDRESS}"
echo "PIHOLE_DNS_1=${PIHOLE_DNS_1}"
echo "PIHOLE_DNS_2=${PIHOLE_DNS_2}"
echo "QUERY_LOGGING=${QUERY_LOGGING}"
}>> "${setupVars}"
}
installPihole() {
# Install base files and web interface
create_pihole_user
if [ ! -d "/var/www/html" ]; then
mkdir -p /var/www/html
fi
chown ${LIGHTTPD_USER}:${LIGHTTPD_GROUP} /var/www/html
chmod 775 /var/www/html
usermod -a -G ${LIGHTTPD_GROUP} pihole
if [ -x "$(command -v lighty-enable-mod)" ]; then
lighty-enable-mod fastcgi fastcgi-php > /dev/null || true
else
printf "\n:::\tWarning: 'lighty-enable-mod' utility not found. Please ensure fastcgi is enabled if you experience issues.\n"
fi
installScripts
installConfigs
CreateLogFile
configureSelinux
installPiholeWeb
installCron
configureFirewall
finalExports
runGravity
}
accountForRefactor() {
# At some point in the future this list can be pruned, for now we'll need it to ensure updates don't break.
# Refactoring of install script has changed the name of a couple of variables. Sort them out here.
sed -i 's/piholeInterface/PIHOLE_INTERFACE/g' ${setupVars}
sed -i 's/IPv4_address/IPV4_ADDRESS/g' ${setupVars}
sed -i 's/IPv4addr/IPV4_ADDRESS/g' ${setupVars}
sed -i 's/IPv6_address/IPV6_ADDRESS/g' ${setupVars}
sed -i 's/piholeIPv6/IPV6_ADDRESS/g' ${setupVars}
sed -i 's/piholeDNS1/PIHOLE_DNS_1/g' ${setupVars}
sed -i 's/piholeDNS2/PIHOLE_DNS_2/g' ${setupVars}
}
updatePihole() {
accountForRefactor
# Source ${setupVars} for use in the rest of the functions.
. ${setupVars}
# Install base files and web interface
installScripts
installConfigs
CreateLogFile
configureSelinux
installPiholeWeb
installCron
configureFirewall
finalExports #re-export setupVars.conf to account for any new vars added in new versions
runGravity
}
configureSelinux() {
if [ -x "$(command -v getenforce)" ]; then
printf "\n::: SELinux Detected\n"
printf ":::\tChecking for SELinux policy development packages..."
package_check_install "selinux-policy-devel" > /dev/null
echo " installed!"
printf ":::\tEnabling httpd server side includes (SSI).. "
setsebool -P httpd_ssi_exec on &> /dev/null && echo "Success" || echo "SELinux not enabled"
printf "\n:::\tCompiling Pi-Hole SELinux policy..\n"
if ! [ -x "$(command -v systemctl)" ]; then
sed -i.bak '/systemd/d' /etc/.pihole/advanced/selinux/pihole.te
fi
checkmodule -M -m -o /etc/pihole/pihole.mod /etc/.pihole/advanced/selinux/pihole.te
semodule_package -o /etc/pihole/pihole.pp -m /etc/pihole/pihole.mod
semodule -i /etc/pihole/pihole.pp
rm -f /etc/pihole/pihole.mod
semodule -l | grep pihole &> /dev/null && echo "::: Installed Pi-Hole SELinux policy" || echo "::: Warning: Pi-Hole SELinux policy did not install."
fi
}
displayFinalMessage() {
if (( ${#1} > 0 )) ; then
# Final completion message to user
whiptail --msgbox --backtitle "Make it so." --title "Installation Complete!" "Configure your devices to use the Pi-hole as their DNS server using:
IPv4: ${IPV4_ADDRESS%/*}
IPv6: ${IPV6_ADDRESS}
If you set a new IP address, you should restart the Pi.
The install log is in /etc/pihole.
View the web interface at http://pi.hole/admin or http://${IPV4_ADDRESS%/*}/admin
The currently set password is ${1}" ${r} ${c}
else
whiptail --msgbox --backtitle "Make it so." --title "Installation Complete!" "Configure your devices to use the Pi-hole as their DNS server using:
IPv4: ${IPV4_ADDRESS%/*}
IPv6: ${IPV6_ADDRESS}
If you set a new IP address, you should restart the Pi.
The install log is in /etc/pihole.
View the web interface at http://pi.hole/admin or http://${IPV4_ADDRESS%/*}/admin" ${r} ${c}
fi
}
update_dialogs() {
# reconfigure
if [ "${reconfigure}" = true ]; then
opt1a="Repair"
opt1b="This will retain existing settings"
strAdd="You will remain on the same version"
else
opt1a="Update"
opt1b="This will retain existing settings."
strAdd="You will be updated to the latest version."
fi
opt2a="Reconfigure"
opt2b="This will allow you to enter new settings"
UpdateCmd=$(whiptail --title "Existing Install Detected!" --menu "\n\nWe have detected an existing install.\n\nPlease choose from the following options: \n($strAdd)" ${r} ${c} 2 \
"${opt1a}" "${opt1b}" \
"${opt2a}" "${opt2b}" 3>&2 2>&1 1>&3)
if [[ $? = 0 ]];then
case ${UpdateCmd} in
${opt1a})
echo "::: ${opt1a} option selected."
useUpdateVars=true
;;
${opt2a})
echo "::: ${opt2a} option selected"
useUpdateVars=false
;;
esac
else
echo "::: Cancel selected. Exiting..."
exit 1
fi
}
main() {
# Check arguments for the undocumented flags
for var in "$@"; do
case "$var" in
"--reconfigure" ) reconfigure=true;;
"--i_do_not_follow_recommendations" ) skipSpaceCheck=false;;
"--unattended" ) runUnattended=true;;
esac
done
if [[ -f ${setupVars} ]]; then
if [[ "${runUnattended}" == true ]]; then
echo "::: --unattended passed to install script, no whiptail dialogs will be displayed"
useUpdateVars=true
else
update_dialogs
fi
fi
# Start the installer
# Verify there is enough disk space for the install
if [[ "${skipSpaceCheck}" == true ]]; then
echo "::: --i_do_not_follow_recommendations passed to script, skipping free disk space verification!"
else
verifyFreeDiskSpace
fi
# Update package cache
update_pacakge_cache
# Notify user of package availability
notify_package_updates_available
# Install packages used by this installation script
install_dependent_packages INSTALLER_DEPS[@]
if [[ "${reconfigure}" == true ]]; then
echo "::: --reconfigure passed to install script. Not downloading/updating local repos"
else
# Get Git files for Core and Admin
getGitFiles ${PI_HOLE_LOCAL_REPO} ${piholeGitUrl}
getGitFiles ${webInterfaceDir} ${webInterfaceGitUrl}
fi
if [[ ${useUpdateVars} == false ]]; then
# Display welcome dialogs
welcomeDialogs
# Create directory for Pi-hole storage
mkdir -p /etc/pihole/
# Remove legacy scripts from previous storage location
remove_legacy_scripts
# Stop resolver and webserver while installing proceses
stop_service dnsmasq
stop_service lighttpd
# Determine available interfaces
get_available_interfaces
# Find interfaces and let the user choose one
chooseInterface
# Let the user decide if they want to block ads over IPv4 and/or IPv6
use4andor6
# Decide what upstream DNS Servers to use
setDNS
# Let the user decide if they want query logging enabled...
setLogging
# Install packages used by the Pi-hole
install_dependent_packages PIHOLE_DEPS[@]
# Install and log everything to a file
installPihole | tee ${tmpLog}
else
# update packages used by the Pi-hole
install_dependent_packages PIHOLE_DEPS[@]
updatePihole | tee ${tmpLog}
fi
# Move the log file into /etc/pihole for storage
mv ${tmpLog} ${instalLogLoc}
# Add password to web UI if there is none
pw=""
if [[ $(grep 'WEBPASSWORD' -c /etc/pihole/setupVars.conf) == 0 ]] ; then
pw=$(tr -dc _A-Z-a-z-0-9 < /dev/urandom | head -c 8)
pihole -a -p ${pw}
fi
if [[ "${useUpdateVars}" == false ]]; then
displayFinalMessage ${pw}
fi
echo "::: Restarting services..."
# Start services
start_service dnsmasq
enable_service dnsmasq
start_service lighttpd
enable_service lighttpd
echo "::: done."
echo ":::"
if [[ "${useUpdateVars}" == false ]]; then
echo "::: Installation Complete! Configure your devices to use the Pi-hole as their DNS server using:"
echo "::: ${IPV4_ADDRESS%/*}"
echo "::: ${IPV6_ADDRESS}"
echo ":::"
echo "::: If you set a new IP address, you should restart the Pi."
echo "::: View the web interface at http://pi.hole/admin or http://${IPV4_ADDRESS%/*}/admin"
else
echo "::: Update complete!"
fi
if (( ${#pw} > 0 )) ; then
echo ":::"
echo "::: Note: As security measure a password has been installed for your web interface"
echo "::: The currently set password is"
echo "::: ${pw}"
echo ":::"
echo "::: You can always change it using"
echo "::: pihole -a -p new_password"
fi
echo ":::"
echo "::: The install log is located at: /etc/pihole/install.log"
}
if [[ "${PH_TEST}" != true ]] ; then
main "$@"
fi
\ No newline at end of file
From 7f3b0030ea478e4c5867b8e173a0f5b68aec8688 Mon Sep 17 00:00:00 2001
From: Dan Schaper
Date: Tue, 20 Dec 2016 16:47:43 -0800
Subject: [PATCH 222/228] LF
Signed-off-by: Dan Schaper
---
automated install/basic-install.sh | 1144 +++++++++++++++++++++++++++-
1 file changed, 1143 insertions(+), 1 deletion(-)
diff --git a/automated install/basic-install.sh b/automated install/basic-install.sh
index c64c3864..0c66094f 100755
--- a/automated install/basic-install.sh
+++ b/automated install/basic-install.sh
@@ -1 +1,1143 @@
-#!/usr/bin/env bash
# Pi-hole: A black hole for Internet advertisements
# (c) 2015, 2016 by Jacob Salmela
# Network-wide ad blocking via your Raspberry Pi
# http://pi-hole.net
# Installs Pi-hole
#
# Pi-hole is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 2 of the License, or
# (at your option) any later version.
# pi-hole.net/donate
#
# Install with this command (from your Pi):
#
# curl -L install.pi-hole.net | bash
set -e
######## VARIABLES #########
tmpLog=/tmp/pihole-install.log
instalLogLoc=/etc/pihole/install.log
setupVars=/etc/pihole/setupVars.conf
webInterfaceGitUrl="https://github.com/pi-hole/AdminLTE.git"
webInterfaceDir="/var/www/html/admin"
piholeGitUrl="https://github.com/pi-hole/pi-hole.git"
PI_HOLE_LOCAL_REPO="/etc/.pihole"
PI_HOLE_FILES=(chronometer list piholeDebug piholeLogFlush setupLCD update version)
useUpdateVars=false
IPV4_ADDRESS=""
IPV6_ADDRESS=""
QUERY_LOGGING=true
# Find the rows and columns will default to 80x24 is it can not be detected
screen_size=$(stty size 2>/dev/null || echo 24 80)
rows=$(echo $screen_size | awk '{print $1}')
columns=$(echo $screen_size | awk '{print $2}')
# Divide by two so the dialogs take up half of the screen, which looks nice.
r=$(( rows / 2 ))
c=$(( columns / 2 ))
# Unless the screen is tiny
r=$(( r < 20 ? 20 : r ))
c=$(( c < 70 ? 70 : c ))
######## Undocumented Flags. Shhh ########
skipSpaceCheck=false
reconfigure=false
runUnattended=false
######## FIRST CHECK ########
# Must be root to install
echo ":::"
if [[ ${EUID} -eq 0 ]]; then
echo "::: You are root."
else
echo "::: Script called with non-root privileges. The Pi-hole installs server packages and configures"
echo "::: system networking, it requires elevated rights. Please check the contents of the script for"
echo "::: any concerns with this requirement. Please be sure to download this script from a trusted source."
echo ":::"
echo "::: Detecting the presence of the sudo utility for continuation of this install..."
if [ -x "$(command -v sudo)" ]; then
echo "::: Utility sudo located."
exec curl -sSL https://install.pi-hole.net | sudo bash "$@"
exit $?
else
echo "::: sudo is needed for the Web interface to run pihole commands. Please run this script as root and it will be automatically installed."
exit 1
fi
fi
# Compatibility
if [[ $(command -v apt-get) ]]; then
#Debian Family
#############################################
PKG_MANAGER="apt-get"
PKG_CACHE="/var/lib/apt/lists/"
UPDATE_PKG_CACHE="${PKG_MANAGER} update"
PKG_UPDATE="${PKG_MANAGER} upgrade"
PKG_INSTALL="${PKG_MANAGER} --yes --fix-missing install"
# grep -c will return 1 retVal on 0 matches, block this throwing the set -e with an OR TRUE
PKG_COUNT="${PKG_MANAGER} -s -o Debug::NoLocking=true upgrade | grep -c ^Inst || true"
# #########################################
# fixes for dependancy differences
# Debian 7 doesn't have iproute2 use iproute
${PKG_MANAGER} install --dry-run iproute2 > /dev/null 2>&1 && IPROUTE_PKG="iproute2" || IPROUTE_PKG="iproute"
# Prefer the php metapackage if it's there, fall back on the php5 pacakges
${PKG_MANAGER} install --dry-run php > /dev/null 2>&1 && phpVer="php" || phpVer="php5"
# #########################################
INSTALLER_DEPS=(apt-utils debconf dhcpcd5 git whiptail)
PIHOLE_DEPS=(bc cron curl dnsmasq dnsutils ${IPROUTE_PKG} iputils-ping lighttpd lsof netcat ${phpVer}-common ${phpVer}-cgi sudo unzip wget)
LIGHTTPD_USER="www-data"
LIGHTTPD_GROUP="www-data"
LIGHTTPD_CFG="lighttpd.conf.debian"
DNSMASQ_USER="dnsmasq"
package_check_install() {
dpkg-query -W -f='${Status}' "${1}" 2>/dev/null | grep -c "ok installed" || ${PKG_INSTALL} "${1}"
}
elif [ $(command -v rpm) ]; then
# Fedora Family
if [ $(command -v dnf) ]; then
PKG_MANAGER="dnf"
else
PKG_MANAGER="yum"
fi
PKG_CACHE="/var/cache/${PKG_MANAGER}"
UPDATE_PKG_CACHE="${PKG_MANAGER} check-update"
PKG_UPDATE="${PKG_MANAGER} update -y"
PKG_INSTALL="${PKG_MANAGER} install -y"
PKG_COUNT="${PKG_MANAGER} check-update | egrep '(.i686|.x86|.noarch|.arm|.src)' | wc -l"
INSTALLER_DEPS=(git iproute net-tools newt procps-ng)
PIHOLE_DEPS=(bc bind-utils cronie curl dnsmasq epel-release findutils lighttpd lighttpd-fastcgi nmap-ncat php php-common php-cli sudo unzip wget)
if grep -q 'Fedora' /etc/redhat-release; then
remove_deps=(epel-release);
PIHOLE_DEPS=( ${PIHOLE_DEPS[@]/$remove_deps} );
fi
LIGHTTPD_USER="lighttpd"
LIGHTTPD_GROUP="lighttpd"
LIGHTTPD_CFG="lighttpd.conf.fedora"
DNSMASQ_USER="nobody"
package_check_install() {
rpm -qa | grep ^"${1}"- > /dev/null || ${PKG_INSTALL} "${1}"
}
else
echo "OS distribution not supported"
exit
fi
####### FUNCTIONS ##########
is_repo() {
# Use git to check if directory is currently under VCS, return the value
local directory="${1}"
git -C "${directory}" status --short &> /dev/null
return
}
make_repo() {
local directory="${1}"
local remoteRepo="${2}"
# Remove the non-repod interface and clone the interface
echo -n "::: Cloning $remoteRepo into $directory..."
rm -rf "${directory}"
git clone -q --depth 1 "${remoteRepo}" "${directory}" &> /dev/null
echo " done!"
}
update_repo() {
local directory="${1}"
# Pull the latest commits
echo -n "::: Updating repo in $1..."
cd "${directory}" || exit 1
git stash -q &> /dev/null
git pull -q &> /dev/null
echo " done!"
}
getGitFiles() {
# Setup git repos for directory and repository passed
# as arguments 1 and 2
local directory="${1}"
local remoteRepo="${2}"
echo ":::"
echo "::: Checking for existing repository..."
if is_repo "${directory}"; then
update_repo "${directory}"
else
make_repo "${directory}" "${remoteRepo}"
fi
}
find_IPv4_information() {
# Find IP used to route to outside world
IPv4dev=$(ip route get 8.8.8.8 | awk '{for(i=1;i<=NF;i++)if($i~/dev/)print $(i+1)}')
IPV4_ADDRESS=$(ip -o -f inet addr show dev "$IPv4dev" | awk '{print $4}' | awk 'END {print}')
IPv4gw=$(ip route get 8.8.8.8 | awk '{print $3}')
}
get_available_interfaces() {
# Get available interfaces. Consider only getting UP interfaces in the future, and leaving DOWN interfaces out of list.
availableInterfaces=$(ip -o link | awk '{print $2}' | grep -v "lo" | cut -d':' -f1 | cut -d'@' -f1)
}
welcomeDialogs() {
# Display the welcome dialog
whiptail --msgbox --backtitle "Welcome" --title "Pi-hole automated installer" "\n\nThis installer will transform your device into a network-wide ad blocker!" ${r} ${c}
# Support for a part-time dev
whiptail --msgbox --backtitle "Plea" --title "Free and open source" "\n\nThe Pi-hole is free, but powered by your donations: http://pi-hole.net/donate" ${r} ${c}
# Explain the need for a static address
whiptail --msgbox --backtitle "Initiating network interface" --title "Static IP Needed" "\n\nThe Pi-hole is a SERVER so it needs a STATIC IP ADDRESS to function properly.
In the next section, you can choose to use your current network settings (DHCP) or to manually edit them." ${r} ${c}
}
verifyFreeDiskSpace() {
# 50MB is the minimum space needed (45MB install (includes web admin bootstrap/jquery libraries etc) + 5MB one day of logs.)
# - Fourdee: Local ensures the variable is only created, and accessible within this function/void. Generally considered a "good" coding practice for non-global variables.
echo "::: Verifying free disk space..."
local required_free_kilobytes=51200
local existing_free_kilobytes=$(df -Pk | grep -m1 '\/$' | awk '{print $4}')
# - Unknown free disk space , not a integer
if ! [[ "${existing_free_kilobytes}" =~ ^([0-9])+$ ]]; then
echo "::: Unknown free disk space!"
echo "::: We were unable to determine available free disk space on this system."
echo "::: You may override this check and force the installation, however, it is not recommended"
echo "::: To do so, pass the argument '--i_do_not_follow_recommendations' to the install script"
echo "::: eg. curl -L https://install.pi-hole.net | bash /dev/stdin --i_do_not_follow_recommendations"
exit 1
# - Insufficient free disk space
elif [[ ${existing_free_kilobytes} -lt ${required_free_kilobytes} ]]; then
echo "::: Insufficient Disk Space!"
echo "::: Your system appears to be low on disk space. pi-hole recommends a minimum of $required_free_kilobytes KiloBytes."
echo "::: You only have ${existing_free_kilobytes} KiloBytes free."
echo "::: If this is a new install you may need to expand your disk."
echo "::: Try running 'sudo raspi-config', and choose the 'expand file system option'"
echo "::: After rebooting, run this installation again. (curl -L https://install.pi-hole.net | bash)"
echo "Insufficient free space, exiting..."
exit 1
fi
}
chooseInterface() {
# Turn the available interfaces into an array so it can be used with a whiptail dialog
local interfacesArray=()
# Number of available interfaces
local interfaceCount
# Whiptail variable storage
local chooseInterfaceCmd
# Temporary Whiptail options storage
local chooseInterfaceOptions
# Loop sentinel variable
local firstLoop=1
while read -r line; do
mode="OFF"
if [[ ${firstLoop} -eq 1 ]]; then
firstLoop=0
mode="ON"
fi
interfacesArray+=("${line}" "available" "${mode}")
done <<< "${availableInterfaces}"
# Find out how many interfaces are available to choose from
interfaceCount=$(echo "${availableInterfaces}" | wc -l)
chooseInterfaceCmd=(whiptail --separate-output --radiolist "Choose An Interface (press space to select)" ${r} ${c} ${interfaceCount})
chooseInterfaceOptions=$("${chooseInterfaceCmd[@]}" "${interfacesArray[@]}" 2>&1 >/dev/tty)
if [[ $? = 0 ]]; then
for desiredInterface in ${chooseInterfaceOptions}; do
PIHOLE_INTERFACE=${desiredInterface}
echo "::: Using interface: $PIHOLE_INTERFACE"
done
else
echo "::: Cancel selected, exiting...."
exit 1
fi
}
useIPv6dialog() {
# Show the IPv6 address used for blocking
IPV6_ADDRESS=$(ip -6 route get 2001:4860:4860::8888 | awk -F " " '{ for(i=1;i<=NF;i++) if ($i == "src") print $(i+1) }')
whiptail --msgbox --backtitle "IPv6..." --title "IPv6 Supported" "$IPV6_ADDRESS will be used to block ads." ${r} ${c}
}
use4andor6() {
local useIPv4
local useIPv6
# Let use select IPv4 and/or IPv6
cmd=(whiptail --separate-output --checklist "Select Protocols (press space to select)" ${r} ${c} 2)
options=(IPv4 "Block ads over IPv4" on
IPv6 "Block ads over IPv6" on)
choices=$("${cmd[@]}" "${options[@]}" 2>&1 >/dev/tty)
if [[ $? = 0 ]];then
for choice in ${choices}
do
case ${choice} in
IPv4 ) useIPv4=true;;
IPv6 ) useIPv6=true;;
esac
done
if [[ ${useIPv4} ]]; then
find_IPv4_information
getStaticIPv4Settings
setStaticIPv4
fi
if [[ ${useIPv6} ]]; then
useIPv6dialog
fi
echo "::: IPv4 address: ${IPV4_ADDRESS}"
echo "::: IPv6 address: ${IPV6_ADDRESS}"
if [ ! ${useIPv4} ] && [ ! ${useIPv6} ]; then
echo "::: Cannot continue, neither IPv4 or IPv6 selected"
echo "::: Exiting"
exit 1
fi
else
echo "::: Cancel selected. Exiting..."
exit 1
fi
}
getStaticIPv4Settings() {
# Ask if the user wants to use DHCP settings as their static IP
if (whiptail --backtitle "Calibrating network interface" --title "Static IP Address" --yesno "Do you want to use your current network settings as a static address?
IP address: ${IPV4_ADDRESS}
Gateway: ${IPv4gw}" ${r} ${c}); then
# If they choose yes, let the user know that the IP address will not be available via DHCP and may cause a conflict.
whiptail --msgbox --backtitle "IP information" --title "FYI: IP Conflict" "It is possible your router could still try to assign this IP to a device, which would cause a conflict. But in most cases the router is smart enough to not do that.
If you are worried, either manually set the address, or modify the DHCP reservation pool so it does not include the IP you want.
It is also possible to use a DHCP reservation, but if you are going to do that, you might as well set a static address." ${r} ${c}
# Nothing else to do since the variables are already set above
else
# Otherwise, we need to ask the user to input their desired settings.
# Start by getting the IPv4 address (pre-filling it with info gathered from DHCP)
# Start a loop to let the user enter their information with the chance to go back and edit it if necessary
until [[ ${ipSettingsCorrect} = True ]]; do
# Ask for the IPv4 address
IPV4_ADDRESS=$(whiptail --backtitle "Calibrating network interface" --title "IPv4 address" --inputbox "Enter your desired IPv4 address" ${r} ${c} "${IPV4_ADDRESS}" 3>&1 1>&2 2>&3)
if [[ $? = 0 ]]; then
echo "::: Your static IPv4 address: ${IPV4_ADDRESS}"
# Ask for the gateway
IPv4gw=$(whiptail --backtitle "Calibrating network interface" --title "IPv4 gateway (router)" --inputbox "Enter your desired IPv4 default gateway" ${r} ${c} "${IPv4gw}" 3>&1 1>&2 2>&3)
if [[ $? = 0 ]]; then
echo "::: Your static IPv4 gateway: ${IPv4gw}"
# Give the user a chance to review their settings before moving on
if (whiptail --backtitle "Calibrating network interface" --title "Static IP Address" --yesno "Are these settings correct?
IP address: ${IPV4_ADDRESS}
Gateway: ${IPv4gw}" ${r} ${c}); then
# After that's done, the loop ends and we move on
ipSettingsCorrect=True
else
# If the settings are wrong, the loop continues
ipSettingsCorrect=False
fi
else
# Cancelling gateway settings window
ipSettingsCorrect=False
echo "::: Cancel selected. Exiting..."
exit 1
fi
else
# Cancelling IPv4 settings window
ipSettingsCorrect=False
echo "::: Cancel selected. Exiting..."
exit 1
fi
done
# End the if statement for DHCP vs. static
fi
}
setDHCPCD() {
# Append these lines to dhcpcd.conf to enable a static IP
echo "## interface ${PIHOLE_INTERFACE}
static ip_address=${IPV4_ADDRESS}
static routers=${IPv4gw}
static domain_name_servers=${IPv4gw}" | tee -a /etc/dhcpcd.conf >/dev/null
}
setStaticIPv4() {
local IFCFG_FILE
local IPADDR
local CIDR
if [[ -f /etc/dhcpcd.conf ]]; then
# Debian Family
if grep -q "${IPV4_ADDRESS}" /etc/dhcpcd.conf; then
echo "::: Static IP already configured"
else
setDHCPCD
ip addr replace dev "${PIHOLE_INTERFACE}" "${IPV4_ADDRESS}"
echo ":::"
echo "::: Setting IP to ${IPV4_ADDRESS}. You may need to restart after the install is complete."
echo ":::"
fi
elif [[ -f /etc/sysconfig/network-scripts/ifcfg-${PIHOLE_INTERFACE} ]];then
# Fedora Family
IFCFG_FILE=/etc/sysconfig/network-scripts/ifcfg-${PIHOLE_INTERFACE}
if grep -q "${IPV4_ADDRESS}" "${IFCFG_FILE}"; then
echo "::: Static IP already configured"
else
IPADDR=$(echo "${IPV4_ADDRESS}" | cut -f1 -d/)
CIDR=$(echo "${IPV4_ADDRESS}" | cut -f2 -d/)
# Backup existing interface configuration:
cp "${IFCFG_FILE}" "${IFCFG_FILE}".pihole.orig
# Build Interface configuration file:
{
echo "# Configured via Pi-Hole installer"
echo "DEVICE=$PIHOLE_INTERFACE"
echo "BOOTPROTO=none"
echo "ONBOOT=yes"
echo "IPADDR=$IPADDR"
echo "PREFIX=$CIDR"
echo "GATEWAY=$IPv4gw"
echo "DNS1=$PIHOLE_DNS_1"
echo "DNS2=$PIHOLE_DNS_2"
echo "USERCTL=no"
}> "${IFCFG_FILE}"
ip addr replace dev "${PIHOLE_INTERFACE}" "${IPV4_ADDRESS}"
if [ -x "$(command -v nmcli)" ];then
# Tell NetworkManager to read our new sysconfig file
nmcli con load "${IFCFG_FILE}" > /dev/null
fi
echo ":::"
echo "::: Setting IP to ${IPV4_ADDRESS}. You may need to restart after the install is complete."
echo ":::"
fi
else
echo "::: Warning: Unable to locate configuration file to set static IPv4 address!"
exit 1
fi
}
valid_ip() {
local ip=${1}
local stat=1
if [[ ${ip} =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then
OIFS=$IFS
IFS='.'
ip=(${ip})
IFS=${OIFS}
[[ ${ip[0]} -le 255 && ${ip[1]} -le 255 \
&& ${ip[2]} -le 255 && ${ip[3]} -le 255 ]]
stat=$?
fi
return ${stat}
}
setDNS() {
DNSChooseCmd=(whiptail --separate-output --radiolist "Select Upstream DNS Provider. To use your own, select Custom." ${r} ${c} 6)
DNSChooseOptions=(Google "" on
OpenDNS "" off
Level3 "" off
Norton "" off
Comodo "" off
Custom "" off)
DNSchoices=$("${DNSChooseCmd[@]}" "${DNSChooseOptions[@]}" 2>&1 >/dev/tty)
if [[ $? = 0 ]];then
case ${DNSchoices} in
Google)
echo "::: Using Google DNS servers."
PIHOLE_DNS_1="8.8.8.8"
PIHOLE_DNS_2="8.8.4.4"
;;
OpenDNS)
echo "::: Using OpenDNS servers."
PIHOLE_DNS_1="208.67.222.222"
PIHOLE_DNS_2="208.67.220.220"
;;
Level3)
echo "::: Using Level3 servers."
PIHOLE_DNS_1="4.2.2.1"
PIHOLE_DNS_2="4.2.2.2"
;;
Norton)
echo "::: Using Norton ConnectSafe servers."
PIHOLE_DNS_1="199.85.126.10"
PIHOLE_DNS_2="199.85.127.10"
;;
Comodo)
echo "::: Using Comodo Secure servers."
PIHOLE_DNS_1="8.26.56.26"
PIHOLE_DNS_2="8.20.247.20"
;;
Custom)
until [[ ${DNSSettingsCorrect} = True ]]; do
strInvalid="Invalid"
if [ ! ${PIHOLE_DNS_1} ]; then
if [ ! ${PIHOLE_DNS_2} ]; then
prePopulate=""
else
prePopulate=", ${PIHOLE_DNS_2}"
fi
elif [ ${PIHOLE_DNS_1} ] && [ ! ${PIHOLE_DNS_2} ]; then
prePopulate="${PIHOLE_DNS_1}"
elif [ ${PIHOLE_DNS_1} ] && [ ${PIHOLE_DNS_2} ]; then
prePopulate="${PIHOLE_DNS_1}, ${PIHOLE_DNS_2}"
fi
piholeDNS=$(whiptail --backtitle "Specify Upstream DNS Provider(s)" --inputbox "Enter your desired upstream DNS provider(s), seperated by a comma.\n\nFor example '8.8.8.8, 8.8.4.4'" ${r} ${c} "${prePopulate}" 3>&1 1>&2 2>&3)
if [[ $? = 0 ]]; then
PIHOLE_DNS_1=$(echo "${piholeDNS}" | sed 's/[, \t]\+/,/g' | awk -F, '{print$1}')
PIHOLE_DNS_2=$(echo "${piholeDNS}" | sed 's/[, \t]\+/,/g' | awk -F, '{print$2}')
if ! valid_ip "${PIHOLE_DNS_1}" || [ ! "${PIHOLE_DNS_1}" ]; then
PIHOLE_DNS_1=${strInvalid}
fi
if ! valid_ip "${PIHOLE_DNS_2}" && [ "${PIHOLE_DNS_2}" ]; then
PIHOLE_DNS_2=${strInvalid}
fi
else
echo "::: Cancel selected, exiting...."
exit 1
fi
if [[ ${PIHOLE_DNS_1} == "${strInvalid}" ]] || [[ ${PIHOLE_DNS_2} == "${strInvalid}" ]]; then
whiptail --msgbox --backtitle "Invalid IP" --title "Invalid IP" "One or both entered IP addresses were invalid. Please try again.\n\n DNS Server 1: $PIHOLE_DNS_1\n DNS Server 2: ${PIHOLE_DNS_2}" ${r} ${c}
if [[ ${PIHOLE_DNS_1} == "${strInvalid}" ]]; then
PIHOLE_DNS_1=""
fi
if [[ ${PIHOLE_DNS_2} == "${strInvalid}" ]]; then
PIHOLE_DNS_2=""
fi
DNSSettingsCorrect=False
else
if (whiptail --backtitle "Specify Upstream DNS Provider(s)" --title "Upstream DNS Provider(s)" --yesno "Are these settings correct?\n DNS Server 1: $PIHOLE_DNS_1\n DNS Server 2: ${PIHOLE_DNS_2}" ${r} ${c}); then
DNSSettingsCorrect=True
else
# If the settings are wrong, the loop continues
DNSSettingsCorrect=False
fi
fi
done
;;
esac
else
echo "::: Cancel selected. Exiting..."
exit 1
fi
}
setLogging() {
local LogToggleCommand
local LogChooseOptions
local LogChoices
LogToggleCommand=(whiptail --separate-output --radiolist "Do you want to log queries?\n (Disabling will render graphs on the Admin page useless):" ${r} ${c} 6)
LogChooseOptions=("On (Reccomended)" "" on
Off "" off)
LogChoices=$("${LogToggleCommand[@]}" "${LogChooseOptions[@]}" 2>&1 >/dev/tty) || (echo "::: Cancel selected. Exiting..." && exit 1)
case ${LogChoices} in
"On (Recommended)")
echo "::: Logging On."
QUERY_LOGGING=true
;;
Off)
echo "::: Logging Off."
QUERY_LOGGING=false
;;
esac
}
version_check_dnsmasq() {
# Check if /etc/dnsmasq.conf is from pihole. If so replace with an original and install new in .d directory
local dnsmasq_conf="/etc/dnsmasq.conf"
local dnsmasq_conf_orig="/etc/dnsmasq.conf.orig"
local dnsmasq_pihole_id_string="addn-hosts=/etc/pihole/gravity.list"
local dnsmasq_original_config="/etc/.pihole/advanced/dnsmasq.conf.original"
local dnsmasq_pihole_01_snippet="/etc/.pihole/advanced/01-pihole.conf"
local dnsmasq_pihole_01_location="/etc/dnsmasq.d/01-pihole.conf"
if [ -f ${dnsmasq_conf} ]; then
echo -n "::: Existing dnsmasq.conf found..."
if grep -q ${dnsmasq_pihole_id_string} ${dnsmasq_conf}; then
echo " it is from a previous pi-hole install."
echo -n "::: Backing up dnsmasq.conf to dnsmasq.conf.orig..."
mv -f ${dnsmasq_conf} ${dnsmasq_conf_orig}
echo " done."
echo -n "::: Restoring default dnsmasq.conf..."
cp ${dnsmasq_original_config} ${dnsmasq_conf}
echo " done."
else
echo " it is not a pi-hole file, leaving alone!"
fi
else
echo -n "::: No dnsmasq.conf found.. restoring default dnsmasq.conf..."
cp ${dnsmasq_original_config} ${dnsmasq_conf}
echo " done."
fi
echo -n "::: Copying 01-pihole.conf to /etc/dnsmasq.d/01-pihole.conf..."
cp ${dnsmasq_pihole_01_snippet} ${dnsmasq_pihole_01_location}
echo " done."
sed -i "s/@INT@/$PIHOLE_INTERFACE/" ${dnsmasq_pihole_01_location}
if [[ "${PIHOLE_DNS_1}" != "" ]]; then
sed -i "s/@DNS1@/$PIHOLE_DNS_1/" ${dnsmasq_pihole_01_location}
else
sed -i '/^server=@DNS1@/d' ${dnsmasq_pihole_01_location}
fi
if [[ "${PIHOLE_DNS_2}" != "" ]]; then
sed -i "s/@DNS2@/$PIHOLE_DNS_2/" ${dnsmasq_pihole_01_location}
else
sed -i '/^server=@DNS2@/d' ${dnsmasq_pihole_01_location}
fi
sed -i 's/^#conf-dir=\/etc\/dnsmasq.d$/conf-dir=\/etc\/dnsmasq.d/' ${dnsmasq_conf}
if [[ "${QUERY_LOGGING}" == false ]] ; then
#Disable Logging
sed -i 's/^log-queries/#log-queries/' ${dnsmasq_pihole_01_location}
else
#Enable Logging
sed -i 's/^#log-queries/log-queries/' ${dnsmasq_pihole_01_location}
fi
}
remove_legacy_scripts() {
#Tidy up /usr/local/bin directory if installing over previous install.
oldFiles=( gravity chronometer whitelist blacklist piholeLogFlush updateDashboard uninstall setupLCD piholeDebug)
for i in "${oldFiles[@]}"; do
if [ -f "/usr/local/bin/$i.sh" ]; then
rm /usr/local/bin/"$i".sh
fi
done
}
clean_existing() {
# Clean an exiting installation to prepare for upgrade/reinstall
# ${1} Directory to clean; ${2} Array of files to remove
local clean_directory="${1}"
local old_files=${2}
for script in "${old_files[@]}"; do
rm -f "${clean_directory}${script}.sh"
done
}
installScripts() {
# Install the scripts from repository to their various locations
readonly install_dir="/opt/pihole/"
echo ":::"
echo -n "::: Installing scripts from ${PI_HOLE_LOCAL_REPO}..."
# Clear out script files from Pi-hole scripts directory.
clean_existing "${install_dir}" "${PI_HOLE_FILES}"
# Install files from local core repository
if is_repo "${PI_HOLE_LOCAL_REPO}"; then
cd "${PI_HOLE_LOCAL_REPO}"
install -o "${USER}" -Dm755 -t /opt/pihole/ gravity.sh
install -o "${USER}" -Dm755 -t /opt/pihole/ ./advanced/Scripts/*.sh
install -o "${USER}" -Dm755 -t /opt/pihole/ ./automated\ install/uninstall.sh
install -o "${USER}" -Dm755 -t /usr/local/bin/ pihole
install -Dm644 ./advanced/bash-completion/pihole /etc/bash_completion.d/pihole
echo " done."
else
echo " *** ERROR: Local repo ${core_repo} not found, exiting."
exit 1
fi
}
installConfigs() {
# Install the configs from /etc/.pihole to their various locations
echo ":::"
echo "::: Installing configs..."
version_check_dnsmasq
if [ ! -d "/etc/lighttpd" ]; then
mkdir /etc/lighttpd
chown "${USER}":root /etc/lighttpd
elif [ -f "/etc/lighttpd/lighttpd.conf" ]; then
mv /etc/lighttpd/lighttpd.conf /etc/lighttpd/lighttpd.conf.orig
fi
cp /etc/.pihole/advanced/${LIGHTTPD_CFG} /etc/lighttpd/lighttpd.conf
mkdir -p /var/run/lighttpd
chown ${LIGHTTPD_USER}:${LIGHTTPD_GROUP} /var/run/lighttpd
mkdir -p /var/cache/lighttpd/compress
chown ${LIGHTTPD_USER}:${LIGHTTPD_GROUP} /var/cache/lighttpd/compress
mkdir -p /var/cache/lighttpd/uploads
chown ${LIGHTTPD_USER}:${LIGHTTPD_GROUP} /var/cache/lighttpd/uploads
}
stop_service() {
# Stop service passed in as argument.
# Can softfail, as process may not be installed when this is called
echo ":::"
echo -n "::: Stopping ${1} service..."
if [ -x "$(command -v systemctl)" ]; then
systemctl stop "${1}" &> /dev/null || true
else
service "${1}" stop &> /dev/null || true
fi
echo " done."
}
start_service() {
# Start/Restart service passed in as argument
# This should not fail, it's an error if it does
echo ":::"
echo -n "::: Starting ${1} service..."
if [ -x "$(command -v systemctl)" ]; then
systemctl restart "${1}" &> /dev/null
else
service "${1}" restart &> /dev/null
fi
echo " done."
}
enable_service() {
# Enable service so that it will start with next reboot
echo ":::"
echo -n "::: Enabling ${1} service to start on reboot..."
if [ -x "$(command -v systemctl)" ]; then
systemctl enable "${1}" &> /dev/null
else
update-rc.d "${1}" defaults &> /dev/null
fi
echo " done."
}
update_pacakge_cache() {
#Running apt-get update/upgrade with minimal output can cause some issues with
#requiring user input (e.g password for phpmyadmin see #218)
#Check to see if apt-get update has already been run today
#it needs to have been run at least once on new installs!
timestamp=$(stat -c %Y ${PKG_CACHE})
timestampAsDate=$(date -d @"${timestamp}" "+%b %e")
today=$(date "+%b %e")
if [ ! "${today}" == "${timestampAsDate}" ]; then
#update package lists
echo ":::"
echo -n "::: ${PKG_MANAGER} update has not been run today. Running now..."
${UPDATE_PKG_CACHE} &> /dev/null
echo " done!"
fi
}
notify_package_updates_available() {
# Let user know if they have outdated packages on their system and
# advise them to run a package update at soonest possible.
echo ":::"
echo -n "::: Checking ${PKG_MANAGER} for upgraded packages...."
updatesToInstall=$(eval "${PKG_COUNT}")
echo " done!"
echo ":::"
if [[ ${updatesToInstall} -eq "0" ]]; then
echo "::: Your system is up to date! Continuing with Pi-hole installation..."
else
echo "::: There are ${updatesToInstall} updates available for your system!"
echo "::: We recommend you run '${PKG_UPDATE}' after installing Pi-Hole! "
echo ":::"
fi
}
install_dependent_packages() {
# Install packages passed in via argument array
# No spinner - conflicts with set -e
declare -a argArray1=("${!1}")
if command -v debconf-apt-progress &> /dev/null; then
debconf-apt-progress -- ${PKG_INSTALL} "${argArray1[@]}"
else
for i in "${argArray1[@]}"; do
echo -n "::: Checking for $i..."
package_check_install "${i}" &> /dev/null
echo " installed!"
done
fi
}
CreateLogFile() {
# Create logfiles if necessary
echo ":::"
echo -n "::: Creating log file and changing owner to dnsmasq..."
if [ ! -f /var/log/pihole.log ]; then
touch /var/log/pihole.log
chmod 644 /var/log/pihole.log
chown "${DNSMASQ_USER}":root /var/log/pihole.log
echo " done!"
else
echo " already exists!"
fi
}
installPiholeWeb() {
# Install the web interface
echo ":::"
echo "::: Installing pihole custom index page..."
if [ -d "/var/www/html/pihole" ]; then
if [ -f "/var/www/html/pihole/index.html" ]; then
echo "::: Existing index.html detected, not overwriting"
else
echo -n "::: index.html missing, replacing... "
cp /etc/.pihole/advanced/index.html /var/www/html/pihole/
echo " done!"
fi
if [ -f "/var/www/html/pihole/index.js" ]; then
echo "::: Existing index.js detected, not overwriting"
else
echo -n "::: index.js missing, replacing... "
cp /etc/.pihole/advanced/index.js /var/www/html/pihole/
echo " done!"
fi
else
mkdir /var/www/html/pihole
if [ -f /var/www/html/index.lighttpd.html ]; then
mv /var/www/html/index.lighttpd.html /var/www/html/index.lighttpd.orig
else
printf "\n:::\tNo default index.lighttpd.html file found... not backing up"
fi
cp /etc/.pihole/advanced/index.* /var/www/html/pihole/.
echo " done!"
fi
# Install Sudoer file
echo ":::"
echo -n "::: Installing sudoer file..."
mkdir -p /etc/sudoers.d/
cp /etc/.pihole/advanced/pihole.sudo /etc/sudoers.d/pihole
chmod 0440 /etc/sudoers.d/pihole
echo " done!"
}
installCron() {
# Install the cron job
echo ":::"
echo -n "::: Installing latest Cron script..."
cp /etc/.pihole/advanced/pihole.cron /etc/cron.d/pihole
echo " done!"
}
runGravity() {
# Run gravity.sh to build blacklists
echo ":::"
echo "::: Preparing to run gravity.sh to refresh hosts..."
if ls /etc/pihole/list* 1> /dev/null 2>&1; then
echo "::: Cleaning up previous install (preserving whitelist/blacklist)"
rm /etc/pihole/list.*
fi
echo "::: Running gravity.sh"
/opt/pihole/gravity.sh
}
create_pihole_user() {
# Check if user pihole exists and create if not
echo "::: Checking if user 'pihole' exists..."
id -u pihole &> /dev/null && echo "::: User 'pihole' already exists" || (echo "::: User 'pihole' doesn't exist. Creating..." && useradd -r -s /usr/sbin/nologin pihole)
}
configureFirewall() {
# Allow HTTP and DNS traffic
if [ -x "$(command -v firewall-cmd)" ]; then
firewall-cmd --state &> /dev/null && ( echo "::: Configuring firewalld for httpd and dnsmasq.." && firewall-cmd --permanent --add-port=80/tcp && firewall-cmd --permanent --add-port=53/tcp \
&& firewall-cmd --permanent --add-port=53/udp && firewall-cmd --reload) || echo "::: FirewallD not enabled"
elif [ -x "$(command -v iptables)" ]; then
echo "::: Configuring iptables for httpd and dnsmasq.."
iptables -A INPUT -p tcp -m tcp --dport 80 -j ACCEPT
iptables -A INPUT -p tcp -m tcp --dport 53 -j ACCEPT
iptables -A INPUT -p udp -m udp --dport 53 -j ACCEPT
else
echo "::: No firewall detected.. skipping firewall configuration."
fi
}
finalExports() {
# Update variables in setupVars.conf file
if [ -e "${setupVars}" ]; then
sed -i.update.bak '/PIHOLE_INTERFACE/d;/IPV4_ADDRESS/d;/IPV6_ADDRESS/d;/PIHOLE_DNS_1/d;/PIHOLE_DNS_2/d;/QUERY_LOGGING/d;' "${setupVars}"
fi
{
echo "PIHOLE_INTERFACE=${PIHOLE_INTERFACE}"
echo "IPV4_ADDRESS=${IPV4_ADDRESS}"
echo "IPV6_ADDRESS=${IPV6_ADDRESS}"
echo "PIHOLE_DNS_1=${PIHOLE_DNS_1}"
echo "PIHOLE_DNS_2=${PIHOLE_DNS_2}"
echo "QUERY_LOGGING=${QUERY_LOGGING}"
}>> "${setupVars}"
}
installPihole() {
# Install base files and web interface
create_pihole_user
if [ ! -d "/var/www/html" ]; then
mkdir -p /var/www/html
fi
chown ${LIGHTTPD_USER}:${LIGHTTPD_GROUP} /var/www/html
chmod 775 /var/www/html
usermod -a -G ${LIGHTTPD_GROUP} pihole
if [ -x "$(command -v lighty-enable-mod)" ]; then
lighty-enable-mod fastcgi fastcgi-php > /dev/null || true
else
printf "\n:::\tWarning: 'lighty-enable-mod' utility not found. Please ensure fastcgi is enabled if you experience issues.\n"
fi
installScripts
installConfigs
CreateLogFile
configureSelinux
installPiholeWeb
installCron
configureFirewall
finalExports
runGravity
}
accountForRefactor() {
# At some point in the future this list can be pruned, for now we'll need it to ensure updates don't break.
# Refactoring of install script has changed the name of a couple of variables. Sort them out here.
sed -i 's/piholeInterface/PIHOLE_INTERFACE/g' ${setupVars}
sed -i 's/IPv4_address/IPV4_ADDRESS/g' ${setupVars}
sed -i 's/IPv4addr/IPV4_ADDRESS/g' ${setupVars}
sed -i 's/IPv6_address/IPV6_ADDRESS/g' ${setupVars}
sed -i 's/piholeIPv6/IPV6_ADDRESS/g' ${setupVars}
sed -i 's/piholeDNS1/PIHOLE_DNS_1/g' ${setupVars}
sed -i 's/piholeDNS2/PIHOLE_DNS_2/g' ${setupVars}
}
updatePihole() {
accountForRefactor
# Source ${setupVars} for use in the rest of the functions.
. ${setupVars}
# Install base files and web interface
installScripts
installConfigs
CreateLogFile
configureSelinux
installPiholeWeb
installCron
configureFirewall
finalExports #re-export setupVars.conf to account for any new vars added in new versions
runGravity
}
configureSelinux() {
if [ -x "$(command -v getenforce)" ]; then
printf "\n::: SELinux Detected\n"
printf ":::\tChecking for SELinux policy development packages..."
package_check_install "selinux-policy-devel" > /dev/null
echo " installed!"
printf ":::\tEnabling httpd server side includes (SSI).. "
setsebool -P httpd_ssi_exec on &> /dev/null && echo "Success" || echo "SELinux not enabled"
printf "\n:::\tCompiling Pi-Hole SELinux policy..\n"
if ! [ -x "$(command -v systemctl)" ]; then
sed -i.bak '/systemd/d' /etc/.pihole/advanced/selinux/pihole.te
fi
checkmodule -M -m -o /etc/pihole/pihole.mod /etc/.pihole/advanced/selinux/pihole.te
semodule_package -o /etc/pihole/pihole.pp -m /etc/pihole/pihole.mod
semodule -i /etc/pihole/pihole.pp
rm -f /etc/pihole/pihole.mod
semodule -l | grep pihole &> /dev/null && echo "::: Installed Pi-Hole SELinux policy" || echo "::: Warning: Pi-Hole SELinux policy did not install."
fi
}
displayFinalMessage() {
if (( ${#1} > 0 )) ; then
# Final completion message to user
whiptail --msgbox --backtitle "Make it so." --title "Installation Complete!" "Configure your devices to use the Pi-hole as their DNS server using:
IPv4: ${IPV4_ADDRESS%/*}
IPv6: ${IPV6_ADDRESS}
If you set a new IP address, you should restart the Pi.
The install log is in /etc/pihole.
View the web interface at http://pi.hole/admin or http://${IPV4_ADDRESS%/*}/admin
The currently set password is ${1}" ${r} ${c}
else
whiptail --msgbox --backtitle "Make it so." --title "Installation Complete!" "Configure your devices to use the Pi-hole as their DNS server using:
IPv4: ${IPV4_ADDRESS%/*}
IPv6: ${IPV6_ADDRESS}
If you set a new IP address, you should restart the Pi.
The install log is in /etc/pihole.
View the web interface at http://pi.hole/admin or http://${IPV4_ADDRESS%/*}/admin" ${r} ${c}
fi
}
update_dialogs() {
# reconfigure
if [ "${reconfigure}" = true ]; then
opt1a="Repair"
opt1b="This will retain existing settings"
strAdd="You will remain on the same version"
else
opt1a="Update"
opt1b="This will retain existing settings."
strAdd="You will be updated to the latest version."
fi
opt2a="Reconfigure"
opt2b="This will allow you to enter new settings"
UpdateCmd=$(whiptail --title "Existing Install Detected!" --menu "\n\nWe have detected an existing install.\n\nPlease choose from the following options: \n($strAdd)" ${r} ${c} 2 \
"${opt1a}" "${opt1b}" \
"${opt2a}" "${opt2b}" 3>&2 2>&1 1>&3)
if [[ $? = 0 ]];then
case ${UpdateCmd} in
${opt1a})
echo "::: ${opt1a} option selected."
useUpdateVars=true
;;
${opt2a})
echo "::: ${opt2a} option selected"
useUpdateVars=false
;;
esac
else
echo "::: Cancel selected. Exiting..."
exit 1
fi
}
main() {
# Check arguments for the undocumented flags
for var in "$@"; do
case "$var" in
"--reconfigure" ) reconfigure=true;;
"--i_do_not_follow_recommendations" ) skipSpaceCheck=false;;
"--unattended" ) runUnattended=true;;
esac
done
if [[ -f ${setupVars} ]]; then
if [[ "${runUnattended}" == true ]]; then
echo "::: --unattended passed to install script, no whiptail dialogs will be displayed"
useUpdateVars=true
else
update_dialogs
fi
fi
# Start the installer
# Verify there is enough disk space for the install
if [[ "${skipSpaceCheck}" == true ]]; then
echo "::: --i_do_not_follow_recommendations passed to script, skipping free disk space verification!"
else
verifyFreeDiskSpace
fi
# Update package cache
update_pacakge_cache
# Notify user of package availability
notify_package_updates_available
# Install packages used by this installation script
install_dependent_packages INSTALLER_DEPS[@]
if [[ "${reconfigure}" == true ]]; then
echo "::: --reconfigure passed to install script. Not downloading/updating local repos"
else
# Get Git files for Core and Admin
getGitFiles ${PI_HOLE_LOCAL_REPO} ${piholeGitUrl}
getGitFiles ${webInterfaceDir} ${webInterfaceGitUrl}
fi
if [[ ${useUpdateVars} == false ]]; then
# Display welcome dialogs
welcomeDialogs
# Create directory for Pi-hole storage
mkdir -p /etc/pihole/
# Remove legacy scripts from previous storage location
remove_legacy_scripts
# Stop resolver and webserver while installing proceses
stop_service dnsmasq
stop_service lighttpd
# Determine available interfaces
get_available_interfaces
# Find interfaces and let the user choose one
chooseInterface
# Let the user decide if they want to block ads over IPv4 and/or IPv6
use4andor6
# Decide what upstream DNS Servers to use
setDNS
# Let the user decide if they want query logging enabled...
setLogging
# Install packages used by the Pi-hole
install_dependent_packages PIHOLE_DEPS[@]
# Install and log everything to a file
installPihole | tee ${tmpLog}
else
# update packages used by the Pi-hole
install_dependent_packages PIHOLE_DEPS[@]
updatePihole | tee ${tmpLog}
fi
# Move the log file into /etc/pihole for storage
mv ${tmpLog} ${instalLogLoc}
# Add password to web UI if there is none
pw=""
if [[ $(grep 'WEBPASSWORD' -c /etc/pihole/setupVars.conf) == 0 ]] ; then
pw=$(tr -dc _A-Z-a-z-0-9 < /dev/urandom | head -c 8)
pihole -a -p ${pw}
fi
if [[ "${useUpdateVars}" == false ]]; then
displayFinalMessage ${pw}
fi
echo "::: Restarting services..."
# Start services
start_service dnsmasq
enable_service dnsmasq
start_service lighttpd
enable_service lighttpd
echo "::: done."
echo ":::"
if [[ "${useUpdateVars}" == false ]]; then
echo "::: Installation Complete! Configure your devices to use the Pi-hole as their DNS server using:"
echo "::: ${IPV4_ADDRESS%/*}"
echo "::: ${IPV6_ADDRESS}"
echo ":::"
echo "::: If you set a new IP address, you should restart the Pi."
echo "::: View the web interface at http://pi.hole/admin or http://${IPV4_ADDRESS%/*}/admin"
else
echo "::: Update complete!"
fi
if (( ${#pw} > 0 )) ; then
echo ":::"
echo "::: Note: As security measure a password has been installed for your web interface"
echo "::: The currently set password is"
echo "::: ${pw}"
echo ":::"
echo "::: You can always change it using"
echo "::: pihole -a -p new_password"
fi
echo ":::"
echo "::: The install log is located at: /etc/pihole/install.log"
}
if [[ "${PH_TEST}" != true ]] ; then
main "$@"
fi
\ No newline at end of file
+#!/usr/bin/env bash
+# Pi-hole: A black hole for Internet advertisements
+# (c) 2015, 2016 by Jacob Salmela
+# Network-wide ad blocking via your Raspberry Pi
+# http://pi-hole.net
+# Installs Pi-hole
+#
+# Pi-hole is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 2 of the License, or
+# (at your option) any later version.
+
+# pi-hole.net/donate
+#
+# Install with this command (from your Pi):
+#
+# curl -L install.pi-hole.net | bash
+
+set -e
+######## VARIABLES #########
+tmpLog=/tmp/pihole-install.log
+instalLogLoc=/etc/pihole/install.log
+setupVars=/etc/pihole/setupVars.conf
+
+webInterfaceGitUrl="https://github.com/pi-hole/AdminLTE.git"
+webInterfaceDir="/var/www/html/admin"
+piholeGitUrl="https://github.com/pi-hole/pi-hole.git"
+PI_HOLE_LOCAL_REPO="/etc/.pihole"
+PI_HOLE_FILES=(chronometer list piholeDebug piholeLogFlush setupLCD update version)
+useUpdateVars=false
+
+IPV4_ADDRESS=""
+IPV6_ADDRESS=""
+QUERY_LOGGING=true
+
+# Find the rows and columns will default to 80x24 is it can not be detected
+screen_size=$(stty size 2>/dev/null || echo 24 80)
+rows=$(echo $screen_size | awk '{print $1}')
+columns=$(echo $screen_size | awk '{print $2}')
+
+# Divide by two so the dialogs take up half of the screen, which looks nice.
+r=$(( rows / 2 ))
+c=$(( columns / 2 ))
+# Unless the screen is tiny
+r=$(( r < 20 ? 20 : r ))
+c=$(( c < 70 ? 70 : c ))
+
+######## Undocumented Flags. Shhh ########
+skipSpaceCheck=false
+reconfigure=false
+runUnattended=false
+
+######## FIRST CHECK ########
+# Must be root to install
+echo ":::"
+if [[ ${EUID} -eq 0 ]]; then
+ echo "::: You are root."
+else
+ echo "::: Script called with non-root privileges. The Pi-hole installs server packages and configures"
+ echo "::: system networking, it requires elevated rights. Please check the contents of the script for"
+ echo "::: any concerns with this requirement. Please be sure to download this script from a trusted source."
+ echo ":::"
+ echo "::: Detecting the presence of the sudo utility for continuation of this install..."
+
+ if [ -x "$(command -v sudo)" ]; then
+ echo "::: Utility sudo located."
+ exec curl -sSL https://install.pi-hole.net | sudo bash "$@"
+ exit $?
+ else
+ echo "::: sudo is needed for the Web interface to run pihole commands. Please run this script as root and it will be automatically installed."
+ exit 1
+ fi
+fi
+
+# Compatibility
+
+if [[ $(command -v apt-get) ]]; then
+ #Debian Family
+ #############################################
+ PKG_MANAGER="apt-get"
+ PKG_CACHE="/var/lib/apt/lists/"
+ UPDATE_PKG_CACHE="${PKG_MANAGER} update"
+ PKG_UPDATE="${PKG_MANAGER} upgrade"
+ PKG_INSTALL="${PKG_MANAGER} --yes --fix-missing install"
+ # grep -c will return 1 retVal on 0 matches, block this throwing the set -e with an OR TRUE
+ PKG_COUNT="${PKG_MANAGER} -s -o Debug::NoLocking=true upgrade | grep -c ^Inst || true"
+ # #########################################
+ # fixes for dependancy differences
+ # Debian 7 doesn't have iproute2 use iproute
+ ${PKG_MANAGER} install --dry-run iproute2 > /dev/null 2>&1 && IPROUTE_PKG="iproute2" || IPROUTE_PKG="iproute"
+ # Prefer the php metapackage if it's there, fall back on the php5 pacakges
+ ${PKG_MANAGER} install --dry-run php > /dev/null 2>&1 && phpVer="php" || phpVer="php5"
+ # #########################################
+ INSTALLER_DEPS=(apt-utils debconf dhcpcd5 git whiptail)
+ PIHOLE_DEPS=(bc cron curl dnsmasq dnsutils ${IPROUTE_PKG} iputils-ping lighttpd lsof netcat ${phpVer}-common ${phpVer}-cgi sudo unzip wget)
+ LIGHTTPD_USER="www-data"
+ LIGHTTPD_GROUP="www-data"
+ LIGHTTPD_CFG="lighttpd.conf.debian"
+ DNSMASQ_USER="dnsmasq"
+
+ package_check_install() {
+ dpkg-query -W -f='${Status}' "${1}" 2>/dev/null | grep -c "ok installed" || ${PKG_INSTALL} "${1}"
+ }
+elif [ $(command -v rpm) ]; then
+ # Fedora Family
+ if [ $(command -v dnf) ]; then
+ PKG_MANAGER="dnf"
+ else
+ PKG_MANAGER="yum"
+ fi
+ PKG_CACHE="/var/cache/${PKG_MANAGER}"
+ UPDATE_PKG_CACHE="${PKG_MANAGER} check-update"
+ PKG_UPDATE="${PKG_MANAGER} update -y"
+ PKG_INSTALL="${PKG_MANAGER} install -y"
+ PKG_COUNT="${PKG_MANAGER} check-update | egrep '(.i686|.x86|.noarch|.arm|.src)' | wc -l"
+ INSTALLER_DEPS=(git iproute net-tools newt procps-ng)
+ PIHOLE_DEPS=(bc bind-utils cronie curl dnsmasq epel-release findutils lighttpd lighttpd-fastcgi nmap-ncat php php-common php-cli sudo unzip wget)
+
+ if grep -q 'Fedora' /etc/redhat-release; then
+ remove_deps=(epel-release);
+ PIHOLE_DEPS=( ${PIHOLE_DEPS[@]/$remove_deps} );
+ fi
+ LIGHTTPD_USER="lighttpd"
+ LIGHTTPD_GROUP="lighttpd"
+ LIGHTTPD_CFG="lighttpd.conf.fedora"
+ DNSMASQ_USER="nobody"
+
+ package_check_install() {
+ rpm -qa | grep ^"${1}"- > /dev/null || ${PKG_INSTALL} "${1}"
+ }
+else
+ echo "OS distribution not supported"
+ exit
+fi
+
+####### FUNCTIONS ##########
+is_repo() {
+ # Use git to check if directory is currently under VCS, return the value
+ local directory="${1}"
+ git -C "${directory}" status --short &> /dev/null
+ return
+}
+
+make_repo() {
+ local directory="${1}"
+ local remoteRepo="${2}"
+ # Remove the non-repod interface and clone the interface
+ echo -n "::: Cloning $remoteRepo into $directory..."
+ rm -rf "${directory}"
+ git clone -q --depth 1 "${remoteRepo}" "${directory}" &> /dev/null
+ echo " done!"
+}
+
+update_repo() {
+ local directory="${1}"
+ # Pull the latest commits
+ echo -n "::: Updating repo in $1..."
+ cd "${directory}" || exit 1
+ git stash -q &> /dev/null
+ git pull -q &> /dev/null
+ echo " done!"
+}
+
+getGitFiles() {
+ # Setup git repos for directory and repository passed
+ # as arguments 1 and 2
+ local directory="${1}"
+ local remoteRepo="${2}"
+ echo ":::"
+ echo "::: Checking for existing repository..."
+ if is_repo "${directory}"; then
+ update_repo "${directory}"
+ else
+ make_repo "${directory}" "${remoteRepo}"
+ fi
+}
+
+find_IPv4_information() {
+ # Find IP used to route to outside world
+ IPv4dev=$(ip route get 8.8.8.8 | awk '{for(i=1;i<=NF;i++)if($i~/dev/)print $(i+1)}')
+ IPV4_ADDRESS=$(ip -o -f inet addr show dev "$IPv4dev" | awk '{print $4}' | awk 'END {print}')
+ IPv4gw=$(ip route get 8.8.8.8 | awk '{print $3}')
+}
+
+get_available_interfaces() {
+ # Get available interfaces. Consider only getting UP interfaces in the future, and leaving DOWN interfaces out of list.
+ availableInterfaces=$(ip -o link | awk '{print $2}' | grep -v "lo" | cut -d':' -f1 | cut -d'@' -f1)
+}
+
+welcomeDialogs() {
+ # Display the welcome dialog
+ whiptail --msgbox --backtitle "Welcome" --title "Pi-hole automated installer" "\n\nThis installer will transform your device into a network-wide ad blocker!" ${r} ${c}
+
+ # Support for a part-time dev
+ whiptail --msgbox --backtitle "Plea" --title "Free and open source" "\n\nThe Pi-hole is free, but powered by your donations: http://pi-hole.net/donate" ${r} ${c}
+
+ # Explain the need for a static address
+ whiptail --msgbox --backtitle "Initiating network interface" --title "Static IP Needed" "\n\nThe Pi-hole is a SERVER so it needs a STATIC IP ADDRESS to function properly.
+
+In the next section, you can choose to use your current network settings (DHCP) or to manually edit them." ${r} ${c}
+}
+
+verifyFreeDiskSpace() {
+
+ # 50MB is the minimum space needed (45MB install (includes web admin bootstrap/jquery libraries etc) + 5MB one day of logs.)
+ # - Fourdee: Local ensures the variable is only created, and accessible within this function/void. Generally considered a "good" coding practice for non-global variables.
+ echo "::: Verifying free disk space..."
+ local required_free_kilobytes=51200
+ local existing_free_kilobytes=$(df -Pk | grep -m1 '\/$' | awk '{print $4}')
+
+ # - Unknown free disk space , not a integer
+ if ! [[ "${existing_free_kilobytes}" =~ ^([0-9])+$ ]]; then
+ echo "::: Unknown free disk space!"
+ echo "::: We were unable to determine available free disk space on this system."
+ echo "::: You may override this check and force the installation, however, it is not recommended"
+ echo "::: To do so, pass the argument '--i_do_not_follow_recommendations' to the install script"
+ echo "::: eg. curl -L https://install.pi-hole.net | bash /dev/stdin --i_do_not_follow_recommendations"
+ exit 1
+ # - Insufficient free disk space
+ elif [[ ${existing_free_kilobytes} -lt ${required_free_kilobytes} ]]; then
+ echo "::: Insufficient Disk Space!"
+ echo "::: Your system appears to be low on disk space. pi-hole recommends a minimum of $required_free_kilobytes KiloBytes."
+ echo "::: You only have ${existing_free_kilobytes} KiloBytes free."
+ echo "::: If this is a new install you may need to expand your disk."
+ echo "::: Try running 'sudo raspi-config', and choose the 'expand file system option'"
+ echo "::: After rebooting, run this installation again. (curl -L https://install.pi-hole.net | bash)"
+
+ echo "Insufficient free space, exiting..."
+ exit 1
+
+ fi
+
+}
+
+
+chooseInterface() {
+ # Turn the available interfaces into an array so it can be used with a whiptail dialog
+ local interfacesArray=()
+ # Number of available interfaces
+ local interfaceCount
+ # Whiptail variable storage
+ local chooseInterfaceCmd
+ # Temporary Whiptail options storage
+ local chooseInterfaceOptions
+ # Loop sentinel variable
+ local firstLoop=1
+
+ while read -r line; do
+ mode="OFF"
+ if [[ ${firstLoop} -eq 1 ]]; then
+ firstLoop=0
+ mode="ON"
+ fi
+ interfacesArray+=("${line}" "available" "${mode}")
+ done <<< "${availableInterfaces}"
+
+ # Find out how many interfaces are available to choose from
+ interfaceCount=$(echo "${availableInterfaces}" | wc -l)
+ chooseInterfaceCmd=(whiptail --separate-output --radiolist "Choose An Interface (press space to select)" ${r} ${c} ${interfaceCount})
+ chooseInterfaceOptions=$("${chooseInterfaceCmd[@]}" "${interfacesArray[@]}" 2>&1 >/dev/tty)
+ if [[ $? = 0 ]]; then
+ for desiredInterface in ${chooseInterfaceOptions}; do
+ PIHOLE_INTERFACE=${desiredInterface}
+ echo "::: Using interface: $PIHOLE_INTERFACE"
+ done
+ else
+ echo "::: Cancel selected, exiting...."
+ exit 1
+ fi
+}
+
+useIPv6dialog() {
+ # Show the IPv6 address used for blocking
+ IPV6_ADDRESS=$(ip -6 route get 2001:4860:4860::8888 | awk -F " " '{ for(i=1;i<=NF;i++) if ($i == "src") print $(i+1) }')
+ whiptail --msgbox --backtitle "IPv6..." --title "IPv6 Supported" "$IPV6_ADDRESS will be used to block ads." ${r} ${c}
+}
+
+
+use4andor6() {
+ local useIPv4
+ local useIPv6
+ # Let use select IPv4 and/or IPv6
+ cmd=(whiptail --separate-output --checklist "Select Protocols (press space to select)" ${r} ${c} 2)
+ options=(IPv4 "Block ads over IPv4" on
+ IPv6 "Block ads over IPv6" on)
+ choices=$("${cmd[@]}" "${options[@]}" 2>&1 >/dev/tty)
+ if [[ $? = 0 ]];then
+ for choice in ${choices}
+ do
+ case ${choice} in
+ IPv4 ) useIPv4=true;;
+ IPv6 ) useIPv6=true;;
+ esac
+ done
+ if [[ ${useIPv4} ]]; then
+ find_IPv4_information
+ getStaticIPv4Settings
+ setStaticIPv4
+ fi
+ if [[ ${useIPv6} ]]; then
+ useIPv6dialog
+ fi
+ echo "::: IPv4 address: ${IPV4_ADDRESS}"
+ echo "::: IPv6 address: ${IPV6_ADDRESS}"
+ if [ ! ${useIPv4} ] && [ ! ${useIPv6} ]; then
+ echo "::: Cannot continue, neither IPv4 or IPv6 selected"
+ echo "::: Exiting"
+ exit 1
+ fi
+ else
+ echo "::: Cancel selected. Exiting..."
+ exit 1
+ fi
+}
+
+getStaticIPv4Settings() {
+ # Ask if the user wants to use DHCP settings as their static IP
+ if (whiptail --backtitle "Calibrating network interface" --title "Static IP Address" --yesno "Do you want to use your current network settings as a static address?
+ IP address: ${IPV4_ADDRESS}
+ Gateway: ${IPv4gw}" ${r} ${c}); then
+ # If they choose yes, let the user know that the IP address will not be available via DHCP and may cause a conflict.
+ whiptail --msgbox --backtitle "IP information" --title "FYI: IP Conflict" "It is possible your router could still try to assign this IP to a device, which would cause a conflict. But in most cases the router is smart enough to not do that.
+If you are worried, either manually set the address, or modify the DHCP reservation pool so it does not include the IP you want.
+It is also possible to use a DHCP reservation, but if you are going to do that, you might as well set a static address." ${r} ${c}
+ # Nothing else to do since the variables are already set above
+ else
+ # Otherwise, we need to ask the user to input their desired settings.
+ # Start by getting the IPv4 address (pre-filling it with info gathered from DHCP)
+ # Start a loop to let the user enter their information with the chance to go back and edit it if necessary
+ until [[ ${ipSettingsCorrect} = True ]]; do
+ # Ask for the IPv4 address
+ IPV4_ADDRESS=$(whiptail --backtitle "Calibrating network interface" --title "IPv4 address" --inputbox "Enter your desired IPv4 address" ${r} ${c} "${IPV4_ADDRESS}" 3>&1 1>&2 2>&3)
+ if [[ $? = 0 ]]; then
+ echo "::: Your static IPv4 address: ${IPV4_ADDRESS}"
+ # Ask for the gateway
+ IPv4gw=$(whiptail --backtitle "Calibrating network interface" --title "IPv4 gateway (router)" --inputbox "Enter your desired IPv4 default gateway" ${r} ${c} "${IPv4gw}" 3>&1 1>&2 2>&3)
+ if [[ $? = 0 ]]; then
+ echo "::: Your static IPv4 gateway: ${IPv4gw}"
+ # Give the user a chance to review their settings before moving on
+ if (whiptail --backtitle "Calibrating network interface" --title "Static IP Address" --yesno "Are these settings correct?
+ IP address: ${IPV4_ADDRESS}
+ Gateway: ${IPv4gw}" ${r} ${c}); then
+ # After that's done, the loop ends and we move on
+ ipSettingsCorrect=True
+ else
+ # If the settings are wrong, the loop continues
+ ipSettingsCorrect=False
+ fi
+ else
+ # Cancelling gateway settings window
+ ipSettingsCorrect=False
+ echo "::: Cancel selected. Exiting..."
+ exit 1
+ fi
+ else
+ # Cancelling IPv4 settings window
+ ipSettingsCorrect=False
+ echo "::: Cancel selected. Exiting..."
+ exit 1
+ fi
+ done
+ # End the if statement for DHCP vs. static
+ fi
+}
+
+setDHCPCD() {
+ # Append these lines to dhcpcd.conf to enable a static IP
+ echo "## interface ${PIHOLE_INTERFACE}
+ static ip_address=${IPV4_ADDRESS}
+ static routers=${IPv4gw}
+ static domain_name_servers=${IPv4gw}" | tee -a /etc/dhcpcd.conf >/dev/null
+}
+
+setStaticIPv4() {
+ local IFCFG_FILE
+ local IPADDR
+ local CIDR
+ if [[ -f /etc/dhcpcd.conf ]]; then
+ # Debian Family
+ if grep -q "${IPV4_ADDRESS}" /etc/dhcpcd.conf; then
+ echo "::: Static IP already configured"
+ else
+ setDHCPCD
+ ip addr replace dev "${PIHOLE_INTERFACE}" "${IPV4_ADDRESS}"
+ echo ":::"
+ echo "::: Setting IP to ${IPV4_ADDRESS}. You may need to restart after the install is complete."
+ echo ":::"
+ fi
+ elif [[ -f /etc/sysconfig/network-scripts/ifcfg-${PIHOLE_INTERFACE} ]];then
+ # Fedora Family
+ IFCFG_FILE=/etc/sysconfig/network-scripts/ifcfg-${PIHOLE_INTERFACE}
+ if grep -q "${IPV4_ADDRESS}" "${IFCFG_FILE}"; then
+ echo "::: Static IP already configured"
+ else
+ IPADDR=$(echo "${IPV4_ADDRESS}" | cut -f1 -d/)
+ CIDR=$(echo "${IPV4_ADDRESS}" | cut -f2 -d/)
+ # Backup existing interface configuration:
+ cp "${IFCFG_FILE}" "${IFCFG_FILE}".pihole.orig
+ # Build Interface configuration file:
+ {
+ echo "# Configured via Pi-Hole installer"
+ echo "DEVICE=$PIHOLE_INTERFACE"
+ echo "BOOTPROTO=none"
+ echo "ONBOOT=yes"
+ echo "IPADDR=$IPADDR"
+ echo "PREFIX=$CIDR"
+ echo "GATEWAY=$IPv4gw"
+ echo "DNS1=$PIHOLE_DNS_1"
+ echo "DNS2=$PIHOLE_DNS_2"
+ echo "USERCTL=no"
+ }> "${IFCFG_FILE}"
+ ip addr replace dev "${PIHOLE_INTERFACE}" "${IPV4_ADDRESS}"
+ if [ -x "$(command -v nmcli)" ];then
+ # Tell NetworkManager to read our new sysconfig file
+ nmcli con load "${IFCFG_FILE}" > /dev/null
+ fi
+ echo ":::"
+ echo "::: Setting IP to ${IPV4_ADDRESS}. You may need to restart after the install is complete."
+ echo ":::"
+ fi
+ else
+ echo "::: Warning: Unable to locate configuration file to set static IPv4 address!"
+ exit 1
+ fi
+}
+
+valid_ip() {
+ local ip=${1}
+ local stat=1
+
+ if [[ ${ip} =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then
+ OIFS=$IFS
+ IFS='.'
+ ip=(${ip})
+ IFS=${OIFS}
+ [[ ${ip[0]} -le 255 && ${ip[1]} -le 255 \
+ && ${ip[2]} -le 255 && ${ip[3]} -le 255 ]]
+ stat=$?
+ fi
+ return ${stat}
+}
+
+setDNS() {
+ DNSChooseCmd=(whiptail --separate-output --radiolist "Select Upstream DNS Provider. To use your own, select Custom." ${r} ${c} 6)
+ DNSChooseOptions=(Google "" on
+ OpenDNS "" off
+ Level3 "" off
+ Norton "" off
+ Comodo "" off
+ Custom "" off)
+ DNSchoices=$("${DNSChooseCmd[@]}" "${DNSChooseOptions[@]}" 2>&1 >/dev/tty)
+ if [[ $? = 0 ]];then
+ case ${DNSchoices} in
+ Google)
+ echo "::: Using Google DNS servers."
+ PIHOLE_DNS_1="8.8.8.8"
+ PIHOLE_DNS_2="8.8.4.4"
+ ;;
+ OpenDNS)
+ echo "::: Using OpenDNS servers."
+ PIHOLE_DNS_1="208.67.222.222"
+ PIHOLE_DNS_2="208.67.220.220"
+ ;;
+ Level3)
+ echo "::: Using Level3 servers."
+ PIHOLE_DNS_1="4.2.2.1"
+ PIHOLE_DNS_2="4.2.2.2"
+ ;;
+ Norton)
+ echo "::: Using Norton ConnectSafe servers."
+ PIHOLE_DNS_1="199.85.126.10"
+ PIHOLE_DNS_2="199.85.127.10"
+ ;;
+ Comodo)
+ echo "::: Using Comodo Secure servers."
+ PIHOLE_DNS_1="8.26.56.26"
+ PIHOLE_DNS_2="8.20.247.20"
+ ;;
+ Custom)
+ until [[ ${DNSSettingsCorrect} = True ]]; do
+ strInvalid="Invalid"
+ if [ ! ${PIHOLE_DNS_1} ]; then
+ if [ ! ${PIHOLE_DNS_2} ]; then
+ prePopulate=""
+ else
+ prePopulate=", ${PIHOLE_DNS_2}"
+ fi
+ elif [ ${PIHOLE_DNS_1} ] && [ ! ${PIHOLE_DNS_2} ]; then
+ prePopulate="${PIHOLE_DNS_1}"
+ elif [ ${PIHOLE_DNS_1} ] && [ ${PIHOLE_DNS_2} ]; then
+ prePopulate="${PIHOLE_DNS_1}, ${PIHOLE_DNS_2}"
+ fi
+
+ piholeDNS=$(whiptail --backtitle "Specify Upstream DNS Provider(s)" --inputbox "Enter your desired upstream DNS provider(s), seperated by a comma.\n\nFor example '8.8.8.8, 8.8.4.4'" ${r} ${c} "${prePopulate}" 3>&1 1>&2 2>&3)
+
+ if [[ $? = 0 ]]; then
+ PIHOLE_DNS_1=$(echo "${piholeDNS}" | sed 's/[, \t]\+/,/g' | awk -F, '{print$1}')
+ PIHOLE_DNS_2=$(echo "${piholeDNS}" | sed 's/[, \t]\+/,/g' | awk -F, '{print$2}')
+ if ! valid_ip "${PIHOLE_DNS_1}" || [ ! "${PIHOLE_DNS_1}" ]; then
+ PIHOLE_DNS_1=${strInvalid}
+ fi
+ if ! valid_ip "${PIHOLE_DNS_2}" && [ "${PIHOLE_DNS_2}" ]; then
+ PIHOLE_DNS_2=${strInvalid}
+ fi
+ else
+ echo "::: Cancel selected, exiting...."
+ exit 1
+ fi
+ if [[ ${PIHOLE_DNS_1} == "${strInvalid}" ]] || [[ ${PIHOLE_DNS_2} == "${strInvalid}" ]]; then
+ whiptail --msgbox --backtitle "Invalid IP" --title "Invalid IP" "One or both entered IP addresses were invalid. Please try again.\n\n DNS Server 1: $PIHOLE_DNS_1\n DNS Server 2: ${PIHOLE_DNS_2}" ${r} ${c}
+ if [[ ${PIHOLE_DNS_1} == "${strInvalid}" ]]; then
+ PIHOLE_DNS_1=""
+ fi
+ if [[ ${PIHOLE_DNS_2} == "${strInvalid}" ]]; then
+ PIHOLE_DNS_2=""
+ fi
+ DNSSettingsCorrect=False
+ else
+ if (whiptail --backtitle "Specify Upstream DNS Provider(s)" --title "Upstream DNS Provider(s)" --yesno "Are these settings correct?\n DNS Server 1: $PIHOLE_DNS_1\n DNS Server 2: ${PIHOLE_DNS_2}" ${r} ${c}); then
+ DNSSettingsCorrect=True
+ else
+ # If the settings are wrong, the loop continues
+ DNSSettingsCorrect=False
+ fi
+ fi
+ done
+ ;;
+ esac
+ else
+ echo "::: Cancel selected. Exiting..."
+ exit 1
+ fi
+}
+
+setLogging() {
+ local LogToggleCommand
+ local LogChooseOptions
+ local LogChoices
+
+ LogToggleCommand=(whiptail --separate-output --radiolist "Do you want to log queries?\n (Disabling will render graphs on the Admin page useless):" ${r} ${c} 6)
+ LogChooseOptions=("On (Reccomended)" "" on
+ Off "" off)
+ LogChoices=$("${LogToggleCommand[@]}" "${LogChooseOptions[@]}" 2>&1 >/dev/tty) || (echo "::: Cancel selected. Exiting..." && exit 1)
+ case ${LogChoices} in
+ "On (Recommended)")
+ echo "::: Logging On."
+ QUERY_LOGGING=true
+ ;;
+ Off)
+ echo "::: Logging Off."
+ QUERY_LOGGING=false
+ ;;
+ esac
+}
+
+
+version_check_dnsmasq() {
+ # Check if /etc/dnsmasq.conf is from pihole. If so replace with an original and install new in .d directory
+ local dnsmasq_conf="/etc/dnsmasq.conf"
+ local dnsmasq_conf_orig="/etc/dnsmasq.conf.orig"
+ local dnsmasq_pihole_id_string="addn-hosts=/etc/pihole/gravity.list"
+ local dnsmasq_original_config="/etc/.pihole/advanced/dnsmasq.conf.original"
+ local dnsmasq_pihole_01_snippet="/etc/.pihole/advanced/01-pihole.conf"
+ local dnsmasq_pihole_01_location="/etc/dnsmasq.d/01-pihole.conf"
+
+ if [ -f ${dnsmasq_conf} ]; then
+ echo -n "::: Existing dnsmasq.conf found..."
+ if grep -q ${dnsmasq_pihole_id_string} ${dnsmasq_conf}; then
+ echo " it is from a previous pi-hole install."
+ echo -n "::: Backing up dnsmasq.conf to dnsmasq.conf.orig..."
+ mv -f ${dnsmasq_conf} ${dnsmasq_conf_orig}
+ echo " done."
+ echo -n "::: Restoring default dnsmasq.conf..."
+ cp ${dnsmasq_original_config} ${dnsmasq_conf}
+ echo " done."
+ else
+ echo " it is not a pi-hole file, leaving alone!"
+ fi
+ else
+ echo -n "::: No dnsmasq.conf found.. restoring default dnsmasq.conf..."
+ cp ${dnsmasq_original_config} ${dnsmasq_conf}
+ echo " done."
+ fi
+
+ echo -n "::: Copying 01-pihole.conf to /etc/dnsmasq.d/01-pihole.conf..."
+ cp ${dnsmasq_pihole_01_snippet} ${dnsmasq_pihole_01_location}
+ echo " done."
+ sed -i "s/@INT@/$PIHOLE_INTERFACE/" ${dnsmasq_pihole_01_location}
+ if [[ "${PIHOLE_DNS_1}" != "" ]]; then
+ sed -i "s/@DNS1@/$PIHOLE_DNS_1/" ${dnsmasq_pihole_01_location}
+ else
+ sed -i '/^server=@DNS1@/d' ${dnsmasq_pihole_01_location}
+ fi
+ if [[ "${PIHOLE_DNS_2}" != "" ]]; then
+ sed -i "s/@DNS2@/$PIHOLE_DNS_2/" ${dnsmasq_pihole_01_location}
+ else
+ sed -i '/^server=@DNS2@/d' ${dnsmasq_pihole_01_location}
+ fi
+
+ sed -i 's/^#conf-dir=\/etc\/dnsmasq.d$/conf-dir=\/etc\/dnsmasq.d/' ${dnsmasq_conf}
+
+ if [[ "${QUERY_LOGGING}" == false ]] ; then
+ #Disable Logging
+ sed -i 's/^log-queries/#log-queries/' ${dnsmasq_pihole_01_location}
+ else
+ #Enable Logging
+ sed -i 's/^#log-queries/log-queries/' ${dnsmasq_pihole_01_location}
+ fi
+}
+
+remove_legacy_scripts() {
+ #Tidy up /usr/local/bin directory if installing over previous install.
+ oldFiles=( gravity chronometer whitelist blacklist piholeLogFlush updateDashboard uninstall setupLCD piholeDebug)
+ for i in "${oldFiles[@]}"; do
+ if [ -f "/usr/local/bin/$i.sh" ]; then
+ rm /usr/local/bin/"$i".sh
+ fi
+ done
+}
+
+clean_existing() {
+ # Clean an exiting installation to prepare for upgrade/reinstall
+ # ${1} Directory to clean; ${2} Array of files to remove
+ local clean_directory="${1}"
+ local old_files=${2}
+
+ for script in "${old_files[@]}"; do
+ rm -f "${clean_directory}${script}.sh"
+ done
+
+}
+
+installScripts() {
+ # Install the scripts from repository to their various locations
+ readonly install_dir="/opt/pihole/"
+
+ echo ":::"
+ echo -n "::: Installing scripts from ${PI_HOLE_LOCAL_REPO}..."
+
+ # Clear out script files from Pi-hole scripts directory.
+ clean_existing "${install_dir}" "${PI_HOLE_FILES}"
+
+ # Install files from local core repository
+ if is_repo "${PI_HOLE_LOCAL_REPO}"; then
+ cd "${PI_HOLE_LOCAL_REPO}"
+ install -o "${USER}" -Dm755 -t /opt/pihole/ gravity.sh
+ install -o "${USER}" -Dm755 -t /opt/pihole/ ./advanced/Scripts/*.sh
+ install -o "${USER}" -Dm755 -t /opt/pihole/ ./automated\ install/uninstall.sh
+ install -o "${USER}" -Dm755 -t /usr/local/bin/ pihole
+ install -Dm644 ./advanced/bash-completion/pihole /etc/bash_completion.d/pihole
+ echo " done."
+ else
+ echo " *** ERROR: Local repo ${core_repo} not found, exiting."
+ exit 1
+ fi
+}
+
+installConfigs() {
+ # Install the configs from /etc/.pihole to their various locations
+ echo ":::"
+ echo "::: Installing configs..."
+ version_check_dnsmasq
+ if [ ! -d "/etc/lighttpd" ]; then
+ mkdir /etc/lighttpd
+ chown "${USER}":root /etc/lighttpd
+ elif [ -f "/etc/lighttpd/lighttpd.conf" ]; then
+ mv /etc/lighttpd/lighttpd.conf /etc/lighttpd/lighttpd.conf.orig
+ fi
+ cp /etc/.pihole/advanced/${LIGHTTPD_CFG} /etc/lighttpd/lighttpd.conf
+ mkdir -p /var/run/lighttpd
+ chown ${LIGHTTPD_USER}:${LIGHTTPD_GROUP} /var/run/lighttpd
+ mkdir -p /var/cache/lighttpd/compress
+ chown ${LIGHTTPD_USER}:${LIGHTTPD_GROUP} /var/cache/lighttpd/compress
+ mkdir -p /var/cache/lighttpd/uploads
+ chown ${LIGHTTPD_USER}:${LIGHTTPD_GROUP} /var/cache/lighttpd/uploads
+}
+
+stop_service() {
+ # Stop service passed in as argument.
+ # Can softfail, as process may not be installed when this is called
+ echo ":::"
+ echo -n "::: Stopping ${1} service..."
+ if [ -x "$(command -v systemctl)" ]; then
+ systemctl stop "${1}" &> /dev/null || true
+ else
+ service "${1}" stop &> /dev/null || true
+ fi
+ echo " done."
+}
+
+start_service() {
+ # Start/Restart service passed in as argument
+ # This should not fail, it's an error if it does
+ echo ":::"
+ echo -n "::: Starting ${1} service..."
+ if [ -x "$(command -v systemctl)" ]; then
+ systemctl restart "${1}" &> /dev/null
+ else
+ service "${1}" restart &> /dev/null
+ fi
+ echo " done."
+}
+
+enable_service() {
+ # Enable service so that it will start with next reboot
+ echo ":::"
+ echo -n "::: Enabling ${1} service to start on reboot..."
+ if [ -x "$(command -v systemctl)" ]; then
+ systemctl enable "${1}" &> /dev/null
+ else
+ update-rc.d "${1}" defaults &> /dev/null
+ fi
+ echo " done."
+}
+
+update_pacakge_cache() {
+ #Running apt-get update/upgrade with minimal output can cause some issues with
+ #requiring user input (e.g password for phpmyadmin see #218)
+
+ #Check to see if apt-get update has already been run today
+ #it needs to have been run at least once on new installs!
+ timestamp=$(stat -c %Y ${PKG_CACHE})
+ timestampAsDate=$(date -d @"${timestamp}" "+%b %e")
+ today=$(date "+%b %e")
+
+ if [ ! "${today}" == "${timestampAsDate}" ]; then
+ #update package lists
+ echo ":::"
+ echo -n "::: ${PKG_MANAGER} update has not been run today. Running now..."
+ ${UPDATE_PKG_CACHE} &> /dev/null
+ echo " done!"
+ fi
+}
+
+notify_package_updates_available() {
+ # Let user know if they have outdated packages on their system and
+ # advise them to run a package update at soonest possible.
+ echo ":::"
+ echo -n "::: Checking ${PKG_MANAGER} for upgraded packages...."
+ updatesToInstall=$(eval "${PKG_COUNT}")
+ echo " done!"
+ echo ":::"
+ if [[ ${updatesToInstall} -eq "0" ]]; then
+ echo "::: Your system is up to date! Continuing with Pi-hole installation..."
+ else
+ echo "::: There are ${updatesToInstall} updates available for your system!"
+ echo "::: We recommend you run '${PKG_UPDATE}' after installing Pi-Hole! "
+ echo ":::"
+ fi
+}
+
+install_dependent_packages() {
+ # Install packages passed in via argument array
+ # No spinner - conflicts with set -e
+ declare -a argArray1=("${!1}")
+
+ if command -v debconf-apt-progress &> /dev/null; then
+ debconf-apt-progress -- ${PKG_INSTALL} "${argArray1[@]}"
+ else
+ for i in "${argArray1[@]}"; do
+ echo -n "::: Checking for $i..."
+ package_check_install "${i}" &> /dev/null
+ echo " installed!"
+ done
+ fi
+}
+
+CreateLogFile() {
+ # Create logfiles if necessary
+ echo ":::"
+ echo -n "::: Creating log file and changing owner to dnsmasq..."
+ if [ ! -f /var/log/pihole.log ]; then
+ touch /var/log/pihole.log
+ chmod 644 /var/log/pihole.log
+ chown "${DNSMASQ_USER}":root /var/log/pihole.log
+ echo " done!"
+ else
+ echo " already exists!"
+ fi
+}
+
+installPiholeWeb() {
+ # Install the web interface
+ echo ":::"
+ echo "::: Installing pihole custom index page..."
+ if [ -d "/var/www/html/pihole" ]; then
+ if [ -f "/var/www/html/pihole/index.html" ]; then
+ echo "::: Existing index.html detected, not overwriting"
+ else
+ echo -n "::: index.html missing, replacing... "
+ cp /etc/.pihole/advanced/index.html /var/www/html/pihole/
+ echo " done!"
+ fi
+
+ if [ -f "/var/www/html/pihole/index.js" ]; then
+ echo "::: Existing index.js detected, not overwriting"
+ else
+ echo -n "::: index.js missing, replacing... "
+ cp /etc/.pihole/advanced/index.js /var/www/html/pihole/
+ echo " done!"
+ fi
+
+ else
+ mkdir /var/www/html/pihole
+ if [ -f /var/www/html/index.lighttpd.html ]; then
+ mv /var/www/html/index.lighttpd.html /var/www/html/index.lighttpd.orig
+ else
+ printf "\n:::\tNo default index.lighttpd.html file found... not backing up"
+ fi
+ cp /etc/.pihole/advanced/index.* /var/www/html/pihole/.
+ echo " done!"
+ fi
+ # Install Sudoer file
+ echo ":::"
+ echo -n "::: Installing sudoer file..."
+ mkdir -p /etc/sudoers.d/
+ cp /etc/.pihole/advanced/pihole.sudo /etc/sudoers.d/pihole
+ chmod 0440 /etc/sudoers.d/pihole
+ echo " done!"
+}
+
+installCron() {
+ # Install the cron job
+ echo ":::"
+ echo -n "::: Installing latest Cron script..."
+ cp /etc/.pihole/advanced/pihole.cron /etc/cron.d/pihole
+ echo " done!"
+}
+
+runGravity() {
+ # Run gravity.sh to build blacklists
+ echo ":::"
+ echo "::: Preparing to run gravity.sh to refresh hosts..."
+ if ls /etc/pihole/list* 1> /dev/null 2>&1; then
+ echo "::: Cleaning up previous install (preserving whitelist/blacklist)"
+ rm /etc/pihole/list.*
+ fi
+ echo "::: Running gravity.sh"
+ /opt/pihole/gravity.sh
+}
+
+create_pihole_user() {
+ # Check if user pihole exists and create if not
+ echo "::: Checking if user 'pihole' exists..."
+ id -u pihole &> /dev/null && echo "::: User 'pihole' already exists" || (echo "::: User 'pihole' doesn't exist. Creating..." && useradd -r -s /usr/sbin/nologin pihole)
+}
+
+configureFirewall() {
+ # Allow HTTP and DNS traffic
+ if [ -x "$(command -v firewall-cmd)" ]; then
+ firewall-cmd --state &> /dev/null && ( echo "::: Configuring firewalld for httpd and dnsmasq.." && firewall-cmd --permanent --add-port=80/tcp && firewall-cmd --permanent --add-port=53/tcp \
+ && firewall-cmd --permanent --add-port=53/udp && firewall-cmd --reload) || echo "::: FirewallD not enabled"
+ elif [ -x "$(command -v iptables)" ]; then
+ echo "::: Configuring iptables for httpd and dnsmasq.."
+ iptables -A INPUT -p tcp -m tcp --dport 80 -j ACCEPT
+ iptables -A INPUT -p tcp -m tcp --dport 53 -j ACCEPT
+ iptables -A INPUT -p udp -m udp --dport 53 -j ACCEPT
+ else
+ echo "::: No firewall detected.. skipping firewall configuration."
+ fi
+}
+
+finalExports() {
+ # Update variables in setupVars.conf file
+ if [ -e "${setupVars}" ]; then
+ sed -i.update.bak '/PIHOLE_INTERFACE/d;/IPV4_ADDRESS/d;/IPV6_ADDRESS/d;/PIHOLE_DNS_1/d;/PIHOLE_DNS_2/d;/QUERY_LOGGING/d;' "${setupVars}"
+ fi
+ {
+ echo "PIHOLE_INTERFACE=${PIHOLE_INTERFACE}"
+ echo "IPV4_ADDRESS=${IPV4_ADDRESS}"
+ echo "IPV6_ADDRESS=${IPV6_ADDRESS}"
+ echo "PIHOLE_DNS_1=${PIHOLE_DNS_1}"
+ echo "PIHOLE_DNS_2=${PIHOLE_DNS_2}"
+ echo "QUERY_LOGGING=${QUERY_LOGGING}"
+ }>> "${setupVars}"
+}
+
+installPihole() {
+ # Install base files and web interface
+ create_pihole_user
+ if [ ! -d "/var/www/html" ]; then
+ mkdir -p /var/www/html
+ fi
+ chown ${LIGHTTPD_USER}:${LIGHTTPD_GROUP} /var/www/html
+ chmod 775 /var/www/html
+ usermod -a -G ${LIGHTTPD_GROUP} pihole
+ if [ -x "$(command -v lighty-enable-mod)" ]; then
+ lighty-enable-mod fastcgi fastcgi-php > /dev/null || true
+ else
+ printf "\n:::\tWarning: 'lighty-enable-mod' utility not found. Please ensure fastcgi is enabled if you experience issues.\n"
+ fi
+ installScripts
+ installConfigs
+ CreateLogFile
+ configureSelinux
+ installPiholeWeb
+ installCron
+ configureFirewall
+ finalExports
+ runGravity
+}
+
+accountForRefactor() {
+ # At some point in the future this list can be pruned, for now we'll need it to ensure updates don't break.
+
+ # Refactoring of install script has changed the name of a couple of variables. Sort them out here.
+
+ sed -i 's/piholeInterface/PIHOLE_INTERFACE/g' ${setupVars}
+ sed -i 's/IPv4_address/IPV4_ADDRESS/g' ${setupVars}
+ sed -i 's/IPv4addr/IPV4_ADDRESS/g' ${setupVars}
+ sed -i 's/IPv6_address/IPV6_ADDRESS/g' ${setupVars}
+ sed -i 's/piholeIPv6/IPV6_ADDRESS/g' ${setupVars}
+ sed -i 's/piholeDNS1/PIHOLE_DNS_1/g' ${setupVars}
+ sed -i 's/piholeDNS2/PIHOLE_DNS_2/g' ${setupVars}
+
+}
+
+updatePihole() {
+ accountForRefactor
+ # Source ${setupVars} for use in the rest of the functions.
+ . ${setupVars}
+ # Install base files and web interface
+ installScripts
+ installConfigs
+ CreateLogFile
+ configureSelinux
+ installPiholeWeb
+ installCron
+ configureFirewall
+ finalExports #re-export setupVars.conf to account for any new vars added in new versions
+ runGravity
+}
+
+configureSelinux() {
+ if [ -x "$(command -v getenforce)" ]; then
+ printf "\n::: SELinux Detected\n"
+ printf ":::\tChecking for SELinux policy development packages..."
+ package_check_install "selinux-policy-devel" > /dev/null
+ echo " installed!"
+ printf ":::\tEnabling httpd server side includes (SSI).. "
+ setsebool -P httpd_ssi_exec on &> /dev/null && echo "Success" || echo "SELinux not enabled"
+ printf "\n:::\tCompiling Pi-Hole SELinux policy..\n"
+ if ! [ -x "$(command -v systemctl)" ]; then
+ sed -i.bak '/systemd/d' /etc/.pihole/advanced/selinux/pihole.te
+ fi
+ checkmodule -M -m -o /etc/pihole/pihole.mod /etc/.pihole/advanced/selinux/pihole.te
+ semodule_package -o /etc/pihole/pihole.pp -m /etc/pihole/pihole.mod
+ semodule -i /etc/pihole/pihole.pp
+ rm -f /etc/pihole/pihole.mod
+ semodule -l | grep pihole &> /dev/null && echo "::: Installed Pi-Hole SELinux policy" || echo "::: Warning: Pi-Hole SELinux policy did not install."
+ fi
+}
+
+displayFinalMessage() {
+ if (( ${#1} > 0 )) ; then
+ # Final completion message to user
+ whiptail --msgbox --backtitle "Make it so." --title "Installation Complete!" "Configure your devices to use the Pi-hole as their DNS server using:
+
+IPv4: ${IPV4_ADDRESS%/*}
+IPv6: ${IPV6_ADDRESS}
+
+If you set a new IP address, you should restart the Pi.
+
+The install log is in /etc/pihole.
+View the web interface at http://pi.hole/admin or http://${IPV4_ADDRESS%/*}/admin
+The currently set password is ${1}" ${r} ${c}
+ else
+ whiptail --msgbox --backtitle "Make it so." --title "Installation Complete!" "Configure your devices to use the Pi-hole as their DNS server using:
+
+IPv4: ${IPV4_ADDRESS%/*}
+IPv6: ${IPV6_ADDRESS}
+
+If you set a new IP address, you should restart the Pi.
+
+The install log is in /etc/pihole.
+View the web interface at http://pi.hole/admin or http://${IPV4_ADDRESS%/*}/admin" ${r} ${c}
+ fi
+}
+
+update_dialogs() {
+ # reconfigure
+ if [ "${reconfigure}" = true ]; then
+ opt1a="Repair"
+ opt1b="This will retain existing settings"
+ strAdd="You will remain on the same version"
+ else
+ opt1a="Update"
+ opt1b="This will retain existing settings."
+ strAdd="You will be updated to the latest version."
+ fi
+ opt2a="Reconfigure"
+ opt2b="This will allow you to enter new settings"
+
+ UpdateCmd=$(whiptail --title "Existing Install Detected!" --menu "\n\nWe have detected an existing install.\n\nPlease choose from the following options: \n($strAdd)" ${r} ${c} 2 \
+ "${opt1a}" "${opt1b}" \
+ "${opt2a}" "${opt2b}" 3>&2 2>&1 1>&3)
+
+ if [[ $? = 0 ]];then
+ case ${UpdateCmd} in
+ ${opt1a})
+ echo "::: ${opt1a} option selected."
+ useUpdateVars=true
+ ;;
+ ${opt2a})
+ echo "::: ${opt2a} option selected"
+ useUpdateVars=false
+ ;;
+ esac
+ else
+ echo "::: Cancel selected. Exiting..."
+ exit 1
+ fi
+
+}
+
+main() {
+# Check arguments for the undocumented flags
+ for var in "$@"; do
+ case "$var" in
+ "--reconfigure" ) reconfigure=true;;
+ "--i_do_not_follow_recommendations" ) skipSpaceCheck=false;;
+ "--unattended" ) runUnattended=true;;
+ esac
+ done
+
+ if [[ -f ${setupVars} ]]; then
+ if [[ "${runUnattended}" == true ]]; then
+ echo "::: --unattended passed to install script, no whiptail dialogs will be displayed"
+ useUpdateVars=true
+ else
+ update_dialogs
+ fi
+ fi
+
+ # Start the installer
+ # Verify there is enough disk space for the install
+ if [[ "${skipSpaceCheck}" == true ]]; then
+ echo "::: --i_do_not_follow_recommendations passed to script, skipping free disk space verification!"
+ else
+ verifyFreeDiskSpace
+ fi
+
+ # Update package cache
+ update_pacakge_cache
+
+ # Notify user of package availability
+ notify_package_updates_available
+
+ # Install packages used by this installation script
+ install_dependent_packages INSTALLER_DEPS[@]
+
+ if [[ "${reconfigure}" == true ]]; then
+ echo "::: --reconfigure passed to install script. Not downloading/updating local repos"
+ else
+ # Get Git files for Core and Admin
+ getGitFiles ${PI_HOLE_LOCAL_REPO} ${piholeGitUrl}
+ getGitFiles ${webInterfaceDir} ${webInterfaceGitUrl}
+ fi
+
+ if [[ ${useUpdateVars} == false ]]; then
+ # Display welcome dialogs
+ welcomeDialogs
+ # Create directory for Pi-hole storage
+ mkdir -p /etc/pihole/
+ # Remove legacy scripts from previous storage location
+ remove_legacy_scripts
+ # Stop resolver and webserver while installing proceses
+ stop_service dnsmasq
+ stop_service lighttpd
+ # Determine available interfaces
+ get_available_interfaces
+ # Find interfaces and let the user choose one
+ chooseInterface
+ # Let the user decide if they want to block ads over IPv4 and/or IPv6
+ use4andor6
+ # Decide what upstream DNS Servers to use
+ setDNS
+ # Let the user decide if they want query logging enabled...
+ setLogging
+
+ # Install packages used by the Pi-hole
+ install_dependent_packages PIHOLE_DEPS[@]
+
+ # Install and log everything to a file
+ installPihole | tee ${tmpLog}
+ else
+ # update packages used by the Pi-hole
+ install_dependent_packages PIHOLE_DEPS[@]
+
+ updatePihole | tee ${tmpLog}
+ fi
+
+ # Move the log file into /etc/pihole for storage
+ mv ${tmpLog} ${instalLogLoc}
+
+ # Add password to web UI if there is none
+ pw=""
+ if [[ $(grep 'WEBPASSWORD' -c /etc/pihole/setupVars.conf) == 0 ]] ; then
+ pw=$(tr -dc _A-Z-a-z-0-9 < /dev/urandom | head -c 8)
+ pihole -a -p ${pw}
+ fi
+
+ if [[ "${useUpdateVars}" == false ]]; then
+ displayFinalMessage ${pw}
+ fi
+
+ echo "::: Restarting services..."
+ # Start services
+ start_service dnsmasq
+ enable_service dnsmasq
+ start_service lighttpd
+ enable_service lighttpd
+ echo "::: done."
+
+ echo ":::"
+ if [[ "${useUpdateVars}" == false ]]; then
+ echo "::: Installation Complete! Configure your devices to use the Pi-hole as their DNS server using:"
+ echo "::: ${IPV4_ADDRESS%/*}"
+ echo "::: ${IPV6_ADDRESS}"
+ echo ":::"
+ echo "::: If you set a new IP address, you should restart the Pi."
+ echo "::: View the web interface at http://pi.hole/admin or http://${IPV4_ADDRESS%/*}/admin"
+ else
+ echo "::: Update complete!"
+ fi
+
+ if (( ${#pw} > 0 )) ; then
+ echo ":::"
+ echo "::: Note: As security measure a password has been installed for your web interface"
+ echo "::: The currently set password is"
+ echo "::: ${pw}"
+ echo ":::"
+ echo "::: You can always change it using"
+ echo "::: pihole -a -p new_password"
+ fi
+
+ echo ":::"
+ echo "::: The install log is located at: /etc/pihole/install.log"
+}
+
+if [[ "${PH_TEST}" != true ]] ; then
+ main "$@"
+fi
From c72ffae4a2c7bc234d08b9168db482727419de8d Mon Sep 17 00:00:00 2001
From: Dan Schaper
Date: Tue, 20 Dec 2016 17:02:51 -0800
Subject: [PATCH 223/228] Don't install extra packages (openresolv was
installed over resolvconf). No longer need --fix-missing.
Signed-off-by: Dan Schaper
---
automated install/basic-install.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/automated install/basic-install.sh b/automated install/basic-install.sh
index 0c66094f..55c4716c 100755
--- a/automated install/basic-install.sh
+++ b/automated install/basic-install.sh
@@ -81,7 +81,7 @@ if [[ $(command -v apt-get) ]]; then
PKG_CACHE="/var/lib/apt/lists/"
UPDATE_PKG_CACHE="${PKG_MANAGER} update"
PKG_UPDATE="${PKG_MANAGER} upgrade"
- PKG_INSTALL="${PKG_MANAGER} --yes --fix-missing 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
PKG_COUNT="${PKG_MANAGER} -s -o Debug::NoLocking=true upgrade | grep -c ^Inst || true"
# #########################################
From 156a51c945f3c2e537347be467d5a8aabb26c49d Mon Sep 17 00:00:00 2001
From: Dan Schaper
Date: Tue, 20 Dec 2016 17:04:46 -0800
Subject: [PATCH 224/228] Remove extra display only variable.
Signed-off-by: Dan Schaper
---
automated install/basic-install.sh | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/automated install/basic-install.sh b/automated install/basic-install.sh
index 55c4716c..e10fa196 100755
--- a/automated install/basic-install.sh
+++ b/automated install/basic-install.sh
@@ -80,7 +80,6 @@ if [[ $(command -v apt-get) ]]; then
PKG_MANAGER="apt-get"
PKG_CACHE="/var/lib/apt/lists/"
UPDATE_PKG_CACHE="${PKG_MANAGER} update"
- PKG_UPDATE="${PKG_MANAGER} upgrade"
PKG_INSTALL="${PKG_MANAGER} --yes --no-install-recommends install"
# grep -c will return 1 retVal on 0 matches, block this throwing the set -e with an OR TRUE
PKG_COUNT="${PKG_MANAGER} -s -o Debug::NoLocking=true upgrade | grep -c ^Inst || true"
@@ -110,7 +109,6 @@ elif [ $(command -v rpm) ]; then
fi
PKG_CACHE="/var/cache/${PKG_MANAGER}"
UPDATE_PKG_CACHE="${PKG_MANAGER} check-update"
- PKG_UPDATE="${PKG_MANAGER} update -y"
PKG_INSTALL="${PKG_MANAGER} install -y"
PKG_COUNT="${PKG_MANAGER} check-update | egrep '(.i686|.x86|.noarch|.arm|.src)' | wc -l"
INSTALLER_DEPS=(git iproute net-tools newt procps-ng)
@@ -744,7 +742,7 @@ notify_package_updates_available() {
echo "::: Your system is up to date! Continuing with Pi-hole installation..."
else
echo "::: There are ${updatesToInstall} updates available for your system!"
- echo "::: We recommend you run '${PKG_UPDATE}' after installing Pi-Hole! "
+ echo "::: We recommend you update your OS after installing Pi-Hole! "
echo ":::"
fi
}
From ff2783f9fc884e24d2e8d88918f4aeb01ffeb985 Mon Sep 17 00:00:00 2001
From: Dan Schaper
Date: Tue, 20 Dec 2016 17:22:57 -0800
Subject: [PATCH 225/228] Tabs to spaces and formatting.
Signed-off-by: Dan Schaper
---
automated install/basic-install.sh | 1502 ++++++++++++++--------------
1 file changed, 749 insertions(+), 753 deletions(-)
diff --git a/automated install/basic-install.sh b/automated install/basic-install.sh
index a04cac3f..3cd00ac1 100755
--- a/automated install/basic-install.sh
+++ b/automated install/basic-install.sh
@@ -158,393 +158,391 @@ is_repo() {
make_repo() {
local directory="${1}"
- local remoteRepo="${2}"
- # Remove the non-repod interface and clone the interface
- echo -n "::: Cloning $remoteRepo into $directory..."
- rm -rf "${directory}"
- git clone -q --depth 1 "${remoteRepo}" "${directory}" > /dev/null & spinner $!
- echo " done!"
+ local remoteRepo="${2}"
+ # Remove the non-repod interface and clone the interface
+ echo -n "::: Cloning $remoteRepo into $directory..."
+ rm -rf "${directory}"
+ git clone -q --depth 1 "${remoteRepo}" "${directory}" > /dev/null & spinner $!
+ echo " done!"
}
update_repo() {
- local directory="${1}"
- # Pull the latest commits
- echo -n "::: Updating repo in $1..."
- cd "${directory}" || exit 1
- git stash -q > /dev/null & spinner $!
- git pull -q > /dev/null & spinner $!
- echo " done!"
+ local directory="${1}"
+ # Pull the latest commits
+ echo -n "::: Updating repo in $1..."
+ cd "${directory}" || exit 1
+ git stash -q > /dev/null & spinner $!
+ git pull -q > /dev/null & spinner $!
+ echo " done!"
}
getGitFiles() {
- # Setup git repos for directory and repository passed
- # as arguments 1 and 2
- local directory="${1}"
- local remoteRepo="${2}"
- echo ":::"
- echo "::: Checking for existing repository..."
- if is_repo "${directory}"; then
- update_repo "${directory}"
- else
- make_repo "${directory}" "${remoteRepo}"
- fi
+ # Setup git repos for directory and repository passed
+ # as arguments 1 and 2
+ local directory="${1}"
+ local remoteRepo="${2}"
+ echo ":::"
+ echo "::: Checking for existing repository..."
+ if is_repo "${directory}"; then
+ update_repo "${directory}"
+ else
+ make_repo "${directory}" "${remoteRepo}"
+ fi
}
find_IPv4_information() {
- # Find IP used to route to outside world
- IPv4dev=$(ip route get 8.8.8.8 | awk '{for(i=1;i<=NF;i++)if($i~/dev/)print $(i+1)}')
- IPV4_ADDRESS=$(ip -o -f inet addr show dev "$IPv4dev" | awk '{print $4}' | awk 'END {print}')
- IPv4gw=$(ip route get 8.8.8.8 | awk '{print $3}')
+ # Find IP used to route to outside world
+ IPv4dev=$(ip route get 8.8.8.8 | awk '{for(i=1;i<=NF;i++)if($i~/dev/)print $(i+1)}')
+ IPV4_ADDRESS=$(ip -o -f inet addr show dev "$IPv4dev" | awk '{print $4}' | awk 'END {print}')
+ IPv4gw=$(ip route get 8.8.8.8 | awk '{print $3}')
}
get_available_interfaces() {
- # Get available interfaces. Consider only getting UP interfaces in the future, and leaving DOWN interfaces out of list.
- availableInterfaces=$(ip -o link | awk '{print $2}' | grep -v "lo" | cut -d':' -f1 | cut -d'@' -f1)
+ # Get available interfaces. Consider only getting UP interfaces in the future, and leaving DOWN interfaces out of list.
+ availableInterfaces=$(ip -o link | awk '{print $2}' | grep -v "lo" | cut -d':' -f1 | cut -d'@' -f1)
}
welcomeDialogs() {
- # Display the welcome dialog
- whiptail --msgbox --backtitle "Welcome" --title "Pi-hole automated installer" "\n\nThis installer will transform your device into a network-wide ad blocker!" ${r} ${c}
+ # Display the welcome dialog
+ whiptail --msgbox --backtitle "Welcome" --title "Pi-hole automated installer" "\n\nThis installer will transform your device into a network-wide ad blocker!" ${r} ${c}
- # Support for a part-time dev
- whiptail --msgbox --backtitle "Plea" --title "Free and open source" "\n\nThe Pi-hole is free, but powered by your donations: http://pi-hole.net/donate" ${r} ${c}
+ # Support for a part-time dev
+ whiptail --msgbox --backtitle "Plea" --title "Free and open source" "\n\nThe Pi-hole is free, but powered by your donations: http://pi-hole.net/donate" ${r} ${c}
- # Explain the need for a static address
- whiptail --msgbox --backtitle "Initiating network interface" --title "Static IP Needed" "\n\nThe Pi-hole is a SERVER so it needs a STATIC IP ADDRESS to function properly.
+ # Explain the need for a static address
+ whiptail --msgbox --backtitle "Initiating network interface" --title "Static IP Needed" "\n\nThe Pi-hole is a SERVER so it needs a STATIC IP ADDRESS to function properly.
In the next section, you can choose to use your current network settings (DHCP) or to manually edit them." ${r} ${c}
}
verifyFreeDiskSpace() {
- # 50MB is the minimum space needed (45MB install (includes web admin bootstrap/jquery libraries etc) + 5MB one day of logs.)
- # - Fourdee: Local ensures the variable is only created, and accessible within this function/void. Generally considered a "good" coding practice for non-global variables.
- echo "::: Verifying free disk space..."
- local required_free_kilobytes=51200
- local existing_free_kilobytes=$(df -Pk | grep -m1 '\/$' | awk '{print $4}')
+ # 50MB is the minimum space needed (45MB install (includes web admin bootstrap/jquery libraries etc) + 5MB one day of logs.)
+ # - Fourdee: Local ensures the variable is only created, and accessible within this function/void. Generally considered a "good" coding practice for non-global variables.
+ echo "::: Verifying free disk space..."
+ local required_free_kilobytes=51200
+ local existing_free_kilobytes=$(df -Pk | grep -m1 '\/$' | awk '{print $4}')
- # - Unknown free disk space , not a integer
- if ! [[ "${existing_free_kilobytes}" =~ ^([0-9])+$ ]]; then
- echo "::: Unknown free disk space!"
- echo "::: We were unable to determine available free disk space on this system."
- echo "::: You may override this check and force the installation, however, it is not recommended"
- echo "::: To do so, pass the argument '--i_do_not_follow_recommendations' to the install script"
- echo "::: eg. curl -L https://install.pi-hole.net | bash /dev/stdin --i_do_not_follow_recommendations"
- exit 1
- # - Insufficient free disk space
- elif [[ ${existing_free_kilobytes} -lt ${required_free_kilobytes} ]]; then
- echo "::: Insufficient Disk Space!"
- echo "::: Your system appears to be low on disk space. pi-hole recommends a minimum of $required_free_kilobytes KiloBytes."
- echo "::: You only have ${existing_free_kilobytes} KiloBytes free."
- echo "::: If this is a new install you may need to expand your disk."
- echo "::: Try running 'sudo raspi-config', and choose the 'expand file system option'"
- echo "::: After rebooting, run this installation again. (curl -L https://install.pi-hole.net | bash)"
-
- echo "Insufficient free space, exiting..."
- exit 1
-
- fi
+ # - Unknown free disk space , not a integer
+ if ! [[ "${existing_free_kilobytes}" =~ ^([0-9])+$ ]]; then
+ echo "::: Unknown free disk space!"
+ echo "::: We were unable to determine available free disk space on this system."
+ echo "::: You may override this check and force the installation, however, it is not recommended"
+ echo "::: To do so, pass the argument '--i_do_not_follow_recommendations' to the install script"
+ echo "::: eg. curl -L https://install.pi-hole.net | bash /dev/stdin --i_do_not_follow_recommendations"
+ exit 1
+ # - Insufficient free disk space
+ elif [[ ${existing_free_kilobytes} -lt ${required_free_kilobytes} ]]; then
+ echo "::: Insufficient Disk Space!"
+ echo "::: Your system appears to be low on disk space. pi-hole recommends a minimum of $required_free_kilobytes KiloBytes."
+ echo "::: You only have ${existing_free_kilobytes} KiloBytes free."
+ echo "::: If this is a new install you may need to expand your disk."
+ echo "::: Try running 'sudo raspi-config', and choose the 'expand file system option'"
+ echo "::: After rebooting, run this installation again. (curl -L https://install.pi-hole.net | bash)"
+ echo "Insufficient free space, exiting..."
+ exit 1
+ fi
}
chooseInterface() {
- # Turn the available interfaces into an array so it can be used with a whiptail dialog
- local interfacesArray=()
- # Number of available interfaces
- local interfaceCount
- # Whiptail variable storage
- local chooseInterfaceCmd
- # Temporary Whiptail options storage
- local chooseInterfaceOptions
- # Loop sentinel variable
- local firstLoop=1
+ # Turn the available interfaces into an array so it can be used with a whiptail dialog
+ local interfacesArray=()
+ # Number of available interfaces
+ local interfaceCount
+ # Whiptail variable storage
+ local chooseInterfaceCmd
+ # Temporary Whiptail options storage
+ local chooseInterfaceOptions
+ # Loop sentinel variable
+ local firstLoop=1
- while read -r line; do
- mode="OFF"
- if [[ ${firstLoop} -eq 1 ]]; then
- firstLoop=0
- mode="ON"
- fi
- interfacesArray+=("${line}" "available" "${mode}")
- done <<< "${availableInterfaces}"
+ while read -r line; do
+ mode="OFF"
+ if [[ ${firstLoop} -eq 1 ]]; then
+ firstLoop=0
+ mode="ON"
+ fi
+ interfacesArray+=("${line}" "available" "${mode}")
+ done <<< "${availableInterfaces}"
- # Find out how many interfaces are available to choose from
- interfaceCount=$(echo "${availableInterfaces}" | wc -l)
- chooseInterfaceCmd=(whiptail --separate-output --radiolist "Choose An Interface (press space to select)" ${r} ${c} ${interfaceCount})
- chooseInterfaceOptions=$("${chooseInterfaceCmd[@]}" "${interfacesArray[@]}" 2>&1 >/dev/tty)
- if [[ $? = 0 ]]; then
- for desiredInterface in ${chooseInterfaceOptions}; do
- PIHOLE_INTERFACE=${desiredInterface}
- echo "::: Using interface: $PIHOLE_INTERFACE"
- done
- else
- echo "::: Cancel selected, exiting...."
- exit 1
- fi
+ # Find out how many interfaces are available to choose from
+ interfaceCount=$(echo "${availableInterfaces}" | wc -l)
+ chooseInterfaceCmd=(whiptail --separate-output --radiolist "Choose An Interface (press space to select)" ${r} ${c} ${interfaceCount})
+ chooseInterfaceOptions=$("${chooseInterfaceCmd[@]}" "${interfacesArray[@]}" 2>&1 >/dev/tty)
+ if [[ $? = 0 ]]; then
+ for desiredInterface in ${chooseInterfaceOptions}; do
+ PIHOLE_INTERFACE=${desiredInterface}
+ echo "::: Using interface: $PIHOLE_INTERFACE"
+ done
+ else
+ echo "::: Cancel selected, exiting...."
+ exit 1
+ fi
}
useIPv6dialog() {
- # Show the IPv6 address used for blocking
- IPV6_ADDRESS=$(ip -6 route get 2001:4860:4860::8888 | awk -F " " '{ for(i=1;i<=NF;i++) if ($i == "src") print $(i+1) }')
- whiptail --msgbox --backtitle "IPv6..." --title "IPv6 Supported" "$IPV6_ADDRESS will be used to block ads." ${r} ${c}
+ # Show the IPv6 address used for blocking
+ IPV6_ADDRESS=$(ip -6 route get 2001:4860:4860::8888 | awk -F " " '{ for(i=1;i<=NF;i++) if ($i == "src") print $(i+1) }')
+ whiptail --msgbox --backtitle "IPv6..." --title "IPv6 Supported" "$IPV6_ADDRESS will be used to block ads." ${r} ${c}
}
use4andor6() {
- local useIPv4
- local useIPv6
- # Let use select IPv4 and/or IPv6
- cmd=(whiptail --separate-output --checklist "Select Protocols (press space to select)" ${r} ${c} 2)
- options=(IPv4 "Block ads over IPv4" on
- IPv6 "Block ads over IPv6" on)
- choices=$("${cmd[@]}" "${options[@]}" 2>&1 >/dev/tty)
- if [[ $? = 0 ]];then
- for choice in ${choices}
- do
- case ${choice} in
- IPv4 ) useIPv4=true;;
- IPv6 ) useIPv6=true;;
- esac
- done
- if [[ ${useIPv4} ]]; then
- find_IPv4_information
- getStaticIPv4Settings
- setStaticIPv4
- fi
- if [[ ${useIPv6} ]]; then
- useIPv6dialog
- fi
- echo "::: IPv4 address: ${IPV4_ADDRESS}"
- echo "::: IPv6 address: ${IPV6_ADDRESS}"
- if [ ! ${useIPv4} ] && [ ! ${useIPv6} ]; then
- echo "::: Cannot continue, neither IPv4 or IPv6 selected"
- echo "::: Exiting"
- exit 1
- fi
- else
- echo "::: Cancel selected. Exiting..."
- exit 1
- fi
+ local useIPv4
+ local useIPv6
+ # Let use select IPv4 and/or IPv6
+ cmd=(whiptail --separate-output --checklist "Select Protocols (press space to select)" ${r} ${c} 2)
+ options=(IPv4 "Block ads over IPv4" on
+ IPv6 "Block ads over IPv6" on)
+ choices=$("${cmd[@]}" "${options[@]}" 2>&1 >/dev/tty)
+ if [[ $? = 0 ]];then
+ for choice in ${choices}
+ do
+ case ${choice} in
+ IPv4 ) useIPv4=true;;
+ IPv6 ) useIPv6=true;;
+ esac
+ done
+ if [[ ${useIPv4} ]]; then
+ find_IPv4_information
+ getStaticIPv4Settings
+ setStaticIPv4
+ fi
+ if [[ ${useIPv6} ]]; then
+ useIPv6dialog
+ fi
+ echo "::: IPv4 address: ${IPV4_ADDRESS}"
+ echo "::: IPv6 address: ${IPV6_ADDRESS}"
+ if [ ! ${useIPv4} ] && [ ! ${useIPv6} ]; then
+ echo "::: Cannot continue, neither IPv4 or IPv6 selected"
+ echo "::: Exiting"
+ exit 1
+ fi
+ else
+ echo "::: Cancel selected. Exiting..."
+ exit 1
+ fi
}
getStaticIPv4Settings() {
- # Ask if the user wants to use DHCP settings as their static IP
- if (whiptail --backtitle "Calibrating network interface" --title "Static IP Address" --yesno "Do you want to use your current network settings as a static address?
- IP address: ${IPV4_ADDRESS}
- Gateway: ${IPv4gw}" ${r} ${c}); then
- # If they choose yes, let the user know that the IP address will not be available via DHCP and may cause a conflict.
- whiptail --msgbox --backtitle "IP information" --title "FYI: IP Conflict" "It is possible your router could still try to assign this IP to a device, which would cause a conflict. But in most cases the router is smart enough to not do that.
+ # Ask if the user wants to use DHCP settings as their static IP
+ if (whiptail --backtitle "Calibrating network interface" --title "Static IP Address" --yesno "Do you want to use your current network settings as a static address?
+ IP address: ${IPV4_ADDRESS}
+ Gateway: ${IPv4gw}" ${r} ${c}); then
+ # If they choose yes, let the user know that the IP address will not be available via DHCP and may cause a conflict.
+ whiptail --msgbox --backtitle "IP information" --title "FYI: IP Conflict" "It is possible your router could still try to assign this IP to a device, which would cause a conflict. But in most cases the router is smart enough to not do that.
If you are worried, either manually set the address, or modify the DHCP reservation pool so it does not include the IP you want.
It is also possible to use a DHCP reservation, but if you are going to do that, you might as well set a static address." ${r} ${c}
- # Nothing else to do since the variables are already set above
- else
- # Otherwise, we need to ask the user to input their desired settings.
- # Start by getting the IPv4 address (pre-filling it with info gathered from DHCP)
- # Start a loop to let the user enter their information with the chance to go back and edit it if necessary
- until [[ ${ipSettingsCorrect} = True ]]; do
- # Ask for the IPv4 address
- IPV4_ADDRESS=$(whiptail --backtitle "Calibrating network interface" --title "IPv4 address" --inputbox "Enter your desired IPv4 address" ${r} ${c} "${IPV4_ADDRESS}" 3>&1 1>&2 2>&3)
- if [[ $? = 0 ]]; then
- echo "::: Your static IPv4 address: ${IPV4_ADDRESS}"
- # Ask for the gateway
- IPv4gw=$(whiptail --backtitle "Calibrating network interface" --title "IPv4 gateway (router)" --inputbox "Enter your desired IPv4 default gateway" ${r} ${c} "${IPv4gw}" 3>&1 1>&2 2>&3)
- if [[ $? = 0 ]]; then
- echo "::: Your static IPv4 gateway: ${IPv4gw}"
- # Give the user a chance to review their settings before moving on
- if (whiptail --backtitle "Calibrating network interface" --title "Static IP Address" --yesno "Are these settings correct?
- IP address: ${IPV4_ADDRESS}
- Gateway: ${IPv4gw}" ${r} ${c}); then
- # After that's done, the loop ends and we move on
- ipSettingsCorrect=True
- else
- # If the settings are wrong, the loop continues
- ipSettingsCorrect=False
- fi
- else
- # Cancelling gateway settings window
- ipSettingsCorrect=False
- echo "::: Cancel selected. Exiting..."
- exit 1
- fi
- else
- # Cancelling IPv4 settings window
- ipSettingsCorrect=False
- echo "::: Cancel selected. Exiting..."
- exit 1
- fi
- done
- # End the if statement for DHCP vs. static
- fi
+ # Nothing else to do since the variables are already set above
+ else
+ # Otherwise, we need to ask the user to input their desired settings.
+ # Start by getting the IPv4 address (pre-filling it with info gathered from DHCP)
+ # Start a loop to let the user enter their information with the chance to go back and edit it if necessary
+ until [[ ${ipSettingsCorrect} = True ]]; do
+ # Ask for the IPv4 address
+ IPV4_ADDRESS=$(whiptail --backtitle "Calibrating network interface" --title "IPv4 address" --inputbox "Enter your desired IPv4 address" ${r} ${c} "${IPV4_ADDRESS}" 3>&1 1>&2 2>&3)
+ if [[ $? = 0 ]]; then
+ echo "::: Your static IPv4 address: ${IPV4_ADDRESS}"
+ # Ask for the gateway
+ IPv4gw=$(whiptail --backtitle "Calibrating network interface" --title "IPv4 gateway (router)" --inputbox "Enter your desired IPv4 default gateway" ${r} ${c} "${IPv4gw}" 3>&1 1>&2 2>&3)
+ if [[ $? = 0 ]]; then
+ echo "::: Your static IPv4 gateway: ${IPv4gw}"
+ # Give the user a chance to review their settings before moving on
+ if (whiptail --backtitle "Calibrating network interface" --title "Static IP Address" --yesno "Are these settings correct?
+ IP address: ${IPV4_ADDRESS}
+ Gateway: ${IPv4gw}" ${r} ${c}); then
+ # After that's done, the loop ends and we move on
+ ipSettingsCorrect=True
+ else
+ # If the settings are wrong, the loop continues
+ ipSettingsCorrect=False
+ fi
+ else
+ # Cancelling gateway settings window
+ ipSettingsCorrect=False
+ echo "::: Cancel selected. Exiting..."
+ exit 1
+ fi
+ else
+ # Cancelling IPv4 settings window
+ ipSettingsCorrect=False
+ echo "::: Cancel selected. Exiting..."
+ exit 1
+ fi
+ done
+ # End the if statement for DHCP vs. static
+ fi
}
setDHCPCD() {
- # Append these lines to dhcpcd.conf to enable a static IP
- echo "## interface ${PIHOLE_INTERFACE}
- static ip_address=${IPV4_ADDRESS}
- static routers=${IPv4gw}
- static domain_name_servers=${IPv4gw}" | tee -a /etc/dhcpcd.conf >/dev/null
+ # Append these lines to dhcpcd.conf to enable a static IP
+ echo "## interface ${PIHOLE_INTERFACE}
+ static ip_address=${IPV4_ADDRESS}
+ static routers=${IPv4gw}
+ static domain_name_servers=${IPv4gw}" | tee -a /etc/dhcpcd.conf >/dev/null
}
setStaticIPv4() {
- local IFCFG_FILE
- local IPADDR
- local CIDR
- if [[ -f /etc/dhcpcd.conf ]]; then
- # Debian Family
- if grep -q "${IPV4_ADDRESS}" /etc/dhcpcd.conf; then
- echo "::: Static IP already configured"
- else
- setDHCPCD
- ip addr replace dev "${PIHOLE_INTERFACE}" "${IPV4_ADDRESS}"
- echo ":::"
- echo "::: Setting IP to ${IPV4_ADDRESS}. You may need to restart after the install is complete."
- echo ":::"
- fi
- elif [[ -f /etc/sysconfig/network-scripts/ifcfg-${PIHOLE_INTERFACE} ]];then
- # Fedora Family
- IFCFG_FILE=/etc/sysconfig/network-scripts/ifcfg-${PIHOLE_INTERFACE}
- if grep -q "${IPV4_ADDRESS}" "${IFCFG_FILE}"; then
- echo "::: Static IP already configured"
- else
- IPADDR=$(echo "${IPV4_ADDRESS}" | cut -f1 -d/)
- CIDR=$(echo "${IPV4_ADDRESS}" | cut -f2 -d/)
- # Backup existing interface configuration:
- cp "${IFCFG_FILE}" "${IFCFG_FILE}".pihole.orig
- # Build Interface configuration file:
- {
- echo "# Configured via Pi-Hole installer"
- echo "DEVICE=$PIHOLE_INTERFACE"
- echo "BOOTPROTO=none"
- echo "ONBOOT=yes"
- echo "IPADDR=$IPADDR"
- echo "PREFIX=$CIDR"
- echo "GATEWAY=$IPv4gw"
- echo "DNS1=$PIHOLE_DNS_1"
- echo "DNS2=$PIHOLE_DNS_2"
- echo "USERCTL=no"
- }> "${IFCFG_FILE}"
- ip addr replace dev "${PIHOLE_INTERFACE}" "${IPV4_ADDRESS}"
- if [ -x "$(command -v nmcli)" ];then
- # Tell NetworkManager to read our new sysconfig file
- nmcli con load "${IFCFG_FILE}" > /dev/null
- fi
- echo ":::"
- echo "::: Setting IP to ${IPV4_ADDRESS}. You may need to restart after the install is complete."
- echo ":::"
- fi
- else
- echo "::: Warning: Unable to locate configuration file to set static IPv4 address!"
- exit 1
- fi
+ local IFCFG_FILE
+ local IPADDR
+ local CIDR
+ if [[ -f /etc/dhcpcd.conf ]]; then
+ # Debian Family
+ if grep -q "${IPV4_ADDRESS}" /etc/dhcpcd.conf; then
+ echo "::: Static IP already configured"
+ else
+ setDHCPCD
+ ip addr replace dev "${PIHOLE_INTERFACE}" "${IPV4_ADDRESS}"
+ echo ":::"
+ echo "::: Setting IP to ${IPV4_ADDRESS}. You may need to restart after the install is complete."
+ echo ":::"
+ fi
+ elif [[ -f /etc/sysconfig/network-scripts/ifcfg-${PIHOLE_INTERFACE} ]];then
+ # Fedora Family
+ IFCFG_FILE=/etc/sysconfig/network-scripts/ifcfg-${PIHOLE_INTERFACE}
+ if grep -q "${IPV4_ADDRESS}" "${IFCFG_FILE}"; then
+ echo "::: Static IP already configured"
+ else
+ IPADDR=$(echo "${IPV4_ADDRESS}" | cut -f1 -d/)
+ CIDR=$(echo "${IPV4_ADDRESS}" | cut -f2 -d/)
+ # Backup existing interface configuration:
+ cp "${IFCFG_FILE}" "${IFCFG_FILE}".pihole.orig
+ # Build Interface configuration file:
+ {
+ echo "# Configured via Pi-Hole installer"
+ echo "DEVICE=$PIHOLE_INTERFACE"
+ echo "BOOTPROTO=none"
+ echo "ONBOOT=yes"
+ echo "IPADDR=$IPADDR"
+ echo "PREFIX=$CIDR"
+ echo "GATEWAY=$IPv4gw"
+ echo "DNS1=$PIHOLE_DNS_1"
+ echo "DNS2=$PIHOLE_DNS_2"
+ echo "USERCTL=no"
+ }> "${IFCFG_FILE}"
+ ip addr replace dev "${PIHOLE_INTERFACE}" "${IPV4_ADDRESS}"
+ if [ -x "$(command -v nmcli)" ];then
+ # Tell NetworkManager to read our new sysconfig file
+ nmcli con load "${IFCFG_FILE}" > /dev/null
+ fi
+ echo ":::"
+ echo "::: Setting IP to ${IPV4_ADDRESS}. You may need to restart after the install is complete."
+ echo ":::"
+ fi
+ else
+ echo "::: Warning: Unable to locate configuration file to set static IPv4 address!"
+ exit 1
+ fi
}
valid_ip() {
- local ip=${1}
- local stat=1
+ local ip=${1}
+ local stat=1
- if [[ ${ip} =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then
- OIFS=$IFS
- IFS='.'
- ip=(${ip})
- IFS=${OIFS}
- [[ ${ip[0]} -le 255 && ${ip[1]} -le 255 \
- && ${ip[2]} -le 255 && ${ip[3]} -le 255 ]]
- stat=$?
- fi
- return ${stat}
+ if [[ ${ip} =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then
+ OIFS=$IFS
+ IFS='.'
+ ip=(${ip})
+ IFS=${OIFS}
+ [[ ${ip[0]} -le 255 && ${ip[1]} -le 255 \
+ && ${ip[2]} -le 255 && ${ip[3]} -le 255 ]]
+ stat=$?
+ fi
+ return ${stat}
}
setDNS() {
- DNSChooseCmd=(whiptail --separate-output --radiolist "Select Upstream DNS Provider. To use your own, select Custom." ${r} ${c} 6)
- DNSChooseOptions=(Google "" on
- OpenDNS "" off
- Level3 "" off
- Norton "" off
- Comodo "" off
- Custom "" off)
- DNSchoices=$("${DNSChooseCmd[@]}" "${DNSChooseOptions[@]}" 2>&1 >/dev/tty)
- if [[ $? = 0 ]];then
- case ${DNSchoices} in
- Google)
- echo "::: Using Google DNS servers."
- PIHOLE_DNS_1="8.8.8.8"
- PIHOLE_DNS_2="8.8.4.4"
- ;;
- OpenDNS)
- echo "::: Using OpenDNS servers."
- PIHOLE_DNS_1="208.67.222.222"
- PIHOLE_DNS_2="208.67.220.220"
- ;;
- Level3)
- echo "::: Using Level3 servers."
- PIHOLE_DNS_1="4.2.2.1"
- PIHOLE_DNS_2="4.2.2.2"
- ;;
- Norton)
- echo "::: Using Norton ConnectSafe servers."
- PIHOLE_DNS_1="199.85.126.10"
- PIHOLE_DNS_2="199.85.127.10"
- ;;
- Comodo)
- echo "::: Using Comodo Secure servers."
- PIHOLE_DNS_1="8.26.56.26"
- PIHOLE_DNS_2="8.20.247.20"
- ;;
- Custom)
- until [[ ${DNSSettingsCorrect} = True ]]; do
- strInvalid="Invalid"
- if [ ! ${PIHOLE_DNS_1} ]; then
- if [ ! ${PIHOLE_DNS_2} ]; then
- prePopulate=""
- else
- prePopulate=", ${PIHOLE_DNS_2}"
- fi
- elif [ ${PIHOLE_DNS_1} ] && [ ! ${PIHOLE_DNS_2} ]; then
- prePopulate="${PIHOLE_DNS_1}"
- elif [ ${PIHOLE_DNS_1} ] && [ ${PIHOLE_DNS_2} ]; then
- prePopulate="${PIHOLE_DNS_1}, ${PIHOLE_DNS_2}"
- fi
+ DNSChooseCmd=(whiptail --separate-output --radiolist "Select Upstream DNS Provider. To use your own, select Custom." ${r} ${c} 6)
+ DNSChooseOptions=(Google "" on
+ OpenDNS "" off
+ Level3 "" off
+ Norton "" off
+ Comodo "" off
+ Custom "" off)
+ DNSchoices=$("${DNSChooseCmd[@]}" "${DNSChooseOptions[@]}" 2>&1 >/dev/tty)
+ if [[ $? = 0 ]];then
+ case ${DNSchoices} in
+ Google)
+ echo "::: Using Google DNS servers."
+ PIHOLE_DNS_1="8.8.8.8"
+ PIHOLE_DNS_2="8.8.4.4"
+ ;;
+ OpenDNS)
+ echo "::: Using OpenDNS servers."
+ PIHOLE_DNS_1="208.67.222.222"
+ PIHOLE_DNS_2="208.67.220.220"
+ ;;
+ Level3)
+ echo "::: Using Level3 servers."
+ PIHOLE_DNS_1="4.2.2.1"
+ PIHOLE_DNS_2="4.2.2.2"
+ ;;
+ Norton)
+ echo "::: Using Norton ConnectSafe servers."
+ PIHOLE_DNS_1="199.85.126.10"
+ PIHOLE_DNS_2="199.85.127.10"
+ ;;
+ Comodo)
+ echo "::: Using Comodo Secure servers."
+ PIHOLE_DNS_1="8.26.56.26"
+ PIHOLE_DNS_2="8.20.247.20"
+ ;;
+ Custom)
+ until [[ ${DNSSettingsCorrect} = True ]]; do
+ strInvalid="Invalid"
+ if [ ! ${PIHOLE_DNS_1} ]; then
+ if [ ! ${PIHOLE_DNS_2} ]; then
+ prePopulate=""
+ else
+ prePopulate=", ${PIHOLE_DNS_2}"
+ fi
+ elif [ ${PIHOLE_DNS_1} ] && [ ! ${PIHOLE_DNS_2} ]; then
+ prePopulate="${PIHOLE_DNS_1}"
+ elif [ ${PIHOLE_DNS_1} ] && [ ${PIHOLE_DNS_2} ]; then
+ prePopulate="${PIHOLE_DNS_1}, ${PIHOLE_DNS_2}"
+ fi
- piholeDNS=$(whiptail --backtitle "Specify Upstream DNS Provider(s)" --inputbox "Enter your desired upstream DNS provider(s), seperated by a comma.\n\nFor example '8.8.8.8, 8.8.4.4'" ${r} ${c} "${prePopulate}" 3>&1 1>&2 2>&3)
+ piholeDNS=$(whiptail --backtitle "Specify Upstream DNS Provider(s)" --inputbox "Enter your desired upstream DNS provider(s), seperated by a comma.\n\nFor example '8.8.8.8, 8.8.4.4'" ${r} ${c} "${prePopulate}" 3>&1 1>&2 2>&3)
- if [[ $? = 0 ]]; then
- PIHOLE_DNS_1=$(echo "${piholeDNS}" | sed 's/[, \t]\+/,/g' | awk -F, '{print$1}')
- PIHOLE_DNS_2=$(echo "${piholeDNS}" | sed 's/[, \t]\+/,/g' | awk -F, '{print$2}')
- if ! valid_ip "${PIHOLE_DNS_1}" || [ ! "${PIHOLE_DNS_1}" ]; then
- PIHOLE_DNS_1=${strInvalid}
- fi
- if ! valid_ip "${PIHOLE_DNS_2}" && [ "${PIHOLE_DNS_2}" ]; then
- PIHOLE_DNS_2=${strInvalid}
- fi
- else
- echo "::: Cancel selected, exiting...."
- exit 1
- fi
- if [[ ${PIHOLE_DNS_1} == "${strInvalid}" ]] || [[ ${PIHOLE_DNS_2} == "${strInvalid}" ]]; then
- whiptail --msgbox --backtitle "Invalid IP" --title "Invalid IP" "One or both entered IP addresses were invalid. Please try again.\n\n DNS Server 1: $PIHOLE_DNS_1\n DNS Server 2: ${PIHOLE_DNS_2}" ${r} ${c}
- if [[ ${PIHOLE_DNS_1} == "${strInvalid}" ]]; then
- PIHOLE_DNS_1=""
- fi
- if [[ ${PIHOLE_DNS_2} == "${strInvalid}" ]]; then
- PIHOLE_DNS_2=""
- fi
- DNSSettingsCorrect=False
- else
- if (whiptail --backtitle "Specify Upstream DNS Provider(s)" --title "Upstream DNS Provider(s)" --yesno "Are these settings correct?\n DNS Server 1: $PIHOLE_DNS_1\n DNS Server 2: ${PIHOLE_DNS_2}" ${r} ${c}); then
- DNSSettingsCorrect=True
- else
- # If the settings are wrong, the loop continues
- DNSSettingsCorrect=False
- fi
- fi
- done
- ;;
- esac
- else
- echo "::: Cancel selected. Exiting..."
- exit 1
- fi
+ if [[ $? = 0 ]]; then
+ PIHOLE_DNS_1=$(echo "${piholeDNS}" | sed 's/[, \t]\+/,/g' | awk -F, '{print$1}')
+ PIHOLE_DNS_2=$(echo "${piholeDNS}" | sed 's/[, \t]\+/,/g' | awk -F, '{print$2}')
+ if ! valid_ip "${PIHOLE_DNS_1}" || [ ! "${PIHOLE_DNS_1}" ]; then
+ PIHOLE_DNS_1=${strInvalid}
+ fi
+ if ! valid_ip "${PIHOLE_DNS_2}" && [ "${PIHOLE_DNS_2}" ]; then
+ PIHOLE_DNS_2=${strInvalid}
+ fi
+ else
+ echo "::: Cancel selected, exiting...."
+ exit 1
+ fi
+ if [[ ${PIHOLE_DNS_1} == "${strInvalid}" ]] || [[ ${PIHOLE_DNS_2} == "${strInvalid}" ]]; then
+ whiptail --msgbox --backtitle "Invalid IP" --title "Invalid IP" "One or both entered IP addresses were invalid. Please try again.\n\n DNS Server 1: $PIHOLE_DNS_1\n DNS Server 2: ${PIHOLE_DNS_2}" ${r} ${c}
+ if [[ ${PIHOLE_DNS_1} == "${strInvalid}" ]]; then
+ PIHOLE_DNS_1=""
+ fi
+ if [[ ${PIHOLE_DNS_2} == "${strInvalid}" ]]; then
+ PIHOLE_DNS_2=""
+ fi
+ DNSSettingsCorrect=False
+ else
+ if (whiptail --backtitle "Specify Upstream DNS Provider(s)" --title "Upstream DNS Provider(s)" --yesno "Are these settings correct?\n DNS Server 1: $PIHOLE_DNS_1\n DNS Server 2: ${PIHOLE_DNS_2}" ${r} ${c}); then
+ DNSSettingsCorrect=True
+ else
+ # If the settings are wrong, the loop continues
+ DNSSettingsCorrect=False
+ fi
+ fi
+ done
+ ;;
+ esac
+ else
+ echo "::: Cancel selected. Exiting..."
+ exit 1
+ fi
}
setLogging() {
@@ -552,69 +550,69 @@ setLogging() {
local LogChooseOptions
local LogChoices
- LogToggleCommand=(whiptail --separate-output --radiolist "Do you want to log queries?\n (Disabling will render graphs on the Admin page useless):" ${r} ${c} 6)
- LogChooseOptions=("On (Reccomended)" "" on
- Off "" off)
- LogChoices=$("${LogToggleCommand[@]}" "${LogChooseOptions[@]}" 2>&1 >/dev/tty) || (echo "::: Cancel selected. Exiting..." && exit 1)
- case ${LogChoices} in
- "On (Recommended)")
- echo "::: Logging On."
- QUERY_LOGGING=true
- ;;
- Off)
- echo "::: Logging Off."
- QUERY_LOGGING=false
- ;;
- esac
+ LogToggleCommand=(whiptail --separate-output --radiolist "Do you want to log queries?\n (Disabling will render graphs on the Admin page useless):" ${r} ${c} 6)
+ LogChooseOptions=("On (Reccomended)" "" on
+ Off "" off)
+ LogChoices=$("${LogToggleCommand[@]}" "${LogChooseOptions[@]}" 2>&1 >/dev/tty) || (echo "::: Cancel selected. Exiting..." && exit 1)
+ case ${LogChoices} in
+ "On (Recommended)")
+ echo "::: Logging On."
+ QUERY_LOGGING=true
+ ;;
+ Off)
+ echo "::: Logging Off."
+ QUERY_LOGGING=false
+ ;;
+ esac
}
version_check_dnsmasq() {
- # Check if /etc/dnsmasq.conf is from pihole. If so replace with an original and install new in .d directory
- local dnsmasq_conf="/etc/dnsmasq.conf"
- local dnsmasq_conf_orig="/etc/dnsmasq.conf.orig"
- local dnsmasq_pihole_id_string="addn-hosts=/etc/pihole/gravity.list"
- local dnsmasq_original_config="/etc/.pihole/advanced/dnsmasq.conf.original"
- local dnsmasq_pihole_01_snippet="/etc/.pihole/advanced/01-pihole.conf"
- local dnsmasq_pihole_01_location="/etc/dnsmasq.d/01-pihole.conf"
+ # Check if /etc/dnsmasq.conf is from pihole. If so replace with an original and install new in .d directory
+ local dnsmasq_conf="/etc/dnsmasq.conf"
+ local dnsmasq_conf_orig="/etc/dnsmasq.conf.orig"
+ local dnsmasq_pihole_id_string="addn-hosts=/etc/pihole/gravity.list"
+ local dnsmasq_original_config="/etc/.pihole/advanced/dnsmasq.conf.original"
+ local dnsmasq_pihole_01_snippet="/etc/.pihole/advanced/01-pihole.conf"
+ local dnsmasq_pihole_01_location="/etc/dnsmasq.d/01-pihole.conf"
- if [ -f ${dnsmasq_conf} ]; then
- echo -n "::: Existing dnsmasq.conf found..."
- if grep -q ${dnsmasq_pihole_id_string} ${dnsmasq_conf}; then
- echo " it is from a previous pi-hole install."
- echo -n "::: Backing up dnsmasq.conf to dnsmasq.conf.orig..."
- mv -f ${dnsmasq_conf} ${dnsmasq_conf_orig}
- echo " done."
- echo -n "::: Restoring default dnsmasq.conf..."
- cp ${dnsmasq_original_config} ${dnsmasq_conf}
- echo " done."
- else
- echo " it is not a pi-hole file, leaving alone!"
- fi
- else
- echo -n "::: No dnsmasq.conf found.. restoring default dnsmasq.conf..."
- cp ${dnsmasq_original_config} ${dnsmasq_conf}
- echo " done."
- fi
+ if [ -f ${dnsmasq_conf} ]; then
+ echo -n "::: Existing dnsmasq.conf found..."
+ if grep -q ${dnsmasq_pihole_id_string} ${dnsmasq_conf}; then
+ echo " it is from a previous pi-hole install."
+ echo -n "::: Backing up dnsmasq.conf to dnsmasq.conf.orig..."
+ mv -f ${dnsmasq_conf} ${dnsmasq_conf_orig}
+ echo " done."
+ echo -n "::: Restoring default dnsmasq.conf..."
+ cp ${dnsmasq_original_config} ${dnsmasq_conf}
+ echo " done."
+ else
+ echo " it is not a pi-hole file, leaving alone!"
+ fi
+ else
+ echo -n "::: No dnsmasq.conf found.. restoring default dnsmasq.conf..."
+ cp ${dnsmasq_original_config} ${dnsmasq_conf}
+ echo " done."
+ fi
- echo -n "::: Copying 01-pihole.conf to /etc/dnsmasq.d/01-pihole.conf..."
- cp ${dnsmasq_pihole_01_snippet} ${dnsmasq_pihole_01_location}
- echo " done."
- sed -i "s/@INT@/$PIHOLE_INTERFACE/" ${dnsmasq_pihole_01_location}
- if [[ "${PIHOLE_DNS_1}" != "" ]]; then
- sed -i "s/@DNS1@/$PIHOLE_DNS_1/" ${dnsmasq_pihole_01_location}
- else
- sed -i '/^server=@DNS1@/d' ${dnsmasq_pihole_01_location}
- fi
- if [[ "${PIHOLE_DNS_2}" != "" ]]; then
- sed -i "s/@DNS2@/$PIHOLE_DNS_2/" ${dnsmasq_pihole_01_location}
- else
- sed -i '/^server=@DNS2@/d' ${dnsmasq_pihole_01_location}
- fi
+ echo -n "::: Copying 01-pihole.conf to /etc/dnsmasq.d/01-pihole.conf..."
+ cp ${dnsmasq_pihole_01_snippet} ${dnsmasq_pihole_01_location}
+ echo " done."
+ sed -i "s/@INT@/$PIHOLE_INTERFACE/" ${dnsmasq_pihole_01_location}
+ if [[ "${PIHOLE_DNS_1}" != "" ]]; then
+ sed -i "s/@DNS1@/$PIHOLE_DNS_1/" ${dnsmasq_pihole_01_location}
+ else
+ sed -i '/^server=@DNS1@/d' ${dnsmasq_pihole_01_location}
+ fi
+ if [[ "${PIHOLE_DNS_2}" != "" ]]; then
+ sed -i "s/@DNS2@/$PIHOLE_DNS_2/" ${dnsmasq_pihole_01_location}
+ else
+ sed -i '/^server=@DNS2@/d' ${dnsmasq_pihole_01_location}
+ fi
- sed -i 's/^#conf-dir=\/etc\/dnsmasq.d$/conf-dir=\/etc\/dnsmasq.d/' ${dnsmasq_conf}
+ sed -i 's/^#conf-dir=\/etc\/dnsmasq.d$/conf-dir=\/etc\/dnsmasq.d/' ${dnsmasq_conf}
- if [[ "${QUERY_LOGGING}" == false ]] ; then
+ if [[ "${QUERY_LOGGING}" == false ]] ; then
#Disable Logging
sed -i 's/^log-queries/#log-queries/' ${dnsmasq_pihole_01_location}
else
@@ -624,13 +622,13 @@ version_check_dnsmasq() {
}
remove_legacy_scripts() {
- #Tidy up /usr/local/bin directory if installing over previous install.
- oldFiles=( gravity chronometer whitelist blacklist piholeLogFlush updateDashboard uninstall setupLCD piholeDebug)
- for i in "${oldFiles[@]}"; do
- if [ -f "/usr/local/bin/$i.sh" ]; then
- rm /usr/local/bin/"$i".sh
- fi
- done
+ #Tidy up /usr/local/bin directory if installing over previous install.
+ oldFiles=( gravity chronometer whitelist blacklist piholeLogFlush updateDashboard uninstall setupLCD piholeDebug)
+ for i in "${oldFiles[@]}"; do
+ if [ -f "/usr/local/bin/$i.sh" ]; then
+ rm /usr/local/bin/"$i".sh
+ fi
+ done
}
clean_existing() {
@@ -639,21 +637,20 @@ clean_existing() {
local clean_directory="${1}"
local old_files=${2}
- for script in "${old_files[@]}"; do
- rm -f "${clean_directory}${script}.sh"
- done
-
+ for script in "${old_files[@]}"; do
+ rm -f "${clean_directory}${script}.sh"
+ done
}
installScripts() {
# Install the scripts from repository to their various locations
readonly install_dir="/opt/pihole/"
- echo ":::"
- echo -n "::: Installing scripts from ${PI_HOLE_LOCAL_REPO}..."
+ echo ":::"
+ echo -n "::: Installing scripts from ${PI_HOLE_LOCAL_REPO}..."
- # Clear out script files from Pi-hole scripts directory.
- clean_existing "${install_dir}" "${PI_HOLE_FILES}"
+ # Clear out script files from Pi-hole scripts directory.
+ clean_existing "${install_dir}" "${PI_HOLE_FILES}"
# Install files from local core repository
if is_repo "${PI_HOLE_LOCAL_REPO}"; then
@@ -663,7 +660,7 @@ installScripts() {
install -o "${USER}" -Dm755 -t /opt/pihole/ ./automated\ install/uninstall.sh
install -o "${USER}" -Dm755 -t /usr/local/bin/ pihole
install -Dm644 ./advanced/bash-completion/pihole /etc/bash_completion.d/pihole
- echo " done."
+ echo " done."
else
echo " *** ERROR: Local repo ${core_repo} not found, exiting."
exit 1
@@ -671,258 +668,258 @@ installScripts() {
}
installConfigs() {
- # Install the configs from /etc/.pihole to their various locations
- echo ":::"
- echo "::: Installing configs..."
- version_check_dnsmasq
- if [ ! -d "/etc/lighttpd" ]; then
- mkdir /etc/lighttpd
- chown "${USER}":root /etc/lighttpd
- elif [ -f "/etc/lighttpd/lighttpd.conf" ]; then
- mv /etc/lighttpd/lighttpd.conf /etc/lighttpd/lighttpd.conf.orig
- fi
- cp /etc/.pihole/advanced/${LIGHTTPD_CFG} /etc/lighttpd/lighttpd.conf
- mkdir -p /var/run/lighttpd
- chown ${LIGHTTPD_USER}:${LIGHTTPD_GROUP} /var/run/lighttpd
- mkdir -p /var/cache/lighttpd/compress
- chown ${LIGHTTPD_USER}:${LIGHTTPD_GROUP} /var/cache/lighttpd/compress
- mkdir -p /var/cache/lighttpd/uploads
- chown ${LIGHTTPD_USER}:${LIGHTTPD_GROUP} /var/cache/lighttpd/uploads
+ # Install the configs from /etc/.pihole to their various locations
+ echo ":::"
+ echo "::: Installing configs..."
+ version_check_dnsmasq
+ if [ ! -d "/etc/lighttpd" ]; then
+ mkdir /etc/lighttpd
+ chown "${USER}":root /etc/lighttpd
+ elif [ -f "/etc/lighttpd/lighttpd.conf" ]; then
+ mv /etc/lighttpd/lighttpd.conf /etc/lighttpd/lighttpd.conf.orig
+ fi
+ cp /etc/.pihole/advanced/${LIGHTTPD_CFG} /etc/lighttpd/lighttpd.conf
+ mkdir -p /var/run/lighttpd
+ chown ${LIGHTTPD_USER}:${LIGHTTPD_GROUP} /var/run/lighttpd
+ mkdir -p /var/cache/lighttpd/compress
+ chown ${LIGHTTPD_USER}:${LIGHTTPD_GROUP} /var/cache/lighttpd/compress
+ mkdir -p /var/cache/lighttpd/uploads
+ chown ${LIGHTTPD_USER}:${LIGHTTPD_GROUP} /var/cache/lighttpd/uploads
}
stop_service() {
- # Stop service passed in as argument.
- # Can softfail, as process may not be installed when this is called
- echo ":::"
- echo -n "::: Stopping ${1} service..."
- if [ -x "$(command -v systemctl)" ]; then
- systemctl stop "${1}" &> /dev/null & spinner $! || true
- else
- service "${1}" stop &> /dev/null & spinner $! || true
- fi
- echo " done."
+ # Stop service passed in as argument.
+ # Can softfail, as process may not be installed when this is called
+ echo ":::"
+ echo -n "::: Stopping ${1} service..."
+ if [ -x "$(command -v systemctl)" ]; then
+ systemctl stop "${1}" &> /dev/null & spinner $! || true
+ else
+ service "${1}" stop &> /dev/null & spinner $! || true
+ fi
+ echo " done."
}
start_service() {
- # Start/Restart service passed in as argument
- # This should not fail, it's an error if it does
- echo ":::"
- echo -n "::: Starting ${1} service..."
- if [ -x "$(command -v systemctl)" ]; then
- systemctl restart "${1}" &> /dev/null & spinner $!
- else
- service "${1}" restart &> /dev/null & spinner $!
- fi
- echo " done."
+ # Start/Restart service passed in as argument
+ # This should not fail, it's an error if it does
+ echo ":::"
+ echo -n "::: Starting ${1} service..."
+ if [ -x "$(command -v systemctl)" ]; then
+ systemctl restart "${1}" &> /dev/null & spinner $!
+ else
+ service "${1}" restart &> /dev/null & spinner $!
+ fi
+ echo " done."
}
enable_service() {
- # Enable service so that it will start with next reboot
- echo ":::"
- echo -n "::: Enabling ${1} service to start on reboot..."
- if [ -x "$(command -v systemctl)" ]; then
- systemctl enable "${1}" &> /dev/null & spinner $!
- else
- update-rc.d "${1}" defaults &> /dev/null & spinner $!
- fi
- echo " done."
+ # Enable service so that it will start with next reboot
+ echo ":::"
+ echo -n "::: Enabling ${1} service to start on reboot..."
+ if [ -x "$(command -v systemctl)" ]; then
+ systemctl enable "${1}" &> /dev/null & spinner $!
+ else
+ update-rc.d "${1}" defaults &> /dev/null & spinner $!
+ fi
+ echo " done."
}
update_pacakge_cache() {
- #Running apt-get update/upgrade with minimal output can cause some issues with
- #requiring user input (e.g password for phpmyadmin see #218)
+ #Running apt-get update/upgrade with minimal output can cause some issues with
+ #requiring user input (e.g password for phpmyadmin see #218)
- #Check to see if apt-get update has already been run today
- #it needs to have been run at least once on new installs!
- timestamp=$(stat -c %Y ${PKG_CACHE})
- timestampAsDate=$(date -d @"${timestamp}" "+%b %e")
- today=$(date "+%b %e")
+ #Check to see if apt-get update has already been run today
+ #it needs to have been run at least once on new installs!
+ timestamp=$(stat -c %Y ${PKG_CACHE})
+ timestampAsDate=$(date -d @"${timestamp}" "+%b %e")
+ today=$(date "+%b %e")
- if [ ! "${today}" == "${timestampAsDate}" ]; then
- #update package lists
- echo ":::"
- echo -n "::: ${PKG_MANAGER} update has not been run today. Running now..."
- ${UPDATE_PKG_CACHE} &> /dev/null & spinner $!
- echo " done!"
- fi
+ if [ ! "${today}" == "${timestampAsDate}" ]; then
+ #update package lists
+ echo ":::"
+ echo -n "::: ${PKG_MANAGER} update has not been run today. Running now..."
+ ${UPDATE_PKG_CACHE} &> /dev/null & spinner $!
+ echo " done!"
+ fi
}
notify_package_updates_available() {
# Let user know if they have outdated packages on their system and
# advise them to run a package update at soonest possible.
- echo ":::"
- echo -n "::: Checking ${PKG_MANAGER} for upgraded packages...."
- updatesToInstall=$(eval "${PKG_COUNT}")
- echo " done!"
- echo ":::"
- if [[ ${updatesToInstall} -eq "0" ]]; then
- echo "::: Your system is up to date! Continuing with Pi-hole installation..."
- else
- echo "::: There are ${updatesToInstall} updates available for your system!"
- echo "::: We recommend you run '${PKG_UPDATE}' after installing Pi-Hole! "
- echo ":::"
- fi
+ echo ":::"
+ echo -n "::: Checking ${PKG_MANAGER} for upgraded packages...."
+ updatesToInstall=$(eval "${PKG_COUNT}")
+ echo " done!"
+ echo ":::"
+ if [[ ${updatesToInstall} -eq "0" ]]; then
+ echo "::: Your system is up to date! Continuing with Pi-hole installation..."
+ else
+ echo "::: There are ${updatesToInstall} updates available for your system!"
+ echo "::: We recommend you run '${PKG_UPDATE}' after installing Pi-Hole! "
+ echo ":::"
+ fi
}
install_dependent_packages() {
- # Install packages passed in via argument array
- # No spinner - conflicts with set -e
- declare -a argArray1=("${!1}")
+ # Install packages passed in via argument array
+ # No spinner - conflicts with set -e
+ declare -a argArray1=("${!1}")
- for i in "${argArray1[@]}"; do
- echo -n "::: Checking for $i..."
- package_check_install "${i}" &> /dev/null
- echo " installed!"
- done
+ for i in "${argArray1[@]}"; do
+ echo -n "::: Checking for $i..."
+ package_check_install "${i}" &> /dev/null
+ echo " installed!"
+ done
}
CreateLogFile() {
- # Create logfiles if necessary
- echo ":::"
- echo -n "::: Creating log file and changing owner to dnsmasq..."
- if [ ! -f /var/log/pihole.log ]; then
- touch /var/log/pihole.log
- chmod 644 /var/log/pihole.log
- chown "${DNSMASQ_USER}":root /var/log/pihole.log
- echo " done!"
- else
- echo " already exists!"
- fi
+ # Create logfiles if necessary
+ echo ":::"
+ echo -n "::: Creating log file and changing owner to dnsmasq..."
+ if [ ! -f /var/log/pihole.log ]; then
+ touch /var/log/pihole.log
+ chmod 644 /var/log/pihole.log
+ chown "${DNSMASQ_USER}":root /var/log/pihole.log
+ echo " done!"
+ else
+ echo " already exists!"
+ fi
}
installPiholeWeb() {
- # Install the web interface
- echo ":::"
- echo "::: Installing pihole custom index page..."
- if [ -d "/var/www/html/pihole" ]; then
- if [ -f "/var/www/html/pihole/index.html" ]; then
- echo "::: Existing index.html detected, not overwriting"
- else
- echo -n "::: index.html missing, replacing... "
- cp /etc/.pihole/advanced/index.html /var/www/html/pihole/
- echo " done!"
- fi
+ # Install the web interface
+ echo ":::"
+ echo "::: Installing pihole custom index page..."
+ if [ -d "/var/www/html/pihole" ]; then
+ if [ -f "/var/www/html/pihole/index.html" ]; then
+ echo "::: Existing index.html detected, not overwriting"
+ else
+ echo -n "::: index.html missing, replacing... "
+ cp /etc/.pihole/advanced/index.html /var/www/html/pihole/
+ echo " done!"
+ fi
- if [ -f "/var/www/html/pihole/index.js" ]; then
- echo "::: Existing index.js detected, not overwriting"
- else
- echo -n "::: index.js missing, replacing... "
- cp /etc/.pihole/advanced/index.js /var/www/html/pihole/
- echo " done!"
- fi
+ if [ -f "/var/www/html/pihole/index.js" ]; then
+ echo "::: Existing index.js detected, not overwriting"
+ else
+ echo -n "::: index.js missing, replacing... "
+ cp /etc/.pihole/advanced/index.js /var/www/html/pihole/
+ echo " done!"
+ fi
- else
- mkdir /var/www/html/pihole
- if [ -f /var/www/html/index.lighttpd.html ]; then
- mv /var/www/html/index.lighttpd.html /var/www/html/index.lighttpd.orig
- else
- printf "\n:::\tNo default index.lighttpd.html file found... not backing up"
- fi
- cp /etc/.pihole/advanced/index.* /var/www/html/pihole/.
- echo " done!"
- fi
- # Install Sudoer file
- echo ":::"
- echo -n "::: Installing sudoer file..."
- mkdir -p /etc/sudoers.d/
- cp /etc/.pihole/advanced/pihole.sudo /etc/sudoers.d/pihole
- chmod 0440 /etc/sudoers.d/pihole
- echo " done!"
+ else
+ mkdir /var/www/html/pihole
+ if [ -f /var/www/html/index.lighttpd.html ]; then
+ mv /var/www/html/index.lighttpd.html /var/www/html/index.lighttpd.orig
+ else
+ printf "\n:::\tNo default index.lighttpd.html file found... not backing up"
+ fi
+ cp /etc/.pihole/advanced/index.* /var/www/html/pihole/.
+ echo " done!"
+ fi
+ # Install Sudoer file
+ echo ":::"
+ echo -n "::: Installing sudoer file..."
+ mkdir -p /etc/sudoers.d/
+ cp /etc/.pihole/advanced/pihole.sudo /etc/sudoers.d/pihole
+ chmod 0440 /etc/sudoers.d/pihole
+ echo " done!"
}
installCron() {
- # Install the cron job
- echo ":::"
- echo -n "::: Installing latest Cron script..."
- cp /etc/.pihole/advanced/pihole.cron /etc/cron.d/pihole
- echo " done!"
+ # Install the cron job
+ echo ":::"
+ echo -n "::: Installing latest Cron script..."
+ cp /etc/.pihole/advanced/pihole.cron /etc/cron.d/pihole
+ echo " done!"
}
runGravity() {
- # Run gravity.sh to build blacklists
- echo ":::"
- echo "::: Preparing to run gravity.sh to refresh hosts..."
- if ls /etc/pihole/list* 1> /dev/null 2>&1; then
- echo "::: Cleaning up previous install (preserving whitelist/blacklist)"
- rm /etc/pihole/list.*
- fi
- echo "::: Running gravity.sh"
- /opt/pihole/gravity.sh
+ # Run gravity.sh to build blacklists
+ echo ":::"
+ echo "::: Preparing to run gravity.sh to refresh hosts..."
+ if ls /etc/pihole/list* 1> /dev/null 2>&1; then
+ echo "::: Cleaning up previous install (preserving whitelist/blacklist)"
+ rm /etc/pihole/list.*
+ fi
+ echo "::: Running gravity.sh"
+ /opt/pihole/gravity.sh
}
create_pihole_user() {
- # Check if user pihole exists and create if not
- echo "::: Checking if user 'pihole' exists..."
- id -u pihole &> /dev/null && echo "::: User 'pihole' already exists" || (echo "::: User 'pihole' doesn't exist. Creating..." && useradd -r -s /usr/sbin/nologin pihole)
+ # Check if user pihole exists and create if not
+ echo "::: Checking if user 'pihole' exists..."
+ id -u pihole &> /dev/null && echo "::: User 'pihole' already exists" || (echo "::: User 'pihole' doesn't exist. Creating..." && useradd -r -s /usr/sbin/nologin pihole)
}
configureFirewall() {
- # Allow HTTP and DNS traffic
- if [ -x "$(command -v firewall-cmd)" ]; then
- firewall-cmd --state &> /dev/null && ( echo "::: Configuring firewalld for httpd and dnsmasq.." && firewall-cmd --permanent --add-port=80/tcp && firewall-cmd --permanent --add-port=53/tcp \
- && firewall-cmd --permanent --add-port=53/udp && firewall-cmd --reload) || echo "::: FirewallD not enabled"
- elif [ -x "$(command -v iptables)" ]; then
- echo "::: Configuring iptables for httpd and dnsmasq.."
- iptables -A INPUT -p tcp -m tcp --dport 80 -j ACCEPT
- iptables -A INPUT -p tcp -m tcp --dport 53 -j ACCEPT
- iptables -A INPUT -p udp -m udp --dport 53 -j ACCEPT
- else
- echo "::: No firewall detected.. skipping firewall configuration."
- fi
+ # Allow HTTP and DNS traffic
+ if [ -x "$(command -v firewall-cmd)" ]; then
+ firewall-cmd --state &> /dev/null && ( echo "::: Configuring firewalld for httpd and dnsmasq.." && firewall-cmd --permanent --add-port=80/tcp && firewall-cmd --permanent --add-port=53/tcp \
+ && firewall-cmd --permanent --add-port=53/udp && firewall-cmd --reload) || echo "::: FirewallD not enabled"
+ elif [ -x "$(command -v iptables)" ]; then
+ echo "::: Configuring iptables for httpd and dnsmasq.."
+ iptables -A INPUT -p tcp -m tcp --dport 80 -j ACCEPT
+ iptables -A INPUT -p tcp -m tcp --dport 53 -j ACCEPT
+ iptables -A INPUT -p udp -m udp --dport 53 -j ACCEPT
+ else
+ echo "::: No firewall detected.. skipping firewall configuration."
+ fi
}
finalExports() {
- # Update variables in setupVars.conf file
- if [ -e "${setupVars}" ]; then
- sed -i.update.bak '/PIHOLE_INTERFACE/d;/IPV4_ADDRESS/d;/IPV6_ADDRESS/d;/PIHOLE_DNS_1/d;/PIHOLE_DNS_2/d;/QUERY_LOGGING/d;' "${setupVars}"
- fi
+ # Update variables in setupVars.conf file
+ if [ -e "${setupVars}" ]; then
+ sed -i.update.bak '/PIHOLE_INTERFACE/d;/IPV4_ADDRESS/d;/IPV6_ADDRESS/d;/PIHOLE_DNS_1/d;/PIHOLE_DNS_2/d;/QUERY_LOGGING/d;' "${setupVars}"
+ fi
{
- echo "PIHOLE_INTERFACE=${PIHOLE_INTERFACE}"
- echo "IPV4_ADDRESS=${IPV4_ADDRESS}"
- echo "IPV6_ADDRESS=${IPV6_ADDRESS}"
- echo "PIHOLE_DNS_1=${PIHOLE_DNS_1}"
- echo "PIHOLE_DNS_2=${PIHOLE_DNS_2}"
- echo "QUERY_LOGGING=${QUERY_LOGGING}"
+ echo "PIHOLE_INTERFACE=${PIHOLE_INTERFACE}"
+ echo "IPV4_ADDRESS=${IPV4_ADDRESS}"
+ echo "IPV6_ADDRESS=${IPV6_ADDRESS}"
+ echo "PIHOLE_DNS_1=${PIHOLE_DNS_1}"
+ echo "PIHOLE_DNS_2=${PIHOLE_DNS_2}"
+ echo "QUERY_LOGGING=${QUERY_LOGGING}"
}>> "${setupVars}"
}
installPihole() {
- # Install base files and web interface
- create_pihole_user
- if [ ! -d "/var/www/html" ]; then
- mkdir -p /var/www/html
- fi
- chown ${LIGHTTPD_USER}:${LIGHTTPD_GROUP} /var/www/html
- chmod 775 /var/www/html
- usermod -a -G ${LIGHTTPD_GROUP} pihole
- if [ -x "$(command -v lighty-enable-mod)" ]; then
- lighty-enable-mod fastcgi fastcgi-php > /dev/null || true
- else
- printf "\n:::\tWarning: 'lighty-enable-mod' utility not found. Please ensure fastcgi is enabled if you experience issues.\n"
- fi
- installScripts
- installConfigs
- CreateLogFile
- configureSelinux
- installPiholeWeb
- installCron
- configureFirewall
- finalExports
- runGravity
+ # Install base files and web interface
+ create_pihole_user
+ if [ ! -d "/var/www/html" ]; then
+ mkdir -p /var/www/html
+ fi
+ chown ${LIGHTTPD_USER}:${LIGHTTPD_GROUP} /var/www/html
+ chmod 775 /var/www/html
+ usermod -a -G ${LIGHTTPD_GROUP} pihole
+ if [ -x "$(command -v lighty-enable-mod)" ]; then
+ lighty-enable-mod fastcgi fastcgi-php > /dev/null || true
+ else
+ printf "\n:::\tWarning: 'lighty-enable-mod' utility not found. Please ensure fastcgi is enabled if you experience issues.\n"
+ fi
+ installScripts
+ installConfigs
+ CreateLogFile
+ configureSelinux
+ installPiholeWeb
+ installCron
+ configureFirewall
+ finalExports
+ runGravity
}
accountForRefactor() {
- # At some point in the future this list can be pruned, for now we'll need it to ensure updates don't break.
+ # At some point in the future this list can be pruned, for now we'll need it to ensure updates don't break.
- # Refactoring of install script has changed the name of a couple of variables. Sort them out here.
+ # Refactoring of install script has changed the name of a couple of variables. Sort them out here.
- sed -i 's/piholeInterface/PIHOLE_INTERFACE/g' ${setupVars}
- sed -i 's/IPv4_address/IPV4_ADDRESS/g' ${setupVars}
- sed -i 's/IPv4addr/IPV4_ADDRESS/g' ${setupVars}
- sed -i 's/IPv6_address/IPV6_ADDRESS/g' ${setupVars}
- sed -i 's/piholeIPv6/IPV6_ADDRESS/g' ${setupVars}
- sed -i 's/piholeDNS1/PIHOLE_DNS_1/g' ${setupVars}
- sed -i 's/piholeDNS2/PIHOLE_DNS_2/g' ${setupVars}
+ sed -i 's/piholeInterface/PIHOLE_INTERFACE/g' ${setupVars}
+ sed -i 's/IPv4_address/IPV4_ADDRESS/g' ${setupVars}
+ sed -i 's/IPv4addr/IPV4_ADDRESS/g' ${setupVars}
+ sed -i 's/IPv6_address/IPV6_ADDRESS/g' ${setupVars}
+ sed -i 's/piholeIPv6/IPV6_ADDRESS/g' ${setupVars}
+ sed -i 's/piholeDNS1/PIHOLE_DNS_1/g' ${setupVars}
+ sed -i 's/piholeDNS2/PIHOLE_DNS_2/g' ${setupVars}
}
@@ -943,29 +940,29 @@ updatePihole() {
}
configureSelinux() {
- if [ -x "$(command -v getenforce)" ]; then
- printf "\n::: SELinux Detected\n"
- printf ":::\tChecking for SELinux policy development packages..."
- package_check_install "selinux-policy-devel" > /dev/null
- echo " installed!"
- printf ":::\tEnabling httpd server side includes (SSI).. "
- setsebool -P httpd_ssi_exec on &> /dev/null && echo "Success" || echo "SELinux not enabled"
- printf "\n:::\tCompiling Pi-Hole SELinux policy..\n"
- if ! [ -x "$(command -v systemctl)" ]; then
- sed -i.bak '/systemd/d' /etc/.pihole/advanced/selinux/pihole.te
- fi
- checkmodule -M -m -o /etc/pihole/pihole.mod /etc/.pihole/advanced/selinux/pihole.te
- semodule_package -o /etc/pihole/pihole.pp -m /etc/pihole/pihole.mod
- semodule -i /etc/pihole/pihole.pp
- rm -f /etc/pihole/pihole.mod
- semodule -l | grep pihole &> /dev/null && echo "::: Installed Pi-Hole SELinux policy" || echo "::: Warning: Pi-Hole SELinux policy did not install."
- fi
+ if [ -x "$(command -v getenforce)" ]; then
+ printf "\n::: SELinux Detected\n"
+ printf ":::\tChecking for SELinux policy development packages..."
+ package_check_install "selinux-policy-devel" > /dev/null
+ echo " installed!"
+ printf ":::\tEnabling httpd server side includes (SSI).. "
+ setsebool -P httpd_ssi_exec on &> /dev/null && echo "Success" || echo "SELinux not enabled"
+ printf "\n:::\tCompiling Pi-Hole SELinux policy..\n"
+ if ! [ -x "$(command -v systemctl)" ]; then
+ sed -i.bak '/systemd/d' /etc/.pihole/advanced/selinux/pihole.te
+ fi
+ checkmodule -M -m -o /etc/pihole/pihole.mod /etc/.pihole/advanced/selinux/pihole.te
+ semodule_package -o /etc/pihole/pihole.pp -m /etc/pihole/pihole.mod
+ semodule -i /etc/pihole/pihole.pp
+ rm -f /etc/pihole/pihole.mod
+ semodule -l | grep pihole &> /dev/null && echo "::: Installed Pi-Hole SELinux policy" || echo "::: Warning: Pi-Hole SELinux policy did not install."
+ fi
}
displayFinalMessage() {
- if (( ${#1} > 0 )) ; then
- # Final completion message to user
- whiptail --msgbox --backtitle "Make it so." --title "Installation Complete!" "Configure your devices to use the Pi-hole as their DNS server using:
+ if (( ${#1} > 0 )) ; then
+ # Final completion message to user
+ whiptail --msgbox --backtitle "Make it so." --title "Installation Complete!" "Configure your devices to use the Pi-hole as their DNS server using:
IPv4: ${IPV4_ADDRESS%/*}
IPv6: ${IPV6_ADDRESS}
@@ -975,8 +972,8 @@ If you set a new IP address, you should restart the Pi.
The install log is in /etc/pihole.
View the web interface at http://pi.hole/admin or http://${IPV4_ADDRESS%/*}/admin
The currently set password is ${1}" ${r} ${c}
- else
- whiptail --msgbox --backtitle "Make it so." --title "Installation Complete!" "Configure your devices to use the Pi-hole as their DNS server using:
+ else
+ whiptail --msgbox --backtitle "Make it so." --title "Installation Complete!" "Configure your devices to use the Pi-hole as their DNS server using:
IPv4: ${IPV4_ADDRESS%/*}
IPv6: ${IPV6_ADDRESS}
@@ -985,170 +982,169 @@ If you set a new IP address, you should restart the Pi.
The install log is in /etc/pihole.
View the web interface at http://pi.hole/admin or http://${IPV4_ADDRESS%/*}/admin" ${r} ${c}
- fi
+ fi
}
update_dialogs() {
- # reconfigure
- if [ "${reconfigure}" = true ]; then
- opt1a="Repair"
- opt1b="This will retain existing settings"
- strAdd="You will remain on the same version"
- else
- opt1a="Update"
- opt1b="This will retain existing settings."
- strAdd="You will be updated to the latest version."
- fi
- opt2a="Reconfigure"
- opt2b="This will allow you to enter new settings"
+ # reconfigure
+ if [ "${reconfigure}" = true ]; then
+ opt1a="Repair"
+ opt1b="This will retain existing settings"
+ strAdd="You will remain on the same version"
+ else
+ opt1a="Update"
+ opt1b="This will retain existing settings."
+ strAdd="You will be updated to the latest version."
+ fi
+ opt2a="Reconfigure"
+ opt2b="This will allow you to enter new settings"
- UpdateCmd=$(whiptail --title "Existing Install Detected!" --menu "\n\nWe have detected an existing install.\n\nPlease choose from the following options: \n($strAdd)" ${r} ${c} 2 \
- "${opt1a}" "${opt1b}" \
- "${opt2a}" "${opt2b}" 3>&2 2>&1 1>&3)
-
- if [[ $? = 0 ]];then
- case ${UpdateCmd} in
- ${opt1a})
- echo "::: ${opt1a} option selected."
- useUpdateVars=true
- ;;
- ${opt2a})
- echo "::: ${opt2a} option selected"
- useUpdateVars=false
- ;;
- esac
- else
- echo "::: Cancel selected. Exiting..."
- exit 1
- fi
+ UpdateCmd=$(whiptail --title "Existing Install Detected!" --menu "\n\nWe have detected an existing install.\n\nPlease choose from the following options: \n($strAdd)" ${r} ${c} 2 \
+ "${opt1a}" "${opt1b}" \
+ "${opt2a}" "${opt2b}" 3>&2 2>&1 1>&3)
+ if [[ $? = 0 ]];then
+ case ${UpdateCmd} in
+ ${opt1a})
+ echo "::: ${opt1a} option selected."
+ useUpdateVars=true
+ ;;
+ ${opt2a})
+ echo "::: ${opt2a} option selected"
+ useUpdateVars=false
+ ;;
+ esac
+ else
+ echo "::: Cancel selected. Exiting..."
+ exit 1
+ fi
}
main() {
# Check arguments for the undocumented flags
- for var in "$@"; do
- case "$var" in
- "--reconfigure" ) reconfigure=true;;
- "--i_do_not_follow_recommendations" ) skipSpaceCheck=false;;
- "--unattended" ) runUnattended=true;;
- esac
- done
+ for var in "$@"; do
+ case "$var" in
+ "--reconfigure" ) reconfigure=true;;
+ "--i_do_not_follow_recommendations" ) skipSpaceCheck=false;;
+ "--unattended" ) runUnattended=true;;
+ esac
+ done
- if [[ -f ${setupVars} ]]; then
- if [[ "${runUnattended}" == true ]]; then
- echo "::: --unattended passed to install script, no whiptail dialogs will be displayed"
- useUpdateVars=true
- else
- update_dialogs
- fi
- fi
+ if [[ -f ${setupVars} ]]; then
+ if [[ "${runUnattended}" == true ]]; then
+ echo "::: --unattended passed to install script, no whiptail dialogs will be displayed"
+ useUpdateVars=true
+ else
+ update_dialogs
+ fi
+ fi
- # Start the installer
- # Verify there is enough disk space for the install
- if [[ "${skipSpaceCheck}" == true ]]; then
- echo "::: --i_do_not_follow_recommendations passed to script, skipping free disk space verification!"
- else
- verifyFreeDiskSpace
- fi
+ # Start the installer
+ # Verify there is enough disk space for the install
+ if [[ "${skipSpaceCheck}" == true ]]; then
+ echo "::: --i_do_not_follow_recommendations passed to script, skipping free disk space verification!"
+ else
+ verifyFreeDiskSpace
+ fi
- # Update package cache
- update_pacakge_cache
+ # Update package cache
+ update_pacakge_cache
- # Notify user of package availability
- notify_package_updates_available
+ # Notify user of package availability
+ notify_package_updates_available
- # Install packages used by this installation script
- install_dependent_packages INSTALLER_DEPS[@]
+ # Install packages used by this installation script
+ install_dependent_packages INSTALLER_DEPS[@]
- if [[ "${reconfigure}" == true ]]; then
- echo "::: --reconfigure passed to install script. Not downloading/updating local repos"
- else
- # Get Git files for Core and Admin
- getGitFiles ${PI_HOLE_LOCAL_REPO} ${piholeGitUrl}
- getGitFiles ${webInterfaceDir} ${webInterfaceGitUrl}
- fi
+ if [[ "${reconfigure}" == true ]]; then
+ echo "::: --reconfigure passed to install script. Not downloading/updating local repos"
+ else
+ # Get Git files for Core and Admin
+ getGitFiles ${PI_HOLE_LOCAL_REPO} ${piholeGitUrl}
+ getGitFiles ${webInterfaceDir} ${webInterfaceGitUrl}
+ fi
- if [[ ${useUpdateVars} == false ]]; then
- # Display welcome dialogs
- welcomeDialogs
- # Create directory for Pi-hole storage
- mkdir -p /etc/pihole/
- # Remove legacy scripts from previous storage location
- remove_legacy_scripts
- # Stop resolver and webserver while installing proceses
- stop_service dnsmasq
- stop_service lighttpd
- # Determine available interfaces
- get_available_interfaces
- # Find interfaces and let the user choose one
- chooseInterface
- # Let the user decide if they want to block ads over IPv4 and/or IPv6
- use4andor6
- # Decide what upstream DNS Servers to use
- setDNS
- # Let the user decide if they want query logging enabled...
- setLogging
+ if [[ ${useUpdateVars} == false ]]; then
+ # Display welcome dialogs
+ welcomeDialogs
+ # Create directory for Pi-hole storage
+ mkdir -p /etc/pihole/
+ # Remove legacy scripts from previous storage location
+ remove_legacy_scripts
+ # Stop resolver and webserver while installing proceses
+ stop_service dnsmasq
+ stop_service lighttpd
+ # Determine available interfaces
+ get_available_interfaces
+ # Find interfaces and let the user choose one
+ chooseInterface
+ # Let the user decide if they want to block ads over IPv4 and/or IPv6
+ use4andor6
+ # Decide what upstream DNS Servers to use
+ setDNS
+ # Let the user decide if they want query logging enabled...
+ setLogging
- # Install packages used by the Pi-hole
- install_dependent_packages PIHOLE_DEPS[@]
+ # Install packages used by the Pi-hole
+ install_dependent_packages PIHOLE_DEPS[@]
- # Install and log everything to a file
+ # Install and log everything to a file
installPihole | tee ${tmpLog}
- else
- # update packages used by the Pi-hole
- install_dependent_packages PIHOLE_DEPS[@]
+ else
+ # update packages used by the Pi-hole
+ install_dependent_packages PIHOLE_DEPS[@]
- updatePihole | tee ${tmpLog}
- fi
+ updatePihole | tee ${tmpLog}
+ fi
- # Move the log file into /etc/pihole for storage
- mv ${tmpLog} ${instalLogLoc}
+ # Move the log file into /etc/pihole for storage
+ mv ${tmpLog} ${instalLogLoc}
- # Add password to web UI if there is none
- pw=""
- if [[ $(grep 'WEBPASSWORD' -c /etc/pihole/setupVars.conf) == 0 ]] ; then
- pw=$(tr -dc _A-Z-a-z-0-9 < /dev/urandom | head -c 8)
- pihole -a -p ${pw}
- fi
+ # Add password to web UI if there is none
+ pw=""
+ if [[ $(grep 'WEBPASSWORD' -c /etc/pihole/setupVars.conf) == 0 ]] ; then
+ pw=$(tr -dc _A-Z-a-z-0-9 < /dev/urandom | head -c 8)
+ pihole -a -p ${pw}
+ fi
- if [[ "${useUpdateVars}" == false ]]; then
- displayFinalMessage ${pw}
- fi
+ if [[ "${useUpdateVars}" == false ]]; then
+ displayFinalMessage ${pw}
+ fi
- echo "::: Restarting services..."
- # Start services
- start_service dnsmasq
- enable_service dnsmasq
- start_service lighttpd
- enable_service lighttpd
- echo "::: done."
+ echo "::: Restarting services..."
+ # Start services
+ start_service dnsmasq
+ enable_service dnsmasq
+ start_service lighttpd
+ enable_service lighttpd
+ echo "::: done."
- echo ":::"
- if [[ "${useUpdateVars}" == false ]]; then
- echo "::: Installation Complete! Configure your devices to use the Pi-hole as their DNS server using:"
- echo "::: ${IPV4_ADDRESS%/*}"
- echo "::: ${IPV6_ADDRESS}"
- echo ":::"
- echo "::: If you set a new IP address, you should restart the Pi."
+ echo ":::"
+ if [[ "${useUpdateVars}" == false ]]; then
+ echo "::: Installation Complete! Configure your devices to use the Pi-hole as their DNS server using:"
+ echo "::: ${IPV4_ADDRESS%/*}"
+ echo "::: ${IPV6_ADDRESS}"
+ echo ":::"
+ echo "::: If you set a new IP address, you should restart the Pi."
echo "::: View the web interface at http://pi.hole/admin or http://${IPV4_ADDRESS%/*}/admin"
- else
- echo "::: Update complete!"
- fi
+ else
+ echo "::: Update complete!"
+ fi
- if (( ${#pw} > 0 )) ; then
- echo ":::"
- echo "::: Note: As security measure a password has been installed for your web interface"
- echo "::: The currently set password is"
- echo "::: ${pw}"
- echo ":::"
- echo "::: You can always change it using"
- echo "::: pihole -a -p new_password"
- fi
+ if (( ${#pw} > 0 )) ; then
+ echo ":::"
+ echo "::: Note: As security measure a password has been installed for your web interface"
+ echo "::: The currently set password is"
+ echo "::: ${pw}"
+ echo ":::"
+ echo "::: You can always change it using"
+ echo "::: pihole -a -p new_password"
+ fi
- echo ":::"
- echo "::: The install log is located at: /etc/pihole/install.log"
+ echo ":::"
+ echo "::: The install log is located at: /etc/pihole/install.log"
}
if [[ "${PH_TEST}" != true ]] ; then
- main "$@"
+ main "$@"
fi
From 8117ec8e20fe7253009b87922cdbc9d9e50a5ddc Mon Sep 17 00:00:00 2001
From: Dan Schaper
Date: Tue, 20 Dec 2016 17:50:44 -0800
Subject: [PATCH 226/228] Remove v1 legacy detection code.
Signed-off-by: Dan Schaper
---
automated install/basic-install.sh | 18 ++++--------------
1 file changed, 4 insertions(+), 14 deletions(-)
diff --git a/automated install/basic-install.sh b/automated install/basic-install.sh
index a04cac3f..77d28651 100755
--- a/automated install/basic-install.sh
+++ b/automated install/basic-install.sh
@@ -62,7 +62,7 @@ else
echo ":::"
echo "::: Detecting the presence of the sudo utility for continuation of this install..."
- if [ -x "$(command -v sudo)" ]; then
+ if command -v sudo; then
echo "::: Utility sudo located."
exec curl -sSL https://install.pi-hole.net | sudo bash "$@"
exit $?
@@ -74,7 +74,7 @@ fi
# Compatibility
-if [[ $(command -v apt-get) ]]; then
+if command -v apt-get; then
#Debian Family
#############################################
PKG_MANAGER="apt-get"
@@ -101,9 +101,9 @@ if [[ $(command -v apt-get) ]]; then
package_check_install() {
dpkg-query -W -f='${Status}' "${1}" 2>/dev/null | grep -c "ok installed" || ${PKG_INSTALL} "${1}"
}
-elif [ $(command -v rpm) ]; then
+elif command -v rpm; then
# Fedora Family
- if [ $(command -v dnf) ]; then
+ if command -v dnf; then
PKG_MANAGER="dnf"
else
PKG_MANAGER="yum"
@@ -623,16 +623,6 @@ version_check_dnsmasq() {
fi
}
-remove_legacy_scripts() {
- #Tidy up /usr/local/bin directory if installing over previous install.
- oldFiles=( gravity chronometer whitelist blacklist piholeLogFlush updateDashboard uninstall setupLCD piholeDebug)
- for i in "${oldFiles[@]}"; do
- if [ -f "/usr/local/bin/$i.sh" ]; then
- rm /usr/local/bin/"$i".sh
- fi
- done
-}
-
clean_existing() {
# Clean an exiting installation to prepare for upgrade/reinstall
# ${1} Directory to clean; ${2} Array of files to remove
From 58261098fbb2847eb7e08f4610c998e165b4e9f1 Mon Sep 17 00:00:00 2001
From: DL6ER
Date: Wed, 21 Dec 2016 12:07:44 +0100
Subject: [PATCH 227/228] We should not call a function that Dan deleted
---
automated install/basic-install.sh | 2 --
1 file changed, 2 deletions(-)
diff --git a/automated install/basic-install.sh b/automated install/basic-install.sh
index 0c47aacd..cddc4dbf 100755
--- a/automated install/basic-install.sh
+++ b/automated install/basic-install.sh
@@ -1059,8 +1059,6 @@ main() {
welcomeDialogs
# Create directory for Pi-hole storage
mkdir -p /etc/pihole/
- # Remove legacy scripts from previous storage location
- remove_legacy_scripts
# Stop resolver and webserver while installing proceses
stop_service dnsmasq
stop_service lighttpd
From 8841bdd2523be3774b245064173979c12d436df7 Mon Sep 17 00:00:00 2001
From: DL6ER
Date: Wed, 21 Dec 2016 12:57:02 +0100
Subject: [PATCH 228/228] Reset the if's
---
automated install/basic-install.sh | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/automated install/basic-install.sh b/automated install/basic-install.sh
index cddc4dbf..fb8570e0 100755
--- a/automated install/basic-install.sh
+++ b/automated install/basic-install.sh
@@ -62,7 +62,7 @@ else
echo ":::"
echo "::: Detecting the presence of the sudo utility for continuation of this install..."
- if command -v sudo; then
+ if [ -x "$(command -v sudo)" ]; then
echo "::: Utility sudo located."
exec curl -sSL https://install.pi-hole.net | sudo bash "$@"
exit $?
@@ -74,7 +74,7 @@ fi
# Compatibility
-if command -v apt-get; then
+if [[ $(command -v apt-get) ]]; then
#Debian Family
#############################################
PKG_MANAGER="apt-get"
@@ -101,9 +101,9 @@ if command -v apt-get; then
package_check_install() {
dpkg-query -W -f='${Status}' "${1}" 2>/dev/null | grep -c "ok installed" || ${PKG_INSTALL} "${1}"
}
-elif command -v rpm; then
+elif [ $(command -v rpm) ]; then
# Fedora Family
- if command -v dnf; then
+ if [ $(command -v dnf) ]; then
PKG_MANAGER="dnf"
else
PKG_MANAGER="yum"