この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
この人はこのレコードに対して更新しかできないようにしたい
こんにちは、のんピ(@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)でした!