目次
let's encrypt
無料のサーバ証明書
以下nginxに証明書を設定する流れ
インストール
githubからcloneする
git clone https://github.com/certbot/certbot.git
必要なパッケージをインストールする
cd certbot ./certbot-auto
証明書の発行
ここでは example.com と www.example.com の2つのドメインに対する証明書を発行するものとして記述する。
証明書を発行するために、このサーバの管理者がドメインの所持者であることを確認する必要がある。let's encryptでは指定ドメインのport 80にHTTPアクセスして、certbotコマンドが作成したファイルを取得できればドメイン所持者であると見做す。
まずnginxをインストールして、ドメイン所持確認用の設定を追加し、nginxを起動する。
server { server_name: example.com; listen 80; root /var/www/example.com/htdocs; location ^~ /.well-known/acme-challenge/ { root /var/www/html; try_files $uri =404; } // ... 以下略 } server { server_name: www.example.com listen 80; root /var/www/www.example.com/htdocs location ^~ /.well-known/acme-challenge/ { root /var/www/html; try_files $uri =404; } }
次に証明書を発行する。-wはnginxのドキュメントルートを指定する。ここにドメイン確認のためのファイルが作成される。-dはドメインで複数設定可能。サブジェクト代替名(SAN/Subject Alternative Name)によって1枚で複数のサーバ名に対応する証明書が発行される。
sudo -H /path/to/certbot-auto certonly --webroot -w /var/www/html -d example.com -d www.example.com
証明書は /etc/letsencrypt/live/example.com
以下に作成される(/etc/letsencrypt/live/www.example.com
というディレクトリは作られません)。
- privkey.pem - 秘密鍵、漏らしてはいけないやつ
- fullchain.pem - サーバ証明書+中間証明書のセット
- cert.pem - サーバ証明書
- chain.pen - 中間証明書
httpsの設定
nginxにsslの設定を行う。以下の設定ではhttp2も有効になる(http2はnginx 1.9.5以降で有効)。
server { server_name: example.com; listen 80; listen 443 ssl http2; ssl on; ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; root /var/www/example.com/htdocs; location ^~ /.well-known/acme-challenge/ { root /var/www/html; try_files $uri =404; } // ... 以下略 } server { server_name: www.example.com listen 80; listen 443 ssl http2; ssl on; ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; root /var/www/www.example.com/htdocs location ^~ /.well-known/acme-challenge/ { root /var/www/html; try_files $uri =404; } }
nginxをリロードする
sudo service nginx reload
証明書の更新
let's encryptの証明書は有効期間が3ヶ月と短く、cronなどで自動更新処理を行う運用を想定している。
以下のコマンドをroot権限で週一ぐらいの頻度で実行するとよい。
sudo -H /path/to/certbot-auto renew -n sudo service nginx reload
期限切れまで残り1ヶ月を切ったときに実行されると証明書が更新される。
メモ
インストール時のエラー
./certbot-autoを実行して必要なパッケージのインストール中(pythonのvirtualenv設定中)にエラー
Creating virtual environment... Traceback (most recent call last): File "/usr/lib/python3/dist-packages/virtualenv.py", line 2363, in <module> main() File "/usr/lib/python3/dist-packages/virtualenv.py", line 719, in main symlink=options.symlink) File "/usr/lib/python3/dist-packages/virtualenv.py", line 988, in create_environment download=download, File "/usr/lib/python3/dist-packages/virtualenv.py", line 918, in install_wheel call_subprocess(cmd, show_stdout=False, extra_env=env, stdin=SCRIPT) File "/usr/lib/python3/dist-packages/virtualenv.py", line 812, in call_subprocess % (cmd_desc, proc.returncode)) OSError: Command /home/hisanori/.loca...ncrypt/bin/python2.7 - setuptools pkg_resources pip wheel failed with error code 1
OSに日本語パッケージが入ってないのに、LANGがja_JP.UTF-8等になっている(SSHクライアントによって設定される)場合に発生する
export LANG=C
としてからcertbot-autoを実行する。
セキュリティの強化
Strict Transport Security (HSTS) の設定
あるドメインへhttpsでアクセスした場合、以降そのドメインへの接続にはハイパーリンクなどでhttpが指定されていてもhttpsを使うようにブラウザに指示するHTTPヘッダ
server { add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; }
- max-age - 有効期間(秒、31536000は1年間)を指定するヘッダオプション、この期間ブラウザはhttpsを使うよう記憶する。
- includeSubDomains - サブドメインもhttpsを使うようにブラウザに指示するヘッダオプション。
- always - nginxのすべてのレスポンス(内部的に生成されたエラーレスポンスなどの場合も)ヘッダを付加するようにnginxに指示する。
プロトコルと暗号化スイートの指定
最早セキュアではないプロトコルと暗号化スイートを除外する。設定によっては古いブラウザやデバイスではアクセス不能になる。
セキュアな設定は年々変化するので、これをコピーして使わないこと。
server { ssl_protocols TLSv1.2; ssl_ciphers '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'; ssl_prefer_server_ciphers on; }
- ssl_protocols 通信プロトコル
- ssl_ciphers 使用可能な暗号スイート
- ssl_prefer_server_ciphers onにすると暗号スイートの選択はサーバ側の指定に従い、クライアントの指定は無視される
https://mozilla.github.io/server-side-tls/ssl-config-generator/