俺のアウトプット

調べたこと、試したことを書きます

シンプルなネットワークとサーバーをCloudFormationで構築する 〜2. セキュリティ設定〜

前回はVPC、サブネット、インターネットゲートウェイ、ルートテーブルを作成して、ネットワークを構築しました。

oreout.hatenablog.com

今回はセキュリティを作成・設定します。

セキュリティーグループとネットワークACL

VPCのファイアウォール機能として、セキュリティーグループネットワークACLがあります。
両者は適用するレベル(単位)が異なります。 インスタンス単位で動作する第1層のセキュリティーグループ、サブネット単位で動作する第2層のネットワークACLです。

セキュリティーグループとネットワークACLの大まかな違いは下記になります。

セキュリティーグループ ネットワークACL
適用単位 インスタンス単位 サブネット単位
ルール 許可 許可と拒否
ルールロジック すべてのルールを評価 順番にルールを処理
作成されたデフォルト値 インバウンド: すべて拒否
アウトバウンド:すべて許可
インバウンド: すべて許可
アウトバウンド:すべて許可
特徴 ステートフル
許可された送信の戻りは自動的に許可
ステートレス
許可された送信の戻りもルールチェックされる

ネットワークACLは、VPC作成時にデフォルトのネットワークACLが作成されます。 インバウンド、アウトバウンドともにすべて許可されているので、拒否ルールが不要であればデフォルトを利用します。

セキュリティ設定用のテンプレート

今回作成したテンプレートは以下になります。

security.template.yaml

AWSTemplateFormatVersion: 2010-09-09
Parameters:
  ProjectCode:
    Type: String
    Description: Enter your project code
  SSHLocation:
    Type: String
    Description: The IP address range that can be used to SSH to the EC2 instances
    ConstraintDescription: must be a valid IP CIDR range of the form x.x.x.x/x.
    MinLength: 9
    MaxLength: 18
    Default: 0.0.0.0/0
    AllowedPattern: (\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})/(\d{1,2})
Resources:
  SecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      VpcId:
        Fn::ImportValue: !Sub ${ProjectCode}-vpc
      GroupDescription: Enable SSH access via port 22, 80
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 22
          ToPort: 22
          CidrIp: !Ref SSHLocation
        - IpProtocol: tcp
          FromPort: 80
          ToPort: 80
          CidrIp: 0.0.0.0/0
      Tags:
      -
        Key: Name
        Value: !Ref ProjectCode
  NetworkAcl:
    Type: AWS::EC2::NetworkAcl
    Properties:
      VpcId:
        Fn::ImportValue: !Sub ${ProjectCode}-vpc
      Tags:
      -
        Key: Name
        Value: !Ref ProjectCode
  InboundHTTPNetworkAclEntry:
    Type: AWS::EC2::NetworkAclEntry
    Properties:
      NetworkAclId: !Ref NetworkAcl
      RuleNumber: 100
      Protocol: 6
      RuleAction: allow
      Egress: false
      CidrBlock: 0.0.0.0/0
      PortRange:
        From: 80
        To: 80
  InboundSSHNetworkAclEntry:
    Type: AWS::EC2::NetworkAclEntry
    Properties:
      NetworkAclId: !Ref NetworkAcl
      RuleNumber: 101
      Protocol: 6
      RuleAction: allow
      Egress: false
      CidrBlock: 0.0.0.0/0
      PortRange:
        From: 22
        To: 22
  InboundResponsePortsNetworkAclEntry:
    Type: AWS::EC2::NetworkAclEntry
    Properties:
      NetworkAclId: !Ref NetworkAcl
      RuleNumber: 102
      Protocol: 6
      RuleAction: allow
      Egress: false
      CidrBlock: 0.0.0.0/0
      PortRange:
        From: 1024
        To: 65535
  OutBoundHTTPNetworkAclEntry:
    Type: AWS::EC2::NetworkAclEntry
    Properties:
      NetworkAclId: !Ref NetworkAcl
      RuleNumber: 100
      Protocol: 6
      RuleAction: allow
      Egress: true
      CidrBlock: 0.0.0.0/0
      PortRange:
        From: 80
        To: 80
  OutBoundHTTPSNetworkAclEntry:
    Type: AWS::EC2::NetworkAclEntry
    Properties:
      NetworkAclId: !Ref NetworkAcl
      RuleNumber: 101
      Protocol: 6
      RuleAction: allow
      Egress: true
      CidrBlock: 0.0.0.0/0
      PortRange:
        From: 443
        To: 443
  OutBoundResponsePortsNetworkAclEntry:
    Type: AWS::EC2::NetworkAclEntry
    Properties:
      NetworkAclId: !Ref NetworkAcl
      RuleNumber: 102
      Protocol: 6
      RuleAction: allow
      Egress: true
      CidrBlock: 0.0.0.0/0
      PortRange:
        From: 1024
        To: 65535
  SubnetNetworkAclAssociation:
    Type: AWS::EC2::SubnetNetworkAclAssociation
    Properties:
      SubnetId:
        Fn::ImportValue: !Sub ${ProjectCode}-subnet
      NetworkAclId: !Ref NetworkAcl
