Route 53 Resolver Endpointに必要なセキュリティグループのルールを確認してみた

Route 53 Resolver EndpointとRoute 53 Resolver間の通信はセキュリティグループで制御できない
2022.10.28

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

AWS公式ドキュメントに0.0.0.0/0を許可しろとあるけれども

こんにちは、のんピ(@non____97)です。

皆さんはRoute 53 Resolver Endpointに必要なセキュリティグループのルールが気になったことはありますか? 私はあります。

Route 53 Resolver Endpointを使うことによってVPC外からの名前解決の問い合わせを受け付けたり、VPC外に名前解決の問い合わせを転送したりできます。

ここで、AWS公式ドキュメントを見ると、以下のようにInbound EndpointもOutbound Endpointのどちらのセキュリティグループも0.0.0.0/0を許可することが推奨されていました。

インバウンドおよびアウトバウンドリゾルバーのセキュリティグループにおける推奨事項

抜粋 : リゾルバーエンドポイントのスケーリング - Amazon Route 53

Inbound Endpointのインバウンドルールと、Outbound Endpointのアウトバウンドルールはサービスの役割的に必要なのが納得いきますが、Inbound Endpointのアウトバウンドルールと、Outbound Endpointのインバウンドルールが必要なのはよく分かりません。

Route 53 Resolver Endpointのセキュリティグループの検証環境

ということで、Resolver Endpointで名前解決をするにあたって、Inbound Endpointへのアウトバウンドルールと、Outbound Endpointのインバウンドルールが必要なのか確認してみました。

いきなりまとめ

  • Route 53 Resolver Endpointのセキュリティグループで以下のように設定しても名前解決できる
    • Inbound Endpointにアウトバウンドルールを設定しない
    • Outbound Endpointにインバウンドルールを設定しない

検証環境

検証環境は以下の通りです。

Route 53 Resolver Endpointのセキュリティグループの検証環境2

Route 53 Resolver Inbound EndpointとOutbound Endpointを作成し、以下のように転送設定をします。

  • Route 53 Resolver Rule : corp.non-97.netへの問い合わせはcorp.non-97.netのゾーンを管理するDNSサーバーのIPアドレスに転送
  • corp.non-97.net のゾーンを管理するDNSサーバー : amazonaws.comへの問い合わせはRoute 53 Resolver Inbound EndpointのIPアドレスに転送

そして、Inbound Endpointのアウトバウンドルールと、Outbound Endpointのインバウンドルールを設定しない状態で、以下のような名前解決をしてみます。

  • スタブリゾルバからRoute 53 Resolverをフルサービスリゾルバとして、a.corp.non-97.netの名前解決ができるか
  • スタブリゾルバからcorp.non-97.netのゾーンを管理するDNSサーバーをフルサービスリゾルバとして、VPCエンドポイントの名前解決ができるか

検証環境の準備

VPCやcorp.non-97.netのゾーンを管理するDNSサーバーは以下記事の検証で使った環境を再利用します。

まず、Route 53 Resolver Inbound EndpointとOutbound Endpointそれぞれに割り当てるセキュリティグループを準備します。

それぞれのセキュリティグループのルールは以下の通りです。

# Route 53 Resolver Inbound Endpointに割り当てるセキュリティグループのルール
# VPCのCIDR 10.0.1.0/24 からのtcp/53、udp/53を許可するインバウンドルールのみ
$ aws ec2 describe-security-group-rules \
    --filters 'Name=group-id,Values=sg-0a3c37645af5cc28f'
{
    "SecurityGroupRules": [
        {
            "SecurityGroupRuleId": "sgr-082a4a5263b557202",
            "GroupId": "sg-0a3c37645af5cc28f",
            "GroupOwnerId": "<AWSアカウントID>",
            "IsEgress": false,
            "IpProtocol": "tcp",
            "FromPort": 53,
            "ToPort": 53,
            "CidrIpv4": "10.0.1.0/24",
            "Tags": []
        },
        {
            "SecurityGroupRuleId": "sgr-05a385798defe7849",
            "GroupId": "sg-0a3c37645af5cc28f",
            "GroupOwnerId": "<AWSアカウントID>",
            "IsEgress": false,
            "IpProtocol": "udp",
            "FromPort": 53,
            "ToPort": 53,
            "CidrIpv4": "10.0.1.0/24",
            "Tags": []
        }
    ]
}

