アルパカログ

プログラミングとマネジメントがメインです。時々エモいのも書きます。

EC2へのSSHをIAMユーザーに限定する

小規模開発において、EC2にSSHできるユーザーをIAMユーザーに限定したい(≒IAMで擬似的に管理したい)というニーズはよくあると思います。

開発者やサーバー台数が少ないケースでLDAPは管理コストがかかるし、LDAPの導入に時間を使うなら開発に使いたいというのがあるでしょう。

そこで、できるだけシンプルに実現するために次のような仕組みを構築します。

f:id:otoyo0122:20190615112501p:plain:w480

  1. 公開鍵をIAMに登録する
  2. 公開鍵の取得をEC2に許可するポリシーを作成する
  3. 公開鍵を取得するシェルスクリプトを作成する
  4. sshd configのAuthorizedKeysCommandにスクリプトを指定する

以下、それぞれの項目を説明します。セキュリティの考慮漏れがあるかもしれないので、使用は自己責任でお願いします。

1. 公開鍵をIAMに登録する

AWSマネジメントコンソールを開き、IAM > ユーザー > 認証情報 > AWS CodeCommit の SSH キー > SSH パブリックキーのアップロードからユーザーごとに公開鍵をアップロードします。

f:id:otoyo0122:20190615110812p:plain:w400

2. 公開鍵の取得をEC2に許可するポリシーを作成する

iam:ListUsers, iam:ListSSHPublicKeys, GetSSHPublicKey を許可するポリシーを作成しEC2にアタッチします。下記はポリシーの例です。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "",
            "Effect": "Allow",
            "Action": [
                "iam:ListSSHPublicKeys",
                "iam:ListUsers",
                "iam:GetSSHPublicKey"
            ],
            "Resource": "*"
        }
    ]
}

3. 公開鍵を取得するシェルスクリプトを作成する

全てのIAMユーザーの公開鍵を標準出力に列挙します。ユーザーや鍵が増えるにつれて遅くなる点に注意してください。

また、BOTユーザーなどがいて除外したい場合は、ユーザーにグループを付与して list-users の代わりに get-group を使用すると良いでしょう。その場合はポリシーで iam:GetGroup も許可します。

#!/bin/sh
for user_name in $(aws iam list-users --query 'Users[].UserName' --output text)
do
  for key_id in $(aws iam list-ssh-public-keys --user-name $user_name --query 'SSHPublicKeys[].SSHPublicKeyId' --output text)
  do
    aws iam get-ssh-public-key --encoding SSH --user-name $user_name --ssh-public-key-id $key_id --query 'SSHPublicKey.SSHPublicKeyBody' --output text
  done
done

ファイルは root:root 755 で作成し /etc/ssh/iam-key-finder などに配置します。

4. sshd configのAuthorizedKeysCommandにスクリプトを指定する

/etc/ssh/sshd_configAuthorizedKeysCommand, AuthorizedKeysCommandUser を設定し、sshd を再起動します。

AuthorizedKeysCommand /etc/ssh/iam-key-finder
AuthorizedKeysCommandUser nobody

iam-key-finder での鍵の取得に少し時間がかかりますが、SSHログインできれば成功です。

参考情報