git: 1817be481b87 - main - Add net.inet6.ip6.source_address_validation
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Fri, 12 Nov 2021 17:07:25 UTC
The branch main has been updated by glebius: URL: https://cgit.FreeBSD.org/src/commit/?id=1817be481b8703ae86730b151a6f49cc3022930f commit 1817be481b8703ae86730b151a6f49cc3022930f Author: Gleb Smirnoff <glebius@FreeBSD.org> AuthorDate: 2021-11-12 17:01:13 +0000 Commit: Gleb Smirnoff <glebius@FreeBSD.org> CommitDate: 2021-11-12 17:01:40 +0000 Add net.inet6.ip6.source_address_validation Drop packets arriving from the network that have our source IPv6 address. If maliciously crafted they can create evil effects like an RST exchange between two of our listening TCP ports. Such packets just can't be legitimate. Enable the tunable by default. Long time due for a modern Internet host. Reviewed by: melifaro, donner, kp Differential revision: https://reviews.freebsd.org/D32915 --- share/man/man4/inet6.4 | 10 +++++++++- sys/netinet6/ip6_input.c | 12 ++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/share/man/man4/inet6.4 b/share/man/man4/inet6.4 index 300f98abb196..87c57ea2c3d2 100644 --- a/share/man/man4/inet6.4 +++ b/share/man/man4/inet6.4 @@ -29,7 +29,7 @@ .\" .\" $FreeBSD$ .\" -.Dd November 25, 2020 +.Dd November 12, 2021 .Dt INET6 4 .Os .Sh NAME @@ -341,6 +341,14 @@ mapped address on .Dv AF_INET6 sockets. Defaults to on. +.It Va ip6.source_address_validation +Boolean: perform source address validation for packets destined for the local +host. +Consider this as following Section 3.2 of RFC3704/BCP84, where we treat local +host as our own infrastructure. +This has no effect on packets to be forwarded, so don't consider it as +anti-spoof feature for a router. +Enabled by default. .El .Ss Interaction between IPv4/v6 sockets By default, diff --git a/sys/netinet6/ip6_input.c b/sys/netinet6/ip6_input.c index 30ad9a53006a..2d4e63ca83b6 100644 --- a/sys/netinet6/ip6_input.c +++ b/sys/netinet6/ip6_input.c @@ -163,6 +163,12 @@ SYSCTL_PROC(_net_inet6_ip6, IPV6CTL_INTRQMAXLEN, intr_queue_maxlen, 0, 0, sysctl_netinet6_intr_queue_maxlen, "I", "Maximum size of the IPv6 input queue"); +VNET_DEFINE_STATIC(bool, ip6_sav) = true; +#define V_ip6_sav VNET(ip6_sav) +SYSCTL_BOOL(_net_inet6_ip6, OID_AUTO, source_address_validation, + CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(ip6_sav), true, + "Drop incoming packets with source address that is a local address"); + #ifdef RSS static struct netisr_handler ip6_direct_nh = { .nh_name = "ip6_direct", @@ -816,6 +822,12 @@ passin: ip6_sprintf(ip6bufd, &ip6->ip6_dst))); goto bad; } + if (V_ip6_sav && !(rcvif->if_flags & IFF_LOOPBACK) && + __predict_false(in6_localip_fib(&ip6->ip6_src, + rcvif->if_fib))) { + IP6STAT_INC(ip6s_badscope); /* XXX */ + goto bad; + } /* Count the packet in the ip address stats */ counter_u64_add(ia->ia_ifa.ifa_ipackets, 1); counter_u64_add(ia->ia_ifa.ifa_ibytes, m->m_pkthdr.len);