我一直在尝试想出一个解决路由问题的方法(多个接口连接到一个 Docker 容器,确保响应数据包从正确的接口发出),并且发现了一个有趣的现象:虽然使用 TRACE 记录数据包仅显示源 IP 是 Docker 网络接口,但 tcpdump 设法显示所连接接口的实际源 IP 地址。见下文。有人能告诉我这个源地址来自哪里吗?如果有人有想法,还有一个附加问题,我该如何在 iptables 规则中匹配这个源地址(如果可能的话)?
Oct 23 09:54:43 <hostname> kernel: [145206.331674] TRACE: raw:PREROUTING:policy:3 IN=br-55939cd46cf5 OUT= PHYSIN=<phys> MAC=<mac> SRC=172.23.0.2 DST=<ext ip> LEN=60 TOS=0x00 PREC=0x00 TTL=64 ID=0 DF PROTO=TCP SPT=80 DPT=63742 SEQ=515334190 ACK=1161940855 WINDOW=28960 RES=0x00 ACK SYN URGP=0 OPT (020405B40402080A0228C591A136C09A01030307)
10.112.0.103.80 > <external ip>.64710: Flags [S.], cksum 0x839a (incorrect -> 0x3647), seq 3129672596, ack 2031230462, win 28960, options [mss 1460,sackOK,TS val 36559662 ecr 2706000943,nop,wscale 7], length 0
这不是我实际遇到的问题,但至少可以帮助我理解。提前致谢!
答案1
在 Linux 系统上,有许多地方可以检查网络数据包(例如 TCP/IP 数据包)。当您提到 TRACE 时,我假设您指的是来自 iptables 的 TRACE。tcpdump 和 iptables 在数据包流经系统期间的不同时间查看数据包。因此,正如 Michael Hampton 所评论的那样,“一个是在 NAT 之前,一个是在 NAT 之后”。
有许多有用的图表描述了 Linux 系统中的数据包流(在 Google 上搜索“linux 网络数据包流”)。要更详细地了解答案,请查看以下 StackExchange Unix 和 Linux 问题中的图表:
也可在此处获取 SVG 版本: https://en.wikipedia.org/wiki/Netfilter#/media/File:Netfilter-packet-flow.svg
在该图中,我相信 tcpdump(通过 libpcap)在标记为“taps(例如 AF_PACKET)”的步骤中检查数据包。然后,根据您插入 TRACE 的位置,您可能会看到不同的源地址。您将 TRACE 插入到哪里(例如在基础主机中还是在 docker 容器中)?我应该在评论中提出这个问题,但我仍然没有足够的声誉来为 Server Fault 中的问题添加评论。
Stack Exchange 超级用户网站也有一个类似的问题,并且给出了很好的答案: https://superuser.com/questions/925286/does-tcpdump-bypass-iptables