mirror of https://github.com/pi-hole/pi-hole
Merge 206cf9c4ea
into eaa878e7a4
commit
05464fc1ac
@ -1,3 +1,4 @@
|
|||||||
doubleclick
|
doubleclick
|
||||||
wan
|
wan
|
||||||
nwe
|
nwe
|
||||||
|
padd
|
||||||
|
@ -1,35 +0,0 @@
|
|||||||
# Pi-hole: A black hole for Internet advertisements
|
|
||||||
# (c) 2017 Pi-hole, LLC (https://pi-hole.net)
|
|
||||||
# Network-wide ad blocking via your own hardware.
|
|
||||||
#
|
|
||||||
# Dnsmasq config for Pi-hole's FTLDNS
|
|
||||||
#
|
|
||||||
# This file is copyright under the latest version of the EUPL.
|
|
||||||
# Please see LICENSE file for your rights under this license.
|
|
||||||
|
|
||||||
###############################################################################
|
|
||||||
# FILE AUTOMATICALLY POPULATED BY PI-HOLE INSTALL/UPDATE PROCEDURE. #
|
|
||||||
# ANY CHANGES MADE TO THIS FILE AFTER INSTALL WILL BE LOST ON THE NEXT UPDATE #
|
|
||||||
# #
|
|
||||||
# IF YOU WISH TO CHANGE THE UPSTREAM SERVERS, CHANGE THEM IN: #
|
|
||||||
# /etc/pihole/setupVars.conf #
|
|
||||||
# #
|
|
||||||
# ANY OTHER CHANGES SHOULD BE MADE IN A SEPARATE CONFIG FILE #
|
|
||||||
# WITHIN /etc/dnsmasq.d/yourname.conf #
|
|
||||||
###############################################################################
|
|
||||||
|
|
||||||
addn-hosts=/etc/pihole/local.list
|
|
||||||
addn-hosts=/etc/pihole/custom.list
|
|
||||||
|
|
||||||
domain-needed
|
|
||||||
|
|
||||||
localise-queries
|
|
||||||
|
|
||||||
bogus-priv
|
|
||||||
|
|
||||||
no-resolv
|
|
||||||
|
|
||||||
log-queries
|
|
||||||
log-facility=/var/log/pihole/pihole.log
|
|
||||||
|
|
||||||
log-async
|
|
@ -1,42 +0,0 @@
|
|||||||
# Pi-hole: A black hole for Internet advertisements
|
|
||||||
# (c) 2021 Pi-hole, LLC (https://pi-hole.net)
|
|
||||||
# Network-wide ad blocking via your own hardware.
|
|
||||||
#
|
|
||||||
# RFC 6761 config file 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 POPULATED 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 #
|
|
||||||
# WITHIN /etc/dnsmasq.d/yourname.conf #
|
|
||||||
###############################################################################
|
|
||||||
|
|
||||||
# RFC 6761: Caching DNS servers SHOULD recognize
|
|
||||||
# test, localhost, invalid
|
|
||||||
# names as special and SHOULD NOT attempt to look up NS records for them, or
|
|
||||||
# otherwise query authoritative DNS servers in an attempt to resolve these
|
|
||||||
# names.
|
|
||||||
server=/test/
|
|
||||||
server=/localhost/
|
|
||||||
server=/invalid/
|
|
||||||
|
|
||||||
# The same RFC requests something similar for
|
|
||||||
# 10.in-addr.arpa. 21.172.in-addr.arpa. 27.172.in-addr.arpa.
|
|
||||||
# 16.172.in-addr.arpa. 22.172.in-addr.arpa. 28.172.in-addr.arpa.
|
|
||||||
# 17.172.in-addr.arpa. 23.172.in-addr.arpa. 29.172.in-addr.arpa.
|
|
||||||
# 18.172.in-addr.arpa. 24.172.in-addr.arpa. 30.172.in-addr.arpa.
|
|
||||||
# 19.172.in-addr.arpa. 25.172.in-addr.arpa. 31.172.in-addr.arpa.
|
|
||||||
# 20.172.in-addr.arpa. 26.172.in-addr.arpa. 168.192.in-addr.arpa.
|
|
||||||
# Pi-hole implements this via the dnsmasq option "bogus-priv" (see
|
|
||||||
# 01-pihole.conf) because this also covers IPv6.
|
|
||||||
|
|
||||||
# OpenWRT furthermore blocks bind, local, onion domains
|
|
||||||
# see https://git.openwrt.org/?p=openwrt/openwrt.git;a=blob_plain;f=package/network/services/dnsmasq/files/rfc6761.conf;hb=HEAD
|
|
||||||
# and https://www.iana.org/assignments/special-use-domain-names/special-use-domain-names.xhtml
|
|
||||||
# We do not include the ".local" rule ourselves, see https://github.com/pi-hole/pi-hole/pull/4282#discussion_r689112972
|
|
||||||
server=/bind/
|
|
||||||
server=/onion/
|
|
@ -0,0 +1,194 @@
|
|||||||
|
#!/usr/bin/env sh
|
||||||
|
# shellcheck disable=SC3043 #https://github.com/koalaman/shellcheck/wiki/SC3043#exceptions
|
||||||
|
|
||||||
|
# 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.
|
||||||
|
#
|
||||||
|
# Script to hold api functions for use in other scripts
|
||||||
|
#
|
||||||
|
# This file is copyright under the latest version of the EUPL.
|
||||||
|
# Please see LICENSE file for your rights under this license.
|
||||||
|
|
||||||
|
|
||||||
|
# The basic usage steps are
|
||||||
|
# 1) Test Availability of the API
|
||||||
|
# 2) Try to authenticate (read password if needed)
|
||||||
|
# 3) Get the data from the API endpoint
|
||||||
|
# 4) Delete the session
|
||||||
|
|
||||||
|
|
||||||
|
TestAPIAvailability() {
|
||||||
|
|
||||||
|
# as we are running locally, we can get the port value from FTL directly
|
||||||
|
local chaos_api_list availabilityResonse
|
||||||
|
|
||||||
|
# Query the API URLs from FTL using CHAOS TXT local.api.ftl
|
||||||
|
# The result is a space-separated enumeration of full URLs
|
||||||
|
# e.g., "http://localhost:80/api/" "https://localhost:443/api/"
|
||||||
|
chaos_api_list="$(dig +short chaos txt local.api.ftl @127.0.0.1)"
|
||||||
|
|
||||||
|
# If the query was not successful, the variable is empty
|
||||||
|
if [ -z "${chaos_api_list}" ]; then
|
||||||
|
echo "API not available. Please check connectivity"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Iterate over space-separated list of URLs
|
||||||
|
while [ -n "${chaos_api_list}" ]; do
|
||||||
|
# Get the first URL
|
||||||
|
API_URL="${chaos_api_list%% *}"
|
||||||
|
# Strip leading and trailing quotes
|
||||||
|
API_URL="${API_URL%\"}"
|
||||||
|
API_URL="${API_URL#\"}"
|
||||||
|
|
||||||
|
# Test if the API is available at this URL
|
||||||
|
availabilityResonse=$(curl -skS -o /dev/null -w "%{http_code}" "${API_URL}auth")
|
||||||
|
|
||||||
|
# Test if http status code was 200 (OK) or 401 (authentication required)
|
||||||
|
if [ ! "${availabilityResonse}" = 200 ] && [ ! "${availabilityResonse}" = 401 ]; then
|
||||||
|
# API is not available at this port/protocol combination
|
||||||
|
API_PORT=""
|
||||||
|
else
|
||||||
|
# API is available at this URL combination
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Remove the first URL from the list
|
||||||
|
local last_api_list
|
||||||
|
last_api_list="${chaos_api_list}"
|
||||||
|
chaos_api_list="${chaos_api_list#* }"
|
||||||
|
|
||||||
|
# If the list did not change, we are at the last element
|
||||||
|
if [ "${last_api_list}" = "${chaos_api_list}" ]; then
|
||||||
|
# Remove the last element
|
||||||
|
chaos_api_list=""
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
# if API_PORT is empty, no working API port was found
|
||||||
|
if [ -n "${API_PORT}" ]; then
|
||||||
|
echo "API not available at: ${API_URL}"
|
||||||
|
echo "Exiting."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
Authentication() {
|
||||||
|
# Try to authenticate
|
||||||
|
LoginAPI
|
||||||
|
|
||||||
|
while [ "${validSession}" = false ] || [ -z "${validSession}" ] ; do
|
||||||
|
echo "Authentication failed. Please enter your Pi-hole password"
|
||||||
|
|
||||||
|
# secretly read the password
|
||||||
|
secretRead; printf '\n'
|
||||||
|
|
||||||
|
# Try to authenticate again
|
||||||
|
LoginAPI
|
||||||
|
done
|
||||||
|
|
||||||
|
# Loop exited, authentication was successful
|
||||||
|
echo "Authentication successful."
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
LoginAPI() {
|
||||||
|
sessionResponse="$(curl -skS -X POST "${API_URL}auth" --user-agent "Pi-hole cli " --data "{\"password\":\"${password}\"}" )"
|
||||||
|
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
|
||||||
|
DeleteSession() {
|
||||||
|
# if a valid Session exists (no password required or successful Authentication) and
|
||||||
|
# SID is not null (successful Authentication only), delete the session
|
||||||
|
if [ "${validSession}" = true ] && [ ! "${SID}" = null ]; then
|
||||||
|
# Try to delete the session. Omit the output, but get the http status code
|
||||||
|
deleteResponse=$(curl -skS -o /dev/null -w "%{http_code}" -X DELETE "${API_URL}auth" -H "Accept: application/json" -H "sid: ${SID}")
|
||||||
|
|
||||||
|
case "${deleteResponse}" in
|
||||||
|
"204") printf "%b" "Session successfully deleted.\n";;
|
||||||
|
"401") printf "%b" "Logout attempt without a valid session. Unauthorized!\n";;
|
||||||
|
esac;
|
||||||
|
fi
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
GetFTLData() {
|
||||||
|
local data response status
|
||||||
|
# get the data from querying the API as well as the http status code
|
||||||
|
response=$(curl -skS -w "%{http_code}" -X GET "${API_URL}$1" -H "Accept: application/json" -H "sid: ${SID}" )
|
||||||
|
|
||||||
|
# status are the last 3 characters
|
||||||
|
status=$(printf %s "${response#"${response%???}"}")
|
||||||
|
# data is everything from response without the last 3 characters
|
||||||
|
data=$(printf %s "${response%???}")
|
||||||
|
|
||||||
|
if [ "${status}" = 200 ]; then
|
||||||
|
# response OK
|
||||||
|
printf %s "${data}"
|
||||||
|
elif [ "${status}" = 000 ]; then
|
||||||
|
# connection lost
|
||||||
|
echo "000"
|
||||||
|
elif [ "${status}" = 401 ]; then
|
||||||
|
# unauthorized
|
||||||
|
echo "401"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
secretRead() {
|
||||||
|
|
||||||
|
# POSIX compliant function to read user-input and
|
||||||
|
# mask every character entered by (*)
|
||||||
|
#
|
||||||
|
# This is challenging, because in POSIX, `read` does not support
|
||||||
|
# `-s` option (suppressing the input) or
|
||||||
|
# `-n` option (reading n chars)
|
||||||
|
|
||||||
|
|
||||||
|
# This workaround changes the terminal characteristics to not echo input and later resets this option
|
||||||
|
# credits https://stackoverflow.com/a/4316765
|
||||||
|
# showing asterisk instead of password
|
||||||
|
# https://stackoverflow.com/a/24600839
|
||||||
|
# https://unix.stackexchange.com/a/464963
|
||||||
|
|
||||||
|
|
||||||
|
# Save current terminal settings (needed for later restore after password prompt)
|
||||||
|
stty_orig=$(stty -g)
|
||||||
|
|
||||||
|
stty -echo # do not echo user input
|
||||||
|
stty -icanon min 1 time 0 # disable canonical mode https://man7.org/linux/man-pages/man3/termios.3.html
|
||||||
|
|
||||||
|
unset password
|
||||||
|
unset key
|
||||||
|
unset charcount
|
||||||
|
charcount=0
|
||||||
|
while key=$(dd ibs=1 count=1 2>/dev/null); do #read one byte of input
|
||||||
|
if [ "${key}" = "$(printf '\0' | tr -d '\0')" ] ; then
|
||||||
|
# Enter - accept password
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
if [ "${key}" = "$(printf '\177')" ] ; then
|
||||||
|
# Backspace
|
||||||
|
if [ $charcount -gt 0 ] ; then
|
||||||
|
charcount=$((charcount-1))
|
||||||
|
printf '\b \b'
|
||||||
|
password="${password%?}"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
# any other character
|
||||||
|
charcount=$((charcount+1))
|
||||||
|
printf '*'
|
||||||
|
password="$password$key"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
# restore original terminal settings
|
||||||
|
stty "${stty_orig}"
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
.timeout 30000
|
||||||
|
|
||||||
|
PRAGMA FOREIGN_KEYS=OFF;
|
||||||
|
|
||||||
|
BEGIN TRANSACTION;
|
||||||
|
|
||||||
|
ALTER TABLE adlist ADD COLUMN abp_entries INTEGER NOT NULL DEFAULT 0;
|
||||||
|
|
||||||
|
UPDATE info SET value = 16 WHERE property = 'version';
|
||||||
|
|
||||||
|
COMMIT;
|
@ -0,0 +1,27 @@
|
|||||||
|
.timeout 30000
|
||||||
|
|
||||||
|
PRAGMA FOREIGN_KEYS=OFF;
|
||||||
|
|
||||||
|
BEGIN TRANSACTION;
|
||||||
|
|
||||||
|
ALTER TABLE adlist ADD COLUMN type INTEGER NOT NULL DEFAULT 0;
|
||||||
|
|
||||||
|
UPDATE adlist SET type = 0;
|
||||||
|
|
||||||
|
CREATE VIEW vw_antigravity AS SELECT domain, adlist_by_group.group_id AS group_id
|
||||||
|
FROM antigravity
|
||||||
|
LEFT JOIN adlist_by_group ON adlist_by_group.adlist_id = antigravity.adlist_id
|
||||||
|
LEFT JOIN adlist ON adlist.id = antigravity.adlist_id
|
||||||
|
LEFT JOIN "group" ON "group".id = adlist_by_group.group_id
|
||||||
|
WHERE adlist.enabled = 1 AND (adlist_by_group.group_id IS NULL OR "group".enabled = 1) AND adlist.type = 1;
|
||||||
|
|
||||||
|
DROP VIEW vw_adlist;
|
||||||
|
|
||||||
|
CREATE VIEW vw_adlist AS SELECT DISTINCT address, id, type
|
||||||
|
FROM adlist
|
||||||
|
WHERE enabled = 1
|
||||||
|
ORDER BY id;
|
||||||
|
|
||||||
|
UPDATE info SET value = 17 WHERE property = 'version';
|
||||||
|
|
||||||
|
COMMIT;
|
@ -0,0 +1,25 @@
|
|||||||
|
.timeout 30000
|
||||||
|
|
||||||
|
PRAGMA FOREIGN_KEYS=OFF;
|
||||||
|
|
||||||
|
BEGIN TRANSACTION;
|
||||||
|
|
||||||
|
DROP VIEW vw_gravity;
|
||||||
|
CREATE VIEW vw_gravity AS SELECT domain, adlist.id AS adlist_id, adlist_by_group.group_id AS group_id
|
||||||
|
FROM gravity
|
||||||
|
LEFT JOIN adlist_by_group ON adlist_by_group.adlist_id = gravity.adlist_id
|
||||||
|
LEFT JOIN adlist ON adlist.id = gravity.adlist_id
|
||||||
|
LEFT JOIN "group" ON "group".id = adlist_by_group.group_id
|
||||||
|
WHERE adlist.enabled = 1 AND (adlist_by_group.group_id IS NULL OR "group".enabled = 1);
|
||||||
|
|
||||||
|
DROP VIEW vw_antigravity;
|
||||||
|
CREATE VIEW vw_antigravity AS SELECT domain, adlist.id AS adlist_id, adlist_by_group.group_id AS group_id
|
||||||
|
FROM antigravity
|
||||||
|
LEFT JOIN adlist_by_group ON adlist_by_group.adlist_id = antigravity.adlist_id
|
||||||
|
LEFT JOIN adlist ON adlist.id = antigravity.adlist_id
|
||||||
|
LEFT JOIN "group" ON "group".id = adlist_by_group.group_id
|
||||||
|
WHERE adlist.enabled = 1 AND (adlist_by_group.group_id IS NULL OR "group".enabled = 1) AND adlist.type = 1;
|
||||||
|
|
||||||
|
UPDATE info SET value = 18 WHERE property = 'version';
|
||||||
|
|
||||||
|
COMMIT;
|
@ -0,0 +1,27 @@
|
|||||||
|
.timeout 30000
|
||||||
|
|
||||||
|
PRAGMA FOREIGN_KEYS=OFF;
|
||||||
|
|
||||||
|
BEGIN TRANSACTION;
|
||||||
|
|
||||||
|
DROP TRIGGER tr_domainlist_delete;
|
||||||
|
CREATE TRIGGER tr_domainlist_delete BEFORE DELETE ON domainlist
|
||||||
|
BEGIN
|
||||||
|
DELETE FROM domainlist_by_group WHERE domainlist_id = OLD.id;
|
||||||
|
END;
|
||||||
|
|
||||||
|
DROP TRIGGER tr_adlist_delete;
|
||||||
|
CREATE TRIGGER tr_adlist_delete BEFORE DELETE ON adlist
|
||||||
|
BEGIN
|
||||||
|
DELETE FROM adlist_by_group WHERE adlist_id = OLD.id;
|
||||||
|
END;
|
||||||
|
|
||||||
|
DROP TRIGGER tr_client_delete;
|
||||||
|
CREATE TRIGGER tr_client_delete BEFORE DELETE ON client
|
||||||
|
BEGIN
|
||||||
|
DELETE FROM client_by_group WHERE client_id = OLD.id;
|
||||||
|
END;
|
||||||
|
|
||||||
|
UPDATE info SET value = 19 WHERE property = 'version';
|
||||||
|
|
||||||
|
COMMIT;
|
@ -1,259 +1,160 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env sh
|
||||||
# shellcheck disable=SC1090
|
# shellcheck disable=SC1090
|
||||||
|
|
||||||
|
# Ignore warning about `local` being undefinded in POSIX
|
||||||
|
# shellcheck disable=SC3043
|
||||||
|
# https://github.com/koalaman/shellcheck/wiki/SC3043#exceptions
|
||||||
|
|
||||||
# Pi-hole: A black hole for Internet advertisements
|
# Pi-hole: A black hole for Internet advertisements
|
||||||
# (c) 2018 Pi-hole, LLC (https://pi-hole.net)
|
# (c) 2023 Pi-hole, LLC (https://pi-hole.net)
|
||||||
# Network-wide ad blocking via your own hardware.
|
# Network-wide ad blocking via your own hardware.
|
||||||
#
|
#
|
||||||
# Query Domain Lists
|
# Search Adlists
|
||||||
#
|
#
|
||||||
# This file is copyright under the latest version of the EUPL.
|
# This file is copyright under the latest version of the EUPL.
|
||||||
# Please see LICENSE file for your rights under this license.
|
# Please see LICENSE file for your rights under this license.
|
||||||
|
|
||||||
# Globals
|
# Globals
|
||||||
piholeDir="/etc/pihole"
|
PI_HOLE_INSTALL_DIR="/opt/pihole"
|
||||||
GRAVITYDB="${piholeDir}/gravity.db"
|
max_results="20"
|
||||||
options="$*"
|
partial="false"
|
||||||
all=""
|
domain=""
|
||||||
exact=""
|
|
||||||
matchType="match"
|
|
||||||
# Source pihole-FTL from install script
|
|
||||||
pihole_FTL="${piholeDir}/pihole-FTL.conf"
|
|
||||||
if [[ -f "${pihole_FTL}" ]]; then
|
|
||||||
source "${pihole_FTL}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Set this only after sourcing pihole-FTL.conf as the gravity database path may
|
|
||||||
# have changed
|
|
||||||
gravityDBfile="${GRAVITYDB}"
|
|
||||||
|
|
||||||
|
# Source color table
|
||||||
colfile="/opt/pihole/COL_TABLE"
|
colfile="/opt/pihole/COL_TABLE"
|
||||||
source "${colfile}"
|
. "${colfile}"
|
||||||
|
|
||||||
|
# Source api functions
|
||||||
|
. "${PI_HOLE_INSTALL_DIR}/api.sh"
|
||||||
|
|
||||||
if [[ "${options}" == "-h" ]] || [[ "${options}" == "--help" ]]; then
|
Help() {
|
||||||
echo "Usage: pihole -q [option] <domain>
|
echo "Usage: pihole -q [option] <domain>
|
||||||
Example: 'pihole -q -exact domain.com'
|
Example: 'pihole -q --partial domain.com'
|
||||||
Query the adlists for a specified domain
|
Query the adlists for a specified domain
|
||||||
|
|
||||||
Options:
|
Options:
|
||||||
-exact Search the adlists for exact domain matches
|
--partial Search the adlists for partially matching domains
|
||||||
-all Return all query matches within the adlists
|
--all Return all query matches within the adlists
|
||||||
-h, --help Show this help dialog"
|
-h, --help Show this help dialog"
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
|
||||||
|
|
||||||
# Handle valid options
|
|
||||||
[[ "${options}" == *"-all"* ]] && all=true
|
|
||||||
if [[ "${options}" == *"-exact"* ]]; then
|
|
||||||
exact="exact"; matchType="exact ${matchType}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Strip valid options, leaving only the domain and invalid options
|
|
||||||
# This allows users to place the options before or after the domain
|
|
||||||
options=$(sed -E 's/ ?-(all|exact) ?//g' <<< "${options}")
|
|
||||||
|
|
||||||
# Handle remaining options
|
|
||||||
# If $options contain non ASCII characters, convert to punycode
|
|
||||||
case "${options}" in
|
|
||||||
"" ) str="No domain specified";;
|
|
||||||
*" "* ) str="Unknown query option specified";;
|
|
||||||
*[![:ascii:]]* ) rawDomainQuery=$(idn2 "${options}");;
|
|
||||||
* ) rawDomainQuery="${options}";;
|
|
||||||
esac
|
|
||||||
|
|
||||||
# convert the domain to lowercase
|
|
||||||
domainQuery=$(echo "${rawDomainQuery}" | tr '[:upper:]' '[:lower:]')
|
|
||||||
|
|
||||||
if [[ -n "${str:-}" ]]; then
|
|
||||||
echo -e "${str}${COL_NC}\\nTry 'pihole -q --help' for more information."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Scan a domain again a list of RegEX
|
|
||||||
scanRegExList(){
|
|
||||||
local domain="${1}" list="${2}"
|
|
||||||
|
|
||||||
for entry in ${list}; do
|
|
||||||
if [[ "${domain}" =~ ${entry} ]]; then
|
|
||||||
printf "%b\n" "${entry}";
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
scanDatabaseTable() {
|
GenerateOutput() {
|
||||||
local domain table list_type querystr result extra abpquerystr abpfound abpentry searchstr
|
local data gravity_data lists_data num_gravity num_lists search_type_str
|
||||||
domain="$(printf "%q" "${1}")"
|
local gravity_data_csv lists_data_csv line current_domain url type color
|
||||||
table="${2}"
|
data="${1}"
|
||||||
list_type="${3:-}"
|
|
||||||
|
|
||||||
# As underscores are legitimate parts of domains, we escape them when using the LIKE operator.
|
# construct a new json for the list results where each object contains the domain and the related type
|
||||||
# Underscores are SQLite wildcards matching exactly one character. We obviously want to suppress this
|
lists_data=$(printf %s "${data}" | jq '.search.domains | [.[] | {domain: .domain, type: .type}]')
|
||||||
# behavior. The "ESCAPE '\'" clause specifies that an underscore preceded by an '\' should be matched
|
|
||||||
# as a literal underscore character. We pretreat the $domain variable accordingly to escape underscores.
|
|
||||||
if [[ "${table}" == "gravity" ]]; then
|
|
||||||
|
|
||||||
# Are there ABP entries on gravity?
|
# construct a new json for the gravity results where each object contains the adlist URL and the related domains
|
||||||
# Return 1 if abp_domain=1 or Zero if abp_domain=0 or not set
|
gravity_data=$(printf %s "${data}" | jq '.search.gravity | group_by(.address,.type) | map({ address: (.[0].address), type: (.[0].type), domains: [.[] | .domain] })')
|
||||||
abpquerystr="SELECT EXISTS (SELECT 1 FROM info WHERE property='abp_domains' and value='1')"
|
|
||||||
abpfound="$(pihole-FTL sqlite3 -ni "${gravityDBfile}" "${abpquerystr}")" 2> /dev/null
|
|
||||||
|
|
||||||
# Create search string for ABP entries only if needed
|
# number of objects in each json
|
||||||
if [ "${abpfound}" -eq 1 ]; then
|
num_gravity=$(printf %s "${gravity_data}" | jq length)
|
||||||
abpentry="${domain}"
|
num_lists=$(printf %s "${lists_data}" | jq length)
|
||||||
|
|
||||||
searchstr="'||${abpentry}^'"
|
|
||||||
|
|
||||||
# While a dot is found ...
|
|
||||||
while [ "${abpentry}" != "${abpentry/./}" ]
|
|
||||||
do
|
|
||||||
# ... remove text before the dot (including the dot) and append the result to $searchstr
|
|
||||||
abpentry=$(echo "${abpentry}" | cut -f 2- -d '.')
|
|
||||||
searchstr="$searchstr, '||${abpentry}^'"
|
|
||||||
done
|
|
||||||
|
|
||||||
# The final search string will look like:
|
if [ "${partial}" = true ]; then
|
||||||
# "domain IN ('||sub2.sub1.domain.com^', '||sub1.domain.com^', '||domain.com^', '||com^') OR"
|
search_type_str="partially"
|
||||||
searchstr="domain IN (${searchstr}) OR "
|
|
||||||
fi
|
|
||||||
|
|
||||||
case "${exact}" in
|
|
||||||
"exact" ) querystr="SELECT gravity.domain,adlist.address,adlist.enabled FROM gravity LEFT JOIN adlist ON adlist.id = gravity.adlist_id WHERE domain = '${domain}'";;
|
|
||||||
* ) querystr="SELECT gravity.domain,adlist.address,adlist.enabled FROM gravity LEFT JOIN adlist ON adlist.id = gravity.adlist_id WHERE ${searchstr} domain LIKE '%${domain//_/\\_}%' ESCAPE '\\'";;
|
|
||||||
esac
|
|
||||||
else
|
else
|
||||||
case "${exact}" in
|
search_type_str="exactly"
|
||||||
"exact" ) querystr="SELECT domain,enabled FROM domainlist WHERE type = '${list_type}' AND domain = '${domain}'";;
|
|
||||||
* ) querystr="SELECT domain,enabled FROM domainlist WHERE type = '${list_type}' AND domain LIKE '%${domain//_/\\_}%' ESCAPE '\\'";;
|
|
||||||
esac
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Send prepared query to gravity database
|
# Results from allow/deny list
|
||||||
result="$(pihole-FTL sqlite3 -ni -separator ',' "${gravityDBfile}" "${querystr}")" 2> /dev/null
|
printf "%s\n\n" "Found ${num_lists} domains ${search_type_str} matching '${COL_BLUE}${domain}${COL_NC}'."
|
||||||
if [[ -z "${result}" ]]; then
|
if [ "${num_lists}" -gt 0 ]; then
|
||||||
# Return early when there are no matches in this table
|
# Convert the data to a csv, each line is a "domain,type" string
|
||||||
return
|
# not using jq's @csv here as it quotes each value individually
|
||||||
fi
|
lists_data_csv=$(printf %s "${lists_data}" | jq --raw-output '.[] | [.domain, .type] | join(",")')
|
||||||
|
|
||||||
if [[ "${table}" == "gravity" ]]; then
|
# Generate output for each csv line, separating line in a domain and type substring at the ','
|
||||||
echo "${result}"
|
echo "${lists_data_csv}" | while read -r line; do
|
||||||
return
|
printf "%s\n\n" " - ${COL_GREEN}${line%,*}${COL_NC} (type: exact ${line#*,} domain)"
|
||||||
|
done
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Mark domain as having been white-/blacklist matched (global variable)
|
# Results from gravity
|
||||||
wbMatch=true
|
printf "%s\n\n" "Found ${num_gravity} adlists ${search_type_str} matching '${COL_BLUE}${domain}${COL_NC}'."
|
||||||
|
if [ "${num_gravity}" -gt 0 ]; then
|
||||||
# Print table name
|
# Convert the data to a csv, each line is a "URL,domain,domain,...." string
|
||||||
echo " ${matchType^} found in ${COL_BOLD}exact ${table}${COL_NC}"
|
# not using jq's @csv here as it quotes each value individually
|
||||||
|
gravity_data_csv=$(printf %s "${gravity_data}" | jq --raw-output '.[] | [.address, .type, .domains[]] | join(",")')
|
||||||
# Loop over results and print them
|
|
||||||
mapfile -t results <<< "${result}"
|
# Generate line-by-line output for each csv line
|
||||||
for result in "${results[@]}"; do
|
echo "${gravity_data_csv}" | while read -r line; do
|
||||||
domain="${result/,*}"
|
# Get first part of the line, the URL
|
||||||
if [[ "${result#*,}" == "0" ]]; then
|
url=${line%%,*}
|
||||||
extra=" (disabled)"
|
|
||||||
|
# cut off URL, leaving "type,domain,domain,...."
|
||||||
|
line=${line#*,}
|
||||||
|
type=${line%%,*}
|
||||||
|
# type == "block" -> red, type == "allow" -> green
|
||||||
|
if [ "${type}" = "block" ]; then
|
||||||
|
color="${COL_RED}"
|
||||||
else
|
else
|
||||||
extra=""
|
color="${COL_GREEN}"
|
||||||
fi
|
fi
|
||||||
echo " ${domain}${extra}"
|
|
||||||
|
# print adlist URL
|
||||||
|
printf "%s (%s)\n\n" " - ${COL_BLUE}${url}${COL_NC}" "${color}${type}${COL_NC}"
|
||||||
|
|
||||||
|
# cut off type, leaving "domain,domain,...."
|
||||||
|
line=${line#*,}
|
||||||
|
# print each domain and remove it from the string until nothing is left
|
||||||
|
while [ ${#line} -gt 0 ]; do
|
||||||
|
current_domain=${line%%,*}
|
||||||
|
printf ' - %s\n' "${COL_GREEN}${current_domain}${COL_NC}"
|
||||||
|
# we need to remove the current_domain and the comma in two steps because
|
||||||
|
# the last domain won't have a trailing comma and the while loop wouldn't exit
|
||||||
|
line=${line#"${current_domain}"}
|
||||||
|
line=${line#,}
|
||||||
|
done
|
||||||
|
printf "\n\n"
|
||||||
done
|
done
|
||||||
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
scanRegexDatabaseTable() {
|
Main() {
|
||||||
local domain list list_type
|
local data
|
||||||
domain="${1}"
|
|
||||||
list="${2}"
|
|
||||||
list_type="${3:-}"
|
|
||||||
|
|
||||||
# Query all regex from the corresponding database tables
|
if [ -z "${domain}" ]; then
|
||||||
mapfile -t regexList < <(pihole-FTL sqlite3 -ni "${gravityDBfile}" "SELECT domain FROM domainlist WHERE type = ${list_type}" 2> /dev/null)
|
echo "No domain specified"
|
||||||
|
exit 1
|
||||||
# If we have regexps to process
|
|
||||||
if [[ "${#regexList[@]}" -ne 0 ]]; then
|
|
||||||
# Split regexps over a new line
|
|
||||||
str_regexList=$(printf '%s\n' "${regexList[@]}")
|
|
||||||
# Check domain against regexps
|
|
||||||
mapfile -t regexMatches < <(scanRegExList "${domain}" "${str_regexList}")
|
|
||||||
# If there were regex matches
|
|
||||||
if [[ "${#regexMatches[@]}" -ne 0 ]]; then
|
|
||||||
# Split matching regexps over a new line
|
|
||||||
str_regexMatches=$(printf '%s\n' "${regexMatches[@]}")
|
|
||||||
# Form a "matched" message
|
|
||||||
str_message="${matchType^} found in ${COL_BOLD}regex ${list}${COL_NC}"
|
|
||||||
# Form a "results" message
|
|
||||||
str_result="${COL_BOLD}${str_regexMatches}${COL_NC}"
|
|
||||||
# If we are displaying more than just the source of the block
|
|
||||||
# Set the wildcard match flag
|
|
||||||
wcMatch=true
|
|
||||||
# Echo the "matched" message, indented by one space
|
|
||||||
echo " ${str_message}"
|
|
||||||
# Echo the "results" message, each line indented by three spaces
|
|
||||||
# shellcheck disable=SC2001
|
|
||||||
echo "${str_result}" | sed 's/^/ /'
|
|
||||||
fi
|
|
||||||
fi
|
fi
|
||||||
}
|
# domains are lowercased and converted to punycode by FTL since
|
||||||
|
# https://github.com/pi-hole/FTL/pull/1715
|
||||||
# Scan Whitelist and Blacklist
|
# no need to do it here
|
||||||
scanDatabaseTable "${domainQuery}" "whitelist" "0"
|
|
||||||
scanDatabaseTable "${domainQuery}" "blacklist" "1"
|
|
||||||
|
|
||||||
# Scan Regex table
|
# Test if the authentication endpoint is available
|
||||||
scanRegexDatabaseTable "${domainQuery}" "whitelist" "2"
|
TestAPIAvailability
|
||||||
scanRegexDatabaseTable "${domainQuery}" "blacklist" "3"
|
|
||||||
|
|
||||||
# Query block lists
|
# Users can configure FTL in a way, that for accessing a) all endpoints (webserver.api.localAPIauth)
|
||||||
mapfile -t results <<< "$(scanDatabaseTable "${domainQuery}" "gravity")"
|
# or b) for the /search endpoint (webserver.api.searchAPIauth) no authentication is required.
|
||||||
|
# Therefore, we try to query directly without authentication but do authenticat if 401 is returned
|
||||||
|
|
||||||
# Handle notices
|
data=$(GetFTLData "search/${domain}?N=${max_results}&partial=${partial}")
|
||||||
if [[ -z "${wbMatch:-}" ]] && [[ -z "${wcMatch:-}" ]] && [[ -z "${results[*]}" ]]; then
|
|
||||||
echo -e " ${INFO} No ${exact/t/t }results found for ${COL_BOLD}${domainQuery}${COL_NC} within the adlists"
|
|
||||||
exit 0
|
|
||||||
elif [[ -z "${results[*]}" ]]; then
|
|
||||||
# Result found in WL/BL/Wildcards
|
|
||||||
exit 0
|
|
||||||
elif [[ -z "${all}" ]] && [[ "${#results[*]}" -ge 100 ]]; then
|
|
||||||
echo -e " ${INFO} Over 100 ${exact/t/t }results found for ${COL_BOLD}${domainQuery}${COL_NC}
|
|
||||||
This can be overridden using the -all option"
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Print "Exact matches for" title
|
if [ "${data}" = 401 ]; then
|
||||||
if [[ -n "${exact}" ]]; then
|
# Unauthenticated, so authenticate with the FTL server required
|
||||||
plural=""; [[ "${#results[*]}" -gt 1 ]] && plural="es"
|
Authentication
|
||||||
echo " ${matchType^}${plural} for ${COL_BOLD}${domainQuery}${COL_NC} found in:"
|
|
||||||
fi
|
|
||||||
|
|
||||||
for result in "${results[@]}"; do
|
# send query again
|
||||||
match="${result/,*/}"
|
data=$(GetFTLData "search/${domain}?N=${max_results}&partial=${partial}")
|
||||||
extra="${result#*,}"
|
|
||||||
adlistAddress="${extra/,*/}"
|
|
||||||
extra="${extra#*,}"
|
|
||||||
if [[ "${extra}" == "0" ]]; then
|
|
||||||
extra=" (disabled)"
|
|
||||||
else
|
|
||||||
extra=""
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ -n "${exact}" ]]; then
|
GenerateOutput "${data}"
|
||||||
echo " - ${adlistAddress}${extra}"
|
DeleteSession
|
||||||
else
|
}
|
||||||
if [[ ! "${adlistAddress}" == "${adlistAddress_prev:-}" ]]; then
|
|
||||||
count=""
|
|
||||||
echo " ${matchType^} found in ${COL_BOLD}${adlistAddress}${COL_NC}:"
|
|
||||||
adlistAddress_prev="${adlistAddress}"
|
|
||||||
fi
|
|
||||||
: $((count++))
|
|
||||||
|
|
||||||
# Print matching domain if $max_count has not been reached
|
# Process all options (if present)
|
||||||
[[ -z "${all}" ]] && max_count="50"
|
while [ "$#" -gt 0 ]; do
|
||||||
if [[ -z "${all}" ]] && [[ "${count}" -ge "${max_count}" ]]; then
|
case "$1" in
|
||||||
[[ "${count}" -gt "${max_count}" ]] && continue
|
"-h" | "--help") Help ;;
|
||||||
echo " ${COL_GRAY}Over ${count} results found, skipping rest of file${COL_NC}"
|
"--partial") partial="true" ;;
|
||||||
else
|
"--all") max_results=10000 ;; # hard-coded FTL limit
|
||||||
echo " ${match}${extra}"
|
*) domain=$1 ;;
|
||||||
fi
|
esac
|
||||||
fi
|
shift
|
||||||
done
|
done
|
||||||
|
|
||||||
exit 0
|
Main "${domain}"
|
||||||
|
@ -1,890 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
# shellcheck disable=SC1090
|
|
||||||
# shellcheck disable=SC2154
|
|
||||||
|
|
||||||
|
|
||||||
# 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.
|
|
||||||
#
|
|
||||||
# Web interface settings
|
|
||||||
#
|
|
||||||
# This file is copyright under the latest version of the EUPL.
|
|
||||||
# Please see LICENSE file for your rights under this license.
|
|
||||||
|
|
||||||
readonly dnsmasqconfig="/etc/dnsmasq.d/01-pihole.conf"
|
|
||||||
readonly dhcpconfig="/etc/dnsmasq.d/02-pihole-dhcp.conf"
|
|
||||||
readonly FTLconf="/etc/pihole/pihole-FTL.conf"
|
|
||||||
# 03 -> wildcards
|
|
||||||
readonly dhcpstaticconfig="/etc/dnsmasq.d/04-pihole-static-dhcp.conf"
|
|
||||||
readonly dnscustomfile="/etc/pihole/custom.list"
|
|
||||||
readonly dnscustomcnamefile="/etc/dnsmasq.d/05-pihole-custom-cname.conf"
|
|
||||||
|
|
||||||
readonly gravityDBfile="/etc/pihole/gravity.db"
|
|
||||||
|
|
||||||
|
|
||||||
readonly setupVars="/etc/pihole/setupVars.conf"
|
|
||||||
readonly PI_HOLE_BIN_DIR="/usr/local/bin"
|
|
||||||
|
|
||||||
# Root of the web server
|
|
||||||
readonly webroot="/var/www/html"
|
|
||||||
|
|
||||||
# Source utils script
|
|
||||||
utilsfile="/opt/pihole/utils.sh"
|
|
||||||
source "${utilsfile}"
|
|
||||||
|
|
||||||
coltable="/opt/pihole/COL_TABLE"
|
|
||||||
if [[ -f ${coltable} ]]; then
|
|
||||||
source ${coltable}
|
|
||||||
fi
|
|
||||||
|
|
||||||
helpFunc() {
|
|
||||||
echo "Usage: pihole -a [options]
|
|
||||||
Example: pihole -a -p password
|
|
||||||
Set options for the Admin Console
|
|
||||||
|
|
||||||
Options:
|
|
||||||
-p, password Set Admin Console password
|
|
||||||
-c, celsius Set Celsius as preferred temperature unit
|
|
||||||
-f, fahrenheit Set Fahrenheit as preferred temperature unit
|
|
||||||
-k, kelvin Set Kelvin as preferred temperature unit
|
|
||||||
-h, --help Show this help dialog
|
|
||||||
-i, interface Specify dnsmasq's interface listening behavior
|
|
||||||
-l, privacylevel Set privacy level (0 = lowest, 3 = highest)
|
|
||||||
-t, teleporter Backup configuration as an archive
|
|
||||||
-t, teleporter myname.tar.gz Backup configuration to archive with name myname.tar.gz as specified"
|
|
||||||
exit 0
|
|
||||||
}
|
|
||||||
|
|
||||||
add_setting() {
|
|
||||||
addOrEditKeyValPair "${setupVars}" "${1}" "${2}"
|
|
||||||
}
|
|
||||||
|
|
||||||
delete_setting() {
|
|
||||||
removeKey "${setupVars}" "${1}"
|
|
||||||
}
|
|
||||||
|
|
||||||
change_setting() {
|
|
||||||
addOrEditKeyValPair "${setupVars}" "${1}" "${2}"
|
|
||||||
}
|
|
||||||
|
|
||||||
addFTLsetting() {
|
|
||||||
addOrEditKeyValPair "${FTLconf}" "${1}" "${2}"
|
|
||||||
}
|
|
||||||
|
|
||||||
deleteFTLsetting() {
|
|
||||||
removeKey "${FTLconf}" "${1}"
|
|
||||||
}
|
|
||||||
|
|
||||||
changeFTLsetting() {
|
|
||||||
addOrEditKeyValPair "${FTLconf}" "${1}" "${2}"
|
|
||||||
}
|
|
||||||
|
|
||||||
add_dnsmasq_setting() {
|
|
||||||
addOrEditKeyValPair "${dnsmasqconfig}" "${1}" "${2}"
|
|
||||||
}
|
|
||||||
|
|
||||||
delete_dnsmasq_setting() {
|
|
||||||
removeKey "${dnsmasqconfig}" "${1}"
|
|
||||||
}
|
|
||||||
|
|
||||||
SetTemperatureUnit() {
|
|
||||||
addOrEditKeyValPair "${setupVars}" "TEMPERATUREUNIT" "${unit}"
|
|
||||||
echo -e " ${TICK} Set temperature unit to ${unit}"
|
|
||||||
}
|
|
||||||
|
|
||||||
HashPassword() {
|
|
||||||
# Compute password hash twice to avoid rainbow table vulnerability
|
|
||||||
return=$(echo -n "${1}" | sha256sum | sed 's/\s.*$//')
|
|
||||||
return=$(echo -n "${return}" | sha256sum | sed 's/\s.*$//')
|
|
||||||
echo "${return}"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Check an IP address to see if it is a valid one
|
|
||||||
valid_ip() {
|
|
||||||
# Local, named variables
|
|
||||||
local ip=${1}
|
|
||||||
local stat=1
|
|
||||||
|
|
||||||
# Regex matching one IPv4 component, i.e. an integer from 0 to 255.
|
|
||||||
# See https://tools.ietf.org/html/rfc1340
|
|
||||||
local ipv4elem="(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]?|0)";
|
|
||||||
# Regex matching an optional port (starting with '#') range of 1-65536
|
|
||||||
local portelem="(#(6553[0-5]|655[0-2][0-9]|65[0-4][0-9]{2}|6[0-4][0-9]{3}|[1-5][0-9]{4}|[1-9][0-9]{0,3}|0))?";
|
|
||||||
# Build a full IPv4 regex from the above subexpressions
|
|
||||||
local regex="^${ipv4elem}\\.${ipv4elem}\\.${ipv4elem}\\.${ipv4elem}${portelem}$"
|
|
||||||
|
|
||||||
# Evaluate the regex, and return the result
|
|
||||||
[[ $ip =~ ${regex} ]]
|
|
||||||
|
|
||||||
stat=$?
|
|
||||||
return "${stat}"
|
|
||||||
}
|
|
||||||
|
|
||||||
valid_ip6() {
|
|
||||||
local ip=${1}
|
|
||||||
local stat=1
|
|
||||||
|
|
||||||
# Regex matching one IPv6 element, i.e. a hex value from 0000 to FFFF
|
|
||||||
local ipv6elem="[0-9a-fA-F]{1,4}"
|
|
||||||
# Regex matching an IPv6 CIDR, i.e. 1 to 128
|
|
||||||
local v6cidr="(\\/([1-9]|[1-9][0-9]|1[0-1][0-9]|12[0-8])){0,1}"
|
|
||||||
# Regex matching an optional port (starting with '#') range of 1-65536
|
|
||||||
local portelem="(#(6553[0-5]|655[0-2][0-9]|65[0-4][0-9]{2}|6[0-4][0-9]{3}|[1-5][0-9]{4}|[1-9][0-9]{0,3}|0))?";
|
|
||||||
# Build a full IPv6 regex from the above subexpressions
|
|
||||||
local regex="^(((${ipv6elem}))*((:${ipv6elem}))*::((${ipv6elem}))*((:${ipv6elem}))*|((${ipv6elem}))((:${ipv6elem})){7})${v6cidr}${portelem}$"
|
|
||||||
|
|
||||||
# Evaluate the regex, and return the result
|
|
||||||
[[ ${ip} =~ ${regex} ]]
|
|
||||||
|
|
||||||
stat=$?
|
|
||||||
return "${stat}"
|
|
||||||
}
|
|
||||||
|
|
||||||
SetWebPassword() {
|
|
||||||
if [ "${SUDO_USER}" == "www-data" ]; then
|
|
||||||
echo "Security measure: user www-data is not allowed to change webUI password!"
|
|
||||||
echo "Exiting"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "${SUDO_USER}" == "lighttpd" ]; then
|
|
||||||
echo "Security measure: user lighttpd is not allowed to change webUI password!"
|
|
||||||
echo "Exiting"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if (( ${#args[2]} > 0 )) ; then
|
|
||||||
readonly PASSWORD="${args[2]}"
|
|
||||||
readonly CONFIRM="${PASSWORD}"
|
|
||||||
else
|
|
||||||
# Prevents a bug if the user presses Ctrl+C and it continues to hide the text typed.
|
|
||||||
# So we reset the terminal via stty if the user does press Ctrl+C
|
|
||||||
trap '{ echo -e "\nNo password will be set" ; stty sane ; exit 1; }' INT
|
|
||||||
read -s -r -p "Enter New Password (Blank for no password): " PASSWORD
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
if [ "${PASSWORD}" == "" ]; then
|
|
||||||
addOrEditKeyValPair "${setupVars}" "WEBPASSWORD" ""
|
|
||||||
echo -e " ${TICK} Password Removed"
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
read -s -r -p "Confirm Password: " CONFIRM
|
|
||||||
echo ""
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "${PASSWORD}" == "${CONFIRM}" ] ; then
|
|
||||||
# We do not wrap this in brackets, otherwise BASH will expand any appropriate syntax
|
|
||||||
hash=$(HashPassword "$PASSWORD")
|
|
||||||
# Save hash to file
|
|
||||||
addOrEditKeyValPair "${setupVars}" "WEBPASSWORD" "${hash}"
|
|
||||||
echo -e " ${TICK} New password set"
|
|
||||||
else
|
|
||||||
echo -e " ${CROSS} Passwords don't match. Your password has not been changed"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
ProcessDNSSettings() {
|
|
||||||
source "${setupVars}"
|
|
||||||
|
|
||||||
removeKey "${dnsmasqconfig}" "server"
|
|
||||||
|
|
||||||
COUNTER=1
|
|
||||||
while true ; do
|
|
||||||
var=PIHOLE_DNS_${COUNTER}
|
|
||||||
if [ -z "${!var}" ]; then
|
|
||||||
break;
|
|
||||||
fi
|
|
||||||
addKey "${dnsmasqconfig}" "server=${!var}"
|
|
||||||
(( COUNTER++ ))
|
|
||||||
done
|
|
||||||
|
|
||||||
# The option LOCAL_DNS_PORT is deprecated
|
|
||||||
# We apply it once more, and then convert it into the current format
|
|
||||||
if [ -n "${LOCAL_DNS_PORT}" ]; then
|
|
||||||
addOrEditKeyValPair "${dnsmasqconfig}" "server" "127.0.0.1#${LOCAL_DNS_PORT}"
|
|
||||||
addOrEditKeyValPair "${setupVars}" "PIHOLE_DNS_${COUNTER}" "127.0.0.1#${LOCAL_DNS_PORT}"
|
|
||||||
removeKey "${setupVars}" "LOCAL_DNS_PORT"
|
|
||||||
fi
|
|
||||||
|
|
||||||
removeKey "${dnsmasqconfig}" "domain-needed"
|
|
||||||
removeKey "${dnsmasqconfig}" "expand-hosts"
|
|
||||||
|
|
||||||
if [[ "${DNS_FQDN_REQUIRED}" == true ]]; then
|
|
||||||
addKey "${dnsmasqconfig}" "domain-needed"
|
|
||||||
addKey "${dnsmasqconfig}" "expand-hosts"
|
|
||||||
fi
|
|
||||||
|
|
||||||
removeKey "${dnsmasqconfig}" "bogus-priv"
|
|
||||||
|
|
||||||
if [[ "${DNS_BOGUS_PRIV}" == true ]]; then
|
|
||||||
addKey "${dnsmasqconfig}" "bogus-priv"
|
|
||||||
fi
|
|
||||||
|
|
||||||
removeKey "${dnsmasqconfig}" "dnssec"
|
|
||||||
removeKey "${dnsmasqconfig}" "trust-anchor"
|
|
||||||
|
|
||||||
if [[ "${DNSSEC}" == true ]]; then
|
|
||||||
echo "dnssec
|
|
||||||
trust-anchor=.,20326,8,2,E06D44B80B8F1D39A95C0B0D7C65D08458E880409BBC683457104237C7F8EC8D
|
|
||||||
" >> "${dnsmasqconfig}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
removeKey "${dnsmasqconfig}" "host-record"
|
|
||||||
|
|
||||||
if [ -n "${HOSTRECORD}" ]; then
|
|
||||||
addOrEditKeyValPair "${dnsmasqconfig}" "host-record" "${HOSTRECORD}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Setup interface listening behavior of dnsmasq
|
|
||||||
removeKey "${dnsmasqconfig}" "interface"
|
|
||||||
removeKey "${dnsmasqconfig}" "local-service"
|
|
||||||
removeKey "${dnsmasqconfig}" "except-interface"
|
|
||||||
removeKey "${dnsmasqconfig}" "bind-interfaces"
|
|
||||||
|
|
||||||
if [[ "${DNSMASQ_LISTENING}" == "all" ]]; then
|
|
||||||
# Listen on all interfaces, permit all origins
|
|
||||||
addOrEditKeyValPair "${dnsmasqconfig}" "except-interface" "nonexisting"
|
|
||||||
elif [[ "${DNSMASQ_LISTENING}" == "local" ]]; then
|
|
||||||
# Listen only on all interfaces, but only local subnets
|
|
||||||
addKey "${dnsmasqconfig}" "local-service"
|
|
||||||
else
|
|
||||||
# Options "bind" and "single"
|
|
||||||
# Listen only on one interface
|
|
||||||
# Use eth0 as fallback interface if interface is missing in setupVars.conf
|
|
||||||
if [ -z "${PIHOLE_INTERFACE}" ]; then
|
|
||||||
PIHOLE_INTERFACE="eth0"
|
|
||||||
fi
|
|
||||||
|
|
||||||
addOrEditKeyValPair "${dnsmasqconfig}" "interface" "${PIHOLE_INTERFACE}"
|
|
||||||
|
|
||||||
if [[ "${DNSMASQ_LISTENING}" == "bind" ]]; then
|
|
||||||
# Really bind to interface
|
|
||||||
addKey "${dnsmasqconfig}" "bind-interfaces"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ "${CONDITIONAL_FORWARDING}" == true ]]; then
|
|
||||||
# Convert legacy "conditional forwarding" to rev-server configuration
|
|
||||||
# Remove any existing REV_SERVER settings
|
|
||||||
removeKey "${setupVars}" "REV_SERVER"
|
|
||||||
removeKey "${setupVars}" "REV_SERVER_DOMAIN"
|
|
||||||
removeKey "${setupVars}" "REV_SERVER_TARGET"
|
|
||||||
removeKey "${setupVars}" "REV_SERVER_CIDR"
|
|
||||||
|
|
||||||
REV_SERVER=true
|
|
||||||
addOrEditKeyValPair "${setupVars}" "REV_SERVER" "true"
|
|
||||||
|
|
||||||
REV_SERVER_DOMAIN="${CONDITIONAL_FORWARDING_DOMAIN}"
|
|
||||||
addOrEditKeyValPair "${setupVars}" "REV_SERVER_DOMAIN" "${REV_SERVER_DOMAIN}"
|
|
||||||
|
|
||||||
REV_SERVER_TARGET="${CONDITIONAL_FORWARDING_IP}"
|
|
||||||
addOrEditKeyValPair "${setupVars}" "REV_SERVER_TARGET" "${REV_SERVER_TARGET}"
|
|
||||||
|
|
||||||
#Convert CONDITIONAL_FORWARDING_REVERSE if necessary e.g:
|
|
||||||
# 1.1.168.192.in-addr.arpa to 192.168.1.1/32
|
|
||||||
# 1.168.192.in-addr.arpa to 192.168.1.0/24
|
|
||||||
# 168.192.in-addr.arpa to 192.168.0.0/16
|
|
||||||
# 192.in-addr.arpa to 192.0.0.0/8
|
|
||||||
if [[ "${CONDITIONAL_FORWARDING_REVERSE}" == *"in-addr.arpa" ]];then
|
|
||||||
arrRev=("${CONDITIONAL_FORWARDING_REVERSE//./ }")
|
|
||||||
case ${#arrRev[@]} in
|
|
||||||
6 ) REV_SERVER_CIDR="${arrRev[3]}.${arrRev[2]}.${arrRev[1]}.${arrRev[0]}/32";;
|
|
||||||
5 ) REV_SERVER_CIDR="${arrRev[2]}.${arrRev[1]}.${arrRev[0]}.0/24";;
|
|
||||||
4 ) REV_SERVER_CIDR="${arrRev[1]}.${arrRev[0]}.0.0/16";;
|
|
||||||
3 ) REV_SERVER_CIDR="${arrRev[0]}.0.0.0/8";;
|
|
||||||
esac
|
|
||||||
else
|
|
||||||
# Set REV_SERVER_CIDR to whatever value it was set to
|
|
||||||
REV_SERVER_CIDR="${CONDITIONAL_FORWARDING_REVERSE}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# If REV_SERVER_CIDR is not converted by the above, then use the REV_SERVER_TARGET variable to derive it
|
|
||||||
if [ -z "${REV_SERVER_CIDR}" ]; then
|
|
||||||
# Convert existing input to /24 subnet (preserves legacy behavior)
|
|
||||||
# This sed converts "192.168.1.2" to "192.168.1.0/24"
|
|
||||||
# shellcheck disable=2001
|
|
||||||
REV_SERVER_CIDR="$(sed "s+\\.[0-9]*$+\\.0/24+" <<< "${REV_SERVER_TARGET}")"
|
|
||||||
fi
|
|
||||||
addOrEditKeyValPair "${setupVars}" "REV_SERVER_CIDR" "${REV_SERVER_CIDR}"
|
|
||||||
|
|
||||||
# Remove obsolete settings from setupVars.conf
|
|
||||||
removeKey "${setupVars}" "CONDITIONAL_FORWARDING"
|
|
||||||
removeKey "${setupVars}" "CONDITIONAL_FORWARDING_REVERSE"
|
|
||||||
removeKey "${setupVars}" "CONDITIONAL_FORWARDING_DOMAIN"
|
|
||||||
removeKey "${setupVars}" "CONDITIONAL_FORWARDING_IP"
|
|
||||||
fi
|
|
||||||
|
|
||||||
removeKey "${dnsmasqconfig}" "rev-server"
|
|
||||||
|
|
||||||
if [[ "${REV_SERVER}" == true ]]; then
|
|
||||||
addKey "${dnsmasqconfig}" "rev-server=${REV_SERVER_CIDR},${REV_SERVER_TARGET}"
|
|
||||||
if [ -n "${REV_SERVER_DOMAIN}" ]; then
|
|
||||||
# Forward local domain names to the CF target, too
|
|
||||||
addKey "${dnsmasqconfig}" "server=/${REV_SERVER_DOMAIN}/${REV_SERVER_TARGET}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ "${DNS_FQDN_REQUIRED}" != true ]]; then
|
|
||||||
# Forward unqualified names to the CF target only when the "never
|
|
||||||
# forward non-FQDN" option is unticked
|
|
||||||
addKey "${dnsmasqconfig}" "server=//${REV_SERVER_TARGET}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
fi
|
|
||||||
|
|
||||||
# We need to process DHCP settings here as well to account for possible
|
|
||||||
# changes in the non-FQDN forwarding. This cannot be done in 01-pihole.conf
|
|
||||||
# as we don't want to delete all local=/.../ lines so it's much safer to
|
|
||||||
# simply rewrite the entire corresponding config file (which is what the
|
|
||||||
# DHCP settings subroutine is doing)
|
|
||||||
ProcessDHCPSettings
|
|
||||||
}
|
|
||||||
|
|
||||||
SetDNSServers() {
|
|
||||||
# Save setting to file
|
|
||||||
removeKey "${setupVars}" "PIHOLE_DNS"
|
|
||||||
IFS=',' read -r -a array <<< "${args[2]}"
|
|
||||||
for index in "${!array[@]}"
|
|
||||||
do
|
|
||||||
# Replace possible "\#" by "#". This fixes web#1427
|
|
||||||
local ip
|
|
||||||
ip="${array[index]//\\#/#}"
|
|
||||||
|
|
||||||
if valid_ip "${ip}" || valid_ip6 "${ip}" ; then
|
|
||||||
addOrEditKeyValPair "${setupVars}" "PIHOLE_DNS_$((index+1))" "${ip}"
|
|
||||||
else
|
|
||||||
echo -e " ${CROSS} Invalid IP has been passed"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
if [[ "${args[3]}" == "domain-needed" ]]; then
|
|
||||||
addOrEditKeyValPair "${setupVars}" "DNS_FQDN_REQUIRED" "true"
|
|
||||||
else
|
|
||||||
addOrEditKeyValPair "${setupVars}" "DNS_FQDN_REQUIRED" "false"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ "${args[4]}" == "bogus-priv" ]]; then
|
|
||||||
addOrEditKeyValPair "${setupVars}" "DNS_BOGUS_PRIV" "true"
|
|
||||||
else
|
|
||||||
addOrEditKeyValPair "${setupVars}" "DNS_BOGUS_PRIV" "false"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ "${args[5]}" == "dnssec" ]]; then
|
|
||||||
addOrEditKeyValPair "${setupVars}" "DNSSEC" "true"
|
|
||||||
else
|
|
||||||
addOrEditKeyValPair "${setupVars}" "DNSSEC" "false"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ "${args[6]}" == "rev-server" ]]; then
|
|
||||||
addOrEditKeyValPair "${setupVars}" "REV_SERVER" "true"
|
|
||||||
addOrEditKeyValPair "${setupVars}" "REV_SERVER_CIDR" "${args[7]}"
|
|
||||||
addOrEditKeyValPair "${setupVars}" "REV_SERVER_TARGET" "${args[8]}"
|
|
||||||
addOrEditKeyValPair "${setupVars}" "REV_SERVER_DOMAIN" "${args[9]}"
|
|
||||||
else
|
|
||||||
addOrEditKeyValPair "${setupVars}" "REV_SERVER" "false"
|
|
||||||
fi
|
|
||||||
|
|
||||||
ProcessDNSSettings
|
|
||||||
|
|
||||||
# Restart dnsmasq to load new configuration
|
|
||||||
RestartDNS
|
|
||||||
}
|
|
||||||
|
|
||||||
SetExcludeDomains() {
|
|
||||||
addOrEditKeyValPair "${setupVars}" "API_EXCLUDE_DOMAINS" "${args[2]}"
|
|
||||||
}
|
|
||||||
|
|
||||||
SetExcludeClients() {
|
|
||||||
addOrEditKeyValPair "${setupVars}" "API_EXCLUDE_CLIENTS" "${args[2]}"
|
|
||||||
}
|
|
||||||
|
|
||||||
Poweroff(){
|
|
||||||
nohup bash -c "sleep 5; poweroff" &> /dev/null </dev/null &
|
|
||||||
}
|
|
||||||
|
|
||||||
Reboot() {
|
|
||||||
nohup bash -c "sleep 5; reboot" &> /dev/null </dev/null &
|
|
||||||
}
|
|
||||||
|
|
||||||
RestartDNS() {
|
|
||||||
"${PI_HOLE_BIN_DIR}"/pihole restartdns
|
|
||||||
}
|
|
||||||
|
|
||||||
SetQueryLogOptions() {
|
|
||||||
addOrEditKeyValPair "${setupVars}" "API_QUERY_LOG_SHOW" "${args[2]}"
|
|
||||||
}
|
|
||||||
|
|
||||||
ProcessDHCPSettings() {
|
|
||||||
source "${setupVars}"
|
|
||||||
|
|
||||||
if [[ "${DHCP_ACTIVE}" == "true" ]]; then
|
|
||||||
interface="${PIHOLE_INTERFACE}"
|
|
||||||
|
|
||||||
# Use eth0 as fallback interface
|
|
||||||
if [ -z ${interface} ]; then
|
|
||||||
interface="eth0"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ "${PIHOLE_DOMAIN}" == "" ]]; then
|
|
||||||
PIHOLE_DOMAIN="lan"
|
|
||||||
addOrEditKeyValPair "${setupVars}" "PIHOLE_DOMAIN" "${PIHOLE_DOMAIN}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ "${DHCP_LEASETIME}" == "0" ]]; then
|
|
||||||
leasetime="infinite"
|
|
||||||
elif [[ "${DHCP_LEASETIME}" == "" ]]; then
|
|
||||||
leasetime="24h"
|
|
||||||
addOrEditKeyValPair "${setupVars}" "DHCP_LEASETIME" "24"
|
|
||||||
else
|
|
||||||
leasetime="${DHCP_LEASETIME}h"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Write settings to file
|
|
||||||
echo "###############################################################################
|
|
||||||
# DHCP SERVER CONFIG FILE AUTOMATICALLY POPULATED BY PI-HOLE WEB INTERFACE. #
|
|
||||||
# ANY CHANGES MADE TO THIS FILE WILL BE LOST ON CHANGE #
|
|
||||||
###############################################################################
|
|
||||||
dhcp-authoritative
|
|
||||||
dhcp-range=${DHCP_START},${DHCP_END},${leasetime}
|
|
||||||
dhcp-option=option:router,${DHCP_ROUTER}
|
|
||||||
dhcp-leasefile=/etc/pihole/dhcp.leases
|
|
||||||
#quiet-dhcp
|
|
||||||
" > "${dhcpconfig}"
|
|
||||||
chmod 644 "${dhcpconfig}"
|
|
||||||
|
|
||||||
if [[ "${PIHOLE_DOMAIN}" != "none" ]]; then
|
|
||||||
echo "domain=${PIHOLE_DOMAIN}" >> "${dhcpconfig}"
|
|
||||||
|
|
||||||
# When there is a Pi-hole domain set and "Never forward non-FQDNs" is
|
|
||||||
# ticked, we add `local=/domain/` to tell FTL that this domain is purely
|
|
||||||
# local and FTL may answer queries from /etc/hosts or DHCP but should
|
|
||||||
# never forward queries on that domain to any upstream servers
|
|
||||||
if [[ "${DNS_FQDN_REQUIRED}" == true ]]; then
|
|
||||||
echo "local=/${PIHOLE_DOMAIN}/" >> "${dhcpconfig}"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Sourced from setupVars
|
|
||||||
# shellcheck disable=SC2154
|
|
||||||
if [[ "${DHCP_rapid_commit}" == "true" ]]; then
|
|
||||||
echo "dhcp-rapid-commit" >> "${dhcpconfig}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ "${DHCP_IPv6}" == "true" ]]; then
|
|
||||||
echo "#quiet-dhcp6
|
|
||||||
#enable-ra
|
|
||||||
dhcp-option=option6:dns-server,[::]
|
|
||||||
dhcp-range=::,constructor:${interface},ra-names,ra-stateless,64
|
|
||||||
|
|
||||||
" >> "${dhcpconfig}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
else
|
|
||||||
if [[ -f "${dhcpconfig}" ]]; then
|
|
||||||
rm "${dhcpconfig}" &> /dev/null
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
EnableDHCP() {
|
|
||||||
addOrEditKeyValPair "${setupVars}" "DHCP_ACTIVE" "true"
|
|
||||||
addOrEditKeyValPair "${setupVars}" "DHCP_START" "${args[2]}"
|
|
||||||
addOrEditKeyValPair "${setupVars}" "DHCP_END" "${args[3]}"
|
|
||||||
addOrEditKeyValPair "${setupVars}" "DHCP_ROUTER" "${args[4]}"
|
|
||||||
addOrEditKeyValPair "${setupVars}" "DHCP_LEASETIME" "${args[5]}"
|
|
||||||
addOrEditKeyValPair "${setupVars}" "PIHOLE_DOMAIN" "${args[6]}"
|
|
||||||
addOrEditKeyValPair "${setupVars}" "DHCP_IPv6" "${args[7]}"
|
|
||||||
addOrEditKeyValPair "${setupVars}" "DHCP_rapid_commit" "${args[8]}"
|
|
||||||
|
|
||||||
# Remove possible old setting from file
|
|
||||||
removeKey "${dnsmasqconfig}" "dhcp-"
|
|
||||||
removeKey "${dnsmasqconfig}" "quiet-dhcp"
|
|
||||||
|
|
||||||
# If a DHCP client claims that its name is "wpad", ignore that.
|
|
||||||
# This fixes a security hole. see CERT Vulnerability VU#598349
|
|
||||||
# We also ignore "localhost" as Windows behaves strangely if a
|
|
||||||
# device claims this host name
|
|
||||||
addKey "${dnsmasqconfig}" "dhcp-name-match=set:hostname-ignore,wpad
|
|
||||||
dhcp-name-match=set:hostname-ignore,localhost
|
|
||||||
dhcp-ignore-names=tag:hostname-ignore"
|
|
||||||
|
|
||||||
ProcessDHCPSettings
|
|
||||||
|
|
||||||
RestartDNS
|
|
||||||
}
|
|
||||||
|
|
||||||
DisableDHCP() {
|
|
||||||
addOrEditKeyValPair "${setupVars}" "DHCP_ACTIVE" "false"
|
|
||||||
|
|
||||||
# Remove possible old setting from file
|
|
||||||
removeKey "${dnsmasqconfig}" "dhcp-"
|
|
||||||
removeKey "${dnsmasqconfig}" "quiet-dhcp"
|
|
||||||
|
|
||||||
ProcessDHCPSettings
|
|
||||||
|
|
||||||
RestartDNS
|
|
||||||
}
|
|
||||||
|
|
||||||
SetWebUILayout() {
|
|
||||||
addOrEditKeyValPair "${setupVars}" "WEBUIBOXEDLAYOUT" "${args[2]}"
|
|
||||||
}
|
|
||||||
|
|
||||||
SetWebUITheme() {
|
|
||||||
addOrEditKeyValPair "${setupVars}" "WEBTHEME" "${args[2]}"
|
|
||||||
}
|
|
||||||
|
|
||||||
CheckUrl(){
|
|
||||||
local regex check_url
|
|
||||||
# Check for characters NOT allowed in URLs
|
|
||||||
regex="[^a-zA-Z0-9:/?&%=~._()-;]"
|
|
||||||
|
|
||||||
# this will remove first @ that is after schema and before domain
|
|
||||||
# \1 is optional schema, \2 is userinfo
|
|
||||||
check_url="$( sed -re 's#([^:/]*://)?([^/]+)@#\1\2#' <<< "$1" )"
|
|
||||||
|
|
||||||
if [[ "${check_url}" =~ ${regex} ]]; then
|
|
||||||
return 1
|
|
||||||
else
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
CustomizeAdLists() {
|
|
||||||
local address
|
|
||||||
address="${args[3]}"
|
|
||||||
local comment
|
|
||||||
comment="${args[4]}"
|
|
||||||
|
|
||||||
if CheckUrl "${address}"; then
|
|
||||||
if [[ "${args[2]}" == "enable" ]]; then
|
|
||||||
pihole-FTL sqlite3 -ni "${gravityDBfile}" "UPDATE adlist SET enabled = 1 WHERE address = '${address}'"
|
|
||||||
elif [[ "${args[2]}" == "disable" ]]; then
|
|
||||||
pihole-FTL sqlite3 -ni "${gravityDBfile}" "UPDATE adlist SET enabled = 0 WHERE address = '${address}'"
|
|
||||||
elif [[ "${args[2]}" == "add" ]]; then
|
|
||||||
pihole-FTL sqlite3 -ni "${gravityDBfile}" "INSERT OR IGNORE INTO adlist (address, comment) VALUES ('${address}', '${comment}')"
|
|
||||||
elif [[ "${args[2]}" == "del" ]]; then
|
|
||||||
pihole-FTL sqlite3 -ni "${gravityDBfile}" "DELETE FROM adlist WHERE address = '${address}'"
|
|
||||||
else
|
|
||||||
echo "Not permitted"
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
echo "Invalid Url"
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
AddDHCPStaticAddress() {
|
|
||||||
mac="${args[2]}"
|
|
||||||
ip="${args[3]}"
|
|
||||||
host="${args[4]}"
|
|
||||||
|
|
||||||
if [[ "${ip}" == "noip" ]]; then
|
|
||||||
# Static host name
|
|
||||||
echo "dhcp-host=${mac},${host}" >> "${dhcpstaticconfig}"
|
|
||||||
elif [[ "${host}" == "nohost" ]]; then
|
|
||||||
# Static IP
|
|
||||||
echo "dhcp-host=${mac},${ip}" >> "${dhcpstaticconfig}"
|
|
||||||
else
|
|
||||||
# Full info given
|
|
||||||
echo "dhcp-host=${mac},${ip},${host}" >> "${dhcpstaticconfig}"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
RemoveDHCPStaticAddress() {
|
|
||||||
mac="${args[2]}"
|
|
||||||
if [[ "$mac" =~ ^([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})$ ]]; then
|
|
||||||
sed -i "/dhcp-host=${mac}.*/d" "${dhcpstaticconfig}"
|
|
||||||
else
|
|
||||||
echo " ${CROSS} Invalid Mac Passed!"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
SetListeningMode() {
|
|
||||||
source "${setupVars}"
|
|
||||||
|
|
||||||
if [[ "$3" == "-h" ]] || [[ "$3" == "--help" ]]; then
|
|
||||||
echo "Usage: pihole -a -i [interface]
|
|
||||||
Example: 'pihole -a -i local'
|
|
||||||
Specify dnsmasq's network interface listening behavior
|
|
||||||
|
|
||||||
Interfaces:
|
|
||||||
local Only respond to queries from devices that
|
|
||||||
are at most one hop away (local devices)
|
|
||||||
single Respond only on interface ${PIHOLE_INTERFACE}
|
|
||||||
bind Bind only on interface ${PIHOLE_INTERFACE}
|
|
||||||
all Listen on all interfaces, permit all origins"
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ "${args[2]}" == "all" ]]; then
|
|
||||||
echo -e " ${INFO} Listening on all interfaces, permitting all origins. Please use a firewall!"
|
|
||||||
addOrEditKeyValPair "${setupVars}" "DNSMASQ_LISTENING" "all"
|
|
||||||
elif [[ "${args[2]}" == "local" ]]; then
|
|
||||||
echo -e " ${INFO} Listening on all interfaces, permitting origins from one hop away (LAN)"
|
|
||||||
addOrEditKeyValPair "${setupVars}" "DNSMASQ_LISTENING" "local"
|
|
||||||
elif [[ "${args[2]}" == "bind" ]]; then
|
|
||||||
echo -e " ${INFO} Binding on interface ${PIHOLE_INTERFACE}"
|
|
||||||
addOrEditKeyValPair "${setupVars}" "DNSMASQ_LISTENING" "bind"
|
|
||||||
else
|
|
||||||
echo -e " ${INFO} Listening only on interface ${PIHOLE_INTERFACE}"
|
|
||||||
addOrEditKeyValPair "${setupVars}" "DNSMASQ_LISTENING" "single"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Don't restart DNS server yet because other settings
|
|
||||||
# will be applied afterwards if "-web" is set
|
|
||||||
if [[ "${args[3]}" != "-web" ]]; then
|
|
||||||
ProcessDNSSettings
|
|
||||||
# Restart dnsmasq to load new configuration
|
|
||||||
RestartDNS
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
Teleporter() {
|
|
||||||
local filename
|
|
||||||
filename="${args[2]}"
|
|
||||||
if [[ -z "${filename}" ]]; then
|
|
||||||
local datetimestamp
|
|
||||||
local host
|
|
||||||
datetimestamp=$(date "+%Y-%m-%d_%H-%M-%S")
|
|
||||||
host=$(hostname)
|
|
||||||
host="${host//./_}"
|
|
||||||
filename="pi-hole-${host:-noname}-teleporter_${datetimestamp}.tar.gz"
|
|
||||||
fi
|
|
||||||
php "${webroot}/admin/scripts/pi-hole/php/teleporter.php" > "${filename}"
|
|
||||||
}
|
|
||||||
|
|
||||||
checkDomain()
|
|
||||||
{
|
|
||||||
local domain validDomain
|
|
||||||
# Convert to lowercase
|
|
||||||
domain="${1,,}"
|
|
||||||
validDomain=$(grep -P "^((-|_)*[a-z0-9]((-|_)*[a-z0-9])*(-|_)*)(\\.(-|_)*([a-z0-9]((-|_)*[a-z0-9])*))*$" <<< "${domain}") # Valid chars check
|
|
||||||
validDomain=$(grep -P "^[^\\.]{1,63}(\\.[^\\.]{1,63})*$" <<< "${validDomain}") # Length of each label
|
|
||||||
echo "${validDomain}"
|
|
||||||
}
|
|
||||||
|
|
||||||
escapeDots()
|
|
||||||
{
|
|
||||||
# SC suggest bashism ${variable//search/replace}
|
|
||||||
# shellcheck disable=SC2001
|
|
||||||
escaped=$(echo "$1" | sed 's/\./\\./g')
|
|
||||||
echo "${escaped}"
|
|
||||||
}
|
|
||||||
|
|
||||||
addAudit()
|
|
||||||
{
|
|
||||||
shift # skip "-a"
|
|
||||||
shift # skip "audit"
|
|
||||||
local domains validDomain
|
|
||||||
domains=""
|
|
||||||
for domain in "$@"
|
|
||||||
do
|
|
||||||
# Check domain to be added. Only continue if it is valid
|
|
||||||
validDomain="$(checkDomain "${domain}")"
|
|
||||||
if [[ -n "${validDomain}" ]]; then
|
|
||||||
# Put comma in between domains when there is
|
|
||||||
# more than one domains to be added
|
|
||||||
# SQL INSERT allows adding multiple rows at once using the format
|
|
||||||
## INSERT INTO table (domain) VALUES ('abc.de'),('fgh.ij'),('klm.no'),('pqr.st');
|
|
||||||
if [[ -n "${domains}" ]]; then
|
|
||||||
domains="${domains},"
|
|
||||||
fi
|
|
||||||
domains="${domains}('${domain}')"
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
# Insert only the domain here. The date_added field will be
|
|
||||||
# filled with its default value (date_added = current timestamp)
|
|
||||||
pihole-FTL sqlite3 -ni "${gravityDBfile}" "INSERT INTO domain_audit (domain) VALUES ${domains};"
|
|
||||||
}
|
|
||||||
|
|
||||||
clearAudit()
|
|
||||||
{
|
|
||||||
pihole-FTL sqlite3 -ni "${gravityDBfile}" "DELETE FROM domain_audit;"
|
|
||||||
}
|
|
||||||
|
|
||||||
SetPrivacyLevel() {
|
|
||||||
# Set privacy level. Minimum is 0, maximum is 3
|
|
||||||
if [ "${args[2]}" -ge 0 ] && [ "${args[2]}" -le 3 ]; then
|
|
||||||
addOrEditKeyValPair "${FTLconf}" "PRIVACYLEVEL" "${args[2]}"
|
|
||||||
pihole restartdns reload-lists
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
AddCustomDNSAddress() {
|
|
||||||
echo -e " ${TICK} Adding custom DNS entry..."
|
|
||||||
|
|
||||||
ip="${args[2]}"
|
|
||||||
host="${args[3]}"
|
|
||||||
reload="${args[4]}"
|
|
||||||
|
|
||||||
validHost="$(checkDomain "${host}")"
|
|
||||||
if [[ -n "${validHost}" ]]; then
|
|
||||||
if valid_ip "${ip}" || valid_ip6 "${ip}" ; then
|
|
||||||
echo "${ip} ${validHost}" >> "${dnscustomfile}"
|
|
||||||
else
|
|
||||||
echo -e " ${CROSS} Invalid IP has been passed"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
echo " ${CROSS} Invalid Domain passed!"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Restart dnsmasq to load new custom DNS entries only if $reload not false
|
|
||||||
if [[ ! $reload == "false" ]]; then
|
|
||||||
RestartDNS
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
RemoveCustomDNSAddress() {
|
|
||||||
echo -e " ${TICK} Removing custom DNS entry..."
|
|
||||||
|
|
||||||
ip="${args[2]}"
|
|
||||||
host="${args[3]}"
|
|
||||||
reload="${args[4]}"
|
|
||||||
|
|
||||||
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"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
echo " ${CROSS} Invalid Domain passed!"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Restart dnsmasq to load new custom DNS entries only if reload is not false
|
|
||||||
if [[ ! $reload == "false" ]]; then
|
|
||||||
RestartDNS
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
AddCustomCNAMERecord() {
|
|
||||||
echo -e " ${TICK} Adding custom CNAME record..."
|
|
||||||
|
|
||||||
domain="${args[2]}"
|
|
||||||
target="${args[3]}"
|
|
||||||
reload="${args[4]}"
|
|
||||||
|
|
||||||
validDomain="$(checkDomain "${domain}")"
|
|
||||||
if [[ -n "${validDomain}" ]]; then
|
|
||||||
validTarget="$(checkDomain "${target}")"
|
|
||||||
if [[ -n "${validTarget}" ]]; then
|
|
||||||
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
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
echo " ${CROSS} Invalid Domain passed!"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
# Restart dnsmasq to load new custom CNAME records only if reload is not false
|
|
||||||
if [[ ! $reload == "false" ]]; then
|
|
||||||
RestartDNS
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
RemoveCustomCNAMERecord() {
|
|
||||||
echo -e " ${TICK} Removing custom CNAME record..."
|
|
||||||
|
|
||||||
domain="${args[2]}"
|
|
||||||
target="${args[3]}"
|
|
||||||
reload="${args[4]}"
|
|
||||||
|
|
||||||
validDomain="$(checkDomain "${domain}")"
|
|
||||||
if [[ -n "${validDomain}" ]]; then
|
|
||||||
validTarget="$(checkDomain "${target}")"
|
|
||||||
if [[ -n "${validTarget}" ]]; then
|
|
||||||
validDomain=$(escapeDots "${validDomain}")
|
|
||||||
validTarget=$(escapeDots "${validTarget}")
|
|
||||||
sed -i "/^cname=${validDomain},${validTarget}$/Id" "${dnscustomcnamefile}"
|
|
||||||
else
|
|
||||||
echo " ${CROSS} Invalid Target Passed!"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
echo " ${CROSS} Invalid Domain passed!"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Restart dnsmasq to update removed custom CNAME records only if $reload not false
|
|
||||||
if [[ ! $reload == "false" ]]; then
|
|
||||||
RestartDNS
|
|
||||||
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
|
|
||||||
addOrEditKeyValPair "${FTLconf}" "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=("$@")
|
|
||||||
|
|
||||||
case "${args[1]}" in
|
|
||||||
"-p" | "password" ) SetWebPassword;;
|
|
||||||
"-c" | "celsius" ) unit="C"; SetTemperatureUnit;;
|
|
||||||
"-f" | "fahrenheit" ) unit="F"; SetTemperatureUnit;;
|
|
||||||
"-k" | "kelvin" ) unit="K"; SetTemperatureUnit;;
|
|
||||||
"setdns" ) SetDNSServers;;
|
|
||||||
"setexcludedomains" ) SetExcludeDomains;;
|
|
||||||
"setexcludeclients" ) SetExcludeClients;;
|
|
||||||
"poweroff" ) Poweroff;;
|
|
||||||
"reboot" ) Reboot;;
|
|
||||||
"restartdns" ) RestartDNS;;
|
|
||||||
"setquerylog" ) SetQueryLogOptions;;
|
|
||||||
"enabledhcp" ) EnableDHCP;;
|
|
||||||
"disabledhcp" ) DisableDHCP;;
|
|
||||||
"layout" ) SetWebUILayout;;
|
|
||||||
"theme" ) SetWebUITheme;;
|
|
||||||
"-h" | "--help" ) helpFunc;;
|
|
||||||
"addstaticdhcp" ) AddDHCPStaticAddress;;
|
|
||||||
"removestaticdhcp" ) RemoveDHCPStaticAddress;;
|
|
||||||
"-i" | "interface" ) SetListeningMode "$@";;
|
|
||||||
"-t" | "teleporter" ) Teleporter;;
|
|
||||||
"adlist" ) CustomizeAdLists;;
|
|
||||||
"audit" ) addAudit "$@";;
|
|
||||||
"clearaudit" ) clearAudit;;
|
|
||||||
"-l" | "privacylevel" ) SetPrivacyLevel;;
|
|
||||||
"addcustomdns" ) AddCustomDNSAddress;;
|
|
||||||
"removecustomdns" ) RemoveCustomDNSAddress;;
|
|
||||||
"addcustomcname" ) AddCustomCNAMERecord;;
|
|
||||||
"removecustomcname" ) RemoveCustomCNAMERecord;;
|
|
||||||
"ratelimit" ) SetRateLimit;;
|
|
||||||
* ) helpFunc;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
shift
|
|
||||||
|
|
||||||
if [[ $# = 0 ]]; then
|
|
||||||
helpFunc
|
|
||||||
fi
|
|
||||||
}
|
|
@ -1,9 +0,0 @@
|
|||||||
# Pi-hole: A black hole for Internet advertisements
|
|
||||||
# (c) 2017 Pi-hole, LLC (https://pi-hole.net)
|
|
||||||
# Network-wide ad blocking via your own hardware.
|
|
||||||
#
|
|
||||||
# Allows the WebUI to use Pi-hole commands
|
|
||||||
#
|
|
||||||
# This file is copyright under the latest version of the EUPL.
|
|
||||||
# Please see LICENSE file for your rights under this license.
|
|
||||||
#
|
|
@ -1,648 +0,0 @@
|
|||||||
# Configuration file for dnsmasq.
|
|
||||||
#
|
|
||||||
# Format is one option per line, legal options are the same
|
|
||||||
# as the long options legal on the command line. See
|
|
||||||
# "/usr/sbin/dnsmasq --help" or "man 8 dnsmasq" for details.
|
|
||||||
|
|
||||||
# Listen on this specific port instead of the standard DNS port
|
|
||||||
# (53). Setting this to zero completely disables DNS function,
|
|
||||||
# leaving only DHCP and/or TFTP.
|
|
||||||
#port=5353
|
|
||||||
|
|
||||||
# The following two options make you a better netizen, since they
|
|
||||||
# tell dnsmasq to filter out queries which the public DNS cannot
|
|
||||||
# answer, and which load the servers (especially the root servers)
|
|
||||||
# unnecessarily. If you have a dial-on-demand link they also stop
|
|
||||||
# these requests from bringing up the link unnecessarily.
|
|
||||||
|
|
||||||
# Never forward plain names (without a dot or domain part)
|
|
||||||
#domain-needed
|
|
||||||
# Never forward addresses in the non-routed address spaces.
|
|
||||||
#bogus-priv
|
|
||||||
|
|
||||||
# Uncomment these to enable DNSSEC validation and caching:
|
|
||||||
# (Requires dnsmasq to be built with DNSSEC option.)
|
|
||||||
#conf-file=%%PREFIX%%/share/dnsmasq/trust-anchors.conf
|
|
||||||
#dnssec
|
|
||||||
|
|
||||||
# Replies which are not DNSSEC signed may be legitimate, because the domain
|
|
||||||
# is unsigned, or may be forgeries. Setting this option tells dnsmasq to
|
|
||||||
# check that an unsigned reply is OK, by finding a secure proof that a DS
|
|
||||||
# record somewhere between the root and the domain does not exist.
|
|
||||||
# The cost of setting this is that even queries in unsigned domains will need
|
|
||||||
# one or more extra DNS queries to verify.
|
|
||||||
#dnssec-check-unsigned
|
|
||||||
|
|
||||||
# Uncomment this to filter useless windows-originated DNS requests
|
|
||||||
# which can trigger dial-on-demand links needlessly.
|
|
||||||
# Note that (amongst other things) this blocks all SRV requests,
|
|
||||||
# so don't use it if you use eg Kerberos, SIP, XMMP or Google-talk.
|
|
||||||
# This option only affects forwarding, SRV records originating for
|
|
||||||
# dnsmasq (via srv-host= lines) are not suppressed by it.
|
|
||||||
#filterwin2k
|
|
||||||
|
|
||||||
# Change this line if you want dns to get its upstream servers from
|
|
||||||
# somewhere other that /etc/resolv.conf
|
|
||||||
#resolv-file=
|
|
||||||
|
|
||||||
# By default, dnsmasq will send queries to any of the upstream
|
|
||||||
# servers it knows about and tries to favor servers to are known
|
|
||||||
# to be up. Uncommenting this forces dnsmasq to try each query
|
|
||||||
# with each server strictly in the order they appear in
|
|
||||||
# /etc/resolv.conf
|
|
||||||
#strict-order
|
|
||||||
|
|
||||||
# If you don't want dnsmasq to read /etc/resolv.conf or any other
|
|
||||||
# file, getting its servers from this file instead (see below), then
|
|
||||||
# uncomment this.
|
|
||||||
#no-resolv
|
|
||||||
|
|
||||||
# If you don't want dnsmasq to poll /etc/resolv.conf or other resolv
|
|
||||||
# files for changes and re-read them then uncomment this.
|
|
||||||
#no-poll
|
|
||||||
|
|
||||||
# Add other name servers here, with domain specs if they are for
|
|
||||||
# non-public domains.
|
|
||||||
#server=/localnet/192.168.0.1
|
|
||||||
|
|
||||||
# Example of routing PTR queries to nameservers: this will send all
|
|
||||||
# address->name queries for 192.168.3/24 to nameserver 10.1.2.3
|
|
||||||
#server=/3.168.192.in-addr.arpa/10.1.2.3
|
|
||||||
|
|
||||||
# Add local-only domains here, queries in these domains are answered
|
|
||||||
# from /etc/hosts or DHCP only.
|
|
||||||
#local=/localnet/
|
|
||||||
|
|
||||||
# Add domains which you want to force to an IP address here.
|
|
||||||
# The example below send any host in double-click.net to a local
|
|
||||||
# web-server.
|
|
||||||
#address=/double-click.net/127.0.0.1
|
|
||||||
|
|
||||||
# --address (and --server) work with IPv6 addresses too.
|
|
||||||
#address=/www.thekelleys.org.uk/fe80::20d:60ff:fe36:f83
|
|
||||||
|
|
||||||
# Add the IPs of all queries to yahoo.com, google.com, and their
|
|
||||||
# subdomains to the vpn and search ipsets:
|
|
||||||
#ipset=/yahoo.com/google.com/vpn,search
|
|
||||||
|
|
||||||
# You can control how dnsmasq talks to a server: this forces
|
|
||||||
# queries to 10.1.2.3 to be routed via eth1
|
|
||||||
# server=10.1.2.3@eth1
|
|
||||||
|
|
||||||
# and this sets the source (ie local) address used to talk to
|
|
||||||
# 10.1.2.3 to 192.168.1.1 port 55 (there must be a interface with that
|
|
||||||
# IP on the machine, obviously).
|
|
||||||
# server=10.1.2.3@192.168.1.1#55
|
|
||||||
|
|
||||||
# If you want dnsmasq to change uid and gid to something other
|
|
||||||
# than the default, edit the following lines.
|
|
||||||
#user=
|
|
||||||
#group=
|
|
||||||
|
|
||||||
# If you want dnsmasq to listen for DHCP and DNS requests only on
|
|
||||||
# specified interfaces (and the loopback) give the name of the
|
|
||||||
# interface (eg eth0) here.
|
|
||||||
# Repeat the line for more than one interface.
|
|
||||||
#interface=
|
|
||||||
# Or you can specify which interface _not_ to listen on
|
|
||||||
#except-interface=
|
|
||||||
# Or which to listen on by address (remember to include 127.0.0.1 if
|
|
||||||
# you use this.)
|
|
||||||
#listen-address=
|
|
||||||
# If you want dnsmasq to provide only DNS service on an interface,
|
|
||||||
# configure it as shown above, and then use the following line to
|
|
||||||
# disable DHCP and TFTP on it.
|
|
||||||
#no-dhcp-interface=
|
|
||||||
|
|
||||||
# On systems which support it, dnsmasq binds the wildcard address,
|
|
||||||
# even when it is listening on only some interfaces. It then discards
|
|
||||||
# requests that it shouldn't reply to. This has the advantage of
|
|
||||||
# working even when interfaces come and go and change address. If you
|
|
||||||
# want dnsmasq to really bind only the interfaces it is listening on,
|
|
||||||
# uncomment this option. About the only time you may need this is when
|
|
||||||
# running another nameserver on the same machine.
|
|
||||||
#bind-interfaces
|
|
||||||
|
|
||||||
# If you don't want dnsmasq to read /etc/hosts, uncomment the
|
|
||||||
# following line.
|
|
||||||
#no-hosts
|
|
||||||
# or if you want it to read another file, as well as /etc/hosts, use
|
|
||||||
# this.
|
|
||||||
#addn-hosts=/etc/banner_add_hosts
|
|
||||||
|
|
||||||
# Set this (and domain: see below) if you want to have a domain
|
|
||||||
# automatically added to simple names in a hosts-file.
|
|
||||||
#expand-hosts
|
|
||||||
|
|
||||||
# Set the domain for dnsmasq. this is optional, but if it is set, it
|
|
||||||
# does the following things.
|
|
||||||
# 1) Allows DHCP hosts to have fully qualified domain names, as long
|
|
||||||
# as the domain part matches this setting.
|
|
||||||
# 2) Sets the "domain" DHCP option thereby potentially setting the
|
|
||||||
# domain of all systems configured by DHCP
|
|
||||||
# 3) Provides the domain part for "expand-hosts"
|
|
||||||
#domain=thekelleys.org.uk
|
|
||||||
|
|
||||||
# Set a different domain for a particular subnet
|
|
||||||
#domain=wireless.thekelleys.org.uk,192.168.2.0/24
|
|
||||||
|
|
||||||
# Same idea, but range rather then subnet
|
|
||||||
#domain=reserved.thekelleys.org.uk,192.68.3.100,192.168.3.200
|
|
||||||
|
|
||||||
# Uncomment this to enable the integrated DHCP server, you need
|
|
||||||
# to supply the range of addresses available for lease and optionally
|
|
||||||
# a lease time. If you have more than one network, you will need to
|
|
||||||
# repeat this for each network on which you want to supply DHCP
|
|
||||||
# service.
|
|
||||||
#dhcp-range=192.168.0.50,192.168.0.150,12h
|
|
||||||
|
|
||||||
# This is an example of a DHCP range where the netmask is given. This
|
|
||||||
# is needed for networks we reach the dnsmasq DHCP server via a relay
|
|
||||||
# agent. If you don't know what a DHCP relay agent is, you probably
|
|
||||||
# don't need to worry about this.
|
|
||||||
#dhcp-range=192.168.0.50,192.168.0.150,255.255.255.0,12h
|
|
||||||
|
|
||||||
# This is an example of a DHCP range which sets a tag, so that
|
|
||||||
# some DHCP options may be set only for this network.
|
|
||||||
#dhcp-range=set:red,192.168.0.50,192.168.0.150
|
|
||||||
|
|
||||||
# Use this DHCP range only when the tag "green" is set.
|
|
||||||
#dhcp-range=tag:green,192.168.0.50,192.168.0.150,12h
|
|
||||||
|
|
||||||
# Specify a subnet which can't be used for dynamic address allocation,
|
|
||||||
# is available for hosts with matching --dhcp-host lines. Note that
|
|
||||||
# dhcp-host declarations will be ignored unless there is a dhcp-range
|
|
||||||
# of some type for the subnet in question.
|
|
||||||
# In this case the netmask is implied (it comes from the network
|
|
||||||
# configuration on the machine running dnsmasq) it is possible to give
|
|
||||||
# an explicit netmask instead.
|
|
||||||
#dhcp-range=192.168.0.0,static
|
|
||||||
|
|
||||||
# Enable DHCPv6. Note that the prefix-length does not need to be specified
|
|
||||||
# and defaults to 64 if missing/
|
|
||||||
#dhcp-range=1234::2, 1234::500, 64, 12h
|
|
||||||
|
|
||||||
# Do Router Advertisements, BUT NOT DHCP for this subnet.
|
|
||||||
#dhcp-range=1234::, ra-only
|
|
||||||
|
|
||||||
# Do Router Advertisements, BUT NOT DHCP for this subnet, also try and
|
|
||||||
# add names to the DNS for the IPv6 address of SLAAC-configured dual-stack
|
|
||||||
# hosts. Use the DHCPv4 lease to derive the name, network segment and
|
|
||||||
# MAC address and assume that the host will also have an
|
|
||||||
# IPv6 address calculated using the SLAAC algorithm.
|
|
||||||
#dhcp-range=1234::, ra-names
|
|
||||||
|
|
||||||
# Do Router Advertisements, BUT NOT DHCP for this subnet.
|
|
||||||
# Set the lifetime to 46 hours. (Note: minimum lifetime is 2 hours.)
|
|
||||||
#dhcp-range=1234::, ra-only, 48h
|
|
||||||
|
|
||||||
# Do DHCP and Router Advertisements for this subnet. Set the A bit in the RA
|
|
||||||
# so that clients can use SLAAC addresses as well as DHCP ones.
|
|
||||||
#dhcp-range=1234::2, 1234::500, slaac
|
|
||||||
|
|
||||||
# Do Router Advertisements and stateless DHCP for this subnet. Clients will
|
|
||||||
# not get addresses from DHCP, but they will get other configuration information.
|
|
||||||
# They will use SLAAC for addresses.
|
|
||||||
#dhcp-range=1234::, ra-stateless
|
|
||||||
|
|
||||||
# Do stateless DHCP, SLAAC, and generate DNS names for SLAAC addresses
|
|
||||||
# from DHCPv4 leases.
|
|
||||||
#dhcp-range=1234::, ra-stateless, ra-names
|
|
||||||
|
|
||||||
# Do router advertisements for all subnets where we're doing DHCPv6
|
|
||||||
# Unless overridden by ra-stateless, ra-names, et al, the router
|
|
||||||
# advertisements will have the M and O bits set, so that the clients
|
|
||||||
# get addresses and configuration from DHCPv6, and the A bit reset, so the
|
|
||||||
# clients don't use SLAAC addresses.
|
|
||||||
#enable-ra
|
|
||||||
|
|
||||||
# Supply parameters for specified hosts using DHCP. There are lots
|
|
||||||
# of valid alternatives, so we will give examples of each. Note that
|
|
||||||
# IP addresses DO NOT have to be in the range given above, they just
|
|
||||||
# need to be on the same network. The order of the parameters in these
|
|
||||||
# do not matter, it's permissible to give name, address and MAC in any
|
|
||||||
# order.
|
|
||||||
|
|
||||||
# Always allocate the host with Ethernet address 11:22:33:44:55:66
|
|
||||||
# The IP address 192.168.0.60
|
|
||||||
#dhcp-host=11:22:33:44:55:66,192.168.0.60
|
|
||||||
|
|
||||||
# Always set the name of the host with hardware address
|
|
||||||
# 11:22:33:44:55:66 to be "fred"
|
|
||||||
#dhcp-host=11:22:33:44:55:66,fred
|
|
||||||
|
|
||||||
# Always give the host with Ethernet address 11:22:33:44:55:66
|
|
||||||
# the name fred and IP address 192.168.0.60 and lease time 45 minutes
|
|
||||||
#dhcp-host=11:22:33:44:55:66,fred,192.168.0.60,45m
|
|
||||||
|
|
||||||
# Give a host with Ethernet address 11:22:33:44:55:66 or
|
|
||||||
# 12:34:56:78:90:12 the IP address 192.168.0.60. Dnsmasq will assume
|
|
||||||
# that these two Ethernet interfaces will never be in use at the same
|
|
||||||
# time, and give the IP address to the second, even if it is already
|
|
||||||
# in use by the first. Useful for laptops with wired and wireless
|
|
||||||
# addresses.
|
|
||||||
#dhcp-host=11:22:33:44:55:66,12:34:56:78:90:12,192.168.0.60
|
|
||||||
|
|
||||||
# Give the machine which says its name is "bert" IP address
|
|
||||||
# 192.168.0.70 and an infinite lease
|
|
||||||
#dhcp-host=bert,192.168.0.70,infinite
|
|
||||||
|
|
||||||
# Always give the host with client identifier 01:02:02:04
|
|
||||||
# the IP address 192.168.0.60
|
|
||||||
#dhcp-host=id:01:02:02:04,192.168.0.60
|
|
||||||
|
|
||||||
# Always give the host with client identifier "marjorie"
|
|
||||||
# the IP address 192.168.0.60
|
|
||||||
#dhcp-host=id:marjorie,192.168.0.60
|
|
||||||
|
|
||||||
# Enable the address given for "judge" in /etc/hosts
|
|
||||||
# to be given to a machine presenting the name "judge" when
|
|
||||||
# it asks for a DHCP lease.
|
|
||||||
#dhcp-host=judge
|
|
||||||
|
|
||||||
# Never offer DHCP service to a machine whose Ethernet
|
|
||||||
# address is 11:22:33:44:55:66
|
|
||||||
#dhcp-host=11:22:33:44:55:66,ignore
|
|
||||||
|
|
||||||
# Ignore any client-id presented by the machine with Ethernet
|
|
||||||
# address 11:22:33:44:55:66. This is useful to prevent a machine
|
|
||||||
# being treated differently when running under different OS's or
|
|
||||||
# between PXE boot and OS boot.
|
|
||||||
#dhcp-host=11:22:33:44:55:66,id:*
|
|
||||||
|
|
||||||
# Send extra options which are tagged as "red" to
|
|
||||||
# the machine with Ethernet address 11:22:33:44:55:66
|
|
||||||
#dhcp-host=11:22:33:44:55:66,set:red
|
|
||||||
|
|
||||||
# Send extra options which are tagged as "red" to
|
|
||||||
# any machine with Ethernet address starting 11:22:33:
|
|
||||||
#dhcp-host=11:22:33:*:*:*,set:red
|
|
||||||
|
|
||||||
# Give a fixed IPv6 address and name to client with
|
|
||||||
# DUID 00:01:00:01:16:d2:83:fc:92:d4:19:e2:d8:b2
|
|
||||||
# Note the MAC addresses CANNOT be used to identify DHCPv6 clients.
|
|
||||||
# Note also the they [] around the IPv6 address are obligatory.
|
|
||||||
#dhcp-host=id:00:01:00:01:16:d2:83:fc:92:d4:19:e2:d8:b2, fred, [1234::5]
|
|
||||||
|
|
||||||
# Ignore any clients which are not specified in dhcp-host lines
|
|
||||||
# or /etc/ethers. Equivalent to ISC "deny unknown-clients".
|
|
||||||
# This relies on the special "known" tag which is set when
|
|
||||||
# a host is matched.
|
|
||||||
#dhcp-ignore=tag:!known
|
|
||||||
|
|
||||||
# Send extra options which are tagged as "red" to any machine whose
|
|
||||||
# DHCP vendorclass string includes the substring "Linux"
|
|
||||||
#dhcp-vendorclass=set:red,Linux
|
|
||||||
|
|
||||||
# Send extra options which are tagged as "red" to any machine one
|
|
||||||
# of whose DHCP userclass strings includes the substring "accounts"
|
|
||||||
#dhcp-userclass=set:red,accounts
|
|
||||||
|
|
||||||
# Send extra options which are tagged as "red" to any machine whose
|
|
||||||
# MAC address matches the pattern.
|
|
||||||
#dhcp-mac=set:red,00:60:8C:*:*:*
|
|
||||||
|
|
||||||
# If this line is uncommented, dnsmasq will read /etc/ethers and act
|
|
||||||
# on the ethernet-address/IP pairs found there just as if they had
|
|
||||||
# been given as --dhcp-host options. Useful if you keep
|
|
||||||
# MAC-address/host mappings there for other purposes.
|
|
||||||
#read-ethers
|
|
||||||
|
|
||||||
# Send options to hosts which ask for a DHCP lease.
|
|
||||||
# See RFC 2132 for details of available options.
|
|
||||||
# Common options can be given to dnsmasq by name:
|
|
||||||
# run "dnsmasq --help dhcp" to get a list.
|
|
||||||
# Note that all the common settings, such as netmask and
|
|
||||||
# broadcast address, DNS server and default route, are given
|
|
||||||
# sane defaults by dnsmasq. You very likely will not need
|
|
||||||
# any dhcp-options. If you use Windows clients and Samba, there
|
|
||||||
# are some options which are recommended, they are detailed at the
|
|
||||||
# end of this section.
|
|
||||||
|
|
||||||
# Override the default route supplied by dnsmasq, which assumes the
|
|
||||||
# router is the same machine as the one running dnsmasq.
|
|
||||||
#dhcp-option=3,1.2.3.4
|
|
||||||
|
|
||||||
# Do the same thing, but using the option name
|
|
||||||
#dhcp-option=option:router,1.2.3.4
|
|
||||||
|
|
||||||
# Override the default route supplied by dnsmasq and send no default
|
|
||||||
# route at all. Note that this only works for the options sent by
|
|
||||||
# default (1, 3, 6, 12, 28) the same line will send a zero-length option
|
|
||||||
# for all other option numbers.
|
|
||||||
#dhcp-option=3
|
|
||||||
|
|
||||||
# Set the NTP time server addresses to 192.168.0.4 and 10.10.0.5
|
|
||||||
#dhcp-option=option:ntp-server,192.168.0.4,10.10.0.5
|
|
||||||
|
|
||||||
# Send DHCPv6 option. Note [] around IPv6 addresses.
|
|
||||||
#dhcp-option=option6:dns-server,[1234::77],[1234::88]
|
|
||||||
|
|
||||||
# Send DHCPv6 option for namservers as the machine running
|
|
||||||
# dnsmasq and another.
|
|
||||||
#dhcp-option=option6:dns-server,[::],[1234::88]
|
|
||||||
|
|
||||||
# Ask client to poll for option changes every six hours. (RFC4242)
|
|
||||||
#dhcp-option=option6:information-refresh-time,6h
|
|
||||||
|
|
||||||
# Set the NTP time server address to be the same machine as
|
|
||||||
# is running dnsmasq
|
|
||||||
#dhcp-option=42,0.0.0.0
|
|
||||||
|
|
||||||
# Set the NIS domain name to "welly"
|
|
||||||
#dhcp-option=40,welly
|
|
||||||
|
|
||||||
# Set the default time-to-live to 50
|
|
||||||
#dhcp-option=23,50
|
|
||||||
|
|
||||||
# Set the "all subnets are local" flag
|
|
||||||
#dhcp-option=27,1
|
|
||||||
|
|
||||||
# Send the etherboot magic flag and then etherboot options (a string).
|
|
||||||
#dhcp-option=128,e4:45:74:68:00:00
|
|
||||||
#dhcp-option=129,NIC=eepro100
|
|
||||||
|
|
||||||
# Specify an option which will only be sent to the "red" network
|
|
||||||
# (see dhcp-range for the declaration of the "red" network)
|
|
||||||
# Note that the tag: part must precede the option: part.
|
|
||||||
#dhcp-option = tag:red, option:ntp-server, 192.168.1.1
|
|
||||||
|
|
||||||
# The following DHCP options set up dnsmasq in the same way as is specified
|
|
||||||
# for the ISC dhcpcd in
|
|
||||||
# http://www.samba.org/samba/ftp/docs/textdocs/DHCP-Server-Configuration.txt
|
|
||||||
# adapted for a typical dnsmasq installation where the host running
|
|
||||||
# dnsmasq is also the host running samba.
|
|
||||||
# you may want to uncomment some or all of them if you use
|
|
||||||
# Windows clients and Samba.
|
|
||||||
#dhcp-option=19,0 # option ip-forwarding off
|
|
||||||
#dhcp-option=44,0.0.0.0 # set netbios-over-TCP/IP nameserver(s) aka WINS server(s)
|
|
||||||
#dhcp-option=45,0.0.0.0 # netbios datagram distribution server
|
|
||||||
#dhcp-option=46,8 # netbios node type
|
|
||||||
|
|
||||||
# Send an empty WPAD option. This may be REQUIRED to get windows 7 to behave.
|
|
||||||
#dhcp-option=252,"\n"
|
|
||||||
|
|
||||||
# Send RFC-3397 DNS domain search DHCP option. WARNING: Your DHCP client
|
|
||||||
# probably doesn't support this......
|
|
||||||
#dhcp-option=option:domain-search,eng.apple.com,marketing.apple.com
|
|
||||||
|
|
||||||
# Send RFC-3442 classless static routes (note the netmask encoding)
|
|
||||||
#dhcp-option=121,192.168.1.0/24,1.2.3.4,10.0.0.0/8,5.6.7.8
|
|
||||||
|
|
||||||
# Send vendor-class specific options encapsulated in DHCP option 43.
|
|
||||||
# The meaning of the options is defined by the vendor-class so
|
|
||||||
# options are sent only when the client supplied vendor class
|
|
||||||
# matches the class given here. (A substring match is OK, so "MSFT"
|
|
||||||
# matches "MSFT" and "MSFT 5.0"). This example sets the
|
|
||||||
# mtftp address to 0.0.0.0 for PXEClients.
|
|
||||||
#dhcp-option=vendor:PXEClient,1,0.0.0.0
|
|
||||||
|
|
||||||
# Send microsoft-specific option to tell windows to release the DHCP lease
|
|
||||||
# when it shuts down. Note the "i" flag, to tell dnsmasq to send the
|
|
||||||
# value as a four-byte integer - that's what microsoft wants. See
|
|
||||||
# http://technet2.microsoft.com/WindowsServer/en/library/a70f1bb7-d2d4-49f0-96d6-4b7414ecfaae1033.mspx?mfr=true
|
|
||||||
#dhcp-option=vendor:MSFT,2,1i
|
|
||||||
|
|
||||||
# Send the Encapsulated-vendor-class ID needed by some configurations of
|
|
||||||
# Etherboot to allow is to recognize the DHCP server.
|
|
||||||
#dhcp-option=vendor:Etherboot,60,"Etherboot"
|
|
||||||
|
|
||||||
# Send options to PXELinux. Note that we need to send the options even
|
|
||||||
# though they don't appear in the parameter request list, so we need
|
|
||||||
# to use dhcp-option-force here.
|
|
||||||
# See http://syslinux.zytor.com/pxe.php#special for details.
|
|
||||||
# Magic number - needed before anything else is recognized
|
|
||||||
#dhcp-option-force=208,f1:00:74:7e
|
|
||||||
# Configuration file name
|
|
||||||
#dhcp-option-force=209,configs/common
|
|
||||||
# Path prefix
|
|
||||||
#dhcp-option-force=210,/tftpboot/pxelinux/files/
|
|
||||||
# Reboot time. (Note 'i' to send 32-bit value)
|
|
||||||
#dhcp-option-force=211,30i
|
|
||||||
|
|
||||||
# Set the boot filename for netboot/PXE. You will only need
|
|
||||||
# this is you want to boot machines over the network and you will need
|
|
||||||
# a TFTP server; either dnsmasq's built in TFTP server or an
|
|
||||||
# external one. (See below for how to enable the TFTP server.)
|
|
||||||
#dhcp-boot=pxelinux.0
|
|
||||||
|
|
||||||
# The same as above, but use custom tftp-server instead machine running dnsmasq
|
|
||||||
#dhcp-boot=pxelinux,server.name,192.168.1.100
|
|
||||||
|
|
||||||
# Boot for Etherboot gPXE. The idea is to send two different
|
|
||||||
# filenames, the first loads gPXE, and the second tells gPXE what to
|
|
||||||
# load. The dhcp-match sets the gpxe tag for requests from gPXE.
|
|
||||||
#dhcp-match=set:gpxe,175 # gPXE sends a 175 option.
|
|
||||||
#dhcp-boot=tag:!gpxe,undionly.kpxe
|
|
||||||
#dhcp-boot=mybootimage
|
|
||||||
|
|
||||||
# Encapsulated options for Etherboot gPXE. All the options are
|
|
||||||
# encapsulated within option 175
|
|
||||||
#dhcp-option=encap:175, 1, 5b # priority code
|
|
||||||
#dhcp-option=encap:175, 176, 1b # no-proxydhcp
|
|
||||||
#dhcp-option=encap:175, 177, string # bus-id
|
|
||||||
#dhcp-option=encap:175, 189, 1b # BIOS drive code
|
|
||||||
#dhcp-option=encap:175, 190, user # iSCSI username
|
|
||||||
#dhcp-option=encap:175, 191, pass # iSCSI password
|
|
||||||
|
|
||||||
# Test for the architecture of a netboot client. PXE clients are
|
|
||||||
# supposed to send their architecture as option 93. (See RFC 4578)
|
|
||||||
#dhcp-match=peecees, option:client-arch, 0 #x86-32
|
|
||||||
#dhcp-match=itanics, option:client-arch, 2 #IA64
|
|
||||||
#dhcp-match=hammers, option:client-arch, 6 #x86-64
|
|
||||||
#dhcp-match=mactels, option:client-arch, 7 #EFI x86-64
|
|
||||||
|
|
||||||
# Do real PXE, rather than just booting a single file, this is an
|
|
||||||
# alternative to dhcp-boot.
|
|
||||||
#pxe-prompt="What system shall I netboot?"
|
|
||||||
# or with timeout before first available action is taken:
|
|
||||||
#pxe-prompt="Press F8 for menu.", 60
|
|
||||||
|
|
||||||
# Available boot services. for PXE.
|
|
||||||
#pxe-service=x86PC, "Boot from local disk"
|
|
||||||
|
|
||||||
# Loads <tftp-root>/pxelinux.0 from dnsmasq TFTP server.
|
|
||||||
#pxe-service=x86PC, "Install Linux", pxelinux
|
|
||||||
|
|
||||||
# Loads <tftp-root>/pxelinux.0 from TFTP server at 1.2.3.4.
|
|
||||||
# Beware this fails on old PXE ROMS.
|
|
||||||
#pxe-service=x86PC, "Install Linux", pxelinux, 1.2.3.4
|
|
||||||
|
|
||||||
# Use bootserver on network, found my multicast or broadcast.
|
|
||||||
#pxe-service=x86PC, "Install windows from RIS server", 1
|
|
||||||
|
|
||||||
# Use bootserver at a known IP address.
|
|
||||||
#pxe-service=x86PC, "Install windows from RIS server", 1, 1.2.3.4
|
|
||||||
|
|
||||||
# If you have multicast-FTP available,
|
|
||||||
# information for that can be passed in a similar way using options 1
|
|
||||||
# to 5. See page 19 of
|
|
||||||
# http://download.intel.com/design/archives/wfm/downloads/pxespec.pdf
|
|
||||||
|
|
||||||
|
|
||||||
# Enable dnsmasq's built-in TFTP server
|
|
||||||
#enable-tftp
|
|
||||||
|
|
||||||
# Set the root directory for files available via FTP.
|
|
||||||
#tftp-root=/var/ftpd
|
|
||||||
|
|
||||||
# Make the TFTP server more secure: with this set, only files owned by
|
|
||||||
# the user dnsmasq is running as will be send over the net.
|
|
||||||
#tftp-secure
|
|
||||||
|
|
||||||
# This option stops dnsmasq from negotiating a larger blocksize for TFTP
|
|
||||||
# transfers. It will slow things down, but may rescue some broken TFTP
|
|
||||||
# clients.
|
|
||||||
#tftp-no-blocksize
|
|
||||||
|
|
||||||
# Set the boot file name only when the "red" tag is set.
|
|
||||||
#dhcp-boot=tag:red,pxelinux.red-net
|
|
||||||
|
|
||||||
# An example of dhcp-boot with an external TFTP server: the name and IP
|
|
||||||
# address of the server are given after the filename.
|
|
||||||
# Can fail with old PXE ROMS. Overridden by --pxe-service.
|
|
||||||
#dhcp-boot=/var/ftpd/pxelinux.0,boothost,192.168.0.3
|
|
||||||
|
|
||||||
# If there are multiple external tftp servers having a same name
|
|
||||||
# (using /etc/hosts) then that name can be specified as the
|
|
||||||
# tftp_servername (the third option to dhcp-boot) and in that
|
|
||||||
# case dnsmasq resolves this name and returns the resultant IP
|
|
||||||
# addresses in round robin fashion. This facility can be used to
|
|
||||||
# load balance the tftp load among a set of servers.
|
|
||||||
#dhcp-boot=/var/ftpd/pxelinux.0,boothost,tftp_server_name
|
|
||||||
|
|
||||||
# Set the limit on DHCP leases, the default is 150
|
|
||||||
#dhcp-lease-max=150
|
|
||||||
|
|
||||||
# The DHCP server needs somewhere on disk to keep its lease database.
|
|
||||||
# This defaults to a sane location, but if you want to change it, use
|
|
||||||
# the line below.
|
|
||||||
#dhcp-leasefile=/var/lib/misc/dnsmasq.leases
|
|
||||||
|
|
||||||
# Set the DHCP server to authoritative mode. In this mode it will barge in
|
|
||||||
# and take over the lease for any client which broadcasts on the network,
|
|
||||||
# whether it has a record of the lease or not. This avoids long timeouts
|
|
||||||
# when a machine wakes up on a new network. DO NOT enable this if there's
|
|
||||||
# the slightest chance that you might end up accidentally configuring a DHCP
|
|
||||||
# server for your campus/company accidentally. The ISC server uses
|
|
||||||
# the same option, and this URL provides more information:
|
|
||||||
# http://www.isc.org/files/auth.html
|
|
||||||
#dhcp-authoritative
|
|
||||||
|
|
||||||
# Run an executable when a DHCP lease is created or destroyed.
|
|
||||||
# The arguments sent to the script are "add" or "del",
|
|
||||||
# then the MAC address, the IP address and finally the hostname
|
|
||||||
# if there is one.
|
|
||||||
#dhcp-script=/bin/echo
|
|
||||||
|
|
||||||
# Set the cachesize here.
|
|
||||||
#cache-size=150
|
|
||||||
|
|
||||||
# If you want to disable negative caching, uncomment this.
|
|
||||||
#no-negcache
|
|
||||||
|
|
||||||
# Normally responses which come from /etc/hosts and the DHCP lease
|
|
||||||
# file have Time-To-Live set as zero, which conventionally means
|
|
||||||
# do not cache further. If you are happy to trade lower load on the
|
|
||||||
# server for potentially stale date, you can set a time-to-live (in
|
|
||||||
# seconds) here.
|
|
||||||
#local-ttl=
|
|
||||||
|
|
||||||
# If you want dnsmasq to detect attempts by Verisign to send queries
|
|
||||||
# to unregistered .com and .net hosts to its sitefinder service and
|
|
||||||
# have dnsmasq instead return the correct NXDOMAIN response, uncomment
|
|
||||||
# this line. You can add similar lines to do the same for other
|
|
||||||
# registries which have implemented wildcard A records.
|
|
||||||
#bogus-nxdomain=64.94.110.11
|
|
||||||
|
|
||||||
# If you want to fix up DNS results from upstream servers, use the
|
|
||||||
# alias option. This only works for IPv4.
|
|
||||||
# This alias makes a result of 1.2.3.4 appear as 5.6.7.8
|
|
||||||
#alias=1.2.3.4,5.6.7.8
|
|
||||||
# and this maps 1.2.3.x to 5.6.7.x
|
|
||||||
#alias=1.2.3.0,5.6.7.0,255.255.255.0
|
|
||||||
# and this maps 192.168.0.10->192.168.0.40 to 10.0.0.10->10.0.0.40
|
|
||||||
#alias=192.168.0.10-192.168.0.40,10.0.0.0,255.255.255.0
|
|
||||||
|
|
||||||
# Change these lines if you want dnsmasq to serve MX records.
|
|
||||||
|
|
||||||
# Return an MX record named "maildomain.com" with target
|
|
||||||
# servermachine.com and preference 50
|
|
||||||
#mx-host=maildomain.com,servermachine.com,50
|
|
||||||
|
|
||||||
# Set the default target for MX records created using the localmx option.
|
|
||||||
#mx-target=servermachine.com
|
|
||||||
|
|
||||||
# Return an MX record pointing to the mx-target for all local
|
|
||||||
# machines.
|
|
||||||
#localmx
|
|
||||||
|
|
||||||
# Return an MX record pointing to itself for all local machines.
|
|
||||||
#selfmx
|
|
||||||
|
|
||||||
# Change the following lines if you want dnsmasq to serve SRV
|
|
||||||
# records. These are useful if you want to serve ldap requests for
|
|
||||||
# Active Directory and other windows-originated DNS requests.
|
|
||||||
# See RFC 2782.
|
|
||||||
# You may add multiple srv-host lines.
|
|
||||||
# The fields are <name>,<target>,<port>,<priority>,<weight>
|
|
||||||
# If the domain part if missing from the name (so that is just has the
|
|
||||||
# service and protocol sections) then the domain given by the domain=
|
|
||||||
# config option is used. (Note that expand-hosts does not need to be
|
|
||||||
# set for this to work.)
|
|
||||||
|
|
||||||
# A SRV record sending LDAP for the example.com domain to
|
|
||||||
# ldapserver.example.com port 389
|
|
||||||
#srv-host=_ldap._tcp.example.com,ldapserver.example.com,389
|
|
||||||
|
|
||||||
# A SRV record sending LDAP for the example.com domain to
|
|
||||||
# ldapserver.example.com port 389 (using domain=)
|
|
||||||
#domain=example.com
|
|
||||||
#srv-host=_ldap._tcp,ldapserver.example.com,389
|
|
||||||
|
|
||||||
# Two SRV records for LDAP, each with different priorities
|
|
||||||
#srv-host=_ldap._tcp.example.com,ldapserver.example.com,389,1
|
|
||||||
#srv-host=_ldap._tcp.example.com,ldapserver.example.com,389,2
|
|
||||||
|
|
||||||
# A SRV record indicating that there is no LDAP server for the domain
|
|
||||||
# example.com
|
|
||||||
#srv-host=_ldap._tcp.example.com
|
|
||||||
|
|
||||||
# The following line shows how to make dnsmasq serve an arbitrary PTR
|
|
||||||
# record. This is useful for DNS-SD. (Note that the
|
|
||||||
# domain-name expansion done for SRV records _does_not
|
|
||||||
# occur for PTR records.)
|
|
||||||
#ptr-record=_http._tcp.dns-sd-services,"New Employee Page._http._tcp.dns-sd-services"
|
|
||||||
|
|
||||||
# Change the following lines to enable dnsmasq to serve TXT records.
|
|
||||||
# These are used for things like SPF and zeroconf. (Note that the
|
|
||||||
# domain-name expansion done for SRV records _does_not
|
|
||||||
# occur for TXT records.)
|
|
||||||
|
|
||||||
#Example SPF.
|
|
||||||
#txt-record=example.com,"v=spf1 a -all"
|
|
||||||
|
|
||||||
#Example zeroconf
|
|
||||||
#txt-record=_http._tcp.example.com,name=value,paper=A4
|
|
||||||
|
|
||||||
# Provide an alias for a "local" DNS name. Note that this _only_ works
|
|
||||||
# for targets which are names from DHCP or /etc/hosts. Give host
|
|
||||||
# "bert" another name, bertrand
|
|
||||||
#cname=bertand,bert
|
|
||||||
|
|
||||||
# For debugging purposes, log each DNS query as it passes through
|
|
||||||
# dnsmasq.
|
|
||||||
#log-queries
|
|
||||||
|
|
||||||
# Log lots of extra information about DHCP transactions.
|
|
||||||
#log-dhcp
|
|
||||||
|
|
||||||
# Include another lot of configuration options.
|
|
||||||
#conf-file=/etc/dnsmasq.more.conf
|
|
||||||
#conf-dir=/etc/dnsmasq.d
|
|
||||||
|
|
||||||
# Include all the files in a directory except those ending in .bak
|
|
||||||
#conf-dir=/etc/dnsmasq.d,.bak
|
|
||||||
|
|
||||||
# Include all files in a directory which end in .conf
|
|
||||||
#conf-dir=/etc/dnsmasq.d/*.conf
|
|
@ -1,73 +0,0 @@
|
|||||||
# Pi-hole: A black hole for Internet advertisements
|
|
||||||
# (c) 2017 Pi-hole, LLC (https://pi-hole.net)
|
|
||||||
# Network-wide ad blocking via your own hardware.
|
|
||||||
#
|
|
||||||
# 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.
|
|
||||||
|
|
||||||
###################################################################################################
|
|
||||||
# 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_auth",
|
|
||||||
"mod_expire",
|
|
||||||
"mod_redirect",
|
|
||||||
"mod_setenv",
|
|
||||||
"mod_rewrite"
|
|
||||||
)
|
|
||||||
|
|
||||||
server.document-root = "/var/www/html"
|
|
||||||
server.upload-dirs = ( "/var/cache/lighttpd/uploads" )
|
|
||||||
server.errorlog = "/var/log/lighttpd/error-pihole.log"
|
|
||||||
server.pid-file = "/run/lighttpd.pid"
|
|
||||||
server.username = "www-data"
|
|
||||||
server.groupname = "www-data"
|
|
||||||
# For lighttpd version 1.4.46 or above, the port can be overwritten in `/etc/lighttpd/external.conf` using the := operator
|
|
||||||
# e.g. server.port := 8000
|
|
||||||
server.port = 80
|
|
||||||
|
|
||||||
# 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" )
|
|
||||||
|
|
||||||
mimetype.assign = (
|
|
||||||
".ico" => "image/x-icon",
|
|
||||||
".jpeg" => "image/jpeg",
|
|
||||||
".jpg" => "image/jpeg",
|
|
||||||
".png" => "image/png",
|
|
||||||
".svg" => "image/svg+xml",
|
|
||||||
".css" => "text/css; charset=utf-8",
|
|
||||||
".html" => "text/html; charset=utf-8",
|
|
||||||
".js" => "text/javascript; charset=utf-8",
|
|
||||||
".json" => "application/json; charset=utf-8",
|
|
||||||
".map" => "application/json; charset=utf-8",
|
|
||||||
".txt" => "text/plain; charset=utf-8",
|
|
||||||
".eot" => "application/vnd.ms-fontobject",
|
|
||||||
".otf" => "font/otf",
|
|
||||||
".ttc" => "font/collection",
|
|
||||||
".ttf" => "font/ttf",
|
|
||||||
".woff" => "font/woff",
|
|
||||||
".woff2" => "font/woff2"
|
|
||||||
)
|
|
||||||
|
|
||||||
# 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
|
|
||||||
include "/etc/lighttpd/conf-enabled/*.conf"
|
|
@ -1,87 +0,0 @@
|
|||||||
# Pi-hole: A black hole for Internet advertisements
|
|
||||||
# (c) 2017 Pi-hole, LLC (https://pi-hole.net)
|
|
||||||
# Network-wide ad blocking via your own hardware.
|
|
||||||
#
|
|
||||||
# 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.
|
|
||||||
|
|
||||||
###################################################################################################
|
|
||||||
# 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",
|
|
||||||
"mod_auth",
|
|
||||||
"mod_expire",
|
|
||||||
"mod_fastcgi",
|
|
||||||
"mod_accesslog",
|
|
||||||
"mod_redirect",
|
|
||||||
"mod_setenv",
|
|
||||||
"mod_rewrite"
|
|
||||||
)
|
|
||||||
|
|
||||||
server.document-root = "/var/www/html"
|
|
||||||
server.upload-dirs = ( "/var/cache/lighttpd/uploads" )
|
|
||||||
server.errorlog = "/var/log/lighttpd/error-pihole.log"
|
|
||||||
server.pid-file = "/run/lighttpd.pid"
|
|
||||||
server.username = "lighttpd"
|
|
||||||
server.groupname = "lighttpd"
|
|
||||||
# For lighttpd version 1.4.46 or above, the port can be overwritten in `/etc/lighttpd/external.conf` using the := operator
|
|
||||||
# e.g. server.port := 8000
|
|
||||||
server.port = 80
|
|
||||||
|
|
||||||
# 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" )
|
|
||||||
|
|
||||||
mimetype.assign = (
|
|
||||||
".ico" => "image/x-icon",
|
|
||||||
".jpeg" => "image/jpeg",
|
|
||||||
".jpg" => "image/jpeg",
|
|
||||||
".png" => "image/png",
|
|
||||||
".svg" => "image/svg+xml",
|
|
||||||
".css" => "text/css; charset=utf-8",
|
|
||||||
".html" => "text/html; charset=utf-8",
|
|
||||||
".js" => "text/javascript; charset=utf-8",
|
|
||||||
".json" => "application/json; charset=utf-8",
|
|
||||||
".map" => "application/json; charset=utf-8",
|
|
||||||
".txt" => "text/plain; charset=utf-8",
|
|
||||||
".eot" => "application/vnd.ms-fontobject",
|
|
||||||
".otf" => "font/otf",
|
|
||||||
".ttc" => "font/collection",
|
|
||||||
".ttf" => "font/ttf",
|
|
||||||
".woff" => "font/woff",
|
|
||||||
".woff2" => "font/woff2"
|
|
||||||
)
|
|
||||||
|
|
||||||
# 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
|
|
||||||
#include_shell "/usr/share/lighttpd/create-mime.assign.pl"
|
|
||||||
#include_shell "/usr/share/lighttpd/include-conf-enabled.pl"
|
|
||||||
|
|
||||||
fastcgi.server = (
|
|
||||||
".php" => (
|
|
||||||
"localhost" => (
|
|
||||||
"socket" => "/tmp/php-fastcgi.socket",
|
|
||||||
"bin-path" => "/usr/bin/php-cgi"
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
include "/etc/lighttpd/conf.d/pihole-admin.conf"
|
|
File diff suppressed because it is too large
Load Diff
@ -1,154 +0,0 @@
|
|||||||
.TH "Pihole-FTL" "8" "pihole-FTL" "Pi-hole" "November 2020"
|
|
||||||
.SH "NAME"
|
|
||||||
pihole-FTL - Pi-hole : The Faster-Than-Light (FTL) Engine
|
|
||||||
.br
|
|
||||||
.SH "SYNOPSIS"
|
|
||||||
\fBservice pihole-FTL \fR(\fBstart\fR|\fBstop\fR|\fBrestart\fR)
|
|
||||||
.br
|
|
||||||
|
|
||||||
\fBpihole-FTL debug\fR
|
|
||||||
.br
|
|
||||||
\fBpihole-FTL test\fR
|
|
||||||
.br
|
|
||||||
\fBpihole-FTL -v|-vv\fR
|
|
||||||
.br
|
|
||||||
\fBpihole-FTL -t\fR
|
|
||||||
.br
|
|
||||||
\fBpihole-FTL -b\fR
|
|
||||||
.br
|
|
||||||
\fBpihole-FTL -f\fR
|
|
||||||
.br
|
|
||||||
\fBpihole-FTL -h\fR
|
|
||||||
.br
|
|
||||||
\fBpihole-FTL dnsmasq-test\fR
|
|
||||||
.br
|
|
||||||
\fBpihole-FTL regex-test str\fR
|
|
||||||
.br
|
|
||||||
\fBpihole-FTL regex-test str rgx\fR
|
|
||||||
.br
|
|
||||||
\fBpihole-FTL lua\fR
|
|
||||||
.br
|
|
||||||
\fBpihole-FTL luac\fR
|
|
||||||
.br
|
|
||||||
\fBpihole-FTL dhcp-discover\fR
|
|
||||||
.br
|
|
||||||
\fBpihole-FTL --\fR (\fBoptions\fR)
|
|
||||||
.br
|
|
||||||
|
|
||||||
.SH "DESCRIPTION"
|
|
||||||
Pi-hole : The Faster-Than-Light (FTL) Engine is a lightweight, purpose-built daemon used to provide statistics needed for the Pi-hole Web Interface, and its API can be easily integrated into your own projects. Although it is an optional component of the Pi-hole ecosystem, it will be installed by default to provide statistics. As the name implies, FTL does its work \fIvery\fR \fIquickly\fR!
|
|
||||||
.br
|
|
||||||
|
|
||||||
Usage
|
|
||||||
.br
|
|
||||||
|
|
||||||
\fBservice pihole-FTL start\fR
|
|
||||||
.br
|
|
||||||
Start the pihole-FTL daemon
|
|
||||||
.br
|
|
||||||
|
|
||||||
\fBservice pihole-FTL stop\fR
|
|
||||||
.br
|
|
||||||
Stop the pihole-FTL daemon
|
|
||||||
.br
|
|
||||||
|
|
||||||
\fBservice pihole-FTL restart\fR
|
|
||||||
.br
|
|
||||||
If the pihole-FTP daemon is running, stop and then start, otherwise start.
|
|
||||||
.br
|
|
||||||
|
|
||||||
Command line arguments
|
|
||||||
.br
|
|
||||||
|
|
||||||
\fBdebug\fR
|
|
||||||
.br
|
|
||||||
Don't go into daemon mode (stay in foreground) + more verbose logging
|
|
||||||
.br
|
|
||||||
|
|
||||||
\fBtest\fR
|
|
||||||
.br
|
|
||||||
Start FTL and process everything, but shut down immediately afterwards
|
|
||||||
.br
|
|
||||||
|
|
||||||
\fB-v, version\fR
|
|
||||||
.br
|
|
||||||
Don't start FTL, show only version
|
|
||||||
.br
|
|
||||||
|
|
||||||
\fB-vv\fR
|
|
||||||
.br
|
|
||||||
Don't start FTL, show verbose version information of embedded applications
|
|
||||||
.br
|
|
||||||
|
|
||||||
\fB-t, tag\fR
|
|
||||||
.br
|
|
||||||
Don't start FTL, show only git tag
|
|
||||||
.br
|
|
||||||
|
|
||||||
\fB-b, branch\fR
|
|
||||||
.br
|
|
||||||
Don't start FTL, show only git branch FTL was compiled from
|
|
||||||
.br
|
|
||||||
|
|
||||||
\fB-f, no-daemon\fR
|
|
||||||
.br
|
|
||||||
Don't go into background (daemon mode)
|
|
||||||
.br
|
|
||||||
|
|
||||||
\fB-h, help\fR
|
|
||||||
.br
|
|
||||||
Don't start FTL, show help
|
|
||||||
.br
|
|
||||||
|
|
||||||
\fBdnsmasq-test\fR
|
|
||||||
.br
|
|
||||||
Test resolver config file syntax
|
|
||||||
.br
|
|
||||||
|
|
||||||
\fBregex-test str\fR
|
|
||||||
.br
|
|
||||||
Test str against all regular expressions in the database
|
|
||||||
.br
|
|
||||||
|
|
||||||
\fBregex-test str rgx\fR
|
|
||||||
.br
|
|
||||||
Test str against regular expression given by rgx
|
|
||||||
.br
|
|
||||||
|
|
||||||
\fBlua\fR
|
|
||||||
.br
|
|
||||||
Start the embedded Lua interpreter
|
|
||||||
.br
|
|
||||||
|
|
||||||
\fBluac\fR
|
|
||||||
.br
|
|
||||||
Execute the embedded Lua compiler
|
|
||||||
.br
|
|
||||||
|
|
||||||
\fBdhcp-discover\fR
|
|
||||||
.br
|
|
||||||
Discover DHCP servers in the local network
|
|
||||||
.br
|
|
||||||
|
|
||||||
\fB--\fR (options)
|
|
||||||
.br
|
|
||||||
Pass options to internal dnsmasq resolver
|
|
||||||
.br
|
|
||||||
.SH "EXAMPLE"
|
|
||||||
Command line arguments can be arbitrarily combined, e.g:
|
|
||||||
.br
|
|
||||||
|
|
||||||
\fBpihole-FTL debug test\fR
|
|
||||||
.br
|
|
||||||
|
|
||||||
Start ftl in foreground with more verbose logging, process everything and shutdown immediately
|
|
||||||
.br
|
|
||||||
.SH "SEE ALSO"
|
|
||||||
\fBpihole\fR(8)
|
|
||||||
.br
|
|
||||||
\fBFor FTL's config options please see https://docs.pi-hole.net/ftldns/configfile/\fR
|
|
||||||
.br
|
|
||||||
.SH "COLOPHON"
|
|
||||||
|
|
||||||
Get sucked into the latest news and community activity by entering Pi-hole's orbit. Information about Pi-hole, and the latest version of the software can be found at https://pi-hole.net
|
|
||||||
.br
|
|
@ -1,27 +0,0 @@
|
|||||||
import pytest
|
|
||||||
from .conftest import (
|
|
||||||
tick_box,
|
|
||||||
info_box,
|
|
||||||
cross_box,
|
|
||||||
mock_command,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def test_enable_epel_repository_centos(host):
|
|
||||||
"""
|
|
||||||
confirms the EPEL package repository is enabled when installed on CentOS
|
|
||||||
"""
|
|
||||||
package_manager_detect = host.run(
|
|
||||||
"""
|
|
||||||
source /opt/pihole/basic-install.sh
|
|
||||||
package_manager_detect
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
expected_stdout = info_box + (
|
|
||||||
" Enabling EPEL package repository " "(https://fedoraproject.org/wiki/EPEL)"
|
|
||||||
)
|
|
||||||
assert expected_stdout in package_manager_detect.stdout
|
|
||||||
expected_stdout = tick_box + " Installed"
|
|
||||||
assert expected_stdout in package_manager_detect.stdout
|
|
||||||
epel_package = host.package("epel-release")
|
|
||||||
assert epel_package.is_installed
|
|
@ -1,15 +0,0 @@
|
|||||||
def test_epel_and_remi_not_installed_fedora(host):
|
|
||||||
"""
|
|
||||||
confirms installer does not attempt to install EPEL/REMI repositories
|
|
||||||
on Fedora
|
|
||||||
"""
|
|
||||||
package_manager_detect = host.run(
|
|
||||||
"""
|
|
||||||
source /opt/pihole/basic-install.sh
|
|
||||||
package_manager_detect
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
assert package_manager_detect.stdout == ""
|
|
||||||
|
|
||||||
epel_package = host.package("epel-release")
|
|
||||||
assert not epel_package.is_installed
|
|
Loading…
Reference in new issue