AWS VPC Public 與 Private Subnet 設計與配置指南

🌏 Read the English version


為什麼需要 Public 與 Private Subnet?

AWS VPC 網路架構的核心設計理念

在 Amazon Web Services (AWS) 的 Virtual Private Cloud (VPC) 架構中,Public Subnet 與 Private Subnet 的設計並非任意區分,而是基於「最小權限原則」與「縱深防禦」的資安最佳實踐。這種網路分層設計能有效降低攻擊面,保護關鍵資源,同時保持必要的外部連線能力。

1. 安全性分層防護

Public Subnet 的暴露風險

  • 直接暴露於網際網路,面臨更高的攻擊風險(DDoS、掃描、暴力破解)
  • 必須具備強大的安全防護(Security Group、NACL、WAF)
  • 適合放置「必須對外服務」的元件(Load Balancer、NAT Gateway、Bastion Host)

Private Subnet 的隔離保護

  • 完全隔離於網際網路直接訪問,大幅降低攻擊面
  • 僅能透過特定管道訪問(Bastion Host、VPN、AWS Systems Manager)
  • 適合放置「不應對外」的敏感資源(資料庫、應用伺服器、內部服務)

實際案例:2023 年某企業因將 RDS 資料庫放在 Public Subnet 並開放 0.0.0.0/0 訪問,導致資料外洩。若採用 Private Subnet + 嚴格的 Security Group,此類事故可完全避免。

2. 成本優化與效能提升

  • NAT Gateway 集中管理:Private Subnet 中的所有實例共用 NAT Gateway 出站,節省 Elastic IP 成本
  • VPC Endpoint 省流量費:Private Subnet 可透過 VPC Endpoint 訪問 AWS 服務(S3, DynamoDB),流量不經網際網路,免除資料傳輸費用
  • 降低頻寬成本:內部服務間通訊保持在 VPC 內,避免昂貴的外網流量費用

3. 合規性需求

許多合規標準(GDPR、HIPAA、PCI-DSS)要求:

  • 敏感資料必須儲存在隔離環境
  • 資料庫不得直接暴露於網際網路
  • 需有明確的網路存取控制與稽核

Private Subnet 的設計天然符合這些要求,能大幅簡化合規性驗證流程。


Public Subnet 詳解

定義與特徵

Public Subnet 是指其內部的 EC2 實例可以直接與網際網路雙向通訊的子網路。關鍵特徵:

  • ✅ 路由表包含指向 Internet Gateway (IGW) 的路由(0.0.0.0/0 → IGW)
  • ✅ 實例具備 Public IP 或 Elastic IP (EIP)
  • ✅ Security Group 允許來自網際網路的入站流量(特定埠)
  • ✅ Network ACL 允許進出流量

完整配置步驟

1. 建立 VPC 與 Internet Gateway

# 建立 VPC
aws ec2 create-vpc --cidr-block 10.0.0.0/16 --tag-specifications 'ResourceType=vpc,Tags=[{Key=Name,Value=MyVPC}]'

# 建立 Internet Gateway
aws ec2 create-internet-gateway --tag-specifications 'ResourceType=internet-gateway,Tags=[{Key=Name,Value=MyIGW}]'

# 將 IGW 附加到 VPC
aws ec2 attach-internet-gateway --vpc-id vpc-xxxxxxxx --internet-gateway-id igw-yyyyyyyy

2. 建立 Public Subnet

# 建立 Public Subnet(使用可用區 us-east-1a)
aws ec2 create-subnet 
  --vpc-id vpc-xxxxxxxx 
  --cidr-block 10.0.1.0/24 
  --availability-zone us-east-1a 
  --tag-specifications 'ResourceType=subnet,Tags=[{Key=Name,Value=PublicSubnet-1A}]'

# 啟用自動分配 Public IP
aws ec2 modify-subnet-attribute 
  --subnet-id subnet-xxxxxxxx 
  --map-public-ip-on-launch

3. 設定路由表

# 建立路由表
aws ec2 create-route-table 
  --vpc-id vpc-xxxxxxxx 
  --tag-specifications 'ResourceType=route-table,Tags=[{Key=Name,Value=PublicRouteTable}]'

# 新增指向 IGW 的路由
aws ec2 create-route 
  --route-table-id rtb-xxxxxxxx 
  --destination-cidr-block 0.0.0.0/0 
  --gateway-id igw-yyyyyyyy