# Route 53 Resolver Outbound Endpointに割り当てるセキュリティグループのルール
# VPCのCIDR 10.0.1.0/24 へのtcp/53、udp/53を許可するアウトバウンドルールのみ
$ aws ec2 describe-security-group-rules \
    --filters 'Name=group-id,Values=sg-0daba2c1761b6912d'
{
    "SecurityGroupRules": [
        {
            "SecurityGroupRuleId": "sgr-0b113042f1845a569",
            "GroupId": "sg-0daba2c1761b6912d",
            "GroupOwnerId": "<AWSアカウントID>",
            "IsEgress": true,
            "IpProtocol": "udp",
            "FromPort": 53,
            "ToPort": 53,
            "CidrIpv4": "10.0.1.0/24",
            "Tags": []
        },
        {
            "SecurityGroupRuleId": "sgr-06873789b733dbc99",
            "GroupId": "sg-0daba2c1761b6912d",
            "GroupOwnerId": "<AWSアカウントID>",
            "IsEgress": true,
            "IpProtocol": "tcp",
            "FromPort": 53,
            "ToPort": 53,
            "CidrIpv4": "10.0.1.0/24",
            "Tags": []
        }
    ]
}

なお、Route 53 Resolver Endpointに割り当てるセキュリティグループは後から変更することができません。専用のセキュリティグループを用意することをおすすめします。

次に、Route 53 Resolver Endpointを用意します。

作成したRoute 53 Resolver Endpointは以下の通りです。

$ aws route53resolver list-resolver-endpoints
{
    "ResolverEndpoints": [
        {
            "Id": "rslvr-in-ce764e77eda841efb",
            "CreatorRequestId": "AWSConsole.4.1666952800226",
            "Arn": "arn:aws:route53resolver:us-east-1:<AWSアカウントID>:resolver-endpoint/rslvr-in-ce764e77eda841efb",
            "Name": "resolver_inbound",
            "SecurityGroupIds": [
                "sg-0a3c37645af5cc28f"
            ],
            "Direction": "INBOUND",
            "IpAddressCount": 2,
            "HostVPCId": "vpc-08b84da1f793ed513",
            "Status": "OPERATIONAL",
            "StatusMessage": "This Resolver Endpoint is operational.",
            "CreationTime": "2022-10-28T10:26:40.794323Z",
            "ModificationTime": "2022-10-28T10:27:03.558Z"
        },
        {
            "Id": "rslvr-out-d05047ecfc7e4e389",
            "CreatorRequestId": "AWSConsole.47.1666952800227",
            "Arn": "arn:aws:route53resolver:us-east-1:<AWSアカウントID>:resolver-endpoint/rslvr-out-d05047ecfc7e4e389",
            "Name": "resolver_outbound",
            "SecurityGroupIds": [
                "sg-0daba2c1761b6912d"
            ],
            "Direction": "OUTBOUND",
            "IpAddressCount": 2,
            "HostVPCId": "vpc-08b84da1f793ed513",
            "Status": "OPERATIONAL",
            "StatusMessage": "This Resolver Endpoint is operational.",
            "CreationTime": "2022-10-28T10:26:41.000081Z",
            "ModificationTime": "2022-10-28T10:28:31.805Z"
        }
    ],
    "MaxResults": 10
}

Route 53 Resolver Ruleは以下の通りです。

