From 63a8f5e714357d445d54d89988aa184dca0dfc19 Mon Sep 17 00:00:00 2001 From: DL6ER Date: Thu, 9 Apr 2020 09:03:50 +0200 Subject: [PATCH] Improve conditional forwarding settings so users can specify the subnet according to their needs. Signed-off-by: DL6ER --- scripts/pi-hole/js/settings.js | 34 +++++++++------- scripts/pi-hole/php/savesettings.php | 53 +++++++++++++++++++----- settings.php | 61 ++++++++++++++++++---------- 3 files changed, 102 insertions(+), 46 deletions(-) diff --git a/scripts/pi-hole/js/settings.js b/scripts/pi-hole/js/settings.js index 93974e5e4..b4a1a10e9 100644 --- a/scripts/pi-hole/js/settings.js +++ b/scripts/pi-hole/js/settings.js @@ -215,21 +215,8 @@ $(function() { // DHCP leases tooltips $(document).ready(function() { $('[data-toggle="tooltip"]').tooltip({ html: true, container: "body" }); -}); -// Change "?tab=" parameter in URL for save and reload -$(".nav-tabs a").on("shown.bs.tab", function(e) { - var tab = e.target.hash.substring(1); - window.history.pushState("", "", "?tab=" + tab); - if (tab === "piholedhcp") { - window.location.reload(); - } - - window.scrollTo(0, 0); -}); - -// Auto dismissal for info notifications -$(document).ready(function() { + // Auto dismissal for info notifications var alInfo = $("#alInfo"); if (alInfo.length) { alInfo.delay(3000).fadeOut(2000, function() { @@ -243,4 +230,23 @@ $(document).ready(function() { input.setAttribute("autocorrect", "off"); input.setAttribute("autocapitalize", "off"); input.setAttribute("spellcheck", false); + + // En-/disable conditional forwarding input fields based + // on the checkbox state + $('input[name="rev_server"]').click(function() { + $('input[name="rev_server_cidr"]').prop("disabled", !this.checked); + $('input[name="rev_server_target"]').prop("disabled", !this.checked); + $('input[name="rev_server_domain"]').prop("disabled", !this.checked); + }); +}); + +// Change "?tab=" parameter in URL for save and reload +$(".nav-tabs a").on("shown.bs.tab", function(e) { + var tab = e.target.hash.substring(1); + window.history.pushState("", "", "?tab=" + tab); + if (tab === "piholedhcp") { + window.location.reload(); + } + + window.scrollTo(0, 0); }); diff --git a/scripts/pi-hole/php/savesettings.php b/scripts/pi-hole/php/savesettings.php index 6c8b1e893..ecad2bcfc 100644 --- a/scripts/pi-hole/php/savesettings.php +++ b/scripts/pi-hole/php/savesettings.php @@ -19,6 +19,30 @@ function validIP($address){ return !filter_var($address, FILTER_VALIDATE_IP) === false; } +function validCIDRIP($address){ + // This validation strategy has been taken from ../js/groups-common.js + $isIPv6 = strpos($address, ":") !== false; + if($isIPv6) { + // One IPv6 element is 16bit: 0000 - FFFF + $v6elem = "[0-9A-Fa-f]{1,4}"; + // CIDR for IPv6 is any multiple of 4 from 4 up to 128 bit + $v6cidr = "(4"; + for ($i=8; $i <= 128; $i+=4) { + $v6cidr .= "|$i"; + } + $v6cidr .= ")"; + $validator = "/^(((?:$v6elem))((?::$v6elem))*::((?:$v6elem))((?::$v6elem))*|((?:$v6elem))((?::$v6elem)){7})\/$v6cidr$/"; + return preg_match($validator, $address); + } else { + // One IPv4 element is 8bit: 0 - 256 + $v4elem = "(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]?|0)"; + // Note that rev-server accepts only /8, /16, /24, and /32 + $allowedv4cidr = "(8|16|24|32)"; + $validator = "/^$v4elem\.$v4elem\.$v4elem\.$v4elem\/$allowedv4cidr$/"; + return preg_match($validator, $address); + } +} + // Check for existance of variable // and test it only if it exists function istrue(&$argument) { @@ -329,25 +353,32 @@ function addStaticDHCPLease($mac, $ip, $hostname) { $extra .= "no-dnssec"; } - // Check if Conditional Forwarding is requested - if(isset($_POST["conditionalForwarding"])) + // Check if rev-server is requested + if(isset($_POST["rev_server"])) { - // Validate conditional forwarding IP - if (!validIP($_POST["conditionalForwardingIP"])) + // Validate CIDR IP + if (!validCIDRIP($_POST["rev_server_cidr"])) { - $error .= "Conditional forwarding IP (".htmlspecialchars($_POST["conditionalForwardingIP"]).") is invalid!
"; + $error .= "Conditional forwarding subnet (\"".htmlspecialchars($_POST["rev_server_cidr"])."\") is invalid!
". + "This field requires CIDR notation for local subnets (e.g., 192.168.0.0/16).
". + "Please use only subnets /8, /16, /24, and /32.
"; } - // Validate conditional forwarding domain name - if(!validDomain($_POST["conditionalForwardingDomain"])) + // Validate target IP + if (!validIP($_POST["rev_server_target"])) { - $error .= "Conditional forwarding domain name (".htmlspecialchars($_POST["conditionalForwardingDomain"]).") is invalid!
"; + $error .= "Conditional forwarding target IP (\"".htmlspecialchars($_POST["rev_server_target"])."\") is invalid!
"; } + + // Validate conditional forwarding domain name (empty is okay) + if(strlen($_POST["rev_server_domain"]) > 0 && !validDomain($_POST["rev_server_domain"])) + { + $error .= "Conditional forwarding domain name (\"".htmlspecialchars($_POST["rev_server_domain"])."\") is invalid!
"; + } + if(!$error) { - $addressArray = explode(".", $_POST["conditionalForwardingIP"]); - $reverseAddress = $addressArray[2].".".$addressArray[1].".".$addressArray[0].".in-addr.arpa"; - $extra .= " conditional_forwarding ".$_POST["conditionalForwardingIP"]." ".$_POST["conditionalForwardingDomain"]." $reverseAddress"; + $extra .= " rev-server ".$_POST["rev_server_cidr"]." ".$_POST["rev_server_target"]." ".$_POST["rev_server_domain"]; } } diff --git a/settings.php b/settings.php index 18826b591..3de64c648 100644 --- a/settings.php +++ b/settings.php @@ -164,12 +164,13 @@ } else { $DNSinterface = "single"; } -if (isset($setupVars["CONDITIONAL_FORWARDING"]) && ($setupVars["CONDITIONAL_FORWARDING"] == 1)) { - $conditionalForwarding = true; - $conditionalForwardingDomain = $setupVars["CONDITIONAL_FORWARDING_DOMAIN"]; - $conditionalForwardingIP = $setupVars["CONDITIONAL_FORWARDING_IP"]; +if (isset($setupVars["REV_SERVER"]) && ($setupVars["REV_SERVER"] == 1)) { + $rev_server = true; + $rev_server_cidr = $setupVars["REV_SERVER_CIDR"]; + $rev_server_target = $setupVars["REV_SERVER_TARGET"]; + $rev_server_domain = $setupVars["REV_SERVER_DOMAIN"]; } else { - $conditionalForwarding = false; + $rev_server = false; } ?> @@ -807,36 +808,54 @@ function convertseconds($argument) the size of your log might increase significantly when enabling DNSSEC. A DNSSEC resolver test can be found here.

- -

If not configured as your DHCP server, Pi-hole won't be able to + +

If not configured as your DHCP server, Pi-hole typically won't be able to determine the names of devices on your local network. As a result, tables such as Top Clients will only show IP addresses.

One solution for this is to configure Pi-hole to forward these - requests to your DHCP server (most likely your router), but only for devices on your - home network. To configure this we will need to know the IP - address of your DHCP server and the name of your local network.

-

Note: The local domain name must match the domain name specified - in your DHCP server, likely found within the DHCP settings.

+ requests to your DHCP server (most likely your router), but only for devices on your + home network. To configure this we will need to know the IP + address of your DHCP server and which addresses belong to your local network. + Exemplary inout is given below as placeholder in the text boxes (if empty).

+

If your local network spans 192.168.0.1 - 192.168.0.255, then you will have to input + 192.168.0.0/24. If your local network is 192.168.0.1 - 192.168.0.255, it will + be 192.168.47.0/24 and similar. If your network is larger, the CIDR has to be + different, for instance a range of 10.8.0.1 - 10.8.255.255 results in 10.8.0.0/16, + whereas an even wider network of 10.0.0.1 - 10.255.255.255 results in 10.0.0.0/8. + Feel free to reach out to us on our + Discourse forum + in case you need any assistance setting up local host name resolution for your particular system.

+

You can also specify a local domain name (like fritz.box) to ensure queries to + devices ending in your local domain name will not leave your network, however, this is optional. + The local domain name must match the domain name specified + in your DHCP server for this to work. You can likely find it within the DHCP settings.

- +
- - + + +
- +
IP of your routerLocal domain nameLocal network in CIDR notationIP address of your DHCP server (router)Local domain name (optional)
- value=""> + value="" + disabled> value=""> + + value="" + disabled> + value="" + disabled>