Post

[AWS-Security] 6.2. VPC 엔드포인트와 PrivateLink를 통한 서비스에 대한 접근 보안

[AWS-Security] 6.2. VPC 엔드포인트와 PrivateLink를 통한 서비스에 대한 접근 보안

1. EC2가 SQS에 접근하는 두가지 방법

  1. 과거 (Internet Gateway 사용)
    1. 구조 : EC2를 Public Subnet에 배치하고, Internet Gateway를 배치하여 Public Internet 망으로 나간 뒤 SQS API를 호출한다.
    2. 문제점 : 트래픽이 외부 인터넷을 타고 나가므로 위험에 노출되며, 인스턴스 자체가 Public 환경에 있어 공격 대상이 되기 쉽다.
  2. 최신 (VPC Endpoint 사용)
    1. 구조 : EC2를 외부와 단절된 Private Subnet에 배치하고, 서브넷 안에 인터페이스 VPC Endpoint를 생성한다. 트래픽은 이 엔드포인트를 타고 AWS 내부망을 통해 SQS로 바로 연결된다.
    2. 장점 : Internet Gateway가 필요 없다. 인스턴스가 Private 상태를 유지하므로 외부에서 내부 인스턴스로 접속하는 것이 불가능하다.

2. Public 트래픽의 문제점

  • 잠재적 위협 노출 : 리소스가 인터넷에 노출되면 전 세계 모든 사람이 공격(포트 스캔, 무차별 대입 등)을 시도할 수 있다.
  • 휴먼 에러의 위험성 : Security Group, NACL, NAT Gateway 등 겹겹이 설정해 두더라도, 관리자가 실수로 하나의 라우팅/방화벽 규칙을 잘못 설정하면 순식간에 외부에 노출되는 사고가 발생한다.
  • 원천 차단 : 애초에 VPC에 Internet Gateway를 없애버리면, 우발적인 실수로 인한 노출 위험도도 사라진다.

애플리케이션이 인터넷 접근을 필요로 하는 유일한 이유가 단순히 ‘다른 AWS 서비스(S3, SQS 등)’에 연결하기 위한 것이라면, 무조건 VPC Endpoint를 도입하여 공격 경로를 제거해야 한다.

3. VPC 엔드포인트

3.1. 문제 상황

  • 현재 해당 EC2 인스턴스는 외부와 단절된 Private Subnet에서 실행되고 있다.
  • 추가적인 네트워킹 리소스 (IGW 등)가 없기 때문에 해당 인스턴스는 SQS 서비스에 연결할 수 없는 상태이다. image

3.2. 인터페이스 VPC 엔드포인트 생성

Private Subnet에 위치한 EC2 인스턴스가 SQS와 통신하기 위해 필요한 것은 동일한 VPC 및 서브넷에 ‘SQS용 인터페이스 VPC 엔드포인트’를 생성하는 것이다.

AWS CLI의 create-vpc-endpoint 명령을 통해 생성 가능하며, 전제 조건으로 해당 VPC는 DNS 호스트 이름이 활성화되어 있어야 한다.

1
2
3
4
5
6
7
# SQS용 VPC 엔드포인트 생성
$ aws ec2 create-vpc-endpoint \
    --vpc-id vpc123 \                              # 인스턴스가 있는 VPC의 ID
    --vpc-endpoint-type Interface \                # 대부분의 서비스는 'Interface(인터페이스)'를 사용 (DynamoDB와 S3는 예외)
    --service-name com.amazonaws.us-east-1.sqs \   # 연결할 AWS 서비스의 이름 및 리전 지정
    --subnet-id subnet-123 \                       # 인터페이스 VPC 엔드포인트를 배치할, 인스턴스와 같은 서브넷 ID
    --security-group-id sg-123                     # VPC 엔드포인트에 적용할 보안 그룹

image

3.3. 연결 테스트

1
2
3
# receive message API를 호출해 SQS VPC 엔드포인트 테스트
$ aws sqs receive-message \
    --queue-url https://sqs.us-east-1.amazonaws.com/123456789012/MyQueue  # 접근하려는 대기열의 URL

모든 것이 정상적으로 설정 되었다면, 네트워크 오류나 무단 접근 오류 대신 아래와 같이 SQS 대기열의 실제 메시지(JSON)가 출력 값으로 표시된다.

  • 예시
    1
    2
    3
    4
    5
    6
    7
    8
    9
    
      {
        "Messages": [{
          "Body": "Example SQS message.",
          "ReceiptHandle": "...",
          "MD5OfBody": "...",
          "MessageId": "...",
          ...
        }]
      }
    

3.4. 지원되는 서비스

AWS 내의 여러 서비스는 각각 VPC 엔드포인트를 지원하며, 비슷한 방식으로 구성할 수 있다.

  • Amazon Athena
  • AWS CloudTrail
  • AWS CloudWatch
  • AWS Config
  • AWS Elastic Container Registry
  • AWS Key Management Service
  • Amazon Kinesis
  • Amazon SageMaker
  • AWS Secrets Manager
  • AWS Security Token Service
  • AWS SNS
  • Amazon SQS
  • Amazon S3*
  • Amazon DynamoDB*

3.5. 두 가지 엔드포인트

