読者です 読者をやめる 読者になる 読者になる

らくがきちょう

なんとなく

Let's Encrypt で無料のサーバ証明書を証明書を発行する(Certbot 編)

Linux

Let's Encrypt を使うと無料で SSL/TLS サーバ証明書を発行することが出来ます。Let's Encrypt を利用する際、以前は letsencrypt-auto というツールを使ったのですが、現在は certbot-auto というツールを使います。基本的な使い方はあまり変わらないのですが、今回は certbot-auto の使い方をメモしておきます。また、後半で証明書の自動更新についても記載しています。詳細は後述しますが、Let's Encrypt での証明書取得は単位時間辺りの枚数制限がありますので、頻繁過ぎる更新は避けるべきです。

目次

前提条件

検証は以下の環境で実施しました。

  • AWS EC2 上に作成した以下のインスタンスを利用
  • CentOS 7 (x86_64) - with Updates HVM (2016/02/26)
  • Web サーバには Apache + mod_ssl を利用
  • 作業は一般ユーザ(centos)で実施。このユーザは root へ昇格する権限を持っている(※ AMI のデフォルトで権限があるので特に設定の必要無し)

Let's Encrypt とは

Web サイトを保護する(HTTPS 化する)為には、CA 局(認証局)に費用を支払って SSL/TLS サーバ証明書を発行して貰う必要があります。しかし、Let's Encrypt という CA 局では SSL/TLS 証明書を無料で、しかも簡単に発行することが可能です。Let's Encrypt は ISRG (Internet Security Research Group) という公益団体によって運営されています。ISRG には以下のような企業が参加しています。

Let's Encrypt のページには ISRG について以下のように書かれています。

Let’s Encrypt is a free, automated, and open certificate authority brought to you by the non-profit Internet Security Research Group (ISRG).

Apache のインストール

Apache をインストールします。また、ApacheHTTPS 対応にする為に mod_ssl もインストールします。

sudo yum update -y
sudo yum install -y httpd mod_ssl
sudo systemctl start httpd.service

今回の環境では以下がインストールされました。Apache は「2.4.6-40.el7.centos.1」、mod_ssl は「1:2.4.6-40.el7.centos.1」がインストールされました。

  • Installing:
  • Installing for dependencies:
    • apr
    • apr-util
    • httpd-tools
    • mailcap

Apache の設定ファイルに ServerName の定義を追加しておきます。/etc/httpd/conf/httpd.conf に以下を追加します。

#ServerName www.example.com:80
ServerName example.com:80

Certbot のヘルプ仕様変更について

以降で Certbot をインストールします。従来は Certbot のインストール直後に Certbot の動作確認や依存パッケージのインストールに certbot-auto --help というコマンドを使っていました。これは本来、ヘルプを表示するコマンドですが、同時に root 権限へ昇格し、不足のパッケージがあればインストールする… ということをしてくる為、「Certbot インストール直後は certbot-auto --help を実行してヨロシクやってね!」という手順が一般的だったと思います。

しかし、2016/5/18 頃に --help オプションの仕様が変更され、--help オプションでは root 権限へ昇格されなくなりました。以下は仕様変更に関するページからの抜粋です。

現在は ./certbot-auto を一度も実行したことがない場合( --help オプションやその省略形の --h オプションを付けて実行した場合は除く)に、./certbot-auto --help や ./certbot-auto -h (省略形)を実行した場合には、下記のメッセージの表示のみが行われ、root権限の要求やパッケージのダウンロードや自動アップデートは行われない仕様に変更されています。

よって、今回は Certbot インストール直後に certbot-auto --help は使いません。

Certbot のインストール

Certbot は GitHub で提供されている為、git をインストールします。

sudo yum install -y git

Certbot をダウンロードしたいディレクトリに移動し、git で Certbot を取得します。今回は一般ユーザのホームディレクトリにしました。

cd ~
git clone https://github.com/certbot/certbot

Certbot を実行します。

cd ~/certbot
./certbot-auto

この際、Certbot の実行に必要なパッケージもインストールされます。今回の環境では以下がインストールされました。

  • Installing:
  • Installing for dependencies:
    • cpp
    • dwz
    • fontconfig
    • fontpackages-filesystem
    • glibc-devel
    • glibc-headers
    • kernel-headers
    • keyutils-libs-devel
    • krb5-devel
    • libX11
    • libX11-common
    • libXau
    • libXft
    • libXrender
    • libcom_err-devel
    • libmpc
    • libselinux-devel
    • libsepol-devel
    • libverto-devel
    • libxcb
    • mpfr
    • pcre-devel
    • perl-srpm-macros
    • tcl
    • tix
    • tk
    • tkinter
    • zip
    • zlib-devel

途中で以下のように表示された場合は「No」を選択します。

f:id:sig9:20160710123451p:plain

No names were found in your configuration files. You should specify ServerNames in your config files in order to allow for accurate installation of your certificate. If you do use the default vhost, you may specify the name manually. Would you like to continue?

Certbot で証明書を発行する

いよいよ証明書の発行です! 以下のように実行して証明書を発行します。

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

オプションには以下のような意味があります。

オプション 意味
certonly 証明書の発行のみを実行する
--abree-tos ライセンス条項に同意する。現在のライセンスバージョンは v1.0.1 だが、2016/8/1 からは v1.1.1 が適用される予定
--webroot 発行された証明書の一時保存に Web サーバの指定ディレクトリを使う Webroot モードを指定する。取得が完了し、ファイルが移動されればファイルは削除される。このオプションを指定しない場合(Standalone モード)は証明書の取得時に Web サーバを停止し、TCP/80 が利用されていない状態にする必要がある
-w Webroot モード時に利用する証明書の一時保存ディレクトリを指定する。実際には指定したディレクトリ配下に .well-known/ というディレクトリを作成しているらしい
-d 発行する証明書の FQDN を指定する。-d オプションを複数指定すれば、一枚の証明書で複数の FQDN を証明出来る
-m 証明書の期限切れ等をお知らせするメールの宛先を指定する

実行例は以下の通りです。

$ ./certbot-auto certonly \
>   --agree-tos \
>   --webroot \
>   -w /var/www/html  \
>   -d example.com \
>   -m sample@example.com
Requesting root privileges to run certbot...
  /home/centos/.local/share/letsencrypt/bin/letsencrypt certonly --webroot --agree-tos -w /var/www/html -d example.com -m sample@example.com

IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at
   /etc/letsencrypt/live/example.com/fullchain.pem. Your cert
   will expire on 2016-10-08. To obtain a new or tweaked version of
   this certificate in the future, simply run certbot-auto again. To
   non-interactively renew *all* of your certificates, run
   "certbot-auto renew"
 - If you lose your account credentials, you can recover through
   e-mails sent to sample@example.com.
 - Your account credentials have been saved in your Certbot
   configuration directory at /etc/letsencrypt. You should make a
   secure backup of this folder now. This configuration directory will
   also contain certificates and private keys obtained by Certbot so
   making regular backups of this folder is ideal.
 - 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

Apache の設定ファイルを修正する

発行された証明書自体は /etc/letsencrypt/archive/ に保存されます。また、このディレクトリにある証明書や秘密鍵等へのシンボリックリンク/etc/letsencrypt/live/ に作成されます。証明書を再発行してもシンボリックリンクは常に最新の証明書をポイントする為、Web サーバの設定ファイルから証明書等を参照する際は(/etc/letsencrypt/archive/ にある実体では無く)このシンボリックリンクを参照するようにします。

今回は Apache を使っているので /etc/httpd/conf.d/ssl.conf を修正し、Let's Encrypt から取得した SSL/TLS サーバ証明書秘密鍵・中間証明書を指定します。

変更前 (/etc/httpd/conf.d/ssl.conf)

SSLCertificateFile /etc/pki/tls/certs/localhost.crt
SSLCertificateKeyFile /etc/pki/tls/private/localhost.key
#SSLCertificateChainFile /etc/pki/tls/certs/server-chain.crt

変更後

SSLCertificateFile /etc/letsencrypt/live/example.com/cert.pem
SSLCertificateKeyFile /etc/letsencrypt/live/example.com/privkey.pem
SSLCertificateChainFile /etc/letsencrypt/live/example.com/chain.pem

修正が完了したら、変更を反映する為に Apache を再起動します。

sudo systemctl restart httpd.service

通信確認

ブラウザから実際にアクセスし、「鍵マークが表示されること」を確認します。

f:id:sig9:20160710125448p:plain

chrome の場合は「鍵マーク → 詳細」の順にクリックすることで、以下のような情報を表示することが出来ます。

f:id:sig9:20160710125456p:plain

証明書の詳細な内容を確認したい場合は View certificate をクリックします。

  • 証明書の更新

証明書や秘密鍵、中間証明書の実体は /etc/letsencrypt/archive/FQDN に保存されています。

$ sudo ls -l /etc/letsencrypt/archive/example.com
total 16
-rw-r--r--. 1 root root 1809 Jul 11 11:37 cert1.pem
-rw-r--r--. 1 root root 1647 Jul 11 11:37 chain1.pem
-rw-r--r--. 1 root root 3456 Jul 11 11:37 fullchain1.pem
-rw-r--r--. 1 root root 1704 Jul 11 11:37 privkey1.pem

Let's Encrypt で発行した証明書の有効期限は 90 日間です。証明書の更新は certbot-auto renew で実施します。但し、有効期限が残り 30 日を切っていないと更新処理は行われません。

$ cd ~/certbot
$ ./certbot-auto renew
Requesting root privileges to run certbot...
  /home/centos/.local/share/letsencrypt/bin/letsencrypt renew

-------------------------------------------------------------------------------
Processing /etc/letsencrypt/renewal/example.com.conf
-------------------------------------------------------------------------------

The following certs are not due for renewal yet:
  /etc/letsencrypt/live/example.com/fullchain.pem (skipped)
No renewals were attempted.

有効期間の残り日数に関わらず、強制的に証明書の更新を実行するには --force-renew オプションを指定します。但し、Let's Encrypt での証明書取得には制限があります。詳細は公式サイトの Rate Limits ページを参照してください。

$ ./certbot-auto renew \
>   --force-renew
Requesting root privileges to run certbot...
  /home/centos/.local/share/letsencrypt/bin/letsencrypt renew --force-renew

-------------------------------------------------------------------------------
Processing /etc/letsencrypt/renewal/example.com.conf
-------------------------------------------------------------------------------

-------------------------------------------------------------------------------
new certificate deployed without reload, fullchain is
/etc/letsencrypt/live/example.com/fullchain.pem
-------------------------------------------------------------------------------

Congratulations, all renewals succeeded. The following certs have been renewed:
  /etc/letsencrypt/live/example.com/fullchain.pem (success)

ls で確認してみると更新された証明書等の一式が増えているのが分かります。Apache の設定ファイルからはシンボリックリンクで定義しており、証明書の更新時にシンボリックリンクの参照先も更新される為、Apache の設定ファイルは修正する必要がありません。

$ sudo ls -l /etc/letsencrypt/archive/example.com
total 32
-rw-r--r--. 1 root root 1809 Jul 11 11:37 cert1.pem
-rw-r--r--. 1 root root 1809 Jul 11 11:52 cert2.pem
-rw-r--r--. 1 root root 1647 Jul 11 11:37 chain1.pem
-rw-r--r--. 1 root root 1647 Jul 11 11:52 chain2.pem
-rw-r--r--. 1 root root 3456 Jul 11 11:37 fullchain1.pem
-rw-r--r--. 1 root root 3456 Jul 11 11:52 fullchain2.pem
-rw-r--r--. 1 root root 1704 Jul 11 11:37 privkey1.pem
-rw-r--r--. 1 root root 1704 Jul 11 11:52 privkey2.pem

ちなみに --dry-run を指定すると証明書の更新は行わず、「更新処理が可能か?」という動作テストだけを実施することが出来ます。また、--dry-run を実行した場合は証明書の取得枚数制限には影響しません。

$ ./certbot-auto renew \
>   --force-renew \
>   --dry-run
Requesting root privileges to run certbot...
  /home/centos/.local/share/letsencrypt/bin/letsencrypt renew --force-renew --dry-run

-------------------------------------------------------------------------------
Processing /etc/letsencrypt/renewal/example.com.conf
-------------------------------------------------------------------------------
** DRY RUN: simulating 'certbot renew' close to cert expiry
**          (The test certificates below have not been saved.)

Congratulations, all renewals succeeded. The following certs have been renewed:
  /etc/letsencrypt/live/example.com/fullchain.pem (success)
** DRY RUN: simulating 'certbot renew' close to cert expiry
**          (The test certificates above have not been saved.)

IMPORTANT NOTES:
 - Your account credentials have been saved in your Certbot
   configuration directory at /etc/letsencrypt. You should make a
   secure backup of this folder now. This configuration directory will
   also contain certificates and private keys obtained by Certbot so
   making regular backups of this folder is ideal.

更新された証明書を反映する為に Apache を再起動します。しかし、Restart(急な再起動)すると接続中のセッションも切断されてしまう為、Graceful Restart(緩やかな再起動)します。CentOS7 ではサービスが Systemd で管理されていますので、Apache の Graceful Restart には reload を指定します。

sudo systemctl reload httpd.service

ブラウザから再度、Web サイトにアクセスし、証明書を表示すると有効期限が更新されているはずです。尚、Apache の定義ファイルは /usr/lib/systemd/system/httpd.service にあります。CentOS7 では以下となっており、Graceful Restart に関する部分は「ExecReload=/usr/sbin/httpd $OPTIONS -k graceful」と定義されているのが分かります。

[Unit]
Description=The Apache HTTP Server
After=network.target remote-fs.target nss-lookup.target
Documentation=man:httpd(8)
Documentation=man:apachectl(8)

[Service]
Type=notify
EnvironmentFile=/etc/sysconfig/httpd
ExecStart=/usr/sbin/httpd $OPTIONS -DFOREGROUND
ExecReload=/usr/sbin/httpd $OPTIONS -k graceful
ExecStop=/bin/kill -WINCH ${MAINPID}
# We want systemd to give httpd some time to finish gracefully, but still want
# it to kill httpd after TimeoutStopSec if something went wrong during the
# graceful stop. Normally, Systemd sends SIGTERM signal right after the
# ExecStop, which would kill httpd. We are sending useless SIGCONT here to give
# httpd time to finish.
KillSignal=SIGCONT
PrivateTmp=true

[Install]
WantedBy=multi-user.target

ヘルプ表示

参考までにヘルプの出力結果を掲載しておきます。

$ ./certbot-auto --help
Requesting root privileges to run certbot...
  /home/centos/.local/share/letsencrypt/bin/letsencrypt --help

  certbot-auto [SUBCOMMAND] [options] [-d domain] [-d domain] ...

Certbot can obtain and install HTTPS/TLS/SSL certificates.  By default,
it will attempt to use a webserver both for obtaining and installing the
cert. Major SUBCOMMANDS are:

  (default) run        Obtain & install a cert in your current webserver
  certonly             Obtain cert, but do not install it (aka "auth")
  install              Install a previously obtained cert in a server
  renew                Renew previously obtained certs that are near expiry
  revoke               Revoke a previously obtained certificate
  register             Perform tasks related to registering with the CA
  rollback             Rollback server configuration changes made during install
  config_changes       Show changes made to server config during installation
  plugins              Display information about installed plugins

Choice of server plugins for obtaining and installing cert:

  --apache          Use the Apache plugin for authentication & installation
  --standalone      Run a standalone webserver for authentication
  (nginx support is experimental, buggy, and not installed by default)
  --webroot         Place files in a server's webroot folder for authentication

OR use different plugins to obtain (authenticate) the cert and then install it:

  --authenticator standalone --installer apache

More detailed help:

  -h, --help [topic]    print this message, or detailed help on a topic;
                        the available topics are:

   all, automation, paths, security, testing, or any of the subcommands or
   plugins (certonly, install, register, nginx, apache, standalone, webroot,
   etc.)