話題の記事

自宅とAWSをVPN接続してみた

2019.05.03

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

しばたです。

個人的な興味半分、業務上の理由半分でオンプレミスとAWSをDirect ConnectまたはVPNで接続した環境でのActive Directory関連の動作検証をしたくなり、Direct Connectを個人で試すのは難しいため、自宅をオンプレ環境に見立てVPNでAWSと接続し検証環境を作ることにしました。

構成図

構成図はこんな感じです。

AWS側VPCのCIDRは172.18.0.0/16、プライベートなサブネット172.18.1.0/24、172.18.2.0/24を用意しています。 オンプレ(自宅)側は192.168.9.0/24と192.168.10.0/24の2つのネットワークと二台のドメインコントローラー(Windows Server 2012 R2)を用意しています。

構築手順

本記事ではAWS側環境を作り、オンプレ環境とVPN接続するところまでを解説します。

方式について

目的は違うのですが、つい先日弊社中山によってRTX830の「クラウド接続」機能をつかってお手軽にVPN環境を構築する手順が公開されました。

YAMAHA RTX830でお手軽VPN接続

本記事では私自身の勉強を兼ねて上述の「クラウド接続」は使わずCloudFormationでAWS側のリソースを作成、手作業でRTX830のコンフィグを設定という手順で環境構築を行っています。 環境構築という目的を果たすだけであれば「クラウド接続」の方が楽かと思いますのでそういった場合は中山の記事を参考にすると良いでしょう。

CloudFormationテンプレート

各種リソースを一つずつ作るのは面倒なのでCloudFormationで必要なネットワークリソースを一気に作成します。 以下のテンプレートで、

  • VPC
  • NACL
  • Subnet x 2
  • RouteTable
  • Security Group(SSH, RDP, ICMP)
  • VGW
  • VPNConnection
  • Customer Gateway

を作成することができます。

AWSTemplateFormatVersion: 2010-09-09
Parameters:
  SystemName:
    Description: "System name of each resource names."
    Type: String
    Default: "devio"
  EnvironmentName:
    Description: "Environment name of each resource names."
    Type: String
    Default: "test"
  AZ1:
    Description: "AZ1"
    Type: AWS::EC2::AvailabilityZone::Name
    Default: "ap-northeast-1a"
  AZ2:
    Description: "AZ2"
    Type: AWS::EC2::AvailabilityZone::Name
    Default: "ap-northeast-1c"
  CGWIP:
    Description: "IP addres of Customer Gateway"
    Type: String
    Default: "xxx.xxx.xxx.xxx"
Outputs:
  VPC1:
    Value:
      Ref: VPC1
    Export:
    Name:
      Fn::Sub: "${SystemName}-${EnvironmentName}-vpc"
  PrivateSubnet1:
    Value:
      Ref: PrivateSubnet1
    Export:
    Name:
      Fn::Sub: "${SystemName}-${EnvironmentName}-private-subnet-1"
  PrivateSubnet2:
    Value:
      Ref: PrivateSubnet2
    Export:
      Name:
        Fn::Sub: "${SystemName}-${EnvironmentName}-private-subnet-2"
  PrivateRouteTable1:
    Value:
      Ref: PrivateRouteTable1
    Export:
      Name:
        Fn::Sub: "${SystemName}-${EnvironmentName}-private-rtb"
