Let's EncryptでSSL証明書の新規作成と自動更新

py-certbot と dehydrated

インストール

準備

証明書の設置場所

# cd /usr/local/etc/dehydrated/certs/コモンネーム
# ls -alF
total 122
-rw-------  1 root  wheel   436 May 29 06:02 cert-1464469337.csr
-rw-------  1 root  wheel  1533 May 29 06:02 cert-1464469337.pem
lrwx------  1 root  wheel    19 May 29 06:02 cert.csr@ -> cert-1464469337.csr
lrwx------  1 root  wheel    19 May 29 06:02 cert.pem@ -> cert-1464469337.pem
-rw-------  1 root  wheel  1647 May 29 06:02 chain-1464469337.pem
lrwx------  1 root  wheel    20 May 29 06:02 chain.pem@ -> chain-1464469337.pem
-rw-------  1 root  wheel  3180 May 29 06:02 fullchain-1464469337.pem
lrwx------  1 root  wheel    24 May 29 06:02 fullchain.pem@ -> fullchain-1464469337.pem
-rw-------  1 root  wheel   302 May 29 06:02 privkey-1464469337.pem
lrwx------  1 root  wheel    22 May 29 06:02 privkey.pem@ -> privkey-1464469337.pem

  SSLCertificateFile    /usr/local/etc/dehydrated/certs/コモンネーム/fullchain.pem
  SSLCertificateKeyFile /usr/local/etc/dehydrated/certs/コモンネーム/privkey.pem

ドメイン所有者確認トークンディレクトリの指定

66.133.109.36 - - [29/May/2016:06:02:21 +0900] "GET /.well-known/acme-challenge/チャレンジトークン HTTP/1.1" 200 87 "-" "Mozilla/5.0 (compatible; Let's Encrypt validation server; +https://www.letsencrypt.org)"

Alias /.well-known/acme-challenge/ /usr/local/etc/dehydrated/.acme-challenges/

<Directory /usr/local/etc/dehydrated/.acme-challenges>
  Options       None
  AllowOverride None
  Require       all granted
  Header        add Content-Type text/plain
</Directory>

アカウントキーの保存ディレクトリの指定

設定ファイル

設定ファイル例

   1 alias openssl="/usr/bin/openssl"
   2 
   3 RENEW_DAYS="30"
   4 KEY_ALGO="prime256v1"
   5 #KEY_ALGO="rsa" KEYSIZE="2048"
   6 PRIVATE_KEY_RENEW="yes"
   7 CONTACT_EMAIL="メールアドレス"
   8 WELLKNOWN="/usr/local/etc/dehydrated/.acme-challenges"        #デフォルト設定
   9 ACCOUNT_KEY="/usr/local/etc/dehydrated/private_key.pem"       #デフォルト設定
  10 ACCOUNT_KEY_JSON="/usr/local/etc/dehydrated/private_key.json" #デフォルト設定
  11 

コモンネームファイル

example.org www.example.org
example.com www.example.com wiki.example.com

初回実行ないしは手動更新の仕方

dehydrated -c

自動更新

weekly_dehydrated_enable="YES"
weekly_dehydrated_deployscript="/usr/local/etc/dehydrated/deploy.sh"

/usr/local/etc/dehydrated/deploy.sh 例

#/bin/sh
/usr/sbin/service apache24 restart && /usr/local/bin/dehydrated -gc

よくある質問とその答え

Q. ECDSA 対応は必須?

A. 提供必須というほど、対応しているブラウザは普及してないですね。ごく最新の有名どころブラウザはともかく、四方山ブラウザを考慮するとまだまだ。 サーバー側でRSAとECDSAの両方を提案してブラウザが受け入れられる方を…という解決策も無くもないですが(使えるか知らないし興味ない)、結局RSAの鍵も作らないと行けないことには変わりないので、当面、RSA2048で行くのが正解かと。

Q. ports/security/dehydrated と ports/security/py-certbot とどっちがいいですか?

A. 目標が違うのでどっちとも言えない。 単純なサーバー構成(jail だの docker だの無し)で、そう複雑で無いSSL証明書の運用を行うなら、 python 依存が無い ports/security/dehydrated を使うのがシンプルと思われ。

【要検証】もう一つ、ports/security/dehydrated にメリットがあるとすれば、現状(py-letsencrypt は 0.5.0)では ECDSA で証明書を作成・更新するのが手間である点くらい(最新の py-certbot 0.8.1 では未検証)。

Q. 下記のように所有者確認アクセスに失敗、証明書が更新されません!

66.133.109.36 - - [29/May/2016:04:45:29 +0900] "GET /.well-known/acme-challenge/チャレンジトークン HTTP/1.1" 404 268 "-" "Mozilla/5.0 (compatible; Let's Encrypt validation server; +https://www.letsencrypt.org)"

A. Webサーバーの設定ミスの可能性があります! 自分は Alias /.well-known/acme-challenge/ /usr/local/etc/dehydrated/.acme-challenges}と最後に「/」を入れ忘れていました! このケースでは Alias の第一、第二引数ともに最後に「/」を含める必要がある。

他にも良くありそうなのが、設定した後にサーバー再起動(ないしは再読み込み)を忘れていたなどが考えられる。

あとリカバリとして、更新に失敗して残ってるCSRや秘密鍵を削除するのに dehydrated -gc を実施すること。

参考文献