回答

回答

是的,我已经搜索了互联网并阅读了大多数流行的 IPTables/DNAT 指南/页面/帖子。

我的问题

概括 我有一个包含多个子网的 VPC。其中一个子网特别需要 EIP 才能连接互联网。我有一个 Web 服务器位于此子网中。我需要从在后面一个 nat(也在同一个子网中,有一个 EIP)。我试图设置我的 NAT,以便传入发往某个端口的数据包被发送到不同的主机(本质上我需要 DNAT)

第 1 部分:在 VPC 中:

我已通过 WAN 可访问的 SSH 代理通过 SSH 连接到我的 NAT 实例。这是 amazon 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  

所以,一切看起来应该可以正常工作。但事实并非如此。:(。我可以在 nat 和 web 服务器之间随心所欲地使用 wget / telnet / ping / ssh。我可以在一些端口连接到我的 NAT,但其他端口只是超时。我有三倍检查管理 NAT 实例的 AWS 安全组是否允许正确的端口进出。出于测试目的,我允许全部所有端口的进出流量。我仍然遇到同样的问题。

网络服务器在其任何日志上均未显示任何活动。

以下是我的一些输出当地的机器显示了整天困扰我的事情:

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,尽管 iptables 明确允许这些端口上的流量?

最后一点有用的信息是 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

有没有想过为什么数据包甚至没有到达我的网络服务器?

答案1

根据您问题中的信息,我假设您使用了 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 规则)。
  • 至少需要两个子网:
    • 一个“公共”子网,该子网在 VPC 路由表中的默认路由指向 Internet 网关。此子网中的所有主机都需要 EIP 才能访问 Internet。NAT 网关服务器必须位于此子网中。
    • 一个“私有”子网,其默认路由指向 NAT 网关服务器。这是被 NAT 隐藏的网络,很像家庭网络中的 DSL 路由器。该子网中的所有主机都将通过 NAT 及其 EIP 访问互联网(或公共子网中的主机,如果使用公共 EIP 地址而不是其私有 RFC1918 地址)。

最后,如果您想避免为 Web 服务器提供 EIP,那么我会尝试的一件事(尽管我还没有亲自测试过)是将 Web 服务器移到私有子网中,并更改 DNAT 规则以指向其内部地址。显然,需要根据上述 AWS 文档配置 VPC 子网、路由等。

答案2

[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 范围,这对我来说有效,使用上面所有的相同配置。注意:您的 Web 应用程序或 nat 实例的公共 IP 将与我通过 nestat 找到的返回 IP 不同。

相关内容