Merge branch 'development-v6' into tweak/settings_changed_only

Signed-off-by: DL6ER <dl6er@dl6er.de>
This commit is contained in:
DL6ER
2024-02-11 10:14:49 +01:00
17 changed files with 172 additions and 164 deletions

View File

@@ -22,7 +22,7 @@ jobs:
uses: actions/checkout@v4.1.1
- name: Set up Node.js
uses: actions/setup-node@v4.0.1
uses: actions/setup-node@v4.0.2
with:
node-version: "20.x"
cache: npm

36
package-lock.json generated
View File

@@ -29,11 +29,11 @@
"select2": "4.0.13"
},
"devDependencies": {
"autoprefixer": "^10.4.16",
"autoprefixer": "^10.4.17",
"eslint-plugin-compat": "^4.2.0",
"postcss": "^8.4.33",
"postcss": "^8.4.35",
"postcss-cli": "^11.0.0",
"prettier": "^3.1.1",
"prettier": "^3.2.5",
"xo": "^0.56.0"
}
},
@@ -1318,9 +1318,9 @@
}
},
"node_modules/autoprefixer": {
"version": "10.4.16",
"resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.16.tgz",
"integrity": "sha512-7vd3UC6xKp0HLfua5IjZlcXvGAGy7cBAXTg2lyQ/8WpNhd6SiZ8Be+xm3FyBSYJx5GKcpRCzBh7RH4/0dnY+uQ==",
"version": "10.4.17",
"resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.17.tgz",
"integrity": "sha512-/cpVNRLSfhOtcGflT13P2794gVSgmPgTR+erw5ifnMLZb0UnSlkK4tquLmkd3BhA+nLo5tX8Cu0upUsGKvKbmg==",
"dev": true,
"funding": [
{
@@ -1337,9 +1337,9 @@
}
],
"dependencies": {
"browserslist": "^4.21.10",
"caniuse-lite": "^1.0.30001538",
"fraction.js": "^4.3.6",
"browserslist": "^4.22.2",
"caniuse-lite": "^1.0.30001578",
"fraction.js": "^4.3.7",
"normalize-range": "^0.1.2",
"picocolors": "^1.0.0",
"postcss-value-parser": "^4.2.0"
@@ -1771,9 +1771,9 @@
}
},
"node_modules/caniuse-lite": {
"version": "1.0.30001572",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001572.tgz",
"integrity": "sha512-1Pbh5FLmn5y4+QhNyJE9j3/7dK44dGB83/ZMjv/qJk86TvDbjk0LosiZo0i0WB0Vx607qMX9jYrn1VLHCkN4rw==",
"version": "1.0.30001579",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001579.tgz",
"integrity": "sha512-u5AUVkixruKHJjw/pj9wISlcMpgFWzSrczLZbrqBSxukQixmg0SJ5sZTpvaFvxU0HoQKd4yoyAogyrAz9pzJnA==",
"dev": true,
"funding": [
{
@@ -5734,9 +5734,9 @@
}
},
"node_modules/postcss": {
"version": "8.4.33",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.33.tgz",
"integrity": "sha512-Kkpbhhdjw2qQs2O2DGX+8m5OVqEcbB9HRBvuYM9pgrjEFUg30A9LmXNlTAUj4S9kgtGyrMbTzVjH7E+s5Re2yg==",
"version": "8.4.35",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.35.tgz",
"integrity": "sha512-u5U8qYpBCpN13BsiEB0CbR1Hhh4Gc0zLFuedrHJKMctHCHAGrMdG0PRM/KErzAL3CU6/eckEtmHNB3x6e3c0vA==",
"dev": true,
"funding": [
{
@@ -5861,9 +5861,9 @@
}
},
"node_modules/prettier": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-3.1.1.tgz",
"integrity": "sha512-22UbSzg8luF4UuZtzgiUOfcGM8s4tjBv6dJRT7j275NXsy2jb4aJa4NNveul5x4eqlF1wuhuR2RElK71RvmVaw==",
"version": "3.2.5",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-3.2.5.tgz",
"integrity": "sha512-3/GWa9aOC0YeD7LUfvOG2NiDyhOWRvt1k+rcKhOuYnMY24iiCphgneUfJDyFXd6rZCAnuLBv6UeAULtrhT/F4A==",
"dev": true,
"bin": {
"prettier": "bin/prettier.cjs"

View File

@@ -25,11 +25,11 @@
"testpr": "npm run prettier:fix && git diff --ws-error-highlight=all --color=always --exit-code && npm run xo:check"
},
"devDependencies": {
"autoprefixer": "^10.4.16",
"autoprefixer": "^10.4.17",
"eslint-plugin-compat": "^4.2.0",
"postcss": "^8.4.33",
"postcss": "^8.4.35",
"postcss-cli": "^11.0.0",
"prettier": "^3.1.1",
"prettier": "^3.2.5",
"xo": "^0.56.0"
},
"browserslist": [

View File

@@ -37,10 +37,16 @@ function secondsTimeSpanToHMS(s) {
return h + ":" + (m < 10 ? "0" + m : m) + ":" + (s < 10 ? "0" + s : s); //zero padding on minutes and seconds
}
function piholeChanged(blocking) {
var status = $("#status");
var ena = $("#pihole-enable");
var dis = $("#pihole-disable");
function piholeChanged(blocking, timer = null) {
const status = $("#status");
const ena = $("#pihole-enable");
const dis = $("#pihole-disable");
const enaT = $("#enableTimer");
if (timer !== null && parseFloat(timer) > 0) {
enaT.html(Date.now() + parseFloat(timer) * 1000);
setTimeout(countDown, 100);
}
switch (blocking) {
case "enabled": {
@@ -81,7 +87,7 @@ function piholeChanged(blocking) {
function countDown() {
var ena = $("#enableLabel");
var enaT = $("#enableTimer");
var target = new Date(parseInt(enaT.html(), 10));
var target = new Date(parseInt(enaT.text(), 10));
var seconds = Math.round((target.getTime() - Date.now()) / 1000);
//Stop and remove timer when user enabled early
@@ -95,7 +101,7 @@ function countDown() {
ena.text("Enable Blocking (" + secondsTimeSpanToHMS(seconds) + ")");
} else {
ena.text("Enable Blocking");
piholeChanged("enabled");
piholeChanged("enabled", null);
if (localStorage) {
localStorage.removeItem("countDownTarget");
}
@@ -114,7 +120,7 @@ function checkBlocking() {
method: "GET",
})
.done(function (data) {
piholeChanged(data.blocking);
piholeChanged(data.blocking, data.timer);
utils.setTimer(checkBlocking, REFRESH_INTERVAL.blocking);
})
.fail(function (data) {
@@ -124,8 +130,7 @@ function checkBlocking() {
}
function piholeChange(action, duration) {
var enaT = $("#enableTimer");
var btnStatus;
let btnStatus = null;
switch (action) {
case "enable":
@@ -153,11 +158,7 @@ function piholeChange(action, duration) {
.done(function (data) {
if (data.blocking === action + "d") {
btnStatus.html("");
piholeChanged(data.blocking);
if (duration > 0) {
enaT.html(Date.now() + duration * 1000);
setTimeout(countDown, 100);
}
piholeChanged(data.blocking, data.timer);
}
})
.fail(function (data) {

View File

@@ -66,6 +66,7 @@ function delGroupItems(type, ids, table) {
$.ajax({
url: url,
data: JSON.stringify(ids),
contentType: "application/json",
method: "POST",
})
.done(function () {

View File

@@ -7,8 +7,7 @@
/* global utils:false, apiFailure:false, updateFtlInfo:false, processGroupResult:false, delGroupItems:false */
var table,
idNames = {};
var table;
function handleAjaxError(xhr, textStatus) {
if (textStatus === "timeout") {
@@ -73,20 +72,20 @@ $(function () {
"\nDatabase ID: " +
data.id;
$("td:eq(1)", row).html(
'<input id="name_' + data.id + '" title="' + tooltip + '" class="form-control">'
'<input id="name_' + dataId + '" title="' + tooltip + '" class="form-control">'
);
var nameEl = $("#name_" + data.id, row);
var nameEl = $("#name_" + dataId, row);
nameEl.val(data.name);
nameEl.on("change", editGroup);
$("td:eq(2)", row).html(
'<input type="checkbox" id="enabled_' +
data.id +
dataId +
'"' +
(data.enabled ? " checked" : "") +
">"
);
var enabledEl = $("#enabled_" + data.id, row);
var enabledEl = $("#enabled_" + dataId, row);
enabledEl.bootstrapToggle({
on: "Enabled",
off: "Disabled",
@@ -96,9 +95,9 @@ $(function () {
});
enabledEl.on("change", editGroup);
$("td:eq(3)", row).html('<input id="comment_' + data.id + '" class="form-control">');
$("td:eq(3)", row).html('<input id="comment_' + dataId + '" class="form-control">');
var comment = data.comment !== null ? data.comment : "";
var commentEl = $("#comment_" + data.id, row);
var commentEl = $("#comment_" + dataId, row);
commentEl.val(comment);
commentEl.on("change", editGroup);
@@ -292,7 +291,7 @@ function editGroup() {
const elem = $(this).attr("id");
const tr = $(this).closest("tr");
const id = tr.attr("data-id");
const oldName = idNames[id];
const oldName = utils.hexDecode(id);
const name = tr.find("#name_" + id).val();
const enabled = tr.find("#enabled_" + id).is(":checked");
const comment = tr.find("#comment_" + id).val();

View File

@@ -200,6 +200,13 @@ function parseQueryStatus(data) {
buttontext =
'<button type="button" class="btn btn-default btn-sm text-red btn-blacklist"><i class="fa fa-ban"></i> Deny</button>';
break;
case "SPECIAL_DOMAIN":
colorClass = "text-red";
icon = "fa-solid fa-ban";
fieldtext = data.status;
buttontext = "";
blocked = true;
break;
default:
colorClass = "text-orange";
icon = "fa-solid fa-question";
@@ -276,17 +283,16 @@ function formatInfo(data) {
"</span></strong></div>";
}
var regexInfo = "",
var listInfo = "",
cnameInfo = "";
if (data.regex_id !== null && data.regex_id > -1) {
var regexLink =
'<a href="groups/domains?domainid=' +
data.regex_id +
'" target="_blank">entry with ID ' +
data.regex_id +
"</a>";
regexInfo =
divStart + "Query was " + queryStatus.matchText + " by </td><td>" + regexLink + "</div>";
if (data.list_id !== null && data.list_id !== -1) {
// Some list matched - add link to search page
var listLink =
'<a href="search?domain=' +
encodeURIComponent(data.domain) +
'" target="_blank">search lists</a>';
listInfo = divStart + "Query was " + queryStatus.matchText + ", " + listLink + "</div>";
}
if (queryStatus.isCNAME) {
@@ -349,7 +355,7 @@ function formatInfo(data) {
dnssecInfo +
statusInfo +
cnameInfo +
regexInfo +
listInfo +
ttlInfo +
replyInfo +
dbInfo +

View File

@@ -6,6 +6,18 @@
* Please see LICENSE file for your rights under this license. */
/* global utils:false, apiFailure:false */
var GETDict = {};
$(function () {
GETDict = utils.parseQueryString();
if (GETDict.domain !== undefined) {
$("input[id^='domain']").val(GETDict.domain);
}
if (GETDict.N !== undefined) {
$("#number").val(GETDict.number);
}
});
function eventsource(partial) {
const ta = $("#output");

View File

@@ -58,7 +58,7 @@ function generateRow(topic, key, value) {
: "") +
"</h3>" +
"<p>" +
utils.escapeHtml(value.description).replace("\n", "<br>") +
utils.escapeHtml(value.description).replaceAll("\n", "<br>") +
"</p>" +
"</div>" +
'<div class="box-body">' +

View File

@@ -51,7 +51,7 @@ function importZIP() {
$("#modal-import-success-title").text("Import successful");
var text = "<p>Processed files:</p><ul>";
for (var i = 0; i < data.files.length; i++) {
text += "<li>/" + utils.escapeHtml(data.files[i]) + "</li>";
text += "<li>" + utils.escapeHtml(data.files[i]) + "</li>";
}
text += "</ul>";

View File

@@ -152,6 +152,10 @@ function showAlert(type, icon, title, message) {
}
function datetime(date, html, humanReadable) {
if (date === 0 && humanReadable) {
return "Never";
}
var format = html === false ? "Y-MM-DD HH:mm:ss z" : "Y-MM-DD [<br class='hidden-lg'>]HH:mm:ss z";
var timestr = moment.unix(Math.floor(date)).format(format).trim();
return humanReadable
@@ -391,7 +395,7 @@ function checkMessages() {
})
.done(function (data) {
if (data.count > 0) {
var more = '\nAccess "Tools/Pi-hole diganosis" for further details.';
var more = '\nAccess "Tools/Pi-hole diagnosis" for further details.';
var title =
data.count > 1
? "There are " + data.count + " warnings." + more

View File

@@ -24,14 +24,19 @@ mg.include('scripts/pi-hole/lua/settings_header.lp','r')
<div class="box-body">
<div class="row">
<div class="col-md-6">
<p><strong>Domains to be excluded from Top Domains / Ads Lists</strong></p>
<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><strong>Domains to be excluded from Top Domain Lists and Query Log</strong></p>
<textarea class="form-control" rows="4" id="webserver.api.excludeDomains" data-key="webserver.api.excludeDomains" placeholder="Enter regex 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>
</div>
<div class="col-md-6">
<p><strong>Clients to be excluded from Top Clients List</strong></p>
<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><strong>Clients to be excluded from Top Client Lists and Query Log </strong></p>
<textarea class="form-control" rows="4" id="webserver.api.excludeClients" data-key="webserver.api.excludeClients" placeholder="Enter regex 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>
</div>
</div>
<div class="row">
<div class="col-md-12">
<p><strong>Important:</strong> Those input fields accept regex entries only. Please refer to <a href="https://docs.pi-hole.net/regex/tutorial/" rel="noopener" target="_blank">our guide</a> how to construct valid regex entries.
</div>
</div>
</div>

View File

@@ -61,16 +61,19 @@ mg.include('scripts/pi-hole/lua/settings_header.lp','r')
</div>
</div>
<div class="col-xs-12 col-sm-6 col-md-12 col-lg-6">
<label>Netmask (<code>0.0.0.0</code> = auto)</label>
<label>Netmask</label>
<div class="form-group">
<div class="input-group">
<div class="input-group-addon">Netmask</div>
<input type="text" class="form-control DHCPgroup" id="dhcp.netmask" data-key="dhcp.netmask"
autocomplete="off" spellcheck="false" autocapitalize="none"
autocorrect="off" value="">
autocorrect="off" value="" placeholder="automatic">
</div>
</div>
</div>
<div class="col-md-12">
<p>Leave the netmask field empty to have Pi-hole infer it from the configured IP address of your device. If you want to specify a netmask, you can use the format <code>255.255.255.0</code>.</p>
</div>
<div class="col-md-12">
<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>

View File

@@ -59,64 +59,48 @@ mg.include('scripts/pi-hole/lua/settings_header.lp','r')
</div>
<div class="box box-warning settings-level-expert">
<div class="box-header with-border">
<h3 class="box-title" data-configkeys="dns.revServer.active dns.revServer.cidr dns.revServer.target dns.revServer.domain">Conditional forwarding</h3>
<h3 class="box-title" data-configkeys="dns.domain dns.expandHosts">DNS domain settings</h3>
</div>
<div class="box-body">
<div class="row">
<div class="col-md-12">
<label>Pi-hole domain name</label>
<div class="form-group">
<div class="input-group">
<div class="input-group-addon">Domain</div>
<input type="text" class="form-control" id="dns.domain" data-key="dns.domain" value="">
</div>
</div>
<p>The DNS domains for your Pi-hole. If no domain is specified and you are using Pi-hole's DHCP server, then any hostnames 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>
<div>
<input type="checkbox" id="dns.expandHosts" data-key="dns.expandHosts" title="domain-needed">
<label for="dns.expandHosts"><strong>Expand hostnames</strong></label>
<p>If set, the domain is added to simple names (without a period) in /etc/hosts in the same way as for DHCP-derived names.</p>
</div>
</div>
</div>
</div>
</div>
<div class="box box-warning settings-level-expert">
<div class="box-header with-border">
<h3 class="box-title" data-configkeys="dns.rateLimit.count dns.rateLimit.interval">Rate-limiting</h3>
</div>
<div class="box-body">
<div class="row">
<div class="col-lg-12">
<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 which addresses belong to your local network.
Exemplary input 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>.
Setting up IPv6 ranges is exactly similar to setting up IPv4 here and fully supported.
Feel free to reach out to us on our
<a href="https://discourse.pi-hole.net" rel="noopener" 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>
<p>Enabling Conditional Forwarding will also forward all hostnames (i.e., non-FQDNs) to the router
when "Never forward non-FQDNs" is <em>not</em> enabled.</p>
<div class="form-group">
<div>
<input type="checkbox" id="dns.revServer.active" data-key="dns.revServer.active">
<label for="dns.revServer.active"><strong>Use Conditional Forwarding</strong></label>
</div>
<div class="input-group">
<table class="table table-bordered">
<thead>
<tr>
<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>
</thead>
<tbody>
<tr>
<td>
<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>
<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>
<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>
</tr>
</tbody>
</table>
</div>
</div>
<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" 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
gets rate-limited. Rate-limited queries are answered with a
<code>REFUSED</code> reply and not further processed by FTL
and prevent Pi-holes getting overwhelmed by rogue clients.
It is important to note that rate-limiting is happening on a
per-client basis. Other clients can continue to use FTL while
rate-limited clients are short-circuited at the same time.</p>
<p>Rate-limiting may be disabled altogether by setting both
values to zero. See
<a href="https://docs.pi-hole.net/ftldns/configfile/#rate_limit" target="_blank">our documentation</a>
for further details.</p>
</div>
</div>
</div>
@@ -164,30 +148,6 @@ mg.include('scripts/pi-hole/lua/settings_header.lp','r')
</div>
</div>
</div>
<div class="box box-warning">
<div class="box-header with-border">
<h3 class="box-title" data-configkeys="dns.domain dns.expandHosts">DNS domain settings</h3>
</div>
<div class="box-body">
<div class="row">
<div class="col-md-12">
<label>Pi-hole domain name</label>
<div class="form-group">
<div class="input-group">
<div class="input-group-addon">Domain</div>
<input type="text" class="form-control" id="dns.domain" data-key="dns.domain" value="">
</div>
</div>
<p>The DNS domains for your Pi-hole. If no domain is specified and you are using Pi-hole's DHCP server, then any hostnames 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>
<div>
<input type="checkbox" id="dns.expandHosts" data-key="dns.expandHosts" title="domain-needed">
<label for="dns.expandHosts"><strong>Expand hostnames</strong></label>
<p>If set, the domain is added to simple names (without a period) in /etc/hosts in the same way as for DHCP-derived names.</p>
</div>
</div>
</div>
</div>
</div>
<div class="box box-warning">
<div class="box-header with-border">
<h3 class="box-title" data-configkeys="dns.domainNeeded dns.bogusPriv dns.dnssec">Advanced DNS settings</h3>
@@ -233,26 +193,40 @@ mg.include('scripts/pi-hole/lua/settings_header.lp','r')
</div>
</div>
</div>
</div>
<div class="col-lg-12">
<div class="box box-warning settings-level-expert">
<div class="box-header with-border">
<h3 class="box-title" data-configkeys="dns.rateLimit.count dns.rateLimit.interval">Rate-limiting</h3>
<h3 class="box-title" data-configkeys="dns.revServers">Conditional forwarding</h3>
</div>
<div class="box-body">
<div class="row">
<div class="col-lg-12">
<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" 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
gets rate-limited. Rate-limited queries are answered with a
<code>REFUSED</code> reply and not further processed by FTL
and prevent Pi-holes getting overwhelmed by rogue clients.
It is important to note that rate-limiting is happening on a
per-client basis. Other clients can continue to use FTL while
rate-limited clients are short-circuited at the same time.</p>
<p>Rate-limiting may be disabled altogether by setting both
values to zero. See
<a href="https://docs.pi-hole.net/ftldns/configfile/#rate_limit" target="_blank">our documentation</a>
for further details.</p>
<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 which addresses belong to your local network.
Exemplary input 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>.
Setting up IPv6 ranges is exactly similar to setting up IPv4 here and fully supported.
Feel free to reach out to us on our
<a href="https://discourse.pi-hole.net" rel="noopener" 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>
<p>Enabling Conditional Forwarding will also forward all hostnames (i.e., non-FQDNs) to the router
when "Never forward non-FQDNs" is <em>not</em> enabled.</p>
<p>The following list contains all reverse servers you want to add. The expected format is one server per line in form of <code>&lt;enabled&gt;,&lt;ip-address&gt;[/&lt;prefix-len&gt;],&lt;server&gt;[#&lt;port&gt;][,&lt;domain&gt;]</code>. A valid config line could look like <code>true,192.168.0.0/24,192.168.0.1,fritz.box</code></p>
<textarea class="form-control" rows="3" id="dns.revServers" data-key="dns.revServers" placeholder="Enter reverse DNS servers, one per line" style="resize: vertical;"></textarea>
</div>
</div>
</div>

View File

@@ -20,8 +20,8 @@ mg.include('scripts/pi-hole/lua/settings_header.lp','r')
<h3 class="box-title">Export your Pi-hole's configuration</h3>
</div>
<div class="box-body">
<p>Warning: This archive contains sensitive information about your Pi-hole installation, e.g. the API token and the 2FA-TOTP secret (if enabled). Please be careful with this file and do not share it with anyone even if they claim to help you.</p>
<? if not is_secure then ?><p class='text-danger'>Warning: You are currently not using an end-to-end encryption. This means that your API token and 2FA-TOTP secret will be transmitted in plain text. We recommend to use HTTPS when exporting your configuration.</p><? end ?>
<p>Warning: This archive contains sensitive information about your Pi-hole installation, e.g. your 2FA-TOTP secret (if enabled). Please be careful with this file and do not share it with anyone even if they claim to help you.</p>
<? if not is_secure then ?><p class='text-danger'>Warning: You are currently not using an end-to-end encryption. This means that secrets like your 2FA-TOTP secret will be transmitted in plain text. We recommend to use HTTPS when exporting your configuration.</p><? end ?>
<div class="pull-right">
<a class="btn btn-app btn-success" id="GETTeleporter" target="_blank">
<i class="fa fa-save"></i><br>Export
@@ -38,7 +38,7 @@ mg.include('scripts/pi-hole/lua/settings_header.lp','r')
<div class="box-body">
<div class="form-group">
<label for="file">File input</label>
<input type="file" name="file" id="file" accept=".zip">
<input type="file" name="file" id="file" accept=".zip,.tar.gz">
<p class="help-block">When importing settings from a <em>newer</em> version of Pi-hole, not yet existing settings will be ignored. When importing from an <em>older</em> version of Pi-hole, settings for newer features will be initialized with their default values.</p>
</div>
<div class="pull-right">

View File

@@ -1068,12 +1068,15 @@ table.dataTable tbody > tr > .selected {
#output {
position: relative;
display: grid;
margin: 5px 0;
min-height: 36px;
padding: 4px 8px;
}
#output.pre-taillog {
display: grid;
}
.loading::before {
content: " ";
position: absolute;

View File

@@ -25,7 +25,7 @@ mg.include('scripts/pi-hole/lua/header_authenticated.lp','r')
<div class="box-body">
<div class="row">
<div class="col-md-12">
<pre id="output" class="pre pre-scrollable"></pre>
<pre id="output" class="pre pre-scrollable pre-taillog"></pre>
</div>
</div>
</div>