AWS帳號代充值 AWS實例無法訪問外網NAT網關配置
問題的核心:為什麼EC2突然訪問不了外網?
在AWS裡,要讓位於「私有子網」的EC2主機訪問外網,常見解法是配置NAT網關。你可能已經做了NAT、也看過路由表,按理說應該能通。但現實往往不是「做了就一定通」,而是某個細節沒有對上,導致流量根本沒走到NAT,或走到了卻被卡在安全層。
我見過最多的情況是:路由表只改了一半、NAT網關綁錯子網、或安全群組/網路ACL與預期方向不一致。還有一種較隱蔽的狀況是:看起來「連外網失敗」,其實是DNS解析失敗,應用層報錯以為是連線問題。本文會把這些可能性拆開講,並給出一套清晰的排查路線,讓你不用反覆猜。
第一章:先確認你到底要解決哪一種「不通」
AWS帳號代充值 在開始改設定前,建議先把現象說清楚。因為不同現象對應的排查方向不同:
1)無法連線到任何網站(連IP也不行)
如果連外網的IP(例如用ping或curl直接打IP)也不行,通常是網路層路由、NAT、IGW關聯、ACL/安全群組方向有問題。
2)能連IP,但不能解析域名
這是DNS問題的典型特徵。即便NAT路由正確,若DNS解析失敗,應用仍會認為外網不通。可先檢查解析服務(Route 53/本地DNS解析/在VPC設定的DNS功能)與目的地是否能走到DNS解析路徑。
3)只有特定網站或特定埠失敗
AWS帳號代充值 例如只有https(443)不行、或只有某些網段不行,可能是安全群組/ACL對埠或方向限制。也有可能是公司代理、機器時間偏差導致TLS失敗,但這屬於更上層的問題。
本篇以「私有子網EC2無法透過NAT訪問外網」為主,預設目標是能正常出站到一般網站(443/80)與DNS。
第二章:NAT網關的基本工作方式(你需要抓住的幾個關鍵點)
理解NAT的流向能大幅縮短排查時間。典型流程是:
- 私有子網EC2(有私網IP)想連外網某IP(公網)
- 它看目的地是否匹配路由表規則;若匹配「0.0.0.0/0 → NAT網關」,就把封包送到NAT
- NAT位於公有子網,對外使用公網IP轉發
- 返回封包再經由NAT回到私有子網的該EC2連線
所以只要任意一環不對:路由沒指到NAT、NAT所在子網沒有通向Internet Gateway、或者回程被ACL/安全群組攔下,就會造成「外網不可用」。
第三章:最常見的原因一覽(照著檢查會最快)
下面這些是我認為最值得先查的點,因為它們出現頻率高,而且每一項都能直接導致「無法訪問外網」。
原因1:私有子網的路由表沒有把0.0.0.0/0指向NAT網關
這幾乎是第一名。你可能建立過路由,但:
- 改錯了路由表(例如EC2所在子網使用了另一張路由表)
- 只改了某個子網,還有其他子網的EC2沒改
- NAT網關ID填錯或版本變更後沒有更新
- 存在更具體的路由覆蓋(例如某些自訂prefix路由導致0.0.0.0/0沒有生效)
檢查方法很簡單:進到VPC→Route Tables,找到EC2所在的私有子網對應的路由表,確認有一條類似:
Destination: 0.0.0.0/0 → Target: nat-xxxx
同時確認回程不需要額外路由(NAT會處理狀態追蹤),你不必為返回方向再加路由。
原因2:NAT網關放在錯誤的子網,或該子網沒有連到Internet Gateway
NAT網關必須在公有子網(Public Subnet)中,且該公有子網透過Route Table指向Internet Gateway(IGW)。常見錯誤:
- 把NAT放在私有子網(這會直接失效,因為NAT需要對外公網)
- NAT所在公有子網的路由表沒有到0.0.0.0/0 → IGW
- IGW已存在但沒有關聯到正確路由表
檢查要點:進入公有子網的路由表,確認:
Destination: 0.0.0.0/0 → Target: igw-xxxx
如果你最近有重建VPC、變更路由或新增子網,這一項特別容易漏掉。
原因3:網路ACL(NACL)沒有放行出站或回站流量
安全群組(Security Group)是狀態式的,但網路ACL(Network ACL)是非狀態式的。這意味著你必須同時確保:
- 入站與出站規則都允許需要的埠
- 回應封包的來源/目的埠也符合規則
例如你的出站允許了TCP 443,但回程規則沒有放行,那也會卡住。NACL的規則方向與檢查方式常讓人踩坑。
實務建議:若你不確定NACL,先暫時用最寬鬆策略測試(只在測試時、並在確認後恢復)。至少要包含:私有子網的NACL允許流量進出,且方向正確。
原因4:安全群組(Security Group)只允許了入站,卻忽略了出站
安全群組通常預設允許出站(Outbound allow all),但如果你在強化安全策略時改成「只允許特定目的地/埠」,就可能阻斷NAT後的回應,或者在某些情況下直接造成出站失敗。
請確認EC2的安全群組是否允許至少:
- 出站到外部的HTTP/HTTPS(80/443)
- 出站到DNS(53)—若你需要解析域名
有些環境會把DNS解析交給特定解析器(例如R53或自建Bind/Unbound),那就要允許對應解析器IP與埠。
原因5:DNS相關設定使得應用「看起來像外網不通」
很多人看到curl報錯就直接懷疑NAT,卻不查DNS。其實當DNS解析失敗時,連線程式往往不會成功發起TCP握手。
你可以從兩個方向確認:
- EC2上輸入解析指令,例如看resolv.conf內容(Linux)或nslookup/dig(若有工具)。
- 嘗試用IP直連測試:如果IP可連,但域名不行,基本就鎖定DNS。
此外,也要確認VPC層級是否啟用DNS解析與DNS主機名(DNS resolution / DNS hostnames)。AWS的預設行為與你是否自訂了DHCP options會影響結果。
原因6:目的地並非你以為的「外網」,或有自訂路由導致匹配錯誤
有時候你以為是訪問外網,但其實目標IP落在你VPC內或某個對等連線(Peering/VPN)網段。只要路由被自訂prefix覆蓋,NAT不會被用到。
例如你設了某條更精確的prefix路由指向VGW或其他目標,但實際你要走的是NAT,結果封包走偏了。檢查路由表時,不只看0.0.0.0/0,也要掃描其他prefix路由是否覆蓋了你要連的目的網段。
第四章:一個可操作的排查流程(照順序做,通常半小時內定位)
AWS帳號代充值 下面是一套我常用的排查順序。你不需要一次改所有設定,只要按順序確認每一層都能通。
AWS帳號代充值 步驟1:確認EC2真的在「私有子網」且使用對的路由表
先到EC2→實例,找到子網ID,回到VPC→Route Tables,確認該子網關聯的是你以為的那張路由表。
很多事故就發生在「你改的是A路由表,但實例其實在B路由表」。
AWS帳號代充值 步驟2:在私有子網路由表確認0.0.0.0/0指向NAT網關
確認目標是nat-xxxx(或gateway ID對應)。如果有多條0.0.0.0/0(通常不會允許),就看實際生效的規則。
同時檢查是否有更精確prefix路由覆蓋目的地。
步驟3:確認NAT網關所在公有子網的路由表通向IGW
進入NAT網關資源,查看它所在的Subnet。然後檢查該Subnet的Route Table 是否:
0.0.0.0/0 → Internet Gateway
如果你沒有看到這條,NAT就算存在也無法對外發起連線。
步驟4:檢查安全群組出站與入站(至少要覆蓋443與DNS)
對EC2實例的安全群組檢查Outbound:
- 至少允許TCP 443至0.0.0.0/0或必要範圍
- 若要解析域名,允許UDP/TCP 53到DNS解析器IP或VPC內DNS
入站通常不影響出站,但若你做了很嚴格的網路隔離,仍要確保回應路徑不會被擋。
安全群組是狀態式的,所以入站回應一般會自動放行,但當你把規則做得過度狹窄仍可能出問題。
步驟5:檢查NACL(雙向放行 + 方向一致)
到私有子網和公有子網對應的NACL規則。至少確認:
- 私有子網NACL允許出站到外部目的的埠(例如TCP 443)
- 私有子網NACL允許回程封包(來源/目的埠與規則匹配)
若你不確定如何計算回程方向,先做「最小化開放」測試:允許需要的臨時埠回來(對應TCP回應的來源埠通常是對方80/443,而目的埠是你本機的臨時埠)。
實務上,若NACL規則很多,建議先暫時將NACL調整為與安全群組一致的寬鬆策略,驗證後再回復。
步驟6:排除DNS與時間問題
若連線到IP可行但域名不行,集中檢查DNS。
若HTTPS握手失敗,可能是憑證鏈或時間不準。雖然這不一定是NAT問題,但現象會很像「外網連不上」。確認系統時間與NTP設定。
第五章:用情境快速定位(你可以對照自己的狀況)
情境A:你確認路由指向NAT,但仍無法連線
這通常表示NAT對外路徑或回程被卡住。你要回頭檢查:
- NAT所在公有子網是否有IGW路由
- 公有子網/私有子網的NACL是否阻擋
- 安全群組Outbound是否限制過嚴
AWS帳號代充值 如果這些都OK,才進一步看DNS與應用端。
情境B:curl IP可以,但curl網域名不行
這基本不是NAT路由問題。你需要檢查EC2的DNS設定:
- 解析器地址(resolv.conf)是否正確
- 是否使用自建DNS或DHCP options導致解析不可達
- 53埠是否在安全群組/ACL允許
很多人把精力放在NAT路由,結果其實只是DNS沒走出來。
情境C:只有部分埠(例如443)不通
這通常與安全群組/ACL的埠規則有關。你可以把測試目標改成不同服務,迅速判斷是TCP/UDP、還是特定埠被擋。
也可以用本機抓包或trace工具觀察是否能完成握手,但對多數環境而言,檢查規則會更快。
第六章:配置層級的檢查清單(建議你存起來)
以下是一份可直接照做的清單。你每次遇到「NAT不工作」,就從上到下確認。
路由層
- 私有子網路由表:0.0.0.0/0 → NAT網關
- AWS帳號代充值 NAT網關所在公有子網路由表:0.0.0.0/0 → Internet Gateway
- 路由表是否正確關聯到EC2所在子網
- 是否存在其他prefix路由覆蓋導致不走NAT
安全層
- EC2安全群組:Outbound至少允許TCP 443(必要時80)
- EC2安全群組:允許DNS(UDP/TCP 53)到你使用的解析器
- NACL:私有子網與公有子網的入站/出站規則雙向正確
主機與應用層
- DNS解析可用:網域名能解析到IP
- AWS帳號代充值 HTTPS握手問題:系統時間正確、證書鏈可驗證
- 代理設定:若有http_proxy/https_proxy環境變數,確認代理不可用時的行為
第七章:避免踩坑的實務建議
很多問題不是第一次設錯,而是後續變更造成。AWS環境一旦有多個團隊協作、頻繁新增子網或重建VPC,就容易產生「看起來相同但其實不一樣」的狀態。以下是幾個可降低故障率的做法:
- 把NAT相關路由寫成可追蹤的變更流程:例如在部署腳本或IaC裡集中管理,而不是手動改路由表。
- 子網與路由表命名規範化:避免「看起來一樣」的路由表被改錯。
- 對NACL保持必要的簡化:當你把NACL設得太複雜,問題出現時回溯成本高。
- 把DNS與網路測試納入日常驗證:至少定期測域名解析與一個固定的HTTPS目標。
結語:外網訪問失敗,先抓路由,再看回程與DNS
當你遇到「AWS實例無法訪問外網、NAT網關配置後仍不通」時,最有效的策略不是盲目加規則,而是按層次定位:先確認私有子網的路由表確實把流量導向NAT,再確認NAT所在公有子網能透過IGW出到Internet,接著檢查安全群組與NACL是否阻斷了回程,最後才處理DNS與應用層的問題。
只要你遵循本文的流程,通常都能在很短時間內找到是哪一個環節出了偏差。NAT不是神秘魔法,它只是在正確的路由與安全設定下,扮演把私網流量轉換成可對外連線的角色;你只要讓每一步都對上,就能恢復穩定的外網連通。

