マネージドプレフィックスリストを利用したセキュリティグループのルール数の計算方法について

記事タイトルとURLをコピーする

みなさん、こんにちは。AWS CLI が好きなテクニカルサポート課の市野です。

マネージドプレフィックスリストを用いたセキュリティグループの管理をご検討のお客様で、ルール数の計算が合わない場面があり、エントリ数の設定などハマりやすいポイントがありましたので、以下、検証時の内容を備忘録として記載します。

また、せっかくですので、大量のデータが CSV ファイルとして存在しているなどの想定で、AWS CLI を利用した手順として作成していますので、大量のルールの管理に苦慮されている場合のご参考となれば幸いです。

想定

  • セキュリティグループのルール数については上限緩和しておらず、デフォルトのまま(60)で利用している。
  • プレフィックスリストの CIDR とその説明は CSV ファイルで管理されていると想定。(prefixlist-01.csv、prefixlist-02.csv)
  • 該当の CSV ファイルから読み取って AWS CLI で一括登録する処理として組み立てる。
  • プレフィックスリストは2つ作り、同一のセキュリティグループのインバウンドルールに以下のようにアタッチする。
    • 80/TCP → プレフィックスリスト1
    • 8080/TCP → プレフィックスリスト2

検証内容

セキュリティグループのルールにマネージドプレフィックスリストを含めた時のルール数のカウント方法の確認

まとめ

少し手順も長く、ブログのエントリ自体が長くなってしまったので、結論を先に。

AWS 公式ドキュメントにも記載があることを確認しましたが、セキュリティグループのルール内からマネージドプレフィックスリストを参照する場合、該当のマネージドプレフィックスリストとして作成する際に設定した最大エントリ数がカウントされます。

実際にエントリとして登録されている CIDR の記述の行数ではない点に注意が必要です。

検証手順

環境

以下の通り、Amazon CloudShell を利用して実行します。

[cloudshell-user@ip-10-0-162-194 ~]$ cat /etc/os-release 
NAME="Amazon Linux"
VERSION="2"
ID="amzn"
ID_LIKE="centos rhel fedora"
VERSION_ID="2"
PRETTY_NAME="Amazon Linux 2"
ANSI_COLOR="0;33"
CPE_NAME="cpe:2.3:o:amazon:amazon_linux:2"
HOME_URL="https://amazonlinux.com/"

[cloudshell-user@ip-10-0-162-194 ~]$ bash --version
GNU bash, version 4.2.46(2)-release (x86_64-koji-linux-gnu)
Copyright (C) 2011 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>

This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

一つ目のプレフィックスリストのための処理

プレフィックスリスト管理表の作成

cat << EOF > prefixlist-01.csv
cidr,description
10.0.0.0/27,subnet-1a
EOF

プレフィックスリスト管理表から --entries オプション用文字列の生成

ENTRIES=""
SEPARATOR=""
while read line
do
  ENTRIES+="${SEPARATOR}Cidr=$(cut -d ',' -f 1 <<<$line),"
  ENTRIES+="Description=$(cut -d ',' -f 2 <<<${line})"
  if [ "${SEPARATOR}" = "" ]; then
    SEPARATOR=" "
  fi
done < <(tail -n +2 prefixlist-01.csv) 

echo ${ENTRIES}

プレフィックスリストの作成

リスト( CSV ファイル)には 1 エントリのみの記載になっているが、将来用に --max-entries を 32 とし、確保しておく想定をしている。

aws ec2 create-managed-prefix-list \
  --prefix-list-name prefixlist-01 \
  --max-entries 32 \
  --address-family IPv4 \
  --entries $(echo "${ENTRIES}")

【注意】
--prefix-list-name オプションの入力値は既存のプリフィックスリスト名との重複を考慮していない点に注意が必要です。
重複が起こった場合、後述のプリフィクスリスト ID の取得後の処理でエラーが出るので注意が必要です。

二つ目のプレフィックスリストのための処理

プレフィックスリスト管理表の作成

