2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

AWS で IPv6アドレスの検証環境を整える (脱パブリックIPv4)

Last updated at Posted at 2024-03-03

はじめに

AWS のパブリック IPv4 アドレスが有償化になりましたが、
検証でなるべくお金をかけたくなかったので、IPv6 を使用する検証環境用の CFn を作成しました。
本記事は、その IPv6 の検証環境の使い方(IPv6アドレスを設定したEC2への接続方法)について解説した記事になります。

全体図

Untitled Diagram-Page-2.drawio.png

上記が本 CFn で作成する検証環境のイメージになります。
インスタンスの図を記載してますが、本 CFn を使用してもインスタンスは構築されません。
※インスタンスへの接続方法を記載する都合上、図があった方がわかりやすいため、インスタンスの図を記載しています。

イメージ図の中で重要なサービスについて、簡単に記載します。

  • EC2 Instance Connect Endpoint
    • パブリック IPv4 アドレスがないインスタンスに接続できる機能。
    • プライベートサブネットの EC2 にも接続可能
    • 使用料金がなんと無料!
  • Internet gateway
    • IPv6 のインスタンスでインターネットからの Ingress(受信)、Egress(送信)用に使用
  • Egress Only インターネットゲートウェイ
    • プライベートサブネットに配置しているインスタンスの Egress(送信)用に使用。簡単に説明すると NAT ゲートウェイの IPv6 バージョン。
    • 追加費用なし!

プライベートサブネットでは Egress Only インターネットゲートウェイが、
パブリックサブネットではインターネットゲートウェイのルートが設定してありますので
どちらのサブネットでインスタンスを立てた場合でも、インターネットへは接続できる状態です。

CFn

本検証環境の構築で使用する CFn はこちらになります。

CFnコード
AWSTemplateFormatVersion: "2010-09-09"
Description: "IPv6 VPC"
Metadata:
  AWS::CloudFormation::Interface:
    ParameterGroups:
      - Label:
          default: "Network Configuration"
        Parameters:
          - CIDR
      - Label:
          default: "Normal Configuration"
        Parameters:
          - Prefix
          - Regiton

Parameters:
  Prefix:
    Type: String
    Default: test-Ipv6
  CIDR:
    Description: Please type the CidrBlock.
    Type: String
    Default: 192.168.0.0/16

