無料SSL証明書のLet’s Encryptを使ってみる

WebサイトのSSL化事情

一般的にSSL化したWebサイトを立てる時には二つのハードルがあります。一つは、本来SSL化できるサイトはひとつのIPアドレスでひとつだけ(IPベースのSSL)ということ。もう一つは、正式なSSL証明書を入手するにはある程度のコストが毎年かかるということです。一つ目のハードルは、SNIという手法が開発されて、ひとつのIPアドレスでも複数のSSLサイトを運用できるようになりました。しかし、これはブラウザ側の対応も同時に必要なのでそれが普及するまでしばらく時間が必要でした。二つ目は、有料でも比較的安いSSL証明書が提供されるようになってきています。それを利用すれば年間1,000円程度で済みますし、元々IPベースのSSLでの運用だと使えるホスト(ドメイン名)の数も必然的に限られていたこともあり、コスト的にも許せる程度で収まっていました。

そこへ、最近の「全てのWebサイトのSSL化が望ましい」という流れです。バーチャルドメインで複数のドメイン名サイトを複数のFQDNで運用しているのを全てSSL化するのは有料だとさすがにキツイので困っていたところに出てきたのがLet’s Encryptという無料SSL証明書です。また、SNIが実装されたブラウザが普及してきた(というよりは非対応のブラウザとそのプラットホームが淘汰されてきた)というのもあって、ようやく重い腰を上げたという訳です。

certbotのインストール

Let’s Encryptはcertbotというサーバー上で実行されるアプリを使い、自動的にSSL証明書のセット(秘密鍵,公開鍵,中間証明書)をサーバー上に作成します。まずはそのcertbotのインストールから始めます。FreeBSDではportsかpackageで用意されてます。私はports派なのでportsを使いました。

# cd /usr/ports/security/py-certbot
# make install

インストールできたらオプション無しでcertbotを起動させてこんな感じのメッセージが出ればまずはOKです。

# certbot
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Certbot doesn't know how to automatically configure the web server on this system. However, it can still get a certificate for you. Please run "certbot certonly" to do so. You'll need to manually configure your web server to use the resulting certificate.

certbotを使う

さっそくertbotを使って証明書を作成してみます。certbotは二つのモードがあって、certbot自身の持っているWebサーバー機能を使ってサイト証明(FQDNで名前解決されるIPアドレスからの要求かどうか)を行う standalone モードと、稼働中のWebサーバーを使ってサイト証明を行う webroot モードの二種類の方法があります。standaloneモードでは80番ポートか443番ポートを使うので、他にWebサーバーが稼働している場合は(大抵の場合は動いてますよね)止める必要があります。 webroot モードは稼働中のWebサーバーをそのまま使い、そのドキュメントルートに一時ファイルを置いてホスト認証を行います。従って、このモードを使う場合にはドキュメントルートを -w オプションで指定してやる必要があります。共通のオプションとして、-d オプションで証明書を生成するFQDNを指定します。また、-m オプションでメールアドレスを指定します。これは証明書の期限切れの前にそれの通知を受け取るために必要です。最初に一度だけ指定すれば良いみたいです。
具体的にはこんな感じで実行されます。ここではstandaloneモードを使っていますので、前後でapacheを停止&起動させています。

# apachectl stop
Stopping apache24.
Waiting for PIDS: 63093.
# certbot certonly --standalone -m [メールアドレス] -d www.example.com
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator standalone, Installer None

-------------------------------------------------------------------------------
Please read the Terms of Service at
https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf. You must
agree in order to register with the ACME server at
https://acme-v01.api.letsencrypt.org/directory
-------------------------------------------------------------------------------
(A)gree/(C)ancel: A ←ここは使用条件に同意の「A」

-------------------------------------------------------------------------------
Would you be willing to share your email address with the Electronic Frontier
Foundation, a founding partner of the Let's Encrypt project and the non-profit
organization that develops Certbot? We'd like to send you email about EFF and
our work to encrypt the web, protect its users and defend digital rights.
-------------------------------------------------------------------------------
(Y)es/(N)o: N ←ここはEFFからメールを受け取るかどうか。受け取らないなら「N」
Obtaining a new certificate
Performing the following challenges:
http-01 challenge for www.example.com
Waiting for verification...
Cleaning up challenges

IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at:
   /usr/local/etc/letsencrypt/live/www.example.com/fullchain.pem
   Your key file has been saved at:
   /usr/local/etc/letsencrypt/live/www.example.com/privkey.pem
   Your cert will expire on 2018-xx-xx. To obtain a new or tweaked
   version of this certificate in the future, simply run certbot
   again. To non-interactively renew *all* of your certificates, run
   "certbot 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

# apachectl start
Performing sanity check on apache24 configuration:
Syntax OK
Starting apache24.
#

「(A)gree/(C)ancel:」と「(Y)es/(N)o:」は最初に一度だけ回答すれば以降は聞いてきません。
最後の「IMPORTANT NOTES:」の所を見ると、生成された証明書の場所と有効期限が書いてあります。
実際にその場所を見てみるとこんな感じになります。

