VPC 端點概述
VPC 端點(VPC Endpoints)是 AWS 提供的一項服務,允許您在 VPC 內部私密地連接到 AWS 服務,而無需透過網際網路閘道、NAT 裝置、VPN 連線或 AWS Direct Connect。這樣可以確保流量始終保持在 AWS 網路內部,提高安全性並降低資料傳輸成本。
VPC 端點的優勢
- 增強安全性:流量不會離開 AWS 網路,降低資料外洩風險
- 降低成本:避免 NAT 閘道的資料處理費用
- 降低延遲:直接在 AWS 骨幹網路中傳輸資料
- 簡化網路架構:私有子網路中的資源可直接存取 AWS 服務
Gateway Endpoint vs Interface Endpoint
AWS 提供兩種類型的 VPC 端點,各有不同的用途和特性:
Gateway Endpoint(閘道端點)
- 支援服務:僅支援 S3 和 DynamoDB
- 實作方式:透過路由表項目將流量導向端點
- 費用:完全免費
- 高可用性:AWS 自動管理,跨可用區域冗餘
1
2
3
4
5
| # 查詢支援 Gateway Endpoint 的服務
aws ec2 describe-vpc-endpoint-services \
--filters "Name=service-type,Values=Gateway" \
--query 'ServiceDetails[*].ServiceName' \
--region ap-northeast-1
|
Interface Endpoint(介面端點)
- 支援服務:支援大多數 AWS 服務(如 EC2、SSM、CloudWatch 等)
- 實作方式:在子網路中建立彈性網路介面(ENI)
- 費用:依使用時間和資料傳輸量計費
- 高可用性:需要在多個可用區域建立端點
1
2
3
4
5
| # 查詢支援 Interface Endpoint 的服務
aws ec2 describe-vpc-endpoint-services \
--filters "Name=service-type,Values=Interface" \
--query 'ServiceDetails[*].ServiceName' \
--region ap-northeast-1
|
建立 S3 Gateway Endpoint
S3 是最常使用的 AWS 服務之一,建立 Gateway Endpoint 可以讓私有子網路中的 EC2 實例直接存取 S3,而無需透過 NAT 閘道。
步驟一:取得 VPC 和路由表資訊
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
| # 取得 VPC ID
VPC_ID=$(aws ec2 describe-vpcs \
--filters "Name=tag:Name,Values=my-vpc" \
--query 'Vpcs[0].VpcId' \
--output text \
--region ap-northeast-1)
echo "VPC ID: $VPC_ID"
# 取得私有子網路的路由表 ID
ROUTE_TABLE_ID=$(aws ec2 describe-route-tables \
--filters "Name=vpc-id,Values=$VPC_ID" \
"Name=tag:Name,Values=private-route-table" \
--query 'RouteTables[0].RouteTableId' \
--output text \
--region ap-northeast-1)
echo "Route Table ID: $ROUTE_TABLE_ID"
|
步驟二:建立 S3 Gateway Endpoint
1
2
3
4
5
6
7
| # 建立 S3 Gateway Endpoint
aws ec2 create-vpc-endpoint \
--vpc-id $VPC_ID \
--service-name com.amazonaws.ap-northeast-1.s3 \
--route-table-ids $ROUTE_TABLE_ID \
--tag-specifications 'ResourceType=vpc-endpoint,Tags=[{Key=Name,Value=s3-gateway-endpoint}]' \
--region ap-northeast-1
|
步驟三:驗證端點建立
1
2
3
4
5
6
7
| # 查看端點狀態
aws ec2 describe-vpc-endpoints \
--filters "Name=vpc-id,Values=$VPC_ID" \
"Name=service-name,Values=com.amazonaws.ap-northeast-1.s3" \
--query 'VpcEndpoints[*].[VpcEndpointId,State,ServiceName]' \
--output table \
--region ap-northeast-1
|
建立 Interface Endpoint(以 SSM 為例)
AWS Systems Manager(SSM)允許您在不開放 SSH 連接埠的情況下管理 EC2 實例。為了讓私有子網路中的實例使用 SSM,需要建立相關的 Interface Endpoint。
步驟一:建立安全群組
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
| # 建立端點專用的安全群組
ENDPOINT_SG_ID=$(aws ec2 create-security-group \
--group-name vpc-endpoint-sg \
--description "Security group for VPC endpoints" \
--vpc-id $VPC_ID \
--query 'GroupId' \
--output text \
--region ap-northeast-1)
# 允許 VPC CIDR 範圍的 HTTPS 流量
aws ec2 authorize-security-group-ingress \
--group-id $ENDPOINT_SG_ID \
--protocol tcp \
--port 443 \
--cidr 10.0.0.0/16 \
--region ap-northeast-1
echo "Security Group ID: $ENDPOINT_SG_ID"
|
步驟二:取得私有子網路 ID
1
2
3
4
5
6
7
8
9
| # 取得私有子網路 ID
SUBNET_IDS=$(aws ec2 describe-subnets \
--filters "Name=vpc-id,Values=$VPC_ID" \
"Name=tag:Name,Values=*private*" \
--query 'Subnets[*].SubnetId' \
--output text \
--region ap-northeast-1)
echo "Subnet IDs: $SUBNET_IDS"
|
步驟三:建立 SSM 相關端點
SSM 需要三個端點才能完整運作:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
| # 建立 SSM 端點
aws ec2 create-vpc-endpoint \
--vpc-id $VPC_ID \
--vpc-endpoint-type Interface \
--service-name com.amazonaws.ap-northeast-1.ssm \
--subnet-ids $SUBNET_IDS \
--security-group-ids $ENDPOINT_SG_ID \
--private-dns-enabled \
--tag-specifications 'ResourceType=vpc-endpoint,Tags=[{Key=Name,Value=ssm-endpoint}]' \
--region ap-northeast-1
# 建立 SSM Messages 端點
aws ec2 create-vpc-endpoint \
--vpc-id $VPC_ID \
--vpc-endpoint-type Interface \
--service-name com.amazonaws.ap-northeast-1.ssmmessages \
--subnet-ids $SUBNET_IDS \
--security-group-ids $ENDPOINT_SG_ID \
--private-dns-enabled \
--tag-specifications 'ResourceType=vpc-endpoint,Tags=[{Key=Name,Value=ssmmessages-endpoint}]' \
--region ap-northeast-1
# 建立 EC2 Messages 端點
aws ec2 create-vpc-endpoint \
--vpc-id $VPC_ID \
--vpc-endpoint-type Interface \
--service-name com.amazonaws.ap-northeast-1.ec2messages \
--subnet-ids $SUBNET_IDS \
--security-group-ids $ENDPOINT_SG_ID \
--private-dns-enabled \
--tag-specifications 'ResourceType=vpc-endpoint,Tags=[{Key=Name,Value=ec2messages-endpoint}]' \
--region ap-northeast-1
|
PrivateLink 概念說明
AWS PrivateLink 是一種技術,讓您可以透過私有 IP 位址存取 AWS 服務、第三方服務或自己建立的服務。PrivateLink 是 Interface Endpoint 的底層技術,但也可以用來建立自定義的端點服務。
PrivateLink 架構元件
- 端點服務(Endpoint Service):服務提供者建立的 Network Load Balancer 背後的服務
- VPC 端點(VPC Endpoint):服務消費者在其 VPC 中建立的連接點
- 私有 DNS:允許使用服務的公開 DNS 名稱解析到私有 IP
PrivateLink 使用場景
- 跨帳戶服務共享:在不同 AWS 帳戶間安全地共享服務
- SaaS 服務整合:連接到第三方 SaaS 提供者的服務
- 微服務架構:在 VPC 之間安全地連接微服務
建立 VPC Endpoint Service
如果您想將自己的服務透過 PrivateLink 提供給其他 VPC 或帳戶使用,需要建立 VPC Endpoint Service。
步驟一:建立 Network Load Balancer
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
| # 建立 NLB
NLB_ARN=$(aws elbv2 create-load-balancer \
--name my-privatelink-nlb \
--type network \
--scheme internal \
--subnets $SUBNET_IDS \
--tags Key=Name,Value=my-privatelink-nlb \
--query 'LoadBalancers[0].LoadBalancerArn' \
--output text \
--region ap-northeast-1)
echo "NLB ARN: $NLB_ARN"
# 建立目標群組
TARGET_GROUP_ARN=$(aws elbv2 create-target-group \
--name my-privatelink-tg \
--protocol TCP \
--port 80 \
--vpc-id $VPC_ID \
--target-type ip \
--query 'TargetGroups[0].TargetGroupArn' \
--output text \
--region ap-northeast-1)
# 建立監聽器
aws elbv2 create-listener \
--load-balancer-arn $NLB_ARN \
--protocol TCP \
--port 80 \
--default-actions Type=forward,TargetGroupArn=$TARGET_GROUP_ARN \
--region ap-northeast-1
|
步驟二:建立 VPC Endpoint Service
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
| # 建立端點服務
ENDPOINT_SERVICE_ID=$(aws ec2 create-vpc-endpoint-service-configuration \
--network-load-balancer-arns $NLB_ARN \
--acceptance-required \
--tag-specifications 'ResourceType=vpc-endpoint-service,Tags=[{Key=Name,Value=my-endpoint-service}]' \
--query 'ServiceConfiguration.ServiceId' \
--output text \
--region ap-northeast-1)
echo "Endpoint Service ID: $ENDPOINT_SERVICE_ID"
# 取得服務名稱
SERVICE_NAME=$(aws ec2 describe-vpc-endpoint-service-configurations \
--service-ids $ENDPOINT_SERVICE_ID \
--query 'ServiceConfigurations[0].ServiceName' \
--output text \
--region ap-northeast-1)
echo "Service Name: $SERVICE_NAME"
|
步驟三:設定允許的主體
1
2
3
4
5
| # 允許特定 AWS 帳戶連接
aws ec2 modify-vpc-endpoint-service-permissions \
--service-id $ENDPOINT_SERVICE_ID \
--add-allowed-principals "arn:aws:iam::123456789012:root" \
--region ap-northeast-1
|
安全群組設定
VPC 端點的安全群組設定是確保服務安全的關鍵。以下是常見的安全群組設定範例:
端點安全群組最佳實踐
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
| # 建立端點安全群組
ENDPOINT_SG=$(aws ec2 create-security-group \
--group-name vpc-endpoints-sg \
--description "Security group for VPC endpoints" \
--vpc-id $VPC_ID \
--query 'GroupId' \
--output text \
--region ap-northeast-1)
# 僅允許來自 VPC CIDR 的 HTTPS 流量
aws ec2 authorize-security-group-ingress \
--group-id $ENDPOINT_SG \
--protocol tcp \
--port 443 \
--cidr 10.0.0.0/16 \
--region ap-northeast-1
# 或者僅允許特定安全群組的流量
aws ec2 authorize-security-group-ingress \
--group-id $ENDPOINT_SG \
--protocol tcp \
--port 443 \
--source-group sg-0123456789abcdef0 \
--region ap-northeast-1
|
端點政策設定
VPC 端點政策可以進一步限制透過端點可以執行的操作,提供額外的安全層級。
S3 端點政策範例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
| # 建立端點政策 JSON 檔案
cat > s3-endpoint-policy.json << 'EOF'
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowAccessToSpecificBucket",
"Effect": "Allow",
"Principal": "*",
"Action": [
"s3:GetObject",
"s3:PutObject",
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::my-application-bucket",
"arn:aws:s3:::my-application-bucket/*"
]
},
{
"Sid": "DenyAccessToOtherBuckets",
"Effect": "Deny",
"Principal": "*",
"Action": "s3:*",
"Resource": "*",
"Condition": {
"StringNotEquals": {
"s3:ResourceAccount": "123456789012"
}
}
}
]
}
EOF
# 套用端點政策
aws ec2 modify-vpc-endpoint \
--vpc-endpoint-id vpce-0123456789abcdef0 \
--policy-document file://s3-endpoint-policy.json \
--region ap-northeast-1
|
SSM 端點政策範例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
| # 建立 SSM 端點政策
cat > ssm-endpoint-policy.json << 'EOF'
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowSSMActions",
"Effect": "Allow",
"Principal": "*",
"Action": [
"ssm:UpdateInstanceInformation",
"ssm:ListAssociations",
"ssm:ListInstanceAssociations",
"ssm:GetDocument",
"ssm:DescribeDocument"
],
"Resource": "*"
}
]
}
EOF
|
成本考量
在規劃 VPC 端點時,了解相關成本是很重要的:
Gateway Endpoint 成本
Interface Endpoint 成本
- 端點費用:約 $0.01/小時/可用區域(以美東區域為例)
- 資料處理費:約 $0.01/GB
成本最佳化建議
1
2
3
4
5
6
7
8
9
10
11
| # 查看目前的端點使用情況
aws ec2 describe-vpc-endpoints \
--filters "Name=vpc-id,Values=$VPC_ID" \
--query 'VpcEndpoints[*].[VpcEndpointId,ServiceName,State,VpcEndpointType]' \
--output table \
--region ap-northeast-1
# 刪除不使用的端點
aws ec2 delete-vpc-endpoints \
--vpc-endpoint-ids vpce-0123456789abcdef0 \
--region ap-northeast-1
|
成本估算範例
| 端點類型 | 數量 | 可用區域 | 月費用估算 |
|---|
| Gateway (S3) | 1 | - | $0 |
| Interface (SSM) | 3 | 2 | ~$43.20 |
| Interface (ECR) | 2 | 2 | ~$28.80 |
總結
VPC 端點和 PrivateLink 是建立安全、高效能 AWS 架構的重要元件。透過本文介紹的設定方式,您可以:
- 使用 Gateway Endpoint 免費存取 S3 和 DynamoDB
- 使用 Interface Endpoint 安全地存取其他 AWS 服務
- 透過 PrivateLink 建立自己的端點服務
- 正確設定安全群組和端點政策以確保安全性
在實作時,請根據實際需求評估成本效益,並遵循最小權限原則設定端點政策。
參考資料