AWS Client VPN 네이티브 Transit Gateway 연결 검증

검증 테스트 계획: Client VPN 네이티브 Transit Gateway 연결

AWS 공식 문서가 아닙니다. 개인 실습 기록이며 AWS의 입장을 대변하지 않습니다(기준일 2026-10-25). 정확한 정보는 AWS 공식 문서를 확인하세요. 기능 설명은 기능 정리, 실행 결과는 테스트 결과를 참고하세요. 이 문서의 절차와 기대 결과는 2026-10-25 실습 결과를 반영했습니다. T14(비용 확인)는 아직 결과가 없습니다.

1. 목적과 범위

Client VPN 엔드포인트를 Transit Gateway에 직접 연결했을 때 클라이언트 IP가 SNAT 없이 보존되는지 확인하고, 문서에 적힌 동작과 제약을 실제 환경에서 검증합니다.

범위 항목
포함 IPv4, 상호 인증서 인증, 단일 계정, 서울 리전, 소스 IP·포트 보존, VPC 연결 방식과의 비교, 보안 그룹, 분할/전체 터널, 권한 부여 규칙, 다중 VPC, TGW 복귀 경로, 흐름 로그·연결 로그, DNS, 제약 사항(음성 테스트)
제외 IPv6·듀얼 스택, Active Directory·SAML 그룹 권한, RAM 교차 계정, 온프레미스 연결, AZ 추가·제거와 같은 운영·복원력 테스트

2. 테스트 환경

실습 전체 구성도

2.1 주소 계획

대상 CIDR 비고
cvpn-tgw 클라이언트 CIDR 10.100.0.0/22 검증 대상(TGW 연결형, AZ 2a·2c)
cvpn-legacy 클라이언트 CIDR 10.104.0.0/22 비교 대상(VPC 연결형)
Transit Gateway CIDR 블록 10.255.0.0/24 TGW 연결형 엔드포인트에 필수
VPC-A(workload) 10.10.0.0/16 app-a 10.10.1.10
VPC-B(workload) 10.20.0.0/16 app-b 10.20.1.10
Egress VPC 10.30.0.0/16 NAT 게이트웨이(전체 터널, 패키지 설치, SSM)
Legacy hosting VPC 10.40.0.0/16 cvpn-legacy ENI 서브넷 10.40.1.0/24
Client-sim VPC 192.168.100.0/24 TGW 미연결, 인터넷으로 엔드포인트 접속

2.2 구성 요소

스택/스크립트 만드는 자원
scripts/10-certs.sh 실습용 CA, 서버 인증서, client1·client2 인증서(로컬 pki/), ACM에 서버 인증서 가져오기
cvpn-lab-network (infra/network.yaml) TGW(기본 연결·전파 끔), TGW 라우팅 테이블 4개, VPC 5개, TGW VPC 연결 4개, NAT 게이트웨이, EC2 Instance Connect Endpoint(EICE) 3개, 보안 그룹, IAM 역할(SSM, 흐름 로그), TGW·VPC-A 흐름 로그, EC2 4대
cvpn-lab-endpoint-tgw (infra/endpoint-tgw.yaml) + scripts/30-endpoint-tgw.sh TGW 연결형 엔드포인트, 연결 로그, 권한 부여(VPC-A), 라우트(VPC-A·B). client-vpn 연결을 rt-cvpn에 연결하고 rt-spoke·rt-egress에 전파
cvpn-lab-endpoint-legacy (infra/endpoint-legacy.yaml) VPC 연결형 엔드포인트(2a 서브넷 1개), 엔드포인트 SG, 연결 로그

2.3 Transit Gateway 라우팅

라우팅 테이블 연결(association) 전파(propagation) 정적 라우트
rt-cvpn client-vpn 연결 VPC-A, VPC-B 0.0.0.0/0 → Egress, 10.0.0.0/8 블랙홀
rt-spoke VPC-A, VPC-B client-vpn, Legacy 0.0.0.0/0 → Egress, 10.0.0.0/8 블랙홀
rt-legacy Legacy VPC-A 10.0.0.0/8 블랙홀
rt-egress Egress client-vpn, VPC-A, VPC-B, Legacy -

2.4 테스트 호스트와 접속

