Compare commits

...

62 Commits

Author SHA1 Message Date
Adam Warner
0f7803b775 Pi-hole Core v6.0.6 (#6118) 2025-03-30 17:54:55 +01:00
yubiuser
73074f1557 Bump tox from 4.24.2 to 4.25.0 in /test (#6116) 2025-03-29 21:46:47 +01:00
yubiuser
bc23303788 Bump actions/setup-python from 5.4.0 to 5.5.0 (#6117) 2025-03-29 21:43:58 +01:00
dependabot[bot]
49fbdc4c00 Bump actions/setup-python from 5.4.0 to 5.5.0
Bumps [actions/setup-python](https://github.com/actions/setup-python) from 5.4.0 to 5.5.0.
- [Release notes](https://github.com/actions/setup-python/releases)
- [Commits](https://github.com/actions/setup-python/compare/v5.4.0...v5.5.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-03-29 10:25:36 +00:00
dependabot[bot]
315528d740 Bump tox from 4.24.2 to 4.25.0 in /test
Bumps [tox](https://github.com/tox-dev/tox) from 4.24.2 to 4.25.0.
- [Release notes](https://github.com/tox-dev/tox/releases)
- [Changelog](https://github.com/tox-dev/tox/blob/main/docs/changelog.rst)
- [Commits](https://github.com/tox-dev/tox/compare/4.24.2...4.25.0)

---
updated-dependencies:
- dependency-name: tox
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-03-29 10:25:08 +00:00
Adam Warner
e5cb0efd61 revert #6030 in preparation for docker-pi-hole #1794 (#6086) 2025-03-25 17:06:01 +00:00
Michael Woolweaver
3a592471c6 revert pi-hole/pi-hole/pull/6030
in preparation for pi-hole/docker-pi-hole/pull/1786

Signed-off-by: Michael Woolweaver <michael@woolweaver.bid>
2025-03-14 14:32:29 -05:00
yubiuser
3f5c00919b Remove WEB_CALL from COL_TABLE (#6062) 2025-03-10 06:14:47 +01:00
yubiuser
349544b24a Create webserver.log on FTL startup (#6051) 2025-03-10 06:14:22 +01:00
yubiuser
387ec3a3c2 Bump pytest from 8.3.4 to 8.3.5 in /test (#6068) 2025-03-08 11:50:40 +01:00
dependabot[bot]
6b873b2d7f Bump pytest from 8.3.4 to 8.3.5 in /test
Bumps [pytest](https://github.com/pytest-dev/pytest) from 8.3.4 to 8.3.5.
- [Release notes](https://github.com/pytest-dev/pytest/releases)
- [Changelog](https://github.com/pytest-dev/pytest/blob/main/CHANGELOG.rst)
- [Commits](https://github.com/pytest-dev/pytest/compare/8.3.4...8.3.5)

---
updated-dependencies:
- dependency-name: pytest
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-03-08 10:46:01 +00:00
yubiuser
46e5b3b02e Bump tox from 4.24.1 to 4.24.2 in /test (#6067) 2025-03-08 11:44:54 +01:00
dependabot[bot]
27aeed76f0 Bump tox from 4.24.1 to 4.24.2 in /test
Bumps [tox](https://github.com/tox-dev/tox) from 4.24.1 to 4.24.2.
- [Release notes](https://github.com/tox-dev/tox/releases)
- [Changelog](https://github.com/tox-dev/tox/blob/main/docs/changelog.rst)
- [Commits](https://github.com/tox-dev/tox/compare/4.24.1...4.24.2)

---
updated-dependencies:
- dependency-name: tox
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-03-08 10:30:22 +00:00
yubiuser
80d63eca93 Add 2FA handling to api.sh (#6065) 2025-03-08 10:46:54 +01:00
yubiuser
72404c983d Add trailing / when changing ownership of /etc/pihole (#6057) 2025-03-07 23:08:04 +01:00
casperklein
9b4502a7a9 Add trailing / to directories
Signed-off-by: casperklein <casperklein@users.noreply.github.com>
2025-03-07 23:00:40 +01:00
Christian König
5de9b6ae69 Add 2FA handling to api.sh
Signed-off-by: Christian König <github@yubiuser.dev>
2025-03-07 13:43:41 +01:00
Christian König
f3dc202e36 Remove WEB_CALL from COL_TABLE
Signed-off-by: Christian König <github@yubiuser.dev>
2025-03-07 10:16:25 +01:00
yubiuser
9050e47049 version.sh: fix typo in comment (#6056) 2025-03-06 20:49:20 +01:00
XhmikosR
45cb722e50 version.sh: fix typo in comment
Signed-off-by: XhmikosR <xhmikosr@gmail.com>
2025-03-06 21:40:17 +02:00
yubiuser
98b17edfd7 README.md: switch to the SVG logo (#6052) 2025-03-06 14:27:58 +01:00
XhmikosR
d094b197e3 README.md: switch to the SVG logo
Signed-off-by: XhmikosR <xhmikosr@gmail.com>
2025-03-06 15:06:34 +02:00
Christian König
e437e3a805 Create webserver.log on FTL startup
Signed-off-by: Christian König <github@yubiuser.dev>
2025-03-06 09:48:06 +01:00
Adam Warner
411b9fcb6d Sync master back into development (#6046) 2025-03-04 19:46:03 +00:00
Adam Warner
9fe687bd62 Pi-hole Core v6.0.5 (#6042) 2025-03-04 17:21:05 +00:00
Adam Warner
edf336067a Fix gravity.sh -- Alpine / Docker specific issue (#6030) 2025-03-03 17:44:45 +00:00
Adam Warner
196a84721f Fix find command syntax, remove log dir from search (#6035) 2025-03-03 17:40:12 +00:00
Adam Warner
978694f262 Improve update/fresh install detection (#6034) 2025-03-03 12:23:29 +00:00
Dominik
7eef780fbc Revert "Improve gravity on systems with low memory" (#6039) 2025-03-03 11:01:45 +01:00
Dominik
df814ece91 Revert "Improve gravity on systems with low memory" 2025-03-03 09:00:17 +01:00
Karol Kania
9c7e02f213 Update gravity.sh
remove the left-over commented debug code 

Signed-off-by: Karol Kania <44871508+karolkania@users.noreply.github.com>
2025-03-02 12:05:42 +01:00
Jack'lul
0130f7be74 Fix find command syntax, remove log dir from search
Signed-off-by: Jack'lul <8418678+jacklul@users.noreply.github.com>
2025-03-01 14:43:36 +01:00
Dan Schaper
f207385269 Removing kernel check based on discussion in Pi-Hole PR pi-hole#5957. (#6020) 2025-02-28 20:00:00 -08:00
Adam Warner
ce73691082 Juggle some code around:
- Move random password generation block inside final "fresh install" if block, ensure password is ONLY generated on fresh installs.
 - Add additional check for fresh install around setting of PIHOLE_DNS1/2, QUERY_LOGGING, and PRIVACY_LEVEL
 - Remove dedicated displayFinalMessage function.

Signed-off-by: Adam Warner <me@adamwarner.co.uk>
2025-02-28 23:06:52 +00:00
Adam Warner
8874757958 Start by renaming useUpdateVars to fresh_install and flipping the logic, the old name is not relevant any more
Signed-off-by: Adam Warner <me@adamwarner.co.uk>
2025-02-28 21:29:33 +00:00
Adam Warner
821c953216 Remove 'reconfigure' option (#5887) 2025-02-28 21:14:18 +00:00
Dominik
53e241f057 Improve gravity on systems with low memory (#5977) 2025-02-28 17:02:56 +01:00
Karol Kania
a9650ae287 Update gravity.sh
fix the `if statement` that doesn't seem to work for neither of alpine's ash / bash - applying some workaround with the `stat` command

Signed-off-by: Karol Kania <44871508+karolkania@users.noreply.github.com>
2025-02-28 12:52:07 +01:00
Christian König
7282aada25 Don't show a warning before the repair is done
Signed-off-by: Christian König <github@yubiuser.dev>
2025-02-28 11:51:09 +01:00
Dominik
c5d66c2162 Do not overwrite TLS cert/key mode (#5998) 2025-02-27 19:45:32 +01:00
UltChowsk
869411a514 Fixing whitespaces after removing lines.
Signed-off-by: UltChowsk <ult@chowsk.net>
2025-02-27 06:24:13 -05:00
UltChowsk
d1b5f95aa7 Removing kernel check based on discussion in Pi-Hole PR pi-hole#5957.
Signed-off-by: UltChowsk <ult@chowsk.net>
2025-02-26 20:37:20 -05:00
MichaIng
ad6a48b219 Add comment about TLS-related file permissions
Co-authored-by: Dominik <DL6ER@users.noreply.github.com>
Signed-off-by: MichaIng <micha@dietpi.com>
2025-02-26 20:59:32 +01:00
MichaIng
83a38bb71d Add comment about file permissions
Co-authored-by: Dominik <DL6ER@users.noreply.github.com>
Signed-off-by: MichaIng <micha@dietpi.com>
2025-02-26 12:26:50 +01:00
MichaIng
232d581916 Re-add comment about execute bit on directory
Co-authored-by: Dominik <DL6ER@users.noreply.github.com>
Signed-off-by: MichaIng <micha@dietpi.com>
2025-02-26 12:25:51 +01:00
Dan Schaper
002536ae09 Do not hide error messages when dealing with services (#5983) 2025-02-25 12:30:39 -08:00
yubiuser
8a788ad755 Update README.md - Fix Text+URL for allowlisting/denylisting (#5993) 2025-02-25 20:57:57 +01:00
MichaIng
0b380d671d Follow symlinks with find
Incorporating https://github.com/pi-hole/pi-hole/pull/5997

Signed-off-by: MichaIng <micha@dietpi.com>
2025-02-24 17:37:01 +01:00
MichaIng
65bcb24d0e Fix test
Do not check whether the pihole user can read /etc/pihole/logrotate. It needs to be readable by root only, which is always true.

Signed-off-by: MichaIng <micha@dietpi.com>
2025-02-24 17:29:59 +01:00
MichaIng
e70981d80f Do not overwrite TLS cert/key mode
FTL correctly creates the cert and especially private key with 0600 mode. But the prestart scripts changes it to 0660.

After removing the dedicated webserver from Pi-hole setups, the pihole group has no purpose anymore, and files should not be writable to any other user than pihole itself, and the private TLS key not reasable to anyone else either.

Additionally, this commit consolidates the chmod calls, applying 0755 to all directories and 0640 to all files, but the TLS key and cert.

Signed-off-by: MichaIng <micha@dietpi.com>
2025-02-24 17:29:58 +01:00
yubiuser
9840b42847 Add missing trailing / when setting permissions of /etc/pihole (#5997) 2025-02-24 17:24:10 +01:00
Christian König
b59ab5852a Add missing trailing / when setting permissions of /etc/pihole
Signed-off-by: Christian König <github@yubiuser.dev>
2025-02-24 15:59:11 +01:00
Jeroen Habets
a0541dd7fb Update README.md
Fix Text+URL for allowlisting/denylisting. Keep former terms for when people search for them.

Signed-off-by: Jeroen Habets <jeroenhabets@users.noreply.github.com>
2025-02-24 10:45:17 +01:00
Dominik
48c4efd7b0 Improve dig error handlin in api.sh (#5965) 2025-02-23 20:15:31 +01:00
MichaIng
729a44f82a Do not hide error messages when dealing with services
If service start/stop/restart/enable/disable fails, it help to debug the issue, if STDERR is not hidden, hence the error message can be seen. systemctl furthermore has the `-q` option to suppress non-error output. It works as well for "is-enabled", but until a certain systemd version still throws an error, if the checked service does not exist at all. Once Debian Bullseye support is dropped by Pi-hole, also STDERR form systemctl is-enabled does not need to be suppressed anymore.

Signed-off-by: MichaIng <micha@dietpi.com>
2025-02-23 15:48:32 +01:00
Dominik
9c995962a5 If there are no files to change, don't print an error (#5953) 2025-02-23 09:04:16 +01:00
DL6ER
5da5d0d4c1 Use temp_store = FILE to avoid memory exhaustion on build the tree for very large databases
Signed-off-by: DL6ER <dl6er@dl6er.de>
2025-02-23 08:50:08 +01:00
Adam Warner
a7e414aca4 Sync master back into development (#5976) 2025-02-22 23:17:53 +00:00
Christian König
cadee26dba Improve dig error handlin in api.sh
Signed-off-by: Christian König <github@yubiuser.dev>
2025-02-22 13:48:55 +01:00
Christian König
cd269cbca1 If there are no files to change, don't print an error
Signed-off-by: Christian König <github@yubiuser.dev>
2025-02-21 22:02:03 +01:00
Christian König
dfc2b32248 Use better function name
Signed-off-by: Christian König <github@yubiuser.dev>
2025-02-06 21:57:17 +01:00
Christian König
49cf5bb221 Remove 'reconfigure' option
Signed-off-by: Christian König <github@yubiuser.dev>
2025-02-06 21:57:05 +01:00
13 changed files with 170 additions and 223 deletions

View File

@@ -77,7 +77,7 @@ jobs:
uses: actions/checkout@v4.2.2
- name: Set up Python 3.10
uses: actions/setup-python@v5.4.0
uses: actions/setup-python@v5.5.0
with:
python-version: "3.10"

View File

@@ -3,13 +3,9 @@
#
<p align="center">
<picture>
<source media="(prefers-color-scheme: dark)" srcset="https://pi-hole.github.io/graphics/Vortex/Vortex_Vertical_wordmark_darkmode.png">
<source media="(prefers-color-scheme: light)" srcset="https://pi-hole.github.io/graphics/Vortex/Vortex_Vertical_wordmark_lightmode.png">
<img src="https://pi-hole.github.io/graphics/Vortex/Vortex_Vertical_wordmark_lightmode.png" width="168" height="270" alt="Pi-hole website">
</picture>
<br>
<strong>Network-wide ad blocking via your own Linux hardware</strong>
<img src="https://raw.githubusercontent.com/pi-hole/graphics/refs/heads/master/Vortex/vortex_with_text.svg" alt="Pi-hole website" width="168" height="270">
<br>
<strong>Network-wide ad blocking via your own Linux hardware</strong>
</p>
<!-- markdownlint-enable MD033 -->
@@ -140,7 +136,7 @@ The [pihole](https://docs.pi-hole.net/core/pihole-command/) command has all the
Some notable features include:
- [Whitelisting, Blacklisting, and Regex](https://docs.pi-hole.net/core/pihole-command/#whitelisting-blacklisting-and-regex)
- [Allowlisting, Denylisting (fka Whitelisting, Blacklisting), and Regex](https://docs.pi-hole.net/core/pihole-command/#allowlisting-denylisting-and-regex)
- [Debugging utility](https://docs.pi-hole.net/core/pihole-command/#debugger)
- [Viewing the live log file](https://docs.pi-hole.net/core/pihole-command/#tail)
- [Updating Ad Lists](https://docs.pi-hole.net/core/pihole-command/#gravity)

View File

@@ -1,5 +1,6 @@
#!/usr/bin/env sh
# Determine if terminal is capable of showing colors
if ([ -t 1 ] && [ $(tput colors) -ge 8 ]) || [ "${WEBCALL}" ]; then
if [ -t 1 ] && [ "$(tput colors)" -ge 8 ]; then
# Bold and underline may not show up on all clients
# If something MUST be emphasized, use both
COL_BOLD=''

View File

@@ -21,7 +21,7 @@
TestAPIAvailability() {
# as we are running locally, we can get the port value from FTL directly
local chaos_api_list availabilityResponse
local chaos_api_list authResponse authStatus authData
# Query the API URLs from FTL using CHAOS TXT local.api.ftl
# The result is a space-separated enumeration of full URLs
@@ -34,6 +34,12 @@ TestAPIAvailability() {
exit 1
fi
# If an error occurred, the variable starts with ;;
if [ "${chaos_api_list#;;}" != "${chaos_api_list}" ]; then
echo "Communication error. Is FTL running?"
exit 1
fi
# Iterate over space-separated list of URLs
while [ -n "${chaos_api_list}" ]; do
# Get the first URL
@@ -43,20 +49,29 @@ TestAPIAvailability() {
API_URL="${API_URL#\"}"
# Test if the API is available at this URL
availabilityResponse=$(curl -skS -o /dev/null -w "%{http_code}" "${API_URL}auth")
authResponse=$(curl --connect-timeout 2 -skS -w "%{http_code}" "${API_URL}auth")
# authStatus are the last 3 characters
# not using ${authResponse#"${authResponse%???}"}" here because it's extremely slow on big responses
authStatus=$(printf "%s" "${authResponse}" | tail -c 3)
# data is everything from response without the last 3 characters
authData=$(printf %s "${authResponse%???}")
# Test if http status code was 200 (OK) or 401 (authentication required)
if [ ! "${availabilityResponse}" = 200 ] && [ ! "${availabilityResponse}" = 401 ]; then
if [ ! "${authStatus}" = 200 ] && [ ! "${authStatus}" = 401 ]; then
# API is not available at this port/protocol combination
API_PORT=""
else
# API is available at this URL combination
if [ "${availabilityResponse}" = 200 ]; then
if [ "${authStatus}" = 200 ]; then
# API is available without authentication
needAuth=false
fi
# Check if 2FA is required
needTOTP=$(echo "${authData}"| jq --raw-output .session.totp 2>/dev/null)
break
fi
@@ -102,22 +117,51 @@ LoginAPI() {
echo "API Authentication: Trying to use CLI password"
fi
# Try to authenticate using the CLI password
Authentication "${1}"
# If we can read the CLI password, we can skip 2FA even when it's required otherwise
needTOTP=false
elif [ "${1}" = "verbose" ]; then
echo "API Authentication: CLI password not available"
fi
if [ -z "${password}" ]; then
# no password read from CLI file
echo "Please enter your password:"
# secretly read the password
secretRead; printf '\n'
fi
if [ "${needTOTP}" = true ]; then
# 2FA required
echo "Please enter the correct second factor."
echo "(Can be any number if you used the app password)"
read -r totp
fi
# If this did not work, ask the user for the password
while [ "${validSession}" = false ] || [ -z "${validSession}" ] ; do
# Try to authenticate using the supplied password (CLI file or user input) and TOTP
Authentication "${1}"
# Try to login again until the session is valid
while [ ! "${validSession}" = true ] ; do
echo "Authentication failed. Please enter your Pi-hole password"
# Print the error message if there is one
if [ ! "${sessionError}" = "null" ] && [ "${1}" = "verbose" ]; then
echo "Error: ${sessionError}"
fi
# Print the session message if there is one
if [ ! "${sessionMessage}" = "null" ] && [ "${1}" = "verbose" ]; then
echo "Error: ${sessionMessage}"
fi
# secretly read the password
secretRead; printf '\n'
if [ "${needTOTP}" = true ]; then
echo "Please enter the correct second factor:"
echo "(Can be any number if you used the app password)"
read -r totp
fi
# Try to authenticate again
Authentication "${1}"
done
@@ -125,23 +169,27 @@ LoginAPI() {
}
Authentication() {
sessionResponse="$(curl -skS -X POST "${API_URL}auth" --user-agent "Pi-hole cli " --data "{\"password\":\"${password}\"}" )"
sessionResponse="$(curl --connect-timeout 2 -skS -X POST "${API_URL}auth" --user-agent "Pi-hole cli" --data "{\"password\":\"${password}\", \"totp\":${totp:-null}}" )"
if [ -z "${sessionResponse}" ]; then
echo "No response from FTL server. Please check connectivity"
exit 1
fi
# obtain validity and session ID from session response
validSession=$(echo "${sessionResponse}"| jq .session.valid 2>/dev/null)
SID=$(echo "${sessionResponse}"| jq --raw-output .session.sid 2>/dev/null)
if [ "${1}" = "verbose" ]; then
if [ "${validSession}" = true ]; then
echo "API Authentication: ${COL_GREEN}Success${COL_NC}"
else
echo "API Authentication: ${COL_RED}Failed${COL_NC}"
if [ -z "${sessionResponse}" ]; then
echo "No response from FTL server. Please check connectivity"
exit 1
fi
# obtain validity, session ID and sessionMessage from session response
validSession=$(echo "${sessionResponse}"| jq .session.valid 2>/dev/null)
SID=$(echo "${sessionResponse}"| jq --raw-output .session.sid 2>/dev/null)
sessionMessage=$(echo "${sessionResponse}"| jq --raw-output .session.message 2>/dev/null)
# obtain the error message from the session response
sessionError=$(echo "${sessionResponse}"| jq --raw-output .error.message 2>/dev/null)
if [ "${1}" = "verbose" ]; then
if [ "${validSession}" = true ]; then
echo "API Authentication: ${COL_GREEN}Success${COL_NC}"
else
echo "API Authentication: ${COL_RED}Failed${COL_NC}"
fi
fi
fi
}
LogoutAPI() {

View File

@@ -218,7 +218,7 @@ main() {
fi
if [[ "${FTL_update}" == true || "${core_update}" == true ]]; then
${PI_HOLE_FILES_DIR}/automated\ install/basic-install.sh --reconfigure --unattended || \
${PI_HOLE_FILES_DIR}/automated\ install/basic-install.sh --repair --unattended || \
echo -e "${basicError}" && exit 1
fi

View File

@@ -12,7 +12,7 @@
# shellcheck disable=SC3043
# https://github.com/koalaman/shellcheck/wiki/SC3043#exceptions
# Source the versions file poupulated by updatechecker.sh
# Source the versions file populated by updatechecker.sh
cachedVersions="/etc/pihole/versions"
if [ -f ${cachedVersions} ]; then

View File

@@ -10,25 +10,21 @@ utilsfile="${PI_HOLE_SCRIPT_DIR}/utils.sh"
FTL_PID_FILE="$(getFTLConfigValue files.pid)"
# Ensure that permissions are set so that pihole-FTL can edit all necessary files
# shellcheck disable=SC2174
mkdir -pm 0640 /var/log/pihole
chown -R pihole:pihole /etc/pihole /var/log/pihole
chmod -R 0640 /var/log/pihole
chmod -R 0660 /etc/pihole
# Logrotate config file need to be owned by root and must not be writable by group and others
chown root:root /etc/pihole/logrotate
chmod 0644 /etc/pihole/logrotate
# allow all users to enter the directories
chmod 0755 /etc/pihole /var/log/pihole
mkdir -p /var/log/pihole
chown -R pihole:pihole /etc/pihole/ /var/log/pihole/
# allow pihole to access subdirs in /etc/pihole (sets execution bit on dirs)
# credits https://stackoverflow.com/a/11512211
find /etc/pihole -type d -exec chmod 0755 {} \;
find /etc/pihole/ /var/log/pihole/ -type d -exec chmod 0755 {} +
# Set all files (except TLS-related ones) to u+rw g+r
find /etc/pihole/ /var/log/pihole/ -type f ! \( -name '*.pem' -o -name '*.crt' \) -exec chmod 0640 {} +
# Set TLS-related files to a more restrictive u+rw *only* (they may contain private keys)
find /etc/pihole/ -type f \( -name '*.pem' -o -name '*.crt' \) -exec chmod 0600 {} +
# Logrotate config file need to be owned by root
chown root:root /etc/pihole/logrotate
# Touch files to ensure they exist (create if non-existing, preserve if existing)
[ -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 640 -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 /var/log/pihole/webserver.log ] || install -m 640 -o pihole -g pihole /dev/null /var/log/pihole/webserver.log
[ -f /etc/pihole/dhcp.leases ] || install -m 644 -o pihole -g pihole /dev/null /etc/pihole/dhcp.leases

View File

@@ -7,7 +7,7 @@ _pihole() {
case "${prev}" in
"pihole")
opts="allow allow-regex allow-wild deny checkout debug disable enable flush help logging query reconfigure regex reloaddns reloadlists status tail uninstall updateGravity updatePihole version wildcard arpflush api"
opts="allow allow-regex allow-wild deny checkout debug disable enable flush help logging query repair regex reloaddns reloadlists status tail uninstall updateGravity updatePihole version wildcard arpflush api"
COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
;;
"allow"|"deny"|"wildcard"|"regex"|"allow-regex"|"allow-wild")

View File

@@ -81,9 +81,7 @@ PI_HOLE_INSTALL_DIR="/opt/pihole"
PI_HOLE_CONFIG_DIR="/etc/pihole"
PI_HOLE_BIN_DIR="/usr/local/bin"
PI_HOLE_V6_CONFIG="${PI_HOLE_CONFIG_DIR}/pihole.toml"
if [ -z "$useUpdateVars" ]; then
useUpdateVars=false
fi
fresh_install=true
adlistFile="/etc/pihole/adlists.list"
# Pi-hole needs an IP address; to begin, these variables are empty since we don't know what the IP is until this script can run
@@ -91,9 +89,7 @@ IPV4_ADDRESS=${IPV4_ADDRESS}
IPV6_ADDRESS=${IPV6_ADDRESS}
# Give settings their default values. These may be changed by prompts later in the script.
QUERY_LOGGING=
WEBPORT=
PRIVACY_LEVEL=
v5_to_v6_update=false
# Where old configs go to if a v6 migration is performed
V6_CONF_MIGRATION_DIR="/etc/pihole/migration_backup_v6"
@@ -143,12 +139,12 @@ EOM
######## Undocumented Flags. Shhh ########
# These are undocumented flags; some of which we can use when repairing an installation
# The runUnattended flag is one example of this
reconfigure=false
repair=false
runUnattended=false
# Check arguments for the undocumented flags
for var in "$@"; do
case "$var" in
"--reconfigure") reconfigure=true ;;
"--repair") repair=true ;;
"--unattended") runUnattended=true ;;
esac
done
@@ -1112,7 +1108,7 @@ setPrivacyLevel() {
# A function to display a list of example blocklists for users to select
chooseBlocklists() {
# Back up any existing adlist file, on the off chance that it exists. Useful in case of a reconfigure.
# Back up any existing adlist file, on the off chance that it exists.
if [[ -f "${adlistFile}" ]]; then
mv "${adlistFile}" "${adlistFile}.old"
fi
@@ -1355,9 +1351,9 @@ stop_service() {
local str="Stopping ${1} service"
printf " %b %s..." "${INFO}" "${str}"
if is_command systemctl; then
systemctl stop "${1}" &>/dev/null || true
systemctl -q stop "${1}" || true
else
service "${1}" stop &>/dev/null || true
service "${1}" stop >/dev/null || true
fi
printf "%b %b %s...\\n" "${OVER}" "${TICK}" "${str}"
}
@@ -1370,10 +1366,10 @@ restart_service() {
# If systemctl exists,
if is_command systemctl; then
# use that to restart the service
systemctl restart "${1}" &>/dev/null
systemctl -q restart "${1}"
else
# Otherwise, fall back to the service command
service "${1}" restart &>/dev/null
service "${1}" restart >/dev/null
fi
printf "%b %b %s...\\n" "${OVER}" "${TICK}" "${str}"
}
@@ -1386,10 +1382,10 @@ enable_service() {
# If systemctl exists,
if is_command systemctl; then
# use that to enable the service
systemctl enable "${1}" &>/dev/null
systemctl -q enable "${1}"
else
# Otherwise, use update-rc.d to accomplish this
update-rc.d "${1}" defaults &>/dev/null
update-rc.d "${1}" defaults >/dev/null
fi
printf "%b %b %s...\\n" "${OVER}" "${TICK}" "${str}"
}
@@ -1402,10 +1398,10 @@ disable_service() {
# If systemctl exists,
if is_command systemctl; then
# use that to disable the service
systemctl disable "${1}" &>/dev/null
systemctl -q disable "${1}"
else
# Otherwise, use update-rc.d to accomplish this
update-rc.d "${1}" disable &>/dev/null
update-rc.d "${1}" disable >/dev/null
fi
printf "%b %b %s...\\n" "${OVER}" "${TICK}" "${str}"
}
@@ -1414,7 +1410,7 @@ check_service_active() {
# If systemctl exists,
if is_command systemctl; then
# use that to check the status of the service
systemctl is-enabled "${1}" &>/dev/null
systemctl -q is-enabled "${1}" 2>/dev/null
else
# Otherwise, fall back to service command
service "${1}" status &>/dev/null
@@ -1473,16 +1469,11 @@ notify_package_updates_available() {
# Store the list of packages in a variable
updatesToInstall=$(eval "${PKG_COUNT}")
if [[ -d "/lib/modules/$(uname -r)" ]]; then
if [[ "${updatesToInstall}" -eq 0 ]]; then
printf "%b %b %s... up to date!\\n\\n" "${OVER}" "${TICK}" "${str}"
else
printf "%b %b %s... %s updates available\\n" "${OVER}" "${TICK}" "${str}" "${updatesToInstall}"
printf " %b %bIt is recommended to update your OS after installing the Pi-hole!%b\\n\\n" "${INFO}" "${COL_LIGHT_GREEN}" "${COL_NC}"
fi
if [[ "${updatesToInstall}" -eq 0 ]]; then
printf "%b %b %s... up to date!\\n\\n" "${OVER}" "${TICK}" "${str}"
else
printf "%b %b %s\\n" "${OVER}" "${CROSS}" "${str}"
printf " Kernel update detected. If the install fails, please reboot and try again\\n"
printf "%b %b %s... %s updates available\\n" "${OVER}" "${TICK}" "${str}" "${updatesToInstall}"
printf " %b %bIt is recommended to update your OS after installing the Pi-hole!%b\\n\\n" "${INFO}" "${COL_LIGHT_GREEN}" "${COL_NC}"
fi
}
@@ -1757,83 +1748,6 @@ checkSelinux() {
fi
}
# Installation complete message with instructions for the user
displayFinalMessage() {
# TODO: COME BACK TO THIS, WHAT IS GOING ON?
# If the number of arguments is > 0,
if [[ "${#1}" -gt 0 ]]; then
# set the password to the first argument.
pwstring="$1"
elif [[ -n $(pihole-FTL --config webserver.api.pwhash) ]]; then
# Else if the password exists from previous setup, we'll load it later
pwstring="unchanged"
else
# Else, inform the user that there is no set password.
pwstring="NOT SET"
fi
# Store a message in a variable and display it
additional="View the web interface at http://pi.hole/admin:${WEBPORT} or http://${IPV4_ADDRESS%/*}:${WEBPORT}/admin\\n\\nYour Admin Webpage login password is ${pwstring}"
# Final completion message to user
dialog --no-shadow --keep-tite \
--title "Installation Complete!" \
--msgbox "Configure your devices to use the Pi-hole as their DNS server using:\
\\n\\nIPv4: ${IPV4_ADDRESS%/*}\
\\nIPv6: ${IPV6_ADDRESS:-"Not Configured"}\
\\nIf you have not done so already, the above IP should be set to static.\
\\n${additional}" "${r}" "${c}"
}
update_dialogs() {
# If pihole -r "reconfigure" option was selected,
if [[ "${reconfigure}" = true ]]; then
# set some variables that will be used
opt1a="Repair"
opt1b="This will retain existing settings"
strAdd="You will remain on the same version"
else
# Otherwise, set some variables with different values
opt1a="Update"
opt1b="This will retain existing settings."
strAdd="You will be updated to the latest version."
fi
opt2a="Reconfigure"
opt2b="Resets Pi-hole and allows re-selecting settings."
# Display the information to the user
UpdateCmd=$(dialog --no-shadow --keep-tite --output-fd 1 \
--cancel-label Exit \
--title "Existing Install Detected!" \
--menu "\\n\\nWe have detected an existing install.\
\\n\\nPlease choose from the following options:\
\\n($strAdd)" \
"${r}" "${c}" 2 \
"${opt1a}" "${opt1b}" \
"${opt2a}" "${opt2b}") || result=$?
case ${result} in
"${DIALOG_CANCEL}" | "${DIALOG_ESC}")
printf " %b Cancel was selected, exiting installer%b\\n" "${COL_LIGHT_RED}" "${COL_NC}"
exit 1
;;
esac
# Set the variable based on if the user chooses
case ${UpdateCmd} in
# repair, or
"${opt1a}")
printf " %b %s option selected\\n" "${INFO}" "${opt1a}"
useUpdateVars=true
;;
# reconfigure,
"${opt2a}")
printf " %b %s option selected\\n" "${INFO}" "${opt2a}"
useUpdateVars=false
;;
esac
}
check_download_exists() {
# Check if the download exists and we can reach the server
local status=$(curl --head --silent "https://ftl.pi-hole.net/${1}" | head -n 1)
@@ -1920,10 +1834,10 @@ checkout_pull_branch() {
return 0
}
clone_or_update_repos() {
# If the user wants to reconfigure,
if [[ "${reconfigure}" == true ]]; then
printf " %b Performing reconfiguration, skipping download of local repos\\n" "${INFO}"
clone_or_reset_repos() {
# If the user wants to repair/update,
if [[ "${repair}" == true ]]; then
printf " %b Resetting local repos\\n" "${INFO}"
# Reset the Core repo
resetRepo ${PI_HOLE_LOCAL_REPO} ||
{
@@ -1936,7 +1850,7 @@ clone_or_update_repos() {
printf " %b Unable to reset %s, exiting installer%b\\n" "${COL_LIGHT_RED}" "${webInterfaceDir}" "${COL_NC}"
exit 1
}
# Otherwise, a repair is happening
# Otherwise, a fresh installation is happening
else
# so get git files for Core
getGitFiles ${PI_HOLE_LOCAL_REPO} ${piholeGitUrl} ||
@@ -1999,7 +1913,7 @@ FTLinstall() {
curl -sSL "https://ftl.pi-hole.net/macvendor.db" -o "${PI_HOLE_CONFIG_DIR}/macvendor.db" || true
# Stop pihole-FTL service if available
stop_service pihole-FTL &>/dev/null
stop_service pihole-FTL >/dev/null
# Install the new version with the correct permissions
install -T -m 0755 "${binary}" /usr/bin/pihole-FTL
@@ -2339,8 +2253,6 @@ migrate_dnsmasq_configs() {
# Print a blank line for separation
printf "\\n"
v5_to_v6_update=true
}
# Check for availability of either the "service" or "systemctl" commands
@@ -2430,22 +2342,19 @@ main() {
exit 1
fi
# in case of an update (can be a v5 -> v6 or v6 -> v6 update)
# in case of an update (can be a v5 -> v6 or v6 -> v6 update) or repair
if [[ -f "${PI_HOLE_V6_CONFIG}" ]] || [[ -f "/etc/pihole/setupVars.conf" ]]; then
# retain settings
fresh_install=false
# if it's running unattended,
if [[ "${runUnattended}" == true ]]; then
printf " %b Performing unattended setup, no dialogs will be displayed\\n" "${INFO}"
# Use the setup variables
useUpdateVars=true
# also disable debconf-apt-progress dialogs
export DEBIAN_FRONTEND="noninteractive"
else
# If running attended, show the available options (repair/reconfigure)
update_dialogs
fi
fi
if [[ "${useUpdateVars}" == false ]]; then
if [[ "${fresh_install}" == true ]]; then
# Display welcome dialogs
welcomeDialogs
# Create directory for Pi-hole storage (/etc/pihole/)
@@ -2468,9 +2377,8 @@ main() {
# Setup adlist file if not exists
installDefaultBlocklists
fi
# Download or update the scripts by updating the appropriate git repos
clone_or_update_repos
# Download or reset the appropriate git repos depending on the 'repair' flag
clone_or_reset_repos
# Create the pihole user
create_pihole_user
@@ -2500,11 +2408,9 @@ main() {
# Copy the temp log file into final log location for storage
copy_to_install_log
# Migrate existing install to v6.0
migrate_dnsmasq_configs
# Check for and disable systemd-resolved-DNSStubListener before reloading resolved
# DNSStubListener needs to remain in place for installer to download needed files,
# so this change needs to be made after installation is complete,
@@ -2527,28 +2433,25 @@ main() {
restart_service pihole-FTL
# Add password to web UI if there is none
pw=""
# If this is a fresh installation and no password is set,
if [[ ${v5_to_v6_update} = false && -z $(getFTLConfigValue webserver.api.pwhash) ]]; then
# generate a random password
pw=$(tr -dc _A-Z-a-z-0-9 </dev/urandom | head -c 8)
pihole setpassword "${pw}"
fi
if [[ "${fresh_install}" == true ]]; then
# apply settings to pihole.toml
# needs to be done after FTL service has been started, otherwise pihole.toml does not exist
# set on fresh installations by setDNS() and setPrivacyLevel() and setLogging()
# apply settings to pihole.toml
# needs to be done after FTL service has been started, otherwise pihole.toml does not exist
# set on fresh installations by setDNS() and setPrivacyLevel() and setLogging()
if [ -n "${PIHOLE_DNS_1}" ]; then
local string="\"${PIHOLE_DNS_1}\""
[ -n "${PIHOLE_DNS_2}" ] && string+=", \"${PIHOLE_DNS_2}\""
setFTLConfigValue "dns.upstreams" "[ $string ]"
fi
if [ -n "${QUERY_LOGGING}" ]; then
setFTLConfigValue "dns.queryLogging" "${QUERY_LOGGING}"
fi
if [ -n "${PRIVACY_LEVEL}" ]; then
setFTLConfigValue "misc.privacylevel" "${PRIVACY_LEVEL}"
# Upstreams may be needed in order to run gravity.sh
if [ -n "${PIHOLE_DNS_1}" ]; then
local string="\"${PIHOLE_DNS_1}\""
[ -n "${PIHOLE_DNS_2}" ] && string+=", \"${PIHOLE_DNS_2}\""
setFTLConfigValue "dns.upstreams" "[ $string ]"
fi
if [ -n "${QUERY_LOGGING}" ]; then
setFTLConfigValue "dns.queryLogging" "${QUERY_LOGGING}"
fi
if [ -n "${PRIVACY_LEVEL}" ]; then
setFTLConfigValue "misc.privacylevel" "${PRIVACY_LEVEL}"
fi
fi
# Download and compile the aggregated block list
@@ -2557,28 +2460,35 @@ main() {
# Update local and remote versions via updatechecker
/opt/pihole/updatecheck.sh
# If there is a password
if ((${#pw} > 0)); then
# display the password
printf " %b Web Interface password: %b%s%b\\n" "${INFO}" "${COL_LIGHT_GREEN}" "${pw}" "${COL_NC}"
printf " %b This can be changed using 'pihole setpassword'\\n\\n" "${INFO}"
fi
if [[ "${fresh_install}" == true ]]; then
if [[ "${useUpdateVars}" == false ]]; then
# Get the Web interface port, return only the first port and strip all non-numeric characters
WEBPORT=$(getFTLConfigValue webserver.port|cut -d, -f1 | tr -cd '0-9')
# Display the completion dialog
displayFinalMessage "${pw}"
# If the Web interface was installed,
printf " %b View the web interface at http://pi.hole:${WEBPORT}/admin or http://%s/admin\\n\\n" "${INFO}" "${IPV4_ADDRESS%/*}:${WEBPORT}"
# If this is a fresh install, we will set a random password.
# Users can change this password after installation if they wish
pw=$(tr -dc _A-Z-a-z-0-9 </dev/urandom | head -c 8)
pihole setpassword "${pw}" > /dev/null
# Explain to the user how to use Pi-hole as their DNS server
printf " %b You may now configure your devices to use the Pi-hole as their DNS server\\n" "${INFO}"
printf "\\n %b You may now configure your devices to use the Pi-hole as their DNS server\\n" "${INFO}"
[[ -n "${IPV4_ADDRESS%/*}" ]] && printf " %b Pi-hole DNS (IPv4): %s\\n" "${INFO}" "${IPV4_ADDRESS%/*}"
[[ -n "${IPV6_ADDRESS}" ]] && printf " %b Pi-hole DNS (IPv6): %s\\n" "${INFO}" "${IPV6_ADDRESS}"
printf " %b If you have not done so already, the above IP should be set to static.\\n" "${INFO}"
printf " %b View the web interface at http://pi.hole:${WEBPORT}/admin or http://%s/admin\\n\\n" "${INFO}" "${IPV4_ADDRESS%/*}:${WEBPORT}"
printf " %b Web Interface password: %b%s%b\\n" "${INFO}" "${COL_LIGHT_GREEN}" "${pw}" "${COL_NC}"
printf " %b This can be changed using 'pihole setpassword'\\n\\n" "${INFO}"
# Final dialog message to the user
dialog --no-shadow --keep-tite \
--title "Installation Complete!" \
--msgbox "Configure your devices to use the Pi-hole as their DNS server using:\
\\n\\nIPv4: ${IPV4_ADDRESS%/*}\
\\nIPv6: ${IPV6_ADDRESS:-"Not Configured"}\
\\nIf you have not done so already, the above IP should be set to static.\
\\nView the web interface at http://pi.hole/admin:${WEBPORT} or http://${IPV4_ADDRESS%/*}:${WEBPORT}/admin\\n\\nYour Admin Webpage login password is ${pw}" "${r}" "${c}"
INSTALL_TYPE="Installation"
else
INSTALL_TYPE="Update"

View File

@@ -1082,7 +1082,7 @@ migrate_to_listsCache_dir() {
fi
# Update the list's paths in the corresponding .sha1 files to the new location
sed -i "s|${piholeDir}/|${listsCacheDir}/|g" "${listsCacheDir}"/*.sha1
sed -i "s|${piholeDir}/|${listsCacheDir}/|g" "${listsCacheDir}"/*.sha1 2>/dev/null
}
helpFunc() {

10
pihole
View File

@@ -107,11 +107,11 @@ updatePiholeFunc() {
fi
}
reconfigurePiholeFunc() {
repairPiholeFunc() {
if [ -n "${DOCKER_VERSION}" ]; then
unsupportedFunc
else
/etc/.pihole/automated\ install/basic-install.sh --reconfigure
/etc/.pihole/automated\ install/basic-install.sh --repair
exit 0;
fi
}
@@ -479,7 +479,7 @@ Debugging Options:
Add '-c' or '--check-database' to include a Pi-hole database integrity check
Add '-a' to automatically upload the log to tricorder.pi-hole.net
-f, flush Flush the Pi-hole log
-r, reconfigure Reconfigure or Repair Pi-hole subsystems
-r, repair Repair Pi-hole subsystems
-t, tail [arg] View the live output of the Pi-hole log.
Add an optional argument to filter the log
(regular expressions are supported)
@@ -536,7 +536,7 @@ case "${1}" in
"--allow-wild" | "allow-wild" ) need_root=0;;
"-f" | "flush" ) ;;
"-up" | "updatePihole" ) ;;
"-r" | "reconfigure" ) ;;
"-r" | "repair" ) ;;
"-l" | "logging" ) ;;
"uninstall" ) ;;
"enable" ) need_root=0;;
@@ -579,7 +579,7 @@ case "${1}" in
"-d" | "debug" ) debugFunc "$@";;
"-f" | "flush" ) flushFunc "$@";;
"-up" | "updatePihole" ) updatePiholeFunc "$@";;
"-r" | "reconfigure" ) reconfigurePiholeFunc;;
"-r" | "repair" ) repairPiholeFunc;;
"-g" | "updateGravity" ) updateGravityFunc "$@";;
"-l" | "logging" ) piholeLogging "$@";;
"uninstall" ) uninstallFunc;;

View File

@@ -1,6 +1,6 @@
pyyaml == 6.0.2
pytest == 8.3.4
pytest == 8.3.5
pytest-xdist == 3.6.1
pytest-testinfra == 10.1.1
tox == 4.24.1
tox == 4.25.0
pytest-clarity == 1.0.1

View File

@@ -89,10 +89,10 @@ def test_installPihole_fresh_install_readableFiles(host):
export DEBIAN_FRONTEND=noninteractive
umask 0027
runUnattended=true
useUpdateVars=true
fresh_install=false
source /opt/pihole/basic-install.sh > /dev/null
runUnattended=true
useUpdateVars=true
fresh_install=false
main
/opt/pihole/pihole-FTL-prestart.sh
"""
@@ -127,10 +127,6 @@ def test_installPihole_fresh_install_readableFiles(host):
check_localversion = test_cmd.format("r", "/etc/pihole/versions", piholeuser)
actual_rc = host.run(check_localversion).rc
assert exit_status_success == actual_rc
# readable logrotate
check_logrotate = test_cmd.format("r", "/etc/pihole/logrotate", piholeuser)
actual_rc = host.run(check_logrotate).rc
assert exit_status_success == actual_rc
# readable macvendor.db
check_macvendor = test_cmd.format("r", "/etc/pihole/macvendor.db", piholeuser)
actual_rc = host.run(check_macvendor).rc