目次

FreeBSDのWeb ServerにLet's Encryptの証明書を突っ込む

かねてからの懸案だったLet's Encrypt証明書対応のメモ。

2017/02/01現在、まだFreeBSDでの動作確認をしていないので、この記事を鵜呑みにしても動かない可能性が高い。

Let's Encryptとは?

Let's Encryptは、公共の利益を図る目的で Internet Security Research Group (ISRG) が運営する、無料で利用できる自動化されていてオープンな認証局。

その基本方針は

以上、About - Let's Encrypt - Free SSL/TLS Certificatesより抜粋。

実際に利用するレベルから見ると、

というサービスを提供してくれるサイト及びサービスである。

日本語訳のサイトがあるので、是非一度見て見ることを勧める。Let's Encrypt 総合ポータル

注意点

事前準備

まずは、何はともあれ、公開するサイトを作成すること。 今回の諸元は以下のとおり

項目 内容 備考
Platform XenServer
VMのCPU vCPU x2
VMのMemory 2G
VMのDisk 20G(boot)+100G(Data/DB)
NIC vNIC2本 管理用と対外接続用
OS FreeBSD 11.0 Release Install時点では -p7
pkg Head(latest)
HTTPd NGINX pkgからinstall
CMS DokuWiki / WordPress 手動 install
SMTPd Postfix 試験用
IMAPd dovecot 試験用

Let's Encryptから証明書を取得する方法は複数ある。 Let's Encrypt自身はLet's Encryptの配布するcertbotを利用することを強く推奨している。 今回は、certbot利用する。

その他の実装

certbotを利用する

certbotはPython 2.7系用のscriptなので、Python 2.7が導入されていなければならない。まぁ、自分の場合、XenToolsが入っているので、どうせPython2.7がInstallされているから諦めるのがいいかもしれない。

証明書関連処理

必要なサイトのURLを確認する。 ここでは、仮に、Named Virtual Hostとして、

を保持しており、管理者のMail Addressを

とする。

引数関係は コマンド解説(コマンドリファレンス)を参照のこと。 ちょっとだけメモ。

取得の前提条件

DV証明書である以上、Domainにアクセスできなければならない。したがって、上記2ドメインにhttpでアクセスするとサイトが返答する状況にしておくことが重要 また、管理用のメールアドレスもちゃんとメールが受け取れるようになっていることが重要。

取得

certbot certonly --webroot \
  -w /tmp/le/com -d www.example.com \
  -w /tmp/le/org -d www.example.org \
  -m foo@example.net --agree-tos

更新

certbot certonly --webroot \
  -w /tmp/le/com -d www.example.com \
  -w /tmp/le/org -d www.example.org \
  --renew-by-default

この更新スクリプトを作成し、cronでDailyに実行すれば、勝手に証明書が取得できる。 取得した証明書のTimestampを確認して、必要に応じてnginx restartすれば済むはず

問題点

上記のやり方の場合、現在の自分の構成ではうまく動作しない。 現状の構成は、

                        +--- WAF1
                        |
            +--- lb1 ---+--- IPS1 ---+--- Web
Internet ---+           |            |
            +--- lb2 ---+--- IPS2 ---+--- Web
                        |
                        +--- WAF2

となっているため、Let's Encryptをlb1/lb2に仕掛けなければならない。 この場合、以下の問題が発生する

これを解決するには、

を利用し、URIにWebサーバー側で提供することのないURIを設定した上で、そこにチャレンジしてもらうという手が考えられる。 流れはおそらく

  1. 外部のHostからLet's EncryptのTokenを引っ張ってくる
  2. lbの設定で、nginxでいうlocation指定にあるコンテンツにTokenを記載
  3. Let's EncryptでChllangeしてもらう

となるはず。これをacme-clientで実行できるならば、そちらでやる手もあるし、certbotでやる手もありそうだ。 何れにしても、lbで処理を行うことは難しいと考えられるので、何らかのscriptを考える必要がありそうだ。

なお、Let's EncryptにおけるACMEでのドメインの検査は、http-01, tls-sni-01, dns-01の3種類があるので、dns-01を利用する手も考えられる。しかし、自分の管理しているDNSはDNS Server間での同期処理はさせず、全DNS Serverにコンテンツを個別に設置している。しかも、一部のNSは外部に設置しているので、更新処理を自動化するのは悩ましい。

なお、ACMEはInternet Draft(ID)になっており、2017/02/01現在、draft-ietf-acme-acme-04として公開されている。これを見ると、oob-01も定義されている模様。

この問題に関しては、少しゆっくり考える必要がありそうだ。