실습 예제 · 10
VPC 엔드포인트로 S3 비공개 접근
프라이빗 서브넷에서 Amazon S3를 호출하면 기본적으로 NAT 게이트웨이를 지나 인터넷 경로로 나갑니다. VPC 엔드포인트를 만들면 그 트래픽이 VPC 안에서 처리되고, 보안 요구와 비용 요구를 동시에 만족시킵니다.
학습 목표
- 게이트웨이 엔드포인트와 인터페이스 엔드포인트의 구현 위치 차이를 설명할 수 있습니다.
- 게이트웨이 엔드포인트가 라우팅 테이블을 어떻게 바꾸는지 확인할 수 있습니다.
- 엔드포인트 정책으로 접근 가능한 리소스를 제한할 수 있습니다.
- 인터페이스 엔드포인트의 프라이빗 DNS가 무엇을 바꾸는지 설명할 수 있습니다.
- 버킷 정책으로 특정 VPC 엔드포인트 경유만 허용할 수 있습니다.
시나리오
실습 1의 네트워크에서 프라이빗 서브넷의 워크로드가 Amazon S3와 AWS Systems Manager를 호출합니다. 요구는 이렇습니다.
- 이 트래픽이 인터넷을 경유하면 안 됩니다.
- NAT 게이트웨이를 지나는 데이터양을 줄여야 합니다.
- 지정된 버킷 외에는 접근할 수 없어야 합니다.
- 애플리케이션 코드는 바꾸지 않습니다.
아키텍처 개요
| 항목 | 게이트웨이 엔드포인트 | 인터페이스 엔드포인트(PrivateLink) |
|---|---|---|
| 구현 위치 | 라우팅 테이블의 경로 | 서브넷 안의 네트워크 인터페이스 |
| 대상 서비스 | Amazon S3, Amazon DynamoDB | 대부분의 AWS 서비스와 PrivateLink 서비스 |
| 보안 그룹 | 연결하지 않는다 | 연결한다 |
| DNS | 공용 이름 그대로, 경로만 바뀐다 | 프라이빗 DNS로 공용 이름을 가로챌 수 있다 |
| 온프레미스에서 사용 | 직접 불가 | 가능 |
| 접근 제어 | 엔드포인트 정책 | 엔드포인트 정책 + 보안 그룹 |
요구를 나누면 이렇게 배정됩니다 — Amazon S3는 게이트웨이 엔드포인트, Systems Manager는 인터페이스 엔드포인트입니다.
구성 단계
1 · 사용 가능한 엔드포인트 서비스 확인
aws ec2 describe-vpc-endpoint-services \
--query 'ServiceDetails[?ServiceType[0].ServiceType==`Gateway`].ServiceName' \
--output table
aws ec2 describe-vpc-endpoint-services \
--query 'ServiceDetails[?contains(ServiceName, `ssm`)].[ServiceName, ServiceType[0].ServiceType, PrivateDnsName]' \
--output table
서비스 이름은 com.amazonaws.<리전>.<서비스> 형태입니다.
게이트웨이 유형으로 제공되는 것은 Amazon S3와 Amazon DynamoDB뿐이라는 사실을
위 첫 번째 명령의 출력으로 직접 확인할 수 있습니다.
2 · S3 게이트웨이 엔드포인트
VPC_ID=vpc-0123456789abcdef0
REGION=ap-northeast-2
# 경로를 추가할 프라이빗 라우팅 테이블을 확인합니다.
aws ec2 describe-route-tables \
--filters Name=vpc-id,Values="$VPC_ID" \
--query 'RouteTables[].[RouteTableId,Tags[?Key==`Name`].Value|[0]]' \
--output table
ENDPOINT_ID=$(aws ec2 create-vpc-endpoint \
--vpc-id "$VPC_ID" \
--vpc-endpoint-type Gateway \
--service-name "com.amazonaws.$REGION.s3" \
--route-table-ids rtb-0private0000000a rtb-0private0000000b \
--query 'VpcEndpoint.VpcEndpointId' --output text)
echo "$ENDPOINT_ID"
3 · 엔드포인트 정책으로 범위 제한
엔드포인트 정책은 이 엔드포인트를 통해 무엇을 할 수 있는지를 정합니다. 기본값은 전체 허용이므로, 요구 3(지정 버킷만)을 만족시키려면 좁혀야 합니다.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowSpecificBucketsOnly",
"Effect": "Allow",
"Principal": "*",
"Action": ["s3:GetObject", "s3:PutObject", "s3:ListBucket"],
"Resource": [
"arn:aws:s3:::example-lab10-data",
"arn:aws:s3:::example-lab10-data/*"
]
}
]
}
aws ec2 modify-vpc-endpoint \
--vpc-endpoint-id "$ENDPOINT_ID" \
--policy-document file://endpoint-policy.json
4 · 버킷 쪽에서 경로를 강제
반대 방향의 통제도 가능합니다. 버킷 정책에 특정 엔드포인트를 지나지 않은 요청은 거부하는 조건을 넣으면, 인터넷 경유 접근 자체가 막힙니다.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "DenyUnlessThroughVpcEndpoint",
"Effect": "Deny",
"Principal": "*",
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::example-lab10-data",
"arn:aws:s3:::example-lab10-data/*"
],
"Condition": {
"StringNotEquals": {
"aws:SourceVpce": "vpce-0123456789abcdef0"
}
}
}
]
}
5 · 인터페이스 엔드포인트
aws ec2 create-vpc-endpoint \
--vpc-id "$VPC_ID" \
--vpc-endpoint-type Interface \
--service-name "com.amazonaws.$REGION.ssm" \
--subnet-ids subnet-0prv00000000000a subnet-0prv00000000000b \
--security-group-ids sg-0vpce00000000000 \
--private-dns-enabled \
--query 'VpcEndpoint.[VpcEndpointId,State]' --output table
--private-dns-enabled가 요구 4(코드 무변경)의 핵심입니다.
이 옵션을 켜면 공용 서비스 이름이 VPC 안에서 엔드포인트의 사설 IP로 해석되므로,
애플리케이션은 평소와 같은 엔드포인트를 호출하면 됩니다.
검증 방법
라우팅 테이블이 실제로 바뀌었는가
aws ec2 describe-route-tables \
--route-table-ids rtb-0private0000000a \
--query 'RouteTables[0].Routes[].[DestinationCidrBlock,DestinationPrefixListId,GatewayId,NatGatewayId]' \
--output table
게이트웨이 엔드포인트를 만들면 DestinationPrefixListId가 채워진 경로가
새로 나타나고 대상이 vpce-로 시작합니다.
이것이 게이트웨이 엔드포인트가 "라우팅 테이블에 구현된다"는 말의 실체입니다.
aws ec2 describe-vpc-endpoints \
--filters Name=vpc-id,Values="$VPC_ID" \
--query 'VpcEndpoints[].[VpcEndpointId,VpcEndpointType,ServiceName,State,PrivateDnsEnabled]' \
--output table
# 인터페이스 엔드포인트가 만든 네트워크 인터페이스를 확인합니다.
aws ec2 describe-vpc-endpoints \
--vpc-endpoint-ids vpce-0interface00000 \
--query 'VpcEndpoints[0].[NetworkInterfaceIds, SubnetIds, DnsEntries[].DnsName]' \
--output json
| 항목 | 통과 기준 |
|---|---|
| 라우팅 테이블 | 접두사 목록 경로의 대상이 vpce-다 |
| 인터페이스 엔드포인트 | 서브넷마다 네트워크 인터페이스가 생겼다 |
| S3 접근 | 프라이빗 서브넷 인스턴스에서 지정 버킷 접근이 성공한다 |
| 범위 제한 | 정책에 없는 다른 버킷 접근이 거부된다 |
| NAT 처리량 | S3 트래픽이 NAT 지표에서 사라진다 |
# 허용된 버킷 — 성공해야 합니다.
aws s3 ls s3://example-lab10-data/
# 정책 범위 밖 버킷 — 거부되어야 합니다.
aws s3 ls s3://example-other-bucket/
비용 고려
| 항목 | 변화 |
|---|---|
| NAT 게이트웨이 처리량 | 줄어든다 — S3 트래픽이 더 이상 지나지 않는다 |
| 게이트웨이 엔드포인트 | 라우팅 경로로 동작한다. 별도의 가동 자원이 생기지 않는다 |
| 인터페이스 엔드포인트 | 가용 영역마다 인터페이스와 처리량이 항목이 된다 |
| 가용 영역 간 전송 | 엔드포인트를 가용 영역마다 두면 경계를 넘는 트래픽이 줄어든다 |
판단 기준은 단순합니다. S3와 DynamoDB는 게이트웨이 엔드포인트를 거의 항상 만드는 편이 낫습니다. 인터페이스 엔드포인트는 그 서비스로 가는 트래픽이 충분히 클 때 유리하며, 트래픽이 적으면 엔드포인트 항목이 NAT 절감분보다 클 수 있습니다.
프로덕션 고려사항
- 인터페이스 엔드포인트를 가용 영역마다 둡니다. 한 가용 영역에만 두면 그 가용 영역 장애 시 호출이 끊기고, 평상시에도 가용 영역을 넘는 전송이 생깁니다.
- 엔드포인트 정책을 기본 전체 허용으로 두지 않습니다. 경로를 좁힌 만큼 권한도 좁히는 것이 일관됩니다.
- 버킷 정책의
aws:SourceVpce조건은 신중하게. 적용 범위를 잘못 잡으면 배포 파이프라인이나 운영 도구가 함께 막힙니다. - 온프레미스에서 접근해야 하면 게이트웨이 엔드포인트로는 안 됩니다. 전용 회선이나 VPN과 인터페이스 엔드포인트를 조합합니다.
- 엔드포인트에도 흐름 로그가 유용합니다. 인터페이스 엔드포인트의 네트워크 인터페이스에서 트래픽을 관측할 수 있습니다.
- 서비스별로 필요한 엔드포인트 목록을 정리해 둡니다. 컨테이너 워크로드라면 ECR·로그·S3 조합이 함께 필요합니다(실습 9).
정리 — 리소스 삭제
aws ec2 delete-vpc-endpoints \
--vpc-endpoint-ids vpce-0gateway000000 vpce-0interface00000
# 게이트웨이 엔드포인트를 지우면 라우팅 테이블의 접두사 목록 경로도 사라집니다.
aws ec2 describe-route-tables \
--route-table-ids rtb-0private0000000a \
--query 'RouteTables[0].Routes[].[DestinationCidrBlock,DestinationPrefixListId,GatewayId]' \
--output table
# 버킷 정책에 엔드포인트 조건을 넣었다면 함께 제거합니다.
aws s3api delete-bucket-policy --bucket example-lab10-data
자주 하는 실수
| 실수 | 증상 | 고치는 법 |
|---|---|---|
| 게이트웨이 엔드포인트를 만들고 라우팅 테이블을 지정하지 않음 | 경로가 추가되지 않아 여전히 NAT로 나간다 | --route-table-ids에 프라이빗 라우팅 테이블을 전부 넣는다 |
| 인터페이스 엔드포인트에 보안 그룹 허용 없음 | 호출이 시간 초과된다 | 워크로드에서 엔드포인트로 향하는 HTTPS를 허용한다 |
| VPC의 DNS 설정이 꺼져 있음 | 프라이빗 DNS가 동작하지 않는다 | DNS 확인과 DNS 호스트 이름을 켠다 |
| 엔드포인트 정책을 기본값으로 방치 | 이 경로로 모든 버킷에 접근할 수 있다 | 필요한 리소스로 정책을 좁힌다 |
| 버킷 정책 조건을 범위 확인 없이 적용 | 콘솔과 운영 도구까지 막힌다 | 접근 주체 목록을 먼저 만들고 예외를 함께 넣는다 |
| 온프레미스에서 게이트웨이 엔드포인트 사용 시도 | 경로가 성립하지 않는다 | 인터페이스 엔드포인트를 쓴다 |
| 엔드포인트를 한 가용 영역에만 | 가용 영역 장애 시 호출이 끊긴다 | 가용 영역마다 서브넷을 지정한다 |
이어서 볼 곳
- 4장 · VPC 연결과 하이브리드 엔드포인트와 PrivateLink, 피어링과 Transit Gateway, 하이브리드 연결을 다룹니다.
- 실습 1 · 3계층 VPC 직접 구성 이 실습이 전제하는 프라이빗 서브넷과 라우팅 테이블을 만듭니다.
- 케이스 6 · 데이터 전송 요금이 예산을 넘겼다 엔드포인트가 NAT 처리량을 줄이는 구조를 비용 관점에서 다룹니다.
- 케이스 4 · 퍼블릭 서브넷에 데이터베이스를 뒀다 인터넷 경로를 없애는 설계가 보안 관점에서 왜 강한지 다룹니다.
- 실습 9 · ECS Fargate 서비스 배포 프라이빗 서브넷 태스크가 이미지와 로그 경로를 확보하는 데 이 구성이 쓰입니다.
공식 문서 출처
- Amazon EC2 API 레퍼런스 — CreateVpcEndpoint
— 엔드포인트 유형(
Gateway·Interface), 라우팅 테이블·서브넷·보안 그룹 지정, 프라이빗 DNS 옵션 - Amazon EC2 API 레퍼런스 — ModifyVpcEndpoint — 엔드포인트 정책 변경과 라우팅 테이블 추가·제거
- Amazon EC2 API 레퍼런스 — DescribeVpcEndpointServices — 리전에서 제공되는 서비스와 유형, 프라이빗 DNS 이름 확인
- Amazon EC2 API 레퍼런스 — DescribeRouteTables — 접두사 목록 대상 경로의 표현
- Amazon S3 API 레퍼런스 — PutBucketPolicy — 조건 키를 사용한 접근 제한
- Amazon VPC 사용 설명서 — NAT 게이트웨이 — 프라이빗 서브넷의 기본 아웃바운드 경로