AWS - Network 연결 옵션 (4): Route 53 DNS Resolver (DNS 해석기)


이 포스트는 하이브리드 환경에서 온프레미스와 VPC 간 DNS 쿼리가 가능하도록 해주는 Route 53 Resolver 에 대해 알아본다.

본 포스트는 AWS - Load Balancing (2): Route 53, AWS - Network 연결 옵션 (1): VPC Peering 와 함께 보시면 도움이 됩니다.


아래는 이번 포스트에서 다뤄볼 범위 도식화이다.

이번 포스트 범위 도식화


1. VPC DNS

Private Hosted Zones (Private 호스팅 영역) 은 AWS VPC 로 생성한 도메인과 그 하위 도메인에 대해 AWS Route 53 의 DNS 쿼리 응답 정보 (DNS 정보가 담긴 Zone 파일) 가 담긴 일종의 컨테이너이다.

VPC DNS 옵션은 아래와 같이 2개가 있다.

  • DNS resolution
    • 비활성화 시 AWS 제공 DNS Resolver 사용 불가
  • DNS hostnames
    • AWS 제공 Public/Private Hostname 사용
    • 비활성화 시 AWS 제공 Hostname 사용 불가

VPC DNS 옵션

nameserver, hostname 확인

# EC2 Public IP, VPC 20.70.0.0/16 사용
$ ssh -i sandbox-jh.pem ec2-user@15.165.xxx.xxx

# EC2 에 설정된 DNS 서버 확인
[ec2-user@WEBSRV1 ~]$ cat /etc/resolv.conf
; generated by /usr/sbin/dhclient-script
search ap-northeast-2.compute.internal # <-- 도메인 네임
options timeout:2 attempts:5
nameserver 20.70.0.2 # <-- 네임 서버

# Private & Public Hostname 확인
[ec2-user@WEBSRV1 ~]$ dig +short ip-20-70-1-100.ap-northeast-2.compute.internal  # private
20.70.1.100
[ec2-user@WEBSRV1 ~]$ dig +short ec2-15-165-19-76.ap-northeast-2.compute.amazonaws.com  # public
20.70.1.100
[ec2-user@WEBSRV1 ~]$ ping ip-20-70-1-100
PING ip-20-70-1-100.ap-northeast-2.compute.internal (20.70.1.100) 56(84) bytes of data.
64 bytes from ip-20-70-1-100.ap-northeast-2.compute.internal (20.70.1.100): icmp_seq=1 ttl=255 time=0.013 ms

VPC DHCP option set 를 통해 도메인 네임과 도메인 네임 서버 정보를 제공한다.
원하는 도메인 네임과 도메인 네임 서버 정보를 지정한 DHCP option set 를 생성하여 VPC 에 적용 가능하다. VPC DHCP option set

Private Hosted Zones 존재 시 AWS 제공 DNS Resolver 는 해당 영역에 DNS 쿼리를 한다.
Private Hosted Zones 과 여러 VPC 를 연결하여 DNS 쿼리를 할 수도 있는데 타 계정의 VPC 연결은 AWS CLI, AWS SDK, AWS Route 53 API 등을 통해 가능하다.

VPC DNS 는 Private Hosted Zones DNS 쿼리가 Public Hosted Zones DSN 쿼리보다 우선하며,
EC2 Instance 는 Route 53 Resolver 에 초당 최대 1,024 개의 요청을 보낼 수 있다.


2. Route 53 Resolver (해석기)

온프레미스와 VPC 간에 DNS 쿼리는 불가능한데 이 때 Route 53 ResolverConditional forwarding rules (전달 규칙) 을 사용하면 서로 간 DNS 쿼리가 가능하다.
Route 53 Resolver 를 사용하려면 VPC DNS 옵션 중 DNS HostnameDNS Resolution 을 활성화해야 한다.

2.1. Route 53 Resolver 관련 용어

Forwarding Rule (전달 규칙)

다른 네트워크 환경에 도메인 쿼리를 하기 위한 정보이다.

Inbound Endpoint

AWS VPC 에 DNS 쿼리를 받을 수 있는 ENI (Elastic Network Interface) 이다.

Outbound Endpoint

Forwarding Rule 을 다른 네트워크로 쿼리할 수 있는 ENI 이다.


2.2. 하이브리드 환경에서 Route 53 Resolver 동작

  • 온프레미스에서 AWS 로 DNS 쿼리를 할 경우
    • Inbound Endpoint 를 생성하여 해당 Endpoint 로 DNS 쿼리
  • AWS 에서 온프레미스로 DNS 쿼리를 할 경우
    • Outbound Endpoint 를 생성하여 해당 Endpoint 로 DNS 쿼리
    • Outbound Endpoint 는 반드시 Forwarding Rule 를 생성하여 VPC 에 연결해야 하며, 만일 타 계정의 VPC 는 AWS RAM (Resource Access Manager) 를 이용해서 연결 가능

2.3. Route 53 Resolver 규칙 유형

  • Conditional forwarding rules (전달 규칙)
    • 지정한 IP (=DNS 서버) 로 특정 도메인에 대한 쿼리 전달
  • System rules (시스템 규칙)
    • Private Hosted Zones (Private DNS), Auto defined VPC DNS (ap-northeast-2.compute.internal 등) 이 있으며 System rules 는 Conditional forwarding rules 보다 우선함

3. Route 53 Resolver - Query Logs

기존에는 Public 영역에 대한 DNS 쿼리 로깅만 가능했지만 Route 53 Resolver Query Logs 를 사용하면 VPC 내의 모든 Resource (EC2, Lambda 등) 에서 DNS 쿼리를 보내는 경우에도 로깅이 가능하다.
Query Logs 는 CloudWatch Logs(LogInsights), S3, Kinesis Data Firehose 에 보낼 수 있다.


4. Route 53 DNS Resolver 테스트

AWS 내부망과 IDC 내부망 간 하이브리드 클라우드 환경을 구성하여 Private 도메인 주소로 통신하는 구성을 해본다.