cat << EOF > prefixlist-02.csv
cidr,description
10.1.0.0/27,subnet-1a
10.1.0.64/26,subnet-1b
10.1.1.0/27,subnet-2b
10.1.1.64/26,subnet-2b
10.1.2.0/27,subnet-3a
10.1.2.64/26,subnet-3b
10.1.3.0/27,subnet-4a
10.1.3.64/26,subnet-4b
10.1.4.0/27,subnet-5a
10.1.4.64/26,subnet-5a
10.1.5.0/27,subnet-6a
10.1.5.64/26,subnet-6c
10.1.6.0/27,subnet-7a
10.1.6.64/26,subnet-7a
10.1.7.0/27,subnet-8a
10.1.7.64/26,subnet-8b
10.1.8.0/27,subnet-9a
10.1.8.64/26,subnet-9b
10.1.9.0/27,subnet-10a
10.1.9.64/26,subnet-10b
10.1.10.0/27,subnet-11a
10.1.10.64/26,subnet-11b
10.1.11.0/27,subnet-12b
10.1.11.64/26,subnet-12b
10.1.12.0/27,subnet-13a
10.1.12.64/26,subnet-13b
10.1.13.0/27,subnet-14a
10.1.13.64/26,subnet-14b
10.1.14.0/27,subnet-15a
10.1.14.64/26,subnet-15a
10.1.15.0/27,subnet-16a
10.1.15.64/26,subnet-16c
10.1.16.0/27,subnet-17a
10.1.16.64/26,subnet-17a
10.1.17.0/27,subnet-18a
10.1.17.64/26,subnet-18b
10.1.18.0/27,subnet-19a
10.1.18.64/26,subnet-19b
10.1.19.0/27,subnet-20a
10.1.19.64/26,subnet-20b
EOF

プレフィックスリスト管理表から --entries オプション用文字列の生成

ENTRIES=""
SEPARATOR=""
while read line
do
  ENTRIES+="${SEPARATOR}Cidr=$(cut -d ',' -f 1 <<<$line),"
  ENTRIES+="Description=$(cut -d ',' -f 2 <<<${line})"
  if [ "${SEPARATOR}" = "" ]; then
    SEPARATOR=" "
  fi
done < <(tail -n +2 prefixlist-02.csv) \

echo ${ENTRIES}

プレフィックスリストの作成

ここでは、--max-entries はリストに存在している行数(40)としている。(件数が確定している想定)

aws ec2 create-managed-prefix-list \
  --prefix-list-name prefixlist-02 \
  --max-entries 40 \
  --address-family IPv4 \
  --entries $(echo "${ENTRIES}")

【注意】
--prefix-list-name オプションの入力値は既存のプリフィックスリスト名との重複を考慮していない点に注意が必要です。
重複が起こった場合、後述のプリフィクスリスト ID の取得後の処理でエラーが出るので注意が必要です。

セキュリティグループの作成とルールへのプリフィックスリストの適用

セキュリティグループの作成

VPC_ID=vpc-xxxxxxxxxxxxxxxxx

aws ec2 create-security-group \
  --vpc-id ${VPC_ID} \
  --group-name for-prefix \
  --description sg-for-prefix

【注意】
上記コマンドでは、--group-name オプションの値として設定した文字列と、同一のセキュリティグループ名を持つ既存のセキュリティグループの考慮をしていないため注意が必要です。

セキュリティグループへのプリフィックスリストの適用

セキュリティグループ ID の取得
SECURITY_GROUP_ID=$(aws ec2 describe-security-groups \
  --filters "Name=group-name,Values=for-prefix" \
  --query "SecurityGroups[].GroupId" \
  --output text) \
  && echo ${SECURITY_GROUP_ID}
プリフィックスリスト ID の取得(一つ目)
PREFIX_LIST_ID_01=$(aws ec2 describe-managed-prefix-lists \
  --filters "Name=prefix-list-name,Values=prefixlist-01" \
  --query 'PrefixLists[].PrefixListId' \
  --output text) \
  && echo ${PREFIX_LIST_ID_01}
プリフィックスリスト ID の取得(二つ目)
PREFIX_LIST_ID_02=$(aws ec2 describe-managed-prefix-lists \
  --filters "Name=prefix-list-name,Values=prefixlist-02" \
  --query 'PrefixLists[].PrefixListId' \
  --output text)
セキュリティグループへのルールの追加(一つ目)
aws ec2 authorize-security-group-ingress \
  --group-id ${SECURITY_GROUP_ID} \
  --ip-permissions "ToPort=80,FromPort=80,IpProtocol=tcp,PrefixListIds=[{Description=${PREFIX_LIST_ID_01},PrefixListId=${PREFIX_LIST_ID_01}}]"