Resources:
  # ------------------------------------------------------------#
  #  VPC
  # ------------------------------------------------------------#
  Vpc:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: !Ref CIDR
      EnableDnsHostnames: true
      EnableDnsSupport: true
      Tags:
        - Key: Name
          Value: !Sub ${Prefix}-vpc
  # ------------------------------------------------------------#
  # IPv6 Cidr
  # ------------------------------------------------------------#
  VpcIpv6:
    Type: AWS::EC2::VPCCidrBlock
    Properties:
      AmazonProvidedIpv6CidrBlock: true
      VpcId: !Ref Vpc

  # ------------------------------------------------------------#
  #  Subnets
  # ------------------------------------------------------------#
  PublicSubnet1a:
    DependsOn: VpcIpv6
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref Vpc
      AvailabilityZone: !Sub "${AWS::Region}a"
      CidrBlock: !Select [0, !Cidr [!GetAtt Vpc.CidrBlock, 2, 8]] # 192.168.0.0/24
      AssignIpv6AddressOnCreation: true
      Ipv6CidrBlock:
        !Select [0, !Cidr [!Select [0, !GetAtt Vpc.Ipv6CidrBlocks], 2, 64]]
      Tags:
        - Key: Name
          Value: !Sub ${Prefix}-subnet-public-a

  PrivateSubnet1a:
    DependsOn: VpcIpv6
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref Vpc
      AvailabilityZone: !Sub "${AWS::Region}a"
      CidrBlock: !Select [1, !Cidr [!GetAtt Vpc.CidrBlock, 2, 8]]
      AssignIpv6AddressOnCreation: true
      Ipv6CidrBlock:
        !Select [1, !Cidr [!Select [0, !GetAtt Vpc.Ipv6CidrBlocks], 2, 64]]
      Tags:
        - Key: Name
          Value: !Sub ${Prefix}-subnet-private-a

  # ------------------------------------------------------------#
  #  Security Groups
  # ------------------------------------------------------------#
  EICSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      VpcId: !Ref Vpc
      GroupDescription: EIC SG
      GroupName: !Sub ${Prefix}-eic-sg
      Tags:
        - Key: Name
          Value: !Sub ${Prefix}-eic-sg

  EICSecurityGroupEgress1:
    Type: AWS::EC2::SecurityGroupEgress
    DependsOn: Ec2SecurityGroup
    Properties:
      Description: EC2 ssh egress
      IpProtocol: tcp
      GroupId: !Ref EICSecurityGroup
      FromPort: 22
      ToPort: 22
      DestinationSecurityGroupId: !Ref Ec2SecurityGroup

  EICSecurityGroupEgress2:
    Type: AWS::EC2::SecurityGroupEgress
    DependsOn: Ec2SecurityGroup
    Properties:
      Description: EC2 rdp egress
      IpProtocol: tcp
      GroupId: !Ref EICSecurityGroup
      FromPort: 3389
      ToPort: 3389
      DestinationSecurityGroupId: !Ref Ec2SecurityGroup

  Ec2SecurityGroup:
    DependsOn: EICSecurityGroup
    Type: AWS::EC2::SecurityGroup
    Properties:
      VpcId: !Ref Vpc
      GroupDescription: EC2 SG
      GroupName: !Sub ${Prefix}-ec2-sg
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 22
          ToPort: 22
          SourceSecurityGroupId: !Ref EICSecurityGroup
        - IpProtocol: tcp
          FromPort: 3389
          ToPort: 3389
          SourceSecurityGroupId: !Ref EICSecurityGroup
      SecurityGroupEgress:
        - IpProtocol: -1
          DestinationSecurityGroupId: !Ref EICSecurityGroup
        - IpProtocol: -1
          CidrIp: 0.0.0.0/0
        - IpProtocol: -1
          CidrIpv6: ::/0
      Tags:
        - Key: Name
          Value: !Sub ${Prefix}-ec2-sg

  # ------------------------------------------------------------#
  #  EC2 Instance Connect Endpoint
  # ------------------------------------------------------------#
  EicEndpointPrivate:
    Type: AWS::EC2::InstanceConnectEndpoint
    DependsOn: EICSecurityGroup
    Properties:
      SubnetId: !Ref PrivateSubnet1a
      SecurityGroupIds:
        - !Ref EICSecurityGroup

  # ------------------------------------------------------------#
  #  Internet Gateway
  # ------------------------------------------------------------#
  InternetGateway:
    Type: AWS::EC2::InternetGateway

  InternetGatewayAttachment:
    Type: AWS::EC2::VPCGatewayAttachment
    Properties:
      VpcId: !Ref Vpc
      InternetGatewayId: !Ref InternetGateway

  # ------------------------------------------------------------#
  #  Egress Only Internet Gateway
  # ------------------------------------------------------------#
  EgressOnlyInternetGateway:
    Type: AWS::EC2::EgressOnlyInternetGateway
    Properties:
      VpcId: !Ref Vpc
  # ------------------------------------------------------------#
  #  Route Tables
  # ------------------------------------------------------------#
  PublicRouteTable:
    Type: "AWS::EC2::RouteTable"
    Properties:
      VpcId: !Ref Vpc
      Tags:
        - Key: Name
          Value: !Sub ${Prefix}-public-rtb

  PrivateRouteTable:
    Type: "AWS::EC2::RouteTable"
    Properties:
      VpcId: !Ref Vpc
      Tags:
        - Key: Name
          Value: !Sub ${Prefix}-private-rtb

  # ------------------------------------------------------------#
  #  Subnet Route Table Associations
  # ------------------------------------------------------------#
  PublicSubnet1aRouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PublicSubnet1a
      RouteTableId: !Ref PublicRouteTable

  PrivateSubnet1aRouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PrivateSubnet1a
      RouteTableId: !Ref PrivateRouteTable

  # ------------------------------------------------------------#
  #  Routing
  # ------------------------------------------------------------#
  PublicRoute:
    Type: AWS::EC2::Route
    Properties:
      RouteTableId: !Ref PublicRouteTable
      DestinationIpv6CidrBlock: ::/0
      GatewayId: !Ref InternetGateway

  PublicRoute1:
    Type: AWS::EC2::Route
    Properties:
      RouteTableId: !Ref PublicRouteTable
      DestinationCidrBlock: 0.0.0.0/0
      GatewayId: !Ref InternetGateway

  PrivateRoute1:
    Type: AWS::EC2::Route
    Properties:
      RouteTableId: !Ref PrivateRouteTable
      DestinationIpv6CidrBlock: ::/0
      EgressOnlyInternetGatewayId: !Ref EgressOnlyInternetGateway

