[アップデート] Amazon Route 53 が DNS リソースレコードセットレベルでのアクセス許可をサポートしました
この人はこのレコードに対して更新しかできないようにしたい
こんにちは、のんピ(@non____97)です。
皆さんはAmazon Route 53を使っていて「この人はこのレコードに対して更新しかできないようにしたい」と思ったことはありますか? 私はあります。
レコードに対する処理はChangeResourceRecordSets APIで行います。
従来、IAMポリシーでRoute 53のレコードの操作を制限するのはホストゾーン単位でした。
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "route53:ChangeResourceRecordSets", "Resource": "arn:aws:route53:::hostedzone/<ホストゾーンID>" } ] }
そのため、「このレコードのみ変更加えても良い」といった制限をかけることはできませんでした。
また、処理の種類はCREATE
/DELETE
/UPSERT
の3種類ありますが、「CREATE
しか行わせないようにする」といった制限もできませんでした。
今回、Amazon Route 53 が DNS リソースレコードセットレベルでのアクセス許可をサポートしました。
これにより、ホストゾーン単位ではなく、レコード単位でアクセス制限をすることができます。
具体的にはIAMのResource
ではなくCondition
で制限をします。
早速試してみたので、紹介します。
いきなりまとめ
- 追加されたConditionの条件キーは以下の3つ
route53:ChangeResourceRecordSetsNormalizedRecordNames
route53:ChangeResourceRecordSetsRecordTypes
route53:ChangeResourceRecordSetsActions
- いずれも複数の値を指定することができる
追加されたConditionの条件キーを確認
それでは今回のアップデートで追加されたConditionの条件キーを確認します。
追加されたConditionの条件キーは以下の3つです。
route53:ChangeResourceRecordSetsNormalizedRecordNames
route53:ChangeResourceRecordSetsRecordTypes
route53:ChangeResourceRecordSetsActions
名前から大体どんな制限ができそうか想像できますね。
一つ一つ確認していきます。
route53:ChangeResourceRecordSetsNormalizedRecordNames
まず、route53:ChangeResourceRecordSetsNormalizedRecordNames
です。
こちらはレコードの名前に対して制限をかける条件キーです。
複数のレコード名を値として指定できます。値は以下の条件を満たす必要があります。
- 使用できる文字は
a-z
0-9
-
(ハイフン)_
(アンダースコア).
(ドット)
- それ以外の文字はエスケープコード
/
を付与した3桁の8進数にエンコードする必要がある- かな文字などASCII文字以外は8進数にエンコードすると3桁に収まらないので、全ての文字がエンコードすれば設定できるという訳ではない
- すべての文字は小文字でなければならない
- 末尾にドットを付けてはならない
実際に試してみましょう。
rrset-test.non-97.net
というPublic Hosted Zoneを作成しました。
また、以下のようなIAMポリシーを用意しました。
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "route53:ChangeResourceRecordSets", "Resource": "arn:aws:route53:::hostedzone/Z10299392E0FL5KN3PZOY", "Condition": { "StringLike": { "route53:ChangeResourceRecordSetsNormalizedRecordNames": [ "rrset-test.non-97.net", "\\050wassyoi\\040\\041\\051.rrset-test.non-97.net", "*.sub.rrset-test.non-97.net" ] } } } ] }
こちらのIAMポリシーを使って、test.rrset-test.non-97.net
というAレコードを作成しようとしてみます。
$ hosted_zone_id=Z10299392E0FL5KN3PZOY $ change_resource_record_sets_input=$(cat <<EOM { "Changes": [ { "Action": "CREATE", "ResourceRecordSet": { "Name": "test.rrset-test.non-97.net", "Type": "A", "TTL": 300, "ResourceRecords": [ { "Value": "10.0.0.1" } ] } } ] } EOM ) $ aws route53 change-resource-record-sets \ --hosted-zone-id "$hosted_zone_id" \ --change-batch "$change_resource_record_sets_input" An error occurred (AccessDenied) when calling the ChangeResourceRecordSets operation: User: arn:aws:sts::<AWSアカウントID>:assumed-role/route-53-test/<IAMユーザー名> is not authorized to perform: route53:ChangeResourceRecordSets on resource: arn:aws:route53:::hostedzone/Z10299392E0FL5KN3PZOY because no identity-based policy allows the route53:ChangeResourceRecordSets action
Conditionのroute53:ChangeResourceRecordSetsNormalizedRecordNames
に指定されていない値なので権限不足で弾かれましたね。
次に、Zone Apexであるrrset-test.non-97.net
のAレコードを作成しようとしています。
$ change_resource_record_sets_input=$(cat <<EOM { "Changes": [ { "Action": "CREATE", "ResourceRecordSet": { "Name": "rrset-test.non-97.net", "Type": "A", "TTL": 300, "ResourceRecords": [ { "Value": "10.0.0.1" } ] } } ] } EOM ) $ aws route53 change-resource-record-sets \ --hosted-zone-id "$hosted_zone_id" \ --change-batch "$change_resource_record_sets_input" { "ChangeInfo": { "Id": "/change/C02410842653BYPKVC5A8", "Status": "PENDING", "SubmittedAt": "2022-09-22T00:28:25.262000+00:00" } }
こちらはConditionのroute53:ChangeResourceRecordSetsNormalizedRecordNames
に指定されている値なので作成できたようですね。
次に、(wassyoi !).rrset-test.non-97.net
というレコードを作成しようとしてみます。
$ change_resource_record_sets_input=$(cat <<"EOM" { "Changes": [ { "Action": "CREATE", "ResourceRecordSet": { "Name": "\\050wassyoi\\040\\041\\051.rrset-test.non-97.net", "Type": "A", "TTL": 300, "ResourceRecords": [ { "Value": "10.0.0.1" } ] } } ] } EOM ) $ aws route53 change-resource-record-sets \ --hosted-zone-id "$hosted_zone_id" \ --change-batch "$change_resource_record_sets_input" { "ChangeInfo": { "Id": "/change/C0975728197YW8XZCU9I1", "Status": "PENDING", "SubmittedAt": "2022-09-22T00:47:59.049000+00:00" } }
Conditionの\\050wassyoi\\040\\041\\051.rrset-test.non-97.net
で(
や)
、!
、スペースを3桁の8進数にエンコードしているので許可されました。
次に、test.sub.rrset-test.non-97.net
というレコードを作成しようとしてみます。
$ change_resource_record_sets_input=$(cat <<EOM { "Changes": [ { "Action": "CREATE", "ResourceRecordSet": { "Name": "test.sub.rrset-test.non-97.net", "Type": "A", "TTL": 300, "ResourceRecords": [ { "Value": "10.0.0.1" } ] } } ] } EOM ) $ aws route53 change-resource-record-sets \ --hosted-zone-id "$hosted_zone_id" \ --change-batch "$change_resource_record_sets_input" { "ChangeInfo": { "Id": "/change/C09867703SFPH0YQ6T8D4", "Status": "PENDING", "SubmittedAt": "2022-09-22T00:59:54.207000+00:00" } }
Conditionの*.sub.rrset-test.non-97.net
で許可されているので通りました。
なお、当然ですがsub.rrset-test.non-97.net
はConditionで指定されていないので、拒否されます。
$ change_resource_record_sets_input=$(cat <<EOM { "Changes": [ { "Action": "CREATE", "ResourceRecordSet": { "Name": "sub.rrset-test.non-97.net", "Type": "A", "TTL": 300, "ResourceRecords": [ { "Value": "10.0.0.1" } ] } } ] } EOM ) $ aws route53 change-resource-record-sets \ --hosted-zone-id "$hosted_zone_id" \ --change-batch "$change_resource_record_sets_input" An error occurred (AccessDenied) when calling the ChangeResourceRecordSets operation: User: arn:aws:sts::<AWSアカウントID>:assumed-role/route-53-test/<IAMユーザー名> is not authorized to perform: route53:ChangeResourceRecordSets on resource: arn:aws:route53:::hostedzone/Z10299392E0FL5KN3PZOY because no identity-based policy allows the route53:ChangeResourceRecordSets action
route53:ChangeResourceRecordSetsRecordTypes
次に、route53:ChangeResourceRecordSetsRecordTypes
の確認をします。
こちらはレコードタイプに制限をかける条件キーです。
複数のレコードタイプを値として指定できます。値は大文字でRoute 53がサポートしているレコードタイプである必要があります。
- A
- AAAA
- CAA
- CNAME
- DS
- MX
- NAPTR
- NS
- PTR
- SOA
- SPF
- SRV
- TXT
実際に試してみます。
CNAME
とTXT
レコードのみが作成できるIAMポリシーを用意しました。
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "route53:ChangeResourceRecordSets", "Resource": "arn:aws:route53:::hostedzone/Z10299392E0FL5KN3PZOY", "Condition": { "StringLike": { "route53:ChangeResourceRecordSetsNormalizedRecordNames": [ "rrset-test.non-97.net", "\\050wassyoi\\040\\041\\051.rrset-test.non-97.net", "*.sub.rrset-test.non-97.net" ] }, "StringEquals": { "route53:ChangeResourceRecordSetsRecordTypes": ["CNAME","TXT"] } } } ] }
試しにyeah.sub.rrset-test.non-97.net
でAレコードを作成しようとしてみます。
$ change_resource_record_sets_input=$(cat <<EOM { "Changes": [ { "Action": "CREATE", "ResourceRecordSet": { "Name": "yeah.sub.rrset-test.non-97.net", "Type": "A", "TTL": 300, "ResourceRecords": [ { "Value": "10.0.0.1" } ] } } ] } EOM ) $ aws route53 change-resource-record-sets \ --hosted-zone-id "$hosted_zone_id" \ --change-batch "$change_resource_record_sets_input" An error occurred (AccessDenied) when calling the ChangeResourceRecordSets operation: User: arn:aws:sts::<AWSアカウントID>:assumed-role/route-53-test/<IAMユーザー名> is not authorized to perform: route53:ChangeResourceRecordSets on resource: arn:aws:route53:::hostedzone/Z10299392E0FL5KN3PZOY because no identity-based policy allows the route53:ChangeResourceRecordSets action
許可されていないので弾かれました。
続いてyeah.sub.rrset-test.non-97.net
のCNAMEレコードを作成しようとみます。
$ change_resource_record_sets_input=$(cat <<EOM { "Changes": [ { "Action": "CREATE", "ResourceRecordSet": { "Name": "yeah.sub.rrset-test.non-97.net", "Type": "CNAME", "TTL": 300, "ResourceRecords": [ { "Value": "test.sub.rrset-test.non-97.net" } ] } } ] } EOM ) $ aws route53 change-resource-record-sets \ --hosted-zone-id "$hosted_zone_id" \ --change-batch "$change_resource_record_sets_input" { "ChangeInfo": { "Id": "/change/C014001034MVS6DL0GB1Y", "Status": "PENDING", "SubmittedAt": "2022-09-22T01:25:09.185000+00:00" } }
こちらは通りましたね。
ちなみに、Conditonの条件キーが複数ある場合は、ANDで評価されます。
そのため、route53:ChangeResourceRecordSetsNormalizedRecordNames
で指定していない名前のレコードを作成することはできません。
sub.rrset-test.non-97.net
のCNAMEレコードを作成しようとすると、以下のように怒られます。
$ change_resource_record_sets_input=$(cat <<EOM { "Changes": [ { "Action": "CREATE", "ResourceRecordSet": { "Name": "sub.rrset-test.non-97.net", "Type": "CNAME", "TTL": 300, "ResourceRecords": [ { "Value": "test.sub.rrset-test.non-97.net" } ] } } ] } EOM ) $ aws route53 change-resource-record-sets \ --hosted-zone-id "$hosted_zone_id" \ --change-batch "$change_resource_record_sets_input" An error occurred (AccessDenied) when calling the ChangeResourceRecordSets operation: User: arn:aws:sts::<AWSアカウントID>:assumed-role/route-53-test/<IAMユーザー名> is not authorized to perform: route53:ChangeResourceRecordSets on resource: arn:aws:route53:::hostedzone/Z10299392E0FL5KN3PZOY because no identity-based policy allows the route53:ChangeResourceRecordSets action
route53:ChangeResourceRecordSetsActions
最後にroute53:ChangeResourceRecordSetsActions
について確認します。
こちらはレコードに対するアクションに制限をかける条件キーです。
複数のアクションを値として指定できます。値は以下のいずれかである必要があります。
CREATE
UPSERT
DELETE
非常に分かりやすいですね。
以下のようにCREATE
とUPSERT
のみ許可したIAMポリシーで動作確認をしてみます。
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "route53:ChangeResourceRecordSets", "Resource": "arn:aws:route53:::hostedzone/Z10299392E0FL5KN3PZOY", "Condition": { "StringLike": { "route53:ChangeResourceRecordSetsNormalizedRecordNames": [ "rrset-test.non-97.net", "\\050wassyoi\\040\\041\\051.rrset-test.non-97.net", "*.sub.rrset-test.non-97.net" ] }, "ForAllValues:StringEquals": { "route53:ChangeResourceRecordSetsRecordTypes": [ "CNAME", "TXT" ], "route53:ChangeResourceRecordSetsActions": [ "CREATE", "UPSERT" ] } } } ] }
まず、CREATE
が正常に行えることを確認します。
$ change_resource_record_sets_input=$(cat <<"EOM" { "Changes": [ { "Action": "CREATE", "ResourceRecordSet": { "Name": "\\050wassyoi\\040\\041\\051.rrset-test.non-97.net", "Type": "TXT", "TTL": 300, "ResourceRecords": [ { "Value": "\"wassyoi\"" } ] } } ] } EOM ) $ aws route53 change-resource-record-sets \ --hosted-zone-id "$hosted_zone_id" \ --change-batch "$change_resource_record_sets_input" { "ChangeInfo": { "Id": "/change/C0195540B7SCL9BGSA5L", "Status": "PENDING", "SubmittedAt": "2022-09-22T01:39:44.887000+00:00" } }
できましたね。
作成したレコードを更新(UPSERT
)してみます。
$ change_resource_record_sets_input=$(cat <<"EOM" { "Changes": [ { "Action": "UPSERT", "ResourceRecordSet": { "Name": "\\050wassyoi\\040\\041\\051.rrset-test.non-97.net", "Type": "TXT", "TTL": 300, "ResourceRecords": [ { "Value": "\"wassyoi_wassyoi\"" } ] } } ] } EOM ) $ aws route53 change-resource-record-sets \ --hosted-zone-id "$hosted_zone_id" \ --change-batch "$change_resource_record_sets_input" { "ChangeInfo": { "Id": "/change/C0759493CM7C297GPG52", "Status": "PENDING", "SubmittedAt": "2022-09-22T01:41:25.175000+00:00" } }
こちらもできました。
それでは最後にDELETE
ができないことを確認します。
$ change_resource_record_sets_input=$(cat <<"EOM" { "Changes": [ { "Action": "DELETE", "ResourceRecordSet": { "Name": "\\050wassyoi\\040\\041\\051.rrset-test.non-97.net", "Type": "TXT", "TTL": 300, "ResourceRecords": [ { "Value": "\"wassyoi_wassyoi\"" } ] } } ] } EOM ) $ aws route53 change-resource-record-sets \ --hosted-zone-id "$hosted_zone_id" \ --change-batch "$change_resource_record_sets_input" An error occurred (AccessDenied) when calling the ChangeResourceRecordSets operation: User: arn:aws:sts::<AWSアカウントID>:assumed-role/route-53-test/<IAMユーザー名> is not authorized to perform: route53:ChangeResourceRecordSets on resource: arn:aws:route53:::hostedzone/Z10299392E0FL5KN3PZOY because no identity-based policy allows the route53:ChangeResourceRecordSets action
意図した通り、DELETE
のみ拒否されました。
Route 53のレコードに対して詳細なアクセス制限ができるようになりました
Amazon Route 53 が DNS リソースレコードセットレベルでのアクセス許可をサポートしたアップデートを紹介しました。
今回のアップデートにより、Route 53のレコードに対して詳細なアクセス制限ができるようになりました。
「ゾーンを分けるほどでもないけど、このレコードは触ってほしくない」みたいな場合に役立ちそうです。
この記事が誰かの助けになれば幸いです。
以上、AWS事業本部 コンサルティング部の のんピ(@non____97)でした!