Compare commits
206 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d86b325dfe | ||
|
|
c65ea9c47c | ||
|
|
741717aa38 | ||
|
|
2d13cd2f1d | ||
|
|
788e7cc777 | ||
|
|
0ac89ac2e3 | ||
|
|
e5ea361b53 | ||
|
|
df0155abe1 | ||
|
|
ca00ffa101 | ||
|
|
3ad8965959 | ||
|
|
460f83580e | ||
|
|
c7ad7113d7 | ||
|
|
0a6ebadb52 | ||
|
|
b9e401aaa3 | ||
|
|
18ab94135f | ||
|
|
be0efa2332 | ||
|
|
9bde5de601 | ||
|
|
db42ed1e4f | ||
|
|
262ffe458b | ||
|
|
e59f5db145 | ||
|
|
362c604744 | ||
|
|
68a03cc877 | ||
|
|
671da760d3 | ||
|
|
3c3d913934 | ||
|
|
50be36400c | ||
|
|
5f9523afa6 | ||
|
|
81a31b9e7b | ||
|
|
d0affcb376 | ||
|
|
9939cf1d77 | ||
|
|
ce7f926e92 | ||
|
|
6b4f77bdfe | ||
|
|
267792aa1e | ||
|
|
9331cbff4b | ||
|
|
d30a5f1b95 | ||
|
|
d6e25403ee | ||
|
|
79f4a7cef0 | ||
|
|
9ed3ede0d9 | ||
|
|
771b7cfcc7 | ||
|
|
7bb86e4118 | ||
|
|
c992fd48b0 | ||
|
|
afc8241c2c | ||
|
|
6cae37e720 | ||
|
|
d604aec9f1 | ||
|
|
bb4698429f | ||
|
|
634e3b0e46 | ||
|
|
21c7c8a008 | ||
|
|
9048429bbb | ||
|
|
9c33fcb32a | ||
|
|
eb1f2ac01c | ||
|
|
d88e940a57 | ||
|
|
f27f796b34 | ||
|
|
318ee3b7d3 | ||
|
|
f894585a2e | ||
|
|
ac2f63b138 | ||
|
|
be8f25f8b8 | ||
|
|
c85e4227cf | ||
|
|
c9042704d5 | ||
|
|
57f29a2c5d | ||
|
|
142e9f4a1a | ||
|
|
0c65c27e0c | ||
|
|
4a53e56bd2 | ||
|
|
d349a4640f | ||
|
|
dfcdb1a747 | ||
|
|
e05ef73011 | ||
|
|
2c29b25782 | ||
|
|
d87cad76fb | ||
|
|
9e47b61c8f | ||
|
|
4413224a31 | ||
|
|
d882652a85 | ||
|
|
f73b965fcd | ||
|
|
fe598a05f6 | ||
|
|
09977fdfec | ||
|
|
b9ebb05246 | ||
|
|
955e36a955 | ||
|
|
972591fe39 | ||
|
|
14db88d6bb | ||
|
|
64d0621d2b | ||
|
|
5dabdfe354 | ||
|
|
e7c0ca47b4 | ||
|
|
2bb7c05ed1 | ||
|
|
20ad03fe15 | ||
|
|
58231e55df | ||
|
|
12674c0824 | ||
|
|
c59e11a332 | ||
|
|
ec1d4c5500 | ||
|
|
34f45d011d | ||
|
|
539f9d4da0 | ||
|
|
c6342ed84c | ||
|
|
9072a6a7f0 | ||
|
|
3b5d10d087 | ||
|
|
0d5d3a1b22 | ||
|
|
8d2e023ec0 | ||
|
|
4a1473aee9 | ||
|
|
78f9e38425 | ||
|
|
08c7691d1e | ||
|
|
62bf9957dc | ||
|
|
dafc9983f5 | ||
|
|
a44b8e4bfc | ||
|
|
c8e69c6139 | ||
|
|
da8893f477 | ||
|
|
7562376373 | ||
|
|
619cebb62c | ||
|
|
6a2200a8e6 | ||
|
|
661433c115 | ||
|
|
e7e7a817bb | ||
|
|
d245226053 | ||
|
|
a5d10a6256 | ||
|
|
c32761e786 | ||
|
|
095696ec04 | ||
|
|
7971cf0adc | ||
|
|
fc83883934 | ||
|
|
1550f29f06 | ||
|
|
a206980242 | ||
|
|
8c2f56b0e6 | ||
|
|
b4349b41ce | ||
|
|
67f04787d6 | ||
|
|
1ee922d16c | ||
|
|
14ab586603 | ||
|
|
372070ab39 | ||
|
|
4004a93d1a | ||
|
|
c2bb190dce | ||
|
|
b8eae60fcc | ||
|
|
c86ff5d084 | ||
|
|
126da094bd | ||
|
|
f713b14ba0 | ||
|
|
a4e20f79a3 | ||
|
|
6b146ed2d1 | ||
|
|
e0e0baf076 | ||
|
|
95e799ed6e | ||
|
|
202aa25c09 | ||
|
|
06de172952 | ||
|
|
ff5ee29566 | ||
|
|
d393497641 | ||
|
|
0034538794 | ||
|
|
33d2163f19 | ||
|
|
ea26171c18 | ||
|
|
82dfcbcd83 | ||
|
|
233453267e | ||
|
|
f3c27f706f | ||
|
|
983d79b3e6 | ||
|
|
6d8abc2e30 | ||
|
|
38775cffdf | ||
|
|
b13a75a223 | ||
|
|
21026d9414 | ||
|
|
ba74051502 | ||
|
|
cdbe4c9b86 | ||
|
|
ca04c13315 | ||
|
|
3c86af0e59 | ||
|
|
ddaa1bf0d4 | ||
|
|
6b8ba3c15e | ||
|
|
7536c312ee | ||
|
|
a8b6eb9b70 | ||
|
|
67385b7ed4 | ||
|
|
64e61aac4a | ||
|
|
2fd5b944ad | ||
|
|
f91606bb17 | ||
|
|
122bc6b927 | ||
|
|
3491dbfd04 | ||
|
|
871067acd8 | ||
|
|
06cf7afbc2 | ||
|
|
81927334f2 | ||
|
|
01bf9ca42a | ||
|
|
c8c6533440 | ||
|
|
f1b15f7e92 | ||
|
|
e0c351f0e4 | ||
|
|
7957acf42f | ||
|
|
c3e8d76d63 | ||
|
|
128a3ab1be | ||
|
|
df3e9e5f51 | ||
|
|
c322458dcb | ||
|
|
21be1bd58e | ||
|
|
469a267150 | ||
|
|
090727b1d3 | ||
|
|
85ffbcf05e | ||
|
|
528abc9c97 | ||
|
|
8b98fd06ed | ||
|
|
bc6fb0c934 | ||
|
|
e773e3302c | ||
|
|
0cf59cf0fa | ||
|
|
bc471cb0bd | ||
|
|
429510e168 | ||
|
|
4c9401175c | ||
|
|
235673dac8 | ||
|
|
d737948f64 | ||
|
|
52283478c8 | ||
|
|
c84be5de61 | ||
|
|
d85982dc51 | ||
|
|
5c61f6cb65 | ||
|
|
4c0a94d2b9 | ||
|
|
5c090d25e1 | ||
|
|
89c0706abc | ||
|
|
e5695f862f | ||
|
|
e3db5fc601 | ||
|
|
9c51050283 | ||
|
|
9471c69882 | ||
|
|
79c0b446e1 | ||
|
|
a478f2460b | ||
|
|
2dc599f266 | ||
|
|
d7f7ef9965 | ||
|
|
888e44e53d | ||
|
|
18d28533eb | ||
|
|
56527e5dd9 | ||
|
|
c90d8284ef | ||
|
|
7ab9664255 | ||
|
|
3a22657645 | ||
|
|
4567f264b4 |
10
.github/dependabot.yml
vendored
10
.github/dependabot.yml
vendored
@@ -10,3 +10,13 @@ updates:
|
||||
target-branch: development
|
||||
reviewers:
|
||||
- "pi-hole/core-maintainers"
|
||||
- package-ecosystem: pip
|
||||
directory: "/test"
|
||||
schedule:
|
||||
interval: weekly
|
||||
day: saturday
|
||||
time: "10:00"
|
||||
open-pull-requests-limit: 10
|
||||
target-branch: development
|
||||
reviewers:
|
||||
- "pi-hole/core-maintainers"
|
||||
|
||||
2
.github/workflows/codeql-analysis.yml
vendored
2
.github/workflows/codeql-analysis.yml
vendored
@@ -25,7 +25,7 @@ jobs:
|
||||
steps:
|
||||
-
|
||||
name: Checkout repository
|
||||
uses: actions/checkout@v3.1.0
|
||||
uses: actions/checkout@v3.3.0
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
-
|
||||
name: Initialize CodeQL
|
||||
|
||||
21
.github/workflows/merge-conflict.yml
vendored
Normal file
21
.github/workflows/merge-conflict.yml
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
name: "Check for merge conflicts"
|
||||
on:
|
||||
# So that PRs touching the same files as the push are updated
|
||||
push:
|
||||
# So that the `dirtyLabel` is removed if conflicts are resolve
|
||||
# We recommend `pull_request_target` so that github secrets are available.
|
||||
# In `pull_request` we wouldn't be able to change labels of fork PRs
|
||||
pull_request_target:
|
||||
types: [synchronize]
|
||||
|
||||
jobs:
|
||||
main:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Check if PRs are have merge conflicts
|
||||
uses: eps1lon/actions-label-merge-conflict@v2.1.0
|
||||
with:
|
||||
dirtyLabel: "PR: Merge Conflict"
|
||||
repoToken: "${{ secrets.GITHUB_TOKEN }}"
|
||||
commentOnDirty: "This pull request has conflicts, please resolve those before we can evaluate the pull request."
|
||||
commentOnClean: "Conflicts have been resolved."
|
||||
2
.github/workflows/stale.yml
vendored
2
.github/workflows/stale.yml
vendored
@@ -13,7 +13,7 @@ jobs:
|
||||
issues: write
|
||||
|
||||
steps:
|
||||
- uses: actions/stale@v6.0.1
|
||||
- uses: actions/stale@v7.0.0
|
||||
with:
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
days-before-stale: 30
|
||||
|
||||
35
.github/workflows/stale_pr.yml
vendored
Normal file
35
.github/workflows/stale_pr.yml
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
name: Close stale PR
|
||||
# This action will add a `stale` label and close immediately every PR that meets the following conditions:
|
||||
# - it is already marked with "merge conflict" label
|
||||
# - there was no update/comment on the PR in the last 30 days.
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: '0 10 * * *'
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
stale:
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
issues: write
|
||||
pull-requests: write
|
||||
|
||||
steps:
|
||||
- uses: actions/stale@v7.0.0
|
||||
with:
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
# Do not automatically mark PR/issue as stale
|
||||
days-before-stale: -1
|
||||
# Override 'days-before-stale' for PR only
|
||||
days-before-pr-stale: 30
|
||||
# Close PRs immediately, after marking them 'stale'
|
||||
days-before-pr-close: 0
|
||||
# only run the action on merge conflict PR
|
||||
any-of-labels: 'PR: Merge Conflict'
|
||||
exempt-pr-labels: 'internal, never-stale, ON HOLD, WIP'
|
||||
exempt-all-pr-assignees: true
|
||||
operations-per-run: 300
|
||||
stale-pr-message: ''
|
||||
close-pr-message: 'Existing merge conflicts have not been addressed. This PR is considered abandoned.'
|
||||
15
.github/workflows/sync-back-to-dev.yml
vendored
15
.github/workflows/sync-back-to-dev.yml
vendored
@@ -11,17 +11,8 @@ jobs:
|
||||
name: Syncing branches
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3.1.0
|
||||
uses: actions/checkout@v3.3.0
|
||||
- name: Opening pull request
|
||||
id: pull
|
||||
uses: tretuna/sync-branches@1.4.0
|
||||
with:
|
||||
run: gh pr create -B development -H master --title 'Sync master back into development' --body 'Created by Github action' --label 'internal'
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
FROM_BRANCH: 'master'
|
||||
TO_BRANCH: 'development'
|
||||
- name: Label the pull request to ignore for release note generation
|
||||
uses: actions-ecosystem/action-add-labels@v1.1.3
|
||||
with:
|
||||
labels: internal
|
||||
repo: ${{ github.repository }}
|
||||
number: ${{ steps.pull.outputs.PULL_REQUEST_NUMBER }}
|
||||
|
||||
12
.github/workflows/test.yml
vendored
12
.github/workflows/test.yml
vendored
@@ -13,7 +13,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v3.1.0
|
||||
uses: actions/checkout@v3.3.0
|
||||
|
||||
- name: Check scripts in repository are executable
|
||||
run: |
|
||||
@@ -54,20 +54,24 @@ jobs:
|
||||
ubuntu_20,
|
||||
ubuntu_22,
|
||||
centos_8,
|
||||
fedora_35,
|
||||
centos_9,
|
||||
fedora_36,
|
||||
fedora_37,
|
||||
]
|
||||
env:
|
||||
DISTRO: ${{matrix.distro}}
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v3.1.0
|
||||
uses: actions/checkout@v3.3.0
|
||||
|
||||
- name: Set up Python 3.10
|
||||
uses: actions/setup-python@v4.2.0
|
||||
uses: actions/setup-python@v4.5.0
|
||||
with:
|
||||
python-version: "3.10"
|
||||
|
||||
- name: Install wheel
|
||||
run: pip install wheel
|
||||
|
||||
- name: Install dependencies
|
||||
run: pip install -r test/requirements.txt
|
||||
|
||||
|
||||
12
README.md
12
README.md
@@ -16,11 +16,11 @@
|
||||
|
||||
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
|
||||
- **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
|
||||
@@ -60,7 +60,7 @@ Please refer to the [Pi-hole docker repo](https://github.com/pi-hole/docker-pi-h
|
||||
|
||||
## [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).
|
||||
|
||||
@@ -70,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!**
|
||||
|
||||
@@ -132,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:
|
||||
|
||||
|
||||
@@ -42,11 +42,6 @@ warning1() {
|
||||
esac
|
||||
}
|
||||
|
||||
updateCheckFunc() {
|
||||
/opt/pihole/updatecheck.sh
|
||||
/opt/pihole/updatecheck.sh x remote
|
||||
}
|
||||
|
||||
checkout() {
|
||||
local corebranches
|
||||
local webbranches
|
||||
@@ -169,8 +164,8 @@ checkout() {
|
||||
exit 1
|
||||
fi
|
||||
checkout_pull_branch "${webInterfaceDir}" "${2}"
|
||||
# Force an update of the updatechecker
|
||||
updateCheckFunc
|
||||
# Update local and remote versions via updatechecker
|
||||
/opt/pihole/updatecheck.sh
|
||||
elif [[ "${1}" == "ftl" ]] ; then
|
||||
local path
|
||||
local oldbranch
|
||||
@@ -185,8 +180,8 @@ checkout() {
|
||||
FTLinstall "${binary}"
|
||||
restart_service pihole-FTL
|
||||
enable_service pihole-FTL
|
||||
# Force an update of the updatechecker
|
||||
updateCheckFunc
|
||||
# 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}') )
|
||||
|
||||
@@ -44,17 +44,12 @@ fi
|
||||
# shellcheck disable=SC1091
|
||||
. /etc/pihole/versions
|
||||
|
||||
OBFUSCATED_PLACEHOLDER="<DOMAIN OBFUSCATED>"
|
||||
|
||||
# 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_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,9 +66,10 @@ RUN_DIRECTORY="/run"
|
||||
LOG_DIRECTORY="/var/log/pihole"
|
||||
WEB_SERVER_LOG_DIRECTORY="/var/log/lighttpd"
|
||||
WEB_SERVER_CONFIG_DIRECTORY="/etc/lighttpd"
|
||||
WEB_SERVER_CONFIG_DIRECTORY_FEDORA="${WEB_SERVER_CONFIG_DIRECTORY}/conf.d"
|
||||
WEB_SERVER_CONFIG_DIRECTORY_DEBIAN="${WEB_SERVER_CONFIG_DIRECTORY}/conf-enabled"
|
||||
HTML_DIRECTORY="/var/www/html"
|
||||
WEB_GIT_DIRECTORY="${HTML_DIRECTORY}/admin"
|
||||
#BLOCK_PAGE_DIRECTORY="${HTML_DIRECTORY}/pihole"
|
||||
SHM_DIRECTORY="/dev/shm"
|
||||
ETC="/etc"
|
||||
|
||||
@@ -83,6 +79,8 @@ PIHOLE_CRON_FILE="${CRON_D_DIRECTORY}/pihole"
|
||||
|
||||
WEB_SERVER_CONFIG_FILE="${WEB_SERVER_CONFIG_DIRECTORY}/lighttpd.conf"
|
||||
WEB_SERVER_CUSTOM_CONFIG_FILE="${WEB_SERVER_CONFIG_DIRECTORY}/external.conf"
|
||||
WEB_SERVER_PIHOLE_CONFIG_FILE_DEBIAN="${WEB_SERVER_CONFIG_DIRECTORY_DEBIAN}/15-pihole-admin.conf"
|
||||
WEB_SERVER_PIHOLE_CONFIG_FILE_FEDORA="${WEB_SERVER_CONFIG_DIRECTORY_FEDORA}/pihole-admin.conf"
|
||||
|
||||
PIHOLE_INSTALL_LOG_FILE="${PIHOLE_DIRECTORY}/install.log"
|
||||
PIHOLE_RAW_BLOCKLIST_FILES="${PIHOLE_DIRECTORY}/list.*"
|
||||
@@ -91,6 +89,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.
|
||||
#
|
||||
@@ -145,6 +144,8 @@ PIHOLE_PROCESSES=( "lighttpd" "pihole-FTL" )
|
||||
REQUIRED_FILES=("${PIHOLE_CRON_FILE}"
|
||||
"${WEB_SERVER_CONFIG_FILE}"
|
||||
"${WEB_SERVER_CUSTOM_CONFIG_FILE}"
|
||||
"${WEB_SERVER_PIHOLE_CONFIG_FILE_DEBIAN}"
|
||||
"${WEB_SERVER_PIHOLE_CONFIG_FILE_FEDORA}"
|
||||
"${PIHOLE_INSTALL_LOG_FILE}"
|
||||
"${PIHOLE_RAW_BLOCKLIST_FILES}"
|
||||
"${PIHOLE_LOCAL_HOSTS_FILE}"
|
||||
@@ -162,7 +163,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 +242,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 +255,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,22 +317,15 @@ compare_local_version_to_git_version() {
|
||||
}
|
||||
|
||||
check_ftl_version() {
|
||||
local ftl_name="FTL"
|
||||
local FTL_VERSION FTL_COMMIT FTL_BRANCH
|
||||
echo_current_diagnostic "${ftl_name} version"
|
||||
echo_current_diagnostic "FTL version"
|
||||
# Use the built in command to check FTL's version
|
||||
FTL_VERSION=$(pihole-FTL -vv | grep -m 1 Version | awk '{printf $2}')
|
||||
FTL_BRANCH=$(pihole-FTL -vv | grep -m 1 Branch | awk '{printf $2}')
|
||||
FTL_COMMIT=$(pihole-FTL -vv | grep -m 1 Commit | awk '{printf $2}')
|
||||
FTL_VERSION=$(pihole-FTL version)
|
||||
FTL_BRANCH=$(pihole-FTL branch)
|
||||
FTL_COMMIT=$(pihole-FTL --hash)
|
||||
|
||||
# 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}"
|
||||
else
|
||||
# If not, show it in yellow, signifying there is an update
|
||||
log_write "${INFO} ${ftl_name}: ${COL_YELLOW}${FTL_VERSION}${COL_NC} (${FAQ_UPDATE_PI_HOLE})"
|
||||
fi
|
||||
|
||||
log_write "${TICK} Version: ${FTL_VERSION}"
|
||||
|
||||
# If they use the master branch, they are on the stable codebase
|
||||
if [[ "${FTL_BRANCH}" == "master" ]]; then
|
||||
@@ -355,7 +334,7 @@ check_ftl_version() {
|
||||
# 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}${FTL_BRANCH}${COL_NC} (${FAQ_CHECKOUT_COMMAND})"
|
||||
log_write "${INFO} Branch: ${COL_YELLOW}${FTL_BRANCH}${COL_NC}"
|
||||
fi
|
||||
|
||||
# echo the current commit
|
||||
@@ -421,41 +400,53 @@ os_check() {
|
||||
# Extract dig response
|
||||
response="${cmdResult%%$'\n'*}"
|
||||
|
||||
IFS=" " read -r -a supportedOS < <(echo "${response}" | tr -d '"')
|
||||
for distro_and_versions in "${supportedOS[@]}"
|
||||
do
|
||||
distro_part="${distro_and_versions%%=*}"
|
||||
versions_part="${distro_and_versions##*=}"
|
||||
|
||||
if [[ "${detected_os^^}" =~ ${distro_part^^} ]]; then
|
||||
valid_os=true
|
||||
IFS="," read -r -a supportedVer <<<"${versions_part}"
|
||||
for version in "${supportedVer[@]}"
|
||||
do
|
||||
if [[ "${detected_version}" =~ $version ]]; then
|
||||
valid_version=true
|
||||
break
|
||||
fi
|
||||
done
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
log_write "${INFO} dig return code: ${digReturnCode}"
|
||||
log_write "${INFO} dig response: ${response}"
|
||||
|
||||
if [ "$valid_os" = true ]; then
|
||||
log_write "${TICK} Distro: ${COL_GREEN}${detected_os^}${COL_NC}"
|
||||
|
||||
if [ "$valid_version" = true ]; then
|
||||
log_write "${TICK} Version: ${COL_GREEN}${detected_version}${COL_NC}"
|
||||
else
|
||||
log_write "${CROSS} Version: ${COL_RED}${detected_version}${COL_NC}"
|
||||
log_write "${CROSS} Error: ${COL_RED}${detected_os^} is supported but version ${detected_version} is currently unsupported (${FAQ_HARDWARE_REQUIREMENTS})${COL_NC}"
|
||||
fi
|
||||
if [ "${digReturnCode}" -ne 0 ]; then
|
||||
log_write "${INFO} Distro: ${detected_os^}"
|
||||
log_write "${INFO} Version: ${detected_version}"
|
||||
log_write "${CROSS} dig return code: ${COL_RED}${digReturnCode}${COL_NC}"
|
||||
log_write "${CROSS} dig response: ${response}"
|
||||
log_write "${CROSS} Error: ${COL_RED}dig command failed - Unable to check OS${COL_NC}"
|
||||
else
|
||||
log_write "${CROSS} Distro: ${COL_RED}${detected_os^}${COL_NC}"
|
||||
log_write "${CROSS} Error: ${COL_RED}${detected_os^} is not a supported distro (${FAQ_HARDWARE_REQUIREMENTS})${COL_NC}"
|
||||
IFS=" " read -r -a supportedOS < <(echo "${response}" | tr -d '"')
|
||||
for distro_and_versions in "${supportedOS[@]}"
|
||||
do
|
||||
distro_part="${distro_and_versions%%=*}"
|
||||
versions_part="${distro_and_versions##*=}"
|
||||
|
||||
if [[ "${detected_os^^}" =~ ${distro_part^^} ]]; then
|
||||
valid_os=true
|
||||
IFS="," read -r -a supportedVer <<<"${versions_part}"
|
||||
for version in "${supportedVer[@]}"
|
||||
do
|
||||
if [[ "${detected_version}" =~ $version ]]; then
|
||||
valid_version=true
|
||||
break
|
||||
fi
|
||||
done
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
local finalmsg
|
||||
if [ "$valid_os" = true ]; then
|
||||
log_write "${TICK} Distro: ${COL_GREEN}${detected_os^}${COL_NC}"
|
||||
|
||||
if [ "$valid_version" = true ]; then
|
||||
log_write "${TICK} Version: ${COL_GREEN}${detected_version}${COL_NC}"
|
||||
finalmsg="${TICK} ${COL_GREEN}Distro and version supported${COL_NC}"
|
||||
else
|
||||
log_write "${CROSS} Version: ${COL_RED}${detected_version}${COL_NC}"
|
||||
finalmsg="${CROSS} Error: ${COL_RED}${detected_os^} is supported but version ${detected_version} is currently unsupported ${COL_NC}(${FAQ_HARDWARE_REQUIREMENTS})${COL_NC}"
|
||||
fi
|
||||
else
|
||||
log_write "${CROSS} Distro: ${COL_RED}${detected_os^}${COL_NC}"
|
||||
finalmsg="${CROSS} Error: ${COL_RED}${detected_os^} is not a supported distro ${COL_NC}(${FAQ_HARDWARE_REQUIREMENTS})${COL_NC}"
|
||||
fi
|
||||
|
||||
# Print dig response and the final check result
|
||||
log_write "${TICK} dig return code: ${COL_GREEN}${digReturnCode}${COL_NC}"
|
||||
log_write "${INFO} dig response: ${response}"
|
||||
log_write "${finalmsg}"
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -952,10 +943,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
|
||||
@@ -981,6 +983,20 @@ ftl_full_status(){
|
||||
fi
|
||||
}
|
||||
|
||||
lighttpd_test_configuration(){
|
||||
# let lighttpd test it's own configuration
|
||||
local lighttpd_conf_test
|
||||
echo_current_diagnostic "Lighttpd configuration test"
|
||||
lighttpd_conf_test=$(lighttpd -tt -f /etc/lighttpd/lighttpd.conf)
|
||||
if [ -z "${lighttpd_conf_test}" ]; then
|
||||
# empty output
|
||||
log_write "${TICK} ${COL_GREEN}No error in lighttpd configuration${COL_NC}"
|
||||
else
|
||||
log_write "${CROSS} ${COL_RED}Error in lighttpd configuration${COL_NC}"
|
||||
log_write " ${lighttpd_conf_test}"
|
||||
fi
|
||||
}
|
||||
|
||||
make_array_from_file() {
|
||||
local filename="${1}"
|
||||
# The second argument can put a limit on how many line should be read from the file
|
||||
@@ -1073,10 +1089,13 @@ dir_check() {
|
||||
# check if exists first; if it does,
|
||||
if ls "${filename}" 1> /dev/null 2>&1; then
|
||||
# do nothing
|
||||
:
|
||||
true
|
||||
return
|
||||
else
|
||||
# Otherwise, show an error
|
||||
log_write "${COL_RED}${directory} does not exist.${COL_NC}"
|
||||
false
|
||||
return
|
||||
fi
|
||||
done
|
||||
}
|
||||
@@ -1084,6 +1103,19 @@ dir_check() {
|
||||
list_files_in_dir() {
|
||||
# Set the first argument passed to this function as a named variable for better readability
|
||||
local dir_to_parse="${1}"
|
||||
|
||||
# show files and sizes of some directories, don't print the file content (yet)
|
||||
if [[ "${dir_to_parse}" == "${SHM_DIRECTORY}" ]]; then
|
||||
# SHM file - we do not want to see the content, but we want to see the files and their sizes
|
||||
log_write "$(ls -lh "${dir_to_parse}/")"
|
||||
elif [[ "${dir_to_parse}" == "${WEB_SERVER_CONFIG_DIRECTORY_FEDORA}" ]]; then
|
||||
# we want to see all files files in /etc/lighttpd/conf.d
|
||||
log_write "$(ls -lh "${dir_to_parse}/" 2> /dev/null )"
|
||||
elif [[ "${dir_to_parse}" == "${WEB_SERVER_CONFIG_DIRECTORY_DEBIAN}" ]]; then
|
||||
# we want to see all files files in /etc/lighttpd/conf.d
|
||||
log_write "$(ls -lh "${dir_to_parse}/"/ 2> /dev/null )"
|
||||
fi
|
||||
|
||||
# Store the files found in an array
|
||||
mapfile -t files_found < <(ls "${dir_to_parse}")
|
||||
# For each file in the array,
|
||||
@@ -1099,11 +1131,8 @@ list_files_in_dir() {
|
||||
[[ "${dir_to_parse}/${each_file}" == "${PIHOLE_WEB_SERVER_ACCESS_LOG_FILE}" ]] || \
|
||||
[[ "${dir_to_parse}/${each_file}" == "${PIHOLE_LOG_GZIPS}" ]]; then
|
||||
:
|
||||
elif [[ "${dir_to_parse}" == "${SHM_DIRECTORY}" ]]; then
|
||||
# SHM file - we do not want to see the content, but we want to see the files and their sizes
|
||||
log_write "$(ls -lhd "${dir_to_parse}"/"${each_file}")"
|
||||
elif [[ "${dir_to_parse}" == "${DNSMASQ_D_DIRECTORY}" ]]; then
|
||||
# in case of the dnsmasq directory inlcuede all files in the debug output
|
||||
# in case of the dnsmasq directory include all files in the debug output
|
||||
log_write "\\n${COL_GREEN}$(ls -lhd "${dir_to_parse}"/"${each_file}")${COL_NC}"
|
||||
make_array_from_file "${dir_to_parse}/${each_file}"
|
||||
else
|
||||
@@ -1136,9 +1165,10 @@ show_content_of_files_in_dir() {
|
||||
# Set a local variable for better readability
|
||||
local directory="${1}"
|
||||
# Check if the directory exists
|
||||
dir_check "${directory}"
|
||||
# if it does, list the files in it
|
||||
list_files_in_dir "${directory}"
|
||||
if dir_check "${directory}"; then
|
||||
# if it does, list the files in it
|
||||
list_files_in_dir "${directory}"
|
||||
fi
|
||||
}
|
||||
|
||||
show_content_of_pihole_files() {
|
||||
@@ -1146,6 +1176,8 @@ show_content_of_pihole_files() {
|
||||
show_content_of_files_in_dir "${PIHOLE_DIRECTORY}"
|
||||
show_content_of_files_in_dir "${DNSMASQ_D_DIRECTORY}"
|
||||
show_content_of_files_in_dir "${WEB_SERVER_CONFIG_DIRECTORY}"
|
||||
show_content_of_files_in_dir "${WEB_SERVER_CONFIG_DIRECTORY_FEDORA}"
|
||||
show_content_of_files_in_dir "${WEB_SERVER_CONFIG_DIRECTORY_DEBIAN}"
|
||||
show_content_of_files_in_dir "${CRON_D_DIRECTORY}"
|
||||
show_content_of_files_in_dir "${WEB_SERVER_LOG_DIRECTORY}"
|
||||
show_content_of_files_in_dir "${LOG_DIRECTORY}"
|
||||
@@ -1381,49 +1413,8 @@ spinner(){
|
||||
fi
|
||||
}
|
||||
|
||||
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})"
|
||||
else
|
||||
# If the variable does not a value (the current default behavior), so do not obfuscate anything
|
||||
if [[ -z ${OBFUSCATE} ]]; then
|
||||
log_write " ${line}"
|
||||
# Otherwise, 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
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
analyze_pihole_log() {
|
||||
echo_current_diagnostic "Pi-hole log"
|
||||
local pihole_log_head=()
|
||||
local pihole_log_tail=()
|
||||
local pihole_log_permissions
|
||||
local logging_enabled
|
||||
|
||||
@@ -1433,22 +1424,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() {
|
||||
@@ -1553,6 +1532,7 @@ check_name_resolution
|
||||
check_dhcp_servers
|
||||
process_status
|
||||
ftl_full_status
|
||||
lighttpd_test_configuration
|
||||
parse_setup_vars
|
||||
check_x_headers
|
||||
analyze_ftl_db
|
||||
|
||||
@@ -77,7 +77,7 @@ 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/ ?-(adlists?|all|exact) ?//g' <<< "${options}")
|
||||
options=$(sed -E 's/ ?-(all|exact) ?//g' <<< "${options}")
|
||||
|
||||
# Handle remaining options
|
||||
# If $options contain non ASCII characters, convert to punycode
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -15,16 +15,30 @@ 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=8 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
|
||||
|
||||
# Source the utils file
|
||||
# Source the utils file for addOrEditKeyValPair()
|
||||
# shellcheck disable=SC1091
|
||||
. /opt/pihole/utils.sh
|
||||
|
||||
@@ -46,54 +60,74 @@ if [[ ! "${DOCKER_TAG}" =~ $regex ]]; then
|
||||
unset DOCKER_TAG
|
||||
fi
|
||||
|
||||
if [[ "$2" == "remote" ]]; then
|
||||
|
||||
if [[ "$3" == "reboot" ]]; then
|
||||
# used in cronjob
|
||||
if [[ "$1" == "reboot" ]]; then
|
||||
sleep 30
|
||||
fi
|
||||
fi
|
||||
|
||||
GITHUB_CORE_VERSION="$(curl -s 'https://api.github.com/repos/pi-hole/pi-hole/releases/latest' 2> /dev/null | jq --raw-output .tag_name)"
|
||||
addOrEditKeyValPair "${VERSION_FILE}" "GITHUB_CORE_VERSION" "${GITHUB_CORE_VERSION}"
|
||||
|
||||
if [[ "${INSTALL_WEB_INTERFACE}" == true ]]; then
|
||||
GITHUB_WEB_VERSION="$(curl -s 'https://api.github.com/repos/pi-hole/AdminLTE/releases/latest' 2> /dev/null | jq --raw-output .tag_name)"
|
||||
addOrEditKeyValPair "${VERSION_FILE}" "GITHUB_WEB_VERSION" "${GITHUB_WEB_VERSION}"
|
||||
fi
|
||||
# get Core versions
|
||||
|
||||
GITHUB_FTL_VERSION="$(curl -s 'https://api.github.com/repos/pi-hole/FTL/releases/latest' 2> /dev/null | jq --raw-output .tag_name)"
|
||||
addOrEditKeyValPair "${VERSION_FILE}" "GITHUB_FTL_VERSION" "${GITHUB_FTL_VERSION}"
|
||||
CORE_VERSION="$(get_local_version /etc/.pihole)"
|
||||
addOrEditKeyValPair "${VERSION_FILE}" "CORE_VERSION" "${CORE_VERSION}"
|
||||
|
||||
if [[ "${DOCKER_TAG}" ]]; then
|
||||
GITHUB_DOCKER_VERSION="$(curl -s 'https://api.github.com/repos/pi-hole/docker-pi-hole/releases/latest' 2> /dev/null | jq --raw-output .tag_name)"
|
||||
addOrEditKeyValPair "${VERSION_FILE}" "GITHUB_DOCKER_VERSION" "${GITHUB_DOCKER_VERSION}"
|
||||
fi
|
||||
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}"
|
||||
|
||||
CORE_BRANCH="$(get_local_branch /etc/.pihole)"
|
||||
addOrEditKeyValPair "${VERSION_FILE}" "CORE_BRANCH" "${CORE_BRANCH}"
|
||||
GITHUB_CORE_VERSION="$(get_remote_version pi-hole)"
|
||||
addOrEditKeyValPair "${VERSION_FILE}" "GITHUB_CORE_VERSION" "${GITHUB_CORE_VERSION}"
|
||||
|
||||
if [[ "${INSTALL_WEB_INTERFACE}" == true ]]; then
|
||||
WEB_BRANCH="$(get_local_branch /var/www/html/admin)"
|
||||
addOrEditKeyValPair "${VERSION_FILE}" "WEB_BRANCH" "${WEB_BRANCH}"
|
||||
fi
|
||||
GITHUB_CORE_HASH="$(get_remote_hash pi-hole "${CORE_BRANCH}")"
|
||||
addOrEditKeyValPair "${VERSION_FILE}" "GITHUB_CORE_HASH" "${GITHUB_CORE_HASH}"
|
||||
|
||||
FTL_BRANCH="$(pihole-FTL branch)"
|
||||
addOrEditKeyValPair "${VERSION_FILE}" "FTL_BRANCH" "${FTL_BRANCH}"
|
||||
|
||||
CORE_VERSION="$(get_local_version /etc/.pihole)"
|
||||
addOrEditKeyValPair "${VERSION_FILE}" "CORE_VERSION" "${CORE_VERSION}"
|
||||
# get Web versions
|
||||
|
||||
if [[ "${INSTALL_WEB_INTERFACE}" == true ]]; then
|
||||
WEB_VERSION="$(get_local_version /var/www/html/admin)"
|
||||
addOrEditKeyValPair "${VERSION_FILE}" "WEB_VERSION" "${WEB_VERSION}"
|
||||
fi
|
||||
if [[ "${INSTALL_WEB_INTERFACE}" == true ]]; then
|
||||
|
||||
FTL_VERSION="$(pihole-FTL version)"
|
||||
addOrEditKeyValPair "${VERSION_FILE}" "FTL_VERSION" "${FTL_VERSION}"
|
||||
WEB_VERSION="$(get_local_version /var/www/html/admin)"
|
||||
addOrEditKeyValPair "${VERSION_FILE}" "WEB_VERSION" "${WEB_VERSION}"
|
||||
|
||||
if [[ "${DOCKER_TAG}" ]]; then
|
||||
addOrEditKeyValPair "${VERSION_FILE}" "DOCKER_VERSION" "${DOCKER_TAG}"
|
||||
fi
|
||||
WEB_BRANCH="$(get_local_branch /var/www/html/admin)"
|
||||
addOrEditKeyValPair "${VERSION_FILE}" "WEB_BRANCH" "${WEB_BRANCH}"
|
||||
|
||||
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
|
||||
|
||||
@@ -31,6 +31,9 @@ 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}"
|
||||
@@ -51,6 +54,9 @@ 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}"
|
||||
|
||||
@@ -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,179 +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
|
||||
cachedVersions="/etc/pihole/versions"
|
||||
|
||||
#If the above file exists, then we can read from that. Prevents overuse of GitHub API
|
||||
if [[ -f "$cachedVersions" ]]; then
|
||||
|
||||
# shellcheck disable=SC1090
|
||||
. "$cachedVersions"
|
||||
|
||||
case $daemon in
|
||||
"pi-hole" ) echo "${GITHUB_CORE_VERSION}";;
|
||||
"AdminLTE" ) [[ "${INSTALL_WEB_INTERFACE}" == true ]] && echo "${GITHUB_WEB_VERSION}";;
|
||||
"FTL" ) echo "${GITHUB_FTL_VERSION}";;
|
||||
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() {
|
||||
@@ -189,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
|
||||
|
||||
@@ -217,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;;
|
||||
|
||||
@@ -627,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"
|
||||
@@ -702,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"
|
||||
@@ -729,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
|
||||
@@ -755,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
|
||||
|
||||
13
advanced/Templates/pihole-FTL-poststop.sh
Executable file
13
advanced/Templates/pihole-FTL-poststop.sh
Executable file
@@ -0,0 +1,13 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
# Source utils.sh for getFTLPIDFile()
|
||||
PI_HOLE_SCRIPT_DIR='/opt/pihole'
|
||||
utilsfile="${PI_HOLE_SCRIPT_DIR}/utils.sh"
|
||||
# shellcheck disable=SC1090
|
||||
. "${utilsfile}"
|
||||
|
||||
# Get file paths
|
||||
FTL_PID_FILE="$(getFTLPIDFile)"
|
||||
|
||||
# Cleanup
|
||||
rm -f /run/pihole/FTL.sock /dev/shm/FTL-* "${FTL_PID_FILE}"
|
||||
38
advanced/Templates/pihole-FTL-prestart.sh
Executable file
38
advanced/Templates/pihole-FTL-prestart.sh
Executable file
@@ -0,0 +1,38 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
# Source utils.sh for getFTLPIDFile()
|
||||
PI_HOLE_SCRIPT_DIR='/opt/pihole'
|
||||
utilsfile="${PI_HOLE_SCRIPT_DIR}/utils.sh"
|
||||
# shellcheck disable=SC1090
|
||||
. "${utilsfile}"
|
||||
|
||||
# Get file paths
|
||||
FTL_PID_FILE="$(getFTLPIDFile)"
|
||||
|
||||
# Touch files to ensure they exist (create if non-existing, preserve if existing)
|
||||
# shellcheck disable=SC2174
|
||||
mkdir -pm 0755 /run/pihole /var/log/pihole
|
||||
[ -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
|
||||
# Ensure that permissions are set so that pihole-FTL can edit all necessary files
|
||||
chown pihole:pihole /run/pihole /etc/pihole /var/log/pihole /var/log/pihole/FTL.log /var/log/pihole/pihole.log /etc/pihole/dhcp.leases
|
||||
# Ensure that permissions are set so that pihole-FTL can edit the files. We ignore errors as the file may not (yet) exist
|
||||
chmod -f 0644 /etc/pihole/macvendor.db /etc/pihole/dhcp.leases /var/log/pihole/FTL.log
|
||||
chmod -f 0640 /var/log/pihole/pihole.log
|
||||
# Chown database files to the user FTL runs as. We ignore errors as the files may not (yet) exist
|
||||
chown -f pihole:pihole /etc/pihole/pihole-FTL.db /etc/pihole/gravity.db /etc/pihole/macvendor.db
|
||||
# Chmod database file permissions so that the pihole group (web interface) can edit the file. We ignore errors as the files may not (yet) exist
|
||||
chmod -f 0664 /etc/pihole/pihole-FTL.db
|
||||
|
||||
# Backward compatibility for user-scripts that still expect log files in /var/log instead of /var/log/pihole
|
||||
# Should be removed with Pi-hole v6.0
|
||||
if [ ! -f /var/log/pihole.log ]; then
|
||||
ln -sf /var/log/pihole/pihole.log /var/log/pihole.log
|
||||
chown -h pihole:pihole /var/log/pihole.log
|
||||
fi
|
||||
if [ ! -f /var/log/pihole-FTL.log ]; then
|
||||
ln -sf /var/log/pihole/FTL.log /var/log/pihole-FTL.log
|
||||
chown -h pihole:pihole /var/log/pihole-FTL.log
|
||||
fi
|
||||
@@ -9,9 +9,10 @@
|
||||
# Description: Enable service provided by pihole-FTL daemon
|
||||
### END INIT INFO
|
||||
|
||||
#source utils.sh for getFTLPIDFile(), getFTLPID ()
|
||||
# Source utils.sh for getFTLPIDFile(), getFTLPID()
|
||||
PI_HOLE_SCRIPT_DIR="/opt/pihole"
|
||||
utilsfile="${PI_HOLE_SCRIPT_DIR}/utils.sh"
|
||||
# shellcheck disable=SC1090
|
||||
. "${utilsfile}"
|
||||
|
||||
|
||||
@@ -22,45 +23,31 @@ is_running() {
|
||||
return 1
|
||||
}
|
||||
|
||||
cleanup() {
|
||||
# Run post-stop script, which does cleanup among runtime files
|
||||
sh "${PI_HOLE_SCRIPT_DIR}/pihole-FTL-poststop.sh"
|
||||
}
|
||||
|
||||
|
||||
# Start the service
|
||||
start() {
|
||||
if is_running; then
|
||||
echo "pihole-FTL is already running"
|
||||
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 -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
|
||||
# Ensure that permissions are set so that pihole-FTL can edit all necessary files
|
||||
chown pihole:pihole /run/pihole /etc/pihole /var/log/pihole /var/log/pihole/FTL.log /var/log/pihole/pihole.log /etc/pihole/dhcp.leases
|
||||
# Ensure that permissions are set so that pihole-FTL can edit the files. We ignore errors as the file may not (yet) exist
|
||||
chmod -f 0644 /etc/pihole/macvendor.db /etc/pihole/dhcp.leases /var/log/pihole/FTL.log
|
||||
chmod -f 0640 /var/log/pihole/pihole.log
|
||||
# Chown database files to the user FTL runs as. We ignore errors as the files may not (yet) exist
|
||||
chown -f pihole:pihole /etc/pihole/pihole-FTL.db /etc/pihole/gravity.db /etc/pihole/macvendor.db
|
||||
# Chown database file permissions so that the pihole group (web interface) can edit the file. We ignore errors as the files may not (yet) exist
|
||||
chmod -f 0664 /etc/pihole/pihole-FTL.db
|
||||
|
||||
# Backward compatibility for user-scripts that still expect log files in /var/log instead of /var/log/pihole/
|
||||
# Should be removed with Pi-hole v6.0
|
||||
if [ ! -f /var/log/pihole.log ]; then
|
||||
ln -s /var/log/pihole/pihole.log /var/log/pihole.log
|
||||
chown -h pihole:pihole /var/log/pihole.log
|
||||
|
||||
fi
|
||||
if [ ! -f /var/log/pihole-FTL.log ]; then
|
||||
ln -s /var/log/pihole/FTL.log /var/log/pihole-FTL.log
|
||||
chown -h pihole:pihole /var/log/pihole-FTL.log
|
||||
fi
|
||||
# Run pre-start script, which pre-creates all expected files with correct permissions
|
||||
sh "${PI_HOLE_SCRIPT_DIR}/pihole-FTL-prestart.sh"
|
||||
|
||||
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 || exit $?
|
||||
su -s /bin/sh -c "/usr/bin/pihole-FTL" pihole
|
||||
else
|
||||
echo "Warning: Starting pihole-FTL as root because setting capabilities is not supported on this system"
|
||||
/usr/bin/pihole-FTL || exit $?
|
||||
/usr/bin/pihole-FTL
|
||||
fi
|
||||
rc=$?
|
||||
# Cleanup if startup failed
|
||||
if [ "${rc}" != 0 ]; then
|
||||
cleanup
|
||||
exit $rc
|
||||
fi
|
||||
echo
|
||||
fi
|
||||
@@ -89,8 +76,7 @@ stop() {
|
||||
else
|
||||
echo "Not running"
|
||||
fi
|
||||
# Cleanup
|
||||
rm -f /run/pihole/FTL.sock /dev/shm/FTL-* "${FTL_PID_FILE}"
|
||||
cleanup
|
||||
echo
|
||||
}
|
||||
|
||||
@@ -108,11 +94,14 @@ status() {
|
||||
|
||||
### main logic ###
|
||||
|
||||
# Get file paths
|
||||
# catch sudden termination
|
||||
trap 'cleanup; exit 1' INT HUP TERM ABRT
|
||||
|
||||
# Get FTL's PID file path
|
||||
FTL_PID_FILE="$(getFTLPIDFile)"
|
||||
|
||||
# Get FTL's current PID
|
||||
FTL_PID="$(getFTLPID ${FTL_PID_FILE})"
|
||||
FTL_PID="$(getFTLPID "${FTL_PID_FILE}")"
|
||||
|
||||
case "$1" in
|
||||
stop)
|
||||
|
||||
41
advanced/Templates/pihole-FTL.systemd
Normal file
41
advanced/Templates/pihole-FTL.systemd
Normal file
@@ -0,0 +1,41 @@
|
||||
[Unit]
|
||||
Description=Pi-hole FTL
|
||||
# This unit is supposed to indicate when network functionality is available, but it is only
|
||||
# very weakly defined what that is supposed to mean, with one exception: at shutdown, a unit
|
||||
# that is ordered after network-online.target will be stopped before the network
|
||||
Wants=network-online.target
|
||||
After=network-online.target
|
||||
# A target that should be used as synchronization point for all host/network name service lookups.
|
||||
# All services for which the availability of full host/network name resolution is essential should
|
||||
# be ordered after this target, but not pull it in.
|
||||
Wants=nss-lookup.target
|
||||
Before=nss-lookup.target
|
||||
|
||||
# Limit (re)start loop to 5 within 1 minute
|
||||
StartLimitBurst=5
|
||||
StartLimitIntervalSec=60s
|
||||
|
||||
[Service]
|
||||
User=pihole
|
||||
PermissionsStartOnly=true
|
||||
AmbientCapabilities=CAP_NET_BIND_SERVICE CAP_NET_RAW CAP_NET_ADMIN CAP_SYS_NICE CAP_IPC_LOCK CAP_CHOWN
|
||||
|
||||
ExecStartPre=/opt/pihole/pihole-FTL-prestart.sh
|
||||
ExecStart=/usr/bin/pihole-FTL -f
|
||||
Restart=on-failure
|
||||
RestartSec=5s
|
||||
ExecReload=/bin/kill -HUP $MAINPID
|
||||
ExecStopPost=/opt/pihole/pihole-FTL-poststop.sh
|
||||
|
||||
# Use graceful shutdown with a reasonable timeout
|
||||
TimeoutStopSec=10s
|
||||
|
||||
# Make /usr, /boot, /etc and possibly some more folders read-only...
|
||||
ProtectSystem=full
|
||||
# ... except /etc/pihole
|
||||
# This merely retains r/w access rights, it does not add any new.
|
||||
# Must still be writable on the host!
|
||||
ReadWriteDirectories=/etc/pihole
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
@@ -28,6 +28,6 @@
|
||||
|
||||
@reboot root /usr/sbin/logrotate --state /var/lib/logrotate/pihole /etc/pihole/logrotate
|
||||
|
||||
# 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
|
||||
|
||||
@@ -1,81 +0,0 @@
|
||||
<?php
|
||||
/* 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. */
|
||||
|
||||
// Sanitize SERVER_NAME output
|
||||
$serverName = htmlspecialchars($_SERVER["SERVER_NAME"]);
|
||||
// Remove external ipv6 brackets if any
|
||||
$serverName = preg_replace('/^\[(.*)\]$/', '${1}', $serverName);
|
||||
|
||||
// Set landing page location, found within /var/www/html/
|
||||
$landPage = "../landing.php";
|
||||
|
||||
// Define array for hostnames to be accepted as self address for splash page
|
||||
$authorizedHosts = [ "localhost" ];
|
||||
if (!empty($_SERVER["FQDN"])) {
|
||||
// If setenv.add-environment = ("fqdn" => "true") is configured in lighttpd,
|
||||
// append $serverName to $authorizedHosts
|
||||
array_push($authorizedHosts, $serverName);
|
||||
} else if (!empty($_SERVER["VIRTUAL_HOST"])) {
|
||||
// Append virtual hostname to $authorizedHosts
|
||||
array_push($authorizedHosts, $_SERVER["VIRTUAL_HOST"]);
|
||||
}
|
||||
|
||||
// Determine block page type
|
||||
if ($serverName === "pi.hole"
|
||||
|| (!empty($_SERVER["VIRTUAL_HOST"]) && $serverName === $_SERVER["VIRTUAL_HOST"])) {
|
||||
// Redirect to Web Interface
|
||||
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($authorizedHosts);
|
||||
// If $landPage file is present
|
||||
if (is_file(getcwd()."/$landPage")) {
|
||||
unset($serverName, $viewPort); // unset extra variables not to be included in $landpage
|
||||
include $landPage;
|
||||
exit();
|
||||
}
|
||||
// If $landPage file was not present, Set Splash Page output
|
||||
$splashPage = <<<EOT
|
||||
<!doctype html>
|
||||
<html lang='en'>
|
||||
<head>
|
||||
<meta charset='utf-8'>
|
||||
<meta name='viewport' content='width=device-width, initial-scale=1'>
|
||||
<title>● $serverName</title>
|
||||
<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>
|
||||
<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);
|
||||
}
|
||||
|
||||
header("HTTP/1.1 404 Not Found");
|
||||
exit();
|
||||
?>
|
||||
@@ -7,17 +7,18 @@
|
||||
# This file is copyright under the latest version of the EUPL.
|
||||
# Please see LICENSE file for your rights under this license.
|
||||
|
||||
###############################################################################
|
||||
# FILE AUTOMATICALLY OVERWRITTEN BY PI-HOLE INSTALL/UPDATE PROCEDURE. #
|
||||
# ANY CHANGES MADE TO THIS FILE AFTER INSTALL WILL BE LOST ON THE NEXT UPDATE #
|
||||
# #
|
||||
# CHANGES SHOULD BE MADE IN A SEPARATE CONFIG FILE: #
|
||||
# /etc/lighttpd/external.conf #
|
||||
###############################################################################
|
||||
###################################################################################################
|
||||
# IF THIS HEADER EXISTS, THE FILE WILL BE OVERWRITTEN BY PI-HOLE'S UPDATE PROCEDURE. #
|
||||
# ANY CHANGES MADE TO THIS FILE WILL BE LOST ON THE NEXT UPDATE UNLESS YOU REMOVE THIS HEADER #
|
||||
# #
|
||||
# ENSURE THAT YOU DO NOT REMOVE THE REQUIRED LINE: #
|
||||
# #
|
||||
# include "/etc/lighttpd/conf-enabled/*.conf" #
|
||||
# #
|
||||
###################################################################################################
|
||||
|
||||
server.modules = (
|
||||
"mod_access",
|
||||
"mod_accesslog",
|
||||
"mod_auth",
|
||||
"mod_expire",
|
||||
"mod_redirect",
|
||||
@@ -26,7 +27,6 @@ server.modules = (
|
||||
)
|
||||
|
||||
server.document-root = "/var/www/html"
|
||||
server.error-handler-404 = "/pihole/index.php"
|
||||
server.upload-dirs = ( "/var/cache/lighttpd/uploads" )
|
||||
server.errorlog = "/var/log/lighttpd/error-pihole.log"
|
||||
server.pid-file = "/run/lighttpd.pid"
|
||||
@@ -35,8 +35,6 @@ 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"
|
||||
|
||||
# Allow streaming response
|
||||
# reference: https://redmine.lighttpd.net/projects/lighttpd/wiki/Server_stream-response-bodyDetails
|
||||
@@ -67,48 +65,9 @@ mimetype.assign = (
|
||||
".woff2" => "font/woff2"
|
||||
)
|
||||
|
||||
# Add user chosen options held in external file
|
||||
# This uses include_shell instead of an include wildcard for compatibility
|
||||
include_shell "cat external.conf 2>/dev/null"
|
||||
# Add user chosen options held in (optional) external file
|
||||
include "external*.conf"
|
||||
|
||||
# default listening port for IPv6 falls back to the IPv4 port
|
||||
include_shell "/usr/share/lighttpd/use-ipv6.pl " + server.port
|
||||
|
||||
# Prevent Lighttpd from enabling Let's Encrypt SSL for every blocked domain
|
||||
#include_shell "/usr/share/lighttpd/include-conf-enabled.pl"
|
||||
include_shell "find /etc/lighttpd/conf-enabled -name '*.conf' -a ! -name 'letsencrypt.conf' -printf 'include \"%p\"\n' 2>/dev/null"
|
||||
|
||||
# If the URL starts with /admin, it is the Web interface
|
||||
$HTTP["url"] =~ "^/admin/" {
|
||||
# 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 it’s 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-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"
|
||||
)
|
||||
}
|
||||
|
||||
# Block . files from being served, such as .git, .github, .gitignore
|
||||
$HTTP["url"] =~ "^/admin/\.(.*)" {
|
||||
url.access-deny = ("")
|
||||
}
|
||||
|
||||
# allow teleporter and API qr code iframe on settings page
|
||||
$HTTP["url"] =~ "/(teleporter|api_token)\.php$" {
|
||||
$HTTP["referer"] =~ "/admin/settings\.php" {
|
||||
setenv.add-response-header = ( "X-Frame-Options" => "SAMEORIGIN" )
|
||||
}
|
||||
}
|
||||
|
||||
# Default expire header
|
||||
expire.url = ( "" => "access plus 0 seconds" )
|
||||
include "/etc/lighttpd/conf-enabled/*.conf"
|
||||
|
||||
@@ -7,13 +7,15 @@
|
||||
# This file is copyright under the latest version of the EUPL.
|
||||
# Please see LICENSE file for your rights under this license.
|
||||
|
||||
###############################################################################
|
||||
# FILE AUTOMATICALLY OVERWRITTEN BY PI-HOLE INSTALL/UPDATE PROCEDURE. #
|
||||
# ANY CHANGES MADE TO THIS FILE AFTER INSTALL WILL BE LOST ON THE NEXT UPDATE #
|
||||
# #
|
||||
# CHANGES SHOULD BE MADE IN A SEPARATE CONFIG FILE: #
|
||||
# /etc/lighttpd/external.conf #
|
||||
###############################################################################
|
||||
###################################################################################################
|
||||
# IF THIS HEADER EXISTS, THE FILE WILL BE OVERWRITTEN BY PI-HOLE'S UPDATE PROCEDURE. #
|
||||
# ANY CHANGES MADE TO THIS FILE WILL BE LOST ON THE NEXT UPDATE UNLESS YOU REMOVE THIS HEADER #
|
||||
# #
|
||||
# ENSURE THAT YOU DO NOT REMOVE THE REQUIRED LINE: #
|
||||
# #
|
||||
# include "/etc/lighttpd/conf.d/pihole-admin.conf" #
|
||||
# #
|
||||
###################################################################################################
|
||||
|
||||
server.modules = (
|
||||
"mod_access",
|
||||
@@ -27,7 +29,6 @@ server.modules = (
|
||||
)
|
||||
|
||||
server.document-root = "/var/www/html"
|
||||
server.error-handler-404 = "/pihole/index.php"
|
||||
server.upload-dirs = ( "/var/cache/lighttpd/uploads" )
|
||||
server.errorlog = "/var/log/lighttpd/error-pihole.log"
|
||||
server.pid-file = "/run/lighttpd.pid"
|
||||
@@ -36,8 +37,6 @@ 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"
|
||||
|
||||
# Allow streaming response
|
||||
# reference: https://redmine.lighttpd.net/projects/lighttpd/wiki/Server_stream-response-bodyDetails
|
||||
@@ -68,9 +67,8 @@ mimetype.assign = (
|
||||
".woff2" => "font/woff2"
|
||||
)
|
||||
|
||||
# Add user chosen options held in external file
|
||||
# This uses include_shell instead of an include wildcard for compatibility
|
||||
include_shell "cat external.conf 2>/dev/null"
|
||||
# Add user chosen options held in (optional) external file
|
||||
include "external*.conf"
|
||||
|
||||
# default listening port for IPv6 falls back to the IPv4 port
|
||||
#include_shell "/usr/share/lighttpd/use-ipv6.pl " + server.port
|
||||
@@ -86,37 +84,4 @@ fastcgi.server = (
|
||||
)
|
||||
)
|
||||
|
||||
# If the URL starts with /admin, it is the Web interface
|
||||
$HTTP["url"] =~ "^/admin/" {
|
||||
# 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 it’s 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-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"
|
||||
)
|
||||
}
|
||||
|
||||
# Block . files from being served, such as .git, .github, .gitignore
|
||||
$HTTP["url"] =~ "^/admin/\.(.*)" {
|
||||
url.access-deny = ("")
|
||||
}
|
||||
|
||||
# allow teleporter and API qr code iframe on settings page
|
||||
$HTTP["url"] =~ "/(teleporter|api_token)\.php$" {
|
||||
$HTTP["referer"] =~ "/admin/settings\.php" {
|
||||
setenv.add-response-header = ( "X-Frame-Options" => "SAMEORIGIN" )
|
||||
}
|
||||
}
|
||||
|
||||
# Default expire header
|
||||
expire.url = ( "" => "access plus 0 seconds" )
|
||||
include "/etc/lighttpd/conf.d/pihole-admin.conf"
|
||||
|
||||
82
advanced/pihole-admin.conf
Normal file
82
advanced/pihole-admin.conf
Normal file
@@ -0,0 +1,82 @@
|
||||
# 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.
|
||||
#
|
||||
# Lighttpd config for Pi-hole
|
||||
#
|
||||
# This file is copyright under the latest version of the EUPL.
|
||||
# Please see LICENSE file for your rights under this license.
|
||||
|
||||
###############################################################################
|
||||
# FILE AUTOMATICALLY OVERWRITTEN BY PI-HOLE INSTALL/UPDATE PROCEDURE. #
|
||||
# ANY CHANGES MADE TO THIS FILE AFTER INSTALL WILL BE LOST ON THE NEXT UPDATE #
|
||||
###############################################################################
|
||||
|
||||
server.errorlog := "/var/log/lighttpd/error-pihole.log"
|
||||
|
||||
$HTTP["url"] =~ "^/admin/" {
|
||||
server.document-root = "/var/www/html"
|
||||
server.stream-response-body = 1
|
||||
accesslog.filename = "/var/log/lighttpd/access-pihole.log"
|
||||
accesslog.format = "%{%s}t|%h|%V|%r|%s|%b"
|
||||
|
||||
fastcgi.server = (
|
||||
".php" => (
|
||||
"localhost" => (
|
||||
"socket" => "/run/lighttpd/pihole-php-fastcgi.socket",
|
||||
"bin-path" => "/usr/bin/php-cgi",
|
||||
"min-procs" => 1,
|
||||
"max-procs" => 1,
|
||||
"bin-environment" => (
|
||||
"PHP_FCGI_CHILDREN" => "4",
|
||||
"PHP_FCGI_MAX_REQUESTS" => "10000",
|
||||
),
|
||||
"bin-copy-environment" => (
|
||||
"PATH", "SHELL", "USER"
|
||||
),
|
||||
"broken-scriptfilename" => "enable",
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
# 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. (deprecated; disabled)
|
||||
# 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 it’s 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-XSS-Protection" => "0",
|
||||
"X-Content-Type-Options" => "nosniff",
|
||||
"Content-Security-Policy" => "default-src 'self' 'unsafe-inline';",
|
||||
"X-Permitted-Cross-Domain-Policies" => "none",
|
||||
"Referrer-Policy" => "same-origin"
|
||||
)
|
||||
|
||||
# Block . files from being served, such as .git, .github, .gitignore
|
||||
$HTTP["url"] =~ "^/admin/\." {
|
||||
url.access-deny = ("")
|
||||
}
|
||||
|
||||
# allow teleporter and API qr code iframe on settings page
|
||||
$HTTP["url"] =~ "/(teleporter|api_token)\.php$" {
|
||||
$HTTP["referer"] =~ "/admin/settings\.php" {
|
||||
setenv.set-response-header = ( "X-Frame-Options" => "SAMEORIGIN" )
|
||||
}
|
||||
}
|
||||
}
|
||||
else $HTTP["url"] == "/admin" {
|
||||
url.redirect = ("" => "/admin/")
|
||||
}
|
||||
|
||||
$HTTP["host"] == "pi.hole" {
|
||||
$HTTP["url"] == "/" {
|
||||
url.redirect = ("" => "/admin/")
|
||||
}
|
||||
}
|
||||
|
||||
# (keep this on one line for basic-install.sh filtering during install)
|
||||
server.modules += ( "mod_access", "mod_accesslog", "mod_redirect", "mod_fastcgi", "mod_setenv" )
|
||||
@@ -82,7 +82,6 @@ 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_404_DIR="${webroot}/pihole"
|
||||
FTL_CONFIG_FILE="${PI_HOLE_CONFIG_DIR}/pihole-FTL.conf"
|
||||
if [ -z "$useUpdateVars" ]; then
|
||||
useUpdateVars=false
|
||||
@@ -358,9 +357,9 @@ 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)
|
||||
INSTALLER_DEPS=(git dialog iproute newt procps-ng chkconfig ca-certificates)
|
||||
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"
|
||||
@@ -828,8 +827,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
|
||||
@@ -1377,37 +1379,96 @@ installConfigs() {
|
||||
fi
|
||||
fi
|
||||
|
||||
# Install pihole-FTL.service
|
||||
install -T -m 0755 "${PI_HOLE_LOCAL_REPO}/advanced/Templates/pihole-FTL.service" "/etc/init.d/pihole-FTL"
|
||||
# Install pihole-FTL systemd or init.d service, based on whether systemd is the init system or not
|
||||
# Follow debhelper logic, which checks for /run/systemd/system to derive whether systemd is the init system
|
||||
if [[ -d '/run/systemd/system' ]]; then
|
||||
install -T -m 0644 "${PI_HOLE_LOCAL_REPO}/advanced/Templates/pihole-FTL.systemd" '/etc/systemd/system/pihole-FTL.service'
|
||||
|
||||
# Remove init.d service if present
|
||||
if [[ -e '/etc/init.d/pihole-FTL' ]]; then
|
||||
rm '/etc/init.d/pihole-FTL'
|
||||
update-rc.d pihole-FTL remove
|
||||
fi
|
||||
|
||||
# Load final service
|
||||
systemctl daemon-reload
|
||||
else
|
||||
install -T -m 0755 "${PI_HOLE_LOCAL_REPO}/advanced/Templates/pihole-FTL.service" '/etc/init.d/pihole-FTL'
|
||||
fi
|
||||
install -T -m 0755 "${PI_HOLE_LOCAL_REPO}/advanced/Templates/pihole-FTL-prestart.sh" "${PI_HOLE_INSTALL_DIR}/pihole-FTL-prestart.sh"
|
||||
install -T -m 0755 "${PI_HOLE_LOCAL_REPO}/advanced/Templates/pihole-FTL-poststop.sh" "${PI_HOLE_INSTALL_DIR}/pihole-FTL-poststop.sh"
|
||||
|
||||
# If the user chose to install the dashboard,
|
||||
if [[ "${INSTALL_WEB_SERVER}" == true ]]; then
|
||||
# and if the Web server conf directory does not exist,
|
||||
if [[ ! -d "/etc/lighttpd" ]]; then
|
||||
# make it and set the owners
|
||||
install -d -m 755 -o "${USER}" -g root /etc/lighttpd
|
||||
# Otherwise, if the config file already exists
|
||||
elif [[ -f "${lighttpdConfig}" ]]; then
|
||||
# back up the original
|
||||
mv "${lighttpdConfig}"{,.orig}
|
||||
fi
|
||||
# and copy in the config file Pi-hole needs
|
||||
install -D -m 644 -T ${PI_HOLE_LOCAL_REPO}/advanced/${LIGHTTPD_CFG} "${lighttpdConfig}"
|
||||
# Make sure the external.conf file exists, as lighttpd v1.4.50 crashes without it
|
||||
if [ ! -f /etc/lighttpd/external.conf ]; then
|
||||
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_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
|
||||
# set permissions on /etc/lighttpd/lighttpd.conf so pihole user (other) can read the file
|
||||
chmod o+x /etc/lighttpd
|
||||
chmod o+r "${lighttpdConfig}"
|
||||
|
||||
# Ensure /run/lighttpd exists and is owned by lighttpd user
|
||||
# Needed for the php socket
|
||||
mkdir -p /run/lighttpd
|
||||
chown ${LIGHTTPD_USER}:${LIGHTTPD_GROUP} /run/lighttpd
|
||||
mkdir -p /var/cache/lighttpd/compress
|
||||
chown ${LIGHTTPD_USER}:${LIGHTTPD_GROUP} /var/cache/lighttpd/compress
|
||||
mkdir -p /var/cache/lighttpd/uploads
|
||||
chown ${LIGHTTPD_USER}:${LIGHTTPD_GROUP} /var/cache/lighttpd/uploads
|
||||
|
||||
if grep -q -F "OVERWRITTEN BY PI-HOLE" "${lighttpdConfig}"; then
|
||||
# Attempt to preserve backwards compatibility with older versions
|
||||
install -D -m 644 -T ${PI_HOLE_LOCAL_REPO}/advanced/${LIGHTTPD_CFG} "${lighttpdConfig}"
|
||||
# Make the directories if they do not exist and set the owners
|
||||
mkdir -p /var/cache/lighttpd/compress
|
||||
chown ${LIGHTTPD_USER}:${LIGHTTPD_GROUP} /var/cache/lighttpd/compress
|
||||
mkdir -p /var/cache/lighttpd/uploads
|
||||
chown ${LIGHTTPD_USER}:${LIGHTTPD_GROUP} /var/cache/lighttpd/uploads
|
||||
fi
|
||||
# Copy the config file to include for pihole admin interface
|
||||
if [[ -d "/etc/lighttpd/conf.d" ]]; then
|
||||
install -D -m 644 -T ${PI_HOLE_LOCAL_REPO}/advanced/pihole-admin.conf /etc/lighttpd/conf.d/pihole-admin.conf
|
||||
if grep -q -F 'include "/etc/lighttpd/conf.d/pihole-admin.conf"' "${lighttpdConfig}"; then
|
||||
:
|
||||
else
|
||||
echo 'include "/etc/lighttpd/conf.d/pihole-admin.conf"' >> "${lighttpdConfig}"
|
||||
fi
|
||||
# Avoid some warnings trace from lighttpd, which might break tests
|
||||
conf=/etc/lighttpd/conf.d/pihole-admin.conf
|
||||
if lighttpd -f "${lighttpdConfig}" -tt 2>&1 | grep -q -F "WARNING: unknown config-key: dir-listing\."; then
|
||||
echo '# Avoid some warnings trace from lighttpd, which might break tests' >> $conf
|
||||
echo 'server.modules += ( "mod_dirlisting" )' >> $conf
|
||||
fi
|
||||
if lighttpd -f "${lighttpdConfig}" -tt 2>&1 | grep -q -F "warning: please use server.use-ipv6"; then
|
||||
echo '# Avoid some warnings trace from lighttpd, which might break tests' >> $conf
|
||||
echo 'server.use-ipv6 := "disable"' >> $conf
|
||||
fi
|
||||
elif [[ -d "/etc/lighttpd/conf-available" ]]; then
|
||||
conf=/etc/lighttpd/conf-available/15-pihole-admin.conf
|
||||
install -D -m 644 -T ${PI_HOLE_LOCAL_REPO}/advanced/pihole-admin.conf $conf
|
||||
|
||||
# Get the version number of lighttpd
|
||||
version=$(dpkg-query -f='${Version}\n' --show lighttpd)
|
||||
# Test if that version is greater than or euqal to 1.4.56
|
||||
if dpkg --compare-versions "$version" "ge" "1.4.56"; then
|
||||
# If it is, then we don't need to disable the modules
|
||||
# (server.modules duplication is ignored in lighttpd 1.4.56+)
|
||||
:
|
||||
else
|
||||
# disable server.modules += ( ... ) in $conf to avoid module dups
|
||||
if awk '!/^server\.modules/{print}' $conf > $conf.$$ && mv $conf.$$ $conf; then
|
||||
:
|
||||
else
|
||||
rm $conf.$$
|
||||
fi
|
||||
fi
|
||||
|
||||
chmod 644 $conf
|
||||
if is_command lighty-enable-mod ; then
|
||||
lighty-enable-mod pihole-admin access accesslog redirect fastcgi setenv > /dev/null || true
|
||||
else
|
||||
# Otherwise, show info about installing them
|
||||
printf " %b Warning: 'lighty-enable-mod' utility not found\\n" "${INFO}"
|
||||
printf " Please ensure fastcgi is enabled if you experience issues\\n"
|
||||
fi
|
||||
else
|
||||
# lighttpd config include dir not found
|
||||
printf " %b Warning: lighttpd config include dir not found\\n" "${INFO}"
|
||||
printf " Please manually install pihole-admin.conf\\n"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -1658,30 +1719,6 @@ install_dependent_packages() {
|
||||
|
||||
# Install the Web interface dashboard
|
||||
installPiholeWeb() {
|
||||
printf "\\n %b Installing 404 page...\\n" "${INFO}"
|
||||
|
||||
local str="Creating directory for 404 page, and copying files"
|
||||
printf " %b %s..." "${INFO}" "${str}"
|
||||
# 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}"
|
||||
|
||||
local str="Backing up index.lighttpd.html"
|
||||
printf " %b %s..." "${INFO}" "${str}"
|
||||
# If the default index file exists,
|
||||
if [[ -f "${webroot}/index.lighttpd.html" ]]; then
|
||||
# back it up
|
||||
mv ${webroot}/index.lighttpd.html ${webroot}/index.lighttpd.orig
|
||||
printf "%b %b %s\\n" "${OVER}" "${TICK}" "${str}"
|
||||
else
|
||||
# Otherwise, don't do anything
|
||||
printf "%b %b %s\\n" "${OVER}" "${INFO}" "${str}"
|
||||
printf " No default index.lighttpd.html file found... not backing up\\n"
|
||||
fi
|
||||
|
||||
# Install Sudoers file
|
||||
local str="Installing sudoer file"
|
||||
printf "\\n %b %s..." "${INFO}" "${str}"
|
||||
@@ -1757,20 +1794,35 @@ create_pihole_user() {
|
||||
else
|
||||
# If the pihole user doesn't exist,
|
||||
printf "%b %b %s" "${OVER}" "${CROSS}" "${str}"
|
||||
local str="Creating user 'pihole'"
|
||||
printf "%b %b %s..." "${OVER}" "${INFO}" "${str}"
|
||||
# create her with the useradd command,
|
||||
local str="Checking for group 'pihole'"
|
||||
printf " %b %s..." "${INFO}" "${str}"
|
||||
if getent group pihole > /dev/null 2>&1; then
|
||||
# then add her to the pihole group (as it already exists)
|
||||
# group pihole exists
|
||||
printf "%b %b %s\\n" "${OVER}" "${TICK}" "${str}"
|
||||
# then create and add her to the pihole group
|
||||
local str="Creating user 'pihole'"
|
||||
printf "%b %b %s..." "${OVER}" "${INFO}" "${str}"
|
||||
if useradd -r --no-user-group -g pihole -s /usr/sbin/nologin pihole; then
|
||||
printf "%b %b %s\\n" "${OVER}" "${TICK}" "${str}"
|
||||
else
|
||||
printf "%b %b %s\\n" "${OVER}" "${CROSS}" "${str}"
|
||||
fi
|
||||
else
|
||||
# add user pihole with default group settings
|
||||
if useradd -r -s /usr/sbin/nologin pihole; then
|
||||
# group pihole does not exist
|
||||
printf "%b %b %s\\n" "${OVER}" "${CROSS}" "${str}"
|
||||
local str="Creating group 'pihole'"
|
||||
# if group can be created
|
||||
if groupadd pihole; then
|
||||
printf "%b %b %s\\n" "${OVER}" "${TICK}" "${str}"
|
||||
# create and add pihole user to the pihole group
|
||||
local str="Creating user 'pihole'"
|
||||
printf "%b %b %s..." "${OVER}" "${INFO}" "${str}"
|
||||
if useradd -r --no-user-group -g pihole -s /usr/sbin/nologin pihole; then
|
||||
printf "%b %b %s\\n" "${OVER}" "${TICK}" "${str}"
|
||||
else
|
||||
printf "%b %b %s\\n" "${OVER}" "${CROSS}" "${str}"
|
||||
fi
|
||||
|
||||
else
|
||||
printf "%b %b %s\\n" "${OVER}" "${CROSS}" "${str}"
|
||||
fi
|
||||
@@ -1869,15 +1921,6 @@ installPihole() {
|
||||
# Give lighttpd access to the pihole group so the web interface can
|
||||
# manage the gravity.db database
|
||||
usermod -a -G pihole ${LIGHTTPD_USER}
|
||||
# If the lighttpd command is executable,
|
||||
if is_command lighty-enable-mod ; then
|
||||
# enable fastcgi and fastcgi-php
|
||||
lighty-enable-mod fastcgi fastcgi-php > /dev/null || true
|
||||
else
|
||||
# Otherwise, show info about installing them
|
||||
printf " %b Warning: 'lighty-enable-mod' utility not found\\n" "${INFO}"
|
||||
printf " Please ensure fastcgi is enabled if you experience issues\\n"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
# Install base files and web interface
|
||||
@@ -2267,7 +2310,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
|
||||
@@ -2693,9 +2736,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}"
|
||||
|
||||
@@ -131,6 +131,7 @@ removeNoPurge() {
|
||||
fi
|
||||
|
||||
if package_check lighttpd > /dev/null; then
|
||||
# Attempt to preserve backwards compatibility with older versions
|
||||
if [[ -f /etc/lighttpd/lighttpd.conf.orig ]]; then
|
||||
${SUDO} mv /etc/lighttpd/lighttpd.conf.orig /etc/lighttpd/lighttpd.conf
|
||||
fi
|
||||
@@ -139,6 +140,29 @@ removeNoPurge() {
|
||||
${SUDO} rm /etc/lighttpd/external.conf
|
||||
fi
|
||||
|
||||
# Fedora-based
|
||||
if [[ -f /etc/lighttpd/conf.d/pihole-admin.conf ]]; then
|
||||
${SUDO} rm /etc/lighttpd/conf.d/pihole-admin.conf
|
||||
conf=/etc/lighttpd/lighttpd.conf
|
||||
tconf=/tmp/lighttpd.conf.$$
|
||||
if awk '!/^include "\/etc\/lighttpd\/conf\.d\/pihole-admin\.conf"$/{print}' \
|
||||
$conf > $tconf && mv $tconf $conf; then
|
||||
:
|
||||
else
|
||||
rm $tconf
|
||||
fi
|
||||
${SUDO} chown root:root $conf
|
||||
${SUDO} chmod 644 $conf
|
||||
fi
|
||||
|
||||
# Debian-based
|
||||
if [[ -f /etc/lighttpd/conf-available/pihole-admin.conf ]]; then
|
||||
if is_command lighty-disable-mod ; then
|
||||
${SUDO} lighty-disable-mod pihole-admin > /dev/null || true
|
||||
fi
|
||||
${SUDO} rm /etc/lighttpd/conf-available/15-pihole-admin.conf
|
||||
fi
|
||||
|
||||
echo -e " ${TICK} Removed lighttpd configs"
|
||||
fi
|
||||
|
||||
|
||||
190
gravity.sh
190
gravity.sh
@@ -244,7 +244,7 @@ database_adlist_number() {
|
||||
return;
|
||||
fi
|
||||
|
||||
output=$( { printf ".timeout 30000\\nUPDATE adlist SET number = %i, invalid_domains = %i WHERE id = %i;\\n" "${num_source_lines}" "${num_invalid}" "${1}" | pihole-FTL sqlite3 "${gravityDBfile}"; } 2>&1 )
|
||||
output=$( { printf ".timeout 30000\\nUPDATE adlist SET number = %i, invalid_domains = %i WHERE id = %i;\\n" "${num_domains}" "${num_non_domains}" "${1}" | pihole-FTL sqlite3 "${gravityDBfile}"; } 2>&1 )
|
||||
status="$?"
|
||||
|
||||
if [[ "${status}" -ne 0 ]]; then
|
||||
@@ -519,45 +519,80 @@ gravity_DownloadBlocklists() {
|
||||
gravity_Blackbody=true
|
||||
}
|
||||
|
||||
# num_target_lines does increase for every correctly added domain in pareseList()
|
||||
num_target_lines=0
|
||||
num_source_lines=0
|
||||
num_invalid=0
|
||||
# num_total_imported_domains increases for each list processed
|
||||
num_total_imported_domains=0
|
||||
num_domains=0
|
||||
num_non_domains=0
|
||||
parseList() {
|
||||
local adlistID="${1}" src="${2}" target="${3}" incorrect_lines
|
||||
local adlistID="${1}" src="${2}" target="${3}" non_domains sample_non_domains tmp_non_domains_str false_positive
|
||||
# This sed does the following things:
|
||||
# 1. Remove all domains containing invalid characters. Valid are: a-z, A-Z, 0-9, dot (.), minus (-), underscore (_)
|
||||
# 2. Append ,adlistID to every line
|
||||
# 3. Remove trailing period (see https://github.com/pi-hole/pi-hole/issues/4701)
|
||||
# 4. Ensures there is a newline on the last line
|
||||
sed -e "/[^a-zA-Z0-9.\_-]/d;s/\.$//;s/$/,${adlistID}/;/.$/a\\" "${src}" >> "${target}"
|
||||
# Find (up to) five domains containing invalid characters (see above)
|
||||
incorrect_lines="$(sed -e "/[^a-zA-Z0-9.\_-]/!d" "${src}" | head -n 5)"
|
||||
# 1. Remove all lines containing no domains
|
||||
# 2. Remove all domains containing invalid characters. Valid are: a-z, A-Z, 0-9, dot (.), minus (-), underscore (_)
|
||||
# 3. Append ,adlistID to every line
|
||||
# 4. Remove trailing period (see https://github.com/pi-hole/pi-hole/issues/4701)
|
||||
# 5. Ensures there is a newline on the last line
|
||||
sed -r "/([^\.]+\.)+[^\.]{2,}/!d;/[^a-zA-Z0-9.\_-]/d;s/\.$//;s/$/,${adlistID}/;/.$/a\\" "${src}" >> "${target}"
|
||||
|
||||
local num_target_lines_new num_correct_lines
|
||||
# Get number of lines in source file
|
||||
num_source_lines="$(grep -c "^" "${src}")"
|
||||
# Get the new number of lines in destination file
|
||||
num_target_lines_new="$(grep -c "^" "${target}")"
|
||||
# Number of new correctly added lines
|
||||
num_correct_lines="$(( num_target_lines_new-num_target_lines ))"
|
||||
# Update number of lines in target file
|
||||
num_target_lines="$num_target_lines_new"
|
||||
num_invalid="$(( num_source_lines-num_correct_lines ))"
|
||||
if [[ "${num_invalid}" -eq 0 ]]; then
|
||||
echo " ${INFO} Analyzed ${num_source_lines} domains"
|
||||
# Find lines containing no domains or with invalid characters (see above)
|
||||
# Remove duplicates from the list
|
||||
mapfile -t non_domains <<< "$(sed -r "/([^\.]+\.)+[^\.]{2,}/d" < "${src}")"
|
||||
mapfile -t -O "${#non_domains[@]}" non_domains <<< "$(sed -r "/[^a-zA-Z0-9.\_-]/!d" < "${src}")"
|
||||
IFS=" " read -r -a non_domains <<< "$(tr ' ' '\n' <<< "${non_domains[@]}" | sort -u | tr '\n' ' ')"
|
||||
|
||||
# A list of items of common local hostnames not to report as unusable
|
||||
# Some lists (i.e StevenBlack's) contain these as they are supposed to be used as HOST files
|
||||
# but flagging them as unusable causes more confusion than it's worth - so we suppress them from the output
|
||||
false_positives=(
|
||||
"localhost"
|
||||
"localhost.localdomain"
|
||||
"local"
|
||||
"broadcasthost"
|
||||
"localhost"
|
||||
"ip6-localhost"
|
||||
"ip6-loopback"
|
||||
"lo0 localhost"
|
||||
"ip6-localnet"
|
||||
"ip6-mcastprefix"
|
||||
"ip6-allnodes"
|
||||
"ip6-allrouters"
|
||||
"ip6-allhosts"
|
||||
)
|
||||
|
||||
# Read the unusable lines into a string
|
||||
tmp_non_domains_str=" ${non_domains[*]} "
|
||||
for false_positive in "${false_positives[@]}"; do
|
||||
# Remove false positives from tmp_non_domains_str
|
||||
tmp_non_domains_str="${tmp_non_domains_str/ ${false_positive} / }"
|
||||
done
|
||||
# Read the string back into an array
|
||||
IFS=" " read -r -a non_domains <<< "${tmp_non_domains_str}"
|
||||
|
||||
# Get a sample of non-domain entries, limited to 5 (the list should already have been de-duplicated)
|
||||
IFS=" " read -r -a sample_non_domains <<< "$(tr ' ' '\n' <<< "${non_domains[@]}" | head -n 5 | tr '\n' ' ')"
|
||||
|
||||
local tmp_new_imported_total
|
||||
# Get the new number of domains in destination file
|
||||
tmp_new_imported_total="$(grep -c "^" "${target}")"
|
||||
# Number of imported lines for this file is the difference between the new total and the old total. (Or, the number of domains we just added.)
|
||||
num_domains="$(( tmp_new_imported_total-num_total_imported_domains ))"
|
||||
# Replace the running total with the new total.
|
||||
num_total_imported_domains="$tmp_new_imported_total"
|
||||
# Get the number of non_domains (this is the number of entries left after stripping the source of comments/duplicates/false positives/domains)
|
||||
num_non_domains="${#non_domains[@]}"
|
||||
|
||||
# If there are unusable lines, we display some information about them. This is not error or major cause for concern.
|
||||
if [[ "${num_non_domains}" -ne 0 ]]; then
|
||||
echo " ${INFO} Imported ${num_domains} domains, ignoring ${num_non_domains} non-domain entries"
|
||||
echo " Sample of non-domain entries:"
|
||||
for each in "${sample_non_domains[@]}"
|
||||
do
|
||||
echo " - ${each}"
|
||||
done
|
||||
else
|
||||
echo " ${INFO} Analyzed ${num_source_lines} domains, ${num_invalid} domains invalid!"
|
||||
fi
|
||||
|
||||
# Display sample of invalid lines if we found some
|
||||
if [[ -n "${incorrect_lines}" ]]; then
|
||||
echo " Sample of invalid domains:"
|
||||
while IFS= read -r line; do
|
||||
echo " - ${line}"
|
||||
done <<< "${incorrect_lines}"
|
||||
echo " ${INFO} Imported ${num_domains} domains"
|
||||
fi
|
||||
}
|
||||
|
||||
compareLists() {
|
||||
local adlistID="${1}" target="${2}"
|
||||
|
||||
@@ -710,8 +745,8 @@ gravity_DownloadBlocklistFromUrl() {
|
||||
else
|
||||
echo -e " ${CROSS} List download failed: ${COL_LIGHT_RED}no cached list available${COL_NC}"
|
||||
# Manually reset these two numbers because we do not call parseList here
|
||||
num_source_lines=0
|
||||
num_invalid=0
|
||||
num_domains=0
|
||||
num_non_domains=0
|
||||
database_adlist_number "${adlistID}"
|
||||
database_adlist_status "${adlistID}" "4"
|
||||
fi
|
||||
@@ -720,72 +755,25 @@ gravity_DownloadBlocklistFromUrl() {
|
||||
|
||||
# Parse source files into domains format
|
||||
gravity_ParseFileIntoDomains() {
|
||||
local src="${1}" destination="${2}" firstLine
|
||||
local src="${1}" destination="${2}"
|
||||
|
||||
# Determine if we are parsing a consolidated list
|
||||
#if [[ "${src}" == "${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
|
||||
< "${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}"
|
||||
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 < "${src}"
|
||||
|
||||
# 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=/" "${src}" &> /dev/null; then
|
||||
# Parse Dnsmasq format lists
|
||||
echo -e " ${CROSS} Format: Dnsmasq (list type not supported)"
|
||||
elif grep -q -E "^https?://" "${src}" &> /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 }
|
||||
' "${src}" 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 "${src}" "${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) Remove empty lines
|
||||
< "${src}" tr -d '\r' | \
|
||||
tr '[:upper:]' '[:lower:]' | \
|
||||
sed 's/\s*#.*//g' | \
|
||||
sed -r '/(\/).*$/d' | \
|
||||
sed -r 's/^.*\s+//g' | \
|
||||
sed '/^$/d'> "${destination}"
|
||||
chmod 644 "${destination}"
|
||||
}
|
||||
|
||||
# Report number of entries in a table
|
||||
|
||||
@@ -23,7 +23,7 @@ Pi-hole : A black-hole for internet advertisements
|
||||
.br
|
||||
pihole -r
|
||||
.br
|
||||
pihole -t
|
||||
\fBpihole\fR \fB-t\fR [arg]
|
||||
.br
|
||||
pihole -g\fR
|
||||
.br
|
||||
@@ -113,11 +113,15 @@ Available commands and options:
|
||||
Reconfigure or Repair Pi-hole subsystems
|
||||
.br
|
||||
|
||||
\fB-t, tail\fR
|
||||
\fB-t, tail\fR [arg]
|
||||
.br
|
||||
View the live output of the Pi-hole log
|
||||
.br
|
||||
|
||||
[arg] Optional argument to filter the log for
|
||||
(regular expressions are supported)
|
||||
.br
|
||||
|
||||
\fB-a, admin\fR [options]
|
||||
.br
|
||||
|
||||
|
||||
41
pihole
41
pihole
@@ -23,6 +23,14 @@ source "${colfile}"
|
||||
utilsfile="${PI_HOLE_SCRIPT_DIR}/utils.sh"
|
||||
source "${utilsfile}"
|
||||
|
||||
versionsfile="/etc/pihole/versions"
|
||||
if [ -f "${versionsfile}" ]; then
|
||||
# Only source versionsfile if the file exits
|
||||
# fixes a warning during installation where versionsfile does not exist yet
|
||||
# but gravity calls `pihole -status` and thereby sourcing the file
|
||||
source "${versionsfile}"
|
||||
fi
|
||||
|
||||
webpageFunc() {
|
||||
source "${PI_HOLE_SCRIPT_DIR}/webpage.sh"
|
||||
main "$@"
|
||||
@@ -63,14 +71,22 @@ arpFunc() {
|
||||
}
|
||||
|
||||
updatePiholeFunc() {
|
||||
shift
|
||||
"${PI_HOLE_SCRIPT_DIR}"/update.sh "$@"
|
||||
exit 0
|
||||
if [ -n "${DOCKER_VERSION}" ]; then
|
||||
unsupportedFunc
|
||||
else
|
||||
shift
|
||||
"${PI_HOLE_SCRIPT_DIR}"/update.sh "$@"
|
||||
exit 0
|
||||
fi
|
||||
}
|
||||
|
||||
reconfigurePiholeFunc() {
|
||||
/etc/.pihole/automated\ install/basic-install.sh --reconfigure
|
||||
exit 0;
|
||||
if [ -n "${DOCKER_VERSION}" ]; then
|
||||
unsupportedFunc
|
||||
else
|
||||
/etc/.pihole/automated\ install/basic-install.sh --reconfigure
|
||||
exit 0;
|
||||
fi
|
||||
}
|
||||
|
||||
updateGravityFunc() {
|
||||
@@ -91,8 +107,12 @@ chronometerFunc() {
|
||||
|
||||
|
||||
uninstallFunc() {
|
||||
"${PI_HOLE_SCRIPT_DIR}"/uninstall.sh
|
||||
exit 0
|
||||
if [ -n "${DOCKER_VERSION}" ]; then
|
||||
unsupportedFunc
|
||||
else
|
||||
"${PI_HOLE_SCRIPT_DIR}"/uninstall.sh
|
||||
exit 0
|
||||
fi
|
||||
}
|
||||
|
||||
versionFunc() {
|
||||
@@ -429,6 +449,11 @@ updateCheckFunc() {
|
||||
exit 0
|
||||
}
|
||||
|
||||
unsupportedFunc(){
|
||||
echo "Function not supported in Docker images"
|
||||
exit 0
|
||||
}
|
||||
|
||||
helpFunc() {
|
||||
echo "Usage: pihole [options]
|
||||
Example: 'pihole -w -h'
|
||||
@@ -553,7 +578,7 @@ case "${1}" in
|
||||
"restartdns" ) restartDNS "$2";;
|
||||
"-a" | "admin" ) webpageFunc "$@";;
|
||||
"checkout" ) piholeCheckoutFunc "$@";;
|
||||
"updatechecker" ) updateCheckFunc "$@";;
|
||||
"updatechecker" ) shift; updateCheckFunc "$@";;
|
||||
"arpflush" ) arpFunc "$@";;
|
||||
"-t" | "tail" ) tailFunc "$2";;
|
||||
esac
|
||||
|
||||
18
test/_centos_9.Dockerfile
Normal file
18
test/_centos_9.Dockerfile
Normal file
@@ -0,0 +1,18 @@
|
||||
FROM quay.io/centos/centos:stream9
|
||||
RUN yum install -y --allowerasing curl git initscripts
|
||||
|
||||
ENV GITDIR /etc/.pihole
|
||||
ENV SCRIPTDIR /opt/pihole
|
||||
|
||||
RUN mkdir -p $GITDIR $SCRIPTDIR /etc/pihole
|
||||
ADD . $GITDIR
|
||||
RUN cp $GITDIR/advanced/Scripts/*.sh $GITDIR/gravity.sh $GITDIR/pihole $GITDIR/automated\ install/*.sh $SCRIPTDIR/
|
||||
ENV PATH /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:$SCRIPTDIR
|
||||
|
||||
RUN true && \
|
||||
chmod +x $SCRIPTDIR/*
|
||||
|
||||
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 && \
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM fedora:35
|
||||
FROM fedora:37
|
||||
RUN dnf install -y git initscripts
|
||||
|
||||
ENV GITDIR /etc/.pihole
|
||||
@@ -1,5 +1,6 @@
|
||||
docker-compose
|
||||
pytest
|
||||
pytest-xdist
|
||||
pytest-testinfra
|
||||
tox
|
||||
docker-compose == 1.29.2
|
||||
pytest == 7.2.1
|
||||
pytest-xdist == 3.1.0
|
||||
pytest-testinfra == 7.0.0
|
||||
tox == 4.4.4
|
||||
|
||||
|
||||
@@ -129,34 +129,16 @@ def test_installPiholeWeb_fresh_install_no_errors(host):
|
||||
installPiholeWeb
|
||||
"""
|
||||
)
|
||||
expected_stdout = info_box + " Installing 404 page..."
|
||||
assert expected_stdout in installWeb.stdout
|
||||
expected_stdout = tick_box + (
|
||||
" Creating directory for 404 page, " "and copying files"
|
||||
)
|
||||
assert expected_stdout in installWeb.stdout
|
||||
expected_stdout = info_box + " Backing up index.lighttpd.html"
|
||||
assert expected_stdout in installWeb.stdout
|
||||
expected_stdout = "No default index.lighttpd.html file found... " "not backing up"
|
||||
assert expected_stdout in installWeb.stdout
|
||||
expected_stdout = tick_box + " Installing sudoer file"
|
||||
assert expected_stdout in installWeb.stdout
|
||||
web_directory = host.run("ls -r /var/www/html/pihole").stdout
|
||||
assert "index.php" in web_directory
|
||||
|
||||
|
||||
def get_directories_recursive(host, directory):
|
||||
if directory is None:
|
||||
return directory
|
||||
ls = host.run("ls -d {}".format(directory + "/*/"))
|
||||
directories = list(filter(bool, ls.stdout.splitlines()))
|
||||
dirs = directories
|
||||
for dirval in directories:
|
||||
dir_rec = get_directories_recursive(host, dirval)
|
||||
if isinstance(dir_rec, str):
|
||||
dirs.extend([dir_rec])
|
||||
else:
|
||||
dirs.extend(dir_rec)
|
||||
# returns all non-hidden subdirs of 'directory'
|
||||
dirs_raw = host.run("find {} -type d -not -path '*/.*'".format(directory))
|
||||
dirs = list(filter(bool, dirs_raw.stdout.splitlines()))
|
||||
return dirs
|
||||
|
||||
|
||||
@@ -211,6 +193,8 @@ def test_installPihole_fresh_install_readableFiles(host):
|
||||
maninstalled = True
|
||||
if (info_box + " man not installed") in install.stdout:
|
||||
maninstalled = False
|
||||
if (info_box + " man pages not installed") in install.stdout:
|
||||
maninstalled = False
|
||||
piholeuser = "pihole"
|
||||
exit_status_success = 0
|
||||
test_cmd = 'su --shell /bin/bash --command "test -{0} {1}" -p {2}'
|
||||
@@ -287,6 +271,24 @@ def test_installPihole_fresh_install_readableFiles(host):
|
||||
check_lighttpd = test_cmd.format("r", "/etc/lighttpd/lighttpd.conf", piholeuser)
|
||||
actual_rc = host.run(check_lighttpd).rc
|
||||
assert exit_status_success == actual_rc
|
||||
# check readable /etc/lighttpd/conf*/pihole-admin.conf
|
||||
check_lighttpd = test_cmd.format("r", "/etc/lighttpd/conf.d", piholeuser)
|
||||
if host.run(check_lighttpd).rc == exit_status_success:
|
||||
check_lighttpd = test_cmd.format(
|
||||
"r", "/etc/lighttpd/conf.d/pihole-admin.conf", piholeuser
|
||||
)
|
||||
actual_rc = host.run(check_lighttpd).rc
|
||||
assert exit_status_success == actual_rc
|
||||
else:
|
||||
check_lighttpd = test_cmd.format(
|
||||
"r", "/etc/lighttpd/conf-available", piholeuser
|
||||
)
|
||||
if host.run(check_lighttpd).rc == exit_status_success:
|
||||
check_lighttpd = test_cmd.format(
|
||||
"r", "/etc/lighttpd/conf-available/15-pihole-admin.conf", piholeuser
|
||||
)
|
||||
actual_rc = host.run(check_lighttpd).rc
|
||||
assert exit_status_success == actual_rc
|
||||
# check readable and executable manpages
|
||||
if maninstalled is True:
|
||||
check_man = test_cmd.format("x", "/usr/local/share/man", piholeuser)
|
||||
@@ -396,7 +398,7 @@ def test_installPihole_fresh_install_readableBlockpage(host, test_webpage):
|
||||
usergroup="${{LIGHTTPD_USER}}:${{LIGHTTPD_GROUP}}",
|
||||
chmodarg="{{}}",
|
||||
config="/etc/lighttpd/lighttpd.conf",
|
||||
run="/var/run/lighttpd",
|
||||
run="/run/lighttpd",
|
||||
cache="/var/cache/lighttpd",
|
||||
uploads="/var/cache/lighttpd/uploads",
|
||||
compress="/var/cache/lighttpd/compress",
|
||||
@@ -512,7 +514,7 @@ def test_installPihole_fresh_install_readableBlockpage(host, test_webpage):
|
||||
check_admin = test_cmd.format("x", webroot + "/admin", webuser)
|
||||
actual_rc = host.run(check_admin).rc
|
||||
assert exit_status_success == actual_rc
|
||||
directories = get_directories_recursive(host, webroot + "/admin/*/")
|
||||
directories = get_directories_recursive(host, webroot + "/admin/")
|
||||
for directory in directories:
|
||||
check_pihole = test_cmd.format("r", directory, webuser)
|
||||
actual_rc = host.run(check_pihole).rc
|
||||
@@ -536,16 +538,6 @@ def test_installPihole_fresh_install_readableBlockpage(host, test_webpage):
|
||||
return bool(m)
|
||||
|
||||
if installWebInterface is True:
|
||||
check_pihole = test_cmd.format("r", webroot + "/pihole", webuser)
|
||||
actual_rc = host.run(check_pihole).rc
|
||||
assert exit_status_success == actual_rc
|
||||
check_pihole = test_cmd.format("x", webroot + "/pihole", webuser)
|
||||
actual_rc = host.run(check_pihole).rc
|
||||
assert exit_status_success == actual_rc
|
||||
# check most important files in $webroot for read permission
|
||||
check_index = test_cmd.format("r", webroot + "/pihole/index.php", webuser)
|
||||
actual_rc = host.run(check_index).rc
|
||||
assert exit_status_success == actual_rc
|
||||
if test_webpage is True:
|
||||
# check webpage for unreadable files
|
||||
noPHPfopen = re.compile(
|
||||
@@ -619,10 +611,15 @@ def test_FTL_detect_aarch64_no_errors(host):
|
||||
"""
|
||||
# mock uname to return aarch64 platform
|
||||
mock_command("uname", {"-m": ("aarch64", "0")}, host)
|
||||
# mock `which sh` to return `/bin/sh`
|
||||
mock_command("which", {"sh": ("/bin/sh", "0")}, host)
|
||||
# mock ldd to respond with aarch64 shared library
|
||||
mock_command("ldd", {"/bin/sh": ("/lib/ld-linux-aarch64.so.1", "0")}, host)
|
||||
mock_command(
|
||||
"ldd",
|
||||
{
|
||||
"/bin/sh": ("/lib/ld-linux-aarch64.so.1", "0"),
|
||||
"/usr/bin/sh": ("/lib/ld-linux-aarch64.so.1", "0"),
|
||||
},
|
||||
host,
|
||||
)
|
||||
detectPlatform = host.run(
|
||||
"""
|
||||
source /opt/pihole/basic-install.sh
|
||||
@@ -647,10 +644,15 @@ def test_FTL_detect_armv4t_no_errors(host):
|
||||
"""
|
||||
# mock uname to return armv4t platform
|
||||
mock_command("uname", {"-m": ("armv4t", "0")}, host)
|
||||
# mock `which sh` to return `/bin/sh`
|
||||
mock_command("which", {"sh": ("/bin/sh", "0")}, host)
|
||||
# mock ldd to respond with armv4t shared library
|
||||
mock_command("ldd", {"/bin/sh": ("/lib/ld-linux.so.3", "0")}, host)
|
||||
mock_command(
|
||||
"ldd",
|
||||
{
|
||||
"/bin/sh": ("/lib/ld-linux.so.3", "0"),
|
||||
"/usr/bin/sh": ("/lib/ld-linux.so.3", "0"),
|
||||
},
|
||||
host,
|
||||
)
|
||||
detectPlatform = host.run(
|
||||
"""
|
||||
source /opt/pihole/basic-install.sh
|
||||
@@ -675,10 +677,15 @@ def test_FTL_detect_armv5te_no_errors(host):
|
||||
"""
|
||||
# mock uname to return armv5te platform
|
||||
mock_command("uname", {"-m": ("armv5te", "0")}, host)
|
||||
# mock `which sh` to return `/bin/sh`
|
||||
mock_command("which", {"sh": ("/bin/sh", "0")}, host)
|
||||
# mock ldd to respond with ld-linux shared library
|
||||
mock_command("ldd", {"/bin/sh": ("/lib/ld-linux.so.3", "0")}, host)
|
||||
mock_command(
|
||||
"ldd",
|
||||
{
|
||||
"/bin/sh": ("/lib/ld-linux.so.3", "0"),
|
||||
"/usr/bin/sh": ("/lib/ld-linux.so.3", "0"),
|
||||
},
|
||||
host,
|
||||
)
|
||||
detectPlatform = host.run(
|
||||
"""
|
||||
source /opt/pihole/basic-install.sh
|
||||
@@ -704,9 +711,14 @@ def test_FTL_detect_armv6l_no_errors(host):
|
||||
# mock uname to return armv6l platform
|
||||
mock_command("uname", {"-m": ("armv6l", "0")}, host)
|
||||
# mock ldd to respond with ld-linux-armhf shared library
|
||||
# mock `which sh` to return `/bin/sh`
|
||||
mock_command("which", {"sh": ("/bin/sh", "0")}, host)
|
||||
mock_command("ldd", {"/bin/sh": ("/lib/ld-linux-armhf.so.3", "0")}, host)
|
||||
mock_command(
|
||||
"ldd",
|
||||
{
|
||||
"/bin/sh": ("/lib/ld-linux-armhf.so.3", "0"),
|
||||
"/usr/bin/sh": ("/lib/ld-linux-armhf.so.3", "0"),
|
||||
},
|
||||
host,
|
||||
)
|
||||
detectPlatform = host.run(
|
||||
"""
|
||||
source /opt/pihole/basic-install.sh
|
||||
@@ -734,9 +746,14 @@ def test_FTL_detect_armv7l_no_errors(host):
|
||||
# mock uname to return armv7l platform
|
||||
mock_command("uname", {"-m": ("armv7l", "0")}, host)
|
||||
# mock ldd to respond with ld-linux-armhf shared library
|
||||
# mock `which sh` to return `/bin/sh`
|
||||
mock_command("which", {"sh": ("/bin/sh", "0")}, host)
|
||||
mock_command("ldd", {"/bin/sh": ("/lib/ld-linux-armhf.so.3", "0")}, host)
|
||||
mock_command(
|
||||
"ldd",
|
||||
{
|
||||
"/bin/sh": ("/lib/ld-linux-armhf.so.3", "0"),
|
||||
"/usr/bin/sh": ("/lib/ld-linux-armhf.so.3", "0"),
|
||||
},
|
||||
host,
|
||||
)
|
||||
detectPlatform = host.run(
|
||||
"""
|
||||
source /opt/pihole/basic-install.sh
|
||||
@@ -763,10 +780,15 @@ def test_FTL_detect_armv8a_no_errors(host):
|
||||
"""
|
||||
# mock uname to return armv8a platform
|
||||
mock_command("uname", {"-m": ("armv8a", "0")}, host)
|
||||
# mock `which sh` to return `/bin/sh`
|
||||
mock_command("which", {"sh": ("/bin/sh", "0")}, host)
|
||||
# mock ldd to respond with ld-linux-armhf shared library
|
||||
mock_command("ldd", {"/bin/sh": ("/lib/ld-linux-armhf.so.3", "0")}, host)
|
||||
mock_command(
|
||||
"ldd",
|
||||
{
|
||||
"/bin/sh": ("/lib/ld-linux-armhf.so.3", "0"),
|
||||
"/usr/bin/sh": ("/lib/ld-linux-armhf.so.3", "0"),
|
||||
},
|
||||
host,
|
||||
)
|
||||
detectPlatform = host.run(
|
||||
"""
|
||||
source /opt/pihole/basic-install.sh
|
||||
@@ -789,8 +811,6 @@ def test_FTL_detect_x86_64_no_errors(host):
|
||||
"""
|
||||
confirms only x86_64 package is downloaded for FTL engine
|
||||
"""
|
||||
# mock `which sh` to return `/bin/sh`
|
||||
mock_command("which", {"sh": ("/bin/sh", "0")}, host)
|
||||
detectPlatform = host.run(
|
||||
"""
|
||||
source /opt/pihole/basic-install.sh
|
||||
@@ -813,8 +833,6 @@ def test_FTL_detect_unknown_no_errors(host):
|
||||
"""confirms only generic package is downloaded for FTL engine"""
|
||||
# mock uname to return generic platform
|
||||
mock_command("uname", {"-m": ("mips", "0")}, host)
|
||||
# mock `which sh` to return `/bin/sh`
|
||||
mock_command("which", {"sh": ("/bin/sh", "0")}, host)
|
||||
detectPlatform = host.run(
|
||||
"""
|
||||
source /opt/pihole/basic-install.sh
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
[tox]
|
||||
envlist = py3
|
||||
|
||||
[testenv]
|
||||
[testenv:py3]
|
||||
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
|
||||
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
|
||||
|
||||
8
test/tox.centos_9.ini
Normal file
8
test/tox.centos_9.ini
Normal file
@@ -0,0 +1,8 @@
|
||||
[tox]
|
||||
envlist = py3
|
||||
|
||||
[testenv:py3]
|
||||
allowlist_externals = docker
|
||||
deps = -rrequirements.txt
|
||||
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
|
||||
@@ -1,7 +1,7 @@
|
||||
[tox]
|
||||
envlist = py3
|
||||
|
||||
[testenv]
|
||||
[testenv:py3]
|
||||
allowlist_externals = docker
|
||||
deps = -rrequirements.txt
|
||||
commands = docker build -f _debian_10.Dockerfile -t pytest_pihole:test_container ../
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
[tox]
|
||||
envlist = py3
|
||||
|
||||
[testenv]
|
||||
[testenv:py3]
|
||||
allowlist_externals = docker
|
||||
deps = -rrequirements.txt
|
||||
commands = docker build -f _debian_11.Dockerfile -t pytest_pihole:test_container ../
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
[tox]
|
||||
envlist = py3
|
||||
|
||||
[testenv]
|
||||
[testenv:py3]
|
||||
allowlist_externals = docker
|
||||
deps = -rrequirements.txt
|
||||
commands = docker build -f _fedora_36.Dockerfile -t pytest_pihole:test_container ../
|
||||
|
||||
@@ -4,5 +4,5 @@ envlist = py3
|
||||
[testenv]
|
||||
allowlist_externals = docker
|
||||
deps = -rrequirements.txt
|
||||
commands = docker build -f _fedora_35.Dockerfile -t pytest_pihole:test_container ../
|
||||
commands = docker build -f _fedora_37.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
|
||||
@@ -1,7 +1,7 @@
|
||||
[tox]
|
||||
envlist = py3
|
||||
|
||||
[testenv]
|
||||
[testenv:py3]
|
||||
allowlist_externals = docker
|
||||
deps = -rrequirements.txt
|
||||
commands = docker build -f _ubuntu_20.Dockerfile -t pytest_pihole:test_container ../
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
[tox]
|
||||
envlist = py3
|
||||
|
||||
[testenv]
|
||||
[testenv:py3]
|
||||
allowlist_externals = docker
|
||||
deps = -rrequirements.txt
|
||||
commands = docker build -f _ubuntu_22.Dockerfile -t pytest_pihole:test_container ../
|
||||
|
||||
Reference in New Issue
Block a user