# 將路由表關聯至 Public Subnet
aws ec2 associate-route-table 
  --route-table-id rtb-xxxxxxxx 
  --subnet-id subnet-xxxxxxxx

4. 設定 Security Group

# 建立 Security Group(允許 HTTP/HTTPS 入站)
aws ec2 create-security-group 
  --group-name WebServerSG 
  --description "Allow HTTP/HTTPS from internet" 
  --vpc-id vpc-xxxxxxxx

# 允許 HTTP 入站
aws ec2 authorize-security-group-ingress 
  --group-id sg-xxxxxxxx 
  --protocol tcp 
  --port 80 
  --cidr 0.0.0.0/0

# 允許 HTTPS 入站
aws ec2 authorize-security-group-ingress 
  --group-id sg-xxxxxxxx 
  --protocol tcp 
  --port 443 
  --cidr 0.0.0.0/0

# 允許 SSH(建議限制來源 IP)
aws ec2 authorize-security-group-ingress 
  --group-id sg-xxxxxxxx 
  --protocol tcp 
  --port 22 
  --cidr YOUR_IP/32

適用場景

  1. Web 伺服器:Apache、Nginx、IIS 等需直接接受使用者請求的伺服器
  2. Application Load Balancer (ALB):分散流量至後端應用伺服器
  3. NAT Gateway:為 Private Subnet 提供出站網際網路訪問
  4. Bastion Host (Jump Server):作為進入 Private Subnet 的安全跳板
  5. VPN Gateway:企業內部網路與 AWS VPC 的連線端點

Private Subnet 詳解

定義與特徵

Private Subnet 是指其內部的 EC2 實例無法直接與網際網路雙向通訊的子網路。關鍵特徵:

  • ✅ 路由表「不包含」指向 Internet Gateway 的路由
  • ✅ 實例「不分配」Public IP(僅有 Private IP)
  • ✅ 出站網際網路訪問需透過 NAT Gateway 或 NAT Instance
  • ✅ 入站訪問僅能透過 VPC 內部或 VPN/Direct Connect

完整配置步驟

1. 建立 Private Subnet

# 建立 Private Subnet(使用可用區 us-east-1a)
aws ec2 create-subnet 
  --vpc-id vpc-xxxxxxxx 
  --cidr-block 10.0.10.0/24 
  --availability-zone us-east-1a 
  --tag-specifications 'ResourceType=subnet,Tags=[{Key=Name,Value=PrivateSubnet-1A}]'

# 確認不自動分配 Public IP(預設即為關閉)
aws ec2 describe-subnets --subnet-ids subnet-xxxxxxxx --query 'Subnets[0].MapPublicIpOnLaunch'

2. 建立 NAT Gateway(讓 Private Subnet 可出站訪問網際網路)

# 先分配 Elastic IP
aws ec2 allocate-address --domain vpc

# 建立 NAT Gateway(必須放在 Public Subnet)
aws ec2 create-nat-gateway 
  --subnet-id subnet-PUBLIC-SUBNET-ID 
  --allocation-id eipalloc-xxxxxxxx 
  --tag-specifications 'ResourceType=nat-gateway,Tags=[{Key=Name,Value=MyNATGateway}]'

3. 設定 Private Subnet 路由表

# 建立路由表
aws ec2 create-route-table 
  --vpc-id vpc-xxxxxxxx 
  --tag-specifications 'ResourceType=route-table,Tags=[{Key=Name,Value=PrivateRouteTable}]'

# 新增指向 NAT Gateway 的路由
aws ec2 create-route 
  --route-table-id rtb-xxxxxxxx 
  --destination-cidr-block 0.0.0.0/0 
  --nat-gateway-id nat-xxxxxxxx

# 將路由表關聯至 Private Subnet
aws ec2 associate-route-table 
  --route-table-id rtb-xxxxxxxx 
  --subnet-id subnet-xxxxxxxx

4. 設定 Security Group(僅允許 VPC 內部訪問)

# 建立 Security Group(僅允許來自 VPC 內部的流量)
aws ec2 create-security-group 
  --group-name PrivateAppSG 
  --description "Allow traffic only from VPC" 
  --vpc-id vpc-xxxxxxxx

# 允許來自 Public Subnet 的 HTTP 流量(例如來自 ALB)
aws ec2 authorize-security-group-ingress 
  --group-id sg-xxxxxxxx 
  --protocol tcp 
  --port 8080 
  --source-group sg-PUBLIC-SG-ID

