AWSやGCP等のクラウドサービスを使っていると、SSL/TLS証明書のマネージドサービスが提供されていることが多く、大変手軽で便利ですよね。一方で、マネージドサービスがない場合や、あってもその証明書を使えないケースが私の周りでもたまにあり、自前でSSL/TLS証明書を発行・管理しなければならないことがあります。
ドメイン認証であれば Let's Encrypt で十分なことがほとんどなので、無料でSSL/TLS証明書を発行・自動更新することができます。
certbot-autoを使うという情報が多いようだが…
私も数年前まではcertbot-autoというツールを使っていたのですが、コマンドを実行するとデフォルトで自動アップデートされるようになっています。自動アップデートを抑制するオプションを付けずにSSL/TLS証明書を自動更新するように設定してしまうと、certbot-autoが自動アップデートされて、Pythonに関するエラーによってSSL/TLS証明書を自動更新できなくなるという現象が起こっていました。
2021年8月2日現在、certbot-autoは非推奨となっており、代わりにsnapでインストールしたCertbotを使うのが推奨されているようです。しかし、新しいCertbotもPythonに依存しており、ふとした拍子に動かなくなることがあるかもしれません(最近のCertbot事情はあまりよく知らないので杞憂かも)。
そこで、今回は lego というツールを使って、SSL/TLS証明書を発行・管理する方法を紹介します。
legoをインストール
legoはGo製のツールで、実行環境に応じたバイナリをダウンロードすればすぐに実行できます。
2021年8月2日現在の最新バージョンである4.4.0を使います。サーバでは最も多いであろうLinux AMD64のバイナリを使いますが、各自の環境に合うものを使ってください。
$ wget https://github.com/go-acme/lego/releases/download/v4.4.0/lego_v4.4.0_linux_amd64.tar.gz -O /opt/lego_v4.4.0_linux_amd64.tar.gz
$ mkdir /opt/lego
$ tar zxf /opt/lego_v4.4.0_linux_amd64.tar.gz -C /opt/lego
バイナリに実行権限が付いているので、すぐに実行できます。
$ /opt/lego/lego -v
lego version 4.4.0 linux/amd64
SSL/TLS証明書を発行
DNSのTXTレコードを設定してドメインの所有確認を行う方法もありますが、DNSの設定を自由に変更できないことがあるので、今回はHTTPの方式にします。nginxの場合、以下のような設定が必要です。
location ^~ /.well-known/acme-challenge/ {
root /var/www; # 任意のパスでOK
}
コマンドを実行し、SSL/TLS証明書を発行しましょう。
$ /opt/lego/lego --accept-tos \
--path "/etc/lego" \ # 任意のパスでOK
--http \
--http.webroot "/var/www" \ # nginxのドキュメントルート
--domains "tls.example.com" \ # 各自の所有しているドメイン
--email "your-email@example.com" \ # 各自のメールアドレス
run
SSL/TLS証明書の発行に成功すると、 /etc/lego/certificates
以下に証明書が生成されます。
$ ls /etc/lego/certificates
tls.example.com.crt tls.example.com.json
tls.example.com.issuer.crt tls.example.com.key
ここまでできれば、後は証明書のパスをWebサーバの設定ファイルに追記して再起動するだけです。nginxの場合、以下のような設定になります。
ssl_certificate /etc/lego/certificates/tls.example.com.crt;
ssl_certificate_key /etc/lego/certificates/tls.example.com.key;
これで、HTTPSが使えるようになりました
SSL/TLS証明書を自動更新
自動更新のコマンドは、発行する際のコマンドとほぼ同じです。cronが動いている環境であればcrontabで設定しましょう。 --renew-hook
オプションで、自動更新後に実行するコマンドを指定できます。
0 0 1 * * /opt/lego/lego --path "/etc/lego" --http --http.webroot "/var/www" --domains "tls.example.com" --email "your-email@example.com" --renew-hook "/usr/bin/systemctl reload nginx"
以上で、無料で発行したSSL/TLS証明書を自動更新できるようになります。証明書の期限切れに怯えることもありません
最後に
クラウドサービスには便利なマネージドサービスが次々に追加されていきますが、やりたいことに合ったサービスがなかったり、あったとしてもうまく合致しないことはよくあります。今回のように自前で設定する方法も含め、いろいろな手段を持っておきたいですね。