LoginSignup
0

posted at

CloudFormationで最低限のセキュリティ設計を考慮したクラウド環境をさくっと建てる

本記事の内容

  • AWSが提供するCloudFormationサービスを利用し、AWSのクラウド環境に最低限のセキュリティ設計を考慮したサーバをさくっと建てる方法を記載した記事です。
  • AWSアカウントをすでに持って入れば、本ページに記載のCloudFormationテンプレートを使うことで、10分程でクラウド環境を作成できます。

先日投稿した「【AWS入門】知識ゼロでもこれを読めばAWSを理解しつつ1~2時間後にサーバを建てられる」の記事で手動で構築した環境をCloudFormationを使って作成します。

本記事の手順で以下のような構成のクラウド環境を作成できます。
aws1.drawio_r2.png

またAWSの操作画面はサービスリリースと共に更新されていくため、本記事をご覧いただくタイミングによっては、現在の画面と異なる場合があります。その点はご了承頂ければと思います。※本記事内の画面キャプチャーは2022年5月の物となっています。

設計のポイントと意図を以下に記載しておきます。

  • 設計のポイント

    • クラウド内のネットワークからインターネット接続するためにインターネットゲートウェイを設定
    • クラウド内のネットワークをパブリックとプライベートなネットワークに分離
    • プライベートネットワークにアプリケーション(AP)サーバを設置
    • パブリックネットワークにAPサーバへのSSH接続用の踏み台サーバを設置
    • プライベートネットワーク内のAPサーバがインターネット通信を出来るようにするNATゲートウェイをパブリックネットワークに設置
  • 設計の意図

    • クラウド内のネットワークをパブリック/プライベートに分離。サーバを用途に応じ適切に配置することでセキュリティ向上を図る。
    • 各サーバへの通信は、ファイアウォール(AWSではネットワークACLとセキュリティグループという設定がある)で適切に制御する。
      • APサーバへの通信は、インターネットからのhttp通信(8080)と踏み台サーバからのSSH接続のみ接続可能とする。
      • 踏み台サーバへの通信は、SSH接続のみ許可
    • 踏み台サーバのログイン方法も公開鍵認証とし、セキュアなログインを行う。※AWSのEC2サーバは公開鍵認証方式でのログインがデフォルト

実施環境

  • Windows 10
  • Chrome
  • AWS

手順の流れ

  1. CloudFormationで環境を構築
  2. 投入したテンプレートの解説

1. CloudFormationで環境を構築

AWSマネジメントコンソールにアクセスし、「CloudFormationサービス」を選択する。
1.png
2.png
3.png

「スタックの作成」をクリックする。
4.png

「テンプレートファイルのアップロード」をクリックする。
5.png

「ファイルの選択」をクリックし、アップロードするテンプレートファイルを選択する。※ファイルは、2.投入したテンプレートの解説に記載の「VPC_CloudFormation_r2_for_Qita.yml」
6.png

「次へ」をクリックする。
7.png

「スタックの名前」を入力する。
8.png

パラメータとして、EC2にログインする際のキーペアーを設定し、「次へ」をクリックする。※前提として事前にキーペーアを作成を行っていること
9.png

画面の末尾に表示されている「次へ」をクリックする。
10.png
11_2.png

画面の末尾に表示されている「スタックの作成」をクリックする。
11.png
12.png

構築が開始すると以下のような画面になる。
13.png

画面左の欄で表示が「CREATE_IN_PROGRESS」から「CREATE_COMPLETE」に変わったらCloudFormationによる構築が完了。
14.png

それぞれの画面で作成されたリソースを確認する

VPC
20.png

サブネット
21.png

インターネットゲートウェイ
22.png

NATゲートウェイ
23.png

ルートテーブル
25.png

セキュリティグループ
24.png

・パブリックサブネット用のセキュリティグループ
28.png

・プライベートサブネット用のセキュリティグループ
27.png
インバウンドルールの一行目でHTTP通信の設定を行っている。
二行目の設定でSSH通信を行っており、パブリックサブネットからの通信のみに制限している。