Route 53 Resolver Endpoint 는 한 개당 1시간에 $0.125 비용 발생!!

  • 기본 환경 구성
    • CloudFormation 적용
    • CloudFormation 을 통해 생성된 자원 확인
    • 기본 통신 환경 검증
      • bbAWS-VPC1 에서 기본 환경 검증
        • bbAWS-WEBSRV1 Instance 확인
        • Route 53 Private Hosted Zone 확인
        • Public Routing Table, VPC Peering 확인
      • bbIDC-VPC2 에서 기본 환경 검증
        • DHCP Option Set 확인
        • bbIDC-DNSSRV(DNS 서버) Instance 확인
        • bbIDC-WEBSRV Instance 확인
        • Public Routing Table, VPC Peering 확인
  • Inbound DNS 쿼리 전달
    • Inbound Endpoint 설정
    • Inbound DNS 쿼리 전달 동작 확인
  • Outbound DNS 쿼리 전달
    • Outbound Endpoint 설정
    • 전달 규칙 설정
    • Outbound DNS 쿼리 전달 동작 확인
  • Resource 삭제

목표 구성도


4.1. 기본 환경 구성

  • CloudFormation 적용
  • CloudFormation 을 통해 생성된 자원 확인
  • 기본 통신 환경 검증
    • bbAWS-VPC1 에서 기본 환경 검증
      • bbAWS-WEBSRV1 Instance 확인
      • Route 53 Private Hosted Zone 확인
      • Public Routing Table, VPC Peering 확인
    • bbIDC-VPC2 에서 기본 환경 검증
      • DHCP Option Set 확인
      • bbIDC-DNSSRV(DNS 서버) Instance 확인
      • bbIDC-WEBSRV Instance 확인
      • Public Routing Table, VPC Peering 확인
    • 기본 환경 검증 종합

기본 환경 구성도


4.1.1. CloudFormation 적용

[CloudFormation] - [Stacks]

CloudFormation Template Download

CloudFormation Template (펼쳐보기)
Parameters:
  KeyName:
    Description: Name of an existing EC2 KeyPair to enable SSH access to the instances. Linked to AWS Parameter
    Type: AWS::EC2::KeyPair::KeyName
    ConstraintDescription: must be the name of an existing EC2 KeyPair.
  LatestAmiId:
    Description: (DO NOT CHANGE)
    Type: 'AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>'
    Default: '/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2'
    AllowedValues:
      - /aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2

