788 Commits

Author SHA1 Message Date
DL6ER d67d13303d Add downstream EDE info for synthesized replies
Signed-off-by: DL6ER <dl6er@dl6er.de>
2024-09-14 10:17:14 +02:00
DL6ER af1c5b3039 Add new config option dns.cache.upstreamTTL (defaulting to one day) for configuring how long relpies from upstream are cached
Signed-off-by: DL6ER <dl6er@dl6er.de>
2024-08-21 20:18:59 +02:00
DL6ER 070544bde1 Implement DNS caching for queries blocked upstream (NXDOMAIN + no RA, 0.0.0.0/::, and known Umbrella IP blocking pages) accompanied with suitable CI testing. This change improves handling of externally blocked queries in two ways:
1. Once we know the domain is externally blocked, we don't forward it again for the same client (it is currently forwarded each time)
2. We can recognize cache content with the specified addresses/flags as being upstream blocked and don't return them as "OK (cached)" through the API/in the database

Signed-off-by: DL6ER <dl6er@dl6er.de>
2024-08-21 20:14:51 +02:00
DL6ER e5d901a80c Improve pihole-FTL process concurrency
FTL is trying hard to prevent you from starting another instance of itself. It does so by creating a PID file in `/run/pihole-FTL.pid` and checking for its existence. If the file is present, FTL assumes that another instance is already running and exits. It also checks for the existence of the shared memory objects `/dev/shm/FTL-*` and exits if they are present. These checks can be fooled by manually removing the PID file or shared memory objects (needs `root` privileges). This can lead to multiple instances of FTL running at the same time, which can cause various issues. The most commonly seen issue is that, when the first process needs more memory, its original shared memory objects are already gone. Hence, it actually tries to resize the shared memory objects of the second instance which, on the other hand, doesn't expect this and crashes. As the first process was not able to allocate more memory, this process will eventually crash as well.

This commit resolves this by:
1. Improve support for concurrent `pihole-FTL` instances. Even when this continues to be somewhat discouraged, it is now possible to run multiple instances of `pihole-FTL` at the same time. This is achieved by ensuring that we keep the shared memory object file descriptors open as long as the process is running. This way, the shared memory objects are not removed until the process exits. This also means that the shared memory objects are not *hard* removed when they are deleted from the outside of the process (in Linux, a file continues to exist as long as there is at least one open file descriptor pointing to it). A hypothetical second instance of `pihole-FTL` will now be able to create new shared memory objects without interfering with the first instance. This is a more robust solution than the previous one, as it doesn't rely on the existence of the PID file or shared memory objects which might have been removed by external influences.
2. Check for a potential second instance earlier in the code. We move the check to before even trying to create shared memory objects. This way, we can exit early if we detect that another instance is already running. This is a more efficient solution than the previous one, as we don't need to create shared memory objects just to find out that we can't use them.
3. Add an exclusive lock on the shared memory objects. Even when this is not strictly necessary, it is a good practice to prevent other processes from interfering with the shared memory objects. This is especially important on systems which isolate processes from each other and is a safety net in rare cases such aas multiple Docker containers (isolating processes from one another by default) with (incorrectly!) host-mounted shared memory folders. Once they remove the mounting of `dev/shm`, they will again be able to run multiple `pihole-FTL` across multiple containers.

