背景
AWS CodeBuildを使ってバッチを構築している中で、外部サーバーにSSH接続し、特定の処理を実行する必要があった。その際、接続先のサーバーではAWS Systems Manager (SSM) パラメータを取得する処理が含まれていた。
初期実装
SSMパラメータを取得するためには、CodeBuildのAWSクレデンシャル情報(AWS_ACCESS_KEY_ID、AWS_SECRET_ACCESS_KEY、AWS_SESSION_TOKEN)が必要になる。そのため、以下のように環境変数を設定してSSH接続時に渡す方法をとった。
ssh -o StrictHostKeyChecking=no user@remote-server \
"export AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID; \
export AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY; \
export AWS_SESSION_TOKEN=$AWS_SESSION_TOKEN; \
./some_script.sh"
セキュリティ上の問題点
この方法は一見シンプルで動作するが、ChatGPTによると以下のリスクがある。
- クレデンシャルがSSHコマンドの引数として記録される可能性
ps aux
などで環境変数が漏洩する可能性がある。- シェルの履歴 (
history
) に残るリスク。
- クレデンシャルがリモートサーバー上で意図せず保持される可能性
- セッションが切れた後も環境変数が残る。
- 誤ってログに出力されるリスク。
改善策:一時ファイルを利用
より安全な方法として、一時ファイルを使用する方法がある。
- CodeBuild側で一時ファイルを作成し、クレデンシャル情報を保存
- SCPで一時ファイルをリモートサーバーに転送
- リモートサーバー側で環境変数として読み込み、処理後に削除
実装例
1. CodeBuild側
echo "AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID" > creds.tmp
echo "AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY" >> creds.tmp
echo "AWS_SESSION_TOKEN=$AWS_SESSION_TOKEN" >> creds.tmp
scp -o StrictHostKeyChecking=no creds.tmp user@remote-server:/tmp/creds.tmp
rm creds.tmp
2. リモートサーバー側
source /tmp/creds.tmp
./some_script.sh
rm /tmp/creds.tmp
まとめ
CodeBuildから外部サーバーにSSH接続して処理を実行する際、環境変数を直接渡すのはセキュリティリスクが高い。より安全な方法として、一時ファイルを利用することでクレデンシャルの漏洩リスクを低減できる。
この方法を採用することで、安全性を確保しながら必要な処理を実行できるようになる。