Resources:
  VPC1:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: 20.70.0.0/16
      EnableDnsSupport: true
      EnableDnsHostnames: true
      Tags:
        - Key: Name
          Value: bbAWS-VPC1
  InternetGateway1:
    Type: AWS::EC2::InternetGateway
    Properties:
      Tags:
        - Key: Name
          Value: bbAWS-IGW1
  InternetGatewayAttachment1:
    Type: AWS::EC2::VPCGatewayAttachment
    Properties:
      InternetGatewayId: !Ref InternetGateway1
      VpcId: !Ref VPC1

  PrivateDNS1:
    Type: AWS::Route53::HostedZone
    DependsOn: VPC1
    Properties:
      HostedZoneConfig:
        Comment: Private hosted zone for awsneta.net
      Name: awsneta.internal
      VPCs:
        - VPCId: !Ref VPC1
          VPCRegion: ap-northeast-2
      HostedZoneTags:
        - Key: Name
          Value: bbawsnetadomain

  RouteTable1:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref VPC1
      Tags:
        - Key: Name
          Value: bbAWS-PublicRT
  DefaultRoute1:
    Type: AWS::EC2::Route
    DependsOn: InternetGatewayAttachment1
    Properties:
      RouteTableId: !Ref RouteTable1
      DestinationCidrBlock: 0.0.0.0/0
      GatewayId: !Ref InternetGateway1

  Subnet1:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC1
      AvailabilityZone: !Select [0, !GetAZs '']
      MapPublicIpOnLaunch: true
      CidrBlock: 20.70.1.0/24
      Tags:
        - Key: Name
          Value: bbAWS-VPC1-Subnet1
  Subnet1RouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      RouteTableId: !Ref RouteTable1
      SubnetId: !Ref Subnet1
  Subnet2:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC1
      AvailabilityZone: !Select [2, !GetAZs '']
      MapPublicIpOnLaunch: true
      CidrBlock: 20.70.2.0/24
      Tags:
        - Key: Name
          Value: bbAWS-VPC1-Subnet2
  Subnet2RouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      RouteTableId: !Ref RouteTable1
      SubnetId: !Ref Subnet2

  VPC2:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: 20.80.0.0/16
      EnableDnsSupport: false
      EnableDnsHostnames: false
      Tags:
        - Key: Name
          Value: bbIDC-VPC2
  VPC2DNSOptions:
    Type: AWS::EC2::DHCPOptions
    Properties:
      DomainName: idcneta.internal
      DomainNameServers:
        - 20.80.1.200
        - 8.8.8.8
      NtpServers:
        - 203.248.240.140
        - 168.126.3.6
      Tags:
        - Key: Name
          Value: IDC-VPC2-DHCPOptions
  VPC2DNSOptionsAssociation:
    Type: AWS::EC2::VPCDHCPOptionsAssociation
    Properties:
      DhcpOptionsId: !Ref VPC2DNSOptions
      VpcId: !Ref VPC2

  InternetGateway2:
    Type: AWS::EC2::InternetGateway
    Properties:
      Tags:
        - Key: Name
          Value: bbIDC-IGW2
  InternetGatewayAttachment2:
    Type: AWS::EC2::VPCGatewayAttachment
    Properties:
      InternetGatewayId: !Ref InternetGateway2
      VpcId: !Ref VPC2

  RouteTable3:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref VPC2
      Tags:
        - Key: Name
          Value: bbIDC-PublicRT
  DefaultRoute3:
    Type: AWS::EC2::Route
    DependsOn: InternetGatewayAttachment2
    Properties:
      RouteTableId: !Ref RouteTable3
      DestinationCidrBlock: 0.0.0.0/0
      GatewayId: !Ref InternetGateway2
  Subnet3:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC2
      AvailabilityZone: !Select [0, !GetAZs '']
      CidrBlock: 20.80.1.0/24
      Tags:
        - Key: Name
          Value: bbIDC-VPC2-Subnet
  Subnet3RouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      RouteTableId: !Ref RouteTable3
      SubnetId: !Ref Subnet3

  VPCPeering:
    Type: AWS::EC2::VPCPeeringConnection
    Properties:
      VpcId: !Ref VPC1
      PeerVpcId: !Ref VPC2
      Tags:
        - Key: Name
          Value: bbVPCPeering

  PeeringRoute1:
    Type: AWS::EC2::Route
    Properties:
      DestinationCidrBlock: 20.80.0.0/16
      RouteTableId: !Ref RouteTable1
      VpcPeeringConnectionId: !Ref VPCPeering

  PeeringRoute2:
    Type: AWS::EC2::Route
    Properties:
      DestinationCidrBlock: 20.70.0.0/16
      RouteTableId: !Ref RouteTable3
      VpcPeeringConnectionId: !Ref VPCPeering

  Instance3ENIEth0:
    Type: AWS::EC2::NetworkInterface
    Properties:
      SubnetId: !Ref Subnet3
      Description: Instance3 eth0
      GroupSet:
        - !Ref SG3
      PrivateIpAddress: 20.80.1.200
      Tags:
        - Key: Name
          Value: bbIDC-DNSSRV eth0
  VPCEIP3:
    Type: AWS::EC2::EIP
    Properties:
      Domain: vpc
  VPCAssociateEIP3:
    Type: AWS::EC2::EIPAssociation
    Properties:
      AllocationId: !GetAtt VPCEIP3.AllocationId
      NetworkInterfaceId: !Ref Instance3ENIEth0

  Instance1:
    Type: AWS::EC2::Instance
    Properties:
      ImageId: !Ref LatestAmiId
      InstanceType: t2.micro
      KeyName: !Ref KeyName
      Tags:
        - Key: Name
          Value: bbAWS-WEBSRV1
      NetworkInterfaces:
        - DeviceIndex: 0
          SubnetId: !Ref Subnet1
          GroupSet:
            - !Ref SG1
          PrivateIpAddress: 20.70.1.100
      UserData:
        Fn::Base64: |
          #!/bin/bash
          hostnamectl --static set-hostname WEBSRV1
          sed -i "s/localhost4.localdomain4/localhost4.localdomain4 WEBSRV1/g" /etc/hosts
          yum -y install tcpdump httpd
          systemctl start httpd && systemctl enable httpd
          echo "<h1>CloudNet@ AWS Web Server 1 - 20.70.1.100 - websrv1.awsneta.internal</h1>" > /var/www/html/index.html

  Instance2:
    Type: AWS::EC2::Instance
    Properties:
      ImageId: !Ref LatestAmiId
      InstanceType: t2.micro
      KeyName: !Ref KeyName
      Tags:
        - Key: Name
          Value: bbAWS-WEBSRV2
      NetworkInterfaces:
        - DeviceIndex: 0
          SubnetId: !Ref Subnet2
          GroupSet:
            - !Ref SG1
          PrivateIpAddress: 20.70.2.100
      UserData:
        Fn::Base64: |
          #!/bin/bash
          hostnamectl --static set-hostname WEBSRV2
          sed -i "s/localhost4.localdomain4/localhost4.localdomain4 WEBSRV2/g" /etc/hosts
          yum -y install tcpdump httpd
          systemctl start httpd && systemctl enable httpd
          echo "<h1>CloudNet@ AWS Web Server 2 - 20.70.2.100 - websrv2.awsneta.internal</h1>" > /var/www/html/index.html

  Instance3:
    Type: AWS::EC2::Instance
    Properties:
      ImageId: ami-07b7be0099924913e
      InstanceType: t2.micro
      KeyName: !Ref KeyName
      Tags:
        - Key: Name
          Value: bbIDC-DNSSRV
      NetworkInterfaces:
        - NetworkInterfaceId: !Ref Instance3ENIEth0
          DeviceIndex: 0
      UserData:
        Fn::Base64: |
          #!/bin/bash
          hostnamectl --static set-hostname DNSSRV
          sed -i "s/^127.0.0.1 localhost/127.0.0.1 localhost DNSSRV/g" /etc/hosts
          apt-get update -y
          apt-get install bind9 bind9-doc language-pack-ko -y
          # named.conf.options
          cat <<EOF> /etc/bind/named.conf.options
          options {
             directory "/var/cache/bind";
             recursion yes;
             allow-query { any; };
             forwarders {
                   8.8.8.8;
                    };
              forward only;
              auth-nxdomain no;
          };
          zone "awsneta.internal" {
              type forward;
              forward only;
              forwarders { 20.70.1.250; 20.70.2.250; };
          };
          zone "ap-northeast-2.compute.internal" {
              type forward;
              forward only;
              forwarders { 20.70.1.250; 20.70.2.250; };
          };
          EOF
          # named.conf.local
          cat <<EOF> /etc/bind/named.conf.local
          zone "idcneta.internal" {
              type master;
              file "/etc/bind/db.idcneta.internal"; # zone file path
          };

          zone "80.20.in-addr.arpa" {
              type master;
              file "/etc/bind/db.20.80";  # 20.80.0.0/16 subnet
          };
          EOF
          # db.idcneta.internal
          cat <<EOF> /etc/bind/db.idcneta.internal
          \$TTL 30
          @ IN SOA idcneta.internal. root.idcneta.internal. (
            2019122114 ; serial
            3600       ; refresh
            900        ; retry
            604800     ; expire
            86400      ; minimum ttl
          )

          ; dns server
          @      IN NS ns1.idcneta.internal.

          ; ip address of dns server
          ns1    IN A  20.80.1.200

          ; Hosts
          websrv   IN A  20.80.1.100
          dnssrv   IN A  20.80.1.200
          EOF
          # db.20.80
          cat <<EOF> /etc/bind/db.20.80
          \$TTL 30
          @ IN SOA idcneta.internal. root.idcneta.internal. (
            2019122114 ; serial
            3600       ; refresh
            900        ; retry
            604800     ; expire
            86400      ; minimum ttl
          )

          ; dns server
          @      IN NS ns1.idcneta.internal.

          ; ip address of dns server
          3      IN PTR  ns1.idcneta.internal.

          ; A Record list
          100.1    IN PTR  websrv.idcneta.internal.
          200.1    IN PTR  dnssrv.idcneta.internal.
          EOF
          # bind9 service start
          systemctl start bind9 && systemctl enable bind9

  Instance4:
    Type: AWS::EC2::Instance
    DependsOn: Instance3
    Properties:
      ImageId: !Ref LatestAmiId
      InstanceType: t2.micro
      KeyName: !Ref KeyName
      Tags:
        - Key: Name
          Value: bbIDC-WEBSRV
      NetworkInterfaces:
        - DeviceIndex: 0
          SubnetId: !Ref Subnet3
          GroupSet:
            - !Ref SG4
          PrivateIpAddress: 20.80.1.100
          AssociatePublicIpAddress: true
      UserData:
        Fn::Base64: |
          #!/bin/bash
          hostnamectl --static set-hostname WEBSRV
          sed -i "s/localhost4.localdomain4/localhost4.localdomain4 WEBSRV/g" /etc/hosts
          yum -y install tcpdump httpd
          systemctl start httpd && systemctl enable httpd
          echo "<h1>CloudNet@ IDC Web Server - 20.80.1.100 - websrv.idcneta.internal</h1>" > /var/www/html/index.html

  SG1:
    Type: AWS::EC2::SecurityGroup
    Properties:
      VpcId: !Ref VPC1
      GroupDescription: VPC1-AWS-WEBSRV-SG
      Tags:
        - Key: Name
          Value: bbVPC1-AWS-WEBSRV-SG
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: '22'
          ToPort: '22'
          CidrIp: 0.0.0.0/0
        - IpProtocol: tcp
          FromPort: '80'
          ToPort: '80'
          CidrIp: 0.0.0.0/0
        - IpProtocol: icmp
          FromPort: -1
          ToPort: -1
          CidrIp: 0.0.0.0/0

  SG2:
    Type: AWS::EC2::SecurityGroup
    Properties:
      VpcId: !Ref VPC1
      GroupDescription: VPC1-Route53-Resolver-SG
      Tags:
        - Key: Name
          Value: bbVPC1-Route53-Resolver-SG
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: '53'
          ToPort: '53'
          CidrIp: 20.0.0.0/8
        - IpProtocol: udp
          FromPort: '53'
          ToPort: '53'
          CidrIp: 20.0.0.0/8
        - IpProtocol: icmp
          FromPort: -1
          ToPort: -1
          CidrIp: 0.0.0.0/0

  SG3:
    Type: AWS::EC2::SecurityGroup
    Properties:
      VpcId: !Ref VPC2
      GroupDescription: VPC2-IDC-DNSSRV-SG
      Tags:
        - Key: Name
          Value: bbVPC2-IDC-DNSSRV-SG
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: '22'
          ToPort: '22'
          CidrIp: 0.0.0.0/0
        - IpProtocol: udp
          FromPort: '53'
          ToPort: '53'
          CidrIp: 20.0.0.0/8
        - IpProtocol: tcp
          FromPort: '53'
          ToPort: '53'
          CidrIp: 20.0.0.0/8
        - IpProtocol: icmp
          FromPort: -1
          ToPort: -1
          CidrIp: 0.0.0.0/0

  SG4:
    Type: AWS::EC2::SecurityGroup
    Properties:
      VpcId: !Ref VPC2
      GroupDescription: VPC2-IDC-WEBSRV-SG
      Tags:
        - Key: Name
          Value: bbVPC2-IDC-WEBSRV-SG
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: '22'
          ToPort: '22'
          CidrIp: 0.0.0.0/0
        - IpProtocol: tcp
          FromPort: '80'
          ToPort: '80'
          CidrIp: 0.0.0.0/0
        - IpProtocol: icmp
          FromPort: -1
          ToPort: -1
          CidrIp: 0.0.0.0/0

  DNSRecordInstance1:
    Type: AWS::Route53::RecordSet
    Properties:
      HostedZoneId: !Ref PrivateDNS1
      Comment: DNS name for AWS WEBSRV1 instance.
      Name: websrv1.awsneta.internal
      Type: A
      TTL: 60
      ResourceRecords:
        - !GetAtt Instance1.PrivateIp

  DNSRecordInstance2:
    Type: AWS::Route53::RecordSet
    Properties:
      HostedZoneId: !Ref PrivateDNS1
      Comment: DNS name for AWS WEBSRV2 instance.
      Name: websrv2.awsneta.internal
      Type: A
      TTL: 60
      ResourceRecords:
        - !GetAtt Instance2.PrivateIp