EC2インスタンス
26.png

以上の手順でクラウド環境の構築は完了である。

2. 投入したテンプレートの解説

以下が実際に投入したファイルです。

VPC_CloudFormation_r2_for_Qita.yml
AWSTemplateFormatVersion: 2010-09-09
Parameters:
  KeyName:
    Description: The Key Pair for the EC2 instance.
    Type: "AWS::EC2::KeyPair::KeyName"
  Ec2ImageId:
    Type: AWS::SSM::Parameter::Value<String>
    Default: /aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2

Resources:

#####################################################
# VPC
#####################################################
  CFStudyVPC:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: 10.0.0.0/16
      Tags:
        - Key: Name
          Value: CFStudyVPC

#####################################################
# Public Subnet
#####################################################
  CFStudyPubSub:
    Type: AWS::EC2::Subnet
    Properties:
      CidrBlock: 10.0.1.0/24
      MapPublicIpOnLaunch: true
      VpcId: !Ref CFStudyVPC
      AvailabilityZone: ap-northeast-1a
      Tags:
        - Key: Name
          Value: CFStudyPubSub

#####################################################
# Private Subnet
#####################################################
  CFStudyPriSub:
    Type: AWS::EC2::Subnet
    Properties:
      CidrBlock: 10.0.2.0/24
      MapPublicIpOnLaunch: false
      VpcId: !Ref CFStudyVPC
      AvailabilityZone: ap-northeast-1a
      Tags:
        - Key: Name
          Value: CFStudyPriSub

#####################################################
# Internet Gateway
#####################################################
  CFStudyIG:
    Type: AWS::EC2::InternetGateway
    Properties:
      Tags:
        - Key: Name
          Value: CFStudyIG
  AttachCfInternetGateway:
    Type: AWS::EC2::VPCGatewayAttachment
    Properties:
      InternetGatewayId : !Ref CFStudyIG
      VpcId: !Ref CFStudyVPC

#####################################################
# RouteTable For Public Subnet
#####################################################
  CFStudyRouteTablePubSub:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref CFStudyVPC
      Tags:
        - Key: Name
          Value: CFStudyRouteTablePubSub
          
  RouteForPublicSubnet:
    Type: AWS::EC2::Route
    Properties:
      RouteTableId: !Ref CFStudyRouteTablePubSub
      DestinationCidrBlock: 0.0.0.0/0
      GatewayId: !Ref CFStudyIG

  CfAssocciateRouteTableForPublicSubnet:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      RouteTableId: !Ref CFStudyRouteTablePubSub
      SubnetId: !Ref CFStudyPubSub

#####################################################
# NAT-GW and Elastic IP
#####################################################
  NatGatewayEIP:
    Type: AWS::EC2::EIP
    Properties:
      Domain: vpc

  NatGateway:
    Type: AWS::EC2::NatGateway
    Properties:
      AllocationId:
        !GetAtt NatGatewayEIP.AllocationId 
      SubnetId: !Ref CFStudyPubSub
      Tags:
        - Key: Name
          Value: NatGateway

#####################################################
# RouteTable For Priavte Subnet
#####################################################
  CFStudyRouteTablePriSub:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref CFStudyVPC
      Tags:
        - Key: Name
          Value: CFStudyRouteTablePriSub

  RouteForPrivateSubnet:
    Type: AWS::EC2::Route
    Properties:
      RouteTableId: !Ref CFStudyRouteTablePriSub
      DestinationCidrBlock: 0.0.0.0/0
      NatGatewayId: !Ref NatGateway

  CfAssocciateRouteTableForPrivateSubnet:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      RouteTableId: !Ref CFStudyRouteTablePriSub
      SubnetId: !Ref CFStudyPriSub

#####################################################
# EC2(Bastion) on Public Subnet
#####################################################
  EC2Pub: 
    Type: AWS::EC2::Instance
    Properties: 
      ImageId: !Ref Ec2ImageId
      KeyName: !Ref KeyName
      InstanceType: t2.micro
      NetworkInterfaces: 
        - AssociatePublicIpAddress: "true"
          DeviceIndex: "0"
          SubnetId: !Ref CFStudyPubSub
          GroupSet:
            - !Ref EC2SGPub
      Tags:
          - Key: Name
            Value: CFStudySSH

