AWS DirectConnect を通して社内ネットワークに存在するEC2がプロキシ除外するべきIPアドレス
概要
AWS DirectConnect を利用して社内ネットワークに接続しているEC2があるとき、インターネットへの通信も含めてすべての通信を社内プロキシサーバーから出ていくようにしたかったがAWS関連の通信がうまく行かなかったときの対処法。
セキュリティー的な観点からインターネットゲートウェイを使用したくなかった。
結論
プロキシ除外設定に169.254.169.254を追加する。
こちらの記事にお世話になりました。
参考:プロキシに阻まれながらAWS CLIをEC2インスタンスから動かしたときの話
何が起きたのか
環境
AWS EC2(Amazon Linux 2023)
現象
概要にあるような環境で起動しているEC2サーバーが存在し、検証期間中はDirectConnectの設定の関係もあってインターネットゲートウェイを使用した状態で処理のエラー時にAWS SNSを使用して通知を行う仕組みを持っていた。
検証中はうまく行っていたものの、本番切替のタイミングでインターネットゲートウェイを削除したところGoogleなど外への通信は問題なく行えるものの、AWSサービスに対する通信がうまく行かなくなった。
また、assumeRoleをして他AWSアカウントのS3からファイルを取得するような処理もあったものの、こちらも同様にうまく行かなくなった。
プロキシサーバーの指定
# /etc/profile.d/proxy.sh
PROXY='http://proxy.example.co.jp:8080'
export http_proxy=$PROXY
export HTTP_PROXY=$PROXY
export https_proxy=$PROXY
export HTTPS_PROXY=$PROXY
上記の設定でSNS用のpublishコマンドを実行する
SNS_TOPIC_ARN="arn:aws:sns:ap-northeast-1:XXXXXXXXXXX:sns_example_topic"
aws sns publish --topic-arn ${SNS_TOPIC_ARN} --subject "test subject" --message "test message" --region ap-northeast-1
- subject: test subject
- body: test message
で送るだけの簡単なもの。
当該のEC2サーバーにはもちろんsns:Publishのポリシーがアタッチされている。
表示されたエラー
Unable to locate credentials. You can configure credentials by running "aws configure".
クレデンシャルがないと言われる。IAMを使うわけでもなく検証期間中は問題なくできたため何かおかしい。
--debug オプションを付けてもう一度実行してみる。
しばらくただの実行過程のログが出るのだが
(前略)
2024-07-02 14:55:20,193 - MainThread - urllib3.connectionpool - DEBUG - Starting new HTTP connection (1): proxy.example.co.jp:8080
2024-07-02 14:55:21,211 - MainThread - urllib3.connectionpool - DEBUG - Starting new HTTP connection (2): proxy.example.co.jp:8080
2024-07-02 14:55:22,232 - MainThread - botocore.utils - DEBUG - Caught retryable HTTP exception while making metadata service request to http://169.254.169.254/latest/meta-data/iam/security-credentials/: Read timeout on endpoint URL: "http://169.254.169.254/latest/meta-data/iam/security-credentials/"
Traceback (most recent call last):
(中略)
socket.timeout: timed out
(後略)
プロキシに接続しに行った後にIAMにクレデンシャルの確認に行く際にタイムアウトしている雰囲気がある。pingも通らない。
(さらに後のログではプロキシサーバーへの接続時にタイムアウトになっているように見えていたため余計にはまった)
そしてここで同じようにプロキシサーバーを経由する環境にEC2をたてている人はいるはず!となり、結論にある記事にたどり着いた。
ということで除外設定
# /etc/profile.d/proxy.sh
PROXY='http://proxy.example.co.jp:8080'
NO_PROXY='169.254.169.254'
export http_proxy=$PROXY
export HTTP_PROXY=$PROXY
export https_proxy=$PROXY
export HTTPS_PROXY=$PROXY
export no_proxy=$NO_PROXY
export NO_PROXY=$NO_PROXY
source /etc/profile
で再読込
もう一度同じSNSコマンドを実行
aws sns publish --topic-arn ${SNS_TOPIC_ARN} --subject "test subject" --message "test message" --region ap-northeast-1
{
"MessageId": "xxxxxx-xxxx-xxxxxx-xxxxx-xxxxxxxxxxx"
}
MessageIdが返ってきたので成功!
詳しくは調べていないものの、169.254.169.254はEC2がインスタンスメタデータにアクセスするためのアドレスである模様。IPv6用のものもあったのでIPv6で主に運用している方はそちらを参照。
参考:インスタンスメタデータの取得
Discussion