Outputs:
  AWSWEBServer1IP:
    Description: Public IP assigned to AWS WEBSRV1 Instance eth0 interface
    Value: !GetAtt Instance1.PublicIp
  AWSWEBServer2IP:
    Description: Public IP assigned to AWS WEBSRV2 Instance eth0 interface
    Value: !GetAtt Instance2.PublicIp
  IDCDNSSRVInstanceEIP:
    Description: Elastic IP assigned to IDC DNSSRV Instance eth0 interface
    Value: !GetAtt Instance3.PublicIp
  IDCWEBServerIP:
    Description: Public IP assigned to IDC WEBSRV Instance eth0 interface
    Value: !GetAtt Instance4.PublicIp

key pair 생성은 AWS - Infra3. 사전 준비 를 참고하세요.

ICMP (Internet Group Management Protocol)
ICMP 는 TCP/IP 에서 IP 패킷 처리 시 발생되는 문제를 알려주는 프로토콜임.
IP 에는 오로지 패킷을 목적지에 도달시키지 위한 내용들로만 구성이 되어 있기 때문에 정상적으로 목적지 도달 시 IP 에서 통신 성공 후 종료되므로 아무런 문제가 없지만, 목적지가 꺼져있거나 비정상인 경우 패킷 전달을 의뢰한 출발지에 이 사실을 알릴 수가 없음. (IP 에는 이러한 에러에 대한 처리 방법이 명시되지 있지 않으므로)

