こんにちは、Aireです。
本記事では、CloudFormationを用いて、Linuxインスタンスを起動する際にデフォルトアカウントを無効化し、代わりに同等の権限を持つユーザアカウントを新規に作成する方法を紹介します。
AWS環境にAmazon Linux等のLinuxインスタンスを起動する際、多くの場合はデフォルトアカウントとしてec2-user
が作成されます。ログイン情報の一部が広く知れ渡っている状態はセキュリティ的に望ましくないため、ec2-user
を無効化する代わりに同等の権限を持つユーザアカウントを作成してみます。
OS上で直接コマンドを実行して設定する場合
はじめに比較情報として、OS上で直接コマンドを実行する場合の手順を紹介します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
# 1. ユーザアカウントを新規作成する $ UserId="new-user" $ sudo useradd ${UserId} $ cat /etc/passwd | grep ${UserId} new-user:x:1001:1001::/home/new-user:/bin/bash ## 1-1. sudoコマンドをパスワード入力なしで使用したい場合は以下のコマンドを実行する $ echo "${UserId} ALL=(ALL) NOPASSWD:ALL" | sudo tee --append /etc/sudoers.d/90-cloud-init-users new-user ALL=(ALL) NOPASSWD:ALL ## 1-2. パスワードを設定する場合は以下のコマンドを実行する $ UserPw="new-passwd" $ echo "${UserId}:${UserPw}" | sudo chpasswd # 2. ユーザアカウントに管理者権限を追加する $ sudo usermod -aG wheel ${UserId} $ cat /etc/group | grep wheel wheel:x:10:ec2-user,new-user # 3. ec2-userの公開鍵をコピーして権限を変更する(使い回す) $ sudo cp -R /home/ec2-user/.ssh /home/${UserId} $ sudo chown -R ${UserId}:${UserId} /home/${UserId}/.ssh $ sudo chmod -R 600 /home/${UserId}/.ssh $ sudo chmod 700 /home/${UserId}/.ssh $ sudo ls -la /home/${UserId}/.ssh total 4 drwx------. 2 new-user new-user 29 Apr 16 13:29 . drwx------. 3 new-user new-user 74 Apr 16 13:29 .. -rw-------. 1 new-user new-user 390 Apr 16 13:29 authorized_keys # 4. ec2-userを無効化する $ echo "DenyUsers ec2-user" | sudo tee --append /etc/ssh/sshd_config DenyUsers ec2-user $ sudo systemctl restart sshd |
ユーザアカウントを新規作成する
useradd
コマンドを実行し、ec2-user
の代わりとなる新規ユーザアカウントを作成します。その後、/etc/passwd
ファイルを参照し、新規ユーザアカウントが作成されたことを確認します。
1 2 3 4 5 |
# 1. ユーザアカウントを新規作成する $ UserId="new-user" $ sudo useradd ${UserId} $ cat /etc/passwd | grep ${UserId} new-user:x:1001:1001::/home/new-user:/bin/bash |
ec2-user
と同じようにsudo
コマンドをパスワードなしで使用したい場合は、/etc/sudoers.d/90-cloud-init-users
ファイルに<新規ユーザアカウント名> ALL=(ALL) NOPASSWD:ALL
という記載を追加します。
1 2 3 |
## 1-1. sudoコマンドをパスワード入力なしで使用したい場合は以下のコマンドを実行する $ echo "${UserId} ALL=(ALL) NOPASSWD:ALL" | sudo tee --append /etc/sudoers.d/90-cloud-init-users new-user ALL=(ALL) NOPASSWD:ALL |
パスワードを設定する場合はchpasswd
コマンドを実行します。passwd
コマンドでもパスワードを設定できますが、標準入力でパスワードを指定する必要があるので、スクリプトやCloudFormationでの実行を考慮しchpasswd
コマンドを使用しています。
1 2 3 |
## 1-2. パスワードを設定する場合は以下のコマンドを実行する $ UserPw="new-passwd" $ echo "${UserId}:${UserPw}" | sudo chpasswd |
ユーザアカウントに管理者権限を追加する
usermod
コマンドを使用するとユーザの設定変更が可能です。ここでは新規ユーザアカウントをwheel
管理グループに追加することで管理者権限を付与しています。
1 2 3 4 |
# 2. ユーザアカウントに管理者権限を追加する $ sudo usermod -aG wheel ${UserId} $ cat /etc/group | grep wheel wheel:x:10:ec2-user,new-user |
ec2-userの公開鍵をコピーして権限を変更する
公開鍵認証によるSSH接続ができるように/home/ec2-user/.ssh
配下にあるec2-user
の公開鍵を/home/<新規ユーザアカウント名>
にコピーします。その後、新規ユーザアカウントがコピーしたファイルやディレクトリにアクセスできるように権限を変更します。
1 2 3 4 5 6 7 8 9 10 |
# 3. ec2-userの公開鍵をコピーして権限を変更する(既存公開鍵を使い回す) $ sudo cp -R /home/ec2-user/.ssh /home/${UserId} $ sudo chown -R ${UserId}:${UserId} /home/${UserId}/.ssh $ sudo chmod -R 600 /home/${UserId}/.ssh $ sudo chmod 700 /home/${UserId}/.ssh $ sudo ls -la /home/${UserId}/.ssh total 4 drwx------. 2 new-user new-user 29 Apr 16 13:29 . drwx------. 3 new-user new-user 74 Apr 16 13:29 .. -rw-------. 1 new-user new-user 390 Apr 16 13:29 authorized_keys |
ec2-userを無効化する
本節までの手順で新規ユーザアカウントの設定が完了しました。
以下、/etc/ssh/sshd_config
ファイルにDenyUsers ec2-user
と記載することで、ec2-user
へのSSHアクセスを無効化しています。また、sshd
サービスを再起動し、ec2-user
のSSHの無効化設定を有効にしています。
1 2 3 4 |
# 4. ec2-userを無効化する $ echo "DenyUsers ec2-user" | sudo tee --append /etc/ssh/sshd_config DenyUsers ec2-user $ sudo systemctl restart sshd |
ec2-user
でSSHアクセスを試みると、以下のようにアクセスが拒否されます。
1 2 |
$ ssh -i <秘密鍵の保存先> ec2-user@<IPアドレス> ec2-user@<IPアドレス>: Permission denied (publickey,gssapi-keyex,gssapi-with-mic). |
実際の運用では、ec2-user
を無効化する前に新規ユーザアカウントでSSH接続できるか確認することをおすすめします。
CloudFormationテンプレート内でユーザデータとしてコマンドを記載して設定する場合
本題に入りますが、前章で紹介した設定手順をCloudFormationで実行する方法を紹介します。(なお、新規ユーザアカウントのパスワードは設定しない手順で話を進めます)
OS上で実行するコマンドについては、UserData
セクションと呼ばれる箇所に記載します。また、以下のテンプレート例では、Parameters
セクションで変数UserId
を用意し、ユーザが入力した文字列を新規ユーザアカウント名として利用しています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
Parameters: UserId: Description: 'Enter a new user id instead of "ec2-user".' Type: String UserData: Fn::Base64: Fn::Sub: - | #!/bin/bash # 1. ユーザアカウントを新規作成する useradd ${UserId} cat /etc/passwd | grep ${UserId} echo "${UserId} ALL=(ALL) NOPASSWD:ALL" | tee --append /etc/sudoers.d/90-cloud-init-users # 2. ユーザアカウントに管理者権限を追加する usermod -aG wheel ${UserId} cat /etc/group | grep wheel # 3. ec2-userの公開鍵をコピーして権限を変更する(使い回す) cp -R /home/ec2-user/.ssh /home/${UserId} chown -R ${UserId}:${UserId} /home/${UserId}/.ssh chmod -R 600 /home/${UserId}/.ssh chmod 700 /home/${UserId}/.ssh ls -la /home/${UserId}/.ssh # 4. ec2-userを無効化する echo "DenyUsers ec2-user" | tee --append /etc/ssh/sshd_config systemctl restart sshd - { UserId: !Ref UserId } |
直接コマンドを実行する場合とCloudFormationテンプレートに記載する場合の違いですが、sudo
コマンドの記載を削除しています。これはwhoami
コマンドを実行すると分かりますが、ユーザデータを実行するのはec2-user
ではなくroot
であるためです。(sudo -u ec2-user
と実行すると、それ以降のコマンドをec2-user
として実行することも可能です)
次のテンプレート例では、新規ユーザアカウント名をOSのシェル変数として直接宣言して使用する場合の記載方法です。
先ほどのテンプレートとの違いは、Fn::Sub
の変数UserId
が不要になったのでFn::Sub:
と記載された行を削除している点と、もう一つは、UserId
をOSのシェル変数として認識させるため、最初の中括弧{
の後ろに感嘆符!
をつけることでエスケープしている点です。これはシェル変数の表記がFn::Sub
の変数の表記${xxxxx}
と被っているためにCloudFormation側で用意された回避手段です。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
UserData: Fn::Base64: - | #!/bin/bash # 1. ユーザアカウントを新規作成する UserId="new-user" useradd ${!UserId} cat /etc/passwd | grep ${!UserId} echo "${!UserId} ALL=(ALL) NOPASSWD:ALL" | tee --append /etc/sudoers.d/90-cloud-init-users # 2. ユーザアカウントに管理者権限を追加する usermod -aG wheel ${!UserId} cat /etc/group | grep wheel # 3. ec2-userの公開鍵をコピーして権限を変更する(使い回す) cp -R /home/ec2-user/.ssh /home/${!UserId} chown -R ${!UserId}:${!UserId} /home/${!UserId}/.ssh chmod -R 600 /home/${!UserId}/.ssh chmod 700 /home/${!UserId}/.ssh ls -la /home/${!UserId}/.ssh # 4. ec2-userを無効化する echo "DenyUsers ec2-user" | tee --append /etc/ssh/sshd_config systemctl restart sshd |
ユーザデータの実行結果を確認する方法
UserData
セクションに記載したコマンドの実行結果は、インスタンス内の/var/log/cloud-init-output.log
ファイルに記録されるので、結果を確認したい場合はそちらのファイルを参照してください。
1 |
cat /var/log/cloud-init-output.log |
インスタンス作成時にユーザデータとしてコマンドを入力して設定する場合
おまけになりますが、CloudFormationは利用せず、EC2コンソール画面からインスタンスを作成するときにもユーザデータを入力することができるのでそちらの方法も紹介します。
以下がユーザデータの入力例になります。注意点は、シェル変数の記載方法はOS上で直接コマンドを実行する場合と同様で、最初の中括弧{
の後ろに感嘆符!
をつけてエスケープをする必要はありません。また、ユーザデータはroot
によって実行されるため、sudo
コマンドの記載を削除しています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
#!/bin/bash # 1. ユーザアカウントを新規作成する UserId="new-user" useradd ${UserId} cat /etc/passwd | grep ${UserId} echo "${UserId} ALL=(ALL) NOPASSWD:ALL" | tee --append /etc/sudoers.d/90-cloud-init-users # 2. ユーザアカウントに管理者権限を追加する usermod -aG wheel ${UserId} cat /etc/group | grep wheel # 3. ec2-userの公開鍵をコピーして権限を変更する(使い回す) cp -R /home/ec2-user/.ssh /home/${UserId} chown -R ${UserId}:${UserId} /home/${UserId}/.ssh chmod -R 600 /home/${UserId}/.ssh chmod 700 /home/${UserId}/.ssh ls -la /home/${UserId}/.ssh # 4. ec2-userを無効化する echo "DenyUsers ec2-user" | tee --append /etc/ssh/sshd_config systemctl restart sshd |
以上、ここまで。