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);