14
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 3 years have passed since last update.

株式会社Works Human IntelligenceAdvent Calendar 2021

Day 2

VPCプレフィックスリストとCloudFormationで、セキュリティグループのIP管理をグッと楽にする

Last updated at Posted at 2021-12-01

AWSのEC2インスタンスやALBをパブリックサブネットに置く場合、セキュリティグループで特定のIPからのみアクセスを許可することがあります。

例えば、社内システムなので事業所ネットワークの出口IPからのみHTTPSアクセス可能にしたいといったケースです。

セキュリティグループ設定例
TCP 443 本社ビルネットワークの出口IP/32
TCP 443 大阪事業所ネットワークの出口IP/32

IP管理の問題点

セキュリティグループでの設定は簡単ではありますが、同じようなセキュリティグループが増えてしまうと、IPの追加や変更があった場合に修正が面倒で修正漏れも起きやすくなります。

IP変更であれば、以前のIPは他者が取得する可能性もあるので、セキュリティリスク になる可能性があります。
また、IPの説明を詳しく書いていなければ、時間が経つにつれて 謎のIPと化す というのもよくある話です(経験談)。

NGなセキュリティグループの例
TCP 443 新本社ビルネットワークの出口IP/32 ※これはOK
TCP 443 新大阪事業所ネットワークの出口IP/32 ※これもOK
TCP 443 古い出口IP/32 ※削除漏れ
TCP 443 なんか不明なIP/32 ※削除漏れ且つ謎IP化

VPCプレフィックスリストとは

VPCプレフィックスリストとは、よく使うIPグループを事前に定義しておき、複数のセキュリティグループで使い回すことができる機能です。2020年6月にリリースされた、比較的新しい機能になります。

これがあれば、例えば「社内ネットワークの出口IPリスト」を1つ作っておき、セキュリティグループではプレフィックスリストのIDを指定するだけでよくなります。

さらに、IPの追加や変更も、その共通のプレフィックスリストを修正するだけで完了するので、管理がとても楽になります。
※ちなみに、セキュリティグループ以外にもルートテーブルでも使えますが、この記事では割愛します。

設定例

AWSコンソールから、VPC → マネージドプレフィックスリスト → プレフィックスリストを作成 を選択します。CIDRブロックのところに、IPアドレスと説明を入れます。
prefix-lists-example.png

セキュリティグループでは、カスタムソースとして pl- から始まるプレフィックスリストを指定できます。固定されるのはあくまでIPだけなので、ポートはルール毎に自由に設定できます。
prefix-lists-in-sg.png

プレフィックスリスト設定のポイント

  1. IPには必ず説明を入れる
    説明が空のIPは、謎IP化する確率が高くなります。プレフィックスリストなら一度入れるだけでいいので、面倒くさがらず必ず記載しておきましょう。

  2. ポート設定する単位でグループ化する
    とりあえず使いそうなIPを全部一つのプレフィックスリストに入れてしまうと、不要なIPにまでポートを開けることになってしまい本末転倒です。「オフィスの出口IPリスト」、「外部サービスの出口IPリスト」など、使い回ししやすい単位で作成しましょう。

CloudFormationを使う場合

AWSリソースはCloudFormation(やCDK)で管理している場合も多いと思います。
プレフィックスリストももちろんCloudFormationで定義できます。
以下の例では、将来的なIP変更をコンソールからすることを想定し、パラメータとしてCIDRを入力させています。

AWSTemplateFormatVersion: 2010-09-09
Parameters:
  MainExitIP:
    Type: String
    Description: "本社ビルネットワークの出口IP"
    Default: x.x.x.x/32
    AllowedPattern: (\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})/(\d{1,2})
  OsakaExitIP:
    Type: String
    Description: "大阪事業所ネットワークの出口IP"
    Default: x.x.x.x/32
    AllowedPattern: (\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})/(\d{1,2})
    ConstraintDescription: "CIDRは x.x.x.x/x の形で指定してください"
Resources:
  OfficeNetworkExitIps:
    Type: AWS::EC2::PrefixList
    Properties:
      AddressFamily: IPv4
      Entries:
        - Cidr: !Ref MainExitIP
          Description: "本社ビルネットワークの出口IP(CIDR)"
        - Cidr: !Ref OsakaExitIP
          Description: "大阪事業所ネットワークの出口IP(CIDR)"
      MaxEntries: 20
      PrefixListName: office-network-exit-ips
      Tags:
        - Key: Name
          Value: office-network-exit-ips

プレフィックスリストを複数作る場合のひと工夫

複数のプレフィックスリストを作る場合には、1つのCloudFormation stackに入れておいて他stackからはImportValueで参照すると、プレフィックスリストのIDを書く必要がないので便利です。

プレフィックスリスト用 stack

AWSTemplateFormatVersion: 2010-09-09
Resources:
  OfficeNetworkExitIps:
    Type: AWS::EC2::PrefixList
    Properties:
      AddressFamily: IPv4
      Entries:
        - Cidr: x.x.x.x/32
          Description: "本社ビルネットワークの出口IP(CIDR)"
        - Cidr: x.x.x.x/32
          Description: "大阪事業所ネットワークの出口IP(CIDR)"
      MaxEntries: 20
      PrefixListName: office-network-exit-ips
      Tags:
        - Key: Name
          Value: office-network-exit-ips
  ExternalServiceExitIps:
    Type: AWS::EC2::PrefixList
    Properties:
      AddressFamily: IPv4
      Entries:
        - Cidr: x.x.x.x/24
          Description: サービスA
        - Cidr: x.x.x.x/32
          Description: サービスB
      MaxEntries: 20
      PrefixListName: external-service-exit-ips
      Tags:
        - Key: Name
          Value: external-service-exit-ips
Outputs:
  ExternalServiceExitIpsOutput:
    Description: ""
    Value: !Ref OfficeNetworkExitIps
    Export:
      Name: !Sub "${AWS::StackName}-OfficeNetworkExitIpsPrefixList"
  ExternalServiceExitIpsOutput:
    Description: ""
    Value: !Ref ExternalServiceExitIps
    Export:
      Name: !Sub "${AWS::StackName}-ExternalServiceExitIpsPrefixList"

プレフィックスリストを利用するstack

パラメータとしてstack名を指定させています。Security Groupでは、SourcePrefixListId: !ImportValue を使ってプレフィックスリストを読み込んでいます(ImportValueのAWSドキュメント)。

AWSTemplateFormatVersion: 2010-09-09
Parameters:
  PrefixListStackName:
    Type: String
    Default: test-vpc-prefix-list
    Description: VPCプレフィックスリストのstack名
Resources:
  TestVpc:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: 10.100.0.0/24
      EnableDnsHostnames: true
      Tags:
        - Key: Name
          Value: TestVpc
  TestSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: 社内と外部システムからのアクセス許可
      GroupName: test
      SecurityGroupIngress:
        - SourcePrefixListId: !ImportValue
            'Fn::Sub': '${PrefixListStackName}-OfficeNetworkExitIpsPrefixList'
          FromPort: 443
          ToPort: 443
          IpProtocol: tcp
        - SourcePrefixListId: !ImportValue
            'Fn::Sub': '${PrefixListStackName}-ExternalServiceExitIpsPrefixList'
          FromPort: 443
          ToPort: 443
          IpProtocol: tcp
      VpcId: !Ref TestVpc

最後に

VPCプレフィックスリストとCloudFormationを使えば、セキュリティグループの作成もその後のIP管理もグッと楽になります。

IP管理で悩んでいる方はぜひ使ってみてください。

14
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
14
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?