前程として、対象鯖は dns で正引きが出来る事。
今回は例題として以下のホスト名を用いる。
example.jp
example.com
example.org
xn--w22as22a.example.jp
以上4ホスト名
OS は FreeBSD 11.2-RELEASE を前提として記述しているが、ディレクトリや軽微なコマンドを読み替える事で他の unix 系 OS 等にも対応できると思われる。
また本記事は FreeBSD 経験者を対象に書いているので、事細かい配慮はされていません。
www/nginx 導入
web server の nginx をインスコして OS 再起動後でも自動起動の設定をする
cd /usr/ports/www/nginx
make install
sysrc nginx_enable="YES"
nginx の設定
http {
server {
listen [::]:80;
listen 80;
server_name example.jp;
location ^~ /.well-known/acme-challenge/ {
alias /usr/local/www/acme/;
}
location / {
return 301 https://$host$request_uri;
}
}
server {
listen [::]:80;
listen 80;
server_name example.com;
location ^~ /.well-known/acme-challenge/ {
alias /usr/local/www/acme/;
}
location / {
return 301 https://$host$request_uri;
}
}
server {
listen [::]:80;
listen 80;
server_name example.org;
location ^~ /.well-known/acme-challenge/ {
alias /usr/local/www/acme/;
}
location / {
return 301 https://$host$request_uri;
}
}
server {
listen [::]:80;
listen 80;
server_name xn--w22as22a.example.jp;
location ^~ /.well-known/acme-challenge/ {
alias /usr/local/www/acme/;
}
location / {
return 301 https://$host$request_uri;
}
}
}
nginx の設定確認
nginx -t
ここで「test is successful」が表示しなければ nginx.conf の記述ミスか、個別環境の差異を吸収し切れていないので、再度確認する。
nginx 起動
service nginx start
acme-client の設定下準備
touch /usr/local/www/acme/hogehoge
fetch -qo- http://example.jp/.well-known/acme-challenge/hogehoge
ここでエラーが出れば、dns 含めた記述ミスなので、再度確認。
問題が無ければ他のホスト名も確認しておく。
fetch -qo- http://example.jp/.well-known/acme-challenge/hogehoge
fetch -qo- http://example.com/.well-known/acme-challenge/hogehoge
fetch -qo- http://example.org/.well-known/acme-challenge/hogehoge
fetch -qo- http://xn--w22as22a.example.jp/.well-known/acme-challenge/hogehoge
エラーが無ければ、テストファイルを削除しておく。
unlink /usr/local/www/acme/hogehoge
security/acme-client 導入
cd /usr/ports/security/acme-client
make install
acme-client の設定
### security/acme-client
weekly_acme_client_enable="YES"
weekly_acme_client_domains="example.jp example.com example.org xn--w22as22a.example.jp"
証明書の発行手続き
acme-client -vnN example.jp example.com example.org xn--w22as22a.example.jp
実行すると以下のようなログが流れていく
acme-client: /usr/local/etc/acme/privkey.pem: account key exists (not creating)
acme-client: /usr/local/etc/ssl/acme/private/privkey.pem: domain key exists (not creating)
acme-client: adding SAN: example.com
acme-client: adding SAN: example.org
acme-client: adding SAN: xn--w22as22a.example.jp
acme-client: https://acme-v01.api.letsencrypt.org/directory: directories
acme-client: acme-v01.api.letsencrypt.org: DNS: 2600:140b:1:181::3a8e
acme-client: acme-v01.api.letsencrypt.org: DNS: 2600:140b:1:185::3a8e
acme-client: acme-v01.api.letsencrypt.org: DNS: 23.42.210.228
acme-client: https://acme-v01.api.letsencrypt.org/acme/new-authz: req-auth: example.jp
acme-client: https://acme-v01.api.letsencrypt.org/acme/new-authz: req-auth: example.com
acme-client: https://acme-v01.api.letsencrypt.org/acme/new-authz: req-auth: example.org
acme-client: https://acme-v01.api.letsencrypt.org/acme/new-authz: req-auth: xn--w22as22a.example.jp
acme-client: /usr/local/www/acme/HhYYlbiFlhOtlp9x1aBPgZzURFWLObWBrc72k6SAxsU: created
acme-client: https://acme-v01.api.letsencrypt.org/acme/challenge/uW0ibZCGOH8TJzRmi6mkQwQ-WB5svZRW4omby4-kteE/5874344542: challenge
acme-client: /usr/local/www/acme/ldhbr5pVkPJcJd5vqWDzn8d8XA5T_yAjT6bmbCgxsCw: created
acme-client: https://acme-v01.api.letsencrypt.org/acme/challenge/kwiPqOzuQkZyGDIqJYH9hAJbQuyvzaUKOaJXafQ2-mw/6213869611: challenge
acme-client: /usr/local/www/acme/UDsdFCp0mIMsxu_uD8qwXxhJx9ePK_o19Z6P7zR2o7Y: created
acme-client: https://acme-v01.api.letsencrypt.org/acme/challenge/jIjdHQQxItemccxAVpRDQV4nfThYdlGHwjN5Yb3-hNM/6213910989: challenge
acme-client: /usr/local/www/acme/m2OoOOj_068FX5ADOuceiFmP-XMywS9Mf5_tCSq52dU: created
acme-client: https://acme-v01.api.letsencrypt.org/acme/challenge/Cynvst15YKcEe1melPpmykZd97TBHRpMAUV42eiW9k8/6213911979: challenge
acme-client: https://acme-v01.api.letsencrypt.org/acme/challenge/uW0ibZCGOH8TJzRmi6mkQwQ-WB5svZRW4omby4-kteE/5874344542: status
acme-client: https://acme-v01.api.letsencrypt.org/acme/challenge/kwiPqOzuQkZyGDIqJYH9hAJbQuyvzaUKOaJXafQ2-mw/6213869611: status
acme-client: https://acme-v01.api.letsencrypt.org/acme/challenge/jIjdHQQxItemccxAVpRDQV4nfThYdlGHwjN5Yb3-hNM/6213910989: status
acme-client: https://acme-v01.api.letsencrypt.org/acme/challenge/Cynvst15YKcEe1melPpmykZd97TBHRpMAUV42eiW9k8/6213911979: status
acme-client: https://acme-v01.api.letsencrypt.org/acme/new-cert: certificate
acme-client: http://cert.int-x3.letsencrypt.org/: full chain
acme-client: cert.int-x3.letsencrypt.org: DNS: 2600:140b:1:18b::ce0
acme-client: cert.int-x3.letsencrypt.org: DNS: 2600:140b:1:193::ce0
acme-client: cert.int-x3.letsencrypt.org: DNS: 23.42.221.179
acme-client: /usr/local/etc/ssl/acme/chain.pem: created
acme-client: /usr/local/etc/ssl/acme/cert.pem: created
acme-client: /usr/local/etc/ssl/acme/fullchain.pem: created
2600:3000:1511:200::1d - - [14/Nov/2018:13:25:04 +0900] "GET /.well-known/acme-challenge/HhYYlbiFlhOtlp9x1aBPgZzURFWLObWBrc72k6SAxsU HTTP/1.1" 200 87 "-" "Mozilla/5.0 (compatible; Let's Encrypt validation server; +https://www.letsencrypt.org)"
2600:3000:1511:200::1d - - [14/Nov/2018:13:25:07 +0900] "GET /.well-known/acme-challenge/ldhbr5pVkPJcJd5vqWDzn8d8XA5T_yAjT6bmbCgxsCw HTTP/1.1" 200 87 "-" "Mozilla/5.0 (compatible; Let's Encrypt validation server; +https://www.letsencrypt.org)"
2600:3000:1511:200::1d - - [14/Nov/2018:13:25:09 +0900] "GET /.well-known/acme-challenge/UDsdFCp0mIMsxu_uD8qwXxhJx9ePK_o19Z6P7zR2o7Y HTTP/1.1" 200 87 "-" "Mozilla/5.0 (compatible; Let's Encrypt validation server; +https://www.letsencrypt.org)"
2600:3000:1511:200::1d - - [14/Nov/2018:13:25:12 +0900] "GET /.well-known/acme-challenge/m2OoOOj_068FX5ADOuceiFmP-XMywS9Mf5_tCSq52dU HTTP/1.1" 200 87 "-" "Mozilla/5.0 (compatible; Let's Encrypt validation server; +https://www.letsencrypt.org)"
ここで、エラーになると厄介。
ひとまず
/usr/local/etc/ssl/acme
このディレクトリを一旦移動させて、再度 acme-client コマンドを叩くのが楽であるが、短期間に繰り返し実行すると、再認証制限に引っかかるので要注意。(30回/日)
丸々最初から証明書を作り直すと幸せになれます。
nginx の SSL 設定
冒頭の設定ファイル最後の一行との間に追記する事。
インデントに注意!
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name example.jp;
access_log /var/log/nginx/access_SSL_example.jp.log;
error_log /var/log/nginx/error_SSL_example.jp.log;
ssl_certificate /usr/local/etc/ssl/acme/fullchain.pem;
ssl_certificate_key /usr/local/etc/ssl/acme/private/privkey.pem;
ssl_session_timeout 5m;
ssl_session_cache shared:SSL:1m;
ssl_session_tickets on;
ssl_dhparam /etc/mail/certs/dh.param;
ssl_protocols TLSv1.2;
ssl_ciphers ECDHE:ECDSA:!RC4:!NULL:!3DES:!CBC;
ssl_prefer_server_ciphers on;
add_header Strict-Transport-Security "max-age=15768000; includeSubDomains";
ssl_stapling on;
ssl_stapling_verify on;
ssl_trusted_certificate /usr/local/etc/ssl/acme/fullchain.pem;
ssl_session_ticket_key /usr/local/etc/ssl/ticket.key;
location / {
root /usr/local/www/example.jp;
}
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name example.com;
access_log /var/log/nginx/access_SSL_example.com.log;
error_log /var/log/nginx/error_SSL_example.com.log;
ssl_certificate /usr/local/etc/ssl/acme/fullchain.pem;
ssl_certificate_key /usr/local/etc/ssl/acme/private/privkey.pem;
ssl_session_timeout 5m;
ssl_session_cache shared:SSL:1m;
ssl_session_tickets on;
ssl_dhparam /etc/mail/certs/dh.param;
ssl_protocols TLSv1.2;
ssl_ciphers ECDHE:ECDSA:!RC4:!NULL:!3DES:!CBC;
ssl_prefer_server_ciphers on;
add_header Strict-Transport-Security "max-age=15768000; includeSubDomains";
ssl_stapling on;
ssl_stapling_verify on;
ssl_trusted_certificate /usr/local/etc/ssl/acme/fullchain.pem;
ssl_session_ticket_key /usr/local/etc/ssl/ticket.key;
location / {
root /usr/local/www/example.com;
}
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name example.org;
access_log /var/log/nginx/access_SSL_example.org.log;
error_log /var/log/nginx/error_SSL_example.org.log;
ssl_certificate /usr/local/etc/ssl/acme/fullchain.pem;
ssl_certificate_key /usr/local/etc/ssl/acme/private/privkey.pem;
ssl_session_timeout 5m;
ssl_session_cache shared:SSL:1m;
ssl_session_tickets on;
ssl_dhparam /etc/mail/certs/dh.param;
ssl_protocols TLSv1.2;
ssl_ciphers ECDHE:ECDSA:!RC4:!NULL:!3DES:!CBC;
ssl_prefer_server_ciphers on;
add_header Strict-Transport-Security "max-age=15768000; includeSubDomains";
ssl_stapling on;
ssl_stapling_verify on;
ssl_trusted_certificate /usr/local/etc/ssl/acme/fullchain.pem;
ssl_session_ticket_key /usr/local/etc/ssl/ticket.key;
location / {
root /usr/local/www/example.org;
}
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name xn--w22as22a.example.jp;
access_log /var/log/nginx/access_SSL_xn--w22as22a.example.jp.log;
error_log /var/log/nginx/error_SSL_xn--w22as22a.example.jp.log;
ssl_certificate /usr/local/etc/ssl/acme/fullchain.pem;
ssl_certificate_key /usr/local/etc/ssl/acme/private/privkey.pem;
ssl_session_timeout 5m;
ssl_session_cache shared:SSL:1m;
ssl_session_tickets on;
ssl_dhparam /etc/mail/certs/dh.param;
ssl_protocols TLSv1.2;
ssl_ciphers ECDHE:ECDSA:!RC4:!NULL:!3DES:!CBC;
ssl_prefer_server_ciphers on;
add_header Strict-Transport-Security "max-age=15768000; includeSubDomains";
ssl_stapling on;
ssl_stapling_verify on;
ssl_trusted_certificate /usr/local/etc/ssl/acme/fullchain.pem;
ssl_session_ticket_key /usr/local/etc/ssl/ticket.key;
location / {
root /usr/local/www/xn--w22as22a.example.jp;
}
}
/etc/mail/certs/dh.param ファイルの作成
nginx の SSL 対応設定ファイルの中で ssl_dhparam で必要とされるファイルを作成しておく
openssl dhparam 3072 -out /etc/mail/certs/dh.param
<ぼそ>ディレクトリの配置場所は /usr/local/etc/ssl 辺りが好ましい</ぼそ>
nginx 設定ファイル再読み込み
nginx -k reload
おしまい😄