diff --git a/.github/workflows/calibreapp-image-actions.yml b/.github/workflows/calibreapp-image-actions.yml index 15aabf1..18da39d 100644 --- a/.github/workflows/calibreapp-image-actions.yml +++ b/.github/workflows/calibreapp-image-actions.yml @@ -16,7 +16,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Clone repository - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 #v6.0.1 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2 with: persist-credentials: false diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3d89007..72b58f3 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -18,20 +18,20 @@ jobs: runs-on: ubuntu-latest steps: - name: Clone repository - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 #v6.0.1 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2 with: persist-credentials: false fetch-depth: 0 - name: Set up Python - uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 #v6.1.0 + uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 #v6.2.0 with: python-version: "${{ env.PYTHON_VERSION }}" architecture: "x64" cache: pip - name: Set up Node.js - uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f #v6.1.0 + uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f #v6.3.0 with: node-version: "${{ env.NODE }}" cache: npm diff --git a/.github/workflows/codespell.yml b/.github/workflows/codespell.yml index 0f4865a..870c372 100644 --- a/.github/workflows/codespell.yml +++ b/.github/workflows/codespell.yml @@ -9,7 +9,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Clone repository - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 #v6.0.1 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2 with: persist-credentials: false diff --git a/.github/workflows/editorconfig-checker.yml b/.github/workflows/editorconfig-checker.yml index e4769cd..9a1d68d 100644 --- a/.github/workflows/editorconfig-checker.yml +++ b/.github/workflows/editorconfig-checker.yml @@ -10,7 +10,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Clone repository - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 #v6.0.1 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2 with: persist-credentials: false - uses: editorconfig-checker/action-editorconfig-checker@4b6cd6190d435e7e084fb35e36a096e98506f7b9 #v2.1.0 diff --git a/.github/workflows/stale_pr.yml b/.github/workflows/stale_pr.yml index 7739b93..34fc398 100644 --- a/.github/workflows/stale_pr.yml +++ b/.github/workflows/stale_pr.yml @@ -16,7 +16,7 @@ jobs: pull-requests: write steps: - - uses: actions/stale@997185467fa4f803885201cee163a9f38240193d #v10.1.1 + - uses: actions/stale@b5d41d4e1d5dceea10e7104786b73624c18a190f #v10.2.0 with: repo-token: ${{ secrets.GITHUB_TOKEN }} # Do not automatically mark PR/issue as stale diff --git a/docs/api/auth.md b/docs/api/auth.md index db8125c..18f9b70 100644 --- a/docs/api/auth.md +++ b/docs/api/auth.md @@ -388,7 +388,7 @@ To end your session before the SID expires, you can send a `DELETE` request to t ???+ success "Success response" - Response code: `HTTP/1.1 410 - Gone` + Response code: `HTTP/1.1 204 - No Content` No content diff --git a/docs/api/tls.md b/docs/api/tls.md index 3ceeab3..2f2c459 100644 --- a/docs/api/tls.md +++ b/docs/api/tls.md @@ -107,4 +107,4 @@ If the last step did not work, see the remark below the Firefox instructions abo ## Using your own certificate -If you want to use your own certificate, you can do so by placing the certificate and the private key in a location that can be read by user `pihole` (e.g., `/etc/pihole`) and, change the path in `/etc/pihole/pihole.toml` (setting `webserver.api.tls.cert`) and restart `pihole-FTL` (e.g., `sudo service pihole-FTL restart`). The certificate and the private key must be in PEM format (check automatically generated certificate for an example). +If you want to use your own certificate, you can do so by placing the certificate and the private key in a location that can be read by user `pihole` (e.g., `/etc/pihole`) and, change the path in `/etc/pihole/pihole.toml` (setting `webserver.tls.cert`) and restart `pihole-FTL` (e.g., `sudo service pihole-FTL restart`). The certificate and the private key must be in PEM format (check automatically generated certificate for an example). diff --git a/docs/ftldns/compile.md b/docs/ftldns/compile.md index 1c0468f..93943d8 100644 --- a/docs/ftldns/compile.md +++ b/docs/ftldns/compile.md @@ -1,4 +1,4 @@ -We pre-compile *FTL*DNS for you to save you the trouble of compiling anything yourself. However, sometimes you may want to make your own modifications. To test them, you have to compile *FTL*DNS from source. Luckily, you don't have to be a programmer to build *FTL*DNS from source and install it on your system; you only have to know the basics we provide in here. With just a few commands, you can build *FTL*DNS from source like a pro. +We pre-compile FTL for you to save you the trouble of compiling anything yourself. However, sometimes you may want to make your own modifications. To test them, you have to compile FTL from source. Luckily, you don't have to be a programmer to build FTL from source and install it on your system; you only have to know the basics we provide in here. With just a few commands, you can build FTL from source like a pro. # Install native build environment @@ -23,7 +23,7 @@ sudo dnf install git wget ca-certificates gcc gmp-devel gmp-static m4 cmake libi ## Compile `libnettle` from source -*FTL*DNS uses a cryptographic library (`libnettle`) for handling DNSSEC signatures. +FTL uses a cryptographic library (`libnettle`) for handling DNSSEC signatures. Compile and install a recent version using: ```bash @@ -39,25 +39,26 @@ Since Ubuntu 20.04, you need to specify the library directory explicitly. Otherw ## Compile `libmbedtls` from source -*FTL*DNS uses another cryptographic library (`libmbedtls`) containing cryptographic primitives, X.509 certificate manipulation and the SSL/TLS and DTLS protocols used for serving the web interface and the API over HTTPS. +FTL uses another cryptographic library (`libmbedtls`) containing cryptographic primitives, X.509 certificate manipulation and the SSL/TLS and DTLS protocols used for serving the web interface and the API over HTTPS. Compile and install a recent version using: ```bash -wget https://github.com/Mbed-TLS/mbedtls/archive/refs/tags/v3.6.4.tar.gz -O mbedtls-3.6.4.tar.gz -tar -xzf mbedtls-3.6.4.tar.gz -cd mbedtls-3.6.4 +wget https://github.com/Mbed-TLS/mbedtls/releases/download/mbedtls-4.0.0/mbedtls-4.0.0.tar.bz2 -O mbedtls-4.0.0.tar.bz2 +tar -xjf mbedtls-4.0.0.tar.bz2 +cd mbedtls-4.0.0 sed -i '/#define MBEDTLS_THREADING_C/s*^//**g' include/mbedtls/mbedtls_config.h sed -i '/#define MBEDTLS_THREADING_PTHREAD/s*^//**g' include/mbedtls/mbedtls_config.h -make -j $(nproc) -sudo make install +cmake -S . -B build -DCMAKE_C_FLAGS="-fomit-frame-pointer" +cmake --build build -j $(nproc) +sudo cmake --install build ``` The `sed` commands are necessary to enable multi-threading support in `libmbedtls` as there is no `configure` script to do this for us (see also [here](https://github.com/Mbed-TLS/mbedtls#configuration)). ## Get the source -Now, clone the *FTL*DNS repo (or your own fork) to get the source code of *FTL*DNS: +Now, clone the FTL repo (or your own fork) to get the source code of FTL: ```bash git clone https://github.com/pi-hole/FTL.git && cd FTL @@ -71,7 +72,7 @@ git checkout development ## Compile the source -*FTL*DNS can now be compiled using either the build script +FTL can now be compiled using either the build script ```bash ./build.sh @@ -101,7 +102,7 @@ or cd cmake && sudo make install ``` -Finally, restart *FTL*DNS to use the new binary: +Finally, restart FTL to use the new binary: ```bash sudo service pihole-FTL restart diff --git a/docs/ftldns/configfile.md b/docs/ftldns/configfile.md index a16a0ea..63d10dc 100644 --- a/docs/ftldns/configfile.md +++ b/docs/ftldns/configfile.md @@ -53,16 +53,19 @@ Array of IP addresses and/or hostnames, optionally with a port (#...) === "TOML" ```toml [dns] - upstreams = [] + upstreams = [ "8.8.8.8", "127.0.0.1#5335", "docker-resolver" ] ``` === "CLI" ```shell - sudo pihole-FTL --config dns.upstreams [] + sudo pihole-FTL --config dns.upstreams '[ "8.8.8.8", "127.0.0.1#5335", "docker-resolver" ]' ``` === "Environment (Docker Compose)" ```yaml environment: - FTLCONF_dns_upstreams: [] + FTLCONF_dns_upstreams: |- + 8.8.8.8 + 127.0.0.1#5335 + docker-resolver ``` ### `CNAMEdeepInspect` @@ -353,16 +356,18 @@ Array of custom DNS records each one in HOSTS form: `"IP HOSTNAME [HOSTNAME ...] === "TOML" ```toml [dns] - hosts = [] + hosts = [ "127.0.0.1 mylocal", "192.168.0.1 therouter" ] ``` === "CLI" ```shell - sudo pihole-FTL --config dns.hosts [] + sudo pihole-FTL --config dns.hosts '[ "127.0.0.1 mylocal", "192.168.0.1 therouter" ]' ``` === "Environment (Docker Compose)" ```yaml environment: - FTLCONF_dns_hosts: [] + FTLCONF_dns_hosts: |- + 127.0.0.1 mylocal + 192.168.0.1 therouter ``` ### `domainNeeded` @@ -506,16 +511,16 @@ A string in the format === "TOML" ```toml [dns] - hostRecord = "" + hostRecord = "laptop,laptop.lan,192.168.0.1,1234::100" ``` === "CLI" ```shell - sudo pihole-FTL --config dns.hostRecord "" + sudo pihole-FTL --config dns.hostRecord "laptop,laptop.lan,192.168.0.1,1234::100" ``` === "Environment (Docker Compose)" ```yaml environment: - FTLCONF_dns_hostRecord: '' + FTLCONF_dns_hostRecord: 'laptop,laptop.lan,192.168.0.1,1234::100' ``` ### `listeningMode` @@ -617,7 +622,7 @@ Array of CNAMEs, each one in the following form: `",[,]"` ``` === "CLI" ```shell - sudo pihole-FTL --config dns.cnameRecords [] + sudo pihole-FTL --config dns.cnameRecords '[]' ``` === "Environment (Docker Compose)" ```yaml @@ -715,16 +720,17 @@ want here. === "TOML" ```toml [dns] - revServers = [] + revServers = [ "true,192.168.0.0/24,192.168.0.1,fritz.box" ] ``` === "CLI" ```shell - sudo pihole-FTL --config dns.revServers [] + sudo pihole-FTL --config dns.revServers '[ "true,192.168.0.0/24,192.168.0.1,fritz.box" ]' ``` === "Environment (Docker Compose)" ```yaml environment: - FTLCONF_dns_revServers: [] + FTLCONF_dns_revServers: |- + true,192.168.0.0/24,192.168.0.1,fritz.box ``` @@ -902,6 +908,32 @@ blocked queries FTLCONF_dns_cache_upstreamBlockedTTL: 86400 ``` +### `rrtype` + +This is dnsmasq's --cache-rr option, which allows you to define which DNS record +types should be cached by PiHole. This option can take a comma-separated list of +RR-types as input. The default value ANY caches all record types. + +**Allowed values are:** +Valid DNS record types in the following form: ```[,...]` + +**Default value:** `"ANY"` + +=== "TOML" + ```toml + [dns.cache] + rrtype = "ANY" + ``` +=== "CLI" + ```shell + sudo pihole-FTL --config dns.cache.rrtype "ANY" + ``` +=== "Environment (Docker Compose)" + ```yaml + environment: + FTLCONF_dns_cache_rrtype: 'ANY' + ``` + ## `[dns.blocking]` @@ -1436,16 +1468,16 @@ A valid IPv4 address, or empty string (`""`) === "TOML" ```toml [dhcp] - start = "" + start = "192.168.0.10" ``` === "CLI" ```shell - sudo pihole-FTL --config dhcp.start "" + sudo pihole-FTL --config dhcp.start "192.168.0.10" ``` === "Environment (Docker Compose)" ```yaml environment: - FTLCONF_dhcp_start: '' + FTLCONF_dhcp_start: '192.168.0.10' ``` ### `end` @@ -1462,16 +1494,16 @@ A valid IPv4 address, or empty string (`""`) === "TOML" ```toml [dhcp] - end = "" + end = "192.168.0.250" ``` === "CLI" ```shell - sudo pihole-FTL --config dhcp.end "" + sudo pihole-FTL --config dhcp.end "192.168.0.250" ``` === "Environment (Docker Compose)" ```yaml environment: - FTLCONF_dhcp_end: '' + FTLCONF_dhcp_end: '192.168.0.250' ``` ### `router` @@ -1489,16 +1521,16 @@ A valid IPv4 address, or empty string (`""`) === "TOML" ```toml [dhcp] - router = "" + router = "192.168.0.1" ``` === "CLI" ```shell - sudo pihole-FTL --config dhcp.router "" + sudo pihole-FTL --config dhcp.router "192.168.0.1" ``` === "Environment (Docker Compose)" ```yaml environment: - FTLCONF_dhcp_router: '' + FTLCONF_dhcp_router: '192.168.0.1' ``` ### `netmask` @@ -1522,16 +1554,16 @@ Any valid netmask, or an empty string (`""`) for auto-discovery === "TOML" ```toml [dhcp] - netmask = "" + netmask = "255.255.255.0" ``` === "CLI" ```shell - sudo pihole-FTL --config dhcp.netmask "" + sudo pihole-FTL --config dhcp.netmask "255.255.255.0" ``` === "Environment (Docker Compose)" ```yaml environment: - FTLCONF_dhcp_netmask: '' + FTLCONF_dhcp_netmask: '255.255.255.0' ``` ### `leaseTime` @@ -1718,16 +1750,19 @@ Array of static leases each one in the following form: === "TOML" ```toml [dhcp] - hosts = [] + hosts = [ "00:20:e0:3b:13:af,192.168.0.123,laptop,24h", + "00:20:e0:ab:cd:ef,192.168.0.124,desktop,24h"] ``` === "CLI" ```shell - sudo pihole-FTL --config dhcp.hosts [] + sudo pihole-FTL --config dhcp.hosts '["00:20:e0:3b:13:af,192.168.0.123,laptop,24h","00:20:e0:ab:cd:ef,192.168.0.124,desktop,24h"]' ``` === "Environment (Docker Compose)" ```yaml environment: - FTLCONF_dhcp_hosts: [] + FTLCONF_dhcp_hosts: |- + 00:20:e0:3b:13:af,192.168.0.123,laptop,24h + 00:20:e0:ab:cd:ef,192.168.0.124,desktop,24h ``` @@ -1974,16 +2009,16 @@ A valid RTC device path, or empty string (`""`) for auto-discovery === "TOML" ```toml [ntp.sync.rtc] - device = "" + device = "/dev/rtc0" ``` === "CLI" ```shell - sudo pihole-FTL --config ntp.sync.rtc.device "" + sudo pihole-FTL --config ntp.sync.rtc.device "/dev/rtc0" ``` === "Environment (Docker Compose)" ```yaml environment: - FTLCONF_ntp_sync_rtc_device: '' + FTLCONF_ntp_sync_rtc_device: '/dev/rtc0' ``` ### `utc` @@ -2243,6 +2278,37 @@ true or false FTLCONF_database_useWAL: true ``` +### `forceDisk` + +Should FTL force the use of disk storage for the history database? By default, FTL +uses an in-memory database for much improved performance when browsing the history +from the dashboard. However, on systems with very limited RAM and only occasional +usage of the web interface, it may be useful to force the use of disk storage +instead of holding everything in memory. + +Note that using disk storage *will* reduce performance, especially on systems with +slow storage media (e.g., SD cards). + +**Allowed values are:** +true or false + +**Default value:** `false` + +=== "TOML" + ```toml + [database] + forceDisk = false + ``` +=== "CLI" + ```shell + sudo pihole-FTL --config database.forceDisk false + ``` +=== "Environment (Docker Compose)" + ```yaml + environment: + FTLCONF_database_forceDisk: false + ``` + ## `[database.network]` @@ -2498,7 +2564,7 @@ An array of HTTP headers ```toml [ "X-DNS-Prefetch-Control: off", - "Content-Security-Policy: default-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:;", + "Content-Security-Policy: default-src 'none'; connect-src 'self'; font-src 'self'; frame-ancestors 'none'; img-src 'self'; manifest-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'", "X-Frame-Options: DENY", "X-XSS-Protection: 0", "X-Content-Type-Options: nosniff", @@ -2511,7 +2577,7 @@ An array of HTTP headers [webserver] headers = [ "X-DNS-Prefetch-Control: off", - "Content-Security-Policy: default-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:;", + "Content-Security-Policy: default-src 'none'; connect-src 'self'; font-src 'self'; frame-ancestors 'none'; img-src 'self'; manifest-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'", "X-Frame-Options: DENY", "X-XSS-Protection: 0", "X-Content-Type-Options: nosniff", @@ -2520,20 +2586,18 @@ An array of HTTP headers ``` === "CLI" ```shell - sudo pihole-FTL --config webserver.headers '["X-DNS-Prefetch-Control:off","Content-Security-Policy:default-src'self';style-src'self''unsafe-inline';img-src'self'data:;","X-Frame-Options:DENY","X-XSS-Protection:0","X-Content-Type-Options:nosniff","Referrer-Policy:strict-origin-when-cross-origin"]' + sudo pihole-FTL --config webserver.headers '["X-DNS-Prefetch-Control:off","Content-Security-Policy:default-src'none';connect-src'self';font-src'self';frame-ancestors'none';img-src'self';manifest-src'self';script-src'self';style-src'self''unsafe-inline'","X-Frame-Options:DENY","X-XSS-Protection:0","X-Content-Type-Options:nosniff","Referrer-Policy:strict-origin-when-cross-origin"]' ``` === "Environment (Docker Compose)" ```yaml environment: - FTLCONF_webserver_headers: | - [ - 'X-DNS-Prefetch-Control: off', - 'Content-Security-Policy: default-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:;', - 'X-Frame-Options: DENY', - 'X-XSS-Protection: 0', - 'X-Content-Type-Options: nosniff', - 'Referrer-Policy: strict-origin-when-cross-origin' - ] + FTLCONF_webserver_headers: |- + X-DNS-Prefetch-Control: off + Content-Security-Policy: default-src 'none'; connect-src 'self'; font-src 'self'; frame-ancestors 'none'; img-src 'self'; manifest-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline + X-Frame-Options: DENY + X-XSS-Protection: 0 + X-Content-Type-Options: nosniff + Referrer-Policy: strict-origin-when-cross-origin ``` ### `serve_all` @@ -2587,16 +2651,18 @@ An array of valid CivetWeb options === "TOML" ```toml [webserver] - advancedOpts = [] + advancedOpts = [ "ssl_protocol_version=4", "ssl_cipher_list=AES128:!MD5" ] ``` === "CLI" ```shell - sudo pihole-FTL --config webserver.advancedOpts [] + sudo pihole-FTL --config webserver.advancedOpts '[ "ssl_protocol_version=4", "ssl_cipher_list=AES128:!MD5" ]' ``` === "Environment (Docker Compose)" ```yaml environment: - FTLCONF_webserver_advancedOpts: [] + FTLCONF_webserver_advancedOpts: |- + ssl_protocol_version=4 + ssl_cipher_list=AES128:!MD5 ``` @@ -3109,16 +3175,19 @@ An array of regular expressions describing clients === "TOML" ```toml [webserver.api] - excludeClients = [] + excludeClients = [ "^192\\.168\\.2\\.56$", "^fe80::341:[0-9a-f]*$", "^localhost$" ] ``` === "CLI" ```shell - sudo pihole-FTL --config webserver.api.excludeClients [] + sudo pihole-FTL --config webserver.api.excludeClients '[ "^192\\.168\\.2\\.56$", "^fe80::341:[0-9a-f]*$", "^localhost$" ]' ``` === "Environment (Docker Compose)" ```yaml environment: - FTLCONF_webserver_api_excludeClients: [] + FTLCONF_webserver_api_excludeClients: |- + ^192\\.168\\.2\\.56$ + ^fe80::341:[0-9a-f]*$ + ^localhost$ ``` ### `excludeDomains` @@ -3139,16 +3208,18 @@ An array of regular expressions describing domains === "TOML" ```toml [webserver.api] - excludeDomains = [] + excludeDomains = [ "(^|\\.)\\.google\\.de$", "\\.pi-hole\\.net$" ] ``` === "CLI" ```shell - sudo pihole-FTL --config webserver.api.excludeDomains [] + sudo pihole-FTL --config webserver.api.excludeDomains '[ "(^|\\.)\\.google\\.de$", "\\.pi-hole\\.net$" ]' ``` === "Environment (Docker Compose)" ```yaml environment: - FTLCONF_webserver_api_excludeDomains: [] + FTLCONF_webserver_api_excludeDomains: |- + (^|\\.)\\.google\\.de$ + \\.pi-hole\\.net$ ``` ### `maxHistory` @@ -3367,6 +3438,31 @@ Any FTL database FTLCONF_files_database: '/etc/pihole/pihole-FTL.db' ``` +### `tmp_db` + +The location of FTL's short-term temporary database (only used when +database.forceDisk is true) + +**Allowed values are:** +Any FTL database + +**Default value:** `"/etc/pihole/pihole-tmp.db"` + +=== "TOML" + ```toml + [files] + tmp_db = "/etc/pihole/pihole-tmp.db" + ``` +=== "CLI" + ```shell + sudo pihole-FTL --config files.tmp_db "/etc/pihole/pihole-tmp.db" + ``` +=== "Environment (Docker Compose)" + ```yaml + environment: + FTLCONF_files_tmp_db: '/etc/pihole/pihole-tmp.db' + ``` + ### `gravity` The location of Pi-hole's gravity database @@ -3715,6 +3811,9 @@ from working. Use this option with extra care. +**Example:** `[ "address=/example.com/192.168.0.1", "address=/example.org/192.168.0.2", +"address=/example.net/192.168.0.3" ]` + **Allowed values are:** Array of valid dnsmasq config line options @@ -3723,16 +3822,20 @@ Array of valid dnsmasq config line options === "TOML" ```toml [misc] - dnsmasq_lines = [] + dnsmasq_lines = [ "address=/example.com/192.168.0.1", "address=/example.org/192.168.0.2", + "address=/example.net/192.168.0.3" ] ``` === "CLI" ```shell - sudo pihole-FTL --config misc.dnsmasq_lines [] + sudo pihole-FTL --config misc.dnsmasq_lines '["address=/example.com/192.168.0.1","address=/example.org/192.168.0.2","address=/example.net/192.168.0.3"]' ``` === "Environment (Docker Compose)" ```yaml environment: - FTLCONF_misc_dnsmasq_lines: [] + FTLCONF_misc_dnsmasq_lines: |- + address=/example.com/192.168.0.1 + address=/example.org/192.168.0.2 + address=/example.net/192.168.0.3 ``` ### `extraLogging` @@ -3853,6 +3956,37 @@ true or false FTLCONF_misc_hide_dnsmasq_warn: false ``` +### `hide_connection_error` + +Should FTL hide network connection errors? + +By default, FTL reports network connection errors (e.g., Connection prematurely +closed by remote server) to the FTL log file. These warnings can be useful to +identify intermittent network problems or general problem with upstream servers. +However, in some setups, these warnings may be expected (e.g. due to low-quality +Internet connectivity) and cannot be fixed. Enabling this setting will hide all +connection warnings. + +**Allowed values are:** +true or false + +**Default value:** `false` + +=== "TOML" + ```toml + [misc] + hide_connection_error = false + ``` +=== "CLI" + ```shell + sudo pihole-FTL --config misc.hide_connection_error false + ``` +=== "Environment (Docker Compose)" + ```yaml + environment: + FTLCONF_misc_hide_connection_error: false + ``` + ## `[misc.check]` @@ -4066,7 +4200,7 @@ true or false ``` === "CLI" ```shell - sudo pihole-FTL --config debug.flags alse + sudo pihole-FTL --config debug.flags false ``` === "Environment (Docker Compose)" ```yaml diff --git a/docs/ftldns/index.md b/docs/ftldns/index.md index 8fb9b0e..647b9a6 100644 --- a/docs/ftldns/index.md +++ b/docs/ftldns/index.md @@ -4,5 +4,8 @@ powered by Pi-hole®

