delhi09の勉強日記

技術トピック専用のブログです。自分用のメモ書きの投稿が多いです。あくまで「勉強日記」なので記事の内容は鵜呑みにしないでください。

DjangoをEC2インスタンス上で動かす環境を構築する(その1:ユーザー作成)

前提

EC2インスタンスを立ち上げてec2-userでSSHログインするところまではできているものとする。

やること

今回は検証目的なので、必要最小限で以下の要件とする。

f:id:kamatimaru:20200522052717p:plain

参考文献

その1:ユーザー作成

概要

EC2上に必要なユーザーを作成する。

作成するユーザー

以下のユーザーを作成する。

No ユーザー名 sudo権限 目的
1 admin サーバー構築・sudo権限が必要なオペレーションの実行
2 release × ソースコードの取得・管理
3 webserver × Nginxの起動
4 appserver × Gunicornの起動

方針

rootユーザーは使わない

rootユーザーで作業することは、以下の記事に書かれているように、セキュリティ的に問題があるため、rootユーザーは使用せず、sudo権限のある管理者ユーザーを作成する。

www.atmarkit.co.jp

アプリケーションを起動するユーザーの権限を最小限にする

体系的に学ぶ 安全なWebアプリケーションの作り方 第2版 脆弱性が生まれる原理と対策の実践』の「OSコマンド・インジェクション」の項には以下のように書かれている。

OSコマンド・インジェクション脆弱性を攻撃された場合、コマンドの実行権限はWebアプリケーションの持つ権限となるため、Webアプリケーションの権限を必要最低限に制限しておくと、攻撃の被害を最小限にとどめることができます。(中略)
このユーザ権限を最小限にするという保険的対策は、ディレクトリ・トラバーサル脆弱性などに対しても有効です。
p307

極端な例を挙げると、OSコマンド・インジェクション脆弱性が存在して、rm -rf /を実行されたとしても、ユーザーの権限を正しく設計していれば、削除されるのは「Webアプリケーションを起動しているユーザー」が書き込み権限を持っているディレクトリ・ファイルに限定される。

もし、rootでWebアプリケーションを起動していると、理論上は全てのディレクトリ・ファイルが削除されてしまう。
(やったことないので実際どうなるのかは知らない。実際にやってみた方の記事があった。)
qiita.com

従って、Nginxを起動するユーザー・Gunicornを起動するユーザーには、それぞれ権限の小さい専用のユーザーを作成する。

手順

0.事前準備(重要)

何も考えずに流れに沿ってEC2インスタンスを作成すると、以下のセキュリティグループが割り当てられているため、(鍵があれば)全世界からssh可能な状態になっており、EC2インスタンスは立ち上がった直後から、sshログインのリスト型攻撃を受け続けている。

インバウンドルール

タイプ プロトコル ポート範囲 ソース 説明 - オプション
SSH TCP 22 0.0.0.0/0 -

この状態で誤って以下の①〜③の条件を満たすようなユーザーを作成してしまうと、簡単にアカウントを乗っ取られてしまう。

①パスワードによるsshログイン可
②パスワードが脆弱(admin/adminなど)
→ 検証用の環境だからと脆弱なパスワードを設定しがち
③sudo権限がある。

※ パスワードによるsshログインはデフォルトでは許可されていない。

$ grep 'PasswordAuthentication ' /etc/ssh/sshd_config
#PasswordAuthentication yes
PasswordAuthentication no
$

従って、割り当てるセキュリティグループを変更して、自宅のIPアドレス以外からはssh接続できないようにする。

①以下のセキュリティグループの割り当てを解除する。
インバウンドルール

タイプ プロトコル ポート範囲 ソース 説明 - オプション
SSH TCP 22 0.0.0.0/0 -

②以下のセキュリティグループを作成して割り当てる。
インバウンドルール

タイプ プロトコル ポート範囲 ソース 説明 - オプション
SSH TCP 22 ${自宅のIPアドレス}/32 -

マネージメントコンソール上での操作は以下

アクション > ネットワーキング > セキュリティグループの変更

※ 固定IPではない場合は、PCをシャットダウンしたりするとIPアドレスが変わるので注意。

1.「admin」ユーザーを作成する

・「admin」ユーザーを作成する。

$ sudo useradd -m admin

-mはユーザー作成時にユーザーのホームディレクトリを作成する。

・パスワードを設定する。

$ sudo passwd admin

・adminにログインしてみる。

