WEB

wwwへ転送するネイキッドドメインのSSLをLet’s Encrypt で自動更新したい

問題

Let’s EncryptでSSLを自動更新したいけど、転送設定が邪魔して証明書が更新できない問題が発生。

ネイキッドドメインからwwwへ転送をかけている状況で、ネイキッドドメインのSSLを更新しようとして、webrootにcertbotがファイルを書き込むも、証明書更新しようとするとwww付きへ転送されてしまってファイルがみつからず、更新できないという状態になります。

背景とやりたいこと

Webサービス(ここでは主にカートシステムやブログサービスの事です)で独自ドメインが使えるけどCNAMEで指定する仕様の時、ネイキッドドメイン(wwwやサブドメイン無しのドメイン)をどうするか問題があります。

ネイキッドドメインに対してCNAMEレコードは設定できない事がほとんどです。(一部のDNSサービスでは出来るようです)

例)
https://www.example.com ←CNAME指定可能なドメイン
https://example.com ←ネイキッドドメイン

出来れば、ネイキッドドメインのURLを直打ちした場合でもwwwサイトが表示されるようにしたいものです。つまり、アドレスバーで「example.com」とだけ打っても「https://www.example.com」に転送されるようにしたいですよね。

「example.com」用のサーバーを立てて、アクセスがあったら「www.example.com」に転送するという方法があります。

その場合、「.htacess」を設置して下記のように転送をかけます。

RewriteEngine on
RewriteRule ^(.*)$ https://www.example.com/$1 [L,R=301]

で、このときネイキッドドメイン側にもSSLがないと転送するまえに「信頼のないサイト」となって転送前にアラートが出てしまいます。怪しいサイトだ!と思われて離脱されることでしょう。

ネイキッドドメインにSSLを適用しつつ、wwwへ転送したい。
SSL証明書は無料のLet’s Encryptを使用したい。できれば自動更新したい。

解決するには

certbotでSSL更新する時だけ、転送設定を解除できればいいのです。
.htaccessをリネームなんかして、SSL更新したあとに、元に戻す。

そして上記を90日の有効期限が切れる前にCronで自動実行したい!

やってみる

シェルスクリプトを作成し、Cronで自動実行するやり方です。(certbotのインストールなどは済んでいる状態とします。)

※ドキュメントルートを/var/www/html/example.com/html としています。

シェルスクリプトを作成

適当な場所に下記のシェルスクリプトを配置します。
ここでは /var/www/html/example.com/certrenew.sh として作成しました。パーミッションは755にしました。

#!/bin/bash

date

mv /var/www/html/example.com/html/.htaccess /var/www/html/example.com/html/.htaccess_bk

certbot certonly --webroot -w /var/www/html/example.com/html --email youraddress@example.com --debug -d example.com

systemctl restart httpd.service

mv /var/www/html/example.com/html/.htaccess_bk /var/www/html/example.com/html/.htaccess
解説
  1. dateコマンドはログに実行時間を記録するためです
  2. mvで.htaccessをリネームしています
  3. このサーバーには複数のサイトがあるので、certbot renewではなくて、certonlyをつかって対象のドメインのみwebroot認証させています。※一連のテストするときは「–dry-run」をオプションでつけると、結果のみ返してくれます。
  4. apacheを再起動して更新を適用します
  5. 最後にリネームした.htaccessを元に戻します

 

Cronの設定

/etc/cron.d/letsencrypt を作成して以下の内容を記述します

0 16 */80 * * root /var/www/html/example.com/certrenew.sh >> /var/www/html/example.com/cert.log 2>&1
解説

80日毎(90日だとギリギリ感があるし、月イチだとlet’s encryptに負荷をかけて申し訳ないので80日としました。※残存30日以下だと更新できます。)の16:00にシェルスクリプトをrootで実行します。実行結果はshと同じ場所にあるcert.logに追記していきます。ここに先ほどのdateで出力した日時が記録されるのでいつ実行されたかわかります。

まとめ

シェルスクリプトを使って、若干めんどくさい更新も自動化できました。

Let's Encrypt でワイルドカード証明書の発行と更新...

 

reiko suzuki
OLD SKOOLシステムエンジニア。ねこを撫でながら働いています。