在 AF_INET6 套接字上接收 IPv4 连接是否不安全?

信息安全 IPv6 打开bsd freebsd
2021-08-31 23:42:07

inet6的FreeBSD 手册页有以下内容:

默认情况下,FreeBSD 不会将 IPv4 流量路由到 AF_INET6 套接字。出于安全原因,默认行为故意违反 RFC2553。如果要同时接受 IPv4 和 IPv6 流量,请侦听两个套接字。IPv4 流量可以使用特定的每套接字/每节点配置进行路由,但是不建议这样做。有关详细信息,请参阅 ip6(4)。

OpenBSD 在其手册页中也有类似的措辞

出于安全原因,OpenBSD 不将 IPv4 流量路由到 AF_INET6 套接字,并且不支持 IPv4 映射地址,其中 IPv4 流量被视为来自 IPv6 地址,例如 ::ffff:10.1.1.1。在需要接受 IPv4 和 IPv6 流量的地方,监听两个套接字。

这是参考RFC2553 的第 3.7 节(被RFC3493废弃)关于 IPv4 地址被翻译成::FFFF:<IPv4-address>.

我不明白接受 IPv4 连接会暴露什么样的安全问题?是什么让翻译后的 IPv4 地址比任何其他 IPv6 地址更不安全?为什么 Linux 会允许这种“不安全”的行为?

1个回答

当主机通过网络接受 IPv4 映射的 IPv6 流量,而不是接受 IPv4 流量并将其呈现给具有映射地址的 IPv6 套接字上的应用程序时,就会出现大多数这些安全问题。应用程序可能没有很好的方法来区分并检测正在进行的潜在攻击。当然,任何主机都不应该接受来自网络的映射地址,但是从什么时候起操作系统表现得完美呢?

RFC 4942 § 2.2深入解释了这些问题:

重载功能始终是一把双刃剑:它可能会产生一些部署优势,但通常也会带来含糊不清的代价。

其中一个示例是 IPv4 映射的 IPv6 地址 (::ffff/96):在 [RFC3493] 中定义的操作系统内将 IPv4 地址表示为 IPv6 地址。自最初的规范以来,IPv4 映射地址的使用已扩展到一种转换机制,即无状态 IP/ICMP 转换算法 (SIIT) [RFC2765],它们可能用于在线数据包的地址中。

因此,很难明确区分 IPv4 映射地址是否真的是以 IPv6 地址格式表示的 IPv4 地址(基本 API 行为)从线路接收的 IPv6 地址(可能会受到地址伪造等的影响)。(SIIT 行为)。在网络上使用 IPv4 映射地址时,由不明确行为引起的安全问题包括:

  • 如果攻击者在 IPv6 源地址字段中传输带有 ::ffff:127.0.0.1 的 IPv6 数据包,他可能会通过欺骗应用程序相信数据包来自节点本身(特别是 IPv4环回地址,127.0.0.1)。可以使用节点的 IPv4 接口地址来执行相同的攻击。

  • 如果攻击者在与站点安全边界内的 IPv4 地址相对应的 IPv6 目标地址字段中传输 IPv4 映射地址的 IPv6 数据包(例如 ::ffff:10.1.1.1),他可能能够绕过 IPv4 数据包过滤规则并穿越站点的防火墙。

  • 如果攻击者将在 IPv6 源和目标字段中具有 IPv4 映射地址的 IPv6 数据包传输到交换 IPv6 源和目标地址的协议,他可能能够将节点用作某些类型的攻击的代理。例如,这可能用于构建广播乘法和代理 TCP 端口扫描攻击。

此外,像这样的特殊情况,虽然在某些领域具有部署优势,但需要相当多的代码复杂性(例如,在 bind() 系统调用和反向 DNS 查找的实现中),这可能是不可取的,但可以在此管理案件。

在实践中,尽管 SIIT 的数据包转换机制在“网络地址转换器 - 协议转换器 (NAT-PT)”[RFC2766] 中指定使用,但 NAT-PT 使用与 IPv4 映射的 IPv6 地址不同的机制来通信嵌入的 IPv4 地址在 IPv6 地址中。此外,不建议将 SIIT 用作独立的过渡机制。鉴于已确定的问题,在线路上不应使用映射地址似乎是合适的。但是,通过在操作系统接口中弃用映射地址来改变应用程序行为将对 [RFC4038] 中描述的应用程序移植方法产生重大影响,并且预计 IPv4 映射的 IPv6 地址将继续在 API 中使用以帮助应用程序的可移植性。

使用基本 API 行为有一些安全隐患,因为它增加了基于地址的访问控制的额外复杂性。出现的主要问题是,即使节点没有打开 IPv4 (AF_INET) 套接字,IPv6 (AF_INET6) 套接字也会接受 IPv4 数据包。应用程序开发人员必须考虑到这一点,即使没有打开的 IPv4 套接字,也可能允许恶意 IPv4 对等方访问服务。这违反了“最小意外”的安全原则。