# 允許來自 Bastion Host 的 SSH
aws ec2 authorize-security-group-ingress 
  --group-id sg-xxxxxxxx 
  --protocol tcp 
  --port 22 
  --source-group sg-BASTION-SG-ID

適用場景

  1. 資料庫伺服器:RDS、Aurora、自建 MySQL/PostgreSQL/MongoDB
  2. 應用伺服器:後端 API、微服務、處理業務邏輯的伺服器
  3. 快取層:ElastiCache (Redis/Memcached)
  4. 訊息佇列:Amazon MQ、RabbitMQ、Kafka
  5. 批次處理伺服器:資料分析、ETL 任務、排程作業

Public vs Private Subnet 對比表

特性 Public Subnet Private Subnet
Internet Gateway ✅ 路由表指向 IGW ❌ 路由表不指向 IGW
Public IP ✅ 自動分配或手動綁定 EIP ❌ 僅有 Private IP
入站網際網路訪問 ✅ 允許(需 Security Group 開放) ❌ 禁止
出站網際網路訪問 ✅ 直接透過 IGW ✅ 透過 NAT Gateway/Instance
安全性風險 ⚠️ 高(直接暴露) ✅ 低(隔離保護)
適用資源 ALB、Web Server、Bastion RDS、App Server、Cache
NAT Gateway 費用 不需要 需要($0.045/小時 + 流量費)
VPC Endpoint 可選 強烈建議(省流量費)

常見問題 FAQ

Q1: Private Subnet 中的 EC2 如何更新軟體套件?

答案:透過 NAT Gateway 或 VPC Endpoint

方案 1:使用 NAT Gateway(適用於一般網際網路訪問)

# 在 Private Subnet 的 EC2 上執行
sudo yum update -y  # Amazon Linux
sudo apt update && sudo apt upgrade -y  # Ubuntu

# 流量路徑:EC2 → NAT Gateway → Internet Gateway → 網際網路

方案 2:使用 VPC Endpoint(適用於 AWS 服務,免流量費)

# 建立 S3 VPC Endpoint (Gateway Endpoint,免費)
aws ec2 create-vpc-endpoint 
  --vpc-id vpc-xxxxxxxx 
  --service-name com.amazonaws.us-east-1.s3 
  --route-table-ids rtb-PRIVATE-ROUTE-TABLE

# 建立 Systems Manager VPC Endpoint (Interface Endpoint,每小時 $0.01)
aws ec2 create-vpc-endpoint 
  --vpc-id vpc-xxxxxxxx 
  --vpc-endpoint-type Interface 
  --service-name com.amazonaws.us-east-1.ssm 
  --subnet-ids subnet-xxxxxxxx 
  --security-group-ids sg-xxxxxxxx

成本對比

  • NAT Gateway:$0.045/小時 + $0.045/GB 流量 ≈ $33/月 + 流量費
  • VPC Endpoint (S3):免費
  • VPC Endpoint (Interface):$0.01/小時 ≈ $7.2/月

Q2: 如何從本地連線到 Private Subnet 的資料庫?

答案:三種常見方案

方案 1:透過 Bastion Host (Jump Server)

# SSH 隧道連線
ssh -i mykey.pem -L 3306:rds-endpoint.amazonaws.com:3306 ec2-user@BASTION-PUBLIC-IP

# 本地連線資料庫
mysql -h 127.0.0.1 -P 3306 -u admin -p

方案 2:使用 AWS Systems Manager Session Manager(無需 Bastion Host)

# 安裝 Session Manager Plugin
curl "https://s3.amazonaws.com/session-manager-downloads/plugin/latest/mac/sessionmanager-bundle.zip" -o "sessionmanager-bundle.zip"
unzip sessionmanager-bundle.zip
sudo ./sessionmanager-bundle/install -i /usr/local/sessionmanagerplugin -b /usr/local/bin/session-manager-plugin

# 透過 SSM 建立 Port Forwarding
aws ssm start-session 
  --target i-PRIVATE-INSTANCE-ID 
  --document-name AWS-StartPortForwardingSessionToRemoteHost 
  --parameters '{"host":["rds-endpoint.amazonaws.com"],"portNumber":["3306"], "localPortNumber":["3306"]}'

# 本地連線資料庫
mysql -h 127.0.0.1 -P 3306 -u admin -p

