概述

阿里云 VPC 环境中如何通过 ECS 绑定 EIP 实现 SNAT 和 DNAT 功能,以下步骤分两种功能(SNAT 和 DNAT)的应用场景分别介绍

实现 SNAT

同一 VPC 下存在多台 ECS 实例,对其中 1 台进行绑定 EIP 后,另外的 ECS 通过绑定 EIP 的 ECS 实例进行访问外网。

1、绑定同一 VPC 下的其中 1 台 ECS 实例。
2、使用 SSH 终端工具,如 Xshell 等,执行以下命令,登录绑定 EIP 的 ECS 实例。
3、开启系统的 IP 转发功能。

  1. sed -i 's/net.ipv4.ip_forward = 0/net.ipv4.ip_forward = 1/g' /etc/sysctl.conf
  2. sysctl -p

4、执行以下命令,实现 SNAT 转换。

  1. iptables -t nat -I POSTROUTING -s [$Intranet_CIDR] -j SNAT --to-source [$Intranet_IP]

说明:

  • [$Intranet_CIDR] 为内网网段,例如:172.16.X.0/24。
  • [$Intranet_IP] 为绑定 EIP 的 ECS 实例的内网 IP 地址。

5、登录专有网络控制台,选择 vpc,选择交换机,添加目标网段为 0.0.0.0/0 的路由。

自建 nat 及规则不生效问题排查 - 图1说明:下一跳 ECS 实例,选择绑定 EIP 的 ECS 实例。

6、登录转发机执行命令查看规则

  1. iptables -nL -t nat

自建 nat 及规则不生效问题排查 - 图2

7、目标机执行以下命令,确认实例可以访问外网

  1. ping baidu.com

实现 DNAT

通过映射后端服务,提供外部访问,请参考以下步骤执行:

1、如何绑定 EIP 并开启 IP 转发功能,请参考实现 snat 的前三步。
2、执行以下命令,实现 DNAT 转换。

  1. iptables -t nat -I PREROUTING -p tcp --dport 80 -j DNAT --to [$Destination_IP]

说明:[$Destination_IP] 为需要转发到请求的目的 IP 地址,非绑定 EIP 的 ECS 实例 IP。

3、登录转发到的 ECS 实例,执行以下命令,让转发的数据包实现 “双向通路”。

  1. iptables -t nat -I POSTROUTING -p tcp --dport 80 -j MASQUERADE

自建 SNAT 策略后网络不通

问题原因

  • 没有开启内核路由转发。
  • VPC 上的 VRoute 路由配置问题。
  • timestamps 的原因。
  • 安全组的原因。
  • SNAT 网关上 IPtables FORWARD 链的问题。
  • MTU 的问题。

解决方案

没有开启内核路由转发

在网关上开启 ip_forward 后,到达网关的请求才会被 iptables 转发出去。所以一定要先开启 ip_forward。执行如下命令,如果返回 1 说明已开启。

  1. more /proc/sys/net/ipv4/ip_forward

自建 nat 及规则不生效问题排查 - 图3

VPC 上的 VRoute 路由配置问题

自建 SNAT 策略后,在网络访问过程中,先由客户端 ECS 发起请求,然后需要把这个请求转发到网关的 ECS 上。所以需要在 VPC 上的 VRoute 上配置相应的路由指向到这台网关的 ECS 上。如下图所示。

自建 nat 及规则不生效问题排查 - 图4

timestamps 的原因

根据 tcp_timestamps 选项的特性。

  • 当 Server 端 tcp_tw_recycle 和 tcp_timestamps 的值都是 1 的时候,在 60 秒内检查收到数据包 TCP 选项字段中的 timestamp 值。
  • 当同一个 IP 地址后来的数据包中 TCP 选项字段如果有 timestamp,且比前面的数据包中的 timestamp 小,则 Server 不做 ACK 响应。

所以会造成 Ping 正常。Telnet 端口不通的现象。并且是同个 SNAT 作用域下,部分机器能通,部分机器不通。

解决办法如下所示:

  • 客户端关闭 tcp_timestamps。
  • 服务端关闭 tcp_tw_recycle。

根据实际情况关闭其中一端即可,无需服务端和客户端同时关闭。

安全组的原因

自建 SNAT 策略的网关是通过 ECS 搭建,所有客户端 ECS 的请求会到达该网关 ECS 上,所以要保证客户端 ECS 和网关 ECS 之间网络通信正常。因此在 ECS 层面,如果不在同个安全组下,需要安全组之间互相打通。如:

自建 nat 及规则不生效问题排查 - 图5

SNAT 网关上 iptables 的 FORWARD 链的问题

iptables 的内部的转发原理,如下图所示。

自建 nat 及规则不生效问题排查 - 图6根据该图可得如下结论:

  • 当一个数据包进入网卡时,数据包首先进入 PREROUTING 链,在 PREROUTING 链中可以修改数据包的目的 IP,然后内核的路由模块根据数据包目的 IP 以及内核中的路由表判断是否需要转送出去。
  • 如果数据包的目的 IP 是本机的网口 IP,数据包就会到达 INPUT 链。数据包到达 INPUT 链后,任何进程都会收到它。
  • 本机上运行的程序也可以发送数据包,这些数据包经过 OUTPUT 链,然后到达 POSTROTING 链输出。
  • 如果数据包的目的 IP 地址不在当前子网中,且内核允许转发,数据包就会向右移动,经过 FORWARD 链,然后到达 POSTROUTING 链输出。

所以在网关上的 iptales 的 FORWARD 链尽量默认允许访问。

MTU 的问题

在某些情况下,如果客户端 ECS 和网关 ECS 对 MTU 设置不同,也可能会出现网络不通的情况。所以请保证两端 MTU 的值一致。

适用于

  • VPC 专有网络