SSL認証Let's Encryptの導入 (Certbot)

新たな導入環境に合わせ、以前ブログで記述した内容を改訂しています。
Let’s EncryptによるフリーのSSL認証を導入する手順です。

lets-encrypt

事前準備

導入環境 Ubuntu Server 16.04

導入前準備として以下項目を再確認・設定して下さい。

Apacheの設定ファイルsite-available内のdefault.confのServerName, ServerAliasを指定して下さい。
サブドメインの場合はServerNameだけを指定して下さい。

ServerName sub.example.com
ServerAlias example.com

Apacheでsslモジュールを有効にします。

sudo a2enmod ssl

Apacheを再起動しSSLアクセスを有効にします。

sudo service apache2 restart

Step 1 — Gitのインストール

まずパッケージマネージャーをアップデートします。

sudo apt-get update

Let’s Encrypt はGitHubにより管理・更新されているため、Gitをインストールします。

sudo apt-get install git

Step 2 — Let’s Encrypt Clientのダウンロード

サードパーティアプリが一般的にインストールされるoptディレクトリにLet’s Encryptをインストールします。

Gitによりクローンを作成します。

sudo git clone GitHub - certbot/certbot: Certbot is EFF's tool to obtain certs from Let's Encrypt and (optionally) auto-enable HTTPS on your server. It can also act as a client for any other CA that uses the ACME protocol. /opt/letsencrypt

上記コマンドにより、Let’s Encrypt公式レポジトリのコピーが /opt/letsencrypt に作成されます。

Step 3 — SSL認証のセットアップ

Let’s EncryptによるSSL認証は非常に簡単です。ドメインと設定ファイルの指定のみで、認証処理は自動的に行われます。

まずletsencryptのディレクトリに移動します。

cd /opt/letsencrypt

インタラクティブな認証処理が下記コマンドで行われます。サブドメインの場合はサブドメインを指定します。

./letsencrypt-auto --apache -d example.com

または (2016年後半にcertbot-autoに変更になったようです。)

./certbot-auto --apache -d example.com

サブドメインの場合

./letsencrypt-auto --apache -d sub.example.com

または

./certbot-auto --apache -d sub.example.com

ベースドメインに加え、サブドメインの認証処理を同時に行う場合は、サブドメインの箇所を追加して下さい。

./letsencrypt-auto --apache -d example.com -d sub.example.com

上記コマンド実行中、認証オプションを選択する画面が表示されます。

  1. ドメインが記述された設定ファイルの選択
  2. e-mailアドレス
  3. httpアクセスをhttpsへリダイレクトするかどうか

などを選択して下さい。

インストール終了後、以下サイトで指定のサイトがSSL認証されているかどうか確認して下さい。example.comにはベースのドメインまたはサブドメインを入力します。

Step 4 — 認証の自動更新

Let’s Encryptによる認証有効期間は90日です。余裕を見て60日以内ごとに更新することをお勧めします。

以下更新コマンドです。

./letsencrypt-auto renew

インストールした時点では、まだ更新の必要がない旨のメッセージが表示されます。

Checking for new version…
Requesting root privileges to run letsencrypt…
/root/.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.

複数のドメインを指定した場合には、ベースドメインのみ上記のメッセージに表示されるようですが、認証の更新は問題なく登録ドメインについて行われます。

その都度更新コマンドを実行するのは手間ですので、cronジョブに代行させます。

crontabにスケジュール、実行コマンドを追加します。

sudo crontab -e
30 2 * * 1 /opt/letsencrypt/letsencrypt-auto renew >> /var/log/le-renew.log

letsencrypt-auto renew コマンドを毎週月曜日AM2:30に実行し、ログを/var/log/le-renewal.logに記録します。

Step 6 — Let’s Encryptのアップデート

Gitによる更新コマンドです。

​cd /opt/letsencrypt
sudo git pull

失敗した場合などは/etc/letsencryptフォルダを削除して再トライして下さい。

sudo rm -r /etc/letsencrypt

https://letsencrypt.jp/docs/using.html#where-are-my-certificates