Signed-off-by: DL6ER <dl6er@dl6er.de>
2024-08-06 18:40:42 +02:00
DL6ER 4c4489a539 Use pipe to main process instead of printing directly from the signal handler to avoid futex wait blocking
Signed-off-by: DL6ER <dl6er@dl6er.de>
2024-07-31 18:57:15 +02:00
DL6ER e942301897 Improve automatic PTR handling code, fix a small memory leak and remove a bit of duplicated code
Signed-off-by: DL6ER <dl6er@dl6er.de>
2024-07-30 20:20:55 +02:00
DL6ER d54f0a2205 Handle SIGTERM in FTL if dnsmasq failed to start. Otherwise, we may end up in a situation where nobody feels responsible for handling SIGTERM events and FTL ends up in an un-terminate-able state
Build, Test, Deploy / smoke-tests (push) Has been cancelled
Codespell / spell-check (push) Has been cancelled
Check for merge conflicts / merge-conflict (push) Has been cancelled
API validation / Node (push) Has been cancelled
Build, Test, Deploy / gha (pihole-FTL-386, , linux/386) (push) Has been cancelled
Build, Test, Deploy / gha (pihole-FTL-amd64, , linux/amd64) (push) Has been cancelled
Build, Test, Deploy / gha (pihole-FTL-amd64-clang, clang, linux/amd64) (push) Has been cancelled
Build, Test, Deploy / gha (pihole-FTL-riscv64, , linux/riscv64) (push) Has been cancelled
Build, Test, Deploy / self-hosted (pihole-FTL-arm64, linux/arm64/v8) (push) Has been cancelled
Build, Test, Deploy / self-hosted (pihole-FTL-armv6, linux/arm/v6) (push) Has been cancelled
Build, Test, Deploy / self-hosted (pihole-FTL-armv7, linux/arm/v7) (push) Has been cancelled
Signed-off-by: DL6ER <dl6er@dl6er.de>
2024-07-25 18:33:55 +02:00
DL6ER 8b566e37f0 Add extra debug logging and reduce code duplication in signal handling (no functional change)
Signed-off-by: DL6ER <dl6er@dl6er.de>
2024-07-25 18:33:25 +02:00
DL6ER f07d902802 Merge branch 'development-v6' into tweak/api_network_info
Build, Test, Deploy / smoke-tests (push) Has been cancelled
Codespell / spell-check (push) Has been cancelled
Check for merge conflicts / merge-conflict (push) Has been cancelled
API validation / Node (push) Has been cancelled
Build, Test, Deploy / gha (pihole-FTL-386, , linux/386) (push) Has been cancelled
Build, Test, Deploy / gha (pihole-FTL-amd64, , linux/amd64) (push) Has been cancelled
Build, Test, Deploy / gha (pihole-FTL-amd64-clang, clang, linux/amd64) (push) Has been cancelled
Build, Test, Deploy / gha (pihole-FTL-riscv64, , linux/riscv64) (push) Has been cancelled
Build, Test, Deploy / self-hosted (pihole-FTL-arm64, linux/arm64/v8) (push) Has been cancelled
Build, Test, Deploy / self-hosted (pihole-FTL-armv6, linux/arm/v6) (push) Has been cancelled
Build, Test, Deploy / self-hosted (pihole-FTL-armv7, linux/arm/v7) (push) Has been cancelled
Signed-off-by: DL6ER <dl6er@dl6er.de>
2024-07-19 09:47:18 +02:00
DL6ER 6cf1a6774e Add netlink implementation
Signed-off-by: DL6ER <dl6er@dl6er.de>
2024-07-09 21:57:45 +02:00
DL6ER 87dd091535 Fix crash caused by double free() corruption encountered with rev-server addresses with prefix lengths != {8,16,24,32}
Signed-off-by: DL6ER <dl6er@dl6er.de>
2024-06-16 21:28:27 +02:00
DL6ER dc204a41b0 Use v2.6 CI containers and nightly for the devcontainer
Signed-off-by: DL6ER <dl6er@dl6er.de>
2024-05-25 09:54:37 +02:00
DL6ER 1a72da3616 Do not build static exectuable in clang test to avoid LTO linking issue
Signed-off-by: DL6ER <dl6er@dl6er.de>
2024-05-20 22:10:46 +02:00
DL6ER 20173437ad Merge branch 'development-v6' into new/clang 2024-05-18 20:38:56 +02:00
Erik Karlsson 98407e3a58 Update DNS records after pruning DHCP leases
Not doing so can result in a use after free since the name for DHCP
derived DNS records is represented as a pointer into the DHCP lease
table. Update will only happen when necessary since lease_update_dns
tests internally on dns_dirty and the force argument is zero.

Signed-off-by: Erik Karlsson <erik.karlsson@iopsys.eu>
Signed-off-by: DL6ER <dl6er@dl6er.de>
2024-05-18 09:13:54 +02:00
DL6ER 32de390b00 Add Clang compiler support, tested with Clang 14.0.0 (Ubuntu 22.04.3 LTS), Clang 16.0.2 (Alpine 3.18), and Clang 17.0.6 (Alping Edge)
Signed-off-by: DL6ER <dl6er@dl6er.de>
2024-05-15 20:41:52 +02:00
DL6ER ed41584c92 Add extra logging around network issues (EDE: network error)
Signed-off-by: DL6ER <dl6er@dl6er.de>
2024-04-02 12:05:28 +02:00
DL6ER 05867e20f2 Ensure cJSON is used in a thread-safe manner and add CI tests ensuring this. Also ensure every JSON parsing is doing error checking and reduce some code duplication. No functional change.
Signed-off-by: DL6ER <dl6er@dl6er.de>
2024-03-24 08:55:12 +01:00
Simon Kelley 157b589391 Fix spurious "resource limit exceeded" messages.
Replies from upstream with a REFUSED rcode can result in
log messages stating that a resource limit has been exceeded,
which is not the case.

Thanks to Dominik Derigs and the Pi-hole project for
spotting this.

