Let's EncryptでSSL証明書の新規作成と自動更新(http-01編)

対象環境

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

  SSLCertificateFile      /usr/local/etc/dehydrated/certs/コモンネーム/cert.pem
  SSLCertificateChainFile /usr/local/etc/dehydrated/certs/コモンネーム/chain.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 CONTACT_EMAIL="メールアドレス"
   7 #テスト発行したい場合、以下の2行を有効にすること。
   8 #CA="https://acme-staging.api.letsencrypt.org/directory"
   9 #CA_TERMS="https://acme-staging.api.letsencrypt.org/terms"
  10 

コモンネームファイル

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

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

dehydrated --register --accept-terms
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. 目標が違うのでどっちとも言えない。 certbot は Let' Encrypt 推奨ACMEクライアントで、 証明書の失効(revoke)までできるので、 フルスペックの機能使うなら…というところでしょうね。

ACMEクライアントは、certbot、dehydrated だけでなく、他にもあるので、チェックしてみるといいかもしれない。

あと、certbot はWebサーバー内蔵で http(TCP ポート 80)開いてるかぎり使える点がうれしいかも。 ただ、既にWebサーバーが稼働済みの場合、certbot よりも、Webサーバーを内蔵してない dehydrated の方が都合がよい。

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 を実施すること。

Q. Webサービス立ち上げてないサーバーでSSL証明書使いたいです!

A. そんなあなたにDNS認証(dns-01)。続きはWebで。

【付録】 dehydrated v0.40 での変更

v0.40 で、ライセンス受諾の確認が必須になりました。 それまでは暗黙の受諾として、dehydrated が勝手に受諾していましたが、 別途手動で、dehydrated --register --accept-terms を実行する必要があります。

ステージング用のライセンス受諾ともまた別の話となりますので、 CA だけでなく、CA_TERMS も合わせて設定する必要があります。

この振る舞いは /usr/local/etc/dehydrated/accounts/ハッシュキー/account_key.pem の有り無しがトリガーとなりますので、 既にこのファイルがある環境では影響有りません。

初回実行に手動で実行していれば気がつくレベルとなります(エラーメッセージ等「読まない」人についてはノーコメント)。

【付録】 letsencrypt.sh から dehydrated への移行

商標上の理由で、letsencrypt.sh から dehydrated へ名前変更が実施された。 合わせてディレクトリから設定まで色々変更になったので対応についてメモっておく。

ディレクトリ名の変更

/usr/local/etc/letsencrypt.sh から /usr/local/etc/dehydrated へ変更になったわけであるが、更新後は新しいディレクトリが作成されていることもあり、こまめに手を入れる必要がある。

/usr/local/etc/letsencrypt.sh/config.sh

mv /usr/local/etc/letsencrypt.sh/config.sh /usr/local/etc/dehydrated/config

※config.sh から config に変更になったので合わせて変更を実施する。

/usr/local/etc/letsencrypt.sh/deploy.sh

mv /usr/local/etc/letsencrypt.sh/deploy.sh /usr/local/etc/dehydrated/

/usr/local/etc/letsencrypt.sh/domains.txt

mv /usr/local/etc/letsencrypt.sh/domains.txt /usr/local/etc/dehydrated/

/usr/local/etc/letsencrypt.sh/hook.sh

mv /usr/local/etc/letsencrypt.sh/hook.sh /usr/local/etc/dehydrated/

/usr/local/etc/letsencrypt.sh/certs/

mv /usr/local/etc/letsencrypt.sh/certs /usr/local/etc/dehydrated/

/usr/local/etc/letsencrypt.sh/archive/

mv /usr/local/etc/letsencrypt.sh/archive /usr/local/etc/dehydrated/

後始末

rmdir /usr/local/etc/letsencrypt.sh

※全ての移動が完了すれば、ディレクトリもファイルも残ってないはずなので削除する。

設定ファイルの変更

リネームによる影響で変更になるファイルは以下の3ファイルである。 ディレクトリ名およびコマンド名に letsencrypt.sh というキーワードが無いか確認し、dehydrated に置き換えること。

SSL証明書利用アプリケーションの設定変更

本例では Apache(2.4)を例に説明した。 当該箇所のディレクトリ名変更を新しいディレクトリ名に変更する。

SSL証明書の旧指定例

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

トークンディレクトリの旧指定例

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

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

起動設定(periodic)の変更

/etc/periodic.conf あるいは /etc/periodic.conf.local のどちらかの設定で定期更新を実施しているわけだが、変数名が変更になっている。

本例では以下のような設定を実施しているが、

weekly_letsencrypt_enable="YES"
weekly_letsencrypt_deployscript="/usr/local/etc/letsencrypt.sh/deploy.sh"

下記のように変更する。

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

単純に letsencrypt や letsencrypt.sh を dehydrated に置き換えるだけである。

参考文献