日記

日々のことと、Python/Django/PHP/Laravel/nodejs などソフトウェア開発のことを書き綴ります

let's encrypt で複数ホスト名対応な証明書を作る

let’s encrypt で複数ホスト名対応な証明書を作る

タイトル通りですが、割と簡単に複数のホスト名に対応した証明書が取得できるので、やってみました。

今回は ansible playbook のおまけ付きです。

let’s encrypt の困った問題

let’s encrypt ではワイルドカード証明書が無いので、複数のホスト名を1台のサーバでホスティングできないため、ちょっと困っていました。

ググって調べてみたら、let’s encrypt は SAN 対応の証明書だったら発行できる、と言うことだったので実際にやってみました。

その前に、SAN って何よ?

ワイルドカード証明書だと良く聞くと思うのですが、 SAN って何よ?と思う人も多いと思います。

SAN とは Subject Alternative Name の略称で、サブジェクトの別名です。

ん?サブジェクトってなに? サブジェクトは証明書に設定された Common Name です。

要は、 san01.tnamao.net を Common Name として証明書を作り、その時に別名としての san02.tnamao.net を SAN として登録する形になります。

SAN とワイルドカードの違い

SAN があったら、ワイルドカードいらなくない?要らない子じゃない?となりがちですが、何が違うのか?

ワイルドカードの場合は *.tnamao.net で取得すれば、 abc.tnamao.net も def.tnamao.net も xyz.tnamao.net も利用可能です。

しかし、SAN の場合は abc.tnamao.net も def.tnamao.net も xyz.tnamao.net も証明書を発行する時に指定する必要があります。

ワイルドカードサブドメインが増えても、同一の証明書で対応できます。しかし SAN の場合は必要になる別名が増えた段階で証明書の再発行が必要です。

技術的な側面は置いといて、利用する上ではここが一番大きい差だと思います。

今回使うサーバ

最近は前払い方式のクラウドサーバ (VPS に近い) の Vultr を使ってます。

時間払いも選べるので、グローバル IP が欲しいときに、さっとサーバ立てて実験してサーバを破棄すれば経済的でおすすめです。

実験をだらだらやってるとお金が減ってくのも集中しなきゃ、という気になるので精神面からも良い感じです。

let’s encrypt での SAN 対応証明書の作成

では、本題の let’s encrypt での複数ホスト対応証明書の作り方です。

certbot のインストール方法などは省略するので、過去のブログエントリを参照してください。

では、証明書を発行します。コマンドは次のようにします。

$ ./certbot-auto certonly \
      --no-self-upgrade \
      -n \
      --webroot \
      --agree-tos \
      --email tnamao@yourdomain.com \
      -w /var/www/letsencrypt_webroot/ \
      -d abc.yourdomain.com \
      -d xyz.yourdomain.com

こんな感じで、-d で指定するドメインを複数並べます。一番先に指定したドメインが Common Name として使用されます。

自分の場合は、san.tnamao.net と san2.tnamao.net の置き換えて、コマンドが無事に実行しました。

正常にコマンドが実行できたら、Web サーバの再読込を行い、ブラウザでアクセス

f:id:monajiro:20160821161610p:plain

出来た\(^o^)/

証明書は san.tnamao.net だけど、サブジェクト代替名として san.tnamao.net と san2.tnamao.net が登録してあります。 この状態であれば、 https://san.tnamao.net/https://san2.tnamao.net/ のどちらでアクセスしても正常な証明書としてブラウザが認識します。

この方法は古いサーバを集約したい、なんて時に非常に便利だと思います。

以前に証明書発行済みのサブドメインを新しい証明書の SAN として組み込む

使い捨ての時代なのでドメインも使い捨てに… と言うわけにもいかず、一般に向けて何かを公開すると終息させるまでの面倒を見る必要も出てきますよね。

昔、証明書を取って https を使っちゃってるからサーバだけ残さないといけないんだよなぁ。お金かかってやだなぁ…

そんなときも SAN を設定した証明書を活用することでマイグレーションが可能です。

上で使った証明書作成済みの san.tnamao.net を、別の証明書の SAN として設定してみます。

$ ./certbot-auto certonly \
      --no-self-upgrade \
      -n \
      --webroot \
      --agree-tos \
      --email tnamao@yourdomain.com \
      -w /var/www/letsencrypt_webroot/ \
      -d san3.tnamao.net \
      -d san.tnamao.net

新しいサーバ上に環境を作って、上記のコマンドを流してみました。ちなみに DNS は切り替え済みです。

今度は、san3.tnamao.net の代替名として san.tnamao.net を設定してみました。

nginx を再読込させて

f:id:monajiro:20160821163003p:plain

できた\(^o^)/ 証明書の Common Name が san3.tnamao.net になって、代替名もさっきとは変わってますよね。

まとめ

let’s encrypt でワイルドカード証明書は対応してないから、単一 IP アドレスのサーバでマルチドメインホスティングは難しいかと思っていましたが、SAN を使うことで可能でした。

ワイルドカード証明書に比べると自由度は下がります。でも、ホスティングするドメインが決まっていれば有効な方法だと思いました。

おまけ (ansible playbook)

今回の実験するときに、何度か環境作るのが分かってたので、 ansible playbook を書きました。

Ubuntu 16.04 にしか対応してないけど、証明書の取得を簡単に試したい人はどうぞ。 Vultr と組み合わせる時は非常に楽ちんだと思うので、使ってみてください。