あけましておめでとうございます。本年度もよろしくお願い致します。
年末年始にLINE BOT AWARDの作品を作ろうとして、callbackが自鯖のオレオレ自己証明書だとVerifyで弾かれてしまい、年始早々打ちのめされたので、この際だからアレしようと思って、ちゃんとSSL化した時のメモ
この記事に書いてある事一覧
- Let’s EncryptでDV型証明書を発行した
- 発行にはcertbotのwebrootプラグインを使用
- httpからhttpsに301リダイレクトさせてHSTSで1年間保持するように設定
LetsEncryptで証明書の発行(certbotクライアントのインストール)
Debianではjessie-backportsでパッケージが提供されているようですが、backportsは使用せず、certbot-auto
スクリプトを使用しました
なお、certbotのDockerイメージも公開されているため、Dockerコンテナでcertbotを使いたい場合はこちらを利用する方法もあります。
// Dockerfile
RUN wget "https://dl.eff.org/certbot-auto" -P /usr/local/bin/
RUN chmod a+x /usr/local/bin/certbot-auto
RUN /usr/local/bin/certbot-auto --os-packages-only --non-interactive
--os-packages-only
オプションを指定すると、実際に証明書の発行はせずに、必要なパッケージのインストールのみ行い、exitしてくれます。逆にこれを指定しないと、心の準備が伴っていない場合もどんどん処理が進みます。
--non-interactive
オプションは、対話式でなく自動でcertbotの処理が進むようになるオプション。今回は、--os-packages-only
を同時に指定しているので不要のように見えますが、このオプションが無いとapt-getの[Y/n]で停止したので、これを指定するとそこが自動になります(地味)
Letsencryptで証明書の発行(認証方式になやむ)
認証方式がたくさんあって、apache
とかnginx
とか指定して勝手に設定ファイルいじられたり再起動されたりするのはなんか嫌だし、じゃあstandalone
かwebroot
?これって何が違うのよ?というので調べ回ってたのですが、以下の記事に図解があって大変わかりやすかったです
そして、ACMEプロトコルについては以下の記事がとても参考になりました
結論として自分の環境では、webrootプラグインを使う事にしました
Letsencryptで証明書の発行(認証する)
webrootプラグインは、認証の過程で[DocumentRoot]/.well-known/acme-challenge/
に一時的にトークンを出力し、そのトークンに対してアクセスしにくるので、
certbot-auto
実行ユーザが[DocumentRoot]/.well-known/acme-challenge/
へのファイル書き込み権限がある事- 対象のドメインでHTTPアクセス(80)が出来る事。
このあたりはクリアにする必要があるようです。(この流れが分かってなかったので結構右往左往しました)
// 証明書発行コマンド
$ docker exec [webのコンテナ名] certbot-auto certonly --webroot --non-interactive --agree-tos -w [DocumentRootのPATH] --email [メールアドレス] -d [発行するドメイン]
長いですね。このままッターンってやってもかっこいいと思いますが僕は嫌です
設定ファイルにしてしまいましょう。設定ファイルの雛形はここにあります
// つくったiniファイル(以下、余分な行は省略してます)
$ cat 7me.ini
# This is an example of the kind of things you can do in a configuration file.
# All flags used by the client can be configured here. Run Certbot with
# "--help" to learn more about the available options.
# Use a 4096 bit RSA key instead of 2048
rsa-key-size = 4096
# Uncomment and update to register with the specified e-mail address
email = [メールアドレス]
# Uncomment and update to generate certificates for the specified
# domains.
domains = [発行するドメイン(※カンマ区切りで複数指定可)]
# Uncomment to use a text interface instead of ncurses
# text = True
# Uncomment to use the standalone authenticator on port 443
# authenticator = standalone
# standalone-supported-challenges = tls-sni-01
# Uncomment to use the webroot authenticator. Replace webroot-path with the
# path to the public_html / webroot folder being served by your web server.
authenticator = webroot
webroot-path = [DocumentRootのPATH]
このiniファイルを元に実行します。
$ docker exec [webのコンテナ名] certbot-auto certonly --config /path/to/7me.ini --non-interactive --agree-tos
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Starting new HTTPS connection (1): acme-v01.api.letsencrypt.org
Obtaining a new certificate
Performing the following challenges:
http-01 challenge for [ドメイン名]
Using the webroot path [DocumentRootのPATH] for all unmatched domains.
Waiting for verification...
Cleaning up challenges
Generating key (4096 bits): /etc/letsencrypt/keys/0002_key-certbot.pem
Creating CSR: /etc/letsencrypt/csr/0002_csr-certbot.pem
IMPORTANT NOTES:
- Congratulations! Your certificate and chain have been saved at
/etc/letsencrypt/live/[ドメイン名]/fullchain.pem. Your cert will
expire on 2017-04-03. To obtain a new or tweaked version of this
certificate in the future, simply run certbot-auto again. To
non-interactively renew *all* of your certificates, run
"certbot-auto renew"
- If you like Certbot, please consider supporting our work by:
Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate
Donating to EFF: https://eff.org/donate-le
うまく行けばこんな感じに表示されます。そして、/etc/letsencrypt/live/[ドメイン名]/ あたりに、証明書が出力されていると思います
$ docker exec [webのコンテナ名] ls -l /etc/letsencrypt/live/[ドメイン名]
合計 0
lrwxrwxrwx 1 root root 38 1月 3 15:23 cert.pem -> ../../archive/[ドメイン名]/cert1.pem
lrwxrwxrwx 1 root root 39 1月 3 15:23 chain.pem -> ../../archive/[ドメイン名]/chain1.pem
lrwxrwxrwx 1 root root 43 1月 3 15:23 fullchain.pem -> ../../archive/[ドメイン名]/fullchain1.pem
lrwxrwxrwx 1 root root 41 1月 3 15:23 privkey.pem -> ../../archive/[ドメイン名]/privkey1.pem
Webサーバに設定する
Nginx or Apacheに以下のように設定
// Nginx
ssl_certificate /path/to/fullchain.pem;
ssl_certificate_key /path/to/privkey.pem;
// Apache2
SSLCertificateFile /path/to/fullchain.pem
SSLCertificateKeyFile /path/to/privkey.pem
HTTPからHTTPSへ301リダイレクトさせてHSTSを仕込む
Nginxの場合
server {
listen 80;
server_name [ドメイン名];
location / {
return 301 https://$host$request_uri; # ← 301リダイレクトさせる
# proxy_pass http://172.19.0.xx/; # ← プロキシさせてた箇所(跡地)
break;
}
}
server {
listen 443 ssl;
server_name [ドメイン名];
ssl_certificate /path/to/fullchain.pem;
ssl_certificate_key /path/to/privkey.pem;
add_header Strict-Transport-Security 'max-age=31536000; includeSubDomains;preload'; # ← HSTSの値をセット
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 5m;
ssl_protocols SSLv2 SSLv3 TLSv1;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
location / {
proxy_pass https://172.19.0.xx/;
break;
}
}
Apacheの場合
// 必要に応じてモジュールを有効にする
$ sudo a2enmod rewrite ssl headers
$ sudo systemctl restart apache2
$ cat vhost.conf
<VirtualHost *:80>
RewriteEngine on
RewriteCond %{HTTP_HOST} ^example\.com
RewriteRule ^/(.*)$ https://example.com/$1 [R=301,L]
</VirtualHost>
<VirtualHost *:443>
SSLEngine on
SSLCertificateFile /etc/letsencrypt/live/example.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/example.com/privkey.pem
Header set Strict-Transport-Security 'max-age=31536000; includeSubDomains;preload'
ServerAdmin hoge@example.local
DocumentRoot "/var/virtualdomains/example.com/"
ServerName example.com
CustomLog "/var/log/apache2/vhost/example.com-access-ssl.log" combined
ErrorLog "/var/log/apache2/vhost/example.com-error-ssl.log"
<Directory "/var/virtualdomains/example.com/">
Allowoverride All
Require all granted
</Directory>
</VirtualHost>