이러한 IP 의 부족한 점을 보완하는 것이 ICMP 프로토콜임.

예를 들어 ping 같은 경우도 ICMP 프로토콜을 이용한 방법임.


4.1.2. CloudFormation 을 통해 생성된 자원 확인

  • VPC
    • bbAWS-VPC1
      • IP CIDR: 20.70.0.0/16
    • bbIDC-VPC2
      • IP CIDR: 20.80.0.0/16
      • DHCP option sets 사용자 지정
  • IGW
    • bbAWS-IGW1
      • 연결: bbAWS-VPC1
    • bbIDC-IGW2
      • 연결: bbIDC-VPC2
  • Route 53 Hosted Zones
    • awsneta.internal
      • Record name: websrv1.awsneta.internal(A) → 20.70.1.100
      • Record name: websrv2.awsneta.internal(A) → 20.70.2.100
  • Public Subnet
    • bbAWS-VPC1-Subnet1
      • IP CIDR: 20.70.1.0/24
      • AZ: ap-northeast-2a
    • bbAWS-VPC1-Subnet2
      • IP CIDR: 20.70.2.0/24
      • AZ: ap-northeast-2c
    • bbIDC-VPC2-Subnet
      • IP CIDR: 20.80.1.0/24
      • AZ: ap-northeast-2a
  • Public Routing Table
    • bbAWS-PublicRT
      • 연결: bbAWS-VPC1-Subnet1, bbAWS-VPC1-Subnet2
      • 라우팅 정보
        • 대상: 0.0.0.0/0, 타깃: bbAWS-IGW1
        • 대상: 20.80.0.0/16, 타깃: PCX-# (VPC Peering)
    • bbIDC-PublicRT
      • 연결: bbIDC-VPC2-Subnet
      • 라우팅 정보
        • 대상: 0.0.0.0/0, 타깃: bbIDC-IGW2
        • 대상: 20.70.0.0/16, 타깃: PCX-# (VPC Peering)
  • VPC Peering
    • bbVPCPeering
      • bbAWS-VPC1 과 bbIDC-VPC2 간 연결 및 수락
  • EC2 Instance
    • bbAWS-WEBSRV1
      • 연결: bbAWS-VPC1-Subnet1
      • 웹 서비스 동작
      • Private IP: 20.70.1.100 (Public IP 사용)
    • bbAWS-WEBSRV2
      • 연결: bbAWS-VPC1-Subnet2
      • 웹 서비스 동작
      • Private IP: 20.70.2.100 (Public IP 사용)
    • bbIDC-DNSSRV
      • 연결: bbIDC-VPC2-Subnet
      • Private IP: 20.80.1.200 (EIP 사용)
      • DNS 서버 (bind9) 동작
        • Record name: websrv.idcneta.internal(A) → 20.80.1.100
        • Record name: dnssrv.idcneta.internal(A) → 20.80.1.200
        • zone ‘awsneta.internal’ forwarder → 20.70.1.252, 20.70.2.250
    • bbIDC-WEBSRV
      • 연결: bbIDC-VPC2-Subnet
      • 웹 서비스 동작
      • Private IP: 20.80.1.100 (Public IP 사용)
  • Security Group
    • bbVPC1-AWS-WEBSRV-SG
      • inbound rule
        • SSH/HTTP(Source) - 0.0.0.0/0
        • ICMP(Source) - 0.0.0.0/0
    • bbVPC1-Route53-Resolver-SG
      • inbound rule
        • SSH/HTTP(Source) - 0.0.0.0/0
        • ICMP(Source) - 0.0.0.0/0

VPC 영역별로 내용을 보자.

기본 환경 구성도

AWS 영역

  • Route 53 Private Hosted Zone 영역 (bbAWS-VPC1 연결)
    • ‘awsneta.internal’ 도메인에 대한 DNS 서비스 제공
    • A Record참고(웹서버의 Private IP) 생성
  • Public Instance (bbAWS-WEBSRC1,2)
    • 2대 모두 웹서버 동작
  • Public Routing Table (bbAWS-PublicRT)
    • VPC Peering 을 통해 IDC 영역과 통신 가능

Record 대한 내용은 AWS - Load Balancing (2): Route 531. DNS (Domain Name System) 를 참고하세요.


IDC(기업망) 영역

  • Public Instance (bbIDC-DNSSRV)
    • ‘idcneta.internal’ 도메인에 대한 DNS 서비스(bind9참고) 제공
    • ‘awsneta.internal’ 도메인 전달자 (forwarder) 로 20.70.1.250 과 20.70.2.250 에 질의
  • Public Instance (bbIDC-WEBSRV)
    • 웹서버 동작
  • DHCP Option Set (IDC-VPC2-DHCPOptions)
    • DHCP 로 정보 전달 시 직접 설정한 DNS 서버 (20.80.1.200, 8.8.8.8참고) 의 주소와 도메인 네임 제공
  • Public Routing Table (bbIDC-PublicRT)
    • VPC Peering 을 통해 AWS 영역과 통신 가능

bind9
도메인 네임 시스템을 제공하는 애플리케이션

8.8.8.8 은 구글 DNS 서버


4.1.3. 기본 통신 환경 검증

  • bbAWS-VPC1 에서 기본 환경 검증
    • bbAWS-WEBSRV1 Instance 확인
    • Route 53 Private Hosted Zone 확인
    • Public Routing Table, VPC Peering 확인
  • bbIDC-VPC2 에서 기본 환경 검증
    • bbIDC-DNSSRV(DNS 서버) Instance 확인
    • bbIDC-WEBSRV Instance 확인
    • Public Routing Table, VPC Peering 확인
  • 기본 환경 검증 종합

기본 환경 구성도


4.1.3.1. bbAWS-VPC1 에서 기본 환경 검증

  • bbAWS-WEBSRV1 Instance 확인
  • Route 53 Private Hosted Zone 확인
  • Public Routing Table, VPC Peering 확인