方案 3:使用 VPN 或 Direct Connect(企業級方案)

  • 建立 AWS Client VPN Endpoint
  • 本地透過 VPN 連線進入 VPC
  • 直接訪問 Private Subnet 資源

Q3: NAT Gateway 故障會影響 Private Subnet 的服務嗎?

答案:視服務類型而定

不受影響的場景

  • ✅ VPC 內部通訊(例如 ALB → App Server → RDS)
  • ✅ 透過 VPC Endpoint 訪問 AWS 服務(S3, DynamoDB)
  • ✅ 已建立連線的長期任務(若無需新建出站連線)

受影響的場景

  • ❌ 需要訪問外部 API(例如第三方支付、簡訊服務)
  • ❌ 需要下載網際網路資源(apt/yum update、Docker pull)
  • ❌ 需要發送外部通知(Email、Webhook)

高可用性方案

# 在每個可用區建立獨立的 NAT Gateway
# AZ 1a
aws ec2 create-nat-gateway --subnet-id subnet-public-1a --allocation-id eipalloc-1a

# AZ 1b
aws ec2 create-nat-gateway --subnet-id subnet-public-1b --allocation-id eipalloc-1b

# 各 Private Subnet 的路由表指向同可用區的 NAT Gateway
# PrivateSubnet-1A → NAT-1A
# PrivateSubnet-1B → NAT-1B

成本影響:每個 NAT Gateway $33/月,雙 AZ 部署 = $66/月 + 流量費

Q4: Public Subnet 中的資源是否一定不安全?

答案:不一定,關鍵在於正確配置

Public Subnet 安全配置最佳實踐

  1. 最小化開放埠
    # ✅ 僅開放必要埠
    Security Group: 允許 80, 443 (HTTP/HTTPS)
    禁止: 22 (SSH), 3389 (RDP), 3306 (MySQL)
    
    # ❌ 危險設定
    0.0.0.0/0:0-65535 ALLOW
    
  2. 使用 ALB/NLB 作為前端
    • ALB/NLB 放在 Public Subnet
    • 實際應用伺服器放在 Private Subnet
    • ALB 提供 WAF、SSL Termination、DDoS 防護
  3. 啟用 VPC Flow Logs
    # 建立 Flow Logs(監控可疑流量)
    aws ec2 create-flow-logs 
      --resource-type VPC 
      --resource-ids vpc-xxxxxxxx 
      --traffic-type ALL 
      --log-destination-type cloud-watch-logs 
      --log-group-name /aws/vpc/flowlogs
    
  4. 定期安全掃描
    • 使用 AWS Inspector 掃描漏洞
    • 使用 GuardDuty 偵測異常行為
    • 使用 Security Hub 統一管理安全狀態

Q5: 可以將 RDS 放在 Public Subnet 嗎?

答案:技術上可行,但強烈不建議

為什麼不建議

  • 違反最小權限原則:資料庫無需直接對外訪問
  • 增加攻擊面:暴露於網際網路掃描與攻擊
  • 合規性問題:違反 PCI-DSS、HIPAA 等標準
  • 意外風險:錯誤配置 Security Group 可能導致資料外洩

正確架構

網際網路
   ↓
Internet Gateway
   ↓
ALB (Public Subnet)
   ↓
App Server (Private Subnet)
   ↓
RDS (Private Subnet - 使用 DB Subnet Group)

例外情況

  • 開發/測試環境需要外部工具直接連線(不建議,應使用 Bastion 或 SSM)
  • 臨時 POC 驗證(務必在測試後立即遷移至 Private Subnet)

Q6: 如何選擇 NAT Gateway 還是 NAT Instance?

答案:大多數情況推薦 NAT Gateway

特性 NAT Gateway(推薦) NAT Instance
可用性 ✅ AWS 管理,高可用性 ❌ 單點故障,需自建 HA
效能 ✅ 最高 100 Gbps ⚠️ 受限於實例規格
維護成本 ✅ 零維護 ❌ 需自行管理、打補丁
費用 ⚠️ $0.045/小時 + 流量費 ✅ 僅 EC2 費用
適用場景 生產環境 開發/測試、成本敏感

NAT Instance 設定範例(僅供參考):

# 啟動 NAT Instance(使用 AWS 官方 NAT AMI)
aws ec2 run-instances 
  --image-id ami-xxxxxxxxxxxx 
  --instance-type t3.micro 
  --subnet-id subnet-PUBLIC-SUBNET 
  --security-group-ids sg-xxxxxxxx