セキュリティグループへのルールの追加(二つ目)そしてエラーが発生
aws ec2 authorize-security-group-ingress \
  --group-id ${SECURITY_GROUP_ID} \
  --ip-permissions "ToPort=8080,FromPort=8080,IpProtocol=tcp,PrefixListIds=[{Description=${PREFIX_LIST_ID_02},PrefixListId=${PREFIX_LIST_ID_02}}]"

戻り値

An error occurred (RulesPerSecurityGroupLimitExceeded) when calling the AuthorizeSecurityGroupIngress operation: The maximum number of rules per security group has been reached.

エラー内容の確認と精査

発生したエラーメッセージには「The maximum number of rules per security group has been reached.」とあるので、セキュリティグループのルールの上限値に達したものと推察されます。

新規に作成したセキュリティグループのため、プレフィックスリスト1に記載のエントリ 1 + プレフィックスリスト2に記載のエントリ 40 = 41 となっている計算をしていましたので、該当のエラーが出る想定をしていませんでした。

あらためて、マネージドプレフィックスリストについて公式ドキュメントを確認したところ、ちゃんと以下のように記載がありました。

マネージドプレフィックスリストを使用して CIDR ブロックをグループ化する - プレフィックスリストの概念とルール

リソース内でプレフィックスリストを参照する場合、プレフィックスリストのエントリの最大数は、リソースのエントリの数のクォータに対してカウントされます。例えば、エントリ数が 20 個のプレフィックスリストを作成し、セキュリティグループルール内でそのプレフィックスリストを参照する場合、セキュリティグループの 20 個のルールとしてカウントされます。

上記の記載の通り、セキュリティグループ内でプレフィックスリストを参照する場合、作成時の最大エントリ数としてカウントされるため、今回の例では、プレフィックスリスト1に設定した最大エントリ数 32 + プレフィックスリスト2に設定した最大エントリ数 40 = 72 としてカウントされ、「セキュリティグループ当たりのインバウンドルールまたはアウトバウンドルールの数」のデフォルト 60 を超えたため発生したエラーだと分かりました。

修正と再設定による確認

プレフィックスリスト1の修正

aws ec2 modify-managed-prefix-list \
  --prefix-list-id ${PREFIX_LIST_ID_01} \
  --max-entries 20

戻り値

{
    "PrefixList": {
        "PrefixListId": "pl-00000000000000000",
        "AddressFamily": "IPv4",
        "State": "modify-in-progress",
        "StateMessage": "Attempting to modify maximum entries from (32) to (20).",
        "PrefixListArn": "arn:aws:ec2:ap-northeast-1:000000000000:prefix-list/pl-00000000000000000",
        "PrefixListName": "prefixlist-01",
        "MaxEntries": 32,
        "Version": 1,
        "OwnerId": "000000000000"
    }
}

実際には、State が modify-complete となるまで、待機する必要があります。

セキュリティグループへのルールの追加(二つ目)の再試行

aws ec2 authorize-security-group-ingress \
  --group-id ${SECURITY_GROUP_ID} \
  --ip-permissions "ToPort=8080,FromPort=8080,IpProtocol=tcp,PrefixListIds=[{Description=${PREFIX_LIST_ID_02},PrefixListId=${PREFIX_LIST_ID_02}}]"

エラーなくセキュリティグループへのルール追加が完了することを確認。

最後に

  • 試しに、すでにセキュリティグループにアタッチされたマネージドプレフィックスリストに対して、セキュリティグループの上限値を超えるだけの最大エントリ数を設定するように、modify-managed-prefix-list を実行すると、AWS CLI 上の API コールではエラー発生はないものの、結果的に State が modify-failed となり、失敗します。( modify-managed-prefix-list サブコマンド実行時には気づくことができないので注意が必要です。)
  • ブログのエントリ中では、マネージドプレフィックスリストを雑に作っていますが、もう少しまとめられる CIDR はまとめるなどの整理は必要です。
  • 結局、セキュリティグループを含め、全体的なネットワーク設計は必要

では、また。

市野 和明 (記事一覧)

マネージドサービス部・テクニカルサポート課

お客様から寄せられたご質問や技術検証を通じて得られた気づきを投稿していきます。

情シスだった前職までの経験で、UI がコロコロ変わる AWS においては GUI で手順を残していると画面構成が変わってしまって後々まごつくことが多かった経験から、極力変わりにくい AWS CLI での記事が多めです。

X(Twitter):@kazzpapa3(AWS Community Builder)