-*FTL*DNS[™](https://pi-hole.net/trademark-rules-and-brand-guidelines/) (`pihole-FTL`) offers DNS services within the Pi-hole[®](https://pi-hole.net/trademark-rules-and-brand-guidelines/) project. -It provides blazing fast DNS and DHCP services. It can also provide TFTP and more as the resolver part based on the popular `dnsmasq`. Furthermore, FTL offers an interactive API where extensive network analysis data and statistics may be queried. +*FTL*DNS™, or simply FTL (`pihole-FTL`), offers DNS blazing fast services within the Pi-hole® project. + +It provides DHCP and [Web server](https://docs.pi-hole.net/ftldns/webserver/) services. It can also provide TFTP and more as the resolver part based on the popular `dnsmasq`. Use `pihole-FTL -h` to learn more about all FTL commands. + +Furthermore, FTL offers an [interactive API](https://docs.pi-hole.net/api/) where extensive network analysis data and statistics may be queried. diff --git a/docs/ftldns/signals.md b/docs/ftldns/signals.md index 2761747..bb345e4 100644 --- a/docs/ftldns/signals.md +++ b/docs/ftldns/signals.md @@ -21,7 +21,7 @@ When FTL receives a `SIGHUP`, it clears the entire DNS cache, and then - The FTL database connection (`/etc/pihole/pihole-FTL.db`) is re-opened. - The privacy level is re-read from `pihole.toml` (`misc.privacylevel`). -- The blocking status is re-read from `setupVars.conf` (`BLOCKING_ENABLED`). +- The blocking status is re-read from `pihole.toml` (`dns.blocking.active`). - The debug settings are re-read from `pihole.toml` (`debug.*`). - The gravity database connection (`/etc/pihole/gravity.db`) is re-opened. - The number of blocked domains is updated. diff --git a/docs/guides/dns/cloudflared.md b/docs/guides/dns/cloudflared.md index 0943dfa..acadd79 100644 --- a/docs/guides/dns/cloudflared.md +++ b/docs/guides/dns/cloudflared.md @@ -240,6 +240,8 @@ sudo deluser cloudflared sudo rm /etc/default/cloudflared sudo rm /etc/systemd/system/cloudflared.service sudo rm /usr/local/bin/cloudflared +sudo rm /etc/cron.weekly/cloudflared-updater +sudo apt purge cloudflared -y ``` #### If installed with `cloudflare service install` diff --git a/docs/guides/dns/dnscrypt-proxy.md b/docs/guides/dns/dnscrypt-proxy.md index 5bef82e..2a2f2ff 100644 --- a/docs/guides/dns/dnscrypt-proxy.md +++ b/docs/guides/dns/dnscrypt-proxy.md @@ -17,13 +17,31 @@ However for those using distributions which don't provide an official package, [ By default, `FTLDNS` listens on the standard DNS port 53. -To avoid conflicts with `FTLDNS`, edit `/usr/lib/systemd/system/dnscrypt-proxy.socket`, ensuring `dnscrypt-proxy` listens on a port that is not in use by other services. +To avoid conflicts with `FTLDNS`, add a systemd override file with `sudo systemctl edit dnscrypt-proxy.socket`, ensuring `dnscrypt-proxy` listens on a port that is not in use by other services. -The following settings in `/usr/lib/systemd/system/dnscrypt-proxy.socket`, let `dnscrypt-proxy` listen on localhost on port 5053: +You will be greeted with an empty override file: ```text +### Editing /etc/systemd/system/dnscrypt-proxy.socket.d/override.conf +### Anything between here and the comment below will become the contents of the drop-in file + + +### Edits below this comment will be discarded +``` + +In the new systemd override file, unset the old values first and let `dnscrypt-proxy` listen on localhost on port 5053: + +```text +### Editing /etc/systemd/system/dnscrypt-proxy.socket.d/override.conf +### Anything between here and the comment below will become the contents of the drop-in file + +[Socket] +ListenStream= +ListenDatagram= ListenStream=127.0.0.1:5053 ListenDatagram=127.0.0.1:5053 + +### Edits below this comment will be discarded ``` If you have `cloudflared` installed, you may uninstall it, as `dnscrypt-proxy` will replace it, or choose a unique port for `dnscrypt-proxy`. diff --git a/docs/guides/dns/unbound.md b/docs/guides/dns/unbound.md index d1c435c..2583f85 100644 --- a/docs/guides/dns/unbound.md +++ b/docs/guides/dns/unbound.md @@ -50,6 +50,48 @@ You can easily imagine even longer chains for subdomains as the query process co - Drawback: Traversing the path may be slow, especially for the first time you visit a website - while the bigger DNS providers always have answers for commonly used domains in their cache, you will have to traverse the path if you visit a page for the first time. The first request to a formerly unknown TLD may take up to a second (or even more if you're also using DNSSEC). Subsequent requests to domains under the same TLD usually complete in `< 0.1s`. Fortunately, both your Pi-hole as well as your recursive server will be configured for efficient caching to minimize the number of queries that will actually have to be performed. +### Recommended: Test access to root servers + +Some ISPs intercept and redirect outbound DNS traffic on port 53 to their own resolvers, without any indication that this is happening. Security or parental filtering software, including the firmware on many consumer-grade and home routers may do the same. Either of these will prevent `unbound` from reaching the root servers directly, and likely cause it to fail in ways that can be difficult to diagnose. + +Before proceeding, it is worth confirming that your device can definitively reach a root server. The following tests use `a.root-servers.net` at `198.41.0.4`, and should be run on the system upon which you intend to install unbound. + +1. **Test UDP reachability and check for interception.** Query `a.root-servers.net` directly for the root name servers, without requesting recursion: + + ```bash + dig @198.41.0.4 . NS +norec +time=3 + ``` + + Check the `flags:` line in the response. If you are talking directly to a root server, the response will include `aa` (*Authoritative Answer*) which confirms the server is authoritative for the root zone and simultaneously the `ra` (*Recursion Available*) flag will be **absent**, as root servers do not offer recursion. + + e.g. `;; flags: qr aa; QUERY: 1, ANSWER: 13, AUTHORITY: 0, ADDITIONAL: 27` + + If your DNS traffic is being intercepted, the `ra` flag will be **present** and `aa` will most likely be absent, as an ISP resolver or proxy is answering instead of the root server. + + e.g. `;; flags: qr ra; QUERY: 1, ANSWER: 13, AUTHORITY: 0, ADDITIONAL: 0` + +2. **Test TCP reachability.** `unbound` relies on TCP/53 for large DNSSEC responses and for retries: + + ```bash + dig @198.41.0.4 . NS +norec +tcp +time=3 + ``` + + Some CG-NAT implementations pass UDP DNS traffic unscathed while silently dropping TCP DNS traffic. If step 1 succeeded but this command times out then this will likely cause cryptic `unbound` failures on your network when larger DNS requests are required. If you are reaching the root server, the `flags:` line will be structurally identical to the previous step. + +3. **Confirm server identity via the `CHAOS` class.** Root servers respond to `CHAOS` (`CH`) class queries with unique identifiers. Most ISP interception proxies do not handle `CHAOS` queries: + + ```bash + dig @198.41.0.4 version.bind CH TXT +time=3 + ``` + + If you are connecting to the root server directly, the response will be a `TXT` record containing `ATLAS`. + + e.g. `version.bind. 0 CH TXT "ATLAS"` + + If your traffic is being intercepted then this command will return a string othert that `ATLAS` or could time out or return `SERVFAIL`. This can happen even if the previous tests appeared to succeed, as proxies generally handle standard query classes correctly. If the first two tests succeed but this one fails then be aware that your DNS traffic is being proxied, including an understanding that DNS reliability and privacy of **any** unencrypted DNS queries may be effected. + +If any of these tests fail, it is not recommended to proceed with installation of unbound as a local recursive resolver before investigating the source of failure (e.g. ISP redirection or proxying of DNS queries, CG-NAT blocking of TCP DNS traffic or security/parental filtering on router) and its successful remediation. + ## Setting up Pi-hole as a recursive DNS server solution We will use [`unbound`](https://github.com/NLnetLabs/unbound), a secure open-source recursive DNS server primarily developed by NLnet Labs, VeriSign Inc., Nominet, and Kirei. diff --git a/docs/main/coverage.md b/docs/main/coverage.md index bbaa914..efa0ee9 100644 --- a/docs/main/coverage.md +++ b/docs/main/coverage.md @@ -32,3 +32,4 @@ last_updated: Sun Jan 13 19:20:35 2019 UTC - [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_ - [How a Single Raspberry PI made my Home Network Faster](https://brianchristner.io/how-a-single-raspberry-pi-made-my-home-network-faster/) _March 1, 2019_ - [Coding Horror: An Exercise Program for the Fat Web](https://blog.codinghorror.com/an-exercise-program-for-the-fat-web/) _May 30, 2019_ +- [How to Self-Host Pi-hole with Docker Compose](https://selfhosting.sh/apps/pi-hole/) - Docker Compose setup guide covering installation, custom DNS, DHCP configuration, and ad list management. diff --git a/mkdocs.yml b/mkdocs.yml index a289100..e5c157f 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -245,6 +245,7 @@ plugins: - search - git-revision-date-localized: fallback_to_build_date: true + enable_parallel_processing: false - redirects: redirect_maps: 'ftldns/database.md': database/index.md diff --git a/package-lock.json b/package-lock.json index 907307b..9d4dfc5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,31 +9,8 @@ "version": "1.0.0", "license": "CC-BY-SA-4.0", "devDependencies": { - "linkinator": "^7.5.1", - "markdownlint-cli2": "0.19.1" - } - }, - "node_modules/@isaacs/balanced-match": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@isaacs/balanced-match/-/balanced-match-4.0.1.tgz", - "integrity": "sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": "20 || >=22" - } - }, - "node_modules/@isaacs/brace-expansion": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@isaacs/brace-expansion/-/brace-expansion-5.0.0.tgz", - "integrity": "sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@isaacs/balanced-match": "^4.0.1" - }, - "engines": { - "node": "20 || >=22" + "linkinator": "^7.6.1", + "markdownlint-cli2": "0.21.0" } }, "node_modules/@nodelib/fs.scandir": { @@ -118,6 +95,19 @@ "dev": true, "license": "MIT" }, + "node_modules/ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, "node_modules/argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", @@ -125,6 +115,29 @@ "dev": true, "license": "Python-2.0" }, + "node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/brace-expansion": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.4.tgz", + "integrity": "sha512-h+DEnpVvxmfVefa4jFbCf5HdH5YMDXRsmKflpf1pILZWRFlTbJpxeU55nJl4Smt5HQaGzg1o6RHFPJaOqnmBDg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + } + }, "node_modules/braces": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", @@ -347,9 +360,9 @@ } }, "node_modules/fastq": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz", - "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==", + "version": "1.20.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.20.1.tgz", + "integrity": "sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==", "dev": true, "license": "ISC", "dependencies": { @@ -369,6 +382,19 @@ "node": ">=8" } }, + "node_modules/get-east-asian-width": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.4.0.tgz", + "integrity": "sha512-QZjmEOC+IT1uk6Rx0sX22V6uHWVwbdbxf1faPqJ1QhLdGgsRGCZoyaQBm/piRdJy/D2um6hM1UP7ZEeQ4EkP+Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/github-slugger": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/github-slugger/-/github-slugger-2.0.0.tgz", @@ -408,18 +434,18 @@ } }, "node_modules/globby": { - "version": "15.0.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-15.0.0.tgz", - "integrity": "sha512-oB4vkQGqlMl682wL1IlWd02tXCbquGWM4voPEI85QmNKCaw8zGTm1f1rubFgkg3Eli2PtKlFgrnmUqasbQWlkw==", + "version": "16.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-16.1.0.tgz", + "integrity": "sha512-+A4Hq7m7Ze592k9gZRy4gJ27DrXRNnC1vPjxTt1qQxEY8RxagBkBxivkCwg7FxSTG0iLLEMaUx13oOr0R2/qcQ==", "dev": true, "license": "MIT", "dependencies": { "@sindresorhus/merge-streams": "^4.0.0", "fast-glob": "^3.3.3", "ignore": "^7.0.5", - "path-type": "^6.0.0", + "is-path-inside": "^4.0.0", "slash": "^5.1.0", - "unicorn-magic": "^0.3.0" + "unicorn-magic": "^0.4.0" }, "engines": { "node": ">=20" @@ -552,6 +578,19 @@ "node": ">=0.12.0" } }, + "node_modules/is-path-inside": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-4.0.0.tgz", + "integrity": "sha512-lJJV/5dYS+RcL8uQdBDW9c9uWFLLBNRyFhnAKXw5tVqLlKZ4RMGZKv+YQ/IA3OhD+RpbJa1LLFM1FQPGyIXvOA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/js-yaml": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", @@ -573,9 +612,9 @@ "license": "MIT" }, "node_modules/katex": { - "version": "0.16.25", - "resolved": "https://registry.npmjs.org/katex/-/katex-0.16.25.tgz", - "integrity": "sha512-woHRUZ/iF23GBP1dkDQMh1QBad9dmr8/PAwNA54VrSOVYgI12MAcE14TqnDdQOdzyEonGzMepYnqBMYdsoAr8Q==", + "version": "0.16.27", + "resolved": "https://registry.npmjs.org/katex/-/katex-0.16.27.tgz", + "integrity": "sha512-aeQoDkuRWSqQN6nSvVCEFvfXdqo1OQiCmmW1kc9xSdjutPv7BGO7pqY9sQRJpMOGrEdfDgF2TfRXe5eUAD2Waw==", "dev": true, "funding": [ "https://opencollective.com/katex", @@ -600,9 +639,9 @@ } }, "node_modules/linkinator": { - "version": "7.5.1", - "resolved": "https://registry.npmjs.org/linkinator/-/linkinator-7.5.1.tgz", - "integrity": "sha512-Q/r6wFgazHFRs49od0U3NFGviYkSjidHIfYNIHufH63/h8ehDZ6xCKbXLYVfqjbrs20PWrPvT6i+9A9F48S0/g==", + "version": "7.6.1", + "resolved": "https://registry.npmjs.org/linkinator/-/linkinator-7.6.1.tgz", + "integrity": "sha512-+VzKKZXA8wyCW1x0B0YeQvyuenDu3vZGIWMdzK1yEK0HlBfmEKopt87+Judt4VdPOGRMioKzJK0+X8ifIvOc5Q==", "dev": true, "license": "MIT", "dependencies": { @@ -614,7 +653,6 @@ "marked-gfm-heading-id": "^4.1.3", "meow": "^14.0.0", "mime": "^4.0.0", - "server-destroy": "^1.0.1", "srcset": "^5.0.0", "undici": "^7.16.0" }, @@ -636,9 +674,9 @@ } }, "node_modules/markdown-it": { - "version": "14.1.0", - "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.1.0.tgz", - "integrity": "sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==", + "version": "14.1.1", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.1.1.tgz", + "integrity": "sha512-BuU2qnTti9YKgK5N+IeMubp14ZUKUUw7yeJbkjtosvHiP0AZ5c8IAgEMk79D0eC8F23r4Ac/q8cAIFdm2FtyoA==", "dev": true, "license": "MIT", "dependencies": { @@ -654,9 +692,9 @@ } }, "node_modules/markdownlint": { - "version": "0.39.0", - "resolved": "https://registry.npmjs.org/markdownlint/-/markdownlint-0.39.0.tgz", - "integrity": "sha512-Xt/oY7bAiHwukL1iru2np5LIkhwD19Y7frlsiDILK62v3jucXCD6JXlZlwMG12HZOR+roHIVuJZrfCkOhp6k3g==", + "version": "0.40.0", + "resolved": "https://registry.npmjs.org/markdownlint/-/markdownlint-0.40.0.tgz", + "integrity": "sha512-UKybllYNheWac61Ia7T6fzuQNDZimFIpCg2w6hHjgV1Qu0w1TV0LlSgryUGzM0bkKQCBhy2FDhEELB73Kb0kAg==", "dev": true, "license": "MIT", "dependencies": { @@ -667,7 +705,8 @@ "micromark-extension-gfm-footnote": "2.1.0", "micromark-extension-gfm-table": "2.1.1", "micromark-extension-math": "3.1.0", - "micromark-util-types": "2.0.2" + "micromark-util-types": "2.0.2", + "string-width": "8.1.0" }, "engines": { "node": ">=20" @@ -677,18 +716,17 @@ } }, "node_modules/markdownlint-cli2": { - "version": "0.19.1", - "resolved": "https://registry.npmjs.org/markdownlint-cli2/-/markdownlint-cli2-0.19.1.tgz", - "integrity": "sha512-p3JTemJJbkiMjXEMiFwgm0v6ym5g8K+b2oDny+6xdl300tUKySxvilJQLSea48C6OaYNmO30kH9KxpiAg5bWJw==", + "version": "0.21.0", + "resolved": "https://registry.npmjs.org/markdownlint-cli2/-/markdownlint-cli2-0.21.0.tgz", + "integrity": "sha512-DzzmbqfMW3EzHsunP66x556oZDzjcdjjlL2bHG4PubwnL58ZPAfz07px4GqteZkoCGnBYi779Y2mg7+vgNCwbw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { - "globby": "15.0.0", + "globby": "16.1.0", "js-yaml": "4.1.1", "jsonc-parser": "3.3.1", - "markdown-it": "14.1.0", - "markdownlint": "0.39.0", + "markdown-it": "14.1.1", + "markdownlint": "0.40.0", "markdownlint-cli2-formatter-default": "0.0.6", "micromatch": "4.0.8" }, @@ -721,7 +759,6 @@ "integrity": "sha512-boeBdiS0ghpWcSwoNm/jJBwdpFaMnZWRzjA6SkUMYb40SVaN1x7mmfGKp0jvexGcx+7y2La5zRZsYFZI6Qpypg==", "dev": true, "license": "MIT", - "peer": true, "bin": { "marked": "bin/marked.js" }, @@ -1339,16 +1376,16 @@ } }, "node_modules/minimatch": { - "version": "10.1.1", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.1.1.tgz", - "integrity": "sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ==", + "version": "10.2.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.4.tgz", + "integrity": "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg==", "dev": true, "license": "BlueOak-1.0.0", "dependencies": { - "@isaacs/brace-expansion": "^5.0.0" + "brace-expansion": "^5.0.2" }, "engines": { - "node": "20 || >=22" + "node": "18 || 20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" @@ -1408,19 +1445,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/path-type": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-6.0.0.tgz", - "integrity": "sha512-Vj7sf++t5pBD637NSfkxpHSMfWaeig5+DKWLhcqIYx6mWQz5hdJTGDVMQiJcw1ZYkhs7AazKDGpRVji1LJCZUQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/picomatch": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", @@ -1500,13 +1524,6 @@ "queue-microtask": "^1.2.2" } }, - "node_modules/server-destroy": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/server-destroy/-/server-destroy-1.0.1.tgz", - "integrity": "sha512-rb+9B5YBIEzYcD6x2VKidaa+cqYBJQKnU4oe4E3ANwRRN56yk/ua1YCJT1n21NTS8w6CcOclAKNP3PhdCXKYtQ==", - "dev": true, - "license": "ISC" - }, "node_modules/slash": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/slash/-/slash-5.1.0.tgz", @@ -1533,6 +1550,39 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/string-width": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-8.1.0.tgz", + "integrity": "sha512-Kxl3KJGb/gxkaUMOjRsQ8IrXiGW75O4E3RPjFIINOVH8AMl2SQ/yWdTzWwF3FevIX9LcMAjJW+GRwAlAbTSXdg==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-east-asian-width": "^1.3.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/strip-ansi": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", + "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", @@ -1554,9 +1604,9 @@ "license": "MIT" }, "node_modules/undici": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/undici/-/undici-7.16.0.tgz", - "integrity": "sha512-QEg3HPMll0o3t2ourKwOeUAZ159Kn9mx5pnzHRQO8+Wixmh88YdZRiIwat0iNzNNXn0yoEtXJqFpyW7eM8BV7g==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/undici/-/undici-7.24.1.tgz", + "integrity": "sha512-5xoBibbmnjlcR3jdqtY2Lnx7WbrD/tHlT01TmvqZUFVc9Q1w4+j5hbnapTqbcXITMH1ovjq/W7BkqBilHiVAaA==", "dev": true, "license": "MIT", "engines": { @@ -1564,13 +1614,13 @@ } }, "node_modules/unicorn-magic": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.3.0.tgz", - "integrity": "sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==", + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.4.0.tgz", + "integrity": "sha512-wH590V9VNgYH9g3lH9wWjTrUoKsjLF6sGLjhR4sH1LWpLmCOH0Zf7PukhDA8BiS7KHe4oPNkcTHqYkj7SOGUOw==", "dev": true, "license": "MIT", "engines": { - "node": ">=18" + "node": ">=20" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" diff --git a/package.json b/package.json index 98b7768..3582e87 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,7 @@ "start": "npm run serve" }, "devDependencies": { - "linkinator": "^7.5.1", - "markdownlint-cli2": "0.19.1" + "linkinator": "^7.6.1", + "markdownlint-cli2": "0.21.0" } } diff --git a/requirements.txt b/requirements.txt index dba9c13..b88566b 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,5 @@ mkdocs==1.6.1 -mkdocs-git-revision-date-localized-plugin==1.5.0 -mkdocs-material==9.7.0 +mkdocs-git-revision-date-localized-plugin==1.5.1 +mkdocs-material==9.7.5 mkdocs-redirects==1.2.2 markdown-include==0.8.1