セキュリティグループのインバウンドルールのソースに「マイIP」を指定できることは有名ですが、このマイIPってグローバルIPが変わるたびに手動で設定しなおさないといけないんですよね。これの更新を自動化できないものか、と考えていました。
ググるとhttp://checkip.amazonaws.com/
にGETリクエストを投げるとグローバルIPが取得できるので、そのIPアドレスをインバウンドルールのソースに設定する(というスクリプトを作る)。というのが定石のようでしたが、なんかこのURLで得られるIPアドレスと、マネージメントコンソール上で表示されるマイIPが異なっており、checkip.amazonaws.com
は使えませんでした。実際、checkip.amazonaws.com
から取得したIPをセキュリティグループのインバウンドルールに追加してみましたが接続が弾かれましたよ。
そこで、API Gateway経由でLambda関数にGETリクエストを投げて、Lambda関数がリクエストコンテキストのソースIPの値を返すようなWeb APIを実装し、このAPIに向かってGETリクエストを投げることにしました。
このAPIから返されたIPアドレスは、セキュリティグループで表示されるマイIPと同じアドレスになっていました…が、たまたま一致しただけかもしれません。
それはともかく、その時に実装したバッチファイルを載せておきます。
- 僕が使っている実際のバッチでは
http://checkip.amazonaws.com/
の部分が、自作のWeb APIのURLになっています。 -
curl
コマンドを使用しているため、Windows 10限定です。 -
SG_ID_SSH
に、マイIPを更新したいセキュリティグループIDを代入します。 - セキュリティグループ(インバウンド)の22番ポートのエントリをDelete & Insertするという単純な作りなので、利用の際はご注意下さい。
@echo off
set "SG_ID_SSH=sg-xxxxxxxxxxxxxxxxx"
for /f "usebackq" %%a in (`curl --silent http://checkip.amazonaws.com/`) do set MYIP_NEW=%%a
echo What is my IP address ? - '%MYIP_NEW%'
call :UpdateSecurityGroup %SG_ID_SSH% 22 %MYIP_NEW%
pause
goto :EOF
:UpdateSecurityGroup
setlocal
set "SG_ID=%~1"
set "PORT=%~2"
set "MYIP_NEW=%~3"
echo Security group id: %SG_ID%
set "CMD_DESC_SG=aws ec2 describe-security-groups --group-id %SG_ID% --output text --query "SecurityGroups[*].IpPermissions[?FromPort==`%PORT%`].IpRanges[0].[CidrIp][0]""
for /f "usebackq" %%a in (`%CMD_DESC_SG%`) do set MYIP_OLD=%%a
if not "%MYIP_OLD%"=="" (
aws ec2 revoke-security-group-ingress --group-id %SG_ID% --protocol tcp --port %PORT% --cidr %MYIP_OLD%
echo '%MYIP_OLD%' has been revoked successfully.
)
aws ec2 authorize-security-group-ingress --group-id %SG_ID% --protocol tcp --port %PORT% --cidr %MYIP_NEW%/32
echo '%MYIP_NEW%/32' has been authorized successfully.
endlocal
exit /b
What is my IP address ? - 'xxx.xxx.xx.xxx'
Security group id: sg-xxxxxxxxxxxxxxxxx
'zzz.zzz.zz.zzz/32' has been revoked successfully.
'xxx.xxx.xx.xxx/32' has been authorized successfully.
続行するには何かキーを押してください . . .
aws ec2
のクエリの書き方は難しいですね。PowerShellっぽい印象を受けました。
参考までに、checkip.amazonaws.com
の再発明に使ったLambda関数の実装を載せておきます。
import json
def lambda_handler(event, context):
return {
'statusCode': 200,
'headers': {
'Content-Type': 'text/html; charset=utf-8'
},
'body': event['requestContext']['identity']['sourceIp']
}
ところで、なんでバッチファイルで実装したのかって?マゾだからですかね。