$ aws route53resolver list-resolver-rules
{
    "ResolverRules": [
        {
            "Id": "rslvr-autodefined-rr-internet-resolver",
            "CreatorRequestId": "",
            "Arn": "arn:aws:route53resolver:us-east-1::autodefined-rule/rslvr-autodefined-rr-internet-resolver",
            "DomainName": ".",
            "Status": "COMPLETE",
            "RuleType": "RECURSIVE",
            "Name": "Internet Resolver",
            "OwnerId": "Route 53 Resolver",
            "ShareStatus": "NOT_SHARED"
        },
        {
            "Id": "rslvr-rr-f967a273923045da8",
            "CreatorRequestId": "AWSConsole.63.1666952801128",
            "Arn": "arn:aws:route53resolver:us-east-1:<AWSアカウントID>:resolver-rule/rslvr-rr-f967a273923045da8",
            "DomainName": "corp.non-97.net.",
            "Status": "COMPLETE",
            "StatusMessage": "[Trace id: 1-635bae61-798840264a83d2a17062a35b] Successfully created Resolver Rule.",
            "RuleType": "FORWARD",
            "Name": "resolver_rule",
            "TargetIps": [
                {
                    "Ip": "10.0.1.10",
                    "Port": 53
                }
            ],
            "ResolverEndpointId": "rslvr-out-d05047ecfc7e4e389",
            "OwnerId": "<AWSアカウントID>",
            "ShareStatus": "NOT_SHARED",
            "CreationTime": "2022-10-28T10:26:41.298097Z",
            "ModificationTime": "2022-10-28T10:26:41.298097Z"
        }
    ],
    "MaxResults": 30
}

次にVPCエンドポイントを用意します。今回はFSxのVPCエンドポイントを作成しました。作成したVPCエンドポイントは以下の通りです。

$ aws ec2 describe-vpc-endpoints
{
    "VpcEndpoints": [
        {
            "VpcEndpointId": "vpce-012040b50d1561e8b",
            "VpcEndpointType": "Interface",
            "VpcId": "vpc-08b84da1f793ed513",
            "ServiceName": "com.amazonaws.us-east-1.fsx",
            "State": "available",
            "PolicyDocument": "{\n  \"Statement\": [\n    {\n      \"Action\": \"*\", \n      \"Effect\": \"Allow\", \n      \"Principal\": \"*\", \n      \"Resource\": \"*\"\n    }\n  ]\n}",
            "RouteTableIds": [],
            "SubnetIds": [
                "subnet-0f2a829b61fbe09df"
            ],
            "Groups": [
                {
                    "GroupId": "sg-004bd768e7fa0c6af",
                    "GroupName": "default"
                }
            ],
            "IpAddressType": "ipv4",
            "DnsOptions": {
                "DnsRecordIpType": "ipv4"
            },
            "PrivateDnsEnabled": true,
            "RequesterManaged": false,
            "NetworkInterfaceIds": [
                "eni-03b2e748069f1d90c"
            ],
            "DnsEntries": [
                {
                    "DnsName": "vpce-012040b50d1561e8b-m5vkuenn.fsx.us-east-1.vpce.amazonaws.com",
                    "HostedZoneId": "Z7HUB22UULQXV"
                },
                {
                    "DnsName": "vpce-012040b50d1561e8b-m5vkuenn-us-east-1a.fsx.us-east-1.vpce.amazonaws.com",
                    "HostedZoneId": "Z7HUB22UULQXV"
                },
                {
                    "DnsName": "fsx.us-east-1.amazonaws.com",
                    "HostedZoneId": "Z0245063P0VKD361P590"
                }
            ],
            "CreationTimestamp": "2022-10-28T10:29:45.802000+00:00",
            "Tags": [],
            "OwnerId": "<AWSアカウントID>"
        }
    ]
}

最後に、corp.non-97.netのゾーンを管理するDNSサーバーでRoute 53 Resolver Inbound Endpointへの条件付きフォワーダーを設定します。

> $fqdn = 'amazonaws.com'
> $dnsServers = @('10.0.1.22','10.0.1.36') # Route 53 Resolver Inbound Endpoint
> $params = @{
    Name = $fqdn
    MasterServers = $dnsServers
    ReplicationScope = 'Domain'
}
> Add-DnsServerConditionalForwarderZone @params