# 停用來源/目標檢查(必要設定)
aws ec2 modify-instance-attribute 
  --instance-id i-xxxxxxxx 
  --no-source-dest-check

# 修改 Private Subnet 路由表指向 NAT Instance
aws ec2 create-route 
  --route-table-id rtb-xxxxxxxx 
  --destination-cidr-block 0.0.0.0/0 
  --instance-id i-NAT-INSTANCE-ID

Q7: VPC Peering 或 Transit Gateway 環境下如何配置 Subnet?

答案:需調整路由表以支援跨 VPC 通訊

場景:VPC-A 與 VPC-B 透過 VPC Peering 連線

# VPC-A (10.0.0.0/16) ←→ VPC-B (10.1.0.0/16)

# 在 VPC-A 的 Private Subnet 路由表新增指向 VPC-B 的路由
aws ec2 create-route 
  --route-table-id rtb-VPC-A-PRIVATE 
  --destination-cidr-block 10.1.0.0/16 
  --vpc-peering-connection-id pcx-xxxxxxxx

# 在 VPC-B 的 Private Subnet 路由表新增指向 VPC-A 的路由
aws ec2 create-route 
  --route-table-id rtb-VPC-B-PRIVATE 
  --destination-cidr-block 10.0.0.0/16 
  --vpc-peering-connection-id pcx-xxxxxxxx

Transit Gateway 架構(推薦用於多 VPC 環境):

VPC-A (10.0.0.0/16)  ─┐
VPC-B (10.1.0.0/16)  ─┼─→ Transit Gateway ←─ On-Premises (192.168.0.0/16)
VPC-C (10.2.0.0/16)  ─┘
# 各 VPC 的路由表新增指向 TGW 的路由
aws ec2 create-route 
  --route-table-id rtb-VPC-A-PRIVATE 
  --destination-cidr-block 0.0.0.0/0 
  --transit-gateway-id tgw-xxxxxxxx

最佳實踐

架構設計

  1. 三層架構標準配置
    Public Subnet:  ALB, NAT Gateway, Bastion Host
    Private Subnet: Application Servers, Lambda (in VPC)
    Data Subnet:    RDS, ElastiCache, Redshift (更嚴格的 Security Group)
    
  2. 多可用區部署(高可用性)
    • 每個 AZ 都配置 Public Subnet 與 Private Subnet
    • 每個 AZ 都配置獨立的 NAT Gateway
    • RDS 使用 Multi-AZ 部署
  3. CIDR 規劃原則
    VPC:            10.0.0.0/16  (65536 個 IP)
    Public-1A:      10.0.1.0/24  (256 個 IP)
    Public-1B:      10.0.2.0/24
    Private-1A:     10.0.10.0/24
    Private-1B:     10.0.11.0/24
    Data-1A:        10.0.20.0/24
    Data-1B:        10.0.21.0/24
    預留:           10.0.100.0/22 (未來擴充)
    

安全性

  1. Security Group 最小化原則
    • 僅開放必要埠
    • 使用 Security Group ID 而非 CIDR(例如:允許來自 sg-alb 的流量)
    • 禁止 0.0.0.0/0 訪問敏感埠
  2. Network ACL 作為第二道防線
    # 阻擋已知惡意 IP 段
    aws ec2 create-network-acl-entry 
      --network-acl-id acl-xxxxxxxx 
      --rule-number 10 
      --protocol -1 
      --rule-action deny 
      --cidr-block 123.45.67.0/24
    
  3. 啟用 VPC Flow Logs 與 GuardDuty

成本優化

  1. 使用 VPC Endpoint 取代 NAT Gateway(適用於 AWS 服務)
    • S3, DynamoDB 使用 Gateway Endpoint(免費)
    • 其他服務使用 Interface Endpoint($0.01/小時,但省流量費)
  2. 評估 NAT Gateway 必要性
    • 若僅需訪問 AWS 服務 → 使用 VPC Endpoint
    • 若需訪問外部 API → 保留 NAT Gateway
  3. 使用 Reserved Capacity(長期使用)

維運管理

  1. 使用 AWS Systems Manager 取代 Bastion Host
    • 無需維護跳板機
    • 完整的稽核記錄
    • 支援 Session Manager, Port Forwarding
  2. 自動化備份與災難復原
    • 使用 Terraform/CloudFormation 管理基礎設施
    • 定期測試災難復原流程
  3. 監控與告警
    • 監控 NAT Gateway 流量與錯誤率
    • 監控 VPC Flow Logs 異常流量
    • 設定 CloudWatch Alarm 通知

