Docker容器内Golang应用仅能通过FQDN/IP访问同子网VM的问题
问题根源与解决方案
问题出在你的nftables规则里的**ip saddr 127.0.0.0/8 drop**规则——它直接丢弃了所有来自本地回环网段的入站流量,包括宿主机上systemd-resolved(监听127.0.0.53:53)返回的DNS响应。Docker容器默认使用宿主机的127.0.0.53作为DNS服务器,当容器内应用解析短域名machine2时,DNS查询的响应被这条规则拦截,导致超时;而FQDN或IP地址无需经过本地DNS解析(或走了其他解析路径),因此能正常访问。
修改nftables规则
编辑/etc/nftables.conf中的input链,在丢弃回环流量的规则之后,添加允许本地DNS响应的规则:
table inet filter { chain input { #block all inbound traffic type filter hook input priority filter; policy accept; ip saddr 127.0.0.0/8 counter packets 53160 bytes 3216598 drop ip6 saddr ::1 counter packets 729 bytes 58320 drop # 新增:允许本地回环的DNS响应流量 ip saddr 127.0.0.0/8 udp sport 53 accept ip saddr 127.0.0.0/8 tcp sport 53 accept #allow subnet inbound 80, 443, 8080 ip saddr SUBNET_CONTAINING_MACHINE1_AND_MACHINE2 tcp sport { 80, 443, 8080 } accept #allow my workstation inbound SSH ip saddr WORKSTATION_IP tcp dport { 22 } accept ip daddr MACHINE1_IP tcp sport { 53, 88, 389, 445, 636, 3268, 3269 } tcp dport 1-65535 accept ip daddr MACHINE1_IP udp sport { 53, 88, 389, 445, 636, 3268, 3269 } udp dport 1-65535 accept ip daddr MACHINE1_IP tcp sport 443 tcp dport 1-65535 accept log prefix "Dropped: " level debug } chain forward { type filter hook forward priority filter; policy accept; } chain output { type filter hook output priority filter; policy accept; } }
如果需要更精准的规则(仅允许127.0.0.53的DNS流量),可以替换成:
ip saddr 127.0.0.53 udp sport 53 accept ip saddr 127.0.0.53 tcp sport 53 accept
加载修改后的规则
执行以下命令重新加载nftables配置:
nft -f /etc/nftables.conf
补充说明
之前nftables日志未捕获到被拦截的DNS流量,是因为drop规则在log规则之前执行——流量被丢弃后不会触发后续的日志记录。如果需要验证拦截行为,可以临时将log规则移到drop规则之前。
内容的提问来源于stack exchange,提问作者Dylan James
相关产品推荐
相关产品推荐

