Compare commits
48 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
49c0287d4e | ||
|
c65c22d60d | ||
|
c942e99941 | ||
|
6532f3665e | ||
|
e79ae76866 | ||
|
dd27e0f157 | ||
|
c293af7a5a | ||
|
6b5e02fc7d | ||
|
0d74b27101 | ||
|
fe9031b26f | ||
|
326cd6a1f8 | ||
|
063f92f8f4 | ||
|
be6a73f102 | ||
|
b714c4598a | ||
|
0f192998eb | ||
|
8a5c7dec71 | ||
|
69e4e9a2ae | ||
|
4230be0c80 | ||
|
d45c9fc522 | ||
|
efa99a177e | ||
|
c2384ecc6f | ||
|
2f38452565 | ||
|
5cebceadda | ||
|
329c161054 | ||
|
f8e84b3c3f | ||
|
c9809371ab | ||
|
a48750e257 | ||
|
0d4c69cc6f | ||
|
479b2bc075 | ||
|
2ade05d60f | ||
|
ff5e788889 | ||
|
ab7d83384f | ||
|
48136c5bbc | ||
|
0219e5dfe0 | ||
|
0631cb4984 | ||
|
40b96e673b | ||
|
36ca858668 | ||
|
899cac0aac | ||
|
16b732fe8a | ||
|
1bf2f8d0b7 | ||
|
c756bcb9d1 | ||
|
42424b515b | ||
|
bd956b5f16 | ||
|
9be5199f7c | ||
|
9db19c5e96 | ||
|
91b4233d3a | ||
|
0b905c28c1 | ||
|
6ffa2ba1b2 |
2
.github/workflows/stale.yml
vendored
2
.github/workflows/stale.yml
vendored
@@ -20,6 +20,6 @@ jobs:
|
||||
days-before-close: 5
|
||||
stale-issue-message: 'This issue is stale because it has been open 30 days with no activity. Please comment or update this issue or it will be closed in 5 days.'
|
||||
stale-issue-label: 'stale'
|
||||
exempt-issue-labels: 'Internal, Fixed in next release, Bug: Confirmed'
|
||||
exempt-issue-labels: 'Internal, Fixed in next release, Bug: Confirmed, Documentation Needed'
|
||||
exempt-all-issue-assignees: true
|
||||
operations-per-run: 300
|
||||
|
1
.github/workflows/sync-back-to-dev.yml
vendored
1
.github/workflows/sync-back-to-dev.yml
vendored
@@ -19,7 +19,6 @@ jobs:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
FROM_BRANCH: 'master'
|
||||
TO_BRANCH: 'development'
|
||||
CONTENT_COMPARISON: true
|
||||
- name: Label the pull request to ignore for release note generation
|
||||
uses: actions-ecosystem/action-add-labels@v1
|
||||
with:
|
||||
|
2
.github/workflows/test.yml
vendored
2
.github/workflows/test.yml
vendored
@@ -37,7 +37,7 @@ jobs:
|
||||
uses: actions/checkout@v2
|
||||
-
|
||||
name: Set up Python 3.8
|
||||
uses: actions/setup-python@v2
|
||||
uses: actions/setup-python@v3
|
||||
with:
|
||||
python-version: 3.8
|
||||
-
|
||||
|
@@ -161,4 +161,4 @@ Some notable features include:
|
||||
There are several ways to [access the dashboard](https://discourse.pi-hole.net/t/how-do-i-access-pi-holes-dashboard-admin-interface/3168):
|
||||
|
||||
1. `http://pi.hole/admin/` (when using Pi-hole as your DNS server)
|
||||
2. `http://<IP_ADDPRESS_OF_YOUR_PI_HOLE>/admin/`
|
||||
2. `http://<IP_ADDRESS_OF_YOUR_PI_HOLE>/admin/`
|
||||
|
@@ -1,5 +1,5 @@
|
||||
# Determine if terminal is capable of showing colors
|
||||
if [[ -t 1 ]] && [[ $(tput colors) -ge 8 ]]; then
|
||||
if ([[ -t 1 ]] && [[ $(tput colors) -ge 8 ]]) || [[ "${WEBCALL}" ]]; then
|
||||
# Bold and underline may not show up on all clients
|
||||
# If something MUST be emphasized, use both
|
||||
COL_BOLD='[1m'
|
||||
|
@@ -906,9 +906,11 @@ dig_at() {
|
||||
# Removes all interfaces which are not UP
|
||||
# s/^[0-9]*: //g;
|
||||
# Removes interface index
|
||||
# s/@.*//g;
|
||||
# Removes everything after @ (if found)
|
||||
# s/: <.*//g;
|
||||
# Removes everything after the interface name
|
||||
interfaces="$(ip link show | sed "/ master /d;/UP/!d;s/^[0-9]*: //g;s/: <.*//g;")"
|
||||
interfaces="$(ip link show | sed "/ master /d;/UP/!d;s/^[0-9]*: //g;s/@.*//g;s/: <.*//g;")"
|
||||
|
||||
while IFS= read -r iface ; do
|
||||
# Get addresses of current interface
|
||||
@@ -1273,7 +1275,7 @@ show_clients() {
|
||||
}
|
||||
|
||||
show_messages() {
|
||||
show_FTL_db_entries "Pi-hole diagnosis messages" "SELECT id,datetime(timestamp,'unixepoch','localtime') timestamp,type,message,blob1,blob2,blob3,blob4,blob5 FROM message;" "4 19 20 60 20 20 20 20 20"
|
||||
show_FTL_db_entries "Pi-hole diagnosis messages" "SELECT count (message) as count, datetime(max(timestamp),'unixepoch','localtime') as 'last timestamp', type, message, blob1, blob2, blob3, blob4, blob5 FROM message GROUP BY type, message, blob1, blob2, blob3, blob4, blob5;" "6 19 20 60 20 20 20 20 20"
|
||||
}
|
||||
|
||||
analyze_gravity_list() {
|
||||
|
@@ -33,3 +33,30 @@ addOrEditKeyValPair() {
|
||||
echo "${key}=${value}" >> "${file}"
|
||||
fi
|
||||
}
|
||||
|
||||
#######################
|
||||
# returns FTL's current telnet API port
|
||||
#######################
|
||||
getFTLAPIPort(){
|
||||
local -r FTLCONFFILE="/etc/pihole/pihole-FTL.conf"
|
||||
local -r DEFAULT_PORT_FILE="/run/pihole-FTL.port"
|
||||
local -r DEFAULT_FTL_PORT=4711
|
||||
local PORTFILE
|
||||
local ftl_api_port
|
||||
|
||||
if [[ -f "$FTLCONFFILE" ]]; then
|
||||
# if PORTFILE is not set in pihole-FTL.conf, use the default path
|
||||
PORTFILE="$( (grep "^PORTFILE=" $FTLCONFFILE || echo "$DEFAULT_PORT_FILE") | cut -d"=" -f2-)"
|
||||
fi
|
||||
|
||||
if [[ -s "$PORTFILE" ]]; then
|
||||
# -s: FILE exists and has a size greater than zero
|
||||
ftl_api_port=$(<"$PORTFILE")
|
||||
# Exploit prevention: unset the variable if there is malicious content
|
||||
# Verify that the value read from the file is numeric
|
||||
[[ "$ftl_api_port" =~ [^[:digit:]] ]] && unset ftl_api_port
|
||||
fi
|
||||
|
||||
# echo the port found in the portfile or default to the default port
|
||||
echo "${ftl_api_port:=$DEFAULT_FTL_PORT}"
|
||||
}
|
||||
|
@@ -808,6 +808,23 @@ RemoveCustomCNAMERecord() {
|
||||
fi
|
||||
}
|
||||
|
||||
SetRateLimit() {
|
||||
local rate_limit_count rate_limit_interval reload
|
||||
rate_limit_count="${args[2]}"
|
||||
rate_limit_interval="${args[3]}"
|
||||
reload="${args[4]}"
|
||||
|
||||
# Set rate-limit setting inf valid
|
||||
if [ "${rate_limit_count}" -ge 0 ] && [ "${rate_limit_interval}" -ge 0 ]; then
|
||||
changeFTLsetting "RATE_LIMIT" "${rate_limit_count}/${rate_limit_interval}"
|
||||
fi
|
||||
|
||||
# Restart FTL to update rate-limit settings only if $reload not false
|
||||
if [[ ! $reload == "false" ]]; then
|
||||
RestartDNS
|
||||
fi
|
||||
}
|
||||
|
||||
main() {
|
||||
args=("$@")
|
||||
|
||||
@@ -841,6 +858,7 @@ main() {
|
||||
"removecustomdns" ) RemoveCustomDNSAddress;;
|
||||
"addcustomcname" ) AddCustomCNAMERecord;;
|
||||
"removecustomcname" ) RemoveCustomCNAMERecord;;
|
||||
"ratelimit" ) SetRateLimit;;
|
||||
* ) helpFunc;;
|
||||
esac
|
||||
|
||||
|
@@ -9,8 +9,39 @@
|
||||
# Description: Enable service provided by pihole-FTL daemon
|
||||
### END INIT INFO
|
||||
|
||||
# Get PID of main pihole-FTL process
|
||||
FTLCONFFILE="/etc/pihole/pihole-FTL.conf"
|
||||
DEFAULT_PID_FILE="/run/pihole-FTL.pid"
|
||||
getFTLPID() {
|
||||
if [ -s "$FTLCONFFILE" ]; then
|
||||
# if PIDFILE is not set in pihole-FTL.conf, use the default path
|
||||
FTL_PID_FILE="$( (grep "^PIDFILE=" $FTLCONFFILE || echo "$DEFAULT_PID_FILE") | cut -d"=" -f2-)"
|
||||
else
|
||||
# if there is no pihole-FTL.conf, use the default path
|
||||
FTL_PID_FILE="$DEFAULT_PID_FILE"
|
||||
fi
|
||||
|
||||
if [ -s "${FTL_PID_FILE}" ]; then
|
||||
# -s: FILE exists and has a size greater than zero
|
||||
FTL_PID="$(cat "$FTL_PID_FILE")"
|
||||
# Exploit prevention: unset the variable if there is malicious content
|
||||
# Verify that the value read from the file is numeric
|
||||
expr "$FTL_PID" : "[^[:digit:]]" > /dev/null && unset FTL_PID
|
||||
fi
|
||||
|
||||
# If FTL is not running, or the PID file contains malicious stuff, substitute
|
||||
# negative PID to signal this to the caller
|
||||
echo "${FTL_PID:=-1}"
|
||||
}
|
||||
|
||||
|
||||
is_running() {
|
||||
pgrep -xo "pihole-FTL" > /dev/null
|
||||
FTL_PID="$(getFTLPID)"
|
||||
if [ "$FTL_PID" -eq "-1" ]; then
|
||||
return 1
|
||||
else
|
||||
echo 0
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
@@ -21,12 +52,13 @@ start() {
|
||||
else
|
||||
# Touch files to ensure they exist (create if non-existing, preserve if existing)
|
||||
mkdir -pm 0755 /run/pihole
|
||||
touch /run/pihole-FTL.pid /run/pihole-FTL.port /var/log/pihole-FTL.log /var/log/pihole.log /etc/pihole/dhcp.leases
|
||||
[ ! -f /var/log/pihole-FTL.log ] && install -m 644 -o pihole -g pihole /dev/null /var/log/pihole-FTL.log
|
||||
[ ! -f /var/log/pihole.log ] && install -m 644 -o pihole -g pihole /dev/null /var/log/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-FTL.pid /run/pihole-FTL.port /var/log/pihole-FTL.log /var/log/pihole.log /etc/pihole/dhcp.leases /run/pihole /etc/pihole
|
||||
chmod 0644 /run/pihole-FTL.pid /run/pihole-FTL.port /var/log/pihole-FTL.log /var/log/pihole.log /etc/pihole/dhcp.leases
|
||||
chown pihole:pihole /run/pihole /etc/pihole /var/log/pihole.log /var/log/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
|
||||
chmod -f 0644 /etc/pihole/macvendor.db /etc/pihole/dhcp.leases /var/log/pihole-FTL.log /var/log/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
|
||||
@@ -44,7 +76,7 @@ start() {
|
||||
# Stop the service
|
||||
stop() {
|
||||
if is_running; then
|
||||
pkill -xo "pihole-FTL"
|
||||
pkill -F "${FTL_PID_FILE}"
|
||||
for i in 1 2 3 4 5; do
|
||||
if ! is_running; then
|
||||
break
|
||||
@@ -57,8 +89,8 @@ stop() {
|
||||
|
||||
if is_running; then
|
||||
echo "Not stopped; may still be shutting down or shutdown may have failed, killing now"
|
||||
pkill -xo -9 "pihole-FTL"
|
||||
exit 1
|
||||
pkill -9 -F "${FTL_PID_FILE}"
|
||||
exit 0
|
||||
else
|
||||
echo "Stopped"
|
||||
fi
|
||||
@@ -66,7 +98,7 @@ stop() {
|
||||
echo "Not running"
|
||||
fi
|
||||
# Cleanup
|
||||
rm -f /run/pihole/FTL.sock /dev/shm/FTL-*
|
||||
rm -f /run/pihole/FTL.sock /dev/shm/FTL-* "${FTL_PID_FILE}"
|
||||
echo
|
||||
}
|
||||
|
||||
|
@@ -164,13 +164,35 @@ ini_set("default_socket_timeout", 3);
|
||||
function queryAds($serverName) {
|
||||
// Determine the time it takes while querying adlists
|
||||
$preQueryTime = microtime(true)-$_SERVER["REQUEST_TIME_FLOAT"];
|
||||
|
||||
// Determine which protocol should be used
|
||||
$protocol = "http";
|
||||
if ((isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on') ||
|
||||
(isset($_SERVER['REQUEST_SCHEME']) && $_SERVER['REQUEST_SCHEME'] === 'https') ||
|
||||
(isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https')
|
||||
) {
|
||||
$protocol = "https";
|
||||
}
|
||||
|
||||
// Format the URL
|
||||
$queryAdsURL = sprintf(
|
||||
"http://127.0.0.1:%s/admin/scripts/pi-hole/php/queryads.php?domain=%s&bp",
|
||||
"%s://127.0.0.1:%s/admin/scripts/pi-hole/php/queryads.php?domain=%s&bp",
|
||||
$protocol,
|
||||
$_SERVER["SERVER_PORT"],
|
||||
$serverName
|
||||
);
|
||||
$queryAds = file($queryAdsURL, FILE_IGNORE_NEW_LINES);
|
||||
$queryAds = array_values(array_filter(preg_replace("/data:\s+/", "", $queryAds)));
|
||||
|
||||
// Request the file and receive the response
|
||||
$queryAdsFile = file($queryAdsURL, FILE_IGNORE_NEW_LINES);
|
||||
|
||||
// $queryAdsFile must be an array (to avoid PHP 8.0+ error)
|
||||
if (is_array($queryAdsFile)) {
|
||||
$queryAds = array_values(array_filter(preg_replace("/data:\s+/", "", $queryAdsFile)));
|
||||
} else {
|
||||
// if not an array, return an error message
|
||||
return array("0" => "error", "1" => "<br>(".gettype($queryAdsFile).")<br>".print_r($queryAdsFile, true));
|
||||
}
|
||||
|
||||
$queryTime = sprintf("%.0f", (microtime(true)-$_SERVER["REQUEST_TIME_FLOAT"]) - $preQueryTime);
|
||||
|
||||
// Exception Handling
|
||||
|
@@ -36,6 +36,11 @@ server.port = 80
|
||||
accesslog.filename = "/var/log/lighttpd/access.log"
|
||||
accesslog.format = "%{%s}t|%V|%r|%s|%b"
|
||||
|
||||
# Allow streaming response
|
||||
# reference: https://redmine.lighttpd.net/projects/lighttpd/wiki/Server_stream-response-bodyDetails
|
||||
server.stream-response-body = 1
|
||||
#ssl.read-ahead = "disable"
|
||||
|
||||
index-file.names = ( "index.php", "index.html", "index.lighttpd.html" )
|
||||
url.access-deny = ( "~", ".inc", ".md", ".yml", ".ini" )
|
||||
static-file.exclude-extensions = ( ".php", ".pl", ".fcgi" )
|
||||
|
@@ -37,6 +37,11 @@ server.port = 80
|
||||
accesslog.filename = "/var/log/lighttpd/access.log"
|
||||
accesslog.format = "%{%s}t|%V|%r|%s|%b"
|
||||
|
||||
# Allow streaming response
|
||||
# reference: https://redmine.lighttpd.net/projects/lighttpd/wiki/Server_stream-response-bodyDetails
|
||||
server.stream-response-body = 1
|
||||
#ssl.read-ahead = "disable"
|
||||
|
||||
index-file.names = ( "index.php", "index.html", "index.lighttpd.html" )
|
||||
url.access-deny = ( "~", ".inc", ".md", ".yml", ".ini" )
|
||||
static-file.exclude-extensions = ( ".php", ".pl", ".fcgi" )
|
||||
|
@@ -287,7 +287,7 @@ package_manager_detect() {
|
||||
# Packages required to run this install script (stored as an array)
|
||||
INSTALLER_DEPS=(git iproute2 whiptail ca-certificates)
|
||||
# Packages required to run Pi-hole (stored as an array)
|
||||
PIHOLE_DEPS=(cron curl iputils-ping psmisc sudo unzip idn2 libcap2-bin dns-root-data libcap2 netcat-openbsd)
|
||||
PIHOLE_DEPS=(cron curl iputils-ping psmisc sudo unzip idn2 libcap2-bin dns-root-data libcap2 netcat-openbsd procps)
|
||||
# Packages required for the Web admin interface (stored as an array)
|
||||
# It's useful to separate this from Pi-hole, since the two repos are also setup separately
|
||||
PIHOLE_WEB_DEPS=(lighttpd "${phpVer}-common" "${phpVer}-cgi" "${phpVer}-sqlite3" "${phpVer}-xml" "${phpVer}-intl")
|
||||
@@ -1128,8 +1128,11 @@ chooseBlocklists() {
|
||||
appendToListsFile "${choice}"
|
||||
done
|
||||
# Create an empty adList file with appropriate permissions.
|
||||
touch "${adlistFile}"
|
||||
if [ ! -f "${adlistFile}" ]; then
|
||||
install -m 644 /dev/null "${adlistFile}"
|
||||
else
|
||||
chmod 644 "${adlistFile}"
|
||||
fi
|
||||
}
|
||||
|
||||
# Accept a string parameter, it must be one of the default lists
|
||||
@@ -1330,8 +1333,9 @@ installConfigs() {
|
||||
# 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
|
||||
touch /etc/lighttpd/external.conf
|
||||
chmod 644 /etc/lighttpd/external.conf
|
||||
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_BLOCKPAGE_DIR}/custom.php" ]]; then
|
||||
sed -i 's/^\(server\.error-handler-404\s*=\s*\).*$/\1"\/pihole\/custom\.php"/' "${lighttpdConfig}"
|
||||
|
7
pihole
7
pihole
@@ -316,9 +316,10 @@ analyze_ports() {
|
||||
|
||||
statusFunc() {
|
||||
# Determine if there is pihole-FTL service is listening
|
||||
local listening pid port
|
||||
local pid port ftl_api_port
|
||||
|
||||
pid="$(getFTLPID)"
|
||||
ftl_api_port="$(getFTLAPIPort)"
|
||||
if [[ "$pid" -eq "-1" ]]; then
|
||||
case "${1}" in
|
||||
"web") echo "-1";;
|
||||
@@ -326,8 +327,8 @@ statusFunc() {
|
||||
esac
|
||||
return 0
|
||||
else
|
||||
#get the port pihole-FTL is listening on by using FTL's telnet API
|
||||
port="$(echo ">dns-port >quit" | nc 127.0.0.1 4711)"
|
||||
#get the DNS port pihole-FTL is listening on by using FTL's telnet API
|
||||
port="$(echo ">dns-port >quit" | nc 127.0.0.1 "$ftl_api_port")"
|
||||
if [[ "${port}" == "0" ]]; then
|
||||
case "${1}" in
|
||||
"web") echo "-1";;
|
||||
|
@@ -1,4 +1,4 @@
|
||||
FROM buildpack-deps:hirsute-scm
|
||||
FROM buildpack-deps:impish-scm
|
||||
|
||||
ENV GITDIR /etc/.pihole
|
||||
ENV SCRIPTDIR /opt/pihole
|
||||
|
@@ -1,16 +1,38 @@
|
||||
def test_key_val_replacement_works(host):
|
||||
''' Confirms addOrEditKeyValPair provides the expected output '''
|
||||
host.run('''
|
||||
setupvars=./testoutput
|
||||
source /opt/pihole/utils.sh
|
||||
addOrEditKeyValPair "KEY_ONE" "value1" "./testoutput"
|
||||
addOrEditKeyValPair "KEY_TWO" "value2" "./testoutput"
|
||||
addOrEditKeyValPair "KEY_ONE" "value3" "./testoutput"
|
||||
addOrEditKeyValPair "KEY_FOUR" "value4" "./testoutput"
|
||||
cat ./testoutput
|
||||
''')
|
||||
output = host.run('''
|
||||
cat ./testoutput
|
||||
''')
|
||||
expected_stdout = 'KEY_ONE=value3\nKEY_TWO=value2\nKEY_FOUR=value4\n'
|
||||
assert expected_stdout == output.stdout
|
||||
|
||||
|
||||
def test_getFTLAPIPort_default(host):
|
||||
''' Confirms getFTLAPIPort returns the default API port '''
|
||||
output = host.run('''
|
||||
source /opt/pihole/utils.sh
|
||||
getFTLAPIPort
|
||||
''')
|
||||
expected_stdout = '4711\n'
|
||||
assert expected_stdout == output.stdout
|
||||
|
||||
|
||||
def test_getFTLAPIPort_custom(host):
|
||||
''' Confirms getFTLAPIPort returns a custom API port in a custom PORTFILE location '''
|
||||
host.run('''
|
||||
echo "PORTFILE=/tmp/port.file" > /etc/pihole/pihole-FTL.conf
|
||||
echo "1234" > /tmp/port.file
|
||||
''')
|
||||
output = host.run('''
|
||||
source /opt/pihole/utils.sh
|
||||
getFTLAPIPort
|
||||
''')
|
||||
expected_stdout = '1234\n'
|
||||
assert expected_stdout == output.stdout
|
||||
|
Reference in New Issue
Block a user