實戰案例:三層架構完整部署

架構圖

                        網際網路
                            ↓
                    Internet Gateway
                            ↓
        ┌───────────────────┴───────────────────┐
        │           Public Subnet                │
        │  - ALB (443, 80)                       │
        │  - NAT Gateway (AZ-1A, AZ-1B)          │
        │  - Bastion Host (SSH 僅限公司 IP)      │
        └───────────────────┬───────────────────┘
                            ↓
        ┌───────────────────┴───────────────────┐
        │          Private Subnet                │
        │  - App Servers (Auto Scaling)          │
        │  - Lambda Functions (in VPC)           │
        │  - ElastiCache Redis                   │
        └───────────────────┬───────────────────┘
                            ↓
        ┌───────────────────┴───────────────────┐
        │           Data Subnet                  │
        │  - RDS Aurora (Multi-AZ)               │
        │  - Redshift Cluster                    │
        └───────────────────────────────────────┘

完整部署腳本(使用 AWS CLI)

#!/bin/bash
# 三層架構部署腳本

# 變數設定
VPC_CIDR="10.0.0.0/16"
PUBLIC_SUBNET_1A="10.0.1.0/24"
PUBLIC_SUBNET_1B="10.0.2.0/24"
PRIVATE_SUBNET_1A="10.0.10.0/24"
PRIVATE_SUBNET_1B="10.0.11.0/24"
DATA_SUBNET_1A="10.0.20.0/24"
DATA_SUBNET_1B="10.0.21.0/24"

# 1. 建立 VPC
VPC_ID=$(aws ec2 create-vpc --cidr-block $VPC_CIDR --query 'Vpc.VpcId' --output text)
aws ec2 create-tags --resources $VPC_ID --tags Key=Name,Value=Production-VPC

# 2. 建立 Internet Gateway
IGW_ID=$(aws ec2 create-internet-gateway --query 'InternetGateway.InternetGatewayId' --output text)
aws ec2 attach-internet-gateway --vpc-id $VPC_ID --internet-gateway-id $IGW_ID

# 3. 建立 Public Subnets
PUBLIC_SUBNET_1A_ID=$(aws ec2 create-subnet --vpc-id $VPC_ID --cidr-block $PUBLIC_SUBNET_1A --availability-zone us-east-1a --query 'Subnet.SubnetId' --output text)
PUBLIC_SUBNET_1B_ID=$(aws ec2 create-subnet --vpc-id $VPC_ID --cidr-block $PUBLIC_SUBNET_1B --availability-zone us-east-1b --query 'Subnet.SubnetId' --output text)

# 4. 建立 Private Subnets
PRIVATE_SUBNET_1A_ID=$(aws ec2 create-subnet --vpc-id $VPC_ID --cidr-block $PRIVATE_SUBNET_1A --availability-zone us-east-1a --query 'Subnet.SubnetId' --output text)
PRIVATE_SUBNET_1B_ID=$(aws ec2 create-subnet --vpc-id $VPC_ID --cidr-block $PRIVATE_SUBNET_1B --availability-zone us-east-1b --query 'Subnet.SubnetId' --output text)

# 5. 建立 Data Subnets
DATA_SUBNET_1A_ID=$(aws ec2 create-subnet --vpc-id $VPC_ID --cidr-block $DATA_SUBNET_1A --availability-zone us-east-1a --query 'Subnet.SubnetId' --output text)
DATA_SUBNET_1B_ID=$(aws ec2 create-subnet --vpc-id $VPC_ID --cidr-block $DATA_SUBNET_1B --availability-zone us-east-1b --query 'Subnet.SubnetId' --output text)

# 6. 建立 NAT Gateways(每個 AZ 一個)
EIP_1A=$(aws ec2 allocate-address --domain vpc --query 'AllocationId' --output text)
EIP_1B=$(aws ec2 allocate-address --domain vpc --query 'AllocationId' --output text)
NAT_1A=$(aws ec2 create-nat-gateway --subnet-id $PUBLIC_SUBNET_1A_ID --allocation-id $EIP_1A --query 'NatGateway.NatGatewayId' --output text)
NAT_1B=$(aws ec2 create-nat-gateway --subnet-id $PUBLIC_SUBNET_1B_ID --allocation-id $EIP_1B --query 'NatGateway.NatGatewayId' --output text)

