💡 先搞懂問題
虛構公司「青松物流」的工程師第一次在 AWS 開了一台 EC2 放訂單查詢網站。他直接用了每個區域都附的預設 VPC(default VPC),精靈建立的安全群組還把 SSH(TCP 22)開給了 0.0.0.0/0,也就是整個網際網路。後來資安顧問建議三件事:網站主機和資料庫分到不同的子網路、資料庫不能有對外的路、在網站的子網路加一道網路 ACL,把一直來掃描的某段 IP 擋掉。他照著做完,網站卻整個打不開了。網路 ACL 明明寫了「允許 TCP 443」,安全群組也允許 443,問題出在哪?
先把名詞對齊。Amazon VPC(Virtual Private Cloud)是你在一個區域(Region)裡擁有的私人網路,建立時給一段 IPv4 CIDR,例如 10.0.0.0/16,再切成數個子網路(subnet),每個子網路固定在一個可用區域(Availability Zone,AZ)。子網路的封包要往哪裡送,由路由表(route table)決定:路由表裡有一條 0.0.0.0/0 指向網際網路閘道(internet gateway)的,就是公有子網路;沒有的就是私有子網路。私有子網路的主機要連出去下載更新,得透過放在公有子網路裡的 NAT 閘道(NAT gateway),它只讓裡面的人連出去,外面的人連不進來。
流量過濾有兩道關卡。網路 ACL(network ACL)掛在子網路上,所有進出這個子網路的封包都要經過它;安全群組(security group)掛在執行個體(instance)的網路介面(ENI)上,像每台主機自己的防火牆。兩道關卡的比對規則完全不同,這正是新手最常卡住的地方:以為網路 ACL 和安全群組一樣會記得「這條連線剛才允許過」,結果回應封包被擋;以為安全群組可以寫拒絕規則,其實它只有允許;以為「公有子網路」是建立時勾的選項,其實是路由表決定的;切子網路時也常忘記 AWS 會在每個子網路先保留 5 個位址。
生活比喻:有大廳管理員和電子鎖的社區大樓
青松社區有圍牆和一套門牌編號規則,社區裡分成幾棟樓,每一棟蓋在固定的街區上。社區只有一個大門通往大馬路;每棟樓一樓有路標,寫著「往外縣市請走大門」或「寄信請交給代寄處」。A 棟的路標指向大門,所以 A 棟住戶可以直接出入;B 棟的路標只指向代寄處,B 棟住戶可以把信寄出去、也收得到回信,但陌生人沒辦法直接找上門。
每棟樓的大廳坐著一位管理員,手上一本編號名冊:「第 90 條:192.0.2 開頭的車牌一律不准進」「第 100 條:送貨到 443 號櫃台的可以進」……管理員從最小的編號往下對,對到就照做,不會再往下看;名冊最後一行印著「其餘一律不准」。這位管理員有個特點:他不記人。你剛才進門時登記過,出門時他還是要再翻一次名冊,而且出門用的是另一本「出門名冊」。每戶門口則裝著電子鎖,鎖裡只存「可以開門的人」,沒有黑名單;但它記得剛才是誰開門進來,同一個人要離開時不必再刷一次。
這個比喻有四個地方和實際不同。第一,電子鎖的名單除了寫 IP 範圍,還可以寫「某某公司的員工都能進」,也就是把另一個安全群組當成來源,例如資料庫只允許「網站層安全群組」的主機連 3306,網站主機增減都不必改規則;網路 ACL 就只認 IP 範圍。第二,真實的管理員也許會看你的包包,網路 ACL 和安全群組都只看 IP、通訊協定與連接埠,不看封包內容,擋 SQL 注入那類攻擊是 AWS WAF 的工作。第三,社區大門對所有住戶開放,但網際網路閘道只替有公有 IP 或 Elastic IP 的資源轉換位址,就算放在公有子網路,沒有公有 IP 的執行個體一樣出不去。第四,也是青松物流卡住的地方:比喻裡「出門時管理員要再翻一次名冊」,對應的是回應封包。回應封包的目的連接埠不是 443,而是用戶端當初隨機挑的一個臨時連接埠(ephemeral port,也有人譯作暫時連接埠),通常落在 1024~65535 之間。出門名冊如果只寫「443 可以通過」,回應封包就會一路落到最後的 * 規則被拒絕。
🎮 互動實驗室一:網路 ACL+安全群組封包模擬器
情境:青松物流的網站主機 web01(私人 IP 10.0.0.25,另有公有 IP)放在公有子網路 10.0.0.0/24。子網路關聯了一個自訂網路 ACL,web01 套用一個安全群組。選好連線類型、對方、通訊協定與連接埠後按「送出連線」,畫面會先跑去程、再跑回程:網路 ACL 依規則編號一條一條比對、第一條符合就停;安全群組則所有規則一起看,回程封包因為有狀態直接放行。你可以改規則編號、刪除或新增規則,也可以切換成預設網路 ACL 或新建的自訂網路 ACL,看下方四個任務是否全部達成。
① 網路 ACL:acl-web(子網路層)
無狀態:進、出各一份規則表,依編號由小到大比對,第一條符合就停;最後的 * 拒絕其餘流量。
入站規則 進入子網路的封包
出站規則 離開子網路的封包
② 安全群組:sg-web(web01 的網路介面)
有狀態:只有允許規則,所有規則一起看,任一條符合就允許;已允許連線的回應自動放行。
入站規則 沒寫到的一律拒絕
出站規則 新建時預設允許全部
🎮 互動實驗室二:子網路規劃與路由計算器
左邊先輸入 VPC 的 CIDR、子網路的前置長度(/16~/28)和要用幾個 AZ,計算器會像主控台的「VPC 及更多」一樣,替每個 AZ 切一個公有子網路和一個私有子網路,算出每個子網路的位址總數、AWS 保留的 5 個位址與可用數量。接著調整下方的路由設定:網際網路閘道有沒有連接、公有與私有路由表的 0.0.0.0/0 指向哪裡、NAT 閘道放在哪裡。右邊會逐一判斷每個子網路實際上是公有還是私有、能不能連出網際網路,以及外面能不能連進來。可以先按「常見錯誤」看看錯誤長什麼樣子。
一、位址規劃
二、路由設定
三、子網路與連線判斷
🛠️ 操作教學:建立 VPC、子網路與安全群組
跟著 8 個步驟,在左邊的示意主控台用「VPC 及更多」替青松物流建立 VPC、公有與私有子網路、網際網路閘道、NAT 閘道與路由表,再建立網站用的安全群組和一條入站規則。你填的名稱、區域、CIDR 與規則會即時反映到右邊的 AWS CLI 與 CloudFormation;目前步驟對應的那幾行以黃色底標示。填錯時畫面會說明原因,修正後才能進到下一步。
自己動手時要注意
權限:執行的 IAM 身分要能建立 VPC 元件,例如 AWS 受管政策 AmazonVPCFullAccess,或至少包含 ec2:CreateVpc、ec2:CreateSubnet、ec2:CreateInternetGateway、ec2:CreateRouteTable、ec2:CreateNatGateway、ec2:AllocateAddress、ec2:CreateSecurityGroup、ec2:AuthorizeSecurityGroupIngress 等動作;用 CloudFormation 部署還需要 cloudformation:CreateStack 等權限。正式環境請依最小權限原則另外設計政策,不要拿管理員權限練習。
費用:VPC、子網路、路由表、網際網路閘道、安全群組與網路 ACL 本身不收費,S3 閘道端點也不收費。會產生費用的是 NAT 閘道(依存在的小時數加上處理的資料量),以及公有 IPv4 位址:2024-02-01 起,不論使用中或閒置的公有 IPv4(包含 NAT 閘道用的 Elastic IP)都依小時計費。2025-07-15 以後建立的帳戶採抵用金制的 Free Tier,練習產生的費用會先從抵用金扣;選擇免費方案(Free account plan)的帳戶,抵用金用完或滿 6 個月就會關閉(查證日期 2026-10-07)。練習完請馬上刪除 NAT 閘道並釋放 Elastic IP。
收尾:用 CloudFormation 建立的,刪除堆疊就會刪除它建立的所有資源;用 CLI 建立的,要先刪 NAT 閘道並釋放 Elastic IP,再依序刪除端點、安全群組、子網路、路由表,卸離並刪除網際網路閘道,最後刪除 VPC。在主控台刪除 VPC 時,子網路、安全群組、網路 ACL、路由表、網際網路閘道與閘道端點會一起刪除,但 NAT 閘道、執行個體、負載平衡器與介面端點要先自己刪掉。
# 方法一:CloudFormation 建立的,刪除堆疊即可(無法復原,確認名稱再執行)
aws cloudformation delete-stack --stack-name qingsong-network
# 方法二:CLI 建立的,依序刪除(ID 換成自己的值)
aws ec2 delete-nat-gateway --nat-gateway-id nat-0123456789abcdef0
aws ec2 wait nat-gateway-deleted --nat-gateway-ids nat-0123456789abcdef0
aws ec2 release-address --allocation-id eipalloc-0123456789abcdef0
aws ec2 delete-vpc-endpoints --vpc-endpoint-ids vpce-0123456789abcdef0
aws ec2 delete-security-group --group-id sg-0123456789abcdef0
aws ec2 delete-subnet --subnet-id subnet-0123456789abcdef0
aws ec2 delete-route-table --route-table-id rtb-0123456789abcdef0
aws ec2 detach-internet-gateway --internet-gateway-id igw-0123456789abcdef0 --vpc-id vpc-0123456789abcdef0
aws ec2 delete-internet-gateway --internet-gateway-id igw-0123456789abcdef0
aws ec2 delete-vpc --vpc-id vpc-0123456789abcdef0
範例裡沒有任何存取金鑰、密碼或帳戶 ID。用 CLI 前先以 aws configure sso(IAM Identity Center)或 aws configure 設定好身分,再用 aws sts get-caller-identity 確認目前是哪個帳戶;畫面上的 vpc-0123…、sg-0123… 都是佔位字,請換成實際建立後取得的 ID,也不要把自己的帳戶 ID 貼到公開的地方。
📘 原理補完
VPC 與子網路:先把位址規劃好
VPC 屬於單一區域,可以涵蓋該區域的所有 AZ;子網路則只屬於一個 AZ,建立後不能搬。建立 VPC 時要給一段 IPv4 CIDR,大小介於 /16 到 /28,之後還可以加次要 CIDR 或 IPv6,但使用中的 CIDR 不能直接縮小或更改。官方建議使用 RFC 1918 的私人範圍(10.0.0.0/8、172.16.0.0/12、192.168.0.0/16),而且不要和地端網路或日後要互連的 VPC 重疊,否則 VPC 對等互連或 Transit Gateway 都會卡住。預設配額是每個區域 5 個 VPC、每個 VPC 200 個子網路,都可以申請調高。
每個 IPv4 子網路 AWS 保留 5 個位址:第一個是網路位址;第二個給 VPC 路由器;第三個保留給 DNS(Amazon 提供的 DNS 伺服器位址是 VPC 網段的基底加二);第四個保留給未來使用;最後一個是網路廣播位址,VPC 不支援廣播,所以 AWS 保留它。子網路大小同樣介於 /16 到 /28,所以 /24 可用 256 − 5 = 251 個,/28 只剩 11 個。實驗室二的計算就是 2(32−n) − 5。
路由表決定公有或私有
每張路由表都有一條不能刪除的 local 路由,讓 VPC 內所有子網路互通;每個子網路一定關聯一張路由表,沒有明確關聯的就用主路由表(main route table)。一個子網路只能關聯一張路由表,一張路由表可以給多個子網路用。比對時採最長前綴優先(longest prefix match),例如同時有 10.0.0.0/16 local 與 0.0.0.0/0 → igw,往 10.0.128.15 的封包會走 local。
所謂公有子網路,就是它的路由表有一條 0.0.0.0/0 指向網際網路閘道。網際網路閘道是水平擴展、高可用的元件,本身不收費,一個 VPC 只能連接一個;它替有公有 IPv4 或 Elastic IP 的資源做位址轉換,沒有公有 IP 的執行個體就算放在公有子網路也出不去。私有子網路要連出去,路由表把 0.0.0.0/0 指向 NAT 閘道,而公有 NAT 閘道必須放在公有子網路並綁定 Elastic IP,它自己再經由網際網路閘道出去。傳統的 NAT 閘道是區域型(zonal),只在所在的 AZ 內有備援,多個 AZ 共用一個時,那個 AZ 故障會讓其他 AZ 的私有子網路一起斷線,所以建議每個 AZ 各放一個;2025-11 起另有區域可用性模式(regional availability mode)的 NAT 閘道,會依工作負載自動延伸到各 AZ。私有子網路只是要存取 S3 或 DynamoDB 時,用免費的閘道端點就好,不必經過 NAT 閘道。
網路 ACL:編號順序、無狀態與臨時連接埠
網路 ACL 的每條規則有編號(1~32766)、通訊協定、連接埠範圍、來源或目的地 CIDR,以及允許或拒絕。AWS 從最小的編號開始比對,封包符合某條規則就套用並停止,後面的規則不再評估;每個網路 ACL 都有一條編號為 * 的規則,不能刪除,任何封包沒有對到編號規則時就被它拒絕。入站與出站是兩份獨立的規則表,預設上限每個方向 20 條,可以申請調高。
每個 VPC 都附一個預設網路 ACL,它的入站與出站規則 100 都是允許全部流量,所以新子網路一開始不會被網路 ACL 擋。你自己建立的網路 ACL 則一開始只有 * 規則,拒絕全部,關聯到子網路的那一刻,這個子網路的進出流量就全停了,必須自己加允許規則。每個子網路同時只能關聯一個網路 ACL,一個網路 ACL 可以給多個子網路用;沒有明確關聯的子網路自動使用預設網路 ACL。
無狀態是網路 ACL 最常讓人踩雷的地方。一條 TCP 連線的回程封包,目的連接埠是發起端隨機挑的臨時連接埠,範圍依作業系統而定。AWS 文件列出的範圍是:Linux 核心(包含 Amazon Linux)32768~61000、Windows Server 2008 以後 49152~65535、Elastic Load Balancing、NAT 閘道與 Lambda 都是 1024~65535(查證時間 2026 年 10 月)。因為公開網站的用戶端什麼系統都有,官方建議實務上開 1024~65535,若要擋這段範圍裡的特定連接埠,就在前面加編號更小的拒絕規則。方向也別弄反:外面連進來時,回應走的是出站規則的臨時連接埠;你的執行個體主動連出去時(例如下載更新),回應走的是入站規則的臨時連接埠。
安全群組:有狀態、只允許、可以參照別的安全群組
安全群組套用在網路介面上,一個網路介面預設最多 5 個安全群組,每個安全群組的入站與出站規則預設各 60 條(都可調整)。規則只有允許,沒有拒絕:所有規則一起評估,任何一條符合就放行,沒寫到的一律拒絕,所以「規則順序」對安全群組沒有意義。新建立的安全群組沒有任何入站規則、出站則允許全部流量;每個 VPC 的預設安全群組(default security group)則允許「同一個安全群組裡的資源」彼此連線。安全群組不會過濾往 Amazon DNS、DHCP、執行個體中繼資料等特定流量。
安全群組最好用的地方,是規則的來源可以寫另一個安全群組。三層式網站可以這樣寫:負載平衡器的安全群組允許 0.0.0.0/0 的 443;網站主機的安全群組只允許「負載平衡器安全群組」的 8080;資料庫的安全群組只允許「網站主機安全群組」的 3306。Auto Scaling 加減主機時,IP 怎麼變都不用改規則。名稱方面,安全群組名稱在 VPC 內不可重複、最多 255 個字元、不能以 sg- 開頭;名稱與描述只能用英數字、空格和 ._-:/()#,@[]+=&;{}!$* 這些符號,中文不能用,操作教學會檢查這一點。
| 比較項目 | 安全群組(security group) | 網路 ACL(network ACL) |
|---|---|---|
| 套用位置 | 網路介面(執行個體、負載平衡器、端點等) | 子網路,所有進出子網路的流量 |
| 狀態 | 有狀態:允許的連線,回應自動放行 | 無狀態:進、出分開比對,回應要放行臨時連接埠 |
| 規則種類 | 只有允許 | 允許與拒絕 |
| 評估方式 | 所有規則一起看,任一條符合就允許 | 依編號 1~32766 由小到大,第一條符合就停,最後 * 拒絕 |
| 來源寫法 | CIDR、前綴清單、另一個安全群組 | 只有 CIDR |
| 新建時的預設 | 沒有入站規則、出站全部允許 | 預設網路 ACL 全部允許;自建的全部拒絕 |
| 數量 | 每個網路介面預設 5 個 | 每個子網路同時只能 1 個 |
管理連線:不要把 SSH、RDP 開給 0.0.0.0/0
青松物流一開始的安全群組把 SSH 開給整個網際網路,這等於讓全世界的掃描程式都能來嘗試登入,唯一的防線只剩金鑰或密碼。比較好的做法有兩種。AWS Systems Manager Session Manager:執行個體上跑 SSM Agent(Amazon Linux 等官方 AMI 已預先安裝),掛上包含 AmazonSSMManagedInstanceCore 權限的 IAM 角色,Agent 會主動用 HTTPS 443 連出到 Systems Manager(經由 NAT 閘道或介面端點),管理員從主控台或 CLI 開啟工作階段,執行個體完全不需要入站規則,工作階段還能記錄到 CloudWatch Logs 或 S3。EC2 Instance Connect Endpoint:在 VPC 的子網路建立一個端點,讓沒有公有 IP 的執行個體也能用 SSH 或 RDP 連線,執行個體的安全群組只需要允許來自端點安全群組的 22 或 3389,誰能連線由 IAM 控制。
相似功能怎麼分
| 功能 | 解決什麼問題 | 判斷依據 | 位置與費用 |
|---|---|---|---|
| 安全群組 | 每個資源的允許清單 | IP、連接埠、通訊協定;可參照其他安全群組;有狀態 | 網路介面;不另收費 |
| 網路 ACL | 整個子網路的允許/拒絕 | 只認 CIDR;可拒絕特定 IP 範圍;無狀態 | 子網路;不另收費 |
| AWS WAF | 擋 SQL 注入、XSS、惡意機器人 | 看 HTTP 請求內容(第 7 層) | 掛在 ALB、CloudFront、API Gateway 等;另計費 |
| AWS Network Firewall | 集中檢查 VPC 進出流量 | 有狀態檢查、網域名稱過濾、入侵防禦規則 | 專用子網路與路由導流;另計費 |
| VPC 流量日誌 | 事後查是誰被擋、誰被放行 | 記錄 ACCEPT/REJECT 等中繼資料,不擋流量 | VPC、子網路或網路介面;依日誌用量計費 |
| VPC 端點 | 不經網際網路存取 AWS 服務 | 閘道端點(S3、DynamoDB,免費)或介面端點(PrivateLink,收費) | 路由表或子網路中的網路介面 |
判斷步驟
- 先畫出流量方向:誰發起連線、從網際網路還是從 VPC 內部、目的連接埠是多少,回程的目的連接埠是哪個臨時連接埠。
- 看路由:來源子網路的路由表有沒有往目的地的路;要上網的公有子網路有沒有 0.0.0.0/0 → 網際網路閘道、執行個體有沒有公有 IP;私有子網路是不是指向放在公有子網路的 NAT 閘道。
- 進子網路時先比網路 ACL 入站規則(依編號、第一條符合就停),再比安全群組入站規則(全部一起看)。
- 回程離開子網路時,安全群組自動放行,網路 ACL 出站規則要另外允許對方的臨時連接埠;主動連出的情境則反過來,入站規則要允許臨時連接埠。
- 還是不通,就開 VPC 流量日誌看 REJECT 紀錄,或用 VPC Reachability Analyzer 分析兩端之間的路徑卡在哪一個元件。
容易考錯的地方
安全群組不能拒絕:題目要「封鎖某段惡意 IP」時,答案是網路 ACL 的拒絕規則,不是安全群組。干擾選項常寫「在安全群組新增一條拒絕規則」,這個選項本身就不存在。
編號方向:網路 ACL 編號越小越先評估,拒絕規則要放在允許規則前面才有效。
回應要另開規則嗎:安全群組不用(有狀態);網路 ACL 要(無狀態),而且是臨時連接埠範圍,不是服務連接埠。
自建網路 ACL 的預設:預設網路 ACL 全部允許,新建的自訂網路 ACL 全部拒絕。題目說「新建一個網路 ACL 關聯到子網路後所有連線都斷了」,原因就在這裡。
公有子網路的定義:是路由表有 0.0.0.0/0 指向網際網路閘道,不是「開啟自動指派公有 IP」,也不是子網路名稱。NAT 閘道要放在公有子網路,私有子網路的路由指向它。
可用 IP:每個子網路扣 5 個,/28 只剩 11 個;VPC 與子網路的 IPv4 大小都是 /16~/28。
相關考試:CLF-C02 的「雲端技術與服務」領域要求認得 VPC 元件與安全功能;SAA-C03 的安全架構領域涵蓋 VPC 架構、網路分段與安全群組;SOA-C03 與 SCS-C03 的 in-scope 清單明確列出 security groups 與 network ACLs;ANS-C01 會考更深的路由與混合連線。
✅ 自我檢測
以下 6 題都是原創題,選完會立即顯示對錯與解析,全部作答後會出現總分。目前得分:0 / 6