doudonn WEB制作やサーバーの話とかいろいろ

Ubuntu 22.04.1 LTS&NginxのロードバランサにLet’s EncryptのSSL証明書を取得し自動更新&同期する方法

  doudonn 更新日:
Ubuntu 22.04.1 LTS&NginxのロードバランサにLet’s EncryptのSSL証明書を取得し自動更新&同期する方法

ロードバランサ(Nginx)にLet’s EncryptのSSL証明書を取得

今はSSLが必須なので、WEBサーバー構築も難しくなった。
SSLだけで難易度が2倍くらいになっているような…

自分もけっこう困ったのでわかりやすく解説したい。

<環境>
・Ubuntu 22.04.1 LTS
・Nginx 1.27.0
・certbot 1.21.0
・さくらVPS

1、Let’s EncryptでSSL証明書を取得する仕組み

Let's EncryptでSSL証明書を取得する仕組み

取得は2つの方法があります。

一つ目は、一時的にランダム名のファイルを作ってアクセスできるか確認する方法。

普通にWEBページが表示できる状態であれば取得できる。
「http://doudonn.com/秘密のファイル」にアクセスできればいい。
Nginxで複雑な設定をしていると404エラーになってしまうので、そこだけ注意です。

この方法が基本となります。
ただし、SSLサイトのサーバー移転等では不可能なため、
下記のDNS認証でサーバー移転前に取得します。

Let's EncryptでSSL証明書を取得する仕組み(DNS認証)

DNSのTXTレコードさえ編集できればOK。

この方法だとエックスサーバーで運営しているサイトもSSL証明書を取得できます。
事前に証明書を準備できるので移転時のダウンが無い。

ただし更新時もDNSの認証が必要となってしまうので、
移転後にファイル認証で再度取得する必要があります。

2、ロードバランサでLet’s EncryptのSSL証明書を取得

ロードバランサでLet's EncryptのSSL証明書を取得

ロードバランサでSSL処理をするので、ここに証明書を入れる。

ロードバランサはネットにも繋がっているので理想的。
もちろん、WEBサーバーに入れて使っても良いですが、
ここではロードバランサに入れる方法を解説します。

3、ロードバランサに入れるために

Let's EncryptでSSL証明書をロードバランサに入れるためには転送が必要

取得はDNS認証ができますが、更新時はファイル認証となります(DNSの自動処理は複雑)。
したがって、Let’s Encryptを更新するロードバランサを固定します。

Let’s Encryptが自動で作成した秘密のファイルにアクセスしないといけないので、
更新時はそのファイルがあるサーバーに絶対に繋がないといけない。
Let’s Encryptからのアクセスを転送する必要があります。

4、取得・更新したLet’s EncryptのSSL証明書を同期

取得したLet's EncryptのSSL証明書を同期

そっくりそのまま同期すれば使い回せる。

「rsync」で同期するだけです。
特にサーバー認識・IP認識というのは無い。
SSL証明書ファイルさえあればOKです。

5、Let’s Encryptの取得方法

ファイル認証の場合

「http://取得したいドメイン/.well-known/acme-challenge/xxxxx」に
アクセスされて表示できる状態にしてください。

次のコマンドを実行します。
※ドメイン・メールアドレスは変更ください。

certbot certonly --webroot --agree-tos --dry-run -w /var/www/html -m info@doudonn.com -d doudonn.com

「–dry-run」を付けているのでテスト実行です。
通常は連続失敗で制限にかかるので、必ず–dry-runで試してください。

「Successfully received certificate.」と出たら成功です。
「–dry-run」を外して再度実行します。

certbot certonly --webroot --agree-tos -w /var/www/html -m info@doudonn.com -d doudonn.com

DNS認証の場合

最初にDNSのTXTレコードをすぐ変更できるよう、
ドメイン会社、レンサバ等のDNS設定画面を開いておいてください。

そして、取得するサーバーで、
Let’s Encrypt取得・更新ソフトとなる「certbot」をインストールします。

apt -y install certbot

インストールしたら下記コマンドを実行します。
※ドメインは変更してください。

certbot certonly --manual -d doudonn.com --key-type ecdsa --preferred-challenges dns

するとこんな文章がずらっと出ます。

Saving debug log to /var/log/letsencrypt/letsencrypt.log

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Please deploy a DNS TXT record under the name:

_acme-challenge.doudonn.com.

with the following value:

ge-50PQfSCdCDd1W2AF8R67-7YzI6Jm7u2vm-O7heAo

Before continuing, verify the TXT record has been deployed. Depending on the DNS
provider, this may take some time, from a few seconds to multiple minutes. You can
check if it has finished deploying with aid of online tools, such as the Google
Admin Toolbox: https://toolbox.googleapps.com/apps/dig/#TXT/_acme-challenge.doudonn.com.
Look for one or more bolded line(s) below the line ';ANSWER'. It should show the
value(s) you've just added.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Press Enter to Continue

ここで何も入力せずストップしてください。
この指定の通りTXTレコードを追加します。

サブドメイン:_acme-challenge.doudonn.com
TXTレコード内容:ge-50PQfSCdCDd1W2AF8R67-7YzI6Jm7u2vm-O7heAo

追加したら、5分ほど放置してください。

「digコマンド」等で反映しているか確認できますが、あてになりません。
経験上、5分待った方がいいです。

5分後にエンターボタンを押すと、証明書発行完了!です。

「/etc/letsencrypt」というフォルダが作られていることを確認してみてください。

6、Let’s Encryptの証明書の暗号方式をECDSAに指定する

デフォルトだとRSAという方式なので、それを変えます。

公式マニュアルを見たら、
今はデフォルトで「ecdsa」の「secp256r1」になっていましたので、
この設定は特にやらなくても良いです。

一応、高セキュリティ型の「secp384r1」をデフォルトにする方法を記載します。
(処理は若干遅くなる)

<編集ファイル(新規作成)>

/etc/letsencrypt/cli.ini

<下記を記載する>

key-type = ecdsa
elliptic-curve = secp384r1

※個人サイトで高セキュリティ型はやる必要無いと思います

7、ssl_dhparamを作成する

Nginxのssl設定で指定して使うファイルです。

<このディレクトリを作成し、ここに移動>

/etc/nginx/ssl/

<次のコマンドを実行>

openssl dhparam 2048 -out dhparam.pem

ファイル作成に1分くらいかかるので休憩です。

8、Let’s Encrypt更新用のNginxの設定方法

※参考として自分の設定を紹介します。
※暗号関係はこちらのサイトを参考にしました

証明書を取得するサーバー

server {
listen 80;
server_name doudonn.com www.doudonn.com;

location ^~ /.well-known/acme-challenge/ {
root /var/www/html;
}

location / {
return 301 https://$host$request_uri;
}

}

server {
listen 443 ssl;
http2 on;
server_name doudonn.com www.doudonn.com;

ssl_session_cache shared:SSL:10m;
ssl_session_timeout 5m;
ssl_prefer_server_ciphers on;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_certificate /etc/letsencrypt/live/doudonn.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/doudonn.com/privkey.pem;
ssl_dhparam /etc/nginx/ssl/dhparam.pem;
ssl_ciphers ECDHE+AESGCM:DHE+aRSA+AESGCM:ECDHE+AESCCM:DHE+aRSA+AESCCM:+AES256:ECDHE+CHACHA20:DHE+aRSA+CHACHA20:+DHE:ECDHE+AES128:ECDHE+CAMELLIA128:ECDHE+AES:ECDHE+CAMELLIA:+ECDHE+SHA:DHE+aRSA+AES128:DHE+aRSA+CAMELLIA128:DHE+aRSA+AES:DHE+aRSA+CAMELLIA:+DHE+aRSA+SHA;
ssl_conf_command Ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_128_CCM_SHA256:TLS_AES_128_CCM_8_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256;

location / {
proxy_pass http://backend;
}

}

更新時もLet’s Encryptはhttp(80番ポート)でアクセスして来ます。
そのため「/.well-known/acme-challenge/」のアクセスだけはバックエンドに流さず、
このサーバーで処理するようにします。

自分の場合は「root /var/www/html;」というルートを指定しています。

転送するサーバー

upstream backend2 {
server 192.168.0.1:80;
}

server {
listen 80;
server_name doudonn.com www.doudonn.com;

location ^~ /.well-known/acme-challenge/ {
proxy_pass http://backend2;
}

location / {
return 301 https://$host$request_uri;
}

}