$ sudo su - admin
$ whoami
admin

・現状ではsudo権限がないことを確認する。

$ sudo pwd

We trust you have received the usual lecture from the local System
Administrator. It usually boils down to these three things:

    #1) Respect the privacy of others.
    #2) Think before you type.
    #3) With great power comes great responsibility.

[sudo] password for admin:
admin is not in the sudoers file.  This incident will be reported.
$

・ec2-userに戻ってadminにsudo権限を追加して保存する。

$ exit
$ whoami
ec2-user
$ sudo visudo

→ ファイルの最後に以下の1行を追加して保存する。

admin ALL=(ALL) ALL

・adminでログインしてsudoができるようになっていることを確認する。

$ sudo su - admin
$ sudo pwd
[sudo] password for admin:
/home/admin
$

・クライアント側(Mac)で秘密鍵と公開鍵を作成する。(質問は全部Enter)
ssh-keygenで鍵を生成する時のオプションについては、いつもコピペで済ましてしまっているので、いつかちゃんと理解したい。

$ ssh-keygen -b 2048

以下の記事にあるように、クライアント側(ログインする側)で公開鍵と秘密鍵を作成して、公開鍵のみをサーバー側に送信するというのがあるべき形なので、その方針で作業していく。
dev.classmethod.jp

・公開鍵をEC2インスタンスに転送する。

$ scp -i mysecretkey.pem ~/.ssh/id_rsa.pub ec2-user@xxx.xxx.xxx.xxx:~/
id_rsa.pub                                    100%  424     3.1KB/s   00:00
$

・adminユーザーのhomeディレクトリ配下に.sshディレクトリを作成する。

$ sudo mkdir /home/admin/.ssh
$ sudo chown admin:admin /home/admin/.ssh
$ sudo chmod 700 /home/admin/.ssh
$ sudo ls -ld /home/admin/.ssh
drwx------ 2 admin admin 6  524 16:11 /home/admin/.ssh
$

.sshディレクトリ配下にauthorized_keysを作成し、公開鍵を登録する。

$ sudo touch /home/admin/.ssh/authorized_keys
$ cat id_rsa.pub | sudo tee /home/admin/.ssh/authorized_keys > /dev/null
$ sudo chown admin:admin /home/admin/.ssh/authorized_keys
$ sudo chmod 400  /home/admin/.ssh/authorized_keys
$ sudo ls -l /home/admin/.ssh/authorized_keys
-r-------- 1 admin admin 424  524 16:24 /home/admin/.ssh/authorized_keys
$ rm -i id_rsa.pub

id_rsa.pubの内容をauthorized_keysにリダイレクトするところ、最初は

$ sudo cat id_rsa.pub >> /home/admin/.ssh/authorized_keys
-bash: /home/admin/.ssh/authorized_keys: Permission denied

としたがPermission deniedが出てしまい、以下の記事を参照させて頂いた。
tetsuyai.hatenablog.com


・クライアントPC(Mac)からadminユーザーでsshログインできるようになったことを確認する。

$ ssh admin@xxx.xxx.xxx.xxx
Last login: Sun May 24 15:34:00 2020

       __|  __|_  )
       _|  (     /   Amazon Linux 2 AMI
      ___|\___|___|

https://aws.amazon.com/amazon-linux-2/
1 package(s) needed for security, out of 16 available
Run "sudo yum update" to apply all updates.
$ whoami
admin
$

以上でadminユーザーの作成は完了。

2.ec2-userを削除する。

sudo権限のある「admin」ユーザーを作成したことで、「ec2-user」は不要になったので削除する。

$ whoami
admin
$ sudo userdel -r ec2-user

-rはホームディレクトリとメールスプールも削除する。

3.「release」、「webserver」、「appserver」ユーザーをそれぞれ作成する。

「release」、「webserver」、「appserver」ユーザーの要件は以下の通り。

  • sudo権限なし。
  • homeディレクトリは作成しない。
  • パスワードは設定しない。

作成していく。

$ whoami
admin
$ sudo useradd -M release
$ sudo useradd -M webserver
$ sudo useradd -M appserver

-Mは作成時にユーザーのホームディレクトリを作成しない。

・ユーザーが作成されていることを確認する。

$ sudo su release
$ whoami
release
$ exit
$ sudo su webserver
$ whoami
webserver
$ exit
$ sudo su appserver
$ whoami
appserver

以上で「その1:ユーザー作成」は完了。
その2に続く。