mirror of
https://github.com/pi-hole/pi-hole.git
synced 2024-11-29 01:23:18 +00:00
Remove all the undocumented now useless stuff from pihole -a
Signed-off-by: DL6ER <dl6er@dl6er.de>
This commit is contained in:
parent
b5800ef718
commit
137e6dc184
1 changed files with 5 additions and 785 deletions
|
@ -43,126 +43,23 @@ fi
|
||||||
helpFunc() {
|
helpFunc() {
|
||||||
echo "Usage: pihole -a [options]
|
echo "Usage: pihole -a [options]
|
||||||
Example: pihole -a -p password
|
Example: pihole -a -p password
|
||||||
Set options for the Admin Console
|
Set options for the API/Web interface
|
||||||
|
|
||||||
Options:
|
Options:
|
||||||
-p, password Set Admin Console password
|
-p, password Set API/Web interface password
|
||||||
-c, celsius Set Celsius as preferred temperature unit
|
-h, --help Show this help dialog"
|
||||||
-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
|
exit 0
|
||||||
}
|
}
|
||||||
|
|
||||||
add_setting() {
|
# TODO: We can probably remove the reliance on this function too, just tell people to pihole-FTL --config webserver.api.password "password"
|
||||||
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() {
|
|
||||||
pihole-FTL --config "${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() {
|
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
|
if (( ${#args[2]} > 0 )) ; then
|
||||||
readonly PASSWORD="${args[2]}"
|
readonly PASSWORD="${args[2]}"
|
||||||
readonly CONFIRM="${PASSWORD}"
|
readonly CONFIRM="${PASSWORD}"
|
||||||
else
|
else
|
||||||
# Prevents a bug if the user presses Ctrl+C and it continues to hide the text typed.
|
# 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
|
# 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
|
trap '{ echo -e "\nNot changed" ; stty sane ; exit 1; }' INT
|
||||||
read -s -r -p "Enter New Password (Blank for no password): " PASSWORD
|
read -s -r -p "Enter New Password (Blank for no password): " PASSWORD
|
||||||
echo ""
|
echo ""
|
||||||
|
|
||||||
|
@ -186,689 +83,12 @@ SetWebPassword() {
|
||||||
fi
|
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 AdminLTE#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]}"
|
|
||||||
}
|
|
||||||
|
|
||||||
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 "${gravityDBfile}" "UPDATE adlist SET enabled = 1 WHERE address = '${address}'"
|
|
||||||
elif [[ "${args[2]}" == "disable" ]]; then
|
|
||||||
pihole-FTL sqlite3 "${gravityDBfile}" "UPDATE adlist SET enabled = 0 WHERE address = '${address}'"
|
|
||||||
elif [[ "${args[2]}" == "add" ]]; then
|
|
||||||
pihole-FTL sqlite3 "${gravityDBfile}" "INSERT OR IGNORE INTO adlist (address, comment) VALUES ('${address}', '${comment}')"
|
|
||||||
elif [[ "${args[2]}" == "del" ]]; then
|
|
||||||
pihole-FTL sqlite3 "${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 "${gravityDBfile}" "INSERT INTO domain_audit (domain) VALUES ${domains};"
|
|
||||||
}
|
|
||||||
|
|
||||||
clearAudit()
|
|
||||||
{
|
|
||||||
pihole-FTL sqlite3 "${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() {
|
main() {
|
||||||
args=("$@")
|
args=("$@")
|
||||||
|
|
||||||
case "${args[1]}" in
|
case "${args[1]}" in
|
||||||
"-p" | "password" ) SetWebPassword;;
|
"-p" | "password" ) SetWebPassword;;
|
||||||
"-c" | "celsius" ) unit="C"; SetTemperatureUnit;;
|
|
||||||
"-f" | "fahrenheit" ) unit="F"; SetTemperatureUnit;;
|
|
||||||
"-k" | "kelvin" ) unit="K"; SetTemperatureUnit;;
|
|
||||||
"setdns" ) SetDNSServers;;
|
|
||||||
"setexcludedomains" ) SetExcludeDomains;;
|
|
||||||
"setexcludeclients" ) SetExcludeClients;;
|
|
||||||
"restartdns" ) RestartDNS;;
|
|
||||||
"setquerylog" ) SetQueryLogOptions;;
|
|
||||||
"enabledhcp" ) EnableDHCP;;
|
|
||||||
"disabledhcp" ) DisableDHCP;;
|
|
||||||
"layout" ) SetWebUILayout;;
|
|
||||||
"theme" ) SetWebUITheme;;
|
|
||||||
"-h" | "--help" ) helpFunc;;
|
"-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;;
|
* ) helpFunc;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue