Let's Encrypt サーバー証明書の取得と自動更新設定メモ

Linux
Linux
スポンサーリンク

Let's Encrypt は、自分が所有しているドメインのSSL/TLSサーバー証明書を、無料で発行してくれる認証局(CA)です。この認証局は、Mozilla、アカマイ、シスコなどが参加するISRGというカリフォルニア州の公益法人が運営しています。

Let's Encrypt は、証明書にまつわる作業の「自動化」を目指しているため、わずか1行のコマンドを実行するだけで、証明書が取得できます。ただ、一般的な証明書取得の手続きと概念が大きく異なるため、正直少し戸惑いました。そこで今回は、Let's Encrypt でSSL/TLSサーバー証明書を取得する手順と、自動更新の設定方法をまとめてみました。

(更新)2017年11月4日 「certbot」のインストール手順を更新しました。

(追記)2016年5月12日 Let's Encrypt クライアントソフトが「certbot」に変更されました。
https://www.eff.org/deeplinks/2016/05/announcing-certbot-new-tls-robot

(追記)2016年4月12日 Let's Encrypt がベータ版から正式版になりました。
https://letsencrypt.org/2016/04/12/leaving-beta-new-sponsors.html

Let's Encrypt の証明書はドメイン認証型(DV)

SSL/TLSサーバー証明書には、以下の3つの種類があり、Let's Encrypt が発行するのは、ドメイン認証型(DV)の証明書になります。

ドメイン認証型(DV)ドメインの所有権を認証
実在証明型(OV)組織の存在を認証
EVタイプ(EV)OVよりも厳密な審査を経て認証

用途にもよりますが、通信の暗号化を目的とするのであれば、ドメイン認証型で十分です。例えば HTTP/2 でWEBサーバを動かすには、事実上SSL/TLSが必須になりますので、そういった用途でも普及しそうですね。

Let's Encrypt の証明書取得方法

Let's Encrypt クライアントソフト(コマンド)をインストールして、証明書取得用のコマンドを打つだけです。

冒頭にも書きましたが、Let's Encrypt での証明書取得の手続きは、他の認証局のものと大きく異なります。Let's Encrypt のサイトに行って「CSRを送信する申請フォームはどこだろう?」と探したのは、私だけではないはずです(^^;)

参考までに、一般的なドメイン認証型の証明書発行の流れは、以下の通りです。

      (1) 秘密鍵を作成
      (2) 秘密鍵を元に、CSR(証明書を発行するための署名要求)を生成
      (3) 認証局へCSRを送信
      (4) 認証局からドメイン所有者へ確認メールが届くので承認する
      (5) 認証局から証明書がメールなどで届く

Let's Encrypt では、これらすべての作業を、専用のクライアントソフトがやってくれます。

証明書取得の前に必要な準備

ドメインを所有していることと、そのドメインに対応するIPアドレスを持つサーバが、インターネットに公開され、Let's Encrypt のサーバから、HTTPまたはHTTPS接続できることが必要です。

要するに、所有しているドメインで、WEBサイトが公開されていれば、それだけで準備OKです。クローズドな環境では証明証の取得時のみ、ポートを開けるといった工夫が必要になります。

下図の例では、example.com ドメインを所有しているとして「192.0.2.1」のサーバに、Let's Encrypt クライアントソフトをインストールして、証明書を取得することになります。
LetsEncryptで証明書を取得する仕組み

Let's Encrypt クライアント「certbot」のインストール

こちらの手順でインストールした CentOS7.4+Apahce2.4のサーバにインストールしました。

まずはじめに EPELリポジトリをインストールします。

yum -y install epel-release

yum から EPELリポジトリを追加できない場合は、以下で追加することができます。

rpm -ivh http://dl.fedoraproject.org/pub/epel/7/x86_64/Packages/e/epel-release-7-11.noarch.rpm
rpm --import http://dl.fedoraproject.org/pub/epel/RPM-GPG-KEY-EPEL-7

Let's Encrypt クライアント「certbot」をインストールします、

yum install certbot

「certbot」は python で作られているため、python 関連のライブラリなどがインストールもしくはアップデートされます。問題がなければ「y」を入力してインストールします。

=======================================================================================================================================================================
 Package                                         Arch                            Version                                        Repository                        Size
=======================================================================================================================================================================
Installing:
 certbot                                         noarch                          0.19.0-1.el7                                   epel                              20 k
Installing for dependencies:
 dialog                                          x86_64                          1.2-4.20130523.el7                             base                             208 k
 pyOpenSSL                                       x86_64                          0.13.1-3.el7                                   base                             133 k
 python-cffi                                     x86_64                          1.6.0-5.el7                                    base                             218 k
 python-enum34                                   noarch                          1.0.4-1.el7                                    base                              52 k
 python-idna                                     noarch                          2.4-1.el7                                      base                              94 k
 python-ipaddress                                noarch                          1.0.16-2.el7                                   base                              34 k
 python-ndg_httpsclient                          noarch                          0.3.2-1.el7                                    epel                              43 k
 python-parsedatetime                            noarch                          1.5-3.el7                                      epel                              61 k
 python-ply                                      noarch                          3.4-11.el7                                     base                             123 k
 python-pycparser                                noarch                          2.14-1.el7                                     base                             104 k
 python-zope-component                           noarch                          1:4.1.0-3.el7                                  epel                             227 k
 python-zope-event                               noarch                          4.0.3-2.el7                                    epel                              79 k
 python-zope-interface                           x86_64                          4.0.5-4.el7                                    base                             138 k
 python2-acme                                    noarch                          0.19.0-1.el7                                   epel                             176 k
 python2-certbot                                 noarch                          0.19.0-1.el7                                   epel                             471 k
 python2-configargparse                          noarch                          0.11.0-1.el7                                   epel                              30 k
 python2-cryptography                            x86_64                          1.7.2-1.el7_4.1                                updates                          502 k
 python2-dialog                                  noarch                          3.3.0-6.el7                                    epel                              94 k
 python2-future                                  noarch                          0.16.0-2.el7                                   epel                             799 k
 python2-mock                                    noarch                          1.0.1-9.el7                                    epel                              92 k
 python2-psutil                                  x86_64                          2.2.1-2.el7                                    epel                             116 k
 python2-pyrfc3339                               noarch                          1.0-2.el7                                      epel                              13 k
 pytz                                            noarch                          2016.10-2.el7                                  base                              46 k

Transaction Summary
=======================================================================================================================================================================
Install  1 Package (+23 Dependent packages)

Total download size: 3.8 M
Installed size: 18 M
Is this ok [y/d/N]: y ←入力してエンター
 

 
certbotコマンドの引数に「--help all」を付けると、詳細なヘルプを表示できます。英語ですが、比較的分かりやすく書かれています。(^^)

certbot --help all

証明書取得コマンド

環境によってオプションが異なってくると思いますが、公開WEBサイトの証明書を取得する場合は、下記のようになります。( root権限で実行する必要があります)

certbot certonly --webroot \
-w /var/www/example \
-d example.com \
-m sample@example.com \
--agree-tos -n

オプションについて

certonly
 証明書の取得のみを行います。デフォルト値は「run」で、証明書の取得とApache等のSSL設定もやってくれるそうですが、まだうまく動かないことが多いようです。

--webroot
 ApacheなどWEBサーバのドキュメントルートに、認証用ファイルを生成します。ドキュメントルート直下に「.well-known/」というディレクトリが作成され、この中に生成されているようです。証明書の取得が終われば、この認証用ファイルは削除されます。稼働しているWEBサーバがない場合(メールサーバなど)は --standalone を指定すると良いでしょう。

-w
 ドキュメントルートのパスを指定します。Apacheの場合は、DocumentRoot で指定しているパスです。

-d
 証明書を取得するドメイン名を指定します。Apacheの場合は、ServerName で指定しているドメイン名です。

-m
 ご自分のメールアドレスを指定します。なにかトラブルがあった場合などに Let's Encrypt との連絡用に使用されます。また、証明書の更新期限が近づくと、ここで指定したメールアドレス宛に、お知らせメールが届きます。

--agree-tos
 Let's Encrypt の利用規約に同意します。事前に利用規約「https://letsencrypt.org/repository/」を確認しておきましょう。

-n
 --non-interactive の省略オプションです。対話メッセージの表示や入力を求められないようにできます。
 

ドメイン名は複数指定できますので、バーチャルホストで複数のサイトを動かしている場合でも、いっぺんにそれぞれのサイトの証明書を取得できます。その場合は、ドキュメントルートとドメイン名が、対になるように指定します。

certbot certonly --webroot \
-w /var/www/example -d example.com -d www.example.com \
-w /var/www/thing -d thing.is -d m.thing.is \
-m sample@example.com \
--agree-tos -n

また、HTTPやHTTPSの待ち受けポートを変更している場合は、以下のオプションでポート番号を指定します。

HTTPのポート番号指定

--http-01-port 8080

HTTPSのポート番号指定

--tls-sni-01-port 4443

証明書が保存される場所

証明書取得コマンドを実行して、以下のような表示がされれば取得成功です。

IMPORTANT NOTES:
- Congratulations! Your certificate and chain have been saved at
/etc/letsencrypt/live/blog.apar.jp/fullchain.pem. Your cert will
expire on 2016-03-11. To obtain a new version of the certificate in
the future, simply run Let's Encrypt again.
- If like Let's Encrypt, please consider supporting our work by:

証明書や秘密鍵は「/etc/letsencrypt/archive/」以下に保存され、下記の場所にシンボリックリンクが作成されます。証明書を更新するたびに、 シンボリックリンクのリンク先を、新しい証明書に変更してくれます。

証明書
/etc/letsencrypt/live/<ドメイン名>/cert.pem

証明書+中間CA証明書
/etc/letsencrypt/live/<ドメイン名>/fullchain.pem

秘密鍵
/etc/letsencrypt/live/<ドメイン名>/privkey.pem

中間CA証明書
/etc/letsencrypt/live/<ドメイン名>/chain.pem

WEBサーバの設定

Apacheのバージョンが2.4.8以下の場合は「証明書」「秘密鍵」「中間CA証明書」を設定します。以下はApache2.4.6での設定サンプルです。バージョンが2.4.8以上の場合や、WEBサーバがNginxの場合は「証明書+中間CA証明書」と「秘密鍵」使います。

<VirtualHost *:443>
   ServerName example.com
   DocumentRoot "/var/www/example"

   SSLEngine on
   SSLHonorCipherOrder on
   Header set Strict-Transport-Security "max-age=31536000; includeSubDomains"
   SSLProtocol -All +TLSv1 +TLSv1.1 +TLSv1.2
   SSLCipherSuite HIGH:MEDIUM:!aNULL:!MD5

   SSLCertificateFile /etc/letsencrypt/live/example.com/cert.pem
   SSLCertificateKeyFile /etc/letsencrypt/live/example.com/privkey.pem
   SSLCertificateChainFile /etc/letsencrypt/live/example.com/chain.pem
   
    <Directory "/var/www/example">
        Options FollowSymLinks
        AllowOverride None
        Require all granted
    </Directory>

    SetEnvIf Request_URI "\.(gif|jpg|png|css|js)$" nolog
    ErrorLog logs/error_log
    CustomLog logs/access_log combined env=!nolog
</VirtualHost>

設定が終わりましたら、設定を再読込します。

systemctl reload httpd

以上でブラウザから、認証局が Let's Encrypt になっていることを確認できると思います。
ブラウザでLetsEncryptが発行した証明書を確認

証明書の自動更新設定

Let's Encrypt の証明書の有効期限は、90日間と比較的短いため、定期的に更新する必要があります。これは自動更新を前提としているためのようです。自動更新の方法は「certbot renew」コマンドを実行するだけです。証明書の有効期限をチェックして、期限が近づいていれば更新してくれます。

また、指定した日時に証明書を更新したい場合は「--force-renewal」オプションを付けて実行します。ただ、このオプションを付けて毎日コマンドを実行してしまうと取得数制限に引っかかってしまうため、実行するのは月1回程度にしておきましょう。

If you are manually renewing all of your certificates, the --force-renewal flag may be helpful; it causes the expiration time of the certificate(s) to be ignored when considering renewal, and attempts to renew each and every installed certificate regardless of its age. (This form is not appropriate to run daily because each certificate will be renewed every day, which will quickly run into the certificate authority rate limit.)

http://letsencrypt.readthedocs.org/en/latest/using.html#renewal より引用

これらをふまえて以下を crontab に登録します。毎月1日の朝5時に証明書を自動更新しApacheをリロードします。更新日時はお好みで設定してください。
vi /etc/crontab

00 05 01 * * root /bin/certbot renew --force-renewal && /bin/systemctl reload httpd

自動更新のテストをする場合は「--dry-run」オプションが便利です。証明書は更新されずに動作のみ確認することができるので、取得数制限に引っかかることもありません。

/bin/certbot renew --force-renewal --dry-run

ドメインごとの証明書更新

「certbot renew」で全ての証明書が更新されるのですが、ドメインごとに更新できないかと「certbot renew -d example.com」と実行してみましたが、現時点(2017年11月4日)では対応していないようです。

Currently, the renew verb is only capable of renewing all installed certificates that are due to be renewed; individual domains cannot be specified with this action. If you would like to renew specific certificates, use the certonly command. The renew verb may provide other options for selecting certificates to renew in the future.

ドメインごとに証明書を更新する場合は、初回取得時と同じように「certonly」コマンドを使います。

00 05 01 * * /bin/certbot certonly --webroot -w /var/www/example -d example.com --renew-by-default && /bin/systemctl reload httpd

Let's Encrypt は DNS CAA に対応済み

DNS CAA は、自分が所有しているドメインに対して証明書を発行できる認証局を指定できる仕組みです。Let's Encrypt は CAA に対応していますので、CAAレコードで指定することもできます。もし興味がありましたら「DNS CAAレコードに Let's Encrypt 認証局を設定する」の記事をご参照ください。

終わりに

GoogleのHTTPSランキングシグナル導入、HTTP/2の標準化、そしてこの Let's Encrypt によるSSL/TLSサーバー証明書の無料化と、ますますWEBのHTTPS化が進みそうですね。

コメント

  1. 菊月プロジェクトWebサイトにHSTSを導入しました | 菊月保存会 より:

    […] 1) Let’s Encryptを利用したサーバ証明書の取得と自動更新の設定を行います。 2) HSTS Preload Submissionします。 […]

  2. […] [1] Let’s Encrypt サーバー証明書の取得と自動更新設定メモ […]

  3. […] Let’s Encrypt サーバー証明書の取得と自動更新設定メモ […]

  4. GitLab | フリーランスSEの仕事中に得た知識を体系化 より:

    […] そのときに中々良さそうな認証局をみつけたのでメモ。 […]

  5. […] https://blog.apar.jp/linux/3619 […]

  6. 【メモ】Let’s Encrypt – りばーす.swift より:

    […] 参考: Let’s Encrypt サーバー証明書の取得と自動更新設定メモ […]

  7. SSLの導入 - TechNote より:

    […] 参考:Let's Encrypt サーバー証明書の取得と自動更新設定メモ […]

  8. HTTP2を導入してみた より:

    […] Let’s Encrypt サーバー証明書の取得と自動更新設定メモ | あぱーブログLet's Encrypt は、自分が所有しているドメインのSSL/TLSサーバー証明書を、無料で発行してくれる認証局(CA)です。この認証局は、Mozilla、アカマイ、シスコなどが参加するISRGというカリフォルニア州の公益法人が運営しています。 Let's Encrypt は、証明書にまつわる作業の「自動化」を目…blog.apar.jp […]

  9. SSL非対応のサイトには警告マークが出るようになった。 | ギジン株式会社 より:

    […] あぱーブログ […]

  10. SSL非対応のサイトに警告マークが出るようになった。 | ギジン株式会社 より:

    […] あぱーブログ […]

  11. CentOS でサーバを設定するときの色々 – ぶろろぐ より:

    […] Let’s Encrypt サーバー証明書の取得と自動更新設定メモ | あぱーブログ […]

  12. 証明書 Let’s Encrypt より:

    […] https://blog.apar.jp/linux/3619/#Lets_Encrypt_DV […]

タイトルとURLをコピーしました