Skip to content

Commit

Permalink
Improve conditional forwarding settings so users can specify the subn…
Browse files Browse the repository at this point in the history
…et according to their needs.

Signed-off-by: DL6ER <[email protected]>
  • Loading branch information
DL6ER committed Apr 10, 2020
1 parent 25a08ed commit 373d59f
Show file tree
Hide file tree
Showing 3 changed files with 102 additions and 46 deletions.
34 changes: 20 additions & 14 deletions scripts/pi-hole/js/settings.js
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand All @@ -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);
});
53 changes: 42 additions & 11 deletions scripts/pi-hole/php/savesettings.php
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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!<br>";
$error .= "Conditional forwarding subnet (\"".htmlspecialchars($_POST["rev_server_cidr"])."\") is invalid!<br>".
"This field requires CIDR notation for local subnets (e.g., 192.168.0.0/16).<br>".
"Please use only subnets /8, /16, /24, and /32.<br>";
}

// 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!<br>";
$error .= "Conditional forwarding target IP (\"".htmlspecialchars($_POST["rev_server_target"])."\") is invalid!<br>";
}

// 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!<br>";
}

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"];
}
}

Expand Down
61 changes: 40 additions & 21 deletions settings.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
?>

Expand Down Expand Up @@ -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
<a href="https://dnssec.vs.uni-due.de/" rel="noopener" target="_blank">here</a>.</p>
<label>Conditional Forwarding</label>
<p>If not configured as your DHCP server, Pi-hole won't be able to
<label>Conditional forwarding</label>
<p>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.</p>
<p>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.</p>
<p>Note: The local domain name must match the domain name specified
in your DHCP server, likely found within the DHCP settings.</p>
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).</p>
<p>If your local network spans 192.168.0.1 - 192.168.0.255, then you will have to input
<code>192.168.0.0/24</code>. If your local network is 192.168.47.1 - 192.168.47.255, it will
be <code>192.168.47.0/24</code> 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 <code>10.8.0.0/16</code>,
whereas an even wider network of 10.0.0.1 - 10.255.255.255 results in <code>10.0.0.0/8</code>.
Feel free to reach out to us on our
<a href="https://discourse.pi-hole.net" target="_blank">Discourse forum</a>
in case you need any assistance setting up local host name resolution for your particular system.</p>
<p>You can also specify a local domain name (like <code>fritz.box</code>) 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.</p>
<div class="form-group">
<div class="checkbox">
<label><input type="checkbox" name="conditionalForwarding" value="conditionalForwarding"
<?php if(isset($conditionalForwarding) && ($conditionalForwarding == true)){ ?>checked<?php }
?>>Use Conditional Forwarding</label>
<label><input type="checkbox" name="rev_server" value="rev_server"
<?php if(isset($rev_server) && ($rev_server == true)){ ?>checked<?php } ?>>Use this feature</label>
</div>
<div class="input-group">
<table class="table table-bordered">
<tr>
<th>IP of your router</th>
<th>Local domain name</th>
<th>Local network in <a href="https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing" target="_blank">CIDR notation</a></th>
<th>IP address of your DHCP server (router)</th>
<th>Local domain name (optional)</th>
</tr>
<tr>
<div class="input-group">
<td>
<input type="text" name="conditionalForwardingIP" class="form-control" autocomplete="off" spellcheck="false" autocapitalize="none" autocorrect="off"
<?php if(isset($conditionalForwardingIP)){ ?>value="<?php echo $conditionalForwardingIP; ?>"<?php } ?>>
<input type="text" name="rev_server_cidr" placeholder="192.168.0.0/16" class="form-control" autocomplete="off" spellcheck="false" autocapitalize="none" autocorrect="off"
<?php if(isset($rev_server_cidr)){ ?>value="<?php echo $rev_server_cidr; ?>"<?php } ?>
<?php if(!isset($rev_server) || !$rev_server){ ?>disabled<?php } ?>>
</td>
<td><input type="text" name="conditionalForwardingDomain" class="form-control" data-mask autocomplete="off" spellcheck="false" autocapitalize="none" autocorrect="off"
<?php if(isset($conditionalForwardingDomain)){ ?>value="<?php echo $conditionalForwardingDomain; ?>"<?php } ?>>
<td>
<input type="text" name="rev_server_target" placeholder="192.168.0.1" class="form-control" autocomplete="off" spellcheck="false" autocapitalize="none" autocorrect="off"
<?php if(isset($rev_server_target)){ ?>value="<?php echo $rev_server_target; ?>"<?php } ?>
<?php if(!isset($rev_server) || !$rev_server){ ?>disabled<?php } ?>>
</td>
<td><input type="text" name="rev_server_domain" placeholder="local" class="form-control" data-mask autocomplete="off" spellcheck="false" autocapitalize="none" autocorrect="off"
<?php if(isset($rev_server_domain)){ ?>value="<?php echo $rev_server_domain; ?>"<?php } ?>
<?php if(!isset($rev_server) || !$rev_server){ ?>disabled<?php } ?>>
</td>
</div>
</tr>
Expand Down

0 comments on commit 373d59f

Please sign in to comment.