bbAWS-WEBSRV1 Instance 확인

bbAWS-WEBSRV1 Public IP 로 SSH 접속한다.

VPC Peering 으로 연결된 IDC 영역의 웹서버의 도메인 주소(websrv.idcneta.internal) 로 통신 확인 (통신 불가)

# bbAWS-WEBSRV1 Public IP
$ ssh -i sandbox-jh.pem ec2-user@15.165.xxx.xxx

# EC2 에 설정된 DNS 서버 확인
[ec2-user@WEBSRV1 ~]$ cat /etc/resolv.conf
; generated by /usr/sbin/dhclient-script
search ap-northeast-2.compute.internal
options timeout:2 attempts:5
nameserver 20.70.0.2

# awsneta.internal Private 도메인에 대한 DNS 질의/응답 확인
[ec2-user@WEBSRV1 ~]$ dig +short websrv1.awsneta.internal
20.70.1.100
[ec2-user@WEBSRV1 ~]$ dig +short websrv2.awsneta.internal
20.70.2.100

# Private 도메인 주소로 웹 접속 확인
[ec2-user@WEBSRV1 ~]$ curl websrv1.awsneta.internal
<h1>CloudNet@ AWS Web Server 1 - 20.70.1.100 - websrv1.awsneta.internal</h1>
[ec2-user@WEBSRV1 ~]$ curl websrv2.awsneta.internal
<h1>CloudNet@ AWS Web Server 2 - 20.70.2.100 - websrv2.awsneta.internal</h1>

# VPC Peering 으로 연결된 IDC 영역의 웹서버(20.80.1.100) ping 확인
[ec2-user@WEBSRV1 ~]$ ping 20.80.1.100 -c 1 -W 1
PING 20.80.1.100 (20.80.1.100) 56(84) bytes of data.
64 bytes from 20.80.1.100: icmp_seq=1 ttl=255 time=0.761 ms

--- 20.80.1.100 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.761/0.761/0.761/0.000 ms

# VPC Peering 으로 연결된 IDC 영역의 웹서버(20.80.1.100)로 웹 접속 확인
[ec2-user@WEBSRV1 ~]$ curl 20.80.1.100
<h1>CloudNet@ IDC Web Server - 20.80.1.100 - websrv.idcneta.internal</h1>

# VPC Peering 으로 연결된 IDC 영역의 웹서버의 도메인 주소(websrv.idcneta.internal) 로 통신 확인 (통신 불가)
[ec2-user@WEBSRV1 ~]$ dig +short websrv.idcneta.internal
[ec2-user@WEBSRV1 ~]$ ping websrv.idcneta.internal -c 1 -W 1
ping: websrv.idcneta.internal: Name or service not known
[ec2-user@WEBSRV1 ~]$ curl websrv.idcneta.internal
curl: (6) Could not resolve host: websrv.idcneta.internal

dig 명령어를 통해 DNS 주소에 대한 IP 주소 정보 확인 가능


Route 53 Private Hosted Zone 확인

‘awsneta.internal’ Private 도메인에 대한 Route 53 Hosted Zones 을 확인한다.

[Route 53] - [Hosted zones] - [awsneta.internal 선택] websrv1,2 A Record 확인


Public Routing Table, VPC Peering 확인

외부 인터넷 통신을 위한 대상과 VPC Peering 을 통해 IDC 영역과 통신을 위한 라우팅 정보를 확인한다.

[VPC] - [Route tables] - [bbAWS-PublicRT 선택] Public Route Table 확인

[VPC] - [Virtual private cloud] - [Peering connections] - [bbVPCPeering 선택] bbAWS-VPC1 과 bbIDC-VPC2 간 VPC Peering 정보 확인


4.1.3.2. bbIDC-VPC2 에서 기본 환경 검증

  • DHCP Option Set 확인
  • bbIDC-DNSSRV(DNS 서버) Instance 확인
  • bbIDC-WEBSRV Instance 확인
  • Public Routing Table, VPC Peering 확인

DHCP Option Set 확인

IDC 내부에서 사용하는 도메인 네임(idcneta.internal) 과 도메인 네임 서버(20.80.1.200, 8.8.8.8) 정보를 확인한다.

[VPC] - [Virtual private cloud] - [DHCP option sets] - [IDC-VPC2-DHCPOptions 선택] DHCP Option Sets 정보 확인


bbIDC-DNSSRV(DNS 서버) Instance 확인

bbIDC-DNSSRV 의 EIP 로 SSH 접속한다. 이 때 username 은 ec2-user 가 아닌 ubuntu 로 접속한다.

VPC Peering 으로 연결된 AWS 영역의 웹서버의 도메인 주소(websrv1.awsneta.internal) 로 통신 확인 (통신 불가)

# bbIDC-DNSSRV 의 EIP
$ ssh -i sandbox-jh.pem ubuntu@15.165.xxx.xxx

# bbIDC-DNSSRV 가 DNS 서버 역할을 하고 2차 DNS 서버는 구글(8.8.8.8) 로 설정되어 있는지 확인
ubuntu@DNSSRV:~$ cat /etc/resolv.conf
# Dynamic resolv.conf(5) file for glibc resolver(3) generated by resolvconf(8)
#     DO NOT EDIT THIS FILE BY HAND -- YOUR CHANGES WILL BE OVERWRITTEN
nameserver 20.80.1.200
nameserver 8.8.8.8
search idcneta.internal

# idcneta.internal Private 도메인에 대한 DNS 질의/응답 확인
ubuntu@DNSSRV:~$ dig +short websrv.idcneta.internal
20.80.1.100
ubuntu@DNSSRV:~$ dig +short dnssrv.idcneta.internal
20.80.1.200

# Private 도메인 주소로 웹 접속 확인
ubuntu@DNSSRV:~$ curl websrv.idcneta.internal
<h1>CloudNet@ IDC Web Server - 20.80.1.100 - websrv.idcneta.internal</h1>

