Certbot(Let's Encrypt)入門

certbotコマンド(旧称letsencrypt)は、公的な認証局Let's Encryptが発行する無料のTLSサーバ証明書を、簡単なコマンド操作で取得・更新できる、革命的なオープンソースソフト。

Certbot公式サイト: https://certbot.eff.org/https://github.com/certbot/certbot


概要

    インストール

      準備

        証明書取得

          Webサーバに証明書設定

            証明書更新


              SSL/TLSサーバ証明書とは

              ちまたで言うSSLは今は技術的に発展したTLSのこと。これに対応したサイトのURLがhttps://で始まるので、HTTPSとも呼ばれる。以降TLSと表記する。

              TLSサーバ証明書の役割

              Let's Encryptはブラウザに組み込まれている認証局であり、TLSサーバ証明書(ドメイン認証)を簡単なcertbotコマンドでいつでもすぐに無料で取得できるようになった。革命的。

              詳しく…


              certbotコマンドで証明書を取得できる仕組み

              1. ドメイン運用側サーバでcertbotコマンドを実行
              2. Let's Encrypt側サーバから確認のためのアクセス(ACMEプロトコル)
              3. アクセス(認証)成功で、TLSサーバ証明書発行

              旧来のような本人確認がないのに、コマンド一発で証明書を取得できるのは、ドメインサーバ側へのアクセスがDNSサーバを利用して行われることで、「コマンドの実行者 = ドメインサーバの所有者」を確認でき、第三者の成りすましを防止できるため。


              証明書取得までの流れ

              1. certbotコマンドのインストール(git cloneコマンドとスクリプト実行)
              2. certbotコマンドでTLSサーバ証明書取得
              3. Webサーバに証明書を設定

              ここでは、certbotコマンドでは証明書の取得だけを行うことにし、httpdへの設定は手動で行う流れにする。下記分類のstandaloneプラグインによる方法。


              certbotのプラグイン

              証明書取得とサーバ設定の方式は色々あり、これをプラグインと称して、コマンドオプションで指定する。

              本来のWebサーバを一時停止できないシステムなら、standaloneプラグイン以外にする。

              これ以外にサードパーティのプラグイン(別途インストールが必要)もある。


              certbotコマンドのインストール環境

              Linux各種のパッケージ管理システムからcertbotコマンドをインストールできるが、ここでは、GitHubの公式リポジトリhttps://github.com/certbot/certbotから取得する方法による。

              このリポジトリにcertbot-autoスクリプトが含まれており、これはコマンド同様の機能のため、当サイトでcertbotコマンドと言えばcertbot-autoスクリプトのこと。

              LinuxはCentOS7、WebサーバはApache httpd2.4で例示するが、certbot-auto一発で、Linuxごとに依存パーケージがインストールされるので、他のLinuxでも同様らしい。

              以降の例ではcertbot 0.27.1で確認。


              Gitのインストール

              certbotの入手をgitコマンドでするので、gitパッケージをなければインストールする。

              yum install git

              certbotコマンドのインストール

              git cloneして、certbot-autoスクリプトで、依存パッケージがインストールされる。基本的にcertbotroot権限で操作する。

              スクリプトへのパスが面倒なので、環境変数PATHに含まれる/usr/local/sbin/にリンクを置いて、コマンド化する。名前はそのままcertbot-autoとするが、certbotコマンドの環境は読みかえること。

              # 任意のディレクトリに移って、
              cd /usr/local/src/
              # git clone
              git clone https://github.com/certbot/certbot
              
              # リンク作成してコマンド化
              ln --symbolic $PWD/certbot/certbot-auto /usr/local/sbin/
              
              # 依存パッケージのインストール
              certbot-auto --install-only
              
              # バージョン
              certbot-auto --version
              certbot 0.27.1
              

              コマンドヘルプ

              # コマンド概要 
              certbot-auto --help
              
              # サブコマンドのリスト
              certbot-auto --help commands
              
              # 証明書の取得だけするcertonlyコマンドについて
              certbot-auto --help certonly
              
              # 利用可能なプラグインのリスト
              certbot-auto plugins
              
              # standaloneプラグインについて
              certbot-auto --help standalone
              
              # 全ヘルプ
              certbot-auto --help all
              

              DNSサーバの設定

              certbotで証明書取得する際、Let's Encrypt側サーバからドメイン運用側サーバに「対象のドメイン名によるアクセス」があるので、事前にDNSサーバの稼働が必要。

              DNS設定直後は外部に情報が未達の可能性があるため、ドメインサーバ外のクライアントから名前解決ができるか、予めdigコマンドなどで確認しておく。

              # ANSWER SECTIONに結果が出たらOK
              dig @1.1.1.1 ドメイン名
              # (中略)
              ;; ANSWER SECTION:
              ドメイン名. 35982 IN    A   IPアドレス
              

              ここではDNSプラグインのTXTレコードによる方法ではないので、単にドメインの名前解決できればいい。


              Webサーバのインストール

              WebサーバがApache httpdの場合で例示する。httpdパッケージをインストールする。

              yum install httpd
              # バージョン確認
              httpd -v
              Server version: Apache/2.4.6 (CentOS)

              mod_sslモジュール

              TLSではmod_sslモジュールが必要だが、certbot-autoコマンドとともに自動インストールされる。

              # もしなかったら
              yum install mod_ssl
              

              POODLE SSLv3.0 脆弱性の対策(httpd.conf)

              古いバージョンのSSLには「POODLE SSLv3.0」と呼ばれる脆弱性があるので、TLSのみ有効にしておく。httpdの設定ファイル/etc/httpd/conf/httpd.confの最終行にでも下記を追加するだけ。

              SSLProtocol All -SSLv2 -SSLv3

              その他、ドメインごとの設定は後で。


              ファイアウォールにhttps追加

              certbotで証明書取得する際、httpsでの通信があるので、firewall-cmdコマンドで予めファイアウォールにhttpsを許可しておく。

              # https許可
              firewall-cmd --permanent --zone=public --add-service=https
              # 再読込
              firewall-cmd --reload
              # 確認
              firewall-cmd --zone=public --list-services
              

              standaloneプラグインの場合、--preferred-challenges httpで80ポート利用のプロトコルに変更できるが、証明書取得したら結局https使う。


              本来のWebサーバは一時停止しておく

              standaloneプラグインの方法のため、証明書取得過程でポート80(http)や443(https)と競合するので、(動いていれば)いったんWebサーバ(httpd)を停止する。

              systemctl stop httpd

              ただし、ここで停止せずとも、取得時のcertbot-autoコマンドに--pre-hook 'systemctl stop httpd'を付ける方法でもよい。すると、/etc/letsencrypt/renewal/ドメイン.confに記録が残り、証明書更新のcertbot-auto renewコマンドでも、同様の処理が自動でなされるから便利。


              certbot certonlyコマンドで証明書取得(standaloneプラグイン)

              本来のWebサーバを停止し、certbotに含まれるstandaloneサーバ(一時的なWebサーバ)で認証し、証明書の取得だけを行う方法。Webサーバへの証明書の指定は別途手動で行う。

              email='メールアドレス'
              domains='ドメインを複数なら,区切りで'
              
              certbot-auto certonly --standalone --non-interactive --agree-tos \
                --keep --expand --email $email --no-eff-email --domains $domains \
                --pre-hook 'systemctl stop httpd' --post-hook 'systemctl start httpd'
              

              詳しく…


              証明書のディレクトリ

              certbotで取得した証明書は、/etc/letsencrypt/archive/以下に保存され、その最新版へのリンクが/etc/letsencrypt/live/以下に置かれる。Webサーバへの証明書設定はリンクの方で指定すればいい。

              詳しく…


              Let's Encrypt証明書取得の回数制限

              Let's Encryptサーバ側で回数制限がある。1ドメインで、1週間で5000サブドメインも可能。

              その他制限詳細


              httpd.confで証明書を指定

              /etc/httpd/conf/httpd.conf/etc/httpd/conf.d/以下の設定ファイルを作って、/etc/letsencrypt/live/以下の証明書(リンク)などを指定する。

              <VirtualHost *:443>
                ServerName ドメイン名
                DocumentRoot /var/www/ドメイン名
                SSLEngine on
                SSLCertificateFile /etc/letsencrypt/live/証明書の名前/cert.pem
                SSLCertificateChainFile /etc/letsencrypt/live/証明書の名前/chain.pem
                # Apache2.4.8から全証明書
                #SSLCertificateFile /etc/letsencrypt/live/証明書の名前/fullchain.pem
                SSLCertificateKeyFile /etc/letsencrypt/live/証明書の名前/privkey.pem
              </VirtualHost>
              

              詳しく…


              Webサーバを起動

              証明書やコンテンツの格納が済んだら、httpdサーバを起動。ブラウザでも動作確認

              # 起動
              systemctl start httpd
              
              # --post-hookを使って起動ずみなら、証明書設定を読み込む
              systemctl reload httpd
              
              # 動作確認
              systemctl status httpd
              

              certbot renewコマンドで証明書更新

              証明書の有効期限は90日。期限まで30日未満になったら、certbot-auto renewを実行すれば更新される。

              追加のドメインがあるなど、内容が変わるなら、certbot-auto certonly --expandによる再取得へ。

              詳しく…