AWS中如何通过network interface路由整个子网实现EC2网关转发
基于EC2 ENI实现子网流量网关的配置方案
可以通过EC2绑定的ENI实现整子网流量转发,你当前配置不生效是踩了VPC默认规则和系统配置的几个坑,按以下步骤排查调整即可:
核心故障原因
你目前只能收到目的地址为ENI自身IP的流量,最核心的原因是AWS默认对所有ENI开启源/目的地址校验:底层转发逻辑会直接丢弃目的IP不属于该ENI、源IP不是该ENI发出的数据包,这类数据包根本不会被送到EC2实例操作系统层面,只有目的IP是ENI自身绑定地址的流量能通过校验送达实例。
必做配置项
- 关闭ENI的源/目的检查
找到这台作为网关的EC2绑定的目标ENI,在控制台操作菜单选择「更改源/目标检查」,设置为关闭;也可以通过CLI执行命令完成配置:aws ec2 modify-network-interface-attribute --network-interface-id <你的ENI资源ID> --no-source-dest-check - 正确配置路由表关联
跨子网流量才会查询路由表,同子网内的流量默认走二层转发,不会经过三层路由条目:- 要实现其他子网访问Subnet A的流量全部经过该EC2,需要在其他所有访问源所在子网关联的路由表中,添加目标为Subnet A网段、下一跳为该EC2对应ENI的路由条目,确认路由状态为
active而非黑洞状态。 - 如果需要Subnet A主动对外访问的流量也经过该EC2,再将对应路由条目添加到Subnet A自身关联的路由表中。
- 要实现其他子网访问Subnet A的流量全部经过该EC2,需要在其他所有访问源所在子网关联的路由表中,添加目标为Subnet A网段、下一跳为该EC2对应ENI的路由条目,确认路由状态为
- 配置EC2实例本身的转发能力
数据包送达EC2后,默认操作系统不会转发目的地址非自身的数据包,需要手动开启转发:- 对于Linux实例,执行命令开启IPv4转发,临时生效执行
sysctl -w net.ipv4.ip_forward=1,永久生效需要在/etc/sysctl.conf中添加配置net.ipv4.ip_forward = 1后执行sysctl -p加载。 - 放通安全组和网络ACL:网关EC2的安全组需要放通来自源网段的入向流量、放通到Subnet A网段的出向流量;Subnet A关联的网络ACL需要放通来自网关ENI的入向流量、对应回包的出向流量。
- 避免三角路由问题:初期调试可以直接在网关EC2上配置源NAT,将跨子网转发的数据包源IP转换为网关ENI自身的IP,这样Subnet A内的资源回包会直接送达网关,不需要额外调整Subnet A内资源的路由。Linux下可通过iptables快速配置:
iptables -t nat -A POSTROUTING -d <Subnet A网段> -j MASQUERADE
- 对于Linux实例,执行命令开启IPv4转发,临时生效执行
验证方法
配置完成后,从其他子网的测试实例发起对Subnet A内非网关ENI地址的访问,同时在网关EC2上执行抓包命令:
tcpdump -i <对应网卡名> dst <Subnet A内测试IP> -nn
如果能抓到对应访问包,说明流量已经成功送达网关,再逐步排查转发、安全组规则即可实现全子网流量经该EC2转发的效果。
内容的提问来源于stack exchange,提问作者user3767974
相关产品推荐
相关产品推荐