위 엔드포인트 지원 서비스 중 두 서비스(Amazon S3, Amazon DynamoDB)는 예외 사항으로, 다른 방식의 엔드포인트를 지원한다.

  • 인터페이스 엔드포인트 (대부분의 서비스) : SQS 예제에서 생성한 방식
  • 게이트웨이 엔드포인트 (S3, DynamoDB 전용) : 인터페이스 방식이 아닌, 게이트웨이 엔드포인트 라는 약간 다른 프로세스를 통해 VPC 엔드포인트를 지원한다.

[두 방식의 핵심 차이점]

  1. 위치 : 게이트웨이 엔드포인트는 서브넷 수준이 아닌, VPC 수준에서 동작한다.
  2. 제어 방식(라우팅 테이블) : 인터페이스 엔드포인트는 ‘Security Group’을 사용했지만, 게이트웨이 엔드포인트는 서브넷의 트래픽을 ‘Route table’을 통해 라우팅하는 방식으로 동작한다.

AWS CLI의 create-vpc-endpoint 명령어를 사용할 때 라우팅 테이블 ID를 지정한다. 새 게이트웨이 엔드포인트로 향하는 경로(라우팅)가 포함되도록 라우팅 테이블이 자동으로 업데이트 된다.

4.1. 기능 및 비교

AWS PrivateLink는 API와 같은 자체 서비스를 가진 제공자가 VPC 엔드포인트 서비스를 생성하며, 클라이언트(소비자)가 Public Internet을 거치지 않고 해당 API에 접근할 수 있게 해주는 기능이다.

  • Public Subnet의 애플리케이션 : 트래픽이 Public Internet을 통해 라우팅되므로 리소스가 잠재적인 공격에 취약하다.
  • VPC 피어링 연결
    • 피어링은 두 VPC 간에 양방향 프라이빗 통신을 허용한다.
    • 상대방이 내 VPC의 다른 리소스에도 접근할 위험이 있어 라우팅 테이블과 방화벽을 꼼꼼히 설정해야 한다.
    • 다른 VPC를 완전히 신뢰하지 않는 경우, 권장되지 않는다.
  • PrivateLink 지원 애플리케이션
    • 허용되는 유일한 연결이 ‘단일 엔드포인트에 대한 한 방향(소비자->호스트)’으로만 가능하다.
    • 내 VPC 전체를 열어줄 필요가 없으므로 접근 제한에 대한 걱정이 비교적 적은 안전한 방법이다.

4.2. PrivateLinke 설정

계정 1(제공자)의 Private Subnet에 네트워크 로드 밸런서(NLB) 뒤에서 실행 중인 API가 있고, 계정 2(소비자)가 이 API를 호출하려는 상황을 가정한다.

4.2.1. 계정 1에서 VPC 엔드포인트 구성 생성

자신의 NLB를 가리키는 엔드포인트 서비스 생성

1
2
3
4
5
# VPC 엔드포인트 서비스 구성 생성
$ aws ec2 create-vpc-endpoint-service-configuration \
    --network-load-balancer-arns arn:aws:elasticloadbalancing:us-east-1:123456789012:loadbalancer/net/nlb-vpce/e94221227f1ba532 \ # 애플리케이션 전면에 있는 네트워크 로드 밸런서(NLB)의 ARN
    --acceptance-required \ # 애플리케이션에 대한 VPC 엔드포인트 생성 요청을 수동으로 승인/거부 가능
    --privateDnsName example.com # 고객이 긴 프라이빗 IP 대신 사용할 수 있는 프라이빗 DNS 이름

명령 실행 후 반환되는 ‘서비스 이름(Service name)’ 기록해야함

4.2.2. 계정 2에서 인터페이스 VPC 엔드포인트 연결 요청 생성

소비자는 1단계에서 얻은 ‘서비스 이름’을 사용하여 자신의 VPC에 엔드포인트를 생성한다.

1
2
3
4
5
6
7
# 사용자 지정 서비스 구성에서 신규 VPC 엔드포인트 생성
$ aws ec2 create-vpc-endpoint \
    --vpc-id vpc-ec43eb89 \                  # 인터페이스 VPC 엔드포인트를 생성할 (소비자의) VPC ID
    --vpc-endpoint-type Interface \          # VPC 엔드포인트 서비스에는 항상 인터페이스를 사용함
    --service-name com.amazonaws.vpce.us-east-1.vpce-svc-0e123abc123198abc \ # 1단계에서 생성된 VPC 엔드포인트 서비스의 이름
    --subnet-id subnet-abababab \            
    --security-group-id sg-1a2b3c4d

4.2.3. 계정 1에서 연결 요청 수락

제공자는 대기 중인 요청을 확인하고 승인한다.

1
2
3
4
5
6
7
8
9
10
# VPC 엔드포인트에 대한 대기 중인 연결 요청 나열
$ aws ec2 describe-vpc-endpoint-connections \
    --filters Name=vpc-endpoint-state,Values=pendingAcceptance  # 승인 대기 중인 요청에 대한 필터

# (응답에서 VpcEndpointId와 ServiceId를 확인)

# VPC 엔드포인트 연결 요청 수락
$ aws ec2 accept-vpc-endpoint-connections \
    --service-id vpce-svc-0123abc \
    --vpc-endpoint-ids vpce-0123abc
This post is licensed under CC BY 4.0 by the author.