Published on

AWS VPC 피어링 통신 불가? 라우트·SG·NACL 점검

Authors

VPC 피어링을 만들고 상태가 active인데도 핑이 안 되거나, 특정 포트만 타임아웃이 나는 경우가 꽤 흔합니다. 이유는 단순합니다. VPC 피어링은 “연결”만 제공하고, 실제 데이터 플레인은 각 VPC의 라우팅/보안 정책이 모두 맞아야 열립니다.

이 글은 “왜 안 되지?”에서 “어디가 막혔는지”로 바로 이동할 수 있도록, 라우트 테이블, Security Group, NACL, DNS/서비스별 제약을 순서대로 점검하는 실전 체크리스트를 제공합니다.

아래 내용은 같은 리전/다른 리전 피어링 모두에 적용되며, 특히 EKS나 프라이빗 서브넷 간 통신 문제에도 그대로 쓰입니다. (네트워크 타임아웃이 간헐적으로 보인다면 커널/커넥션 추적 이슈도 함께 볼 가치가 있습니다: EKS conntrack 테이블 포화로 연결 끊김 해결법)

1) 먼저 전제 확인: 피어링이 “가능한 구조”인가

CIDR 겹침(Overlapping CIDR)

VPC 피어링은 두 VPC의 CIDR이 겹치면 성립 자체가 안 되거나(생성 불가), 부분적으로 라우팅이 꼬입니다. 겹치지 않는지 먼저 확인하세요.

  • VPC A: 10.0.0.0/16
  • VPC B: 10.0.0.0/16 또는 10.0.1.0/24 같은 포함 관계면 불가

CLI 예시:

aws ec2 describe-vpcs --vpc-ids vpc-aaaa vpc-bbbb \
  --query 'Vpcs[*].{VpcId:VpcId,Cidr:CidrBlock}' --output table

피어링의 “전이(transitive) 라우팅” 불가

A - B, B - C 피어링이 있어도 A에서 C로는 기본적으로 못 갑니다. “B를 경유해서” 같은 구성은 피어링으로 해결되지 않습니다(Transit Gateway 같은 별도 구성 필요).

보안 장비/프록시를 통한 중간 검사 기대 금지

피어링은 라우팅 레벨 연결이라, VPC 간 트래픽을 중앙 방화벽으로 강제 우회시키는 패턴(헤어핀/인스펙션)은 설계가 따로 필요합니다.

2) 가장 흔한 원인 1순위: 라우트 테이블(양쪽 모두)

피어링은 “양쪽 라우트 테이블”에 상대 CIDR로 향하는 경로가 있어야 합니다. 한쪽만 넣으면 단방향처럼 보이거나, SYN은 가는데 SYN-ACK가 못 돌아오는 형태로 타임아웃이 납니다.

체크 포인트

  • 통신 주체가 속한 서브넷의 라우트 테이블이 맞는지(연결된 RTB 확인)
  • 대상 CIDR이 정확한지(너무 좁거나 넓은 CIDR 실수)
  • 타겟이 pcx-...(피어링 연결)인지
  • 라우트 우선순위(더 구체적인 경로가 다른 곳으로 빠지지 않는지)

CLI로 라우트 확인:

aws ec2 describe-route-tables \
  --filters Name=vpc-id,Values=vpc-aaaa \
  --query 'RouteTables[*].{Rtb:RouteTableId,Routes:Routes[*].{Dest:DestinationCidrBlock,Target:VpcPeeringConnectionId,State:State}}'

라우트 추가(예시):

aws ec2 create-route \
  --route-table-id rtb-aaaa \
  --destination-cidr-block 10.20.0.0/16 \
  --vpc-peering-connection-id pcx-1234567890abcdef

“서브넷 라우트 테이블 착각” 패턴

운영에서 자주 보는 실수는, 피어링 라우트를 “메인 라우트 테이블”에만 넣고 실제 인스턴스가 붙은 서브넷은 다른 RTB를 쓰는 경우입니다.

확인 방법:

aws ec2 describe-route-tables \
  --route-table-ids rtb-aaaa \
  --query 'RouteTables[0].Associations[*].{Subnet:SubnetId,Main:Main,AssocId:RouteTableAssociationId}'

3) Security Group(SG): 상태 기반이지만 “기본 차단”이다

SG는 stateful이라서 “나가는 트래픽 허용 후 응답은 자동 허용” 같은 특성이 있지만, 최초 요청이 들어오는 방향(Inbound)이 막혀 있으면 끝입니다.

