はじめに
EC2(Amazon Linux2023)でdnf updateを実行したところ403エラーになってしまい、その原因を見つけるのに苦労したため、同じように悩んでいる人の助けになればいいなと思い、自身の備忘録も兼ねて本記事を執筆してます。
エラー時の構成と設定
構成
今回の構成は、以下の前提条件をもとに構成していました。
- インターネットを介した通信はしない
- 出来る限り最小限のポリシーを設定する
構成は以下になります。
まず、条件1を満たしつつ、EC2インスタンスからdnfを実行するため、AWSが管理しているAmazon Linux2023のリポジトリ用S3バケットal2023-repos-us-east-1-de612dc2
へGateway型のS3エンドポイント経由でアクセスするという構成を取りました。
参照したドキュメント↓↓
更に条件2つ目を満たすために、S3のエンドポイントのポリシーで以下のように権限を絞りました。
- 許可するプリンシパルをEC2に付与しているIAMロールのみに設定("Condition"で設定)
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Enable Access Amazon Linux repository",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::al2023-repos-us-east-1-de612dc2/*",
"Condition": {
"ArnEquals": {
"aws:PrincipalArn": "arn:aws:iam::xxxxxxxxxxxx:role/ec2-role"
}
}
}
]
}
参照したドキュメント↓↓
特定のIAMロールへのアクセスを制限するポリシーを作成できます。aws:PrincipalArn を使用してプリンシパルへのアクセスを許可する必要があります。
EC2に付与しているIAMロールにも、Amazon Linux2023のリポジトリ用S3バケットへの"s3:GetObject"権限を付与しています。(実際のポリシーは省略します。)
エラー
一見この構成で問題ないように見えるのですが、dnf updateをしてみると403エラーとなってしまいました。
よくエラーの原因となりうる以下の点は確認し、問題ありませんでした。
- Gateway型S3エンドポイントのルートテーブル設定
- EC2のIAMロールに付与しているポリシー
- EC2のセキュリティグループのアウトバウンドルール
原因
記事のタイトルにもあるように、原因はS3エンドポイントに設定したポリシーにありました。
"Condition"の"PrincipalArn"でEC2のIAMロールを指定していることが直接的な原因でした。
"Condition": {
"ArnEquals": {
"aws:PrincipalArn": "arn:aws:iam::xxxxxxxxxxxx:role/ec2-role"
}
}
}
]
}
前述していますが、以下のドキュメントに特定のIAMロールへのアクセスを制限するポリシーを作成できると記載があります。
特定のIAMロールへのアクセスを制限するポリシーを作成できます。aws:PrincipalArn を使用してプリンシパルへのアクセスを許可する必要があります。
それなのに、なぜdnf実行時にエラーが出てしまうかというと、
dnfコマンドはHTTPS通信でS3のリポジトリからパッケージ等をダウンロードしているからです。
特定のIAMロールでアクセスの制御ができるのはAPI通信の場合のみであり、HTTPS通信ではIAMロールによるアクセス制限はできない、というのがエラーの原因でした。
よく考えてみれば確かにそうだと理解できるのですが、盲点でした…
実際にCondition部分を削除してdnf updateを実行したところ、無事に成功しました。
対策
特定のEC2のからのアクセスに絞りたい場合の代替策としては、EC2インスタンスのIPアドレスを"Condition"の"VpcSourceIp"で許可する設定を入れるという方法が可能かと思います。
ただし、特定のEC2インスタンスを明示的に許可拒否するものではないというところには注意が必要です。
"Condition": {
"IpAddress": {
"Aws:VpcSourceIp": "(許可するEC2インスタンスのIPアドレス)/32"
}
}
}
aws:VpcSourceIp 条件キーを使用して、特定の IP アドレス範囲へのアクセスを制限するポリシーを作成できます。
まとめ
最小権限のポリシー付与という条件があったため、できるだけ特定のIAMロールにのみアクセスを制限しようとした結果、今回のような盲点に気づくことができました。
Amazon Linuxのリポジトリ用のS3バケットはAWS管理のオープンなバケットであり、許可アクションもGetObjectのみに設定(おそらくPutやDeleteはバケット側で制限されているだろう)しているので、特定のIAMロールでアクセス制御ができなくても大きな問題が起きる可能性は低いかと思いますが、頭の片隅に置いておきたいと思います。