项目场景:
为学习 network namespace 的知识,我做了一个 Linux bridge + veth的实验;
创建一个新network namespace,实现在其内部访问外部互联网。
此时我已经配置好 br0、veth0并实现veth0 可以 ping 通 ens33
多提一嘴:确保 br0 网桥的网段与 网卡ens33 的网段不同,不然你可能发现配好 br0 网桥后,无法与外网通信了;因为造成了路由表冲突,Linux 不知道从哪个接口出去,而 网桥无法与网卡一样通信,它只能转发包而已。
结构如下:
问题描述
虽然可以在内网中相互 ping 通,但在 ens33 能访问外网的条件下,veth1 却无法访问外网
原因分析:
由于自己创建配置 network namespace 、bridge、veth后,没有配置 iptables,导致数据包无法离开Linux
解决方案:
在iptables 中添加相应的规则,如下
这是一条 nat 规则,实现从 br0 出去的数据包发送到外部网络时,源 IP 地址将被替换为执行 NAT 的接口的 IP 地址。将内部网络的私有 IP 地址转换为公共 IP 地址,以便与外部网络进行通信
-s 10.10.20.0/24 : 源 IP 为 10.10.20.0/24 (br0 的网段)
-t nat : 指定 NAT 表
-A POSTROUTING : 指定 POSTROUTING 链
-j MASQUERADE : 这个操作通常用于将数据包的源地址转换为另一个地址(通常是防火墙或路由器的外部接口地址),以实现地址伪装或 SNAT。
iptables -s 10.10.20.0/24 -t nat -A POSTROUTING -j MASQUERADE
这样 新 network namespace 发出的包就能离开 Linux 完成通信
上面规则:用于源地址伪装(Source Address Masquerading,也称为 SNAT)的。这条规则将来自特定源地址范围(10.10.20.0/24)的数据包在 POSTROUTING 链上进行源地址转换。