Webサーバをセキュアに保つ設定のまとめ

## はじめに

Webサーバをセキュアに保つ為、個人的に行っている設定をざっくりまとめてみました。
設定内容はApache 2.4での運用を想定していますので、他のHTTPdをお使いの方は適宜読み替えてください。
各設定項目は以下のオンラインテストサイトでA+相当を取ることを目指しています。

- 設定ファイル生成
    - [Mozilla SSL Configuration Generator](https://mozilla.github.io/server-side-tls/ssl-config-generator/)
- オンラインテスト
    - [Mozilla Observatory](https://observatory.mozilla.org/)
    - [Qualys SSL Server Test](https://www.ssllabs.com/ssltest/)

## 前提条件

以下で設定する項目は特にHTTPS接続や攻撃防止に関するものになります。
HTTPdそのものに関する基本設定については別記事をご参照ください。

## SSLProtocol

危殆化した古いプロトコルを有効にしている場合、古いプロトコルを標的としたダウングレード攻撃等を受ける可能性がある為、新しいプロトコルのみを有効にする必要があります。
以下の例では接続をTLS1.2のみに制限していますが、古いブラウザでは接続できなくなる可能性がありますので[対応ブラウザ](https://ja.wikipedia.org/wiki/Template:%E3%82%A6%E3%82%A7%E3%83%96%E3%83%96%E3%83%A9%E3%82%A6%E3%82%B6%E3%81%AB%E3%81%8A%E3%81%91%E3%82%8BTLS/SSL%E3%81%AE%E5%AF%BE%E5%BF%9C%E7%8A%B6%E6%B3%81%E3%81%AE%E5%A4%89%E5%8C%96)には十分に注意してください。

```text:ssl.conf
SSLProtocol -All +TLSv1.2
```

## SSLHonorCipherOrder

HTTPS接続時の暗号アルゴリズムを、サーバ設定優先にします。
これにより、ダウングレード攻撃等を防ぐことができます。

```text:ssl.conf
SSLHonorCipherOrder On
```

### SSLCipherSuite

上記とあわせて、暗号アルゴリズムを強度の高いもののみに絞り込む必要があります。
以下の例は最新ブラウザをベースに安全な強度を保つための例です。
アルゴリズムを決めるのは難しい為「[Mozilla SSL Configuration Generator](https://mozilla.github.io/server-side-tls/ssl-config-generator/)」等の利用をお勧めします。

```conf:ssl.conf
SSLCipherSuite ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256
```

## SSLCompression

SSL圧縮機能が有効になっている場合、CRIMEやBEASTといった「[サイドチャネル攻撃](https://ja.wikipedia.org/wiki/%E3%82%B5%E3%82%A4%E3%83%89%E3%83%81%E3%83%A3%E3%83%8D%E3%83%AB%E6%94%BB%E6%92%83)」を受ける可能性がある為、必ず設定でオフにする必要があります。

```text:ssl.conf
SSLCompression off
```

## SSLUseStapling

SSLサーバ証明書の失効をチェックする「OCSP (Online Certificate Status Protocol)」を有効にします。
セキュリティ向上とともに、ブラウザでのSSLハンドシェイク時間の短縮も見込めます。

```text:ssl.conf
SSLUseStapling on
SSLStaplingResponderTimeout 5
SSLStaplingReturnResponderErrors off
SSLStaplingCache shmcb:/var/run/ocsp(128000)
```

## SSLSessionTickets

「[前方秘匿性](https://ja.wikipedia.org/wiki/Forward_secrecy)」を満たす手段として、セッションチケット機能を無効にします。
これにより、1つの鍵が漏れた場合にも他の鍵へ影響しない秘匿性が担保できます。

```text:ssl.conf
SSLSessionTickets off
```

## Mutex

各プロセスが同期をとるためのmutex設定をApacheが自動的に行う設定です。
以下の設定値が推奨されます。

```text:ssl.conf
Mutex default ssl-cache
```

## Strict-Transport-Security ヘッダ

Hypertext Strict Transport Security（HSTS）は、WebブラウザにHTTPS接続を強制するためのポリシーです。
WebブラウザがHSTSが有効なサイトにアクセスした際、サーバは次回からHTTPSアクセスするようWebブラウザに通知します。
この情報をWebブラウザが端末内にキャッシュする事により、次回以降の接続を常にHTTPS化することができます。
HSTSが有効な状態ではHTTP→HTTPSへのリダイレクトが必要なくなるため、特に中間者攻撃(MITM)に対して有効であると言われています。

- [HTTP Strict Transport Security - MDN](https://developer.mozilla.org/ja/docs/Web/Security/HTTP_Strict_Transport_Security)
- [HSTS - IETF](https://tools.ietf.org/html/rfc6797)
- [HSTS - wikipedia](https://ja.wikipedia.org/wiki/HTTP_Strict_Transport_Security)

### HSTSの設定方法

クライアントに対して`Strict-Transport-Security`ヘッダを返却する事で実現できます。
指定可能なオプションは以下の通りです。

| 項目 | 必須 |
|:-----|:----:|
| max-age=[秒数] | ○ |
| includeSubDomains |  |
| preload |  |

複数オプションを設定する場合にはセミコロンで区切ります。

```text:ssl.conf
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
```

#### max-age

ここで指定された秒数の間、HSTS設定をWebブラウザ上でキャッシュします。
この値は1年間（31,536,000秒）以上を指定する必要があります。
**一度ブラウザに保存された設定情報はサーバ側からは消去不可能**なので、ドメイン上でHTTP応答の必要がない事を十分に確認する必要があります。

#### includeSubDomains

この設定を行うと、**全てのサブドメイン**が影響を受けるようになります。
一部のサブドメインをHTTP運用する必要がある場合、このオプションを設定してはいけません。

#### preload

HSTS Preloadを[こちらのサイトより申請](https://hstspreload.org/)する事で、主要ブラウザに設定が記載され、初回接続時にもHTTPを利用しないようになります。

※繰り返しになりますが、サブドメインを含めたHTTPS化が必須となる設定ですので、適用前は充分ご検討ください。

## Content-Security-Policy ヘッダ

Content-Security-Policy（CSP）は、クロスサイトスクリプティングやデータインジェクション等の攻撃を検知し、影響を軽減するための設定です。
JavaScript/CSS/画像/動画/フレーム等の各種リソースを埋め込み可能なドメインを制限することができます。
全てのリソースを**外部ドメインを使って配信していない場合**は以下のように設定します。

```text:ssl.conf
Content-Security-Policy: default-src 'self'
```

その他の設定パターンについては以下をご覧ください。

- [コンテンツセキュリティポリシー (CSP) - MDN](https://developer.mozilla.org/ja/docs/Web/HTTP/CSP)

## Referrer-Policy ヘッダ

Webブラウザがリンク先にアクセスする際、リファラを送信させるかを制御します。
特に遷移先サイトとの取り決めがない場合、設定値は「same-origin（同一ドメイン内）」が良いでしょう。

```conf:ssl.conf
Header always set Referrer-Policy "same-origin"
```

- [Referrer-Policy - MDN](https://developer.mozilla.org/ja/docs/Web/HTTP/Headers/Referrer-Policy)

## X-XSS-Protection ヘッダ

クロスサイトスクリプティングを防ぐための設定です。
Webブラウザが攻撃を検知した場合、表示をブロックするような以下の設定が推奨されます。

```text:ssl.conf
Header always set X-XSS-Protection "1; mode=block"
```

- [X-XSS-Protection - MDN](https://developer.mozilla.org/ja/docs/Web/HTTP/Headers/X-XSS-Protection)

## X-Content-Type-Options ヘッダ

Webブラウザに対して、Content-Type指定を無視してコンテンツを扱う事を禁止するための設定です。
HTTPレスポンス全体の検査（sniffing）をさせない設定を推奨します。

```text:ssl.conf
Header always set X-Content-Type-Options "nosniff"
```

## X-Frame-Options ヘッダ

X-Frame-Options（XFO）は、iframeタグによるクリックジャッキングを防止するための設定です。
サイト内で**該当タグを使用しない場合**には以下の設定を推奨します。

```text:ssl.conf
Header always set X-Frame-Options DENY
```

## X-Permitted-Cross-Domain-Policies ヘッダ

Adobe Acrobat/FlashPlayer 関連のヘッダです。
これらのファイルを扱わないサイトでは、全てのポリシーファイルを不許可とする設定を推奨します。

```text:ssl.conf
Header always set X-Permitted-Cross-Domain-Policies none
```

- [Cross Domain Configuration - Adobe](https://www.adobe.com/devnet-docs/acrobatetk/tools/AppSec/xdomain.html)

## X-Download-Options ヘッダ

`Content-Disposition: attachment` ヘッダを用いてファイルをダウンロードさせる場合に、ファイルを直接実行させない（開けない）ような設定を行う事ができます。

```text:ssl.conf
Header always set X-Download-Options noopen
```

## 最後に

セキュアな設定について解説しているサイトのリンクを紹介します。

- [OWASP Secure Headers Project](https://www.owasp.org/index.php/OWASP_Secure_Headers_Project)