CDKでbastionサーバーを作る

もはやSession Managerを使うことが主流となり、bastionの出番は減ってきたと思うが、CDKでbastionを作ったので手順をしたためておく。

1. key pairを作る

今回はbastionという名前のkey pairをコンソールから作っておく。 手順はこちらを参照してください。

docs.aws.amazon.com

2. Secret Managerに、1作成時に自動ダウンロードされるpemの中身を登録する

今回はbastion-secretというsecret名で、

{"key": "(ダウンロードしたpemの中身。ただし改行コードを\nで置換したもの)"}

という形で登録しておく。 Secret Mangerについてはこちら。

docs.aws.amazon.com

3. CDK実装

例によってlibのファイルのみ載せておく。binはまぁご自由に。

gist.github.com

ポイントは下記の通り。

1. private subnetにbastionを作る

vpcにpublic・privateの各subnetを作った場合、AWSが推奨している(CDKのデフォルトになっている)のはprivate subnetにbastionを作ること。

github.com

その場合、Session Managerを使ってローカルマシンからbastionにアクセスする。

% aws ssm start-session --target {bastionのinstance id}
% sudo su - ec2-user(必要ならね)

(これができるんだから、bastionなんかいらなくね!!??という疑問はもっともである。)

ちなみに訳あってpublic subnetに作る場合は、instance connectで自分の持っている公開鍵を一時的にbastionに登録してsshで繋ぐ。

% aws ec2-instance-connect send-ssh-public-key --instance-id {bastionのinstance id} --instance-os-user {amazon linuxなら"ec2-user"} --ssh-public-key {"file://~/.ssh/id_rsa.pub"とか} --availability-zone {"ap-northeast-1"とか}
% mssh {bastionのinstance id}
2. Secret Managerから取得するpemの中身は、改行コードを実際の改行状態にしておく

改行も含めて鍵。

3. bastionからのSecurity Groupは、他のstackでも使うだろうからエクスポートしておく

今回はallow-from-bastionという名前でエクスポートしておいた。

4. user dataを使って、bastion内の/home/ec2-user/.ssh/id_rsaにkey pairのpemをセットしておく

他にいいやり方知ってる人がいたら教えてください。

5. bastionから繋ぎたい他のインスタンスは、同一subnet内に、key pairをbastionにして作成する

ちなみにその、他のインスタンスに直接ssm agentを入れちゃえば、直接Session Managerでaws ssm session-startで繋げるのでbastionいらずになります。