Spring bootでSSL（HTTPS）を有効にするならnginxを使え

[Spring bootでSSL（HTTPS）を有効にする](http://qiita.com/keigohtr/items/001b84838fefcc170ea2)と[Spring bootでSSL（HTTPS）を有効にする～Let's Encrypt編～](http://qiita.com/keigohtr/items/faa1bd0c647df54d6594)のつづき

## はじめに
Spring bootでSSL使うために色々調べて２個の記事を公開しました。その後も色々と調べてて、最終的な結論としては「nginxを使うのがベスト」となりました。nginxとLet's Encryptの組み合わせはQiitaに限らず多くの情報があるので、この記事ではSpring Bootとの組み合わせにフォーカスして説明します。以下の記事を参考にしました。

[光の速さのWEBサーバー(nginx)をlet's encryptでSSL化及びHTTP/2化。ついでにセキュリティ評価をA＋にする。](http://qiita.com/sak_2/items/ff835b669c0a7e110b09#%E5%85%AC%E9%96%8B%E9%8D%B5%E3%81%A8%E7%A7%98%E5%AF%86%E9%8D%B5%E3%81%AE%E5%A0%B4%E6%89%80%E3%82%92%E8%A8%98%E8%BC%89%E3%81%99%E3%82%8B)

環境はGoogle Cloud Engineです。

## nginxのインストールと設定
下記コマンドでnginxの最新版をインストールできます。OSはUbuntuの`trusty`です。そのあたりは適宜読み替えて下さい。nginxの公式ページに詳しく書いてあります。

```
curl http://nginx.org/keys/nginx_signing.key | sudo apt-key add -
sudo sh -c "echo 'deb http://nginx.org/packages/ubuntu/ trusty nginx' >> /etc/apt/sources.list"
sudo sh -c "echo 'deb-src http://nginx.org/packages/ubuntu/ trusty nginx' >> /etc/apt/sources.list"
sudo apt-get update
sudo apt-get install nginx
```

あとで使うので下記コマンドでDH交換鍵を作っておきます。

```
sudo mkdir /etc/nginx/ssl
cd /etc/nginx/ssl
sudo openssl dhparam 2048 -out dhparam.pem
```

次はnginxの設定ファイルを作ります。

```
cd /etc/nginx/conf.d
sudo cp default.conf default.conf.bak
sudo emacs default.conf
```

以下のようにします。前提としてSpring bootは`localhost（127.0.0.1）の8443ポート`で起動することにしています。ドメインは`example.com`としてますが、適宜読み替えて下さい。また、Let's Encryptで証明書は発行しているものとします。Let's Encryptの使い方については[前回の記事](http://qiita.com/keigohtr/items/faa1bd0c647df54d6594)に書きました。nginxを使うついでに、以下ではhttpへのリクエストをhttpsにリダイレクトするように変更しています。

```
server {
    listen       80;
    listen       [::]:80;
    return       301 https://$host$request_uri;
}

upstream spring_boot {
    server 127.0.0.1:8443;
}

server {
    listen      443 ssl;
    listen      [::]:443 ssl;

    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

    ssl         on;
    ssl_prefer_server_ciphers on;
    ssl_dhparam /etc/nginx/ssl/dhparam.pem;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers ECDHE+RSAGCM:ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:!aNULL:!eNULL:!EXPORT:!DES:!3DES:!MD5:!DSS;

    ssl_stapling on;
    ssl_stapling_verify on;
    ssl_trusted_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
    resolver     8.8.8.8;
    add_header   Strict-Transport-Security 'max-age=31536000; includeSubDomains;';

    server_name  example.com;
    location / {
        proxy_pass    http://spring_boot;
    }
}
```

設定が終わったらnginxを再起動します。

```
sudo /etc/init.d/nginx restart
```

## Spring bootの設定

以下のように変更します。

```application.properties
server.port=8443
#server.ssl.key-store=keystore.p12
#server.ssl.key-store-password=mypassword
#server.ssl.keyStoreType=PKCS12
#server.ssl.keyAlias=tomcat
endpoints.enabled=false
management.add-application-context-header=false
```

`endpoints.enabled`と`management.add-application-context-header`の設定は好みです。どちらも「余計な情報をユーザーに見られないようにする」効果があります。

これまでの記事ではSpring Bootの機能を使ってSSLを実現していました。前回の時点では、[Qualys SSL Report](https://www.ssllabs.com/ssltest/)のセキュリティレポートは評価Bでした。

今回はSpring BootのSSL機能を使わないで、nginxをフロントに立たせるようにしました。今回の設定では、[Qualys SSL Report](https://www.ssllabs.com/ssltest/)のセキュリティレポートは評価A+でした。やったね。

ということで、前回課題にあげた「PKCS12の自動更新」は不要になりました。代わりに、cronで下記コマンドを実行して証明書を更新するだけでOKです。

```
if !./letsencrypt-auto renew > /var/log/letsencrypt/renew.log 2>&1 ; then
    echo Automated renewal failed:
    cat /var/log/letsencrypt/renew.log
    exit 1
fi
```

Spring bootの機能だけでも評価A+を取る方法があるのかもしれませんが、見つけられませんでした。誰か良い方法をご存知でしたらコメントをいただけると助かります。