호스트 역할 확인 수단
app-a, app-b (AL2023) 목적지 서버 nginx가 seen_src=<IP>:<port>로 응답하고 /var/log/nginx/cvpn.log에 기록, tcpdump
client1, client2 (Ubuntu 24.04) VPN 클라이언트 OpenVPN(scripts/40-vpn.sh), curl, dig

3. 비용(서울, 시간당)

항목 수량 시간당
Client VPN 엔드포인트 연결 cvpn-tgw 2 AZ + cvpn-legacy 1 $0.30
Client VPN 연결 최대 2 $0.10
TGW VPC 연결 4 $0.28
TGW client-vpn 연결 1 최대 $0.07(과금 여부 미확인, T14)
NAT 게이트웨이 1 $0.059
EC2 t4g.small 4 $0.083
퍼블릭 IPv4 주소 3(NAT EIP, client1·client2) $0.015
EICE 3 무료
합계   약 $0.84~0.91

CloudWatch Logs 수집·저장 요금(흐름 로그, 연결 로그)과 TGW 데이터 처리 요금은 실습 트래픽 규모에서 미미해 합계에서 뺐습니다.

4. 구축 절차

사전 조건: AWS CLI v2(2.36 이상), jq, openssl, cfn-lint, 실습 계정의 CLI 프로필. 스크립트는 AWS_PROFILE_NAME(기본 default)과 EXPECTED_ACCOUNT(배포할 계정 ID, 필수) 환경 변수를 씁니다. 배포 스크립트는 커밋·push되지 않은 변경이 있으면 멈춥니다.

