Centos+nginxでLet's encrypt(certbot)導入と自動更新まで

author potpro(ぼとぷろ)
2016/12/02

Centos+nginxでLet's encrypt(certbot)導入と自動更新まで

react-nativeをとりあえずすぐ実機で動かしてみる そろそろモチベとネタが落ちてきた。どこまで続くか・・・

potproject.net Advent Calendar 2016 3日目の記事です。


ちょっと前にLet's encryptの導入方法などを書いていましたが、
もはや古くなっている感じだと思います。
というよりいつの間にやら日本語ポータルとか出来ていたりと、かなり充実してきていてびっくりです。 手順も前とかなり変わってきているので、新しく書き直します。

今回はcertbotクライアントを使用し、自動更新までやります。
certbotは元々letsencrypt-autoだったクライアントの名前が変わったものっぽいです。
yumなんかでもインストールが可能になりました。

certbotのインストール(centos7)

epelリポジトリからインストール可能です。

yum install epel-release
yum install certbot

これで終了。初期と比べると手軽になったものです。
Apacheの場合はpython-certbot-apacheというパッケージも必要らしいです。

centbotからSSL証明書の発行

ここで、同じようにApache,nginx,webroot,standaloneといういろいろなプラグインを選べます。

  • Apache : Apacheに最適化したプラグイン。設定を自動書き換え。
  • nginx : nginxに最適化されたプラグイン。設定を自動書き換え。アルファ版らしい
  • webroot : rootにファイルを置くことで認証。Apacheでもnginxでも使える
  • standalone : 自動的にWebサーバを立ち上げて認証。但し現状の鯖は停止する必要あり
  • manual : 手動で認証。Webサーバーを止める必要が無かったりするらしいが結構難しい

個人的にですが、Let's encryptの導入設定はstandaloneを自分はおすすめします。前も言ってた気がしますが。
Apacheやnginxのプラグインは楽だと思いがちですが、実際Apacheは必要パッケージが無いと動かなかったり、nginxはまだアルファ版だったり不安要素が残ります。
そして上2つの一番嫌なところは、自動的に認証してくれるということで、Apacheやnginx設定を変更されてしまうのです。
これが設定破壊されそうで怖い。
webrootは指定したWebのrootに勝手にファイル置かれて、認証後もそのままなのでなんか気持ち悪いです。(アクセス出来ちゃいますし)
なので自分は自動で楽に使えるstandalone版を使っています。
止まっちゃうのは致し方ないけれど、個人レベルであれば数秒くらいは容認できますよね。

certbot

これをコマンドに打ち込むことでGUI設定が出来ます。全てコマンドで自動化も出来るらしいですが、
手順に沿ったほうが確実かなと。 完了すればSuccessfulが表示され、
秘密鍵: ** /etc/letsencrypt/live/ドメイン名/privkey.pem **
公開鍵: ** /etc/letsencrypt/live/ドメイン名/cert.pem ** に鍵が配置されます。

Webサーバ設定(nginx)

この辺は試行錯誤が必要と思いますが、おおむねこんな感じです。http2対応版。

//略//
server {
    # TCP PORT Setting
    listen 443 ssl http2 default_server;
    listen [::]:443 ssl http2 default_server;

    # ServerName & Root
    server_name [ドメイン名];
    root /var/www/;

    #SSL Setting
    ssl_certificate /etc/letsencrypt/live/[ドメイン名]/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/[ドメイン名]/privkey.pem;
    ssl_session_cache shared:SSL:1m;
    ssl_session_timeout  10m;
    ssl_ciphers AESGCM:HIGH:!aNULL:!MD5;
    ssl_prefer_server_ciphers on;
    ...
    //略//
}

ssl_ciphersは受け付ける暗号化スイートの優先順位らしいです。
!がついているものは使用しない。MD5とかは当然除外です。 これが最低限の設定。もっとセキュリティを高めるにはssl_ciphersやssl_protocolsを的確に設定したほうがいいらしい。

例えば、MD5は上の例で除外されてますが、他にも外すものは結構あるでしょう。つうか暗号スイートなんて数が多すぎて流石に普通把握できない。   他にもSSLv3は最近POODLEという脆弱性が一時期人気になって一躍有名になったので外したい。

そこで、MozillaさんがSSL設定ジェネレータを公開しているということを知った。
これすごく使えますね。しかもセキュリティもMozillaなのでピカイチです。
Mozilla SSL Configuration Generator https://mozilla.github.io/server-side-tls/ssl-config-generator/

    #DH鍵交換に使用するパラメータファイル
    ssl_dhparam /path/to/dhparam.pem;

    #SSLプロトコルの指定と暗号化スイートの優先度設定
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers 'ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS';
    ssl_prefer_server_ciphers on;

    # HSTS ヘッダ
    add_header Strict-Transport-Security max-age=15768000;

このあたりをしっかり設定することでセキュリティが上がって大手企業レベル並のセキュリティを確保できそうです。
・・・鯖負担は上がりそうですが。

証明書の自動更新

2回目以降は一々入力せず同じ内容に更新できるようになります。
これはletsencrypt-auto時代には無かった気がします。

certbot renew

使えるオプションとして ** --quiet ** でログ出力しない、** --dry-run ** で更新テスト(実際には更新しない)が出来ます。
更新できる回数は週に何回だと決められているようで、それを突破すると更新できなくなるので使いすぎに注意。 これを押すだけで自動更新、ってまあコマンド打ってたら自動じゃないじゃんということで、これをそのまま自動実行デーモンであるcronに登録します。 今回はnginxです。apacheならapache(httpd)でお願いします。

crontab -e

0 1 1 * * root service nginx stop && certbot renew -force-renew && service nginx start

一度サーバを止めて、更新後にまたサーバをスタートしたいので、こういう風に書きました。
どっちにしろサーバを止める必要があるならこれが一番かなと思います。 これでSSL導入完了。せっかくなのでhttpは止めるかリダイレクトしましょう。


4日目 → nginxでRackアプリケーション(sinatra)を動かす