#####################################################
# Security Group for Public Subnet
#####################################################
  EC2SGPub:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupName: CFStudyPubSG
      GroupDescription: Security Group for Public Subnet
      VpcId: !Ref CFStudyVPC
      SecurityGroupIngress:
        # ssh
        - IpProtocol: tcp
          FromPort: 22
          ToPort: 22
          CidrIp: '0.0.0.0/0'

#####################################################
# EC2(Aplication Sever) on Private Subnet
#####################################################
  EC2Pri: 
    Type: AWS::EC2::Instance
    Properties: 
      ImageId: !Ref Ec2ImageId
      KeyName: !Ref KeyName
      InstanceType: t2.micro
      NetworkInterfaces: 
        - AssociatePublicIpAddress: "false"
          DeviceIndex: "0"
          SubnetId: !Ref CFStudyPriSub
          GroupSet:
            - !Ref EC2SGPriVate
      Tags:
          - Key: Name
            Value: CFStudyAP

#####################################################
#  Security Group for Private Subnet
#####################################################
  EC2SGPriVate:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupName: CFStudyPriSG
      GroupDescription: Security Group for Private Subnet
      VpcId: !Ref CFStudyVPC
      SecurityGroupIngress:
        - SourceSecurityGroupId: !Ref EC2SGPub
          IpProtocol: tcp
          FromPort:  22
          ToPort:  22
        # Web Access
        - IpProtocol: tcp
          FromPort:  8080
          ToPort:  8080
          CidrIp: '0.0.0.0/0'

以下が説明です。

AWSTemplateFormatVersion: 2010-09-09
Parameters:
  KeyName:
    Description: The Key Pair for the EC2 instance.
    Type: "AWS::EC2::KeyPair::KeyName"
  Ec2ImageId:
    Type: AWS::SSM::Parameter::Value<String>
    Default: /aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2
  • AWSTemplateFormatVersion: 2010-09-09

    • 上記はテンプレートフォーマットのバージョン宣言で、年月日は固定です。CloudFormationテンプレートの先頭に記載するおまじない。
  • ParametersのKeyName:

    • EC2ログイン時に必要なキーペーアをCloudFormation実行時に指定できるようにしたパラメータです。
      本項目で設定するキーファイルは、テンプレート内の後半で記載しているEC2の「EC2Pub」や「EC2Pri」の「KeyName: !Ref KeyName」で参照されることで利用できるようになります。
  • ParametersのEc2ImageId:

    • Amazon linux 2 の最新のAMIのIDを参照するためのパラメータです。
Resources:
#####################################################
# VPC
#####################################################
  CFStudyVPC:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: 10.0.0.0/16
      Tags:
        - Key: Name
          Value: CFStudyVPC
  • Resources:

    • 以降でAWSのリソースに関する記載を行うという宣言文です。こちらもおまじないです。
  • CFStudyVPC:

    • 今回作成するVPCである「CFStudyVPC」の設定を書いています。「Properties」の「CidrBlock: 10.0.0.0/16」でIPアドレスの範囲を指定しております。
    • 「- Key: Name Value: CFStudyVPC」の設定でNameタグに「CFStudyVPC」という値を設定して、AWSのコンソールで名前が表示されるようにしています。Key: Nameの指定は他の項目でも利用できますので、頻出です。
