Compare commits

...

257 Commits

Author SHA1 Message Date
Adam Warner
21026d9414 Fix odd behaviour introduced into new version checking script (#5016) 2022-11-14 22:21:16 +00:00
Adam Warner
ba74051502 Grab local FTL hash correctly from FTL's own version output, and grab one digit less for remote hashes (also in debug log)
Signed-off-by: Adam Warner <me@adamwarner.co.uk>
2022-11-14 22:09:26 +00:00
Adam Warner
cdbe4c9b86 Get only the precise tag number when getting local version, do not show branch name when on master branch(es)
Signed-off-by: Adam Warner <me@adamwarner.co.uk>
2022-11-14 20:39:34 +00:00
Adam Warner
ca04c13315 sync: master to development (#5013) 2022-11-14 19:03:11 +00:00
Adam Warner
3c86af0e59 Pi-hole core v5.14 (#5012) 2022-11-14 19:00:40 +00:00
Adam Warner
ddaa1bf0d4 Correctly identify process status in debug script on docker (#5011) 2022-11-14 18:15:57 +00:00
Adam Warner
6b8ba3c15e Replace deprecated shell commands (#4907) 2022-11-14 17:52:31 +00:00
Christian König
7536c312ee Correctly identify process status in debug script on docker
Signed-off-by: Christian König <ckoenig@posteo.de>
2022-11-13 21:53:59 +01:00
Adam Warner
a8b6eb9b70 Touch files before addKey or addOrEditKeyValPair (#4999) 2022-11-09 23:37:30 +00:00
Christian König
67385b7ed4 Touch files before addKey or addOrEditKeyValPair
Signed-off-by: Christian König <ckoenig@posteo.de>
2022-11-09 21:25:09 +01:00
Adam Warner
64e61aac4a Simplify versions.sh (#4959) 2022-11-09 17:15:51 +00:00
Christian König
2fd5b944ad Touch setupVars before writing to it
Signed-off-by: Christian König <ckoenig@posteo.de>
2022-11-03 22:09:12 +01:00
Dan Schaper
f91606bb17 Fix static IP not set because of in-line comment in dhcpcd.conf (#4998) 2022-11-02 15:17:36 -07:00
Stephan Pillhofer
122bc6b927 Fix static IP not set because of in-line comment
Signed-off-by: Stephan Pillhofer <43667664+StephanPillhofer@users.noreply.github.com>
2022-11-02 22:35:39 +01:00
Dan Schaper
3491dbfd04 Check versions file on the debug log (#4977) 2022-10-31 13:25:15 -07:00
Dan Schaper
871067acd8 Fix static IP not set if IP is already present in any way inside dhcpcd.conf (#4995)
Use grep and regex to find uncommented use of `static ip_address` with IP.
2022-10-31 13:23:35 -07:00
Stephan Pillhofer
06cf7afbc2 Fix static IP not set
Signed-off-by: Stephan Pillhofer <43667664+StephanPillhofer@users.noreply.github.com>
2022-10-30 20:19:38 +01:00
yubiuser
01bf9ca42a Prevent CNAME loop (#4988) 2022-10-29 15:44:03 +02:00
Christian König
c8c6533440 Add small explanation.
Signed-off-by: Christian König <ckoenig@posteo.de>
2022-10-29 15:09:14 +02:00
Dan Schaper
f1b15f7e92 Remove check for latest component version in debug log (#4973) 2022-10-28 17:27:05 -07:00
DL6ER
e0c351f0e4 Remove unused possibility to obfuscate pihole.log in debug log (#4974) 2022-10-28 13:16:30 -04:00
DL6ER
7957acf42f Remove unused old code from gravity.sh (#4985) 2022-10-28 13:15:02 -04:00
Dan Schaper
c3e8d76d63 Escape dots in local DNS records/CNAMES before removing them (#4990) 2022-10-24 13:21:07 -07:00
Christian König
128a3ab1be Go POSIX
Signed-off-by: Christian König <ckoenig@posteo.de>
2022-10-22 22:39:42 +02:00
Christian König
df3e9e5f51 Disable shellcheck as it suggests a bashism
Signed-off-by: Christian König <ckoenig@posteo.de>
2022-10-22 22:25:40 +02:00
Christian König
c322458dcb Escape dots in local DNS records/CNAMES before removing them
Signed-off-by: Christian König <ckoenig@posteo.de>
2022-10-21 13:02:21 +02:00
Christian König
21be1bd58e Prevent CNAME loop
Signed-off-by: Christian König <ckoenig@posteo.de>
2022-10-20 07:29:14 +02:00
Adam Warner
469a267150 Adding CentOS Stream 9 tests (#4984) 2022-10-19 19:14:00 +01:00
RD WebDesign
090727b1d3 Remove unnecessary return
Signed-off-by: RD WebDesign <github@rdwebdesign.com.br>
2022-10-17 15:24:49 -03:00
RD WebDesign
85ffbcf05e Allow replacing conflicting existing packages from testing image
Signed-off-by: RD WebDesign <github@rdwebdesign.com.br>
2022-10-17 14:58:42 -03:00
RD WebDesign
528abc9c97 Adding CentOS Stream 9 tests
Signed-off-by: RD WebDesign <github@rdwebdesign.com.br>
2022-10-16 19:36:56 -03:00
RD WebDesign
8b98fd06ed Remove unused old code
Signed-off-by: RD WebDesign <github@rdwebdesign.com.br>
2022-10-16 15:54:24 -03:00
Adam Warner
bc6fb0c934 sync: master to development (#4981) 2022-10-15 15:46:53 +01:00
Adam Warner
e773e3302c Bump actions/setup-python from 4.2.0 to 4.3.0 (#4980) 2022-10-15 15:45:44 +01:00
Adam Warner
0cf59cf0fa Bump actions/setup-python from 4.2.0 to 4.3.0
Bumps [actions/setup-python](https://github.com/actions/setup-python) from 4.2.0 to 4.3.0.
- [Release notes](https://github.com/actions/setup-python/releases)
- [Commits](actions/setup-python@v4.2.0...v4.3.0)

---
updated-dependencies:
- dependency-name: actions/setup-python
  dependency-type: direct:production
  update-type: version-update:semver-minor
...


Signed-off-by: Adam Warner <me@adamwarner.co.uk>
2022-10-15 15:36:20 +01:00
Adam Warner
bc471cb0bd Fix errors in README.md (#4818) 2022-10-15 15:06:06 +01:00
Adam Warner
429510e168 Update README.md
Signed-off-by: Adam Warner <github@adamwarner.co.uk>
2022-10-15 15:03:35 +01:00
Christian König
4c9401175c Remove check for latest version
Signed-off-by: Christian König <ckoenig@posteo.de>
2022-10-15 09:06:57 +02:00
Christian König
235673dac8 Remove unused possibility to obfuscate pihole.log
Signed-off-by: Christian König <ckoenig@posteo.de>
2022-10-15 08:58:12 +02:00
RD WebDesign
d737948f64 Add versions file to the REQUIRED_FILES list
Signed-off-by: RD WebDesign <github@rdwebdesign.com.br>
2022-10-14 14:11:19 -03:00
Christian König
52283478c8 Run pihole updatechecker if versions file is not found
Signed-off-by: Christian König <ckoenig@posteo.de>
2022-10-14 13:26:06 +02:00
Christian König
c84be5de61 Reorganize by component rather then source
Signed-off-by: Christian König <ckoenig@posteo.de>
2022-10-14 13:18:12 +02:00
Christian König
d85982dc51 Use versions file instead of github api to get latest version
Signed-off-by: Christian König <ckoenig@posteo.de>
2022-10-14 10:29:14 +02:00
Christian König
5c61f6cb65 Remove checkout hint
Signed-off-by: Christian König <ckoenig@posteo.de>
2022-10-14 08:43:39 +02:00
Christian König
4c0a94d2b9 Don't rely on pihole -v output but query github to get the lastest versions in debug script
Signed-off-by: Christian König <ckoenig@posteo.de>
2022-10-13 14:44:13 +02:00
MichaIng
5c090d25e1 Fix ldd sh mock in tests
Since "command" is a shell internal, it cannot be mocked, done via /usr/local/bin override. Since Debian containers ship without /bin => /usr/bin symlink, while all other containers do, the "ldd" mock needs to be applied for both paths, then.

Signed-off-by: MichaIng <micha@dietpi.com>
2022-10-12 12:49:50 +02:00
Adam Warner
89c0706abc master -> dev (#4970) 2022-10-12 11:32:30 +01:00
a1346054
e5695f862f test_any_automated_install.py: Use command -v instead of which
Signed-off-by: a1346054 <36859588+a1346054@users.noreply.github.com>
2022-10-11 14:36:26 +00:00
a1346054
e3db5fc601 basic-install.sh: Use command -v instead of which
`command -v` is the standardized version of `which` and doesn't require
any extra packages

Signed-off-by: a1346054 <36859588+a1346054@users.noreply.github.com>
2022-10-11 14:33:30 +00:00
a1346054
9c51050283 basic-install.sh: Use grep -E instead of egrep
Signed-off-by: a1346054 <36859588+a1346054@users.noreply.github.com>
2022-10-11 14:33:30 +00:00
Adam Warner
17779bad94 Pi-hole v5.13 (#4960) 2022-10-10 22:00:47 +01:00
Dan Schaper
fed58f03bf Fix pihole -r dialog exit (#4965) 2022-10-09 21:10:23 -07:00
RD WebDesign
c5b3b8dd68 Fix pihole -r dialog exit
- if an option is selected: Get option (repair/reconfigure);
- if exit or ESC: Get exit code (1/255)

Signed-off-by: RD WebDesign <github@rdwebdesign.com.br>
2022-10-10 00:27:03 -03:00
Adam Warner
46986714d4 Bump actions/stale from 6.0.0 to 6.0.1 (#4963) 2022-10-09 20:03:21 +01:00
Adam Warner
4f3debcb5b Bump actions/checkout from 3.0.2 to 3.1.0 (#4964) 2022-10-09 20:03:10 +01:00
dependabot[bot]
223ef72250 Bump actions/checkout from 3.0.2 to 3.1.0
Bumps [actions/checkout](https://github.com/actions/checkout) from 3.0.2 to 3.1.0.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v3.0.2...v3.1.0)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-10-09 18:46:02 +00:00
dependabot[bot]
cf467db61d Bump actions/stale from 6.0.0 to 6.0.1
Bumps [actions/stale](https://github.com/actions/stale) from 6.0.0 to 6.0.1.
- [Release notes](https://github.com/actions/stale/releases)
- [Changelog](https://github.com/actions/stale/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/stale/compare/v6.0.0...v6.0.1)

---
updated-dependencies:
- dependency-name: actions/stale
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-10-09 18:45:54 +00:00
Adam Warner
fae1d13892 Add initscripts to CentOS8 dockerfile (#4966) 2022-10-09 19:45:13 +01:00
Christian König
4265bcb178 Add initscripts to CentOS8 dockerfile
Signed-off-by: Christian König <ckoenig@posteo.de>
2022-10-08 22:08:39 +02:00
Christian König
9471c69882 Fix spelling
Signed-off-by: Christian König <ckoenig@posteo.de>
2022-10-07 09:34:05 +02:00
Christian König
79c0b446e1 Set missing data to N/A
Signed-off-by: Christian König <ckoenig@posteo.de>
2022-10-06 21:55:49 +02:00
Christian König
a478f2460b POSIX
Signed-off-by: Christian König <ckoenig@posteo.de>
2022-10-06 21:50:07 +02:00
Christian König
2dc599f266 Simplify version.sh
Signed-off-by: Christian König <ckoenig@posteo.de>
2022-10-06 17:58:58 +02:00
Christian König
d7f7ef9965 Only create VERSION_FILE if it does not exist
Signed-off-by: Christian König <ckoenig@posteo.de>
2022-10-06 14:37:56 +02:00
Christian König
888e44e53d Add hash functions to updatecheck
Signed-off-by: Christian König <ckoenig@posteo.de>
2022-10-06 14:34:34 +02:00
Christian König
18d28533eb Update local and remote versions at the same time
Signed-off-by: Christian König <ckoenig@posteo.de>
2022-10-06 12:36:17 +02:00
Christian König
56527e5dd9 Add get_remote_version() to updatechecker
Signed-off-by: Christian König <ckoenig@posteo.de>
2022-10-06 12:03:12 +02:00
Adam Warner
997a771dc8 Fix Deepsource.io warning message for index.php file (#4953) 2022-10-01 22:57:32 +01:00
Adam Warner
77f0012f6b Fix default DHCPv4 leasetime value (#4956) 2022-10-01 22:50:39 +01:00
Adam Warner
b7b5ffa8dd remove old code per review from @yubiuser and @dschaper
Signed-off-by: Adam Warner <me@adamwarner.co.uk>
2022-10-01 22:31:03 +01:00
Adam Warner
34b66002e9 leasetime (local) should have an h after it to signify 24h lease, else it will be read as two minutes (minimum integer value)
Signed-off-by: Adam Warner <me@adamwarner.co.uk>
2022-10-01 22:31:00 +01:00
Dan Schaper
71b560667b Add Fedora 35 and 36, remove 34 to/from the test suite (#4952) 2022-10-01 13:43:13 -07:00
Adam Warner
9dd51b79b5 Remove pihole-FTL.port file (#4945) 2022-10-01 14:30:23 +01:00
Adam Warner
7fd062c4d8 Update Amazon support URL to HTTPS in README (#4954) 2022-10-01 14:28:26 +01:00
Christian König
3731b65bd5 Remoce Fedora 34 from tests
Signed-off-by: Christian König <ckoenig@posteo.de>
2022-10-01 10:04:26 +02:00
Christian König
6057b134ae Add initscripts to Fedora 35 and 36 dockerfile
Signed-off-by: Christian König <ckoenig@posteo.de>
2022-10-01 10:03:13 +02:00
David Beitey
0749de3d1f Update Amazon support URL to HTTPS in README
Signed-off-by: David Beitey <david@davidjb.com>
2022-10-01 09:39:04 +10:00
RD WebDesign
d48c557134 Fix Deepsource warning message for index.php file
Signed-off-by: RD WebDesign <github@rdwebdesign.com.br>
2022-09-30 17:13:08 -03:00
Christian König
a705fbca73 Add Fedora 35 and 36 to the test suite
Signed-off-by: Christian König <ckoenig@posteo.de>
2022-09-29 19:13:23 +02:00
Christian König
276c480f50 Return default port if non-numeric characters are set in pihole-FTL.conf for FTLPORT. FTL does the same in such case and provide the API on 4711
Signed-off-by: Christian König <ckoenig@posteo.de>
2022-09-26 23:40:09 +02:00
Christian König
25ba68104b Remove last traces
Signed-off-by: Christian König <ckoenig@posteo.de>
2022-09-26 22:55:34 +02:00
Christian König
3d01e4d0cf No detour - use pihole-FTL.conf to get the API port number
Signed-off-by: Christian König <ckoenig@posteo.de>
2022-09-26 22:55:30 +02:00
Adam Warner
1b0b0ca445 Update python tests and add black code formatter action (#4926) 2022-09-26 20:00:27 +01:00
Christian König
e1a2591c4d Format test.yml
Signed-off-by: Christian König <ckoenig@posteo.de>
2022-09-26 10:40:39 +02:00
Dan Schaper
f8a12917e2 Handle more than one default gateway in debug script (#4934) 2022-09-25 11:09:26 -07:00
Dan Schaper
37b45d411d Read docker tag from file in root, not the previously set environment variable (#4929) 2022-09-25 11:05:08 -07:00
Christian König
22ebf21487 Use POSIX
Signed-off-by: Christian König <ckoenig@posteo.de>
2022-09-25 18:20:01 +02:00
Christian König
bf5fffaca7 Better wording and test with color
Signed-off-by: Christian König <ckoenig@posteo.de>
2022-09-25 18:03:44 +02:00
Adam Warner
9debd22179 If, after reading /pihole.docker.tag into DOCKER_TAG, it does not match an expected pattern, unset it - this should prevent arbitary code from being run
Signed-off-by: Adam Warner <me@adamwarner.co.uk>
2022-09-25 15:51:09 +01:00
Dan Schaper
a8ce1354c8 Set connection timeout for curl (#4884) 2022-09-24 18:19:15 -07:00
Adam Warner
0a780a959a Fix issue in #4872 missed in review (#4940) 2022-09-24 16:18:49 +01:00
Peter Russell
951b4ed002 Remove cronjob that checks local versions every 10 minutes - only check when required (#4939)
* eliminate updatechecker local from pihole cron job

Signed-off-by: jpgpi250 <jpgpi250@gmail.com>

* resolving stickler-ci items

Signed-off-by: jpgpi250 <jpgpi250@gmail.com>

* undo changes to updatecheck.sh (request from PromoFaux)

Signed-off-by: jpgpi250 <jpgpi250@gmail.com>

* applied recommendation from PromoFaux

Signed-off-by: jpgpi250 <jpgpi250@gmail.com>

* Indent the code inside the function

Signed-off-by: jpgpi250 <jpgpi250@gmail.com>

* removed unnecessary updatecheck for core

Signed-off-by: jpgpi250 <jpgpi250@gmail.com>

* eliminate updatechecker local from pihole cron job

Co-authored-by: jpgpi250 <jpgpi250@gmail.com>
Signed-off-by: Adam Warner <me@adamwarner.co.uk>

Signed-off-by: jpgpi250 <jpgpi250@gmail.com>
Signed-off-by: Adam Warner <me@adamwarner.co.uk>
Co-authored-by: Adam Warner <me@adamwarner.co.uk>
2022-09-24 16:14:44 +01:00
Adam Warner
755ec8bf2f $$ != $
Signed-off-by: Adam Warner <me@adamwarner.co.uk>
2022-09-24 16:08:45 +01:00
Adam Warner
1c1407e083 Use utils.sh in install script (#4872) 2022-09-24 14:00:22 +01:00
Adam Warner
9463c3c69f Change wording in chronometer (#4910) 2022-09-24 13:53:08 +01:00
Adam Warner
54bcf5626f Bump actions/stale from 5.2.0 to 6.0.0 (#4938) 2022-09-24 13:07:51 +01:00
dependabot[bot]
ba8a50c829 Bump actions/stale from 5.2.0 to 6.0.0
Bumps [actions/stale](https://github.com/actions/stale) from 5.2.0 to 6.0.0.
- [Release notes](https://github.com/actions/stale/releases)
- [Changelog](https://github.com/actions/stale/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/stale/compare/v5.2.0...v6.0.0)

---
updated-dependencies:
- dependency-name: actions/stale
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-09-24 10:08:26 +00:00
Christian König
bb57a9e616 Handle more than one default gateway in debug script
Signed-off-by: Christian König <ckoenig@posteo.de>
2022-09-22 22:33:11 +02:00
yubiuser
4f4dfe3ac0 Fix tabs in dialog boxes (#4932) 2022-09-22 22:02:45 +02:00
Christian König
d4ce5b1c2a Fix tabs in dialog boxes
Signed-off-by: Christian König <ckoenig@posteo.de>
2022-09-22 14:49:25 +02:00
Adam Warner
b6d1bd7335 Read docker tag from file in root, not the previously set environment variable
Signed-off-by: Adam Warner <me@adamwarner.co.uk>
2022-09-19 22:01:05 +01:00
Christian König
17ec88d96f Remove installed_binary variable which was leftover from https://github.com/pi-hole/pi-hole/pull/4893
Signed-off-by: Christian König <ckoenig@posteo.de>
2022-09-19 14:50:35 +02:00
Christian König
0df38cd64e Format all /test files with black
Signed-off-by: Christian König <ckoenig@posteo.de>
2022-09-19 14:50:35 +02:00
Christian König
0932c5c498 Add black python code formatter action
Signed-off-by: Christian König <ckoenig@posteo.de>
2022-09-19 14:50:35 +02:00
Christian König
73ca4ebdbc Update test requirements
Signed-off-by: Christian König <ckoenig@posteo.de>
2022-09-19 14:50:35 +02:00
Adam Warner
da6596e516 Master -> Dev (#4925) 2022-09-19 11:15:59 +01:00
Adam Warner
d88629e23f v5.12.2 (#4922) 2022-09-19 11:00:09 +01:00
yubiuser
d581401f4e Fix gravity database integrity check (#4921) 2022-09-18 13:35:03 +02:00
Christian König
60c35cb93c Remove unused check_database_integrity()
Signed-off-by: Christian König <ckoenig@posteo.de>
2022-09-18 13:08:44 +02:00
Christian König
2c3fea321b Remove FAQ_ULA as it is unused in core
Signed-off-by: Christian König <ckoenig@posteo.de>
2022-09-18 09:10:24 +02:00
Christian König
40f00c6f0b Fix gravity database integrity check
Signed-off-by: Christian König <ckoenig@posteo.de>
2022-09-18 09:01:22 +02:00
Christian König
00e51f32b5 Blcked => Block
Signed-off-by: Christian König <ckoenig@posteo.de>
2022-09-17 16:46:31 +02:00
Christian König
f90fb8b946 Change wording in chronometer
Signed-off-by: Christian König <ckoenig@posteo.de>
2022-09-17 16:24:31 +02:00
yubiuser
2ff1fa1b85 Merge branch 'development' into use_utils 2022-09-17 16:14:31 +02:00
yubiuser
7eff36b3bb Update workflow python to 3.10 and allow any python3 version in tests (#4914) 2022-09-17 16:13:48 +02:00
yubiuser
5332b31b92 Add comment in lighttpd.conf how to change the server port (#4917) 2022-09-17 14:05:13 +02:00
yubiuser
16640ee174 Bump actions/stale from 5.1.1 to 5.2.0 (#4918) 2022-09-17 14:04:25 +02:00
dependabot[bot]
5fe170666a Bump actions/stale from 5.1.1 to 5.2.0
Bumps [actions/stale](https://github.com/actions/stale) from 5.1.1 to 5.2.0.
- [Release notes](https://github.com/actions/stale/releases)
- [Changelog](https://github.com/actions/stale/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/stale/compare/v5.1.1...v5.2.0)

---
updated-dependencies:
- dependency-name: actions/stale
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-09-17 10:08:40 +00:00
Christian König
7e6f81f814 Add comment in lighttpd.conf how to change the server port
Signed-off-by: Christian König <ckoenig@posteo.de>
2022-09-17 12:00:33 +02:00
yubiuser
80c770357c Fixing texts forgotten after Blocking Page removal (#4915) 2022-09-16 08:25:15 +02:00
RD WebDesign
5cc317de5b Change texts after Block Page removal
Signed-off-by: RD WebDesign <github@rdwebdesign.com.br>
2022-09-16 03:16:54 -03:00
Adam Warner
515e5f8c8a Store docker version in versions file (If PIHOLE_DOCKER_TAG variable is set) (#4913) 2022-09-15 18:05:42 +01:00
Adam Warner
3d53bda121 Update advanced/Scripts/updatecheck.sh
Co-authored-by: yubiuser <ckoenig@posteo.de>
Signed-off-by: Adam Warner <github@adamwarner.co.uk>
2022-09-15 17:54:54 +01:00
Christian König
8bc5b16527 Set tox envlist to py3
Signed-off-by: Christian König <ckoenig@posteo.de>
2022-09-15 13:55:45 +02:00
Christian König
c1a927fff1 Run test workflows on python 3.10
Signed-off-by: Christian König <ckoenig@posteo.de>
2022-09-15 13:55:45 +02:00
Adam Warner
760325eb76 Update piholeDebug to source versions file for DOCKER_VERSION instead of reading PIHOLE_DOCKER_TAG
Signed-off-by: Adam Warner <me@adamwarner.co.uk>
2022-09-14 22:49:37 +01:00
Adam Warner
bf256aa5a7 If docker version env var is set, store it in /etc/pihole/versions file for later use
Signed-off-by: Adam Warner <me@adamwarner.co.uk>
2022-09-14 22:38:41 +01:00
Adam Warner
8dbe6fc0b7 master-> Dev (#4912) 2022-09-14 22:08:15 +01:00
Adam Warner
fe8b0e98ab v5.12.1 (#4908) 2022-09-14 21:28:44 +01:00
yubiuser
ef45578af3 Fix 4898 (#4899) 2022-09-06 19:43:24 +02:00
Christian König
89b88416b3 Fix 4898
Signed-off-by: Christian König <ckoenig@posteo.de>
2022-09-06 17:09:52 +02:00
Adam Warner
5d913ad192 Release 5.12 (#4889) (#4897) 2022-09-05 08:48:37 +01:00
yubiuser
711035fd8f Update FTL Binary test to ensure we catch incompatibility issues early (#4893) 2022-09-03 14:44:16 +02:00
Adam Warner
0f74165c9d Drop Ubuntu 18 tests
Tweek version_check to only output 1st char of the reported version

Signed-off-by: Adam Warner <me@adamwarner.co.uk>
2022-09-03 12:55:17 +01:00
Adam Warner
46e1a87e9e Tweak FTL test to ensure we don't get false positives on incompatible OS (Will remote Ub18 in a separate commit)
Signed-off-by: Adam Warner <me@adamwarner.co.uk>
2022-09-03 12:09:37 +01:00
Adam Warner
f998eee467 Release 5.12 (#4889) 2022-09-02 18:39:03 +01:00
Christian König
230d6a435f Semi hardcode the connection_timeout value
Signed-off-by: Christian König <ckoenig@posteo.de>
2022-08-31 21:41:57 +02:00
Christian König
53c0982c8b Set connection timeout for curl
Signed-off-by: Christian König <ckoenig@posteo.de>
2022-08-31 14:43:20 +02:00
yubiuser
d6cfa57ef3 Add jq as dependency and remove json_extract (#4878)
**What does this PR aim to accomplish?:**

Adds `jq` as dependency and removes the now obsolete `json_extract` function.
`jq` is a small dependency and adds powerfull json abilities. With `FTL v6` we will have a whole new json-based API where `jq` might be needed anyway. Also for `PADD` to interact with `FTL v6`, `jq` will be a requirement: https://github.com/pi-hole/PADD/pull/247

---
**By submitting this pull request, I confirm the following:** 

1. I have read and understood the [contributors guide](https://docs.pi-hole.net/guides/github/contributing/), as well as this entire template. I understand which branch to base my commits and Pull Requests against. 
2. I have commented my proposed changes within the code and I have tested my changes.
3. I am willing to help maintain this change if there are issues with it later.
4. It is compatible with the [EUPL 1.2 license](https://opensource.org/licenses/EUPL-1.1)
5. I have squashed any insignificant commits. ([`git rebase`](http://gitready.com/advanced/2009/02/10/squashing-commits-with-rebase.html))

---
- [x] I have read the above and my PR is ready for review. _Check this box to confirm_
2022-08-26 10:09:42 +02:00
Christian König
49b9dc8888 Remove json_extract function
Signed-off-by: Christian König <ckoenig@posteo.de>
2022-08-25 09:55:47 +02:00
Christian König
1335c44deb Add jq to dependencies
Signed-off-by: Christian König <ckoenig@posteo.de>
2022-08-25 09:55:42 +02:00
Christian König
9b5ea13a33 Use utils.sh in install script
Signed-off-by: Christian König <ckoenig@posteo.de>
2022-08-24 08:49:20 +02:00
yubiuser
66eeee5548 Remove the email function (#4870)
- **What does this PR aim to accomplish?:**

We offered to set an administrator email which was shown on the blockpage. With the removal of the blockpage (https://github.com/pi-hole/pi-hole/pull/3910) this function is not needed anymore.

Corresponding web interface PR: https://github.com/pi-hole/AdminLTE/pull/2301
2022-08-24 07:21:04 +02:00
Adam Warner
597c045f9e Merge pull request #4875 from pi-hole/tweak/version-file
Store versions as key/value pairs rather than space delimeted values
2022-08-23 19:23:44 +01:00
Adam Warner
a4b899c256 Review suggestions (and shellcheck complaints)
Signed-off-by: Adam Warner <me@adamwarner.co.uk>
2022-08-23 19:10:12 +01:00
Adam Warner
5421aad03e Store versions as key/value pairs rather than space delimeted values
Signed-off-by: Adam Warner <me@adamwarner.co.uk>
2022-08-22 19:11:27 +01:00
Christian König
eeccfb27f8 Remove it also from index.php together with more unused variables
Signed-off-by: Christian König <ckoenig@posteo.de>
2022-08-20 23:07:38 +02:00
yubiuser
4cf3280500 Merge pull request #4862 from pi-hole/tweak/lighttpd_headers
Add security-related headers to Pi-hole web interface
2022-08-18 13:37:28 +02:00
Christian König
8c4a9aa6e3 Remove the email function
Signed-off-by: Christian König <ckoenig@posteo.de>
2022-08-17 23:14:56 +02:00
Adam Warner
9ab566884d Merge pull request #3910 from pi-hole/removeblockpagefunctionality
Remove the advanced functionality of the 404 page (Blockpage)
2022-08-17 21:22:01 +01:00
yubiuser
37102e5a01 Merge branch 'development' into removeblockpagefunctionality 2022-08-17 21:29:58 +02:00
yubiuser
5a98fa1f76 Merge pull request #4843 from MichaIng/patch-1
Skip web server dialog if --disable-install-webserver has been passed
2022-08-17 21:27:59 +02:00
Adam Warner
114f562758 Merge branch 'development' into removeblockpagefunctionality 2022-08-17 20:25:03 +01:00
MichaIng
b3c8045b52 Skip web server dialog if --disable-install-webserver has been passed
Prior to https://github.com/pi-hole/pi-hole/pull/4772, the web server dialog was skipped if --disable-install-webserver was passed (INSTALL_WEB_SERVER=false). This commit restores this behaviour.

Signed-off-by: MichaIng <micha@dietpi.com>
2022-08-17 20:48:11 +02:00
yubiuser
a0419bc1f0 Merge pull request #4864 from pi-hole/debug_FTL_branch
Extend FTL information in debug log
2022-08-08 21:25:56 +02:00
Adam Warner
e35a9da921 Remove the blockpage-focussed customisations to query.sh
Signed-off-by: Adam Warner <me@adamwarner.co.uk>
2022-08-08 18:57:55 +01:00
Christian König
97447b2f3b Do not remove blockingpage.css from existing installations as some users might use them for custom.php
Signed-off-by: Christian König <ckoenig@posteo.de>
2022-08-08 18:20:49 +01:00
yubiuser
c67f313ee8 Apply reviewers suggestion for inline CSS
Co-authored-by: RD WebDesign <github@rdwebdesign.com.br>
Signed-off-by: yubiuser <ckoenig@posteo.de>
2022-08-08 17:21:29 +01:00
Christian König
49a9f6f2db Reproduce blockpage.css for $splashPage
Signed-off-by: Christian König <ckoenig@posteo.de>
2022-08-08 17:21:29 +01:00
Christian König
e6683803ed Use absolut asset paths
Signed-off-by: Christian König <ckoenig@posteo.de>
2022-08-08 17:21:29 +01:00
Christian König
27fa284eda Fix missing PI_HOLE_BLOCKPAGE_DIR
Signed-off-by: Christian König <ckoenig@posteo.de>
2022-08-08 17:21:29 +01:00
Christian König
b98e331375 Only do one curl call in debug when checking the X-Header
Signed-off-by: Christian König <ckoenig@posteo.de>
2022-08-08 17:20:41 +01:00
Christian König
6c9bd7a632 Remove blockingpage.css
Signed-off-by: Christian König <ckoenig@posteo.de>
2022-08-08 17:20:13 +01:00
Adam Warner
5816f495f4 Fix test_installPiholeWeb_fresh_install_no_errors and test_installPihole_fresh_install_readableBlockpage
Signed-off-by: Adam Warner <me@adamwarner.co.uk>
2022-08-08 17:12:16 +01:00
Adam Warner
5d5a85b7b6 X-Pi-hole removed from blocking page...
Signed-off-by: Adam Warner <me@adamwarner.co.uk>
2022-08-08 17:12:16 +01:00
Adam Warner
c78cf82fc6 no need to declare $viewPort
Signed-off-by: Adam Warner <me@adamwarner.co.uk>
2022-08-08 17:12:09 +01:00
Christian König
d77677312c Extend FTL information in debug log
Signed-off-by: Christian König <ckoenig@posteo.de>
2022-08-08 13:52:20 +02:00
yubiuser
d38fcb0549 Merge pull request #4863 from pi-hole/fix/git_indention
Fix git indention
2022-08-07 20:25:42 +02:00
Christian König
c7410b0be9 Always indent
Signed-off-by: Christian König <ckoenig@posteo.de>
2022-08-07 15:50:05 +02:00
Dan Schaper
20c561c83c Merge pull request #4857 from pi-hole/4856-init-script-ftl
Exit init script with error result code if FTL fails to start
2022-08-06 13:15:10 -07:00
Christian König
7320c10dd3 Fix git indention
Signed-off-by: Christian König <ckoenig@posteo.de>
2022-08-06 21:44:19 +02:00
DL6ER
f418481b9f Add security-related headers to Pi-hole web interface
Signed-off-by: DL6ER <dl6er@dl6er.de>
2022-08-06 15:35:01 +02:00
Adam Warner
a3516474e8 Merge pull request #4859 from pi-hole/dependabot/github_actions/development/actions-ecosystem/action-add-labels-1.1.3
Bump actions-ecosystem/action-add-labels from 1.1.0 to 1.1.3
2022-08-06 11:23:15 +01:00
dependabot[bot]
9e2e0019fb Bump actions-ecosystem/action-add-labels from 1.1.0 to 1.1.3
Bumps [actions-ecosystem/action-add-labels](https://github.com/actions-ecosystem/action-add-labels) from 1.1.0 to 1.1.3.
- [Release notes](https://github.com/actions-ecosystem/action-add-labels/releases)
- [Commits](https://github.com/actions-ecosystem/action-add-labels/compare/v1.1.0...v1.1.3)

---
updated-dependencies:
- dependency-name: actions-ecosystem/action-add-labels
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-08-06 10:22:39 +00:00
Adam Warner
aef3d89814 Merge pull request #4860 from pi-hole/dependabot/github_actions/development/actions/stale-5.1.1
Bump actions/stale from 5.1.0 to 5.1.1
2022-08-06 11:20:38 +01:00
Adam Warner
f2641fb0e5 Merge pull request #4861 from pi-hole/dependabot/github_actions/development/actions/setup-python-4.2.0
Bump actions/setup-python from 4.1.0 to 4.2.0
2022-08-06 11:20:21 +01:00
dependabot[bot]
e50438dc11 Bump actions/setup-python from 4.1.0 to 4.2.0
Bumps [actions/setup-python](https://github.com/actions/setup-python) from 4.1.0 to 4.2.0.
- [Release notes](https://github.com/actions/setup-python/releases)
- [Commits](https://github.com/actions/setup-python/compare/v4.1.0...v4.2.0)

---
updated-dependencies:
- dependency-name: actions/setup-python
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-08-06 10:07:31 +00:00
dependabot[bot]
6062df0923 Bump actions/stale from 5.1.0 to 5.1.1
Bumps [actions/stale](https://github.com/actions/stale) from 5.1.0 to 5.1.1.
- [Release notes](https://github.com/actions/stale/releases)
- [Changelog](https://github.com/actions/stale/blob/v5.1.1/CHANGELOG.md)
- [Commits](https://github.com/actions/stale/compare/v5.1.0...v5.1.1)

---
updated-dependencies:
- dependency-name: actions/stale
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-08-06 10:07:28 +00:00
Dan Schaper
989c52ef24 Exit with return code if ftl does not start
Signed-off-by: Dan Schaper <dan.schaper@pi-hole.net>
2022-08-04 17:20:39 -07:00
yubiuser
4a589286b7 Merge pull request #4855 from pi-hole/fix/dir_not_exist
Ensure user defined FTL_PID_FILE and FTL_PORT_FILE dirs are created on startup
2022-08-04 22:27:08 +02:00
Christian König
3327df8d9c Ensure user defined FTL_PID_FILE and FTL_PORT_FILE dirs are created on startup
Signed-off-by: Christian König <ckoenig@posteo.de>
2022-08-04 14:47:43 +02:00
yubiuser
3cdaad060b Merge pull request #4851 from pi-hole/keywords
Dont use bash keywords/programs as variable names
2022-08-01 22:07:21 +02:00
Adam Warner
0b81dd387b type -> list_type per @yubiuser suggestion
Signed-off-by: Adam Warner <me@adamwarner.co.uk>
2022-08-01 20:56:37 +01:00
Adam Warner
64dc002c3f Same per @rdwebdesign suggestion.
Signed-off-by: Adam Warner <me@adamwarner.co.uk>
2022-08-01 20:38:31 +01:00
Adam Warner
6c7a28a7b5 Dont use bash keywords/programs as variable names 2022-08-01 18:38:15 +01:00
Adam Warner
21158cb6bc Merge pull request #4833 from pi-hole/workflow_versions
Explicit set minor and patch version on used actions
2022-08-01 17:20:05 +01:00
Adam Warner
71bc237639 Merge pull request #4828 from pi-hole/centos7-can-do-one
Drop explicit support for CentOS 7 from the install script
2022-07-31 19:15:41 +01:00
Adam Warner
c6da627b7d Move release version check inside the else block
Signed-off-by: Adam Warner <me@adamwarner.co.uk>
2022-07-31 18:55:05 +01:00
Christian König
a3ac1caac6 Update actions to latest versions
Signed-off-by: Christian König <ckoenig@posteo.de>
2022-07-31 09:46:51 +02:00
Christian König
8f3e6f1a50 CodeQl does not use .minor.patch version
Signed-off-by: Christian König <ckoenig@posteo.de>
2022-07-31 09:46:50 +02:00
Christian König
99b7f996e2 Explicite set minor and patch version on used actions
Signed-off-by: Christian König <ckoenig@posteo.de>
2022-07-31 09:46:47 +02:00
yubiuser
aa0a9e2976 Merge pull request #4839 from pi-hole/move_getFTLPIDFile
Move FTL port and PID functions to utils.sh
2022-07-30 21:01:21 +02:00
Adam Warner
9028898ba7 Move code from check_epel_repo_required into the rpm branch of the if check on package_manager_detect(), adjust tests to accommodate
Signed-off-by: Adam Warner <me@adamwarner.co.uk>
2022-07-30 19:27:00 +01:00
Adam Warner
0e8c1ec023 Flip logic on epel check - if _not_ fedora, then (try to, depending on supported OS) install EPEL.
Signed-off-by: Adam Warner <me@adamwarner.co.uk>
2022-07-30 19:03:46 +01:00
Adam Warner
313c0ddf28 Update automated install/basic-install.sh
Co-authored-by: yubiuser <ckoenig@posteo.de>
Signed-off-by: Adam Warner <github@adamwarner.co.uk>
2022-07-30 18:59:57 +01:00
yubiuser
2c38de26b7 Merge pull request #4847 from pi-hole/remove/unused_files
Remove unused and outdated files and scripts
2022-07-30 18:34:58 +02:00
Adam Warner
fc2a564cc0 remove tests no longer needed
Signed-off-by: Adam Warner <me@adamwarner.co.uk>
2022-07-30 16:27:31 +01:00
Adam Warner
b613758419 rename select_rpm_php and simplify it to remove code no longer needed (discussed internally removing the unsupported dialog here to match behaviour on non rpm distros)
Signed-off-by: Adam Warner <me@adamwarner.co.uk>
2022-07-30 16:27:31 +01:00
Adam Warner
9c03915cb0 Remove special Centos7 hand holds. Move the unsupported dialog out to a further if block so that a user may still continue to install on centos7 (provided they have the pre-requisites installed)
Signed-off-by: Adam Warner <me@adamwarner.co.uk>
2022-07-30 16:27:31 +01:00
Adam Warner
e29aa4e205 First things first... 2022-07-30 16:27:29 +01:00
yubiuser
a45c9f9f50 Merge pull request #4848 from pi-hole/indent_update
Indent installation/update complete message
2022-07-30 07:41:04 +02:00
yubiuser
b3ba17bfd4 Merge pull request #4846 from pi-hole/uninstall
Add OS_CHECK_DEPS to uninstall script
2022-07-29 23:43:37 +02:00
Christian König
2610739624 Indent installation/update complete message
Signed-off-by: Christian König <ckoenig@posteo.de>
2022-07-29 23:43:20 +02:00
Christian König
567a915336 Remove unused and outdated files and scripts
Signed-off-by: Christian König <ckoenig@posteo.de>
2022-07-29 23:21:38 +02:00
Christian König
68eddd2377 Add OS_CHECK_DEPS to uninstall script
Signed-off-by: Christian König <ckoenig@posteo.de>
2022-07-29 22:47:40 +02:00
yubiuser
aeb92416c8 Merge pull request #4832 from pi-hole/fix/msg
Fix spaces in dialog msg
2022-07-26 23:57:50 +02:00
yubiuser
cca5c49eaa Merge pull request #4838 from pi-hole/tweak/readme_logo
Use prefers-color-scheme for theme based logo
2022-07-26 23:44:33 +02:00
Christian König
8c778c14dc Move linebreaks
Signed-off-by: Christian König <ckoenig@posteo.de>
2022-07-26 23:43:49 +02:00
yubiuser
d5c798d1a9 Apply reviewers suggestion
Co-authored-by: RD WebDesign <github@rdwebdesign.com.br>
Signed-off-by: yubiuser <ckoenig@posteo.de>
Signed-off-by: Christian König <ckoenig@posteo.de>
2022-07-26 23:39:02 +02:00
Christian König
14e1eea22d Fix spaces in dialog msg
Signed-off-by: Christian König <ckoenig@posteo.de>
2022-07-26 23:39:02 +02:00
Christian König
ab6b37bdcf Fix stickler and codefactor complaints
Signed-off-by: Christian König <ckoenig@posteo.de>
2022-07-26 19:33:38 +02:00
Christian König
c8c4eb59b7 Add getFTLPID() tests
Signed-off-by: Christian König <ckoenig@posteo.de>
2022-07-26 17:34:42 +02:00
Christian König
2651abbe6c Add tests
Signed-off-by: Christian König <ckoenig@posteo.de>
2022-07-26 16:57:06 +02:00
Christian König
7b77d991df Move FTL port and PID functions to utils.sh
Signed-off-by: Christian König <ckoenig@posteo.de>
2022-07-26 14:38:03 +02:00
Christian König
64465510de prefers-color-scheme for logo
Signed-off-by: Christian König <ckoenig@posteo.de>
2022-07-26 13:33:00 +02:00
yubiuser
f59749b1c3 Merge pull request #4834 from pi-hole/fix/spinner
Only execute spinner function if there is a tty
2022-07-26 09:29:55 +02:00
yubiuser
27ef7e5538 Merge branch 'development' into fix/spinner 2022-07-26 09:21:24 +02:00
Adam Warner
a7a467a167 Merge pull request #4837 from pi-hole/dont-fail-fast
Dont fail fast on tests
2022-07-25 22:44:00 +01:00
Adam Warner
21af75a2d2 Ubuntu 21 tests are failing entirely. apt-update does not work on an impish vm, either
Signed-off-by: Adam Warner <me@adamwarner.co.uk>
2022-07-25 22:27:56 +01:00
Adam Warner
2bd3366bb1 Disable fail fast, allowing tests to run despite failures on a particular distro - it is easier to retry failed tests these day 2022-07-25 21:57:30 +01:00
RD WebDesign
d89720330f Address revision requests:
- replace `local var` with `_var` (POSIX style);
- move inline comments

Signed-off-by: RD WebDesign <github@rdwebdesign.com.br>
2022-07-24 20:15:20 -03:00
RD WebDesign
8d1f286f30 Only execute spinner function if there is a tty
Signed-off-by: RD WebDesign <github@rdwebdesign.com.br>
2022-07-24 17:52:17 -03:00
yubiuser
c7108a632c Merge pull request #4824 from pi-hole/Alam_Rocky
Don't fail if Alma or Rocky are detected
2022-07-16 09:59:22 +02:00
yubiuser
b025cfeea9 Merge pull request #4825 from pi-hole/shellcheck_install
Fix shellcheck warnings
2022-07-16 09:59:08 +02:00
Christian König
bc8fcc744c Fix shellcheck warnings
Signed-off-by: Christian König <ckoenig@posteo.de>
2022-07-15 20:43:42 +02:00
Christian König
a3f1317add Don't fail if Alma or Rocky is detected
Signed-off-by: Christian König <ckoenig@posteo.de>
2022-07-15 20:04:37 +02:00
Rauf Shimarov
c90d8284ef Update README.md
Signed-off-by: Rauf Shimarov <55862995+Rauf00@users.noreply.github.com>
2022-07-12 16:20:17 -07:00
Rauf Shimarov
7ab9664255 Update README.md
Co-authored-by: Adam Warner <github@adamwarner.co.uk>

Signed-off-by: Rauf Shimarov <55862995+Rauf00@users.noreply.github.com>
2022-07-11 14:55:15 -07:00
Rauf Shimarov
3a22657645 Update README.md
Co-authored-by: Adam Warner <github@adamwarner.co.uk>

Signed-off-by: Rauf Shimarov <55862995+Rauf00@users.noreply.github.com>
2022-07-11 14:54:19 -07:00
yubiuser
64d75c012e Merge pull request #4815 from pi-hole/debug_spinner
Add spinner for long processes running during debug log
2022-07-11 22:29:06 +02:00
Rauf Shimarov
4567f264b4 Fix errors in README.md
Signed-off-by: Rauf Shimarov <55862995+Rauf00@users.noreply.github.com>
2022-07-11 11:45:09 -07:00
RD WebDesign
cbcd12631d Adding the spinner for foreign_key_check too
Signed-off-by: RD WebDesign <github@rdwebdesign.com.br>
2022-07-11 01:53:30 -03:00
RD WebDesign
c4f9a475f3 Debug log - add spinner for long processes
Signed-off-by: RD WebDesign <github@rdwebdesign.com.br>
2022-07-11 01:34:51 -03:00
yubiuser
71d310c50f Merge pull request #4745 from pi-hole/tweak/debug
Add optional health check to Pi-hole databases in debug script
2022-07-10 23:41:42 +02:00
Christian König
b486786041 Add database healthy checks to debug script
Fix health check output comparison in gravity script as well
Add note about waiting time

Signed-off-by: Christian König <ckoenig@posteo.de>
2022-07-10 23:32:47 +02:00
Adam Warner
3dd26b500d Merge pull request #4813 from pi-hole/master
sync: master to development
2022-07-10 13:56:30 +01:00
Adam Warner
aefbe1f5b6 Merge pull request #4812 from pi-hole/development
Pi-hole core 5.11.4
2022-07-10 13:52:38 +01:00
Adam Warner
13135498c1 Merge pull request #4811 from pi-hole/CAPS
Print all SELINUX output in lowercase
2022-07-10 13:43:29 +01:00
Christian König
9f918972d2 Adjust tests
Signed-off-by: Christian König <ckoenig@posteo.de>
2022-07-10 14:33:43 +02:00
Christian König
b25805348f Print all SELINUX output in lowercase
Signed-off-by: Christian König <ckoenig@posteo.de>
2022-07-10 14:33:24 +02:00
yubiuser
d6c48f80f4 Merge pull request #4810 from pi-hole/tweak/logrotate
Fix broken logrotate config by updating old paths in existing file if they exist
2022-07-10 13:25:45 +02:00
Adam Warner
59dab6a568 Simplifications per @yubiuser's suggestion
Co-authored-by: yubiuser <ckoenig@posteo.de>
Signed-off-by: Adam Warner <me@adamwarner.co.uk>
2022-07-10 11:50:09 +01:00
Adam Warner
ecfb96d339 If old log paths exist in logrotate file, replace them with new ones
Signed-off-by: Adam Warner <me@adamwarner.co.uk>
2022-07-10 10:06:55 +01:00
Adam Warner
e0baf4c7ec Merge pull request #4808 from pi-hole/cure/cancer
Fixes "Set static IP using custom values results in error" (#4807)
2022-07-09 19:12:33 +01:00
Adam Warner
e4444ae6a5 fixes "Set static IP using custom values results in error" (#4807)
Signed-off-by: Adam Warner <me@adamwarner.co.uk>
2022-07-09 19:02:40 +01:00
yubiuser
8e4adb6e39 Merge pull request #4788 from pi-hole/SKIP_INSTALL
Rename PH_TEST to SKIP_INSTALL
2022-07-09 00:01:48 +02:00
yubiuser
6aaa446354 Merge pull request #4802 from pi-hole/codespell
Fix spelling mistakes
2022-07-08 23:51:20 +02:00
yubiuser
7d5f6c8331 Merge pull request #4804 from pi-hole/mkdir
Clean consecutive mkdir
2022-07-08 23:38:53 +02:00
Christian König
3d8672bc59 Clean consecutive mkdir
Signed-off-by: Christian König <ckoenig@posteo.de>
2022-07-08 23:20:30 +02:00
Christian König
b49db58ec2 Fix spelling mistakes
Signed-off-by: Christian König <ckoenig@posteo.de>
2022-07-08 22:00:36 +02:00
yubiuser
edc808ee89 Merge pull request #4791 from pi-hole/master
sync: master to development
2022-07-08 00:02:05 +02:00
Dan Schaper
a28d691387 Merge pull request #4795 from pi-hole/fix/mkdir_always
Logic fix for hotfix
2022-07-07 14:01:18 -07:00
Dan Schaper
56a32047b8 Logic fix
Signed-off-by: Dan Schaper <dan.schaper@pi-hole.net>
2022-07-07 13:50:41 -07:00
Dan Schaper
ef71ca05a9 Merge pull request #4794 from pi-hole/fix/mkdir_always
Always create log directory if it doesn't exist
2022-07-07 13:41:45 -07:00
Dan Schaper
48d5d6bed2 Always create the log target directory before any movements
Signed-off-by: Dan Schaper <dan.schaper@pi-hole.net>
2022-07-07 13:23:13 -07:00
Christian König
518cbd10e0 Rename also in docker files
Signed-off-by: Christian König <ckoenig@posteo.de>
2022-07-06 22:58:14 +02:00
Christian König
0a8761ee68 Rename PH_TEST to SKIP_INSTALL
Signed-off-by: Christian König <ckoenig@posteo.de>
2022-07-06 22:53:09 +02:00
64 changed files with 1626 additions and 2791 deletions

View File

@@ -25,7 +25,7 @@ jobs:
steps:
-
name: Checkout repository
uses: actions/checkout@v3
uses: actions/checkout@v3.1.0
# Initializes the CodeQL tools for scanning.
-
name: Initialize CodeQL

View File

@@ -13,7 +13,7 @@ jobs:
issues: write
steps:
- uses: actions/stale@v5
- uses: actions/stale@v6.0.1
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
days-before-stale: 30

View File

@@ -11,7 +11,7 @@ jobs:
name: Syncing branches
steps:
- name: Checkout
uses: actions/checkout@v3
uses: actions/checkout@v3.1.0
- name: Opening pull request
id: pull
uses: tretuna/sync-branches@1.4.0
@@ -20,7 +20,7 @@ jobs:
FROM_BRANCH: 'master'
TO_BRANCH: 'development'
- name: Label the pull request to ignore for release note generation
uses: actions-ecosystem/action-add-labels@v1
uses: actions-ecosystem/action-add-labels@v1.1.3
with:
labels: internal
repo: ${{ github.repository }}

View File

@@ -12,51 +12,65 @@ jobs:
if: github.event.pull_request.draft == false
runs-on: ubuntu-latest
steps:
-
name: Checkout repository
uses: actions/checkout@v3
-
name: Check scripts in repository are executable
run: |
IFS=$'\n';
for f in $(find . -name '*.sh'); do if [[ ! -x $f ]]; then echo "$f is not executable" && FAIL=1; fi ;done
unset IFS;
# If FAIL is 1 then we fail.
[[ $FAIL == 1 ]] && exit 1 || echo "Scripts are executable!"
-
name: Spell-Checking
uses: codespell-project/actions-codespell@master
with:
ignore_words_file: .codespellignore
-
name: Get editorconfig-checker
uses: editorconfig-checker/action-editorconfig-checker@main
-
name: Run editorconfig-checker
run: editorconfig-checker
- name: Checkout repository
uses: actions/checkout@v3.1.0
- name: Check scripts in repository are executable
run: |
IFS=$'\n';
for f in $(find . -name '*.sh'); do if [[ ! -x $f ]]; then echo "$f is not executable" && FAIL=1; fi ;done
unset IFS;
# If FAIL is 1 then we fail.
[[ $FAIL == 1 ]] && exit 1 || echo "Scripts are executable!"
- name: Spell-Checking
uses: codespell-project/actions-codespell@master
with:
ignore_words_file: .codespellignore
- name: Get editorconfig-checker
uses: editorconfig-checker/action-editorconfig-checker@main # tag v1.0.0 is really out of date
- name: Run editorconfig-checker
run: editorconfig-checker
- name: Check python code formatting with black
uses: psf/black@stable
with:
src: "./test"
options: "--check --diff --color"
distro-test:
if: github.event.pull_request.draft == false
runs-on: ubuntu-latest
needs: smoke-tests
strategy:
fail-fast: false
matrix:
distro: [debian_10, debian_11, ubuntu_18, ubuntu_20, ubuntu_21, ubuntu_22, centos_7, centos_8, fedora_34]
distro:
[
debian_10,
debian_11,
ubuntu_20,
ubuntu_22,
centos_8,
centos_9,
fedora_35,
fedora_36,
]
env:
DISTRO: ${{matrix.distro}}
steps:
-
name: Checkout repository
uses: actions/checkout@v3
-
name: Set up Python 3.8
uses: actions/setup-python@v4
with:
python-version: 3.8
-
name: Install dependencies
run: pip install -r test/requirements.txt
-
name: Test with tox
run: tox -c test/tox.${DISTRO}.ini
- name: Checkout repository
uses: actions/checkout@v3.1.0
- name: Set up Python 3.10
uses: actions/setup-python@v4.3.0
with:
python-version: "3.10"
- name: Install dependencies
run: pip install -r test/requirements.txt
- name: Test with tox
run: tox -c test/tox.${DISTRO}.ini

View File

@@ -3,26 +3,26 @@
#
<p align="center">
<a href="https://pi-hole.net/#gh-light-mode-only">
<img src="https://github.com/pi-hole/graphics/blob/master/Vortex/Vortex_Vertical_wordmark_lightmode.png?raw=true)" alt="Pi-hole">
</a>
<a href="https://pi-hole.net/#gh-dark-mode-only">
<img src="https://github.com/pi-hole/graphics/blob/master/Vortex/Vortex_Vertical_wordmark_darkmode.png?raw=true" alt="Pi-hole">
</a>
<picture>
<source media="(prefers-color-scheme: dark)" srcset="https://pi-hole.github.io/graphics/Vortex/Vortex_Vertical_wordmark_darkmode.png">
<source media="(prefers-color-scheme: light)" srcset="https://pi-hole.github.io/graphics/Vortex/Vortex_Vertical_wordmark_lightmode.png">
<img src="https://pi-hole.github.io/graphics/Vortex/Vortex_Vertical_wordmark_lightmode.png" width="168" height="270" alt="Pi-hole website">
</picture>
<br>
<strong>Network-wide ad blocking via your own Linux hardware</strong>
</p>
<!-- markdownlint-enable MD033 -->
The Pi-hole® is a [DNS sinkhole](https://en.wikipedia.org/wiki/DNS_Sinkhole) that protects your devices from unwanted content without installing any client-side software.
- **Easy-to-install**: our versatile installer walks you through the process and takes less than ten minutes
- **Easy-to-install**: our dialogs walk you through the simple installation process in less than ten minutes
- **Resolute**: content is blocked in _non-browser locations_, such as ad-laden mobile apps and smart TVs
- **Responsive**: seamlessly speeds up the feel of everyday browsing by caching DNS queries
- **Lightweight**: runs smoothly with [minimal hardware and software requirements](https://docs.pi-hole.net/main/prerequisites/)
- **Robust**: a command line interface that is quality assured for interoperability
- **Robust**: a command-line interface that is quality assured for interoperability
- **Insightful**: a beautiful responsive Web Interface dashboard to view and control your Pi-hole
- **Versatile**: can optionally function as a [DHCP server](https://discourse.pi-hole.net/t/how-do-i-use-pi-holes-built-in-dhcp-server-and-why-would-i-want-to/3026), ensuring *all* your devices are protected automatically
- **Versatile**: can optionally function as a [DHCP server](https://discourse.pi-hole.net/t/how-do-i-use-pi-holes-built-in-dhcp-server-and-why-would-i-want-to/3026), ensuring _all_ your devices are protected automatically
- **Scalable**: [capable of handling hundreds of millions of queries](https://pi-hole.net/2017/05/24/how-much-traffic-can-pi-hole-handle/) when installed on server-grade hardware
- **Modern**: blocks ads over both IPv4 and IPv6
- **Free**: open source software that helps ensure _you_ are the sole person in control of your privacy
@@ -53,12 +53,14 @@ sudo bash basic-install.sh
wget -O basic-install.sh https://install.pi-hole.net
sudo bash basic-install.sh
```
### Method 3: Using Docker to deploy Pi-hole
Please refer to the [Pi-hole docker repo](https://github.com/pi-hole/docker-pi-hole) to use the Official Docker Images.
## [Post-install: Make your network take advantage of Pi-hole](https://docs.pi-hole.net/main/post-install/)
Once the installer has been run, you will need to [configure your router to have **DHCP clients use Pi-hole as their DNS server**](https://discourse.pi-hole.net/t/how-do-i-configure-my-devices-to-use-pi-hole-as-their-dns-server/245) which ensures that all devices connecting to your network will have content blocked without any further intervention.
Once the installer has been run, you will need to [configure your router to have **DHCP clients use Pi-hole as their DNS server**](https://discourse.pi-hole.net/t/how-do-i-configure-my-devices-to-use-pi-hole-as-their-dns-server/245). This router configuration will ensure that all devices connecting to your network will have content blocked without any further intervention.
If your router does not support setting the DNS server, you can [use Pi-hole's built-in DHCP server](https://discourse.pi-hole.net/t/how-do-i-use-pi-holes-built-in-dhcp-server-and-why-would-i-want-to/3026); be sure to disable DHCP on your router first (if it has that feature available).
@@ -68,7 +70,7 @@ As a last resort, you can manually set each device to use Pi-hole as their DNS s
## Pi-hole is free but powered by your support
There are many reoccurring costs involved with maintaining free, open source, and privacy-respecting software; expenses which [our volunteer developers](https://github.com/orgs/pi-hole/people) pitch in to cover out-of-pocket. This is just one example of how strongly we feel about our software and the importance of keeping it maintained.
There are many reoccurring costs involved with maintaining free, open-source, and privacy-respecting software; expenses which [our volunteer developers](https://github.com/orgs/pi-hole/people) pitch in to cover out-of-pocket. This is just one example of how strongly we feel about our software and the importance of keeping it maintained.
Make no mistake: **your support is absolutely vital to help keep us innovating!**
@@ -85,7 +87,7 @@ If you'd rather not donate (_which is okay!_), there are other ways you can help
- [Hetzner Cloud](https://hetzner.cloud/?ref=7aceisRX3AzA) _affiliate link_
- [Digital Ocean](https://www.digitalocean.com/?refcode=344d234950e1) _affiliate link_
- [Stickermule](https://www.stickermule.com/unlock?ref_id=9127301701&utm_medium=link&utm_source=invite) _earn a $10 credit after your first purchase_
- [Amazon US](http://www.amazon.com/exec/obidos/redirect-home/pihole09-20) _affiliate link_
- [Amazon US](https://www.amazon.com/exec/obidos/redirect-home/pihole09-20) _affiliate link_
- Spreading the word about our software and how you have benefited from it
### Contributing via GitHub
@@ -115,7 +117,7 @@ While we are primarily reachable on our [Discourse User Forum](https://discourse
### [Faster-than-light Engine](https://github.com/pi-hole/ftl)
[FTLDNS](https://github.com/pi-hole/ftl) is a lightweight, purpose-built daemon used to provide statistics needed for the Web Interface, and its API can be easily integrated into your own projects. As the name implies, FTLDNS does this all *very quickly*!
[FTLDNS](https://github.com/pi-hole/ftl) is a lightweight, purpose-built daemon used to provide statistics needed for the Web Interface, and its API can be easily integrated into your own projects. As the name implies, FTLDNS does this all _very quickly_!
Some of the statistics you can integrate include:
@@ -130,9 +132,9 @@ Some of the statistics you can integrate include:
Access the API via [`telnet`](https://github.com/pi-hole/FTL), the Web (`admin/api.php`) and Command Line (`pihole -c -j`). You can find out [more details over here](https://discourse.pi-hole.net/t/pi-hole-api/1863).
### The Command Line Interface
### The Command-Line Interface
The [pihole](https://docs.pi-hole.net/core/pihole-command/) command has all the functionality necessary to fully administer the Pi-hole, without the need of the Web Interface. It's fast, user-friendly, and auditable by anyone with an understanding of `bash`.
The [pihole](https://docs.pi-hole.net/core/pihole-command/) command has all the functionality necessary to fully administer the Pi-hole, without the need for the Web Interface. It's fast, user-friendly, and auditable by anyone with an understanding of `bash`.
Some notable features include:
@@ -142,7 +144,7 @@ Some notable features include:
- [Updating Ad Lists](https://docs.pi-hole.net/core/pihole-command/#gravity)
- [Querying Ad Lists for blocked domains](https://docs.pi-hole.net/core/pihole-command/#query)
- [Enabling and Disabling Pi-hole](https://docs.pi-hole.net/core/pihole-command/#enable-disable)
- ... and *many* more!
- ... and _many_ more!
You can read our [Core Feature Breakdown](https://docs.pi-hole.net/core/pihole-command/#pi-hole-core) for more information.

View File

@@ -29,13 +29,6 @@ bogus-priv
no-resolv
server=@DNS1@
server=@DNS2@
interface=@INT@
cache-size=@CACHE_SIZE@
log-queries
log-facility=/var/log/pihole/pihole.log

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 37 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 43 B

View File

@@ -14,7 +14,9 @@ LC_NUMERIC=C
# Retrieve stats from FTL engine
pihole-FTL() {
local ftl_port LINE
ftl_port=$(cat /run/pihole-FTL.port 2> /dev/null)
# shellcheck disable=SC1091
. /opt/pihole/utils.sh
ftl_port=$(getFTLAPIPort)
if [[ -n "$ftl_port" ]]; then
# Open connection to FTL
exec 3<>"/dev/tcp/127.0.0.1/$ftl_port"
@@ -503,11 +505,11 @@ chronoFunc() {
fi
printFunc " Pi-hole: " "$ph_status" "$ph_info"
printFunc " Ads Today: " "$ads_percentage_today%" "$ads_info"
printFunc " Blocked: " "$ads_percentage_today%" "$ads_info"
printFunc "Local Qrys: " "$queries_cached_percentage%" "$dns_info"
printFunc " Blocked: " "$recent_blocked"
printFunc "Top Advert: " "$top_ad"
printFunc "Last Block: " "$recent_blocked"
printFunc " Top Block: " "$top_ad"
# Provide more stats on screens with more lines
if [[ "$scr_lines" -eq 17 ]]; then

View File

@@ -9,7 +9,7 @@
# Please see LICENSE file for your rights under this license.
readonly PI_HOLE_FILES_DIR="/etc/.pihole"
PH_TEST="true"
SKIP_INSTALL="true"
source "${PI_HOLE_FILES_DIR}/automated install/basic-install.sh"
# webInterfaceGitUrl set in basic-install.sh
@@ -164,6 +164,8 @@ checkout() {
exit 1
fi
checkout_pull_branch "${webInterfaceDir}" "${2}"
# Update local and remote versions via updatechecker
/opt/pihole/updatecheck.sh
elif [[ "${1}" == "ftl" ]] ; then
local path
local oldbranch
@@ -178,6 +180,8 @@ checkout() {
FTLinstall "${binary}"
restart_service pihole-FTL
enable_service pihole-FTL
# Update local and remote versions via updatechecker
/opt/pihole/updatecheck.sh
else
echo " ${CROSS} Requested branch \"${2}\" is not available"
ftlbranches=( $(git ls-remote https://github.com/pi-hole/ftl | grep 'heads' | sed 's/refs\/heads\///;s/ //g' | awk '{print $2}') )

View File

@@ -41,18 +41,15 @@ else
#OVER="\r\033[K"
fi
OBFUSCATED_PLACEHOLDER="<DOMAIN OBFUSCATED>"
# shellcheck disable=SC1091
. /etc/pihole/versions
# FAQ URLs for use in showing the debug log
FAQ_UPDATE_PI_HOLE="${COL_CYAN}https://discourse.pi-hole.net/t/how-do-i-update-pi-hole/249${COL_NC}"
FAQ_CHECKOUT_COMMAND="${COL_CYAN}https://discourse.pi-hole.net/t/the-pihole-command-with-examples/738#checkout${COL_NC}"
FAQ_HARDWARE_REQUIREMENTS="${COL_CYAN}https://docs.pi-hole.net/main/prerequisites/${COL_NC}"
FAQ_HARDWARE_REQUIREMENTS_PORTS="${COL_CYAN}https://docs.pi-hole.net/main/prerequisites/#ports${COL_NC}"
FAQ_HARDWARE_REQUIREMENTS_FIREWALLD="${COL_CYAN}https://docs.pi-hole.net/main/prerequisites/#firewalld${COL_NC}"
FAQ_GATEWAY="${COL_CYAN}https://discourse.pi-hole.net/t/why-is-a-default-gateway-important-for-pi-hole/3546${COL_NC}"
FAQ_ULA="${COL_CYAN}https://discourse.pi-hole.net/t/use-ipv6-ula-addresses-for-pi-hole/2127${COL_NC}"
FAQ_FTL_COMPATIBILITY="${COL_CYAN}https://github.com/pi-hole/FTL#compatibility-list${COL_NC}"
FAQ_BAD_ADDRESS="${COL_CYAN}https://discourse.pi-hole.net/t/why-do-i-see-bad-address-at-in-pihole-log/3972${COL_NC}"
# Other URLs we may use
FORUMS_URL="${COL_CYAN}https://discourse.pi-hole.net${COL_NC}"
@@ -71,7 +68,6 @@ WEB_SERVER_LOG_DIRECTORY="/var/log/lighttpd"
WEB_SERVER_CONFIG_DIRECTORY="/etc/lighttpd"
HTML_DIRECTORY="/var/www/html"
WEB_GIT_DIRECTORY="${HTML_DIRECTORY}/admin"
#BLOCK_PAGE_DIRECTORY="${HTML_DIRECTORY}/pihole"
SHM_DIRECTORY="/dev/shm"
ETC="/etc"
@@ -89,6 +85,7 @@ PIHOLE_LOGROTATE_FILE="${PIHOLE_DIRECTORY}/logrotate"
PIHOLE_SETUP_VARS_FILE="${PIHOLE_DIRECTORY}/setupVars.conf"
PIHOLE_FTL_CONF_FILE="${PIHOLE_DIRECTORY}/pihole-FTL.conf"
PIHOLE_CUSTOM_HOSTS_FILE="${PIHOLE_DIRECTORY}/custom.list"
PIHOLE_VERSIONS_FILE="${PIHOLE_DIRECTORY}/versions"
# Read the value of an FTL config key. The value is printed to stdout.
#
@@ -124,7 +121,6 @@ PIHOLE_COMMAND="${BIN_DIRECTORY}/pihole"
PIHOLE_COLTABLE_FILE="${BIN_DIRECTORY}/COL_TABLE"
FTL_PID="${RUN_DIRECTORY}/pihole-FTL.pid"
FTL_PORT="${RUN_DIRECTORY}/pihole-FTL.port"
PIHOLE_LOG="${LOG_DIRECTORY}/pihole.log"
PIHOLE_LOG_GZIPS="${LOG_DIRECTORY}/pihole.log.[0-9].*"
@@ -153,7 +149,6 @@ REQUIRED_FILES=("${PIHOLE_CRON_FILE}"
"${PIHOLE_COMMAND}"
"${PIHOLE_COLTABLE_FILE}"
"${FTL_PID}"
"${FTL_PORT}"
"${PIHOLE_LOG}"
"${PIHOLE_LOG_GZIPS}"
"${PIHOLE_DEBUG_LOG}"
@@ -162,7 +157,8 @@ REQUIRED_FILES=("${PIHOLE_CRON_FILE}"
"${PIHOLE_WEB_SERVER_ERROR_LOG_FILE}"
"${RESOLVCONF}"
"${DNSMASQ_CONF}"
"${PIHOLE_CUSTOM_HOSTS_FILE}")
"${PIHOLE_CUSTOM_HOSTS_FILE}"
"${PIHOLE_VERSIONS_FILE}")
DISCLAIMER="This process collects information from your Pi-hole, and optionally uploads it to a unique and random directory on tricorder.pi-hole.net.
@@ -240,15 +236,7 @@ compare_local_version_to_git_version() {
local git_dir="${1}"
# The named component of the project (Core or Web)
local pihole_component="${2}"
# If we are checking the Core versions,
if [[ "${pihole_component}" == "Core" ]]; then
# We need to search for "Pi-hole" when using pihole -v
local search_term="Pi-hole"
elif [[ "${pihole_component}" == "Web" ]]; then
# We need to search for "AdminLTE" so store it in a variable as well
#shellcheck disable=2034
local search_term="AdminLTE"
fi
# Display what we are checking
echo_current_diagnostic "${pihole_component} version"
# Store the error message in a variable in case we want to change and/or reuse it
@@ -261,43 +249,35 @@ compare_local_version_to_git_version() {
log_write "${COL_RED}Could not cd into ${git_dir}$COL_NC"
if git status &> /dev/null; then
# The current version the user is on
local remote_version
remote_version=$(git describe --tags --abbrev=0);
local local_version
local_version=$(git describe --tags --abbrev=0);
# What branch they are on
local remote_branch
remote_branch=$(git rev-parse --abbrev-ref HEAD);
local local_branch
local_branch=$(git rev-parse --abbrev-ref HEAD);
# The commit they are on
local remote_commit
remote_commit=$(git describe --long --dirty --tags --always)
local local_commit
local_commit=$(git describe --long --dirty --tags --always)
# Status of the repo
local local_status
local_status=$(git status -s)
# echo this information out to the user in a nice format
# If the current version matches what pihole -v produces, the user is up-to-date
if [[ "${remote_version}" == "$(pihole -v | awk '/${search_term}/ {print $6}' | cut -d ')' -f1)" ]]; then
log_write "${TICK} ${pihole_component}: ${COL_GREEN}${remote_version}${COL_NC}"
# If not,
else
# echo the current version in yellow, signifying it's something to take a look at, but not a critical error
# Also add a URL to an FAQ
log_write "${INFO} ${pihole_component}: ${COL_YELLOW}${remote_version:-Untagged}${COL_NC} (${FAQ_UPDATE_PI_HOLE})"
fi
log_write "${TICK} Version: ${local_version}"
# Print the repo upstreams
remotes=$(git remote -v)
log_write "${INFO} Remotes: ${remotes//$'\n'/'\n '}"
# If the repo is on the master branch, they are on the stable codebase
if [[ "${remote_branch}" == "master" ]]; then
if [[ "${local_branch}" == "master" ]]; then
# so the color of the text is green
log_write "${INFO} Branch: ${COL_GREEN}${remote_branch}${COL_NC}"
log_write "${INFO} Branch: ${COL_GREEN}${local_branch}${COL_NC}"
# If it is any other branch, they are in a development branch
else
# So show that in yellow, signifying it's something to take a look at, but not a critical error
log_write "${INFO} Branch: ${COL_YELLOW}${remote_branch:-Detached}${COL_NC} (${FAQ_CHECKOUT_COMMAND})"
log_write "${INFO} Branch: ${COL_YELLOW}${local_branch:-Detached}${COL_NC}"
fi
# echo the current commit
log_write "${INFO} Commit: ${remote_commit}"
log_write "${INFO} Commit: ${local_commit}"
# if `local_status` is non-null, then the repo is not clean, display details here
if [[ ${local_status} ]]; then
# Replace new lines in the status with 12 spaces to make the output cleaner
@@ -331,18 +311,28 @@ compare_local_version_to_git_version() {
}
check_ftl_version() {
local ftl_name="FTL"
echo_current_diagnostic "${ftl_name} version"
local FTL_VERSION FTL_COMMIT FTL_BRANCH
echo_current_diagnostic "FTL version"
# Use the built in command to check FTL's version
FTL_VERSION=$(pihole-FTL version)
# Compare the current FTL version to the remote version
if [[ "${FTL_VERSION}" == "$(pihole -v | awk '/FTL/ {print $6}' | cut -d ')' -f1)" ]]; then
# If they are the same, FTL is up-to-date
log_write "${TICK} ${ftl_name}: ${COL_GREEN}${FTL_VERSION}${COL_NC}"
FTL_BRANCH=$(pihole-FTL branch)
FTL_COMMIT=$(pihole-FTL --hash)
log_write "${TICK} Version: ${FTL_VERSION}"
# If they use the master branch, they are on the stable codebase
if [[ "${FTL_BRANCH}" == "master" ]]; then
# so the color of the text is green
log_write "${INFO} Branch: ${COL_GREEN}${FTL_BRANCH}${COL_NC}"
# If it is any other branch, they are in a development branch
else
# If not, show it in yellow, signifying there is an update
log_write "${TICK} ${ftl_name}: ${COL_YELLOW}${FTL_VERSION}${COL_NC} (${FAQ_UPDATE_PI_HOLE})"
# So show that in yellow, signifying it's something to take a look at, but not a critical error
log_write "${INFO} Branch: ${COL_YELLOW}${FTL_BRANCH}${COL_NC}"
fi
# echo the current commit
log_write "${INFO} Commit: ${FTL_COMMIT}"
}
# Checks the core version of the Pi-hole codebase
@@ -448,8 +438,8 @@ diagnose_operating_system() {
# Display the current test that is running
echo_current_diagnostic "Operating system"
# If the PIHOLE_DOCKER_TAG variable is set, include this information in the debug output
[ -n "${PIHOLE_DOCKER_TAG}" ] && log_write "${INFO} Pi-hole Docker Container: ${PIHOLE_DOCKER_TAG}"
# If DOCKER_VERSION is set (Sourced from /etc/pihole/versions at start of script), include this information in the debug output
[ -n "${DOCKER_VERSION}" ] && log_write "${INFO} Pi-hole Docker Container: ${DOCKER_VERSION}"
# If there is a /etc/*release file, it's probably a supported operating system, so we can
if ls /etc/*release 1> /dev/null 2>&1; then
@@ -581,7 +571,7 @@ disk_usage() {
# Some lines of df might contain sensitive information like usernames and passwords.
# E.g. curlftpfs filesystems (https://www.looklinux.com/mount-ftp-share-on-linux-using-curlftps/)
# We are not interested in those lines so we collect keyword, to remove them from the output
# Additinal keywords can be added, separated by "|"
# Additional keywords can be added, separated by "|"
hide="curlftpfs"
# only show those lines not containing a sensitive phrase
@@ -659,15 +649,20 @@ ping_gateway() {
local protocol="${1}"
ping_ipv4_or_ipv6 "${protocol}"
# Check if we are using IPv4 or IPv6
# Find the default gateway using IPv4 or IPv6
# Find the default gateways using IPv4 or IPv6
local gateway
gateway="$(ip -"${protocol}" route | grep default | grep "${PIHOLE_INTERFACE}" | cut -d ' ' -f 3)"
# If the gateway variable has a value (meaning a gateway was found),
if [[ -n "${gateway}" ]]; then
log_write "${INFO} Default IPv${protocol} gateway: ${gateway}"
log_write "${INFO} Default IPv${protocol} gateway(s):"
while IFS= read -r gateway; do
log_write " ${gateway}"
done < <(ip -"${protocol}" route | grep default | grep "${PIHOLE_INTERFACE}" | cut -d ' ' -f 3)
gateway=$(ip -"${protocol}" route | grep default | grep "${PIHOLE_INTERFACE}" | cut -d ' ' -f 3 | head -n 1)
# If there was at least one gateway
if [ -n "${gateway}" ]; then
# Let the user know we will ping the gateway for a response
log_write " * Pinging ${gateway}..."
log_write " * Pinging first gateway ${gateway}..."
# Try to quietly ping the gateway 3 times, with a timeout of 3 seconds, using numeric output only,
# on the pihole interface, and tail the last three lines of the output
# If pinging the gateway is not successful,
@@ -785,7 +780,7 @@ check_networking() {
ping_gateway "6"
# Skip the following check if installed in docker container. Unpriv'ed containers do not have access to the information required
# to resolve the service name listening - and the container should not start if there was a port conflict anyway
[ -z "${PIHOLE_DOCKER_TAG}" ] && check_required_ports
[ -z "${DOCKER_VERSION}" ] && check_required_ports
}
check_x_headers() {
@@ -795,39 +790,24 @@ check_x_headers() {
# Similarly, it will show "X-Pi-hole: The Pi-hole Web interface is working!" if you view the header returned
# when accessing the dashboard (i.e curl -I pi.hole/admin/)
# server is operating correctly
echo_current_diagnostic "Dashboard and block page"
echo_current_diagnostic "Dashboard headers"
# Use curl -I to get the header and parse out just the X-Pi-hole one
local block_page
block_page=$(curl -Is localhost | awk '/X-Pi-hole/' | tr -d '\r')
# Do it for the dashboard as well, as the header is different than above
local full_curl_output_dashboard
local dashboard
dashboard=$(curl -Is localhost/admin/ | awk '/X-Pi-hole/' | tr -d '\r')
full_curl_output_dashboard="$(curl -Is localhost/admin/)"
dashboard=$(echo "${full_curl_output_dashboard}" | awk '/X-Pi-hole/' | tr -d '\r')
# Store what the X-Header should be in variables for comparison later
local block_page_working
block_page_working="X-Pi-hole: A black hole for Internet advertisements."
local dashboard_working
dashboard_working="X-Pi-hole: The Pi-hole Web interface is working!"
local full_curl_output_block_page
full_curl_output_block_page="$(curl -Is localhost)"
local full_curl_output_dashboard
full_curl_output_dashboard="$(curl -Is localhost/admin/)"
# If the X-header found by curl matches what is should be,
if [[ $block_page == "$block_page_working" ]]; then
# display a success message
log_write "$TICK Block page X-Header: ${COL_GREEN}${block_page}${COL_NC}"
else
# Otherwise, show an error
log_write "$CROSS Block page X-Header: ${COL_RED}X-Header does not match or could not be retrieved.${COL_NC}"
log_write "${COL_RED}${full_curl_output_block_page}${COL_NC}"
fi
# Same logic applies to the dashboard as above, if the X-Header matches what a working system should have,
# If the X-Header matches what a working system should have,
if [[ $dashboard == "$dashboard_working" ]]; then
# then we can show a success
log_write "$TICK Web interface X-Header: ${COL_GREEN}${dashboard}${COL_NC}"
else
# Otherwise, it's a failure since the X-Headers either don't exist or have been modified in some way
log_write "$CROSS Web interface X-Header: ${COL_RED}X-Header does not match or could not be retrieved.${COL_NC}"
log_write "${COL_RED}${full_curl_output_dashboard}${COL_NC}"
fi
}
@@ -945,10 +925,21 @@ process_status(){
else
# Otherwise, use the service command and mock the output of `systemctl is-active`
local status_of_process
if service "${i}" status | grep -E 'is\srunning' &> /dev/null; then
status_of_process="active"
# If DOCKER_VERSION is set, the output is slightly different (s6 init system on Docker)
if [ -n "${DOCKER_VERSION}" ]; then
if service "${i}" status | grep -E '^up' &> /dev/null; then
status_of_process="active"
else
status_of_process="inactive"
fi
else
status_of_process="inactive"
# non-Docker system
if service "${i}" status | grep -E 'is\srunning' &> /dev/null; then
status_of_process="active"
else
status_of_process="inactive"
fi
fi
fi
# and print it out to the user
@@ -990,7 +981,7 @@ make_array_from_file() {
else
# Otherwise, read the file line by line
while IFS= read -r line;do
# Othwerise, strip out comments and blank lines
# Otherwise, strip out comments and blank lines
new_line=$(echo "${line}" | sed -e 's/^\s*#.*$//' -e '/^$/d')
# If the line still has content (a non-zero value)
if [[ -n "${new_line}" ]]; then
@@ -1048,7 +1039,7 @@ parse_file() {
}
check_name_resolution() {
# Check name resolution from localhost, Pi-hole's IP, and Google's name severs
# Check name resolution from localhost, Pi-hole's IP, and Google's name servers
# using the function we created earlier
dig_at 4
dig_at 6
@@ -1230,7 +1221,7 @@ check_dhcp_servers() {
OLD_IFS="$IFS"
IFS=$'\n'
local entries=()
mapfile -t entries < <(pihole-FTL dhcp-discover)
mapfile -t entries < <(pihole-FTL dhcp-discover & spinner)
for line in "${entries[@]}"; do
log_write " ${line}"
@@ -1259,12 +1250,21 @@ show_messages() {
show_FTL_db_entries "Pi-hole diagnosis messages" "SELECT count (message) as count, datetime(max(timestamp),'unixepoch','localtime') as 'last timestamp', type, message, blob1, blob2, blob3, blob4, blob5 FROM message GROUP BY type, message, blob1, blob2, blob3, blob4, blob5;" "6 19 20 60 20 20 20 20 20"
}
database_permissions() {
local permissions
permissions=$(ls -lhd "${1}")
log_write "${COL_GREEN}${permissions}${COL_NC}"
}
analyze_gravity_list() {
echo_current_diagnostic "Gravity Database"
local gravity_permissions
gravity_permissions=$(ls -lhd "${PIHOLE_GRAVITY_DB_FILE}")
log_write "${COL_GREEN}${gravity_permissions}${COL_NC}"
database_permissions "${PIHOLE_GRAVITY_DB_FILE}"
# if users want to check database integrity
if [[ "${CHECK_DATABASE}" = true ]]; then
database_integrity_check "${PIHOLE_GRAVITY_DB_FILE}"
fi
show_db_entries "Info table" "SELECT property,value FROM info" "20 40"
gravity_updated_raw="$(pihole-FTL sqlite3 "${PIHOLE_GRAVITY_DB_FILE}" "SELECT value FROM info where property = 'updated'")"
@@ -1286,49 +1286,87 @@ analyze_gravity_list() {
IFS="$OLD_IFS"
}
obfuscated_pihole_log() {
local pihole_log=("$@")
local line
local error_to_check_for
local line_to_obfuscate
local obfuscated_line
for line in "${pihole_log[@]}"; do
# A common error in the pihole.log is when there is a non-hosts formatted file
# that the DNS server is attempting to read. Since it's not formatted
# correctly, there will be an entry for "bad address at line n"
# So we can check for that here and highlight it in red so the user can see it easily
error_to_check_for=$(echo "${line}" | grep 'bad address at')
# Some users may not want to have the domains they visit sent to us
# To that end, we check for lines in the log that would contain a domain name
line_to_obfuscate=$(echo "${line}" | grep ': query\|: forwarded\|: reply')
# If the variable contains a value, it found an error in the log
if [[ -n ${error_to_check_for} ]]; then
# So we can print it in red to make it visible to the user
log_write " ${CROSS} ${COL_RED}${line}${COL_NC} (${FAQ_BAD_ADDRESS})"
analyze_ftl_db() {
echo_current_diagnostic "Pi-hole FTL Query Database"
database_permissions "${PIHOLE_FTL_DB_FILE}"
# if users want to check database integrity
if [[ "${CHECK_DATABASE}" = true ]]; then
database_integrity_check "${PIHOLE_FTL_DB_FILE}"
fi
}
database_integrity_check(){
local result
local database="${1}"
log_write "${INFO} Checking integrity of ${database} ... (this can take several minutes)"
result="$(pihole-FTL "${database}" "PRAGMA integrity_check" 2>&1 & spinner)"
if [[ ${result} = "ok" ]]; then
log_write "${TICK} Integrity of ${database} intact"
log_write "${INFO} Checking foreign key constraints of ${database} ... (this can take several minutes)"
unset result
result="$(pihole-FTL sqlite3 "${database}" -cmd ".headers on" -cmd ".mode column" "PRAGMA foreign_key_check" 2>&1 & spinner)"
if [[ -z ${result} ]]; then
log_write "${TICK} No foreign key errors in ${database}"
else
# If the variable does not a value (the current default behavior), so do not obfuscate anything
if [[ -z ${OBFUSCATE} ]]; then
log_write " ${line}"
# Othwerise, a flag was passed to this command to obfuscate domains in the log
else
# So first check if there are domains in the log that should be obfuscated
if [[ -n ${line_to_obfuscate} ]]; then
# If there are, we need to use awk to replace only the domain name (the 6th field in the log)
# so we substitute the domain for the placeholder value
obfuscated_line=$(echo "${line_to_obfuscate}" | awk -v placeholder="${OBFUSCATED_PLACEHOLDER}" '{sub($6,placeholder); print $0}')
log_write " ${obfuscated_line}"
else
log_write " ${line}"
fi
fi
log_write "${CROSS} ${COL_RED}Foreign key errors in ${database} found.${COL_NC}"
while IFS= read -r line ; do
log_write " $line"
done <<< "$result"
fi
done
else
log_write "${CROSS} ${COL_RED}Integrity errors in ${database} found.\n${COL_NC}"
while IFS= read -r line ; do
log_write " $line"
done <<< "$result"
fi
}
# Show a text spinner during a long process run
spinner(){
# Show the spinner only if there is a tty
if tty -s; then
# PID of the most recent background process
_PID=$!
_spin="/-\|"
_start=0
_elapsed=0
_i=1
# Start the counter
_start=$(date +%s)
# Hide the cursor
tput civis > /dev/tty
# ensures cursor is visible again, in case of premature exit
trap 'tput cnorm > /dev/tty' EXIT
while [ -d /proc/$_PID ]; do
_elapsed=$(( $(date +%s) - _start ))
# use hours only if needed
if [ "$_elapsed" -lt 3600 ]; then
printf "\r${_spin:_i++%${#_spin}:1} %02d:%02d" $((_elapsed/60)) $((_elapsed%60)) >"$(tty)"
else
printf "\r${_spin:_i++%${#_spin}:1} %02d:%02d:%02d" $((_elapsed/3600)) $(((_elapsed/60)%60)) $((_elapsed%60)) >"$(tty)"
fi
sleep 0.25
done
# Return to the begin of the line after completion (the spinner will be overwritten)
printf "\r" >"$(tty)"
# Restore cursor visibility
tput cnorm > /dev/tty
fi
}
analyze_pihole_log() {
echo_current_diagnostic "Pi-hole log"
local pihole_log_head=()
local pihole_log_tail=()
local pihole_log_permissions
local logging_enabled
@@ -1338,22 +1376,10 @@ analyze_pihole_log() {
log_write "${INFO} Query logging is disabled"
log_write ""
fi
# Put the current Internal Field Separator into another variable so it can be restored later
OLD_IFS="$IFS"
# Get the lines that are in the file(s) and store them in an array for parsing later
IFS=$'\r\n'
pihole_log_permissions=$(ls -lhd "${PIHOLE_LOG}")
log_write "${COL_GREEN}${pihole_log_permissions}${COL_NC}"
mapfile -t pihole_log_head < <(head -n 20 ${PIHOLE_LOG})
log_write " ${COL_CYAN}-----head of $(basename ${PIHOLE_LOG})------${COL_NC}"
obfuscated_pihole_log "${pihole_log_head[@]}"
log_write ""
mapfile -t pihole_log_tail < <(tail -n 20 ${PIHOLE_LOG})
log_write " ${COL_CYAN}-----tail of $(basename ${PIHOLE_LOG})------${COL_NC}"
obfuscated_pihole_log "${pihole_log_tail[@]}"
log_write ""
# Set the IFS back to what it was
IFS="$OLD_IFS"
head_tail_log "${PIHOLE_LOG}" 20
}
curl_to_tricorder() {
@@ -1431,7 +1457,7 @@ upload_to_tricorder() {
if [[ "${WEBCALL}" ]] && [[ ! "${AUTOMATED}" ]]; then
:
else
log_write "${CROSS} ${COL_RED}There was an error uploading your debug log.${COL_NC}"
log_write "${CROSS} ${COL_RED}There was an error uploading your debug log.${COL_NC}"
log_write " * Please try again or contact the Pi-hole team for assistance."
fi
fi
@@ -1460,6 +1486,7 @@ process_status
ftl_full_status
parse_setup_vars
check_x_headers
analyze_ftl_db
analyze_gravity_list
show_groups
show_domainlist

View File

@@ -16,7 +16,6 @@ GRAVITYDB="${piholeDir}/gravity.db"
options="$*"
all=""
exact=""
blockpage=""
matchType="match"
# Source pihole-FTL from install script
pihole_FTL="${piholeDir}/pihole-FTL.conf"
@@ -34,7 +33,7 @@ source "${colfile}"
# Scan an array of files for matching strings
scanList(){
# Escape full stops
local domain="${1}" esc_domain="${1//./\\.}" lists="${2}" type="${3:-}"
local domain="${1}" esc_domain="${1//./\\.}" lists="${2}" list_type="${3:-}"
# Prevent grep from printing file path
cd "$piholeDir" || exit 1
@@ -43,7 +42,7 @@ scanList(){
export LC_CTYPE=C
# /dev/null forces filename to be printed when only one list has been generated
case "${type}" in
case "${list_type}" in
"exact" ) grep -i -E -l "(^|(?<!#)\\s)${esc_domain}($|\\s|#)" ${lists} /dev/null 2>/dev/null;;
# Iterate through each regexp and check whether it matches the domainQuery
# If it does, print the matching regexp and continue looping
@@ -71,18 +70,14 @@ Options:
fi
# Handle valid options
if [[ "${options}" == *"-bp"* ]]; then
exact="exact"; blockpage=true
else
[[ "${options}" == *"-all"* ]] && all=true
if [[ "${options}" == *"-exact"* ]]; then
exact="exact"; matchType="exact ${matchType}"
fi
[[ "${options}" == *"-all"* ]] && all=true
if [[ "${options}" == *"-exact"* ]]; then
exact="exact"; matchType="exact ${matchType}"
fi
# Strip valid options, leaving only the domain and invalid options
# This allows users to place the options before or after the domain
options=$(sed -E 's/ ?-(bp|adlists?|all|exact) ?//g' <<< "${options}")
options=$(sed -E 's/ ?-(adlists?|all|exact) ?//g' <<< "${options}")
# Handle remaining options
# If $options contain non ASCII characters, convert to punycode
@@ -99,10 +94,10 @@ if [[ -n "${str:-}" ]]; then
fi
scanDatabaseTable() {
local domain table type querystr result extra
local domain table list_type querystr result extra
domain="$(printf "%q" "${1}")"
table="${2}"
type="${3:-}"
list_type="${3:-}"
# As underscores are legitimate parts of domains, we escape them when using the LIKE operator.
# Underscores are SQLite wildcards matching exactly one character. We obviously want to suppress this
@@ -115,8 +110,8 @@ scanDatabaseTable() {
esac
else
case "${exact}" in
"exact" ) querystr="SELECT domain,enabled FROM domainlist WHERE type = '${type}' AND domain = '${domain}'";;
* ) querystr="SELECT domain,enabled FROM domainlist WHERE type = '${type}' AND domain LIKE '%${domain//_/\\_}%' ESCAPE '\\'";;
"exact" ) querystr="SELECT domain,enabled FROM domainlist WHERE type = '${list_type}' AND domain = '${domain}'";;
* ) querystr="SELECT domain,enabled FROM domainlist WHERE type = '${list_type}' AND domain LIKE '%${domain//_/\\_}%' ESCAPE '\\'";;
esac
fi
@@ -136,17 +131,11 @@ scanDatabaseTable() {
wbMatch=true
# Print table name
if [[ -z "${blockpage}" ]]; then
echo " ${matchType^} found in ${COL_BOLD}exact ${table}${COL_NC}"
fi
echo " ${matchType^} found in ${COL_BOLD}exact ${table}${COL_NC}"
# Loop over results and print them
mapfile -t results <<< "${result}"
for result in "${results[@]}"; do
if [[ -n "${blockpage}" ]]; then
echo "π ${result}"
exit 0
fi
domain="${result/|*}"
if [[ "${result#*|}" == "0" ]]; then
extra=" (disabled)"
@@ -158,13 +147,13 @@ scanDatabaseTable() {
}
scanRegexDatabaseTable() {
local domain list
local domain list list_type
domain="${1}"
list="${2}"
type="${3:-}"
list_type="${3:-}"
# Query all regex from the corresponding database tables
mapfile -t regexList < <(pihole-FTL sqlite3 "${gravityDBfile}" "SELECT domain FROM domainlist WHERE type = ${type}" 2> /dev/null)
mapfile -t regexList < <(pihole-FTL sqlite3 "${gravityDBfile}" "SELECT domain FROM domainlist WHERE type = ${list_type}" 2> /dev/null)
# If we have regexps to process
if [[ "${#regexList[@]}" -ne 0 ]]; then
@@ -181,18 +170,13 @@ scanRegexDatabaseTable() {
# Form a "results" message
str_result="${COL_BOLD}${str_regexMatches}${COL_NC}"
# If we are displaying more than just the source of the block
if [[ -z "${blockpage}" ]]; then
# Set the wildcard match flag
wcMatch=true
# Echo the "matched" message, indented by one space
echo " ${str_message}"
# Echo the "results" message, each line indented by three spaces
# shellcheck disable=SC2001
echo "${str_result}" | sed 's/^/ /'
else
echo "π .wildcard"
exit 0
fi
# Set the wildcard match flag
wcMatch=true
# Echo the "matched" message, indented by one space
echo " ${str_message}"
# Echo the "results" message, each line indented by three spaces
# shellcheck disable=SC2001
echo "${str_result}" | sed 's/^/ /'
fi
fi
}
@@ -222,7 +206,7 @@ elif [[ -z "${all}" ]] && [[ "${#results[*]}" -ge 100 ]]; then
fi
# Print "Exact matches for" title
if [[ -n "${exact}" ]] && [[ -z "${blockpage}" ]]; then
if [[ -n "${exact}" ]]; then
plural=""; [[ "${#results[*]}" -gt 1 ]] && plural="es"
echo " ${matchType^}${plural} for ${COL_BOLD}${domainQuery}${COL_NC} found in:"
fi
@@ -238,9 +222,7 @@ for result in "${results[@]}"; do
extra=""
fi
if [[ -n "${blockpage}" ]]; then
echo "0 ${adlistAddress}"
elif [[ -n "${exact}" ]]; then
if [[ -n "${exact}" ]]; then
echo " - ${adlistAddress}${extra}"
else
if [[ ! "${adlistAddress}" == "${adlistAddress_prev:-}" ]]; then

View File

@@ -1,74 +0,0 @@
#!/usr/bin/env bash
# Pi-hole: A black hole for Internet advertisements
# (c) 2017 Pi-hole, LLC (https://pi-hole.net)
# Network-wide ad blocking via your own hardware.
#
# Automatically configures the Pi to use the 2.8 LCD screen to display stats on it (also works over ssh)
#
# This file is copyright under the latest version of the EUPL.
# Please see LICENSE file for your rights under this license.
############ FUNCTIONS ###########
# Borrowed from adafruit-pitft-helper < borrowed from raspi-config
# https://github.com/adafruit/Adafruit-PiTFT-Helper/blob/master/adafruit-pitft-helper#L324-L334
getInitSys() {
if command -v systemctl > /dev/null && systemctl | grep -q '\-\.mount'; then
SYSTEMD=1
elif [ -f /etc/init.d/cron ] && [ ! -h /etc/init.d/cron ]; then
SYSTEMD=0
else
echo "Unrecognized init system"
return 1
fi
}
# Borrowed from adafruit-pitft-helper:
# https://github.com/adafruit/Adafruit-PiTFT-Helper/blob/master/adafruit-pitft-helper#L274-L285
autoLoginPiToConsole() {
if [ -e /etc/init.d/lightdm ]; then
if [ ${SYSTEMD} -eq 1 ]; then
systemctl set-default multi-user.target
ln -fs /etc/systemd/system/autologin@.service /etc/systemd/system/getty.target.wants/getty@tty1.service
else
update-rc.d lightdm disable 2
sed /etc/inittab -i -e "s/1:2345:respawn:\/sbin\/getty --noclear 38400 tty1/1:2345:respawn:\/bin\/login -f pi tty1 <\/dev\/tty1 >\/dev\/tty1 2>&1/"
fi
fi
}
######### SCRIPT ###########
# Set pi to log in automatically
getInitSys
autoLoginPiToConsole
# Set chronomter to run automatically when pi logs in
echo /usr/local/bin/chronometer.sh >> /home/pi/.bashrc
# OR
#$SUDO echo /usr/local/bin/chronometer.sh >> /etc/profile
# Set up the LCD screen based on Adafruits instuctions:
# https://learn.adafruit.com/adafruit-pitft-28-inch-resistive-touchscreen-display-raspberry-pi/easy-install
curl -SLs https://apt.adafruit.com/add-pin | bash
apt-get -y install raspberrypi-bootloader
apt-get -y install adafruit-pitft-helper
adafruit-pitft-helper -t 28r
# Download the cmdline.txt file that prevents the screen from going blank after a period of time
mv /boot/cmdline.txt /boot/cmdline.orig
curl -o /boot/cmdline.txt https://raw.githubusercontent.com/pi-hole/pi-hole/master/advanced/cmdline.txt
# Back up the original file and download the new one
mv /etc/default/console-setup /etc/default/console-setup.orig
curl -o /etc/default/console-setup https://raw.githubusercontent.com/pi-hole/pi-hole/master/advanced/console-setup
# Instantly apply the font change to the LCD screen
setupcon
reboot
# Start showing the stats on the screen by running the command on another tty:
# https://unix.stackexchange.com/questions/170063/start-a-process-on-a-different-tty
#setsid sh -c 'exec /usr/local/bin/chronometer.sh <> /dev/tty1 >&0 2>&1'

View File

@@ -17,7 +17,7 @@ readonly PI_HOLE_GIT_URL="https://github.com/pi-hole/pi-hole.git"
readonly PI_HOLE_FILES_DIR="/etc/.pihole"
# shellcheck disable=SC2034
PH_TEST=true
SKIP_INSTALL=true
# when --check-only is passed to this script, it will not perform the actual update
CHECK_ONLY=false
@@ -216,9 +216,8 @@ main() {
fi
if [[ "${FTL_update}" == true || "${core_update}" == true || "${web_update}" == true ]]; then
# Force an update of the updatechecker
# Update local and remote versions via updatechecker
/opt/pihole/updatecheck.sh
/opt/pihole/updatecheck.sh x remote
echo -e " ${INFO} Local version file information updated."
fi

View File

@@ -8,23 +8,6 @@
# This file is copyright under the latest version of the EUPL.
# Please see LICENSE file for your rights under this license.
# Credit: https://stackoverflow.com/a/46324904
function json_extract() {
local key=$1
local json=$2
local string_regex='"([^"\]|\\.)*"'
local number_regex='-?(0|[1-9][0-9]*)(\.[0-9]+)?([eE][+-]?[0-9]+)?'
local value_regex="${string_regex}|${number_regex}|true|false|null"
local pair_regex="\"${key}\"[[:space:]]*:[[:space:]]*(${value_regex})"
if [[ ${json} =~ ${pair_regex} ]]; then
echo $(sed 's/^"\|"$//g' <<< "${BASH_REMATCH[1]}")
else
return 1
fi
}
function get_local_branch() {
# Return active branch
cd "${1}" 2> /dev/null || return 1
@@ -32,63 +15,119 @@ function get_local_branch() {
}
function get_local_version() {
# Return active branch
# Return active version
cd "${1}" 2> /dev/null || return 1
git describe --long --dirty --tags 2> /dev/null || return 1
git describe --tags --always 2> /dev/null || return 1
}
function get_local_hash() {
cd "${1}" 2> /dev/null || return 1
git rev-parse --short HEAD || return 1
}
function get_remote_version() {
curl -s "https://api.github.com/repos/pi-hole/${1}/releases/latest" 2> /dev/null | jq --raw-output .tag_name || return 1
}
function get_remote_hash(){
git ls-remote "https://github.com/pi-hole/${1}" --tags "${2}" | awk '{print substr($0, 0,8);}' || return 1
}
# Source the setupvars config file
# shellcheck disable=SC1091
. /etc/pihole/setupVars.conf
if [[ "$2" == "remote" ]]; then
# Source the utils file for addOrEditKeyValPair()
# shellcheck disable=SC1091
. /opt/pihole/utils.sh
if [[ "$3" == "reboot" ]]; then
# Remove the below three legacy files if they exist
rm -f "/etc/pihole/GitHubVersions"
rm -f "/etc/pihole/localbranches"
rm -f "/etc/pihole/localversions"
# Create new versions file if it does not exist
VERSION_FILE="/etc/pihole/versions"
touch "${VERSION_FILE}"
chmod 644 "${VERSION_FILE}"
# if /pihole.docker.tag file exists, we will use it's value later in this script
DOCKER_TAG=$(cat /pihole.docker.tag 2>/dev/null)
regex='^([0-9]+\.){1,2}(\*|[0-9]+)(-.*)?$|(^nightly$)|(^dev.*$)'
if [[ ! "${DOCKER_TAG}" =~ $regex ]]; then
# DOCKER_TAG does not match the pattern (see https://regex101.com/r/RsENuz/1), so unset it.
unset DOCKER_TAG
fi
# used in cronjob
if [[ "$1" == "reboot" ]]; then
sleep 30
fi
fi
GITHUB_VERSION_FILE="/etc/pihole/GitHubVersions"
GITHUB_CORE_VERSION="$(json_extract tag_name "$(curl -s 'https://api.github.com/repos/pi-hole/pi-hole/releases/latest' 2> /dev/null)")"
echo -n "${GITHUB_CORE_VERSION}" > "${GITHUB_VERSION_FILE}"
chmod 644 "${GITHUB_VERSION_FILE}"
# get Core versions
if [[ "${INSTALL_WEB_INTERFACE}" == true ]]; then
GITHUB_WEB_VERSION="$(json_extract tag_name "$(curl -s 'https://api.github.com/repos/pi-hole/AdminLTE/releases/latest' 2> /dev/null)")"
echo -n " ${GITHUB_WEB_VERSION}" >> "${GITHUB_VERSION_FILE}"
fi
CORE_VERSION="$(get_local_version /etc/.pihole)"
addOrEditKeyValPair "${VERSION_FILE}" "CORE_VERSION" "${CORE_VERSION}"
GITHUB_FTL_VERSION="$(json_extract tag_name "$(curl -s 'https://api.github.com/repos/pi-hole/FTL/releases/latest' 2> /dev/null)")"
echo -n " ${GITHUB_FTL_VERSION}" >> "${GITHUB_VERSION_FILE}"
CORE_BRANCH="$(get_local_branch /etc/.pihole)"
addOrEditKeyValPair "${VERSION_FILE}" "CORE_BRANCH" "${CORE_BRANCH}"
else
CORE_HASH="$(get_local_hash /etc/.pihole)"
addOrEditKeyValPair "${VERSION_FILE}" "CORE_HASH" "${CORE_HASH}"
LOCAL_BRANCH_FILE="/etc/pihole/localbranches"
GITHUB_CORE_VERSION="$(get_remote_version pi-hole)"
addOrEditKeyValPair "${VERSION_FILE}" "GITHUB_CORE_VERSION" "${GITHUB_CORE_VERSION}"
CORE_BRANCH="$(get_local_branch /etc/.pihole)"
echo -n "${CORE_BRANCH}" > "${LOCAL_BRANCH_FILE}"
chmod 644 "${LOCAL_BRANCH_FILE}"
GITHUB_CORE_HASH="$(get_remote_hash pi-hole "${CORE_BRANCH}")"
addOrEditKeyValPair "${VERSION_FILE}" "GITHUB_CORE_HASH" "${GITHUB_CORE_HASH}"
if [[ "${INSTALL_WEB_INTERFACE}" == true ]]; then
WEB_BRANCH="$(get_local_branch /var/www/html/admin)"
echo -n " ${WEB_BRANCH}" >> "${LOCAL_BRANCH_FILE}"
fi
FTL_BRANCH="$(pihole-FTL branch)"
echo -n " ${FTL_BRANCH}" >> "${LOCAL_BRANCH_FILE}"
# get Web versions
LOCAL_VERSION_FILE="/etc/pihole/localversions"
if [[ "${INSTALL_WEB_INTERFACE}" == true ]]; then
CORE_VERSION="$(get_local_version /etc/.pihole)"
echo -n "${CORE_VERSION}" > "${LOCAL_VERSION_FILE}"
chmod 644 "${LOCAL_VERSION_FILE}"
WEB_VERSION="$(get_local_version /var/www/html/admin)"
addOrEditKeyValPair "${VERSION_FILE}" "WEB_VERSION" "${WEB_VERSION}"
if [[ "${INSTALL_WEB_INTERFACE}" == true ]]; then
WEB_VERSION="$(get_local_version /var/www/html/admin)"
echo -n " ${WEB_VERSION}" >> "${LOCAL_VERSION_FILE}"
fi
WEB_BRANCH="$(get_local_branch /var/www/html/admin)"
addOrEditKeyValPair "${VERSION_FILE}" "WEB_BRANCH" "${WEB_BRANCH}"
FTL_VERSION="$(pihole-FTL version)"
echo -n " ${FTL_VERSION}" >> "${LOCAL_VERSION_FILE}"
WEB_HASH="$(get_local_hash /var/www/html/admin)"
addOrEditKeyValPair "${VERSION_FILE}" "WEB_HASH" "${WEB_HASH}"
GITHUB_WEB_VERSION="$(get_remote_version AdminLTE)"
addOrEditKeyValPair "${VERSION_FILE}" "GITHUB_WEB_VERSION" "${GITHUB_WEB_VERSION}"
GITHUB_WEB_HASH="$(get_remote_hash AdminLTE "${WEB_BRANCH}")"
addOrEditKeyValPair "${VERSION_FILE}" "GITHUB_WEB_HASH" "${GITHUB_WEB_HASH}"
fi
# get FTL versions
FTL_VERSION="$(pihole-FTL version)"
addOrEditKeyValPair "${VERSION_FILE}" "FTL_VERSION" "${FTL_VERSION}"
FTL_BRANCH="$(pihole-FTL branch)"
addOrEditKeyValPair "${VERSION_FILE}" "FTL_BRANCH" "${FTL_BRANCH}"
FTL_HASH="$(pihole-FTL --hash)"
addOrEditKeyValPair "${VERSION_FILE}" "FTL_HASH" "${FTL_HASH}"
GITHUB_FTL_VERSION="$(get_remote_version FTL)"
addOrEditKeyValPair "${VERSION_FILE}" "GITHUB_FTL_VERSION" "${GITHUB_FTL_VERSION}"
GITHUB_FTL_HASH="$(get_remote_hash FTL "${FTL_BRANCH}")"
addOrEditKeyValPair "${VERSION_FILE}" "GITHUB_FTL_HASH" "${GITHUB_FTL_HASH}"
# get Docker versions
if [[ "${DOCKER_TAG}" ]]; then
addOrEditKeyValPair "${VERSION_FILE}" "DOCKER_VERSION" "${DOCKER_TAG}"
GITHUB_DOCKER_VERSION="$(get_remote_version docker-pi-hole)"
addOrEditKeyValPair "${VERSION_FILE}" "GITHUB_DOCKER_VERSION" "${GITHUB_DOCKER_VERSION}"
fi

View File

@@ -31,9 +31,12 @@ addOrEditKeyValPair() {
local key="${2}"
local value="${3}"
# touch file to prevent grep error if file does not exist yet
touch "${file}"
if grep -q "^${key}=" "${file}"; then
# Key already exists in file, modify the value
sed -i "/^${key}=/c\\${key}=${value}" "${file}"
# Key already exists in file, modify the value
sed -i "/^${key}=/c\\${key}=${value}" "${file}"
else
# Key does not already exist, add it and it's value
echo "${key}=${value}" >> "${file}"
@@ -51,9 +54,12 @@ addKey(){
local file="${1}"
local key="${2}"
# touch file to prevent grep error if file does not exist yet
touch "${file}"
if ! grep -q "^${key}" "${file}"; then
# Key does not exist, add it.
echo "${key}" >> "${file}"
# Key does not exist, add it.
echo "${key}" >> "${file}"
fi
}
@@ -70,29 +76,68 @@ removeKey() {
sed -i "/^${key}/d" "${file}"
}
#######################
# returns FTL's current telnet API port
#######################
# returns FTL's current telnet API port based on the setting in /etc/pihole-FTL.conf
########################
getFTLAPIPort(){
local FTLCONFFILE="/etc/pihole/pihole-FTL.conf"
local DEFAULT_PORT_FILE="/run/pihole-FTL.port"
local DEFAULT_FTL_PORT=4711
local PORTFILE
local ftl_api_port
local FTLCONFFILE="/etc/pihole/pihole-FTL.conf"
local DEFAULT_FTL_PORT=4711
local ftl_api_port
if [ -f "$FTLCONFFILE" ]; then
# if PORTFILE is not set in pihole-FTL.conf, use the default path
PORTFILE="$( (grep "^PORTFILE=" $FTLCONFFILE || echo "$DEFAULT_PORT_FILE") | cut -d"=" -f2-)"
fi
if [ -s "$FTLCONFFILE" ]; then
# if FTLPORT is not set in pihole-FTL.conf, use the default port
ftl_api_port="$({ grep '^FTLPORT=' "${FTLCONFFILE}" || echo "${DEFAULT_FTL_PORT}"; } | cut -d'=' -f2-)"
# Exploit prevention: set the port to the default port if there is malicious (non-numeric)
# content set in pihole-FTL.conf
expr "${ftl_api_port}" : "[^[:digit:]]" > /dev/null && ftl_api_port="${DEFAULT_FTL_PORT}"
else
# if there is no pihole-FTL.conf, use the default port
ftl_api_port="${DEFAULT_FTL_PORT}"
fi
if [ -s "$PORTFILE" ]; then
# -s: FILE exists and has a size greater than zero
ftl_api_port=$(cat "${PORTFILE}")
# Exploit prevention: unset the variable if there is malicious content
# Verify that the value read from the file is numeric
expr "$ftl_api_port" : "[^[:digit:]]" > /dev/null && unset ftl_api_port
fi
# echo the port found in the portfile or default to the default port
echo "${ftl_api_port:=$DEFAULT_FTL_PORT}"
echo "${ftl_api_port}"
}
#######################
# returns path of FTL's PID file
#######################
getFTLPIDFile() {
local FTLCONFFILE="/etc/pihole/pihole-FTL.conf"
local DEFAULT_PID_FILE="/run/pihole-FTL.pid"
local FTL_PID_FILE
if [ -s "${FTLCONFFILE}" ]; then
# if PIDFILE is not set in pihole-FTL.conf, use the default path
FTL_PID_FILE="$({ grep '^PIDFILE=' "${FTLCONFFILE}" || echo "${DEFAULT_PID_FILE}"; } | cut -d'=' -f2-)"
else
# if there is no pihole-FTL.conf, use the default path
FTL_PID_FILE="${DEFAULT_PID_FILE}"
fi
echo "${FTL_PID_FILE}"
}
#######################
# returns FTL's PID based on the content of the pihole-FTL.pid file
#
# Takes one argument: path to pihole-FTL.pid
# Example getFTLPID "/run/pihole-FTL.pid"
#######################
getFTLPID() {
local FTL_PID_FILE="${1}"
local FTL_PID
if [ -s "${FTL_PID_FILE}" ]; then
# -s: FILE exists and has a size greater than zero
FTL_PID="$(cat "${FTL_PID_FILE}")"
# Exploit prevention: unset the variable if there is malicious content
# Verify that the value read from the file is numeric
expr "${FTL_PID}" : "[^[:digit:]]" > /dev/null && unset FTL_PID
fi
# If FTL is not running, or the PID file contains malicious stuff, substitute
# negative PID to signal this
FTL_PID=${FTL_PID:=-1}
echo "${FTL_PID}"
}

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env bash
#!/usr/bin/env sh
# Pi-hole: A black hole for Internet advertisements
# (c) 2017 Pi-hole, LLC (https://pi-hole.net)
# Network-wide ad blocking via your own hardware.
@@ -8,178 +8,104 @@
# This file is copyright under the latest version of the EUPL.
# Please see LICENSE file for your rights under this license.
# Variables
DEFAULT="-1"
COREGITDIR="/etc/.pihole/"
WEBGITDIR="/var/www/html/admin/"
# Source the setupvars config file
# shellcheck disable=SC1091
source /etc/pihole/setupVars.conf
. /etc/pihole/setupVars.conf
# Source the versions file poupulated by updatechecker.sh
cachedVersions="/etc/pihole/versions"
if [ -f ${cachedVersions} ]; then
# shellcheck disable=SC1090
. "$cachedVersions"
else
echo "Could not find /etc/pihole/versions. Running update now."
pihole updatechecker
# shellcheck disable=SC1090
. "$cachedVersions"
fi
getLocalVersion() {
# FTL requires a different method
if [[ "$1" == "FTL" ]]; then
pihole-FTL version
return 0
fi
# Get the tagged version of the local repository
local directory="${1}"
local version
cd "${directory}" 2> /dev/null || { echo "${DEFAULT}"; return 1; }
version=$(git describe --tags --always || echo "$DEFAULT")
if [[ "${version}" =~ ^v ]]; then
echo "${version}"
elif [[ "${version}" == "${DEFAULT}" ]]; then
echo "ERROR"
return 1
else
echo "Untagged"
fi
return 0
case ${1} in
"Pi-hole" ) echo "${CORE_VERSION:=N/A}";;
"AdminLTE" ) [ "${INSTALL_WEB_INTERFACE}" = true ] && echo "${WEB_VERSION:=N/A}";;
"FTL" ) echo "${FTL_VERSION:=N/A}";;
esac
}
getLocalHash() {
# Local FTL hash does not exist on filesystem
if [[ "$1" == "FTL" ]]; then
echo "N/A"
return 0
fi
# Get the short hash of the local repository
local directory="${1}"
local hash
cd "${directory}" 2> /dev/null || { echo "${DEFAULT}"; return 1; }
hash=$(git rev-parse --short HEAD || echo "$DEFAULT")
if [[ "${hash}" == "${DEFAULT}" ]]; then
echo "ERROR"
return 1
else
echo "${hash}"
fi
return 0
case ${1} in
"Pi-hole" ) echo "${CORE_HASH:=N/A}";;
"AdminLTE" ) [ "${INSTALL_WEB_INTERFACE}" = true ] && echo "${WEB_HASH:=N/A}";;
"FTL" ) echo "${FTL_HASH:=N/A}";;
esac
}
getRemoteHash(){
# Remote FTL hash is not applicable
if [[ "$1" == "FTL" ]]; then
echo "N/A"
return 0
fi
local daemon="${1}"
local branch="${2}"
hash=$(git ls-remote --heads "https://github.com/pi-hole/${daemon}" | \
awk -v bra="$branch" '$0~bra {print substr($0,0,8);exit}')
if [[ -n "$hash" ]]; then
echo "$hash"
else
echo "ERROR"
return 1
fi
return 0
case ${1} in
"Pi-hole" ) echo "${GITHUB_CORE_HASH:=N/A}";;
"AdminLTE" ) [ "${INSTALL_WEB_INTERFACE}" = true ] && echo "${GITHUB_WEB_HASH:=N/A}";;
"FTL" ) echo "${GITHUB_FTL_HASH:=N/A}";;
esac
}
getRemoteVersion(){
# Get the version from the remote origin
local daemon="${1}"
local version
local cachedVersions
local arrCache
cachedVersions="/etc/pihole/GitHubVersions"
#If the above file exists, then we can read from that. Prevents overuse of GitHub API
if [[ -f "$cachedVersions" ]]; then
IFS=' ' read -r -a arrCache < "$cachedVersions"
case $daemon in
"pi-hole" ) echo "${arrCache[0]}";;
"AdminLTE" ) [[ "${INSTALL_WEB_INTERFACE}" == true ]] && echo "${arrCache[1]}";;
"FTL" ) [[ "${INSTALL_WEB_INTERFACE}" == true ]] && echo "${arrCache[2]}" || echo "${arrCache[1]}";;
esac
return 0
fi
version=$(curl --silent --fail "https://api.github.com/repos/pi-hole/${daemon}/releases/latest" | \
awk -F: '$1 ~/tag_name/ { print $2 }' | \
tr -cd '[[:alnum:]]._-')
if [[ "${version}" =~ ^v ]]; then
echo "${version}"
else
echo "ERROR"
return 1
fi
return 0
case ${1} in
"Pi-hole" ) echo "${GITHUB_CORE_VERSION:=N/A}";;
"AdminLTE" ) [ "${INSTALL_WEB_INTERFACE}" = true ] && echo "${GITHUB_WEB_VERSION:=N/A}";;
"FTL" ) echo "${GITHUB_FTL_VERSION:=N/A}";;
esac
}
getLocalBranch(){
# Get the checked out branch of the local directory
local directory="${1}"
local branch
# Local FTL btranch is stored in /etc/pihole/ftlbranch
if [[ "$1" == "FTL" ]]; then
branch="$(pihole-FTL branch)"
else
cd "${directory}" 2> /dev/null || { echo "${DEFAULT}"; return 1; }
branch=$(git rev-parse --abbrev-ref HEAD || echo "$DEFAULT")
fi
if [[ ! "${branch}" =~ ^v ]]; then
if [[ "${branch}" == "master" ]]; then
echo ""
elif [[ "${branch}" == "HEAD" ]]; then
echo "in detached HEAD state at "
else
echo "${branch} "
fi
else
# Branch started in "v"
echo "release "
fi
return 0
case ${1} in
"Pi-hole" ) echo "${CORE_BRANCH:=N/A}";;
"AdminLTE" ) [ "${INSTALL_WEB_INTERFACE}" = true ] && echo "${WEB_BRANCH:=N/A}";;
"FTL" ) echo "${FTL_BRANCH:=N/A}";;
esac
}
versionOutput() {
if [[ "$1" == "AdminLTE" && "${INSTALL_WEB_INTERFACE}" != true ]]; then
if [ "$1" = "AdminLTE" ] && [ "${INSTALL_WEB_INTERFACE}" != true ]; then
echo " WebAdmin not installed"
return 1
fi
[[ "$1" == "pi-hole" ]] && GITDIR=$COREGITDIR
[[ "$1" == "AdminLTE" ]] && GITDIR=$WEBGITDIR
[[ "$1" == "FTL" ]] && GITDIR="FTL"
[[ "$2" == "-c" ]] || [[ "$2" == "--current" ]] || [[ -z "$2" ]] && current=$(getLocalVersion $GITDIR) && branch=$(getLocalBranch $GITDIR)
[[ "$2" == "-l" ]] || [[ "$2" == "--latest" ]] || [[ -z "$2" ]] && latest=$(getRemoteVersion "$1")
if [[ "$2" == "-h" ]] || [[ "$2" == "--hash" ]]; then
[[ "$3" == "-c" ]] || [[ "$3" == "--current" ]] || [[ -z "$3" ]] && curHash=$(getLocalHash "$GITDIR") && branch=$(getLocalBranch $GITDIR)
[[ "$3" == "-l" ]] || [[ "$3" == "--latest" ]] || [[ -z "$3" ]] && latHash=$(getRemoteHash "$1" "$(cd "$GITDIR" 2> /dev/null && git rev-parse --abbrev-ref HEAD)")
[ "$2" = "-c" ] || [ "$2" = "--current" ] || [ -z "$2" ] && current=$(getLocalVersion "${1}") && branch=$(getLocalBranch "${1}")
[ "$2" = "-l" ] || [ "$2" = "--latest" ] || [ -z "$2" ] && latest=$(getRemoteVersion "${1}")
if [ "$2" = "--hash" ]; then
[ "$3" = "-c" ] || [ "$3" = "--current" ] || [ -z "$3" ] && curHash=$(getLocalHash "${1}") && branch=$(getLocalBranch "${1}")
[ "$3" = "-l" ] || [ "$3" = "--latest" ] || [ -z "$3" ] && latHash=$(getRemoteHash "${1}") && branch=$(getLocalBranch "${1}")
fi
if [[ -n "$current" ]] && [[ -n "$latest" ]]; then
output="${1^} version is $branch$current (Latest: $latest)"
elif [[ -n "$current" ]] && [[ -z "$latest" ]]; then
output="Current ${1^} version is $branch$current"
elif [[ -z "$current" ]] && [[ -n "$latest" ]]; then
output="Latest ${1^} version is $latest"
elif [[ "$curHash" == "N/A" ]] || [[ "$latHash" == "N/A" ]]; then
output="${1^} hash is not applicable"
elif [[ -n "$curHash" ]] && [[ -n "$latHash" ]]; then
output="${1^} hash is $curHash (Latest: $latHash)"
elif [[ -n "$curHash" ]] && [[ -z "$latHash" ]]; then
output="Current ${1^} hash is $curHash"
elif [[ -z "$curHash" ]] && [[ -n "$latHash" ]]; then
output="Latest ${1^} hash is $latHash"
# We do not want to show the branch name when we are on master,
# blank out the variable in this case
if [ "$branch" = "master" ]; then
branch=""
else
branch="$branch "
fi
if [ -n "$current" ] && [ -n "$latest" ]; then
output="${1} version is $branch$current (Latest: $latest)"
elif [ -n "$current" ] && [ -z "$latest" ]; then
output="Current ${1} version is $branch$current"
elif [ -z "$current" ] && [ -n "$latest" ]; then
output="Latest ${1} version is $latest"
elif [ -n "$curHash" ] && [ -n "$latHash" ]; then
output="Local ${1} hash is $curHash (Remote: $latHash)"
elif [ -n "$curHash" ] && [ -z "$latHash" ]; then
output="Current local ${1} hash is $curHash"
elif [ -z "$curHash" ] && [ -n "$latHash" ]; then
output="Latest remote ${1} hash is $latHash"
elif [ -z "$curHash" ] && [ -z "$latHash" ]; then
output="Hashes for ${1} not available"
else
errorOutput
return 1
fi
[[ -n "$output" ]] && echo " $output"
[ -n "$output" ] && echo " $output"
}
errorOutput() {
@@ -188,9 +114,9 @@ errorOutput() {
}
defaultOutput() {
versionOutput "pi-hole" "$@"
versionOutput "Pi-hole" "$@"
if [[ "${INSTALL_WEB_INTERFACE}" == true ]]; then
if [ "${INSTALL_WEB_INTERFACE}" = true ]; then
versionOutput "AdminLTE" "$@"
fi
@@ -216,7 +142,7 @@ Options:
}
case "${1}" in
"-p" | "--pihole" ) shift; versionOutput "pi-hole" "$@";;
"-p" | "--pihole" ) shift; versionOutput "Pi-hole" "$@";;
"-a" | "--admin" ) shift; versionOutput "AdminLTE" "$@";;
"-f" | "--ftl" ) shift; versionOutput "FTL" "$@";;
"-h" | "--help" ) helpFunc;;

View File

@@ -24,8 +24,8 @@ readonly gravityDBfile="/etc/pihole/gravity.db"
# Source install script for ${setupVars}, ${PI_HOLE_BIN_DIR} and valid_ip()
readonly PI_HOLE_FILES_DIR="/etc/.pihole"
# shellcheck disable=SC2034 # used in basic-install
PH_TEST="true"
# shellcheck disable=SC2034 # used in basic-install to source the script without running it
SKIP_INSTALL="true"
source "${PI_HOLE_FILES_DIR}/automated install/basic-install.sh"
utilsfile="/opt/pihole/utils.sh"
@@ -46,7 +46,6 @@ Options:
-c, celsius Set Celsius as preferred temperature unit
-f, fahrenheit Set Fahrenheit as preferred temperature unit
-k, kelvin Set Kelvin as preferred temperature unit
-e, email Set an administrative contact address for the Block Page
-h, --help Show this help dialog
-i, interface Specify dnsmasq's interface listening behavior
-l, privacylevel Set privacy level (0 = lowest, 3 = highest)
@@ -394,13 +393,8 @@ ProcessDHCPSettings() {
if [[ "${DHCP_LEASETIME}" == "0" ]]; then
leasetime="infinite"
elif [[ "${DHCP_LEASETIME}" == "" ]]; then
leasetime="24"
addOrEditKeyValPair "${setupVars}" "DHCP_LEASETIME" "${leasetime}"
elif [[ "${DHCP_LEASETIME}" == "24h" ]]; then
#Installation is affected by known bug, introduced in a previous version.
#This will automatically clean up setupVars.conf and remove the unnecessary "h"
leasetime="24"
addOrEditKeyValPair "${setupVars}" "DHCP_LEASETIME" "${leasetime}"
leasetime="24h"
addOrEditKeyValPair "${setupVars}" "DHCP_LEASETIME" "24"
else
leasetime="${DHCP_LEASETIME}h"
fi
@@ -568,37 +562,6 @@ RemoveDHCPStaticAddress() {
}
SetAdminEmail() {
if [[ "${1}" == "-h" ]] || [[ "${1}" == "--help" ]]; then
echo "Usage: pihole -a email <address>
Example: 'pihole -a email admin@address.com'
Set an administrative contact address for the Block Page
Options:
\"\" Empty: Remove admin contact
-h, --help Show this help dialog"
exit 0
fi
if [[ -n "${args[2]}" ]]; then
# Sanitize email address in case of security issues
# Regex from https://stackoverflow.com/a/2138832/4065967
local regex
regex="^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}\$"
if [[ ! "${args[2]}" =~ ${regex} ]]; then
echo -e " ${CROSS} Invalid email address"
exit 0
fi
addOrEditKeyValPair "${setupVars}" "ADMIN_EMAIL" "${args[2]}"
echo -e " ${TICK} Setting admin contact to ${args[2]}"
else
addOrEditKeyValPair "${setupVars}" "ADMIN_EMAIL" ""
echo -e " ${TICK} Removing admin contact"
fi
}
SetListeningMode() {
source "${setupVars}"
@@ -664,6 +627,14 @@ checkDomain()
echo "${validDomain}"
}
escapeDots()
{
# SC suggest bashism ${variable//search/replace}
# shellcheck disable=SC2001
escaped=$(echo "$1" | sed 's/\./\\./g')
echo "${escaped}"
}
addAudit()
{
shift # skip "-a"
@@ -739,6 +710,7 @@ RemoveCustomDNSAddress() {
validHost="$(checkDomain "${host}")"
if [[ -n "${validHost}" ]]; then
if valid_ip "${ip}" || valid_ip6 "${ip}" ; then
validHost=$(escapeDots "${validHost}")
sed -i "/^${ip} ${validHost}$/Id" "${dnscustomfile}"
else
echo -e " ${CROSS} Invalid IP has been passed"
@@ -766,7 +738,12 @@ AddCustomCNAMERecord() {
if [[ -n "${validDomain}" ]]; then
validTarget="$(checkDomain "${target}")"
if [[ -n "${validTarget}" ]]; then
echo "cname=${validDomain},${validTarget}" >> "${dnscustomcnamefile}"
if [ "${validDomain}" = "${validTarget}" ]; then
echo " ${CROSS} Domain and target are the same. This would cause a DNS loop."
exit 1
else
echo "cname=${validDomain},${validTarget}" >> "${dnscustomcnamefile}"
fi
else
echo " ${CROSS} Invalid Target Passed!"
exit 1
@@ -792,7 +769,9 @@ RemoveCustomCNAMERecord() {
if [[ -n "${validDomain}" ]]; then
validTarget="$(checkDomain "${target}")"
if [[ -n "${validTarget}" ]]; then
sed -i "/cname=${validDomain},${validTarget}$/Id" "${dnscustomcnamefile}"
validDomain=$(escapeDots "${validDomain}")
validTarget=$(escapeDots "${validTarget}")
sed -i "/^cname=${validDomain},${validTarget}$/Id" "${dnscustomcnamefile}"
else
echo " ${CROSS} Invalid Target Passed!"
exit 1
@@ -847,7 +826,6 @@ main() {
"-h" | "--help" ) helpFunc;;
"addstaticdhcp" ) AddDHCPStaticAddress;;
"removestaticdhcp" ) RemoveDHCPStaticAddress;;
"-e" | "email" ) SetAdminEmail "$3";;
"-i" | "interface" ) SetListeningMode "$@";;
"-t" | "teleporter" ) Teleporter;;
"adlist" ) CustomizeAdLists;;

View File

@@ -9,48 +9,10 @@
# Description: Enable service provided by pihole-FTL daemon
### END INIT INFO
# Global variables
FTLCONFFILE="/etc/pihole/pihole-FTL.conf"
DEFAULT_PID_FILE="/run/pihole-FTL.pid"
DEFAULT_PORT_FILE="/run/pihole-FTL.port"
FTL_PID=''
# Get the file path of the pihole-FTL.pid file
getFTLPIDFile() {
if [ -s "${FTLCONFFILE}" ]; then
# if PIDFILE is not set in pihole-FTL.conf, use the default path
FTL_PID_FILE="$({ grep '^PIDFILE=' "${FTLCONFFILE}" || echo "${DEFAULT_PID_FILE}"; } | cut -d'=' -f2-)"
else
# if there is no pihole-FTL.conf, use the default path
FTL_PID_FILE="${DEFAULT_PID_FILE}"
fi
}
# Get the PID of the FTL process based on the content of the pihole-FTL.pid file
getFTLPID() {
if [ -s "${FTL_PID_FILE}" ]; then
# -s: FILE exists and has a size greater than zero
FTL_PID="$(cat "${FTL_PID_FILE}")"
# Exploit prevention: unset the variable if there is malicious content
# Verify that the value read from the file is numeric
expr "${FTL_PID}" : "[^[:digit:]]" > /dev/null && unset FTL_PID
fi
# If FTL is not running, or the PID file contains malicious stuff, substitute
# negative PID to signal this
FTL_PID=${FTL_PID:=-1}
}
# Get the file path of the pihole-FTL.port file
getFTLPortFile() {
if [ -s "${FTLCONFFILE}" ]; then
# if PORTFILE is not set in pihole-FTL.conf, use the default path
FTL_PORT_FILE="$({ grep '^PORTFILE=' "${FTLCONFFILE}" || echo "${DEFAULT_PORT_FILE}"; } | cut -d'=' -f2-)"
else
# if there is no pihole-FTL.conf, use the default path
FTL_PORT_FILE="${DEFAULT_PORT_FILE}"
fi
}
#source utils.sh for getFTLPIDFile(), getFTLPID ()
PI_HOLE_SCRIPT_DIR="/opt/pihole"
utilsfile="${PI_HOLE_SCRIPT_DIR}/utils.sh"
. "${utilsfile}"
is_running() {
@@ -68,8 +30,7 @@ start() {
else
# Touch files to ensure they exist (create if non-existing, preserve if existing)
mkdir -pm 0755 /run/pihole /var/log/pihole
[ ! -f "${FTL_PID_FILE}" ] && install -m 644 -o pihole -g pihole /dev/null "${FTL_PID_FILE}"
[ ! -f "${FTL_PORT_FILE}" ] && install -m 644 -o pihole -g pihole /dev/null "${FTL_PORT_FILE}"
[ ! -f "${FTL_PID_FILE}" ] && install -D -m 644 -o pihole -g pihole /dev/null "${FTL_PID_FILE}"
[ ! -f /var/log/pihole/FTL.log ] && install -m 644 -o pihole -g pihole /dev/null /var/log/pihole/FTL.log
[ ! -f /var/log/pihole/pihole.log ] && install -m 640 -o pihole -g pihole /dev/null /var/log/pihole/pihole.log
[ ! -f /etc/pihole/dhcp.leases ] && install -m 644 -o pihole -g pihole /dev/null /etc/pihole/dhcp.leases
@@ -96,10 +57,10 @@ start() {
fi
if setcap CAP_NET_BIND_SERVICE,CAP_NET_RAW,CAP_NET_ADMIN,CAP_SYS_NICE,CAP_IPC_LOCK,CAP_CHOWN+eip "/usr/bin/pihole-FTL"; then
su -s /bin/sh -c "/usr/bin/pihole-FTL" pihole
su -s /bin/sh -c "/usr/bin/pihole-FTL" pihole || exit $?
else
echo "Warning: Starting pihole-FTL as root because setting capabilities is not supported on this system"
/usr/bin/pihole-FTL
/usr/bin/pihole-FTL || exit $?
fi
echo
fi
@@ -129,7 +90,7 @@ stop() {
echo "Not running"
fi
# Cleanup
rm -f /run/pihole/FTL.sock /dev/shm/FTL-* "${FTL_PID_FILE}" "${FTL_PORT_FILE}"
rm -f /run/pihole/FTL.sock /dev/shm/FTL-* "${FTL_PID_FILE}"
echo
}
@@ -148,11 +109,10 @@ status() {
### main logic ###
# Get file paths
getFTLPIDFile
getFTLPortFile
FTL_PID_FILE="$(getFTLPIDFile)"
# Get FTL's current PID
getFTLPID
FTL_PID="$(getFTLPID ${FTL_PID_FILE})"
case "$1" in
stop)

View File

@@ -28,9 +28,6 @@
@reboot root /usr/sbin/logrotate --state /var/lib/logrotate/pihole /etc/pihole/logrotate
# Pi-hole: Grab local version and branch every 10 minutes
*/10 * * * * root PATH="$PATH:/usr/sbin:/usr/local/bin/" pihole updatechecker local
# Pi-hole: Grab remote version every 24 hours
59 17 * * * root PATH="$PATH:/usr/sbin:/usr/local/bin/" pihole updatechecker remote
@reboot root PATH="$PATH:/usr/sbin:/usr/local/bin/" pihole updatechecker remote reboot
# Pi-hole: Grab remote and local version every 24 hours
59 17 * * * root PATH="$PATH:/usr/sbin:/usr/local/bin/" pihole updatechecker
@reboot root PATH="$PATH:/usr/sbin:/usr/local/bin/" pihole updatechecker reboot

View File

@@ -15,7 +15,7 @@ _pihole() {
COMPREPLY=( $(compgen -W "${opts_lists}" -- ${cur}) )
;;
"admin")
opts_admin="celsius email fahrenheit interface kelvin password privacylevel"
opts_admin="celsius fahrenheit interface kelvin password privacylevel"
COMPREPLY=( $(compgen -W "${opts_admin}" -- ${cur}) )
;;
"checkout")

View File

@@ -1,455 +0,0 @@
/* Pi-hole: A black hole for Internet advertisements
* (c) 2017 Pi-hole, LLC (https://pi-hole.net)
* Network-wide ad blocking via your own hardware.
*
* This file is copyright under the latest version of the EUPL.
* Please see LICENSE file for your rights under this license. */
/* Text Customisation Options ======> */
.title::before { content: "Website Blocked"; }
.altBtn::before { content: "Why am I here?"; }
.linkPH::before { content: "About Pi-hole"; }
.linkEmail::before { content: "Contact Admin"; }
#bpOutput.add::before { content: "Info"; }
#bpOutput.add::after { content: "The domain is being whitelisted..."; }
#bpOutput.error::before, .unhandled::before { content: "Error"; }
#bpOutput.unhandled::after { content: "An unhandled exception occurred. This may happen when your browser is unable to load jQuery, or when the webserver is denying access to the Pi-hole API."; }
#bpOutput.success::before { content: "Success"; }
#bpOutput.success::after { content: "Website has been whitelisted! You may need to flush your DNS cache"; }
.recentwl::before { content: "This site has been whitelisted. Please flush your DNS cache and/or restart your browser."; }
.unknown::before { content: "This website is not found in any of Pi-hole's blacklists. The reason you have arrived here is unknown."; }
.cname::before { content: "This site is an alias for "; } /* <a href="http://cname.com">cname.com</a> */
.cname::after { content: ", which may be blocked by Pi-hole."; }
.blacklist::before { content: "Manually Blacklisted"; }
.wildcard::before { content: "Manually Blacklisted by Wildcard"; }
.noblock::before { content: "Not found on any Blacklist"; }
#bpBlock::before { content: "Access to the following website has been denied:"; }
#bpFlag::before { content: "This is primarily due to being flagged as:"; }
#bpHelpTxt::before { content: "If you have an ongoing use for this website, please "; }
#bpHelpTxt a::before, #bpHelpTxt span::before { content: "ask the administrator"; }
#bpHelpTxt::after{ content: " of the Pi-hole on this network to have it whitelisted"; }
#bpBack::before { content: "Back to safety"; }
#bpInfo::before { content: "Technical Info"; }
#bpFoundIn::before { content: "This site is found in "; }
#bpFoundIn span::after { content: " of "; }
#bpFoundIn::after { content: " lists:"; }
#bpWhitelist::before { content: "Whitelist"; }
footer span::before { content: "Page generated on "; }
/* Hide whitelisting form entirely */
/* #bpWLButtons { display: none; } */
/* Text Customisation Options <=============================== */
/* http://necolas.github.io/normalize.css ======> */
html { font-family: sans-serif; line-height: 1.15; -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; }
body { margin: 0; }
article, aside, footer, header, nav, section { display: block; }
h1 { font-size: 2em; margin: 0.67em 0; }
figcaption, figure, main { display: block; }
figure { margin: 1em 40px; }
hr { box-sizing: content-box; height: 0; overflow: visible; }
pre { font-family: monospace, monospace; font-size: 1em; }
a { background-color: transparent; -webkit-text-decoration-skip: objects; }
a:active, a:hover { outline-width: 0; }
abbr[title] { border-bottom: none; text-decoration: underline; text-decoration: underline dotted; }
b, strong { font-weight: inherit; }
b, strong { font-weight: bolder; }
code, kbd, samp { font-family: monospace, monospace; font-size: 1em; }
dfn { font-style: italic; }
mark { background-color: #ff0; color: #000; }
small { font-size: 80%; }
sub, sup { font-size: 75%; line-height: 0; position: relative; vertical-align: baseline; }
sub { bottom: -0.25em; }
sup { top: -0.5em; }
audio, video { display: inline-block; }
audio:not([controls]) { display: none; height: 0; }
img { border-style: none; }
svg:not(:root) { overflow: hidden; }
button, input, optgroup, select, textarea { font-family: sans-serif; font-size: 100%; line-height: 1.15; margin: 0; }
button, input { overflow: visible; }
button, select { text-transform: none; }
button, html [type="button"], [type="reset"], [type="submit"] { -webkit-appearance: button; }
button::-moz-focus-inner, [type="button"]::-moz-focus-inner, [type="reset"]::-moz-focus-inner, [type="submit"]::-moz-focus-inner { border-style: none; padding: 0; }
button:-moz-focusring, [type="button"]:-moz-focusring, [type="reset"]:-moz-focusring, [type="submit"]:-moz-focusring { outline: 1px dotted ButtonText; }
fieldset { border: 1px solid #c0c0c0; margin: 0 2px; padding: 0.35em 0.625em 0.75em; }
legend { box-sizing: border-box; color: inherit; display: table; max-width: 100%; padding: 0; white-space: normal; }
progress { display: inline-block; vertical-align: baseline; }
textarea { overflow: auto; }
[type="checkbox"], [type="radio"] { box-sizing: border-box; padding: 0; }
[type="number"]::-webkit-inner-spin-button, [type="number"]::-webkit-outer-spin-button { height: auto; }
[type="search"] { -webkit-appearance: textfield; outline-offset: -2px; }
[type="search"]::-webkit-search-cancel-button, [type="search"]::-webkit-search-decoration { -webkit-appearance: none; }
::-webkit-file-upload-button { -webkit-appearance: button; font: inherit; }
details, menu { display: block; }
summary { display: list-item; }
canvas { display: inline-block; }
template { display: none; }
[hidden] { display: none; }
/* Normalize.css <=============================== */
html { font-size: 62.5%; }
a { color: #3c8dbc; text-decoration: none; }
a:hover { color: #72afda; text-decoration: underline; }
b { color: rgb(68, 68, 68); }
p { margin: 0; }
label, .buttons a {
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
label, .buttons *:not([disabled]) { cursor: pointer; }
/* Touch device dark tap highlight */
header h1 a, label, .buttons * { -webkit-tap-highlight-color: transparent; }
/* Webkit Focus Glow */
textarea, input, button { outline: none; }
@font-face {
font-family: "Source Sans Pro";
font-style: normal;
font-weight: 400;
font-display: swap;
src: local("Source Sans Pro Regular"), local("SourceSansPro-Regular"),
url("/admin/style/vendor/SourceSansPro/source-sans-pro-v13-latin-regular.woff2") format("woff2"),
url("/admin/style/vendor/SourceSansPro/source-sans-pro-v13-latin-regular.woff") format("woff");
}
@font-face {
font-family: "Source Sans Pro";
font-style: normal;
font-weight: 700;
font-display: swap;
src: local("Source Sans Pro Bold"), local("SourceSansPro-Bold"),
url("/admin/style/vendor/SourceSansPro/source-sans-pro-v13-latin-700.woff2") format("woff2"),
url("/admin/style/vendor/SourceSansPro/source-sans-pro-v13-latin-700.woff") format("woff");
}
body {
background: #dbdbdb url("/admin/img/boxed-bg.jpg") repeat fixed;
color: #333;
font: 1.4rem "Source Sans Pro", "Helvetica Neue", Helvetica, Arial, sans-serif;
line-height: 2.2rem;
}
/* User is greeted with a splash page when browsing to Pi-hole IP address */
#splashpage {
background: #222;
color: rgba(255, 255, 255, 0.7);
text-align: center;
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
}
#splashpage img { margin: 5px; width: 256px; }
#splashpage b { color: inherit; }
#bpWrapper {
margin: 0 auto;
max-width: 1250px;
box-shadow: 0 0 8px rgba(0, 0, 0, 0.5);
}
header {
background: #3c8dbc;
display: table;
position: relative;
width: 100%;
}
header h1, header h1 a, header .spc, header #bpAlt label {
display: table-cell;
color: #fff;
white-space: nowrap;
vertical-align: middle;
height: 50px; /* Must match #bpAbout top value */
}
h1 a {
background-color: rgba(0, 0, 0, 0.1);
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
font-size: 2rem;
font-weight: 400;
min-width: 230px;
text-align: center;
}
h1 a:hover, header #bpAlt:hover { background-color: rgba(0, 0, 0, 0.12); color: inherit; text-decoration: none; }
header .spc { width: 100%; }
header #bpAlt label {
background: url("/admin/img/logo.svg") no-repeat center left 15px;
background-size: 15px 23px;
padding: 0 15px;
text-indent: 30px;
}
[type="checkbox"][id$="Toggle"] { display: none; }
[type="checkbox"][id$="Toggle"]:checked ~ #bpAbout,
[type="checkbox"][id$="Toggle"]:checked ~ #bpMoreInfo {
display: block;
}
html, body {
height: 100%;
}
#pihole_card {
width: 400px;
height: auto;
max-width: 400px;
}
#pihole_card p, #pihole_card a {
font-size: 13pt;
text-align: center;
}
#pihole_logo_splash {
height: auto;
width: 100%;
}
/* Click anywhere else on screen to hide #bpAbout */
#bpAboutToggle:checked {
display: block;
height: 300px; /* VH Fallback */
height: 100vh;
left: 0;
top: 0;
opacity: 0;
position: absolute;
width: 100%;
}
#bpAbout {
background: #3c8dbc;
border-bottom-left-radius: 5px;
border: 1px solid #fff;
border-right-width: 0;
box-shadow: -1px 1px 1px rgba(0, 0, 0, 0.12);
box-sizing: border-box;
display: none;
font-size: 1.7rem;
top: 50px;
position: absolute;
right: 0;
width: 280px;
z-index: 1;
}
.aboutPH {
box-sizing: border-box;
color: rgba(255, 255, 255, 0.8);
display: block;
padding: 10px;
width: 100%;
text-align: center;
}
.aboutImg {
background: url("/admin/img/logo.svg") no-repeat center;
background-size: 90px 90px;
height: 90px;
margin: 0 auto;
padding: 2px;
width: 90px;
}
.aboutPH p { margin: 10px 0; }
.aboutPH small { display: block; font-size: 1.2rem; }
.aboutLink {
background: #fff;
border-top: 1px solid #ddd;
display: table;
font-size: 1.4rem;
text-align: center;
width: 100%;
}
.aboutLink a {
display: table-cell;
padding: 14px;
min-width: 50%;
}
main {
background: #ecf0f5;
font-size: 1.65rem;
padding: 10px;
}
#bpOutput {
background: #00c0ef;
border-radius: 3px;
border: 1px solid rgba(0, 0, 0, 0.1);
color: #fff;
font-size: 1.4rem;
margin-bottom: 10px;
margin-top: 5px;
padding: 15px;
}
#bpOutput::before {
background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='7' height='14' viewBox='0 0 7 14'%3E%3Cpath fill='%23fff' d='M6 11a1.371 1.371 0 011 1v1a1.371 1.371 0 01-1 1H1a1.371 1.371 0 01-1-1v-1a1.371 1.371 0 011-1h1V8H1a1.371 1.371 0 01-1-1V6a1.371 1.371 0 011-1h3a1.371 1.371 0 011 1v5h1zM3.5 0A1.5 1.5 0 112 1.5 1.5 1.5 0 013.5 0z'/%3E%3C/svg%3E") no-repeat center left;
display: block;
font-size: 1.8rem;
text-indent: 15px;
}
#bpOutput.hidden { display: none; }
#bpOutput.success { background: #00a65a; }
#bpOutput.error { background: #dd4b39; }
.blockMsg, .flagMsg {
font: 700 1.8rem Consolas, Courier, monospace;
padding: 5px 10px 10px;
text-indent: 15px;
}
#bpHelpTxt { padding-bottom: 10px; }
.buttons {
border-spacing: 5px 0;
display: table;
width: 100%;
}
.buttons * {
-moz-appearance: none;
-webkit-appearance: none;
border-radius: 3px;
border: 1px solid rgba(0, 0, 0, 0.1);
box-sizing: content-box;
display: table-cell;
font-size: 1.65rem;
margin-right: 5px;
min-height: 20px;
padding: 6px 12px;
position: relative;
text-align: center;
vertical-align: top;
white-space: nowrap;
width: auto;
}
.buttons a:hover { text-decoration: none; }
/* Button hover dark overlay */
.buttons *:not(input):not([disabled]):hover {
background-image: linear-gradient(to bottom, rgba(0, 0, 0, 0.1), rgba(0, 0, 0, 0.1));
color: #fff;
}
/* Button active shadow inset */
.buttons *:not([disabled]):not(input):active {
box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
}
/* Input border color */
.buttons *:not([disabled]):hover, .buttons input:focus {
border-color: rgba(0, 0, 0, 0.25);
}
#bpButtons * { width: 50%; color: #fff; }
#bpBack { background-color: #00a65a; }
#bpInfo { background-color: #3c8dbc; }
#bpWhitelist { background-color: #dd4b39; }
#blockpage .buttons [type="password"][disabled] { color: rgba(0, 0, 0, 1); }
#blockpage .buttons [disabled] { color: rgba(0, 0, 0, 0.55); background-color: #e3e3e3; }
#blockpage .buttons [type="password"]:-ms-input-placeholder { color: rgba(51, 51, 51, 0.8); }
input[type="password"] { font-size: 1.5rem; }
@-webkit-keyframes slidein { from { max-height: 0; opacity: 0; } to { max-height: 300px; opacity: 1; } }
@keyframes slidein { from { max-height: 0; opacity: 0; } to { max-height: 300px; opacity: 1; } }
#bpMoreToggle:checked ~ #bpMoreInfo { display: block; margin-top: 8px; -webkit-animation: slidein 0.05s linear; animation: slidein 0.05s linear; }
#bpMoreInfo { display: none; margin-top: 10px; }
#bpQueryOutput {
font-size: 1.2rem;
line-height: 1.65rem;
margin: 5px 0 0;
overflow: auto;
padding: 0 5px;
-webkit-overflow-scrolling: touch;
}
#bpQueryOutput span { margin-right: 4px; }
#bpWLButtons { width: auto; margin-top: 10px; }
#bpWLButtons * { display: inline-block; }
#bpWLDomain { display: none; }
#bpWLPassword { width: 160px; }
#bpWhitelist { color: #fff; }
footer {
background: #fff;
border-top: 1px solid #d2d6de;
color: #444;
font: 1.2rem Consolas, Courier, monospace;
padding: 8px;
}
/* Responsive Content */
@media only screen and (max-width: 500px) {
h1 a {
font-size: 1.8rem;
min-width: 170px;
}
footer span::before {
content: "Generated ";
}
footer span {
display: block;
}
}
@media only screen and (min-width: 1251px) {
#bpWrapper, footer {
border-radius: 0 0 5px 5px;
}
#bpAbout {
border-right-width: 1px;
}
}
@media only screen and (max-width: 400px) {
#pihole_card {
width: 100%;
height: auto;
}
#pihole_card p, #pihole_card a {
font-size: 100%;
}
}
@media only screen and (max-width: 256px) {
#pihole_logo_splash {
width: 90% !important;
height: auto;
}
}

View File

@@ -1 +0,0 @@
dwc_otg.lpm_enable=0 console=ttyAMA0,115200 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait fbcon=map:10 fbcon=font:VGA8x8 consoleblank=0

View File

@@ -1,17 +0,0 @@
# CONFIGURATION FILE FOR SETUPCON
# Consult the console-setup(5) manual page.
ACTIVE_CONSOLES="/dev/tty[1-6]"
CHARMAP="UTF-8"
# For best results with the Adafruit 2.8 LCD and Pi-hole's chronometer
CODESET="guess"
FONTFACE="Terminus"
FONTSIZE="10x20"
VIDEOMODE=
# The following is an example how to use a braille font
# FONT='lat9w-08.psf.gz brl-8x8.psf'

View File

@@ -11,15 +11,6 @@ $serverName = htmlspecialchars($_SERVER["SERVER_NAME"]);
// Remove external ipv6 brackets if any
$serverName = preg_replace('/^\[(.*)\]$/', '${1}', $serverName);
if (!is_file("/etc/pihole/setupVars.conf"))
die("[ERROR] File not found: <code>/etc/pihole/setupVars.conf</code>");
// Get values from setupVars.conf
$setupVars = parse_ini_file("/etc/pihole/setupVars.conf");
$svPasswd = !empty($setupVars["WEBPASSWORD"]);
$svEmail = (!empty($setupVars["ADMIN_EMAIL"]) && filter_var($setupVars["ADMIN_EMAIL"], FILTER_VALIDATE_EMAIL)) ? $setupVars["ADMIN_EMAIL"] : "";
unset($setupVars);
// Set landing page location, found within /var/www/html/
$landPage = "../landing.php";
@@ -34,31 +25,17 @@ if (!empty($_SERVER["FQDN"])) {
array_push($authorizedHosts, $_SERVER["VIRTUAL_HOST"]);
}
// Set which extension types render as Block Page (Including "" for index.ext)
$validExtTypes = array("asp", "htm", "html", "php", "rss", "xml", "");
// Get extension of current URL
$currentUrlExt = pathinfo($_SERVER["REQUEST_URI"], PATHINFO_EXTENSION);
// Set mobile friendly viewport
$viewPort = '<meta name="viewport" content="width=device-width, initial-scale=1">';
// Set response header
function setHeader($type = "x") {
header("X-Pi-hole: A black hole for Internet advertisements.");
if (isset($type) && $type === "js") header("Content-Type: application/javascript");
}
// Determine block page type
if ($serverName === "pi.hole"
|| (!empty($_SERVER["VIRTUAL_HOST"]) && $serverName === $_SERVER["VIRTUAL_HOST"])) {
// Redirect to Web Interface
exit(header("Location: /admin"));
header("Location: /admin");
exit();
} elseif (filter_var($serverName, FILTER_VALIDATE_IP) || in_array($serverName, $authorizedHosts)) {
// When directly browsing via IP or authorized hostname
// Render splash/landing page based off presence of $landPage file
// Unset variables so as to not be included in $landPage or $splashPage
unset($svPasswd, $svEmail, $authorizedHosts, $validExtTypes, $currentUrlExt);
unset($authorizedHosts);
// If $landPage file is present
if (is_file(getcwd()."/$landPage")) {
unset($serverName, $viewPort); // unset extra variables not to be included in $landpage
@@ -71,347 +48,34 @@ if ($serverName === "pi.hole"
<html lang='en'>
<head>
<meta charset='utf-8'>
$viewPort
<meta name='viewport' content='width=device-width, initial-scale=1'>
<title>● $serverName</title>
<link rel='stylesheet' href='/pihole/blockingpage.css'>
<link rel='shortcut icon' href='/admin/img/favicons/favicon.ico' type='image/x-icon'>
<style>
html, body { height: 100% }
body { margin: 0; font: 13pt "Source Sans Pro", "Helvetica Neue", Helvetica, Arial, sans-serif; }
body { background: #222; color: rgba(255, 255, 255, 0.7); text-align: center; }
p { margin: 0; }
a { color: #3c8dbc; text-decoration: none; }
a:hover { color: #72afda; text-decoration: underline; }
#splashpage { display: flex; align-items: center; justify-content: center; }
#splashpage img { margin: 5px; width: 256px; }
#splashpage b { color: inherit; }
</style>
</head>
<body id='splashpage'>
<div id="pihole_card">
<img src='/admin/img/logo.svg' alt='Pi-hole logo' id="pihole_logo_splash" />
<p>Pi-<strong>hole</strong>: Your black hole for Internet advertisements</p>
<a href='/admin'>Did you mean to go to the admin panel?</a>
<div>
<img src='/admin/img/logo.svg' alt='Pi-hole logo' width='256' height='377'>
<br>
<p>Pi-<strong>hole</strong>: Your black hole for Internet advertisements</p>
<a href='/admin'>Did you mean to go to the admin panel?</a>
</div>
</body>
</html>
EOT;
exit($splashPage);
} elseif ($currentUrlExt === "js") {
// Serve Pi-hole JavaScript for blocked domains requesting JS
exit(setHeader("js").'var x = "Pi-hole: A black hole for Internet advertisements."');
} elseif (strpos($_SERVER["REQUEST_URI"], "?") !== FALSE && isset($_SERVER["HTTP_REFERER"])) {
// Serve blank image upon receiving REQUEST_URI w/ query string & HTTP_REFERRER
// e.g: An iframe of a blocked domain
exit(setHeader().'<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8"><script>window.close();</script>
</head>
<body>
<img src="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=">
</body>
</html>');
} elseif (!in_array($currentUrlExt, $validExtTypes) || substr_count($_SERVER["REQUEST_URI"], "?")) {
// Serve SVG upon receiving non $validExtTypes URL extension or query string
// e.g: Not an iframe of a blocked domain, such as when browsing to a file/query directly
// QoL addition: Allow the SVG to be clicked on in order to quickly show the full Block Page
$blockImg = '<a href="/">
<svg xmlns="http://www.w3.org/2000/svg" width="110" height="16">
<circle cx="8" cy="8" r="7" fill="none" stroke="rgba(152,2,2,.5)" stroke-width="2"/>
<path fill="rgba(152,2,2,.5)" d="M11.526 3.04l1.414 1.415-8.485 8.485-1.414-1.414z"/>
<text x="19.3" y="12" opacity=".3" style="font:11px Arial">
Blocked by Pi-hole
</text>
</svg>
</a>';
exit(setHeader()."<!doctype html>
<html lang='en'>
<head>
<meta charset='utf-8'>
$viewPort
</head>
<body>$blockImg</body>
</html>");
}
/* Start processing Block Page from here */
// Define admin email address text based off $svEmail presence
$bpAskAdmin = !empty($svEmail) ? '<a href="mailto:'.$svEmail.'?subject=Site Blocked: '.$serverName.'"></a>' : "<span/>";
// Get possible non-standard location of FTL's database
$FTLsettings = parse_ini_file("/etc/pihole/pihole-FTL.conf");
if (isset($FTLsettings["GRAVITYDB"])) {
$gravityDBFile = $FTLsettings["GRAVITYDB"];
} else {
$gravityDBFile = "/etc/pihole/gravity.db";
}
// Connect to gravity.db
try {
$db = new SQLite3($gravityDBFile, SQLITE3_OPEN_READONLY);
} catch (Exception $exception) {
die("[ERROR]: Failed to connect to gravity.db");
}
// Get all adlist addresses
$adlistResults = $db->query("SELECT address FROM vw_adlist");
$adlistsUrls = array();
while ($row = $adlistResults->fetchArray()) {
array_push($adlistsUrls, $row[0]);
}
if (empty($adlistsUrls))
die("[ERROR]: There are no adlists enabled");
// Get total number of blocklists (Including Whitelist, Blacklist & Wildcard lists)
$adlistsCount = count($adlistsUrls) + 3;
// Set query timeout
ini_set("default_socket_timeout", 3);
// Logic for querying blocklists
function queryAds($serverName) {
// Determine the time it takes while querying adlists
$preQueryTime = microtime(true)-$_SERVER["REQUEST_TIME_FLOAT"];
// Determine which protocol should be used
$protocol = "http";
if ((isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on') ||
(isset($_SERVER['REQUEST_SCHEME']) && $_SERVER['REQUEST_SCHEME'] === 'https') ||
(isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https')
) {
$protocol = "https";
}
// Format the URL
$queryAdsURL = sprintf(
"%s://127.0.0.1:%s/admin/scripts/pi-hole/php/queryads.php?domain=%s&bp",
$protocol,
$_SERVER["SERVER_PORT"],
$serverName
);
// Request the file and receive the response
$queryAdsFile = file($queryAdsURL, FILE_IGNORE_NEW_LINES);
// $queryAdsFile must be an array (to avoid PHP 8.0+ error)
if (is_array($queryAdsFile)) {
$queryAds = array_values(array_filter(preg_replace("/data:\s+/", "", $queryAdsFile)));
} else {
// if not an array, return an error message
return array("0" => "error", "1" => "<br>(".gettype($queryAdsFile).")<br>".print_r($queryAdsFile, true));
}
$queryTime = sprintf("%.0f", (microtime(true)-$_SERVER["REQUEST_TIME_FLOAT"]) - $preQueryTime);
// Exception Handling
try {
// Define Exceptions
if (strpos($queryAds[0], "No exact results") !== FALSE) {
// Return "none" into $queryAds array
return array("0" => "none");
} else if ($queryTime >= ini_get("default_socket_timeout")) {
// Connection Timeout
throw new Exception ("Connection timeout (".ini_get("default_socket_timeout")."s)");
} elseif (!strpos($queryAds[0], ".") !== false) {
// Unknown $queryAds output
throw new Exception ("Unhandled error message (<code>$queryAds[0]</code>)");
}
return $queryAds;
} catch (Exception $e) {
// Return exception as array
return array("0" => "error", "1" => $e->getMessage());
}
}
// Get results of queryads.php exact search
$queryAds = queryAds($serverName);
// Pass error through to Block Page
if ($queryAds[0] === "error")
die("[ERROR]: Unable to parse results from <i>queryads.php</i>: <code>".$queryAds[1]."</code>");
// Count total number of matching blocklists
$featuredTotal = count($queryAds);
// Place results into key => value array
$queryResults = null;
foreach ($queryAds as $str) {
$value = explode(" ", $str);
@$queryResults[$value[0]] .= "$value[1]";
}
// Determine if domain has been blacklisted, whitelisted, wildcarded or CNAME blocked
if (strpos($queryAds[0], "blacklist") !== FALSE) {
$notableFlagClass = "blacklist";
$adlistsUrls = array("π" => substr($queryAds[0], 2));
} elseif (strpos($queryAds[0], "whitelist") !== FALSE) {
$notableFlagClass = "noblock";
$adlistsUrls = array("π" => substr($queryAds[0], 2));
$wlInfo = "recentwl";
} elseif (strpos($queryAds[0], "wildcard") !== FALSE) {
$notableFlagClass = "wildcard";
$adlistsUrls = array("π" => substr($queryAds[0], 2));
} elseif ($queryAds[0] === "none") {
$featuredTotal = "0";
$notableFlagClass = "noblock";
// QoL addition: Determine appropriate info message if CNAME exists
// Suggests to the user that $serverName has a CNAME (alias) that may be blocked
$dnsRecord = dns_get_record("$serverName")[0];
if (array_key_exists("target", $dnsRecord)) {
$wlInfo = $dnsRecord['target'];
} else {
$wlInfo = "unknown";
}
}
// Set #bpOutput notification
$wlOutputClass = (isset($wlInfo) && $wlInfo === "recentwl") ? $wlInfo : "hidden";
$wlOutput = (isset($wlInfo) && $wlInfo !== "recentwl") ? "<a href='http://$wlInfo'>$wlInfo</a>" : "";
// Get Pi-hole Core version
$phVersion = exec("cd /etc/.pihole/ && git describe --long --tags");
// Print $execTime on development branches
// Testing for - is marginally faster than "git rev-parse --abbrev-ref HEAD"
if (explode("-", $phVersion)[1] != "0")
$execTime = microtime(true)-$_SERVER["REQUEST_TIME_FLOAT"];
// Please Note: Text is added via CSS to allow an admin to provide a localized
// language without the need to edit this file
setHeader();
header("HTTP/1.1 404 Not Found");
exit();
?>
<!doctype html>
<!-- Pi-hole: A black hole for Internet advertisements
* (c) 2017 Pi-hole, LLC (https://pi-hole.net)
* Network-wide ad blocking via your own hardware.
*
* This file is copyright under the latest version of the EUPL. -->
<html>
<head>
<meta charset="utf-8">
<?=$viewPort ?>
<meta name="robots" content="noindex,nofollow">
<meta http-equiv="x-dns-prefetch-control" content="off">
<link rel="stylesheet" href="pihole/blockingpage.css">
<link rel="shortcut icon" href="admin/img/favicons/favicon.ico" type="image/x-icon">
<title>● <?=$serverName ?></title>
<script src="admin/scripts/vendor/jquery.min.js"></script>
<script>
window.onload = function () {
<?php
// Remove href fallback from "Back to safety" button
if ($featuredTotal > 0) {
echo '$("#bpBack").removeAttr("href");';
// Enable whitelisting if JS is available
echo '$("#bpWhitelist").prop("disabled", false);';
// Enable password input if necessary
if (!empty($svPasswd)) {
echo '$("#bpWLPassword").attr("placeholder", "Password");';
echo '$("#bpWLPassword").prop("disabled", false);';
}
// Otherwise hide the input
else {
echo '$("#bpWLPassword").hide();';
}
}
?>
}
</script>
</head>
<body id="blockpage"><div id="bpWrapper">
<header>
<h1 id="bpTitle">
<a class="title" href="/"><?php //Website Blocked ?></a>
</h1>
<div class="spc"></div>
<input id="bpAboutToggle" type="checkbox">
<div id="bpAbout">
<div class="aboutPH">
<div class="aboutImg"></div>
<p>Open Source Ad Blocker
<small>Designed for Raspberry Pi</small>
</p>
</div>
<div class="aboutLink">
<a class="linkPH" href="https://docs.pi-hole.net/"><?php //About PH ?></a>
<?php if (!empty($svEmail)) echo '<a class="linkEmail" href="mailto:'.$svEmail.'"></a>'; ?>
</div>
</div>
<div id="bpAlt">
<label class="altBtn" for="bpAboutToggle"><?php //Why am I here? ?></label>
</div>
</header>
<main>
<div id="bpOutput" class="<?=$wlOutputClass ?>"><?=$wlOutput ?></div>
<div id="bpBlock">
<p class="blockMsg"><?=$serverName ?></p>
</div>
<?php if(isset($notableFlagClass)) { ?>
<div id="bpFlag">
<p class="flagMsg <?=$notableFlagClass ?>"></p>
</div>
<?php } ?>
<div id="bpHelpTxt"><?=$bpAskAdmin ?></div>
<div id="bpButtons" class="buttons">
<a id="bpBack" onclick="javascript:history.back()" href="about:home"></a>
<?php if ($featuredTotal > 0) echo '<label id="bpInfo" for="bpMoreToggle"></label>'; ?>
</div>
<input id="bpMoreToggle" type="checkbox">
<div id="bpMoreInfo">
<span id="bpFoundIn"><span><?=$featuredTotal ?></span><?=$adlistsCount ?></span>
<pre id='bpQueryOutput'><?php if ($featuredTotal > 0) foreach ($queryResults as $num => $value) { echo "<span>[$num]:</span>$adlistsUrls[$num]\n"; } ?></pre>
<form id="bpWLButtons" class="buttons">
<input id="bpWLDomain" type="text" value="<?=$serverName ?>" disabled>
<input id="bpWLPassword" type="password" placeholder="JavaScript disabled" disabled>
<button id="bpWhitelist" type="button" disabled></button>
</form>
</div>
</main>
<footer><span><?=date("l g:i A, F dS"); ?>.</span> Pi-hole <?=$phVersion ?> (<?=gethostname()."/".$_SERVER["SERVER_ADDR"]; if (isset($execTime)) printf("/%.2fs", $execTime); ?>)</footer>
</div>
<script>
function add() {
$("#bpOutput").removeClass("hidden error exception");
$("#bpOutput").addClass("add");
var domain = "<?=$serverName ?>";
var pw = $("#bpWLPassword");
if(domain.length === 0) {
return;
}
$.ajax({
url: "/admin/scripts/pi-hole/php/add.php",
method: "post",
data: {"domain":domain, "list":"white", "pw":pw.val()},
success: function(response) {
if(response.indexOf("Pi-hole blocking") !== -1) {
setTimeout(function(){window.location.reload(1);}, 10000);
$("#bpOutput").removeClass("add");
$("#bpOutput").addClass("success");
$("#bpOutput").html("");
} else {
$("#bpOutput").removeClass("add");
$("#bpOutput").addClass("error");
$("#bpOutput").html(""+response+"");
}
},
error: function(jqXHR, exception) {
$("#bpOutput").removeClass("add");
$("#bpOutput").addClass("exception");
$("#bpOutput").html("");
}
});
}
<?php if ($featuredTotal > 0) { ?>
$(document).keypress(function(e) {
if(e.which === 13 && $("#bpWLPassword").is(":focus")) {
add();
}
});
$("#bpWhitelist").on("click", function() {
add();
});
<?php } ?>
</script>
</body></html>

View File

@@ -32,6 +32,8 @@ server.errorlog = "/var/log/lighttpd/error-pihole.log"
server.pid-file = "/run/lighttpd.pid"
server.username = "www-data"
server.groupname = "www-data"
# For lighttpd version 1.4.46 or above, the port can be overwritten in `/etc/lighttpd/external.conf` using the := operator
# e.g. server.port := 8000
server.port = 80
accesslog.filename = "/var/log/lighttpd/access-pihole.log"
accesslog.format = "%{%s}t|%V|%r|%s|%b"
@@ -78,10 +80,21 @@ include_shell "find /etc/lighttpd/conf-enabled -name '*.conf' -a ! -name 'letsen
# If the URL starts with /admin, it is the Web interface
$HTTP["url"] =~ "^/admin/" {
# Create a response header for debugging using curl -I
# X-Pi-hole is a response header for debugging using curl -I
# X-Frame-Options prevents clickjacking attacks and helps ensure your content is not embedded into other sites via < frame >, < iframe > or < object >.
# X-XSS-Protection sets the configuration for the cross-site scripting filters built into most browsers. This is important because it tells the browser to block the response if a malicious script has been inserted from a user input.
# X-Content-Type-Options stops a browser from trying to MIME-sniff the content type and forces it to stick with the declared content-type. This is important because the browser will only load external resources if their content-type matches what is expected, and not malicious hidden code.
# Content-Security-Policy tells the browser where resources are allowed to be loaded and if its allowed to parse/run inline styles or Javascript. This is important because it prevents content injection attacks, such as Cross Site Scripting (XSS).
# X-Permitted-Cross-Domain-Policies is an XML document that grants a web client, such as Adobe Flash Player or Adobe Acrobat (though not necessarily limited to these), permission to handle data across domains.
# Referrer-Policy allows control/restriction of the amount of information present in the referral header for links away from your page—the URL path or even if the header is sent at all.
setenv.add-response-header = (
"X-Pi-hole" => "The Pi-hole Web interface is working!",
"X-Frame-Options" => "DENY"
"X-Frame-Options" => "DENY",
"X-XSS-Protection" => "1; mode=block",
"X-Content-Type-Options" => "nosniff",
"Content-Security-Policy" => "default-src 'self' 'unsafe-inline';",
"X-Permitted-Cross-Domain-Policies" => "none",
"Referrer-Policy" => "same-origin"
)
}

View File

@@ -33,6 +33,8 @@ server.errorlog = "/var/log/lighttpd/error-pihole.log"
server.pid-file = "/run/lighttpd.pid"
server.username = "lighttpd"
server.groupname = "lighttpd"
# For lighttpd version 1.4.46 or above, the port can be overwritten in `/etc/lighttpd/external.conf` using the := operator
# e.g. server.port := 8000
server.port = 80
accesslog.filename = "/var/log/lighttpd/access-pihole.log"
accesslog.format = "%{%s}t|%V|%r|%s|%b"
@@ -86,10 +88,21 @@ fastcgi.server = (
# If the URL starts with /admin, it is the Web interface
$HTTP["url"] =~ "^/admin/" {
# Create a response header for debugging using curl -I
# X-Pi-hole is a response header for debugging using curl -I
# X-Frame-Options prevents clickjacking attacks and helps ensure your content is not embedded into other sites via < frame >, < iframe > or < object >.
# X-XSS-Protection sets the configuration for the cross-site scripting filters built into most browsers. This is important because it tells the browser to block the response if a malicious script has been inserted from a user input.
# X-Content-Type-Options stops a browser from trying to MIME-sniff the content type and forces it to stick with the declared content-type. This is important because the browser will only load external resources if their content-type matches what is expected, and not malicious hidden code.
# Content-Security-Policy tells the browser where resources are allowed to be loaded and if its allowed to parse/run inline styles or Javascript. This is important because it prevents content injection attacks, such as Cross Site Scripting (XSS).
# X-Permitted-Cross-Domain-Policies is an XML document that grants a web client, such as Adobe Flash Player or Adobe Acrobat (though not necessarily limited to these), permission to handle data across domains.
# Referrer-Policy allows control/restriction of the amount of information present in the referral header for links away from your page—the URL path or even if the header is sent at all.
setenv.add-response-header = (
"X-Pi-hole" => "The Pi-hole Web interface is working!",
"X-Frame-Options" => "DENY"
"X-Frame-Options" => "DENY",
"X-XSS-Protection" => "1; mode=block",
"X-Content-Type-Options" => "nosniff",
"Content-Security-Policy" => "default-src 'self' 'unsafe-inline';",
"X-Permitted-Cross-Domain-Policies" => "none",
"Referrer-Policy" => "same-origin"
)
}

View File

@@ -82,7 +82,8 @@ PI_HOLE_FILES=(chronometer list piholeDebug piholeLogFlush setupLCD update versi
PI_HOLE_INSTALL_DIR="/opt/pihole"
PI_HOLE_CONFIG_DIR="/etc/pihole"
PI_HOLE_BIN_DIR="/usr/local/bin"
PI_HOLE_BLOCKPAGE_DIR="${webroot}/pihole"
PI_HOLE_404_DIR="${webroot}/pihole"
FTL_CONFIG_FILE="${PI_HOLE_CONFIG_DIR}/pihole-FTL.conf"
if [ -z "$useUpdateVars" ]; then
useUpdateVars=false
fi
@@ -330,7 +331,7 @@ package_manager_detect() {
# Packages required to run this install script (stored as an array)
INSTALLER_DEPS=(git iproute2 dialog ca-certificates)
# Packages required to run Pi-hole (stored as an array)
PIHOLE_DEPS=(cron curl iputils-ping psmisc sudo unzip idn2 libcap2-bin dns-root-data libcap2 netcat-openbsd procps)
PIHOLE_DEPS=(cron curl iputils-ping psmisc sudo unzip idn2 libcap2-bin dns-root-data libcap2 netcat-openbsd procps jq)
# Packages required for the Web admin interface (stored as an array)
# It's useful to separate this from Pi-hole, since the two repos are also setup separately
PIHOLE_WEB_DEPS=(lighttpd "${phpVer}-common" "${phpVer}-cgi" "${phpVer}-sqlite3" "${phpVer}-xml" "${phpVer}-intl")
@@ -357,15 +358,30 @@ package_manager_detect() {
# These variable names match the ones for apt-get. See above for an explanation of what they are for.
PKG_INSTALL=("${PKG_MANAGER}" install -y)
# CentOS package manager returns 100 when there are packages to update so we need to || true to prevent the script from exiting.
PKG_COUNT="${PKG_MANAGER} check-update | egrep '(.i686|.x86|.noarch|.arm|.src)' | wc -l || true"
PKG_COUNT="${PKG_MANAGER} check-update | grep -E '(.i686|.x86|.noarch|.arm|.src)' | wc -l || true"
OS_CHECK_DEPS=(grep bind-utils)
INSTALLER_DEPS=(git dialog iproute newt procps-ng which chkconfig ca-certificates)
PIHOLE_DEPS=(cronie curl findutils sudo unzip libidn2 psmisc libcap nmap-ncat)
PIHOLE_DEPS=(cronie curl findutils sudo unzip libidn2 psmisc libcap nmap-ncat jq)
PIHOLE_WEB_DEPS=(lighttpd lighttpd-fastcgi php-common php-cli php-pdo php-xml php-json php-intl)
LIGHTTPD_USER="lighttpd"
LIGHTTPD_GROUP="lighttpd"
LIGHTTPD_CFG="lighttpd.conf.fedora"
# If the host OS is centos (or a derivative), epel is required for lighttpd
if ! grep -qiE 'fedora|fedberry' /etc/redhat-release; then
if rpm -qa | grep -qi 'epel'; then
printf " %b EPEL repository already installed\\n" "${TICK}"
else
local RH_RELEASE EPEL_PKG
# EPEL not already installed, add it based on the release version
RH_RELEASE=$(grep -oP '(?<= )[0-9]+(?=\.?)' /etc/redhat-release)
EPEL_PKG="https://dl.fedoraproject.org/pub/epel/epel-release-latest-${RH_RELEASE}.noarch.rpm"
printf " %b Enabling EPEL package repository (https://fedoraproject.org/wiki/EPEL)\\n" "${INFO}"
"${PKG_INSTALL[@]}" "${EPEL_PKG}"
printf " %b Installed %s\\n" "${TICK}" "${EPEL_PKG}"
fi
fi
# If neither apt-get or yum/dnf package managers were found
else
# we cannot install required packages
@@ -375,144 +391,6 @@ package_manager_detect() {
fi
}
select_rpm_php(){
# If the host OS is Fedora,
if grep -qiE 'fedora|fedberry' /etc/redhat-release; then
# all required packages should be available by default with the latest fedora release
: # continue
# or if host OS is CentOS,
elif grep -qiE 'centos|scientific' /etc/redhat-release; then
# Pi-Hole currently supports CentOS 7+ with PHP7+
SUPPORTED_CENTOS_VERSION=7
SUPPORTED_CENTOS_PHP_VERSION=7
# Check current CentOS major release version
CURRENT_CENTOS_VERSION=$(grep -oP '(?<= )[0-9]+(?=\.?)' /etc/redhat-release)
# Check if CentOS version is supported
if [[ $CURRENT_CENTOS_VERSION -lt $SUPPORTED_CENTOS_VERSION ]]; then
printf " %b CentOS %s is not supported.\\n" "${CROSS}" "${CURRENT_CENTOS_VERSION}"
printf " Please update to CentOS release %s or later.\\n" "${SUPPORTED_CENTOS_VERSION}"
# exit the installer
exit
fi
# php-json is not required on CentOS 7 as it is already compiled into php
# verifiy via `php -m | grep json`
if [[ $CURRENT_CENTOS_VERSION -eq 7 ]]; then
# create a temporary array as arrays are not designed for use as mutable data structures
CENTOS7_PIHOLE_WEB_DEPS=()
for i in "${!PIHOLE_WEB_DEPS[@]}"; do
if [[ ${PIHOLE_WEB_DEPS[i]} != "php-json" ]]; then
CENTOS7_PIHOLE_WEB_DEPS+=( "${PIHOLE_WEB_DEPS[i]}" )
fi
done
# re-assign the clean dependency array back to PIHOLE_WEB_DEPS
PIHOLE_WEB_DEPS=("${CENTOS7_PIHOLE_WEB_DEPS[@]}")
unset CENTOS7_PIHOLE_WEB_DEPS
fi
if rpm -qa | grep -qi 'epel'; then
printf " %b EPEL repository already installed\\n" "${TICK}"
else
# CentOS requires the EPEL repository to gain access to Fedora packages
if [[ CURRENT_CENTOS_VERSION -eq 7 ]]; then
EPEL_PKG="https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm"
elif [[ CURRENT_CENTOS_VERSION -eq 8 ]]; then
EPEL_PKG="https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm"
fi
printf " %b Enabling EPEL package repository (https://fedoraproject.org/wiki/EPEL)\\n" "${INFO}"
"${PKG_INSTALL[@]}" ${EPEL_PKG}
printf " %b Installed %s\\n" "${TICK}" "${EPEL_PKG}"
fi
# The default php on CentOS 7.x is 5.4 which is EOL
# Check if the version of PHP available via installed repositories is >= to PHP 7
AVAILABLE_PHP_VERSION=$("${PKG_MANAGER}" info php | grep -i version | grep -o '[0-9]\+' | head -1)
if [[ $AVAILABLE_PHP_VERSION -ge $SUPPORTED_CENTOS_PHP_VERSION ]]; then
# Since PHP 7 is available by default, install via default PHP package names
: # do nothing as PHP is current
printf "PHP 7 is installed"
else
REMI_PKG="remi-release"
REMI_REPO="remi-php72"
REMI_REPO_URL="https://rpms.remirepo.net/enterprise/${REMI_PKG}-$(rpm -E '%{rhel}').rpm"
# The PHP version available via default repositories is older than version 7
dialog --no-shadow --keep-tite \
--title "PHP 7 Update (recommended)" \
--defaultno \
--yesno "PHP 7.x is recommended for both security and language features.\
\\n\\nWould you like to install PHP7 via Remi's RPM repository?\
\\n\\nSee: https://rpms.remirepo.net for more information"\
"${r}" "${c}" && result=0 || result=$?
case ${result} in
"${DIALOG_OK}" )
printf " %b Installing PHP 7 via Remi's RPM repository\\n" "${INFO}"
"${PKG_INSTALL[@]}" "yum-utils" &> /dev/null
if rpm -q ${REMI_PKG} &> /dev/null; then
printf " %b Remi's RPM repository is already installed\\n" "${TICK}"
else
printf " %b Enabling Remi's RPM repository (https://rpms.remirepo.net)\\n" "${INFO}"
yum -y install "${REMI_REPO_URL}"
printf " %b Installed %s from %s\\n" "${TICK}" "${REMI_PKG}" "${REMI_REPO_URL}"
printf " %b Remi's RPM repository has been enabled for PHP7\\n" "${TICK}"
fi
yum-config-manager --disable 'remi-php*'
yum-config-manager --enable "${REMI_REPO}"
# trigger an install/update of PHP to ensure previous version of PHP is updated from REMI
if "${PKG_INSTALL[@]}" "php-cli" &> /dev/null; then
printf " %b PHP7 installed/updated via Remi's RPM repository\\n" "${TICK}"
else
printf " %b There was a problem updating to PHP7 via Remi's RPM repository\\n" "${CROSS}"
exit 1
fi
;;
# User chose not to install PHP 7 via Remi's RPM repository
"${DIALOG_CANCEL}")
# User decided to NOT update PHP from REMI, attempt to install the default available PHP version
printf " %b User opt-out of PHP 7 upgrade on CentOS. Deprecated PHP may be in use.\\n" "${INFO}"
;;
# User closed the dialog window
"${DIALOG_ESC}")
printf " %b Escape pressed, exiting installer at Remi dialog window\\n" "${CROSS}"
exit 1
;;
esac
fi
else
# Warn user of unsupported version of Fedora or CentOS
dialog --no-shadow --keep-tite \
--title "Unsupported RPM based distribution" \
--defaultno \
--no-button "Exit" \
--yes-button "Continue" \
--yesno "Would you like to continue installation on an unsupported RPM based distribution?\
\\n\\nPlease ensure the following packages have been installed manually:\
\\n\\n- lighttpd\\n- lighttpd-fastcgi\\n- PHP version 7+"\
"${r}" "${c}" && result=0 || result=$?
case ${result} in
# User chose to continue installation on an unsupported RPM based distribution
"${DIALOG_OK}")
printf " %b User opted to continue installation on an unsupported RPM based distribution.\\n" "${INFO}"
;;
# User chose not to continue installation on an unsupported RPM based distribution
"${DIALOG_CANCEL}")
printf " %b User opted not to continue installation on an unsupported RPM based distribution.\\n" "${INFO}"
exit 1
;;
"${DIALOG_ESC}")
printf " %b Escape pressed, exiting installer at unsupported RPM based distribution dialog window\\n" "${CROSS}"
exit 1
;;
esac
fi
}
# A function for checking if a directory is a git repository
is_repo() {
# Use a named, local variable instead of the vague $1, which is the first argument passed to this function
@@ -805,7 +683,7 @@ testIPv6() {
find_IPv6_information() {
# Detects IPv6 address used for communication to WAN addresses.
IPV6_ADDRESSES=($(ip -6 address | grep 'scope global' | awk '{print $2}'))
mapfile -t IPV6_ADDRESSES <<<"$(ip -6 address | grep 'scope global' | awk '{print $2}')"
# For each address in the array above, determine the type of IPv6 address it is
for i in "${IPV6_ADDRESSES[@]}"; do
@@ -820,13 +698,13 @@ find_IPv6_information() {
# Determine which address to be used: Prefer ULA over GUA or don't use any if none found
# If the ULA_ADDRESS contains a value,
if [[ ! -z "${ULA_ADDRESS}" ]]; then
if [[ -n "${ULA_ADDRESS}" ]]; then
# set the IPv6 address to the ULA address
IPV6_ADDRESS="${ULA_ADDRESS}"
# Show this info to the user
printf " %b Found IPv6 ULA address\\n" "${INFO}"
# Otherwise, if the GUA_ADDRESS has a value,
elif [[ ! -z "${GUA_ADDRESS}" ]]; then
elif [[ -n "${GUA_ADDRESS}" ]]; then
# Let the user know
printf " %b Found IPv6 GUA address\\n" "${INFO}"
# And assign it to the global variable
@@ -889,9 +767,9 @@ getStaticIPv4Settings() {
--cancel-label "Exit" \
--backtitle "IP information" \
--title "FYI: IP Conflict" \
--msgbox "\\nIt 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.\
--msgbox "\\nIt 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.\n\n\
If you are worried, either manually set the address, or modify the DHCP reservation pool so it does not include the IP you want.\n\n\
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}" && result=0 || result=$?
@@ -912,7 +790,7 @@ It is also possible to use a DHCP reservation, but if you are going to do that,
# Ask for the IPv4 address
_staticIPv4Temp=$(dialog --no-shadow --keep-tite --output-fd 1 \
--cancer-label "Exit" \
--cancel-label "Exit" \
--ok-label "Continue" \
--backtitle "Calibrating network interface" \
--title "IPv4 Address" \
@@ -950,8 +828,11 @@ It is also possible to use a DHCP reservation, but if you are going to do that,
# Configure networking via dhcpcd
setDHCPCD() {
# Check if the IP is already in the file
if grep -q "${IPV4_ADDRESS}" /etc/dhcpcd.conf; then
# Regex for matching a non-commented static ip address setting
local regex="^[ \t]*static ip_address[ \t]*=[ \t]*${IPV4_ADDRESS}"
# Check if static IP is already set in file
if grep -q "${regex}" /etc/dhcpcd.conf; then
printf " %b Static IP already configured\\n" "${INFO}"
# If it's not,
else
@@ -1122,10 +1003,10 @@ If you want to specify a port other than 53, separate it with a hash.\
# and continue the loop.
DNSSettingsCorrect=False
else
dialog --no-shadow --keep-tite \
dialog --no-shadow --no-collapse --keep-tite \
--backtitle "Specify Upstream DNS Provider(s)" \
--title "Upstream DNS Provider(s)" \
--yesno "Are these settings correct?\\n\\tDNS Server 1:\\t${PIHOLE_DNS_1}\\n\\tDNS Server 2:\\t${PIHOLE_DNS_2}" \
--yesno "Are these settings correct?\\n"$'\t'"DNS Server 1:"$'\t'"${PIHOLE_DNS_1}\\n"$'\t'"DNS Server 2:"$'\t'"${PIHOLE_DNS_2}" \
"${r}" "${c}" && result=0 || result=$?
case ${result} in
@@ -1250,8 +1131,8 @@ setAdminFlag() {
;;
esac
# If the user wants to install the Web admin interface (i.e. it has not been deselected above)
if [[ "${INSTALL_WEB_INTERFACE}" == true ]]; then
# If the user wants to install the Web admin interface (i.e. it has not been deselected above) and did not deselect the web server via command-line argument
if [[ "${INSTALL_WEB_INTERFACE}" == true && "${INSTALL_WEB_SERVER}" == true ]]; then
# Get list of required PHP modules, excluding base package (common) and handler (cgi)
local i php_modules
for i in "${PIHOLE_WEB_DEPS[@]}"; do [[ $i == 'php'* && $i != *'-common' && $i != *'-cgi' ]] && php_modules+=" ${i#*-}"; done
@@ -1387,35 +1268,30 @@ version_check_dnsmasq() {
# Copy the new Pi-hole DNS config file into the dnsmasq.d directory
install -D -m 644 -T "${dnsmasq_pihole_01_source}" "${dnsmasq_pihole_01_target}"
printf "%b %b Installed %s\n" "${OVER}" "${TICK}" "${dnsmasq_pihole_01_target}"
# Replace our placeholder values with the GLOBAL DNS variables that we populated earlier
# First, swap in the interface to listen on,
sed -i "s/@INT@/$PIHOLE_INTERFACE/" "${dnsmasq_pihole_01_target}"
# Add settings with the GLOBAL DNS variables that we populated earlier
# First, set the interface to listen on
addOrEditKeyValPair "${dnsmasq_pihole_01_target}" "interface" "$PIHOLE_INTERFACE"
if [[ "${PIHOLE_DNS_1}" != "" ]]; then
# then swap in the primary DNS server.
sed -i "s/@DNS1@/$PIHOLE_DNS_1/" "${dnsmasq_pihole_01_target}"
else
# Otherwise, remove the line which sets DNS1.
sed -i '/^server=@DNS1@/d' "${dnsmasq_pihole_01_target}"
# then add in the primary DNS server.
addOrEditKeyValPair "${dnsmasq_pihole_01_target}" "server" "$PIHOLE_DNS_1"
fi
# Ditto if DNS2 is not empty
if [[ "${PIHOLE_DNS_2}" != "" ]]; then
sed -i "s/@DNS2@/$PIHOLE_DNS_2/" "${dnsmasq_pihole_01_target}"
else
sed -i '/^server=@DNS2@/d' "${dnsmasq_pihole_01_target}"
addKey "${dnsmasq_pihole_01_target}" "server=$PIHOLE_DNS_2"
fi
# Set the cache size
sed -i "s/@CACHE_SIZE@/$CACHE_SIZE/" "${dnsmasq_pihole_01_target}"
addOrEditKeyValPair "${dnsmasq_pihole_01_target}" "cache-size" "$CACHE_SIZE"
sed -i 's/^#conf-dir=\/etc\/dnsmasq.d$/conf-dir=\/etc\/dnsmasq.d/' "${dnsmasq_conf}"
# If the user does not want to enable logging,
if [[ "${QUERY_LOGGING}" == false ]] ; then
# disable it by commenting out the directive in the DNS config file
sed -i 's/^log-queries/#log-queries/' "${dnsmasq_pihole_01_target}"
# remove itfrom the DNS config file
removeKey "${dnsmasq_pihole_01_target}" "log-queries"
else
# Otherwise, enable it by uncommenting the directive in the DNS config file
sed -i 's/^#log-queries/log-queries/' "${dnsmasq_pihole_01_target}"
# Otherwise, enable it by adding the directive to the DNS config file
addKey "${dnsmasq_pihole_01_target}" "log-queries"
fi
printf " %b Installing %s..." "${INFO}" "${dnsmasq_rfc6761_06_source}"
@@ -1488,9 +1364,9 @@ installConfigs() {
chmod 644 "${PI_HOLE_CONFIG_DIR}/dns-servers.conf"
# Install template file if it does not exist
if [[ ! -r "${PI_HOLE_CONFIG_DIR}/pihole-FTL.conf" ]]; then
if [[ ! -r "${FTL_CONFIG_FILE}" ]]; then
install -d -m 0755 ${PI_HOLE_CONFIG_DIR}
if ! install -T -o pihole -m 664 "${PI_HOLE_LOCAL_REPO}/advanced/Templates/pihole-FTL.conf" "${PI_HOLE_CONFIG_DIR}/pihole-FTL.conf" &>/dev/null; then
if ! install -T -o pihole -m 664 "${PI_HOLE_LOCAL_REPO}/advanced/Templates/pihole-FTL.conf" "${FTL_CONFIG_FILE}" &>/dev/null; then
printf " %b Error: Unable to initialize configuration file %s/pihole-FTL.conf\\n" "${COL_LIGHT_RED}" "${PI_HOLE_CONFIG_DIR}"
return 1
fi
@@ -1525,7 +1401,7 @@ installConfigs() {
install -m 644 /dev/null /etc/lighttpd/external.conf
fi
# If there is a custom block page in the html/pihole directory, replace 404 handler in lighttpd config
if [[ -f "${PI_HOLE_BLOCKPAGE_DIR}/custom.php" ]]; then
if [[ -f "${PI_HOLE_404_DIR}/custom.php" ]]; then
sed -i 's/^\(server\.error-handler-404\s*=\s*\).*$/\1"\/pihole\/custom\.php"/' "${lighttpdConfig}"
fi
# Make the directories if they do not exist and set the owners
@@ -1751,9 +1627,9 @@ install_dependent_packages() {
# Running apt-get install with minimal output can cause some issues with
# requiring user input (e.g password for phpmyadmin see #218)
printf " %b Processing %s install(s) for: %s, please wait...\\n" "${INFO}" "${PKG_MANAGER}" "${installArray[*]}"
printf '%*s\n' "$columns" '' | tr " " -;
printf '%*s\n' "${c}" '' | tr " " -;
"${PKG_INSTALL[@]}" "${installArray[@]}"
printf '%*s\n' "$columns" '' | tr " " -;
printf '%*s\n' "${c}" '' | tr " " -;
return
fi
printf "\\n"
@@ -1774,9 +1650,9 @@ install_dependent_packages() {
# If there's anything to install, install everything in the list.
if [[ "${#installArray[@]}" -gt 0 ]]; then
printf " %b Processing %s install(s) for: %s, please wait...\\n" "${INFO}" "${PKG_MANAGER}" "${installArray[*]}"
printf '%*s\n' "$columns" '' | tr " " -;
printf '%*s\n' "${c}" '' | tr " " -;
"${PKG_INSTALL[@]}" "${installArray[@]}"
printf '%*s\n' "$columns" '' | tr " " -;
printf '%*s\n' "${c}" '' | tr " " -;
return
fi
printf "\\n"
@@ -1785,19 +1661,14 @@ install_dependent_packages() {
# Install the Web interface dashboard
installPiholeWeb() {
printf "\\n %b Installing blocking page...\\n" "${INFO}"
printf "\\n %b Installing 404 page...\\n" "${INFO}"
local str="Creating directory for blocking page, and copying files"
local str="Creating directory for 404 page, and copying files"
printf " %b %s..." "${INFO}" "${str}"
# Install the directory,
install -d -m 0755 ${PI_HOLE_BLOCKPAGE_DIR}
# and the blockpage
install -D -m 644 ${PI_HOLE_LOCAL_REPO}/advanced/{index,blockingpage}.* ${PI_HOLE_BLOCKPAGE_DIR}/
# Remove superseded file
if [[ -e "${PI_HOLE_BLOCKPAGE_DIR}/index.js" ]]; then
rm "${PI_HOLE_BLOCKPAGE_DIR}/index.js"
fi
# Install the directory
install -d -m 0755 ${PI_HOLE_404_DIR}
# and the 404 handler
install -D -m 644 ${PI_HOLE_LOCAL_REPO}/advanced/index.php ${PI_HOLE_404_DIR}/
printf "%b %b %s\\n" "${OVER}" "${TICK}" "${str}"
@@ -1912,33 +1783,28 @@ create_pihole_user() {
# This function saves any changes to the setup variables into the setupvars.conf file for future runs
finalExports() {
# If the setup variable file exists,
if [[ -e "${setupVars}" ]]; then
# update the variables in the file
sed -i.update.bak '/PIHOLE_INTERFACE/d;/PIHOLE_DNS_1\b/d;/PIHOLE_DNS_2\b/d;/QUERY_LOGGING/d;/INSTALL_WEB_SERVER/d;/INSTALL_WEB_INTERFACE/d;/LIGHTTPD_ENABLED/d;/CACHE_SIZE/d;/DNS_FQDN_REQUIRED/d;/DNS_BOGUS_PRIV/d;/DNSMASQ_LISTENING/d;' "${setupVars}"
fi
# echo the information to the user
{
echo "PIHOLE_INTERFACE=${PIHOLE_INTERFACE}"
echo "PIHOLE_DNS_1=${PIHOLE_DNS_1}"
echo "PIHOLE_DNS_2=${PIHOLE_DNS_2}"
echo "QUERY_LOGGING=${QUERY_LOGGING}"
echo "INSTALL_WEB_SERVER=${INSTALL_WEB_SERVER}"
echo "INSTALL_WEB_INTERFACE=${INSTALL_WEB_INTERFACE}"
echo "LIGHTTPD_ENABLED=${LIGHTTPD_ENABLED}"
echo "CACHE_SIZE=${CACHE_SIZE}"
echo "DNS_FQDN_REQUIRED=${DNS_FQDN_REQUIRED:-true}"
echo "DNS_BOGUS_PRIV=${DNS_BOGUS_PRIV:-true}"
echo "DNSMASQ_LISTENING=${DNSMASQ_LISTENING:-local}"
}>> "${setupVars}"
# set or update the variables in the file
addOrEditKeyValPair "${setupVars}" "PIHOLE_INTERFACE" "${PIHOLE_INTERFACE}"
addOrEditKeyValPair "${setupVars}" "PIHOLE_DNS_1" "${PIHOLE_DNS_1}"
addOrEditKeyValPair "${setupVars}" "PIHOLE_DNS_2" "${PIHOLE_DNS_2}"
addOrEditKeyValPair "${setupVars}" "QUERY_LOGGING" "${QUERY_LOGGING}"
addOrEditKeyValPair "${setupVars}" "INSTALL_WEB_SERVER" "${INSTALL_WEB_SERVER}"
addOrEditKeyValPair "${setupVars}" "INSTALL_WEB_INTERFACE" "${INSTALL_WEB_INTERFACE}"
addOrEditKeyValPair "${setupVars}" "LIGHTTPD_ENABLED" "${LIGHTTPD_ENABLED}"
addOrEditKeyValPair "${setupVars}" "CACHE_SIZE" "${CACHE_SIZE}"
addOrEditKeyValPair "${setupVars}" "DNS_FQDN_REQUIRED" "${DNS_FQDN_REQUIRED:-true}"
addOrEditKeyValPair "${setupVars}" "DNS_BOGUS_PRIV" "${DNS_BOGUS_PRIV:-true}"
addOrEditKeyValPair "${setupVars}" "DNSMASQ_LISTENING" "${DNSMASQ_LISTENING:-local}"
chmod 644 "${setupVars}"
# Set the privacy level
sed -i '/PRIVACYLEVEL/d' "${PI_HOLE_CONFIG_DIR}/pihole-FTL.conf"
echo "PRIVACYLEVEL=${PRIVACY_LEVEL}" >> "${PI_HOLE_CONFIG_DIR}/pihole-FTL.conf"
addOrEditKeyValPair "${FTL_CONFIG_FILE}" "PRIVACYLEVEL" "${PRIVACY_LEVEL}"
# Bring in the current settings and the functions to manipulate them
source "${setupVars}"
# shellcheck source=advanced/Scripts/webpage.sh
source "${PI_HOLE_LOCAL_REPO}/advanced/Scripts/webpage.sh"
# Look for DNS server settings which would have to be reapplied
@@ -1955,6 +1821,16 @@ installLogrotate() {
printf "\\n %b %s..." "${INFO}" "${str}"
if [[ -f ${target} ]]; then
# Account for changed logfile paths from /var/log -> /var/log/pihole/ made in core v5.11.
if grep -q "/var/log/pihole.log" ${target} || grep -q "/var/log/pihole-FTL.log" ${target}; then
sed -i 's/\/var\/log\/pihole.log/\/var\/log\/pihole\/pihole.log/g' ${target}
sed -i 's/\/var\/log\/pihole-FTL.log/\/var\/log\/pihole\/FTL.log/g' ${target}
printf "\\n\\t%b Old log file paths updated in existing logrotate file. \\n" "${INFO}"
return 3
fi
printf "\\n\\t%b Existing logrotate file found. No changes made.\\n" "${INFO}"
# Return value isn't that important, using 2 to indicate that it's not a fatal error but
# the function did not complete.
@@ -2012,6 +1888,16 @@ installPihole() {
printf " %b Failure in dependent script copy function.\\n" "${CROSS}"
exit 1
fi
# /opt/pihole/utils.sh should be installed by installScripts now, so we can use it
if [ -f "${PI_HOLE_INSTALL_DIR}/utils.sh" ]; then
# shellcheck disable=SC1091
source "${PI_HOLE_INSTALL_DIR}/utils.sh"
else
printf " %b Failure: /opt/pihole/utils.sh does not exist .\\n" "${CROSS}"
exit 1
fi
# Install config files
if ! installConfigs; then
printf " %b Failure in dependent config copy function.\\n" "${CROSS}"
@@ -2050,22 +1936,22 @@ checkSelinux() {
DEFAULT_SELINUX=$(awk -F= '/^SELINUX=/ {print $2}' /etc/selinux/config)
case "${DEFAULT_SELINUX,,}" in
enforcing)
printf " %b %bDefault SELinux: %s%b\\n" "${CROSS}" "${COL_RED}" "${DEFAULT_SELINUX}" "${COL_NC}"
printf " %b %bDefault SELinux: %s%b\\n" "${CROSS}" "${COL_RED}" "${DEFAULT_SELINUX,,}" "${COL_NC}"
SELINUX_ENFORCING=1
;;
*) # 'permissive' and 'disabled'
printf " %b %bDefault SELinux: %s%b\\n" "${TICK}" "${COL_GREEN}" "${DEFAULT_SELINUX}" "${COL_NC}"
printf " %b %bDefault SELinux: %s%b\\n" "${TICK}" "${COL_GREEN}" "${DEFAULT_SELINUX,,}" "${COL_NC}"
;;
esac
# Check the current state of SELinux
CURRENT_SELINUX=$(getenforce)
case "${CURRENT_SELINUX,,}" in
enforcing)
printf " %b %bCurrent SELinux: %s%b\\n" "${CROSS}" "${COL_RED}" "${CURRENT_SELINUX}" "${COL_NC}"
printf " %b %bCurrent SELinux: %s%b\\n" "${CROSS}" "${COL_RED}" "${CURRENT_SELINUX,,}" "${COL_NC}"
SELINUX_ENFORCING=1
;;
*) # 'permissive' and 'disabled'
printf " %b %bCurrent SELinux: %s%b\\n" "${TICK}" "${COL_GREEN}" "${CURRENT_SELINUX}" "${COL_NC}"
printf " %b %bCurrent SELinux: %s%b\\n" "${TICK}" "${COL_GREEN}" "${CURRENT_SELINUX,,}" "${COL_NC}"
;;
esac
else
@@ -2139,9 +2025,8 @@ update_dialogs() {
\\n($strAdd)"\
"${r}" "${c}" 2 \
"${opt1a}" "${opt1b}" \
"${opt2a}" "${opt2b}" || true)
"${opt2a}" "${opt2b}") || result=$?
result=$?
case ${result} in
"${DIALOG_CANCEL}" | "${DIALOG_ESC}")
printf " %b Cancel was selected, exiting installer%b\\n" "${COL_LIGHT_RED}" "${COL_NC}"
@@ -2238,11 +2123,7 @@ checkout_pull_branch() {
git_pull=$(git pull --no-rebase || return 1)
if [[ "$git_pull" == *"up-to-date"* ]]; then
printf " %b %s\\n" "${INFO}" "${git_pull}"
else
printf "%s\\n" "$git_pull"
fi
printf " %b %s\\n" "${INFO}" "${git_pull}"
return 0
}
@@ -2389,7 +2270,7 @@ get_binary_name() {
local rev
rev=$(uname -m | sed "s/[^0-9]//g;")
local lib
lib=$(ldd "$(which sh)" | grep -E '^\s*/lib' | awk '{ print $1 }')
lib=$(ldd "$(command -v sh)" | grep -E '^\s*/lib' | awk '{ print $1 }')
if [[ "${lib}" == "/lib/ld-linux-aarch64.so.1" ]]; then
printf "%b %b Detected AArch64 (64 Bit ARM) processor\\n" "${OVER}" "${TICK}"
# set the binary to be used
@@ -2646,12 +2527,6 @@ main() {
printf " %b Checking for / installing Required dependencies for this install script...\\n" "${INFO}"
install_dependent_packages "${INSTALLER_DEPS[@]}"
#In case of RPM based distro, select the proper PHP version
if [[ "$PKG_MANAGER" == "yum" || "$PKG_MANAGER" == "dnf" ]] ; then
select_rpm_php
fi
# If the setup variable file exists,
if [[ -f "${setupVars}" ]]; then
# if it's running unattended,
@@ -2696,8 +2571,8 @@ main() {
source "${setupVars}"
# Get the privacy level if it exists (default is 0)
if [[ -f "${PI_HOLE_CONFIG_DIR}/pihole-FTL.conf" ]]; then
PRIVACY_LEVEL=$(sed -ne 's/PRIVACYLEVEL=\(.*\)/\1/p' "${PI_HOLE_CONFIG_DIR}/pihole-FTL.conf")
if [[ -f "${FTL_CONFIG_FILE}" ]]; then
PRIVACY_LEVEL=$(sed -ne 's/PRIVACYLEVEL=\(.*\)/\1/p' "${FTL_CONFIG_FILE}")
# If no setting was found, default to 0
PRIVACY_LEVEL="${PRIVACY_LEVEL:-0}"
@@ -2796,6 +2671,10 @@ main() {
stop_service pihole-FTL &> /dev/null
if [ ! -d /var/log/pihole/ ]; then
mkdir -m 0755 /var/log/pihole/
fi
# Special handling for pihole-FTL.log -> pihole/FTL.log
if [ -f /var/log/pihole-FTL.log ] && [ ! -L /var/log/pihole-FTL.log ]; then
# /var/log/pihole-FTL.log -> /var/log/pihole/FTL.log
@@ -2809,7 +2688,6 @@ main() {
# Remaining log files
if [ -f /var/log/pihole.log ] && [ ! -L /var/log/pihole.log ]; then
mkdir -p /var/log/pihole/
mv /var/log/pihole*.* /var/log/pihole/ 2>/dev/null
fi
@@ -2818,9 +2696,8 @@ main() {
# Download and compile the aggregated block list
runGravity
# Force an update of the updatechecker
# Update local and remote versions via updatechecker
/opt/pihole/updatecheck.sh
/opt/pihole/updatecheck.sh x remote
if [[ "${useUpdateVars}" == false ]]; then
displayFinalMessage "${pw}"
@@ -2853,7 +2730,7 @@ main() {
# Display where the log file is
printf "\\n %b The install log is located at: %s\\n" "${INFO}" "${installLogLoc}"
printf "%b%s Complete! %b\\n" "${COL_LIGHT_GREEN}" "${INSTALL_TYPE}" "${COL_NC}"
printf " %b %b%s complete! %b\\n" "${TICK}" "${COL_LIGHT_GREEN}" "${INSTALL_TYPE}" "${COL_NC}"
if [[ "${INSTALL_TYPE}" == "Update" ]]; then
printf "\\n"
@@ -2861,6 +2738,7 @@ main() {
fi
}
if [[ "${PH_TEST}" != true ]] ; then
# allow to source this script without running it
if [[ "${SKIP_INSTALL}" != true ]] ; then
main "$@"
fi

View File

@@ -36,7 +36,7 @@ else
fi
readonly PI_HOLE_FILES_DIR="/etc/.pihole"
PH_TEST="true"
SKIP_INSTALL="true"
source "${PI_HOLE_FILES_DIR}/automated install/basic-install.sh"
# setupVars set in basic-install.sh
source "${setupVars}"
@@ -44,8 +44,8 @@ source "${setupVars}"
# package_manager_detect() sourced from basic-install.sh
package_manager_detect
# Install packages used by the Pi-hole
DEPS=("${INSTALLER_DEPS[@]}" "${PIHOLE_DEPS[@]}")
# Uninstall packages used by the Pi-hole
DEPS=("${INSTALLER_DEPS[@]}" "${PIHOLE_DEPS[@]}" "${OS_CHECK_DEPS[@]}")
if [[ "${INSTALL_WEB_SERVER}" == true ]]; then
# Install the Web dependencies
DEPS+=("${PIHOLE_WEB_DEPS[@]}")

View File

@@ -40,6 +40,7 @@ gravityDBschema="${piholeGitDir}/advanced/Templates/gravity.db.sql"
gravityDBcopy="${piholeGitDir}/advanced/Templates/gravity_copy.sql"
domainsExtension="domains"
curl_connect_timeout=10
# Source setupVars from install script
setupVars="${piholeDir}/setupVars.conf"
@@ -139,9 +140,9 @@ update_gravity_timestamp() {
# Import domains from file and store them in the specified database table
database_table_from_file() {
# Define locals
local table source backup_path backup_file tmpFile type
local table src backup_path backup_file tmpFile list_type
table="${1}"
source="${2}"
src="${2}"
backup_path="${piholeDir}/migration_backup"
backup_file="${backup_path}/$(basename "${2}")"
tmpFile="$(mktemp -p "/tmp" --suffix=".gravity")"
@@ -155,13 +156,13 @@ database_table_from_file() {
# Special handling for domains to be imported into the common domainlist table
if [[ "${table}" == "whitelist" ]]; then
type="0"
list_type="0"
table="domainlist"
elif [[ "${table}" == "blacklist" ]]; then
type="1"
list_type="1"
table="domainlist"
elif [[ "${table}" == "regex" ]]; then
type="3"
list_type="3"
table="domainlist"
fi
@@ -174,9 +175,9 @@ database_table_from_file() {
rowid+=1
fi
# Loop over all domains in ${source} file
# Loop over all domains in ${src} file
# Read file line by line
grep -v '^ *#' < "${source}" | while IFS= read -r domain
grep -v '^ *#' < "${src}" | while IFS= read -r domain
do
# Only add non-empty lines
if [[ -n "${domain}" ]]; then
@@ -185,10 +186,10 @@ database_table_from_file() {
echo "${rowid},\"${domain}\",${timestamp}" >> "${tmpFile}"
elif [[ "${table}" == "adlist" ]]; then
# Adlist table format
echo "${rowid},\"${domain}\",1,${timestamp},${timestamp},\"Migrated from ${source}\",,0,0,0" >> "${tmpFile}"
echo "${rowid},\"${domain}\",1,${timestamp},${timestamp},\"Migrated from ${src}\",,0,0,0" >> "${tmpFile}"
else
# White-, black-, and regexlist table format
echo "${rowid},${type},\"${domain}\",1,${timestamp},${timestamp},\"Migrated from ${source}\"" >> "${tmpFile}"
echo "${rowid},${list_type},\"${domain}\",1,${timestamp},${timestamp},\"Migrated from ${src}\"" >> "${tmpFile}"
fi
rowid+=1
fi
@@ -201,14 +202,14 @@ database_table_from_file() {
status="$?"
if [[ "${status}" -ne 0 ]]; then
echo -e "\\n ${CROSS} Unable to fill table ${table}${type} in database ${gravityDBfile}\\n ${output}"
echo -e "\\n ${CROSS} Unable to fill table ${table}${list_type} in database ${gravityDBfile}\\n ${output}"
gravity_Cleanup "error"
fi
# Move source file to backup directory, create directory if not existing
mkdir -p "${backup_path}"
mv "${source}" "${backup_file}" 2> /dev/null || \
echo -e " ${CROSS} Unable to backup ${source} to ${backup_path}"
mv "${src}" "${backup_file}" 2> /dev/null || \
echo -e " ${CROSS} Unable to backup ${src} to ${backup_path}"
# Delete tmpFile
rm "${tmpFile}" > /dev/null 2>&1 || \
@@ -641,7 +642,7 @@ gravity_DownloadBlocklistFromUrl() {
fi
# shellcheck disable=SC2086
httpCode=$(curl -s -L ${compression} ${cmd_ext} ${heisenbergCompensator} -w "%{http_code}" -A "${agent}" "${url}" -o "${patternBuffer}" 2> /dev/null)
httpCode=$(curl --connect-timeout ${curl_connect_timeout} -s -L ${compression} ${cmd_ext} ${heisenbergCompensator} -w "%{http_code}" -A "${agent}" "${url}" -o "${patternBuffer}" 2> /dev/null)
case $url in
# Did we "download" a local file?
@@ -719,72 +720,25 @@ gravity_DownloadBlocklistFromUrl() {
# Parse source files into domains format
gravity_ParseFileIntoDomains() {
local source="${1}" destination="${2}" firstLine
local src="${1}" destination="${2}"
# Determine if we are parsing a consolidated list
#if [[ "${source}" == "${piholeDir}/${matterAndLight}" ]]; then
# Remove comments and print only the domain name
# Most of the lists downloaded are already in hosts file format but the spacing/formatting is not contiguous
# This helps with that and makes it easier to read
# It also helps with debugging so each stage of the script can be researched more in depth
# 1) Remove carriage returns
# 2) Convert all characters to lowercase
# 3) Remove comments (text starting with "#", include possible spaces before the hash sign)
# 4) Remove lines containing "/"
# 5) Remove leading tabs, spaces, etc.
# 6) Delete lines not matching domain names
< "${source}" tr -d '\r' | \
tr '[:upper:]' '[:lower:]' | \
sed 's/\s*#.*//g' | \
sed -r '/(\/).*$/d' | \
sed -r 's/^.*\s+//g' | \
sed -r '/([^\.]+\.)+[^\.]{2,}/!d' > "${destination}"
chmod 644 "${destination}"
return 0
#fi
# Individual file parsing: Keep comments, while parsing domains from each line
# We keep comments to respect the list maintainer's licensing
read -r firstLine < "${source}"
# Determine how to parse individual source file formats
if [[ "${firstLine,,}" =~ (adblock|ublock|^!) ]]; then
# Compare $firstLine against lower case words found in Adblock lists
echo -e " ${CROSS} Format: Adblock (list type not supported)"
elif grep -q "^address=/" "${source}" &> /dev/null; then
# Parse Dnsmasq format lists
echo -e " ${CROSS} Format: Dnsmasq (list type not supported)"
elif grep -q -E "^https?://" "${source}" &> /dev/null; then
# Parse URL list if source file contains "http://" or "https://"
# Scanning for "^IPv4$" is too slow with large (1M) lists on low-end hardware
echo -ne " ${INFO} Format: URL"
awk '
# Remove URL scheme, optional "username:password@", and ":?/;"
# The scheme must be matched carefully to avoid blocking the wrong URL
# in cases like:
# http://www.evil.com?http://www.good.com
# See RFC 3986 section 3.1 for details.
/[:?\/;]/ { gsub(/(^[a-zA-Z][a-zA-Z0-9+.-]*:\/\/(.*:.*@)?|[:?\/;].*)/, "", $0) }
# Skip lines which are only IPv4 addresses
/^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$/ { next }
# Print if nonempty
length { print }
' "${source}" 2> /dev/null > "${destination}"
chmod 644 "${destination}"
echo -e "${OVER} ${TICK} Format: URL"
else
# Default: Keep hosts/domains file in same format as it was downloaded
output=$( { mv "${source}" "${destination}"; } 2>&1 )
chmod 644 "${destination}"
if [[ ! -e "${destination}" ]]; then
echo -e "\\n ${CROSS} Unable to move tmp file to ${piholeDir}
${output}"
gravity_Cleanup "error"
fi
fi
# Remove comments and print only the domain name
# Most of the lists downloaded are already in hosts file format but the spacing/formatting is not contiguous
# This helps with that and makes it easier to read
# It also helps with debugging so each stage of the script can be researched more in depth
# 1) Remove carriage returns
# 2) Convert all characters to lowercase
# 3) Remove comments (text starting with "#", include possible spaces before the hash sign)
# 4) Remove lines containing "/"
# 5) Remove leading tabs, spaces, etc.
# 6) Delete lines not matching domain names
< "${src}" tr -d '\r' | \
tr '[:upper:]' '[:lower:]' | \
sed 's/\s*#.*//g' | \
sed -r '/(\/).*$/d' | \
sed -r 's/^.*\s+//g' | \
sed -r '/([^\.]+\.)+[^\.]{2,}/!d' > "${destination}"
chmod 644 "${destination}"
}
# Report number of entries in a table
@@ -870,15 +824,19 @@ gravity_Cleanup() {
database_recovery() {
local result
local str="Checking integrity of existing gravity database"
local str="Checking integrity of existing gravity database (this can take a while)"
local option="${1}"
echo -ne " ${INFO} ${str}..."
if result="$(pihole-FTL sqlite3 "${gravityDBfile}" "PRAGMA integrity_check" 2>&1)"; then
result="$(pihole-FTL sqlite3 "${gravityDBfile}" "PRAGMA integrity_check" 2>&1)"
if [[ ${result} = "ok" ]]; then
echo -e "${OVER} ${TICK} ${str} - no errors found"
str="Checking foreign keys of existing gravity database"
str="Checking foreign keys of existing gravity database (this can take a while)"
echo -ne " ${INFO} ${str}..."
if result="$(pihole-FTL sqlite3 "${gravityDBfile}" "PRAGMA foreign_key_check" 2>&1)"; then
unset result
result="$(pihole-FTL sqlite3 "${gravityDBfile}" "PRAGMA foreign_key_check" 2>&1)"
if [[ -z ${result} ]]; then
echo -e "${OVER} ${TICK} ${str} - no errors found"
if [[ "${option}" != "force" ]]; then
return

View File

@@ -11,8 +11,6 @@ Pi-hole : A black-hole for internet advertisements
.br
\fBpihole -a\fR (\fB-c|-f|-k\fR)
.br
\fBpihole -a -e\fR email
.br
\fBpihole -a -i\fR interface
.br
\fBpihole -a -l\fR privacylevel
@@ -132,9 +130,6 @@ Available commands and options:
-f, fahrenheit Set Fahrenheit as preferred temperature unit
.br
-k, kelvin Set Kelvin as preferred temperature unit
.br
-e, email Set an administrative contact address for the
Block Page
.br
-i, interface Specify dnsmasq's interface listening behavior
.br

103
pihole
View File

@@ -16,7 +16,6 @@ readonly PI_HOLE_SCRIPT_DIR="/opt/pihole"
# error due to modifying a readonly variable.
setupVars="/etc/pihole/setupVars.conf"
PI_HOLE_BIN_DIR="/usr/local/bin"
readonly FTL_PID_FILE="/run/pihole-FTL.pid"
readonly colfile="${PI_HOLE_SCRIPT_DIR}/COL_TABLE"
source "${colfile}"
@@ -36,19 +35,20 @@ listFunc() {
}
debugFunc() {
local automated
local web
local automated
local web
local check_database_integrity
# Pull off the `debug` leaving passed call augmentation flags in $1
shift
# Pull off the `debug` leaving passed call augmentation flags in $1
shift
if [[ "$@" == *"-a"* ]]; then
automated="true"
fi
if [[ "$@" == *"-w"* ]]; then
web="true"
fi
for value in "$@"; do
[[ "$value" == *"-a"* ]] && automated="true"
[[ "$value" == *"-w"* ]] && web="true"
[[ "$value" == *"-c"* ]] && check_database_integrity="true"
[[ "$value" == *"--check_database"* ]] && check_database_integrity="true"
done
AUTOMATED=${automated:-} WEBCALL=${web:-} "${PI_HOLE_SCRIPT_DIR}"/piholeDebug.sh
AUTOMATED=${automated:-} WEBCALL=${web:-} CHECK_DATABASE=${check_database_integrity:-} "${PI_HOLE_SCRIPT_DIR}"/piholeDebug.sh
exit 0
}
@@ -100,34 +100,21 @@ versionFunc() {
exec "${PI_HOLE_SCRIPT_DIR}"/version.sh "$@"
}
# Get PID of main pihole-FTL process
getFTLPID() {
local pid
if [ -s "${FTL_PID_FILE}" ]; then
# -s: FILE exists and has a size greater than zero
pid="$(<"$FTL_PID_FILE")"
# Exploit prevention: unset the variable if there is malicious content
# Verify that the value read from the file is numeric
[[ "$pid" =~ [^[:digit:]] ]] && unset pid
fi
# If FTL is not running, or the PID file contains malicious stuff, substitute
# negative PID to signal this to the caller
echo "${pid:=-1}"
}
restartDNS() {
local svcOption svc str output status pid icon
local svcOption svc str output status pid icon FTL_PID_FILE
svcOption="${1:-restart}"
# get the current path to the pihole-FTL.pid
FTL_PID_FILE="$(getFTLPIDFile)"
# Determine if we should reload or restart
if [[ "${svcOption}" =~ "reload-lists" ]]; then
# Reloading of the lists has been requested
# Note 1: This will NOT re-read any *.conf files
# Note 2: We cannot use killall here as it does
# not know about real-time signals
pid="$(getFTLPID)"
pid="$(getFTLPID ${FTL_PID_FILE})"
if [[ "$pid" -eq "-1" ]]; then
svc="true"
str="FTL is not running"
@@ -140,7 +127,7 @@ restartDNS() {
elif [[ "${svcOption}" =~ "reload" ]]; then
# Reloading of the DNS cache has been requested
# Note: This will NOT re-read any *.conf files
pid="$(getFTLPID)"
pid="$(getFTLPID ${FTL_PID_FILE})"
if [[ "$pid" -eq "-1" ]]; then
svc="true"
str="FTL is not running"
@@ -315,33 +302,36 @@ analyze_ports() {
}
statusFunc() {
# Determine if there is pihole-FTL service is listening
local pid port ftl_api_port
# Determine if there is pihole-FTL service is listening
local pid port ftl_api_port ftl_pid_file
pid="$(getFTLPID)"
ftl_api_port="$(getFTLAPIPort)"
if [[ "$pid" -eq "-1" ]]; then
case "${1}" in
"web") echo "-1";;
*) echo -e " ${CROSS} DNS service is NOT running";;
esac
return 0
else
#get the DNS port pihole-FTL is listening on by using FTL's telnet API
port="$(echo ">dns-port >quit" | nc 127.0.0.1 "$ftl_api_port")"
if [[ "${port}" == "0" ]]; then
case "${1}" in
"web") echo "-1";;
*) echo -e " ${CROSS} DNS service is NOT listening";;
esac
return 0
ftl_pid_file="$(getFTLPIDFile)"
pid="$(getFTLPID ${ftl_pid_file})"
ftl_api_port="$(getFTLAPIPort)"
if [[ "$pid" -eq "-1" ]]; then
case "${1}" in
"web") echo "-1";;
*) echo -e " ${CROSS} DNS service is NOT running";;
esac
return 0
else
if [[ "${1}" != "web" ]]; then
echo -e " ${TICK} FTL is listening on port ${port}"
analyze_ports "${port}"
fi
#get the DNS port pihole-FTL is listening on by using FTL's telnet API
port="$(echo ">dns-port >quit" | nc 127.0.0.1 "$ftl_api_port")"
if [[ "${port}" == "0" ]]; then
case "${1}" in
"web") echo "-1";;
*) echo -e " ${CROSS} DNS service is NOT listening";;
esac
return 0
else
if [[ "${1}" != "web" ]]; then
echo -e " ${TICK} FTL is listening on port ${port}"
analyze_ports "${port}"
fi
fi
fi
fi
# Determine if Pi-hole's blocking is enabled
if grep -q "BLOCKING_ENABLED=false" /etc/pihole/setupVars.conf; then
@@ -455,6 +445,7 @@ Whitelist/Blacklist Options:
Debugging Options:
-d, debug Start a debugging session
Add '-c' or '--check-database' to include a Pi-hole database integrity check
Add '-a' to automatically upload the log to tricorder.pi-hole.net
-f, flush Flush the Pi-hole log
-r, reconfigure Reconfigure or Repair Pi-hole subsystems

View File

@@ -1,19 +0,0 @@
FROM centos:7
RUN yum install -y dialog git python3
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
ADD test/centos7.epel.override /etc/yum/pluginconf.d/fastestmirror.conf
RUN true && \
chmod +x $SCRIPTDIR/*
ENV PH_TEST true
ENV OS_CHECK_DOMAIN_NAME dev-supportedos.pi-hole.net
#sed '/# Start the installer/Q' /opt/pihole/basic-install.sh > /opt/pihole/stub_basic-install.sh && \

View File

@@ -1,5 +1,5 @@
FROM quay.io/centos/centos:stream8
RUN yum install -y git
RUN yum install -y git initscripts
ENV GITDIR /etc/.pihole
ENV SCRIPTDIR /opt/pihole
@@ -12,7 +12,7 @@ ENV PATH /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:$SCRIPTDIR
RUN true && \
chmod +x $SCRIPTDIR/*
ENV PH_TEST true
ENV SKIP_INSTALL true
ENV OS_CHECK_DOMAIN_NAME dev-supportedos.pi-hole.net
#sed '/# Start the installer/Q' /opt/pihole/basic-install.sh > /opt/pihole/stub_basic-install.sh && \

View File

@@ -1,4 +1,5 @@
FROM buildpack-deps:impish-scm
FROM quay.io/centos/centos:stream9
RUN yum install -y --allowerasing curl git initscripts
ENV GITDIR /etc/.pihole
ENV SCRIPTDIR /opt/pihole
@@ -7,12 +8,11 @@ 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
ENV DEBIAN_FRONTEND=noninteractive
RUN true && \
chmod +x $SCRIPTDIR/*
ENV PH_TEST true
ENV SKIP_INSTALL true
ENV OS_CHECK_DOMAIN_NAME dev-supportedos.pi-hole.net
#sed '/# Start the installer/Q' /opt/pihole/basic-install.sh > /opt/pihole/stub_basic-install.sh && \

View File

@@ -11,7 +11,7 @@ ENV PATH /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:$SCRIPTDIR
RUN true && \
chmod +x $SCRIPTDIR/*
ENV PH_TEST true
ENV SKIP_INSTALL true
ENV OS_CHECK_DOMAIN_NAME dev-supportedos.pi-hole.net
#sed '/# Start the installer/Q' /opt/pihole/basic-install.sh > /opt/pihole/stub_basic-install.sh && \

View File

@@ -11,7 +11,7 @@ ENV PATH /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:$SCRIPTDIR
RUN true && \
chmod +x $SCRIPTDIR/*
ENV PH_TEST true
ENV SKIP_INSTALL true
ENV OS_CHECK_DOMAIN_NAME dev-supportedos.pi-hole.net
#sed '/# Start the installer/Q' /opt/pihole/basic-install.sh > /opt/pihole/stub_basic-install.sh && \

View File

@@ -1,5 +1,5 @@
FROM fedora:34
RUN dnf install -y git
FROM fedora:35
RUN dnf install -y git initscripts
ENV GITDIR /etc/.pihole
ENV SCRIPTDIR /opt/pihole
@@ -12,7 +12,7 @@ ENV PATH /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:$SCRIPTDIR
RUN true && \
chmod +x $SCRIPTDIR/*
ENV PH_TEST true
ENV SKIP_INSTALL true
ENV OS_CHECK_DOMAIN_NAME dev-supportedos.pi-hole.net
#sed '/# Start the installer/Q' /opt/pihole/basic-install.sh > /opt/pihole/stub_basic-install.sh && \

View File

@@ -1,4 +1,5 @@
FROM buildpack-deps:bionic-scm
FROM fedora:36
RUN dnf install -y git initscripts
ENV GITDIR /etc/.pihole
ENV SCRIPTDIR /opt/pihole
@@ -11,7 +12,7 @@ ENV PATH /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:$SCRIPTDIR
RUN true && \
chmod +x $SCRIPTDIR/*
ENV PH_TEST true
ENV SKIP_INSTALL true
ENV OS_CHECK_DOMAIN_NAME dev-supportedos.pi-hole.net
#sed '/# Start the installer/Q' /opt/pihole/basic-install.sh > /opt/pihole/stub_basic-install.sh && \

View File

@@ -12,7 +12,7 @@ ENV DEBIAN_FRONTEND=noninteractive
RUN true && \
chmod +x $SCRIPTDIR/*
ENV PH_TEST true
ENV SKIP_INSTALL true
ENV OS_CHECK_DOMAIN_NAME dev-supportedos.pi-hole.net
#sed '/# Start the installer/Q' /opt/pihole/basic-install.sh > /opt/pihole/stub_basic-install.sh && \

View File

@@ -12,7 +12,7 @@ ENV DEBIAN_FRONTEND=noninteractive
RUN true && \
chmod +x $SCRIPTDIR/*
ENV PH_TEST true
ENV SKIP_INSTALL true
ENV OS_CHECK_DOMAIN_NAME dev-supportedos.pi-hole.net
#sed '/# Start the installer/Q' /opt/pihole/basic-install.sh > /opt/pihole/stub_basic-install.sh && \

View File

@@ -1,7 +0,0 @@
[main]
verbose = 0
socket_timeout = 3
enabled = 1
hostfilepath = /var/cache/yum/timedhosts.txt
maxhostfileage = 1
exclude=.edu

View File

@@ -6,12 +6,12 @@ from textwrap import dedent
SETUPVARS = {
'PIHOLE_INTERFACE': 'eth99',
'PIHOLE_DNS_1': '4.2.2.1',
'PIHOLE_DNS_2': '4.2.2.2'
"PIHOLE_INTERFACE": "eth99",
"PIHOLE_DNS_1": "4.2.2.1",
"PIHOLE_DNS_2": "4.2.2.2",
}
IMAGE = 'pytest_pihole:test_container'
IMAGE = "pytest_pihole:test_container"
tick_box = "[\x1b[1;32m\u2713\x1b[0m]"
cross_box = "[\x1b[1;31m\u2717\x1b[0m]"
@@ -38,132 +38,187 @@ testinfra.backend.docker.DockerBackend.run = run_bash
@pytest.fixture
def host():
# run a container
docker_id = subprocess.check_output(
['docker', 'run', '-t', '-d', '--cap-add=ALL', IMAGE]).decode().strip()
docker_id = (
subprocess.check_output(["docker", "run", "-t", "-d", "--cap-add=ALL", IMAGE])
.decode()
.strip()
)
# return a testinfra connection to the container
docker_host = testinfra.get_host("docker://" + docker_id)
yield docker_host
# at the end of the test suite, destroy the container
subprocess.check_call(['docker', 'rm', '-f', docker_id])
subprocess.check_call(["docker", "rm", "-f", docker_id])
# Helper functions
def mock_command(script, args, container):
'''
"""
Allows for setup of commands we don't really want to have to run for real
in unit tests
'''
full_script_path = '/usr/local/bin/{}'.format(script)
mock_script = dedent(r'''\
"""
full_script_path = "/usr/local/bin/{}".format(script)
mock_script = dedent(
r"""\
#!/bin/bash -e
echo "\$0 \$@" >> /var/log/{script}
case "\$1" in'''.format(script=script))
case "\$1" in""".format(
script=script
)
)
for k, v in args.items():
case = dedent('''
case = dedent(
"""
{arg})
echo {res}
exit {retcode}
;;'''.format(arg=k, res=v[0], retcode=v[1]))
;;""".format(
arg=k, res=v[0], retcode=v[1]
)
)
mock_script += case
mock_script += dedent('''
esac''')
container.run('''
mock_script += dedent(
"""
esac"""
)
container.run(
"""
cat <<EOF> {script}\n{content}\nEOF
chmod +x {script}
rm -f /var/log/{scriptlog}'''.format(script=full_script_path,
content=mock_script,
scriptlog=script))
rm -f /var/log/{scriptlog}""".format(
script=full_script_path, content=mock_script, scriptlog=script
)
)
def mock_command_passthrough(script, args, container):
'''
"""
Per other mock_command* functions, allows intercepting of commands we don't want to run for real
in unit tests, however also allows only specific arguments to be mocked. Anything not defined will
be passed through to the actual command.
Example use-case: mocking `git pull` but still allowing `git clone` to work as intended
'''
orig_script_path = container.check_output('command -v {}'.format(script))
full_script_path = '/usr/local/bin/{}'.format(script)
mock_script = dedent(r'''\
"""
orig_script_path = container.check_output("command -v {}".format(script))
full_script_path = "/usr/local/bin/{}".format(script)
mock_script = dedent(
r"""\
#!/bin/bash -e
echo "\$0 \$@" >> /var/log/{script}
case "\$1" in'''.format(script=script))
case "\$1" in""".format(
script=script
)
)
for k, v in args.items():
case = dedent('''
case = dedent(
"""
{arg})
echo {res}
exit {retcode}
;;'''.format(arg=k, res=v[0], retcode=v[1]))
;;""".format(
arg=k, res=v[0], retcode=v[1]
)
)
mock_script += case
mock_script += dedent(r'''
mock_script += dedent(
r"""
*)
{orig_script_path} "\$@"
;;'''.format(orig_script_path=orig_script_path))
mock_script += dedent('''
esac''')
container.run('''
;;""".format(
orig_script_path=orig_script_path
)
)
mock_script += dedent(
"""
esac"""
)
container.run(
"""
cat <<EOF> {script}\n{content}\nEOF
chmod +x {script}
rm -f /var/log/{scriptlog}'''.format(script=full_script_path,
content=mock_script,
scriptlog=script))
rm -f /var/log/{scriptlog}""".format(
script=full_script_path, content=mock_script, scriptlog=script
)
)
def mock_command_run(script, args, container):
'''
"""
Allows for setup of commands we don't really want to have to run for real
in unit tests
'''
full_script_path = '/usr/local/bin/{}'.format(script)
mock_script = dedent(r'''\
"""
full_script_path = "/usr/local/bin/{}".format(script)
mock_script = dedent(
r"""\
#!/bin/bash -e
echo "\$0 \$@" >> /var/log/{script}
case "\$1 \$2" in'''.format(script=script))
case "\$1 \$2" in""".format(
script=script
)
)
for k, v in args.items():
case = dedent('''
case = dedent(
"""
\"{arg}\")
echo {res}
exit {retcode}
;;'''.format(arg=k, res=v[0], retcode=v[1]))
;;""".format(
arg=k, res=v[0], retcode=v[1]
)
)
mock_script += case
mock_script += dedent('''
esac''')
container.run('''
mock_script += dedent(
"""
esac"""
)
container.run(
"""
cat <<EOF> {script}\n{content}\nEOF
chmod +x {script}
rm -f /var/log/{scriptlog}'''.format(script=full_script_path,
content=mock_script,
scriptlog=script))
rm -f /var/log/{scriptlog}""".format(
script=full_script_path, content=mock_script, scriptlog=script
)
)
def mock_command_2(script, args, container):
'''
"""
Allows for setup of commands we don't really want to have to run for real
in unit tests
'''
full_script_path = '/usr/local/bin/{}'.format(script)
mock_script = dedent(r'''\
"""
full_script_path = "/usr/local/bin/{}".format(script)
mock_script = dedent(
r"""\
#!/bin/bash -e
echo "\$0 \$@" >> /var/log/{script}
case "\$1 \$2" in'''.format(script=script))
case "\$1 \$2" in""".format(
script=script
)
)
for k, v in args.items():
case = dedent('''
case = dedent(
"""
\"{arg}\")
echo \"{res}\"
exit {retcode}
;;'''.format(arg=k, res=v[0], retcode=v[1]))
;;""".format(
arg=k, res=v[0], retcode=v[1]
)
)
mock_script += case
mock_script += dedent('''
esac''')
container.run('''
mock_script += dedent(
"""
esac"""
)
container.run(
"""
cat <<EOF> {script}\n{content}\nEOF
chmod +x {script}
rm -f /var/log/{scriptlog}'''.format(script=full_script_path,
content=mock_script,
scriptlog=script))
rm -f /var/log/{scriptlog}""".format(
script=full_script_path, content=mock_script, scriptlog=script
)
)
def run_script(Pihole, script):

View File

@@ -1,6 +1,5 @@
docker-compose
pytest
pytest-xdist
pytest-cov
pytest-testinfra
tox

View File

@@ -1,6 +1,7 @@
from setuptools import setup
setup(
setup_requires=['pytest-runner'],
tests_require=['pytest'],
py_modules=[],
setup_requires=["pytest-runner"],
tests_require=["pytest"],
)

File diff suppressed because it is too large Load Diff

View File

@@ -1,22 +1,27 @@
def test_key_val_replacement_works(host):
''' Confirms addOrEditKeyValPair either adds or replaces a key value pair in a given file '''
host.run('''
"""Confirms addOrEditKeyValPair either adds or replaces a key value pair in a given file"""
host.run(
"""
source /opt/pihole/utils.sh
addOrEditKeyValPair "./testoutput" "KEY_ONE" "value1"
addOrEditKeyValPair "./testoutput" "KEY_TWO" "value2"
addOrEditKeyValPair "./testoutput" "KEY_ONE" "value3"
addOrEditKeyValPair "./testoutput" "KEY_FOUR" "value4"
''')
output = host.run('''
"""
)
output = host.run(
"""
cat ./testoutput
''')
expected_stdout = 'KEY_ONE=value3\nKEY_TWO=value2\nKEY_FOUR=value4\n'
"""
)
expected_stdout = "KEY_ONE=value3\nKEY_TWO=value2\nKEY_FOUR=value4\n"
assert expected_stdout == output.stdout
def test_key_addition_works(host):
''' Confirms addKey adds a key (no value) to a file without duplicating it '''
host.run('''
"""Confirms addKey adds a key (no value) to a file without duplicating it"""
host.run(
"""
source /opt/pihole/utils.sh
addKey "./testoutput" "KEY_ONE"
addKey "./testoutput" "KEY_ONE"
@@ -24,17 +29,21 @@ def test_key_addition_works(host):
addKey "./testoutput" "KEY_TWO"
addKey "./testoutput" "KEY_THREE"
addKey "./testoutput" "KEY_THREE"
''')
output = host.run('''
"""
)
output = host.run(
"""
cat ./testoutput
''')
expected_stdout = 'KEY_ONE\nKEY_TWO\nKEY_THREE\n'
"""
)
expected_stdout = "KEY_ONE\nKEY_TWO\nKEY_THREE\n"
assert expected_stdout == output.stdout
def test_key_removal_works(host):
''' Confirms removeKey removes a key or key/value pair '''
host.run('''
"""Confirms removeKey removes a key or key/value pair"""
host.run(
"""
source /opt/pihole/utils.sh
addOrEditKeyValPair "./testoutput" "KEY_ONE" "value1"
addOrEditKeyValPair "./testoutput" "KEY_TWO" "value2"
@@ -42,33 +51,102 @@ def test_key_removal_works(host):
addKey "./testoutput" "KEY_FOUR"
removeKey "./testoutput" "KEY_TWO"
removeKey "./testoutput" "KEY_FOUR"
''')
output = host.run('''
"""
)
output = host.run(
"""
cat ./testoutput
''')
expected_stdout = 'KEY_ONE=value1\nKEY_THREE=value3\n'
"""
)
expected_stdout = "KEY_ONE=value1\nKEY_THREE=value3\n"
assert expected_stdout == output.stdout
def test_getFTLAPIPort_default(host):
''' Confirms getFTLAPIPort returns the default API port '''
output = host.run('''
"""Confirms getFTLAPIPort returns the default API port"""
output = host.run(
"""
source /opt/pihole/utils.sh
getFTLAPIPort
''')
expected_stdout = '4711\n'
"""
)
expected_stdout = "4711\n"
assert expected_stdout == output.stdout
def test_getFTLAPIPort_custom(host):
''' Confirms getFTLAPIPort returns a custom API port in a custom PORTFILE location '''
host.run('''
echo "PORTFILE=/tmp/port.file" > /etc/pihole/pihole-FTL.conf
echo "1234" > /tmp/port.file
''')
output = host.run('''
"""Confirms getFTLAPIPort returns a custom API port"""
host.run(
"""
echo "FTLPORT=1234" > /etc/pihole/pihole-FTL.conf
"""
)
output = host.run(
"""
source /opt/pihole/utils.sh
getFTLAPIPort
''')
expected_stdout = '1234\n'
"""
)
expected_stdout = "1234\n"
assert expected_stdout == output.stdout
def test_getFTLAPIPort_malicious(host):
"""Confirms getFTLAPIPort returns 4711 if the setting in pihole-FTL.conf contains non-digits"""
host.run(
"""
echo "FTLPORT=*$ssdfsd" > /etc/pihole/pihole-FTL.conf
"""
)
output = host.run(
"""
source /opt/pihole/utils.sh
getFTLAPIPort
"""
)
expected_stdout = "4711\n"
assert expected_stdout == output.stdout
def test_getFTLPIDFile_default(host):
"""Confirms getFTLPIDFile returns the default PID file path"""
output = host.run(
"""
source /opt/pihole/utils.sh
getFTLPIDFile
"""
)
expected_stdout = "/run/pihole-FTL.pid\n"
assert expected_stdout == output.stdout
def test_getFTLPID_default(host):
"""Confirms getFTLPID returns the default value if FTL is not running"""
output = host.run(
"""
source /opt/pihole/utils.sh
getFTLPID
"""
)
expected_stdout = "-1\n"
assert expected_stdout == output.stdout
def test_getFTLPIDFile_and_getFTLPID_custom(host):
"""Confirms getFTLPIDFile returns a custom PID file path"""
host.run(
"""
tmpfile=$(mktemp)
echo "PIDFILE=${tmpfile}" > /etc/pihole/pihole-FTL.conf
echo "1234" > ${tmpfile}
"""
)
output = host.run(
"""
source /opt/pihole/utils.sh
FTL_PID_FILE=$(getFTLPIDFile)
getFTLPID "${FTL_PID_FILE}"
"""
)
expected_stdout = "1234\n"
assert expected_stdout == output.stdout

View File

@@ -1,63 +0,0 @@
from .conftest import (
tick_box,
info_box,
mock_command,
)
def test_php_upgrade_default_optout_centos_eq_7(host):
'''
confirms the default behavior to opt-out of installing PHP7 from REMI
'''
package_manager_detect = host.run('''
source /opt/pihole/basic-install.sh
package_manager_detect
select_rpm_php
''')
expected_stdout = info_box + (' User opt-out of PHP 7 upgrade on CentOS. '
'Deprecated PHP may be in use.')
assert expected_stdout in package_manager_detect.stdout
remi_package = host.package('remi-release')
assert not remi_package.is_installed
def test_php_upgrade_user_optout_centos_eq_7(host):
'''
confirms installer behavior when user opt-out of installing PHP7 from REMI
(php not currently installed)
'''
# dialog returns Cancel for user prompt
mock_command('dialog', {'*': ('', '1')}, host)
package_manager_detect = host.run('''
source /opt/pihole/basic-install.sh
package_manager_detect
select_rpm_php
''')
expected_stdout = info_box + (' User opt-out of PHP 7 upgrade on CentOS. '
'Deprecated PHP may be in use.')
assert expected_stdout in package_manager_detect.stdout
remi_package = host.package('remi-release')
assert not remi_package.is_installed
def test_php_upgrade_user_optin_centos_eq_7(host):
'''
confirms installer behavior when user opt-in to installing PHP7 from REMI
(php not currently installed)
'''
# dialog returns Continue for user prompt
mock_command('dialog', {'*': ('', '0')}, host)
package_manager_detect = host.run('''
source /opt/pihole/basic-install.sh
package_manager_detect
select_rpm_php
''')
assert 'opt-out' not in package_manager_detect.stdout
expected_stdout = info_box + (' Enabling Remi\'s RPM repository '
'(https://rpms.remirepo.net)')
assert expected_stdout in package_manager_detect.stdout
expected_stdout = tick_box + (' Remi\'s RPM repository has '
'been enabled for PHP7')
assert expected_stdout in package_manager_detect.stdout
remi_package = host.package('remi-release')
assert remi_package.is_installed

View File

@@ -1,68 +0,0 @@
from .conftest import (
tick_box,
info_box,
mock_command,
)
def test_php_upgrade_default_continue_centos_gte_8(host):
'''
confirms the latest version of CentOS continues / does not optout
(should trigger on CentOS7 only)
'''
package_manager_detect = host.run('''
source /opt/pihole/basic-install.sh
package_manager_detect
select_rpm_php
''')
unexpected_stdout = info_box + (' User opt-out of PHP 7 upgrade on CentOS.'
' Deprecated PHP may be in use.')
assert unexpected_stdout not in package_manager_detect.stdout
# ensure remi was not installed on latest CentOS
remi_package = host.package('remi-release')
assert not remi_package.is_installed
def test_php_upgrade_user_optout_skipped_centos_gte_8(host):
'''
confirms installer skips user opt-out of installing PHP7 from REMI on
latest CentOS (should trigger on CentOS7 only)
(php not currently installed)
'''
# dialog dialog returns Cancel for user prompt
mock_command('dialog', {'*': ('', '1')}, host)
package_manager_detect = host.run('''
source /opt/pihole/basic-install.sh
package_manager_detect
select_rpm_php
''')
unexpected_stdout = info_box + (' User opt-out of PHP 7 upgrade on CentOS.'
' Deprecated PHP may be in use.')
assert unexpected_stdout not in package_manager_detect.stdout
# ensure remi was not installed on latest CentOS
remi_package = host.package('remi-release')
assert not remi_package.is_installed
def test_php_upgrade_user_optin_skipped_centos_gte_8(host):
'''
confirms installer skips user opt-in to installing PHP7 from REMI on
latest CentOS (should trigger on CentOS7 only)
(php not currently installed)
'''
# dialog dialog returns Continue for user prompt
mock_command('dialog', {'*': ('', '0')}, host)
package_manager_detect = host.run('''
source /opt/pihole/basic-install.sh
package_manager_detect
select_rpm_php
''')
assert 'opt-out' not in package_manager_detect.stdout
unexpected_stdout = info_box + (' Enabling Remi\'s RPM repository '
'(https://rpms.remirepo.net)')
assert unexpected_stdout not in package_manager_detect.stdout
unexpected_stdout = tick_box + (' Remi\'s RPM repository has '
'been enabled for PHP7')
assert unexpected_stdout not in package_manager_detect.stdout
remi_package = host.package('remi-release')
assert not remi_package.is_installed

View File

@@ -7,119 +7,21 @@ from .conftest import (
)
def test_release_supported_version_check_centos(host):
'''
confirms installer exits on unsupported releases of CentOS
'''
# modify /etc/redhat-release to mock an unsupported CentOS release
host.run('echo "CentOS Linux release 6.9" > /etc/redhat-release')
package_manager_detect = host.run('''
source /opt/pihole/basic-install.sh
package_manager_detect
select_rpm_php
''')
expected_stdout = cross_box + (' CentOS 6 is not supported.')
assert expected_stdout in package_manager_detect.stdout
expected_stdout = 'Please update to CentOS release 7 or later'
assert expected_stdout in package_manager_detect.stdout
def test_enable_epel_repository_centos(host):
'''
"""
confirms the EPEL package repository is enabled when installed on CentOS
'''
package_manager_detect = host.run('''
"""
package_manager_detect = host.run(
"""
source /opt/pihole/basic-install.sh
package_manager_detect
select_rpm_php
''')
expected_stdout = info_box + (' Enabling EPEL package repository '
'(https://fedoraproject.org/wiki/EPEL)')
"""
)
expected_stdout = info_box + (
" Enabling EPEL package repository " "(https://fedoraproject.org/wiki/EPEL)"
)
assert expected_stdout in package_manager_detect.stdout
expected_stdout = tick_box + ' Installed'
expected_stdout = tick_box + " Installed"
assert expected_stdout in package_manager_detect.stdout
epel_package = host.package('epel-release')
epel_package = host.package("epel-release")
assert epel_package.is_installed
def test_php_version_lt_7_detected_upgrade_default_optout_centos(host):
'''
confirms the default behavior to opt-out of upgrading to PHP7 from REMI
'''
# first we will install the default php version to test installer behavior
php_install = host.run('yum install -y php')
assert php_install.rc == 0
php_package = host.package('php')
default_centos_php_version = php_package.version.split('.')[0]
if int(default_centos_php_version) >= 7: # PHP7 is supported/recommended
pytest.skip("Test deprecated . Detected default PHP version >= 7")
package_manager_detect = host.run('''
source /opt/pihole/basic-install.sh
package_manager_detect
select_rpm_php
''')
expected_stdout = info_box + (' User opt-out of PHP 7 upgrade on CentOS. '
'Deprecated PHP may be in use.')
assert expected_stdout in package_manager_detect.stdout
remi_package = host.package('remi-release')
assert not remi_package.is_installed
def test_php_version_lt_7_detected_upgrade_user_optout_centos(host):
'''
confirms installer behavior when user opt-out to upgrade to PHP7 via REMI
'''
# first we will install the default php version to test installer behavior
php_install = host.run('yum install -y php')
assert php_install.rc == 0
php_package = host.package('php')
default_centos_php_version = php_package.version.split('.')[0]
if int(default_centos_php_version) >= 7: # PHP7 is supported/recommended
pytest.skip("Test deprecated . Detected default PHP version >= 7")
# dialog returns Cancel for user prompt
mock_command('dialog', {'*': ('', '1')}, host)
package_manager_detect = host.run('''
source /opt/pihole/basic-install.sh
package_manager_detect
select_rpm_php
''')
expected_stdout = info_box + (' User opt-out of PHP 7 upgrade on CentOS. '
'Deprecated PHP may be in use.')
assert expected_stdout in package_manager_detect.stdout
remi_package = host.package('remi-release')
assert not remi_package.is_installed
def test_php_version_lt_7_detected_upgrade_user_optin_centos(host):
'''
confirms installer behavior when user opt-in to upgrade to PHP7 via REMI
'''
# first we will install the default php version to test installer behavior
php_install = host.run('yum install -y php')
assert php_install.rc == 0
php_package = host.package('php')
default_centos_php_version = php_package.version.split('.')[0]
if int(default_centos_php_version) >= 7: # PHP7 is supported/recommended
pytest.skip("Test deprecated . Detected default PHP version >= 7")
# dialog returns Continue for user prompt
mock_command('dialog', {'*': ('', '0')}, host)
package_manager_detect = host.run('''
source /opt/pihole/basic-install.sh
package_manager_detect
select_rpm_php
install_dependent_packages PIHOLE_WEB_DEPS[@]
''')
expected_stdout = info_box + (' User opt-out of PHP 7 upgrade on CentOS. '
'Deprecated PHP may be in use.')
assert expected_stdout not in package_manager_detect.stdout
expected_stdout = info_box + (' Enabling Remi\'s RPM repository '
'(https://rpms.remirepo.net)')
assert expected_stdout in package_manager_detect.stdout
expected_stdout = tick_box + (' Remi\'s RPM repository has '
'been enabled for PHP7')
assert expected_stdout in package_manager_detect.stdout
remi_package = host.package('remi-release')
assert remi_package.is_installed
updated_php_package = host.package('php')
updated_php_version = updated_php_package.version.split('.')[0]
assert int(updated_php_version) == 7

View File

@@ -6,60 +6,70 @@ from .conftest import (
def mock_selinux_config(state, host):
'''
"""
Creates a mock SELinux config file with expected content
'''
"""
# validate state string
valid_states = ['enforcing', 'permissive', 'disabled']
valid_states = ["enforcing", "permissive", "disabled"]
assert state in valid_states
# getenforce returns the running state of SELinux
mock_command('getenforce', {'*': (state.capitalize(), '0')}, host)
mock_command("getenforce", {"*": (state.capitalize(), "0")}, host)
# create mock configuration with desired content
host.run('''
host.run(
"""
mkdir /etc/selinux
echo "SELINUX={state}" > /etc/selinux/config
'''.format(state=state.lower()))
""".format(
state=state.lower()
)
)
def test_selinux_enforcing_exit(host):
'''
"""
confirms installer prompts to exit when SELinux is Enforcing by default
'''
"""
mock_selinux_config("enforcing", host)
check_selinux = host.run('''
check_selinux = host.run(
"""
source /opt/pihole/basic-install.sh
checkSelinux
''')
expected_stdout = cross_box + ' Current SELinux: Enforcing'
"""
)
expected_stdout = cross_box + " Current SELinux: enforcing"
assert expected_stdout in check_selinux.stdout
expected_stdout = 'SELinux Enforcing detected, exiting installer'
expected_stdout = "SELinux Enforcing detected, exiting installer"
assert expected_stdout in check_selinux.stdout
assert check_selinux.rc == 1
def test_selinux_permissive(host):
'''
"""
confirms installer continues when SELinux is Permissive
'''
"""
mock_selinux_config("permissive", host)
check_selinux = host.run('''
check_selinux = host.run(
"""
source /opt/pihole/basic-install.sh
checkSelinux
''')
expected_stdout = tick_box + ' Current SELinux: Permissive'
"""
)
expected_stdout = tick_box + " Current SELinux: permissive"
assert expected_stdout in check_selinux.stdout
assert check_selinux.rc == 0
def test_selinux_disabled(host):
'''
"""
confirms installer continues when SELinux is Disabled
'''
"""
mock_selinux_config("disabled", host)
check_selinux = host.run('''
check_selinux = host.run(
"""
source /opt/pihole/basic-install.sh
checkSelinux
''')
expected_stdout = tick_box + ' Current SELinux: Disabled'
"""
)
expected_stdout = tick_box + " Current SELinux: disabled"
assert expected_stdout in check_selinux.stdout
assert check_selinux.rc == 0

View File

@@ -1,16 +1,15 @@
def test_epel_and_remi_not_installed_fedora(host):
'''
"""
confirms installer does not attempt to install EPEL/REMI repositories
on Fedora
'''
package_manager_detect = host.run('''
"""
package_manager_detect = host.run(
"""
source /opt/pihole/basic-install.sh
package_manager_detect
select_rpm_php
''')
assert package_manager_detect.stdout == ''
"""
)
assert package_manager_detect.stdout == ""
epel_package = host.package('epel-release')
epel_package = host.package("epel-release")
assert not epel_package.is_installed
remi_package = host.package('remi-release')
assert not remi_package.is_installed

View File

@@ -1,8 +1,8 @@
[tox]
envlist = py38
envlist = py3
[testenv]
whitelist_externals = docker
allowlist_externals = docker
deps = -rrequirements.txt
commands = docker build -f _centos_8.Dockerfile -t pytest_pihole:test_container ../
pytest {posargs:-vv -n auto} ./test_any_automated_install.py ./test_any_utils.py ./test_centos_fedora_common_support.py ./test_centos_common_support.py ./test_centos_8_support.py
pytest {posargs:-vv -n auto} ./test_any_automated_install.py ./test_any_utils.py ./test_centos_fedora_common_support.py ./test_centos_common_support.py

View File

@@ -1,8 +1,8 @@
[tox]
envlist = py38
envlist = py3
[testenv]
whitelist_externals = docker
allowlist_externals = docker
deps = -rrequirements.txt
commands = docker build -f _centos_7.Dockerfile -t pytest_pihole:test_container ../
pytest {posargs:-vv -n auto} ./test_any_automated_install.py ./test_any_utils.py ./test_centos_fedora_common_support.py ./test_centos_common_support.py ./test_centos_7_support.py
commands = docker build -f _centos_9.Dockerfile -t pytest_pihole:test_container ../
pytest {posargs:-vv -n auto} ./test_any_automated_install.py ./test_any_utils.py ./test_centos_fedora_common_support.py ./test_centos_common_support.py

View File

@@ -1,8 +1,8 @@
[tox]
envlist = py38
envlist = py3
[testenv]
whitelist_externals = docker
allowlist_externals = docker
deps = -rrequirements.txt
commands = docker build -f _debian_10.Dockerfile -t pytest_pihole:test_container ../
pytest {posargs:-vv -n auto} ./test_any_automated_install.py ./test_any_utils.py

View File

@@ -1,8 +1,8 @@
[tox]
envlist = py38
envlist = py3
[testenv]
whitelist_externals = docker
allowlist_externals = docker
deps = -rrequirements.txt
commands = docker build -f _debian_11.Dockerfile -t pytest_pihole:test_container ../
pytest {posargs:-vv -n auto} ./test_any_automated_install.py ./test_any_utils.py

View File

@@ -1,8 +1,8 @@
[tox]
envlist = py38
envlist = py3
[testenv]
whitelist_externals = docker
allowlist_externals = docker
deps = -rrequirements.txt
commands = docker build -f _fedora_34.Dockerfile -t pytest_pihole:test_container ../
commands = docker build -f _fedora_35.Dockerfile -t pytest_pihole:test_container ../
pytest {posargs:-vv -n auto} ./test_any_automated_install.py ./test_any_utils.py ./test_centos_fedora_common_support.py ./test_fedora_support.py

8
test/tox.fedora_36.ini Normal file
View File

@@ -0,0 +1,8 @@
[tox]
envlist = py3
[testenv]
allowlist_externals = docker
deps = -rrequirements.txt
commands = docker build -f _fedora_36.Dockerfile -t pytest_pihole:test_container ../
pytest {posargs:-vv -n auto} ./test_any_automated_install.py ./test_any_utils.py ./test_centos_fedora_common_support.py ./test_fedora_support.py

View File

@@ -1,8 +0,0 @@
[tox]
envlist = py38
[testenv]
whitelist_externals = docker
deps = -rrequirements.txt
commands = docker build -f _ubuntu_18.Dockerfile -t pytest_pihole:test_container ../
pytest {posargs:-vv -n auto} ./test_any_automated_install.py ./test_any_utils.py

View File

@@ -1,8 +1,8 @@
[tox]
envlist = py38
envlist = py3
[testenv]
whitelist_externals = docker
allowlist_externals = docker
deps = -rrequirements.txt
commands = docker build -f _ubuntu_20.Dockerfile -t pytest_pihole:test_container ../
pytest {posargs:-vv -n auto} ./test_any_automated_install.py ./test_any_utils.py

View File

@@ -1,8 +0,0 @@
[tox]
envlist = py38
[testenv]
whitelist_externals = docker
deps = -rrequirements.txt
commands = docker build -f _ubuntu_21.Dockerfile -t pytest_pihole:test_container ../
pytest {posargs:-vv -n auto} ./test_any_automated_install.py ./test_any_utils.py

View File

@@ -1,8 +1,8 @@
[tox]
envlist = py38
envlist = py3
[testenv]
whitelist_externals = docker
allowlist_externals = docker
deps = -rrequirements.txt
commands = docker build -f _ubuntu_22.Dockerfile -t pytest_pihole:test_container ../
pytest {posargs:-vv -n auto} ./test_any_automated_install.py ./test_any_utils.py