Finish DNS, DHCP and API settings pages

Signed-off-by: DL6ER <dl6er@dl6er.de>
This commit is contained in:
DL6ER
2023-05-09 10:06:23 +02:00
parent b30c1e0433
commit 60737f9c39
7 changed files with 117 additions and 100 deletions

View File

@@ -5,7 +5,7 @@
* 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. */
/* global utils:false, apiFailure: false, applyCheckboxRadioStyle: false */ /* global utils:false, apiFailure: false, applyCheckboxRadioStyle: false, saveSettings:false */
/* exported createDynamicConfigTabs */ /* exported createDynamicConfigTabs */
function addAllowedValues(allowed) { function addAllowedValues(allowed) {
@@ -308,66 +308,6 @@ function createDynamicConfigTabs() {
}); });
} }
function saveSettings() {
var settings = {};
$("[data-key]").each(function () {
var key = $(this).data("key");
var value = $(this).val();
if ($(this).is(":checkbox")) {
value = $(this).is(":checked");
}
if ($(this).is("textarea")) {
value = $(this).val();
value = value === "" ? [] : value.split("\n");
}
if ($(this).data("type") === "integer") {
value = parseInt(value, 10);
}
if ($(this).data("type") === "float") {
value = parseFloat(value);
}
// Build deep object
// Transform "foo.bar.baz" into {foo: {bar: {baz: value}}}
var parts = key.split(".");
var obj = {};
var tmp = obj;
for (var i = 0; i < parts.length - 1; i++) {
tmp[parts[i]] = {};
tmp = tmp[parts[i]];
}
tmp[parts[parts.length - 1]] = value;
// Merge deep object into settings
$.extend(true, settings, obj);
});
// Apply changes
$.ajax({
url: "/api/config",
method: "PATCH",
data: JSON.stringify({ config: settings }),
contentType: "application/json; charset=utf-8",
})
.done(function () {
// Success
utils.showAlert(
"success",
"fa-solid fa-fw fa-floppy-disk",
"Successfully saved and applied settings",
""
);
// Reload page
location.reload();
})
.fail(function (data) {
apiFailure(data);
});
}
$(document).ready(function () { $(document).ready(function () {
createDynamicConfigTabs(); createDynamicConfigTabs();
}); });

View File

