SCPを使用してAmazon EC2で起動できるインスタンスタイプを制限する

こんにちは。サービスグループの武田です。アクセスキーが漏洩して高額請求につながるひとつのケースとして、高額なEC2インスタンスの起動があります。AWS OrganizationsのSCPを用いて、そのようなインスタンスタイプの起動を制限してみます。
2021.05.20

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

こんにちは。サービスグループの武田です。

皆さんAWSはセキュアに利用できていますか?自信を持って Yes と言えない場合は次のエントリなどをぜひ熟読ください。

さて世間ではSQLインジェクションなどが話題ですが、被害の契機として多いのはアクセスキーの漏洩です。機密情報のないアカウントであっても、高額なEC2インスタンスを起動されるなどけっして少なくはない被害が起こりえます。

このような対策を万全にしていたとしても事故を100%防ぐことはできません。ほかにできることはないのでしょうか?

アクセスキーが漏洩して高額請求につながるひとつのケースとして、高額なEC2インスタンスの起動があります。このエントリではAWS OrganizationsのSCPを用いて、そのようなインスタンスタイプの起動を制限してみます。

EC2インスタンスのDry Runについて

インスタンスの起動を制限できているかどうかは、実際にAPIを叩いて確認するしかありません。仮に設定ミスをしていた場合、本当に高額インスタンスを起動してしまいます。そこで活用できるのがDry Runです。インスタンス起動コマンドに--dry-runのオプションを指定することで権限のチェックのみを行えます。具体的に次のようなメッセージが表示されればOKです。

$ aws ec2 run-instances --image-id $(aws ssm get-parameters --names /aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2 --query 'Parameters[0].[Value]' --output text) --count 1 --instance-type t3.micro --dry-run

An error occurred (DryRunOperation) when calling the RunInstances operation: Request would have succeeded, but DryRun flag is set.

エラーステータスなので最初は戸惑いますが Request would have succeeded と表示されているのがポイントです。

やってみた

それでは実際にSCPを設定して確認してみましょう。

次のポリシーはt3ファミリー以外のインスタンスタイプの起動を禁止します。作成して検証アカウントにアタッチします。

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "RequireT3Family",
      "Effect": "Deny",
      "Action": "ec2:RunInstances",
      "Resource": "arn:aws:ec2:*:*:instance/*",
      "Condition": {
        "StringNotLike": {
          "ec2:InstanceType": "t3.*"
        }
      }
    }
  ]
}

準備ができたらコマンドを叩いて確認してみます。

$ aws ec2 run-instances --image-id $(aws ssm get-parameters --names /aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2 --query 'Parameters[0].[Value]' --output text) --count 1 --instance-type t3.micro --dry-run

An error occurred (DryRunOperation) when calling the RunInstances operation: Request would have succeeded, but DryRun flag is set.

$ aws ec2 run-instances --image-id $(aws ssm get-parameters --names /aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2 --query 'Parameters[0].[Value]' --output text) --count 1 --instance-type t3a.micro --dry-run

An error occurred (UnauthorizedOperation) when calling the RunInstances operation: You are not authorized to perform this operation. Encoded authorization failure message: KDcwxgnYSP...

t3.microは変わらずsucceededですが、t3a.microUnauthorizedOperation となり起動に失敗しました。SCPが効いているようです。

今回の目的は高額インスタンスの起動制限でした。現在使用できるインスタンスタイプは公式ドキュメントで確認できます。リージョンによって使用可能なインスタンスタイプが変わりますが、バージニア北部がおそらく一番種類豊富なはずです。確認する際はリージョンに注意してください。

448コアとかあるんですねぇ。こんなの起動されたらたまったもんじゃないですね。まるっと制限しちゃいましょう。

{
	"Version": "2012-10-17",
	"Statement": [
		{
			"Sid": "RestrictExpensiveInstanceType",
			"Effect": "Deny",
			"Action": "ec2:RunInstances",
			"Resource": "arn:aws:ec2:*:*:instance/*",
			"Condition": {
				"StringLike": {
					"ec2:InstanceType": [
					    "*.???xlarge",
					    "*.56xlarge",
					    "p4d.*",
					    "p3dn.*"
					]
				}
			}
		}
	]
}

変更できたら確認してみます。

$ aws ec2 run-instances --image-id $(aws ssm get-parameters --names /aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2 --query 'Parameters[0].[Value]' --region us-east-1 --output text) --count 1 --instance-type u-12tb1.112xlarge --dry-run --region us-east-1

An error occurred (UnauthorizedOperation) when calling the RunInstances operation: You are not authorized to perform this operation. Encoded authorization failure message: FRItL3qaVM...

$ aws ec2 run-instances --image-id $(aws ssm get-parameters --names /aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2 --query 'Parameters[0].[Value]' --region us-east-1 --output text) --count 1 --instance-type p4d.24xlarge --dry-run --region us-east-1

An error occurred (UnauthorizedOperation) when calling the RunInstances operation: You are not authorized to perform this operation. Encoded authorization failure message: px5afgBI80...

制限できてます!すばら!

まとめ

アクセスキーの漏洩からマイニングなどに不正利用されるケースが増えているようです。普段からセキュリティ意識を持って、できることから取り組んでいきましょう。

参考リンク