# VPC Peering 으로 연결된 AWS 영역의 웹서버(20.70.1.100) ping 확인
ubuntu@DNSSRV:~$ ping 20.70.1.100 -c 1 -W 1
PING 20.70.1.100 (20.70.1.100) 56(84) bytes of data.
64 bytes from 20.70.1.100: icmp_seq=1 ttl=255 time=0.881 ms

--- 20.70.1.100 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.881/0.881/0.881/0.000 ms

# VPC Peering 으로 연결된 AWS 영역의 웹서버(20.70.1.100)로 웹 접속 확인
ubuntu@DNSSRV:~$ curl 20.70.1.100
<h1>CloudNet@ AWS Web Server 1 - 20.70.1.100 - websrv1.awsneta.internal</h1>
ubuntu@DNSSRV:~$ curl 20.70.2.100
<h1>CloudNet@ AWS Web Server 2 - 20.70.2.100 - websrv2.awsneta.internal</h1>

# VPC Peering 으로 연결된 AWS 영역의 웹서버의 도메인 주소(websrv1.awsneta.internal) 로 통신 확인 (통신 불가)
ubuntu@DNSSRV:~$ dig +short websrv1.awsneta.internal
ubuntu@DNSSRV:~$ ping websrv1.awsneta.internal -c 1 -W 1
ping: unknown host websrv1.awsneta.internal
ubuntu@DNSSRV:~$ curl websrv1.awsneta.internal
curl: (6) Could not resolve host: websrv1.awsneta.internal

# bind9 서비스 상태 정보 확인
ubuntu@DNSSRV:~$ systemctl status bind9
● bind9.service - BIND Domain Name Server
   Loaded: loaded (/lib/systemd/system/bind9.service; enabled; vendor preset: enabled)
  Drop-In: /run/systemd/generator/bind9.service.d
           └─50-insserv.conf-$named.conf
   Active: active (running) since Sun 2023-01-29 01:34:39 UTC; 4h 25min ago # <-- Active
   
# bind9 Record 정보 확인
ubuntu@DNSSRV:~$ cat /etc/bind/db.idcneta.internal
$TTL 30
@ IN SOA idcneta.internal. root.idcneta.internal. (
  2019122114 ; serial
  3600       ; refresh
  900        ; retry
  604800     ; expire
  86400      ; minimum ttl
)

; dns server
@      IN NS ns1.idcneta.internal.

; ip address of dns server
ns1    IN A  20.80.1.200

; Hosts  # <-- Record 정보
websrv   IN A  20.80.1.100
dnssrv   IN A  20.80.1.200

# bind9 zone forwarder 정보 확인
ubuntu@DNSSRV:~$ cat /etc/bind/named.conf.options
...
zone "awsneta.internal" {
    type forward;
    forward only;
    forwarders { 20.70.1.250; 20.70.2.250; };
};
...

bbIDC-WEBSRV Instance 확인

bbIDC-WEBSRV 의 Public IP 로 SSH 접속한다.

VPC Peering 으로 연결된 AWS 영역의 웹서버의 도메인 주소(websrv1.awsneta.internal) 로 통신 확인 (통신 불가)

# bbIDC-WEBSRV 의 Public IP
$ ssh -i sandbox-jh.pem ec2-user@3.38.xxx.xxx

# VPC Peering 으로 연결된 AWS 영역의 웹서버(20.70.1.100)로 웹 접속 확인
[ec2-user@WEBSRV ~]$ curl 20.70.1.100
<h1>CloudNet@ AWS Web Server 1 - 20.70.1.100 - websrv1.awsneta.internal</h1>
[ec2-user@WEBSRV ~]$ curl 20.70.2.100
<h1>CloudNet@ AWS Web Server 2 - 20.70.2.100 - websrv2.awsneta.internal</h1>

# VPC Peering 으로 연결된 AWS 영역의 웹서버의 도메인 주소(websrv1.awsneta.internal) 로 통신 확인 (통신 불가)
[ec2-user@WEBSRV ~]$ dig +short websrv1.awsneta.internal
[ec2-user@WEBSRV ~]$ dig +short websrv2.awsneta.internal
[ec2-user@WEBSRV ~]$ ping websrv1.awsneta.internal -c 1 -W 1
ping: websrv1.awsneta.internal: Name or service not known
[ec2-user@WEBSRV ~]$ ping websrv2.awsneta.internal -c 1 -W 1
ping: websrv2.awsneta.internal: Name or service not known
[ec2-user@WEBSRV ~]$ curl websrv1.awsneta.internal
curl: (6) Could not resolve host: websrv1.awsneta.internal
[ec2-user@WEBSRV ~]$ curl websrv2.awsneta.internal
curl: (6) Could not resolve host: websrv2.awsneta.internal

Public Routing Table, VPC Peering 확인

외부 인터넷 통신을 위한 대상과 VPC Peering 을 통해 AWS 영역과 통신을 위한 라우팅 정보를 확인한다.

[VPC] - [Route tables] - [bbIDC-PublicRT 선택] Public Route Table 확인


4.1.3.3. 기본 환경 검증 종합

현재는 아래처럼 내부에서 사용하는 도메인에 대해 서로 resolve (해석) 가 되지 않고 있다.

기본 환경 검증 종합

4.2. Inbound DNS 쿼리 전달

  • Inbound Endpoint 설정
  • Inbound DNS 쿼리 전달 동작 확인

4.2.1. Inbound Endpoint 설정

IDC 망에서 AWS 망인 ‘awsneta.intenal’ 도메인 해석이 가능하도록 설정한다.

[Route 53] - [Resolver] - [Inbound endpoints] - [Create inbound endpoint]

Inbound Endpoint 생성(1) Inbound Endpoint 생성(2)


4.2.2. Inbound DNS 쿼리 전달 동작 확인

bbIDC-WEBSRV 의 Public IP 로 SSH 접근한다.

# bbIDC-WEBSRV 의 Public IP
$ ssh -i sandbox-jh.pem ec2-user@3.38.xxx.xxx

