给定以下网络设置:
Debian bullseye 主机(Proxmox VE)-> OPNsense 防火墙进行 NAT -> DSL 调制解调器(通过 PPPoE 连接)-> 互联网
该主机无法与互联网上的任何主机建立 TCP 连接。我尝试访问不同的主机,以及一个可以捕获流量的服务器。
我使用 DSL 调制解调器交换机端口的端口镜像捕获了一些流量,以确保我确实看到通过线路传输到互联网的流量。
使用相同拓扑的网络中另一台 Debian 机器的流量看起来很好。
我在两台机器上执行curl -4 http://ftp.de.debian.org/debian
并curl -4 http://www.google.de
比较了 TCP SYN 数据包。
在我看来它们是一样的,不同之处仅在于
- IP 标识头以及 IP 头校验和
- TCP 源端口
- TCP 序列号
- TCP 校验和
- TCP 时间戳值
这些差异是预料之中的。
以下是 DSL 调制解调器端口流量的屏幕截图。捕获内容包含从工作主机到数据包 308 的流量。从数据包 309 开始的流量来自故障主机。
我过滤了设置了 SYN 标志的数据包,因为这些数据包仅是相关的。
如上所述,我还从服务器端捕获了流量。它看起来与屏幕上显示的完全一样(数据包 309、310、320……)。
附加信息:
- LAN 内的 TCP 流量(例如 ssh 到另一台主机)按预期工作。
- 到互联网的 UDP 流量(例如 NTP 流量)正常。
- 到互联网的 ICMP 流量也正常。
什么原因导致互联网主机不使用 SYN-ACK 应答 SYN 数据包?
答案1
简短回答:校验和计算不正确。在 wireshark 中启用校验和验证可以明显发现这一点:
长答案:
问题是由于 OPNsense 在 Proxmox VE 上虚拟化运行而引起的。因此,我在 /etc/network/interfaces 中禁用了 NIC 的一些卸载功能:
[...]
pre-up ethtool -K enp0s20f1 gro off lro off gso off
post-up ethtool -K vmbr1 gro off lro off gso off
此代码片段禁用通用接收卸载和大型接收卸载。这是为了防止 NIC 将多个 TCP 数据包重新组装成可能大于 MTU 的较大数据包。由于在执行简单路由时修改数据包不是一个好主意,因此在许多情况下这会导致连接问题。禁用通用分段偏移可防止 NIC 将大型数据包拆分成多个。
上面的代码片段必须包含tx off
pre-up ethtool -K enp0s20f1 gro off lro off gso off tx off
post-up ethtool -K vmbr1 gro off lro off gso off tx off
强制软件校验和计算。