📌

開発用サーバの証明書の警告をLet's Encryptで解消

2023/12/02に公開

はじめに

検証環境にSSL認証を導入する際、オレオレ証明書を用いる事はよくあります。
その際に気になるのが下記のような警告メッセージ。

一発でページが表示されませんし、アドレスバーの左に「保護されていない通信」と出続けるのは気になります。

通常SSL証明書を導入する場合、有料になるのですが、
Let's Encryptを使えば、無料でSSL証明書を導入できます。

Let's Encryptの導入方法について解説したいと思います。

※Let's Encryptはlocalhostには対応していないです。

Let's Encryptとは

非営利団体、Internet Security Research Group (ISRG) が提供している無料のSSL/TLS証明書は発行してくれる認証局。
https://letsencrypt.org/ja/

Let's Encryptの特徴

  • 無料で使えます。
  • 証明書の取得や更新が自動化できる。
  • SSHでサーバに接続できるなら導入が簡単
  • 幅広い互換性
    特に無料だからといって制限があることもなく、大半のブラウザやOSで問題なく表示されます。
    詳細は以下ページ
    https://letsencrypt.org/ja/docs/certificate-compatibility/
  • 証明書の有効期限は 90 日間。この日数は変更不可。
  • レート制限あり
    • 制限があるといっても検証用であれば制限に引っかかることはないレベル
    • 登録ドメインごとの証明書数 (1週間に50個まで)
    • サブドメインは、最大で証明書ごとに 100 ドメイン名まで1つの証明書に統合可能。
      上の制限と加えると週に5000個の証明書が発行可能です。
    • 検証の失敗は、1アカウントごと、1ホスト名ごと、1時間毎に、5回までに制限されています。
      その他のレート制限の詳細は下記に記載されています。
      https://letsencrypt.org/ja/docs/rate-limits/

Let's Encryptの導入

基本的には以下の内容に沿って進めます。
https://letsencrypt.org/getting-started/

今回導入するサーバはsshで接続できるため、
certbotを用いるのがおすすめされているので、そちらでやっていきます。
読み進めていくと、certbotを使うためにはsnapdのインストールが必要とのこと。

なので、手順としては以下のようになります。

  1. snapdのインストール&有効化
  2. certbotのインストール
  3. certbotを起動

Let's Encryptは認証局なので、Let's Encrypt自体をインストールすることはありません。
サーバではcertbotを用いることでLet's Encryptの証明書を取得し、自動で更新まで行ってくれます。

1.snapdのインストール&有効化

snapd

Snapdは、スナップを自動的に管理および維持するバックグラウンドサービスです。

https://snapcraft.io/docs/installing-snap-on-centos
こちらの手順を元にしています。
ちなみにUbuntuであればプリインストールされているようなのでこの手順は飛ばせそうです。

パッケージの更新

# EPELを追加
sudo dnf install epel-release
sudo dnf upgrade

snapdのインストール

sudo yum install snapd

snapdのサービスを有効化

sudo systemctl enable --now snapd.socket

クラシックsnapのサポートを有効化

snapコマンドを使えるようにします。
シンボリックリンクを張っているだけです。

sudo ln -s /var/lib/snapd/snap /snap

有効化するためには一度サーバから出て入りなおします。

2.certbotのインストール

Certbotとは

https://certbot.eff.org/

Certbotは、手動で管理されるWebサイトでLet's Encrypt証明書を自動的に使用してHTTPSを有効にする、無料のオープンソースソフトウェアツールです。

OS毎のcertbotのインストール手順の選択

まずはRLにアクセスします。
https://certbot.eff.org/instructions?ws=nginx&os=centosrhel8
My HTTP website is runningという部分でWebサーバとOSを選択します。
SoftwareがWebサーバ、SystemがOSです。

今回はSoftwareはNginx、OSはCentOS 8を選びました。
サーバのOSはCentOS 9なのでリストには載ってないのですが、8なら大丈夫だろうということで一旦進めていきます。

certbotのインストール

sudo snap install --classic certbot

certbotコマンドの設定

certbotというコマンドを使えるようにします。
こちらもシンボリックリンクを張ってるだけです。

sudo ln -s /snap/bin/certbot /usr/bin/certbot

3.certbotでnginxに認証を追加

sudo certbot --nginx

Saving debug log to /var/log/letsencrypt/letsencrypt.log
Enter email address (used for urgent renewal and security notices)
 (Enter 'c' to cancel): 

