]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
daemon/io: avoid PMTU discovery for IPv4 server side
authorVladimír Čunát <vladimir.cunat@nic.cz>
Tue, 15 Sep 2020 08:57:37 +0000 (10:57 +0200)
committerLukáš Ježek <lukas.jezek@nic.cz>
Thu, 8 Oct 2020 05:23:52 +0000 (07:23 +0200)
This seems generally considered to be a good thing (for DNS servers).
We don't do it on client side; I can't see an easy way there.

NEWS
daemon/io.c

diff --git a/NEWS b/NEWS
index 52c0bdb61838cd6c5083a969d0a795e053fe32fb..02680d5999ffab0e1ab184cc18dbea1f4c1f95b1 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -5,6 +5,7 @@ Improvements
 ------------
 - net: split the EDNS buffer size into upstream and downstream (!1026)
 - lua-http doh: answer to /dns-query endpoint as well as /doh (!1069)
+- improve resiliency against UDP fragmentation attacks (disable PMTUD) (!1061)
 
 Bugfixes
 --------
index 8c929ecf20c36eb72e09645ecf199c24acb1926f..7b5f910cbf85b9edb86b43f83aadf146036ed486 100644 (file)
@@ -144,6 +144,23 @@ int io_bind(const struct sockaddr *addr, int type, const endpoint_flags_t *flags
                        if (setsockopt(fd, optlevel, optname, &yes, sizeof(yes)))
                                return kr_error(errno);
                }
+
+               /* Linux 3.15 has IP_PMTUDISC_OMIT which makes sockets
+                * ignore PMTU information and send packets with DF=0.
+                * This mitigates DNS fragmentation attacks by preventing
+                * forged PMTU information.  FreeBSD already has same semantics
+                * without setting the option.
+                       https://gitlab.nic.cz/knot/knot-dns/-/issues/640
+                */
+#if defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_OMIT)
+               int omit = IP_PMTUDISC_OMIT;
+               if (type == SOCK_DGRAM && addr->sa_family == AF_INET
+                   && setsockopt(fd, IPPROTO_IP, IP_MTU_DISCOVER, &omit, sizeof(omit))) {
+                       kr_log_error(
+                               "[ io ] failed to disable Path MTU discovery for %s UDP: %s\n",
+                               kr_straddr(addr), strerror(errno));
+               }
+#endif
        }
 
        if (bind(fd, addr, kr_sockaddr_len(addr)))