通過 AWS VPC NAT 進行埠轉發
是的,我已經在網際網路上搜尋並閱讀了大多數流行的 IPTables/DNAT 指南/頁面/文章。
我的問題
總結 我有一個帶有多個子網的 VPC。一個子網尤其需要一個 EIP 來連接網際網路。我在這個子網中有一個 Web 伺服器。我需要從nat後面訪問它(也在同一個子網中,有一個 EIP)。我正在嘗試設置我的 NAT,以便將發往某個埠的傳入數據包發送到不同的主機(本質上我需要 DNAT)
第 1 部分:在 VPC 中:
我已經通過我的 WAN 可訪問 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
行。現在讓我們添加兩個埠轉發,以便可以在 NAT 後面訪問我的 Web 伺服器
[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 伺服器之間的心的內容。我可以在一些埠上遠端登錄到我的 NAT,但其他埠只是超時。我已經三次檢查了 AWS 安全組管理 NAT 實例允許正確的埠進出。只是為了測試,我允許所有埠上的所有流量都進出。我仍然有同樣的問題。
網路伺服器在它的任何日誌上都沒有顯示任何活動。
這是我本地機器的一些輸出,顯示了整天困擾我的事情:
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
關於為什麼數據包甚至無法到達我的網路伺服器的任何想法?
根據您問題中的資訊,我假設您有 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 訪問 Internet(如果使用公共 EIP 地址而不是其私有 RFC1918 地址,則為公共子網中的主機)。
最後,如果您想避免為 Web 伺服器提供 EIP,那麼我會嘗試的一件事(儘管我沒有親自測試過)是將 Web 伺服器移動到私有子網並更改您的 DNAT 規則以指向其內部地址。顯然,VPC 子網、路由等需要根據上面的 AWS 文件進行配置。