# VPC Peering 으로 연결된 AWS 영역의 웹서버의 도메인 주소(websrv1.awsneta.internal) 로 해석 확인 (해석 가능)
[ec2-user@WEBSRV ~]$ dig +short websrv1.awsneta.internal
20.70.1.100
[ec2-user@WEBSRV ~]$ dig +short websrv2.awsneta.internal
20.70.2.100

# VPC Peering 으로 연결된 AWS 영역의 웹서버의 도메인 주소(websrv1.awsneta.internal) 로 통신 확인 (통신 가능)
[ec2-user@WEBSRV ~]$ ping websrv1.awsneta.internal -c 1 -W 1
PING websrv1.awsneta.internal (20.70.1.100) 56(84) bytes of data.
64 bytes from 20.70.1.100 (20.70.1.100): icmp_seq=1 ttl=255 time=0.422 ms

--- websrv1.awsneta.internal ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.422/0.422/0.422/0.000 ms

[ec2-user@WEBSRV ~]$ ping websrv2.awsneta.internal -c 1 -W 1
PING websrv2.awsneta.internal (20.70.2.100) 56(84) bytes of data.
64 bytes from 20.70.2.100 (20.70.2.100): icmp_seq=1 ttl=255 time=1.01 ms

--- websrv2.awsneta.internal ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 1.011/1.011/1.011/0.000 ms

[ec2-user@WEBSRV ~]$ curl websrv1.awsneta.internal
<h1>CloudNet@ AWS Web Server 1 - 20.70.1.100 - websrv1.awsneta.internal</h1>
[ec2-user@WEBSRV ~]$ curl websrv2.awsneta.internal
<h1>CloudNet@ AWS Web Server 2 - 20.70.2.100 - websrv2.awsneta.internal</h1>

bbIDC-DNSSRV 의 EIP 로 SSH 접근한다.

# bbIDC-DNSSRV 의 EIP
$ ssh -i sandbox-jh.pem ubuntu@15.165.xxx.xxx

# bind9 로깅 활성화
ubuntu@DNSSRV:~$ sudo rndc querylog

# 도메인 질의(query) 확인
ubuntu@DNSSRV:~$ tail -f /var/log/syslog
Jan 29 08:21:09 ip-20-80-1-200 named[3741]: client 20.80.1.100#48500 (websrv1.awsneta.internal): query: websrv1.awsneta.internal IN A + (20.80.1.200)
Jan 29 08:21:09 ip-20-80-1-200 named[3741]: client 20.80.1.100#48500 (websrv1.awsneta.internal): query: websrv1.awsneta.internal IN AAAA + (20.80.1.200)

VPC Inbound Endpoint 동작 확인


4.3. Outbound DNS 쿼리 전달

  • Outbound Endpoint 설정
  • 전달 규칙 설정
  • Outbound DNS 쿼리 전달 동작 확인

4.3.1. Outbound Endpoint 설정

AWS 망에서 IDS 망인 ‘idcneta.intenal’ 도메인 해석이 가능하도록 설정한다.

[Route 53] - [Resolver] - [Outbound endpoints] - [Create outbound endpoint]

Outbound Endpoint 생성(1) Outbound Endpoint 생성(2)


4.3.2. 전달 규칙 설정

Inbound Endpoint 와 다르게 Outbound Endpoint 는 전달 규칙을 생성 후 연동해야 한다.

[Route 53] - [Resolver] - [Rules] - [Create rule]

전달 규칙 생성

전달 규칙 확인


4.3.3. Outbound DNS 쿼리 전달 동작 확인

bbAWS-WEBSRV1 의 Public IP 로 SSH 접근한다.

# bbAWS-WEBSRV1 의 Public IP
$ ssh -i sandbox-jh.pem ec2-user@15.165.xxx.xxx

# VPC Peering 으로 연결된 IDC 영역의 웹서버의 도메인 주소(websrv.idcneta.internal) 로 해석 확인 (해석 가능)
[ec2-user@WEBSRV1 ~]$ dig +short websrv.idcneta.internal
20.80.1.100

# VPC Peering 으로 연결된 IDC 영역의 웹서버의 도메인 주소(websrv.idcneta.internal) 로 통신 확인 (통신 가능)
[ec2-user@WEBSRV1 ~]$ curl websrv.idcneta.internal
<h1>CloudNet@ IDC Web Server - 20.80.1.100 - websrv.idcneta.internal</h1>

bbIDC-DNSSRV 의 EIP 로 SSH 접근한다.

# bbIDC-DNSSRV 의 EIP
$ ssh -i sandbox-jh.pem ubuntu@15.165.xxx.xxx

# bind9 로깅 활성화
ubuntu@DNSSRV:~$ sudo rndc querylog

# 도메인 질의(query) 확인
ubuntu@DNSSRV:~$ tail -f /var/log/syslog
Jan 29 08:51:52 ip-20-80-1-200 named[3741]: client 20.70.1.251#5317 (websrv.idcneta.internal): query: websrv.idcneta.internal IN A +ED (20.80.1.200)
Jan 29 08:51:52 ip-20-80-1-200 named[3741]: client 20.70.2.251#5387 (websrv.idcneta.internal): query: websrv.idcneta.internal IN A +ED (20.80.1.200)

VPC Outbound Endpoint 동작 확인


4.4. Resource 삭제

  • 전달 규칙 삭제 ([Route 53] - [Resolver] - [Rules])
    • VPC Disassociate 후 삭제
  • Outbound Endpoint 삭제 ([Route 53] - [Resolver] - [Outbound endpoints])
  • Inbound Endpoint 삭제 ([Route 53] - [Resolver] - [Inbound endpoints])
  • CloudFormation Stack 삭제 ([CloudFormation] - [Stacks] - [Delete])

CloudFormation Stack 이 삭제되면 위의 4.1.2. CloudFormation 을 통해 생성된 자원 확인 의 자원이 모두 삭제되었는지 확인한다.


참고 사이트 & 함께 보면 좋은 사이트

본 포스트는 김원일, 서종호 저자의 따라하며 배우는 AWS 네트워크 입문를 기반으로 스터디하며 정리한 내용들입니다.






© 2020.08. by assu10

Powered by assu10