AWS EC2でサーバを構築 7 - セキュリティ対策

## 記事一覧

- [AWS EC2でサーバを構築 1 \- Amazon Linux 2 準備編](https://qiita.com/ryu-blacknd/items/23b86d9ad768d58ff161)
- [AWS EC2でサーバを構築 2 \- 各種インストール編](https://qiita.com/ryu-blacknd/items/36ccfcf96da7b0c981cf)
- [AWS EC2でサーバを構築 3 \- Apache \+ Let's Ecnrypt \+ PHP\-FPM編 \(脆弱性診断「A\+」を狙う\)](https://qiita.com/ryu-blacknd/items/77eebe43a18a69e7c1e5)
- [AWS EC2でサーバを構築 4 \- Nginx \+ Let's Ecnrypt \+ PHP\-FPM編 \(脆弱性診断「A\+」を狙う\)](https://qiita.com/ryu-blacknd/items/4049f04e445eb1d60e4d)
- [AWS EC2でサーバを構築 5 \- MySQL \+ phpMyAdmin](https://qiita.com/ryu-blacknd/items/03030d11eeef65e3cf67)
- [AWS EC2でサーバを構築 6 \- PostfixとDovecot \(SSL対応とSPAM対策\)](https://qiita.com/ryu-blacknd/items/8e0c28065af3f9b8a06d)
- [AWS EC2でサーバを構築 7 \- **セキュリティ対策**](https://qiita.com/ryu-blacknd/items/20e5540195501e16e90e)

## 概要

EC2上に構築したサーバを運用するうえで必要となるセキュリティ対策です。

前回までの記事でサーバ構築が完了していることが前提です。

## セキュリティグループ

AWSのセキュリティグループがファイアウォールの役割を果たします。

外部公開が必要となるポートだけをインバウンドルールに追加します（**不要なポートを開けないように**）。

### インバウンドルール

|タイプ|プロトコル|ポート範囲|ソース|
|---|---|---|---|
|SSH|TCP|22|0.0.0.0/0|
|HTTP|TCP|80|0.0.0.0/0|
|HTTPS|TCP|443|0.0.0.0/0|
|SMTP|TCP|25|0.0.0.0/0|
|SMTPS|TCP|465|0.0.0.0/0|
|IMAPS|TCP|993|0.0.0.0/0|
|POP3S|TCP|995|0.0.0.0/0|

> SMTPSが有効でも、25/tcpを許可しないとメール送受信ができないので注意してください。

## firewalld

上記に加え、OS側でもfirewalldの設定を追加します。

この作業ができている時点でSSHのポートは空いているはずですので、他のポートを設定します。

```bash
firewall-cmd --permanent --add-service=http
firewall-cmd --permanent --add-service=https
firewall-cmd --permanent --add-service=smtp
firewall-cmd --permanent --add-service=smtps
firewall-cmd --permanent --add-service=imaps
firewall-cmd --permanent --add-service=pop3s
```

変更を反映します。

```bash
firewall-cmd --reload
```

状態確認は以下のコマンドで行えます。

```bash
firewall-cmd --list-all
```

## Fail2ban

`/var/log`にある様々なログを監視し、アクセス失敗（多くは不正アクセス試行）を独自に管理しBan/Unbanします。

以下の設定内容はこのような内容になります。

- 10分間で5回アクセス失敗したIPアドレスを10分間Banする
- 24時間に5回BanされたIPアドレスを7日間Banする（再犯対策）
- サーバ自身と管理者PC（例では123.456.78.90）は監視の対象外とする

**/etc/fail2ban/jail.local**

```vim
[DEFAULT]
backend  = systemd
ignoreip = 127.0.0.0/8 10.0.0.0/16 123.456.78.90

destemail = root@example1.com
sender    = fail2ban@example1.com

banaction = firewallcmd-ipset

bantime  = 600
findtime = 600
maxretry = 5

[sshd]
enabled = true

[postfix-sasl]
enabled = true

[recidive]
enabled  = true
bantime  = 604800
findtime = 86400
maxretry = 5
```

### Logwatch対応

LogwatchがFail2banのログを拾ってくれない問題に対処します。

**/usr/share/logwatch/scripts/services/fail2ban**

```bash
    } elsif ( my ($Service,$Action,$Host) = ($ThisLine =~ m/WARNING:?\s\[?(.*?)[]:]?\s(Ban|Unban)[^\.]* (\S+)/)) {
```

↓ このように変更します。

```bash
    } elsif ( my ($Service,$Action,$Host) = ($ThisLine =~ m/(?:WARNING|NOTICE):?\s+\[?(.*?)[]:]?\s(Ban|Unban)[^\.]* (\S+)/)) {"
```

具体的には`WARNING:?\s`を`(?:WARNING|NOTICE):?\s+`に変更しています。

###  Fail2ban起動

```bash
systemctl start fail2ban
```

### ステータス確認

```bash
fail2ban-client status sshd
```

以下のように表示されます。

```
Status for the jail: sshd
|- Filter
|  |- Currently failed: 1
|  |- Total failed:     2118
|  `- Journal matches:  _SYSTEMD_UNIT=sshd.service + _COMM=sshd
`- Actions
   |- Currently banned: 4
   |- Total banned:     59
   `- Banned IP list:   27.78.14.83 70.37.84.164 193.142.146.21 116.105.216.179
```

### Logwatchの例

Logwatchからのメールでは以下のように記載されます。

```
--------------------- fail2ban-messages Begin ------------------------ 
 
 Banned services with Fail2Ban:				 Bans:Unbans
    sshd:                                       [ 12:6  ]
 
---------------------- fail2ban-messages End -------------------------
 ```

## サーバでの対応

以下はここまでの記事で設定済みです。

- 定期的にパッケージのアップデートを行う（`yum update`）
- 必要のないポートを外部公開しない（セキュリティグループ）
- SSHへのパスワードアクセスを禁止（公開鍵認証のみ）
- FTPサーバを起動しない（Git over SSHやSFTPで代用可能）※
- MySQL (3306/tcp) を外部に公開しない
- 使えるところはすべてSSL通信を行う（SSH, Nginx, Postfix, Dovecot）
- SSL/TLSの古いプロトコルや暗号スイートを使用しない（Nginx）
- 非公開領域にはBASIC認証やアプリケーションでの認証を設定（Nginx）
- 古いバージョンのPHPを使用しない（新規構築なら最低でもPHP 7.3系）
- SPAM対策を行う（Postfix / SMTP認証、RBLデータベース参照）
- 不正アクセスを対策する（Fail2ban）
- ログに目を通す（Logwatch）

> ※あるクライアントが自社サーバの脆弱性診断を業者に依頼したところ、FTP関連の脆弱性が多くを占めていました。

### さらなる対策

- ファイルの改竄検知を行う（AuditやTripwire等）
- ウィルス検知を行う（ClamAV等）
- SPAM検知を強化する（SpamAssassin等）
- 独自に設定したアラートをSlack等へ飛ばす
- Webアプリケーションの脆弱性に気を配る（WordPress等）

他にもできることは多いですが、割愛（もしくは今後記事化）します。