reject IPv4-embedded IPv6 prefixes. - #47
Conversation
|
FAILED profiles/tests/test_xfw.py::test_zeroed_ipv6 - ValueError: |
Reject IPv4-compatible and IPv4-mapped IPv6 prefixes when parsing IPv6 packet filtering rules. IPv4-compatible addresses have been deprecated since RFC 4291. RFC 6890 further specifies that IPv4-mapped addresses are not valid IPv6 packet source or destination addresses (Source=False, Destination=False). Therefore, neither format is expected to appear in legitimate IPv6 packet traffic. Rejecting these prefixes also simplifies GeoIP lookups. MaxMind DBs do not contain IPv4-compatible or IPv4-mapped IPv6 prefixes: IPv4 networks are stored exclusively in the IPv4 search tree. Users should use native IPv4 prefixes and IPv4 GeoIP databases instead of IPv4-embedded IPv6 forms.
d29f55a to
f6917f2
Compare
krizhanovsky
left a comment
There was a problem hiding this comment.
LGTM, but a more careful review in terms of RFC is required. @EvgeniiMekhanik could you please have a look
| * Matches both deprecated IPv4-compatible (::a.b.c.d) and IPv4-mapped | ||
| * (::ffff:a.b.c.d) IPv6 address formats. | ||
| * | ||
| * RFC 6890 marks these prefixes as invalid IPv6 packet source and |
There was a problem hiding this comment.
~The RFC is update by https://datatracker.ietf.org/doc/html/rfc8190 ~ - it seems there are no relevant for us updates in 8190. Also please specify particular RFC chapter and table
| /* | ||
| * Return true if @addr is an IPv4-embedded IPv6 address. | ||
| * | ||
| * Matches both deprecated IPv4-compatible (::a.b.c.d) and IPv4-mapped |
There was a problem hiding this comment.
Could you also reference RFC 4291 2.5.5 in the comment
| } | ||
|
|
||
| static bool | ||
| xfw_is_ipv4_embedded_ipv6(const Ip6Addr &addr) noexcept |
There was a problem hiding this comment.
We have a duplicate logic - can we adjust addr and use the routine from bpf_uapi/ip_helpers.h ?
There was a problem hiding this comment.
static bool
xfw_is_ipv4_embedded_ipv6(const Ip6Addr &addr,
unsigned prefixlen) noexcept
{
if (prefixlen < 96)
return false;
...
} at least we should use such function to adjust prefixlen
krizhanovsky
left a comment
There was a problem hiding this comment.
Well, actually probably there are more things to check against the RFCs...
| * destination addresses (Source=False, Destination=False). | ||
| */ | ||
| if (xfw_is_ipv4_embedded_ipv6(ip6h->saddr.in6_u.u6_addr32) | ||
| || xfw_is_ipv4_embedded_ipv6(ip6h->daddr.in6_u.u6_addr32)) |
There was a problem hiding this comment.
IIUC from our discussion the addresses are deprecated, but we still may receive them, i.e. we should not block them right?
RFC 6890 table 20 says that we should not accept IPv6-mapped addresses (Source=False, Destination=False), but I don't see the check here.
And I do not see an appropriate table in the RFC for embedded addresses (::0/96)
|
GPT-5.6-sol review: • Found one functional issue:
Also, git diff --check reports trailing whitespace in bpf_uapi/ip_helpers.h:44, though that is non-functional. |
|
Review from Fable 5 (~20k tokens): Review: irinak/deny_embedded_addresses vs main (f6917f2) The change moves handling of IPv4-embedded IPv6 addresses (::a.b.c.d, ::ffff:a.b.c.d) from "convert and match against IPv4 rules" to "drop the packets and reject such prefixes in Findings, most important first
Also noted but fine: the guard is address-exact, so a src prefix like ::/96 that covers the embedded range still passes config validation — harmless since the packets are dropped Nothing here is a blocker; #1 is the one I'd want an explicit decision on before merge. |
| * destination addresses (Source=False, Destination=False). | ||
| */ | ||
| static __always_inline bool | ||
| xfw_is_ipv4_embedded_ipv6(const __be32 addr[4]) |
There was a problem hiding this comment.
static __always_inline bool
xfw_is_legacy_ipv4_embedded_ipv6(const __be32 addr[4])
{
/* IPv4-compatible IPv6: ::/96 */
if (!addr[0] && !addr[1] && !addr[2])
return addr[3] != 0 && addr[3] != HTONL(1);
/* IPv4-mapped IPv6: ::ffff:0:0/96 */
return !addr[0] && !addr[1] &&
addr[2] == HTONL(0xffff);
} may be in till be more clear? But up to you
Reject IPv4-compatible and IPv4-mapped IPv6 prefixes when parsing IPv6 packet filtering rules.
IPv4-compatible addresses have been deprecated since RFC 4291. RFC 6890 further specifies that IPv4-mapped addresses are not valid IPv6 packet source or destination addresses (Source=False, Destination=False). Therefore, neither format is expected to appear in legitimate IPv6 packet traffic.
Rejecting these prefixes also simplifies GeoIP lookups. MaxMind DBs do not contain IPv4-compatible or IPv4-mapped IPv6 prefixes: IPv4 networks are stored exclusively in the IPv4 search tree. Users should use native IPv4 prefixes and IPv4 GeoIP databases instead of IPv4-embedded IPv6 forms.
Closes 336(escudo), 331(escudo)