Signed-off-by: DL6ER <dl6er@dl6er.de>
2024-02-19 13:59:52 +01:00
Simon Kelley c95816f3b9 Reverse suppression of ANY query answer logging.
Signed-off-by: DL6ER <dl6er@dl6er.de>
2024-02-13 16:46:14 +01:00
Simon Kelley 4b351cbe36 Add --dnssec-limits option.
Signed-off-by: DL6ER <dl6er@dl6er.de>
2024-02-13 16:45:54 +01:00
Simon Kelley cb577f318e Better allocation code for DS digest cache.
Signed-off-by: DL6ER <dl6er@dl6er.de>
2024-02-13 16:45:19 +01:00
Simon Kelley dcd12a2be6 Better stats and logging from DNSSEC resource limiting.
Signed-off-by: DL6ER <dl6er@dl6er.de>
2024-02-13 16:45:12 +01:00
Simon Kelley 84161ed295 Overhaul data checking in NSEC code.
Signed-off-by: DL6ER <dl6er@dl6er.de>
2024-02-13 16:44:06 +01:00
Simon Kelley 1dbbdc96ca Rework validate-by-DS to avoid DoS vuln without arbitrary limits.
By calculating the hash of a DNSKEY once for each digest algo,
we reduce the hashing work from (no. DS) x (no. DNSKEY) to
(no. DNSKEY) x (no. distinct digests)

The number of distinct digests can never be more than 255 and
it's limited by which hashes we implement, so currently only 4.

Signed-off-by: DL6ER <dl6er@dl6er.de>
2024-02-13 16:43:59 +01:00
Simon Kelley b5e7dd448b Update EDE code -> text conversion.
Signed-off-by: DL6ER <dl6er@dl6er.de>
2024-02-13 16:43:11 +01:00
Simon Kelley f141efdeba Parameterise work limits for DNSSEC validation.
Signed-off-by: DL6ER <dl6er@dl6er.de>
2024-02-13 16:43:03 +01:00
Simon Kelley d92159a836 Fix error introduced in 635bc51cac3d5d7dd49ce9e27149cf7e402b7e79
Signed-off-by: DL6ER <dl6er@dl6er.de>
2024-02-13 16:40:32 +01:00
Simon Kelley 0b9e5543d2 Measure cryptographic work done by DNSSEC.
Signed-off-by: DL6ER <dl6er@dl6er.de>
2024-02-13 16:40:27 +01:00
Simon Kelley ddf44bf916 Update NSEC3 iterations handling to conform with RFC 9276.
Signed-off-by: DL6ER <dl6er@dl6er.de>
2024-02-13 16:38:55 +01:00
Simon Kelley aa565b1dff Update header with new EDE values.
Signed-off-by: DL6ER <dl6er@dl6er.de>
2024-02-13 16:38:50 +01:00
Simon Kelley ebbfb893bd Protection against pathalogical DNSSEC domains.
An attacker can create DNSSEC signed domains which need a lot of
work to verfify. We limit the number of crypto operations to
avoid DoS attacks by CPU exhaustion.

Signed-off-by: DL6ER <dl6er@dl6er.de>
2024-02-13 16:38:46 +01:00
Simon Kelley 75648b4def Make --filter-rr=ANY filter the answer to ANY queries.
Thanks to Dominik Derigs for an earlier patch which inspired this.

Signed-off-by: DL6ER <dl6er@dl6er.de>
2024-02-13 07:15:03 +01:00
Simon Kelley 8cdead96a5 Tweak logging and special handling of T_ANY in rr-filter code.
Signed-off-by: DL6ER <dl6er@dl6er.de>
2024-02-13 07:12:25 +01:00
Heikki Linnakangas 48a0c4591f Don't create a useless inotify file desrcriptor when --port=0
If there are no dynamic configuration directories configured with
dhcp-hostsdir, dhcp-optsdir and hostsdir then we need to use inotify
only to track changes to resolv-files, but we don't need to do
that when DNS is disabled (port=0) or no resolv-files are configured.

It turns out that inotify slots can be a scarce resource, so not
using one when it's not needed is a Goood Thing.

Patch by HL, description above from SRK.

Signed-off-by: DL6ER <dl6er@dl6er.de>
2024-02-08 18:11:37 +01:00
Simon Kelley ef007f2bb1 Refactor the accumulated crud of years in process_reply().
Signed-off-by: DL6ER <dl6er@dl6er.de>
2024-02-08 18:11:37 +01:00
Simon Kelley 68594df9b7 Handle caching SOA for negative PTR queries.
Also deal with the fact that a root SOA is a thing.

Signed-off-by: DL6ER <dl6er@dl6er.de>
2024-02-08 18:11:37 +01:00
Simon Kelley 027d1587cb Fix logic error in signed RR handling.
In extract_addresses() the "secure" argument is only set if the
whole reply is validated (ie the AD bit can be set). Even without
that, some records may be validated, and should be marked
as such in the cache.