# 条件付きフォワーダーが作成されたことを確認
> Get-DnsServerZone

ZoneName                            ZoneType        IsAutoCreated   IsDsIntegrated  IsReverseLookupZone  IsSigned
--------                            --------        -------------   --------------  -------------------  --------
_msdcs.corp.non-97.net              Primary         False           True            False                False
0.in-addr.arpa                      Primary         True            False           True                 False
127.in-addr.arpa                    Primary         True            False           True                 False
255.in-addr.arpa                    Primary         True            False           True                 False
amazonaws.com                       Forwarder       False           True            False
corp.non-97.net                     Primary         False           True            False                False
TrustAnchors                        Primary         False           True            False                False

これで、VPCエンドポイントに対して名前解決したときにRoute 53 Resolver Inbound Endpointに転送されるようになりました。

名前解決してみる

それでは、名前解決してセキュリティグループの必要性を確認してみます。

# スタブリゾルバからRoute 53 Resolverをフルサービスリゾルバとして、a.corp.non-97.netの名前解決ができるか
$ dig a.corp.non-97.net

; <<>> DiG 9.11.4-P2-RedHat-9.11.4-26.P2.amzn2.5.2 <<>> a.corp.non-97.net
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 46778
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;a.corp.non-97.net.             IN      A

;; ANSWER SECTION:
a.corp.non-97.net.      300     IN      A       10.2.2.2

;; Query time: 2 msec
;; SERVER: 10.0.1.2#53(10.0.1.2)
;; WHEN: Fri Oct 28 10:37:54 UTC 2022
;; MSG SIZE  rcvd: 62

# スタブリゾルバからcorp.non-97.netのゾーンを管理するDNSサーバーをフルサービスリゾルバとして、VPCエンドポイントの名前解決ができるか
$ dig fsx.us-east-1.amazonaws.com @10.0.1.10

; <<>> DiG 9.11.4-P2-RedHat-9.11.4-26.P2.amzn2.5.2 <<>> fsx.us-east-1.amazonaws.com @10.0.1.10
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 53589
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4000
;; QUESTION SECTION:
;fsx.us-east-1.amazonaws.com.   IN      A

;; ANSWER SECTION:
fsx.us-east-1.amazonaws.com. 60 IN      A       10.0.1.12

;; Query time: 6 msec
;; SERVER: 10.0.1.10#53(10.0.1.10)
;; WHEN: Fri Oct 28 10:39:01 UTC 2022
;; MSG SIZE  rcvd: 72

どちらのパターンも名前解決できました。

ということで、Inbound Endpointのアウトバウンドルールと、Outbound Endpointのインバウンドルールは設定する必要はなさそうです。どうやらRoute 53 Resolver EndpointとRoute 53 Resolver間の通信はセキュリティグループで制御できないようです。

おまけで、Inbound Endpointのインバウンドルールと、Outbound Endpointのアウトバウンドルールを削除してしまった場合も名前解決できるのか確認してみます。

以下のように各セキュリティグループのルールを全て削除しました。

# Route 53 Resolver Inbound Endpointに割り当てるセキュリティグループのルール
$ aws ec2 describe-security-group-rules \
    --filters 'Name=group-id,Values=sg-0a3c37645af5cc28f'
{
    "SecurityGroupRules": []
}

# Route 53 Resolver Outbound Endpointに割り当てるセキュリティグループのルール
$aws ec2 describe-security-group-rules \
    --filters 'Name=group-id,Values=sg-0daba2c1761b6912d'
{
    "SecurityGroupRules": []
}

この状態で名前解決してみます。

# Outbound Endpointのアウトバウンドルールを削除しても、スタブリゾルバからRoute 53 Resolverをフルサービスリゾルバとして、a.corp.non-97.netの名前解決ができるか
$ dig a.corp.non-97.net