コマンド実行後から、実行ログが保存されます。
/var/log/letsencrypt/letsencrypt.log
認証局関係のログはここに溜まっていくのではないかと思われます。
そして、更新やセキュリティの注意喚起などを通知するためのメールアドレスを登録します。

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Would you be willing, once your first certificate is successfully issued, 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 our work encrypting the web,
EFF news, campaigns, and ways to support digital freedom.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(Y)es/(N)o: y
Account registered.

ここは任意ですが、Let's Encryptの運営会社であるEFFからのニュースが送られるようになります。
初回のメール以外では1週間以上は経ってますが1通来ているくらいです。
この位の頻度であれば良いかなと思っています。
もっとたくさん来るようであれば解除するかもしれません。

Which names would you like to activate HTTPS for?
We recommend selecting either all domains, or all domains in a VirtualHost/server block.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1: {ドメイン}
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Select the appropriate numbers separated by commas and/or spaces, or leave input
blank to select all options shown (Enter 'c' to cancel): 1

こちらが本題です。
どのドメインに証明書を付けるか選択します。
nginxなどWebサーバに複数設定がある場合は、複数から選択することになると思います。
今回は1つしかなかったので、1を選択しました。

Requesting a certificate for {ドメイン}

Successfully received certificate.
Certificate is saved at: /etc/letsencrypt/live/{ドメイン}/fullchain.pem
Key is saved at:         /etc/letsencrypt/live/{ドメイン}/privkey.pem
This certificate expires on 2024-02-28.
These files will be updated when the certificate renews.
Certbot has set up a scheduled task to automatically renew this certificate in the background.

Deploying certificate
Successfully deployed certificate for {ドメイン} to /etc/nginx/conf.d/vhost.conf
Congratulations! You have successfully enabled HTTPS on https://{ドメイン}

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
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
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

これで証明書が更新され、Let's Encryptの認証局に証明された証明書を利用することができました。
改めてブラウザからサイトにアクセスするとアドレスの横の「保護されていない通信」が消えていると思います。

私の場合、Chromeでしたが、証明書を適用してからブラウザで更新しただけでは消えてくれませんでした。
新規タブで開いてもダメ。
ブラウザ閉じて開きなおすことで無事確認ができました。

設定の確認

無事安全な認証が提供できるようになったので、今回行った内容による設定の変更箇所を確認していきたいと思います。

nginx

confファイル

    ssl_certificate /etc/letsencrypt/live/{ドメイン}/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/{ドメイン}/privkey.pem; # managed by Certbot

証明書情報が上記のように書き変わっています。

証明書の自動更新

certbotより引用します。

The Certbot packages on your system come with a cron job or systemd timer that will renew your certificates automatically before they expire. You will not need to run Certbot again, unless you change your configuration. You can test automatic renewal for your certificates by running this command:
システム上の Certbot パッケージには、証明書が期限切れになる前に自動的に更新する cron ジョブまたは systemd タイマーが付属しています。構成を変更しない限り、Certbot を再度実行する必要はありません。次のコマンドを実行して、証明書の自動更新をテストできます。

sudo certbot renew --dry-run

つまり、先ほど実行したコマンドによってもう自動的に更新するようになっているようです。

certbot を更新するコマンドは、次のいずれかの場所にインストールされます。
/etc/crontab/
/etc/cron./
systemctl list-timers

今回の環境ではsytemctlのみ確認できました。
systemctl

systemctl list-timers

NEXT                        LEFT          LAST                        PASSED       UNIT                         ACTIVATES                     
Sun 2023-12-03 09:01:00 JST 14h left      Sat 2023-12-02 12:03:04 JST 5h 58min ago snap.certbot.renew.timer     snap.certbot.renew.service

自動更新をテストする

自動更新をテストしてみます。

sudo certbot renew --dry-run

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

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Processing /etc/letsencrypt/renewal/{ドメイン}.conf
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Simulating renewal of an existing certificate for {ドメイン}

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Congratulations, all simulated renewals succeeded: 
  /etc/letsencrypt/live/{ドメイン}/fullchain.pem (success)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

さいごに

Let's Encrypt認証局を使い、ページ表示の警告を取り除くことができました。
導入も慣れれば30分もかからず完了できると思います。
導入されていない方はぜひ導入してみて、快適な検証環境ライフを実現してください。

Discussion