@@ -38,6 +38,7 @@ $(function () {
{ data: null, width: "22px" }, { data: null, width: "22px" },
{ data: "id" }, { data: "id" },
{ data: "valid", render: renderBool }, { data: "valid", render: renderBool },
{ data: "tls", render: renderBool },
{ data: "login_at", render: utils.renderTimestamp }, { data: "login_at", render: utils.renderTimestamp },
{ data: "valid_until", render: utils.renderTimestamp }, { data: "valid_until", render: utils.renderTimestamp },
{ data: "remote_addr", type: "ip-address" }, { data: "remote_addr", type: "ip-address" },
@@ -78,10 +79,10 @@ $(function () {
'">' + '">' +
'<span class="far fa-trash-alt"></span>' + '<span class="far fa-trash-alt"></span>' +
"</button>"; "</button>";
$("td:eq(7)", row).html(button); $("td:eq(8)", row).html(button);
if (data.current_session) { if (data.current_session) {
ownSessionID = data.id; ownSessionID = data.id;
$("td:eq(5)", row).html( $("td:eq(6)", row).html(
'<strong title="This is the session you are currently using for the web interface">' + '<strong title="This is the session you are currently using for the web interface">' +
data.remote_addr + data.remote_addr +
"</strong>" "</strong>"

View File

@@ -5,13 +5,20 @@
* 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. */
// Handle hiding of alerts /* global utils:false, apiFailure:false */
$(function () { $(function () {
// Handle hiding of alerts
$("[data-hide]").on("click", function () { $("[data-hide]").on("click", function () {
$(this) $(this)
.closest("." + $(this).attr("data-hide")) .closest("." + $(this).attr("data-hide"))
.hide(); .hide();
}); });
// Handle saving of settings
$(".save-button").on("click", function () {
saveSettings();
});
}); });
// Globally available function to set config values // Globally available function to set config values
@@ -65,3 +72,72 @@ function setConfigValues(topic, key, value) {
} }
} }
} }
function saveSettings() {
var settings = {};
$("[data-key]").each(function () {
var key = $(this).data("key");
var value = $(this).val();
// If this is a checkbox, use the checked state
if ($(this).is(":checkbox")) {
value = $(this).is(":checked");
}
// If this is a radio button, skip all but the checked one
if ($(this).is(":radio") && !$(this).is(":checked")) return;
// If this is a string array, split the value into an array
if ($(this).is("textarea")) {
value = $(this).val();
value = value === "" ? [] : value.split("\n");
}
// If this is an integer number, parse it accordignly
if ($(this).data("type") === "integer") {
value = parseInt(value, 10);
}
// If this is a floating point value, parse it accordignly
if ($(this).data("type") === "float") {
value = parseFloat(value);
}
// Build deep object
// Transform "foo.bar.baz" into {foo: {bar: {baz: value}}}
var parts = key.split(".");
var obj = {};
var tmp = obj;
for (var i = 0; i < parts.length - 1; i++) {
tmp[parts[i]] = {};
tmp = tmp[parts[i]];
}
tmp[parts[parts.length - 1]] = value;
// Merge deep object into settings
$.extend(true, settings, obj);
});
// Apply changes
$.ajax({
url: "/api/config",
method: "PATCH",
data: JSON.stringify({ config: settings }),
contentType: "application/json; charset=utf-8",
})
.done(function () {
// Success
utils.showAlert(
"success",
"fa-solid fa-fw fa-floppy-disk",
"Successfully saved and applied settings",
""
);
// Reload page
location.reload();
})
.fail(function (data) {
apiFailure(data);
});
}

View File

@@ -140,17 +140,17 @@
</li> </li>
<li class="<? if scriptname == 'settings-dns.lp' then mg.write(" active") end ?>"> <li class="<? if scriptname == 'settings-dns.lp' then mg.write(" active") end ?>">
<a href="settings-dns.lp"> <a href="settings-dns.lp">
<i class="fa-fw menu-icon fa-solid fa-book-atlas"></i> <span class="text-orange">DNS</span> <i class="fa-fw menu-icon fa-solid fa-book-atlas"></i> <span class="text-green">DNS</span>
</a> </a>
</li> </li>
<li class="<? if scriptname == 'settings-dhcp.lp' then mg.write(" active") end ?>"> <li class="<? if scriptname == 'settings-dhcp.lp' then mg.write(" active") end ?>">
<a href="settings-dhcp.lp"> <a href="settings-dhcp.lp">
<i class="fa-fw menu-icon fa-solid fa-sitemap"></i> <span class="text-orange">DHCP</span> <i class="fa-fw menu-icon fa-solid fa-sitemap"></i> <span class="text-green">DHCP</span>
</a> </a>
</li> </li>
<li class="<? if scriptname == 'settings-api.lp' then mg.write(" active") end ?>"> <li class="<? if scriptname == 'settings-api.lp' then mg.write(" active") end ?>">
<a href="settings-api.lp"> <a href="settings-api.lp">
<i class="fa-fw menu-icon fa-solid fa-window-restore"></i> <span class="text-orange">Web interface / API</span> <i class="fa-fw menu-icon fa-solid fa-window-restore"></i> <span class="text-green">Web interface / API</span>
</a> </a>
</li> </li>
<li class="<? if scriptname == 'settings-privacy.lp' then mg.write(" active") end ?>"> <li class="<? if scriptname == 'settings-privacy.lp' then mg.write(" active") end ?>">

View File

@@ -19,12 +19,12 @@ mg.include('scripts/pi-hole/lua/header_authenticated.lp','r')
<div class="row"> <div class="row">
<div class="col-md-6"> <div class="col-md-6">
<p><strong>Domains to be excluded from Top Domains / Ads Lists</strong></p> <p><strong>Domains to be excluded from Top Domains / Ads Lists</strong></p>
<textarea class="form-control" rows="4" id="webserver.api.excludeDomains" placeholder="Enter domains, one per line" style="resize: vertical;"></textarea> <textarea class="form-control" rows="4" id="webserver.api.excludeDomains" data-key="webserver.api.excludeDomains" placeholder="Enter domains, one per line" style="resize: vertical;"></textarea>
<p class="help-block">Domains may be described by their domain name (like <code>example.com</code>)</p> <p class="help-block">Domains may be described by their domain name (like <code>example.com</code>)</p>
</div> </div>
<div class="col-md-6"> <div class="col-md-6">
<p><strong>Clients to be excluded from Top Clients List</strong></p> <p><strong>Clients to be excluded from Top Clients List</strong></p>
<textarea class="form-control" rows="4" id="webserver.api.excludeClients" placeholder="Enter clients, one per line" style="resize: vertical;"></textarea> <textarea class="form-control" rows="4" id="webserver.api.excludeClients" data-key="webserver.api.excludeClients" placeholder="Enter clients, one per line" style="resize: vertical;"></textarea>
<p class="help-block">Clients may be described either by their IP addresses (IPv4 and IPv6 are supported), or hostnames (like <code>laptop.lan</code>).</p> <p class="help-block">Clients may be described either by their IP addresses (IPv4 and IPv6 are supported), or hostnames (like <code>laptop.lan</code>).</p>
</div> </div>
</div> </div>
@@ -42,12 +42,12 @@ mg.include('scripts/pi-hole/lua/header_authenticated.lp','r')
<div> <div>
<input type="checkbox" name="querylog-permitted" id="querylog-permitted" <? if queryLog == 'permittedonly' or queryLog == 'all' then mg.write("checked") end ?>> <input type="checkbox" name="querylog-permitted" id="querylog-permitted" <? if queryLog == 'permittedonly' or queryLog == 'all' then mg.write("checked") end ?>>
<label for="querylog-permitted"><strong>Show permitted domain entries</strong></label> <label for="querylog-permitted"><strong>Show permitted domain entries</strong></label>
<p class="help-block">This will show all permitted domain entries in the query log.</p> <p class="help-block"><span class="text-red">This will show all permitted domain entries in the query log.</span></p>
</div> </div>
<div> <div>
<input type="checkbox" name="querylog-blocked" id="querylog-blocked" <? if queryLog == 'blockedonly' or queryLog == 'all' then mg.write("checked") end ?>> <input type="checkbox" name="querylog-blocked" id="querylog-blocked" <? if queryLog == 'blockedonly' or queryLog == 'all' then mg.write("checked") end ?>>
<label for="querylog-blocked"><strong>Show blocked domain entries</strong></label> <label for="querylog-blocked"><strong>Show blocked domain entries</strong></label>
<p class="help-block">This will show all blocked domain entries in the query log.</p> <p class="help-block"><span class="text-red">This will show all blocked domain entries in the query log.</span></p>
</div> </div>
</div> </div>
</div> </div>
@@ -63,14 +63,14 @@ mg.include('scripts/pi-hole/lua/header_authenticated.lp','r')
<div class="row"> <div class="row">
<div class="col-lg-12"> <div class="col-lg-12">
<div> <div>
<input type="checkbox" id="webserver.api.localAPIauth"> <input type="checkbox" id="webserver.api.localAPIauth" data-key="webserver.api.localAPIauth">
<label for="webserver.api.localAPIauth"><strong>Local clients need to authenticate to access the API</strong></label> <label for="webserver.api.localAPIauth"><strong>Local clients need to authenticate to access the API</strong></label>
<p class="help-block">This will require local clients to authenticate to access the API. This is useful if you want to prevent local users from accessing the API without knowing the password.</p> <p class="help-block">This will require local clients to authenticate to access the API. This is useful if you want to prevent local users from accessing the API without knowing the password.</p>
</div> </div>
</div> </div>
<div class="col-lg-12"> <div class="col-lg-12">
<div> <div>
<input type="checkbox" id="webserver.api.prettyJSON"> <input type="checkbox" id="webserver.api.prettyJSON" data-key="webserver.api.prettyJSON">
<label for="webserver.api.prettyJSON"><strong>Prettify API output for human-readability</strong></label> <label for="webserver.api.prettyJSON"><strong>Prettify API output for human-readability</strong></label>
<p class="help-block">This will make the API output more human-readable, but will increase the size of the output and make the API a bit slower.</p> <p class="help-block">This will make the API output more human-readable, but will increase the size of the output and make the API a bit slower.</p>
</div> </div>
@@ -81,7 +81,7 @@ mg.include('scripts/pi-hole/lua/header_authenticated.lp','r')
<label for="webserver.api.temp.limit"><strong>Temperature limit for showing "hot":</strong></label> <label for="webserver.api.temp.limit"><strong>Temperature limit for showing "hot":</strong></label>
</div> </div>
<div class="col-md-6"> <div class="col-md-6">
<input type="number" id="webserver.api.temp.limit"> <input type="number" id="webserver.api.temp.limit" data-key="webserver.api.temp.limit">
</div> </div>
</div> </div>
<div class="row"> <div class="row">
@@ -89,7 +89,7 @@ mg.include('scripts/pi-hole/lua/header_authenticated.lp','r')
<label for="webserver.api.temp.unit">Temperature unit:</label> <label for="webserver.api.temp.unit">Temperature unit:</label>
</div> </div>
<div class="col-md-6"> <div class="col-md-6">
<select id="webserver.api.temp.unit" class="form-control" placeholder=""> <select id="webserver.api.temp.unit" data-key="webserver.api.temp.unit" class="form-control" placeholder="">
<option disabled selected>Loading...</option> <option disabled selected>Loading...</option>
</select> </select>
</div> </div>
@@ -115,6 +115,7 @@ mg.include('scripts/pi-hole/lua/header_authenticated.lp','r')
<td></td> <td></td>
<th>ID</th> <th>ID</th>
<th>Valid</th> <th>Valid</th>
<th title="Connection between client and Pi-hole is end-to-end encrypted">TLS</th>
<th>Login at</th> <th>Login at</th>
<th>Valid until</th> <th>Valid until</th>
<th>Client IP</th> <th>Client IP</th>

View File

@@ -19,7 +19,7 @@ mg.include('scripts/pi-hole/lua/header_authenticated.lp','r')
<div class="box-body"> <div class="box-body">
<div class="row"> <div class="row">
<div class="col-md-12"> <div class="col-md-12">
<div><input type="checkbox" id="dhcp.active"><label for="dhcp.active"><strong>DHCP server enabled</strong></label></div> <div><input type="checkbox" id="dhcp.active" data-key="dhcp.active"><label for="dhcp.active"><strong>DHCP server enabled</strong></label></div>
<p id="dhcpnotice" lookatme-text="Make sure your router's DHCP server is disabled when using the Pi-hole DHCP server!">Make sure your router's DHCP server is disabled when using the Pi-hole DHCP server!</p> <p id="dhcpnotice" lookatme-text="Make sure your router's DHCP server is disabled when using the Pi-hole DHCP server!">Make sure your router's DHCP server is disabled when using the Pi-hole DHCP server!</p>
</div> </div>
<div class="col-xs-12"> <div class="col-xs-12">
@@ -29,7 +29,7 @@ mg.include('scripts/pi-hole/lua/header_authenticated.lp','r')
<div class="form-group"> <div class="form-group">
<div class="input-group"> <div class="input-group">
<div class="input-group-addon">From</div> <div class="input-group-addon">From</div>
<input type="text" class="form-control DHCPgroup" id="dhcp.start" <input type="text" class="form-control DHCPgroup" id="dhcp.start" data-key="dhcp.start"
autocomplete="off" spellcheck="false" autocapitalize="none" autocomplete="off" spellcheck="false" autocapitalize="none"
autocorrect="off" value=""> autocorrect="off" value="">
</div> </div>
@@ -39,7 +39,7 @@ mg.include('scripts/pi-hole/lua/header_authenticated.lp','r')
<div class="form-group"> <div class="form-group">
<div class="input-group"> <div class="input-group">
<div class="input-group-addon">To</div> <div class="input-group-addon">To</div>
<input type="text" class="form-control DHCPgroup" id="dhcp.end" <input type="text" class="form-control DHCPgroup" id="dhcp.end" data-key="dhcp.end"
autocomplete="off" spellcheck="false" autocapitalize="none" autocomplete="off" spellcheck="false" autocapitalize="none"
autocorrect="off" value=""> autocorrect="off" value="">
</div> </div>
@@ -50,14 +50,14 @@ mg.include('scripts/pi-hole/lua/header_authenticated.lp','r')
<div class="form-group"> <div class="form-group">
<div class="input-group"> <div class="input-group">
<div class="input-group-addon">Router</div> <div class="input-group-addon">Router</div>
<input type="text" class="form-control DHCPgroup" id="dhcp.router" <input type="text" class="form-control DHCPgroup" id="dhcp.router" data-key="dhcp.router"
autocomplete="off" spellcheck="false" autocapitalize="none" autocomplete="off" spellcheck="false" autocapitalize="none"
autocorrect="off" value=""> autocorrect="off" value="">
</div> </div>
</div> </div>
</div> </div>
<div class="col-md-12"> <div class="col-md-12">
<div><input type="checkbox" id="dhcp.ipv6" class="DHCPgroup">&nbsp;<label for="dhcp.ipv6"><strong>Enable additional IPv6 support (SLAAC + RA)</strong></label></div> <div><input type="checkbox" id="dhcp.ipv6" data-key="dhcp.ipv6" class="DHCPgroup">&nbsp;<label for="dhcp.ipv6"><strong>Enable additional IPv6 support (SLAAC + RA)</strong></label></div>
<p>Enable this option to enable IPv6 support for the Pi-hole DHCP server. This will allow the Pi-hole to hand out IPv6 addresses to clients and also provide IPv6 router advertisements (RA) to clients. This option is only useful if the Pi-hole is configured with an IPv6 address.</p> <p>Enable this option to enable IPv6 support for the Pi-hole DHCP server. This will allow the Pi-hole to hand out IPv6 addresses to clients and also provide IPv6 router advertisements (RA) to clients. This option is only useful if the Pi-hole is configured with an IPv6 address.</p>
</div> </div>
</div> </div>
@@ -76,8 +76,7 @@ mg.include('scripts/pi-hole/lua/header_authenticated.lp','r')
<div class="form-group"> <div class="form-group">
<div class="input-group"> <div class="input-group">
<div class="input-group-addon">Domain</div> <div class="input-group-addon">Domain</div>
<input type="text" class="form-control DHCPgroup" id="dhcp.domain" <input type="text" class="form-control DHCPgroup" id="dhcp.domain" data-key="dhcp.domain" value="">
value="">
</div> </div>
</div> </div>
<p>The DNS domains for the DHCP server. If no domain is specified, then any DHCP hostname with a domain part (i.e., with a period) will be disallowed. If a domain is specified, then hostnames with a domain parts matching the domain here are allowed. In addition, when a suffix is set then hostnames without a domain part have the suffix added as an optional domain part.</p> <p>The DNS domains for the DHCP server. If no domain is specified, then any DHCP hostname with a domain part (i.e., with a period) will be disallowed. If a domain is specified, then hostnames with a domain parts matching the domain here are allowed. In addition, when a suffix is set then hostnames without a domain part have the suffix added as an optional domain part.</p>
@@ -89,7 +88,7 @@ mg.include('scripts/pi-hole/lua/header_authenticated.lp','r')
<div class="input-group-addon">Lease time</div> <div class="input-group-addon">Lease time</div>
<input type="text" class="form-control DHCPgroup" <input type="text" class="form-control DHCPgroup"
autocomplete="off" spellcheck="false" autocapitalize="none" autocomplete="off" spellcheck="false" autocapitalize="none"
autocorrect="off" id="dhcp.leaseTime" value=""> autocorrect="off" id="dhcp.leaseTime" data-key="dhcp.leaseTime" value="">
</div> </div>
</div> </div>
<p>The lease time can be in seconds, minutes (e.g., "45m"), hours (e.g., "1h"), days (like "2d"), or even weeks ("1w"). You may also use "infinite" as string but be aware of the drawbacks: assigned addresses are will only be made available again after the lease time has passed or when leases are manually deleted below.</p> <p>The lease time can be in seconds, minutes (e.g., "45m"), hours (e.g., "1h"), days (like "2d"), or even weeks ("1w"). You may also use "infinite" as string but be aware of the drawbacks: assigned addresses are will only be made available again after the lease time has passed or when leases are manually deleted below.</p>
@@ -97,11 +96,11 @@ mg.include('scripts/pi-hole/lua/header_authenticated.lp','r')
</div> </div>
<div class="row"> <div class="row">
<div class="col-md-6"> <div class="col-md-6">
<div><input type="checkbox" id="dhcp.rapidCommit" class="DHCPgroup">&nbsp;<label for="dhcp.rapidCommit"><strong>Enable DHCPv4 rapid commit (fast address assignment)</strong></label></div> <div><input type="checkbox" id="dhcp.rapidCommit" data-key="dhcp.rapidCommit" class="DHCPgroup">&nbsp;<label for="dhcp.rapidCommit"><strong>Enable DHCPv4 rapid commit (fast address assignment)</strong></label></div>
<p>The DHCPv4 rapid commit option allows the Pi-hole DHCP server to assign an IP address to a client right away. This can noteably speed up the address assignment process and you will notice, e.g., faster WiFi joins in your network. This option should only be enabled if the Pi-hole DHCP server is the only DHCP server in your network.</p> <p>The DHCPv4 rapid commit option allows the Pi-hole DHCP server to assign an IP address to a client right away. This can noteably speed up the address assignment process and you will notice, e.g., faster WiFi joins in your network. This option should only be enabled if the Pi-hole DHCP server is the only DHCP server in your network.</p>
</div> </div>
<div class="col-md-6"> <div class="col-md-6">
<div><input type="checkbox" id="dhcp.multiDNS" class="DHCPgroup">&nbsp;<label for="dhcp.multiDNS"><strong>Advertise DNS server multiple times</strong></label></div> <div><input type="checkbox" id="dhcp.multiDNS" data-key="dhcp.multiDNS" class="DHCPgroup">&nbsp;<label for="dhcp.multiDNS"><strong>Advertise DNS server multiple times</strong></label></div>
<p>Advertise DNS server multiple times to clients. Some devices will add their own proprietary DNS servers to the list of DNS servers, which can cause issues with Pi-hole. This option will advertise the Pi-hole DNS server multiple times to clients, which should prevent this from happening.</p> <p>Advertise DNS server multiple times to clients. Some devices will add their own proprietary DNS servers to the list of DNS servers, which can cause issues with Pi-hole. This option will advertise the Pi-hole DNS server multiple times to clients, which should prevent this from happening.</p>
</div> </div>
</div> </div>
@@ -149,7 +148,7 @@ mg.include('scripts/pi-hole/lua/header_authenticated.lp','r')
<div class="row"> <div class="row">
<div class="col-xs-12 col-md-6"> <div class="col-xs-12 col-md-6">
<p>Specify per host parameters for the DHCP server. This allows a machine with a particular hardware address to be always allocated the same hostname, IP address and lease time. A hostname specified like this overrides any supplied by the DHCP client on the machine. It is also allowable to omit the hardware address and include the hostname, in which case the IP address and lease times will apply to any machine claiming that name.</p> <p>Specify per host parameters for the DHCP server. This allows a machine with a particular hardware address to be always allocated the same hostname, IP address and lease time. A hostname specified like this overrides any supplied by the DHCP client on the machine. It is also allowable to omit the hardware address and include the hostname, in which case the IP address and lease times will apply to any machine claiming that name.</p>
<textarea class="form-control" id="dhcp-hosts" style="resize: vertical;"></textarea><br>&nbsp; <textarea class="form-control" id="dhcp-hosts" data-key="dhcp.hosts" style="resize: vertical;"></textarea><br>&nbsp;
<p>Each entry should be on a separate line, and should be of the form:</p> <p>Each entry should be on a separate line, and should be of the form:</p>
<pre>[&lt;hwaddr&gt;][,id:&lt;client_id&gt;|*][,set:&lt;tag&gt;][,tag:&lt;tag&gt;][,&lt;ipaddr&gt;][,&lt;hostname&gt;][,&lt;lease_time&gt;][,ignore]</pre> <pre>[&lt;hwaddr&gt;][,id:&lt;client_id&gt;|*][,set:&lt;tag&gt;][,tag:&lt;tag&gt;][,&lt;ipaddr&gt;][,&lt;hostname&gt;][,&lt;lease_time&gt;][,ignore]</pre>
<p>Only one entry per MAC address is allowed.</p> <p>Only one entry per MAC address is allowed.</p>

View File

@@ -43,7 +43,7 @@ mg.include('scripts/pi-hole/lua/header_authenticated.lp','r')
</div> </div>
<div class="box-body"> <div class="box-body">
<p>The following list contains all DNS servers selected above. Furthermore, you can add your own custom DNS servers here. The expected format is one server per line in form of <code>IP#port</code>, where the <code>port</code> is optional. If given, it has to be separated by a hash <code>#</code> from the address (e.g. <code>127.0.0.1#5335</code> for a local <code>unbound</code> istance running on port <code>5335</code>). The port defaults to 53 if omitted.</p> <p>The following list contains all DNS servers selected above. Furthermore, you can add your own custom DNS servers here. The expected format is one server per line in form of <code>IP#port</code>, where the <code>port</code> is optional. If given, it has to be separated by a hash <code>#</code> from the address (e.g. <code>127.0.0.1#5335</code> for a local <code>unbound</code> istance running on port <code>5335</code>). The port defaults to 53 if omitted.</p>
<textarea class="form-control" rows="3" id="DNSupstreamsTextfield" placeholder="Enter upstream DNS servers, one per line" style="resize: vertical;"></textarea> <textarea class="form-control" rows="3" id="DNSupstreamsTextfield" data-key="dns.upstreams" placeholder="Enter upstream DNS servers, one per line" style="resize: vertical;"></textarea>
</div> </div>
</div> </div>
</div> </div>
@@ -85,7 +85,7 @@ mg.include('scripts/pi-hole/lua/header_authenticated.lp','r')
when "Never forward non-FQDNs" is <em>not</em> enabled.</p> when "Never forward non-FQDNs" is <em>not</em> enabled.</p>
<div class="form-group"> <div class="form-group">
<div> <div>
<input type="checkbox" id="dns.revServer.active"> <input type="checkbox" id="dns.revServer.active" data-key="dns.revServer.active">
<label for="dns.revServer.active"><strong>Use Conditional Forwarding</strong></label> <label for="dns.revServer.active"><strong>Use Conditional Forwarding</strong></label>
</div> </div>
<div class="input-group"> <div class="input-group">
@@ -100,13 +100,13 @@ mg.include('scripts/pi-hole/lua/header_authenticated.lp','r')
<tbody> <tbody>
<tr> <tr>
<td> <td>
<input type="text" id="dns.revServer.cidr" placeholder="192.168.0.0/16" class="form-control" autocomplete="off" spellcheck="false" autocapitalize="none" autocorrect="off" value=""> <input type="text" id="dns.revServer.cidr" data-key="dns.revServer.cidr" placeholder="192.168.0.0/16" class="form-control" autocomplete="off" spellcheck="false" autocapitalize="none" autocorrect="off" value="">
</td> </td>
<td> <td>
<input type="text" id="dns.revServer.target" placeholder="192.168.0.1" class="form-control" autocomplete="off" spellcheck="false" autocapitalize="none" autocorrect="off" value=""> <input type="text" id="dns.revServer.target" data-key="dns.revServer.target" placeholder="192.168.0.1" class="form-control" autocomplete="off" spellcheck="false" autocapitalize="none" autocorrect="off" value="">
</td> </td>
<td> <td>
<input type="text" id="dns.revServer.domain" placeholder="local" class="form-control" data-mask autocomplete="off" spellcheck="false" autocapitalize="none" autocorrect="off" value=""> <input type="text" id="dns.revServer.domain" data-key="dns.revServer.domain" placeholder="local" class="form-control" data-mask autocomplete="off" spellcheck="false" autocapitalize="none" autocorrect="off" value="">
</td> </td>
</tr> </tr>
</tbody> </tbody>
@@ -130,22 +130,22 @@ mg.include('scripts/pi-hole/lua/header_authenticated.lp','r')
<div class="no-danger-area"> <div class="no-danger-area">
<h4>Recommended setting</h4> <h4>Recommended setting</h4>
<div> <div>
<input type="radio" name="DNSinterface" id="dns.listeningMode-LOCAL"> <input type="radio" name="DNSinterface" id="dns.listeningMode-LOCAL" data-key="dns.listeningMode" value="local">
<label for="dns.listeningMode-LOCAL"><strong>Allow only local requests</strong><br>Allows only queries from devices that are at most one hop away (local devices)</label> <label for="dns.listeningMode-LOCAL"><strong>Allow only local requests</strong><br>Allows only queries from devices that are at most one hop away (local devices)</label>
</div> </div>
</div> </div>
<div class="danger-area"> <div class="danger-area">
<h4>Potentially dangerous options</h4>Make sure your Pi-hole is properly firewalled! <h4>Potentially dangerous options</h4>Make sure your Pi-hole is properly firewalled!
<div> <div>
<input type="radio" name="DNSinterface" id="dns.listeningMode-SINGLE"> <input type="radio" name="DNSinterface" id="dns.listeningMode-SINGLE" data-key="dns.listeningMode" value="single">
<label for="dns.listeningMode-SINGLE"><strong>Respond only on interface <span id="interface-name-1"></span></strong></label> <label for="dns.listeningMode-SINGLE"><strong>Respond only on interface <span id="interface-name-1"></span></strong></label>
</div> </div>
<div> <div>
<input type="radio" name="DNSinterface" id="dns.listeningMode-BIND"> <input type="radio" name="DNSinterface" id="dns.listeningMode-BIND" data-key="dns.listeningMode" value="bind">
<label for="dns.listeningMode-BIND"><strong>Bind only to interface <span id="interface-name-2"></span></strong></label> <label for="dns.listeningMode-BIND"><strong>Bind only to interface <span id="interface-name-2"></span></strong></label>
</div> </div>
<div> <div>
<input type="radio" name="DNSinterface" id="dns.listeningMode-ALL"> <input type="radio" name="DNSinterface" id="dns.listeningMode-ALL" data-key="dns.listeningMode" value="all">
<label for="dns.listeningMode-ALL"><strong>Permit all origins</strong></label> <label for="dns.listeningMode-ALL"><strong>Permit all origins</strong></label>
</div> </div>
<p>These options are dangerous on devices <p>These options are dangerous on devices
@@ -168,7 +168,7 @@ mg.include('scripts/pi-hole/lua/header_authenticated.lp','r')
<div class="row"> <div class="row">
<div class="col-lg-12"> <div class="col-lg-12">
<div> <div>
<input type="checkbox" id="dns.domainNeeded" title="domain-needed"> <input type="checkbox" id="dns.domainNeeded" data-key="dns.domainNeeded" title="domain-needed">
<label for="dns.domainNeeded"><strong>Never forward non-FQDN <code>A</code> and <code>AAAA</code> queries</strong></label> <label for="dns.domainNeeded"><strong>Never forward non-FQDN <code>A</code> and <code>AAAA</code> queries</strong></label>
<p>Tells Pi-hole to never forward A or AAAA queries for plain <p>Tells Pi-hole to never forward A or AAAA queries for plain
names, without dots or domain parts, to upstream nameservers. If names, without dots or domain parts, to upstream nameservers. If
@@ -179,7 +179,7 @@ mg.include('scripts/pi-hole/lua/header_authenticated.lp','r')
</div> </div>
<br> <br>
<div> <div>
<input type="checkbox" id="dns.bogusPriv" title="bogus-priv"> <input type="checkbox" id="dns.bogusPriv" data-key="dns.bogusPriv" title="bogus-priv">
<label for="dns.bogusPriv"><strong>Never forward reverse lookups for private IP ranges</strong></label> <label for="dns.bogusPriv"><strong>Never forward reverse lookups for private IP ranges</strong></label>
<p>All reverse lookups for private IP ranges (i.e., <code>192.168.0.x/24</code>, etc.) <p>All reverse lookups for private IP ranges (i.e., <code>192.168.0.x/24</code>, etc.)
which are not found in <code>/etc/hosts</code> or the DHCP leases are answered which are not found in <code>/etc/hosts</code> or the DHCP leases are answered
@@ -191,7 +191,7 @@ mg.include('scripts/pi-hole/lua/header_authenticated.lp','r')
</div> </div>
<br> <br>
<div> <div>
<input type="checkbox" id="dns.dnssec"> <input type="checkbox" id="dns.dnssec" data-key="dns.dnssec">
<label for="dns.dnssec"><strong>Use DNSSEC</strong></label> <label for="dns.dnssec"><strong>Use DNSSEC</strong></label>
<p>Validate DNS replies and cache DNSSEC data. When forwarding DNS <p>Validate DNS replies and cache DNSSEC data. When forwarding DNS
queries, Pi-hole requests the DNSSEC records needed to validate queries, Pi-hole requests the DNSSEC records needed to validate
@@ -213,8 +213,8 @@ mg.include('scripts/pi-hole/lua/header_authenticated.lp','r')
<div class="box-body"> <div class="box-body">
<div class="row"> <div class="row">
<div class="col-lg-12"> <div class="col-lg-12">
<p>Block clients making more than <input type="number" id="dns.rateLimit.count" value="" min="0" step="10" style="width: 5em;"> queries within <p>Block clients making more than <input type="number" id="dns.rateLimit.count" data-key="dns.rateLimit.count" data-type="integer" value="" min="0" step="10" style="width: 5em;"> queries within
<input type="number" id="dns.rateLimit.interval" value="" min="0" step="10" style="width: 4em;"> seconds.</p> <input type="number" id="dns.rateLimit.interval" data-key="dns.rateLimit.interval" data-type="integer" value="" min="0" step="10" style="width: 4em;"> seconds.</p>
<p>When a client makes too many queries in too short time, it <p>When a client makes too many queries in too short time, it
gets rate-limited. Rate-limited queries are answered with a gets rate-limited. Rate-limited queries are answered with a
<code>REFUSED</code> reply and not further processed by FTL <code>REFUSED</code> reply and not further processed by FTL