AWS VPC + IPtables + NAT:端口转发不起作用

sla*_*fer 10 linux nat iptables linux-networking amazon-vpc

昨天,我在这里发布了一个问题但我认为我的话不够清楚。顺便说一句,这个问题不是重复的。

我有如下 AWS VPC 设置。

在此处输入图片说明

目标/问题:从 Internet SSH 到服务器 A。它不工作。

服务器 A 在私有子网中,因此我想在我的 NAT 实例上启用 iptables NATing,以便我可以直接从 Internet ssh 到服务器 A

我正在关注这个这个

我在 NAT 实例上运行以下命令:

NAT# iptables -t nat -A PREROUTING  -p tcp --dport 2222 -j DNAT --to-destination 10.0.1.243:22
Run Code Online (Sandbox Code Playgroud)

在 NAT 实例上启用 IP 转发:

NAT# sysctl  -p
net.ipv4.ip_forward = 1
Run Code Online (Sandbox Code Playgroud)

MASQUERADE 正在 NAT 实例上运行:

NAT# iptables -t nat -vnL POSTROUTING
Chain POSTROUTING (policy ACCEPT 6 packets, 312 bytes)
 pkts bytes target     prot opt in     out     source               destination
  199 16466 MASQUERADE  all  --  *      eth0    10.0.0.0/16          0.0.0.0/0
Run Code Online (Sandbox Code Playgroud)

AWS 安全组配置良好,以允许此测试用例所需的各种访问。

故障排除:

我可以在端口 22 上从 NAT telnet 到服务器 A。所以访问很好。

当我telnet 54.213.116.251 2222在笔记本电脑上运行时,我在 NAT 上的 tcpdump 中看到以下条目:

NAT# tcpdump -n -i eth0 dst 10.0.1.243 and port 22
09:59:13.738316 IP xxx.xxx.xxx.xxx.51709 > 10.0.1.243.ssh: Flags [S], seq 1868541786, win 8192, options [mss 1460,nop,wscale 2,nop,nop,sackOK], length 0
09:59:16.737009 IP xxx.xxx.xxx.xxx.51709 > 10.0.1.243.ssh: Flags [S], seq 1868541786, win 8192, options [mss 1460,nop,wscale 2,nop,nop,sackOK], length 0
09:59:22.775567 IP xxx.xxx.xxx.xxx.51709 > 10.0.1.243.ssh: Flags [S], seq 1868541786, win 8192, options [mss 1460,nop,nop,sackOK], length 0
Run Code Online (Sandbox Code Playgroud)

所以这意味着 iptables 正在将数据包路由到10.0.1.243. (顺便说一句,xxx.xxx.xxx.xxx是我笔记本电脑的公共 IP 地址)

但是当我在服务器 A 上运行 tcpdump 时,我没有看到任何来自10.0.0.54NAT 的内部/私有 IP 地址的内容(我认为这就是问题所在):

Server A# tcpdump  -n src 10.0.0.54
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes 
Run Code Online (Sandbox Code Playgroud)

但是,如果我从 NAT 实例 telnet 到服务器 A,我会在服务器 A 上的 tcpdump 中看到好东西(这意味着,我的整体PREROUTING规则没有按预期工作):

Server A# tcpdump  -n src 10.0.0.54
05:01:47.500080 IP 10.0.0.54.44627 > 10.0.1.243.ssh: Flags [S], seq 2862522431, win 14600, options [mss 1460,sackOK,TS val 3013083 ecr 0,nop,wscale 7], length 0
05:01:47.501601 IP 10.0.0.54.44627 > 10.0.1.243.ssh: Flags [.], ack 760676524, win 115, options [nop,nop,TS val 3013083 ecr 12074896], length 0
05:01:47.535720 IP 10.0.0.54.44627 > 10.0.1.243.ssh: Flags [.], ack 22, win 115, options [nop,nop,TS val 3013092 ecr 12074928], length 0
Run Code Online (Sandbox Code Playgroud)

结论:

从 NAT 上的 tcpdump 输出来看,Iptables 似乎可以很好地转发我的数据包。

从服务器 A 上的 TCP 转储,我从 NAT 到服务器 A 的连接良好。

但是在端到端中,我无法从我的笔记本电脑连接到服务器 A。

顺便说一句,我知道 SSH 隧道和其他好东西。但我只需要 Iptables 来帮助我。

sla*_*fer 8

最后,我破解了它!!!!

在 NAT 实例上,我必须更改以下命令:

从:

iptables -t nat -A POSTROUTING -o eth0 -s 10.0.0.0/16 -j MASQUERADE
Run Code Online (Sandbox Code Playgroud)

到:

iptables -t nat -A POSTROUTING -j MASQUERADE
Run Code Online (Sandbox Code Playgroud)

它奏效了!!!!

因此,我将很快在 ServerFault 上创建一个新问题,询问使用上述两个命令的优缺点。


c4u*_*elf 7

  • 确保您允许 tcp 端口22220.0.0.0/0您的 nat 框的安全组传入
  • 确保您的 VPC“路由表”设置正确。
  • 至少两个单独的表(一个与私有子网关联,一个与公共子网关联)
  • 您的10.0.1.0(私有)子网应该有一个路由表规则,如: Destination: 0.0.0.0/0, Target: "Nat box"
  • 您的10.0.0.0(公共)子网应该有一个路由表规则,如: Destination: 0.0.0.0/0, Target: "Internet gateway"
  • 确保您在 NAT 盒的 NIC 上禁用了源/目标检查,没有它就没有 NAT 乐趣。(我知道你已经有了这个,但它真的很重要,所以包括它给未来的观众)

  • 确保出站数据包知道去哪里:

    iptables --table nat --append POSTROUTING --source 10.0.0.0/16 --destination 0.0.0.0/0 --jump MASQUERADE

  • 确保入站数据包2222正确重新路由:

    iptables --table nat --append PREROUTING --protocol tcp --dport 2222 --jump DNAT --to-destination 10.0.1.243:22