단계 명령 완료 기준 실측 소요
0 cfn-lint infra/*.yaml 오류 없음 -
1 scripts/10-certs.sh pki/server-cert-arn 생성 1분
2 scripts/20-network.sh 스택 CREATE_COMPLETE, EC2 4대 SSM 온라인 10분
3 scripts/30-endpoint-tgw.sh 엔드포인트 available, routing ready 출력 44분(엔드포인트 22분, 라우트 누락 복구 포함)
4 scripts/35-endpoint-legacy.sh 엔드포인트 available 3단계와 병렬
5 scripts/ssm.sh app-a 'curl -s localhost' server=app-a ... 응답 -

실습에서 확인한 주의 사항

5. 테스트 케이스

명령은 저장소 루트에서 source scripts/env.sh 뒤에 실행합니다.

EP=$(stack_out endpoint-tgw EndpointId); TGW=$(stack_out network TransitGatewayId)
ATT=$(aws_ ec2 describe-transit-gateway-attachments --filters Name=resource-id,Values=$EP \
  --query 'TransitGatewayAttachments[0].TransitGatewayAttachmentId' --output text)
ID 테스트 절차 기대 결과(실측 기준)
T01 엔드포인트 생성과 client-vpn 연결 구축 3단계 동안 describe-client-vpn-endpoints, describe-transit-gateway-attachments --filters Name=resource-type,Values=client-vpn, describe-network-interfaces --filters Name=description,Values="*$EP*", search-transit-gateway-routes(rt-spoke) pending → available. VpcId·SecurityGroupIds 비어 있음. TransitGatewayConfiguration에 TGW ID, 연결 ID, AZ. ResourceType=client-vpn 연결 자동 생성. 고객 VPC에 엔드포인트 ENI 없음. rt-spoke에 클라이언트 CIDR 전파
T02 CLI 매개변수와 AZ 기본값 ① 문서 예시 --transit-gateway-id ② --transit-gateway-configuration TransitGatewayId=$TGW(AZ 미지정)로 생성, AZ 확인 후 삭제 ① Unknown options(문서 예시의 --availability-zone-list도 실제 CLI에 없음) ② AZ 2개 자동 선택(AvailabilityZoneIds로 표시)
T03 소스 IP 보존 40-vpn.sh client1 tgw up → app-a에서 tcpdump -nni ens5 "net 10.100.0.0/22" → client1에서 curl http://10.10.1.10/ → nginx 로그 응답 seen_src, nginx 로그, tcpdump 소스가 모두 client1의 tun IP
T04 VPC 연결 방식 비교 40-vpn.sh client2 legacy up → curl http://10.10.1.10/ seen_src가 cvpn-legacy ENI IP(10.40.1.x)
T05 동시 접속과 소스 포트 두 클라이언트에서 curl --local-port 40000 http://10.10.1.10/를 tgw·legacy로 각각 tgw: 클라이언트별 IP와 포트 40000 보존. legacy: ENI IP로 변환. 문서상 동시 사용자가 같은 대상에 접속하면 PAT가 일어날 수 있음 [D2]
T06 보안 그룹 ① sg-app-a HTTP 규칙을 client1 IP/32로 좁힘 → 두 클라이언트 curl → 원복 ② create-client-vpn-endpoint에 TGW 설정과 --vpc-id/--security-group-ids를 함께 지정 ① client1만 성공 ② 거부(실측은 검증 오류가 아닌 InternalError)
T07 분할·전체 터널 ① 라우트 10.20.0.0/16 삭제 → 재접속 → 클라이언트 라우트 확인 → 대상 서브넷 없이 재생성 ② --no-split-tunnel + 권한 규칙 0.0.0.0/0 + 라우트 0.0.0.0/0 → 재접속 → curl https://checkip.amazonaws.com → 원복. 전체 터널에서는 SSM이 끊길 수 있으므로 EICE로 실행하거나, 연결·확인·해제를 한 명령으로 묶어 실행 ① 삭제 후 클라이언트 라우트에서 빠짐 ② 출구 IP = NAT EIP. 0.0.0.0/0 라우트가 없으면 인터넷 불가
T08 권한 부여와 다중 VPC ① 미승인 VPC-B로 curl http://10.20.1.10/ ② 10.20.0.0/16 승인 → app-a·app-b 호출 ① 시간 초과 ② 두 서버 모두 같은 client IP로 응답
T09 TGW 복귀 경로·분할 ① rt-spoke에서 $ATT 전파 해제 → curl → 재전파 ② rt-cvpn에서 VPC-B 전파 해제 → app-b 호출 → 재전파 ③ TGW 흐름 로그 packets-lost-blackhole ① 실패 후 즉시 복구 ② 실패 후 복구 ③ ①은 app-a 응답이 VPC-A 연결에서, ②는 요청이 client-vpn 연결에서 블랙홀 손실
T10 흐름 로그·연결 로그 TGW 흐름 로그(/cvpn-lab/tgw-flow), VPC-A 흐름 로그(/cvpn-lab/vpc-a-flow), 연결 로그(/cvpn-lab/cvpn-tgw-connection), describe-client-vpn-connections 흐름 로그 srcaddr가 client IP, 연결 로그·연결 목록의 common-name과 IP·시각으로 사용자 특정. 연결 로그는 약 17~23분 늦게 들어옴
T11 DNS client에서 dig @10.10.0.2 amazon.com, dig @10.10.0.2 ip-10-10-1-10.ap-northeast-2.compute.internal(10.10.0.0/16 승인 상태) 실측: VPC 리졸버가 응답하고 사설 이름도 해석(블로그 설명과 다름)
T12 제약 음성 테스트 a TGW 엔드포인트에 서브넷 연결 / b 클라이언트 CIDR이 VPC-A와 겹침 / c TGW CIDR과 겹침 / d CIDR 없는 TGW / e /23 클라이언트 CIDR / f 다른 리전 TGW a·d·e·f는 명확한 오류로 거부. b·c는 거부되지 않고 약 20분 뒤 available(확인 후 삭제)
T13 TGW IP 예약 관찰 10.255.0.0/24 주소를 쓰는 ENI, 흐름 로그 기록 조회 관찰 불가(설계 시 TGW CIDR을 넉넉히)
T14 비용 확인 실습 다음 날 Cost Explorer에서 사용 유형 APN2-TransitGateway-Hours를 작업(operation)별로 묶어 확인. VPC 연결 4개 × 실습 시간을 넘는 사용량이 있으면 client-vpn 연결도 과금 client-vpn 연결의 TGW 시간 요금 여부 확정

6. 정리

실습이 끝나면 다음 순서로 자원을 지웁니다.

  1. OpenVPN 세션 종료(scripts/40-vpn.sh <client> <tgw|legacy> down)
  2. scripts/90-cleanup.sh: 태그가 붙은 CLI 생성 엔드포인트·TGW, 스택 3개, ACM 인증서 삭제
  3. 확인: cvpn-lab 엔드포인트, TGW, NAT 게이트웨이가 남아 있지 않을 것(스크립트 마지막에 출력)