체크 포인트

  • 대상 인스턴스/ENI에 붙은 SG의 Inbound에 소스 CIDR이 상대 VPC 대역으로 열려 있는지
  • 포트가 정확한지(예: DB는 5432, Redis는 6379, gRPC는 서비스 포트)
  • SG 참조를 VPC 간에 하려는 실수(피어링 간 SG ID 참조는 조건이 있으며, 계정/리전/설정에 따라 제약이 있어 “CIDR로 여는 편”이 진단이 쉽습니다)

예: VPC B의 DB SG에 VPC A 대역을 허용

aws ec2 authorize-security-group-ingress \
  --group-id sg-db \
  --ip-permissions 'IpProtocol=tcp,FromPort=5432,ToPort=5432,IpRanges=[{CidrIp=10.10.0.0/16,Description="from vpc-a"}]'

“아웃바운드는 열려 있는데 왜 안 되죠?”

클라이언트에서 서버로 접속할 때, 서버 SG Inbound가 막혀 있으면 타임아웃입니다. 반대로 서버가 클라이언트로 콜백하는 구조(웹훅, 액티브-패시브 복제 등)라면 클라이언트 쪽 SG Inbound도 필요합니다.

4) NACL: 무상태(stateless)라서 양방향/에페멀 포트까지 봐야 한다

NACL(Network ACL)은 stateless입니다. 즉, 인바운드를 열었다면 아웃바운드(응답 트래픽)도 별도로 열려 있어야 합니다. 또한 TCP는 서버 포트뿐 아니라 “클라이언트 에페멀 포트” 범위가 필요할 때가 많습니다.

체크 포인트

  • 양쪽 서브넷의 NACL 규칙이 모두 허용인지
  • 인바운드에 서버 포트 허용 + 아웃바운드에 에페멀 포트 허용(또는 그 반대)
  • 규칙 번호 우선순위(작은 번호가 먼저 매칭)
  • 마지막 DENY에 걸리지 않는지

에페멀 포트 범위(대표적으로 리눅스는 32768-60999 또는 49152-65535 등 환경마다 다를 수 있음)를 넉넉히 열어야 진단이 빠릅니다.

예시 정책(개념):

  • 서버 서브넷 NACL Inbound: tcp 5432 from VPC A CIDR allow
  • 서버 서브넷 NACL Outbound: tcp 1024-65535 to VPC A CIDR allow

NACL 조회:

aws ec2 describe-network-acls \
  --filters Name=vpc-id,Values=vpc-bbbb \
  --query 'NetworkAcls[*].{Nacl:NetworkAclId,Entries:Entries}'

5) DNS/이름 해석 문제: “통신 불가”처럼 보이는 대표적 착시

피어링이 열려도 애플리케이션이 db.internal 같은 프라이빗 DNS 이름으로 접근한다면, 실제 문제는 라우팅이 아니라 DNS일 수 있습니다.

체크 포인트

  • 상대 VPC의 Private Hosted Zone을 공유/연결했는지(Route 53 PHZ association)
  • 피어링 연결에서 DNS resolution 옵션이 필요한지(요구되는 경우가 있음)
  • 클라이언트가 어떤 DNS 서버를 쓰는지(VPC 기본 DNS인지, 커스텀인지)

진단 순서:

  1. 먼저 IP로 직접 접속 시도(이게 되면 네트워크는 열렸고 DNS 문제)
  2. dig 또는 nslookup으로 레코드가 어디로 해석되는지 확인
dig +short db.internal.example.com

6) “핑은 안 되는데 TCP는 되네요” 또는 그 반대

  • ICMP(ping)는 SG/NACL에서 별도로 허용해야 합니다. 보안 정책상 ICMP를 막아두는 경우가 많아, “핑 실패”만으로 피어링 장애라고 결론 내리면 안 됩니다.
  • 반대로 TCP는 특정 포트만 열려 있으면 일부만 됩니다.

권장 테스트:

  • TCP 포트 테스트: nc 또는 curl
# TCP 포트 열림 확인
nc -vz 10.20.1.10 5432

# HTTP 계열이면 curl
curl -m 2 -v http://10.20.1.20:8080/health

7) MTU/단편화 이슈: “큰 패킷만” 실패하는 케이스

피어링 자체는 일반적으로 MTU 문제가 드물지만, 다음 조합에서는 이슈가 튀어나올 수 있습니다.

  • 인스턴스/컨테이너가 Jumbo frame을 강제하거나
  • 터널링(예: 일부 CNI/오버레이), VPN, 프록시 체인이 섞여서 실제 경로 MTU가 줄어든 경우