Outputs:
  WebSecurityGroup:
    Description: Id of the newly created Security Group
    Value: !Ref SecurityGroup
    Export:
      Name: !Sub ${ProjectCode}-web-sg

パラメータ

パラメータは2つあります。

パラメータ 説明
ProjectCode プロジェクトコードを指定します。
各リソースの名前とテンプレート連携(クロススタック参照)で利用します。
SSHLocation SSH接続を許可するIPアドレスです。
デフォルトは制限無しの0.0.0.0/0です。

リソース

1. セキュリティーグループ

VPC上にセキュリティーグループを作成します。
組み込み関数Fn::ImportValueを利用して、前回作成したVPC IDをインポートします。

  SecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      VpcId:
        Fn::ImportValue: !Sub ${ProjectCode}-vpc
      GroupDescription: Enable SSH access via port 22, 80
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 22
          ToPort: 22
          CidrIp: !Ref SSHLocation
        - IpProtocol: tcp
          FromPort: 80
          ToPort: 80
          CidrIp: 0.0.0.0/0

f:id:kitsugi:20180819230325p:plain

この時点では、セキュリティグループに属しているインスタンスはありません。

2. ネットワークACL

ネットワークACLを作成し、サブネットに関連付けをします。
組み込み関数Fn::ImportValueを利用して、前回作成したサブネットIDをインポートします。

  NetworkAcl:
    Type: AWS::EC2::NetworkAcl
    Properties:
      VpcId:
        Fn::ImportValue: !Sub ${ProjectCode}-vpc
  SubnetNetworkAclAssociation:
    Type: AWS::EC2::SubnetNetworkAclAssociation
    Properties:
      SubnetId:
        Fn::ImportValue: !Sub ${ProjectCode}-subnet
      NetworkAclId: !Ref NetworkAcl
ルール設定

ネットワークACLを作成した時点のルールは、インバウンド/アウトバウンドともに、すべて拒否になります。 基本は AWS::EC2::NetworkAclEntryを使用して、許可ルールを設定します。

インバウンド

ルール番号 プロトコル ポート 送信元IP 用途
100 TCP 80 0.0.0.0/0 HTTP
101 TCP 22 0.0.0.0/0 SSH
102 TCP 1024-65535 0.0.0.0/0 サーバー側用一時ポート

アウトバウンド

ルール番号 プロトコル ポート 送信元IP 用途
100 TCP 80 0.0.0.0/0 HTTP
101 TCP 443 0.0.0.0/0 HTTPS
102 TCP 1024-65535 0.0.0.0/0 クライアント側用一時ポート

f:id:kitsugi:20180819230345p:plain

出力

後続のテンプレート用にセキュリティーグループIDをエクスポートします。

パラメータ 説明
WebSecurityGroup セキュリティーグループIDの参照用に、エクスポート名を {プロジェクトコード}-web-sg にします。

スタックの作成

ではスタックを作成してみましょう。

スタックの名前、パラメータを指定します。ProjectCodeは前回と同じ値を設定してください。

f:id:kitsugi:20180820062418p:plain

スタック作成完了後に、出力を確認します。

f:id:kitsugi:20180820062451p:plain

サービス [ネットワーキング & コンテンツ配信] - [VPC] を選択し、各リソースが作成されていることを確認します。

  • ネットワーク ACL
  • セキュリティグループ

参考