現象
踏み台サーバであるAから別サーバのBにSSHで接続しようとしたときに
- PrivateIP、PrivateDNSを指定すると接続可能
- PublicDNSを指定すると接続可能
- PublicIPを指定すると接続不可能
という状況でした。NetworkACLは特に設定しておらず
AB間のSecurityGroupは許可し合っているはずなのに…。
原因
PrivateIPで接続可能である理由
接続先(サーバB)のSecurityGroupのInboundには
サーバAからのSSH接続を許可する内容を設定してありましたが
送信元としてサーバAが属する SecurityGroup を記載していたのが原因でした。
公式ドキュメントには以下のように記載されています。
ルールの送信元または送信先としてセキュリティグループを指定する場合、
ルールはセキュリティグループと関連付けられるすべてのインスタンスに影響します。
着信トラフィックは、ソースセキュリティグループに関連付けられたインスタンスの
プライベート IP アドレスに基づいて許可されます
(パブリック IP アドレスまたは Elastic IP アドレスは考慮されません)。
結果として、サーバBのInboundで許可されていたのはサーバAのPrivateIPのみ。
PrivateIP/DNSを使えば問題なく接続できたのはこのためですね。
SSH接続先としてPublicIPを指定した際には
PublicIP間の通信となり、セキュリティグループに阻まれたと考えています。
サーバBのInboundセキュリティグループにサーバAのPublicIPを直接書くと
PublicIP指定でも接続できるようになりました。
PublicDNSで接続可能である理由
Discussion Forumsの記載内容によると
When you use the public DNS name from within the same EC2 region, you will actually get the current private IP address.
-> 同じリージョンにあるEC2のPublicDNSを解決すると、PrivateIPが得られる。
実際にEC2インスタンスを立てて試してみました。
# @Singapore
$ nslookup ec2-52-78-50-129.ap-southeast-1.compute.amazonaws.com
Server: 10.0.0.2
Address: 10.0.0.2#53
Non-authoritative answer:
Name: ec2-52-78-50-129.ap-southeast-1.compute.amazonaws.com
Address: 10.0.8.105 # <- PrivateIP
# @Sydney
$ nslookup ec2-52-78-50-129.ap-southeast-1.compute.amazonaws.com
Server: 10.0.0.2
Address: 10.0.0.2#53
Non-authoritative answer:
Name: ec2-52-78-50-129.ap-southeast-1.compute.amazonaws.com
Address: 52.77.49.128 # <- PublicIP
つまり、PublicDNSがPrivateIPに変換され
同一ネットワーク内のPrivateIP同士の通信が行われるため
セキュリティグループでの指定通りに接続できたと考えています。
まとめ
PublicIPでSSH接続ができない問題について解説しました。
問題が概ね解決したあとに、以下のような記事を見つけました。
AWSのセキュリティグループにセキュリティグループを指定した時の落とし穴
こちらがかなり参考になり、解決に至ったのですが
そもそも今回の問題を端的に表すキーワードがなく
ググラビリティが非常に低いため、面を増やすためにこの記事を書いた次第です。