Apache や nginx の Installers(インストーラ)プラグインを使用して SSL/TLS サーバ証明書の管理を自動化することを推奨しておりますが、手動で SSL/TLS サーバ証明書の管理を行いたい場合には、下記の必要なファイルの探し方についての情報を参考にしてください。
全ての生成された暗号鍵(公開鍵および秘密鍵)と発行された SSL/TLS サーバ証明書に対するシンボリックリンクは /etc/letsencrypt/live/$domain に作成されます。
これらのファイルをコピーするのではなく、上記のシンボリックリンクをサーバソフトウェア(ウェブサーバなど)の設定ファイルにて直接指定することをお勧めします。
証明書の更新時には /etc/letsencrypt/live 内のシンボリックリンクは、最新の暗号鍵・証明書へリンクするように自動的に書き変わります。
※過去に Certbot クライアントで発行した全ての暗号鍵・SSL/TLS サーバ証明書(更新前・有効期限切れを含む)の実体は、 /etc/letsencrypt/archive と /etc/letsencrypt/keys に保管されています。

※/etc/letsencrypt/live は、最新の暗号鍵・証明書に対するシンボリックリンクです。

利用可能なファイルは、下記の通りです。
privkey.pem
SSL/TLS サーバ証明書の公開鍵に対応する 秘密鍵 です。
Apache 設定ファイルの SSLCertificateKeyFile や、nginx の ssl_certificate_key で指定します。
※秘密鍵は、漏洩しないように保管する必要があります。

※他の誰かと秘密鍵を共有しないでください。Let’s Encrypt の開発者にも渡さないでください。

※SSL/TLS の動作のためには、サーバ(Apache など)がこの秘密鍵ファイルにアクセスできる必要があります。
従って、安全のために秘密鍵を金庫の中のみで保管するといった運用はできません。

cert.pem
SSL/TLS サーバ証明書(公開鍵を含む)です。サーバの証明書のみで、中間証明書などは含みません。
これは、Apache 2.4.8 未満 で使用するファイルで SSLCertificateFile として指定します。
chain.pem
アクセス時にブラウザに提供する必要のある中間証明書です。
SSL/TLS サーバ証明書(cert.pem の内容)は含まれていません。
これは、Apache 2.4.8 未満 で使用するファイルで SSLCertificateChainFile として指定します。
fullchain.pem
SSL/TLS サーバ証明書(公開鍵を含む)と中間証明書の両方が含まれているファイルで、cert.pem と chain.pem の内容が結合されたものです。
これは、Apache 2.4.8 以上 や nginx で使用するファイルです。
Apache 2.4.8 以上の場合は SSLCertificateFile、nginx では ssl_certificate において、このファイルを指定します。
証明書は、ルート証明書(プライマリ証明書)から下層へとたどる構造となっています。
必ず chain.pem か fullchain.pem のどちらかを使用する必要があることに注意してください。
もし、ウェブサーバに cert.pem のみを設定した場合には、ブラウザにおいて証明書に関するエラーが発生します。

Certbotにより自動的にLet’s EncryptによるSSL認証プロセスを実行します。

Ubuntu18.04サーバでCertbotによりSSL認証を取得します。
以下DegitalOceanによる参考サイトです。
DigitalOceanもAWS,GCP同様に仮想マシーンサービスを提供していますが、コスト面含め評判は一番良いようです(要確認、ドキュメントは大変充実しています)。

ドメイン名を変更した際のことを考慮し、ドメイン毎にApacheの仮想ホストマシン用ファイル(/etc/apache2/sites-available/xxx.conf)を作成します。

Certbotのインストール

$ sudo apt install python3-certbot-apache

ドメイン名www.example.comの仮想ホストファイルをデフォルトのファイルからコピーします。

$ cd /etc/apache2/sites-available
$ sudo cp 000-default.conf www-example-com.conf

ServerNameをwww.example.comに書き換えます。

$ sudo pico www-example-com.conf

  ServerName www.example.com

上記仮想ホストを有効にし、設定をリロードします。

$ sudo a2ensite www-example-com
$ sudo systemctl reload apache2

SSL認証取得

$ sudo certbot --apache -d www.example.com

メールアドレスを入力後、以下のオプション画面が表示されます。

Please choose whether or not to redirect HTTP traffic to HTTPS, removing HTTP access.
-------------------------------------------------------------------------------
1: No redirect - Make no further changes to the webserver configuration.
2: Redirect - Make all requests redirect to secure HTTPS access. Choose this for
new sites, or if you're confident your site works on HTTPS. You can undo this
change by editing your web server's configuration.
-------------------------------------------------------------------------------
Select the appropriate number [1-2] then [enter] (press 'c' to cancel):