#####################################################
# Public Subnet
#####################################################
  CFStudyPubSub:
    Type: AWS::EC2::Subnet
    Properties:
      CidrBlock: 10.0.1.0/24
      MapPublicIpOnLaunch: true
      VpcId: !Ref CFStudyVPC
      AvailabilityZone: ap-northeast-1a
      Tags:
        - Key: Name
          Value: CFStudyPubSub
  • CFStudyPubSub:
    • 「Type: AWS::EC2::Subnet」で指定しているようにサブネット設定となります。
    • IPアドレスの範囲は「CidrBlock: 10.0.1.0/24」で設定しています。
    • 「MapPublicIpOnLaunch: true」とすることで外部からアクセス可能なパブリックサブネットとなります。
    • 「VpcId: !Ref CFStudyVPC」こちらの設定でサブネットを作成するVPCをどこにするか指定しています。
    • [AvailabilityZone: ap-northeast-1a」の設定で作成するサブネットは、東京リージョンのAZ(1a)に所属するとしています。

Private Subnetの方の説明は省きます。「MapPublicIpOnLaunch: false」とすることでプライベートサブネットになります。

#####################################################
# Internet Gateway
#####################################################
  CFStudyIG:
    Type: AWS::EC2::InternetGateway
    Properties:
      Tags:
        - Key: Name
          Value: CFStudyIG
  AttachCfInternetGateway:
    Type: AWS::EC2::VPCGatewayAttachment
    Properties:
      InternetGatewayId : !Ref CFStudyIG
      VpcId: !Ref CFStudyVPC
  • CFStudyIG:

    • 作成したVPCをインターネットと通信可能にするためのインターネットゲートウェイの設定となります
  • AttachCfInternetGateway:

    • このタグにより作成したインターネットゲートウェイをどこのVPCに関連付けるかの設定を行っています。
#####################################################
# RouteTable For Public Subnet
#####################################################
  CFStudyRouteTablePubSub:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref CFStudyVPC
      Tags:
        - Key: Name
          Value: CFStudyRouteTablePubSub
          
  RouteForPublicSubnet:
    Type: AWS::EC2::Route
    Properties:
      RouteTableId: !Ref CFStudyRouteTablePubSub
      DestinationCidrBlock: 0.0.0.0/0
      GatewayId: !Ref CFStudyIG

  CfAssocciateRouteTableForPublicSubnet:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      RouteTableId: !Ref CFStudyRouteTablePubSub
      SubnetId: !Ref CFStudyPubSub
  • CFStudyRouteTablePubSub:

    • パブリックサブネット用のルートテーブルの設定です。
  • RouteForPublicSubnet:

    • このタグによりインターネット向けの通信をインターネットゲートウェイを通るようにルーティングしています。
  • CfAssocciateRouteTableForPublicSubnet:

    • 作成したルートテーブルをパブリックサブネットに紐づける設定を行っています。
#####################################################
# NAT-GW and Elastic IP
#####################################################
  NatGatewayEIP:
    Type: AWS::EC2::EIP
    Properties:
      Domain: vpc

  NatGateway:
    Type: AWS::EC2::NatGateway
    Properties:
      AllocationId:
        !GetAtt NatGatewayEIP.AllocationId 
      SubnetId: !Ref CFStudyPubSub
      Tags:
        - Key: Name
          Value: NatGateway
  • NatGatewayEIP:

    • NATゲートウェイに紐づけを行う用のEIP(固定IPアドレス)を作成する設定です。
  • NatGateway:

    • NATゲートウェイの設定となります。
    • AllocationId: !GetAtt NatGatewayEIP.AllocationId でNATゲートウェイに紐づけるEIPのIDを指定しています。
    • SubnetId: !Ref CFStudyPubSub でどこのサブネットにNATゲートウェイを設置するか指定しています。

RouteTable For Priavte Subnet の設定もほぼ同じなので割愛します。
一点だけ違うのは、プライベートサブネットのため「RouteForPrivateSubnet:」のルーティング設定でインターネット向けの通信は直接インターネットゲートウェイにルーティングするのではなく、NATゲートウェイを経由するようにルーティングしています。

#####################################################
# EC2(Bastion) on Public Subnet
#####################################################
  EC2Pub: 
    Type: AWS::EC2::Instance
    Properties: 
      ImageId: !Ref Ec2ImageId
      KeyName: !Ref KeyName
      InstanceType: t2.micro
      NetworkInterfaces: 
        - AssociatePublicIpAddress: "true"
          DeviceIndex: "0"
          SubnetId: !Ref CFStudyPubSub
          GroupSet:
            - !Ref EC2SGPub
      Tags:
          - Key: Name
            Value: CFStudySSH
  • EC2Pub:
    • パブリックサブネットに作成するEC2インスタンス(APサーバ)の設定です
    • ImageId: !Ref Ec2ImageId でファイルの先頭のParameterで設定したインスタンスのイメージ(AMI)を指定しています。
    • InstanceType EC2の性能を指定しています。小型で大丈夫なのでt2.microを指定しています。必要に応じてインスタンスタイプの設計が必要です。
    • NetworkInterfaces:でネットワーク関連の設定です
      • AssociatePublicIpAddress: "true" 本設定をtrueにすることで外部からアクセス可能なEC2インスタンスのパブリックIPを有効化しています。
      • DeviceIndex: "0" プライマリネットワークインターフェイスとしている。
      • SubnetId: !Ref CFStudyPubSub 作成するEC2インスタンスをどこのサブネットに紐づけるか指定を行っている
      • GroupSet: EC2インスタンスに紐づけるセキュリティグループ(ファイアウォール的な物)を指定している
#####################################################
# Security Group for Public Subnet
#####################################################
  EC2SGPub:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupName: CFStudyPubSG
      GroupDescription: Security Group for Public Subnet
      VpcId: !Ref CFStudyVPC
      SecurityGroupIngress:
        # ssh
        - IpProtocol: tcp
          FromPort: 22
          ToPort: 22
          CidrIp: '0.0.0.0/0'
  • EC2SGPub:
    • セキュリティグループの設定です。
    • GroupName: CFStudyPubSG コンソールで表示される際の表示名の指定
    • VpcId: !Ref CFStudyVPC どこのVPCで利用できるように紐づけるかの指定
    • SecurityGroupIngress: ファイアウォールで許可する通信ルールの設定
      • 正解中のどのサーバからのtcpプロトコルの22番ポートの通信を許可する設定
      • 送信元を絞れるGIPをアクセス元が保持している場合は、「CidrIp: '0.0.0.0/0'」のIP部分を変更して指定すること。現状は古オープンでどこのサーバからもアクセス可能である。

EC2(Aplication Sever) on Private Subnet も EC2(Bastion) on Public Subnetの設定とほぼ同様のため割愛する。
正しプライベートサブネットに配置するサーバのためパブリックIPの割り当ては不要であり「AssociatePublicIpAddress: "false"」の設定を行っている。

#####################################################
#  Security Group for Private Subnet
#####################################################
  EC2SGPriVate:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupName: CFStudyPriSG
      GroupDescription: Security Group for Private Subnet
      VpcId: !Ref CFStudyVPC
      SecurityGroupIngress:
        - SourceSecurityGroupId: !Ref EC2SGPub
          IpProtocol: tcp
          FromPort:  22
          ToPort:  22
        # Web Access
        - IpProtocol: tcp
          FromPort:  8080
          ToPort:  8080
          CidrIp: '0.0.0.0/0'
  • EC2SGPriVate:
    • プライベートサブネットに存在するEC2インスタンス向けの設定です。
    • 「SourceSecurityGroupId: !Ref EC2SGPub」「IpProtocol: tcp」「FromPort: 22」「ToPort: 22」の設定で、本セキュリティグループが設定されるインスタンスへのSSH通信はパブリックサブネット「EC2SGPub」からのみ許可するように設定を行っている。
    • SecurityGroupIngress: ファイアウォールで許可する通信ルールの設定
      • 正解中のどのサーバからのtcpプロトコルの8080番ポートの通信を許可する設定
      • 送信元を絞れるGIPをアクセス元が保持している場合は、「CidrIp: '0.0.0.0/0'」のIP部分を変更して指定すること。現状はフルオープンでどこのサーバからもアクセス可能な状態となります。

本記事は以上です。
クラウド環境の作成の手助けになれば嬉しいです。

参考文献

本記事の作成に当たり、以下の情報も参考にさせて頂きました。ありがとうございました。

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
What you can do with signing up
0