; <<>> DiG 9.11.4-P2-RedHat-9.11.4-26.P2.amzn2.5.2 <<>> a.corp.non-97.net
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 10698
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;a.corp.non-97.net.             IN      A

;; ANSWER SECTION:
a.corp.non-97.net.      30      IN      A       10.2.2.2

;; Query time: 3 msec
;; SERVER: 10.0.1.2#53(10.0.1.2)
;; WHEN: Fri Oct 28 10:54:40 UTC 2022
;; MSG SIZE  rcvd: 62

# Inbound Endpointのアウトバウンドルールを削除しても、スタブリゾルバからcorp.non-97.netのゾーンを管理するDNSサーバーをフルサービスリゾルバとして、VPCエンドポイントの名前解決ができるか
$ dig fsx.us-east-1.amazonaws.com @10.0.1.10

; <<>> DiG 9.11.4-P2-RedHat-9.11.4-26.P2.amzn2.5.2 <<>> fsx.us-east-1.amazonaws.com @10.0.1.10
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: SERVFAIL, id: 30122
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4000
;; QUESTION SECTION:
;fsx.us-east-1.amazonaws.com.   IN      A

;; Query time: 1644 msec
;; SERVER: 10.0.1.10#53(10.0.1.10)
;; WHEN: Fri Oct 28 10:54:32 UTC 2022
;; MSG SIZE  rcvd: 56

スタブリゾルバからcorp.non-97.netのゾーンを管理するDNSサーバーをフルサービスリゾルバとして、VPCエンドポイントの名前解決することはできなくなりました。しかし、スタブリゾルバからRoute 53 Resolverをフルサービスリゾルバとして、a.corp.non-97.netの名前解決ができてしまっています。

もしかしたらキャッシュの影響かも知れませんね。

corp.non-97.netのゾーンを管理するDNSサーバーを停止した状態でも名前解決できるか確認してみます。

# Outbound Endpointのアウトバウンドルールを削除しても、スタブリゾルバからRoute 53 Resolverをフルサービスリゾルバとして、a.corp.non-97.netの名前解決ができるか
$ dig a.corp.non-97.net

; <<>> DiG 9.11.4-P2-RedHat-9.11.4-26.P2.amzn2.5.2 <<>> a.corp.non-97.net
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 30538
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;a.corp.non-97.net.             IN      A

;; ANSWER SECTION:
a.corp.non-97.net.      30      IN      A       10.2.2.2

;; Query time: 0 msec
;; SERVER: 10.0.1.2#53(10.0.1.2)
;; WHEN: Fri Oct 28 11:07:50 UTC 2022
;; MSG SIZE  rcvd: 62

# スタブリゾルバからcorp.non-97.netのゾーンを管理するDNSサーバーをフルサービスリゾルバとして、a.corp.non-97.netの名前解決ができるか
$ dig a.corp.non-97.net @10.0.1.10

; <<>> DiG 9.11.4-P2-RedHat-9.11.4-26.P2.amzn2.5.2 <<>> a.corp.non-97.net @10.0.1.10
;; global options: +cmd
;; connection timed out; no servers could be reached

corp.non-97.netのゾーンを管理するDNSサーバーを停止しているので、corp.non-97.netのゾーンを管理するDNSサーバーをフルサービスリゾルバに指定した場合は名前解決できませんでしたが、Route 53 Resolverをフルサービスリゾルバとして指定した場合は継続して名前解決しています。

以上のことからRoute 53 ResolverはDNSのキャッシュを持っていることが分かります。

Route 53 Resolver EndpointとRoute 53 Resolver間の通信はセキュリティグループで制御できない

Route 53 Resolver Endpointに必要なセキュリティグループのルールを確認してみました。

想定していた通り、Route 53 Resolver EndpointとRoute 53 Resolver間の通信はセキュリティグループで制御できないようです。

こちらの検証のきっかけはチバユキからの質問でした。しっかり検証したのでチバユキも満足するでしょう。

この記事が誰かの助けになれば幸いです。

以上、AWS事業本部 コンサルティング部の のんピ(@non____97)でした!