任意ですが、2を選択するとhttpへのアクセスが全てhttpsへリダイレクトされるようにwww-example-com.confに内容が追加されます。

プロセス終了後www-example-com-le-ssl.confファイルが作成され、同ドメイン名でSSL接続が有効になります。

認証チェック

Certbotにより自動的にSSL認証は更新されます。何か問題があれば登録したメールアドレス宛連絡が来るようです。

マニュアルでも更新・チェックができます。

$ sudo certbot renew --dry-run

上記内容は古いため下記参照のこと。

certbotのインストール

https://eff-certbot.readthedocs.io/en/stable/install.html

注) パッケージで提供されているバージョンは古いため、snapによる最新バージョンのインストールが推奨されています。

ex) Ubuntu20.04+Nginx

Dockerによる起動

スタンドアローンで証明書を取得する場合などは、snapやシステムに直接インストールすることなくDockerイメージによる起動が便利です。

Certbot on Docker
https://eff-certbot.readthedocs.io/en/stable/install.html#running-with-docker

スタンドアローン
https://certbot.eff.org/docs/using.html#standalone

certonly:単に指定ドメインの認証を取得したいだけの場合

$ sudo docker run -it --rm --name certbot \
            -v "$PWD/letsencrypt:/etc/letsencrypt" \
            -v "/var/lib/letsencrypt:/var/lib/letsencrypt" \
            -p 80:80 \
            certbot/certbot certonly --standalone -d stun.example.com

コンテナ内の /etc/letsencrypt/live ディレクトリに証明書が作成されるため、-vオプションによりホスト側のアプリ指定のディレクトリと共有させます。

プロキシサーバと経由先サーバのCertbotによるTLS認証

プロキシサーバをIPv4アドレス、経由先サーバをIPv6アドレスでドメイン登録している場合のCertbotによるTLS認証手続きについてのメモ。

ドメインをAAAAレコード(IPv6アドレス)で登録している場合、Certbotが認証時にアクセスするアドレスはこのIPv6アドレスです。

従って、同ドメインでAレコード(IPv4アドレス)として登録している上記プロキシサーバでCertbot認証する際にはエラーが発生します。

このエラーは以下のオプション --http-01-address でIPv4アドレスを指定することで回避できます(以下の例は Windows Server: Power Shell を使用する場合)。

PS C:> certbot certonly --force-renewal --webroot -w C:/nginx/html --http-01-address xx.xx.xx.xx -d www.example.com

PS C:> certbot certonly --expand --webroot -w C:/nginx/html --http-01-address xx.xx.xx.xx -d www.example1.com,www.example2.com

Webroot

Nginx 設定ファイル内で acme challenge に対応した条件追加

server {
    .....
    location ~* /\.well-known/ {
          try_files $uri /;
    }
    .....
    .....

If you’re running a local webserver for which you have the ability to modify the content being served, and you’d prefer not to stop the webserver during the certificate issuance process, you can use the webroot plugin to obtain a certificate by including certonly and --webroot on the command line. In addition, you’ll need to specify --webroot-path or -w with the top-level directory (“web root”) containing the files served by your webserver. For example, --webroot-path /var/www/html or --webroot-path /usr/share/nginx/html are two common webroot paths.

Re-creating and Updating Existing Certificates

The --force-renewal, --duplicate, and --expand options control Certbot’s behavior when re-creating a certificate with the same name as an existing certificate. If you don’t specify a requested behavior, Certbot may ask you what you intended.

--force-renewal tells Certbot to request a new certificate with the same domains as an existing certificate. Each domain must be explicitly specified via -d. If successful, this certificate is saved alongside the earlier one and symbolic links (the “live” reference) will be updated to point to the new certificate. This is a valid method of renewing a specific individual certificate.

--duplicate tells Certbot to create a separate, unrelated certificate with the same domains as an existing certificate. This certificate is saved completely separately from the prior one. Most users will not need to issue this command in normal circumstances.

--expand tells Certbot to update an existing certificate with a new certificate that contains all of the old domains and one or more additional new domains. With the --expand option, use the -d option to specify all existing domains and one or more new domains.

Example:

# certbot --expand -d existing.com,example.com,newdomain.com

If you prefer, you can specify the domains individually like this:

# certbot --expand -d existing.com -d example.com -d newdomain.com