Related, the DNS doctor code has to update the flags for individual
RRs as it works, not the global "secure" flag.

Signed-off-by: DL6ER <dl6er@dl6er.de>
2024-02-08 18:11:37 +01:00
Simon Kelley 31a6b2dbc7 Fix compiler warning.
Signed-off-by: DL6ER <dl6er@dl6er.de>
2024-02-08 18:11:37 +01:00
Simon Kelley 54658e9058 Cache SOAs and return them with cached NXDOMAIN/NODATA replies.
Now we can cache arbirary RRs, give more correct answers when
replying negative answers from cache.

To implement this needed the DNS-doctor code to be untangled from
find_soa(), so it should be under suspicion for any regresssions
in that department.

Signed-off-by: DL6ER <dl6er@dl6er.de>
2024-02-08 18:11:37 +01:00
Simon Kelley ae46201c59 Fix FTBFS introduced in 2748d4e901193c919614276e42d6d54b11f3232d
Signed-off-by: DL6ER <dl6er@dl6er.de>
2024-02-03 22:07:22 +01:00
DL6ER edc4da9f49 Merge branch 'development-v6' into update/dnsmasq 2024-01-14 17:33:44 +01:00
Simon Kelley 9eb920ad7c Bump copyright to 2024.
Signed-off-by: DL6ER <dl6er@dl6er.de>
2024-01-14 17:33:35 +01:00
Petr Menšík 18bf4fd530 Introduce new --local-service=host parameter
Similar to local-service, but more strict. Listen only on localhost
unless other interface is specified. Has no effect when interface is
provided explicitly. I had multiple bugs fillen on Fedora, because I have
changed default configuration to:

interface=lo
bind-interfaces

People just adding configuration parts to /etc/dnsmasq.d or appending to
existing configuration often fail to see some defaults are already there.
Give them auto-ignored configuration as smart default.

Signed-off-by: Petr Menšík <pemensik@redhat.com>

Do not add a new parameter on command line. Instead add just parameter
for behaviour modification of existing local-service option. Now it
accepts two optional values:
- net: exactly the same as before
- host: bind only to lo interface, do not listen on any other addresses
  than loopback.

Signed-off-by: DL6ER <dl6er@dl6er.de>
2024-01-14 17:33:35 +01:00
Simon Kelley da901cbd23 Fix --synth-domain NXDOMAIN responses.
By design, dnsmasq forwards queries for RR-types it has no data
on, even if it has data for the same domain and other RR-types.

This can lead to an inconsitent view of the DNS when an upstream
server returns NXDOMAIN for an RR-type and domain but the same domain
but a different RR-type gets an answer from dnsmasq. To avoid this,
dnsmasq converts NXDOMAIN answer from upstream to NODATA answers if
it would answer a query for the domain and a different RR-type.

An oversight missed out --synth-domain from the code to do this, so
--synth-domain=thekelleys.org.uk,192.168.0.0/24
would result in the correct answer to an A query for
192-168.0.1.thekelleys.org.uk and an AAAA query for the same domain
would be forwarded upstream and the resulting NXDOMAIN reply
returned.

After the fix, the reply gets converted to NODATA.

Thanks to Matt Wong for spotting the bug.

Signed-off-by: DL6ER <dl6er@dl6er.de>
2024-01-14 17:33:35 +01:00
Simon Kelley 6ce28da714 Fix problem with domains associated with DHCP hosts at startup.
At startup, the leases file is read by lease_init(), and
in lease_init() undecorated hostnames are expanded into
FQDNs by adding the domain associated with the address
of the lease.

lease_init() happens relavtively early in the startup, party because
if it calls  the dhcp-lease helper script, we don't want that to inherit
a load of sensitive file descriptors. This has implications if domains
are defined using the --domain=example.com,eth0 format since it's long
before we call enumerate_interfaces(), so get_domain fails for such domains.

The patch just moves the hostname expansion function to a seperate
subroutine that gets called later, after enumerate_interfaces().

Signed-off-by: DL6ER <dl6er@dl6er.de>
2024-01-14 17:33:33 +01:00
DL6ER c81f1a3f6a If someone terminates FTL, try to obtain who is the murderer and log it
Signed-off-by: DL6ER <dl6er@dl6er.de>
2023-12-23 16:06:40 +01:00
DL6ER 0d0cdae84f Fix missing declaration
Signed-off-by: DL6ER <dl6er@dl6er.de>
2023-12-07 20:59:58 +01:00
DL6ER 242b35eba8 Remove CH TXT privacylevel.pihole entry
Signed-off-by: DL6ER <dl6er@dl6er.de>
2023-11-30 21:59:39 +01:00
DL6ER 78e94b9276 Merge branch 'development-v6' into update/dnsmasq 2023-11-30 21:55:22 +01:00