IPsec 配置备忘 Part5 - 防火墙配置

记录一下使用到的端口以及需要做的防火墙配置,不一定能覆盖所有场景,如果有漏掉的规则欢迎留言补充。

TL;DR 在两端均放行:

  • UDP 500
  • UDP 4500
  • ESP 协议

最基本的 IKEv2 使用 UDP 500 端口进行通信。当密钥交换完成后,Linux 内核会将加密了的数据包封装在 ESP 中发送。所以整个包结构是:

Ethernet - 外层IP - ESP - 内层IP - <...>

但是我们也知道,所有除 UDP 和 TCP 以外的四层协议都不能很好地穿过防火墙和 NAT,于是给 ESP 套一层 UDP 就是很自然的事情了:

Ethernet - 外层IP - UDP[dport=4500] - ESP - 内层IP - <...>

这层多出来的 UDP 的端口号就被人为规定成 4500 了。另外由于一些我没有搞明白的原因,strongSwan 会在某些情况下使用 4500 进行 IKE 通信,即使并不需要 ESP UDP 封装。

在默认配置下,strongSwan 需要所有三种规则:使用 UDP 500 和 4500 (即使没有 NAT)进行 IKEv2 协商,然后内核发送 ESP 包。如果有 NAT 存在,strongSwan 会使用 UDP 4500 对数据进行封装而不使用 ESP。

如果你不想放行 4500 又不想影响非 NAT 流量,可以在配置文件中设置mobike = no。你也可以使用encap = yes选项在没有 NAT 的环境中模拟 NAT,强制使用 UDP ESP 封装。如果你能确保你的所有 ESP 流量都是 UDP 封装的,那么不放行 ESP 也是可以的。

如果你使用不封装的 ESP,那么你需要在连接两端都放行 ESP 数据包,不然可能会出现奇怪的现象。比如,你必须先从 A ping B,然后才能从 B ping A,直接 ping 不通,之类的。

用于nftables.conf的放行规则如下:

1
2
3
4
5
udp dport 500 accept
udp dport 4500 accept
# 外层 IP 可能是 IPv4 也可能是 IPv6,需要两条规则来放行所有 ESP 包
ip protocol esp accept
ip6 nexthdr esp accept