# ll /usr/local/etc/letsencrypt
total 1
drwx------  4 root  wheel  4 May 18 14:59 accounts/
drwx------  5 root  wheel  5 May 18 15:07 archive/
drwxr-xr-x  2 root  wheel  5 May 18 15:07 csr/
drwx------  2 root  wheel  5 May 18 15:07 keys/
drwx------  5 root  wheel  5 May 18 15:07 live/
drwxr-xr-x  2 root  wheel  5 May 18 15:07 renewal/
drwxr-xr-x  5 root  wheel  5 May 18 14:57 renewal-hooks/
# ll /usr/local/etc/letsencrypt/live
total 1
drwxr-xr-x  2 root  wheel  7 May 18 14:59 www.example.com/
# ll /usr/local/etc/letsencrypt/live/www.example.com
total 1
lrwxr-xr-x  1 root  wheel   36  5月 17 22:37 cert.pem@ -> ../../archive/www.example.com/cert1.pem
lrwxr-xr-x  1 root  wheel   37  5月 17 22:37 chain.pem@ -> ../../archive/www.example.com/chain1.pem
lrwxr-xr-x  1 root  wheel   41  5月 17 22:37 fullchain.pem@ -> ../../archive/www.example.com/fullchain1.pem
lrwxr-xr-x  1 root  wheel   39  5月 17 22:37 privkey.pem@ -> ../../archive/www.example.com/privkey1.pem
-rw-r--r--  1 root  wheel  682  5月 17 22:37 README
#

証明書の場所は /usr/local/etc/letsencrypt/live/www.example.com で、そこにはシンボリックリンクが張られていて、実体は /usr/local/etc/letsencrypt/archive/www.example.com の方に連番付きで生成されています。証明書の更新などでアップデートがあると、このシンボリックリンクが変更されることでWebサーバー側の設定ファイルを変更しなくて済むようになっています。

Webサーバーを稼働させたままで証明書を取得する場合はこんな感じになります。

# certbot certonly --webroot -m [メールアドレス] -w [ドキュメントルート] -d www.example.com

同一ドメイン名の複数サイトをひとつの証明書にまとめて取得する場合は –expand オプションを付加し、FQDN毎に-d オプションを付けて列挙します。

# certbot certonly --webroot -m [メールアドレス] -w [ドキュメントルート] -d www.example.com -d mail.example.com -d ftp.example.com --expand

ここで注意すべきは証明書の発行数や頻度について制限があるということです。どういう制限かというと、

  • 週当たり20ドメイン名まで
  • ひとつの証明書に100ホスト(サブドメイン)まで
  • 週当たり証明書再発行は5回まで

などなど。ドメイン名やホストの数が多い場合はよく考えないと長いこと待つ羽目になります。–dry-run オプションを使って実行する前に確認するのもいいでしょう。

証明書の有効期限と更新方法

証明書の有効期限は、従来の有料の証明書の場合は最低でも1年以上なのが普通ですが、Let’s Encryptの証明書の有効期限は90日間と結構短期間です。
有効期限が近付いたら -m オプションで指定したメールアドレス宛にメールが届くそうですが、私の場合はまだ期限が来てないのでどうなるかはまだ分りません。
証明書の更新は、

# certbot renew

でできます。standaloneモードで取得した証明書の場合はstandaloneモードで実行されるので、実行する前にWebサーバーを止めて終わったら再起動する必要があります。それには、

# certbot renew --pre-hook "service apache24 stop" --post-hook "service apache24 start"

こういう風にすればOKです。あとは更新を忘れないようにcronで証明書発行頻度の制限など考慮して1週間に一度くらいの頻度で実行するようにすれば良いでしょう。

実際に実行してみるとこんな感じです。まだ期限が来ていないので何も起こっていません。

# certbot renew --pre-hook "service apache24 stop" --post-hook "service apache24 start"
Saving debug log to /var/log/letsencrypt/letsencrypt.log

-------------------------------------------------------------------------------
Processing /usr/local/etc/letsencrypt/renewal/example.com.conf
-------------------------------------------------------------------------------
Cert not yet due for renewal

-------------------------------------------------------------------------------

The following certs are not due for renewal yet:
  /usr/local/etc/letsencrypt/live/example.com/fullchain.pem expires on 2018-08-22 (skipped)
No renewals were attempted.
No hooks were run.
-------------------------------------------------------------------------------
#

最後に

昔から、このSSL証明書というものは個人にとってコストがかかるという意味では結構ハードルの高い技術でした。WebサイトのSSL化やメールのSSL/TLSでの使用に使う証明書を自分自身が認証局になって「オレオレ証明書」を作成し、アクセスの度に「証明書がー!」と言われたり、「証明書のインストール」をしなければいけなかったり、運用面で非常に面倒でしたし、「本当にセキュア」という意味では極めて怪しい状態での運用と言わざるを得ませんでした。今回取り上げたLet’s Encryptのような無料でSSL証明書を取得できる仕組みが提供されているということは、こういった「オレオレ証明書」を使うことなく気軽にSSL化することができるので、非常に有難いことです。ここに感謝の意を表したいと思います。

参考リンク

Let’s Encrypt ユーザーガイド
Let’s Encrypt の使い方
コマンド解説(コマンドリファレンス)
Rate Limits

コメントする

メールアドレスが公開されることはありません。 が付いている欄は必須項目です