Resources:
  # VPC
  VPC1:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: 172.18.0.0/16
      EnableDnsSupport: true
      EnableDnsHostnames: true
      Tags:
        - Key: Name
          Value:
            Fn::Sub: "${SystemName}-${EnvironmentName}-vpc"
  # Subnet
  PrivateSubnet1:
    Type: AWS::EC2::Subnet
    Properties:
      AvailabilityZone:
        Ref: AZ1
      VpcId:
        Ref: VPC1
      CidrBlock: 172.18.1.0/24
      MapPublicIpOnLaunch: False
      Tags:
        - Key: Name
          Value:
            Fn::Sub: "${SystemName}-${EnvironmentName}-private-subnet-1"
  PrivateSubnet2:
    Type: AWS::EC2::Subnet
    Properties:
      AvailabilityZone:
        Ref: AZ2
      VpcId:
        Ref: VPC1
      CidrBlock: 172.18.2.0/24
      MapPublicIpOnLaunch: False
      Tags:
        - Key: Name
          Value:
            Fn::Sub: "${SystemName}-${EnvironmentName}-private-subnet-2"
  # Customer Gateway
  CustomerGateway1:
    Type: AWS::EC2::CustomerGateway
    Properties:
      Type: "ipsec.1"
      BgpAsn: 65000
      IpAddress:
        Ref: CGWIP
      Tags:
        - Key: Name
          Value:
            Fn::Sub: "${SystemName}-${EnvironmentName}-cgw"
  # VPN Gateway
  VPNGateway1:
    Type: AWS::EC2::VPNGateway
    Properties:
      Type: ipsec.1
      Tags:
        - Key: Name
          Value:
            Fn::Sub: "${SystemName}-${EnvironmentName}-vpw"
      AttachVpnGateway1:
        Type: AWS::EC2::VPCGatewayAttachment
        Properties:
          VpcId:
            Ref: VPC1
          VpnGatewayId:
            Ref: VPNGateway1
  # VPN Connection
  VPNConnection1:
    Type: AWS::EC2::VPNConnection
    Properties:
      Type: ipsec.1
      StaticRoutesOnly: False
      CustomerGatewayId:
        Ref: CustomerGateway1
      VpnGatewayId:
        Ref: VPNGateway1
      # Route Tables
      PrivateRouteTable1:
        Type: AWS::EC2::RouteTable
        Properties:
          VpcId:
            Ref: VPC1
          Tags:
            - Key: Name
              Value:
                Fn::Sub: "${SystemName}-${EnvironmentName}-private-rtb"
  PrivateRoute1:
    Type: AWS::EC2::Route
    DependsOn: AttachVpnGateway1
    Properties:
      RouteTableId:
        Ref: PrivateRouteTable1
      DestinationCidrBlock: 192.168.0.0/16
      GatewayId:
        Ref: VPNGateway1
      PrivateRTAssociation1:
        Type: AWS::EC2::SubnetRouteTableAssociation
        Properties:
          RouteTableId:
            Ref: PrivateRouteTable1
          SubnetId:
            Ref: PrivateSubnet1
  PrivateRTAssociation2:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      RouteTableId:
        Ref: PrivateRouteTable1
      SubnetId:
        Ref: PrivateSubnet2
  # NACL (Default only)
  NACL1:
    Type: AWS::EC2::NetworkAcl
    Properties:
      Tags:
        - Key: Name
          Value:
            Fn::Sub: "${SystemName}-${EnvironmentName}-nacl"
      VpcId:
        Ref: VPC1
  NACLEntry1:
    Type: AWS::EC2::NetworkAclEntry
    Properties:
      Egress: true
      CidrBlock: 0.0.0.0/0
      Protocol: -1
      RuleAction : allow
      RuleNumber : 100
      NetworkAclId:
        Ref: NACL1
  NACLEntry2:
    Type: AWS::EC2::NetworkAclEntry
    Properties:
      Egress: false
      CidrBlock: 0.0.0.0/0
      Protocol: -1
      RuleAction : allow
      RuleNumber : 100
      NetworkAclId:
        Ref: NACL1
  SubnetNACLAssociation1:
    Type: AWS::EC2::SubnetNetworkAclAssociation
    Properties:
      SubnetId:
        Ref: PrivateSubnet1
      NetworkAclId:
        Ref: NACL1
      SubnetNACLAssociation2:
        Type: AWS::EC2::SubnetNetworkAclAssociation
        Properties:
          SubnetId:
            Ref: PrivateSubnet2
          NetworkAclId:
            Ref: NACL1
  # Security Group (SSH)
  SecurityGroupSSH:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupName:
        Fn::Sub: "${SystemName}-${EnvironmentName}-ssh-sg"
      GroupDescription:
        Fn::Sub: "${SystemName}-${EnvironmentName}-ssh-sg"
      VpcId:
        Ref: VPC1
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 22
          ToPort: 22
          CidrIp: 172.18.0.0/16
        - IpProtocol: tcp
          FromPort: 22
          ToPort: 22
          CidrIp: 192.168.0.0/16
      Tags:
        - Key: Name
          Value:
            Fn::Sub: "${SystemName}-${EnvironmentName}-ssh-sg"
  # Security Group (RDP)
  SecurityGroupRDP:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupName:
        Fn::Sub: "${SystemName}-${EnvironmentName}-rdp-sg"
      GroupDescription:
        Fn::Sub: "${SystemName}-${EnvironmentName}-rdp-sg"
      VpcId:
        Ref: VPC1
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 3389
          ToPort: 3389
          CidrIp: 172.18.0.0/16
        - IpProtocol: tcp
          FromPort: 3389
          ToPort: 3389
          CidrIp: 192.168.0.0/16
      Tags:
        - Key: Name
          Value:
            Fn::Sub: "${SystemName}-${EnvironmentName}-rdp-sg"
  # Security Group (Ping)
  SecurityGroupICMP:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupName:
        Fn::Sub: "${SystemName}-${EnvironmentName}-icmp-sg"
      GroupDescription:
        Fn::Sub: "${SystemName}-${EnvironmentName}-icmp-sg"
      VpcId:
        Ref: VPC1
      SecurityGroupIngress:
        - IpProtocol: icmp
          FromPort: 8
          ToPort: -1
          CidrIp: 172.18.0.0/16
        - IpProtocol: icmp
          FromPort: 8
          ToPort: -1
          CidrIp: 192.168.0.0/16
      Tags:
        - Key: Name
          Value:
            Fn::Sub: "${SystemName}-${EnvironmentName}-icmp-sg"

VPN接続

先述のCloudFormationテンプレートからスタックを作成するとVPN接続が1つ作成されていますのでマネジメントコンソールから確認してみます。

この接続に対してコンソール上部にある「設定のダウンロード」ボタンをクリックするとオンプレ側ルーターに設定するコンフィグファイルをダウンロードすることができます。

ベンダー、プラットフォーム、ソフトウェアの欄を適切に選択して「ダウンロード」してください。

ダウンロードしたファイルは以下の様な感じでIKE、IPSec、BGPの設定内容が記載されています。

この内容をオンプレにあるRTX830に適用していきます。 オンプレ側環境は千差万別ですので、コンフィグファイルの適用前にその内容はきちんと確認しておいた方が良いでしょう。(初めてVPNを張る場合といったシンプルな環境あればコンフィグの内容をまるっと実行しても問題ないかと思われます)

オンプレ側の設定が反映されれば下図の様にトンネルが張れているはずです。

Ping確認

最後にAWS側に疎通確認用インスタンスを立ててオンプレ側のドメインコントローラー(192.168.9.61、192.168.9.62)にPingを打ってみるときちんと疎通できていることが確認できました。(EC2の構築手順は省略)

最後に

ざっとこんな感じです。 この環境をベースに本来の目的である検証作業を進めていきたいと思います。