server {
listen 443 ssl;
http2 on;
server_name doudonn.com www.doudonn.com;

ssl_session_cache shared:SSL:10m;
ssl_session_timeout 5m;
ssl_prefer_server_ciphers on;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_certificate /etc/letsencrypt/live/doudonn.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/doudonn.com/privkey.pem;
ssl_dhparam /etc/nginx/ssl/dhparam.pem;
ssl_ciphers ECDHE+AESGCM:DHE+aRSA+AESGCM:ECDHE+AESCCM:DHE+aRSA+AESCCM:+AES256:ECDHE+CHACHA20:DHE+aRSA+CHACHA20:+DHE:ECDHE+AES128:ECDHE+CAMELLIA128:ECDHE+AES:ECDHE+CAMELLIA:+ECDHE+SHA:DHE+aRSA+AES128:DHE+aRSA+CAMELLIA128:DHE+aRSA+AES:DHE+aRSA+CAMELLIA:+DHE+aRSA+SHA;
ssl_conf_command Ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_128_CCM_SHA256:TLS_AES_128_CCM_8_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256;

location / {
proxy_pass http://backend;
}

}

「/.well-known/acme-challenge/」に来たやつを更新用のサーバーへ転送するだけです。

この段階で表示されるかのテストをします。
上記設定の場合、「/var/www/html/.well-known/acme-challenge/test.html」でファイルを作り
「http://doudonn.com/.well-known/acme-challenge/test.html」にアクセスして表示されるか確認してください。

表示できれば大丈夫。
(このテストせず下記のcertbotでのテストをしてもいい)

9、正しく更新できるかどうかテストをする

※DNS認証で取得した場合は、ファイル認証にて再度取得してください。
下記の更新方法はファイル認証の場合です。

テストコマンドは下記

certbot renew --dry-run --cert-name doudonn.com

「--dry-run」を付ければテストができます。

Saving debug log to /var/log/letsencrypt/letsencrypt.log

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Processing /etc/letsencrypt/renewal/doudonn.com.conf
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Simulating renewal of an existing certificate for doudonn.com

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Congratulations, all simulated renewals succeeded:
  /etc/letsencrypt/live/doudonn.com/fullchain.pem (success)

「succeeded」と出れば成功です。

10、自動更新用Cronを修正する

certbotでLet's Encryptの発行をすると、
自動的に更新用cronを作成してくれます。
ただ、Nginxのリロードをしないと新しい証明書が反映しないので、そこだけ修正。

<編集ファイル>

/etc/cron.d/certbot

<certbotのcron>

SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin

0 */12 * * * root test -x /usr/bin/certbot -a \! -d /run/systemd/system && perl -e 'sleep int(rand(43200))' && certbot -q renew && nginx -s reload

「 && nginx -s reload」を追加してください。

もしくは別にcronを作っても良いです。

11、他サーバーへ同期する

rsyncで「/etc/letsencrypt」を丸ごと同期してください。

<rsyncコマンド参考>

rsync -a -e 'ssh -i /home/doudonn/rsyncuser/id_ed25519 -p 10022' /etc/letsencrypt/ rsyncuser@192.168.0.2:/etc/letsencrypt/

次回からはcronで自動で同期させます。

<cron作成場所>

/etc/cron.d/

この場所に自由な名前でファイルを作ってください。
cronを登録します。

1 */12 * * * root rsync -a -e 'ssh -i /home/doudonn/rsyncuser/id_ed25519 -p 10022' /etc/letsencrypt/ rsyncuser@192.168.0.2:/etc/letsencrypt/

このあたりは自由に作成してください。

当然、同期後にNginxのリロードが必要なので、
同期先でリロードするCronを作ってください。

<cron内容>

3 */12 * * * root nginx -s reload

12、以上です

これでLet's EncryptのSSL証明書自動更新システムができました。
「/etc/letsencrypt/」に全てのドメインのSSL証明書が保存されるので、
ドメインを増やしても同期はこのままで大丈夫です。

一応、初回更新時はちゃんと更新されているか確認しておこう。

補足(エラーについて)

DNS認証で取得したのにファイル認証で更新すると、
更新時に下記のようなエラーが出ます。

Failed to renew certificate doudonn.com with error: The manual plugin is not working; there may be problems with your existing configuration.
The error was: PluginError('An authentication script must be provided with --manual-auth-hook when using the manual plugin non-interactively.')

この場合はファイル認証で再度取得してください。
途中でこんな選択肢を聞いてきます。

1: Keep the existing certificate for now
2: Renew & replace the certificate (may be subject to CA rate limits)

これは「2」を選んでください。

Nginxの関連記事
サーバーの関連記事

記事一覧はこちら:サーバー

管理人について
doudonn
名前:doudonn(どうどん)
ひたすらWEB制作な人。
一応社長です。音ゲー好き

プロフィール
お知らせ

2022年11月30日に全記事削除しました。
無駄にページ表示速度にこだわってます。

役立ちサイト
wiki

プライバシーポリシー・広告について


© 2022-2024 doudonn All Rights Reserved.