通过AWS VPC NAT进行端口转发

是的,我已经浏览了互联网,并阅读了大多数stream行的IPTable / DNAT指南/页面/post。

我的问题

总结我有一个VPC和几个子网。 一个子网尤其需要EIP来连接互联网。 我有一个Web服务器居住在这个子网。 我需要从nat 后面访问它(也在同一个子网中,有一个EIP)。 我正在尝试设置我的NAT,以便发送到某个端口的传入数据包发送到不同的主机(实质上我需要DNAT)

第1部分:在VPC中:

我通过我的广域网可访问的SSH代理SSH进入我的NAT实例。 这是亚马逊NAT实例附带的默认IPTables。 没有什么特别的,只是像预期的POSTROUTE规则。 NAT实例只有一个接口, eth0(和lo,但让我们假装不存在)

[root@IP_NAT ec2-user]# iptables -t nat -L --line-numbers Chain PREROUTING (policy ACCEPT) num target prot opt source destination Chain INPUT (policy ACCEPT) num target prot opt source destination Chain OUTPUT (policy ACCEPT) num target prot opt source destination Chain POSTROUTING (policy ACCEPT) num target prot opt source destination 

好。 现在让我们添加两个端口转发,这样我的web服务器可以在NAT后面访问

 [root@IP_NAT ec2-user]# iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j DNAT --to-destination IP_WEBSERVER:80 [root@IP_NAT ec2-user]# iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 443 -j DNAT --to-destination IP_WEBSERVER:443 

对! 时间检查我的工作:

 [root@IP_NAT ec2-user]# iptables -t nat -L --line-numbers Chain PREROUTING (policy ACCEPT) num target prot opt source destination 1 DNAT tcp -- anywhere anywhere tcp dpt:http to:IP_WEBSERVER:80 2 DNAT tcp -- anywhere anywhere tcp dpt:https to:IP_WEBSERVER:443 Chain INPUT (policy ACCEPT) num target prot opt source destination Chain OUTPUT (policy ACCEPT) num target prot opt source destination Chain POSTROUTING (policy ACCEPT) num target prot opt source destination 1 MASQUERADE all -- ip-10-0-0-0.us-west-1.compute.internal/16 anywhere 

所以,事情看起来他们应该工作得很好。 除了,他们不。 :(我可以用wget / telnet / ping / ssh把我的内容放在nat和web服务器之间,我可以在一些端口上telnet到我的NAT,但其他的只是超时,我已经三重检查了AWS Security Grouppipe理NAT实例允许正确的端口进出,只是为了testing,我允许所有端口上的所有stream量进出,我仍然有同样的问题。

networking服务器在任何日志上都没有显示任何活动。

以下是本地机器的一些输出结果,显示了我一整天的工作:

 LOCAL_USER@LOCAL_HOST:~$ telnet AWS_EIP 443 Trying AWS_EIP... ^C (time out, here) LOCAL_USER@LOCAL_HOST:~$ telnet AWS_EIP 80 Trying AWS_EIP... ^C (time out, here) LOCAL_USER@LOCAL_HOST:~$ telnet AWS_EIP 22 Trying AWS_EIP... Connected to AWS_EIP. Escape character is '^]'. SSH-2.0-OpenSSH_6.2 asd Protocol mismatch. Connection closed by foreign host. 

所以当我尝试在端口22上打开一个TCP连接时,事情立即起作用。 为什么我的NAT不在端口443或80上“监听”,尽pipeiptables明确允许这些端口上的stream量?

作为有用信息的最后一点,这里是sysctl.conf文件:

 [root@IP_NAT ec2-user]# cat /etc/sysctl.conf # Controls IP packet forwarding net.ipv4.ip_forward = 1 # Controls source route verification net.ipv4.conf.default.rp_filter = 0 # Do not accept source routing net.ipv4.conf.default.accept_source_route = 1 # Controls the System Request debugging functionality of the kernel kernel.sysrq = 0 # Controls whether core dumps will append the PID to the core filename. # Useful for debugging multi-threaded applications. kernel.core_uses_pid = 1 # Controls the use of TCP syncookies net.ipv4.tcp_syncookies = 1 

有什么想法,为什么数据包甚至没有到我的networking服务器?

从你问题中的信息来看,我假设你有2个EIP在使用。 一个用于NAT服务器,一个用于Web服务器。 如果是这样,那么NAT服务器和世界上的每个人都应该能够通过它的EIP连接到Web服务器,假设所有的防火墙/安全组都是正确的。

现在,我很困惑NAT服务器实际上是什么。 我假设你想让这个NAT后面的一组主机能够访问Web服务器,并且你不希望每个主机都拥有自己的EIP? 如果是这样的话,你需要两个VPC子网,NAT服务器需要做SNAT(这似乎是你在用MASQUERADE规则做的事情)。 对于此设置,请参阅http://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/VPC_NAT_Instance.html

基本要求是(而且我在之前的工作中已经完成了):

  • NAT网关服务器是必需的。 必须启用IP转发以及iptables中的MASQUERADE规则(如上所述,没有DNAT规则)。
  • 至less需要两个子网:
    • 一个“公共”子网,VPC路由表中该子网的默认路由指向Internet网关。 此子网中的所有主机都需要EIP才能访问Internet。 NAT网关服务器必须位于此子网中。
    • 一个“私有”子网,其默认路由指向NAT网关服务器。 这就是NAT隐藏的networking,就像家庭networking中的DSL路由器一样。 该子网中的所有主机将通过NAT及其EIP访问互联网(如果使用公共EIP地址代替其私有RFC1918地址,则位于公有子网中的主机)。

最后,如果你想避免给Web服务器一个EIP,那么我会尝试的一件事(尽pipe我没有亲自testing过)是将Web服务器移动到私有子网中,并且改变你的DNAT规则来指向它的内部地址。 显然,VPC子网,路由等需要根据上面的AWS文档进行configuration。

 [root@IP_NAT ec2-user]# iptables -t nat -L --line-numbers Chain PREROUTING (policy ACCEPT) num target prot opt source destination 1 DNAT tcp -- anywhere anywhere tcp dpt:http to:IP_WEBSERVER:80 2 DNAT tcp -- anywhere anywhere tcp dpt:https to:IP_WEBSERVER:443 Chain INPUT (policy ACCEPT) num target prot opt source destination Chain OUTPUT (policy ACCEPT) num target prot opt source destination Chain POSTROUTING (policy ACCEPT) num target prot opt source destination 1 MASQUERADE all -- ip-10-0-0-0.us-west-1.compute.internal/16 anywhere 

回答

对于未来遇到此问题的人:确保您的安全组允许您重新访问正确的公共IP。 我进入了传入IP的CIDR范围,这对我来说使用上面所有相同的configuration。 注意:您的networking应用程序或NAT实例的公共IP将不会与通过nestat发现它的IP相同。