From ccc3f9a7b905c104117c2a620df2e1ad6ff43e43 Mon Sep 17 00:00:00 2001 From: XhmikosR Date: Thu, 15 Oct 2020 07:27:57 +0300 Subject: [PATCH 001/103] Fix https redirects --- docs/ftldns/in-depth.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/ftldns/in-depth.md b/docs/ftldns/in-depth.md index b7f3879..f6d11f3 100644 --- a/docs/ftldns/in-depth.md +++ b/docs/ftldns/in-depth.md @@ -25,8 +25,8 @@ Command-line arguments can be arbitrarily combined, e.g. `pihole-FTL debug test` ## Linux capabilities -Capabilities (POSIX 1003.1e, [capabilities(7)](http://man7.org/linux/man-pages/man7/capabilities.7.html)) provide fine-grained control over superuser permissions, allowing the use of the `root` user to be avoided. -To perform permission checks, traditional UNIX implementations distinguish two categories of processes: *privileged processes* (superuser or `root`), and *unprivileged processes*. Privileged processes bypass all kernel permission checks, while unprivileged processes are subject to full permission checking based on the process's credentials (user and group permissions and supplementary process capabilities). Capabilities are implemented on Linux using extended attributes ([xattr(7)](http://man7.org/linux/man-pages/man5/attr.5.html)) in the `security` namespace. Extended attributes are supported by all major Linux file systems, including Ext2, Ext3, Ext4, Btrfs, JFS, XFS, and ReiserFS. +Capabilities (POSIX 1003.1e, [capabilities(7)](https://man7.org/linux/man-pages/man7/capabilities.7.html)) provide fine-grained control over superuser permissions, allowing the use of the `root` user to be avoided. +To perform permission checks, traditional UNIX implementations distinguish two categories of processes: *privileged processes* (superuser or `root`), and *unprivileged processes*. Privileged processes bypass all kernel permission checks, while unprivileged processes are subject to full permission checking based on the process's credentials (user and group permissions and supplementary process capabilities). Capabilities are implemented on Linux using extended attributes ([xattr(7)](https://man7.org/linux/man-pages/man5/attr.5.html)) in the `security` namespace. Extended attributes are supported by all major Linux file systems, including Ext2, Ext3, Ext4, Btrfs, JFS, XFS, and ReiserFS. For your safety and comfort, `pihole-FTL` is run by the entirely unprivileged user `pihole`. Whereas `dnsmasq` is running as `root` process, we designed `pihole-FTL` to be run by the entirely unprivileged user `pihole`. As a consequence, `pihole-FTL` will not be able to access the files of any other user on this system or mess around with your system's configuration. From 9bf4dedbef486cee073557cc8ba54d8f0981960a Mon Sep 17 00:00:00 2001 From: XhmikosR Date: Thu, 15 Oct 2020 07:29:57 +0300 Subject: [PATCH 002/103] upstream-dns-providers.md: fix redirect --- docs/guides/upstream-dns-providers.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/guides/upstream-dns-providers.md b/docs/guides/upstream-dns-providers.md index 9275ad1..f70223d 100644 --- a/docs/guides/upstream-dns-providers.md +++ b/docs/guides/upstream-dns-providers.md @@ -40,7 +40,7 @@ OpenDNS also provides the OpenDNS FamilyShield (free)- option. The service block - 208.67.222.123 - 208.67.220.123 -[More information on OpenDNS FamilyShield](https://www.opendns.com/setupguide/#familyshield) + [OpenDNS FamilyShield introduction Blog](https://umbrella.cisco.com/blog/2010/06/23/introducing-familyshield-parental-controls/) +[More information on OpenDNS FamilyShield](https://www.opendns.com/setupguide/#familyshield) + [OpenDNS FamilyShield introduction Blog](https://umbrella.cisco.com/blog/introducing-familyshield-parental-controls) ### Level3 DNS From 12d4c1c30f270f23f1fde2e59f2bf941f312a43c Mon Sep 17 00:00:00 2001 From: Marcin Mielnicki Date: Fri, 16 Oct 2020 18:06:46 +0200 Subject: [PATCH 003/103] Syntax highlighting in unbound config --- docs/guides/unbound.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/guides/unbound.md b/docs/guides/unbound.md index 9c62a6b..dcdd7be 100644 --- a/docs/guides/unbound.md +++ b/docs/guides/unbound.md @@ -76,7 +76,7 @@ Highlights: `/etc/unbound/unbound.conf.d/pi-hole.conf`: -```ini +```yaml server: # If no logfile is specified, syslog is used # logfile: "/var/log/unbound/unbound.log" @@ -179,7 +179,7 @@ Level 5 logs client identification for cache misses First, specify the log file and the verbosity level in the `server` part of `/etc/unbound/unbound.conf.d/pi-hole.conf`: -```ini +```yaml server: # If no logfile is specified, syslog is used logfile: "/var/log/unbound/unbound.log" From 9becfeee120783762a5ba5bb23accac350499296 Mon Sep 17 00:00:00 2001 From: XhmikosR Date: Tue, 20 Oct 2020 09:49:48 +0300 Subject: [PATCH 004/103] Switch to markdownlint-cli2 (#404) This is an improved version of of markdownlint-cli, see https://github.com/DavidAnson/markdownlint-cli2 --- package-lock.json | 338 +++++++++++++++++++++++++++------------------- package.json | 4 +- 2 files changed, 204 insertions(+), 138 deletions(-) diff --git a/package-lock.json b/package-lock.json index db68547..09205e7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -82,6 +82,32 @@ } } }, + "@nodelib/fs.scandir": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.3.tgz", + "integrity": "sha512-eGmwYQn3gxo4r7jdQnkrrN6bY478C3P+a/y72IJukF8LjB6ZHeB3c+Ehacj3sYeSmUXGlnA67/PmbM9CVwL7Dw==", + "dev": true, + "requires": { + "@nodelib/fs.stat": "2.0.3", + "run-parallel": "^1.1.9" + } + }, + "@nodelib/fs.stat": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.3.tgz", + "integrity": "sha512-bQBFruR2TAwoevBEd/NWMoAAtNGzTRgdrqnYCc7dhzfoNvqPzLyqlEQnzZ3kVnNrSp25iyxE00/3h2fqGAGArA==", + "dev": true + }, + "@nodelib/fs.walk": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.4.tgz", + "integrity": "sha512-1V9XOY4rDW0rehzbrcqAmHnz8e7SKvX27gh8Gt2WgB0+pdzdiLV83p72kZPU+jvMbS1qU5mauP2iOvO8rhmurQ==", + "dev": true, + "requires": { + "@nodelib/fs.scandir": "2.1.3", + "fastq": "^1.6.0" + } + }, "@sindresorhus/is": { "version": "0.14.0", "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz", @@ -196,18 +222,18 @@ "sprintf-js": "~1.0.2" } }, + "array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true + }, "arrify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", "dev": true }, - "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", - "dev": true - }, "boolbase": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", @@ -248,14 +274,13 @@ } } }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", "dev": true, "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "fill-range": "^7.0.1" } }, "cacheable-request": { @@ -375,21 +400,6 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, - "commander": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.9.0.tgz", - "integrity": "sha1-nJkJQXbhIkDLItbFFGCYQA/g99Q=", - "dev": true, - "requires": { - "graceful-readlink": ">= 1.0.0" - } - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true - }, "configstore": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/configstore/-/configstore-5.0.1.tgz", @@ -470,12 +480,6 @@ "mimic-response": "^1.0.0" } }, - "deep-extend": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.5.1.tgz", - "integrity": "sha512-N8vBdOa+DF7zkRrDCsaOXoCs/E2fJfx9B9MrKnnSiHNh4ws7eSys6YQE4KvT1cecKmOASYQBhbKjeuDD9lT81w==", - "dev": true - }, "defer-to-connect": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.1.3.tgz", @@ -494,6 +498,15 @@ "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=", "dev": true }, + "dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "requires": { + "path-type": "^4.0.0" + } + }, "dom-serializer": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.1.tgz", @@ -612,12 +625,6 @@ "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", "dev": true }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true - }, "etag": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", @@ -642,6 +649,38 @@ "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", "dev": true }, + "fast-glob": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.4.tgz", + "integrity": "sha512-kr/Oo6PX51265qeuCYsyGypiO5uJFgBS0jksyG7FUeCyQzNwYnzrNIMR1NXfkZXsMYXYLRAHgISHBz8gQcxKHQ==", + "dev": true, + "requires": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.0", + "merge2": "^1.3.0", + "micromatch": "^4.0.2", + "picomatch": "^2.2.1" + } + }, + "fastq": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.8.0.tgz", + "integrity": "sha512-SMIZoZdLh/fgofivvIkmknUXyPnvxRE3DhtZ5Me3Mrsk5gyPL42F0xr51TdRXskBxHfMp+07bcYzfsYEsSQA9Q==", + "dev": true, + "requires": { + "reusify": "^1.0.4" + } + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, "finalhandler": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", @@ -673,12 +712,6 @@ "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=", "dev": true }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true - }, "gaxios": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-3.2.0.tgz", @@ -692,12 +725,6 @@ "node-fetch": "^2.3.0" } }, - "get-stdin": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-5.0.1.tgz", - "integrity": "sha1-Ei4WFZHiH/TFJTAwVpPyDmOTo5g=", - "dev": true - }, "get-stream": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", @@ -707,18 +734,13 @@ "pump": "^3.0.0" } }, - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "glob-parent": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", + "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", "dev": true, "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" + "is-glob": "^4.0.1" } }, "global-dirs": { @@ -730,6 +752,20 @@ "ini": "^1.3.5" } }, + "globby": { + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.1.tgz", + "integrity": "sha512-iH9RmgwCmUJHi2z5o2l3eTtGBtXek1OYlHrbcxOYugyHLmAsZrPj43OtHThd62Buh/Vv6VyCBD2bdyWcGNQqoQ==", + "dev": true, + "requires": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.1.1", + "ignore": "^5.1.4", + "merge2": "^1.3.0", + "slash": "^3.0.0" + } + }, "got": { "version": "9.6.0", "resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz", @@ -755,12 +791,6 @@ "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", "dev": true }, - "graceful-readlink": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz", - "integrity": "sha1-TK+tdrxi8C+gObL5Tpo906ORpyU=", - "dev": true - }, "hard-rejection": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz", @@ -877,16 +907,6 @@ "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", "dev": true }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, "inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", @@ -914,12 +934,27 @@ "ci-info": "^2.0.0" } }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true + }, "is-fullwidth-code-point": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", "dev": true }, + "is-glob": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, "is-installed-globally": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.3.2.tgz", @@ -936,6 +971,12 @@ "integrity": "sha512-WW/rQLOazUq+ST/bCAVBp/2oMERWLsR7OrKyt052dNDk4DHcDE0/7QSXITlmi+VBcV13DfIbysG3tZJm5RfdBA==", "dev": true }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, "is-obj": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", @@ -978,16 +1019,6 @@ "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", "dev": true }, - "js-yaml": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", - "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", - "dev": true, - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, "json-buffer": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz", @@ -1000,12 +1031,6 @@ "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", "dev": true }, - "jsonc-parser": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-2.2.1.tgz", - "integrity": "sha512-o6/yDBYccGvTz1+QFevz6l6OBZ2+fMVu2JZ9CIhzsYRX4mjaK5IyX9eldUdCmga16zlgQxyrj5pt9kzuj2C02w==", - "dev": true - }, "jsonexport": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/jsonexport/-/jsonexport-3.0.1.tgz", @@ -1084,18 +1109,6 @@ "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==", "dev": true }, - "lodash.differencewith": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.differencewith/-/lodash.differencewith-4.5.0.tgz", - "integrity": "sha1-uvr7yRi1UVTheRdqALsK76rIVLc=", - "dev": true - }, - "lodash.flatten": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz", - "integrity": "sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8=", - "dev": true - }, "lowercase-keys": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", @@ -1147,28 +1160,35 @@ "markdown-it": "11.0.0" } }, - "markdownlint-cli": { - "version": "0.24.0", - "resolved": "https://registry.npmjs.org/markdownlint-cli/-/markdownlint-cli-0.24.0.tgz", - "integrity": "sha512-AusUxaX4sFayUBFTCKeHc8+fq73KFqIUW+ZZZYyQ/BvY0MoGAnE2C/3xiawSE7WXmpmguaWzhrXRuY6IrOLX7A==", + "markdownlint-cli2": { + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/markdownlint-cli2/-/markdownlint-cli2-0.0.10.tgz", + "integrity": "sha512-tuWKncGgg0ic9YIWzPu1w2upoGNF/CQwb+CMzJmB8LMM2MhFKTUQSDyUt0kM022qs1R7KjxFXG7y5FBmqGVhUQ==", "dev": true, "requires": { - "commander": "~2.9.0", - "deep-extend": "~0.5.1", - "get-stdin": "~5.0.1", - "glob": "~7.1.2", - "ignore": "~5.1.4", - "js-yaml": "~3.13.1", - "jsonc-parser": "~2.2.0", - "lodash.differencewith": "~4.5.0", - "lodash.flatten": "~4.4.0", + "globby": "~11.0.1", "markdownlint": "~0.21.0", + "markdownlint-cli2-formatter-default": "~0.0.1", "markdownlint-rule-helpers": "~0.12.0", - "minimatch": "~3.0.4", - "minimist": "~1.2.5", - "rc": "~1.2.7" + "micromatch": "~4.0.2", + "strip-json-comments": "~3.1.1", + "yaml": "~1.10.0" + }, + "dependencies": { + "strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true + } } }, + "markdownlint-cli2-formatter-default": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/markdownlint-cli2-formatter-default/-/markdownlint-cli2-formatter-default-0.0.1.tgz", + "integrity": "sha512-JvWhlus5zR4cFywXB2RSPVX73YD9177xm9WkV/8CRPDS1MM/Fh6Ds0WnY67ZaiITavZ0H+Fgz1aVhUwrPNa7ug==", + "dev": true + }, "markdownlint-rule-helpers": { "version": "0.12.0", "resolved": "https://registry.npmjs.org/markdownlint-rule-helpers/-/markdownlint-rule-helpers-0.12.0.tgz", @@ -1200,6 +1220,22 @@ "yargs-parser": "^18.1.3" } }, + "merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true + }, + "micromatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", + "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", + "dev": true, + "requires": { + "braces": "^3.0.1", + "picomatch": "^2.0.5" + } + }, "mime": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", @@ -1218,15 +1254,6 @@ "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", "dev": true }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, "minimist": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", @@ -1409,18 +1436,24 @@ "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "dev": true }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true - }, "path-parse": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", "dev": true }, + "path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true + }, + "picomatch": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", + "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", + "dev": true + }, "prepend-http": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz", @@ -1574,6 +1607,18 @@ "lowercase-keys": "^1.0.0" } }, + "reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true + }, + "run-parallel": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.1.9.tgz", + "integrity": "sha512-DEqnSRTDw/Tc3FXf49zedI638Z9onwUotBMiUFKmrO2sdFKIbXamXGQ3Axd4qgphxKB4kw/qP1w5kTxnfU1B9Q==", + "dev": true + }, "safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -1662,6 +1707,12 @@ "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==", "dev": true }, + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true + }, "spdx-correct": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", @@ -1800,6 +1851,15 @@ "integrity": "sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==", "dev": true }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "requires": { + "is-number": "^7.0.0" + } + }, "toidentifier": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", @@ -1936,6 +1996,12 @@ "integrity": "sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==", "dev": true }, + "yaml": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.0.tgz", + "integrity": "sha512-yr2icI4glYaNG+KWONODapy2/jDdMSDnrONSjblABjD9B4Z5LgiircSt8m8sRZFNi08kG9Sm0uSHtEmP3zaEGg==", + "dev": true + }, "yargs-parser": { "version": "18.1.3", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", diff --git a/package.json b/package.json index f1781f3..c82033d 100644 --- a/package.json +++ b/package.json @@ -17,12 +17,12 @@ "homepage": "https://docs.pi-hole.net/", "scripts": { "build": "mkdocs build --clean", - "markdownlint": "markdownlint \"**/*.md\" -i \"**/node_modules/**\"", + "markdownlint": "markdownlint-cli2 \"**/*.md\" \"!**/node_modules/**\"", "linkinator": "linkinator site --recurse --silent --skip \"^(?!http://localhost)\"", "test": "npm run markdownlint && npm run linkinator" }, "devDependencies": { "linkinator": "^2.2.0", - "markdownlint-cli": "^0.24.0" + "markdownlint-cli2": "0.0.10" } } From 0f2603402d8e9439744bb9824670d1991a95208d Mon Sep 17 00:00:00 2001 From: DL6ER Date: Sun, 25 Oct 2020 20:15:56 +0100 Subject: [PATCH 005/103] Update docs/ftldns/in-depth.md Co-authored-by: XhmikosR --- docs/ftldns/in-depth.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/ftldns/in-depth.md b/docs/ftldns/in-depth.md index f6d11f3..570d765 100644 --- a/docs/ftldns/in-depth.md +++ b/docs/ftldns/in-depth.md @@ -26,7 +26,7 @@ Command-line arguments can be arbitrarily combined, e.g. `pihole-FTL debug test` ## Linux capabilities Capabilities (POSIX 1003.1e, [capabilities(7)](https://man7.org/linux/man-pages/man7/capabilities.7.html)) provide fine-grained control over superuser permissions, allowing the use of the `root` user to be avoided. -To perform permission checks, traditional UNIX implementations distinguish two categories of processes: *privileged processes* (superuser or `root`), and *unprivileged processes*. Privileged processes bypass all kernel permission checks, while unprivileged processes are subject to full permission checking based on the process's credentials (user and group permissions and supplementary process capabilities). Capabilities are implemented on Linux using extended attributes ([xattr(7)](https://man7.org/linux/man-pages/man5/attr.5.html)) in the `security` namespace. Extended attributes are supported by all major Linux file systems, including Ext2, Ext3, Ext4, Btrfs, JFS, XFS, and ReiserFS. +To perform permission checks, traditional UNIX implementations distinguish two categories of processes: *privileged processes* (superuser or `root`), and *unprivileged processes*. Privileged processes bypass all kernel permission checks, while unprivileged processes are subject to full permission checking based on the process's credentials (user and group permissions and supplementary process capabilities). Capabilities are implemented on Linux using extended attributes ([xattr(7)](https://man7.org/linux/man-pages/man7/xattr.7.html)) in the `security` namespace. Extended attributes are supported by all major Linux file systems, including Ext2, Ext3, Ext4, Btrfs, JFS, XFS, and ReiserFS. For your safety and comfort, `pihole-FTL` is run by the entirely unprivileged user `pihole`. Whereas `dnsmasq` is running as `root` process, we designed `pihole-FTL` to be run by the entirely unprivileged user `pihole`. As a consequence, `pihole-FTL` will not be able to access the files of any other user on this system or mess around with your system's configuration. From 8b126ca531ab6bb86e658a9c424467845c47f72f Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Sat, 24 Oct 2020 10:12:35 +0000 Subject: [PATCH 006/103] Bump mkdocs-material from 6.0.2 to 6.1.0 Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 6.0.2 to 6.1.0. - [Release notes](https://github.com/squidfunk/mkdocs-material/releases) - [Changelog](https://github.com/squidfunk/mkdocs-material/blob/master/docs/changelog.md) - [Commits](https://github.com/squidfunk/mkdocs-material/compare/6.0.2...6.1.0) Signed-off-by: dependabot-preview[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index b6f789c..42235d2 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,5 @@ markdown-include==0.6.0 mkdocs==1.1.2 mkdocs-git-revision-date-localized-plugin==0.7.2 -mkdocs-material==6.0.2 +mkdocs-material==6.1.0 mkdocs-redirects==1.0.1 From 5e9e13f54dfa64791b2cc1d90bf6a3d3d852fea7 Mon Sep 17 00:00:00 2001 From: XhmikosR Date: Mon, 26 Oct 2020 09:52:31 +0200 Subject: [PATCH 007/103] Update dns-over-https.md (#403) Add the cloudflared archive page --- docs/guides/dns-over-https.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/guides/dns-over-https.md b/docs/guides/dns-over-https.md index 1014ce3..053ae46 100644 --- a/docs/guides/dns-over-https.md +++ b/docs/guides/dns-over-https.md @@ -58,6 +58,10 @@ sudo chmod +x /usr/local/bin/cloudflared cloudflared -v ``` +#### `cloudflared` archive page + +You can find all `cloudflared` binary releases on . + ### Configuring `cloudflared` to run on startup #### Manual way From acec1d0b667e3f9ff7d87a40ddaa26d2d8a64f00 Mon Sep 17 00:00:00 2001 From: redness360 <16584585+redness360@users.noreply.github.com> Date: Mon, 26 Oct 2020 21:44:03 +0000 Subject: [PATCH 008/103] Update installation.md A noob like me didn't realize you have to portforward. It would help if it was written somewhere. --- docs/guides/vpn/installation.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/guides/vpn/installation.md b/docs/guides/vpn/installation.md index 266481c..c8c69b3 100644 --- a/docs/guides/vpn/installation.md +++ b/docs/guides/vpn/installation.md @@ -65,7 +65,7 @@ Finished! Your client configuration is available at /root/pihole.ovpn If you want to add more clients, you simply need to run this script again! ``` - +You can set your port to whatever you would like, however you will have to portforward this port in your routers settings from your public ip to your device (if self hosting). ### Install Pi-hole Next, install Pi-hole and choose `tun0` as the interface and `10.8.0.1/24` as the IP address. You can accept the rest of the defaults, or configure Pi-hole to your liking. The interface selection is the most important step; if you don't choose `tun0` (at least to begin with), it will not work properly. From 7c794678ccbb14ee09457a3133a8139cb57fef18 Mon Sep 17 00:00:00 2001 From: redness360 <16584585+redness360@users.noreply.github.com> Date: Mon, 26 Oct 2020 21:51:11 +0000 Subject: [PATCH 009/103] Update firewall.md --- docs/guides/vpn/firewall.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/guides/vpn/firewall.md b/docs/guides/vpn/firewall.md index 98488e5..92fbbbf 100644 --- a/docs/guides/vpn/firewall.md +++ b/docs/guides/vpn/firewall.md @@ -1,6 +1,6 @@ ### (optional) Secure the server with firewall rules (`iptables`) -**If you are behind a NAT and not running the Pi-hole on a cloud server, you do not need to issue the IPTABLES commands bellow as the firewall rules are already handled by the RoadWarrior installer. +**If you are behind a NAT and not running the Pi-hole on a cloud server, you do not need to issue the IPTABLES commands bellow as the firewall rules are already handled by the RoadWarrior installer, but you will need to portforward whatever port you chose in the setup from your public ip to your device using your router. **This step is optional but recommended if you are running your server in the cloud, such as a droplet made on [Digital Ocean](https://www.digitalocean.com/?refcode=344d234950e1)**. If this is the case, you need to secure the server for your safety as well as others to prevent aiding in DDoS attacks. From 77bbb2bb21b668a08f524368ec245e05a25f9cbc Mon Sep 17 00:00:00 2001 From: redness360 <16584585+redness360@users.noreply.github.com> Date: Tue, 27 Oct 2020 20:59:21 -0400 Subject: [PATCH 010/103] Update firewall.md --- docs/guides/vpn/firewall.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/guides/vpn/firewall.md b/docs/guides/vpn/firewall.md index 92fbbbf..26c0886 100644 --- a/docs/guides/vpn/firewall.md +++ b/docs/guides/vpn/firewall.md @@ -1,6 +1,6 @@ ### (optional) Secure the server with firewall rules (`iptables`) -**If you are behind a NAT and not running the Pi-hole on a cloud server, you do not need to issue the IPTABLES commands bellow as the firewall rules are already handled by the RoadWarrior installer, but you will need to portforward whatever port you chose in the setup from your public ip to your device using your router. +**If you are behind a NAT and not running the Pi-hole on a cloud server, you do not need to issue the IPTABLES commands bellow as the firewall rules are already handled by the RoadWarrior installer, but you will need to portforward whatever port you chose in the setup from your public ip to your device using your router.** **This step is optional but recommended if you are running your server in the cloud, such as a droplet made on [Digital Ocean](https://www.digitalocean.com/?refcode=344d234950e1)**. If this is the case, you need to secure the server for your safety as well as others to prevent aiding in DDoS attacks. From 0522cf28b662ad7b7692673f6c4f32e29a017025 Mon Sep 17 00:00:00 2001 From: redness360 <16584585+redness360@users.noreply.github.com> Date: Tue, 27 Oct 2020 21:01:59 -0400 Subject: [PATCH 011/103] Update installation.md --- docs/guides/vpn/installation.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/guides/vpn/installation.md b/docs/guides/vpn/installation.md index c8c69b3..6aa0fd7 100644 --- a/docs/guides/vpn/installation.md +++ b/docs/guides/vpn/installation.md @@ -65,7 +65,9 @@ Finished! Your client configuration is available at /root/pihole.ovpn If you want to add more clients, you simply need to run this script again! ``` -You can set your port to whatever you would like, however you will have to portforward this port in your routers settings from your public ip to your device (if self hosting). + +**You can set your port to whatever you would like, however you will have to portforward this port in your routers settings from your public ip to your device (if self hosting).** + ### Install Pi-hole Next, install Pi-hole and choose `tun0` as the interface and `10.8.0.1/24` as the IP address. You can accept the rest of the defaults, or configure Pi-hole to your liking. The interface selection is the most important step; if you don't choose `tun0` (at least to begin with), it will not work properly. From d7e671ec21f3dfc363f725a26eec453001cd1380 Mon Sep 17 00:00:00 2001 From: John <41806245+jfb-pihole@users.noreply.github.com> Date: Thu, 29 Oct 2020 11:50:19 -0500 Subject: [PATCH 012/103] Update groups.md The documentation for the group section of the domain database (https://docs.pi-hole.net/database/gravity/groups/) has an incorrect label for one of the fields. The label identified as "comment" in the documentation is "description" in the database. --- docs/database/gravity/groups.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/database/gravity/groups.md b/docs/database/gravity/groups.md index 9958b79..06eb7ce 100644 --- a/docs/database/gravity/groups.md +++ b/docs/database/gravity/groups.md @@ -9,7 +9,7 @@ Label | Type | Uniqueness enforced | Content `id` | integer | Yes | Unique ID for database operations `enabled` | boolean | No | Flag whether domains in this group should be used
(`0` = disabled, `1` = enabled) `name` | text | No | Mandatory group name -`comment` | text | No | Optional field for arbitrary user comments +`description` | text | No | Optional field for arbitrary user comments Group management is implemented using so-called linking tables. Hence, it is possible to From 4b1f07cef55f5f1b3defc1506e6784d2172be758 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Sat, 31 Oct 2020 10:13:32 +0000 Subject: [PATCH 013/103] Bump linkinator from 2.2.0 to 2.2.2 Bumps [linkinator](https://github.com/JustinBeckwith/linkinator) from 2.2.0 to 2.2.2. - [Release notes](https://github.com/JustinBeckwith/linkinator/releases) - [Commits](https://github.com/JustinBeckwith/linkinator/compare/v2.2.0...v2.2.2) Signed-off-by: dependabot-preview[bot] --- package-lock.json | 191 +++++++++++++++++++++++++++++----------------- package.json | 2 +- 2 files changed, 123 insertions(+), 70 deletions(-) diff --git a/package-lock.json b/package-lock.json index 09205e7..2e70967 100644 --- a/package-lock.json +++ b/package-lock.json @@ -130,9 +130,9 @@ "dev": true }, "@types/node": { - "version": "14.11.8", - "resolved": "https://registry.npmjs.org/@types/node/-/node-14.11.8.tgz", - "integrity": "sha512-KPcKqKm5UKDkaYPTuXSx8wEP7vE9GnuaXIZKijwRYcePpZFDVuy2a57LarFKiORbHOuTOOwYzxVxcUzsh2P2Pw==", + "version": "14.14.6", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.6.tgz", + "integrity": "sha512-6QlRuqsQ/Ox/aJEQWBEJG7A9+u7oSYl3mem/K8IzxXG/kAGbV1YPD9Bg9Zw3vyxC/YP+zONKwy8hGkSt1jxFMw==", "dev": true }, "@types/normalize-package-data": { @@ -151,9 +151,9 @@ } }, "agent-base": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.1.tgz", - "integrity": "sha512-01q25QQDwLSsyfhrKbn8yuur+JNw0H+0Y4JiGIKd3z9aYk/w/2kxD/Upc+t2ZBBSUNff50VjPsSW2YxM8QYKVg==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", "dev": true, "requires": { "debug": "4" @@ -480,6 +480,12 @@ "mimic-response": "^1.0.0" } }, + "deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "dev": true + }, "defer-to-connect": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.1.3.tgz", @@ -712,10 +718,16 @@ "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=", "dev": true }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, "gaxios": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-3.2.0.tgz", - "integrity": "sha512-+6WPeVzPvOshftpxJwRi2Ozez80tn/hdtOUag7+gajDHRJvAblKxTFSSMPtr2hmnLy7p0mvYz0rMXLBl8pSO7Q==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-4.0.1.tgz", + "integrity": "sha512-jOin8xRZ/UytQeBpSXFqIzqU7Fi5TqgPNLlUsSB8kjJ76+FiGBfImF8KJu++c6J4jOldfJUtt0YmkRj2ZpSHTQ==", "dev": true, "requires": { "abort-controller": "^3.0.0", @@ -797,6 +809,15 @@ "integrity": "sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==", "dev": true }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "requires": { + "function-bind": "^1.1.1" + } + }, "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -810,10 +831,13 @@ "dev": true }, "hosted-git-info": { - "version": "2.8.8", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.8.tgz", - "integrity": "sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg==", - "dev": true + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-3.0.7.tgz", + "integrity": "sha512-fWqc0IcuXs+BmE9orLDyVykAG9GJtGLGuZAAqgcckPgv5xad4AcXGIv8galtQvlwutxSlaMcdw7BUtq2EIvqCQ==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } }, "htmlparser2": { "version": "3.10.1", @@ -934,6 +958,15 @@ "ci-info": "^2.0.0" } }, + "is-core-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.0.0.tgz", + "integrity": "sha512-jq1AH6C8MuteOoBPwkxHafmByhL9j5q4OaPGdbuD+ZtQJVzH+i6E3BJDQcBA09k57i2Hh2yQbEG8yObZ0jdlWw==", + "dev": true, + "requires": { + "has": "^1.0.3" + } + }, "is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", @@ -1077,17 +1110,17 @@ } }, "linkinator": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/linkinator/-/linkinator-2.2.0.tgz", - "integrity": "sha512-sG/4PxmpnTFvP/GjM1zmgOw6zsFqJYKbz1nTIXcanYfpxzldGuTnE6Q0mdY2DgjzSS8w409WBfysxWwbx5xpJA==", + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/linkinator/-/linkinator-2.2.2.tgz", + "integrity": "sha512-mcMMbo8n8p6qDuCQ5zZaBbxKK9jq79oWsoduBIGc0rRzukDmfLr7t6Ok1jJA7aHHFX251NmtbX2LdQvD54UHow==", "dev": true, "requires": { "chalk": "^4.0.0", "cheerio": "^1.0.0-rc.2", "finalhandler": "^1.1.2", - "gaxios": "^3.0.0", + "gaxios": "^4.0.0", "jsonexport": "^3.0.0", - "meow": "^7.0.0", + "meow": "^8.0.0", "p-queue": "^6.2.1", "serve-static": "^1.14.1", "server-destroy": "^1.0.1", @@ -1115,6 +1148,15 @@ "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==", "dev": true }, + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, "make-dir": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", @@ -1202,9 +1244,9 @@ "dev": true }, "meow": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/meow/-/meow-7.1.1.tgz", - "integrity": "sha512-GWHvA5QOcS412WCo8vwKDlTelGLsCGBVevQB5Kva961rmNfun0PCbv5+xta2kUMFJyR8/oWnn7ddeKdosbAPbA==", + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/meow/-/meow-8.0.0.tgz", + "integrity": "sha512-nbsTRz2fwniJBFgUkcdISq8y/q9n9VbiHYbfwklFh5V4V2uAcxtKQkDc0yCLPM/kP0d+inZBewn3zJqewHE7kg==", "dev": true, "requires": { "@types/minimist": "^1.2.0", @@ -1212,12 +1254,12 @@ "decamelize-keys": "^1.1.0", "hard-rejection": "^2.1.0", "minimist-options": "4.1.0", - "normalize-package-data": "^2.5.0", + "normalize-package-data": "^3.0.0", "read-pkg-up": "^7.0.1", "redent": "^3.0.0", "trim-newlines": "^3.0.0", - "type-fest": "^0.13.1", - "yargs-parser": "^18.1.3" + "type-fest": "^0.18.0", + "yargs-parser": "^20.2.3" } }, "merge2": { @@ -1284,14 +1326,14 @@ "dev": true }, "normalize-package-data": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", - "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.0.tgz", + "integrity": "sha512-6lUjEI0d3v6kFrtgA/lOx4zHCWULXsFNIjHolnZCKCTLA6m/G625cdn3O7eNmT0iD3jfo6HZ9cdImGZwf21prw==", "dev": true, "requires": { - "hosted-git-info": "^2.1.4", - "resolve": "^1.10.0", - "semver": "2 || 3 || 4 || 5", + "hosted-git-info": "^3.0.6", + "resolve": "^1.17.0", + "semver": "^7.3.2", "validate-npm-package-license": "^3.0.1" } }, @@ -1471,9 +1513,9 @@ } }, "pupa": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pupa/-/pupa-2.0.1.tgz", - "integrity": "sha512-hEJH0s8PXLY/cdXh66tNEQGndDrIKNqNC5xmrysZy3i5C3oEoLna7YAOad+7u125+zH1HNXUmGEkrhb3c2VriA==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/pupa/-/pupa-2.1.1.tgz", + "integrity": "sha512-l1jNAspIBSFqbT+y+5FosojNpVpF94nlI+wDUpqP9enwOTfHx9f0gh5nB96vl+6yTpsJsypeNrwfzPrKuHB41A==", "dev": true, "requires": { "escape-goat": "^2.0.0" @@ -1501,14 +1543,6 @@ "ini": "~1.3.0", "minimist": "^1.2.0", "strip-json-comments": "~2.0.1" - }, - "dependencies": { - "deep-extend": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", - "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", - "dev": true - } } }, "read-pkg": { @@ -1523,6 +1557,30 @@ "type-fest": "^0.6.0" }, "dependencies": { + "hosted-git-info": { + "version": "2.8.8", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.8.tgz", + "integrity": "sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg==", + "dev": true + }, + "normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "requires": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + }, "type-fest": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", @@ -1590,11 +1648,12 @@ } }, "resolve": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", - "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", + "version": "1.18.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.18.1.tgz", + "integrity": "sha512-lDfCPaMKfOJXjy0dPayzPdF1phampNWr3qFCjAu+rw/qbQmr5jWH5xN2hwh9QKfw9E5v4hwV7A+jrCmL8yjjqA==", "dev": true, "requires": { + "is-core-module": "^2.0.0", "path-parse": "^1.0.6" } }, @@ -1626,9 +1685,9 @@ "dev": true }, "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", + "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", "dev": true }, "semver-diff": { @@ -1840,9 +1899,9 @@ } }, "term-size": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/term-size/-/term-size-2.2.0.tgz", - "integrity": "sha512-a6sumDlzyHVJWb8+YofY4TW112G6p2FCPEAFk+59gIYHv3XHRhm9ltVQ9kli4hNWeQBwSpe8cRN25x0ROunMOw==", + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/term-size/-/term-size-2.2.1.tgz", + "integrity": "sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==", "dev": true }, "to-readable-stream": { @@ -1873,9 +1932,9 @@ "dev": true }, "type-fest": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz", - "integrity": "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==", + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.18.0.tgz", + "integrity": "sha512-fbDukFPnJBdn2eZ3RR+5mK2slHLFd6gYHY7jna1KWWy4Yr4XysHuCdXRzy+RiG/HwG4WJat00vdC2UHky5eKiQ==", "dev": true }, "typedarray-to-buffer": { @@ -1928,14 +1987,6 @@ "semver": "^7.3.2", "semver-diff": "^3.1.1", "xdg-basedir": "^4.0.0" - }, - "dependencies": { - "semver": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", - "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", - "dev": true - } } }, "url-parse-lax": { @@ -1996,6 +2047,12 @@ "integrity": "sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==", "dev": true }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, "yaml": { "version": "1.10.0", "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.0.tgz", @@ -2003,14 +2060,10 @@ "dev": true }, "yargs-parser": { - "version": "18.1.3", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", - "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", - "dev": true, - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } + "version": "20.2.3", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.3.tgz", + "integrity": "sha512-emOFRT9WVHw03QSvN5qor9QQT9+sw5vwxfYweivSMHTcAXPefwVae2FjO7JJjj8hCE4CzPOPeFM83VwT29HCww==", + "dev": true } } } diff --git a/package.json b/package.json index c82033d..20dd6b8 100644 --- a/package.json +++ b/package.json @@ -22,7 +22,7 @@ "test": "npm run markdownlint && npm run linkinator" }, "devDependencies": { - "linkinator": "^2.2.0", + "linkinator": "^2.2.2", "markdownlint-cli2": "0.0.10" } } From 6120246947f4fbd88c165f5b28025179c13f92eb Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Sun, 1 Nov 2020 14:50:16 +0200 Subject: [PATCH 014/103] Bump mkdocs-git-revision-date-localized-plugin from 0.7.2 to 0.7.3 (#413) Bumps [mkdocs-git-revision-date-localized-plugin](https://github.com/timvink/mkdocs-git-revision-date-localized-plugin) from 0.7.2 to 0.7.3. - [Release notes](https://github.com/timvink/mkdocs-git-revision-date-localized-plugin/releases) - [Commits](https://github.com/timvink/mkdocs-git-revision-date-localized-plugin/compare/v0.7.2...v0.7.3) Signed-off-by: dependabot-preview[bot] Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 42235d2..4d9b3bb 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,5 @@ markdown-include==0.6.0 mkdocs==1.1.2 -mkdocs-git-revision-date-localized-plugin==0.7.2 +mkdocs-git-revision-date-localized-plugin==0.7.3 mkdocs-material==6.1.0 mkdocs-redirects==1.0.1 From b8d7bc8b8c8278377140db5498661f2faaa17034 Mon Sep 17 00:00:00 2001 From: Tripp Sanders <45514010+tigerclaw989@users.noreply.github.com> Date: Sun, 1 Nov 2020 06:52:25 -0600 Subject: [PATCH 015/103] Change cloudflared service installation. (#407) Co-authored-by: XhmikosR --- docs/guides/dns-over-https.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/guides/dns-over-https.md b/docs/guides/dns-over-https.md index 053ae46..f5ee41f 100644 --- a/docs/guides/dns-over-https.md +++ b/docs/guides/dns-over-https.md @@ -154,7 +154,7 @@ proxy-dns-upstream: Now install the service via `cloudflared`'s [service command](https://developers.cloudflare.com/argo-tunnel/reference/arguments/#service-command): ```bash -sudo cloudflared service install +sudo cloudflared service install --legacy ``` Start the `systemd` service and check its status: From 635be7b5d471fdc9388cc0ceb22835afaf0a86c4 Mon Sep 17 00:00:00 2001 From: Michael Woolweaver Date: Wed, 4 Nov 2020 15:29:06 -0600 Subject: [PATCH 016/103] fix group Table name column - Uniqueness enforces should be Yes closes #415 Signed-off-by: Michael Woolweaver --- docs/database/gravity/groups.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/database/gravity/groups.md b/docs/database/gravity/groups.md index 06eb7ce..63d4d36 100644 --- a/docs/database/gravity/groups.md +++ b/docs/database/gravity/groups.md @@ -8,7 +8,7 @@ Label | Type | Uniqueness enforced | Content ----- | ---- | ------------------- | -------- `id` | integer | Yes | Unique ID for database operations `enabled` | boolean | No | Flag whether domains in this group should be used
(`0` = disabled, `1` = enabled) -`name` | text | No | Mandatory group name +`name` | text | Yes | Mandatory group name `description` | text | No | Optional field for arbitrary user comments Group management is implemented using so-called linking tables. Hence, it is possible to From 65e554bc34280a98baaf1f366d85ecd7ff7f022e Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Sat, 7 Nov 2020 10:12:48 +0000 Subject: [PATCH 017/103] Bump mkdocs-material from 6.1.0 to 6.1.3 Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 6.1.0 to 6.1.3. - [Release notes](https://github.com/squidfunk/mkdocs-material/releases) - [Changelog](https://github.com/squidfunk/mkdocs-material/blob/master/docs/changelog.md) - [Commits](https://github.com/squidfunk/mkdocs-material/compare/6.1.0...6.1.3) Signed-off-by: dependabot-preview[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 4d9b3bb..7a3afa6 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,5 @@ markdown-include==0.6.0 mkdocs==1.1.2 mkdocs-git-revision-date-localized-plugin==0.7.3 -mkdocs-material==6.1.0 +mkdocs-material==6.1.3 mkdocs-redirects==1.0.1 From 55ddeeb866f651f9d0f55ac60cdec0faa6bf8013 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Sat, 14 Nov 2020 10:12:54 +0000 Subject: [PATCH 018/103] Bump mkdocs-material from 6.1.3 to 6.1.4 Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 6.1.3 to 6.1.4. - [Release notes](https://github.com/squidfunk/mkdocs-material/releases) - [Changelog](https://github.com/squidfunk/mkdocs-material/blob/master/docs/changelog.md) - [Commits](https://github.com/squidfunk/mkdocs-material/compare/6.1.3...6.1.4) Signed-off-by: dependabot-preview[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 7a3afa6..97a980f 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,5 @@ markdown-include==0.6.0 mkdocs==1.1.2 mkdocs-git-revision-date-localized-plugin==0.7.3 -mkdocs-material==6.1.3 +mkdocs-material==6.1.4 mkdocs-redirects==1.0.1 From 55092ddacafd8d499e6cadfefa3e33a7eb77ebda Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Sat, 14 Nov 2020 21:25:28 +0000 Subject: [PATCH 019/103] Bump markdownlint-cli2 from 0.0.10 to 0.0.11 Bumps [markdownlint-cli2](https://github.com/DavidAnson/markdownlint-cli2) from 0.0.10 to 0.0.11. - [Release notes](https://github.com/DavidAnson/markdownlint-cli2/releases) - [Commits](https://github.com/DavidAnson/markdownlint-cli2/compare/v0.0.10...v0.0.11) Signed-off-by: dependabot-preview[bot] --- package-lock.json | 26 +++++++++++++------------- package.json | 2 +- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/package-lock.json b/package-lock.json index 2e70967..98e6d92 100644 --- a/package-lock.json +++ b/package-lock.json @@ -670,9 +670,9 @@ } }, "fastq": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.8.0.tgz", - "integrity": "sha512-SMIZoZdLh/fgofivvIkmknUXyPnvxRE3DhtZ5Me3Mrsk5gyPL42F0xr51TdRXskBxHfMp+07bcYzfsYEsSQA9Q==", + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.9.0.tgz", + "integrity": "sha512-i7FVWL8HhVY+CTkwFxkN2mk3h+787ixS5S63eb78diVRc1MCssarHq3W5cj0av7YDSwmaV928RNag+U1etRQ7w==", "dev": true, "requires": { "reusify": "^1.0.4" @@ -1194,22 +1194,22 @@ } }, "markdownlint": { - "version": "0.21.0", - "resolved": "https://registry.npmjs.org/markdownlint/-/markdownlint-0.21.0.tgz", - "integrity": "sha512-rTxr0fbCFmS65oxXBD0HNy3/+PSukLS+b7Z6rGDWbjdRJp/e2dKj538r3KTn8oXrusx+ZtuYOozV2Knpnn0pkQ==", + "version": "0.21.1", + "resolved": "https://registry.npmjs.org/markdownlint/-/markdownlint-0.21.1.tgz", + "integrity": "sha512-8kc88w5dyEzlmOWIElp8J17qBgzouOQfJ0LhCcpBFrwgyYK6JTKvILsk4FCEkiNqHkTxwxopT2RS2DYb/10qqg==", "dev": true, "requires": { "markdown-it": "11.0.0" } }, "markdownlint-cli2": { - "version": "0.0.10", - "resolved": "https://registry.npmjs.org/markdownlint-cli2/-/markdownlint-cli2-0.0.10.tgz", - "integrity": "sha512-tuWKncGgg0ic9YIWzPu1w2upoGNF/CQwb+CMzJmB8LMM2MhFKTUQSDyUt0kM022qs1R7KjxFXG7y5FBmqGVhUQ==", + "version": "0.0.11", + "resolved": "https://registry.npmjs.org/markdownlint-cli2/-/markdownlint-cli2-0.0.11.tgz", + "integrity": "sha512-+dwVrLo2sisB8OJE8vdT+gTQCOuaYFJsYKKfh1fnkHedSMxVrX6XMID5kUKI7iSq6GICugPnS5kjjVwCbe01vg==", "dev": true, "requires": { "globby": "~11.0.1", - "markdownlint": "~0.21.0", + "markdownlint": "~0.21.1", "markdownlint-cli2-formatter-default": "~0.0.1", "markdownlint-rule-helpers": "~0.12.0", "micromatch": "~4.0.2", @@ -1673,9 +1673,9 @@ "dev": true }, "run-parallel": { - "version": "1.1.9", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.1.9.tgz", - "integrity": "sha512-DEqnSRTDw/Tc3FXf49zedI638Z9onwUotBMiUFKmrO2sdFKIbXamXGQ3Axd4qgphxKB4kw/qP1w5kTxnfU1B9Q==", + "version": "1.1.10", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.1.10.tgz", + "integrity": "sha512-zb/1OuZ6flOlH6tQyMPUrE3x3Ulxjlo9WIVXR4yVYi4H9UXQaeIsPbLn2R3O3vQCnDKkAl2qHiuocKKX4Tz/Sw==", "dev": true }, "safe-buffer": { diff --git a/package.json b/package.json index 20dd6b8..2dc6c77 100644 --- a/package.json +++ b/package.json @@ -23,6 +23,6 @@ }, "devDependencies": { "linkinator": "^2.2.2", - "markdownlint-cli2": "0.0.10" + "markdownlint-cli2": "0.0.11" } } From 1994f4d9aed36ef7280c0ac0424855b020e099a3 Mon Sep 17 00:00:00 2001 From: XhmikosR Date: Wed, 18 Nov 2020 01:19:29 +0200 Subject: [PATCH 020/103] Fix redirects (#408) * Fix redirects * Remove "Pi-hole stats in your Mac's menu bar" Signed-off-by: XhmikosR --- docs/guides/tor/performance-issues.md | 2 +- docs/guides/vpn/installation.md | 2 +- docs/main/coverage.md | 2 +- docs/main/projects.md | 1 - 4 files changed, 3 insertions(+), 4 deletions(-) diff --git a/docs/guides/tor/performance-issues.md b/docs/guides/tor/performance-issues.md index 792462e..2c05150 100644 --- a/docs/guides/tor/performance-issues.md +++ b/docs/guides/tor/performance-issues.md @@ -39,7 +39,7 @@ This is not recommended, but here are some things you can do: ##### Solution 2 - Only use specific Exit Nodes -1. Navigate to [atlas.torproject.org Top Relays](https://atlas.torproject.org/#toprelays). +1. Navigate to [metrics.torproject.org Top Relays](https://metrics.torproject.org/rs.html#toprelays). 2. Click on two Relays out of the list. 3. Make sure the relay allows Port `53` in his `IPv4 Exit Policy Summary` (and/or `IPv6 Exit Policy Summary` if you want to resolve IPv6 AAAA queries). 4. As root copy the `Fingerprint` (Top Right under Relay Details) of those two Relays to the end of your `/etc/tor/torrc` file on the Pi-hole host in the following format: diff --git a/docs/guides/vpn/installation.md b/docs/guides/vpn/installation.md index 266481c..43b3d13 100644 --- a/docs/guides/vpn/installation.md +++ b/docs/guides/vpn/installation.md @@ -1,6 +1,6 @@ ## Install an operating system -Once you have your preferred OS up and running. You may already have a server set up on your network, or you may prefer to make a [Digital Ocean](https://www.digitalocean.com/?refcode=344d234950e1) droplet. In either case, you'll use the quick OpenVPN "road warrior" installer. The cloud-hosted server option is convenient if you don't want to host the hardware at home, but you'll need to take additional steps to secure the server as it's available on the public Internet. Failure to do so is [not only irresponsible, but you also put yourself and others at risk](https://www.us-cert.gov/ncas/alerts/TA13-088A). +Once you have your preferred OS up and running. You may already have a server set up on your network, or you may prefer to make a [Digital Ocean](https://www.digitalocean.com/?refcode=344d234950e1) droplet. In either case, you'll use the quick OpenVPN "road warrior" installer. The cloud-hosted server option is convenient if you don't want to host the hardware at home, but you'll need to take additional steps to secure the server as it's available on the public Internet. Failure to do so is [not only irresponsible, but you also put yourself and others at risk](https://us-cert.cisa.gov/ncas/alerts/TA13-088A). ## Install OpenVPN + Pi-hole diff --git a/docs/main/coverage.md b/docs/main/coverage.md index 03efdd5..2a5ad8f 100755 --- a/docs/main/coverage.md +++ b/docs/main/coverage.md @@ -26,7 +26,7 @@ last_updated: Sun Jan 13 19:20:35 2019 UTC - [Catchpoint: Ad-Blocking on Apple iOS9: Valuing the End User Experience](http://blog.catchpoint.com/2015/09/14/ad-blocking-apple/) _Sept 14, 2015_ - [Adafruit: Pi-hole is a black hole for internet ads](https://blog.adafruit.com/2016/03/04/pi-hole-is-a-black-hole-for-internet-ads-piday-raspberrypi-raspberry_pi/) _Mar 4, 2016_ - [Devacron: OrangePi Zero as an Ad-Block server with Pi-Hole](https://www.devacron.com/orangepi-zero-as-an-ad-block-server-with-pi-hole/) _Dec 3, 2016_ -- [Linux Pro: The Hole Truth](http://www.linuxpromagazine.com/Issues/2017/200/The-sysadmin-s-daily-grind-Pi-hole) _2017_ +- [Linux Pro: The Hole Truth](https://www.linuxpromagazine.com/Issues/2017/200/The-sysadmin-s-daily-grind-Pi-hole) _2017_ - [CryptoAUSTRALIA: How We Tried 5 Privacy Focused Raspberry Pi Projects](https://blog.cryptoaustralia.org.au/5-privacy-focused-raspberry-pi-projects/) _Oct 5, 2017_ - [CryptoAUSTRALIA: Pi-hole Workshop](https://blog.cryptoaustralia.org.au/pi-hole-network-wide-ad-blocker/) _Nov 2, 2017_ - [Bloomberg: Inside the Brotherhood of the Ad Blockers](https://www.bloomberg.com/news/features/2018-05-10/inside-the-brotherhood-of-pi-hole-ad-blockers) _May 10, 2018_ diff --git a/docs/main/projects.md b/docs/main/projects.md index 2f860d0..4c43bf6 100755 --- a/docs/main/projects.md +++ b/docs/main/projects.md @@ -11,7 +11,6 @@ last_updated: Sun Sep 06 14:28:14 2020 UTC - [Chrome Extension: Pi-Hole List Editor](https://chrome.google.com/webstore/detail/pi-hole-list-editor/hlnoeoejkllgkjbnnnhfolapllcnaglh) ([Source Code](https://github.com/packtloss/pihole-extension)) - [Splunk: Pi-hole Visualiser](https://splunkbase.splunk.com/app/3023/) - [Adblocking with Pi-hole and Ubuntu 14.04 on VirtualBox](https://hbalagtas.blogspot.com/2016/02/adblocking-with-pi-hole-and-ubuntu-1404.html) -- [Pi-hole stats in your Mac's menu bar](https://getbitbar.com/plugins/Network/pi-hole.1m.py) - [Pi-hole unRAID Template](https://forums.unraid.net/topic/36810-support-spants-nodered-mqtt-dashing-couchdb/) - [Copernicus: Windows Tray Application](https://github.com/goldbattle/copernicus) - [Let your blink1 device blink when Pi-hole filters ads](https://gist.github.com/elpatron68/ec0b4c582e5abf604885ac1e068d233f) From 50d5f7cafd1e7c7a8db1d268cba43f3d6c5a4c64 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Sat, 21 Nov 2020 10:13:08 +0000 Subject: [PATCH 021/103] Bump mkdocs-material from 6.1.4 to 6.1.5 Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 6.1.4 to 6.1.5. - [Release notes](https://github.com/squidfunk/mkdocs-material/releases) - [Changelog](https://github.com/squidfunk/mkdocs-material/blob/master/docs/changelog.md) - [Commits](https://github.com/squidfunk/mkdocs-material/compare/6.1.4...6.1.5) Signed-off-by: dependabot-preview[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 97a980f..4385023 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,5 @@ markdown-include==0.6.0 mkdocs==1.1.2 mkdocs-git-revision-date-localized-plugin==0.7.3 -mkdocs-material==6.1.4 +mkdocs-material==6.1.5 mkdocs-redirects==1.0.1 From 74776cc9c7fab1ec5a312a3b342965e1eefca75c Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Sat, 28 Nov 2020 10:13:38 +0000 Subject: [PATCH 022/103] Bump mkdocs-material from 6.1.5 to 6.1.6 Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 6.1.5 to 6.1.6. - [Release notes](https://github.com/squidfunk/mkdocs-material/releases) - [Changelog](https://github.com/squidfunk/mkdocs-material/blob/master/docs/changelog.md) - [Commits](https://github.com/squidfunk/mkdocs-material/compare/6.1.5...6.1.6) Signed-off-by: dependabot-preview[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 4385023..0bf3125 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,5 @@ markdown-include==0.6.0 mkdocs==1.1.2 mkdocs-git-revision-date-localized-plugin==0.7.3 -mkdocs-material==6.1.5 +mkdocs-material==6.1.6 mkdocs-redirects==1.0.1 From 926f706f7472f5779d9e9d42ca905f53a3d30247 Mon Sep 17 00:00:00 2001 From: DL6ER Date: Tue, 1 Dec 2020 10:13:27 +0100 Subject: [PATCH 023/103] Add documentation for new gravity.db:adlist#date_updated column Signed-off-by: DL6ER --- docs/database/gravity/index.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/database/gravity/index.md b/docs/database/gravity/index.md index 5d8dab5..3a5ce1f 100644 --- a/docs/database/gravity/index.md +++ b/docs/database/gravity/index.md @@ -30,6 +30,7 @@ Label | Type | Uniqueness enforced | Content `date_added` | integer | No | Timestamp when domain was added `date_modified` | integer | No | Timestamp when domain was last modified, automatically updated when a record is changed `comment` | text | No | Optional field for arbitrary user comments +`date_updated` | integer | No | Timestamp when this list has last been updated (`pihole -g` does **not** update this timestamp when the downloaded list did not change since the last `pihole -g` run) ## Gravity Table (`gravity`) From 777c0c64e2af9cb8d571fb3b73abdbac4ee5a73c Mon Sep 17 00:00:00 2001 From: DL6ER Date: Wed, 2 Dec 2020 06:33:08 +0100 Subject: [PATCH 024/103] Add REFRESH_HOSTNAMES config item Signed-off-by: DL6ER --- docs/abbreviations.md | 1 + docs/ftldns/configfile.md | 11 +++++++++++ 2 files changed, 12 insertions(+) diff --git a/docs/abbreviations.md b/docs/abbreviations.md index a45aa31..31548b7 100644 --- a/docs/abbreviations.md +++ b/docs/abbreviations.md @@ -10,6 +10,7 @@ *[TCP]: Transmission Control Protocol (protocol providing reliable, ordered, and error-checked delivery of data between applications running on hosts communicating via an IP network) *[UDP]: User Datagram Protocol (a network communications method for sending messages as datagrams) *[API]: Application Programming Interface (a set of subroutine definitions, protocols, and tools for building application software) +*[PE]: Privacy Extension *[PID]: Process identifier (a number used to identify a process) *[HOSTS]: The computer file /etc/hosts is an operating system file that maps hostnames to IP addresses *[POSIX]: Portable Operating System Interface (a family of standards specified by the IEEE Computer Society for maintaining compatibility between operating systems) diff --git a/docs/ftldns/configfile.md b/docs/ftldns/configfile.md index 85cab09..205faf6 100755 --- a/docs/ftldns/configfile.md +++ b/docs/ftldns/configfile.md @@ -93,6 +93,17 @@ host name for another IP address (e.g., a DHCP server managed IPv4 address). In this case, we use the host name associated to the other address as this is the same device. +#### `REFRESH_HOSTNAMES=IPV4|ALL|NONE` (PR [#953](https://github.com/pi-hole/FTL/pull/953)) {#refresh_hostnames data-toc-label='Refresh hostnames'} + +With this option, you can change how (and if) hourly PTR requests are made to check for changes in client and upstream server hostnames. The following options are available: + +- `REFRESH_HOSTNAMES=IPV4` - Do the hourly PTR lookups only for IPv4 addresses + This is the new default since Pi-hole FTL v5.3.2. It should resolve issues with more and more very short-lived PE IPv6 addresses coming up in a lot of networks. +- `REFRESH_HOSTNAMES=ALL` - Do the hourly PTR lookups for all addresses + This is the same as what we're doing with FTL v5.3(.1). This can create a lot of PTR queries for those with many IPv6 addresses in their networks. +- `REFRESH_HOSTNAMES=NONE` - Don't do any hourly PTR lookups + This means we look host names up exactly once (when we first see a client) and never again. You may miss future changes of host names. + --- ### Long-term database settings From 06fba6d6551c167f7e24494c53218c65e076b165 Mon Sep 17 00:00:00 2001 From: Conor O'Callaghan Date: Fri, 4 Dec 2020 14:50:47 +0000 Subject: [PATCH 025/103] adding teleport command doc --- docs/core/pihole-command.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/docs/core/pihole-command.md b/docs/core/pihole-command.md index 86d34db..89b3d40 100644 --- a/docs/core/pihole-command.md +++ b/docs/core/pihole-command.md @@ -267,6 +267,7 @@ Switch Pi-hole subsystems to a different GitHub branch. An admin can specify rep -------------- | -------------- [Web Script](#web-script) | `pihole -a` [Password](#password) | `pihole -a password` +[Teleport](#teleport) | `pihole -a -t` [Temperature Unit](#temperature-unit) | `pihole -a celsius`, `pihole -a fahrenheit`, `pihole -a kelvin` [Host Record](#host-record) | `pihole -a hostrecord` [Email Address](#email-address) | `pihole -a email` @@ -292,6 +293,16 @@ Example Usage | [`pihole -a -p secretpassword`](https://discourse.pi-hole.net/ Set the Web Interface password. Password can be entered as an option (e.g: `pihole -a -p secretpassword`), or separately as to not display on the screen (e.g: `pihole -a -p`). +### Teleport + +| | | + -------------- | -------------- +Help Command | N/A +Script Location | N/A +Example Usage | `pihole -a -t` + +Create a configuration backup. The backup will be created in the directory from which the command is run. The backup can be imported using the Settings > Teleport page. + ### Temperature Unit | | | From e522c4e837bb31e89b24afa93910e9c1f00889c2 Mon Sep 17 00:00:00 2001 From: Conor O'Callaghan Date: Fri, 4 Dec 2020 18:05:42 +0000 Subject: [PATCH 026/103] removing whitepsace --- docs/core/pihole-command.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/core/pihole-command.md b/docs/core/pihole-command.md index 89b3d40..ac1167c 100644 --- a/docs/core/pihole-command.md +++ b/docs/core/pihole-command.md @@ -293,7 +293,7 @@ Example Usage | [`pihole -a -p secretpassword`](https://discourse.pi-hole.net/ Set the Web Interface password. Password can be entered as an option (e.g: `pihole -a -p secretpassword`), or separately as to not display on the screen (e.g: `pihole -a -p`). -### Teleport +### Teleport | | | -------------- | -------------- From 63e2a7f3d6ad1975122834cd4f9460b49e736fb7 Mon Sep 17 00:00:00 2001 From: Dan Schaper Date: Mon, 7 Dec 2020 10:11:00 -0800 Subject: [PATCH 027/103] Remove FTL's API port range We only use 4711, there is no more autoranging for the telnet API. --- docs/main/prerequisites.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/main/prerequisites.md b/docs/main/prerequisites.md index 114e7dc..0c284d2 100644 --- a/docs/main/prerequisites.md +++ b/docs/main/prerequisites.md @@ -62,7 +62,7 @@ Due to the complexity of different ways of setting an IP address across differen | pihole-FTL | 67 (DHCP) | IPv4 UDP | The DHCP server is an optional feature that requires additional ports. | | pihole-FTL | 547 (DHCPv6) | IPv6 UDP | The DHCP server is an optional feature that requires additional ports. | | lighttpd | 80 (HTTP) | TCP | If you have another Web server already running, such as Apache, Pi-hole's Web server will not work. You can either disable the other Web server or change the port on which `lighttpd` listens, which allows you keep both Web servers running. | -| pihole-FTL | 4711-4720 | TCP | FTL is our API engine and uses port 4711 on the localhost interface. This port should not be accessible from any other interface.| +| pihole-FTL | 4711 | TCP | FTL is our API engine and uses port 4711 on the localhost interface. This port should not be accessible from any other interface.| !!! info The use of lighttpd on port _80_ is optional if you decide not to install the Web dashboard during installation. @@ -88,7 +88,7 @@ iptables -I INPUT 1 -s 127.0.0.0/8 -p udp -m udp --dport 53 -j ACCEPT iptables -I INPUT 1 -s 192.168.0.0/16 -p tcp -m tcp --dport 53 -j ACCEPT iptables -I INPUT 1 -s 192.168.0.0/16 -p udp -m udp --dport 53 -j ACCEPT iptables -I INPUT 1 -p udp --dport 67:68 --sport 67:68 -j ACCEPT -iptables -I INPUT 1 -p tcp -m tcp --dport 4711:4720 -i lo -j ACCEPT +iptables -I INPUT 1 -p tcp -m tcp --dport 4711 -i lo -j ACCEPT iptables -I INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT ``` From a16b5acb17737c5c388a956de92acf03c4cc01f4 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Thu, 10 Dec 2020 17:59:03 +0000 Subject: [PATCH 028/103] [Security] Bump ini from 1.3.5 to 1.3.7 Bumps [ini](https://github.com/isaacs/ini) from 1.3.5 to 1.3.7. **This update includes a security fix.** - [Release notes](https://github.com/isaacs/ini/releases) - [Commits](https://github.com/isaacs/ini/compare/v1.3.5...v1.3.7) Signed-off-by: dependabot-preview[bot] --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 98e6d92..1bfe101 100644 --- a/package-lock.json +++ b/package-lock.json @@ -938,9 +938,9 @@ "dev": true }, "ini": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", - "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.7.tgz", + "integrity": "sha512-iKpRpXP+CrP2jyrxvg1kMUpXDyRUFDWurxbnVT1vQPx+Wz9uCYsMIqYuSBLV+PAaZG/d7kRLKRFc9oDMsH+mFQ==", "dev": true }, "is-arrayish": { From ee01dcdb6697cdcf4166a4c56e16cf218089ca8c Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Thu, 10 Dec 2020 19:57:59 +0000 Subject: [PATCH 029/103] Bump linkinator from 2.2.2 to 2.8.0 Bumps [linkinator](https://github.com/JustinBeckwith/linkinator) from 2.2.2 to 2.8.0. - [Release notes](https://github.com/JustinBeckwith/linkinator/releases) - [Commits](https://github.com/JustinBeckwith/linkinator/compare/v2.2.2...v2.8.0) Signed-off-by: dependabot-preview[bot] --- package-lock.json | 172 +++++++++++++++++++++++++++++++++------------- package.json | 2 +- 2 files changed, 126 insertions(+), 48 deletions(-) diff --git a/package-lock.json b/package-lock.json index 1bfe101..c2d84fc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -124,15 +124,15 @@ } }, "@types/minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-aaI6OtKcrwCX8G7aWbNh7i8GOfY=", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.1.tgz", + "integrity": "sha512-fZQQafSREFyuZcdWFAExYjBiCL7AUCdgsk80iO0q4yihYYdcIiH28CcuPTGFgLOCC8RlW49GSQxdHwZP+I7CNg==", "dev": true }, "@types/node": { - "version": "14.14.6", - "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.6.tgz", - "integrity": "sha512-6QlRuqsQ/Ox/aJEQWBEJG7A9+u7oSYl3mem/K8IzxXG/kAGbV1YPD9Bg9Zw3vyxC/YP+zONKwy8hGkSt1jxFMw==", + "version": "14.14.12", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.12.tgz", + "integrity": "sha512-ASH8OPHMNlkdjrEdmoILmzFfsJICvhBsFfAum4aKZ/9U4B6M6tTmTPh+f3ttWdD74CEGV5XvXWkbyfSdXaTd7g==", "dev": true }, "@types/normalize-package-data": { @@ -160,9 +160,9 @@ }, "dependencies": { "debug": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz", - "integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", "dev": true, "requires": { "ms": "2.1.2" @@ -234,6 +234,12 @@ "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", "dev": true }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true + }, "boolbase": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", @@ -274,6 +280,16 @@ } } }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, "braces": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", @@ -400,6 +416,12 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, "configstore": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/configstore/-/configstore-5.0.1.tgz", @@ -718,6 +740,12 @@ "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=", "dev": true }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, "function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", @@ -725,9 +753,9 @@ "dev": true }, "gaxios": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-4.0.1.tgz", - "integrity": "sha512-jOin8xRZ/UytQeBpSXFqIzqU7Fi5TqgPNLlUsSB8kjJ76+FiGBfImF8KJu++c6J4jOldfJUtt0YmkRj2ZpSHTQ==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-4.1.0.tgz", + "integrity": "sha512-vb0to8xzGnA2qcgywAjtshOKKVDf2eQhJoiL6fHhgW5tVN7wNk7egnYIO9zotfn3lQ3De1VPdf7V5/BWfCtCmg==", "dev": true, "requires": { "abort-controller": "^3.0.0", @@ -746,6 +774,20 @@ "pump": "^3.0.0" } }, + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, "glob-parent": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", @@ -891,9 +933,9 @@ }, "dependencies": { "debug": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz", - "integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", "dev": true, "requires": { "ms": "2.1.2" @@ -931,6 +973,16 @@ "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", "dev": true }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, "inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", @@ -959,9 +1011,9 @@ } }, "is-core-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.0.0.tgz", - "integrity": "sha512-jq1AH6C8MuteOoBPwkxHafmByhL9j5q4OaPGdbuD+ZtQJVzH+i6E3BJDQcBA09k57i2Hh2yQbEG8yObZ0jdlWw==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.2.0.tgz", + "integrity": "sha512-XRAfAdyyY5F5cOXn7hYQDqh2Xmii+DEfIcQGxK/uNwMHhIkPWO0g8msXcbzLe+MpGoR951MlqM/2iIlU4vKDdQ==", "dev": true, "requires": { "has": "^1.0.3" @@ -1110,16 +1162,18 @@ } }, "linkinator": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/linkinator/-/linkinator-2.2.2.tgz", - "integrity": "sha512-mcMMbo8n8p6qDuCQ5zZaBbxKK9jq79oWsoduBIGc0rRzukDmfLr7t6Ok1jJA7aHHFX251NmtbX2LdQvD54UHow==", + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/linkinator/-/linkinator-2.8.0.tgz", + "integrity": "sha512-v8MtGeoJT+6RTSEKkB1IPKbv49Esmp5m0o2b4mLzULJ8oX5GFI9OPjMT4ftQ7guhQ/hLy5iDnpoE95t6gB8Plg==", "dev": true, "requires": { "chalk": "^4.0.0", "cheerio": "^1.0.0-rc.2", "finalhandler": "^1.1.2", "gaxios": "^4.0.0", + "glob": "^7.1.6", "jsonexport": "^3.0.0", + "marked": "^1.2.5", "meow": "^8.0.0", "p-queue": "^6.2.1", "serve-static": "^1.14.1", @@ -1237,6 +1291,12 @@ "integrity": "sha512-Q7qfAk+AJvx82ZY52OByC4yjoQYryOZt6D8TKrZJIwCfhZvcj8vCQNuwDqILushtDBTvGFmUPq+uhOb1KIMi6A==", "dev": true }, + "marked": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/marked/-/marked-1.2.6.tgz", + "integrity": "sha512-7vVuSEZ8g/HH3hK/BH/+7u/NJj7x9VY4EHzujLDcqAQLiOUeFJYAsfSAyoWtR17lKrx7b08qyIno4lffwrzTaA==", + "dev": true + }, "mdurl": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", @@ -1296,6 +1356,15 @@ "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", "dev": true }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, "minimist": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", @@ -1478,6 +1547,12 @@ "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "dev": true }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true + }, "path-parse": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", @@ -1630,9 +1705,9 @@ } }, "registry-auth-token": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-4.2.0.tgz", - "integrity": "sha512-P+lWzPrsgfN+UEpDS3U8AQKg/UjZX6mQSJueZj3EK+vNESoqBSpBUD3gmu4sF9lOsjXWjF11dQKUqemf3veq1w==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-4.2.1.tgz", + "integrity": "sha512-6gkSb4U6aWJB4SF2ZvLb76yCBjcvufXBqvvEx1HbmKPkutswjW1xNVRY0+daljIYRbogN7O0etYSlbiaEQyMyw==", "dev": true, "requires": { "rc": "^1.2.8" @@ -1648,12 +1723,12 @@ } }, "resolve": { - "version": "1.18.1", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.18.1.tgz", - "integrity": "sha512-lDfCPaMKfOJXjy0dPayzPdF1phampNWr3qFCjAu+rw/qbQmr5jWH5xN2hwh9QKfw9E5v4hwV7A+jrCmL8yjjqA==", + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.19.0.tgz", + "integrity": "sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg==", "dev": true, "requires": { - "is-core-module": "^2.0.0", + "is-core-module": "^2.1.0", "path-parse": "^1.0.6" } }, @@ -1685,10 +1760,13 @@ "dev": true }, "semver": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", - "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", - "dev": true + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz", + "integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } }, "semver-diff": { "version": "3.1.1", @@ -1799,9 +1877,9 @@ } }, "spdx-license-ids": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.6.tgz", - "integrity": "sha512-+orQK83kyMva3WyPf59k1+Y525csj5JejicWut55zeTWANuN17qSiSLUXWtzHeNWORSvT7GLDJ/E/XiIWoXBTw==", + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.7.tgz", + "integrity": "sha512-U+MTEOO0AiDzxwFvoa4JVnMV6mZlJKk2sBLt90s7G0Gd0Mlknc7kxEn3nuDPNZRta7O2uy8oLcZLVT+4sqNZHQ==", "dev": true }, "sprintf-js": { @@ -1932,9 +2010,9 @@ "dev": true }, "type-fest": { - "version": "0.18.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.18.0.tgz", - "integrity": "sha512-fbDukFPnJBdn2eZ3RR+5mK2slHLFd6gYHY7jna1KWWy4Yr4XysHuCdXRzy+RiG/HwG4WJat00vdC2UHky5eKiQ==", + "version": "0.18.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.18.1.tgz", + "integrity": "sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==", "dev": true }, "typedarray-to-buffer": { @@ -1968,9 +2046,9 @@ "dev": true }, "update-notifier": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-5.0.0.tgz", - "integrity": "sha512-8tqsiVrMv7aZsKNSjqA6DdBLKJpZG1hRpkj1RbOJu1PgyP69OX+EInAnP1EK/ShX5YdPFgwWdk19oquZ0HTM8g==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-5.0.1.tgz", + "integrity": "sha512-BuVpRdlwxeIOvmc32AGYvO1KVdPlsmqSh8KDDBxS6kDE5VR7R8OMP1d8MdhaVBvxl4H3551k9akXr0Y1iIB2Wg==", "dev": true, "requires": { "boxen": "^4.2.0", @@ -1979,11 +2057,11 @@ "has-yarn": "^2.1.0", "import-lazy": "^2.1.0", "is-ci": "^2.0.0", - "is-installed-globally": "^0.3.1", + "is-installed-globally": "^0.3.2", "is-npm": "^5.0.0", "is-yarn-global": "^0.3.0", - "latest-version": "^5.0.0", - "pupa": "^2.0.1", + "latest-version": "^5.1.0", + "pupa": "^2.1.1", "semver": "^7.3.2", "semver-diff": "^3.1.1", "xdg-basedir": "^4.0.0" @@ -2060,9 +2138,9 @@ "dev": true }, "yargs-parser": { - "version": "20.2.3", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.3.tgz", - "integrity": "sha512-emOFRT9WVHw03QSvN5qor9QQT9+sw5vwxfYweivSMHTcAXPefwVae2FjO7JJjj8hCE4CzPOPeFM83VwT29HCww==", + "version": "20.2.4", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", + "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", "dev": true } } diff --git a/package.json b/package.json index 2dc6c77..5f7d877 100644 --- a/package.json +++ b/package.json @@ -22,7 +22,7 @@ "test": "npm run markdownlint && npm run linkinator" }, "devDependencies": { - "linkinator": "^2.2.2", + "linkinator": "^2.8.0", "markdownlint-cli2": "0.0.11" } } From 1659d75265bb5a0d22058fcbd87a6e42c2b11270 Mon Sep 17 00:00:00 2001 From: yubiuser Date: Sun, 13 Dec 2020 21:57:45 +0100 Subject: [PATCH 030/103] Add FritzBox guide Signed-off-by: yubiuser --- mkdocs.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/mkdocs.yml b/mkdocs.yml index 54da3ef..7f848fb 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -98,6 +98,7 @@ nav: - 'Configuring NGINX for Pi-hole': guides/nginx-configuration.md - 'Configuring Caddy for Pi-hole': guides/caddy-configuration.md - 'Configuring Traefik for Pi-hole (not in Docker)': guides/traefik-configuration-nodocker.md + - 'Configuring Fritzboxes for Pi-hole': guides/fritzbox.md - 'Benchmarking': guides/benchmark.md - 'Pi-hole and OpenVPN Server': - 'Overview': guides/vpn/overview.md From a539fc9f24a7b28240722f17e7fcb175076f6eb9 Mon Sep 17 00:00:00 2001 From: yubiuser Date: Sun, 13 Dec 2020 22:03:29 +0100 Subject: [PATCH 031/103] Add guide file Signed-off-by: yubiuser --- docs/guides/fritzbox.md | 69 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 docs/guides/fritzbox.md diff --git a/docs/guides/fritzbox.md b/docs/guides/fritzbox.md new file mode 100644 index 0000000..1c3a721 --- /dev/null +++ b/docs/guides/fritzbox.md @@ -0,0 +1,69 @@ +**This is an unsupported configuration created by the community** + +This guide was developed using a FritzBox 7530 but should work for others too. It aims to line out a few basic prinicples to have a seemless DNS experience with Pihole and Fritzboxes . + +> Note: +There is no single way to do it right. Choose the one best fitting your needs. +This guide is IPv4 only. You need to adjust for IPv6 accordingly + +## 1) Using Pihole as upstream DNS server for your Fritzbox + +Using this configuration, Pihole is used for all devices within your network including the FritzBox itself. DNS requests are send in this order + +```bash +Client -> FritzBox -> Pihole -> Upstream DNS Server +``` + +To set it up, enter Pihole's IP as "Bevorzugter DNS-Server" **and** "Alternativer DNS-Server" in + +```bash +Internet/Zugangsdaten/DNS-Server +``` + +!!! warning + Don't set the FitzBox as upstrem DNS server for pihole! This will lead to a DNS loop as the Pihole will send the queries to the Fritzbox which in turn will send the to Pihole. + +With this configuration, you won't see individual clients in pihole's dashboard. For pihole, all queries will appear as if they are comming from your FitzBox. You will therefore miss out some features, e.g. Group Management. This can be solved using method #2. + + +## 2) Distribute Pihole as DNS server via DHCP + +Using this configuration, all clients will get Pihole's IP offered as DNS server when they request a DHCP lease from your FritzBox. +DNS requests are send in this order + +```bash +Client -> Pihole -> Upstream DNS Server +``` + +> Note: +The FritzBox itself will use whatever is configured under Internet/Zugangsdaten/DNS-Server. +The FritzBox can be Pihole's upstream DNS server, as long Pihole itself is not the the upstream server for the Fritzbox. This would cause a DNS loop. + +To set it up, enter Pihole's IP as "Lokaler DNS-Server" in + +```bash +Heimnetz/Netzwerk/Netzwerkeinstellungen/IP-Adressen/IPv4-Konfiguration +``` + +You should see individual clients in Pihole's web dashboard. + +## 3) Combining 1) and 2) + +You can combine 1) and 2) which will let all clients send DNS requests to your Pihole **and** the Fritzbox itself as well. + +```bash +Client (incl. FritzBox) -> Pihole -> Upstream DNS Server +``` + +!!! warning + Don't set the FitzBox as upstrem DNS server for pihole! This will lead to a DNS loop as the Pihole will send the queries to the Fritzbox which in turn will send the to Pihole + +## Using Pihole within the Guest Network + +You may have noticed, that there is no option to set the DNS server for the guest network in + +```bash +Heimnetz/Netzwerk/Netzwerkeinstellungen/IP-Adressen/IPv4-Konfiguration +``` + +The FritzBox always set its own IP as DNS server for the guest network. To filter its traffic, you have to setup Pihole as upstream DNS server for your FitzBox (see #1). As there is no other option, all DNS requests from your guest network will appear as coming from your FritzBox. From 15862ba397c4e6a6e2b80ccda26ae5556194d535 Mon Sep 17 00:00:00 2001 From: yubiuser Date: Sun, 13 Dec 2020 22:07:29 +0100 Subject: [PATCH 032/103] Fix trailing spaces Signed-off-by: yubiuser --- docs/guides/fritzbox.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/guides/fritzbox.md b/docs/guides/fritzbox.md index 1c3a721..1ff4a5e 100644 --- a/docs/guides/fritzbox.md +++ b/docs/guides/fritzbox.md @@ -2,7 +2,7 @@ This guide was developed using a FritzBox 7530 but should work for others too. It aims to line out a few basic prinicples to have a seemless DNS experience with Pihole and Fritzboxes . -> Note: +> Note: There is no single way to do it right. Choose the one best fitting your needs. This guide is IPv4 only. You need to adjust for IPv6 accordingly @@ -28,14 +28,14 @@ With this configuration, you won't see individual clients in pihole's dashboard. ## 2) Distribute Pihole as DNS server via DHCP -Using this configuration, all clients will get Pihole's IP offered as DNS server when they request a DHCP lease from your FritzBox. +Using this configuration, all clients will get Pihole's IP offered as DNS server when they request a DHCP lease from your FritzBox. DNS requests are send in this order ```bash Client -> Pihole -> Upstream DNS Server ``` -> Note: +> Note: The FritzBox itself will use whatever is configured under Internet/Zugangsdaten/DNS-Server. The FritzBox can be Pihole's upstream DNS server, as long Pihole itself is not the the upstream server for the Fritzbox. This would cause a DNS loop. From 584bb146b3241734734acb9abc43ff80ae5b5a75 Mon Sep 17 00:00:00 2001 From: yubiuser Date: Wed, 16 Dec 2020 20:30:07 +0100 Subject: [PATCH 033/103] Fix name according to vendor Signed-off-by: yubiuser --- docs/guides/fritzbox.md | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/docs/guides/fritzbox.md b/docs/guides/fritzbox.md index 1ff4a5e..0271350 100644 --- a/docs/guides/fritzbox.md +++ b/docs/guides/fritzbox.md @@ -1,17 +1,17 @@ **This is an unsupported configuration created by the community** -This guide was developed using a FritzBox 7530 but should work for others too. It aims to line out a few basic prinicples to have a seemless DNS experience with Pihole and Fritzboxes . +This guide was developed using FRITZ!OS 07.21 but should work for others too. It aims to line out a few basic prinicples to have a seemless DNS experience with Pihole and Fritz!Boxes . > Note: There is no single way to do it right. Choose the one best fitting your needs. This guide is IPv4 only. You need to adjust for IPv6 accordingly -## 1) Using Pihole as upstream DNS server for your Fritzbox +## 1) Using Pihole as upstream DNS server for your Fritz!Box -Using this configuration, Pihole is used for all devices within your network including the FritzBox itself. DNS requests are send in this order +Using this configuration, Pihole is used for all devices within your network including the Fritz!Box itself. DNS requests are send in this order ```bash -Client -> FritzBox -> Pihole -> Upstream DNS Server +Client -> Fritz!Box -> Pihole -> Upstream DNS Server ``` To set it up, enter Pihole's IP as "Bevorzugter DNS-Server" **and** "Alternativer DNS-Server" in @@ -21,14 +21,14 @@ Internet/Zugangsdaten/DNS-Server ``` !!! warning - Don't set the FitzBox as upstrem DNS server for pihole! This will lead to a DNS loop as the Pihole will send the queries to the Fritzbox which in turn will send the to Pihole. + Don't set the Fitz!Box as upstrem DNS server for pihole! This will lead to a DNS loop as the Pihole will send the queries to the Fritz!Box which in turn will send the to Pihole. -With this configuration, you won't see individual clients in pihole's dashboard. For pihole, all queries will appear as if they are comming from your FitzBox. You will therefore miss out some features, e.g. Group Management. This can be solved using method #2. +With this configuration, you won't see individual clients in pihole's dashboard. For pihole, all queries will appear as if they are comming from your Fritz!Box. You will therefore miss out some features, e.g. Group Management. This can be solved using method #2. ## 2) Distribute Pihole as DNS server via DHCP -Using this configuration, all clients will get Pihole's IP offered as DNS server when they request a DHCP lease from your FritzBox. +Using this configuration, all clients will get Pihole's IP offered as DNS server when they request a DHCP lease from your Fritz!Box. DNS requests are send in this order ```bash @@ -36,8 +36,8 @@ Client -> Pihole -> Upstream DNS Server ``` > Note: -The FritzBox itself will use whatever is configured under Internet/Zugangsdaten/DNS-Server. -The FritzBox can be Pihole's upstream DNS server, as long Pihole itself is not the the upstream server for the Fritzbox. This would cause a DNS loop. +The Fritz!Box itself will use whatever is configured under Internet/Zugangsdaten/DNS-Server. +The Fritz!Box can be Pihole's upstream DNS server, as long Pihole itself is not the the upstream server for the Fritz!Box. This would cause a DNS loop. To set it up, enter Pihole's IP as "Lokaler DNS-Server" in @@ -45,18 +45,21 @@ To set it up, enter Pihole's IP as "Lokaler DNS-Server" in Heimnetz/Netzwerk/Netzwerkeinstellungen/IP-Adressen/IPv4-Konfiguration ``` +>Note: +Clients will notice changes in DHCP settings only after they acquire a new DHCP lease. The easiest way to force a renewal is to dis/reconnect the client from the network. + You should see individual clients in Pihole's web dashboard. ## 3) Combining 1) and 2) -You can combine 1) and 2) which will let all clients send DNS requests to your Pihole **and** the Fritzbox itself as well. +You can combine 1) and 2) which will let all clients send DNS requests to your Pihole **and** the Fritz!Box itself as well. ```bash -Client (incl. FritzBox) -> Pihole -> Upstream DNS Server +Client (incl. Fritz!Box) -> Pihole -> Upstream DNS Server ``` !!! warning - Don't set the FitzBox as upstrem DNS server for pihole! This will lead to a DNS loop as the Pihole will send the queries to the Fritzbox which in turn will send the to Pihole + Don't set the Fritz!Box as upstrem DNS server for pihole! This will lead to a DNS loop as the Pihole will send the queries to the Fritz!Box which in turn will send the to Pihole ## Using Pihole within the Guest Network @@ -66,4 +69,4 @@ You may have noticed, that there is no option to set the DNS server for the gues Heimnetz/Netzwerk/Netzwerkeinstellungen/IP-Adressen/IPv4-Konfiguration ``` -The FritzBox always set its own IP as DNS server for the guest network. To filter its traffic, you have to setup Pihole as upstream DNS server for your FitzBox (see #1). As there is no other option, all DNS requests from your guest network will appear as coming from your FritzBox. +The Fritz!Box always set its own IP as DNS server for the guest network. To filter its traffic, you have to setup Pihole as upstream DNS server for your Fritz!Box (see #1). As there is no other option, all DNS requests from your guest network will appear as coming from your Fritz!Box. From 972909e04425989c01b4ed6bc17828c3275ef9a6 Mon Sep 17 00:00:00 2001 From: yubiuser Date: Wed, 16 Dec 2020 20:37:47 +0100 Subject: [PATCH 034/103] Use English terminology Signed-off-by: yubiuser --- docs/guides/fritzbox.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/guides/fritzbox.md b/docs/guides/fritzbox.md index 0271350..852654f 100644 --- a/docs/guides/fritzbox.md +++ b/docs/guides/fritzbox.md @@ -14,10 +14,10 @@ Using this configuration, Pihole is used for all devices within your network inc Client -> Fritz!Box -> Pihole -> Upstream DNS Server ``` -To set it up, enter Pihole's IP as "Bevorzugter DNS-Server" **and** "Alternativer DNS-Server" in +To set it up, enter Pihole's IP as "Preferred DNS server" **and** "Alternative DNS server" in ```bash -Internet/Zugangsdaten/DNS-Server +Internet/Account Information/DNS server ``` !!! warning @@ -36,13 +36,13 @@ Client -> Pihole -> Upstream DNS Server ``` > Note: -The Fritz!Box itself will use whatever is configured under Internet/Zugangsdaten/DNS-Server. +The Fritz!Box itself will use whatever is configured in Internet/Account Information/DNS server. The Fritz!Box can be Pihole's upstream DNS server, as long Pihole itself is not the the upstream server for the Fritz!Box. This would cause a DNS loop. -To set it up, enter Pihole's IP as "Lokaler DNS-Server" in +To set it up, enter Pihole's IP as "Local DNS server" in ```bash -Heimnetz/Netzwerk/Netzwerkeinstellungen/IP-Adressen/IPv4-Konfiguration +Home Network/Network/Network Settings/IP Adresses/IPv4 Configuration/Home Network ``` >Note: @@ -66,7 +66,7 @@ Client (incl. Fritz!Box) -> Pihole -> Upstream DNS Server You may have noticed, that there is no option to set the DNS server for the guest network in ```bash -Heimnetz/Netzwerk/Netzwerkeinstellungen/IP-Adressen/IPv4-Konfiguration +Home Network/Network/Network Settings/IP Adresses/IPv4 Configuration/Guest Network ``` The Fritz!Box always set its own IP as DNS server for the guest network. To filter its traffic, you have to setup Pihole as upstream DNS server for your Fritz!Box (see #1). As there is no other option, all DNS requests from your guest network will appear as coming from your Fritz!Box. From 2d58aef2e84425435431b69da20a0756d3e243cf Mon Sep 17 00:00:00 2001 From: yubiuser Date: Wed, 16 Dec 2020 20:44:51 +0100 Subject: [PATCH 035/103] Create 'Router setup' menu Signed-off-by: yubiuser --- docs/routers/fritzbox-de.md | 72 ++++++++++++++++++++++++++++ docs/{guides => routers}/fritzbox.md | 0 2 files changed, 72 insertions(+) create mode 100644 docs/routers/fritzbox-de.md rename docs/{guides => routers}/fritzbox.md (100%) diff --git a/docs/routers/fritzbox-de.md b/docs/routers/fritzbox-de.md new file mode 100644 index 0000000..0271350 --- /dev/null +++ b/docs/routers/fritzbox-de.md @@ -0,0 +1,72 @@ +**This is an unsupported configuration created by the community** + +This guide was developed using FRITZ!OS 07.21 but should work for others too. It aims to line out a few basic prinicples to have a seemless DNS experience with Pihole and Fritz!Boxes . + +> Note: +There is no single way to do it right. Choose the one best fitting your needs. +This guide is IPv4 only. You need to adjust for IPv6 accordingly + +## 1) Using Pihole as upstream DNS server for your Fritz!Box + +Using this configuration, Pihole is used for all devices within your network including the Fritz!Box itself. DNS requests are send in this order + +```bash +Client -> Fritz!Box -> Pihole -> Upstream DNS Server +``` + +To set it up, enter Pihole's IP as "Bevorzugter DNS-Server" **and** "Alternativer DNS-Server" in + +```bash +Internet/Zugangsdaten/DNS-Server +``` + +!!! warning + Don't set the Fitz!Box as upstrem DNS server for pihole! This will lead to a DNS loop as the Pihole will send the queries to the Fritz!Box which in turn will send the to Pihole. + +With this configuration, you won't see individual clients in pihole's dashboard. For pihole, all queries will appear as if they are comming from your Fritz!Box. You will therefore miss out some features, e.g. Group Management. This can be solved using method #2. + + +## 2) Distribute Pihole as DNS server via DHCP + +Using this configuration, all clients will get Pihole's IP offered as DNS server when they request a DHCP lease from your Fritz!Box. +DNS requests are send in this order + +```bash +Client -> Pihole -> Upstream DNS Server +``` + +> Note: +The Fritz!Box itself will use whatever is configured under Internet/Zugangsdaten/DNS-Server. +The Fritz!Box can be Pihole's upstream DNS server, as long Pihole itself is not the the upstream server for the Fritz!Box. This would cause a DNS loop. + +To set it up, enter Pihole's IP as "Lokaler DNS-Server" in + +```bash +Heimnetz/Netzwerk/Netzwerkeinstellungen/IP-Adressen/IPv4-Konfiguration +``` + +>Note: +Clients will notice changes in DHCP settings only after they acquire a new DHCP lease. The easiest way to force a renewal is to dis/reconnect the client from the network. + +You should see individual clients in Pihole's web dashboard. + +## 3) Combining 1) and 2) + +You can combine 1) and 2) which will let all clients send DNS requests to your Pihole **and** the Fritz!Box itself as well. + +```bash +Client (incl. Fritz!Box) -> Pihole -> Upstream DNS Server +``` + +!!! warning + Don't set the Fritz!Box as upstrem DNS server for pihole! This will lead to a DNS loop as the Pihole will send the queries to the Fritz!Box which in turn will send the to Pihole + +## Using Pihole within the Guest Network + +You may have noticed, that there is no option to set the DNS server for the guest network in + +```bash +Heimnetz/Netzwerk/Netzwerkeinstellungen/IP-Adressen/IPv4-Konfiguration +``` + +The Fritz!Box always set its own IP as DNS server for the guest network. To filter its traffic, you have to setup Pihole as upstream DNS server for your Fritz!Box (see #1). As there is no other option, all DNS requests from your guest network will appear as coming from your Fritz!Box. diff --git a/docs/guides/fritzbox.md b/docs/routers/fritzbox.md similarity index 100% rename from docs/guides/fritzbox.md rename to docs/routers/fritzbox.md From 62e8ef2d7f9e0ef2bd8f120ca6cdab0e0512ec58 Mon Sep 17 00:00:00 2001 From: yubiuser Date: Wed, 16 Dec 2020 20:46:15 +0100 Subject: [PATCH 036/103] Update mkdocs.yml Signed-off-by: yubiuser --- mkdocs.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/mkdocs.yml b/mkdocs.yml index 7f848fb..31eaaed 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -98,7 +98,6 @@ nav: - 'Configuring NGINX for Pi-hole': guides/nginx-configuration.md - 'Configuring Caddy for Pi-hole': guides/caddy-configuration.md - 'Configuring Traefik for Pi-hole (not in Docker)': guides/traefik-configuration-nodocker.md - - 'Configuring Fritzboxes for Pi-hole': guides/fritzbox.md - 'Benchmarking': guides/benchmark.md - 'Pi-hole and OpenVPN Server': - 'Overview': guides/vpn/overview.md @@ -119,6 +118,8 @@ nav: - 'Using TOR': guides/tor/using-tor.md - 'Performance and other issues': guides/tor/performance-issues.md - 'Using DNSSEC': guides/tor/dnssec.md + - 'Router setup': + - 'Fritz!Boxes (EN)': routers/fritzbox.md - 'Community Projects': main/projects.md extra: From ab670e79afa5b6de8b63ba35747ee8f9ea01d3c7 Mon Sep 17 00:00:00 2001 From: yubiuser Date: Wed, 16 Dec 2020 21:52:02 +0100 Subject: [PATCH 037/103] Add German translation Signed-off-by: yubiuser --- docs/routers/fritzbox-de.md | 59 +++++++++++++++++++------------------ mkdocs.yml | 3 +- 2 files changed, 33 insertions(+), 29 deletions(-) diff --git a/docs/routers/fritzbox-de.md b/docs/routers/fritzbox-de.md index 0271350..c2a1c08 100644 --- a/docs/routers/fritzbox-de.md +++ b/docs/routers/fritzbox-de.md @@ -1,72 +1,75 @@ -**This is an unsupported configuration created by the community** +**Dies ist eine inoffizielle Anleitung die durch die Community gepflegt wird** -This guide was developed using FRITZ!OS 07.21 but should work for others too. It aims to line out a few basic prinicples to have a seemless DNS experience with Pihole and Fritz!Boxes . +Diese Anleitung wurde für FRITZ!OS 07.21 geschrieben, sollte jedoch auch mit anderen Firmware-Versionen funktionieren. Ziel ist es, grundlegende Prinzipien für ein reibungsloses Zusammenspiel zwischen Fritz!Box und Pihole zu verdeutlichen. -> Note: -There is no single way to do it right. Choose the one best fitting your needs. -This guide is IPv4 only. You need to adjust for IPv6 accordingly +> Hinweis: +Es gibt nicht nur **die eine Art**, eine funktionierende DNS System aufzusetzen. Konfiguriert euer Netzwerk nach euren Bedürfnissen. +Diese Anleitung wurde für IPv4 geschrieben und muss für IPv6 Netwerke entsprechend angepasst werden. -## 1) Using Pihole as upstream DNS server for your Fritz!Box +## 1) Pihole als Upstream DNS Server der Fritz!Box (WAN Seite) -Using this configuration, Pihole is used for all devices within your network including the Fritz!Box itself. DNS requests are send in this order +Mit dieser Konfiguration, wird Pihole für alle Geräte im Netzwerk, incl. der Fritz!Box genutzt. DNS Anfragen nehmen folgenden Weg ```bash Client -> Fritz!Box -> Pihole -> Upstream DNS Server ``` -To set it up, enter Pihole's IP as "Bevorzugter DNS-Server" **and** "Alternativer DNS-Server" in +Zum Einstellen muss die IP des Pihole als "Bevorzugter DNS-Server" **und** "Alternativer DNS-Server" in ```bash Internet/Zugangsdaten/DNS-Server ``` +eingertagen werden. !!! warning - Don't set the Fitz!Box as upstrem DNS server for pihole! This will lead to a DNS loop as the Pihole will send the queries to the Fritz!Box which in turn will send the to Pihole. + Die Fritz!Box darf nicht als upstream DNS Server im Pihole eingestellt werden. Dies würde zu einem DNS Loop führen, da Pihole dann die Anfragen an dieFritz!Box senden würde, welche sie wiederum an Pihole senden würde. -With this configuration, you won't see individual clients in pihole's dashboard. For pihole, all queries will appear as if they are comming from your Fritz!Box. You will therefore miss out some features, e.g. Group Management. This can be solved using method #2. +Mit dieser Konfiguration sind im Pihole Dashboard keine individuellen Clients sichtbar. Für Pihole scheinen alle Anfragen von der Fritz!Box zu kommen. Dadurch können nicht alle Funktionen von Pihole genutzt werden, z.B. die Möglichkeit, Clients individuell zu filtern (Group Management). Wenn dies gewünscht ist, muss die Konfiguration #2 verwendet werden. -## 2) Distribute Pihole as DNS server via DHCP +## 2) Pihole als DNS Server via DHCP an Clients verteilen (LAN Seite) -Using this configuration, all clients will get Pihole's IP offered as DNS server when they request a DHCP lease from your Fritz!Box. -DNS requests are send in this order +Mit dieser Konfiguration wird allen Clients die IP des Pihole als DNS Server angeboten, wenn sie einen DHCP Lease vom der Fritz!Box anfordern. +DNS Anfragen nehmen folgenden Weg ```bash Client -> Pihole -> Upstream DNS Server ``` -> Note: -The Fritz!Box itself will use whatever is configured under Internet/Zugangsdaten/DNS-Server. -The Fritz!Box can be Pihole's upstream DNS server, as long Pihole itself is not the the upstream server for the Fritz!Box. This would cause a DNS loop. +> Hinweis: +Die Fritz!Box selbst wird den unter Internet/Zugangsdaten/DNS-Server eingestellten DNS Server nutzen. +Die Fritz!Box kann der Upstream Server von Pihole sein, solange Pihole nicht der Upstream Server der Fritz!Box ist. Dies würde zu einem DNS Loop führen. -To set it up, enter Pihole's IP as "Lokaler DNS-Server" in +Um diese Konfiguration zu nutzen, muss die IP des Pihole als "Lokaler DNS-Server" in ```bash -Heimnetz/Netzwerk/Netzwerkeinstellungen/IP-Adressen/IPv4-Konfiguration +Heimnetz/Netzwerk/Netzwerkeinstellungen/IP-Adressen/IPv4-Konfiguration/Heimnetz ``` +eingetragen werden. ->Note: -Clients will notice changes in DHCP settings only after they acquire a new DHCP lease. The easiest way to force a renewal is to dis/reconnect the client from the network. +>Hinweis: +Clients bemerken Änderungen an den DHCP Einstellungen erst, wenn der DHCP Lease erneuert wird. Der einfachste Weg dies zu erzwingen ist ein Unterbrechen und Wiederherstellen der Netzwerkverbindung. -You should see individual clients in Pihole's web dashboard. +Nun sollen einzelne Clients in Piholes Dashboard auftrauchen. -## 3) Combining 1) and 2) +## 3) Kombination aus 1) und 2) -You can combine 1) and 2) which will let all clients send DNS requests to your Pihole **and** the Fritz!Box itself as well. +Durch die Kombination von 1) und 2) senden alle Clients und die Fritz!Box selbst DNS Anfragen direkt an Pihole. ```bash Client (incl. Fritz!Box) -> Pihole -> Upstream DNS Server ``` !!! warning - Don't set the Fritz!Box as upstrem DNS server for pihole! This will lead to a DNS loop as the Pihole will send the queries to the Fritz!Box which in turn will send the to Pihole + Die Fritz!Box darf nicht als Upstream DNS Server des Pihole gesetzt werden. Dies würde zu einem DNS Loop führen, da Pihole die Anfragen an die Fritz!Box senden würde, welche sie wiederum an Pihole weitergeben würde. -## Using Pihole within the Guest Network +## Pihole im Gastnetzwerk nutzen -You may have noticed, that there is no option to set the DNS server for the guest network in +Es gibt in der Fritz!Box keine Möglichkeit unter ```bash -Heimnetz/Netzwerk/Netzwerkeinstellungen/IP-Adressen/IPv4-Konfiguration +Heimnetz/Netzwerk/Netzwerkeinstellungen/IP-Adressen/IPv4-Konfiguration/Gastnetz ``` +den DNS Server des Gastnetzwerks einzustellen. -The Fritz!Box always set its own IP as DNS server for the guest network. To filter its traffic, you have to setup Pihole as upstream DNS server for your Fritz!Box (see #1). As there is no other option, all DNS requests from your guest network will appear as coming from your Fritz!Box. +Die Fritz!Box wird immer ihre eigene IP als DNS Server des Gastnetzes einstellen. Um die DNS Anfragen dennoch über den Pihole zu senden, muss der als Upstream DNS für die Fritz!Box (siehe #1) eingetragen werden. Da es keine andere Option gibt, werden alle Anfragen aus dem Gastnetz für Pihole so erscheinen, als ob sie direkt von der Fritz!Box kommen. Eine individuelle Filterung je nach Client innerhalb des Gastnetzwerks ist deshalb nicht möglich. diff --git a/mkdocs.yml b/mkdocs.yml index 31eaaed..f8d4adb 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -119,7 +119,8 @@ nav: - 'Performance and other issues': guides/tor/performance-issues.md - 'Using DNSSEC': guides/tor/dnssec.md - 'Router setup': - - 'Fritz!Boxes (EN)': routers/fritzbox.md + - 'Fritz!Box (EN)': routers/fritzbox.md + - 'Fritz!Box (DE)': routers/fritzbox-de.md - 'Community Projects': main/projects.md extra: From 485a047af87226457516a75ed00b311655f86bed Mon Sep 17 00:00:00 2001 From: yubiuser Date: Wed, 16 Dec 2020 21:55:30 +0100 Subject: [PATCH 038/103] Fix markdownlint Signed-off-by: yubiuser --- docs/routers/fritzbox-de.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/routers/fritzbox-de.md b/docs/routers/fritzbox-de.md index c2a1c08..218b637 100644 --- a/docs/routers/fritzbox-de.md +++ b/docs/routers/fritzbox-de.md @@ -19,6 +19,7 @@ Zum Einstellen muss die IP des Pihole als "Bevorzugter DNS-Server" **und** "Alte ```bash Internet/Zugangsdaten/DNS-Server ``` + eingertagen werden. !!! warning @@ -45,6 +46,7 @@ Um diese Konfiguration zu nutzen, muss die IP des Pihole als "Lokaler DNS-Server ```bash Heimnetz/Netzwerk/Netzwerkeinstellungen/IP-Adressen/IPv4-Konfiguration/Heimnetz ``` + eingetragen werden. >Hinweis: @@ -70,6 +72,7 @@ Es gibt in der Fritz!Box keine Möglichkeit unter ```bash Heimnetz/Netzwerk/Netzwerkeinstellungen/IP-Adressen/IPv4-Konfiguration/Gastnetz ``` + den DNS Server des Gastnetzwerks einzustellen. Die Fritz!Box wird immer ihre eigene IP als DNS Server des Gastnetzes einstellen. Um die DNS Anfragen dennoch über den Pihole zu senden, muss der als Upstream DNS für die Fritz!Box (siehe #1) eingetragen werden. Da es keine andere Option gibt, werden alle Anfragen aus dem Gastnetz für Pihole so erscheinen, als ob sie direkt von der Fritz!Box kommen. Eine individuelle Filterung je nach Client innerhalb des Gastnetzwerks ist deshalb nicht möglich. From a395743249498f12fa7983ce11e0e28de0daa51a Mon Sep 17 00:00:00 2001 From: yubiuser Date: Wed, 16 Dec 2020 22:07:28 +0100 Subject: [PATCH 039/103] Fix markdownlint2 Signed-off-by: yubiuser --- docs/routers/fritzbox-de.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/routers/fritzbox-de.md b/docs/routers/fritzbox-de.md index 218b637..17750be 100644 --- a/docs/routers/fritzbox-de.md +++ b/docs/routers/fritzbox-de.md @@ -50,7 +50,7 @@ Heimnetz/Netzwerk/Netzwerkeinstellungen/IP-Adressen/IPv4-Konfiguration/Heimnetz eingetragen werden. >Hinweis: -Clients bemerken Änderungen an den DHCP Einstellungen erst, wenn der DHCP Lease erneuert wird. Der einfachste Weg dies zu erzwingen ist ein Unterbrechen und Wiederherstellen der Netzwerkverbindung. +Clients bemerken Änderungen an den DHCP Einstellungen erst, wenn der DHCP Lease erneuert wird. Der einfachste Weg dies zu erzwingen ist ein Unterbrechen und Wiederherstellen der Netzwerkverbindung. Nun sollen einzelne Clients in Piholes Dashboard auftrauchen. From f717de8d2f1f45d052a52cbc54cfc8b590d5c2d5 Mon Sep 17 00:00:00 2001 From: yubiuser Date: Thu, 17 Dec 2020 06:55:24 +0100 Subject: [PATCH 040/103] Add screenshots Signed-off-by: yubiuser --- docs/images/fritzbox-dhcp-de.png | Bin 0 -> 42135 bytes docs/images/fritzbox-dhcp.png | Bin 0 -> 41058 bytes docs/images/fritzbox-wan-dns-de.png | Bin 0 -> 28000 bytes docs/images/fritzbox-wan-dns.png | Bin 0 -> 27213 bytes docs/routers/fritzbox-de.md | 2 ++ docs/routers/fritzbox.md | 2 ++ 6 files changed, 4 insertions(+) create mode 100644 docs/images/fritzbox-dhcp-de.png create mode 100644 docs/images/fritzbox-dhcp.png create mode 100644 docs/images/fritzbox-wan-dns-de.png create mode 100644 docs/images/fritzbox-wan-dns.png diff --git a/docs/images/fritzbox-dhcp-de.png b/docs/images/fritzbox-dhcp-de.png new file mode 100644 index 0000000000000000000000000000000000000000..91a9600f1e7c445351af6ef1a6ef9b9b76c598b0 GIT binary patch literal 42135 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

l5l>Kmq! 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 Fe*x)>2n+xK literal 0 HcmV?d00001 diff --git a/docs/images/fritzbox-dhcp.png b/docs/images/fritzbox-dhcp.png new file mode 100644 index 0000000000000000000000000000000000000000..72235b51219616e89ccf96f9d12ec5fa9ab89867 GIT binary patch literal 41058 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

)M@bbbm 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

  • 9Ynq<2&Gn2YA6JoNN4C~( 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 literal 0 HcmV?d00001 diff --git a/docs/images/fritzbox-wan-dns.png b/docs/images/fritzbox-wan-dns.png new file mode 100644 index 0000000000000000000000000000000000000000..2f04d4daebcfce0a33c63cba1d9bf6e88b486f45 GIT binary patch literal 27213 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 literal 0 HcmV?d00001 diff --git a/docs/routers/fritzbox-de.md b/docs/routers/fritzbox-de.md index 17750be..bb06695 100644 --- a/docs/routers/fritzbox-de.md +++ b/docs/routers/fritzbox-de.md @@ -19,6 +19,7 @@ Zum Einstellen muss die IP des Pihole als "Bevorzugter DNS-Server" **und** "Alte ```bash Internet/Zugangsdaten/DNS-Server ``` +![Screenshot der Fritz!Box WAN DNS Konfiguration](../images/fritzbox-wan-dns-de.png) eingertagen werden. @@ -46,6 +47,7 @@ Um diese Konfiguration zu nutzen, muss die IP des Pihole als "Lokaler DNS-Server ```bash Heimnetz/Netzwerk/Netzwerkeinstellungen/IP-Adressen/IPv4-Konfiguration/Heimnetz ``` +![Screenshot der Fritz!Box DHCP Einstellungen](../images/fritzbox-dhcp-de.png) eingetragen werden. diff --git a/docs/routers/fritzbox.md b/docs/routers/fritzbox.md index 852654f..363494e 100644 --- a/docs/routers/fritzbox.md +++ b/docs/routers/fritzbox.md @@ -19,6 +19,7 @@ To set it up, enter Pihole's IP as "Preferred DNS server" **and** "Alternative D ```bash Internet/Account Information/DNS server ``` +![Screenshot of Fritz!Box WAN DNS Configuration](../images/fritzbox-wan-dns.png) !!! warning Don't set the Fitz!Box as upstrem DNS server for pihole! This will lead to a DNS loop as the Pihole will send the queries to the Fritz!Box which in turn will send the to Pihole. @@ -44,6 +45,7 @@ To set it up, enter Pihole's IP as "Local DNS server" in ```bash Home Network/Network/Network Settings/IP Adresses/IPv4 Configuration/Home Network ``` +![Screenshot of Fritz!Box DHCP Settings](../images/fritzbox-dhcp.png) >Note: Clients will notice changes in DHCP settings only after they acquire a new DHCP lease. The easiest way to force a renewal is to dis/reconnect the client from the network. From e3978ce6f38a4e87037225ae44ab1e001d66ca3d Mon Sep 17 00:00:00 2001 From: yubiuser Date: Thu, 17 Dec 2020 06:59:03 +0100 Subject: [PATCH 041/103] Fix markdownlint3 Signed-off-by: yubiuser --- docs/routers/fritzbox-de.md | 6 ++++-- docs/routers/fritzbox.md | 6 ++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/docs/routers/fritzbox-de.md b/docs/routers/fritzbox-de.md index bb06695..6879c8c 100644 --- a/docs/routers/fritzbox-de.md +++ b/docs/routers/fritzbox-de.md @@ -19,7 +19,8 @@ Zum Einstellen muss die IP des Pihole als "Bevorzugter DNS-Server" **und** "Alte ```bash Internet/Zugangsdaten/DNS-Server ``` -![Screenshot der Fritz!Box WAN DNS Konfiguration](../images/fritzbox-wan-dns-de.png) + +![Screenshot der Fritz!Box WAN DNS Konfiguration](../images/fritzbox-wan-dns-de.png) eingertagen werden. @@ -46,8 +47,9 @@ Um diese Konfiguration zu nutzen, muss die IP des Pihole als "Lokaler DNS-Server ```bash Heimnetz/Netzwerk/Netzwerkeinstellungen/IP-Adressen/IPv4-Konfiguration/Heimnetz + ``` -![Screenshot der Fritz!Box DHCP Einstellungen](../images/fritzbox-dhcp-de.png) +![Screenshot der Fritz!Box DHCP Einstellungen](../images/fritzbox-dhcp-de.png) eingetragen werden. diff --git a/docs/routers/fritzbox.md b/docs/routers/fritzbox.md index 363494e..c5477be 100644 --- a/docs/routers/fritzbox.md +++ b/docs/routers/fritzbox.md @@ -19,7 +19,8 @@ To set it up, enter Pihole's IP as "Preferred DNS server" **and** "Alternative D ```bash Internet/Account Information/DNS server ``` -![Screenshot of Fritz!Box WAN DNS Configuration](../images/fritzbox-wan-dns.png) + +![Screenshot of Fritz!Box WAN DNS Configuration](../images/fritzbox-wan-dns.png) !!! warning Don't set the Fitz!Box as upstrem DNS server for pihole! This will lead to a DNS loop as the Pihole will send the queries to the Fritz!Box which in turn will send the to Pihole. @@ -45,7 +46,8 @@ To set it up, enter Pihole's IP as "Local DNS server" in ```bash Home Network/Network/Network Settings/IP Adresses/IPv4 Configuration/Home Network ``` -![Screenshot of Fritz!Box DHCP Settings](../images/fritzbox-dhcp.png) + +![Screenshot of Fritz!Box DHCP Settings](../images/fritzbox-dhcp.png) >Note: Clients will notice changes in DHCP settings only after they acquire a new DHCP lease. The easiest way to force a renewal is to dis/reconnect the client from the network. From 21ef9007ed13d93d0101191051d9a8be5f73e6c0 Mon Sep 17 00:00:00 2001 From: yubiuser Date: Thu, 17 Dec 2020 07:00:39 +0100 Subject: [PATCH 042/103] Fix markdownlint4 Signed-off-by: yubiuser --- docs/routers/fritzbox-de.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/routers/fritzbox-de.md b/docs/routers/fritzbox-de.md index 6879c8c..523725b 100644 --- a/docs/routers/fritzbox-de.md +++ b/docs/routers/fritzbox-de.md @@ -47,8 +47,8 @@ Um diese Konfiguration zu nutzen, muss die IP des Pihole als "Lokaler DNS-Server ```bash Heimnetz/Netzwerk/Netzwerkeinstellungen/IP-Adressen/IPv4-Konfiguration/Heimnetz - ``` + ![Screenshot der Fritz!Box DHCP Einstellungen](../images/fritzbox-dhcp-de.png) eingetragen werden. From 1049bbfe14df59cbc8c2f1cb2292ecc0e927cf1f Mon Sep 17 00:00:00 2001 From: yubiuser Date: Thu, 17 Dec 2020 20:36:33 +0100 Subject: [PATCH 043/103] Address DL's comments Signed-off-by: yubiuser --- docs/routers/fritzbox-de.md | 40 ++++++++++++++++++------------------- docs/routers/fritzbox.md | 40 ++++++++++++++++++------------------- 2 files changed, 38 insertions(+), 42 deletions(-) diff --git a/docs/routers/fritzbox-de.md b/docs/routers/fritzbox-de.md index 523725b..d49f9a7 100644 --- a/docs/routers/fritzbox-de.md +++ b/docs/routers/fritzbox-de.md @@ -1,20 +1,18 @@ -**Dies ist eine inoffizielle Anleitung die durch die Community gepflegt wird** - -Diese Anleitung wurde für FRITZ!OS 07.21 geschrieben, sollte jedoch auch mit anderen Firmware-Versionen funktionieren. Ziel ist es, grundlegende Prinzipien für ein reibungsloses Zusammenspiel zwischen Fritz!Box und Pihole zu verdeutlichen. +Diese Anleitung wurde für FRITZ!OS 07.21 geschrieben, sollte jedoch auch mit anderen Firmware-Versionen funktionieren. Ziel ist es, grundlegende Prinzipien für ein reibungsloses Zusammenspiel zwischen Fritz!Box und Pi-hole zu verdeutlichen. > Hinweis: Es gibt nicht nur **die eine Art**, eine funktionierende DNS System aufzusetzen. Konfiguriert euer Netzwerk nach euren Bedürfnissen. Diese Anleitung wurde für IPv4 geschrieben und muss für IPv6 Netwerke entsprechend angepasst werden. -## 1) Pihole als Upstream DNS Server der Fritz!Box (WAN Seite) +## 1) Pi-hole als Upstream DNS Server der Fritz!Box (WAN Seite) -Mit dieser Konfiguration, wird Pihole für alle Geräte im Netzwerk, incl. der Fritz!Box genutzt. DNS Anfragen nehmen folgenden Weg +Mit dieser Konfiguration, wird Pi-hole für alle Geräte im Netzwerk, incl. der Fritz!Box genutzt. DNS Anfragen nehmen folgenden Weg ```bash -Client -> Fritz!Box -> Pihole -> Upstream DNS Server +Client -> Fritz!Box -> Pi-hole -> Upstream DNS Server ``` -Zum Einstellen muss die IP des Pihole als "Bevorzugter DNS-Server" **und** "Alternativer DNS-Server" in +Zum Einstellen muss die IP des Pi-hole als "Bevorzugter DNS-Server" **und** "Alternativer DNS-Server" in ```bash Internet/Zugangsdaten/DNS-Server @@ -22,28 +20,28 @@ Internet/Zugangsdaten/DNS-Server ![Screenshot der Fritz!Box WAN DNS Konfiguration](../images/fritzbox-wan-dns-de.png) -eingertagen werden. +eingetragen werden. !!! warning - Die Fritz!Box darf nicht als upstream DNS Server im Pihole eingestellt werden. Dies würde zu einem DNS Loop führen, da Pihole dann die Anfragen an dieFritz!Box senden würde, welche sie wiederum an Pihole senden würde. + Die Fritz!Box darf nicht als upstream DNS Server im Pi-hole eingestellt werden. Dies würde zu einem DNS Loop führen, da Pi-hole dann die Anfragen an die Fritz!Box senden würde, welche sie wiederum an Pi-hole senden würde. -Mit dieser Konfiguration sind im Pihole Dashboard keine individuellen Clients sichtbar. Für Pihole scheinen alle Anfragen von der Fritz!Box zu kommen. Dadurch können nicht alle Funktionen von Pihole genutzt werden, z.B. die Möglichkeit, Clients individuell zu filtern (Group Management). Wenn dies gewünscht ist, muss die Konfiguration #2 verwendet werden. +Mit dieser Konfiguration sind im Pi-hole Dashboard keine individuellen Clients sichtbar. Für Pi-hole scheinen alle Anfragen von der Fritz!Box zu kommen. Dadurch können nicht alle Funktionen von Pi-hole genutzt werden, z.B. die Möglichkeit, Clients individuell zu filtern (Group Management). Wenn dies gewünscht ist, muss die Konfiguration #2 verwendet werden. -## 2) Pihole als DNS Server via DHCP an Clients verteilen (LAN Seite) +## 2) Pi-hole als DNS Server via DHCP an Clients verteilen (LAN Seite) -Mit dieser Konfiguration wird allen Clients die IP des Pihole als DNS Server angeboten, wenn sie einen DHCP Lease vom der Fritz!Box anfordern. +Mit dieser Konfiguration wird allen Clients die IP des Pi-hole als DNS Server angeboten, wenn sie einen DHCP Lease vom der Fritz!Box anfordern. DNS Anfragen nehmen folgenden Weg ```bash -Client -> Pihole -> Upstream DNS Server +Client -> Pi-hole -> Upstream DNS Server ``` > Hinweis: Die Fritz!Box selbst wird den unter Internet/Zugangsdaten/DNS-Server eingestellten DNS Server nutzen. -Die Fritz!Box kann der Upstream Server von Pihole sein, solange Pihole nicht der Upstream Server der Fritz!Box ist. Dies würde zu einem DNS Loop führen. +Die Fritz!Box kann der Upstream Server von Pi-hole sein, solange Pi-hole nicht der Upstream Server der Fritz!Box ist. Dies würde zu einem DNS Loop führen. -Um diese Konfiguration zu nutzen, muss die IP des Pihole als "Lokaler DNS-Server" in +Um diese Konfiguration zu nutzen, muss die IP des Pi-hole als "Lokaler DNS-Server" in ```bash Heimnetz/Netzwerk/Netzwerkeinstellungen/IP-Adressen/IPv4-Konfiguration/Heimnetz @@ -56,20 +54,20 @@ eingetragen werden. >Hinweis: Clients bemerken Änderungen an den DHCP Einstellungen erst, wenn der DHCP Lease erneuert wird. Der einfachste Weg dies zu erzwingen ist ein Unterbrechen und Wiederherstellen der Netzwerkverbindung. -Nun sollen einzelne Clients in Piholes Dashboard auftrauchen. +Nun sollen einzelne Clients in Pi-hole Dashboard auftrauchen. ## 3) Kombination aus 1) und 2) -Durch die Kombination von 1) und 2) senden alle Clients und die Fritz!Box selbst DNS Anfragen direkt an Pihole. +Durch die Kombination von 1) und 2) senden alle Clients und die Fritz!Box selbst DNS Anfragen direkt an Pi-hole. ```bash -Client (incl. Fritz!Box) -> Pihole -> Upstream DNS Server +Client (incl. Fritz!Box) -> Pi-hole -> Upstream DNS Server ``` !!! warning - Die Fritz!Box darf nicht als Upstream DNS Server des Pihole gesetzt werden. Dies würde zu einem DNS Loop führen, da Pihole die Anfragen an die Fritz!Box senden würde, welche sie wiederum an Pihole weitergeben würde. + Die Fritz!Box darf nicht als Upstream DNS Server des Pi-hole gesetzt werden. Dies würde zu einem DNS Loop führen, da Pi-hole die Anfragen an die Fritz!Box senden würde, welche sie wiederum an Pi-hole weitergeben würde. -## Pihole im Gastnetzwerk nutzen +## Pi-hole im Gastnetzwerk nutzen Es gibt in der Fritz!Box keine Möglichkeit unter @@ -79,4 +77,4 @@ Heimnetz/Netzwerk/Netzwerkeinstellungen/IP-Adressen/IPv4-Konfiguration/Gastnetz den DNS Server des Gastnetzwerks einzustellen. -Die Fritz!Box wird immer ihre eigene IP als DNS Server des Gastnetzes einstellen. Um die DNS Anfragen dennoch über den Pihole zu senden, muss der als Upstream DNS für die Fritz!Box (siehe #1) eingetragen werden. Da es keine andere Option gibt, werden alle Anfragen aus dem Gastnetz für Pihole so erscheinen, als ob sie direkt von der Fritz!Box kommen. Eine individuelle Filterung je nach Client innerhalb des Gastnetzwerks ist deshalb nicht möglich. +Die Fritz!Box wird immer ihre eigene IP als DNS Server des Gastnetzes einstellen. Um die DNS Anfragen dennoch über den Pi-hole zu senden, muss der als Upstream DNS für die Fritz!Box (siehe #1) eingetragen werden. Da es keine andere Option gibt, werden alle Anfragen aus dem Gastnetz für Pi-hole so erscheinen, als ob sie direkt von der Fritz!Box kommen. Eine individuelle Filterung je nach Client innerhalb des Gastnetzwerks ist deshalb nicht möglich. diff --git a/docs/routers/fritzbox.md b/docs/routers/fritzbox.md index c5477be..a50aea0 100644 --- a/docs/routers/fritzbox.md +++ b/docs/routers/fritzbox.md @@ -1,20 +1,18 @@ -**This is an unsupported configuration created by the community** - -This guide was developed using FRITZ!OS 07.21 but should work for others too. It aims to line out a few basic prinicples to have a seemless DNS experience with Pihole and Fritz!Boxes . +This guide was developed using FRITZ!OS 07.21 but should work for others too. It aims to line out a few basic principles to have a seamless DNS experience with Pi-hole and Fritz!Boxes . > Note: There is no single way to do it right. Choose the one best fitting your needs. This guide is IPv4 only. You need to adjust for IPv6 accordingly -## 1) Using Pihole as upstream DNS server for your Fritz!Box +## 1) Using Pi-hole as upstream DNS server for your Fritz!Box -Using this configuration, Pihole is used for all devices within your network including the Fritz!Box itself. DNS requests are send in this order +Using this configuration, Pi-hole is used for all devices within your network including the Fritz!Box itself. DNS requests are sent in this order ```bash -Client -> Fritz!Box -> Pihole -> Upstream DNS Server +Client -> Fritz!Box -> Pi-hole -> Upstream DNS Server ``` -To set it up, enter Pihole's IP as "Preferred DNS server" **and** "Alternative DNS server" in +To set it up, enter Pi-hole's IP as "Preferred DNS server" **and** "Alternative DNS server" in ```bash Internet/Account Information/DNS server @@ -23,25 +21,25 @@ Internet/Account Information/DNS server ![Screenshot of Fritz!Box WAN DNS Configuration](../images/fritzbox-wan-dns.png) !!! warning - Don't set the Fitz!Box as upstrem DNS server for pihole! This will lead to a DNS loop as the Pihole will send the queries to the Fritz!Box which in turn will send the to Pihole. + Don't set the Fitz!Box as upstrem DNS server for Pi-hole! This will lead to a DNS loop as the Pi-hole will send the queries to the Fritz!Box which in turn will send the to Pi-hole. -With this configuration, you won't see individual clients in pihole's dashboard. For pihole, all queries will appear as if they are comming from your Fritz!Box. You will therefore miss out some features, e.g. Group Management. This can be solved using method #2. +With this configuration, you won't see individual clients in Pi-hole's dashboard. For Pi-hole, all queries will appear as if they are coming from your Fritz!Box. You will therefore miss out on some features, e.g. Group Management. This can be solved using method #2. -## 2) Distribute Pihole as DNS server via DHCP +## 2) Distribute Pi-hole as DNS server via DHCP -Using this configuration, all clients will get Pihole's IP offered as DNS server when they request a DHCP lease from your Fritz!Box. -DNS requests are send in this order +Using this configuration, all clients will get Pi-hole's IP offered as DNS server when they request a DHCP lease from your Fritz!Box. +DNS requests are sent in this order ```bash -Client -> Pihole -> Upstream DNS Server +Client -> Pi-hole -> Upstream DNS Server ``` > Note: The Fritz!Box itself will use whatever is configured in Internet/Account Information/DNS server. -The Fritz!Box can be Pihole's upstream DNS server, as long Pihole itself is not the the upstream server for the Fritz!Box. This would cause a DNS loop. +The Fritz!Box can be Pi-hole's upstream DNS server, as long Pi-hole itself is not the upstream server for the Fritz!Box. This would cause a DNS loop. -To set it up, enter Pihole's IP as "Local DNS server" in +To set it up, enter Pi-hole's IP as "Local DNS server" in ```bash Home Network/Network/Network Settings/IP Adresses/IPv4 Configuration/Home Network @@ -52,20 +50,20 @@ Home Network/Network/Network Settings/IP Adresses/IPv4 Configuration/Home Networ >Note: Clients will notice changes in DHCP settings only after they acquire a new DHCP lease. The easiest way to force a renewal is to dis/reconnect the client from the network. -You should see individual clients in Pihole's web dashboard. +You should see individual clients in Pi-hole's web dashboard. ## 3) Combining 1) and 2) -You can combine 1) and 2) which will let all clients send DNS requests to your Pihole **and** the Fritz!Box itself as well. +You can combine 1) and 2) which will let all clients send DNS requests to your Pi-hole **and** the Fritz!Box itself as well. ```bash -Client (incl. Fritz!Box) -> Pihole -> Upstream DNS Server +Client (incl. Fritz!Box) -> Pi-hole -> Upstream DNS Server ``` !!! warning - Don't set the Fritz!Box as upstrem DNS server for pihole! This will lead to a DNS loop as the Pihole will send the queries to the Fritz!Box which in turn will send the to Pihole + Don't set the Fritz!Box as upstrem DNS server for Pi-hole! This will lead to a DNS loop as the Pi-hole will send the queries to the Fritz!Box which in turn will send the to Pi-hole -## Using Pihole within the Guest Network +## Using Pi-hole within the Guest Network You may have noticed, that there is no option to set the DNS server for the guest network in @@ -73,4 +71,4 @@ You may have noticed, that there is no option to set the DNS server for the gues Home Network/Network/Network Settings/IP Adresses/IPv4 Configuration/Guest Network ``` -The Fritz!Box always set its own IP as DNS server for the guest network. To filter its traffic, you have to setup Pihole as upstream DNS server for your Fritz!Box (see #1). As there is no other option, all DNS requests from your guest network will appear as coming from your Fritz!Box. +The Fritz!Box always sets its own IP as DNS server for the guest network. To filter its traffic, you have to setup Pi-hole as upstream DNS server for your Fritz!Box (see #1). As there is no other option, all DNS requests from your guest network will appear as coming from your Fritz!Box. From 5a895a6e699918a92ec11b03cabd5beacb15e60f Mon Sep 17 00:00:00 2001 From: "Kenneth (KJ) Karaisz" Date: Wed, 23 Dec 2020 17:09:39 -0500 Subject: [PATCH 044/103] It's Tor, not TOR Signed off by: Kenneth Karaisz --- mkdocs.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mkdocs.yml b/mkdocs.yml index 54da3ef..32af216 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -112,10 +112,10 @@ nav: - 'Optional: Full and DNS-only': guides/vpn/dual-VPN.md - 'Optional: Dynamic DNS': guides/vpn/dynDNS.md - 'Troubleshooting': guides/vpn/troubleshooting.md - - 'TOR & Pi-hole': + - 'Tor & Pi-hole': - 'Overview': guides/tor/overview.md - 'Basic Setup': guides/tor/setup.md - - 'Using TOR': guides/tor/using-tor.md + - 'Using Tor': guides/tor/using-tor.md - 'Performance and other issues': guides/tor/performance-issues.md - 'Using DNSSEC': guides/tor/dnssec.md - 'Community Projects': main/projects.md From a16698c547e161bebcce19589be864b490be6a54 Mon Sep 17 00:00:00 2001 From: deHakkelaar Date: Fri, 25 Dec 2020 12:11:48 +0100 Subject: [PATCH 045/103] Disable `resolvconf` for `unbound` (optional) The `unbound` package can come with a systemd service called `unbound-resolvconf.service` and default enabled (Pi-OS Buster at least). It instructs `resolvconf` to write `unbound`'s own DNS service at `nameserver 127.0.0.1` , but without the 5335 port, into the file `/etc/resolv.conf`. These added instructions allow one to use the DNS servers configured in `dhcpcd.conf` instead of the one pushed by the `unbound-resolvconf` service. --- docs/guides/unbound.md | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/docs/guides/unbound.md b/docs/guides/unbound.md index dcdd7be..6c31a52 100644 --- a/docs/guides/unbound.md +++ b/docs/guides/unbound.md @@ -160,6 +160,42 @@ Finally, configure Pi-hole to use your recursive DNS server by specifying `127.0 (don't forget to hit Return or click on `Save`) +### Disable `resolvconf` for `unbound` (optional) + +The `unbound` package can come with a systemd service called `unbound-resolvconf.service` and default enabled. +It instructs `resolvconf` to write `unbound`'s own DNS service at `nameserver 127.0.0.1` , but without the 5335 port, into the file `/etc/resolv.conf`. +That `/etc/resolv.conf` file is used by local services/processes to determine DNS servers configured. +If you configured `/etc/dhcpcd.conf` with a `static domain_name_servers=` line, these DNS server(s) will be ignored/overruled by this service. + +To check if this service is enabled for your distribution, run below one and take note of the the `Active` line. +It will show either `active` or `inactive` or it might not even be installed resulting in a `could not be found` message: + +```bash +sudo systemctl status unbound-resolvconf.service +``` + +To disable the service if so desire, run below two: + +```bash +sudo systemctl disable unbound-resolvconf.service +``` + +```bash +sudo systemctl stop unbound-resolvconf.service +``` + +To have the `domain_name_servers=` in the file `/etc/dhcpcd.conf` activated/propagate, run below one: + +```bash +sudo systemctl restart dhcpcd +``` + +And check with below one if IP(s) on the `nameserver` line(s) reflects the ones in the `/etc/dhcpcd.conf` file: + +```bash +cat /etc/resolv.conf +``` + ### Add logging to unbound !!! warning From 371168b40bceb097f207f82f5df655e86841f1ea Mon Sep 17 00:00:00 2001 From: DL6ER Date: Sat, 26 Dec 2020 10:43:38 +0100 Subject: [PATCH 046/103] Add REFRESH_HOSTNAMES=UNKNOWN documentation Signed-off-by: DL6ER --- docs/ftldns/configfile.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/ftldns/configfile.md b/docs/ftldns/configfile.md index 205faf6..3b59853 100755 --- a/docs/ftldns/configfile.md +++ b/docs/ftldns/configfile.md @@ -93,7 +93,7 @@ host name for another IP address (e.g., a DHCP server managed IPv4 address). In this case, we use the host name associated to the other address as this is the same device. -#### `REFRESH_HOSTNAMES=IPV4|ALL|NONE` (PR [#953](https://github.com/pi-hole/FTL/pull/953)) {#refresh_hostnames data-toc-label='Refresh hostnames'} +#### `REFRESH_HOSTNAMES=IPV4|ALL|UNKNOWN|NONE` (PR [#953](https://github.com/pi-hole/FTL/pull/953)) {#refresh_hostnames data-toc-label='Refresh hostnames'} With this option, you can change how (and if) hourly PTR requests are made to check for changes in client and upstream server hostnames. The following options are available: @@ -101,6 +101,8 @@ With this option, you can change how (and if) hourly PTR requests are made to ch This is the new default since Pi-hole FTL v5.3.2. It should resolve issues with more and more very short-lived PE IPv6 addresses coming up in a lot of networks. - `REFRESH_HOSTNAMES=ALL` - Do the hourly PTR lookups for all addresses This is the same as what we're doing with FTL v5.3(.1). This can create a lot of PTR queries for those with many IPv6 addresses in their networks. +- `REFRESH_HOSTNAMES=UNKNOWN` - Only resolve unknown hostnames + Already existing hostnames are never refreshedi, i.e., there will be no PTR queries made for clients where hostnames are known. This also means that known hostnames will not be updated once known. - `REFRESH_HOSTNAMES=NONE` - Don't do any hourly PTR lookups This means we look host names up exactly once (when we first see a client) and never again. You may miss future changes of host names. From 5f506852283d9688e59c7ffb698330c679166475 Mon Sep 17 00:00:00 2001 From: DL6ER Date: Sat, 26 Dec 2020 12:06:33 +0100 Subject: [PATCH 047/103] Add signals description Signed-off-by: DL6ER --- docs/ftldns/signals.md | 78 ++++++++++++++++++++++++++++++++++++++++++ mkdocs.yml | 1 + 2 files changed, 79 insertions(+) create mode 100644 docs/ftldns/signals.md diff --git a/docs/ftldns/signals.md b/docs/ftldns/signals.md new file mode 100644 index 0000000..d9f6123 --- /dev/null +++ b/docs/ftldns/signals.md @@ -0,0 +1,78 @@ +You can influence FTL by sending signals to the process. There are various signals supported to trigger specific actions, described below. + +# Reload everything using `SIGHUP` + +When FTL receives a `SIGHUP`, it clears the entire DNS cache, and then + +- Re-loads + - `/etc/hosts`, + - `/etc/ethers`, and + - any file given by + - `dhcp-hostsfile`, + - `dhcp-optsfile`, + - `dhcp-hostsdir` (files in `dhcp-hostsdir` are also re-read on change, without the need to send a signal), + - `dhcp-optsdir` (files in `dhcp-optsdir` are also re-read on change, without the need to send a signal), + - `addn-hosts`, or + - `hostsdir`. +- The DHCP lease change script is called for all existing DHCP leases. +- If `no-poll` is set, FTL also re-reads `/etc/resolv.conf`. +- The config file specified by `servers-file` is re-read. + **Note:** No other `dnsmasq` config files are re-read. + +- The FTL database connection (`/etc/pihole/pihole-FTL.db`) is re-opened. +- The privacy level is re-read from `pihole-FTL.conf` (`PRIVACY_LEVEL`). +- The blocking status is re-read from `setupVars.conf` (`BLOCKING_ENABLED`). +- The debug settings are re-read from `pihole-FTL.conf` (`DEBUG_*`). +- The gravity database connection (`/etc/pihole/gravity.db`) is re-opened. +- The number of blocked domains is updated. +- All regular expression (RegEx) filters in `gravity.db` are re-read and pre-compiled for fast execution later on. +- The blocking cache (storing if a domain has already been analyzed and what the result was) is cleared. +- If `DEBUG_CAPS` is enabled, the current set of available capabilities is logged. + +# Real-time (RT) signals + +While `SIGHUP` updates/flushes almost everything, such a massive operation is often not necessary. Hence, we added several small real-time signals available for fine-grained control of what FTL does. When you see `SIGHUP` as a "big gun", the real-time signals are rather the "scalpel" to serve rather specific needs. + +Real-time signals are not guaranteed to have the same number on all operating systems. FTL will adapt accordingly. For the signals described below, we will always specify them with the real-time signal ID and the *typical* signal number in parentheses. + +Real-time signal can always be executed relative to the first (= minimum) real-time signal just like (for real-time signal 0): + +``` bash +sudo pkill -SIGRTMIN+0 pihole-FTL +``` + +## Real-time signal 0 (SIG34) + +This signal does: + +- The gravity database connection (`/etc/pihole/gravity.db`) is re-opened. +- The number of blocked domains is updated. +- All regular expression (RegEx) filters in `gravity.db` are re-read and pre-compiled for fast execution later on. +- The blocking cache (storing if a domain has already been analyzed and what the result was) is cleared. +- The privacy level is re-read from `pihole-FTL.conf` (`PRIVACY_LEVEL`). + +The most important difference to `SIGHUP` is that the DNS cache itself is **not** flushed. Merely the blocking cache (storing if a domain has already been analyzed and what the result was) is cleared. + +This is the preferred signal to be used after manipulating the `gravity.db` database manually as it reloads only what is needed in this case. + +## Real-time signal 1 (SIG35) + +*Reserved* - Currently ignored + +## Real-time signal 2 (SIG36) + +*Reserved* - Used for internal signaling that a fork or thread crashed and needs to inform the main process to shut down, storing the last (valid) queries still into the long-term database. + +## Real-time signal 3 (SIG37) + +Reimport alias-clients from the database and recompute affected client statistics. + +## Real-time signal 4 (SIG38) + +Re-resolve all clients and forward destination hostnames. This forces refreshing hostnames as in that the usual "resolve only recently active clients" condition is ignored. The re-resolution adheres to the specified `REFRESH_HOSTNAMES` config option meaning that this option may not try to resolve all hostnames. + +## Real-time signal 5 (SIG39) + +Re-parse ARP/neighbour-cache now to update the Network table now + +{!abbreviations.md!} diff --git a/mkdocs.yml b/mkdocs.yml index 32af216..878b4ae 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -81,6 +81,7 @@ nav: - "Tutorial": ftldns/regex/tutorial.md - 'Privacy levels': ftldns/privacylevels.md - 'Telnet API': ftldns/telnet-api.md + - 'Signals': 'ftldns/signals.md' - 'Compatibility': ftldns/compatibility.md - 'Install from source': ftldns/compile.md - 'Debugging FTLDNS': ftldns/debugging.md From 591c4fdaa8487a278a0eb1a2d756b24fa3720df6 Mon Sep 17 00:00:00 2001 From: Adam Warner Date: Sat, 26 Dec 2020 22:10:53 +0000 Subject: [PATCH 048/103] Add libreadline-dev to FTL build page (#432) * Add libreadline-dev to FTL build page * Add readline-devel to fedora section Signed-off-by: Adam Warner --- docs/ftldns/compile.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/ftldns/compile.md b/docs/ftldns/compile.md index f27677f..93a464e 100644 --- a/docs/ftldns/compile.md +++ b/docs/ftldns/compile.md @@ -8,13 +8,13 @@ Install them by running the following command in a terminal: ### Debian / Ubuntu / Raspbian ```bash -sudo apt install build-essential libgmp-dev m4 cmake libidn11-dev +sudo apt install build-essential libgmp-dev m4 cmake libidn11-dev libreadline-dev ``` ### Fedora ```bash -sudo dnf install gcc gmp-devel gmp-static m4 cmake libidn-devel +sudo dnf install gcc gmp-devel gmp-static m4 cmake libidn-devel readline-devel ``` ## Compile `libnettle` from source From e72a65dfc3c88d1314b3777bb35ac827395a3ff9 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Sat, 26 Dec 2020 22:14:00 +0000 Subject: [PATCH 049/103] Bump mkdocs-git-revision-date-localized-plugin from 0.7.3 to 0.8 Bumps [mkdocs-git-revision-date-localized-plugin](https://github.com/timvink/mkdocs-git-revision-date-localized-plugin) from 0.7.3 to 0.8. - [Release notes](https://github.com/timvink/mkdocs-git-revision-date-localized-plugin/releases) - [Commits](https://github.com/timvink/mkdocs-git-revision-date-localized-plugin/compare/v0.7.3...v0.8) Signed-off-by: dependabot-preview[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 0bf3125..08379ab 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,5 @@ markdown-include==0.6.0 mkdocs==1.1.2 -mkdocs-git-revision-date-localized-plugin==0.7.3 +mkdocs-git-revision-date-localized-plugin==0.8 mkdocs-material==6.1.6 mkdocs-redirects==1.0.1 From 5c8f7e4cd51671546861503c04e6a163abb39969 Mon Sep 17 00:00:00 2001 From: seesharp Date: Tue, 29 Dec 2020 13:00:19 -0500 Subject: [PATCH 050/103] Update firewall.md --- docs/guides/vpn/firewall.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/guides/vpn/firewall.md b/docs/guides/vpn/firewall.md index 26c0886..cdedaf0 100644 --- a/docs/guides/vpn/firewall.md +++ b/docs/guides/vpn/firewall.md @@ -1,6 +1,6 @@ ### (optional) Secure the server with firewall rules (`iptables`) -**If you are behind a NAT and not running the Pi-hole on a cloud server, you do not need to issue the IPTABLES commands bellow as the firewall rules are already handled by the RoadWarrior installer, but you will need to portforward whatever port you chose in the setup from your public ip to your device using your router.** +**If you are behind a NAT and not running the Pi-hole on a cloud server, you do not need to issue the IPTABLES commands below as the firewall rules are already handled by the RoadWarrior installer, but you will need to portforward whatever port you chose in the setup from your public ip to your device using your router.** **This step is optional but recommended if you are running your server in the cloud, such as a droplet made on [Digital Ocean](https://www.digitalocean.com/?refcode=344d234950e1)**. If this is the case, you need to secure the server for your safety as well as others to prevent aiding in DDoS attacks. From 58f38b5afaab0e13d28a210d4525bca58b23f20f Mon Sep 17 00:00:00 2001 From: Eric Ma Date: Thu, 31 Dec 2020 12:28:06 -0500 Subject: [PATCH 051/103] [DOC]: Minor doc fix on update command Found that the "update" command in the elaboration was different from the "update" command in the summary table. Testing out both, I found that the summary table version was correct. Submitting this PR to fix the elaboration to match the summary table. --- docs/core/pihole-command.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/core/pihole-command.md b/docs/core/pihole-command.md index ac1167c..d1d59fd 100644 --- a/docs/core/pihole-command.md +++ b/docs/core/pihole-command.md @@ -187,7 +187,7 @@ This command will query your whitelist, blacklist, wildcards and adlists for a s | | | -------------- | -------------- -Help Command | `pihole update` +Help Command | `pihole updatePihole` Script Location | [`/opt/pihole/update.sh`](https://github.com/pi-hole/pi-hole/blob/master/advanced/Scripts/update.sh) Example Usage | `pihole -up` From 743a5439b579f5e2878ad810a42d66600b44ffec Mon Sep 17 00:00:00 2001 From: DL6ER Date: Fri, 8 Jan 2021 19:47:34 +0100 Subject: [PATCH 052/103] Improve DNS cache documentation Signed-off-by: DL6ER --- docs/ftldns/dns-cache.md | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/docs/ftldns/dns-cache.md b/docs/ftldns/dns-cache.md index 492bcf2..6871c25 100644 --- a/docs/ftldns/dns-cache.md +++ b/docs/ftldns/dns-cache.md @@ -1,15 +1,27 @@ `pihole-FTL` offers an efficient DNS cache that helps speed up your Internet experience. This DNS cache is part of the embedded `dnsmasq` server. Setting the cache size to zero disables caching. The DNS TTL value is used for determining the caching period. `pihole-FTL` clears its cache on receiving `SIGHUP`. + +!!! warning Some warning about enlarging the DNS cache size + **There is no benefit in enlarging this number *except* if the DNS cache evictions count is larger than zero.** In contrast, a larger cache *will* consume more memory on your node, leaving less memory available for other caches of your Pi-hole. If you push this number to the extremes, it may even be that your Pi-hole gets short on memory and does not operate as expected. + + ### Cache metrics The Settings page (System panel, FTL table) gives live information about the cache usage. It obtains its information from `http://pi.hole/admin/api.php?getCacheInfo`. #### DNS cache size -Size of the DNS domain cache, defaulting to 10,000 entries. You typically specify this number directly in `/etc/dnsmasq.d/01-pihole.conf`. It is the number of entries that can be actively cached at the same time. There is no benefit in enlarging this number *except* if the DNS cache evictions count is larger than zero. - +Size of the DNS domain cache, defaulting to 10,000 entries. It is the number of entries that can be actively cached at the same time. This information may also be queried using `dig +short chaos txt cachesize.bind` +The cache size is set in `/etc/dnsmasq.d/01-pihole.conf`. However, note that this setting does not survive Pi-hoel updates. If you want to change the cache size permanently, add a setting + +``` plain +CACHE_SIZE=12345 +``` + +in `/etc/pihole/setupVars.conf` and run `pihole -r` (Repair) to get the cache size changed for you automatically. + #### DNS cache insertions Number of total insertions into the cache. This number can be substantially larger than DNS cache size as expiring cache entries naturally make room for new insertions over time. Each lookup with a non-zero TTL will be cached. From 60fe21cb0cdf706430fc61086240abacf624dec3 Mon Sep 17 00:00:00 2001 From: DL6ER Date: Fri, 8 Jan 2021 19:53:49 +0100 Subject: [PATCH 053/103] Also stress that the DNS cache cannot be disabled when using DNSSEC Signed-off-by: DL6ER --- docs/ftldns/dns-cache.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/ftldns/dns-cache.md b/docs/ftldns/dns-cache.md index 6871c25..b906b35 100644 --- a/docs/ftldns/dns-cache.md +++ b/docs/ftldns/dns-cache.md @@ -1,8 +1,10 @@ `pihole-FTL` offers an efficient DNS cache that helps speed up your Internet experience. This DNS cache is part of the embedded `dnsmasq` server. Setting the cache size to zero disables caching. The DNS TTL value is used for determining the caching period. `pihole-FTL` clears its cache on receiving `SIGHUP`. -!!! warning Some warning about enlarging the DNS cache size +!!! warning Some warning about the DNS cache size **There is no benefit in enlarging this number *except* if the DNS cache evictions count is larger than zero.** In contrast, a larger cache *will* consume more memory on your node, leaving less memory available for other caches of your Pi-hole. If you push this number to the extremes, it may even be that your Pi-hole gets short on memory and does not operate as expected. + + Also, note that, because the DNSSEC validation process uses the cache, it is not permitted to reduce the cache size below `150` when DNSSEC is enabled. ### Cache metrics From 38e115dcf3963b016de64200f10c19b7198b4afb Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Sat, 9 Jan 2021 10:13:10 +0000 Subject: [PATCH 054/103] Bump linkinator from 2.8.0 to 2.13.0 Bumps [linkinator](https://github.com/JustinBeckwith/linkinator) from 2.8.0 to 2.13.0. - [Release notes](https://github.com/JustinBeckwith/linkinator/releases) - [Commits](https://github.com/JustinBeckwith/linkinator/compare/v2.8.0...v2.13.0) Signed-off-by: dependabot-preview[bot] --- package-lock.json | 510 ++++++++++++++++------------------------------ package.json | 2 +- 2 files changed, 176 insertions(+), 336 deletions(-) diff --git a/package-lock.json b/package-lock.json index c2d84fc..c791bae 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5,18 +5,18 @@ "requires": true, "dependencies": { "@babel/code-frame": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz", - "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==", + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", + "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", "dev": true, "requires": { "@babel/highlight": "^7.10.4" } }, "@babel/helper-validator-identifier": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz", - "integrity": "sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==", + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz", + "integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==", "dev": true }, "@babel/highlight": { @@ -129,12 +129,6 @@ "integrity": "sha512-fZQQafSREFyuZcdWFAExYjBiCL7AUCdgsk80iO0q4yihYYdcIiH28CcuPTGFgLOCC8RlW49GSQxdHwZP+I7CNg==", "dev": true }, - "@types/node": { - "version": "14.14.12", - "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.12.tgz", - "integrity": "sha512-ASH8OPHMNlkdjrEdmoILmzFfsJICvhBsFfAum4aKZ/9U4B6M6tTmTPh+f3ttWdD74CEGV5XvXWkbyfSdXaTd7g==", - "dev": true - }, "@types/normalize-package-data": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz", @@ -157,23 +151,6 @@ "dev": true, "requires": { "debug": "4" - }, - "dependencies": { - "debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - } } }, "ansi-align": { @@ -299,6 +276,12 @@ "fill-range": "^7.0.1" } }, + "bytes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", + "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=", + "dev": true + }, "cacheable-request": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz", @@ -359,27 +342,41 @@ } }, "cheerio": { - "version": "1.0.0-rc.3", - "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.3.tgz", - "integrity": "sha512-0td5ijfUPuubwLUu0OBoe98gZj8C/AA+RW3v67GPlGOrvxWjZmBXiBCRU+I8VEiNyJzjth40POfHiz2RB3gImA==", + "version": "1.0.0-rc.5", + "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.5.tgz", + "integrity": "sha512-yoqps/VCaZgN4pfXtenwHROTp8NG6/Hlt4Jpz2FEP0ZJQ+ZUkVDd0hAPDNKhj3nakpfPt/CNs57yEtxD1bXQiw==", "dev": true, "requires": { - "css-select": "~1.2.0", - "dom-serializer": "~0.1.1", - "entities": "~1.1.1", - "htmlparser2": "^3.9.1", - "lodash": "^4.15.0", - "parse5": "^3.0.1" + "cheerio-select-tmp": "^0.1.0", + "dom-serializer": "~1.2.0", + "domhandler": "^4.0.0", + "entities": "~2.1.0", + "htmlparser2": "^6.0.0", + "parse5": "^6.0.0", + "parse5-htmlparser2-tree-adapter": "^6.0.0" }, "dependencies": { "entities": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", - "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.1.0.tgz", + "integrity": "sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w==", "dev": true } } }, + "cheerio-select-tmp": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/cheerio-select-tmp/-/cheerio-select-tmp-0.1.1.tgz", + "integrity": "sha512-YYs5JvbpU19VYJyj+F7oYrIE2BOll1/hRU7rEy/5+v9BzkSo3bK81iAeeQEMI92vRIxz677m72UmJUiVwwgjfQ==", + "dev": true, + "requires": { + "css-select": "^3.1.2", + "css-what": "^4.0.0", + "domelementtype": "^2.1.0", + "domhandler": "^4.0.0", + "domutils": "^2.4.4" + } + }, "ci-info": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", @@ -436,6 +433,12 @@ "xdg-basedir": "^4.0.0" } }, + "content-disposition": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz", + "integrity": "sha1-DPaLud318r55YcOoUXjLhdunjLQ=", + "dev": true + }, "crypto-random-string": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz", @@ -443,30 +446,31 @@ "dev": true }, "css-select": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-1.2.0.tgz", - "integrity": "sha1-KzoRBTnFNV8c2NMUYj6HCxIeyFg=", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-3.1.2.tgz", + "integrity": "sha512-qmss1EihSuBNWNNhHjxzxSfJoFBM/lERB/Q4EnsJQQC62R2evJDW481091oAdOr9uh46/0n4nrg0It5cAnj1RA==", "dev": true, "requires": { - "boolbase": "~1.0.0", - "css-what": "2.1", - "domutils": "1.5.1", - "nth-check": "~1.0.1" + "boolbase": "^1.0.0", + "css-what": "^4.0.0", + "domhandler": "^4.0.0", + "domutils": "^2.4.3", + "nth-check": "^2.0.0" } }, "css-what": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/css-what/-/css-what-2.1.3.tgz", - "integrity": "sha512-a+EPoD+uZiNfh+5fxw2nO9QwFa6nJe2Or35fGY6Ipw1R3R4AGz1d1TEZrCegvw2YTmZ0jXirGYlzxxpYSHwpEg==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-4.0.0.tgz", + "integrity": "sha512-teijzG7kwYfNVsUh2H/YN62xW3KK9YhXEgSlbxMlcyjPNvdKJqFx5lrwlJgoFP1ZHlB89iGDlo/JyshKeRhv5A==", "dev": true }, "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", "dev": true, "requires": { - "ms": "2.0.0" + "ms": "2.1.2" } }, "decamelize": { @@ -514,18 +518,6 @@ "integrity": "sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==", "dev": true }, - "depd": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", - "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", - "dev": true - }, - "destroy": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", - "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=", - "dev": true - }, "dir-glob": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", @@ -536,46 +528,40 @@ } }, "dom-serializer": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.1.tgz", - "integrity": "sha512-l0IU0pPzLWSHBcieZbpOKgkIn3ts3vAh7ZuFyXNwJxJXk/c4Gwj9xaTJwIDVQCXawWD0qb3IzMGH5rglQaO0XA==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.2.0.tgz", + "integrity": "sha512-n6kZFH/KlCrqs/1GHMOd5i2fd/beQHuehKdWvNNffbGHTr/almdhuVvTVFb3V7fglz+nC50fFusu3lY33h12pA==", "dev": true, "requires": { - "domelementtype": "^1.3.0", - "entities": "^1.1.1" - }, - "dependencies": { - "entities": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", - "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==", - "dev": true - } + "domelementtype": "^2.0.1", + "domhandler": "^4.0.0", + "entities": "^2.0.0" } }, "domelementtype": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", - "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.1.0.tgz", + "integrity": "sha512-LsTgx/L5VpD+Q8lmsXSHW2WpA+eBlZ9HPf3erD1IoPF00/3JKHZ3BknUVA2QGDNu69ZNmyFmCWBSO45XjYKC5w==", "dev": true }, "domhandler": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz", - "integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.0.0.tgz", + "integrity": "sha512-KPTbnGQ1JeEMQyO1iYXoagsI6so/C96HZiFyByU3T6iAzpXn8EGEvct6unm1ZGoed8ByO2oirxgwxBmqKF9haA==", "dev": true, "requires": { - "domelementtype": "1" + "domelementtype": "^2.1.0" } }, "domutils": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz", - "integrity": "sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8=", + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.4.4.tgz", + "integrity": "sha512-jBC0vOsECI4OMdD0GC9mGn7NXPLb+Qt6KW1YDQzeQYRUFKmNG8lh7mO5HiELfr+lLQE7loDVI4QcAxV80HS+RA==", "dev": true, "requires": { - "dom-serializer": "0", - "domelementtype": "1" + "dom-serializer": "^1.0.1", + "domelementtype": "^2.0.1", + "domhandler": "^4.0.0" } }, "dot-prop": { @@ -593,24 +579,12 @@ "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=", "dev": true }, - "ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=", - "dev": true - }, "emoji-regex": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", "dev": true }, - "encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", - "dev": true - }, "end-of-stream": { "version": "1.4.4", "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", @@ -641,24 +615,12 @@ "integrity": "sha512-8/uIhbG12Csjy2JEW7D9pHbreaVaS/OpN3ycnyvElTdwM5n6GY6W6e2IPemfvGZeUMqZ9A/3GqIZMgKnBhAw/Q==", "dev": true }, - "escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=", - "dev": true - }, "escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", "dev": true }, - "etag": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=", - "dev": true - }, "event-target-shim": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", @@ -691,6 +653,15 @@ "picomatch": "^2.2.1" } }, + "fast-url-parser": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/fast-url-parser/-/fast-url-parser-1.1.3.tgz", + "integrity": "sha1-9K8+qfNNiicc9YrSs3WfQx8LMY0=", + "dev": true, + "requires": { + "punycode": "^1.3.2" + } + }, "fastq": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.9.0.tgz", @@ -709,21 +680,6 @@ "to-regex-range": "^5.0.1" } }, - "finalhandler": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", - "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", - "dev": true, - "requires": { - "debug": "2.6.9", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "on-finished": "~2.3.0", - "parseurl": "~1.3.3", - "statuses": "~1.5.0", - "unpipe": "~1.0.0" - } - }, "find-up": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", @@ -734,12 +690,6 @@ "path-exists": "^4.0.0" } }, - "fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=", - "dev": true - }, "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -798,12 +748,12 @@ } }, "global-dirs": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-2.0.1.tgz", - "integrity": "sha512-5HqUqdhkEovj2Of/ms3IeS/EekcO54ytHRLV4PEY2rhRwrHXLQjeVEES0Lhka0xwNDtGYn58wyC4s5+MHsOO6A==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-2.1.0.tgz", + "integrity": "sha512-MG6kdOUh/xBnyo9cJFeIKkLEc1AyFq42QTU4XiX51i2NEdxLxLWXIjEjmqKeSuKR7pAZjTqUVoT2b2huxVLgYQ==", "dev": true, "requires": { - "ini": "^1.3.5" + "ini": "1.3.7" } }, "globby": { @@ -882,25 +832,15 @@ } }, "htmlparser2": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz", - "integrity": "sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-6.0.0.tgz", + "integrity": "sha512-numTQtDZMoh78zJpaNdJ9MXb2cv5G3jwUoe3dMQODubZvLoGvTE/Ofp6sHvH8OGKcN/8A47pGLi/k58xHP/Tfw==", "dev": true, "requires": { - "domelementtype": "^1.3.1", - "domhandler": "^2.3.0", - "domutils": "^1.5.1", - "entities": "^1.1.1", - "inherits": "^2.0.1", - "readable-stream": "^3.1.1" - }, - "dependencies": { - "entities": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", - "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==", - "dev": true - } + "domelementtype": "^2.0.1", + "domhandler": "^4.0.0", + "domutils": "^2.4.4", + "entities": "^2.0.0" } }, "http-cache-semantics": { @@ -909,19 +849,6 @@ "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==", "dev": true }, - "http-errors": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.3.tgz", - "integrity": "sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw==", - "dev": true, - "requires": { - "depd": "~1.1.2", - "inherits": "2.0.4", - "setprototypeof": "1.1.1", - "statuses": ">= 1.5.0 < 2", - "toidentifier": "1.0.0" - } - }, "https-proxy-agent": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", @@ -930,23 +857,6 @@ "requires": { "agent-base": "6", "debug": "4" - }, - "dependencies": { - "debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - } } }, "ignore": { @@ -1117,9 +1027,9 @@ "dev": true }, "jsonexport": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/jsonexport/-/jsonexport-3.0.1.tgz", - "integrity": "sha512-lxDoAZxmWDt1wa4S75CUYe/ZASdmOYyhV7iYbF4npTWxrDv19ofZpJMGbt20W5Orx0hYuid65zGHpt6rRW0Z3A==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsonexport/-/jsonexport-3.1.0.tgz", + "integrity": "sha512-QekAMWAZZN263aDbA5J06U+dCwRxS+L4vCYGh5pbnI0pw4T2A0RaDWE9APOPcxvGsQcjUvfHiywvnTo/n5Bzcg==", "dev": true }, "keyv": { @@ -1162,21 +1072,20 @@ } }, "linkinator": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/linkinator/-/linkinator-2.8.0.tgz", - "integrity": "sha512-v8MtGeoJT+6RTSEKkB1IPKbv49Esmp5m0o2b4mLzULJ8oX5GFI9OPjMT4ftQ7guhQ/hLy5iDnpoE95t6gB8Plg==", + "version": "2.13.0", + "resolved": "https://registry.npmjs.org/linkinator/-/linkinator-2.13.0.tgz", + "integrity": "sha512-CSktxDpKO80fPs89x/lv8fsUv5fAljvp2kIIF+bbMG6ZN/T02K6KUlsuGm+lK1eJfcKtaopji0dPOFmRvbssmA==", "dev": true, "requires": { "chalk": "^4.0.0", - "cheerio": "^1.0.0-rc.2", - "finalhandler": "^1.1.2", + "cheerio": "^1.0.0-rc.5", "gaxios": "^4.0.0", "glob": "^7.1.6", "jsonexport": "^3.0.0", "marked": "^1.2.5", "meow": "^8.0.0", "p-queue": "^6.2.1", - "serve-static": "^1.14.1", + "serve-handler": "^6.1.3", "server-destroy": "^1.0.1", "update-notifier": "^5.0.0" } @@ -1190,12 +1099,6 @@ "p-locate": "^4.1.0" } }, - "lodash": { - "version": "4.17.20", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz", - "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==", - "dev": true - }, "lowercase-keys": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", @@ -1292,9 +1195,9 @@ "dev": true }, "marked": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/marked/-/marked-1.2.6.tgz", - "integrity": "sha512-7vVuSEZ8g/HH3hK/BH/+7u/NJj7x9VY4EHzujLDcqAQLiOUeFJYAsfSAyoWtR17lKrx7b08qyIno4lffwrzTaA==", + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/marked/-/marked-1.2.7.tgz", + "integrity": "sha512-No11hFYcXr/zkBvL6qFmAp1z6BKY3zqLMHny/JN/ey+al7qwCM2+CMBL9BOgqMxZU36fz4cCWfn2poWIf7QRXA==", "dev": true }, "mdurl": { @@ -1304,9 +1207,9 @@ "dev": true }, "meow": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/meow/-/meow-8.0.0.tgz", - "integrity": "sha512-nbsTRz2fwniJBFgUkcdISq8y/q9n9VbiHYbfwklFh5V4V2uAcxtKQkDc0yCLPM/kP0d+inZBewn3zJqewHE7kg==", + "version": "8.1.2", + "resolved": "https://registry.npmjs.org/meow/-/meow-8.1.2.tgz", + "integrity": "sha512-r85E3NdZ+mpYk1C6RjPFEMSE+s1iZMuHtsHAqY0DT3jZczl0diWUZ8g6oU7h0M9cD2EL+PzaYghhCLzR0ZNn5Q==", "dev": true, "requires": { "@types/minimist": "^1.2.0", @@ -1338,12 +1241,21 @@ "picomatch": "^2.0.5" } }, - "mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "mime-db": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.33.0.tgz", + "integrity": "sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ==", "dev": true }, + "mime-types": { + "version": "2.1.18", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.18.tgz", + "integrity": "sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==", + "dev": true, + "requires": { + "mime-db": "~1.33.0" + } + }, "mimic-response": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", @@ -1383,9 +1295,9 @@ } }, "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, "node-fetch": { @@ -1413,21 +1325,12 @@ "dev": true }, "nth-check": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.2.tgz", - "integrity": "sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.0.0.tgz", + "integrity": "sha512-i4sc/Kj8htBrAiH1viZ0TgU8Y5XqCaV/FziYK6TBczxmeKm3AEFWqqF3195yKudrarqy7Zu80Ra5dobFjn9X/Q==", "dev": true, "requires": { - "boolbase": "~1.0.0" - } - }, - "on-finished": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", - "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", - "dev": true, - "requires": { - "ee-first": "1.1.1" + "boolbase": "^1.0.0" } }, "once": { @@ -1527,20 +1430,20 @@ } }, "parse5": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-3.0.3.tgz", - "integrity": "sha512-rgO9Zg5LLLkfJF9E6CCmXlSE4UVceloys8JrFqCcHloC3usd/kJCyPDwH2SOlzix2j3xaP9sUX3e8+kvkuleAA==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", + "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==", + "dev": true + }, + "parse5-htmlparser2-tree-adapter": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-6.0.1.tgz", + "integrity": "sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA==", "dev": true, "requires": { - "@types/node": "*" + "parse5": "^6.0.1" } }, - "parseurl": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", - "dev": true - }, "path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -1553,12 +1456,24 @@ "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", "dev": true }, + "path-is-inside": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", + "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", + "dev": true + }, "path-parse": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", "dev": true }, + "path-to-regexp": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-2.2.1.tgz", + "integrity": "sha512-gu9bD6Ta5bwGrrU8muHzVOBFFREpp2iRkVfhBJahwJ6p6Xw20SjT0MxLnwkjOibQmGSYhiUnf2FLe7k+jcFmGQ==", + "dev": true + }, "path-type": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", @@ -1587,6 +1502,12 @@ "once": "^1.3.1" } }, + "punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", + "dev": true + }, "pupa": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/pupa/-/pupa-2.1.1.tgz", @@ -1603,9 +1524,9 @@ "dev": true }, "range-parser": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz", + "integrity": "sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4=", "dev": true }, "rc": { @@ -1683,17 +1604,6 @@ } } }, - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - }, "redent": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", @@ -1753,12 +1663,6 @@ "integrity": "sha512-zb/1OuZ6flOlH6tQyMPUrE3x3Ulxjlo9WIVXR4yVYi4H9UXQaeIsPbLn2R3O3vQCnDKkAl2qHiuocKKX4Tz/Sw==", "dev": true }, - "safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true - }, "semver": { "version": "7.3.4", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz", @@ -1785,45 +1689,20 @@ } } }, - "send": { - "version": "0.17.1", - "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", - "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==", + "serve-handler": { + "version": "6.1.3", + "resolved": "https://registry.npmjs.org/serve-handler/-/serve-handler-6.1.3.tgz", + "integrity": "sha512-FosMqFBNrLyeiIDvP1zgO6YoTzFYHxLDEIavhlmQ+knB2Z7l1t+kGLHkZIDN7UVWqQAmKI3D20A6F6jo3nDd4w==", "dev": true, "requires": { - "debug": "2.6.9", - "depd": "~1.1.2", - "destroy": "~1.0.4", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "fresh": "0.5.2", - "http-errors": "~1.7.2", - "mime": "1.6.0", - "ms": "2.1.1", - "on-finished": "~2.3.0", - "range-parser": "~1.2.1", - "statuses": "~1.5.0" - }, - "dependencies": { - "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", - "dev": true - } - } - }, - "serve-static": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz", - "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==", - "dev": true, - "requires": { - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "parseurl": "~1.3.3", - "send": "0.17.1" + "bytes": "3.0.0", + "content-disposition": "0.5.2", + "fast-url-parser": "1.1.3", + "mime-types": "2.1.18", + "minimatch": "3.0.4", + "path-is-inside": "1.0.2", + "path-to-regexp": "2.2.1", + "range-parser": "1.2.0" } }, "server-destroy": { @@ -1832,12 +1711,6 @@ "integrity": "sha1-8Tv5KOQrnD55OD5hzDmYtdFObN0=", "dev": true }, - "setprototypeof": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", - "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==", - "dev": true - }, "signal-exit": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", @@ -1888,12 +1761,6 @@ "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", "dev": true }, - "statuses": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", - "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", - "dev": true - }, "string-width": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", @@ -1934,15 +1801,6 @@ } } }, - "string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dev": true, - "requires": { - "safe-buffer": "~5.2.0" - } - }, "strip-ansi": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", @@ -1997,12 +1855,6 @@ "is-number": "^7.0.0" } }, - "toidentifier": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", - "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==", - "dev": true - }, "trim-newlines": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.0.tgz", @@ -2039,12 +1891,6 @@ "crypto-random-string": "^2.0.0" } }, - "unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", - "dev": true - }, "update-notifier": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-5.0.1.tgz", @@ -2076,12 +1922,6 @@ "prepend-http": "^2.0.0" } }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", - "dev": true - }, "validate-npm-package-license": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", diff --git a/package.json b/package.json index 5f7d877..8636004 100644 --- a/package.json +++ b/package.json @@ -22,7 +22,7 @@ "test": "npm run markdownlint && npm run linkinator" }, "devDependencies": { - "linkinator": "^2.8.0", + "linkinator": "^2.13.0", "markdownlint-cli2": "0.0.11" } } From 9bd7fa9861c3850c8ddc491c8ef4b85dc1c48b53 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Sat, 9 Jan 2021 11:17:20 +0000 Subject: [PATCH 055/103] Bump markdownlint-cli2 from 0.0.11 to 0.0.13 Bumps [markdownlint-cli2](https://github.com/DavidAnson/markdownlint-cli2) from 0.0.11 to 0.0.13. - [Release notes](https://github.com/DavidAnson/markdownlint-cli2/releases) - [Commits](https://github.com/DavidAnson/markdownlint-cli2/compare/v0.0.11...v0.0.13) Signed-off-by: dependabot-preview[bot] --- package-lock.json | 91 +++++++++++++++++++++-------------------------- package.json | 2 +- 2 files changed, 42 insertions(+), 51 deletions(-) diff --git a/package-lock.json b/package-lock.json index c791bae..a93e124 100644 --- a/package-lock.json +++ b/package-lock.json @@ -83,28 +83,28 @@ } }, "@nodelib/fs.scandir": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.3.tgz", - "integrity": "sha512-eGmwYQn3gxo4r7jdQnkrrN6bY478C3P+a/y72IJukF8LjB6ZHeB3c+Ehacj3sYeSmUXGlnA67/PmbM9CVwL7Dw==", + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.4.tgz", + "integrity": "sha512-33g3pMJk3bg5nXbL/+CY6I2eJDzZAni49PfJnL5fghPTggPvBd/pFNSgJsdAgWptuFu7qq/ERvOYFlhvsLTCKA==", "dev": true, "requires": { - "@nodelib/fs.stat": "2.0.3", + "@nodelib/fs.stat": "2.0.4", "run-parallel": "^1.1.9" } }, "@nodelib/fs.stat": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.3.tgz", - "integrity": "sha512-bQBFruR2TAwoevBEd/NWMoAAtNGzTRgdrqnYCc7dhzfoNvqPzLyqlEQnzZ3kVnNrSp25iyxE00/3h2fqGAGArA==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.4.tgz", + "integrity": "sha512-IYlHJA0clt2+Vg7bccq+TzRdJvv19c2INqBSsoOLp1je7xjtr7J26+WXR72MCdvU9q1qTzIWDfhMf+DRvQJK4Q==", "dev": true }, "@nodelib/fs.walk": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.4.tgz", - "integrity": "sha512-1V9XOY4rDW0rehzbrcqAmHnz8e7SKvX27gh8Gt2WgB0+pdzdiLV83p72kZPU+jvMbS1qU5mauP2iOvO8rhmurQ==", + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.6.tgz", + "integrity": "sha512-8Broas6vTtW4GIXTAHDoE32hnN2M5ykgCpWGbuXHQ15vEMqr23pB76e/GZcYsZCHALv50ktd24qhEyKr6wBtow==", "dev": true, "requires": { - "@nodelib/fs.scandir": "2.1.3", + "@nodelib/fs.scandir": "2.1.4", "fastq": "^1.6.0" } }, @@ -191,13 +191,10 @@ } }, "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "requires": { - "sprintf-js": "~1.0.2" - } + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true }, "array-union": { "version": "2.1.0", @@ -663,9 +660,9 @@ } }, "fastq": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.9.0.tgz", - "integrity": "sha512-i7FVWL8HhVY+CTkwFxkN2mk3h+787ixS5S63eb78diVRc1MCssarHq3W5cj0av7YDSwmaV928RNag+U1etRQ7w==", + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.10.0.tgz", + "integrity": "sha512-NL2Qc5L3iQEsyYzweq7qfgy5OtXCmGzGvhElGEd/SoFWEMOEczNh5s5ocaF01HDetxz+p8ecjNPA6cZxxIHmzA==", "dev": true, "requires": { "reusify": "^1.0.4" @@ -757,9 +754,9 @@ } }, "globby": { - "version": "11.0.1", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.1.tgz", - "integrity": "sha512-iH9RmgwCmUJHi2z5o2l3eTtGBtXek1OYlHrbcxOYugyHLmAsZrPj43OtHThd62Buh/Vv6VyCBD2bdyWcGNQqoQ==", + "version": "11.0.2", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.2.tgz", + "integrity": "sha512-2ZThXDvvV8fYFRVIxnrMQBipZQDr7MxKAmQK1vujaj9/7eF0efG7BPUKJ7jP7G5SLF37xKDXvO4S/KKLj/Z0og==", "dev": true, "requires": { "array-union": "^2.1.0", @@ -1138,12 +1135,12 @@ "dev": true }, "markdown-it": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-11.0.0.tgz", - "integrity": "sha512-+CvOnmbSubmQFSA9dKz1BRiaSMV7rhexl3sngKqFyXSagoA3fBdJQ8oZWtRy2knXdpDXaBw44euz37DeJQ9asg==", + "version": "12.0.2", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-12.0.2.tgz", + "integrity": "sha512-4Lkvjbv2kK+moL9TbeV+6/NHx+1Q+R/NIdUlFlkqkkzUcTod4uiyTJRiBidKR9qXSdkNFkgv+AELY8KN9vSgVA==", "dev": true, "requires": { - "argparse": "^1.0.7", + "argparse": "^2.0.1", "entities": "~2.0.0", "linkify-it": "^3.0.1", "mdurl": "^1.0.1", @@ -1151,24 +1148,24 @@ } }, "markdownlint": { - "version": "0.21.1", - "resolved": "https://registry.npmjs.org/markdownlint/-/markdownlint-0.21.1.tgz", - "integrity": "sha512-8kc88w5dyEzlmOWIElp8J17qBgzouOQfJ0LhCcpBFrwgyYK6JTKvILsk4FCEkiNqHkTxwxopT2RS2DYb/10qqg==", + "version": "0.22.0", + "resolved": "https://registry.npmjs.org/markdownlint/-/markdownlint-0.22.0.tgz", + "integrity": "sha512-J4B+iMc12pOdp/wfYi03W2qfAfEyiZzq3qvQh/8vOMNU8vXYY6Jg440EY7dWTBCqROhb1i4nAn3BTByJ5kdx1w==", "dev": true, "requires": { - "markdown-it": "11.0.0" + "markdown-it": "12.0.2" } }, "markdownlint-cli2": { - "version": "0.0.11", - "resolved": "https://registry.npmjs.org/markdownlint-cli2/-/markdownlint-cli2-0.0.11.tgz", - "integrity": "sha512-+dwVrLo2sisB8OJE8vdT+gTQCOuaYFJsYKKfh1fnkHedSMxVrX6XMID5kUKI7iSq6GICugPnS5kjjVwCbe01vg==", + "version": "0.0.13", + "resolved": "https://registry.npmjs.org/markdownlint-cli2/-/markdownlint-cli2-0.0.13.tgz", + "integrity": "sha512-Fg4bIf70vPW9CHHBE6wkL5TYwOF/bQ7XQ+VGXLws5TTgP8voaeVmF085TkyWYOSippWRU+Ify1VkMw1S0VlbwA==", "dev": true, "requires": { "globby": "~11.0.1", - "markdownlint": "~0.21.1", - "markdownlint-cli2-formatter-default": "~0.0.1", - "markdownlint-rule-helpers": "~0.12.0", + "markdownlint": "~0.22.0", + "markdownlint-cli2-formatter-default": "~0.0.2", + "markdownlint-rule-helpers": "~0.13.0", "micromatch": "~4.0.2", "strip-json-comments": "~3.1.1", "yaml": "~1.10.0" @@ -1183,15 +1180,15 @@ } }, "markdownlint-cli2-formatter-default": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/markdownlint-cli2-formatter-default/-/markdownlint-cli2-formatter-default-0.0.1.tgz", - "integrity": "sha512-JvWhlus5zR4cFywXB2RSPVX73YD9177xm9WkV/8CRPDS1MM/Fh6Ds0WnY67ZaiITavZ0H+Fgz1aVhUwrPNa7ug==", + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/markdownlint-cli2-formatter-default/-/markdownlint-cli2-formatter-default-0.0.2.tgz", + "integrity": "sha512-jIz1X3SIC8sX4NDFqQFUXL+JEtfnDoN4i+xocEu+etcxGX455pHb6sx86f/yVk4mKJ2o7aNe2ydSx9an22BfBg==", "dev": true }, "markdownlint-rule-helpers": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/markdownlint-rule-helpers/-/markdownlint-rule-helpers-0.12.0.tgz", - "integrity": "sha512-Q7qfAk+AJvx82ZY52OByC4yjoQYryOZt6D8TKrZJIwCfhZvcj8vCQNuwDqILushtDBTvGFmUPq+uhOb1KIMi6A==", + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/markdownlint-rule-helpers/-/markdownlint-rule-helpers-0.13.0.tgz", + "integrity": "sha512-rRY0itbcHG4e+ntz0bbY3AIceSJMKS0TafEMgEtKVHRZ54/JUSy6/4ypCL618RlJvYRej+xMLxX5nkJqIeTZaQ==", "dev": true }, "marked": { @@ -1755,12 +1752,6 @@ "integrity": "sha512-U+MTEOO0AiDzxwFvoa4JVnMV6mZlJKk2sBLt90s7G0Gd0Mlknc7kxEn3nuDPNZRta7O2uy8oLcZLVT+4sqNZHQ==", "dev": true }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", - "dev": true - }, "string-width": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", diff --git a/package.json b/package.json index 8636004..a45d561 100644 --- a/package.json +++ b/package.json @@ -23,6 +23,6 @@ }, "devDependencies": { "linkinator": "^2.13.0", - "markdownlint-cli2": "0.0.11" + "markdownlint-cli2": "0.0.13" } } From 8c634012e77a51cc7a57a3ca145788de89b70600 Mon Sep 17 00:00:00 2001 From: DL6ER Date: Sat, 9 Jan 2021 07:53:48 +0100 Subject: [PATCH 056/103] Apply suggestions from code review Signed-off-by: DL6ER Co-authored-by: Dan Schaper --- docs/ftldns/dns-cache.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/docs/ftldns/dns-cache.md b/docs/ftldns/dns-cache.md index b906b35..d078973 100644 --- a/docs/ftldns/dns-cache.md +++ b/docs/ftldns/dns-cache.md @@ -2,9 +2,11 @@ !!! warning Some warning about the DNS cache size - **There is no benefit in enlarging this number *except* if the DNS cache evictions count is larger than zero.** In contrast, a larger cache *will* consume more memory on your node, leaving less memory available for other caches of your Pi-hole. If you push this number to the extremes, it may even be that your Pi-hole gets short on memory and does not operate as expected. + **There is no benefit in increasing this number *unless* the number of DNS cache evictions is greater than zero.** - Also, note that, because the DNSSEC validation process uses the cache, it is not permitted to reduce the cache size below `150` when DNSSEC is enabled. + A larger cache *will* consume more memory on your node, leaving less memory available for other caches of your Pi-hole. If you push this number to the extremes, it may even be that your Pi-hole gets short on memory and does not operate as expected. + + You can not reduce the cache size below `150` when DNSSEC is enabled because the DNSSEC validation process uses the cache. ### Cache metrics @@ -16,7 +18,7 @@ The Settings page (System panel, FTL table) gives live information about the cac Size of the DNS domain cache, defaulting to 10,000 entries. It is the number of entries that can be actively cached at the same time. This information may also be queried using `dig +short chaos txt cachesize.bind` -The cache size is set in `/etc/dnsmasq.d/01-pihole.conf`. However, note that this setting does not survive Pi-hoel updates. If you want to change the cache size permanently, add a setting +The cache size is set in `/etc/dnsmasq.d/01-pihole.conf`. However, note that this setting does not survive Pi-hole updates. If you want to change the cache size permanently, add a setting ``` plain CACHE_SIZE=12345 From 835281e421883a09269952efc8cbb0ea8e83fbb9 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Sat, 9 Jan 2021 12:16:53 +0000 Subject: [PATCH 057/103] Bump mkdocs-material from 6.1.6 to 6.2.3 Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 6.1.6 to 6.2.3. - [Release notes](https://github.com/squidfunk/mkdocs-material/releases) - [Changelog](https://github.com/squidfunk/mkdocs-material/blob/master/docs/changelog.md) - [Commits](https://github.com/squidfunk/mkdocs-material/compare/6.1.6...6.2.3) Signed-off-by: dependabot-preview[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 08379ab..1014620 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,5 @@ markdown-include==0.6.0 mkdocs==1.1.2 mkdocs-git-revision-date-localized-plugin==0.8 -mkdocs-material==6.1.6 +mkdocs-material==6.2.3 mkdocs-redirects==1.0.1 From 49482464a9ecf9964eae35c4a2e8d52afbd939c2 Mon Sep 17 00:00:00 2001 From: yubiuser Date: Sun, 10 Jan 2021 20:54:04 +0100 Subject: [PATCH 058/103] Rewrote German guide and added section about conditional forwarding Signed-off-by: yubiuser --- docs/images/conditional-forwarding.png | Bin 0 -> 5751 bytes docs/routers/fritzbox-de.md | 80 +++++++++++++------------ 2 files changed, 43 insertions(+), 37 deletions(-) create mode 100644 docs/images/conditional-forwarding.png diff --git a/docs/images/conditional-forwarding.png b/docs/images/conditional-forwarding.png new file mode 100644 index 0000000000000000000000000000000000000000..27e7eeb2aebe413525aa77be4724419f88376e96 GIT binary patch literal 5751 zcmai22T)V(wgm-2q^O8=6p*5X-lTWwAf2EoS}U<}lD5zL4FHF;3V!YK_Mf38YkqS2od95%JTn%j1I}GY z{s}Aqz(Nk#=cPKZSNl{_2Uy4jaFxG~fff(RDFEm=0tUj>fYIn@A!y)u6~I;lKxa7) zh`?N4;(GVT3e_aUfa8|ER{!{}jV+YZdaHRPlXQogKTedH)iT&&nh zT~jSGqznI4BV0~ZKSD!8M9SMo{%{c&@4_uOBA~ z&H)blm9=b+7Hd(?l4yQo%@?nok$)iOFFw3Bd#2_wg$KZXH8uvS7w8CMdG8l-9YB}A zq>{O|te0ECn1bG`h6A8{;*X9~!tnZeQJ~G~#-xSJ%OTNFQ89~2WC%1Ad5UfG(UH*y z!vSExw{~H*GirbDp#HUTeV8@UR-)NY%R^RFJEE@~D(RB;Em#9upWswkSvg_n9eoeXNsX^3MR_g@YB@!NTl|h z_Dd|x96yB$Yg#-6PHc2T*1C(549zN+0UP&hn@{6|Io6mWzfj8no7X;zbz!)vVQm>p zUzqtoZGHdqPoFTG(H|NyKHZb$SkL;6%G$T5M|k=4;bY*>Tu<{MGHN7oqNHK;55flx zsf|Sy*Os=le?zKSVA&t0S^7V`%?r2)Dr5-3WmNvw-A8tJ#byytMiol z>l|D5?(}2kTOkb3^TbHwE!&c5c!?@pY1oVQ2}X{TwP(sTl1THlM>{qXq%g?4@ad5U z-Br~wlCq42UV@oVg<8_%Dpy!Be8TS$^h$%@`NV(%3qL&k-Lf%0=7 zqPcs8u3`|?lhz8VM+I*V7F5m)d|$xO1Y1S-C4CZ&WXO=x57Bcw8DNWNau1nF)PX1B^HQRUAg?{^nR2)meqUOiuM zw8D7(!XA%F_(=nO_wog&iGr9LhgX8QTvE04!oGn_#7rd9ltuhq#<{)uSpjq#XY|Nt ztC_5weHnU(!|b@M(=fluk2HtF3Mur*oa68B7`K{E+J42tAM>V1S*XD2zYdAM_4;sz z{1ylI3~nSQr7SGn|E1X2v6w-rWl;6;a$HuWh@-?a8G(3E#DEU^PT$lYvNgxevoOOK zP#S=AcB~aYelnl&vhwpZqq*Cp5RZ~;Qv_6h!{zvKc~DKIOSt|n0uBBc_BYqqiqJcX zE3&{CK7WOWw%r#!r{|Hzcn!2vQE!0$C}cE>2OnP<=4Y@xSY~>+4WfyrJ#pW8wrn-n ziW_(KXeq}~id&cL>ia{cDbv_>b=aunf<4J()76(YyUHylZ)l5uM>*dh22WT~(sMI{ z_;YW8$rDgquJ6}t@?e{fELn!zU~aroOg-G`oL$c4amjKGVvDu%l#IAEx{z%(liyM$lY#7w2@sy zA-VPg=3$E0oLCd|-M7yu6!kTcz7mtxYK=tWbVWXrTi5I~bkeaK^KKd9r;J{KZ+>YoI`9yWbIxxlNubp zy`@p8p2VN#8CAC%P2o`S;t~aafC8CZ=c$m*8ombQpgjnjp5=aT`~|(SIW=}r^;l*P z)_jMxYN;d>!PSYwp6K+Z5u3{Wsa4|;@$4%C4mQ*O z=<=(kk5Ps%C@5rz2oa%^eXCl+e{Gm7nLz2m&)_4;_Sc~F%rTtu{|x_+S~Bb}xN6?b zB$(%;Oo%m@Ww1p)Lqz=>!_Ed<9T&4x&!*Z;kmN!jlYV7Ee=H{?ziO|QiyVdhaZEok za+aFLNN4(NwKG&QcvN(8UfS8|3q|W!K{5ErWi7kSNlK;+6Fk6#Hn~XDRFXw`+|Y9% zw)s_!shQlPh}JdV;RQJF==+4-o(JHRm@STTIu^9^b4K$IrSoMIH8tNJXZ!P$n}fsN zOeZYfvcin_uNe6|&^mAw{s2oUvWX#V8BVdv;87f+FqAj{2zMKlSgNQMj2J3OM7@_L z4k90LH@hImG1`L7B&6X1MzqP2p+CvciDB4@8?jiDZg<=f1)TqsUTO0UHCp#+w~|Z4 zcr48Bv$-37qx2CS{B57mvHzApW(~i`SQ`a3I$a4Y;#>B^~^Yc|r;C8w>jBI1aMCC&F4#bj|m}r8*H>PO+SZf04N% z(S=`%<@&f@*Tgi$VbHXbt!_zt*H{&K5TUZ;2jUC9M21EF>3W;cL-U&dN`2d<-D5Bz z27*lb8z!Z)*WP}2bF^wV*;c{hO5Bb3%7PW!3Am`x0e%kmU7o+VWmS#J;E|se$}ITk zz#-G-d5a<<7`(~l`Dq*i=HFtgDT0)MofEMA8I%IFRl|GnWe}Q!358l6drs)}*W35G zelt$jeXc29--HPjh7wIkH1}%aClE#U;&)p&jBK?cVVT&{9tcx@1G$q!L(T!O%+d)) zrWhX)pc9FRmW{zgd9i4wYI>*gKzbgvWbnj&06!f&p?KN*&?_hszB!8b8)ST_mXL%c zMvfH|rML+Gpg-Nr<>s}n)+)<{>Ap3tUvB56tnw5$!LBu+CCJ-rG0Kf}#8mAwJ52a9(EG5TEtR!s`S<#N|QfpqfvIVTJiksE*Oh zGkysD&rX#nnLB1}k#V0)E&B7*=_uQbr}@TCPTd??jg(Br%v0yK+v42|OK0k3isz@t zTZm5S%P2OC^7Gz$*EozdO5r^pDx^Oi5E_#gffHI8v$n18GsDHJMm4{_hNqz}#$%pm zbD4O3#TP`A@rJAwW1u592P1O%Z%j?aS&*W9Gz0xJFK@bs%rIPwFy^y}#I>QIyH1 zWfJYzlL=>pYn|ve$O^wheKS*MAb}U(FWqmKxP{vL@>rGUYBe`YZ0qiMX}(*U-lFE? z-E$3s+$u;Vfv=*@1mF9o%8d=5oD;CtGhF*a z<-|Z&Iw7YBM+{WeJn#WAKXzgOIf2)nF2M87>k$O(|g z8ghegcPfvHY-JG~=$K|#Fg|n+PVZx|oo00>r?Y87qkIXgq7?pKxM-$unFIU&;`=wU z->~GH*oT_t7`OVRu0_}?!Uw~Doy2U@Az*vr4N|PJZ}bd$@dm5YpqUmQk)UyOTly_D zQ|OV_cbEuV^vEegerQzKQH;((mTo^}o@>O$M>!iN(-jBmHK`JsM|TQUIzasMO=B6L4Y)lhN;9_lwX*eRB_~9mG#F|P zo^k%x+A!O;B=iU)ZL;`n{>yn=C5qk7Z%`9%W5);zzZ*mZr={u>3c!C=?dY_!fRN)< zEnGVAj~}G6RweV5!jYXYa$~i6XaF|}od#Q%39$2!?TA}$dYJt*4 zNx$;EzTBP(#vw4Zy`H3+{UL1)G0YV_6Lc&fH_}=|f-akm(-y_Od-{~2bpr+&5Vh$~ zm3dtBTPO^+9h5wde-lnb*L^*60#9^^hiE+E z+HQ@R2+M$LAh~tMv?$x@&jU8(T-Eoroy6WB+*6ii)!a5GWn?TBlUxx za%#@VFRD`_C-SpvdJIAJs)vphdaBfWic?ldZKRz z<4MRqZr;02%V-9)y2DSD8$Y~w;ftvmYj@^^AoAu=TF!1;Ici`J1}8&_4IMk#lk}9a zS-OtzVUw#tZ&B+avvx^bIMsM%c&sOhf!KL-88~5PmC}ocSmjwu)+ZFX0xeQf<|3kc zNg8wn$*8dL9l+6Pn>nO8F`xrOH4Ww;nRt6y*1gO1S5N(vlSkcst&^iV*E>&Y#lURc zHu00+?z&0N^H(Nk-g zaqVG~;QY7X;2YZ+MwKBP;=TJly+UQEvNvtq*UYAwb6CH>RBWc2$Si`zZdGvy^-(*|;FagMj$cq|esI^CydUC+(-AYA(<-!EPN{ln z3ukp%Yit2&d{wi8N4gIa>h9(JynVJzo=<%PjqNA2(!F4u{5q~APWZ9QKuCG*S^dT! zhyR}ns%NVv&E#>7ws9Dwy#xXJcWDNU?evl4g9&h|B$uhOv$%O_evjnaUO`Ob>W}O{ z15f5TrFusRC*-(BcB+eYA8a1*o)B;2j^#T(3acl2)v-R(oz;C6Z#jsd_1T=d5g(i= zSb0qWA3yO7EU+nM=lJR5NZ?hZr8eThO|(JQG!gjnI|=Me`J#MHo07xr=j%I3+e}=q zGX4Q@lFU!WsxkfG7OwE&^jK9D;)Y86CI(ih|IM!b9sa|d!IS^8W(5D{($cR^Zjdcz zat-@y1A@bUJH0D=_n%hozwuZ0juUD|q^3;i7{^(y91@p~?F*jKiS1H|A18wM$#MT} z7yrfd|7X}g@TqP`s9y)TZf=kHH)FyAB?foW{u?=WrysfX0OmYU7-YG|!s_+9cf7R4 z;wZS!k!D=vRM8~A@6gq9mn~TC&%#zk1hf!C+^BVzaYo6E&~YZld&j6w*z@Owy^{83 z$&fy02-c19$1+T!LfcTgDu78lGvV@ysm1>1JF~7*ULyYHFT%FgWpMt3q@(#&=`)r& zO^~V#TWzNqm{Zfhkw8`Bi;2=VwY6Jpjehj9J#w%4eBI2ag?<0DQgt|rMTAke?=?_3 z?jf@d3ri|b1}#a@&{K)mXA?-G^msFHz)Z>3DT2av!4%C^da(E;#e%25AZzl9`HbMw zC5meEzFomOlEz|I;Kzr$H=?Yd#K~MvLG+-<8>)Vu?6+q9R4Rz0lfa>=#D$?H&;tL` z{z$5;n9F#(dBAqspV5y)X;#%qx0vE9C5+m6veLe!&(8nYt!;LqjfGCSVpCXLhsf?L zh-~{OkA2@Dp*`~vHuBc@&k67NF@JQbv&jq2DvpuC6G@6(lsaQ7G@toe= zhdyTwkwrpg#w7W@5-zefj-%lu;ySm{OTwS~FhasD?Z_Vm^r5SC>z1}6p|D4E-g&KG z*(8Nbvn_(u?oBzChO8nEU0y^>M3~!Vbih5n;6?46@&{al2e18c3chtxcaag~znx?* ziH@}q6#af_2Msf2DOS+-hG*O%hmS?xd5Q+RjIZ+F+7~%7Q+xCs*0MrCztd7@*R_eK zND^IcYhaxl7zrJo#pt3QVwdgPm@Bd9!l7Tx+Jnz}hXXw{g*ZWciGI(MyWDGl()H<` z*`3(TC$$Y(V|eol8Aa0-_Lj?EozzKBwwHdXNwymoG|XtCv(@XJ@?9q@A997O;Ib`6 zX0ti?I++f0kJn{pPuP`hf(l2o>v$r z^Uq*dv=3e-lETI1*AC1%CuiQYn+`7^ioj?l_!Gv=T5>a~awp6adTagPF`t28o zQkw@ia4-7Z3vOP@Jd0>x{+BrXQzQP*m)`+s$>MiIns3A=2a9@`C`+})P0733A)tKr z5u#q9ze9HPUlSt`J9 Fritz!Box -> Pi-hole -> Upstream DNS Server -``` - -Zum Einstellen muss die IP des Pi-hole als "Bevorzugter DNS-Server" **und** "Alternativer DNS-Server" in - -```bash -Internet/Zugangsdaten/DNS-Server -``` - -![Screenshot der Fritz!Box WAN DNS Konfiguration](../images/fritzbox-wan-dns-de.png) - -eingetragen werden. - -!!! warning - Die Fritz!Box darf nicht als upstream DNS Server im Pi-hole eingestellt werden. Dies würde zu einem DNS Loop führen, da Pi-hole dann die Anfragen an die Fritz!Box senden würde, welche sie wiederum an Pi-hole senden würde. - -Mit dieser Konfiguration sind im Pi-hole Dashboard keine individuellen Clients sichtbar. Für Pi-hole scheinen alle Anfragen von der Fritz!Box zu kommen. Dadurch können nicht alle Funktionen von Pi-hole genutzt werden, z.B. die Möglichkeit, Clients individuell zu filtern (Group Management). Wenn dies gewünscht ist, muss die Konfiguration #2 verwendet werden. - - -## 2) Pi-hole als DNS Server via DHCP an Clients verteilen (LAN Seite) - -Mit dieser Konfiguration wird allen Clients die IP des Pi-hole als DNS Server angeboten, wenn sie einen DHCP Lease vom der Fritz!Box anfordern. +Mit dieser Konfiguration wird allen Clients die IP des Pi-hole als DNS Server angeboten, wenn sie einen DHCP Lease von der Fritz!Box anfordern. DNS Anfragen nehmen folgenden Weg ```bash @@ -38,7 +14,7 @@ Client -> Pi-hole -> Upstream DNS Server ``` > Hinweis: -Die Fritz!Box selbst wird den unter Internet/Zugangsdaten/DNS-Server eingestellten DNS Server nutzen. +Die Fritz!Box selbst wird den unter Internet/Zugangsdaten/DNS-Server eingestellten DNS Server nutzen (siehe unten). Die Fritz!Box kann der Upstream Server von Pi-hole sein, solange Pi-hole nicht der Upstream Server der Fritz!Box ist. Dies würde zu einem DNS Loop führen. Um diese Konfiguration zu nutzen, muss die IP des Pi-hole als "Lokaler DNS-Server" in @@ -47,27 +23,39 @@ Um diese Konfiguration zu nutzen, muss die IP des Pi-hole als "Lokaler DNS-Serve Heimnetz/Netzwerk/Netzwerkeinstellungen/IP-Adressen/IPv4-Konfiguration/Heimnetz ``` -![Screenshot der Fritz!Box DHCP Einstellungen](../images/fritzbox-dhcp-de.png) - eingetragen werden. +![Screenshot der Fritz!Box DHCP Einstellungen](../images/fritzbox-dhcp-de.png) + >Hinweis: Clients bemerken Änderungen an den DHCP Einstellungen erst, wenn der DHCP Lease erneuert wird. Der einfachste Weg dies zu erzwingen ist ein Unterbrechen und Wiederherstellen der Netzwerkverbindung. -Nun sollen einzelne Clients in Pi-hole Dashboard auftrauchen. +Nun sollten einzelne Clients in Pi-hole Dashboard auftrauchen. -## 3) Kombination aus 1) und 2) +## Pi-hole als Upstream DNS Server der Fritz!Box (WAN Seite) -Durch die Kombination von 1) und 2) senden alle Clients und die Fritz!Box selbst DNS Anfragen direkt an Pi-hole. +Mit dieser Konfiguration wird Pi-hole auch von der Fritz!Box selbst als Upstream DNS Server genutzt. DNS Anfragen nehmen folgenden Weg ```bash -Client (incl. Fritz!Box) -> Pi-hole -> Upstream DNS Server +(Clients) -> Fritz!Box -> Pi-hole -> Upstream DNS Server ``` -!!! warning - Die Fritz!Box darf nicht als Upstream DNS Server des Pi-hole gesetzt werden. Dies würde zu einem DNS Loop führen, da Pi-hole die Anfragen an die Fritz!Box senden würde, welche sie wiederum an Pi-hole weitergeben würde. +Zum Einstellen muss die IP des Pi-hole als "Bevorzugter DNS-Server" **und** "Alternativer DNS-Server" in -## Pi-hole im Gastnetzwerk nutzen +```bash +Internet/Zugangsdaten/DNS-Server +``` + +eingetragen werden. + +![Screenshot der Fritz!Box WAN DNS Konfiguration](../images/fritzbox-wan-dns-de.png) + +!!! warning + Die Fritz!Box darf mit dieser Konfiguration nicht als Upstream DNS Server im Pi-hole eingestellt werden. Dies würde zu einem DNS Loop führen, da Pi-hole dann die Anfragen an die Fritz!Box senden würde, welche sie wiederum an Pi-hole senden würde. + +Wird ausschließlich diese Konfiguration genutz, sind im Pi-hole Dashboard keine individuellen Clients sichtbar. Für Pi-hole scheinen alle Anfragen von der Fritz!Box zu kommen. Dadurch können nicht alle Funktionen von Pi-hole genutzt werden, z.B. die Möglichkeit, Clients individuell zu filtern (Group Management). Wenn dies gewünscht ist, muss Pi-hole (zusätzlich) als DNS Server via DHCP an die Clients verteilt werden (siehe oben). + +### Pi-hole im Gastnetzwerk nutzen Es gibt in der Fritz!Box keine Möglichkeit unter @@ -77,4 +65,22 @@ Heimnetz/Netzwerk/Netzwerkeinstellungen/IP-Adressen/IPv4-Konfiguration/Gastnetz den DNS Server des Gastnetzwerks einzustellen. -Die Fritz!Box wird immer ihre eigene IP als DNS Server des Gastnetzes einstellen. Um die DNS Anfragen dennoch über den Pi-hole zu senden, muss der als Upstream DNS für die Fritz!Box (siehe #1) eingetragen werden. Da es keine andere Option gibt, werden alle Anfragen aus dem Gastnetz für Pi-hole so erscheinen, als ob sie direkt von der Fritz!Box kommen. Eine individuelle Filterung je nach Client innerhalb des Gastnetzwerks ist deshalb nicht möglich. +Die Fritz!Box wird immer ihre eigene IP als DNS Server des Gastnetzes einstellen. Um die DNS Anfragen dennoch über den Pi-hole zu senden, muss dieser als Upstream DNS Server für die Fritz!Box eingetragen werden. Da es keine andere Option gibt, werden alle Anfragen aus dem Gastnetz für Pi-hole so erscheinen, als ob sie direkt von der Fritz!Box kommen. Eine individuelle Filterung je nach Client innerhalb des Gastnetzwerks ist deshalb nicht möglich. + +## Hostnamen in Pi-hole statt IP-Addressen - Conditional forwarding + +Wenn die Fritz!Box im Netzwerk als DHCP Server fungiert, werden die Hostnamen der Clients nur dort registriert. Pi-hole versucht standardmäßig, die IP-Adressen der Clients wieder in Hostnamen aufzulösen. Daher müssen die Anfragen zur Fritz!Box gelangen. +Dafür gibt es zwei Wege: + +* Die Fritz!Box ist der Upstream DNS Server des Pi-holes. Damit landen alle Anfragen sowieso bei der Fritz!Box, welche die Hostnamen an Pi-hole zurücksenden kann. + +!!! warning + Die Fritz!Box darf nur der Upstream DNS Server des Pi-hole sein, wenn dieser nicht gleichzeitig der Upstream DNS Server der Fritz!Box ist. Dies würde zu einem DNS Loop führen. + +* Es werden nur die Anfragen an die Fritz!Box gesendet, welche versuchen im lokalen Netzwerk IP-Adressen wieder Hostnamen zuzuordnene. Alle anderen Anfragen werden an den Upstream DNS Server des Pi-Hole gesendet. Dafür ist die Option *Conditional forwarding* zuständig. +Folgende Einstellungen müssen dafür vorgenommen werden: + * **Local network in CIDR notation:** IP-Bereich des Netzwerks in CIDR Notation, Standard für die Fritz!Box ist **192.168.178.0/24** + * **IP address of your DHCP server (router):** IP-Adresse der Fritz!Box selbst, Standard ist **192.168.178.1** + * **Local domain name (optional):** Name der lokalen Domän, für die Fritz!Box **fritz.box** + +![Screenshot der Conditional Forwarding Einstellungen](../images/conditional-forwarding.png) From f2224ca9b9b99e520beca3abb7150054f12cb65e Mon Sep 17 00:00:00 2001 From: yubiuser Date: Tue, 12 Jan 2021 20:59:48 +0100 Subject: [PATCH 059/103] Add section about the need to activate advanced view Signed-off-by: yubiuser --- docs/images/fritzbox-advanced-de.png | Bin 0 -> 5203 bytes docs/routers/fritzbox-de.md | 6 ++++++ 2 files changed, 6 insertions(+) create mode 100644 docs/images/fritzbox-advanced-de.png diff --git a/docs/images/fritzbox-advanced-de.png b/docs/images/fritzbox-advanced-de.png new file mode 100644 index 0000000000000000000000000000000000000000..de6b62c4b68bdb8d1c9f07966edb99fea00a1560 GIT binary patch literal 5203 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 Date: Wed, 13 Jan 2021 20:51:06 +0100 Subject: [PATCH 060/103] Rewrote English guide in one flow, added info about advances settings and conditional forwarding Signed-off-by: yubiuser --- docs/images/fritzbox-advanced.png | Bin 0 -> 3967 bytes docs/routers/fritzbox-de.md | 2 +- docs/routers/fritzbox.md | 82 +++++++++++++++++------------- 3 files changed, 49 insertions(+), 35 deletions(-) create mode 100644 docs/images/fritzbox-advanced.png diff --git a/docs/images/fritzbox-advanced.png b/docs/images/fritzbox-advanced.png new file mode 100644 index 0000000000000000000000000000000000000000..d0891574a319132fb9413fbb0cc71ee9ca0427e1 GIT binary patch literal 3967 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 Fritz!Box -> Pi-hole -> Upstream DNS Server ``` -Zum Einstellen muss die IP des Pi-hole als "Bevorzugter DNS-Server" **und** "Alternativer DNS-Server" in +Zum Einstellen muss die IP des Pi-hole als "Bevorzugter DNSv4-Server" **und** "Alternativer DNSv4-Server" in ```bash Internet/Zugangsdaten/DNS-Server diff --git a/docs/routers/fritzbox.md b/docs/routers/fritzbox.md index a50aea0..65093d4 100644 --- a/docs/routers/fritzbox.md +++ b/docs/routers/fritzbox.md @@ -1,43 +1,27 @@ -This guide was developed using FRITZ!OS 07.21 but should work for others too. It aims to line out a few basic principles to have a seamless DNS experience with Pi-hole and Fritz!Boxes . +This guide was developed using FRITZ!OS 07.21 but should work for others too. It aims to line out a few basic principles to have a seamless DNS experience with Pi-hole and Fritz!Boxes. > Note: There is no single way to do it right. Choose the one best fitting your needs. -This guide is IPv4 only. You need to adjust for IPv6 accordingly +This guide is IPv4 only. You need to adjust for IPv6 accordingly. -## 1) Using Pi-hole as upstream DNS server for your Fritz!Box +### Enable advanced settings -Using this configuration, Pi-hole is used for all devices within your network including the Fritz!Box itself. DNS requests are sent in this order +Some of the the follwowing settings might be visible only if advanced settings are enabled. Therefore, "View" has to be changed to advanced by clicking on "Standard" in the lower left corner. -```bash -Client -> Fritz!Box -> Pi-hole -> Upstream DNS Server -``` +![Screenshot der Fritz!Box DHCP Einstellungen](../images/fritzbox-advanced.png) -To set it up, enter Pi-hole's IP as "Preferred DNS server" **and** "Alternative DNS server" in - -```bash -Internet/Account Information/DNS server -``` - -![Screenshot of Fritz!Box WAN DNS Configuration](../images/fritzbox-wan-dns.png) - -!!! warning - Don't set the Fitz!Box as upstrem DNS server for Pi-hole! This will lead to a DNS loop as the Pi-hole will send the queries to the Fritz!Box which in turn will send the to Pi-hole. - -With this configuration, you won't see individual clients in Pi-hole's dashboard. For Pi-hole, all queries will appear as if they are coming from your Fritz!Box. You will therefore miss out on some features, e.g. Group Management. This can be solved using method #2. - - -## 2) Distribute Pi-hole as DNS server via DHCP +## Distribute Pi-hole as DNS server via DHCP Using this configuration, all clients will get Pi-hole's IP offered as DNS server when they request a DHCP lease from your Fritz!Box. -DNS requests are sent in this order +DNS queries take the following path ```bash Client -> Pi-hole -> Upstream DNS Server ``` > Note: -The Fritz!Box itself will use whatever is configured in Internet/Account Information/DNS server. -The Fritz!Box can be Pi-hole's upstream DNS server, as long Pi-hole itself is not the upstream server for the Fritz!Box. This would cause a DNS loop. +The Fritz!Box itself will use whatever is configured in Internet/Account Information/DNS server (see below). +The Fritz!Box can be Pi-hole's upstream DNS server, as long Pi-hole itself is not the upstream server of the Fritz!Box. This would cause a DNS loop. To set it up, enter Pi-hole's IP as "Local DNS server" in @@ -48,27 +32,57 @@ Home Network/Network/Network Settings/IP Adresses/IPv4 Configuration/Home Networ ![Screenshot of Fritz!Box DHCP Settings](../images/fritzbox-dhcp.png) >Note: -Clients will notice changes in DHCP settings only after they acquire a new DHCP lease. The easiest way to force a renewal is to dis/reconnect the client from the network. +Clients will notice changes in DHCP settings only after they acquired a new DHCP lease. The easiest way to force a renewal is to dis/reconnect the client from the network. -You should see individual clients in Pi-hole's web dashboard. +Now you should see individual clients in Pi-hole's web dashboard. -## 3) Combining 1) and 2) -You can combine 1) and 2) which will let all clients send DNS requests to your Pi-hole **and** the Fritz!Box itself as well. +## Pi-hole as upstream DNS server for your Fritz!Box + +With this configuration, Pi-hole is also used by the Fritz!Box itself as an upstream DNS server. DNS queries take the following path ```bash -Client (incl. Fritz!Box) -> Pi-hole -> Upstream DNS Server +(Clients) -> Fritz!Box -> Pi-hole -> Upstream DNS Server ``` +To set it up, enter Pi-hole's IP as "Preferred DNSv4 server" **and** "Alternative DNSv4 server" in + +```bash +Internet/Account Information/DNS server +``` + +![Screenshot of Fritz!Box WAN DNS Configuration](../images/fritzbox-wan-dns.png) + !!! warning - Don't set the Fritz!Box as upstrem DNS server for Pi-hole! This will lead to a DNS loop as the Pi-hole will send the queries to the Fritz!Box which in turn will send the to Pi-hole + Don't set the Fitz!Box as upstrem DNS server for Pi-hole if using this configuration! This will lead to a DNS loop as the Pi-hole will send the queries to the Fritz!Box which in turn will send them to Pi-hole. -## Using Pi-hole within the Guest Network +If only this configuration is used, you won't see individual clients in Pi-hole's dashboard. For Pi-hole, all queries will appear as if they are coming from your Fritz!Box. You will therefore miss out on some features, e.g. Group Management. If you want to use them, Pi-hole must (additionally) be distributed to the clients as DNS server via DHCP (see above). -You may have noticed, that there is no option to set the DNS server for the guest network in +### Using Pi-hole within the Guest Network + +There is no option to set the DNS server for the guest network in ```bash Home Network/Network/Network Settings/IP Adresses/IPv4 Configuration/Guest Network ``` -The Fritz!Box always sets its own IP as DNS server for the guest network. To filter its traffic, you have to setup Pi-hole as upstream DNS server for your Fritz!Box (see #1). As there is no other option, all DNS requests from your guest network will appear as coming from your Fritz!Box. +The Fritz!Box always sets its own IP as DNS server for the guest network. To filter its traffic, you have to setup Pi-hole as upstream DNS server for your Fritz!Box. As there is no other option, all DNS requests from your guest network will appear as coming from your Fritz!Box. Individual filtering per client within the guest network is therefore not possible. + +## Hostnames instead of IP addresses in Pi-hole's web interface - Conditional forwarding + +In case the Fritz!Box is used as DHCP server, client's hostames are registered only there. By default, Pi-hole tries to resolve the IP addresses of the clients back into host names. Therefore, the requests must reach the Fritz!Box. +There are two ways to do this: + +* The Fritz!Box is the upstream DNS server of the Pi-hole. This means that all queries end up with the Fritz!Box anyway, which can send the host names back to Pi-hole. + +!!! warning + The Fritz!Box may only be the upstream DNS server of the Pi-hole if Pi-hole is not the upstream DNS server of the Fritz!Box. This would lead to a DNS loop. + +* Only those queries are sent to the Fritz!Box that attempt to determine hostnames for IP addresses (clients) of the local network. All other requests are sent to the upstream DNS server of the Pi-Hole. The *Conditional forwarding* option is responsible for this. +The following settings must be made: + * **Local network in CIDR notation:** Standard IP range of the Fritz!Box is **192.168.178.0/24** + * **IP address of your DHCP server (router):** IP of the Fritz!Box, standard is **192.168.178.1** + * **Local domain name (optional):** Fritz!Box uses **fritz.box** + +![Screenshot der Conditional Forwarding Einstellungen](../images/conditional-forwarding.png) + From ea28e2efbade1c47028f3ae1ada90f892ad01f78 Mon Sep 17 00:00:00 2001 From: DL6ER Date: Sun, 30 Aug 2020 15:20:20 +0200 Subject: [PATCH 061/103] Add WireGuard guide Signed-off-by: DL6ER --- docs/guides/wireguard/client.md | 111 ++++++++++++++++++++++ docs/guides/wireguard/concept.md | 32 +++++++ docs/guides/wireguard/faq.md | 85 +++++++++++++++++ docs/guides/wireguard/internal.md | 71 ++++++++++++++ docs/guides/wireguard/overview.md | 30 ++++++ docs/guides/wireguard/route-everything.md | 13 +++ docs/guides/wireguard/server.md | 110 +++++++++++++++++++++ mkdocs.yml | 9 ++ 8 files changed, 461 insertions(+) create mode 100644 docs/guides/wireguard/client.md create mode 100644 docs/guides/wireguard/concept.md create mode 100644 docs/guides/wireguard/faq.md create mode 100644 docs/guides/wireguard/internal.md create mode 100644 docs/guides/wireguard/overview.md create mode 100644 docs/guides/wireguard/route-everything.md create mode 100644 docs/guides/wireguard/server.md diff --git a/docs/guides/wireguard/client.md b/docs/guides/wireguard/client.md new file mode 100644 index 0000000..359cb2f --- /dev/null +++ b/docs/guides/wireguard/client.md @@ -0,0 +1,111 @@ +# Adding a WireGuard client + +Adding clients is really simple and easy. The process for setting up a client is similar to setting up the server. This is expected as WireGuard's concept is more of the type Peer-to-Peer than server-client as mentioned at the very beginning of the [Server configuration](server.md). + +For each new client, the following steps must be taken. For the sake of simplicity, we will create the config file on the server itself. This, however, means that you need to transfer the config file *securely* to your server as it contains the private key of your client. An alternative way of doing this is to generate the configuration locally on your client and add the necessary lines to your server's configuration. + +## Key generation + +We generate a key-pair for the client `NAME` (replace accordingly everywhere below): + +``` bash +sudo -i +cd /etc/wireguard +umask 077 +wg genkey | tee NAME.key | wg pubkey > NAME.pub +``` + +## PSK Key generation + +We furthermore recommend generating a pre-shared key (PSK) in addition to the keys above. This adds an additional layer of symmetric-key cryptography to be mixed into the already existing public-key cryptography and is mainly for post-quantum resistance. A pre-shared key should be generated for each peer pair and *should not be reused*. + +``` bash +wg genpsk > NAME.psk +``` + +## Add client to server configuration + +Add the following to your `/etc/wireguard/wg0.conf`: + +``` toml +[Peer] +Address = 10.100.0.2/24 # Replace this IP address for subsequent clients +AllowedIPs = 10.100.0.1/32 # This client is only allowed to talk to the server +``` + +Then run + +``` bash +echo "PublicKey = $(cat NAME.pub)" >> /etc/wireguard/wg0.conf +echo "PresharedKey = $(cat NAME.psk)" >> /etc/wireguard/wg0.conf +``` + +to copy the clients's public and pre-shared keys into the server's config file. + +## Create client configuration + +Create a dedicated config file for your new client: + +``` bash +nano NAME.conf +``` + +with the content + +``` toml +[Interface] +Address = 10.100.0.2/24 # Replace this IP address for subsequent clients +DNS = 10.100.0.1 # IP address of your Pi-hole +Domains = ~. # Enforce all DNS over the WireGuard connection +``` + +``` bash +echo "PrivateKey = $(cat NAME.key)" >> NAME.conf +``` + +Then add your server as the only peer for this client: + +``` toml +[Peer] +AllowedIPs = 10.0.0.1/24 +Endpoint = [your public IP or domain]:44711 +PersistentKeepalive = 25 +``` + +Make sure that each IP is used only once. + + +??? info "About the `PersistentKeepalive` setting" + By default WireGuard peers remain silent while they do not need to communicate, so peers located behind a NAT and/or firewall may be unreachable from other peers until they reach out to other peers themselves (or the connection may time out). + + When a peer is behind NAT or a firewall, it typically wants to be able to receive incoming packets even when it is not sending any packets itself. Because NAT and stateful firewalls keep track of "connections", if a peer behind NAT or a firewall wishes to receive incoming packets, he must keep the NAT/firewall mapping valid, by periodically sending keepalive packets. This is called *persistent keepalives*. + + When this option is enabled, a keepalive packet is sent to the server endpoint once every interval seconds. A sensible interval that works with a wide variety of firewalls is `25` seconds. Setting it to 0 turns the feature off, which is the default. + + **TL;DR** If you're behind NAT or a firewall and you want to receive incoming connections long after network traffic has gone silent, this option will keep the "connection" open in the eyes of NAT. + + +Then add the public key of the server as well as the PSK for this connection: + +``` bash +echo "PublicKey = $(cat server.pub)" >> NAME.conf +echo "PresharedKey = $(cat NAME.psk)" >> NAME.conf +``` + +That's it. + +## Copy config file to client + +You can now copy the configuration file to your client (if you created the config on the server). If the client is a mobile device such as a phone, `qrencode` can be used to generate a scanable QR code: + +``` bash +qrencode -t ansiutf8 -r NAME.conf +``` + +(you may need to install `qrencode` using `sudo apt-get install qrencode`) + +## Connect to your WireGuard VPN + +After creating/copying the connection information over to your client, you may use the client you prefer to connect to your system. Mind that setting up auto-start of the WireGuard connection may lead to issues if you are doing this too early (when the system cannot resolve DNS). See our [FAQ](faq.md) for further hints. + +{!abbreviations.md!} diff --git a/docs/guides/wireguard/concept.md b/docs/guides/wireguard/concept.md new file mode 100644 index 0000000..9edcdf6 --- /dev/null +++ b/docs/guides/wireguard/concept.md @@ -0,0 +1,32 @@ +# Conceptual overview + +Before we get started with installing a `wireguard` server, we'll quickly give a general conceptual overview of what WireGuard is about. You can skip this section if you already know what is going on under the hood or don't care (and just want to have it running). + +WireGuard securely encapsulates IP packets over UDP. You add a WireGuard interface, configure it with your private key and your peers' public keys, and then you send packets across it. + +WireGuard works by adding a network interface, like `eth0` or `wlan0`, called `wg0` (or `wg1`, +`wg2`, `wg3`, etc). This interface acts as a tunnel interface. Routes for this network interface will be added automatically based on the configuration file you will learn about below. All aspects of this virtual interface will be configured automatically by the `wg-tools`. + +WireGuard associates tunnel IP addresses with public keys and remote endpoints. When the interface +**sends a packet to a peer**, it does the following: + +1. This packet is meant for `192.168.30.8`. Is this peer configured? + 1. Yes: peer `adams-laptop`. Continue with step 2. + 2. No: Not for any configured peer, drop the packet and end here. + +2. Encrypt the IP packet using peer `adams-laptop`'s public key. +3. What is the remote endpoint of peer `adams-laptop`? Let me look... Okay, the endpoint is host `216.58.211.110:53133` (UDP). +4. Send encrypted data over the Internet to this host. + +When the interface **receives a packet from a peer**, this happens: + +1. Received a packet from host `98.139.183.24:7361`. Let's decrypt it! +2. It decrypted and authenticated properly for peer `evas-android`. Okay, let's remember that peer +`evas-android`'s most recent Internet endpoint is `98.139.183.24:7361` (UDP). +3. Once decrypted, the plain-text packet is from `192.168.43.89`. Is peer `evas-android` allowed to be sending us packets as 192.168.43.89? + 1. Yes: accept the packet on the interface and process it (forwarding to further local client, into the Internet, etc.) + 2. No: drop it. + +Behind the scenes there is much happening to provide proper privacy, authenticity, and perfect forward secrecy, using state-of-the-art cryptography. + +If you're interested in the internal inner workings, you might be interested in reading through the various articles on their official website [www.wireguard.com](https://www.wireguard.com) which is also where we took the vast majority of content in this guide from. diff --git a/docs/guides/wireguard/faq.md b/docs/guides/wireguard/faq.md new file mode 100644 index 0000000..e92e3ec --- /dev/null +++ b/docs/guides/wireguard/faq.md @@ -0,0 +1,85 @@ +# Frequently asked questions + +## Issues with dynamic server IP + +Host names cannot be resolved during startup. This may lead to a five minutes delay during boot. A solution to this is to disable the automatic start of the `wg` interface during start and connect only later (manually) when you are sure that you can resolve host names. + +1. Disable `auto wg0` in `/etc/network/interfaces` (put `#` in front, like `#auto wg0`) +2. Start `wireguard` manually using `sudo ifup wg0` + +If the IP changes while the connection is running, resolving the new IP address fails otten. Reconnect using + +``` bash +sudo ifdown wg0 && sudo ifup wg0 +``` + +To achieve a permanent solution, one can install a `cron` job which restarts the connection automatically whenever a change is detected. This avoids excessive restarts of the interface. Example script (taken from [Ubuntuusers Wiki](https://wiki.ubuntuusers.de/WireGuard)): + +``` bash +#!/bin/bash +# Check state of wg0 interface +wgstatus=$(wg) +if [ "$wgstatus" == "interface: wg0" ]; then + ip link delete wg0 && ifup wg0 +elif [ "$wgstatus" == "interface: wg0" ]; then + ifup wg0 +else + file="/tmp/digIP.txt" + digIP=$(dig +short beispiel2.domain.de) # Change this to your domain ! + if [ -e "$file" ]; then + fileTXT=$(cat "$file") + if [ "$digIP" != "$fileTXT" ]; then + #echo "Daten sind gleich" + /sbin/ifdown wg0 + /sbin/ifup wg0 + echo "$digIP" > "$file" + fi + else + echo "$digIP" > "$file" + fi +fi +``` + +Store this file as `/home/[user name]/wg-restart.sh` and add it to your `crontab`: + +``` bash +sudo crontab -e +``` + +``` plain +*/10 * * * * bash /home/[user name]/wg-restart.sh # Runs the script every 10 minutes +``` + +## Routes are periodically reset + +Users of NetworkManager should make sure that it is not managing the WireGuard interface(s). For example, create the configuration file `/etc/NetworkManager/conf.d/unmanaged.conf` with content + +``` toml +[keyfile] +unmanaged-devices=interface-name:wg* +``` + +[source](https://wiki.archlinux.org/index.php/WireGuard) + +## Broken DNS resolution + +When tunneling all traffic through a WireGuard interface, the connection can become seemingly lost after a while or upon new connection. This could be caused by a network manager or DHCP client overwriting `/etc/resolv.conf`. +By default, `wg-quick` uses `resolvconf` to register new DNS entries (from the DNS keyword in the configuration file). This will cause issues with network managers and DHCP clients that do not use `resolvconf`, as they will overwrite `/etc/resolv.conf` thus removing the DNS servers added by `wg-quick`. + +The solution is to use networking software that supports `resolvconf`. + +!!! info "Hint for Ubuntu users" + Users of `systemd-resolved` should make sure that `systemd-resolvconf` is installed. + +[source](https://wiki.archlinux.org/index.php/WireGuard) + +## Low MTU + +Due to too low MTU (lower than 1280), `wg-quick` may fail to create the WireGuard interface. This can be solved by setting the MTU value in WireGuard configuration in Interface section on client: + +``` toml +[Interface] +MTU = 1500 +``` + +[source](https://wiki.archlinux.org/index.php/WireGuard) diff --git a/docs/guides/wireguard/internal.md b/docs/guides/wireguard/internal.md new file mode 100644 index 0000000..2405b65 --- /dev/null +++ b/docs/guides/wireguard/internal.md @@ -0,0 +1,71 @@ +# Access devices in the internal network through the WireGuard tunnel + +## Enable IP forwarding on the server + +Enable IP forwarding on your server by removing the comments in front of + +``` toml +net.ipv4.ip_forward = 1 +net.ipv6.conf.all.forwarding = 1 +``` + +in the file `/etc/sysctl.d/99-sysctl.conf` + +Then apply the new option with the command below. + +``` bash +sudo sysctl -p +``` + +If you see the options repeated like + +``` plain +net.ipv4.ip_forward=1 +``` + +they were enabled successfully. + +A properly configured firewall is ***highly*** recommended for any Internet-facing device. Configuring a firewall (`iptables`, `ufw`, etc.) is not part of this guide. + +## Enable NAT on the server + +!!! info "Optional for NAT" + If the server is behind a router and receives traffic via NAT, these iptables rules are not needed. + +On your server, add the following to the `[INTERFACE]` section: + +``` toml +PostUp = iptables -w -t nat -A POSTROUTING -o eth0 -j MASQUERADE; ip6tables -w -t nat -A POSTROUTING -o eth0 -j MASQUERADE +PostDown = iptables -w -t nat -D POSTROUTING -o eth0 -j MASQUERADE; ip6tables -w -t nat -D POSTROUTING -o eth0 -j MASQUERADE +``` + +!!! warning "Substitute interface" + Substitute `eth0` in the preceding lines to match the Internet-facing interface. + +??? info "The `PostUp` and `PostDown` options" + `PostUp` and `PostDown` defines steps to be run after the interface is turned on or off, respectively. In this case, iptables is used to set Linux IP masquerade rules to allow all the clients to share the server’s IPv4 and IPv6 address. + The rules will then be cleared once the tunnel is down. + +## Allow clients to access other devices + +In our standard configuration, we have configured the clients in such a way that they can only speak to the server. This has to be changed on both the server and the clients. + +### Server side + +``` toml +[Peer] +AllowedIPs = 10.100.0.1/32 +``` + +Change this to + +``` toml +[Peer] +AllowedIPs = 10.100.0.1/32, 192.168.2.1/24 +``` + +if your internal network is in the IP range `192.168.2.1` - `192.168.2.254`. + +### Client side + +Do the same in the `[Interface]` section. diff --git a/docs/guides/wireguard/overview.md b/docs/guides/wireguard/overview.md new file mode 100644 index 0000000..babbd8d --- /dev/null +++ b/docs/guides/wireguard/overview.md @@ -0,0 +1,30 @@ +### Remote accessing Pi-hole using WireGuard + +WireGuard is an ***extremely simple yet fast and modern VPN*** that utilizes state-of-the-art cryptography. Comparing to other solutions, such as OpenVPN or IPsec, it aims to be **faster, simpler and leaner** while avoiding the massive overhead involved with other VPN solutions. +A combination of extremely high-speed cryptographic primitives and the fact that WireGuard lives +inside the Linux kernel means that secure networking can be very high-speed. +It intends to be considerably more performant than OpenVPN. + +WireGuard is designed as a general purpose VPN for running on embedded interfaces and super computers alike, fit for many circumstances. + +There is no need to manage connections, be concerned about state, manage daemons, or worry about what's under the hood. WireGuard presents an extremely basic yet powerful interface. + +Using WireGuard is a modern and safe way to access your Pi-hole's capabilities remotely. Setting up a DNS server has become a simple task with Pi-hole's automated installer, which has resulted in many people knowingly--or unknowingly--creating an open resolver, which aids in DNS Amplification Attacks. + +WireGuard has been designed with ease-of-implementation and simplicity in mind. It is meant to be +easily implemented in very few lines of code, and easily auditable for security vulnerabilities. + +This article aims to provide a step-by-step walk-through on setting up a server running Pi-hole and WireGuard so you can securely connect to your Pi-hole's DNS (and *optionally* your entire internal network) from anywhere. + +**This tutorial walks you through the installation of a WireGuard server on your Pi-hole**. + +Via this VPN, you can: + +- use the full filtering capabilities of your Pi-hole +- access your Pi-hole dashboard remotely +- access all your internal devices (*optional*) +- reroute your entire Internet traffic through your Pi-hole (*optional*) + +from everywhere around the globe. + +{!abbreviations.md!} diff --git a/docs/guides/wireguard/route-everything.md b/docs/guides/wireguard/route-everything.md new file mode 100644 index 0000000..1363222 --- /dev/null +++ b/docs/guides/wireguard/route-everything.md @@ -0,0 +1,13 @@ +Routing your entire Internet traffic is **optional**, however, it can be advantageous in cases where you are expecting eavesdropping on the network. This may not only happen in unsecure open Wi-Fi networks (airports, hotels, trains, etc.) but also in encrypted Wi-Fi networks where the creator of the network can monitor client activity. + +Rerouting the Internet traffic through your Pi-hole will furthermore cause all of your Internet traffic to reach the Internet from the place where your WireGuard server is located. This can be used to obfuscate your real location as well as to be allowed to access geo-blocked content, e.g., when your Pi-hole is located in Germany but you are traveling in the United States. If you want to access a page only accessible from within Germany (like the live-broadcast of Tagesschau, etc.), this will typically not work. However, if you route your entire Internet through your Pi-hole, your network traffic will originate from Germany, allowing you to watch the content. + +To route all traffic through the tunnel to a specific peer, add the default route (`0.0.0.0/0` for IPv4 and `::/0`for IPv6) to `AllowedIPs` in your WireGuard config files: + +```toml +AllowedIPs = 0.0.0.0/0, ::/0 +``` + +Do **not** set this on the server in the `[Interface]` section. WireGuard will automatically take care of setting up [correct routing](https://www.wireguard.com/netns/#routing-all-your-traffic) so that networking still functions on all your clients. + +That's all you need to do. diff --git a/docs/guides/wireguard/server.md b/docs/guides/wireguard/server.md new file mode 100644 index 0000000..da18b83 --- /dev/null +++ b/docs/guides/wireguard/server.md @@ -0,0 +1,110 @@ +# Installing the WireGuard server + + +!!! info "The terms "server" and "client"" + Usage of the terms `server` and `client` were purposefully chosen in this guide specifically to help both new users and existing OpenVPN users become familiar with the construction of WireGuard's configuration files. + + WireGuard documentation simply refers to both of these concepts as `peers`. + + +## Installing the server components + +Installing everything we will need for a `wireguard` connections is as simple as running: + +``` bash +sudo apt-get install wireguard wireguard-tools wireguard-dkms +``` + +For Ubuntu 18.04 and lower, you need to do some extra steps: + +``` bash +sudo add-apt-repository ppa:wireguard/wireguard +sudo apt update +sudo apt install wireguard wireguard-tools wireguard-dkms +``` + +## Initial configuration + +Each network interface has a private key and a list of peers. Each peer has a public key. Public keys are short and simple, and are used by peers to authenticate each other. They can be passed around for use in configuration files by any out-of-band method, similar to how one might send their SSH public key to a friend for access to a shell server. + +First, we create the folder containing our `wireguard` configuration: + +``` bash +sudo -i +cd /etc/wireguard +umask 077 +``` + +### Key generation + +Inhere, we generate a key-pair for the server: + +``` bash +wg genkey | tee server.key | wg pubkey > server.pub +``` + +### Creating the WireGuard configuration + +Create a config file + +``` bash +sudo nano /etc/wireguard/wg0.conf +``` + +and put the following into it: + +``` toml +[Interface] +Address = 10.100.0.1/24 +ListenPort = 44711 +SaveConfig = true +``` + +Then run + +``` bash +echo "PrivateKey = $(cat server.key)" >> /etc/wireguard/wg0.conf +``` + +to copy the server's private key into your config file. + +## Forward port + +If the server is behind NAT, be sure to forward the specified port on which WireGuard will be running (for this example, `44711/UDP`) from the router to the WireGuard server. + +## Start the server + +Register your server `wg0` as: + +``` bash +systemctl enable wg-quick@wg0.service +systemctl daemon-reload +systemctl start wg-quick@wg0 +``` + +If successful, you should not see any output. In case you get an error like + +``` plain +RTNETLINK answers: Operation not supported +Unable to access interface: Protocol not supported +``` + +you should check that the WireGuard kernel module is loaded with the command below: + +```bash +sudo modprobe wireguard +``` + +If you get an error saying the module is missing, try reinstalling WireGuard or restart your server and try again. This may happen when the WireGuard server is installed for a more recent kernel than you are currently running. This typically happens when you have neither updated nor restarted your system for a long time. + +## Check everything is running + +With the following command, you can check if your `wireguard` server is running: + +``` bash +wg +``` + +You can now continue to add clients. + +{!abbreviations.md!} diff --git a/mkdocs.yml b/mkdocs.yml index 5efd672..505ae0e 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -99,6 +99,15 @@ nav: - 'Configuring Caddy for Pi-hole': guides/caddy-configuration.md - 'Configuring Traefik for Pi-hole (not in Docker)': guides/traefik-configuration-nodocker.md - 'Benchmarking': guides/benchmark.md + - 'Remote accessing Pi-hole using WireGuard': + - 'Overview': guides/wireguard/overview.md + - 'Concept': guides/wireguard/concept.md + - 'Install server': guides/wireguard/server.md + - 'Add client(s)': guides/wireguard/client.md + - 'Optional extra features': + - 'Make all local devices accessible': guides/wireguard/internal.md + - 'Reroute all Internet traffic': guides/wireguard/route-everything.md + - 'Troubleshooting': guides/wireguard/faq.md - 'Pi-hole and OpenVPN Server': - 'Overview': guides/vpn/overview.md - 'Installation': guides/vpn/installation.md From aa8268c1ff8e1d107b775d05d23be9947f6c21a4 Mon Sep 17 00:00:00 2001 From: DL6ER Date: Mon, 14 Sep 2020 00:26:57 +0200 Subject: [PATCH 062/103] Further optimizations and corrections for the WireGuard guide Signed-off-by: DL6ER --- docs/guides/wireguard/client.md | 126 ++++++++++++++++------ docs/guides/wireguard/internal.md | 3 +- docs/guides/wireguard/route-everything.md | 6 +- docs/guides/wireguard/server.md | 42 ++++++-- mkdocs.yml | 16 +-- 5 files changed, 141 insertions(+), 52 deletions(-) diff --git a/docs/guides/wireguard/client.md b/docs/guides/wireguard/client.md index 359cb2f..3ad7960 100644 --- a/docs/guides/wireguard/client.md +++ b/docs/guides/wireguard/client.md @@ -25,22 +25,64 @@ wg genpsk > NAME.psk ## Add client to server configuration -Add the following to your `/etc/wireguard/wg0.conf`: - -``` toml -[Peer] -Address = 10.100.0.2/24 # Replace this IP address for subsequent clients -AllowedIPs = 10.100.0.1/32 # This client is only allowed to talk to the server -``` - -Then run +Add the new client by running the command: ``` bash -echo "PublicKey = $(cat NAME.pub)" >> /etc/wireguard/wg0.conf -echo "PresharedKey = $(cat NAME.psk)" >> /etc/wireguard/wg0.conf +wg set wg0 peer "$(cat NAME.pub)" preshared-key NAME.psk allowed-ips 10.100.0.2/32 ``` -to copy the clients's public and pre-shared keys into the server's config file. + +!!! info "Client IP address" + Make sure to increment the IP address for any further client! We add the first client with the IP address `10.100.0.2` in this example (`10.100.0.1` is the server) + + +Restart your server to have it save your client to its config file: + +``` bash +sudo service wg-quick@wg0 restart +``` + + +!!! info "Restarting is optional" + Note that restarting the WireGuard server is optional and can be skiped. The new client will be stored in the config file on the next restart of the system. However, in case of powerloss, you will loose your new client which is why we restarting the server here (if this can be afforded). + + +After a restart, the server file should look like: + +``` toml +[Interface] +Address = 10.100.0.1/24 +ListenPort = 44711 +SaveConfig = true +PrivateKey = XYZ123456ABC= # PrivateKey will be different + +[Peer] +Address = 10.100.0.2/24 +AllowedIPs = 10.100.0.1/32 +PublicKey = F+80gbmHVlOrU+es13S18oMEX2g= # PublicKey will be different +PresharedKey = 8cLaY8Bkd7PiUs0izYBQYVTEFlA= # PresharedKey will be different + +# Possibly further [Peer] lines +``` + +The command + +``` bash +wg +``` + +should tell you about your new client: + +``` plain +interface: wg0 + public key: XYZ123456ABC= ⬅ Your server's public key will be different + private key: (hidden) + listening port: 44711 + +peer: F+80gbmHVlOrU+es13S18oMEX2g= ⬅ Your peer's public key will be different + preshared key: (hidden) + allowed ips: 10.100.0.2/32 +``` ## Create client configuration @@ -54,37 +96,25 @@ with the content ``` toml [Interface] -Address = 10.100.0.2/24 # Replace this IP address for subsequent clients -DNS = 10.100.0.1 # IP address of your Pi-hole -Domains = ~. # Enforce all DNS over the WireGuard connection +Address = 10.100.0.2/32 # Replace this IP address for subsequent clients +DNS = 10.100.0.1 # IP address of your server (Pi-hole) ``` +and add the private key of this client + ``` bash echo "PrivateKey = $(cat NAME.key)" >> NAME.conf ``` -Then add your server as the only peer for this client: +Next, add your server as peer for this client: ``` toml [Peer] -AllowedIPs = 10.0.0.1/24 +AllowedIPs = 10.100.0.0/24 Endpoint = [your public IP or domain]:44711 PersistentKeepalive = 25 ``` -Make sure that each IP is used only once. - - -??? info "About the `PersistentKeepalive` setting" - By default WireGuard peers remain silent while they do not need to communicate, so peers located behind a NAT and/or firewall may be unreachable from other peers until they reach out to other peers themselves (or the connection may time out). - - When a peer is behind NAT or a firewall, it typically wants to be able to receive incoming packets even when it is not sending any packets itself. Because NAT and stateful firewalls keep track of "connections", if a peer behind NAT or a firewall wishes to receive incoming packets, he must keep the NAT/firewall mapping valid, by periodically sending keepalive packets. This is called *persistent keepalives*. - - When this option is enabled, a keepalive packet is sent to the server endpoint once every interval seconds. A sensible interval that works with a wide variety of firewalls is `25` seconds. Setting it to 0 turns the feature off, which is the default. - - **TL;DR** If you're behind NAT or a firewall and you want to receive incoming connections long after network traffic has gone silent, this option will keep the "connection" open in the eyes of NAT. - - Then add the public key of the server as well as the PSK for this connection: ``` bash @@ -94,6 +124,19 @@ echo "PresharedKey = $(cat NAME.psk)" >> NAME.conf That's it. + +??? info "About the `PersistentKeepalive` setting" + By default WireGuard peers remain silent while they do not need to communicate, so peers located behind a NAT and/or firewall may be unreachable from other peers until they reach out to other peers themselves (or the connection may time out). + + When a peer is behind NAT or a firewall, it typically wants to be able to receive incoming packets even when it is not sending any packets itself. Because NAT and stateful firewalls keep track of "connections", if a peer behind NAT or a firewall wishes to receive incoming packets, he must keep the NAT/firewall mapping valid, by periodically sending keepalive packets. This is called *persistent keepalives*. + + When this option is enabled, a keepalive packet is sent to the server endpoint once every interval seconds. A sensible interval that works with a wide variety of firewalls is `25` seconds. Setting it to 0 turns the feature off, which is the default. + + Handshakes are not the same as keep-alives. A handshake establishes a limited-time session of about 3 minutes. So, for about 3 minutes your client is able to send its keep-alive packets without requireing a new session. Then, when the session expires, sending a new keep-alive requires a new session for which you should see a new handshake. In practice, the client initiates a handshake earlier. + + **TL;DR** If you're behind NAT or a firewall and you want to receive incoming connections long after network traffic has gone silent, this option will keep the "connection" open in the eyes of NAT. + + ## Copy config file to client You can now copy the configuration file to your client (if you created the config on the server). If the client is a mobile device such as a phone, `qrencode` can be used to generate a scanable QR code: @@ -104,8 +147,31 @@ qrencode -t ansiutf8 -r NAME.conf (you may need to install `qrencode` using `sudo apt-get install qrencode`) +You can directly scan this QR code with the official WireGuard app after clicking on the blue plus symbol in the lower right corner. + ## Connect to your WireGuard VPN After creating/copying the connection information over to your client, you may use the client you prefer to connect to your system. Mind that setting up auto-start of the WireGuard connection may lead to issues if you are doing this too early (when the system cannot resolve DNS). See our [FAQ](faq.md) for further hints. +You can check if your client successfully connected by, once again, running + +``` plain +wg +``` + +on the server. It should show some traffic for your client if everything works: + +``` plain +interface: wg0 + public key: XYZ123456ABC= ⬅ Your server's public key will be different + private key: (hidden) + listening port: 44711 + +peer: F+80gbmHVlOrU+es13S18oMEX2g= ⬅ Your peer's public key will be different + preshared key: (hidden) + allowed ips: 10.100.0.2/32 + latest handshake: 32 seconds ago + transfer: 3.43 KiB received, 188 B sent +``` + {!abbreviations.md!} diff --git a/docs/guides/wireguard/internal.md b/docs/guides/wireguard/internal.md index 2405b65..436c42e 100644 --- a/docs/guides/wireguard/internal.md +++ b/docs/guides/wireguard/internal.md @@ -21,6 +21,7 @@ If you see the options repeated like ``` plain net.ipv4.ip_forward=1 +net.ipv6.conf.all.forwarding = 1 ``` they were enabled successfully. @@ -68,4 +69,4 @@ if your internal network is in the IP range `192.168.2.1` - `192.168.2.254`. ### Client side -Do the same in the `[Interface]` section. +Do the same you did above for the server also in the `[Interface]` section of all clients you want to have this feature. It is possible to add this only for a few clients, leaving the others isolated to only the Pi-hole server itself. diff --git a/docs/guides/wireguard/route-everything.md b/docs/guides/wireguard/route-everything.md index 1363222..0aeebaa 100644 --- a/docs/guides/wireguard/route-everything.md +++ b/docs/guides/wireguard/route-everything.md @@ -2,7 +2,7 @@ Routing your entire Internet traffic is **optional**, however, it can be advanta Rerouting the Internet traffic through your Pi-hole will furthermore cause all of your Internet traffic to reach the Internet from the place where your WireGuard server is located. This can be used to obfuscate your real location as well as to be allowed to access geo-blocked content, e.g., when your Pi-hole is located in Germany but you are traveling in the United States. If you want to access a page only accessible from within Germany (like the live-broadcast of Tagesschau, etc.), this will typically not work. However, if you route your entire Internet through your Pi-hole, your network traffic will originate from Germany, allowing you to watch the content. -To route all traffic through the tunnel to a specific peer, add the default route (`0.0.0.0/0` for IPv4 and `::/0`for IPv6) to `AllowedIPs` in your WireGuard config files: +To route all traffic through the tunnel to a specific peer, add the default route (`0.0.0.0/0` for IPv4 and `::/0`for IPv6) to `AllowedIPs` in your clients's WireGuard config files: ```toml AllowedIPs = 0.0.0.0/0, ::/0 @@ -10,4 +10,6 @@ AllowedIPs = 0.0.0.0/0, ::/0 Do **not** set this on the server in the `[Interface]` section. WireGuard will automatically take care of setting up [correct routing](https://www.wireguard.com/netns/#routing-all-your-traffic) so that networking still functions on all your clients. -That's all you need to do. +That's all you need to do. You should use an online check (e.g. www.wieistmeineip.de) to check if your IP changed to the public IP address of your WireGuard server after this change up. It is possible to add this change only for a few clients, leaving the others without a full tunnel for all traffic (e.g., where this is not necessary or not desired). + +{!abbreviations.md!} diff --git a/docs/guides/wireguard/server.md b/docs/guides/wireguard/server.md index da18b83..7c2ff56 100644 --- a/docs/guides/wireguard/server.md +++ b/docs/guides/wireguard/server.md @@ -4,7 +4,7 @@ !!! info "The terms "server" and "client"" Usage of the terms `server` and `client` were purposefully chosen in this guide specifically to help both new users and existing OpenVPN users become familiar with the construction of WireGuard's configuration files. - WireGuard documentation simply refers to both of these concepts as `peers`. + WireGuard itself simply refers to all connected devices as `peers`. It consitutes a connection between computers. ## Installing the server components @@ -82,20 +82,25 @@ systemctl daemon-reload systemctl start wg-quick@wg0 ``` -If successful, you should not see any output. In case you get an error like +If successful, you should not see any output. -``` plain -RTNETLINK answers: Operation not supported -Unable to access interface: Protocol not supported -``` + +??? warning "Error: RTNETLINK answers: Operation not supported" + In case you get an error like -you should check that the WireGuard kernel module is loaded with the command below: + ``` plain + RTNETLINK answers: Operation not supported + Unable to access interface: Protocol not supported + ``` -```bash -sudo modprobe wireguard -``` + you should check that the WireGuard kernel module is loaded with the command below: -If you get an error saying the module is missing, try reinstalling WireGuard or restart your server and try again. This may happen when the WireGuard server is installed for a more recent kernel than you are currently running. This typically happens when you have neither updated nor restarted your system for a long time. + ```bash + sudo modprobe wireguard + ``` + + If you get an error saying the module is missing, try reinstalling WireGuard or restart your server and try again. This may happen when the WireGuard server is installed for a more recent kernel than you are currently running. This typically happens when you have neither updated nor restarted your system for a long time. + ## Check everything is running @@ -105,6 +110,21 @@ With the following command, you can check if your `wireguard` server is running: wg ``` +The output should look like the following: + +``` plain +interface: wg0 + public key: XYZ123456ABC= ⬅ Your public key will be different + private key: (hidden) + listening port: 44711 +``` + +Your public key will be different to ours. This is expected (you just created your own key above). + +## Set your Pi-hole to listen on all interfaces + +On your [Settings page (tab DNS)](http://pi.hole/admin/settings.php?tab=dns), ensure you set the listing mode of your Pi-hole to one of the `Listen of all interfaces` settings. The top one is perferred as it adds a bit of additional safety. Your WireGuard peers/clients will be correctly recognized as being only one hop away. + You can now continue to add clients. {!abbreviations.md!} diff --git a/mkdocs.yml b/mkdocs.yml index 505ae0e..b4178ef 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -92,14 +92,7 @@ nav: - 'How to sign-off commits': guides/github/how-to-signoff.md - 'Guides': - 'Pi-hole as All-Around DNS Solution': guides/unbound.md - - 'Configuring DNS-Over-HTTPS on Pi-hole': guides/dns-over-https.md - - 'Upstream DNS Providers': guides/upstream-dns-providers.md - - 'Editing Whitelist and Blacklist': guides/whitelist-blacklist.md - - 'Configuring NGINX for Pi-hole': guides/nginx-configuration.md - - 'Configuring Caddy for Pi-hole': guides/caddy-configuration.md - - 'Configuring Traefik for Pi-hole (not in Docker)': guides/traefik-configuration-nodocker.md - - 'Benchmarking': guides/benchmark.md - - 'Remote accessing Pi-hole using WireGuard': + - 'Remote access using WireGuard': - 'Overview': guides/wireguard/overview.md - 'Concept': guides/wireguard/concept.md - 'Install server': guides/wireguard/server.md @@ -108,6 +101,13 @@ nav: - 'Make all local devices accessible': guides/wireguard/internal.md - 'Reroute all Internet traffic': guides/wireguard/route-everything.md - 'Troubleshooting': guides/wireguard/faq.md + - 'Configuring DNS-Over-HTTPS on Pi-hole': guides/dns-over-https.md + - 'Upstream DNS Providers': guides/upstream-dns-providers.md + - 'Editing Whitelist and Blacklist': guides/whitelist-blacklist.md + - 'Configuring NGINX for Pi-hole': guides/nginx-configuration.md + - 'Configuring Caddy for Pi-hole': guides/caddy-configuration.md + - 'Configuring Traefik for Pi-hole (not in Docker)': guides/traefik-configuration-nodocker.md + - 'Benchmarking': guides/benchmark.md - 'Pi-hole and OpenVPN Server': - 'Overview': guides/vpn/overview.md - 'Installation': guides/vpn/installation.md From e63dbb4c55a05ce7eb8233f34f516bb8e7cda46f Mon Sep 17 00:00:00 2001 From: DL6ER Date: Mon, 14 Sep 2020 00:42:32 +0200 Subject: [PATCH 063/103] Encourage users to test for DNS leaks after setting up their clients Signed-off-by: DL6ER --- docs/guides/wireguard/client.md | 14 ++++++++++---- docs/guides/wireguard/server.md | 6 +++--- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/docs/guides/wireguard/client.md b/docs/guides/wireguard/client.md index 3ad7960..d893819 100644 --- a/docs/guides/wireguard/client.md +++ b/docs/guides/wireguard/client.md @@ -52,7 +52,7 @@ After a restart, the server file should look like: ``` toml [Interface] Address = 10.100.0.1/24 -ListenPort = 44711 +ListenPort = 47111 SaveConfig = true PrivateKey = XYZ123456ABC= # PrivateKey will be different @@ -77,7 +77,7 @@ should tell you about your new client: interface: wg0 public key: XYZ123456ABC= ⬅ Your server's public key will be different private key: (hidden) - listening port: 44711 + listening port: 47111 peer: F+80gbmHVlOrU+es13S18oMEX2g= ⬅ Your peer's public key will be different preshared key: (hidden) @@ -111,7 +111,7 @@ Next, add your server as peer for this client: ``` toml [Peer] AllowedIPs = 10.100.0.0/24 -Endpoint = [your public IP or domain]:44711 +Endpoint = [your public IP or domain]:47111 PersistentKeepalive = 25 ``` @@ -165,7 +165,7 @@ on the server. It should show some traffic for your client if everything works: interface: wg0 public key: XYZ123456ABC= ⬅ Your server's public key will be different private key: (hidden) - listening port: 44711 + listening port: 47111 peer: F+80gbmHVlOrU+es13S18oMEX2g= ⬅ Your peer's public key will be different preshared key: (hidden) @@ -174,4 +174,10 @@ peer: F+80gbmHVlOrU+es13S18oMEX2g= ⬅ Your peer's public key will be differen transfer: 3.43 KiB received, 188 B sent ``` +## Test for DNS leaks + +You should run a DNS leak test on [www.dnsleaktest.com](https://www.dnsleaktest.com) to ensure your WireGuard tunnel does not leak DNS requests (so all are processed by your Pi-hole). The expected outcome is that you should only see DNS servers belonging to the upstream DNS destination you selected in Pi-hole. If you configured [Pi-hole as All-Around DNS Solution](../unbound.md), you should only see the public IP address of your WireGuard server and no other DNS server. + +See also [What is a DNS leak and why should I care?](https://www.dnsleaktest.com/what-is-a-dns-leak.html) (external link). + {!abbreviations.md!} diff --git a/docs/guides/wireguard/server.md b/docs/guides/wireguard/server.md index 7c2ff56..0955493 100644 --- a/docs/guides/wireguard/server.md +++ b/docs/guides/wireguard/server.md @@ -56,7 +56,7 @@ and put the following into it: ``` toml [Interface] Address = 10.100.0.1/24 -ListenPort = 44711 +ListenPort = 47111 SaveConfig = true ``` @@ -70,7 +70,7 @@ to copy the server's private key into your config file. ## Forward port -If the server is behind NAT, be sure to forward the specified port on which WireGuard will be running (for this example, `44711/UDP`) from the router to the WireGuard server. +If the server is behind NAT, be sure to forward the specified port on which WireGuard will be running (for this example, `47111/UDP`) from the router to the WireGuard server. ## Start the server @@ -116,7 +116,7 @@ The output should look like the following: interface: wg0 public key: XYZ123456ABC= ⬅ Your public key will be different private key: (hidden) - listening port: 44711 + listening port: 47111 ``` Your public key will be different to ours. This is expected (you just created your own key above). From b16365d95617250659e1bfcc682c1eafaf9ba7d1 Mon Sep 17 00:00:00 2001 From: DL6ER Date: Mon, 14 Sep 2020 22:02:20 +0200 Subject: [PATCH 064/103] Add instructions how to compile WireGuard from source Signed-off-by: DL6ER --- docs/guides/wireguard/server.md | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/docs/guides/wireguard/server.md b/docs/guides/wireguard/server.md index 0955493..c9739fc 100644 --- a/docs/guides/wireguard/server.md +++ b/docs/guides/wireguard/server.md @@ -23,6 +23,35 @@ sudo apt update sudo apt install wireguard wireguard-tools wireguard-dkms ``` +If there is no `wireguard` package available for your system, you can follow the instructions below to compile WireGuard from source. + + +???+ info "Compile WireGuard from source" + + With the following commands, you can install WireGuard from source + + ``` bash + sudo apt update && sudo apt upgrade -y + sudo apt install raspberrypi-kernel-headers libmnl-dev libelf-dev build-essential git -y + git clone https://git.zx2c4.com/WireGuard + cd WireGuard/src + sudo make + sudo make install + ``` + + With these commands, you can update your locally compiled WireGuard at any time: + + ``` bash + cd WireGuard/ + git pull + cd src + sudo make + sudo make install + ``` + + The ZX2C4 git repository is the official source for `wireguard-linux`, see [WireGuard#Repositories](https://www.wireguard.com/repositories/) (external link) + + ## Initial configuration Each network interface has a private key and a list of peers. Each peer has a public key. Public keys are short and simple, and are used by peers to authenticate each other. They can be passed around for use in configuration files by any out-of-band method, similar to how one might send their SSH public key to a friend for access to a shell server. From 126cc21092382e17a7eb738d56d46559ee3257a9 Mon Sep 17 00:00:00 2001 From: DL6ER Date: Wed, 23 Sep 2020 17:38:27 +0200 Subject: [PATCH 065/103] Use backports for compiling WireGuard from source. This makes it compatible also with older kernels. Signed-off-by: DL6ER --- docs/guides/wireguard/server.md | 59 +++++++++++++++++++++++++-------- mkdocs.yml | 3 ++ 2 files changed, 49 insertions(+), 13 deletions(-) diff --git a/docs/guides/wireguard/server.md b/docs/guides/wireguard/server.md index c9739fc..fd9dc5f 100644 --- a/docs/guides/wireguard/server.md +++ b/docs/guides/wireguard/server.md @@ -26,27 +26,60 @@ sudo apt install wireguard wireguard-tools wireguard-dkms If there is no `wireguard` package available for your system, you can follow the instructions below to compile WireGuard from source. -???+ info "Compile WireGuard from source" +??? info "Compile WireGuard from source" - With the following commands, you can install WireGuard from source + With the following commands, you can install WireGuard from source as a backport of the WireGuard kernel module for Linux to 3.10 ≤ kernel ≤ 5.5 as an out-of-tree module. More recent kernels already include WireGuard themselves and you only need to install the `wireguard` tools. + + ### Update your local system ``` bash sudo apt update && sudo apt upgrade -y - sudo apt install raspberrypi-kernel-headers libmnl-dev libelf-dev build-essential git -y - git clone https://git.zx2c4.com/WireGuard - cd WireGuard/src - sudo make - sudo make install ``` - With these commands, you can update your locally compiled WireGuard at any time: + ### Install the toolchain + + === "Raspberry Pi" + + ``` bash + sudo apt install -y raspberrypi-kernel-headers libelf-dev build-essential pkg-config git + ``` + + === "Linux" + + ``` bash + sudo apt install -y linux-headers-$(uname -r) libelf-dev build-essential libmnl-dev git + ``` + + ## Download and compile the `wireguard` module ``` bash - cd WireGuard/ - git pull - cd src - sudo make - sudo make install + git clone https://git.zx2c4.com/wireguard-linux-compat + make -C wireguard-linux-compat/src -j$(nproc) + sudo make -C wireguard-linux-compat/src install + ``` + + You can ignore messages like + + ``` plain + Warning: modules_install: missing 'System.map' file. Skipping depmod. + ``` + + !!! info "Check the module installation was successful" + + Run + + ``` bash + sudo modprobe wireguard + ``` + + If there is no output, `wireguard` was loaded correctly. Note that it may be necessary to re-install the `wireguard` module when you update your system's kernel. + + ## Download and compile the `wireguard` tools (`wg`, etc.) + + ``` bash + git clone https://git.zx2c4.com/wireguard-tools + make -C wireguard-tools/src -j$(nproc) + sudo make -C wireguard-tools/src install ``` The ZX2C4 git repository is the official source for `wireguard-linux`, see [WireGuard#Repositories](https://www.wireguard.com/repositories/) (external link) diff --git a/mkdocs.yml b/mkdocs.yml index b4178ef..cdc8508 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -39,6 +39,9 @@ markdown_extensions: - pymdownx.extra # (https://facelessuser.github.io/pymdown-extensions/extensions/details/) - pymdownx.details + # Tabbed provides a syntax to easily add tabbed Markdown content. + # https://facelessuser.github.io/pymdown-extensions/extensions/tabbed/ + - pymdownx.tabbed # Adds syntax for defining footnotes in Markdown documents (https://python-markdown.github.io/extensions/footnotes/) - footnotes # Adds the ability to define abbreviations From 50913fd06c8347cd7d03c7700919385e39bcbf48 Mon Sep 17 00:00:00 2001 From: DL6ER Date: Wed, 23 Sep 2020 22:17:17 +0200 Subject: [PATCH 066/103] Do not use auto-save so the server's config file may be edited at any time Signed-off-by: DL6ER --- docs/guides/wireguard/client.md | 15 ++++++--------- docs/guides/wireguard/server.md | 10 +++++----- 2 files changed, 11 insertions(+), 14 deletions(-) diff --git a/docs/guides/wireguard/client.md b/docs/guides/wireguard/client.md index d893819..6fc1845 100644 --- a/docs/guides/wireguard/client.md +++ b/docs/guides/wireguard/client.md @@ -28,7 +28,10 @@ wg genpsk > NAME.psk Add the new client by running the command: ``` bash -wg set wg0 peer "$(cat NAME.pub)" preshared-key NAME.psk allowed-ips 10.100.0.2/32 +echo "[Peer]" >> /etc/wireguard/wg0.conf +echo "PublicKey = $(cat NAME.pub)" >> /etc/wireguard/wg0.conf +echo "PresharedKey = $(cat NAME.psk)" >> /etc/wireguard/wg0.conf +echo "AllowedIPs = 10.100.0.2/32" >> /etc/wireguard/wg0.conf ``` @@ -36,17 +39,12 @@ wg set wg0 peer "$(cat NAME.pub)" preshared-key NAME.psk allowed-ips 10.100.0.2/ Make sure to increment the IP address for any further client! We add the first client with the IP address `10.100.0.2` in this example (`10.100.0.1` is the server) -Restart your server to have it save your client to its config file: +Restart your server to load the new client config: ``` bash sudo service wg-quick@wg0 restart ``` - -!!! info "Restarting is optional" - Note that restarting the WireGuard server is optional and can be skiped. The new client will be stored in the config file on the next restart of the system. However, in case of powerloss, you will loose your new client which is why we restarting the server here (if this can be afforded). - - After a restart, the server file should look like: ``` toml @@ -57,10 +55,9 @@ SaveConfig = true PrivateKey = XYZ123456ABC= # PrivateKey will be different [Peer] -Address = 10.100.0.2/24 -AllowedIPs = 10.100.0.1/32 PublicKey = F+80gbmHVlOrU+es13S18oMEX2g= # PublicKey will be different PresharedKey = 8cLaY8Bkd7PiUs0izYBQYVTEFlA= # PresharedKey will be different +AllowedIPs = 10.100.0.2/32 # Possibly further [Peer] lines ``` diff --git a/docs/guides/wireguard/server.md b/docs/guides/wireguard/server.md index fd9dc5f..8ff38d9 100644 --- a/docs/guides/wireguard/server.md +++ b/docs/guides/wireguard/server.md @@ -119,13 +119,13 @@ and put the following into it: [Interface] Address = 10.100.0.1/24 ListenPort = 47111 -SaveConfig = true ``` Then run ``` bash echo "PrivateKey = $(cat server.key)" >> /etc/wireguard/wg0.conf +exit # Exit the sudo session ``` to copy the server's private key into your config file. @@ -139,9 +139,9 @@ If the server is behind NAT, be sure to forward the specified port on which Wire Register your server `wg0` as: ``` bash -systemctl enable wg-quick@wg0.service -systemctl daemon-reload -systemctl start wg-quick@wg0 +sudo systemctl enable wg-quick@wg0.service +sudo systemctl daemon-reload +sudo systemctl start wg-quick@wg0 ``` If successful, you should not see any output. @@ -169,7 +169,7 @@ If successful, you should not see any output. With the following command, you can check if your `wireguard` server is running: ``` bash -wg +sudo wg ``` The output should look like the following: From 8e08b657b7f0e78736b0a3d6b84981d4f74e07bf Mon Sep 17 00:00:00 2001 From: DL6ER Date: Wed, 23 Sep 2020 23:09:37 +0200 Subject: [PATCH 067/103] Ensure we configure also an internal IPv6 tunnel (will be transported transparently over IPv4 on the outside) Signed-off-by: DL6ER --- docs/guides/wireguard/client.md | 23 ++++++++++++----------- docs/guides/wireguard/server.md | 2 +- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/docs/guides/wireguard/client.md b/docs/guides/wireguard/client.md index 6fc1845..03550e6 100644 --- a/docs/guides/wireguard/client.md +++ b/docs/guides/wireguard/client.md @@ -31,25 +31,25 @@ Add the new client by running the command: echo "[Peer]" >> /etc/wireguard/wg0.conf echo "PublicKey = $(cat NAME.pub)" >> /etc/wireguard/wg0.conf echo "PresharedKey = $(cat NAME.psk)" >> /etc/wireguard/wg0.conf -echo "AllowedIPs = 10.100.0.2/32" >> /etc/wireguard/wg0.conf +echo "AllowedIPs = 10.100.0.2/32, fd08:4711::2/128" >> /etc/wireguard/wg0.conf ``` !!! info "Client IP address" - Make sure to increment the IP address for any further client! We add the first client with the IP address `10.100.0.2` in this example (`10.100.0.1` is the server) + Make sure to increment the IP address for any further client! We add the first client with the IP addresses `10.100.0.2` and `fd08:4711::2/128` in this example (`10.100.0.1` and `fd08:4711::1/128` are the server) Restart your server to load the new client config: ``` bash -sudo service wg-quick@wg0 restart +systemctl restart wg-quick@wg0 ``` After a restart, the server file should look like: ``` toml [Interface] -Address = 10.100.0.1/24 +Address = 10.100.0.1/24, fd08::1/128 ListenPort = 47111 SaveConfig = true PrivateKey = XYZ123456ABC= # PrivateKey will be different @@ -57,7 +57,7 @@ PrivateKey = XYZ123456ABC= # PrivateKey will be different [Peer] PublicKey = F+80gbmHVlOrU+es13S18oMEX2g= # PublicKey will be different PresharedKey = 8cLaY8Bkd7PiUs0izYBQYVTEFlA= # PresharedKey will be different -AllowedIPs = 10.100.0.2/32 +AllowedIPs = 10.100.0.2/32, fd08:4711::2/128 # Possibly further [Peer] lines ``` @@ -78,7 +78,7 @@ interface: wg0 peer: F+80gbmHVlOrU+es13S18oMEX2g= ⬅ Your peer's public key will be different preshared key: (hidden) - allowed ips: 10.100.0.2/32 + allowed ips: 10.100.0.2/32, fd08::2/128 ``` ## Create client configuration @@ -93,8 +93,8 @@ with the content ``` toml [Interface] -Address = 10.100.0.2/32 # Replace this IP address for subsequent clients -DNS = 10.100.0.1 # IP address of your server (Pi-hole) +Address = 10.100.0.2/32, fd08:4711::2/128 # Replace this IP address for subsequent clients +DNS = 10.100.0.1 # IP address of your server (Pi-hole) ``` and add the private key of this client @@ -107,7 +107,7 @@ Next, add your server as peer for this client: ``` toml [Peer] -AllowedIPs = 10.100.0.0/24 +AllowedIPs = 10.100.0.0/24, fd08::/64 Endpoint = [your public IP or domain]:47111 PersistentKeepalive = 25 ``` @@ -117,6 +117,7 @@ Then add the public key of the server as well as the PSK for this connection: ``` bash echo "PublicKey = $(cat server.pub)" >> NAME.conf echo "PresharedKey = $(cat NAME.psk)" >> NAME.conf +exit ``` That's it. @@ -139,7 +140,7 @@ That's it. You can now copy the configuration file to your client (if you created the config on the server). If the client is a mobile device such as a phone, `qrencode` can be used to generate a scanable QR code: ``` bash -qrencode -t ansiutf8 -r NAME.conf +sudo qrencode -t ansiutf8 -r /etc/wireguard/NAME.conf ``` (you may need to install `qrencode` using `sudo apt-get install qrencode`) @@ -153,7 +154,7 @@ After creating/copying the connection information over to your client, you may u You can check if your client successfully connected by, once again, running ``` plain -wg +sudo wg ``` on the server. It should show some traffic for your client if everything works: diff --git a/docs/guides/wireguard/server.md b/docs/guides/wireguard/server.md index 8ff38d9..6e74b52 100644 --- a/docs/guides/wireguard/server.md +++ b/docs/guides/wireguard/server.md @@ -117,7 +117,7 @@ and put the following into it: ``` toml [Interface] -Address = 10.100.0.1/24 +Address = 10.100.0.1/24, fd08:4711::1/64 ListenPort = 47111 ``` From 2c5b7b2d5c725f53acbd3ef75197f2e065ab0393 Mon Sep 17 00:00:00 2001 From: DL6ER Date: Wed, 23 Sep 2020 23:42:01 +0200 Subject: [PATCH 068/103] Add hint that IP forwarding already needs to be enabled for routing the entire Internet traffic Signed-off-by: DL6ER --- docs/guides/wireguard/client.md | 2 +- docs/guides/wireguard/internal.md | 22 ++++++++++++---------- docs/guides/wireguard/route-everything.md | 10 +++++++++- mkdocs.yml | 6 +++--- 4 files changed, 25 insertions(+), 15 deletions(-) diff --git a/docs/guides/wireguard/client.md b/docs/guides/wireguard/client.md index 03550e6..c326ea2 100644 --- a/docs/guides/wireguard/client.md +++ b/docs/guides/wireguard/client.md @@ -94,7 +94,7 @@ with the content ``` toml [Interface] Address = 10.100.0.2/32, fd08:4711::2/128 # Replace this IP address for subsequent clients -DNS = 10.100.0.1 # IP address of your server (Pi-hole) +DNS = 10.100.0.1 # IP address of your server (Pi-hole) ``` and add the private key of this client diff --git a/docs/guides/wireguard/internal.md b/docs/guides/wireguard/internal.md index 436c42e..399a87b 100644 --- a/docs/guides/wireguard/internal.md +++ b/docs/guides/wireguard/internal.md @@ -1,4 +1,4 @@ -# Access devices in the internal network through the WireGuard tunnel +# Access internal devices through the WireGuard tunnel ## Enable IP forwarding on the server @@ -33,7 +33,7 @@ A properly configured firewall is ***highly*** recommended for any Internet-faci !!! info "Optional for NAT" If the server is behind a router and receives traffic via NAT, these iptables rules are not needed. -On your server, add the following to the `[INTERFACE]` section: +On your server, add the following to the `[INTERFACE]` section of your `/etc/wireguard/wg0.conf`: ``` toml PostUp = iptables -w -t nat -A POSTROUTING -o eth0 -j MASQUERADE; ip6tables -w -t nat -A POSTROUTING -o eth0 -j MASQUERADE @@ -53,19 +53,21 @@ In our standard configuration, we have configured the clients in such a way that ### Server side -``` toml -[Peer] -AllowedIPs = 10.100.0.1/32 -``` - -Change this to +Change the allowed addresses in your `/etc/wireguard/wg0.conf` from ``` toml [Peer] -AllowedIPs = 10.100.0.1/32, 192.168.2.1/24 +AllowedIPs = 10.100.0.1/32, fd08:4711::1/64 ``` -if your internal network is in the IP range `192.168.2.1` - `192.168.2.254`. +to + +``` toml +[Peer] +AllowedIPs = 10.100.0.1/32, fd08:4711::1/64, 192.168.2.1/24 +``` + +assuming your internal network is in the IP range `192.168.2.1` - `192.168.2.254`. ### Client side diff --git a/docs/guides/wireguard/route-everything.md b/docs/guides/wireguard/route-everything.md index 0aeebaa..d3699b0 100644 --- a/docs/guides/wireguard/route-everything.md +++ b/docs/guides/wireguard/route-everything.md @@ -1,14 +1,22 @@ +# Route the entire Internet traffic through the WireGuard tunnel + Routing your entire Internet traffic is **optional**, however, it can be advantageous in cases where you are expecting eavesdropping on the network. This may not only happen in unsecure open Wi-Fi networks (airports, hotels, trains, etc.) but also in encrypted Wi-Fi networks where the creator of the network can monitor client activity. Rerouting the Internet traffic through your Pi-hole will furthermore cause all of your Internet traffic to reach the Internet from the place where your WireGuard server is located. This can be used to obfuscate your real location as well as to be allowed to access geo-blocked content, e.g., when your Pi-hole is located in Germany but you are traveling in the United States. If you want to access a page only accessible from within Germany (like the live-broadcast of Tagesschau, etc.), this will typically not work. However, if you route your entire Internet through your Pi-hole, your network traffic will originate from Germany, allowing you to watch the content. +!!! info "Ensure you're already forwarding traffic" + The following assumes you have already prepared your Pi-hole for [IP forwarding](internal.md). If this is not the case, follow the steps over there before continuing here. + To route all traffic through the tunnel to a specific peer, add the default route (`0.0.0.0/0` for IPv4 and `::/0`for IPv6) to `AllowedIPs` in your clients's WireGuard config files: ```toml AllowedIPs = 0.0.0.0/0, ::/0 ``` -Do **not** set this on the server in the `[Interface]` section. WireGuard will automatically take care of setting up [correct routing](https://www.wireguard.com/netns/#routing-all-your-traffic) so that networking still functions on all your clients. + +!!! warning "Change this setting only on your clients" + Do **not** set this on the server in the `[Interface]` section. WireGuard will automatically take care of setting up [correct routing](https://www.wireguard.com/netns/#routing-all-your-traffic) so that networking still functions on all your clients. + That's all you need to do. You should use an online check (e.g. www.wieistmeineip.de) to check if your IP changed to the public IP address of your WireGuard server after this change up. It is possible to add this change only for a few clients, leaving the others without a full tunnel for all traffic (e.g., where this is not necessary or not desired). diff --git a/mkdocs.yml b/mkdocs.yml index cdc8508..e3664b1 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -95,14 +95,14 @@ nav: - 'How to sign-off commits': guides/github/how-to-signoff.md - 'Guides': - 'Pi-hole as All-Around DNS Solution': guides/unbound.md - - 'Remote access using WireGuard': + - 'WireGuard VPN': - 'Overview': guides/wireguard/overview.md - 'Concept': guides/wireguard/concept.md - 'Install server': guides/wireguard/server.md - 'Add client(s)': guides/wireguard/client.md - 'Optional extra features': - - 'Make all local devices accessible': guides/wireguard/internal.md - - 'Reroute all Internet traffic': guides/wireguard/route-everything.md + - 'Make local devices accessible': guides/wireguard/internal.md + - 'Tunnel all Internet traffic': guides/wireguard/route-everything.md - 'Troubleshooting': guides/wireguard/faq.md - 'Configuring DNS-Over-HTTPS on Pi-hole': guides/dns-over-https.md - 'Upstream DNS Providers': guides/upstream-dns-providers.md From 63b4bd658717f84b547f396894b7e302ee5a683b Mon Sep 17 00:00:00 2001 From: DL6ER Date: Thu, 24 Sep 2020 23:53:25 +0200 Subject: [PATCH 069/103] Add hint to add full-tunnel as second profile Signed-off-by: DL6ER --- docs/guides/wireguard/internal.md | 14 +++++++++++--- docs/guides/wireguard/route-everything.md | 11 +++++++++-- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/docs/guides/wireguard/internal.md b/docs/guides/wireguard/internal.md index 399a87b..cbecca0 100644 --- a/docs/guides/wireguard/internal.md +++ b/docs/guides/wireguard/internal.md @@ -64,11 +64,19 @@ to ``` toml [Peer] -AllowedIPs = 10.100.0.1/32, fd08:4711::1/64, 192.168.2.1/24 +AllowedIPs = 10.100.0.0/24, fd08:4711::/64, 192.168.2.0/24 ``` -assuming your internal network is in the IP range `192.168.2.1` - `192.168.2.254`. +assuming your internal network is in the IP range `192.168.2.1` - `192.168.2.254`. The change `10.100.0.1/32` to `10.100.0.0/24` also allows your WireGuard peers to see each other. ### Client side -Do the same you did above for the server also in the `[Interface]` section of all clients you want to have this feature. It is possible to add this only for a few clients, leaving the others isolated to only the Pi-hole server itself. +Do the same you did above for the server also in the `[Interface]` section of all clients you want to have this feature: + +``` toml +[Peer] +AllowedIPs = 10.0.0.0/24, fd08:4711::/64, 192.168.2.0/24 +``` + + +It is possible to add this only for a few clients, leaving the others isolated to only the Pi-hole server itself. diff --git a/docs/guides/wireguard/route-everything.md b/docs/guides/wireguard/route-everything.md index d3699b0..cd578a5 100644 --- a/docs/guides/wireguard/route-everything.md +++ b/docs/guides/wireguard/route-everything.md @@ -4,8 +4,15 @@ Routing your entire Internet traffic is **optional**, however, it can be advanta Rerouting the Internet traffic through your Pi-hole will furthermore cause all of your Internet traffic to reach the Internet from the place where your WireGuard server is located. This can be used to obfuscate your real location as well as to be allowed to access geo-blocked content, e.g., when your Pi-hole is located in Germany but you are traveling in the United States. If you want to access a page only accessible from within Germany (like the live-broadcast of Tagesschau, etc.), this will typically not work. However, if you route your entire Internet through your Pi-hole, your network traffic will originate from Germany, allowing you to watch the content. -!!! info "Ensure you're already forwarding traffic" - The following assumes you have already prepared your Pi-hole for [IP forwarding](internal.md). If this is not the case, follow the steps over there before continuing here. + +!!! info "Create a second profile" + Instead of editing your existing configuration, you can easily add a new one with the modified `AllowedIPs` line as above. This will give you two tunnel variants and you decide - at any time from mobile - which variant you want. The one with only the DNS traffic being safely forwarded to your Pi-hole or the variant where your entire Internet traffic is encrypted and sent through your Pi-hole. You can choose at any time which is the best solution in your current situation (e.g., trusted network, unencrypted airport Wi-Fi, etc.). + + + +!!! warning "Ensure you're already forwarding traffic" + The following assumes you have already prepared your Pi-hole for [IP forwarding](internal.md#enable-ip-forwarding-on-the-server) and [enabled NAT](internal.md#enable-nat-on-the-server). If this is not the case, follow the steps over there before continuing here. + To route all traffic through the tunnel to a specific peer, add the default route (`0.0.0.0/0` for IPv4 and `::/0`for IPv6) to `AllowedIPs` in your clients's WireGuard config files: From 2eb51183654b96b1b493d73227e4bbf1e3b4133d Mon Sep 17 00:00:00 2001 From: DL6ER Date: Thu, 24 Sep 2020 23:59:25 +0200 Subject: [PATCH 070/103] Use BASH variable for client name so the client generation can be scripted more easily Signed-off-by: DL6ER --- docs/guides/wireguard/client.md | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/docs/guides/wireguard/client.md b/docs/guides/wireguard/client.md index c326ea2..d1ed1db 100644 --- a/docs/guides/wireguard/client.md +++ b/docs/guides/wireguard/client.md @@ -12,7 +12,8 @@ We generate a key-pair for the client `NAME` (replace accordingly everywhere bel sudo -i cd /etc/wireguard umask 077 -wg genkey | tee NAME.key | wg pubkey > NAME.pub +name="client_name" +wg genkey | tee "${name}.key" | wg pubkey > "${name}.pub" ``` ## PSK Key generation @@ -20,7 +21,7 @@ wg genkey | tee NAME.key | wg pubkey > NAME.pub We furthermore recommend generating a pre-shared key (PSK) in addition to the keys above. This adds an additional layer of symmetric-key cryptography to be mixed into the already existing public-key cryptography and is mainly for post-quantum resistance. A pre-shared key should be generated for each peer pair and *should not be reused*. ``` bash -wg genpsk > NAME.psk +wg genpsk > "${name}.psk" ``` ## Add client to server configuration @@ -29,8 +30,8 @@ Add the new client by running the command: ``` bash echo "[Peer]" >> /etc/wireguard/wg0.conf -echo "PublicKey = $(cat NAME.pub)" >> /etc/wireguard/wg0.conf -echo "PresharedKey = $(cat NAME.psk)" >> /etc/wireguard/wg0.conf +echo "PublicKey = $(cat "${name}.pub")" >> /etc/wireguard/wg0.conf +echo "PresharedKey = $(cat "${name}.psk")" >> /etc/wireguard/wg0.conf echo "AllowedIPs = 10.100.0.2/32, fd08:4711::2/128" >> /etc/wireguard/wg0.conf ``` @@ -86,7 +87,7 @@ peer: F+80gbmHVlOrU+es13S18oMEX2g= ⬅ Your peer's public key will be differen Create a dedicated config file for your new client: ``` bash -nano NAME.conf +nano "${name}.conf" ``` with the content @@ -100,7 +101,7 @@ DNS = 10.100.0.1 # IP address of your server (Pi-hole) and add the private key of this client ``` bash -echo "PrivateKey = $(cat NAME.key)" >> NAME.conf +echo "PrivateKey = $(cat "${name}.key")" >> "${name}.conf" ``` Next, add your server as peer for this client: @@ -115,8 +116,8 @@ PersistentKeepalive = 25 Then add the public key of the server as well as the PSK for this connection: ``` bash -echo "PublicKey = $(cat server.pub)" >> NAME.conf -echo "PresharedKey = $(cat NAME.psk)" >> NAME.conf +echo "PublicKey = $(cat server.pub)" >> "${name}.conf" +echo "PresharedKey = $(cat "${name}.psk")" >> "${name}.conf" exit ``` @@ -140,7 +141,7 @@ That's it. You can now copy the configuration file to your client (if you created the config on the server). If the client is a mobile device such as a phone, `qrencode` can be used to generate a scanable QR code: ``` bash -sudo qrencode -t ansiutf8 -r /etc/wireguard/NAME.conf +sudo qrencode -t ansiutf8 -r "/etc/wireguard/${name}.conf" ``` (you may need to install `qrencode` using `sudo apt-get install qrencode`) From df949dc2058aace873c15246aeeed19545e3f215 Mon Sep 17 00:00:00 2001 From: DL6ER Date: Fri, 25 Sep 2020 00:06:07 +0200 Subject: [PATCH 071/103] Add a copy-and-paste friendly box with *all* commands needed to add a new client in one shot. Signed-off-by: DL6ER --- docs/guides/wireguard/client.md | 44 ++++++++++++++++++++++++++------- 1 file changed, 35 insertions(+), 9 deletions(-) diff --git a/docs/guides/wireguard/client.md b/docs/guides/wireguard/client.md index d1ed1db..49bdddc 100644 --- a/docs/guides/wireguard/client.md +++ b/docs/guides/wireguard/client.md @@ -4,6 +4,38 @@ Adding clients is really simple and easy. The process for setting up a client is For each new client, the following steps must be taken. For the sake of simplicity, we will create the config file on the server itself. This, however, means that you need to transfer the config file *securely* to your server as it contains the private key of your client. An alternative way of doing this is to generate the configuration locally on your client and add the necessary lines to your server's configuration. + +??? info "All commands described below at once" + ``` bash + sudo -i + cd /etc/wireguard + umask 077 + + name="client_name" + + wg genkey | tee "${name}.key" | wg pubkey > "${name}.pub" + wg genpsk > "${name}.psk" + + echo "[Peer]" >> /etc/wireguard/wg0.conf + echo "PublicKey = $(cat "${name}.pub")" >> /etc/wireguard/wg0.conf + echo "PresharedKey = $(cat "${name}.psk")" >> /etc/wireguard/wg0.conf + echo "AllowedIPs = 10.100.0.2/32, fd08:4711::2/128" >> /etc/wireguard/wg0.conf + + systemctl restart wg-quick@wg0 + + echo "[Interface]" > "${name}.conf" + echo "Address = 10.100.0.2/32, fd08:4711::2/128" >> "${name}.conf" # May need editing + echo "DNS = 10.100.0.1" >> "${name}.conf" # Your Pi-hole's IP + echo "PrivateKey = $(cat "${name}.key")" >> "${name}.conf" + echo "PublicKey = $(cat server.pub)" >> "${name}.conf" + echo "PresharedKey = $(cat "${name}.psk")" >> "${name}.conf" + + qrencode -t ansiutf8 -r "${name}.conf" + + exit + ``` + + ## Key generation We generate a key-pair for the client `NAME` (replace accordingly everywhere below): @@ -87,15 +119,9 @@ peer: F+80gbmHVlOrU+es13S18oMEX2g= ⬅ Your peer's public key will be differen Create a dedicated config file for your new client: ``` bash -nano "${name}.conf" -``` - -with the content - -``` toml -[Interface] -Address = 10.100.0.2/32, fd08:4711::2/128 # Replace this IP address for subsequent clients -DNS = 10.100.0.1 # IP address of your server (Pi-hole) +echo "[Interface]" > "${name}.conf" +echo "Address = 10.100.0.2/32, fd08:4711::2/128" >> "${name}.conf" # May need editing +echo "DNS = 10.100.0.1" >> "${name}.conf" # Your Pi-hole's IP ``` and add the private key of this client From cd606b24e27988a61b8b0df2409dca53b6cbd411 Mon Sep 17 00:00:00 2001 From: XhmikosR Date: Mon, 19 Oct 2020 08:19:29 +0300 Subject: [PATCH 072/103] Remove redundant spaces after fenced codeblocks --- docs/guides/wireguard/client.md | 32 +++++++++++++-------------- docs/guides/wireguard/faq.md | 12 +++++------ docs/guides/wireguard/internal.md | 14 ++++++------ docs/guides/wireguard/server.md | 36 +++++++++++++++---------------- 4 files changed, 47 insertions(+), 47 deletions(-) diff --git a/docs/guides/wireguard/client.md b/docs/guides/wireguard/client.md index 49bdddc..cc476e3 100644 --- a/docs/guides/wireguard/client.md +++ b/docs/guides/wireguard/client.md @@ -6,7 +6,7 @@ For each new client, the following steps must be taken. For the sake of simplici ??? info "All commands described below at once" - ``` bash + ```bash sudo -i cd /etc/wireguard umask 077 @@ -40,7 +40,7 @@ For each new client, the following steps must be taken. For the sake of simplici We generate a key-pair for the client `NAME` (replace accordingly everywhere below): -``` bash +```bash sudo -i cd /etc/wireguard umask 077 @@ -52,7 +52,7 @@ wg genkey | tee "${name}.key" | wg pubkey > "${name}.pub" We furthermore recommend generating a pre-shared key (PSK) in addition to the keys above. This adds an additional layer of symmetric-key cryptography to be mixed into the already existing public-key cryptography and is mainly for post-quantum resistance. A pre-shared key should be generated for each peer pair and *should not be reused*. -``` bash +```bash wg genpsk > "${name}.psk" ``` @@ -60,7 +60,7 @@ wg genpsk > "${name}.psk" Add the new client by running the command: -``` bash +```bash echo "[Peer]" >> /etc/wireguard/wg0.conf echo "PublicKey = $(cat "${name}.pub")" >> /etc/wireguard/wg0.conf echo "PresharedKey = $(cat "${name}.psk")" >> /etc/wireguard/wg0.conf @@ -74,13 +74,13 @@ echo "AllowedIPs = 10.100.0.2/32, fd08:4711::2/128" >> /etc/wireguard/wg0.conf Restart your server to load the new client config: -``` bash +```bash systemctl restart wg-quick@wg0 ``` After a restart, the server file should look like: -``` toml +```toml [Interface] Address = 10.100.0.1/24, fd08::1/128 ListenPort = 47111 @@ -97,13 +97,13 @@ AllowedIPs = 10.100.0.2/32, fd08:4711::2/128 The command -``` bash +```bash wg ``` should tell you about your new client: -``` plain +```plain interface: wg0 public key: XYZ123456ABC= ⬅ Your server's public key will be different private key: (hidden) @@ -118,7 +118,7 @@ peer: F+80gbmHVlOrU+es13S18oMEX2g= ⬅ Your peer's public key will be differen Create a dedicated config file for your new client: -``` bash +```bash echo "[Interface]" > "${name}.conf" echo "Address = 10.100.0.2/32, fd08:4711::2/128" >> "${name}.conf" # May need editing echo "DNS = 10.100.0.1" >> "${name}.conf" # Your Pi-hole's IP @@ -126,13 +126,13 @@ echo "DNS = 10.100.0.1" >> "${name}.conf" # Your Pi-hol and add the private key of this client -``` bash +```bash echo "PrivateKey = $(cat "${name}.key")" >> "${name}.conf" ``` Next, add your server as peer for this client: -``` toml +```toml [Peer] AllowedIPs = 10.100.0.0/24, fd08::/64 Endpoint = [your public IP or domain]:47111 @@ -141,7 +141,7 @@ PersistentKeepalive = 25 Then add the public key of the server as well as the PSK for this connection: -``` bash +```bash echo "PublicKey = $(cat server.pub)" >> "${name}.conf" echo "PresharedKey = $(cat "${name}.psk")" >> "${name}.conf" exit @@ -158,7 +158,7 @@ That's it. When this option is enabled, a keepalive packet is sent to the server endpoint once every interval seconds. A sensible interval that works with a wide variety of firewalls is `25` seconds. Setting it to 0 turns the feature off, which is the default. Handshakes are not the same as keep-alives. A handshake establishes a limited-time session of about 3 minutes. So, for about 3 minutes your client is able to send its keep-alive packets without requireing a new session. Then, when the session expires, sending a new keep-alive requires a new session for which you should see a new handshake. In practice, the client initiates a handshake earlier. - + **TL;DR** If you're behind NAT or a firewall and you want to receive incoming connections long after network traffic has gone silent, this option will keep the "connection" open in the eyes of NAT. @@ -166,7 +166,7 @@ That's it. You can now copy the configuration file to your client (if you created the config on the server). If the client is a mobile device such as a phone, `qrencode` can be used to generate a scanable QR code: -``` bash +```bash sudo qrencode -t ansiutf8 -r "/etc/wireguard/${name}.conf" ``` @@ -180,13 +180,13 @@ After creating/copying the connection information over to your client, you may u You can check if your client successfully connected by, once again, running -``` plain +```plain sudo wg ``` on the server. It should show some traffic for your client if everything works: -``` plain +```plain interface: wg0 public key: XYZ123456ABC= ⬅ Your server's public key will be different private key: (hidden) diff --git a/docs/guides/wireguard/faq.md b/docs/guides/wireguard/faq.md index e92e3ec..0ec039b 100644 --- a/docs/guides/wireguard/faq.md +++ b/docs/guides/wireguard/faq.md @@ -9,13 +9,13 @@ Host names cannot be resolved during startup. This may lead to a five minutes de If the IP changes while the connection is running, resolving the new IP address fails otten. Reconnect using -``` bash +```bash sudo ifdown wg0 && sudo ifup wg0 ``` To achieve a permanent solution, one can install a `cron` job which restarts the connection automatically whenever a change is detected. This avoids excessive restarts of the interface. Example script (taken from [Ubuntuusers Wiki](https://wiki.ubuntuusers.de/WireGuard)): -``` bash +```bash #!/bin/bash # Check state of wg0 interface wgstatus=$(wg) @@ -42,11 +42,11 @@ fi Store this file as `/home/[user name]/wg-restart.sh` and add it to your `crontab`: -``` bash +```bash sudo crontab -e ``` -``` plain +```plain */10 * * * * bash /home/[user name]/wg-restart.sh # Runs the script every 10 minutes ``` @@ -54,7 +54,7 @@ sudo crontab -e Users of NetworkManager should make sure that it is not managing the WireGuard interface(s). For example, create the configuration file `/etc/NetworkManager/conf.d/unmanaged.conf` with content -``` toml +```toml [keyfile] unmanaged-devices=interface-name:wg* ``` @@ -77,7 +77,7 @@ The solution is to use networking software that supports `resolvconf`. Due to too low MTU (lower than 1280), `wg-quick` may fail to create the WireGuard interface. This can be solved by setting the MTU value in WireGuard configuration in Interface section on client: -``` toml +```toml [Interface] MTU = 1500 ``` diff --git a/docs/guides/wireguard/internal.md b/docs/guides/wireguard/internal.md index cbecca0..8884cf6 100644 --- a/docs/guides/wireguard/internal.md +++ b/docs/guides/wireguard/internal.md @@ -4,7 +4,7 @@ Enable IP forwarding on your server by removing the comments in front of -``` toml +```toml net.ipv4.ip_forward = 1 net.ipv6.conf.all.forwarding = 1 ``` @@ -13,13 +13,13 @@ in the file `/etc/sysctl.d/99-sysctl.conf` Then apply the new option with the command below. -``` bash +```bash sudo sysctl -p ``` If you see the options repeated like -``` plain +```plain net.ipv4.ip_forward=1 net.ipv6.conf.all.forwarding = 1 ``` @@ -35,7 +35,7 @@ A properly configured firewall is ***highly*** recommended for any Internet-faci On your server, add the following to the `[INTERFACE]` section of your `/etc/wireguard/wg0.conf`: -``` toml +```toml PostUp = iptables -w -t nat -A POSTROUTING -o eth0 -j MASQUERADE; ip6tables -w -t nat -A POSTROUTING -o eth0 -j MASQUERADE PostDown = iptables -w -t nat -D POSTROUTING -o eth0 -j MASQUERADE; ip6tables -w -t nat -D POSTROUTING -o eth0 -j MASQUERADE ``` @@ -55,14 +55,14 @@ In our standard configuration, we have configured the clients in such a way that Change the allowed addresses in your `/etc/wireguard/wg0.conf` from -``` toml +```toml [Peer] AllowedIPs = 10.100.0.1/32, fd08:4711::1/64 ``` to -``` toml +```toml [Peer] AllowedIPs = 10.100.0.0/24, fd08:4711::/64, 192.168.2.0/24 ``` @@ -73,7 +73,7 @@ assuming your internal network is in the IP range `192.168.2.1` - `192.168.2.254 Do the same you did above for the server also in the `[Interface]` section of all clients you want to have this feature: -``` toml +```toml [Peer] AllowedIPs = 10.0.0.0/24, fd08:4711::/64, 192.168.2.0/24 ``` diff --git a/docs/guides/wireguard/server.md b/docs/guides/wireguard/server.md index 6e74b52..af539bc 100644 --- a/docs/guides/wireguard/server.md +++ b/docs/guides/wireguard/server.md @@ -11,13 +11,13 @@ Installing everything we will need for a `wireguard` connections is as simple as running: -``` bash +```bash sudo apt-get install wireguard wireguard-tools wireguard-dkms ``` For Ubuntu 18.04 and lower, you need to do some extra steps: -``` bash +```bash sudo add-apt-repository ppa:wireguard/wireguard sudo apt update sudo apt install wireguard wireguard-tools wireguard-dkms @@ -32,7 +32,7 @@ If there is no `wireguard` package available for your system, you can follow the ### Update your local system - ``` bash + ```bash sudo apt update && sudo apt upgrade -y ``` @@ -40,19 +40,19 @@ If there is no `wireguard` package available for your system, you can follow the === "Raspberry Pi" - ``` bash + ```bash sudo apt install -y raspberrypi-kernel-headers libelf-dev build-essential pkg-config git ``` === "Linux" - ``` bash + ```bash sudo apt install -y linux-headers-$(uname -r) libelf-dev build-essential libmnl-dev git ``` ## Download and compile the `wireguard` module - ``` bash + ```bash git clone https://git.zx2c4.com/wireguard-linux-compat make -C wireguard-linux-compat/src -j$(nproc) sudo make -C wireguard-linux-compat/src install @@ -60,7 +60,7 @@ If there is no `wireguard` package available for your system, you can follow the You can ignore messages like - ``` plain + ```plain Warning: modules_install: missing 'System.map' file. Skipping depmod. ``` @@ -68,7 +68,7 @@ If there is no `wireguard` package available for your system, you can follow the Run - ``` bash + ```bash sudo modprobe wireguard ``` @@ -76,7 +76,7 @@ If there is no `wireguard` package available for your system, you can follow the ## Download and compile the `wireguard` tools (`wg`, etc.) - ``` bash + ```bash git clone https://git.zx2c4.com/wireguard-tools make -C wireguard-tools/src -j$(nproc) sudo make -C wireguard-tools/src install @@ -91,7 +91,7 @@ Each network interface has a private key and a list of peers. Each peer has a pu First, we create the folder containing our `wireguard` configuration: -``` bash +```bash sudo -i cd /etc/wireguard umask 077 @@ -101,7 +101,7 @@ umask 077 Inhere, we generate a key-pair for the server: -``` bash +```bash wg genkey | tee server.key | wg pubkey > server.pub ``` @@ -109,13 +109,13 @@ wg genkey | tee server.key | wg pubkey > server.pub Create a config file -``` bash +```bash sudo nano /etc/wireguard/wg0.conf ``` and put the following into it: -``` toml +```toml [Interface] Address = 10.100.0.1/24, fd08:4711::1/64 ListenPort = 47111 @@ -123,7 +123,7 @@ ListenPort = 47111 Then run -``` bash +```bash echo "PrivateKey = $(cat server.key)" >> /etc/wireguard/wg0.conf exit # Exit the sudo session ``` @@ -138,7 +138,7 @@ If the server is behind NAT, be sure to forward the specified port on which Wire Register your server `wg0` as: -``` bash +```bash sudo systemctl enable wg-quick@wg0.service sudo systemctl daemon-reload sudo systemctl start wg-quick@wg0 @@ -150,7 +150,7 @@ If successful, you should not see any output. ??? warning "Error: RTNETLINK answers: Operation not supported" In case you get an error like - ``` plain + ```plain RTNETLINK answers: Operation not supported Unable to access interface: Protocol not supported ``` @@ -168,13 +168,13 @@ If successful, you should not see any output. With the following command, you can check if your `wireguard` server is running: -``` bash +```bash sudo wg ``` The output should look like the following: -``` plain +```plain interface: wg0 public key: XYZ123456ABC= ⬅ Your public key will be different private key: (hidden) From 5daa6b0e860c81c0b687fbc096c90112f20b8d77 Mon Sep 17 00:00:00 2001 From: XhmikosR Date: Wed, 21 Oct 2020 09:21:19 +0300 Subject: [PATCH 073/103] Minor grammar fixes --- docs/guides/wireguard/faq.md | 8 ++++---- docs/guides/wireguard/overview.md | 4 ++-- docs/guides/wireguard/route-everything.md | 4 ++-- docs/guides/wireguard/server.md | 6 +++--- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/docs/guides/wireguard/faq.md b/docs/guides/wireguard/faq.md index 0ec039b..916cd2d 100644 --- a/docs/guides/wireguard/faq.md +++ b/docs/guides/wireguard/faq.md @@ -2,12 +2,12 @@ ## Issues with dynamic server IP -Host names cannot be resolved during startup. This may lead to a five minutes delay during boot. A solution to this is to disable the automatic start of the `wg` interface during start and connect only later (manually) when you are sure that you can resolve host names. +Hostnames cannot be resolved during startup. This may lead to a five minutes delay during boot. A solution to this is to disable the automatic start of the `wg` interface during start and connect only later (manually) when you are sure that you can resolve hostnames. 1. Disable `auto wg0` in `/etc/network/interfaces` (put `#` in front, like `#auto wg0`) 2. Start `wireguard` manually using `sudo ifup wg0` -If the IP changes while the connection is running, resolving the new IP address fails otten. Reconnect using +If the IP changes while the connection is running, resolving the new IP address fails often. Reconnect using ```bash sudo ifdown wg0 && sudo ifup wg0 @@ -63,7 +63,7 @@ unmanaged-devices=interface-name:wg* ## Broken DNS resolution -When tunneling all traffic through a WireGuard interface, the connection can become seemingly lost after a while or upon new connection. This could be caused by a network manager or DHCP client overwriting `/etc/resolv.conf`. +When tunneling all traffic through a WireGuard interface, the connection can become seemingly lost after a while or upon a new connection. This could be caused by a network manager or DHCP client overwriting `/etc/resolv.conf`. By default, `wg-quick` uses `resolvconf` to register new DNS entries (from the DNS keyword in the configuration file). This will cause issues with network managers and DHCP clients that do not use `resolvconf`, as they will overwrite `/etc/resolv.conf` thus removing the DNS servers added by `wg-quick`. The solution is to use networking software that supports `resolvconf`. @@ -75,7 +75,7 @@ The solution is to use networking software that supports `resolvconf`. ## Low MTU -Due to too low MTU (lower than 1280), `wg-quick` may fail to create the WireGuard interface. This can be solved by setting the MTU value in WireGuard configuration in Interface section on client: +Due to too low MTU (lower than 1280), `wg-quick` may fail to create the WireGuard interface. This can be solved by setting the MTU value in WireGuard configuration in the Interface section on the client: ```toml [Interface] diff --git a/docs/guides/wireguard/overview.md b/docs/guides/wireguard/overview.md index babbd8d..b24eefe 100644 --- a/docs/guides/wireguard/overview.md +++ b/docs/guides/wireguard/overview.md @@ -1,11 +1,11 @@ ### Remote accessing Pi-hole using WireGuard -WireGuard is an ***extremely simple yet fast and modern VPN*** that utilizes state-of-the-art cryptography. Comparing to other solutions, such as OpenVPN or IPsec, it aims to be **faster, simpler and leaner** while avoiding the massive overhead involved with other VPN solutions. +WireGuard is an ***extremely simple yet fast and modern VPN*** that utilizes state-of-the-art cryptography. Comparing to other solutions, such as OpenVPN or IPsec, it aims to be **faster, simpler, and leaner** while avoiding the massive overhead involved with other VPN solutions. A combination of extremely high-speed cryptographic primitives and the fact that WireGuard lives inside the Linux kernel means that secure networking can be very high-speed. It intends to be considerably more performant than OpenVPN. -WireGuard is designed as a general purpose VPN for running on embedded interfaces and super computers alike, fit for many circumstances. +WireGuard is designed as a general-purpose VPN for running on embedded interfaces and super computers alike, fit for many circumstances. There is no need to manage connections, be concerned about state, manage daemons, or worry about what's under the hood. WireGuard presents an extremely basic yet powerful interface. diff --git a/docs/guides/wireguard/route-everything.md b/docs/guides/wireguard/route-everything.md index cd578a5..7008234 100644 --- a/docs/guides/wireguard/route-everything.md +++ b/docs/guides/wireguard/route-everything.md @@ -1,6 +1,6 @@ # Route the entire Internet traffic through the WireGuard tunnel -Routing your entire Internet traffic is **optional**, however, it can be advantageous in cases where you are expecting eavesdropping on the network. This may not only happen in unsecure open Wi-Fi networks (airports, hotels, trains, etc.) but also in encrypted Wi-Fi networks where the creator of the network can monitor client activity. +Routing your entire Internet traffic is **optional**, however, it can be advantageous in cases where you are expecting eavesdropping on the network. This may not only happen in insecure open Wi-Fi networks (airports, hotels, trains, etc.) but also in encrypted Wi-Fi networks where the creator of the network can monitor client activity. Rerouting the Internet traffic through your Pi-hole will furthermore cause all of your Internet traffic to reach the Internet from the place where your WireGuard server is located. This can be used to obfuscate your real location as well as to be allowed to access geo-blocked content, e.g., when your Pi-hole is located in Germany but you are traveling in the United States. If you want to access a page only accessible from within Germany (like the live-broadcast of Tagesschau, etc.), this will typically not work. However, if you route your entire Internet through your Pi-hole, your network traffic will originate from Germany, allowing you to watch the content. @@ -25,6 +25,6 @@ AllowedIPs = 0.0.0.0/0, ::/0 Do **not** set this on the server in the `[Interface]` section. WireGuard will automatically take care of setting up [correct routing](https://www.wireguard.com/netns/#routing-all-your-traffic) so that networking still functions on all your clients. -That's all you need to do. You should use an online check (e.g. www.wieistmeineip.de) to check if your IP changed to the public IP address of your WireGuard server after this change up. It is possible to add this change only for a few clients, leaving the others without a full tunnel for all traffic (e.g., where this is not necessary or not desired). +That's all you need to do. You should use an online check (e.g. www.wieistmeineip.de) to check if your IP changed to the public IP address of your WireGuard server after this change. It is possible to add this change only for a few clients, leaving the others without a full tunnel for all traffic (e.g., where this is not necessary or not desired). {!abbreviations.md!} diff --git a/docs/guides/wireguard/server.md b/docs/guides/wireguard/server.md index af539bc..9ffb926 100644 --- a/docs/guides/wireguard/server.md +++ b/docs/guides/wireguard/server.md @@ -4,7 +4,7 @@ !!! info "The terms "server" and "client"" Usage of the terms `server` and `client` were purposefully chosen in this guide specifically to help both new users and existing OpenVPN users become familiar with the construction of WireGuard's configuration files. - WireGuard itself simply refers to all connected devices as `peers`. It consitutes a connection between computers. + WireGuard itself simply refers to all connected devices as `peers`. It constitutes a connection between computers. ## Installing the server components @@ -181,11 +181,11 @@ interface: wg0 listening port: 47111 ``` -Your public key will be different to ours. This is expected (you just created your own key above). +Your public key will be different from ours. This is expected (you just created your own key above). ## Set your Pi-hole to listen on all interfaces -On your [Settings page (tab DNS)](http://pi.hole/admin/settings.php?tab=dns), ensure you set the listing mode of your Pi-hole to one of the `Listen of all interfaces` settings. The top one is perferred as it adds a bit of additional safety. Your WireGuard peers/clients will be correctly recognized as being only one hop away. +On your [Settings page (tab DNS)](http://pi.hole/admin/settings.php?tab=dns), ensure you set the listing mode of your Pi-hole to one of the `Listen of all interfaces` settings. The top one is preferred as it adds a bit of additional safety. Your WireGuard peers/clients will be correctly recognized as being only one hop away. You can now continue to add clients. From c1853a9f8493a434fb1cb1d1f6e0264015fd9796 Mon Sep 17 00:00:00 2001 From: DL6ER Date: Sun, 25 Oct 2020 20:25:44 +0100 Subject: [PATCH 074/103] Use bash instead of toml as syntax highlighting scheme for WireGuard configuration Signed-off-by: DL6ER --- docs/guides/wireguard/client.md | 4 ++-- docs/guides/wireguard/faq.md | 4 ++-- docs/guides/wireguard/internal.md | 14 +++++++------- docs/guides/wireguard/route-everything.md | 2 +- docs/guides/wireguard/server.md | 2 +- 5 files changed, 13 insertions(+), 13 deletions(-) diff --git a/docs/guides/wireguard/client.md b/docs/guides/wireguard/client.md index cc476e3..1b84c4b 100644 --- a/docs/guides/wireguard/client.md +++ b/docs/guides/wireguard/client.md @@ -80,7 +80,7 @@ systemctl restart wg-quick@wg0 After a restart, the server file should look like: -```toml +```bash [Interface] Address = 10.100.0.1/24, fd08::1/128 ListenPort = 47111 @@ -132,7 +132,7 @@ echo "PrivateKey = $(cat "${name}.key")" >> "${name}.conf" Next, add your server as peer for this client: -```toml +```bash [Peer] AllowedIPs = 10.100.0.0/24, fd08::/64 Endpoint = [your public IP or domain]:47111 diff --git a/docs/guides/wireguard/faq.md b/docs/guides/wireguard/faq.md index 916cd2d..8213254 100644 --- a/docs/guides/wireguard/faq.md +++ b/docs/guides/wireguard/faq.md @@ -54,7 +54,7 @@ sudo crontab -e Users of NetworkManager should make sure that it is not managing the WireGuard interface(s). For example, create the configuration file `/etc/NetworkManager/conf.d/unmanaged.conf` with content -```toml +```bash [keyfile] unmanaged-devices=interface-name:wg* ``` @@ -77,7 +77,7 @@ The solution is to use networking software that supports `resolvconf`. Due to too low MTU (lower than 1280), `wg-quick` may fail to create the WireGuard interface. This can be solved by setting the MTU value in WireGuard configuration in the Interface section on the client: -```toml +```bash [Interface] MTU = 1500 ``` diff --git a/docs/guides/wireguard/internal.md b/docs/guides/wireguard/internal.md index 8884cf6..7a22eba 100644 --- a/docs/guides/wireguard/internal.md +++ b/docs/guides/wireguard/internal.md @@ -4,7 +4,7 @@ Enable IP forwarding on your server by removing the comments in front of -```toml +```bash net.ipv4.ip_forward = 1 net.ipv6.conf.all.forwarding = 1 ``` @@ -19,8 +19,8 @@ sudo sysctl -p If you see the options repeated like -```plain -net.ipv4.ip_forward=1 +```bash +net.ipv4.ip_forward = 1 net.ipv6.conf.all.forwarding = 1 ``` @@ -35,7 +35,7 @@ A properly configured firewall is ***highly*** recommended for any Internet-faci On your server, add the following to the `[INTERFACE]` section of your `/etc/wireguard/wg0.conf`: -```toml +```bash PostUp = iptables -w -t nat -A POSTROUTING -o eth0 -j MASQUERADE; ip6tables -w -t nat -A POSTROUTING -o eth0 -j MASQUERADE PostDown = iptables -w -t nat -D POSTROUTING -o eth0 -j MASQUERADE; ip6tables -w -t nat -D POSTROUTING -o eth0 -j MASQUERADE ``` @@ -55,14 +55,14 @@ In our standard configuration, we have configured the clients in such a way that Change the allowed addresses in your `/etc/wireguard/wg0.conf` from -```toml +```bash [Peer] AllowedIPs = 10.100.0.1/32, fd08:4711::1/64 ``` to -```toml +```bash [Peer] AllowedIPs = 10.100.0.0/24, fd08:4711::/64, 192.168.2.0/24 ``` @@ -73,7 +73,7 @@ assuming your internal network is in the IP range `192.168.2.1` - `192.168.2.254 Do the same you did above for the server also in the `[Interface]` section of all clients you want to have this feature: -```toml +```bash [Peer] AllowedIPs = 10.0.0.0/24, fd08:4711::/64, 192.168.2.0/24 ``` diff --git a/docs/guides/wireguard/route-everything.md b/docs/guides/wireguard/route-everything.md index 7008234..5f69bf4 100644 --- a/docs/guides/wireguard/route-everything.md +++ b/docs/guides/wireguard/route-everything.md @@ -16,7 +16,7 @@ Rerouting the Internet traffic through your Pi-hole will furthermore cause all o To route all traffic through the tunnel to a specific peer, add the default route (`0.0.0.0/0` for IPv4 and `::/0`for IPv6) to `AllowedIPs` in your clients's WireGuard config files: -```toml +```bash AllowedIPs = 0.0.0.0/0, ::/0 ``` diff --git a/docs/guides/wireguard/server.md b/docs/guides/wireguard/server.md index 9ffb926..455af07 100644 --- a/docs/guides/wireguard/server.md +++ b/docs/guides/wireguard/server.md @@ -115,7 +115,7 @@ sudo nano /etc/wireguard/wg0.conf and put the following into it: -```toml +```bash [Interface] Address = 10.100.0.1/24, fd08:4711::1/64 ListenPort = 47111 From 053ee1e72db1187b8d2142c9f45bec27207dca43 Mon Sep 17 00:00:00 2001 From: DL6ER Date: Fri, 1 Jan 2021 21:53:15 +0100 Subject: [PATCH 075/103] Improve guide by adding exemplary modified config files in the optional sections and remove the debated highlighting (use plain for all the Wireguard config files) Signed-off-by: DL6ER --- docs/guides/wireguard/client.md | 30 ++++---- docs/guides/wireguard/faq.md | 12 ++-- docs/guides/wireguard/internal.md | 85 +++++++++++++---------- docs/guides/wireguard/route-everything.md | 21 +++++- docs/guides/wireguard/server.md | 26 ++++--- 5 files changed, 107 insertions(+), 67 deletions(-) diff --git a/docs/guides/wireguard/client.md b/docs/guides/wireguard/client.md index 1b84c4b..66d353b 100644 --- a/docs/guides/wireguard/client.md +++ b/docs/guides/wireguard/client.md @@ -6,7 +6,7 @@ For each new client, the following steps must be taken. For the sake of simplici ??? info "All commands described below at once" - ```bash + ``` bash sudo -i cd /etc/wireguard umask 077 @@ -40,7 +40,7 @@ For each new client, the following steps must be taken. For the sake of simplici We generate a key-pair for the client `NAME` (replace accordingly everywhere below): -```bash +``` bash sudo -i cd /etc/wireguard umask 077 @@ -52,7 +52,7 @@ wg genkey | tee "${name}.key" | wg pubkey > "${name}.pub" We furthermore recommend generating a pre-shared key (PSK) in addition to the keys above. This adds an additional layer of symmetric-key cryptography to be mixed into the already existing public-key cryptography and is mainly for post-quantum resistance. A pre-shared key should be generated for each peer pair and *should not be reused*. -```bash +``` bash wg genpsk > "${name}.psk" ``` @@ -60,7 +60,7 @@ wg genpsk > "${name}.psk" Add the new client by running the command: -```bash +``` bash echo "[Peer]" >> /etc/wireguard/wg0.conf echo "PublicKey = $(cat "${name}.pub")" >> /etc/wireguard/wg0.conf echo "PresharedKey = $(cat "${name}.psk")" >> /etc/wireguard/wg0.conf @@ -74,13 +74,13 @@ echo "AllowedIPs = 10.100.0.2/32, fd08:4711::2/128" >> /etc/wireguard/wg0.conf Restart your server to load the new client config: -```bash +``` bash systemctl restart wg-quick@wg0 ``` After a restart, the server file should look like: -```bash +``` plain [Interface] Address = 10.100.0.1/24, fd08::1/128 ListenPort = 47111 @@ -97,13 +97,13 @@ AllowedIPs = 10.100.0.2/32, fd08:4711::2/128 The command -```bash +``` bash wg ``` should tell you about your new client: -```plain +``` plain interface: wg0 public key: XYZ123456ABC= ⬅ Your server's public key will be different private key: (hidden) @@ -118,7 +118,7 @@ peer: F+80gbmHVlOrU+es13S18oMEX2g= ⬅ Your peer's public key will be differen Create a dedicated config file for your new client: -```bash +``` bash echo "[Interface]" > "${name}.conf" echo "Address = 10.100.0.2/32, fd08:4711::2/128" >> "${name}.conf" # May need editing echo "DNS = 10.100.0.1" >> "${name}.conf" # Your Pi-hole's IP @@ -126,13 +126,13 @@ echo "DNS = 10.100.0.1" >> "${name}.conf" # Your Pi-hol and add the private key of this client -```bash +``` bash echo "PrivateKey = $(cat "${name}.key")" >> "${name}.conf" ``` Next, add your server as peer for this client: -```bash +``` plain [Peer] AllowedIPs = 10.100.0.0/24, fd08::/64 Endpoint = [your public IP or domain]:47111 @@ -141,7 +141,7 @@ PersistentKeepalive = 25 Then add the public key of the server as well as the PSK for this connection: -```bash +``` bash echo "PublicKey = $(cat server.pub)" >> "${name}.conf" echo "PresharedKey = $(cat "${name}.psk")" >> "${name}.conf" exit @@ -166,7 +166,7 @@ That's it. You can now copy the configuration file to your client (if you created the config on the server). If the client is a mobile device such as a phone, `qrencode` can be used to generate a scanable QR code: -```bash +``` bash sudo qrencode -t ansiutf8 -r "/etc/wireguard/${name}.conf" ``` @@ -180,13 +180,13 @@ After creating/copying the connection information over to your client, you may u You can check if your client successfully connected by, once again, running -```plain +``` bash sudo wg ``` on the server. It should show some traffic for your client if everything works: -```plain +``` plain interface: wg0 public key: XYZ123456ABC= ⬅ Your server's public key will be different private key: (hidden) diff --git a/docs/guides/wireguard/faq.md b/docs/guides/wireguard/faq.md index 8213254..03198cd 100644 --- a/docs/guides/wireguard/faq.md +++ b/docs/guides/wireguard/faq.md @@ -9,13 +9,13 @@ Hostnames cannot be resolved during startup. This may lead to a five minutes del If the IP changes while the connection is running, resolving the new IP address fails often. Reconnect using -```bash +``` bash sudo ifdown wg0 && sudo ifup wg0 ``` To achieve a permanent solution, one can install a `cron` job which restarts the connection automatically whenever a change is detected. This avoids excessive restarts of the interface. Example script (taken from [Ubuntuusers Wiki](https://wiki.ubuntuusers.de/WireGuard)): -```bash +``` bash #!/bin/bash # Check state of wg0 interface wgstatus=$(wg) @@ -42,11 +42,11 @@ fi Store this file as `/home/[user name]/wg-restart.sh` and add it to your `crontab`: -```bash +``` bash sudo crontab -e ``` -```plain +``` plain */10 * * * * bash /home/[user name]/wg-restart.sh # Runs the script every 10 minutes ``` @@ -54,7 +54,7 @@ sudo crontab -e Users of NetworkManager should make sure that it is not managing the WireGuard interface(s). For example, create the configuration file `/etc/NetworkManager/conf.d/unmanaged.conf` with content -```bash +``` bash [keyfile] unmanaged-devices=interface-name:wg* ``` @@ -77,7 +77,7 @@ The solution is to use networking software that supports `resolvconf`. Due to too low MTU (lower than 1280), `wg-quick` may fail to create the WireGuard interface. This can be solved by setting the MTU value in WireGuard configuration in the Interface section on the client: -```bash +``` bash [Interface] MTU = 1500 ``` diff --git a/docs/guides/wireguard/internal.md b/docs/guides/wireguard/internal.md index 7a22eba..3efd998 100644 --- a/docs/guides/wireguard/internal.md +++ b/docs/guides/wireguard/internal.md @@ -4,7 +4,7 @@ Enable IP forwarding on your server by removing the comments in front of -```bash +``` plain net.ipv4.ip_forward = 1 net.ipv6.conf.all.forwarding = 1 ``` @@ -13,13 +13,13 @@ in the file `/etc/sysctl.d/99-sysctl.conf` Then apply the new option with the command below. -```bash +``` bash sudo sysctl -p ``` If you see the options repeated like -```bash +``` plain net.ipv4.ip_forward = 1 net.ipv6.conf.all.forwarding = 1 ``` @@ -30,9 +30,6 @@ A properly configured firewall is ***highly*** recommended for any Internet-faci ## Enable NAT on the server -!!! info "Optional for NAT" - If the server is behind a router and receives traffic via NAT, these iptables rules are not needed. - On your server, add the following to the `[INTERFACE]` section of your `/etc/wireguard/wg0.conf`: ```bash @@ -40,43 +37,59 @@ PostUp = iptables -w -t nat -A POSTROUTING -o eth0 -j MASQUERADE; ip6tables -w - PostDown = iptables -w -t nat -D POSTROUTING -o eth0 -j MASQUERADE; ip6tables -w -t nat -D POSTROUTING -o eth0 -j MASQUERADE ``` -!!! warning "Substitute interface" - Substitute `eth0` in the preceding lines to match the Internet-facing interface. +!!! warning "**Important:** Substitute interface" + **Without the correct interface name, this will not work!** -??? info "The `PostUp` and `PostDown` options" - `PostUp` and `PostDown` defines steps to be run after the interface is turned on or off, respectively. In this case, iptables is used to set Linux IP masquerade rules to allow all the clients to share the server’s IPv4 and IPv6 address. - The rules will then be cleared once the tunnel is down. + Substitute `eth0` in the preceding lines to match the Internet-facing interface. This may be `ens2p0` or similar on more recent Ubuntu versions (check, e.g., `ip a` for details about your local interfaces). + +`PostUp` and `PostDown` defines steps to be run after the interface is turned on or off, respectively. In this case, iptables is used to set Linux IP masquerade rules to allow all the clients to share the server’s IPv4 and IPv6 address. +The rules will then be cleared once the tunnel is down. + +??? info "Exemplary server config file with this change" + ``` plain + [Interface] + PrivateKey = [your server's private key] + Address = [Wireguard-internal IPs of the server, e.g. 10.100.0.1/24, fd08:4711::1/64] + ListenPort = 47111 + + PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -A FORWARD -o %i -j ACCEPT; iptables -t nat -A POSTROUTING -o enp2s0 -j MASQUERADE + PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -D FORWARD -o %i -j ACCEPT; iptables -t nat -D POSTROUTING -o enp2s0 -j MASQUERADE + + # Android phone + [Peer] + PublicKey = [public key of this client] + PresharedKey = [pre-shared key of this client] + AllowedIPs = [Wireguard-internal IP of this client, e.g., 10.100.0.2/32, fd08:4711::2/128] + + # maybe more [Peer] sections for more clients + ``` + + The important change is the extra PostUp` and `PostDown` in the `[Interface]` section. ## Allow clients to access other devices -In our standard configuration, we have configured the clients in such a way that they can only speak to the server. This has to be changed on both the server and the clients. +In our standard configuration, we have configured the clients in such a way that they can only speak to the server. Add the network range of your local network in CIDR notation (e.g., `192.168.2.1 - 192.168.2.254` -> `192.168.2.0/24`) in the `[Peers]` section of all clients you want to have this feature: -### Server side - -Change the allowed addresses in your `/etc/wireguard/wg0.conf` from - -```bash -[Peer] -AllowedIPs = 10.100.0.1/32, fd08:4711::1/64 -``` - -to - -```bash -[Peer] -AllowedIPs = 10.100.0.0/24, fd08:4711::/64, 192.168.2.0/24 -``` - -assuming your internal network is in the IP range `192.168.2.1` - `192.168.2.254`. The change `10.100.0.1/32` to `10.100.0.0/24` also allows your WireGuard peers to see each other. - -### Client side - -Do the same you did above for the server also in the `[Interface]` section of all clients you want to have this feature: - -```bash +``` plain [Peer] AllowedIPs = 10.0.0.0/24, fd08:4711::/64, 192.168.2.0/24 ``` - It is possible to add this only for a few clients, leaving the others isolated to only the Pi-hole server itself. + +??? info "Exemplary client config file with this change" + ``` plain + [Interface] + PrivateKey = [your client's private key] + Address = [Wireguard-internal IPs of your client, e.g. 10.100.0.2/32, fd08:4711::2/128] + DNS = 10.100.0.1 + + [Peer] + AllowedIPs = 10.100.0.0/24, fd08::/64, 192.168.2.0/24 + Endpoint = [your server's public IP or domain]:47111 + PublicKey = [public key of the server] + PresharedKey = [pre-shared key of this client] + PersistentKeepalive = 25 + ``` + + The important change is the extra `192.168.2.0/24` at the end of the `[Peer] -> AllowedIPs` entry. diff --git a/docs/guides/wireguard/route-everything.md b/docs/guides/wireguard/route-everything.md index 5f69bf4..2048375 100644 --- a/docs/guides/wireguard/route-everything.md +++ b/docs/guides/wireguard/route-everything.md @@ -14,12 +14,29 @@ Rerouting the Internet traffic through your Pi-hole will furthermore cause all o The following assumes you have already prepared your Pi-hole for [IP forwarding](internal.md#enable-ip-forwarding-on-the-server) and [enabled NAT](internal.md#enable-nat-on-the-server). If this is not the case, follow the steps over there before continuing here. -To route all traffic through the tunnel to a specific peer, add the default route (`0.0.0.0/0` for IPv4 and `::/0`for IPv6) to `AllowedIPs` in your clients's WireGuard config files: +To route all traffic through the tunnel to a specific peer, add the default route (`0.0.0.0/0` for IPv4 and `::/0`for IPv6) to `AllowedIPs` in the `[Peer]` section of your clients's WireGuard config files: -```bash +``` plain AllowedIPs = 0.0.0.0/0, ::/0 ``` +??? info "Exemplary client config file with this change" + ``` plain + [Interface] + PrivateKey = [your client's private key] + Address = [Wireguard-internal IPs of your client, e.g. 10.100.0.2/32, fd08:4711::2/128] + DNS = 10.100.0.1 + + [Peer] + AllowedIPs = 0.0.0.0/0, ::/0 + Endpoint = [your server's public IP or domain]:47111 + PublicKey = [public key of the server] + PresharedKey = [pre-shared key of this client] + PersistentKeepalive = 25 + ``` + + The important change is setting the `[Peer] -> AllowedIPs` entry to `0.0.0.0/0, ::/0` + !!! warning "Change this setting only on your clients" Do **not** set this on the server in the `[Interface]` section. WireGuard will automatically take care of setting up [correct routing](https://www.wireguard.com/netns/#routing-all-your-traffic) so that networking still functions on all your clients. diff --git a/docs/guides/wireguard/server.md b/docs/guides/wireguard/server.md index 455af07..cc8e83b 100644 --- a/docs/guides/wireguard/server.md +++ b/docs/guides/wireguard/server.md @@ -109,13 +109,13 @@ wg genkey | tee server.key | wg pubkey > server.pub Create a config file -```bash +``` bash sudo nano /etc/wireguard/wg0.conf ``` and put the following into it: -```bash +``` plain [Interface] Address = 10.100.0.1/24, fd08:4711::1/64 ListenPort = 47111 @@ -123,7 +123,7 @@ ListenPort = 47111 Then run -```bash +``` bash echo "PrivateKey = $(cat server.key)" >> /etc/wireguard/wg0.conf exit # Exit the sudo session ``` @@ -138,7 +138,7 @@ If the server is behind NAT, be sure to forward the specified port on which Wire Register your server `wg0` as: -```bash +``` bash sudo systemctl enable wg-quick@wg0.service sudo systemctl daemon-reload sudo systemctl start wg-quick@wg0 @@ -150,31 +150,41 @@ If successful, you should not see any output. ??? warning "Error: RTNETLINK answers: Operation not supported" In case you get an error like - ```plain + ``` plain RTNETLINK answers: Operation not supported Unable to access interface: Protocol not supported ``` you should check that the WireGuard kernel module is loaded with the command below: - ```bash + ``` bash sudo modprobe wireguard ``` If you get an error saying the module is missing, try reinstalling WireGuard or restart your server and try again. This may happen when the WireGuard server is installed for a more recent kernel than you are currently running. This typically happens when you have neither updated nor restarted your system for a long time. + +??? warning "Error: RTNETLINK answers: File exists" + In case you get an error like + + ``` plain + RTNETLINK answers: File exists + ``` + + you need to check the configured IP addresses (check the CIDR notation). Overlapping IP address ranges cause this error when trying to register a router for an address where a a route already exists. This is meaningful and always an error in your configuration. However, the error message could be more clear about this. + ## Check everything is running With the following command, you can check if your `wireguard` server is running: -```bash +``` bash sudo wg ``` The output should look like the following: -```plain +``` plain interface: wg0 public key: XYZ123456ABC= ⬅ Your public key will be different private key: (hidden) From a5df3c5ed241b7a6c9f607716767a5951c455cd9 Mon Sep 17 00:00:00 2001 From: DL6ER Date: Sat, 2 Jan 2021 10:06:31 +0100 Subject: [PATCH 076/103] markdownlint changes Signed-off-by: DL6ER --- docs/guides/wireguard/internal.md | 11 ++++++++--- docs/guides/wireguard/route-everything.md | 2 +- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/docs/guides/wireguard/internal.md b/docs/guides/wireguard/internal.md index 3efd998..f361071 100644 --- a/docs/guides/wireguard/internal.md +++ b/docs/guides/wireguard/internal.md @@ -37,24 +37,27 @@ PostUp = iptables -w -t nat -A POSTROUTING -o eth0 -j MASQUERADE; ip6tables -w - PostDown = iptables -w -t nat -D POSTROUTING -o eth0 -j MASQUERADE; ip6tables -w -t nat -D POSTROUTING -o eth0 -j MASQUERADE ``` + !!! warning "**Important:** Substitute interface" **Without the correct interface name, this will not work!** Substitute `eth0` in the preceding lines to match the Internet-facing interface. This may be `ens2p0` or similar on more recent Ubuntu versions (check, e.g., `ip a` for details about your local interfaces). + `PostUp` and `PostDown` defines steps to be run after the interface is turned on or off, respectively. In this case, iptables is used to set Linux IP masquerade rules to allow all the clients to share the server’s IPv4 and IPv6 address. The rules will then be cleared once the tunnel is down. + ??? info "Exemplary server config file with this change" ``` plain [Interface] PrivateKey = [your server's private key] Address = [Wireguard-internal IPs of the server, e.g. 10.100.0.1/24, fd08:4711::1/64] ListenPort = 47111 - + PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -A FORWARD -o %i -j ACCEPT; iptables -t nat -A POSTROUTING -o enp2s0 -j MASQUERADE PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -D FORWARD -o %i -j ACCEPT; iptables -t nat -D POSTROUTING -o enp2s0 -j MASQUERADE - + # Android phone [Peer] PublicKey = [public key of this client] @@ -65,7 +68,7 @@ The rules will then be cleared once the tunnel is down. ``` The important change is the extra PostUp` and `PostDown` in the `[Interface]` section. - + ## Allow clients to access other devices In our standard configuration, we have configured the clients in such a way that they can only speak to the server. Add the network range of your local network in CIDR notation (e.g., `192.168.2.1 - 192.168.2.254` -> `192.168.2.0/24`) in the `[Peers]` section of all clients you want to have this feature: @@ -77,6 +80,7 @@ AllowedIPs = 10.0.0.0/24, fd08:4711::/64, 192.168.2.0/24 It is possible to add this only for a few clients, leaving the others isolated to only the Pi-hole server itself. + ??? info "Exemplary client config file with this change" ``` plain [Interface] @@ -93,3 +97,4 @@ It is possible to add this only for a few clients, leaving the others isolated t ``` The important change is the extra `192.168.2.0/24` at the end of the `[Peer] -> AllowedIPs` entry. + diff --git a/docs/guides/wireguard/route-everything.md b/docs/guides/wireguard/route-everything.md index 2048375..6aa4d83 100644 --- a/docs/guides/wireguard/route-everything.md +++ b/docs/guides/wireguard/route-everything.md @@ -20,6 +20,7 @@ To route all traffic through the tunnel to a specific peer, add the default rout AllowedIPs = 0.0.0.0/0, ::/0 ``` + ??? info "Exemplary client config file with this change" ``` plain [Interface] @@ -37,7 +38,6 @@ AllowedIPs = 0.0.0.0/0, ::/0 The important change is setting the `[Peer] -> AllowedIPs` entry to `0.0.0.0/0, ::/0` - !!! warning "Change this setting only on your clients" Do **not** set this on the server in the `[Interface]` section. WireGuard will automatically take care of setting up [correct routing](https://www.wireguard.com/netns/#routing-all-your-traffic) so that networking still functions on all your clients. From 8b137b49f0c7bff271461745adf5c50ad344bba5 Mon Sep 17 00:00:00 2001 From: DL6ER Date: Mon, 4 Jan 2021 10:27:35 +0100 Subject: [PATCH 077/103] Add more description what NAT is Signed-off-by: DL6ER --- docs/abbreviations.md | 1 + docs/guides/wireguard/server.md | 6 +++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/docs/abbreviations.md b/docs/abbreviations.md index 31548b7..44e0007 100644 --- a/docs/abbreviations.md +++ b/docs/abbreviations.md @@ -38,3 +38,4 @@ *[SSH]: Secure Shell is a cryptographic network protocol for operating network services securely over an unsecured network *[TFTP]: Trivial File Transfer Protocol is a simple lockstep File Transfer Protocol which allows a client to get a file from or put a file onto a remote host *[TTL]: Time-To-Live is a mechanism that limits the lifespan or lifetime of data in a computer or network +*[NAT]: Network address translation diff --git a/docs/guides/wireguard/server.md b/docs/guides/wireguard/server.md index cc8e83b..fe4ffa1 100644 --- a/docs/guides/wireguard/server.md +++ b/docs/guides/wireguard/server.md @@ -132,7 +132,11 @@ to copy the server's private key into your config file. ## Forward port -If the server is behind NAT, be sure to forward the specified port on which WireGuard will be running (for this example, `47111/UDP`) from the router to the WireGuard server. +If the server is behind a device, e.g., a router that is doing NAT, be sure to forward the specified port on which WireGuard will be running (for this example, `47111/UDP`) from the router to the WireGuard server. + +??? info "NAT: Network address translation" + Network address translation modifies network packages. Incoming connection requests have their destination address rewritten to a different one. + NAT involves more than just changing the IP addresses. For instance, when mapping address `1.2.3.4` to `5.6.7.8`, there is no need to add a rule to do the reverse translation. A `netfilter` system called `conntrack` recognizes packets that are replies to an existing connection. Each connection has its own NAT state attached to it. Reverse translation is done automatically. ## Start the server From 7a3b000c29dc0d683b54dc164d5a07ccd4c530f1 Mon Sep 17 00:00:00 2001 From: DL6ER Date: Mon, 4 Jan 2021 10:56:29 +0100 Subject: [PATCH 078/103] Add DynDNS recommendation/documentation Signed-off-by: DL6ER --- docs/abbreviations.md | 1 + docs/guides/wireguard/server.md | 33 ++++++++++++++++++++++++++++++++- 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/docs/abbreviations.md b/docs/abbreviations.md index 44e0007..d4af635 100644 --- a/docs/abbreviations.md +++ b/docs/abbreviations.md @@ -39,3 +39,4 @@ *[TFTP]: Trivial File Transfer Protocol is a simple lockstep File Transfer Protocol which allows a client to get a file from or put a file onto a remote host *[TTL]: Time-To-Live is a mechanism that limits the lifespan or lifetime of data in a computer or network *[NAT]: Network address translation +*[DnyDNS]: Dynamic DNS record pointing to a frequently changing IP address diff --git a/docs/guides/wireguard/server.md b/docs/guides/wireguard/server.md index fe4ffa1..d5a6ed2 100644 --- a/docs/guides/wireguard/server.md +++ b/docs/guides/wireguard/server.md @@ -130,7 +130,7 @@ exit # Exit the sudo session to copy the server's private key into your config file. -## Forward port +## Forward port on your router If the server is behind a device, e.g., a router that is doing NAT, be sure to forward the specified port on which WireGuard will be running (for this example, `47111/UDP`) from the router to the WireGuard server. @@ -138,6 +138,37 @@ If the server is behind a device, e.g., a router that is doing NAT, be sure to f Network address translation modifies network packages. Incoming connection requests have their destination address rewritten to a different one. NAT involves more than just changing the IP addresses. For instance, when mapping address `1.2.3.4` to `5.6.7.8`, there is no need to add a rule to do the reverse translation. A `netfilter` system called `conntrack` recognizes packets that are replies to an existing connection. Each connection has its own NAT state attached to it. Reverse translation is done automatically. +## Set up a domain name for your router + +When connecting from outside your network, you'll need to know the public IP address of your router to connect. However, as most households are getting dynamically-assigned public IP addresses (these addresses change periodically), you need to note down the address every day before leaving the house. Since this is obviously *very* uncomfortable, we strongly suggest registering a *dynamic host record* (often called "[DynDNS](https://en.wikipedia.org/wiki/Dynamic_DNS)" record). + +There are many excellent guide and a lot of services offer this for free (with more or less comfort). We suggest a few providers below, however, this list is neither absolute nor exhaustive: + + +??? info "DynDNS providers" + - [Strato.de](https://www.strato.de/hosting/dynamic-dns-free/) (Guides: [EN](https://www.strato.com/faq/en_us/domain/this-is-how-easy-it-is-to-set-up-dyndns-for-your-domains/) / [DE](https://www.strato.de/faq/domains/so-einfach-richten-sie-dyndns-fuer-ihre-domains-ein/)) + + If you already have a hosting package at Strato, you can easily set up a subdomain to be used as DynDNS record. This is entirely free for members. + + - [DNSHome.de](DNSHome.de) + + This provider offers you several free subdomains under different domain names. SSL and also IPv6 are possible. DNSSEC is activated by default. They offer configuration guides for the Fritz!Box and also `ddclient` (update tool for Windows and Linux) on the website. + + - [GoIP.de](http://www.goip.de/) + + Go IP is a German DynDNS provider. The service is completely free and allows the registration of one domain and up to 15 subdomains per person. The website is characterized by extensive help with setting up the router. + + - [noip.com](https://www.noip.com/support/knowledgebase/getting-started-with-no-ip-com/) + + You can up to three hostnames like `myname.no-ip.org` for free. A disadvantage is that you have to confirm the domains at least every 30 days, otherwise they will be deleted. + + - [Dyn.com](https://account.dyn.com/) + + One of the first providers to offer DynDNS was the American company Dyn, whose product "DynDNS" gave its name to an entire service branch. In the meantime, numerous successors whose services are often free of charge came up. DynDNS service is especially easy to use is if it is directly supported by the router. + + +You can either use the methods the corresponding providers recommend or use existing DynDNS solutions inbuilt in your router (if available). Most providers are compatible with, e.g., the popular Fritz!Box routers ([EN](https://en.avm.de/service/fritzbox/fritzbox-4040/knowledge-base/publication/show/30_Setting-up-dynamic-DNS-in-the-FRITZ-Box/) / [DE](https://avm.de/service/fritzbox/fritzbox-7590/wissensdatenbank/publication/show/30_Dynamic-DNS-in-FRITZ-Box-einrichten/)). + ## Start the server Register your server `wg0` as: From af497e9fd95c276db1ee9b6bdf188982b121f34e Mon Sep 17 00:00:00 2001 From: DL6ER Date: Mon, 4 Jan 2021 11:03:08 +0100 Subject: [PATCH 079/103] Suggest DELAY_STARTUP in the FAQ section Signed-off-by: DL6ER --- docs/guides/wireguard/faq.md | 10 ++++++++++ docs/guides/wireguard/server.md | 4 ++-- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/docs/guides/wireguard/faq.md b/docs/guides/wireguard/faq.md index 03198cd..f6d9689 100644 --- a/docs/guides/wireguard/faq.md +++ b/docs/guides/wireguard/faq.md @@ -83,3 +83,13 @@ MTU = 1500 ``` [source](https://wiki.archlinux.org/index.php/WireGuard) + +## Pi-hole not listening on `wg0` after reboot + +If, e.g., after reboot, the `wg0` interface isn't up before Pi-hole is ready (more precisely, the `pihole-FTL` service is started), you may experience that Pi-hole doesn't listen on the Wireguard interface. This can be mitigated by artificially delaying the start of Pi-hole using, e.g., the config option + +``` plain +DELAY_STARTUP=5 +``` + +in `/etc/pihole/pihole-FTL.conf` to have Pi-hole delay the start of the DNS server by `5` seconds. diff --git a/docs/guides/wireguard/server.md b/docs/guides/wireguard/server.md index d5a6ed2..e1b1c6c 100644 --- a/docs/guides/wireguard/server.md +++ b/docs/guides/wireguard/server.md @@ -150,11 +150,11 @@ There are many excellent guide and a lot of services offer this for free (with m If you already have a hosting package at Strato, you can easily set up a subdomain to be used as DynDNS record. This is entirely free for members. - - [DNSHome.de](DNSHome.de) + - [DNSHome.de](https://DNSHome.de) This provider offers you several free subdomains under different domain names. SSL and also IPv6 are possible. DNSSEC is activated by default. They offer configuration guides for the Fritz!Box and also `ddclient` (update tool for Windows and Linux) on the website. - - [GoIP.de](http://www.goip.de/) + - [GoIP.de](https://www.goip.de/) Go IP is a German DynDNS provider. The service is completely free and allows the registration of one domain and up to 15 subdomains per person. The website is characterized by extensive help with setting up the router. From 3bdc419a627ca9854e83d30f5cd09601fb5f31bc Mon Sep 17 00:00:00 2001 From: DL6ER Date: Mon, 4 Jan 2021 11:10:55 +0100 Subject: [PATCH 080/103] Minor grammar adjustments Signed-off-by: DL6ER --- docs/guides/wireguard/server.md | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/docs/guides/wireguard/server.md b/docs/guides/wireguard/server.md index e1b1c6c..a8be67e 100644 --- a/docs/guides/wireguard/server.md +++ b/docs/guides/wireguard/server.md @@ -136,19 +136,21 @@ If the server is behind a device, e.g., a router that is doing NAT, be sure to f ??? info "NAT: Network address translation" Network address translation modifies network packages. Incoming connection requests have their destination address rewritten to a different one. - NAT involves more than just changing the IP addresses. For instance, when mapping address `1.2.3.4` to `5.6.7.8`, there is no need to add a rule to do the reverse translation. A `netfilter` system called `conntrack` recognizes packets that are replies to an existing connection. Each connection has its own NAT state attached to it. Reverse translation is done automatically. + NAT involves more than just changing the IP addresses. For instance, when mapping address `1.2.3.4` to `5.6.7.8`, there is no need to add a rule to do the reverse translation. A `netfilter` system called `conntrack` recognizes packets that are replies to an existing connection. Each connection has its own NAT state attached to it. The reverse translation is done automatically. ## Set up a domain name for your router -When connecting from outside your network, you'll need to know the public IP address of your router to connect. However, as most households are getting dynamically-assigned public IP addresses (these addresses change periodically), you need to note down the address every day before leaving the house. Since this is obviously *very* uncomfortable, we strongly suggest registering a *dynamic host record* (often called "[DynDNS](https://en.wikipedia.org/wiki/Dynamic_DNS)" record). +When connecting from outside your network, you'll need to know the public IP address of your router to connect. However, as most households are getting dynamically-assigned public IP addresses (these addresses change periodically), you need to note down the address every day before leaving the house. Since this is *very* uncomfortable, we strongly suggest registering a *dynamic host record* (often called "[DynDNS](https://en.wikipedia.org/wiki/Dynamic_DNS)" record). -There are many excellent guide and a lot of services offer this for free (with more or less comfort). We suggest a few providers below, however, this list is neither absolute nor exhaustive: +The public IP address is checked at regular intervals. As soon as it changes, the router (or a DynDNS tool) sends a corresponding message to a URL of the service provider, who then updates the record. + +There are many excellent guides and a lot of services offer this for free (with more or less comfort). We suggest a few providers below, however, this list is neither absolute nor exhaustive: ??? info "DynDNS providers" - [Strato.de](https://www.strato.de/hosting/dynamic-dns-free/) (Guides: [EN](https://www.strato.com/faq/en_us/domain/this-is-how-easy-it-is-to-set-up-dyndns-for-your-domains/) / [DE](https://www.strato.de/faq/domains/so-einfach-richten-sie-dyndns-fuer-ihre-domains-ein/)) - If you already have a hosting package at Strato, you can easily set up a subdomain to be used as DynDNS record. This is entirely free for members. + If you already have a hosting package at Strato, you can easily set up a subdomain to be used as a DynDNS record. This is entirely free for members. - [DNSHome.de](https://DNSHome.de) From ba88c67c6920d296c3eb0048ae39f121d84d99f2 Mon Sep 17 00:00:00 2001 From: DL6ER Date: Tue, 19 Jan 2021 10:11:14 +0100 Subject: [PATCH 081/103] Sort guids in subcategories Signed-off-by: DL6ER --- docs/core/pihole-command.md | 2 +- .../{dns-over-https.md => dns/cloudflared.md} | 2 +- docs/guides/{ => dns}/unbound.md | 4 +- .../{ => dns}/upstream-dns-providers.md | 0 docs/guides/{ => misc}/benchmark.md | 2 +- docs/guides/{ => misc}/tor/dnssec.md | 0 docs/guides/{ => misc}/tor/overview.md | 0 .../{ => misc}/tor/performance-issues.md | 0 docs/guides/{ => misc}/tor/setup.md | 0 docs/guides/{ => misc}/tor/using-tor.md | 0 docs/guides/{ => misc}/whitelist-blacklist.md | 0 .../vpn/{ => openvpn}/Android-Connected.png | Bin .../vpn/{ => openvpn}/Android-Import-1.png | Bin .../vpn/{ => openvpn}/Android-Import-2.png | Bin .../vpn/{ => openvpn}/Android-Import-3.png | Bin .../vpn/{ => openvpn}/Android-Import-4.png | Bin .../vpn/{ => openvpn}/Android-Pi-hole.png | Bin .../{ => openvpn}/Android-Transport-Error.png | Bin .../vpn/{ => openvpn}/NetworkManager1.png | Bin .../vpn/{ => openvpn}/NetworkManager2.png | Bin .../vpn/{ => openvpn}/NetworkManager3.png | Bin .../vpn/{ => openvpn}/NetworkManager4.png | Bin .../vpn/{ => openvpn}/NetworkManager5.png | Bin .../vpn/{ => openvpn}/NetworkManager6.png | Bin .../vpn/{ => openvpn}/NetworkManager7.png | Bin .../{ => openvpn}/Strato-DynDNS-Domain.png | Bin .../{ => openvpn}/Strato-DynDNS-Enable.png | Bin .../{ => openvpn}/Strato-DynDNS-Password.png | Bin docs/guides/vpn/{ => openvpn}/VPNclients.png | Bin .../guides/vpn/{ => openvpn}/VPNdashboard.png | Bin .../vpn/{ => openvpn}/android-client.md | 0 docs/guides/vpn/{ => openvpn}/client.ovpn | 0 docs/guides/vpn/{ => openvpn}/clients.md | 0 docs/guides/vpn/{ => openvpn}/dual-VPN.md | 0 .../vpn/{ => openvpn}/dual-operation.md | 0 docs/guides/vpn/{ => openvpn}/dynDNS.md | 0 docs/guides/vpn/{ => openvpn}/firewall.md | 0 docs/guides/vpn/{ => openvpn}/installation.md | 0 .../vpn/{ => openvpn}/listening-behavior.png | Bin .../vpn/{ => openvpn}/only-dns-via-vpn.md | 0 docs/guides/vpn/{ => openvpn}/overview.md | 0 .../vpn/{ => openvpn}/setup-openvpn-server.md | 0 .../vpn/{ => openvpn}/troubleshooting.md | 0 docs/guides/{ => vpn}/wireguard/client.md | 2 +- docs/guides/{ => vpn}/wireguard/concept.md | 0 docs/guides/{ => vpn}/wireguard/faq.md | 0 docs/guides/{ => vpn}/wireguard/internal.md | 0 docs/guides/{ => vpn}/wireguard/overview.md | 0 .../{ => vpn}/wireguard/route-everything.md | 0 docs/guides/{ => vpn}/wireguard/server.md | 0 .../caddy.md} | 0 .../nginx.md} | 0 .../traefik-nodocker.md} | 0 mkdocs.yml | 100 +++++++++++------- 54 files changed, 71 insertions(+), 41 deletions(-) rename docs/guides/{dns-over-https.md => dns/cloudflared.md} (99%) rename docs/guides/{ => dns}/unbound.md (99%) rename docs/guides/{ => dns}/upstream-dns-providers.md (100%) rename docs/guides/{ => misc}/benchmark.md (98%) rename docs/guides/{ => misc}/tor/dnssec.md (100%) rename docs/guides/{ => misc}/tor/overview.md (100%) rename docs/guides/{ => misc}/tor/performance-issues.md (100%) rename docs/guides/{ => misc}/tor/setup.md (100%) rename docs/guides/{ => misc}/tor/using-tor.md (100%) rename docs/guides/{ => misc}/whitelist-blacklist.md (100%) rename docs/guides/vpn/{ => openvpn}/Android-Connected.png (100%) rename docs/guides/vpn/{ => openvpn}/Android-Import-1.png (100%) rename docs/guides/vpn/{ => openvpn}/Android-Import-2.png (100%) rename docs/guides/vpn/{ => openvpn}/Android-Import-3.png (100%) rename docs/guides/vpn/{ => openvpn}/Android-Import-4.png (100%) rename docs/guides/vpn/{ => openvpn}/Android-Pi-hole.png (100%) rename docs/guides/vpn/{ => openvpn}/Android-Transport-Error.png (100%) rename docs/guides/vpn/{ => openvpn}/NetworkManager1.png (100%) rename docs/guides/vpn/{ => openvpn}/NetworkManager2.png (100%) rename docs/guides/vpn/{ => openvpn}/NetworkManager3.png (100%) rename docs/guides/vpn/{ => openvpn}/NetworkManager4.png (100%) rename docs/guides/vpn/{ => openvpn}/NetworkManager5.png (100%) rename docs/guides/vpn/{ => openvpn}/NetworkManager6.png (100%) rename docs/guides/vpn/{ => openvpn}/NetworkManager7.png (100%) rename docs/guides/vpn/{ => openvpn}/Strato-DynDNS-Domain.png (100%) rename docs/guides/vpn/{ => openvpn}/Strato-DynDNS-Enable.png (100%) rename docs/guides/vpn/{ => openvpn}/Strato-DynDNS-Password.png (100%) rename docs/guides/vpn/{ => openvpn}/VPNclients.png (100%) rename docs/guides/vpn/{ => openvpn}/VPNdashboard.png (100%) rename docs/guides/vpn/{ => openvpn}/android-client.md (100%) rename docs/guides/vpn/{ => openvpn}/client.ovpn (100%) rename docs/guides/vpn/{ => openvpn}/clients.md (100%) rename docs/guides/vpn/{ => openvpn}/dual-VPN.md (100%) rename docs/guides/vpn/{ => openvpn}/dual-operation.md (100%) rename docs/guides/vpn/{ => openvpn}/dynDNS.md (100%) rename docs/guides/vpn/{ => openvpn}/firewall.md (100%) rename docs/guides/vpn/{ => openvpn}/installation.md (100%) rename docs/guides/vpn/{ => openvpn}/listening-behavior.png (100%) rename docs/guides/vpn/{ => openvpn}/only-dns-via-vpn.md (100%) rename docs/guides/vpn/{ => openvpn}/overview.md (100%) rename docs/guides/vpn/{ => openvpn}/setup-openvpn-server.md (100%) rename docs/guides/vpn/{ => openvpn}/troubleshooting.md (100%) rename docs/guides/{ => vpn}/wireguard/client.md (98%) rename docs/guides/{ => vpn}/wireguard/concept.md (100%) rename docs/guides/{ => vpn}/wireguard/faq.md (100%) rename docs/guides/{ => vpn}/wireguard/internal.md (100%) rename docs/guides/{ => vpn}/wireguard/overview.md (100%) rename docs/guides/{ => vpn}/wireguard/route-everything.md (100%) rename docs/guides/{ => vpn}/wireguard/server.md (100%) rename docs/guides/{caddy-configuration.md => webserver/caddy.md} (100%) rename docs/guides/{nginx-configuration.md => webserver/nginx.md} (100%) rename docs/guides/{traefik-configuration-nodocker.md => webserver/traefik-nodocker.md} (100%) diff --git a/docs/core/pihole-command.md b/docs/core/pihole-command.md index d1d59fd..a8e714c 100644 --- a/docs/core/pihole-command.md +++ b/docs/core/pihole-command.md @@ -331,4 +331,4 @@ Help Command | `pihole -a interface --help` Script Location | [`/opt/pihole/webpage.sh`](https://github.com/pi-hole/pi-hole/blob/master/advanced/Scripts/webpage.sh) Example Usage | [`pihole -a interface local`](https://discourse.pi-hole.net/t/the-pihole-command-with-examples/738#interface) -Specify interface listening behavior for `pihole-FTL`. When using `pihole -a interface all`, please ensure you use a firewall to prevent your Pi-hole from becoming an unwitting host to [DNS amplification attackers](https://duckduckgo.com/?q=dns+amplification+attack). You may want to consider running [OpenVPN](../guides/vpn/overview.md) to grant your mobile devices access to the Pi-hole. +Specify interface listening behavior for `pihole-FTL`. When using `pihole -a interface all`, please ensure you use a firewall to prevent your Pi-hole from becoming an unwitting host to [DNS amplification attackers](https://duckduckgo.com/?q=dns+amplification+attack). You may want to consider running [Wireguard](../guides/vpn/wireguard/overview.md) to grant your mobile devices access to the Pi-hole. diff --git a/docs/guides/dns-over-https.md b/docs/guides/dns/cloudflared.md similarity index 99% rename from docs/guides/dns-over-https.md rename to docs/guides/dns/cloudflared.md index f5ee41f..8778202 100644 --- a/docs/guides/dns-over-https.md +++ b/docs/guides/dns/cloudflared.md @@ -195,7 +195,7 @@ google.com. 191 IN A 172.217.22.14 Finally, configure Pi-hole to use the local `cloudflared` service as the upstream DNS server by specifying `127.0.0.1#5053` as the Custom DNS (IPv4): -![Screenshot of Pi-hole configuration](../images/DoHConfig.png) +![Screenshot of Pi-hole configuration](/images/DoHConfig.png) (don't forget to hit Return or click on `Save`) diff --git a/docs/guides/unbound.md b/docs/guides/dns/unbound.md similarity index 99% rename from docs/guides/unbound.md rename to docs/guides/dns/unbound.md index 6c31a52..019ed1d 100644 --- a/docs/guides/unbound.md +++ b/docs/guides/dns/unbound.md @@ -1,3 +1,5 @@ +## Pi-hole as All-Around DNS Solution + ### The problem: Whom can you trust? Pi-hole includes a caching and *forwarding* DNS server, now known as *FTL*DNS. After applying the blocking lists, it forwards requests made by the clients to configured upstream DNS server(s). However, as has been mentioned by several users in the past, this leads to some privacy concerns as it ultimately raises the question: _Whom can you trust?_ Recently, more and more small (and not so small) DNS upstream providers have appeared on the market, advertising free and private DNS service, but how can you know that they keep their promises? Right, you can't. @@ -156,7 +158,7 @@ The first command should give a status report of `SERVFAIL` and no IP address. T Finally, configure Pi-hole to use your recursive DNS server by specifying `127.0.0.1#5335` as the Custom DNS (IPv4): -![Upstream DNS Servers Configuration](../images/RecursiveResolver.png) +![Upstream DNS Servers Configuration](/images/RecursiveResolver.png) (don't forget to hit Return or click on `Save`) diff --git a/docs/guides/upstream-dns-providers.md b/docs/guides/dns/upstream-dns-providers.md similarity index 100% rename from docs/guides/upstream-dns-providers.md rename to docs/guides/dns/upstream-dns-providers.md diff --git a/docs/guides/benchmark.md b/docs/guides/misc/benchmark.md similarity index 98% rename from docs/guides/benchmark.md rename to docs/guides/misc/benchmark.md index 4560e3f..c1d4ec1 100644 --- a/docs/guides/benchmark.md +++ b/docs/guides/misc/benchmark.md @@ -29,7 +29,7 @@ The long-term database can be disabled by setting DBFILE= ``` -in `/etc/pihole/pihole-FTL.conf` and running `sudo pihole restartdns` (see also [here](../ftldns/configfile.md#dbfile)). +in `/etc/pihole/pihole-FTL.conf` and running `sudo pihole restartdns` (see also [here](/ftldns/configfile/#dbfile)). ### 2.2 Increase DNS cache size diff --git a/docs/guides/tor/dnssec.md b/docs/guides/misc/tor/dnssec.md similarity index 100% rename from docs/guides/tor/dnssec.md rename to docs/guides/misc/tor/dnssec.md diff --git a/docs/guides/tor/overview.md b/docs/guides/misc/tor/overview.md similarity index 100% rename from docs/guides/tor/overview.md rename to docs/guides/misc/tor/overview.md diff --git a/docs/guides/tor/performance-issues.md b/docs/guides/misc/tor/performance-issues.md similarity index 100% rename from docs/guides/tor/performance-issues.md rename to docs/guides/misc/tor/performance-issues.md diff --git a/docs/guides/tor/setup.md b/docs/guides/misc/tor/setup.md similarity index 100% rename from docs/guides/tor/setup.md rename to docs/guides/misc/tor/setup.md diff --git a/docs/guides/tor/using-tor.md b/docs/guides/misc/tor/using-tor.md similarity index 100% rename from docs/guides/tor/using-tor.md rename to docs/guides/misc/tor/using-tor.md diff --git a/docs/guides/whitelist-blacklist.md b/docs/guides/misc/whitelist-blacklist.md similarity index 100% rename from docs/guides/whitelist-blacklist.md rename to docs/guides/misc/whitelist-blacklist.md diff --git a/docs/guides/vpn/Android-Connected.png b/docs/guides/vpn/openvpn/Android-Connected.png similarity index 100% rename from docs/guides/vpn/Android-Connected.png rename to docs/guides/vpn/openvpn/Android-Connected.png diff --git a/docs/guides/vpn/Android-Import-1.png b/docs/guides/vpn/openvpn/Android-Import-1.png similarity index 100% rename from docs/guides/vpn/Android-Import-1.png rename to docs/guides/vpn/openvpn/Android-Import-1.png diff --git a/docs/guides/vpn/Android-Import-2.png b/docs/guides/vpn/openvpn/Android-Import-2.png similarity index 100% rename from docs/guides/vpn/Android-Import-2.png rename to docs/guides/vpn/openvpn/Android-Import-2.png diff --git a/docs/guides/vpn/Android-Import-3.png b/docs/guides/vpn/openvpn/Android-Import-3.png similarity index 100% rename from docs/guides/vpn/Android-Import-3.png rename to docs/guides/vpn/openvpn/Android-Import-3.png diff --git a/docs/guides/vpn/Android-Import-4.png b/docs/guides/vpn/openvpn/Android-Import-4.png similarity index 100% rename from docs/guides/vpn/Android-Import-4.png rename to docs/guides/vpn/openvpn/Android-Import-4.png diff --git a/docs/guides/vpn/Android-Pi-hole.png b/docs/guides/vpn/openvpn/Android-Pi-hole.png similarity index 100% rename from docs/guides/vpn/Android-Pi-hole.png rename to docs/guides/vpn/openvpn/Android-Pi-hole.png diff --git a/docs/guides/vpn/Android-Transport-Error.png b/docs/guides/vpn/openvpn/Android-Transport-Error.png similarity index 100% rename from docs/guides/vpn/Android-Transport-Error.png rename to docs/guides/vpn/openvpn/Android-Transport-Error.png diff --git a/docs/guides/vpn/NetworkManager1.png b/docs/guides/vpn/openvpn/NetworkManager1.png similarity index 100% rename from docs/guides/vpn/NetworkManager1.png rename to docs/guides/vpn/openvpn/NetworkManager1.png diff --git a/docs/guides/vpn/NetworkManager2.png b/docs/guides/vpn/openvpn/NetworkManager2.png similarity index 100% rename from docs/guides/vpn/NetworkManager2.png rename to docs/guides/vpn/openvpn/NetworkManager2.png diff --git a/docs/guides/vpn/NetworkManager3.png b/docs/guides/vpn/openvpn/NetworkManager3.png similarity index 100% rename from docs/guides/vpn/NetworkManager3.png rename to docs/guides/vpn/openvpn/NetworkManager3.png diff --git a/docs/guides/vpn/NetworkManager4.png b/docs/guides/vpn/openvpn/NetworkManager4.png similarity index 100% rename from docs/guides/vpn/NetworkManager4.png rename to docs/guides/vpn/openvpn/NetworkManager4.png diff --git a/docs/guides/vpn/NetworkManager5.png b/docs/guides/vpn/openvpn/NetworkManager5.png similarity index 100% rename from docs/guides/vpn/NetworkManager5.png rename to docs/guides/vpn/openvpn/NetworkManager5.png diff --git a/docs/guides/vpn/NetworkManager6.png b/docs/guides/vpn/openvpn/NetworkManager6.png similarity index 100% rename from docs/guides/vpn/NetworkManager6.png rename to docs/guides/vpn/openvpn/NetworkManager6.png diff --git a/docs/guides/vpn/NetworkManager7.png b/docs/guides/vpn/openvpn/NetworkManager7.png similarity index 100% rename from docs/guides/vpn/NetworkManager7.png rename to docs/guides/vpn/openvpn/NetworkManager7.png diff --git a/docs/guides/vpn/Strato-DynDNS-Domain.png b/docs/guides/vpn/openvpn/Strato-DynDNS-Domain.png similarity index 100% rename from docs/guides/vpn/Strato-DynDNS-Domain.png rename to docs/guides/vpn/openvpn/Strato-DynDNS-Domain.png diff --git a/docs/guides/vpn/Strato-DynDNS-Enable.png b/docs/guides/vpn/openvpn/Strato-DynDNS-Enable.png similarity index 100% rename from docs/guides/vpn/Strato-DynDNS-Enable.png rename to docs/guides/vpn/openvpn/Strato-DynDNS-Enable.png diff --git a/docs/guides/vpn/Strato-DynDNS-Password.png b/docs/guides/vpn/openvpn/Strato-DynDNS-Password.png similarity index 100% rename from docs/guides/vpn/Strato-DynDNS-Password.png rename to docs/guides/vpn/openvpn/Strato-DynDNS-Password.png diff --git a/docs/guides/vpn/VPNclients.png b/docs/guides/vpn/openvpn/VPNclients.png similarity index 100% rename from docs/guides/vpn/VPNclients.png rename to docs/guides/vpn/openvpn/VPNclients.png diff --git a/docs/guides/vpn/VPNdashboard.png b/docs/guides/vpn/openvpn/VPNdashboard.png similarity index 100% rename from docs/guides/vpn/VPNdashboard.png rename to docs/guides/vpn/openvpn/VPNdashboard.png diff --git a/docs/guides/vpn/android-client.md b/docs/guides/vpn/openvpn/android-client.md similarity index 100% rename from docs/guides/vpn/android-client.md rename to docs/guides/vpn/openvpn/android-client.md diff --git a/docs/guides/vpn/client.ovpn b/docs/guides/vpn/openvpn/client.ovpn similarity index 100% rename from docs/guides/vpn/client.ovpn rename to docs/guides/vpn/openvpn/client.ovpn diff --git a/docs/guides/vpn/clients.md b/docs/guides/vpn/openvpn/clients.md similarity index 100% rename from docs/guides/vpn/clients.md rename to docs/guides/vpn/openvpn/clients.md diff --git a/docs/guides/vpn/dual-VPN.md b/docs/guides/vpn/openvpn/dual-VPN.md similarity index 100% rename from docs/guides/vpn/dual-VPN.md rename to docs/guides/vpn/openvpn/dual-VPN.md diff --git a/docs/guides/vpn/dual-operation.md b/docs/guides/vpn/openvpn/dual-operation.md similarity index 100% rename from docs/guides/vpn/dual-operation.md rename to docs/guides/vpn/openvpn/dual-operation.md diff --git a/docs/guides/vpn/dynDNS.md b/docs/guides/vpn/openvpn/dynDNS.md similarity index 100% rename from docs/guides/vpn/dynDNS.md rename to docs/guides/vpn/openvpn/dynDNS.md diff --git a/docs/guides/vpn/firewall.md b/docs/guides/vpn/openvpn/firewall.md similarity index 100% rename from docs/guides/vpn/firewall.md rename to docs/guides/vpn/openvpn/firewall.md diff --git a/docs/guides/vpn/installation.md b/docs/guides/vpn/openvpn/installation.md similarity index 100% rename from docs/guides/vpn/installation.md rename to docs/guides/vpn/openvpn/installation.md diff --git a/docs/guides/vpn/listening-behavior.png b/docs/guides/vpn/openvpn/listening-behavior.png similarity index 100% rename from docs/guides/vpn/listening-behavior.png rename to docs/guides/vpn/openvpn/listening-behavior.png diff --git a/docs/guides/vpn/only-dns-via-vpn.md b/docs/guides/vpn/openvpn/only-dns-via-vpn.md similarity index 100% rename from docs/guides/vpn/only-dns-via-vpn.md rename to docs/guides/vpn/openvpn/only-dns-via-vpn.md diff --git a/docs/guides/vpn/overview.md b/docs/guides/vpn/openvpn/overview.md similarity index 100% rename from docs/guides/vpn/overview.md rename to docs/guides/vpn/openvpn/overview.md diff --git a/docs/guides/vpn/setup-openvpn-server.md b/docs/guides/vpn/openvpn/setup-openvpn-server.md similarity index 100% rename from docs/guides/vpn/setup-openvpn-server.md rename to docs/guides/vpn/openvpn/setup-openvpn-server.md diff --git a/docs/guides/vpn/troubleshooting.md b/docs/guides/vpn/openvpn/troubleshooting.md similarity index 100% rename from docs/guides/vpn/troubleshooting.md rename to docs/guides/vpn/openvpn/troubleshooting.md diff --git a/docs/guides/wireguard/client.md b/docs/guides/vpn/wireguard/client.md similarity index 98% rename from docs/guides/wireguard/client.md rename to docs/guides/vpn/wireguard/client.md index 66d353b..20842c8 100644 --- a/docs/guides/wireguard/client.md +++ b/docs/guides/vpn/wireguard/client.md @@ -201,7 +201,7 @@ peer: F+80gbmHVlOrU+es13S18oMEX2g= ⬅ Your peer's public key will be differen ## Test for DNS leaks -You should run a DNS leak test on [www.dnsleaktest.com](https://www.dnsleaktest.com) to ensure your WireGuard tunnel does not leak DNS requests (so all are processed by your Pi-hole). The expected outcome is that you should only see DNS servers belonging to the upstream DNS destination you selected in Pi-hole. If you configured [Pi-hole as All-Around DNS Solution](../unbound.md), you should only see the public IP address of your WireGuard server and no other DNS server. +You should run a DNS leak test on [www.dnsleaktest.com](https://www.dnsleaktest.com) to ensure your WireGuard tunnel does not leak DNS requests (so all are processed by your Pi-hole). The expected outcome is that you should only see DNS servers belonging to the upstream DNS destination you selected in Pi-hole. If you configured [Pi-hole as All-Around DNS Solution](/guides/dns/unbound/), you should only see the public IP address of your WireGuard server and no other DNS server. See also [What is a DNS leak and why should I care?](https://www.dnsleaktest.com/what-is-a-dns-leak.html) (external link). diff --git a/docs/guides/wireguard/concept.md b/docs/guides/vpn/wireguard/concept.md similarity index 100% rename from docs/guides/wireguard/concept.md rename to docs/guides/vpn/wireguard/concept.md diff --git a/docs/guides/wireguard/faq.md b/docs/guides/vpn/wireguard/faq.md similarity index 100% rename from docs/guides/wireguard/faq.md rename to docs/guides/vpn/wireguard/faq.md diff --git a/docs/guides/wireguard/internal.md b/docs/guides/vpn/wireguard/internal.md similarity index 100% rename from docs/guides/wireguard/internal.md rename to docs/guides/vpn/wireguard/internal.md diff --git a/docs/guides/wireguard/overview.md b/docs/guides/vpn/wireguard/overview.md similarity index 100% rename from docs/guides/wireguard/overview.md rename to docs/guides/vpn/wireguard/overview.md diff --git a/docs/guides/wireguard/route-everything.md b/docs/guides/vpn/wireguard/route-everything.md similarity index 100% rename from docs/guides/wireguard/route-everything.md rename to docs/guides/vpn/wireguard/route-everything.md diff --git a/docs/guides/wireguard/server.md b/docs/guides/vpn/wireguard/server.md similarity index 100% rename from docs/guides/wireguard/server.md rename to docs/guides/vpn/wireguard/server.md diff --git a/docs/guides/caddy-configuration.md b/docs/guides/webserver/caddy.md similarity index 100% rename from docs/guides/caddy-configuration.md rename to docs/guides/webserver/caddy.md diff --git a/docs/guides/nginx-configuration.md b/docs/guides/webserver/nginx.md similarity index 100% rename from docs/guides/nginx-configuration.md rename to docs/guides/webserver/nginx.md diff --git a/docs/guides/traefik-configuration-nodocker.md b/docs/guides/webserver/traefik-nodocker.md similarity index 100% rename from docs/guides/traefik-configuration-nodocker.md rename to docs/guides/webserver/traefik-nodocker.md diff --git a/mkdocs.yml b/mkdocs.yml index e3664b1..ce1f242 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -94,42 +94,46 @@ nav: - 'Contributing on GitHub': guides/github/contributing.md - 'How to sign-off commits': guides/github/how-to-signoff.md - 'Guides': - - 'Pi-hole as All-Around DNS Solution': guides/unbound.md - - 'WireGuard VPN': - - 'Overview': guides/wireguard/overview.md - - 'Concept': guides/wireguard/concept.md - - 'Install server': guides/wireguard/server.md - - 'Add client(s)': guides/wireguard/client.md - - 'Optional extra features': - - 'Make local devices accessible': guides/wireguard/internal.md - - 'Tunnel all Internet traffic': guides/wireguard/route-everything.md - - 'Troubleshooting': guides/wireguard/faq.md - - 'Configuring DNS-Over-HTTPS on Pi-hole': guides/dns-over-https.md - - 'Upstream DNS Providers': guides/upstream-dns-providers.md - - 'Editing Whitelist and Blacklist': guides/whitelist-blacklist.md - - 'Configuring NGINX for Pi-hole': guides/nginx-configuration.md - - 'Configuring Caddy for Pi-hole': guides/caddy-configuration.md - - 'Configuring Traefik for Pi-hole (not in Docker)': guides/traefik-configuration-nodocker.md - - 'Benchmarking': guides/benchmark.md - - 'Pi-hole and OpenVPN Server': - - 'Overview': guides/vpn/overview.md - - 'Installation': guides/vpn/installation.md - - 'Setup OpenVPN Server': guides/vpn/setup-openvpn-server.md - - 'Firewall Configuration': guides/vpn/firewall.md - - 'Connecting clients': - - 'General': guides/vpn/clients.md - - 'Android': guides/vpn/android-client.md - - 'Optional: Only route DNS via VPN': guides/vpn/only-dns-via-vpn.md - - 'Optional: Dual operation: LAN & VPN at the same time': guides/vpn/dual-operation.md - - 'Optional: Full and DNS-only': guides/vpn/dual-VPN.md - - 'Optional: Dynamic DNS': guides/vpn/dynDNS.md - - 'Troubleshooting': guides/vpn/troubleshooting.md - - 'Tor & Pi-hole': - - 'Overview': guides/tor/overview.md - - 'Basic Setup': guides/tor/setup.md - - 'Using Tor': guides/tor/using-tor.md - - 'Performance and other issues': guides/tor/performance-issues.md - - 'Using DNSSEC': guides/tor/dnssec.md + - 'DNS': + - 'unbound': guides/dns/unbound.md + - 'cloudflared (DoH)': guides/dns/cloudflared.md + - 'Upstream DNS Providers': guides/dns/upstream-dns-providers.md + - 'VPN': + - 'WireGuard': + - 'Overview': guides/vpn/wireguard/overview.md + - 'Concept': guides/vpn/wireguard/concept.md + - 'Install server': guides/vpn/wireguard/server.md + - 'Add client(s)': guides/vpn/wireguard/client.md + - 'Optional extra features': + - 'Make local devices accessible': guides/vpn/wireguard/internal.md + - 'Tunnel all Internet traffic': guides/vpn/wireguard/route-everything.md + - 'Troubleshooting': guides/vpn/wireguard/faq.md + - 'OpenVPN': + - 'Overview': guides/vpn/openvpn/overview.md + - 'Installation': guides/vpn/openvpn/installation.md + - 'Setup OpenVPN Server': guides/vpn/openvpn/setup-openvpn-server.md + - 'Firewall Configuration': guides/vpn/openvpn/firewall.md + - 'Connecting clients': + - 'General': guides/vpn/openvpn/clients.md + - 'Android': guides/vpn/openvpn/android-client.md + - 'Optional: Only route DNS via VPN': guides/vpn/openvpn/only-dns-via-vpn.md + - 'Optional: Dual operation: LAN & VPN at the same time': guides/vpn/openvpn/dual-operation.md + - 'Optional: Full and DNS-only': guides/vpn/openvpn/dual-VPN.md + - 'Optional: Dynamic DNS': guides/vpn/openvpn/dynDNS.md + - 'Troubleshooting': guides/vpn/openvpn/troubleshooting.md + - 'Misc': + - 'Benchmarking': guides/misc/benchmark.md + - 'Tor & Pi-hole': + - 'Overview': guides/misc/tor/overview.md + - 'Basic Setup': guides/misc/tor/setup.md + - 'Using Tor': guides/misc/tor/using-tor.md + - 'Performance and other issues': guides/misc/tor/performance-issues.md + - 'Using DNSSEC': guides/misc/tor/dnssec.md + - 'Whitelist and Blacklist editing': guides/misc/whitelist-blacklist.md + - 'Web server': + - 'NGINX': guides/webserver/nginx.md + - 'Caddy': guides/webserver/caddy.md + - 'Traefik (not in Docker)': guides/webserver/traefik-nodocker.md - 'Router setup': - 'Fritz!Box (EN)': routers/fritzbox.md - 'Fritz!Box (DE)': routers/fritzbox-de.md @@ -156,3 +160,27 @@ plugins: 'ftldns/regex/index.md': ftldns/regex/overview.md 'main/presentations.md': index.md 'main/prerequesites.md': main/prerequisites.md + 'guides/unbound.md': guides/dns/unbound.md + 'guides/upstream-dns-providers.md': guides/dns/upstream-dns-providers.md + 'guides/dns-over-https.md': guides/dns/cloudflared.md + 'guides/vpn/overview.md': guides/vpn/openvpn/overview.md + 'guides/vpn/installation.md': guides/vpn/openvpn/installation.md + 'guides/vpn/setup-openvpn-server.md': guides/vpn/openvpn/setup-openvpn-server.md + 'guides/vpn/firewall.md': guides/vpn/openvpn/firewall.md + 'guides/vpn/clients.md': guides/vpn/openvpn/clients.md + 'guides/vpn/android-client.md': guides/vpn/openvpn/android-client.md + 'guides/vpn/only-dns-via-vpn.md': guides/vpn/openvpn/only-dns-via-vpn.md + 'guides/vpn/dual-operation.md': guides/vpn/openvpn/dual-operation.md + 'guides/vpn/dual-VPN.md': guides/vpn/openvpn/dual-VPN.md + 'guides/vpn/dynDNS.md': guides/vpn/openvpn/dynDNS.md + 'guides/vpn/troubleshooting.md': guides/vpn/openvpn/troubleshooting.md + 'guides/benchmark.md': guides/misc/benchmark.md + 'guides/tor/overview.md': guides/misc/tor/overview.md + 'guides/tor/setup.md': guides/misc/tor/setup.md + 'guides/tor/using-tor.md': guides/misc/tor/using-tor.md + 'guides/tor/performance-issues.md': guides/misc/tor/performance-issues.md + 'guides/tor/dnssec.md': guides/misc/tor/dnssec.md + 'guides/whitelist-blacklist.md': guides/misc/whitelist-blacklist.md + 'guides/nginx-configuration.md': 'guides/webserver/nginx.md' + 'guides/caddy-configuration.md': 'guides/webserver/caddy.md' + 'guides/traefik-configuration-nodocker.md': 'guides/webserver/traefik-nodocker.md' From bc2f0e97a02aa838395381532fa07a317ac2a32c Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Tue, 19 Jan 2021 09:46:23 +0000 Subject: [PATCH 082/103] Bump mkdocs-material from 6.2.3 to 6.2.5 Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 6.2.3 to 6.2.5. - [Release notes](https://github.com/squidfunk/mkdocs-material/releases) - [Changelog](https://github.com/squidfunk/mkdocs-material/blob/master/docs/changelog.md) - [Commits](https://github.com/squidfunk/mkdocs-material/compare/6.2.3...6.2.5) Signed-off-by: dependabot-preview[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 1014620..2400ddc 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,5 @@ markdown-include==0.6.0 mkdocs==1.1.2 mkdocs-git-revision-date-localized-plugin==0.8 -mkdocs-material==6.2.3 +mkdocs-material==6.2.5 mkdocs-redirects==1.0.1 From d4e2dc2799476721bf2edb58a7ed17b17ed60805 Mon Sep 17 00:00:00 2001 From: yubiuser Date: Tue, 19 Jan 2021 20:59:19 +0100 Subject: [PATCH 083/103] Fix typo in conditional forwarding screenshot Signed-off-by: yubiuser --- docs/images/conditional-forwarding.png | Bin 5751 -> 5760 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/docs/images/conditional-forwarding.png b/docs/images/conditional-forwarding.png index 27e7eeb2aebe413525aa77be4724419f88376e96..3aaa2aba9da2e08e902cfed1887ee07ff69416f3 100644 GIT binary patch literal 5760 zcmai2c{o)6_t!!qN=PdENGXc3uNi|G%w(4}%P_J;vhN1j%_7-iEQPXKPRu8Gg!gPs=j*gB64ucxd z(H$q#XdL4S+P!<5;m^Zq5183wIyz?dKi4t3jOQ0=Tv>X$Mj8MB$b-S9rKNjyp7Znb zU@-XT=xA$et8ZvhDX~!sEWZH&KLEfH3N`naoG~KFuZL#vc@6Ej{fJx%mA)u7h z(og$>Uv(C_)6|9LDF9GZxB~$5U@2V-bBkzgFt9xVR`hr|4@ld+vi8UWhLgcknjVT^ zx7@LTG<1*(7;KVWvjHe!JJI^822x-tL>zVZi!RE~zXec5I3=VtemDRcJQZ@LfZ8wz z>fCGGBXa=g?F!Sxj~wc#$oX3Z0NoLDuh78GCo|kTN3`8cxgUNWpaN56XsL=tz{^_W z!9&lMVD+XgfVw;!QomFbVu>zWa*3;lCN$dPdx>tAq0L*C$UDnjFM@3K8Ww5xw7{)h zy1KgCHvwR-LMda|CcF^^k#nx!^K`LQ)U<5;zU%t@gUY?f@hA;!?}4SAPg?f7Z}UuzXAKD8T^RG^ZW;MGrfi^7$w5v%11nxwWb(t7qNAGHSjF zyLYgs@wjfH{o{*OV2XHebL>sfvvHQ7yvw4@f&IzE9zf=Xlc?^677;P?BrLa z;+)!*6QrNl^=Wmvt7EFBp(pQk?i{d|<>67(-kV?`MT~S`I_m42*@!G7W|y~Z>{8nH zJ3b$5ym=d)OY~PcI-^5J#~urZsu}r>{><7}Xa9Dg-94Kp_+$bI|6)ZNLyyAdFy`@N z7zHt;4)YPCPl9g+uB{dcj>d^TYz;Q8GaknQ6#n_-H;qhMe zBIK&bZuVw682xaL7ovHd!}%H`TvLF2jf0Q?p@C5?2q-qpjn^~L+EC2;uU8=MKa5$6 zElbGc%(8Azo4cMngX1eRa;d+Xla8dZ5JCh0{)Ub`Su0XG(sDqza@onwKdMc6MccHf z+hW#)^XcUby0^|e4I=(j&@m~YoLeBn&5IgFvY`7HjyF+Q$U>K;Ac#6GxM>kv3hOy~ zLhR_XEhtILK~3$I)qPmOynYc9_WoD;$qjVY{2a~>v6sI6N!4GinE7gjeK{2a?oExtgy+cs*)xZej6bV64CuNH! zK_7#?^uu+Bbx4LLRK$ls@+|PsQ-$OvbaE9ef(w|}EkSkn*bk>KwhnIO_`A#uaYOP) zlW!_s3pv=#8Xb^Ayqz6LJKcRfEWWL{fc#y5~Vwhj4Q~|Qq9l7hewC0H5&?nMWJULOaHWDD;Ape4y z-HQiSqx3m6;$v`lyDK}nqoV|qxe>wm;P%s>feO@Qh}&z0gCM`U+pXdn>-n=1nW-gp zqC0Oa*|j1dgzFuSw5?85uu|A@X@m942a#=TafLTb%MLlM*Rxjj^9=bmWY7j|H-0O% z=z2cYKwdbjAh0*G&;fHCj5_3pWC&6O51G_ACthc0Hk88pJqSPMgoALGMLO@HIFWM zll=7J^n3@VCB{@tciP(s<+2oW98gSKvs6ffN2r zFJy!)D?}wD?|bT429er~DJ`U(S|iJo|*$}@bI1&NOQD0QhUKN!>8IZ_^PY8lnGn#5y6xL;hQ zgO1qsWFU}>#7p%F#AflvnMyTQhz-REltn6Z*3bh#T=~D)Bh80oBuV#ek*}ZL>k~y)9Wb+ zr?b~OsY*t~ew3+r7j416(z3#C+v3SiHqf~st<0gsNiU-@JD|DDR9V&G-c!{GubY5Gbrp+umIL4D#& zD{~jZb`f8&o}46R4*^v8-d<9%tIl4R_|=^0Rx^KjW~lH1UB>wufg4%Z{nBJ``ZXr_ zXEXF2Z`)_AOUtZYd{)6ff9Ub0&&kj@3KM9OChLCMPB48n=t>6v&gJVETy4+(*YWe8 z-s{DL=A{`+JHF|AH*Lu8pE{G14FknnsX2vz0GC50PdjhQcj2tfYC4h#uIxv*`_cG- zrtYXwk}(jdKfmc@5Bpgf?eLYar0Y#x^??>Y_iOx`K-99jwww3|=F`gfAPl~%@I=v| zlEk%d+F0?~s1LvGt$RjKxjf(Kllmo_eX}#BSEcCQ@!7fLfROX%49W#uT{c<=mWAYT zgd^b=g^mPJh9Dl@v1;I$`&LmL8yCVs(zT5#(m5H%}HmJ*>Oss{@kR7uOKJQ zy-#5(9*ClbgGN1W-+>CPc3q=ao)eS7rEj$-Z0A^P9ho2wDqf#(JlCU$c-OCznnh-X zY~##!7#`yw-Jo^HOkT8TB)8b*$c$6OI7NnNbXN4L?RAJ>^Ch_`t+!lZ8j6}58j1It z;6B`Im1iKEtxD)$c0x5LCGb}+Nr%?^h_A^Ks*{^vpt&Y0|& z_B|MnYzun95wgP?|4ib0(g0l4BU=<&NBkdGVe*OM$S&7`! z33L8EiAPuW)fEi(r0!PY8UKz-qjJQLBTXowTTG4rKo=B+A^LeST@kDSaBE`|{>UVi zE+)szzj$5QJKGDFmcx$BH8<)I4qTFM$V?c6&`Qr)m`@HGa@RL#>!Wi9YvQqY{mHy$ zL`Gxr%oJkq3(c_Q`EY5>4nE1d&Muh%V;GmYd(5 z6gJj)y1B6`&a^9%K|NoJafx*Hwp@&K*j8-$9H`2rnm?d6kkF7=Jn&v)a#RU zp$RfOqgw7LX5LnzCd?$GbY3@&@yo$lduIBiJzM?M}{61yG1K-Z@8u;pv;g| zy7l{GXH<*dN4{~xCkI{~8Mv#J!8&Ian323MG^=M-)D>wqVY&=iWbJbOYodO*RSqzT-V|li!Friz^N0U_IkN_q9`Q>$pfM6Z) z2jSPjNJr4Z%7A#jFPp2Vq5W@Ds{sxU4yE~Rj;FX$?_d6n!Z6LqXkr3t(jCeojIs!; z6OO4vUV!ho#Cc?l;ZZpQ3kSNy{tGT#U!#wWRnz>FWvQVvlX&3vKJ?yIYFSZm);Jeo z-wWfJt77serwB$HW<`7%XJmHr2=y>}RPkdp{c_2Nl&ivcT_tI+BemDbSjOhwVFRS3 zMZ@RhQmgf6H@h7P#Tv6qaT%wyQWyOo6F+Rj9&MKz(iYV;t@uyODI3jVciL3|f>1%sl#evS%Mp;>R1Wm(6-o2#TEG)UgI%j$v` zr1&}+WiV*JdLllQ9H1k4ZCt;;ods@wZn8eR_N2ZRiT+N%kzW&@!opO0^0CgjfNzwL z2g-PuxWE$AZwCxL8Cp%M+D2Uim!UPa(&6(iT#=TiP(YfY&$92{M4h|?%|F2cW)zR( z*hj6?V${#_me$9zkgK&ImyZ_ZH^rZDCX}C+Ky*MQx6W>XZ_$5xs8>Vf6cXXqj;Zij zCN~Pl-xPT~YtwQrG9#*@&^x!hnF5WCP)V$ah~SLj_c~F3@dn-+AHNA=W$@fN`!sSm+CH{|T`==mxP*5){V zHo+{=_hRC#I06Ow0+)H%1c7y$&8C;b`#-jS+9byIWtJsBD8Ud4M#Pckh)u(lp-fT^ zI(5>zHdwhaq-)1a{{YyeL^x2s?jn+&Gyx@X`5qUldtl44eZ2Tof1)fI zCn$gI^oHK{M{JDJBFh_VIo|3B&UgMBIaP&&dd?WxMee3qwoRQCt5N^w>FK{uYF9mS zt+eTdtxmmoa-J;TszFkGAD?>V)AK{IU&_>7=c8T$|NU>>nYWDbl+wWKDVf+Mzg}?7 zsxdkgoyuZmdDhZmDAw_|Nx=h%wpv!T&e@gozFAu`r@w;<}KmCQ-l!>~6GEFsVMq(3U-It}V`F73=F z8H`bw_JY%7AHaJs2je;DWzw{FdDLS#DELHI5JkAYtKUwIMf;Dgd zKh5V~S>xY%#%7w<(3WUU;1eKbl{nNtGp&CB#2p18=wJIA{?h`}8e$qJ6HV|x@b@h2 dkDPZQa3WoS}U<}lD5zL4FHF;3V!YK_Mf38YkqS2od95%JTn%j1I}GY z{s}Aqz(Nk#=cPKZSNl{_2Uy4jaFxG~fff(RDFEm=0tUj>fYIn@A!y)u6~I;lKxa7) zh`?N4;(GVT3e_aUfa8|ER{!{}jV+YZdaHRPlXQogKTedH)iT&&nh zT~jSGqznI4BV0~ZKSD!8M9SMo{%{c&@4_uOBA~ z&H)blm9=b+7Hd(?l4yQo%@?nok$)iOFFw3Bd#2_wg$KZXH8uvS7w8CMdG8l-9YB}A zq>{O|te0ECn1bG`h6A8{;*X9~!tnZeQJ~G~#-xSJ%OTNFQ89~2WC%1Ad5UfG(UH*y z!vSExw{~H*GirbDp#HUTeV8@UR-)NY%R^RFJEE@~D(RB;Em#9upWswkSvg_n9eoeXNsX^3MR_g@YB@!NTl|h z_Dd|x96yB$Yg#-6PHc2T*1C(549zN+0UP&hn@{6|Io6mWzfj8no7X;zbz!)vVQm>p zUzqtoZGHdqPoFTG(H|NyKHZb$SkL;6%G$T5M|k=4;bY*>Tu<{MGHN7oqNHK;55flx zsf|Sy*Os=le?zKSVA&t0S^7V`%?r2)Dr5-3WmNvw-A8tJ#byytMiol z>l|D5?(}2kTOkb3^TbHwE!&c5c!?@pY1oVQ2}X{TwP(sTl1THlM>{qXq%g?4@ad5U z-Br~wlCq42UV@oVg<8_%Dpy!Be8TS$^h$%@`NV(%3qL&k-Lf%0=7 zqPcs8u3`|?lhz8VM+I*V7F5m)d|$xO1Y1S-C4CZ&WXO=x57Bcw8DNWNau1nF)PX1B^HQRUAg?{^nR2)meqUOiuM zw8D7(!XA%F_(=nO_wog&iGr9LhgX8QTvE04!oGn_#7rd9ltuhq#<{)uSpjq#XY|Nt ztC_5weHnU(!|b@M(=fluk2HtF3Mur*oa68B7`K{E+J42tAM>V1S*XD2zYdAM_4;sz z{1ylI3~nSQr7SGn|E1X2v6w-rWl;6;a$HuWh@-?a8G(3E#DEU^PT$lYvNgxevoOOK zP#S=AcB~aYelnl&vhwpZqq*Cp5RZ~;Qv_6h!{zvKc~DKIOSt|n0uBBc_BYqqiqJcX zE3&{CK7WOWw%r#!r{|Hzcn!2vQE!0$C}cE>2OnP<=4Y@xSY~>+4WfyrJ#pW8wrn-n ziW_(KXeq}~id&cL>ia{cDbv_>b=aunf<4J()76(YyUHylZ)l5uM>*dh22WT~(sMI{ z_;YW8$rDgquJ6}t@?e{fELn!zU~aroOg-G`oL$c4amjKGVvDu%l#IAEx{z%(liyM$lY#7w2@sy zA-VPg=3$E0oLCd|-M7yu6!kTcz7mtxYK=tWbVWXrTi5I~bkeaK^KKd9r;J{KZ+>YoI`9yWbIxxlNubp zy`@p8p2VN#8CAC%P2o`S;t~aafC8CZ=c$m*8ombQpgjnjp5=aT`~|(SIW=}r^;l*P z)_jMxYN;d>!PSYwp6K+Z5u3{Wsa4|;@$4%C4mQ*O z=<=(kk5Ps%C@5rz2oa%^eXCl+e{Gm7nLz2m&)_4;_Sc~F%rTtu{|x_+S~Bb}xN6?b zB$(%;Oo%m@Ww1p)Lqz=>!_Ed<9T&4x&!*Z;kmN!jlYV7Ee=H{?ziO|QiyVdhaZEok za+aFLNN4(NwKG&QcvN(8UfS8|3q|W!K{5ErWi7kSNlK;+6Fk6#Hn~XDRFXw`+|Y9% zw)s_!shQlPh}JdV;RQJF==+4-o(JHRm@STTIu^9^b4K$IrSoMIH8tNJXZ!P$n}fsN zOeZYfvcin_uNe6|&^mAw{s2oUvWX#V8BVdv;87f+FqAj{2zMKlSgNQMj2J3OM7@_L z4k90LH@hImG1`L7B&6X1MzqP2p+CvciDB4@8?jiDZg<=f1)TqsUTO0UHCp#+w~|Z4 zcr48Bv$-37qx2CS{B57mvHzApW(~i`SQ`a3I$a4Y;#>B^~^Yc|r;C8w>jBI1aMCC&F4#bj|m}r8*H>PO+SZf04N% z(S=`%<@&f@*Tgi$VbHXbt!_zt*H{&K5TUZ;2jUC9M21EF>3W;cL-U&dN`2d<-D5Bz z27*lb8z!Z)*WP}2bF^wV*;c{hO5Bb3%7PW!3Am`x0e%kmU7o+VWmS#J;E|se$}ITk zz#-G-d5a<<7`(~l`Dq*i=HFtgDT0)MofEMA8I%IFRl|GnWe}Q!358l6drs)}*W35G zelt$jeXc29--HPjh7wIkH1}%aClE#U;&)p&jBK?cVVT&{9tcx@1G$q!L(T!O%+d)) zrWhX)pc9FRmW{zgd9i4wYI>*gKzbgvWbnj&06!f&p?KN*&?_hszB!8b8)ST_mXL%c zMvfH|rML+Gpg-Nr<>s}n)+)<{>Ap3tUvB56tnw5$!LBu+CCJ-rG0Kf}#8mAwJ52a9(EG5TEtR!s`S<#N|QfpqfvIVTJiksE*Oh zGkysD&rX#nnLB1}k#V0)E&B7*=_uQbr}@TCPTd??jg(Br%v0yK+v42|OK0k3isz@t zTZm5S%P2OC^7Gz$*EozdO5r^pDx^Oi5E_#gffHI8v$n18GsDHJMm4{_hNqz}#$%pm zbD4O3#TP`A@rJAwW1u592P1O%Z%j?aS&*W9Gz0xJFK@bs%rIPwFy^y}#I>QIyH1 zWfJYzlL=>pYn|ve$O^wheKS*MAb}U(FWqmKxP{vL@>rGUYBe`YZ0qiMX}(*U-lFE? z-E$3s+$u;Vfv=*@1mF9o%8d=5oD;CtGhF*a z<-|Z&Iw7YBM+{WeJn#WAKXzgOIf2)nF2M87>k$O(|g z8ghegcPfvHY-JG~=$K|#Fg|n+PVZx|oo00>r?Y87qkIXgq7?pKxM-$unFIU&;`=wU z->~GH*oT_t7`OVRu0_}?!Uw~Doy2U@Az*vr4N|PJZ}bd$@dm5YpqUmQk)UyOTly_D zQ|OV_cbEuV^vEegerQzKQH;((mTo^}o@>O$M>!iN(-jBmHK`JsM|TQUIzasMO=B6L4Y)lhN;9_lwX*eRB_~9mG#F|P zo^k%x+A!O;B=iU)ZL;`n{>yn=C5qk7Z%`9%W5);zzZ*mZr={u>3c!C=?dY_!fRN)< zEnGVAj~}G6RweV5!jYXYa$~i6XaF|}od#Q%39$2!?TA}$dYJt*4 zNx$;EzTBP(#vw4Zy`H3+{UL1)G0YV_6Lc&fH_}=|f-akm(-y_Od-{~2bpr+&5Vh$~ zm3dtBTPO^+9h5wde-lnb*L^*60#9^^hiE+E z+HQ@R2+M$LAh~tMv?$x@&jU8(T-Eoroy6WB+*6ii)!a5GWn?TBlUxx za%#@VFRD`_C-SpvdJIAJs)vphdaBfWic?ldZKRz z<4MRqZr;02%V-9)y2DSD8$Y~w;ftvmYj@^^AoAu=TF!1;Ici`J1}8&_4IMk#lk}9a zS-OtzVUw#tZ&B+avvx^bIMsM%c&sOhf!KL-88~5PmC}ocSmjwu)+ZFX0xeQf<|3kc zNg8wn$*8dL9l+6Pn>nO8F`xrOH4Ww;nRt6y*1gO1S5N(vlSkcst&^iV*E>&Y#lURc zHu00+?z&0N^H(Nk-g zaqVG~;QY7X;2YZ+MwKBP;=TJly+UQEvNvtq*UYAwb6CH>RBWc2$Si`zZdGvy^-(*|;FagMj$cq|esI^CydUC+(-AYA(<-!EPN{ln z3ukp%Yit2&d{wi8N4gIa>h9(JynVJzo=<%PjqNA2(!F4u{5q~APWZ9QKuCG*S^dT! zhyR}ns%NVv&E#>7ws9Dwy#xXJcWDNU?evl4g9&h|B$uhOv$%O_evjnaUO`Ob>W}O{ z15f5TrFusRC*-(BcB+eYA8a1*o)B;2j^#T(3acl2)v-R(oz;C6Z#jsd_1T=d5g(i= zSb0qWA3yO7EU+nM=lJR5NZ?hZr8eThO|(JQG!gjnI|=Me`J#MHo07xr=j%I3+e}=q zGX4Q@lFU!WsxkfG7OwE&^jK9D;)Y86CI(ih|IM!b9sa|d!IS^8W(5D{($cR^Zjdcz zat-@y1A@bUJH0D=_n%hozwuZ0juUD|q^3;i7{^(y91@p~?F*jKiS1H|A18wM$#MT} z7yrfd|7X}g@TqP`s9y)TZf=kHH)FyAB?foW{u?=WrysfX0OmYU7-YG|!s_+9cf7R4 z;wZS!k!D=vRM8~A@6gq9mn~TC&%#zk1hf!C+^BVzaYo6E&~YZld&j6w*z@Owy^{83 z$&fy02-c19$1+T!LfcTgDu78lGvV@ysm1>1JF~7*ULyYHFT%FgWpMt3q@(#&=`)r& zO^~V#TWzNqm{Zfhkw8`Bi;2=VwY6Jpjehj9J#w%4eBI2ag?<0DQgt|rMTAke?=?_3 z?jf@d3ri|b1}#a@&{K)mXA?-G^msFHz)Z>3DT2av!4%C^da(E;#e%25AZzl9`HbMw zC5meEzFomOlEz|I;Kzr$H=?Yd#K~MvLG+-<8>)Vu?6+q9R4Rz0lfa>=#D$?H&;tL` z{z$5;n9F#(dBAqspV5y)X;#%qx0vE9C5+m6veLe!&(8nYt!;LqjfGCSVpCXLhsf?L zh-~{OkA2@Dp*`~vHuBc@&k67NF@JQbv&jq2DvpuC6G@6(lsaQ7G@toe= zhdyTwkwrpg#w7W@5-zefj-%lu;ySm{OTwS~FhasD?Z_Vm^r5SC>z1}6p|D4E-g&KG z*(8Nbvn_(u?oBzChO8nEU0y^>M3~!Vbih5n;6?46@&{al2e18c3chtxcaag~znx?* ziH@}q6#af_2Msf2DOS+-hG*O%hmS?xd5Q+RjIZ+F+7~%7Q+xCs*0MrCztd7@*R_eK zND^IcYhaxl7zrJo#pt3QVwdgPm@Bd9!l7Tx+Jnz}hXXw{g*ZWciGI(MyWDGl()H<` z*`3(TC$$Y(V|eol8Aa0-_Lj?EozzKBwwHdXNwymoG|XtCv(@XJ@?9q@A997O;Ib`6 zX0ti?I++f0kJn{pPuP`hf(l2o>v$r z^Uq*dv=3e-lETI1*AC1%CuiQYn+`7^ioj?l_!Gv=T5>a~awp6adTagPF`t28o zQkw@ia4-7Z3vOP@Jd0>x{+BrXQzQP*m)`+s$>MiIns3A=2a9@`C`+})P0733A)tKr z5u#q9ze9HPUlSt`J9 Date: Sat, 30 Jan 2021 10:13:12 +0000 Subject: [PATCH 084/103] Bump mkdocs-material from 6.2.5 to 6.2.6 Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 6.2.5 to 6.2.6. - [Release notes](https://github.com/squidfunk/mkdocs-material/releases) - [Changelog](https://github.com/squidfunk/mkdocs-material/blob/master/docs/changelog.md) - [Commits](https://github.com/squidfunk/mkdocs-material/compare/6.2.5...6.2.6) Signed-off-by: dependabot-preview[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 2400ddc..82c1202 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,5 @@ markdown-include==0.6.0 mkdocs==1.1.2 mkdocs-git-revision-date-localized-plugin==0.8 -mkdocs-material==6.2.5 +mkdocs-material==6.2.6 mkdocs-redirects==1.0.1 From fcee2c01e53ef984d7756b279ce32ba52aac02a9 Mon Sep 17 00:00:00 2001 From: DL6ER Date: Tue, 2 Feb 2021 10:02:08 +0100 Subject: [PATCH 085/103] Improve regex documentation Signed-off-by: DL6ER --- docs/core/pihole-command.md | 2 +- docs/database/ftl.md | 12 +-- docs/ftldns/compile.md | 4 +- docs/ftldns/configfile.md | 2 +- docs/regex/approximate.md | 97 +++++++++++++++++++ docs/{ftldns => }/regex/overview.md | 10 +- docs/regex/pi-hole.md | 144 ++++++++++++++++++++++++++++ docs/regex/testmode.md | 19 ++++ docs/{ftldns => }/regex/tutorial.md | 23 +++-- mkdocs.yml | 13 ++- package.json | 2 +- 11 files changed, 300 insertions(+), 28 deletions(-) create mode 100644 docs/regex/approximate.md rename docs/{ftldns => }/regex/overview.md (79%) create mode 100644 docs/regex/pi-hole.md create mode 100644 docs/regex/testmode.md rename docs/{ftldns => }/regex/tutorial.md (87%) diff --git a/docs/core/pihole-command.md b/docs/core/pihole-command.md index a8e714c..ba48daa 100644 --- a/docs/core/pihole-command.md +++ b/docs/core/pihole-command.md @@ -54,7 +54,7 @@ Example Usage | [`pihole -regex '^example.com$' '.*\.example2.net'`](https://d Administrators need to be able to manually add and remove domains for various purposes, and these commands serve that purpose. -See [Regex Blocking](../ftldns/regex/overview.md) for more information about using Regex. +See [Regex Blocking](../regex/overview.md) for more information about using Regex. **Basic Script Process**: diff --git a/docs/database/ftl.md b/docs/database/ftl.md index d5e615a..f750c9a 100644 --- a/docs/database/ftl.md +++ b/docs/database/ftl.md @@ -113,17 +113,17 @@ ID | Query Type ID | Status | | Details --- | --- | --- | --- 0 | Unknown | ❔ | was not answered by forward destination -1 | Blocked | ❌ | Domain contained in [gravity database](../database/gravity/index.md#gravity-table-gravity) +1 | Blocked | ❌ | Domain contained in [gravity database](gravity/index.md#gravity-table-gravity) 2 | Allowed | ✅ | Forwarded 3 | Allowed | ✅ | Known, replied to from cache -4 | Blocked | ❌ | Domain matched by a [regex blacklist](../database/gravity/index.md#regex-table-regex) filter -5 | Blocked | ❌ | Domain contained in [exact blacklist](../database/gravity/index.md#blacklist-table-blacklist) +4 | Blocked | ❌ | Domain matched by a [regex blacklist](gravity/index.md#regex-table-regex) filter +5 | Blocked | ❌ | Domain contained in [exact blacklist](gravity/index.md#blacklist-table-blacklist) 6 | Blocked | ❌ | By upstream server (known blocking page IP address) 7 | Blocked | ❌ | By upstream server (`0.0.0.0` or `::`) 8 | Blocked | ❌ | By upstream server (`NXDOMAIN` with `RA` bit unset) -9 | Blocked | ❌ | Domain contained in [gravity database](../database/gravity/index.md#gravity-table-gravity)
    *Blocked during deep CNAME inspection* -10 | Blocked | ❌ | Domain matched by a [regex blacklist](../database/gravity/index.md#regex-table-regex) filter
    *Blocked during deep CNAME inspection* -11 | Blocked | ❌ | Domain contained in [exact blacklist](../database/gravity/index.md#blacklist-table-blacklist)
    *Blocked during deep CNAME inspection* +9 | Blocked | ❌ | Domain contained in [gravity database](gravity/index.md#gravity-table-gravity)
    *Blocked during deep CNAME inspection* +10 | Blocked | ❌ | Domain matched by a [regex blacklist](gravity/index.md#regex-table-regex) filter
    *Blocked during deep CNAME inspection* +11 | Blocked | ❌ | Domain contained in [exact blacklist](gravity/index.md#blacklist-table-blacklist)
    *Blocked during deep CNAME inspection* ### Example for interaction with the long-term query database diff --git a/docs/ftldns/compile.md b/docs/ftldns/compile.md index 93a464e..a9e03ca 100644 --- a/docs/ftldns/compile.md +++ b/docs/ftldns/compile.md @@ -8,13 +8,13 @@ Install them by running the following command in a terminal: ### Debian / Ubuntu / Raspbian ```bash -sudo apt install build-essential libgmp-dev m4 cmake libidn11-dev libreadline-dev +sudo apt install build-essential libgmp-dev m4 cmake libidn11-dev libreadline-dev xxd ``` ### Fedora ```bash -sudo dnf install gcc gmp-devel gmp-static m4 cmake libidn-devel readline-devel +sudo dnf install gcc gmp-devel gmp-static m4 cmake libidn-devel readline-devel xxd ``` ## Compile `libnettle` from source diff --git a/docs/ftldns/configfile.md b/docs/ftldns/configfile.md index 3b59853..a122fbf 100755 --- a/docs/ftldns/configfile.md +++ b/docs/ftldns/configfile.md @@ -206,7 +206,7 @@ Controls if *FTL*DNS should print extended details about regex matching into `pi Due to legacy reasons, we also support the following setting to be used for enabling the same functionality:
    `REGEX_DEBUGMODE=false|true` Note that if one of them is set to `true`, the other one cannot be used to disable this setting again.
    -**[More details](regex/overview.md)** +**[More details](../regex/overview.md)** #### `DEBUG_API=false|true` {#debug_api data-toc-label='Telnet'} diff --git a/docs/regex/approximate.md b/docs/regex/approximate.md new file mode 100644 index 0000000..097d906 --- /dev/null +++ b/docs/regex/approximate.md @@ -0,0 +1,97 @@ +# Approximative matching + +You may or not be know `agrep`. It is basically a "forgiving" `grep` and is, for instance, used for searching through (offline) dictionaries. It is tolerant against errors (up to degree you specify). It may be beneficial is you want to match against domains where you don't really know the pattern. It is just an idea, we will have to see if it is actually useful. + +This is a somewhat complicated topic, we'll approach it by examples as it is very complicated to get the head around it by just listening to the specifications. + +The approximate matching settings for a subpattern can be changed by appending *approx-settings* to the subpattern. Limits for the number of errors can be set and an expression for specifying and limiting the costs can be given: + +## Accepted **insertions** (`+`) + +Use `(something){+x}` to specify that the regex should still be matching when `x` characters would need it be *inserted* into the sub-expression `something`. + +Example: + +- `doubleclick.net` is matched by `^doubleclick\.(nt){+1}$` + +The missing `e` in `nt` is inserted. + +Similarly: + +- `doubleclick.net` is matched by `^(doubleclk\.nt){+3}$` + +The missing characters in the domain are substituted. The maximum number of insertions spans the entire domain as is wrapped in the sub-expression `(...)`. + +## Accepted **deletions** (`-`) + +Use `(something){-x}` to specify that the regex should still be matching when `x` characters would need it be *deleted* from the sub-expression `something`: + +Example: + +- `doubleclick.net` is matched by `^doubleclick\.(neet){-1}$` + +The surplus `e` in `neet` is deleted. + +Similarly: + +- `doubleclick.net` is matched by `^(doubleclicky\.netty){-3}$` +- `doubleclick.net` is NOT matched by `^(doubleclicky\.nettfy){-3}$` + +## Accepted **substitutions** (`#`) + +Use `(something){#x}` to specify that the regex should still be matching when `x` characters would need to be *substituted* from the sub-expression `something`: + +Example 1: + +- `oobargoobaploowap` is matched by `(foobar){#2~2}` +Hint: `goobap` is `foobar` with two substitutions `f->g` and `r->p` + +Example 2: + +- `doubleclick.net` is matched by `^doubleclick\.n(tt){#1}$` + +The incorrect `t` in `ntt` is substituted. Note that substitutions are necessary when a character needs to be replaced as the corresponding realization with one insertion and one deletion is **not identical**: + +`doubleclick.net` is matched by `^doubleclick\.n(tt){+1-1}$` + +(`t` is removed, `e` is added), however + +- `doubleclick.nt` is ALSO matched by `^doubleclick\.n(tt){+1-1}$` + +(the `t` is just removed, nothing had to be added) but + +- `doubleclick.nt` is NOT matched by `^doubleclick\.n(tt){#1}$` + +doesn't match as substitutions always require characters to be swapped by others. + +## Combinations and total error limit (`~`) + +All rules from above can be combined like as `{+2-5#6}` allowing (up to!) two insertions, five deletions, and six substitutions. You can enforce an upper limit on the number of tried realizations using the tilde. Even when `{+2-5#6}` can lead to up to 13 operations being tried, this can be limited to (at most) seven tries using `{+2-5#6~7}`. + +Example: + +- `oobargoobploowap` is matched by `(foobar){+2#2~3}` + + Hint: `goobaap` is `foobar` with + - two substitutions `f->g` and `r->p`, and + - one addition `a` between `bar` (to have `baap`) + +Specifying `~2` instead of `~3` will lead to no match as three errors need to be corrected in total for a match in this example. + +## Advanced topic: Cost-equation + +You can even weight the "costs" of insertions, deletions or substitutions. This is really an advanced topic and should only be touched when really needed. + +A *cost-equation* can be thought of as a mathematical equation, where `i`, `d`, and `s` stand for the number of insertions, deletions, and substitutions, respectively. The equation can have a multiplier for each of `i`, `d`, and `s`. +The multiplier is the **cost of the error**, and the number after `<` is the maximum allowed total cost of a match. Spaces and pluses can be inserted to make the equation more readable. When specifying only a cost equation, adding a space after the opening `{` is **required** . + +Example 1: `{ 2i + 1d + 2s < 5 }` + +This sets the cost of an insertion to two, a deletion to one, a substitution to two, and the maximum cost to five. + +Example 2: `{+2-5#6, 2i + 1d + 2s < 5 }` + +This sets the cost of an insertion to two, a deletion to one, a substitution to two, and the maximum cost to five. Furthermore, it allows only up to 2 insertions (coming at a total cost of 4), five deletions and up to 6 substitutions. As six substitutions would come at a cost of `6*2 = 12`, exeeding the total allowed costs of 5, they cannot all be realized. + + +{!abbreviations.md!} diff --git a/docs/ftldns/regex/overview.md b/docs/regex/overview.md similarity index 79% rename from docs/ftldns/regex/overview.md rename to docs/regex/overview.md index ae5a932..d09faa4 100644 --- a/docs/ftldns/regex/overview.md +++ b/docs/regex/overview.md @@ -1,7 +1,7 @@ -A regular expression, or RegEx for short, is a pattern that can be used for building arbitrarily complex filter rules in *FTL*DNS. -We implement the POSIX Extended Regular Expressions similar to the one used by the UNIX `egrep` (or `grep -E`) command. +A regular expression, or RegEx for short, is a pattern that **can be used for building arbitrarily complex filter** rules in *FTL*DNS. +We implement the POSIX Extended Regular Expressions similar to the one used by the UNIX `egrep` (or `grep -E`) command. We amend the regex engine by approximate blocking (compare to `agrep`) and other special features like matching to specific query types only. -Our implementation is light and fast as each domain is only checked once for a match (if you query `google.com`, it will be checked against your RegEx. Any subsequent query to the same domain will not be checked again until you restart `pihole-FTL`). +Our implementation is light and fast as each domain is only checked once for a match. When you query `google.com`, it will be checked against your RegEx. Any subsequent query to the same domain will not be checked again until you restart `pihole-FTL`. ## Hierarchy of regex filters in *FTL*DNS @@ -13,7 +13,7 @@ There are two locations where regex filters are important: ## How to use regular expressions for filtering domains -*FTL*DNS reads in regular expression filters from the two [`regex` database views](../../database/gravity/index.md). +*FTL*DNS reads in regular expression filters from the two [`regex` database views](../database/gravity/index.md). To tell *FTL*DNS to reload the list of regex filters, either: - Execute `pihole restartdns reload-lists` or @@ -26,7 +26,7 @@ The first command is to be preferred as it ensures that the DNS cache itself rem To ease the usage of regular expression filters in *FTL*DNS, we offer a regex debugging mode. Set -``` +``` plain DEBUG_REGEX=true ``` diff --git a/docs/regex/pi-hole.md b/docs/regex/pi-hole.md new file mode 100644 index 0000000..027ac87 --- /dev/null +++ b/docs/regex/pi-hole.md @@ -0,0 +1,144 @@ +# Pi-hole regex extensions + +## Only match specific query types + +You can amend the regular expressions by special keywords added at the end to fine-tine regular expressions to match only specific query types. + +Example: + +``` plain +abc;querytype=AAAA +``` + +will block + +``` bash +dig AAAA abc +``` + +but not + +``` bash +dig A abc +``` + +This allows you to do query type based black-/whitelisting. Some user-provided examples are: + +- `.*;querytype=!A` + + A regex blacklist entry for blocking `AAAA` (in fact, everything else than `A`, call it "anti-`A`") requests for all clients assigned to the same group. This has been mentioned to be benefitial for devices like Chromecast. You may want to fine-tune this further to specific domains. + +- `.*;querytype=PTR` + + A regex whitelist entry used to permit `PTR` lookups with the above "anti-`A`" regex + +- `.*;querytype=ANY` + + A regex blacklist entry to block `ANY` request network wide. + +## Invert matching + +Sometimes, it may be useful to be able to invert a regular expression altogether. Hence, we added the keyword `;invert` to achieve exactly this. + +For instance, + +``` plain +^abc$;querytype=AAAA;invert +``` + +will not block `abc` with type `AAAA` (but everything else) for the clients assigned to the same groups. This inversion is independent for the query type, e.g. + +``` plain +^abc$;invert +``` + +will block **not** block `abc` but **everything else**. + +## Comments + +You can specify comments withing your regex using the syntax + +``` plain +(?#some comment here) +``` + +The comment can contain any characters except for a closing parenthesis `)` (for the sole reason being the terminating element). The text in the comment is completely ignored by the regex parser and it used solely for readability purposes. + +``` plain +$ pihole-FTL regex-test "doubleclick.net" "(^|\.)doubleclick\.(?#TODO: We need to maybe support more than just .net here)net$" + +FTL Regex test: + Domain: "doubleclick.net" + Regex: "(^|\.)doubleclick\.(?#TODO: We need to maybe support more than just .net here)net$" +Step 1: Compiling regex filter... + Compiled regex filter in 0.167 msec +Step 2: Checking domain... + Done in 0.032 msec + +MATCH +``` + +## Back-references + +A back reference is a backslash followed by a single non-zero decimal digit `d`. It matches *the same sequence* of characters matched by the `d`th parenthesized subexpression. + +Example: + +``` plain +"cat.foo.dog---cat%dog!foo" is matched by "(cat)\.(foo)\.(dog)---\1%\3!\2" +``` + +Another (more complex example is): + +``` plain +(1234|4321)\.(foo)\.(dog)--\1 +``` + +``` plain + MATCH: 1234.foo.dog--1234 + MATCH: 4321.foo.dog--4321 +NO MATCH: 1234.foo.dog--4321 +``` + +Mind that the last line gives no match as `\1` matches **exactly** the same sequence the first character group matched. And `4321` is not the same as `1234` even when both are valid replies for `(1234|4321)` Back references are not defined for POSIX EREs (for BREs they are, surprisingly enough). We add them to ERE in the BRE style. + +``` plain +$ pihole-FTL regex-test "someverylongandmaybecomplexthing.foo.dog--someverylongandmaybecomplexthing" "(someverylongandmaybecomplexthing|somelesscomplexitem)\.(foo)\.(dog)--\1" + +FTL Regex test: + Domain: "someverylongandmaybecomplexthing.foo.dog--someverylongandmaybecomplexthing" + Regex: "(someverylongandmaybecomplexthing|somelesscomplexitem)\.(foo)\.(dog)--\1" +Step 1: Compiling regex filter... + Compiled regex filter in 0.563 msec +Step 2: Checking domain... + Done in 0.031 msec + +MATCH +``` + +## More character classes for bracket expressions + +A bracket expression specifies a set of characters by enclosing a nonempty list of items in brackets. Normally anything matching any item in the list is matched. If the list begins with `^` the meaning is negated; any character matching no item in the list is matched. + +1. Multiple characters: `[abc]` matches `a`, `b`, and `c`. +2. Character ranges: `[0-9]` matches any decimal digit. +3. Character classes: + - `[:alnum:]` alphanumeric characters + - `[:alpha:]` alphabetic characters + - `[:blank:]` blank characters + - `[:cntrl:]` control characters + - `[:digit:]` decimal digits (0 - 9) + - `[:graph:]` all printable characters except space + - `[:lower:]` lower-case letters (FTL matches case-insensitive by default) + - `[:print:]` printable characters including space + - `[:punct:]` printable characters not space or alphanumeric + - `[:space:]` white-space characters + - `[:upper:]` upper case letters (FTL matches case-insensitive by default) + - `[:xdigit:]` hexadecimal digits + +Furthermore, there are two shortcurts for some character classes: + +- `\d` - Digit character (equivalent to `[[:digit:]]`) +- `\D` - Non-digit character (equivalent to `[^[:digit:]]`) + +{!abbreviations.md!} diff --git a/docs/regex/testmode.md b/docs/regex/testmode.md new file mode 100644 index 0000000..f141df7 --- /dev/null +++ b/docs/regex/testmode.md @@ -0,0 +1,19 @@ +# Regex Test mode + +In order to ease regex development, we added a regex test mode to `pihole-FTL` which can be invoked like + +``` bash +pihole-FTL regex-test doubleclick.net +``` + +(test `doubleclick.net` against all regexs in the gravity database), or + +``` bash +pihole-FTL regex-test doubleclick.net "(^|\.)double" +``` + +(test `doubleclick.net` against the CLI-provided regex `(^|\.)double`. + +You do NOT need to be `sudo` for this, any arbitrary user should be able to run this command. The test returns `0` on match and `1` on no match and errors, hence, it may be used for scripting. + +{!abbreviations.md!} diff --git a/docs/ftldns/regex/tutorial.md b/docs/regex/tutorial.md similarity index 87% rename from docs/ftldns/regex/tutorial.md rename to docs/regex/tutorial.md index d96962f..0ca66e9 100644 --- a/docs/ftldns/regex/tutorial.md +++ b/docs/regex/tutorial.md @@ -89,13 +89,20 @@ Example | Interpretation In addition to character groups, there are also some special character classes available, such as -Character class | Group equivalent | Interpretation ---- | --- | --- -`[:digit:]` | `[0-9]` | matches digits -`[:lower:]` | `[a-z]` | matched lowercase letters -`[:upper:]` | `[A-Z]` | matched uppercase letters -`[:alpha:]` | `[A-Za-z]` | matches alphabetic characters -`[:alnum:]` | `[A-Za-z0-9]` | matches alphabetic characters and digits +Character class | Group equivalent | Pi-hole specific | Interpretation +--------------- | ---------------- | ---------------- | --------------- +`[:digit:]` | `[0-9]` | No | matches digits +`[:lower:]` | `[a-z]` | No | matched lowercase letters(FTL matches case-insensitive by default) +`[:upper:]` | `[A-Z]` | No | matched uppercase letters(FTL matches case-insensitive by default) +`[:alpha:]` | `[A-Za-z]` | No | matches alphabetic characters +`[:alnum:]` | `[A-Za-z0-9]` | No | matches alphabetic characters and digits +`[:blank:]` | `[ \t]` | Yes | blank characters +`[:cntrl:]` | N/A | Yes | control characters +`[:graph:]` | N/A | Yes | all printable characters except space +`[:print:]` | N/A | Yes | printable characters including space +`[:punct:]` | N/A | Yes | printable characters not space or alphanumeric +`[:space:]` | `[ \f\n\r\t\v]` | Yes | white-space characters +`[:xdigit:]` | `[0-9a-fA-F]` | Yes | hexadecimal digits # Advanced examples @@ -107,7 +114,7 @@ After going through our quick tutorial, we provide some more advanced examples s ^[0-9][^a-z]+\.((com)|(edu))$ ``` -Blocks domains containing only numbers (no letters) and ending in `.com` or `.edu`. Blocks `555661.com`, and `456.edu`, but not `555g555.com` +Blocks domains containing only numbers (no letters) and ending in `.com` or `.edu`. This blocks `555661.com`, and `456.edu`, but not `555g555.com` ### Block domains without subdomains diff --git a/mkdocs.yml b/mkdocs.yml index 2c9952e..f8e4264 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -79,9 +79,6 @@ nav: - 'DNS resolver': ftldns/dns-resolver.md - 'DNS cache': ftldns/dns-cache.md - 'Blocking mode': ftldns/blockingmode.md - - 'RegEx blocking': - - "Overview": ftldns/regex/overview.md - - "Tutorial": ftldns/regex/tutorial.md - 'Privacy levels': ftldns/privacylevels.md - 'Telnet API': ftldns/telnet-api.md - 'Signals': 'ftldns/signals.md' @@ -89,6 +86,12 @@ nav: - 'Install from source': ftldns/compile.md - 'Debugging FTLDNS': ftldns/debugging.md - 'In-depth manual': ftldns/in-depth.md + - 'RegEx blocking': + - "Overview": regex/overview.md + - "Testing": regex/testmode.md + - "Tutorial": regex/tutorial.md + - "Pi-hole extensions": regex/pi-hole.md + - "Approximate matching": regex/approximate.md - 'Docker': - 'DHCP': docker/DHCP.md - 'Contributing': @@ -158,7 +161,6 @@ plugins: - redirects: redirect_maps: 'ftldns/database.md': database/index.md - 'ftldns/regex/index.md': ftldns/regex/overview.md 'main/presentations.md': index.md 'main/prerequesites.md': main/prerequisites.md 'guides/unbound.md': guides/dns/unbound.md @@ -185,3 +187,6 @@ plugins: 'guides/nginx-configuration.md': 'guides/webserver/nginx.md' 'guides/caddy-configuration.md': 'guides/webserver/caddy.md' 'guides/traefik-configuration-nodocker.md': 'guides/webserver/traefik-nodocker.md' + 'ftldns/regex/index.md': regex/overview.md + 'ftldns/regex/overview.md': regex/overview.md + 'ftldns/regex/tutorial.md': regex/tutorial.md diff --git a/package.json b/package.json index a45d561..3556f06 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,7 @@ "scripts": { "build": "mkdocs build --clean", "markdownlint": "markdownlint-cli2 \"**/*.md\" \"!**/node_modules/**\"", - "linkinator": "linkinator site --recurse --silent --skip \"^(?!http://localhost)\"", + "linkinator": "npm run build && linkinator site --recurse --silent --skip \"^(?!http://localhost)\"", "test": "npm run markdownlint && npm run linkinator" }, "devDependencies": { From 687881ba272d6efc7c9fe7baa86e0665ecd7226c Mon Sep 17 00:00:00 2001 From: DL6ER Date: Tue, 2 Feb 2021 10:52:23 +0100 Subject: [PATCH 086/103] Update possible query types and query status in database documentation Signed-off-by: DL6ER --- docs/database/ftl.md | 36 +++++++++++++++++++++--------------- docs/regex/pi-hole.md | 6 ++++-- 2 files changed, 25 insertions(+), 17 deletions(-) diff --git a/docs/database/ftl.md b/docs/database/ftl.md index f750c9a..1d063e3 100644 --- a/docs/database/ftl.md +++ b/docs/database/ftl.md @@ -87,21 +87,24 @@ The FTL table contains some data used by *FTL*DNS for determining which queries ### Supported query types -ID | Query Type +ID | Resource Record (a.k.a. query type) --- | --- -1 | A -2 | AAAA -3 | ANY -4 | SRV -5 | SOA -6 | PTR -7 | TXT -8 | NAPTR -9 | MX -10 | DS -11 | RRSIG -12 | DNSKEY -13 | OTHER (any query type not covered above) +1 | `A` +2 | `AAAA` +3 | `ANY` +4 | `SRV` +5 | `SOA` +6 | `PTR` +7 | `TXT` +8 | `NAPTR` +9 | `MX` +10 | `DS` +11 | `RRSIG` +12 | `DNSKEY` +13 | `NS` +14 | `OTHER` (any query type not covered elsewhere) +15 | `SVCB` +16 | `HTTPS` @@ -112,7 +115,7 @@ ID | Query Type ID | Status | | Details --- | --- | --- | --- -0 | Unknown | ❔ | was not answered by forward destination +0 | Unknown | ❔ | Unknown status (not yet known) 1 | Blocked | ❌ | Domain contained in [gravity database](gravity/index.md#gravity-table-gravity) 2 | Allowed | ✅ | Forwarded 3 | Allowed | ✅ | Known, replied to from cache @@ -124,6 +127,9 @@ ID | Status | | Details 9 | Blocked | ❌ | Domain contained in [gravity database](gravity/index.md#gravity-table-gravity)
    *Blocked during deep CNAME inspection* 10 | Blocked | ❌ | Domain matched by a [regex blacklist](gravity/index.md#regex-table-regex) filter
    *Blocked during deep CNAME inspection* 11 | Blocked | ❌ | Domain contained in [exact blacklist](gravity/index.md#blacklist-table-blacklist)
    *Blocked during deep CNAME inspection* +12 | Allowed | ✅ | Retried query +13 | Allowed | ✅ | Retried but ignored query (this may happen during ongoing DNSSEC validation) +14 | Allowed | ✅ | Already forwarded, not forwarding again ### Example for interaction with the long-term query database diff --git a/docs/regex/pi-hole.md b/docs/regex/pi-hole.md index 027ac87..d0e90ac 100644 --- a/docs/regex/pi-hole.md +++ b/docs/regex/pi-hole.md @@ -2,7 +2,7 @@ ## Only match specific query types -You can amend the regular expressions by special keywords added at the end to fine-tine regular expressions to match only specific query types. +You can amend the regular expressions by special keywords added at the end to fine-tine regular expressions to match only specific [query types](../database/ftl.md#supported-query-types). Example: @@ -22,7 +22,9 @@ but not dig A abc ``` -This allows you to do query type based black-/whitelisting. Some user-provided examples are: +This allows you to do query type based black-/whitelisting. + +Some user-provided examples are: - `.*;querytype=!A` From 1639ffa725ff1d53eaf4a719f95245974f07a3f5 Mon Sep 17 00:00:00 2001 From: DL6ER Date: Tue, 2 Feb 2021 11:07:28 +0100 Subject: [PATCH 087/103] Add missing documentation for EDNS0_ECS and MAXNETAGE options. Signed-off-by: DL6ER --- docs/ftldns/configfile.md | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/docs/ftldns/configfile.md b/docs/ftldns/configfile.md index a122fbf..4a1c1b0 100755 --- a/docs/ftldns/configfile.md +++ b/docs/ftldns/configfile.md @@ -22,6 +22,13 @@ Use this option to disable deep CNAME inspection. This might be beneficial for v ESNI will obviously cause issues for `pixelserv-tls` which will be unable to generate matching certificates on-the-fly when it cannot read the SNI. Cloudflare and Firefox are already enabling ESNI. According to the IEFT draft (link above), we can easily restore `piselserv-tls`'s operation by replying `NXDOMAIN` to `_esni.` subdomains of blocked domains as this mimics a "not configured for this domain" behavior. +#### `EDNS0_ECS=true|false` (PR [#851](https://github.com/pi-hole/FTL/pull/851)) {#block_edns0_ecs data-toc-label='EDNS ECS overwrite'} + +Should we overwrite the query source when client information is provided through EDNS0 client subnet (ECS) information? +This allows Pi-hole to obtain client IPs even if they are hidden behind the NAT of a router. + +This feature has been requested and discussed on [Discourse](https://discourse.pi-hole.net/t/support-for-add-subnet-option-from-dnsmasq-ecs-edns0-client-subnet/35940) where further information how to use it can be found. + --- ### Statistics settings @@ -69,7 +76,7 @@ Should `FTL` try to resolve IPv4 addresses to hostnames? #### `DELAY_STARTUP=0` (PR [#716](https://github.com/pi-hole/FTL/pull/716)) {#delay_startup data-toc-label='Delay resolver startup'} -In certain configurations, you may want FTL to wait a given amount of time before trying to start the DNS revolver. This is typically found when network interfaces appear only late during system startup and the interface startup priorities are configured incorrectly. This setting takes any integer value between 0 and 300 seconds +In certain configurations, you may want FTL to wait a given amount of time before trying to start the DNS revolver. This is typically found when network interfaces appear only late during system startup and the interface startup priorities are configured incorrectly. This setting takes any integer value between 0 and 300 seconds. #### `NICE=-10` (PR [#798](https://github.com/pi-hole/FTL/pull/798)) {#nice data-toc-label='Set niceness'} @@ -81,6 +88,13 @@ to favor or disfavor a process in scheduling decisions. The range of the nice value varies across UNIX systems. On modern Linux, the range is `-20` (high priority = not very nice to other processes) to `+19` (low priority). +#### `MAXNETAGE=[MAXDBDAYS]` (PR [#871](https://github.com/pi-hole/FTL/pull/871)) {#maxnetage data-toc-label='Network table cleaning'} + +IP addresses (and associated host names) older than the specified number of days +are removed to avoid dead entries in the network overview table. This setting +defaults to the same value as `MAXDBDAYS` above but can be changed independently +if needed. + #### `NAMES_FROM_NETDB=true|false` (PR [#784](https://github.com/pi-hole/FTL/pull/784)) {#names_from_netdb data-toc-label='Load names from network table'} Control whether FTL should use the fallback option to try to obtain client names From f8718dabfd6a14febbf077f1fd603da385843edd Mon Sep 17 00:00:00 2001 From: DL6ER Date: Tue, 16 Feb 2021 22:26:47 +0100 Subject: [PATCH 088/103] Add documentation for FTL config option RATE_LIMIT (#474) Signed-off-by: DL6ER --- docs/ftldns/configfile.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/docs/ftldns/configfile.md b/docs/ftldns/configfile.md index 4a1c1b0..068e076 100755 --- a/docs/ftldns/configfile.md +++ b/docs/ftldns/configfile.md @@ -29,6 +29,17 @@ This allows Pi-hole to obtain client IPs even if they are hidden behind the NAT This feature has been requested and discussed on [Discourse](https://discourse.pi-hole.net/t/support-for-add-subnet-option-from-dnsmasq-ecs-edns0-client-subnet/35940) where further information how to use it can be found. +#### `RATE_LIMIT=1000/60` (PR [#1052](https://github.com/pi-hole/FTL/pull/1052)) {#rate_limit data-toc-label='Query rate limiting'} + +Control FTL's query rate-limiting. Rate-limited queries are answered with a `REFUSED` reply and not further processed by FTL. + +The default settings for FTL's rate-limiting are to permit no more than `1000` queries in `60` seconds. Both numbers can be customized independently. +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. + +For this setting, both numbers, the maximum number of queries within a given time, **and** the length of the time interval (seconds) have to be specified. For instance, if you want to set a rate limit of 1 query per hour, the option should look like `RATE_LIMIT=1/3600`. + +Rate-limiting may be disabled altogether by setting `RATE_LIMIT=0/0` (this results in the same behavior as before FTL v5.7). + --- ### Statistics settings From 04c6d65a654d39ee35b26123b5fe1fdf0b1935e5 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Sat, 27 Feb 2021 10:14:04 +0000 Subject: [PATCH 089/103] Bump markdownlint-cli2 from 0.0.13 to 0.0.14 Bumps [markdownlint-cli2](https://github.com/DavidAnson/markdownlint-cli2) from 0.0.13 to 0.0.14. - [Release notes](https://github.com/DavidAnson/markdownlint-cli2/releases) - [Commits](https://github.com/DavidAnson/markdownlint-cli2/compare/v0.0.13...v0.0.14) Signed-off-by: dependabot-preview[bot] --- package-lock.json | 71 +++++++++++++++++++++++++++++------------------ package.json | 2 +- 2 files changed, 45 insertions(+), 28 deletions(-) diff --git a/package-lock.json b/package-lock.json index a93e124..a0ce774 100644 --- a/package-lock.json +++ b/package-lock.json @@ -637,9 +637,9 @@ "dev": true }, "fast-glob": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.4.tgz", - "integrity": "sha512-kr/Oo6PX51265qeuCYsyGypiO5uJFgBS0jksyG7FUeCyQzNwYnzrNIMR1NXfkZXsMYXYLRAHgISHBz8gQcxKHQ==", + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.5.tgz", + "integrity": "sha512-2DtFcgT68wiTTiwZ2hNdJfcHNke9XOfnwmBRWXhmeKM8rF0TGwmC/Qto3S7RoZKp5cilZbxzO5iTNTQsJ+EeDg==", "dev": true, "requires": { "@nodelib/fs.stat": "^2.0.2", @@ -660,9 +660,9 @@ } }, "fastq": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.10.0.tgz", - "integrity": "sha512-NL2Qc5L3iQEsyYzweq7qfgy5OtXCmGzGvhElGEd/SoFWEMOEczNh5s5ocaF01HDetxz+p8ecjNPA6cZxxIHmzA==", + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.11.0.tgz", + "integrity": "sha512-7Eczs8gIPDrVzT+EksYBcupqMyxSHXXrHOLRRxU2/DicV8789MRBRR8+Hc2uWzUupOs4YS4JzBmBxjjCVBxD/g==", "dev": true, "requires": { "reusify": "^1.0.4" @@ -1135,37 +1135,45 @@ "dev": true }, "markdown-it": { - "version": "12.0.2", - "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-12.0.2.tgz", - "integrity": "sha512-4Lkvjbv2kK+moL9TbeV+6/NHx+1Q+R/NIdUlFlkqkkzUcTod4uiyTJRiBidKR9qXSdkNFkgv+AELY8KN9vSgVA==", + "version": "12.0.4", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-12.0.4.tgz", + "integrity": "sha512-34RwOXZT8kyuOJy25oJNJoulO8L0bTHYWXcdZBYZqFnjIy3NgjeoM3FmPXIOFQ26/lSHYMr8oc62B6adxXcb3Q==", "dev": true, "requires": { "argparse": "^2.0.1", - "entities": "~2.0.0", + "entities": "~2.1.0", "linkify-it": "^3.0.1", "mdurl": "^1.0.1", "uc.micro": "^1.0.5" + }, + "dependencies": { + "entities": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.1.0.tgz", + "integrity": "sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w==", + "dev": true + } } }, "markdownlint": { - "version": "0.22.0", - "resolved": "https://registry.npmjs.org/markdownlint/-/markdownlint-0.22.0.tgz", - "integrity": "sha512-J4B+iMc12pOdp/wfYi03W2qfAfEyiZzq3qvQh/8vOMNU8vXYY6Jg440EY7dWTBCqROhb1i4nAn3BTByJ5kdx1w==", + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/markdownlint/-/markdownlint-0.23.1.tgz", + "integrity": "sha512-iOEwhDfNmq2IJlaA8mzEkHYUi/Hwoa6Ss+HO5jkwUR6wQ4quFr0WzSx+Z9rsWZKUaPbyirIdL1zGmJRkWawr4Q==", "dev": true, "requires": { - "markdown-it": "12.0.2" + "markdown-it": "12.0.4" } }, "markdownlint-cli2": { - "version": "0.0.13", - "resolved": "https://registry.npmjs.org/markdownlint-cli2/-/markdownlint-cli2-0.0.13.tgz", - "integrity": "sha512-Fg4bIf70vPW9CHHBE6wkL5TYwOF/bQ7XQ+VGXLws5TTgP8voaeVmF085TkyWYOSippWRU+Ify1VkMw1S0VlbwA==", + "version": "0.0.14", + "resolved": "https://registry.npmjs.org/markdownlint-cli2/-/markdownlint-cli2-0.0.14.tgz", + "integrity": "sha512-h3aXjve9y7pVXJMpka6msP4aGIJamju0Gv7L9knRz3nAdhhaW1aOiRvnLGgqu7BZyp1y7agjWnx8ojh7iLCCeg==", "dev": true, "requires": { - "globby": "~11.0.1", - "markdownlint": "~0.22.0", + "globby": "~11.0.2", + "markdownlint": "~0.23.1", "markdownlint-cli2-formatter-default": "~0.0.2", - "markdownlint-rule-helpers": "~0.13.0", + "markdownlint-rule-helpers": "~0.14.0", "micromatch": "~4.0.2", "strip-json-comments": "~3.1.1", "yaml": "~1.10.0" @@ -1186,9 +1194,9 @@ "dev": true }, "markdownlint-rule-helpers": { - "version": "0.13.0", - "resolved": "https://registry.npmjs.org/markdownlint-rule-helpers/-/markdownlint-rule-helpers-0.13.0.tgz", - "integrity": "sha512-rRY0itbcHG4e+ntz0bbY3AIceSJMKS0TafEMgEtKVHRZ54/JUSy6/4ypCL618RlJvYRej+xMLxX5nkJqIeTZaQ==", + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/markdownlint-rule-helpers/-/markdownlint-rule-helpers-0.14.0.tgz", + "integrity": "sha512-vRTPqSU4JK8vVXmjICHSBhwXUvbfh/VJo+j7hvxqe15tLJyomv3FLgFdFgb8kpj0Fe8SsJa/TZUAXv7/sN+N7A==", "dev": true }, "marked": { @@ -1514,6 +1522,12 @@ "escape-goat": "^2.0.0" } }, + "queue-microtask": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.2.tgz", + "integrity": "sha512-dB15eXv3p2jDlbOiNLyMabYg1/sXvppd8DP2J3EOCQ0AkuSXCW2tP7mnVouVLJKgUMY6yP0kcQDVpLCN13h4Xg==", + "dev": true + }, "quick-lru": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz", @@ -1655,10 +1669,13 @@ "dev": true }, "run-parallel": { - "version": "1.1.10", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.1.10.tgz", - "integrity": "sha512-zb/1OuZ6flOlH6tQyMPUrE3x3Ulxjlo9WIVXR4yVYi4H9UXQaeIsPbLn2R3O3vQCnDKkAl2qHiuocKKX4Tz/Sw==", - "dev": true + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "requires": { + "queue-microtask": "^1.2.2" + } }, "semver": { "version": "7.3.4", diff --git a/package.json b/package.json index 3556f06..9354178 100644 --- a/package.json +++ b/package.json @@ -23,6 +23,6 @@ }, "devDependencies": { "linkinator": "^2.13.0", - "markdownlint-cli2": "0.0.13" + "markdownlint-cli2": "0.0.14" } } From d914ee60b1e1ec53d5051dee0c3b3fdf3a9556e4 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Sun, 28 Feb 2021 13:35:59 +0000 Subject: [PATCH 090/103] Bump linkinator from 2.13.0 to 2.13.6 Bumps [linkinator](https://github.com/JustinBeckwith/linkinator) from 2.13.0 to 2.13.6. - [Release notes](https://github.com/JustinBeckwith/linkinator/releases) - [Commits](https://github.com/JustinBeckwith/linkinator/compare/v2.13.0...v2.13.6) Signed-off-by: dependabot-preview[bot] --- package-lock.json | 334 ++++++++++++++++++---------------------------- package.json | 2 +- 2 files changed, 130 insertions(+), 206 deletions(-) diff --git a/package-lock.json b/package-lock.json index a0ce774..f1797c9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5,12 +5,12 @@ "requires": true, "dependencies": { "@babel/code-frame": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", - "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.13.tgz", + "integrity": "sha512-HV1Cm0Q3ZrpCR93tkWOYiuYIgLxZXZFVG2VgK+MBWjUqZTundupbfx2aXarXuw5Ko5aMcjtJgbSs4vUGBS5v6g==", "dev": true, "requires": { - "@babel/highlight": "^7.10.4" + "@babel/highlight": "^7.12.13" } }, "@babel/helper-validator-identifier": { @@ -20,12 +20,12 @@ "dev": true }, "@babel/highlight": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", - "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", + "version": "7.13.8", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.13.8.tgz", + "integrity": "sha512-4vrIhfJyfNf+lCtXC2ck1rKSzDwciqF7IWFhXXrSOUC2O5DrVp+w4c6ed4AllTxhTkUP5x2tYj41VaxdVMMRDw==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.10.4", + "@babel/helper-validator-identifier": "^7.12.11", "chalk": "^2.0.0", "js-tokens": "^4.0.0" }, @@ -221,35 +221,31 @@ "dev": true }, "boxen": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/boxen/-/boxen-4.2.0.tgz", - "integrity": "sha512-eB4uT9RGzg2odpER62bBwSLvUeGC+WbRjjyyFhGsKnc8wp/m0+hQsMUvUe3H2V0D5vw0nBdO1hCJoZo5mKeuIQ==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/boxen/-/boxen-5.0.0.tgz", + "integrity": "sha512-5bvsqw+hhgUi3oYGK0Vf4WpIkyemp60WBInn7+WNfoISzAqk/HX4L7WNROq38E6UR/y3YADpv6pEm4BfkeEAdA==", "dev": true, "requires": { "ansi-align": "^3.0.0", - "camelcase": "^5.3.1", - "chalk": "^3.0.0", - "cli-boxes": "^2.2.0", - "string-width": "^4.1.0", - "term-size": "^2.1.0", - "type-fest": "^0.8.1", - "widest-line": "^3.1.0" + "camelcase": "^6.2.0", + "chalk": "^4.1.0", + "cli-boxes": "^2.2.1", + "string-width": "^4.2.0", + "type-fest": "^0.20.2", + "widest-line": "^3.1.0", + "wrap-ansi": "^7.0.0" }, "dependencies": { - "chalk": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } + "camelcase": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", + "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==", + "dev": true }, "type-fest": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", - "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", "dev": true } } @@ -273,12 +269,6 @@ "fill-range": "^7.0.1" } }, - "bytes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", - "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=", - "dev": true - }, "cacheable-request": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz", @@ -351,14 +341,6 @@ "htmlparser2": "^6.0.0", "parse5": "^6.0.0", "parse5-htmlparser2-tree-adapter": "^6.0.0" - }, - "dependencies": { - "entities": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.1.0.tgz", - "integrity": "sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w==", - "dev": true - } } }, "cheerio-select-tmp": { @@ -430,12 +412,6 @@ "xdg-basedir": "^4.0.0" } }, - "content-disposition": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz", - "integrity": "sha1-DPaLud318r55YcOoUXjLhdunjLQ=", - "dev": true - }, "crypto-random-string": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz", @@ -592,9 +568,9 @@ } }, "entities": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.0.3.tgz", - "integrity": "sha512-MyoZ0jgnLvB2X3Lg5HqpFmn1kybDiIfEQmKzTb5apr51Rb+T3KdmMiqa70T+bhGnyv7bQ6WMj2QMHpGMmlrUYQ==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.1.0.tgz", + "integrity": "sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w==", "dev": true }, "error-ex": { @@ -612,6 +588,12 @@ "integrity": "sha512-8/uIhbG12Csjy2JEW7D9pHbreaVaS/OpN3ycnyvElTdwM5n6GY6W6e2IPemfvGZeUMqZ9A/3GqIZMgKnBhAw/Q==", "dev": true }, + "escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=", + "dev": true + }, "escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", @@ -624,12 +606,6 @@ "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", "dev": true }, - "eventemitter3": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", - "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", - "dev": true - }, "extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", @@ -650,15 +626,6 @@ "picomatch": "^2.2.1" } }, - "fast-url-parser": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/fast-url-parser/-/fast-url-parser-1.1.3.tgz", - "integrity": "sha1-9K8+qfNNiicc9YrSs3WfQx8LMY0=", - "dev": true, - "requires": { - "punycode": "^1.3.2" - } - }, "fastq": { "version": "1.11.0", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.11.0.tgz", @@ -745,12 +712,12 @@ } }, "global-dirs": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-2.1.0.tgz", - "integrity": "sha512-MG6kdOUh/xBnyo9cJFeIKkLEc1AyFq42QTU4XiX51i2NEdxLxLWXIjEjmqKeSuKR7pAZjTqUVoT2b2huxVLgYQ==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-3.0.0.tgz", + "integrity": "sha512-v8ho2DS5RiCjftj1nD9NmnfaOzTdud7RRnVd9kFNOjqZbISlx5DQ+OrTkywgd0dIt7oFCvKetZSHoHcP3sDdiA==", "dev": true, "requires": { - "ini": "1.3.7" + "ini": "2.0.0" } }, "globby": { @@ -787,9 +754,9 @@ } }, "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "version": "4.2.6", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz", + "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==", "dev": true }, "hard-rejection": { @@ -820,9 +787,9 @@ "dev": true }, "hosted-git-info": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-3.0.7.tgz", - "integrity": "sha512-fWqc0IcuXs+BmE9orLDyVykAG9GJtGLGuZAAqgcckPgv5xad4AcXGIv8galtQvlwutxSlaMcdw7BUtq2EIvqCQ==", + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-3.0.8.tgz", + "integrity": "sha512-aXpmwoOhRBrw6X3j0h5RloK4x1OzsxMPyxqIHyNfSe2pypkVTZFpEiRoSipPEPlMrh0HW/XsjkJ5WgnCirpNUw==", "dev": true, "requires": { "lru-cache": "^6.0.0" @@ -897,9 +864,9 @@ "dev": true }, "ini": { - "version": "1.3.7", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.7.tgz", - "integrity": "sha512-iKpRpXP+CrP2jyrxvg1kMUpXDyRUFDWurxbnVT1vQPx+Wz9uCYsMIqYuSBLV+PAaZG/d7kRLKRFc9oDMsH+mFQ==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ini/-/ini-2.0.0.tgz", + "integrity": "sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==", "dev": true }, "is-arrayish": { @@ -948,13 +915,13 @@ } }, "is-installed-globally": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.3.2.tgz", - "integrity": "sha512-wZ8x1js7Ia0kecP/CHM/3ABkAmujX7WPvQk6uu3Fly/Mk44pySulQpnHG46OMjHGXApINnV4QhY3SWnECO2z5g==", + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.4.0.tgz", + "integrity": "sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ==", "dev": true, "requires": { - "global-dirs": "^2.0.1", - "is-path-inside": "^3.0.1" + "global-dirs": "^3.0.0", + "is-path-inside": "^3.0.2" } }, "is-npm": { @@ -1024,9 +991,9 @@ "dev": true }, "jsonexport": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/jsonexport/-/jsonexport-3.1.0.tgz", - "integrity": "sha512-QekAMWAZZN263aDbA5J06U+dCwRxS+L4vCYGh5pbnI0pw4T2A0RaDWE9APOPcxvGsQcjUvfHiywvnTo/n5Bzcg==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/jsonexport/-/jsonexport-3.2.0.tgz", + "integrity": "sha512-GbO9ugb0YTZatPd/hqCGR0FSwbr82H6OzG04yzdrG7XOe4QZ0jhQ+kOsB29zqkzoYJLmLxbbrFiuwbQu891XnQ==", "dev": true }, "keyv": { @@ -1069,20 +1036,20 @@ } }, "linkinator": { - "version": "2.13.0", - "resolved": "https://registry.npmjs.org/linkinator/-/linkinator-2.13.0.tgz", - "integrity": "sha512-CSktxDpKO80fPs89x/lv8fsUv5fAljvp2kIIF+bbMG6ZN/T02K6KUlsuGm+lK1eJfcKtaopji0dPOFmRvbssmA==", + "version": "2.13.6", + "resolved": "https://registry.npmjs.org/linkinator/-/linkinator-2.13.6.tgz", + "integrity": "sha512-kE4hB0+d5ZDYI6NrC10TlXHTU2OXYVoigJRka58qZ9RwGaAVKpdhLWRLv9k94VTPo7rE6LDwWohqmp1IA7sLTg==", "dev": true, "requires": { "chalk": "^4.0.0", "cheerio": "^1.0.0-rc.5", + "escape-html": "^1.0.3", "gaxios": "^4.0.0", "glob": "^7.1.6", "jsonexport": "^3.0.0", - "marked": "^1.2.5", - "meow": "^8.0.0", - "p-queue": "^6.2.1", - "serve-handler": "^6.1.3", + "marked": "^2.0.0", + "meow": "^9.0.0", + "mime": "^2.5.0", "server-destroy": "^1.0.1", "update-notifier": "^5.0.0" } @@ -1200,9 +1167,9 @@ "dev": true }, "marked": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/marked/-/marked-1.2.7.tgz", - "integrity": "sha512-No11hFYcXr/zkBvL6qFmAp1z6BKY3zqLMHny/JN/ey+al7qwCM2+CMBL9BOgqMxZU36fz4cCWfn2poWIf7QRXA==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/marked/-/marked-2.0.1.tgz", + "integrity": "sha512-5+/fKgMv2hARmMW7DOpykr2iLhl0NgjyELk5yn92iE7z8Se1IS9n3UsFm86hFXIkvMBmVxki8+ckcpjBeyo/hw==", "dev": true }, "mdurl": { @@ -1212,13 +1179,14 @@ "dev": true }, "meow": { - "version": "8.1.2", - "resolved": "https://registry.npmjs.org/meow/-/meow-8.1.2.tgz", - "integrity": "sha512-r85E3NdZ+mpYk1C6RjPFEMSE+s1iZMuHtsHAqY0DT3jZczl0diWUZ8g6oU7h0M9cD2EL+PzaYghhCLzR0ZNn5Q==", + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/meow/-/meow-9.0.0.tgz", + "integrity": "sha512-+obSblOQmRhcyBt62furQqRAQpNyWXo8BuQ5bN7dG8wmwQ+vwHKp/rCFD4CrTP8CsDQD1sjoZ94K417XEUk8IQ==", "dev": true, "requires": { "@types/minimist": "^1.2.0", "camelcase-keys": "^6.2.2", + "decamelize": "^1.2.0", "decamelize-keys": "^1.1.0", "hard-rejection": "^2.1.0", "minimist-options": "4.1.0", @@ -1246,21 +1214,12 @@ "picomatch": "^2.0.5" } }, - "mime-db": { - "version": "1.33.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.33.0.tgz", - "integrity": "sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ==", + "mime": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.5.2.tgz", + "integrity": "sha512-tqkh47FzKeCPD2PUiPB6pkbMzsCasjxAfC62/Wap5qrUWcb+sFasXUC5I3gYM5iBM8v/Qpn4UK0x+j0iHyFPDg==", "dev": true }, - "mime-types": { - "version": "2.1.18", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.18.tgz", - "integrity": "sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==", - "dev": true, - "requires": { - "mime-db": "~1.33.0" - } - }, "mimic-response": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", @@ -1353,12 +1312,6 @@ "integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==", "dev": true }, - "p-finally": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", - "dev": true - }, "p-limit": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", @@ -1377,25 +1330,6 @@ "p-limit": "^2.2.0" } }, - "p-queue": { - "version": "6.6.2", - "resolved": "https://registry.npmjs.org/p-queue/-/p-queue-6.6.2.tgz", - "integrity": "sha512-RwFpb72c/BhQLEXIZ5K2e+AhgNVmIejGlTgiB9MzZ0e93GRvqZ7uSi0dvRF7/XIXDeNkra2fNHBxTyPDGySpjQ==", - "dev": true, - "requires": { - "eventemitter3": "^4.0.4", - "p-timeout": "^3.2.0" - } - }, - "p-timeout": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-3.2.0.tgz", - "integrity": "sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg==", - "dev": true, - "requires": { - "p-finally": "^1.0.0" - } - }, "p-try": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", @@ -1423,9 +1357,9 @@ } }, "parse-json": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.1.0.tgz", - "integrity": "sha512-+mi/lmVVNKFNVyLXV31ERiy2CY5E1/F6QtJFEzoChPRwwngMNXRDQ9GJ5WdE2Z2P4AujsOi0/+2qHID68KwfIQ==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", @@ -1461,24 +1395,12 @@ "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", "dev": true }, - "path-is-inside": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", - "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", - "dev": true - }, "path-parse": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", "dev": true }, - "path-to-regexp": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-2.2.1.tgz", - "integrity": "sha512-gu9bD6Ta5bwGrrU8muHzVOBFFREpp2iRkVfhBJahwJ6p6Xw20SjT0MxLnwkjOibQmGSYhiUnf2FLe7k+jcFmGQ==", - "dev": true - }, "path-type": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", @@ -1507,12 +1429,6 @@ "once": "^1.3.1" } }, - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", - "dev": true - }, "pupa": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/pupa/-/pupa-2.1.1.tgz", @@ -1534,12 +1450,6 @@ "integrity": "sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==", "dev": true }, - "range-parser": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz", - "integrity": "sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4=", - "dev": true - }, "rc": { "version": "1.2.8", "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", @@ -1550,6 +1460,14 @@ "ini": "~1.3.0", "minimist": "^1.2.0", "strip-json-comments": "~2.0.1" + }, + "dependencies": { + "ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "dev": true + } } }, "read-pkg": { @@ -1644,12 +1562,12 @@ } }, "resolve": { - "version": "1.19.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.19.0.tgz", - "integrity": "sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg==", + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", + "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", "dev": true, "requires": { - "is-core-module": "^2.1.0", + "is-core-module": "^2.2.0", "path-parse": "^1.0.6" } }, @@ -1703,22 +1621,6 @@ } } }, - "serve-handler": { - "version": "6.1.3", - "resolved": "https://registry.npmjs.org/serve-handler/-/serve-handler-6.1.3.tgz", - "integrity": "sha512-FosMqFBNrLyeiIDvP1zgO6YoTzFYHxLDEIavhlmQ+knB2Z7l1t+kGLHkZIDN7UVWqQAmKI3D20A6F6jo3nDd4w==", - "dev": true, - "requires": { - "bytes": "3.0.0", - "content-disposition": "0.5.2", - "fast-url-parser": "1.1.3", - "mime-types": "2.1.18", - "minimatch": "3.0.4", - "path-is-inside": "1.0.2", - "path-to-regexp": "2.2.1", - "range-parser": "1.2.0" - } - }, "server-destroy": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/server-destroy/-/server-destroy-1.0.1.tgz", @@ -1770,9 +1672,9 @@ "dev": true }, "string-width": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", - "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.1.tgz", + "integrity": "sha512-LL0OLyN6AnfV9xqGQpDBwedT2Rt63737LxvsRxbcwpa2aIeynBApG2Sm//F3TaLHIR1aJBN52DWklc06b94o5Q==", "dev": true, "requires": { "emoji-regex": "^8.0.0", @@ -1842,12 +1744,6 @@ "has-flag": "^4.0.0" } }, - "term-size": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/term-size/-/term-size-2.2.1.tgz", - "integrity": "sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==", - "dev": true - }, "to-readable-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-1.0.0.tgz", @@ -1900,23 +1796,23 @@ } }, "update-notifier": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-5.0.1.tgz", - "integrity": "sha512-BuVpRdlwxeIOvmc32AGYvO1KVdPlsmqSh8KDDBxS6kDE5VR7R8OMP1d8MdhaVBvxl4H3551k9akXr0Y1iIB2Wg==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-5.1.0.tgz", + "integrity": "sha512-ItnICHbeMh9GqUy31hFPrD1kcuZ3rpxDZbf4KUDavXwS0bW5m7SLbDQpGX3UYr072cbrF5hFUs3r5tUsPwjfHw==", "dev": true, "requires": { - "boxen": "^4.2.0", + "boxen": "^5.0.0", "chalk": "^4.1.0", "configstore": "^5.0.1", "has-yarn": "^2.1.0", "import-lazy": "^2.1.0", "is-ci": "^2.0.0", - "is-installed-globally": "^0.3.2", + "is-installed-globally": "^0.4.0", "is-npm": "^5.0.0", "is-yarn-global": "^0.3.0", "latest-version": "^5.1.0", "pupa": "^2.1.1", - "semver": "^7.3.2", + "semver": "^7.3.4", "semver-diff": "^3.1.1", "xdg-basedir": "^4.0.0" } @@ -1949,6 +1845,34 @@ "string-width": "^4.0.0" } }, + "wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true + }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.0" + } + } + } + }, "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", @@ -1986,9 +1910,9 @@ "dev": true }, "yargs-parser": { - "version": "20.2.4", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", - "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", + "version": "20.2.6", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.6.tgz", + "integrity": "sha512-AP1+fQIWSM/sMiET8fyayjx/J+JmTPt2Mr0FkrgqB4todtfa53sOsrSAcIrJRD5XS20bKUwaDIuMkWKCEiQLKA==", "dev": true } } diff --git a/package.json b/package.json index 9354178..19c7c69 100644 --- a/package.json +++ b/package.json @@ -22,7 +22,7 @@ "test": "npm run markdownlint && npm run linkinator" }, "devDependencies": { - "linkinator": "^2.13.0", + "linkinator": "^2.13.6", "markdownlint-cli2": "0.0.14" } } From f93a38feae02fc7e43cf448574aa6d031332a3c6 Mon Sep 17 00:00:00 2001 From: Anton S Date: Mon, 1 Mar 2021 19:42:41 +0200 Subject: [PATCH 091/103] removed script extension (.sh) for the cron files The cron.weekly scripts are started by run-parts which skips all files with extension. https://serverfault.com/questions/408093/why-does-cron-weekly-not-run --- docs/guides/dns/cloudflared.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/guides/dns/cloudflared.md b/docs/guides/dns/cloudflared.md index 8778202..101f512 100644 --- a/docs/guides/dns/cloudflared.md +++ b/docs/guides/dns/cloudflared.md @@ -232,11 +232,11 @@ sudo systemctl restart cloudflared #### Automating Cloudflared Updates If you want to have the system update `cloudflared` automatically, simply place the update commands for your configuration method in the -file `/etc/cron.weekly/cloudflared-updater.sh`, and adjust permissions: +file `/etc/cron.weekly/cloudflared-updater`, and adjust permissions: ```bash -sudo chmod +x /etc/cron.weekly/cloudflared-updater.sh -sudo chown root:root /etc/cron.weekly/cloudflared-updater.sh +sudo chmod +x /etc/cron.weekly/cloudflared-updater +sudo chown root:root /etc/cron.weekly/cloudflared-updater ``` The system will now attempt to update the cloudflared binary automatically, once per week. From 4ffc9e8ab8bab5edd7b3c2dd22b9e066dbf6bd21 Mon Sep 17 00:00:00 2001 From: zuccs Date: Sun, 7 Mar 2021 07:06:27 +1100 Subject: [PATCH 092/103] Update "alternative support" links as per homepage (#472) Trust this is meant to be here too! --- docs/index.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/index.md b/docs/index.md index 6185927..802a32f 100755 --- a/docs/index.md +++ b/docs/index.md @@ -44,7 +44,9 @@ Sending a donation using our links below is **extremely helpful** in offsetting If you'd rather not donate (_which is okay!_), there are other ways you can help support us: +- [Patreon](https://patreon.com/pihole) _Become a patron for rewards_ - [Digital Ocean](https://www.digitalocean.com/?refcode=344d234950e1) _new account credits with our affiliate link_ +- [Stickermule](https://www.stickermule.com/unlock?ref_id=9127301701&utm_medium=link&utm_source=invite) _earn a $10 credit after your first purchase_ - [Amazon](https://www.amazon.com/exec/obidos/redirect-home/pihole09-20) _affiliate link_ - Spreading the word about our software, and how you have benefited from it From 5c46dc4c01a50385757c64d4287e08a9ccca9776 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Sat, 6 Mar 2021 12:11:40 -0800 Subject: [PATCH 093/103] Bump mkdocs-material from 6.2.6 to 7.0.4 (#481) Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 6.2.6 to 7.0.4. - [Release notes](https://github.com/squidfunk/mkdocs-material/releases) - [Changelog](https://github.com/squidfunk/mkdocs-material/blob/master/docs/changelog.md) - [Commits](https://github.com/squidfunk/mkdocs-material/compare/6.2.6...7.0.4) Signed-off-by: dependabot-preview[bot] Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> Co-authored-by: Dan Schaper --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 82c1202..4e0e556 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,5 @@ markdown-include==0.6.0 mkdocs==1.1.2 mkdocs-git-revision-date-localized-plugin==0.8 -mkdocs-material==6.2.6 +mkdocs-material==7.0.4 mkdocs-redirects==1.0.1 From 5016a3c6c870b7ec896533b93c1d5603a3b250ee Mon Sep 17 00:00:00 2001 From: Bego Mario Garde Date: Sat, 6 Mar 2021 21:49:22 +0100 Subject: [PATCH 094/103] Update cloudflared.md (#475) The proposed software has a bug that stops it from working on some Raspberry Pi models. I have added a note and suggested the use of an older version as a workaround. --- docs/guides/dns/cloudflared.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/guides/dns/cloudflared.md b/docs/guides/dns/cloudflared.md index 101f512..e84e8ec 100644 --- a/docs/guides/dns/cloudflared.md +++ b/docs/guides/dns/cloudflared.md @@ -58,6 +58,8 @@ sudo chmod +x /usr/local/bin/cloudflared cloudflared -v ``` +Note: Users [have reported](https://github.com/cloudflare/cloudflared/issues/38) that the current version of cloudflared produces a segementation fault error on Raspberry Pi Zero W, Model 1B and 2B. As a workaround you can use an older version provided at instead. + #### `cloudflared` archive page You can find all `cloudflared` binary releases on . From 2c5ca37a2c6926904bc96f3b2370c1c860d73ec0 Mon Sep 17 00:00:00 2001 From: DL6ER Date: Sat, 27 Mar 2021 09:21:33 +0100 Subject: [PATCH 095/103] Recommend to use nettle 3.7.2 Signed-off-by: DL6ER --- docs/ftldns/compile.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/ftldns/compile.md b/docs/ftldns/compile.md index a9e03ca..e4c33d8 100644 --- a/docs/ftldns/compile.md +++ b/docs/ftldns/compile.md @@ -23,9 +23,9 @@ sudo dnf install gcc gmp-devel gmp-static m4 cmake libidn-devel readline-devel x Compile and install a recent version using: ```bash -wget https://ftp.gnu.org/gnu/nettle/nettle-3.6.tar.gz -tar -xzf nettle-3.6.tar.gz -cd nettle-3.6 +wget https://ftp.gnu.org/gnu/nettle/nettle-3.7.2.tar.gz +tar -xzf nettle-3.7.2.tar.gz +cd nettle-3.7.2 ./configure --libdir=/usr/local/lib make -j $(nproc) sudo make install From 494a1c4b52b497338baa9fda38488cfbd347715d Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Sat, 27 Mar 2021 10:14:19 +0000 Subject: [PATCH 096/103] Bump markdownlint-cli2 from 0.0.14 to 0.0.15 Bumps [markdownlint-cli2](https://github.com/DavidAnson/markdownlint-cli2) from 0.0.14 to 0.0.15. - [Release notes](https://github.com/DavidAnson/markdownlint-cli2/releases) - [Commits](https://github.com/DavidAnson/markdownlint-cli2/compare/v0.0.14...v0.0.15) Signed-off-by: dependabot-preview[bot] --- package-lock.json | 44 ++++++++++++++++++-------------------------- package.json | 2 +- 2 files changed, 19 insertions(+), 27 deletions(-) diff --git a/package-lock.json b/package-lock.json index f1797c9..b0fcba5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -703,9 +703,9 @@ } }, "glob-parent": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", - "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "dev": true, "requires": { "is-glob": "^4.0.1" @@ -721,9 +721,9 @@ } }, "globby": { - "version": "11.0.2", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.2.tgz", - "integrity": "sha512-2ZThXDvvV8fYFRVIxnrMQBipZQDr7MxKAmQK1vujaj9/7eF0efG7BPUKJ7jP7G5SLF37xKDXvO4S/KKLj/Z0og==", + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.3.tgz", + "integrity": "sha512-ffdmosjA807y7+lA1NM0jELARVmYul/715xiILEjo3hBLPTcirgQNnXECn5g3mtR8TOLCVbkfua1Hpen25/Xcg==", "dev": true, "requires": { "array-union": "^2.1.0", @@ -1112,14 +1112,6 @@ "linkify-it": "^3.0.1", "mdurl": "^1.0.1", "uc.micro": "^1.0.5" - }, - "dependencies": { - "entities": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.1.0.tgz", - "integrity": "sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w==", - "dev": true - } } }, "markdownlint": { @@ -1132,18 +1124,18 @@ } }, "markdownlint-cli2": { - "version": "0.0.14", - "resolved": "https://registry.npmjs.org/markdownlint-cli2/-/markdownlint-cli2-0.0.14.tgz", - "integrity": "sha512-h3aXjve9y7pVXJMpka6msP4aGIJamju0Gv7L9knRz3nAdhhaW1aOiRvnLGgqu7BZyp1y7agjWnx8ojh7iLCCeg==", + "version": "0.0.15", + "resolved": "https://registry.npmjs.org/markdownlint-cli2/-/markdownlint-cli2-0.0.15.tgz", + "integrity": "sha512-XXJ0qd8mhsSUPdIAi4jUK7PFpc0hG/jCXNj7589cX9Ywg9umynOMaUrbcLpSiRTzzVFrKIN5VLxunA6oG+I7YQ==", "dev": true, "requires": { - "globby": "~11.0.2", + "globby": "~11.0.3", "markdownlint": "~0.23.1", - "markdownlint-cli2-formatter-default": "~0.0.2", + "markdownlint-cli2-formatter-default": "^0.0.2", "markdownlint-rule-helpers": "~0.14.0", "micromatch": "~4.0.2", "strip-json-comments": "~3.1.1", - "yaml": "~1.10.0" + "yaml": "~1.10.2" }, "dependencies": { "strip-json-comments": { @@ -1439,9 +1431,9 @@ } }, "queue-microtask": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.2.tgz", - "integrity": "sha512-dB15eXv3p2jDlbOiNLyMabYg1/sXvppd8DP2J3EOCQ0AkuSXCW2tP7mnVouVLJKgUMY6yP0kcQDVpLCN13h4Xg==", + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", "dev": true }, "quick-lru": { @@ -1904,9 +1896,9 @@ "dev": true }, "yaml": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.0.tgz", - "integrity": "sha512-yr2icI4glYaNG+KWONODapy2/jDdMSDnrONSjblABjD9B4Z5LgiircSt8m8sRZFNi08kG9Sm0uSHtEmP3zaEGg==", + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", "dev": true }, "yargs-parser": { diff --git a/package.json b/package.json index 19c7c69..f141eba 100644 --- a/package.json +++ b/package.json @@ -23,6 +23,6 @@ }, "devDependencies": { "linkinator": "^2.13.6", - "markdownlint-cli2": "0.0.14" + "markdownlint-cli2": "0.0.15" } } From 29a85f6828659ccacc6e82ec43163438ad324202 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Sat, 3 Apr 2021 10:14:24 +0000 Subject: [PATCH 097/103] Bump mkdocs-material from 7.0.4 to 7.1.0 Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 7.0.4 to 7.1.0. - [Release notes](https://github.com/squidfunk/mkdocs-material/releases) - [Changelog](https://github.com/squidfunk/mkdocs-material/blob/master/docs/changelog.md) - [Commits](https://github.com/squidfunk/mkdocs-material/compare/7.0.4...7.1.0) Signed-off-by: dependabot-preview[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 4e0e556..528f808 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,5 @@ markdown-include==0.6.0 mkdocs==1.1.2 mkdocs-git-revision-date-localized-plugin==0.8 -mkdocs-material==7.0.4 +mkdocs-material==7.1.0 mkdocs-redirects==1.0.1 From f2aef3ebbb407f7039346c41acdca1a675b126aa Mon Sep 17 00:00:00 2001 From: DL6ER Date: Sat, 3 Apr 2021 12:44:57 +0200 Subject: [PATCH 098/103] Show back-to-top button when the user, after scrolling down, starts to scroll up again. It's rendered in the lower right corner of the viewport. Signed-off-by: DL6ER --- mkdocs.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/mkdocs.yml b/mkdocs.yml index f8e4264..51620f6 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -15,6 +15,8 @@ theme: font: text: 'Source Sans Pro' code: 'Roboto Mono' + features: + - navigation.top markdown_extensions: # Code highlighting in ``` ``` blocks From 87b974345d2b02945c85a6ee6d08eaa99adafadb Mon Sep 17 00:00:00 2001 From: DL6ER Date: Sat, 3 Apr 2021 13:01:20 +0200 Subject: [PATCH 099/103] Add dark mode switch Signed-off-by: DL6ER --- docs/extra.css | 15 +++++++++------ mkdocs.yml | 21 ++++++++++++++++++++- 2 files changed, 29 insertions(+), 7 deletions(-) diff --git a/docs/extra.css b/docs/extra.css index c2c63d7..03afc9c 100644 --- a/docs/extra.css +++ b/docs/extra.css @@ -1,8 +1,3 @@ -body, -input { - color: #000; -} - .md-nav { font-size: 14px; line-height: 1.4; @@ -16,9 +11,17 @@ input { .md-typeset code, .md-typeset pre { white-space: pre-wrap; - color: #532ba8; + color: var(--code-color); } .text-center { text-align: center !important; } + +[data-md-color-scheme="default"] { + --code-color: #532ba8; +} + +[data-md-color-scheme="slate"] { + --code-color: #a47df8; +} diff --git a/mkdocs.yml b/mkdocs.yml index 51620f6..5cd0fc2 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -2,7 +2,7 @@ site_name: 'Pi-hole documentation' site_url: 'https://docs.pi-hole.net/' repo_url: 'https://github.com/pi-hole/pi-hole' edit_uri: '../docs/blob/master/docs/' -copyright: 'Copyright © 2020 Pi-hole LLC' +copyright: 'Copyright © 2021 Pi-hole LLC' remote_branch: gh-pages theme: name: 'material' @@ -17,6 +17,25 @@ theme: code: 'Roboto Mono' features: - navigation.top + palette: + + # Light mode + - media: "(prefers-color-scheme: light)" + scheme: default + primary: indigo + accent: indigo + toggle: + icon: material/lightbulb-outline + name: Switch to dark mode + + # Dark mode + - media: "(prefers-color-scheme: dark)" + scheme: slate + primary: indigo + accent: indigo + toggle: + icon: material/lightbulb + name: Switch to light mode markdown_extensions: # Code highlighting in ``` ``` blocks From a68acdb00b00b9093d21e64af83895a723380eeb Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Sat, 3 Apr 2021 10:24:29 +0000 Subject: [PATCH 100/103] Bump markdownlint-cli2 from 0.0.15 to 0.1.1 Bumps [markdownlint-cli2](https://github.com/DavidAnson/markdownlint-cli2) from 0.0.15 to 0.1.1. - [Release notes](https://github.com/DavidAnson/markdownlint-cli2/releases) - [Commits](https://github.com/DavidAnson/markdownlint-cli2/compare/v0.0.15...v0.1.1) Signed-off-by: dependabot-preview[bot] --- package-lock.json | 6 +++--- package.json | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index b0fcba5..29162ff 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1124,9 +1124,9 @@ } }, "markdownlint-cli2": { - "version": "0.0.15", - "resolved": "https://registry.npmjs.org/markdownlint-cli2/-/markdownlint-cli2-0.0.15.tgz", - "integrity": "sha512-XXJ0qd8mhsSUPdIAi4jUK7PFpc0hG/jCXNj7589cX9Ywg9umynOMaUrbcLpSiRTzzVFrKIN5VLxunA6oG+I7YQ==", + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/markdownlint-cli2/-/markdownlint-cli2-0.1.1.tgz", + "integrity": "sha512-8ly6Z/Y/orOn7Mb14QgZV8/Q9KnBpyozN9ZZFeZeTU7v5KZg3BWjFPCUMnSguWPPEq8Q+4QJFf6LOi9oNeOyfw==", "dev": true, "requires": { "globby": "~11.0.3", diff --git a/package.json b/package.json index f141eba..6a58a88 100644 --- a/package.json +++ b/package.json @@ -23,6 +23,6 @@ }, "devDependencies": { "linkinator": "^2.13.6", - "markdownlint-cli2": "0.0.15" + "markdownlint-cli2": "0.1.1" } } From b6991f2a727731c502bcdabc61590bd27451a7ed Mon Sep 17 00:00:00 2001 From: DL6ER Date: Mon, 5 Apr 2021 19:53:32 +0200 Subject: [PATCH 101/103] Tweak dark theme colors Signed-off-by: DL6ER --- docs/extra.css | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/docs/extra.css b/docs/extra.css index 03afc9c..38ce8b3 100644 --- a/docs/extra.css +++ b/docs/extra.css @@ -18,10 +18,20 @@ text-align: center !important; } +.md-typeset table:not([class]) th { + color: var(--table-foreground); + background-color: var(--table-background); +} + [data-md-color-scheme="default"] { --code-color: #532ba8; + --table-foreground: var(--md-default-bg-color); /* table header backgrounds */ + --table-background: var(--md-default-fg-color--light); /* table header (text) */ } [data-md-color-scheme="slate"] { --code-color: #a47df8; + --md-typeset-a-color: #7c90ff; /* links */ + --table-foreground: #a3acdf; /* table header (text) */ + --table-background: #272e53; /* table header backgrounds */ } From 235a0d87a97a646e078340825fd9d0f4b8b56c01 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Sat, 10 Apr 2021 10:15:25 +0000 Subject: [PATCH 102/103] Bump markdownlint-cli2 from 0.1.1 to 0.1.2 Bumps [markdownlint-cli2](https://github.com/DavidAnson/markdownlint-cli2) from 0.1.1 to 0.1.2. - [Release notes](https://github.com/DavidAnson/markdownlint-cli2/releases) - [Commits](https://github.com/DavidAnson/markdownlint-cli2/compare/v0.1.1...v0.1.2) Signed-off-by: dependabot-preview[bot] --- package-lock.json | 14 +++++++------- package.json | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/package-lock.json b/package-lock.json index 29162ff..97d7730 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1124,9 +1124,9 @@ } }, "markdownlint-cli2": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/markdownlint-cli2/-/markdownlint-cli2-0.1.1.tgz", - "integrity": "sha512-8ly6Z/Y/orOn7Mb14QgZV8/Q9KnBpyozN9ZZFeZeTU7v5KZg3BWjFPCUMnSguWPPEq8Q+4QJFf6LOi9oNeOyfw==", + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/markdownlint-cli2/-/markdownlint-cli2-0.1.2.tgz", + "integrity": "sha512-34rEuA5ZWjjzqhznA7Qn1o+njUqwKJ03xJYYyz1DRgczFbTORWh8La/mByITLXF5rOwP/5ZHFYzDF9rUMcg9eg==", "dev": true, "requires": { "globby": "~11.0.3", @@ -1197,13 +1197,13 @@ "dev": true }, "micromatch": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", - "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.3.tgz", + "integrity": "sha512-ueuSaP4i67F/FAUac9zzZ0Dz/5KeKDkITYIS/k4fps+9qeh1SkeH6gbljcqz97mNBOsaWZ+iv2UobMKK/yD+aw==", "dev": true, "requires": { "braces": "^3.0.1", - "picomatch": "^2.0.5" + "picomatch": "^2.2.1" } }, "mime": { diff --git a/package.json b/package.json index 6a58a88..241a2bb 100644 --- a/package.json +++ b/package.json @@ -23,6 +23,6 @@ }, "devDependencies": { "linkinator": "^2.13.6", - "markdownlint-cli2": "0.1.1" + "markdownlint-cli2": "0.1.2" } } From 8bda7ea939ff978beb04dc1215c0b555ab8ee041 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Sat, 10 Apr 2021 17:05:24 +0000 Subject: [PATCH 103/103] Bump mkdocs-material from 7.1.0 to 7.1.1 Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 7.1.0 to 7.1.1. - [Release notes](https://github.com/squidfunk/mkdocs-material/releases) - [Changelog](https://github.com/squidfunk/mkdocs-material/blob/master/docs/changelog.md) - [Commits](https://github.com/squidfunk/mkdocs-material/compare/7.1.0...7.1.1) Signed-off-by: dependabot-preview[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 528f808..4431f8a 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,5 @@ markdown-include==0.6.0 mkdocs==1.1.2 mkdocs-git-revision-date-localized-plugin==0.8 -mkdocs-material==7.1.0 +mkdocs-material==7.1.1 mkdocs-redirects==1.0.1