# 等待 NAT Gateway 建立完成
aws ec2 wait nat-gateway-available --nat-gateway-ids $NAT_1A $NAT_1B

# 7. 設定路由表
# Public Route Table
PUBLIC_RT=$(aws ec2 create-route-table --vpc-id $VPC_ID --query 'RouteTable.RouteTableId' --output text)
aws ec2 create-route --route-table-id $PUBLIC_RT --destination-cidr-block 0.0.0.0/0 --gateway-id $IGW_ID
aws ec2 associate-route-table --route-table-id $PUBLIC_RT --subnet-id $PUBLIC_SUBNET_1A_ID
aws ec2 associate-route-table --route-table-id $PUBLIC_RT --subnet-id $PUBLIC_SUBNET_1B_ID

# Private Route Tables (每個 AZ 獨立)
PRIVATE_RT_1A=$(aws ec2 create-route-table --vpc-id $VPC_ID --query 'RouteTable.RouteTableId' --output text)
aws ec2 create-route --route-table-id $PRIVATE_RT_1A --destination-cidr-block 0.0.0.0/0 --nat-gateway-id $NAT_1A
aws ec2 associate-route-table --route-table-id $PRIVATE_RT_1A --subnet-id $PRIVATE_SUBNET_1A_ID

PRIVATE_RT_1B=$(aws ec2 create-route-table --vpc-id $VPC_ID --query 'RouteTable.RouteTableId' --output text)
aws ec2 create-route --route-table-id $PRIVATE_RT_1B --destination-cidr-block 0.0.0.0/0 --nat-gateway-id $NAT_1B
aws ec2 associate-route-table --route-table-id $PRIVATE_RT_1B --subnet-id $PRIVATE_SUBNET_1B_ID

# Data Route Table (無網際網路訪問)
DATA_RT=$(aws ec2 create-route-table --vpc-id $VPC_ID --query 'RouteTable.RouteTableId' --output text)
aws ec2 associate-route-table --route-table-id $DATA_RT --subnet-id $DATA_SUBNET_1A_ID
aws ec2 associate-route-table --route-table-id $DATA_RT --subnet-id $DATA_SUBNET_1B_ID

echo "VPC 部署完成!"
echo "VPC ID: $VPC_ID"
echo "Public Subnets: $PUBLIC_SUBNET_1A_ID, $PUBLIC_SUBNET_1B_ID"
echo "Private Subnets: $PRIVATE_SUBNET_1A_ID, $PRIVATE_SUBNET_1B_ID"
echo "Data Subnets: $DATA_SUBNET_1A_ID, $DATA_SUBNET_1B_ID"

總結

AWS VPC 的 Public 與 Private Subnet 設計是雲端架構安全性與可靠性的基石。正確理解與配置這兩種子網路,能有效:

  • 🔒 提升安全性:透過網路隔離降低攻擊面,保護敏感資源
  • 💰 優化成本:使用 VPC Endpoint 降低流量費用,合理配置 NAT Gateway
  • 確保效能:合理的網路架構設計避免不必要的跳轉與延遲
  • 符合合規:滿足 GDPR、HIPAA、PCI-DSS 等法規要求

關鍵要點

  1. ✅ Public Subnet 僅放置「必須對外」的資源(ALB、NAT Gateway、Bastion)
  2. ✅ Private Subnet 放置「不應對外」的敏感資源(RDS、App Server、Cache)
  3. ✅ 使用 NAT Gateway 而非 NAT Instance(除非成本極度敏感)
  4. ✅ 多可用區部署提升可用性(每個 AZ 獨立 NAT Gateway)
  5. ✅ 使用 VPC Endpoint 降低成本(S3、DynamoDB 免費,其他服務省流量費)
  6. ✅ 永遠不要將 RDS 放在 Public Subnet
  7. ✅ 使用 Security Group ID 而非 CIDR 定義規則(更易管理)
  8. ✅ 啟用 VPC Flow Logs 與 GuardDuty 監控安全威脅

透過本文的詳細說明、實戰案例與常見問題解答,您應該能夠設計與部署符合企業級標準的 AWS VPC 網路架構。記住:安全性設計應從網路層開始,Public 與 Private Subnet 的正確配置是雲端安全的第一道防線

Related Articles

Leave a Comment