Outputs:
  VpcId:
    Description: The VPC ID
    Value: !Ref Vpc
    Export:
      Name: VpcId

  PublicSubnetId:
    Description: The public subnet ID
    Value: !Ref PublicSubnet1a
    Export:
      Name: PublicSubnetId

  PrivateSubnetId:
    Description: The private subnet ID
    Value: !Ref PrivateSubnet1a
    Export:
      Name: PrivateSubnetId

  EICSecurityGroupId:
    Description: The EIC SG ID
    Value: !Ref EICSecurityGroup
    Export:
      Name: EICSecurityGroupId

  Ec2SecurityGroupId:
    Description: The EC2 SG ID
    Value: !Ref Ec2SecurityGroup
    Export:
      Name: Ec2SecurityGroupId

CFnのパラメータ

CFnのパラメータについて簡単に説明します。

  • CIDR
    プライベートIPv4のCIDR範囲。デフォルトで192.168.0.0/16を設定されている。
  • Prefix
    各リソース名の接頭辞。Nameタグなどで使用する。
  • Regiton
    構築するリージョン先。本CFnのデフォルト値は、東京リージョンで構築するよう設定しています。

本検証環境に起動したEC2への接続方法

① EC2 Instance Connect Endpoint を利用して、パブリック IPv4 がない Linux インスタンスに接続する。

  1. AWS マネジメントコンソール等から、CFn で作成した環境内に Linux インスタンスを起動する。

    • VPC: CFn で作成した VPC を選択
    • サブネット: プライベート、パブリックどちらのサブネットでも可
    • キーペア:適宜設定。
    • パブリック IP の自動割り当て: 無効
    • IPv6IP を自動で割り当てる: 有効化
    • セキュリティグループ: [『Prefix}-ec2-sg]を選択
  2. インスタンス起動後、[インスタンス]から起動したインスタンスを選択し、[接続]を選択する。

  3. [EC2 Instance Connect]タブを選択し、[EC2 Instance Connect エンドポイントを使用して接続する]を選択し、[接続]を選択する。
    EIC エンドポイントが選択されていない場合は、CFn で作成したエンドポイントを選択する。
    スクリーンショット 2024-03-03 8.36.53.png

パブリック IPv4 がなくても Linux に接続することができました!また、インターネットへの接続も問題なさそうです。
スクリーンショット 2024-03-03 8.41.08.png

ちなみにですが、EIC エンドポイントと AWS CLI を使用することによって、ローカル環境から ssh ができるようになります。
以下が接続する際のコマンドになります。IP アドレスを指定せずともインスタンス ID の指定だけで接続できるようです。

ssh -i my-key-pair.pem ec2-user@{instance_id} \
    -o ProxyCommand='aws ec2-instance-connect open-tunnel --instance-id {instance_id}'

こちらについても無事接続できました!
スクリーンショット 2024-03-03 8.54.24.png

② EC2 Instance Connect Endpoint を利用して、パブリック IPv4 がない Windows インスタンスに RDP 接続する。

警告
本手順は AWS CLI を設定する必要がありますので、ご注意ください。

  1. AWS マネジメントコンソール等から、CFn で作成した環境内に Windows インスタンスを起動する。

    • VPC: CFn で作成した VPC を選択
    • サブネット: プライベート、パブリックどちらのサブネットでも可
    • キーペア:適宜設定。
    • パブリック IP の自動割り当て: 無効
    • IPv6IP を自動で割り当てる: 有効化
    • セキュリティグループ: [{Prefix}-ec2-sg]を選択
  2. 以下のコマンドを実行し、WebSocket のトンネルを張る。

    aws ec2-instance-connect open-tunnel --instance-id {instance_id} --remote-port 3389 --local-port {任意のポート}
    
  3. 手順 2 実行後、[Listening for connections on port <任意のポート>]が表示されることを確認する。

  4. RDP ソフトを起動し、[localhost:<任意のポート>]に接続する。

EIC エンドポイントを利用して、RDP 接続できました!
スクリーンショット 2024-03-03 9.23.50.png

まとめ

パブリック IPv4 アドレスを使用せずとも、Linux、Windows に接続できるようになりました。
また、IPv6アドレスを設定したインスタンスの外部へ通信も、設定することができました。
これで、パブリック IPv4 とはお別れすることができそうです。

参照

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?