Let's Encrypt(以下LE)は、無料でDomain Validation(以下DV)証明書を発行してくれる機関である。 このLEは、申請から証明書発行までを人手を介さずシステムだけで処理してくれる、自動化に非常に向いている仕組みを提供している。
以前、Let's Encryptを少し調べてみたで調査した内容をまとめる。
LEは、Internet Security Research Group (ISRG) が運営する、無料で利用でき、自動化されていて、オープンな認証局。
Let's Encryptの基本方針は
(以上、About - Let's Encrypt - Free SSL/TLS Certificatesより抜粋)
実際に利用するレベルから見ると、
というサービスを提供してくれるサイト及びサービスである。
日本語訳のサイト: Let's Encrypt 総合ポータル
つまり、あくまで、「あるドメイン」が、「申請されたタイミング」で、「管理されているであろう」かつ「存在している」ことのみを証明するものである。 逆に、「仮に乗っ取られていたとしても申請を受けたLE側では判断しない」(管理組織が正当であるかどうかはドメインが存在しているかどうかとは独立の問題なので)ものである。
Let's EncryptはDV証明書を発行するにあたって、ACME(Automatic Certificate Management Environment)を使用する。 このACMEは2017/03/13に、draft-ietf-acme-acme-06として更新されており、将来RFCになることが期待されている。
このACMEを利用した証明書取得のためのツールは様々ある。LEで把握しているACMEの実装に関しては、https://letsencrypt.org/docs/client-options/を参照すること。
acme-clientのManual Pageから抄訳
証明書取得の流れは以下の通り。
証明書失効の流れも同様。
ACMEにおけるChallengeとは、要するに「存在確認」を意味する。この存在確認方法として以下の3つがIDに定義されている。
FreeBSD 11.0 RELEASE-p10 を利用している場合、LEを利用するにはportsに収録されているacme関連のツールを利用するのが一番簡単である。 おそらく、通常最も単純なのは、security/py-certbot を利用することだと考えられるが、今回は以下の理由により別ツールを利用する。
というわけで、代替ツールを利用するが、今回はacme-clientを利用する。 acme-clientはOpenBSDプロジェクトで利用されているacme clientアプリである。
| |
+-- nginx LB1 --+-- Web1a
internet -- Router --+ |
| +-- nginx LB2 --+-- Web1b
| | |
| | |
+----------+-- Work ---+
| |
http://example.comとする)のWeb Server(実態はLB1/LB2)にChallenge Requestを送付http://example.com/.well-known/acme-challenge 宛のRequestをWorkに転送するように設定するhttp://example.com/.well-known/acme-challenge 宛の要求を処理できるようにするacme-clientは、
である。
ここでは、
${CERTDir}${CERTkey}${PRIVKEY}${CHALLENGE}とする。
acme-client -bnNv -k ${CERTkey} -f ${PRIVKEY} -C ${CHALLENGE} -c ${CERTDir} 申請するURL
を実行すると、必要な証明書等を作成し、秘密鍵、公開鍵を取得してくれる。
オプションの意味
....(snip)
upstream HTTP_WWW {
server 198.51.100.11;
server 198.51.100.12;
}
upstream HTTP_ACME {
server 192.0.2.101;
}
server {
listen 203.0.113.11;
server_name www.example.com;
location ^~ /.well-known/acme-challenge/ {
proxy_pass http://HTTP_ACME;
}
location / {
proxy_pass http://HTTP_WWW;
}
}
....(snip)
server {
listen 192.0.2.101:80;
server_name www.example.com;
rewrite /.well-known/acme-challenge/(.*) /$1 last;
location / {
root ${CHALLENGE}; # 実際のChallengeディレクトリを記載してください。
index index.html;
}
}
これで、手元のブラウザから、http://www.example.com/.well-known/acme-challenge/index.html にアクセスして、index.htmlが見えればOK
マルチドメインに対応するために、acmeを一気に処理してくれるscriptを書いたので、参考にどうぞ。 詳しいことは、自力でこのshell scriptを読んでください。
# cat crt-update.sh
#! /bin/sh
# Let's Encrypt Certificate renewal script for FreeBSD and acme-client
# Copyright (C) by seirios@seirios.org
#
# Usage: crt-upd.sh [target domains...]
###############################################################################
: ${DEBUG:=0}
: ${FORCE:=0}
ACME_BASE=/home/seirios/htdocs/acme
OPTS="-bnN"
DOPTS=""; [ ${DEBUG} -ne 0 ] && DOPTS="-v"
FOPTS=""; [ ${FORCE} -ne 0 ] && FOPTS="-F"
ACCKEY=${ACME_BASE}/SSL/privkey.pem
SSL=${ACME_BASE}/SSL
CHALLENGE=${ACME_BASE}/WWW
DOMAINSFILE=${ACME_BASE}/domains.txt
UID=`id -u`
[ ${UID} -ne 0 ] && echo "Must run on root/UID=0" && exit
if [ ${DEBUG} -ne 0 ]; then
ECHO="/bin/echo"
else
ECHO=""
fi
if [ ${#} -eq 0 ]; then
DOMAINS=`cat "${DOMAINSFILE}" | sed 's/[#|].*$//' | while read DOMAIN line ; do
echo -n "${DOMAIN} "
done`
else
DOMAINS=${@}
fi
[ ${DEBUG} -ne 0 ] && /bin/echo "Target domain: ${DOMAINS}"
for i in ${DOMAINS}; do
echo "Getting ${i} Certificates"
DOMKEY=/home/seirios/htdocs/acme/SSL/$i/privkey.pem
[ ! -d ${SSL}/${i} ] && ${ECHO} mkdir ${SSL}/${i}
[ ! -d ${CHALLENGE}/${i} ] && ${ECHO} mkdir ${CHALLENGE}/${i}
${ECHO} acme-client ${OPTS} ${DOPTS} ${FOPTS} -k ${DOMKEY} -f ${ACCKEY} -C ${CHALLENGE}/${i} -c ${SSL}/${i} ${i}
case $? in
0) echo "${i} is updated" ;;
1) echo "${i} is troubled" ;;
2) echo "${i} is not need to update" ;;
esac
done
###############################################################################
#
# Settings.
# Requirement: FreeBSD and acme-client
#
# ToDo
# - Change DEBUG/FORCE controll from environment variable to command
# line options.
#
# Version History
#
# ver: 0.1 Initial revision.
# 0.2 Add DEBUG initializer and FORCE initializer.
# Display acme-client status.
# ex. DEBUG=1 FORCE=1 crt-upd.sh
#
注意
# ACME domain configuration file. # format: domain|server:dir server:dir ... www.example.com|198.51.100.11:/some/where/Certs 198.51.100.12:/some/where/Certs www.example.net|198.51.100.11:/some/where/Certs 198.51.100.12:/some/where/Certs
これで、/some/where/SSL/www.example.(com|net)にcert.pem,chain.pem,fullchain.pem,privkey.pemが作成されるので、必要に応じてファイルをrenameして転送すれば良い。