증상은 보통 “TLS 핸드셰이크가 간헐적으로 멈춤”, “큰 응답에서만 끊김” 같은 형태입니다. 이 경우는 tracepath나 패킷 캡처로 확인합니다.

8) 피어링으로는 안 되는 트래픽: 서비스 제약 정리

피어링은 VPC 간 사설 IP 라우팅입니다. 하지만 다음 요구사항은 피어링만으로 해결되지 않거나 별도 옵션이 필요할 수 있습니다.

  • 중앙집중식 egress/ingress(전이 라우팅 필요)
  • 온프레미스 - VPC A - VPC B 형태로 라우팅 공유(피어링은 전이 불가)
  • 일부 매니지드 서비스 접근은 PrivateLink/엔드포인트가 더 적합

EKS 환경에서 “노드에서만 되고 파드에서 안 된다” 같은 케이스는 CNI 라우팅, 소스 NAT, 보안 정책이 겹쳐 보일 수 있습니다. 이럴 때는 네트워크 자체 차단 여부를 먼저 확정한 다음, 워크로드 레벨로 내려가세요. (EKS 운영 중 보안 경계를 강화해야 한다면: EKS에서 AWS SDK의 IMDS 접근을 확실히 차단하는 법)

9) 10분 진단 체크리스트(현장용)

아래 순서대로 보면 대부분 10분 내 원인이 좁혀집니다.

1) 경로 확인

  • 소스 인스턴스(또는 파드)의 IP/서브넷/라우트 테이블 ID 확인
  • 대상 인스턴스의 IP/서브넷/라우트 테이블 ID 확인
  • 양쪽 RTB에 상대 CIDR -> 피어링(pcx-...) 라우트 존재 확인(부등호 포함 표현은 인라인 코드로 처리)

2) 보안 정책 확인

  • 대상 SG Inbound: 소스 CIDR, 포트 허용
  • 소스 SG Outbound: 대상 CIDR, 포트 허용(기본 전체 허용이 아니라면 필수)
  • 양쪽 NACL: 인바운드/아웃바운드 모두 허용 + 에페멀 포트 고려

3) DNS 착시 제거

  • IP로 먼저 접속 테스트
  • 이름으로 접속이 실패하면 Route 53/피어링 DNS 옵션/리졸버 확인

4) 로그/패킷으로 확정

  • 인스턴스에서 tcpdump로 SYN이 나가는지, SYN-ACK가 돌아오는지 확인
  • VPC Flow Logs를 켜서 ACCEPT/REJECT 확인(특히 NACL/SG에서 거부되는지)

tcpdump 예시:

sudo tcpdump -ni eth0 host 10.20.1.10 and tcp port 5432

10) 실전 예시: “A에서 B의 RDS로 접속이 안 됨”

상황:

  • VPC A 앱 서버 10.10.1.50
  • VPC B RDS 프라이빗 IP 10.20.2.10 (또는 내부 엔드포인트)
  • 피어링 pcx-1234active

점검:

  1. VPC A의 앱 서브넷 RTB에 10.20.0.0/16 대상 라우트가 pcx-1234로 있는지
  2. VPC B의 DB 서브넷 RTB에 10.10.0.0/16 대상 라우트가 pcx-1234로 있는지
  3. DB SG Inbound에 tcp 5432 from 10.10.0.0/16 허용인지
  4. DB 서브넷 NACL에서 tcp 5432 인바운드 허용, tcp 1024-65535 아웃바운드 허용인지
  5. 앱 서버에서 nc -vz 10.20.2.10 5432로 포트 테스트

이 중 2) “리턴 라우트”가 빠져 있는 경우가 정말 많습니다. 요청은 가도 응답이 못 돌아와서 타임아웃이 나기 때문입니다.

마무리

VPC 피어링 통신 장애는 대부분 “연결 상태”가 아니라 “라우트/SG/NACL/DNS 중 하나가 빠진 상태”입니다. 특히 라우트는 반드시 양쪽에 있어야 하고, NACL은 stateless라 응답 방향과 에페멀 포트까지 같이 봐야 합니다.

운영 환경에서 증상이 간헐적이거나 특정 시간대에만 발생한다면, 네트워크 정책 외에도 커널 리소스(예: conntrack) 같은 시스템 요인을 함께 의심해야 합니다. 위 체크리스트로 먼저 ‘정책상 막힘’인지 ‘리소스/성능 이슈’인지 경계를 확정하면, 문제 해결 속도가 크게 빨라집니다.