転載・引用について

ユーザ用ツール

サイト用ツール


サイドバー

Site Contents Index

転載・引用について

RSS

tweet:2017:0131_01

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

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

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

Let's Encryptとは?

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

その基本方針は

  • 無料
    • ドメインを保持する者が無料で信頼された証明書を取得可能
  • 運用の自動化
    • 証明書の取得から更新まで自動化することが可能
  • 安全
    • 認証局サイド、管理者の両面から、最先端のプラットフォームを提供
  • 透明性
    • 証明書の発行と失効が公式に記録され、一般公開され、誰でも監査できる
  • オープン
    • 各手続き(プロトコル)を、オープン標準として公表
  • 互助・協力
    • コミュニティの利益のための共同の取り組みであり、1つの組織によって統制されているものではない

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

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

  • 無料でSSLサーバ証明書を発行してくれるサービス。
    • あくまでもサーバー証明書のみであり、個人証明書などは発行しない
  • ドメイン認証型の証明書
    • 一般に、サーバー証明書は「ドメイン認証(DV)」、「組織(企業)認証(OV)」、「実在性監査済(EV)」がありますが、DVしか発行しない
      • 無料の証明書にそこまで要求してはいけません。そのレベルの要求をするならお金を払いましょう。

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

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

注意点

  • 有効期間が90日
    • もう少し長くても良いような気もするが、自動化されている前提ならこれでいいのかもしれない。
    • 暗号アルゴリズムの危殆化やProtocolの更新などを考えると、短い方が良いかもしれない。
  • 秘密鍵ファイルはパスフレーズで暗号化していない
    • HTTP ServerやSMTP Serverなど、Server用途で利用するなら、これはこれで仕方がないことかもしれない
    • 秘密鍵ファイルの取り扱いには十分な注意をすること。SSLでHTTP部分を(多少)守ったからといって、サーバーが安全になるわけではないことに十分に留意すること
  • 国コードや組織名の入力がない
    • DV(Domain Validation)ならば、Domainが存在しており、かつ、そのドメインが正当であると判断できればよいので、国コードや組織名はなくても問題ない
    • もちろん、OVやEVならば、組織の存在認定などを受けることからも、国コードや組織名は必要

事前準備

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

項目 内容 備考
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利用する。

その他の実装

  • acme-client
    • ports/securityに収録されている。
    • OpenBSDで開発されており、LibreSSLを利用している。
    • Cで記述されており、余計なパッケージ類が不要
    • 連絡先のメールアドレスを指定できない模様。
    • すこし古い(2017/02/01時点でportsは0.1.11だが、開発元では0.1.15)

certbotを利用する

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

  • まずなによりもpkgで。
    • pkg install py27-certbot
      • 思ったよりも大量のpython関連モジュールが入るのでビビる。
      • これ、わからないでもないけど、勘弁して欲しい気もするなぁ。

証明書関連処理

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

  • www.example.com
  • www.example.org

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

  • foo@example.net

とする。

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

  • –rsa-key-size N : RSAの鍵長。defaultは2048。
  • –must-staple : OCSP Must Staple 拡張を追加。defaultは追加しない
  • -cert-path CERT_PATH : 証明書を保存するPathを指定する。defaultは None
  • –key-path KEY_PATH : 証明書のインストールや失効に用いる秘密鍵のパスを指定する。defaultは None
  • –config-dir CONFIG_DIR : 設定ファイルのあるディレクトリを指定する。defaultは /etc/letsencrypt
  • –work-dir WORK_DIR : 作業用ディレクトリを指定する。defaultは /var/lib/letsencrypt
  • –logs-dir LOGS_DIR : ログファイルの保存先ディレクトリを指定する。defaultは /var/log/letsencrypt

取得の前提条件

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に仕掛けなければならない。 この場合、以下の問題が発生する

  • 証明書はlb1/2に設置されなければならない
  • チャレンジ(存在検査)用のTokenはWeb Server側に仕掛けなければならない

これを解決するには、

  • –server SERVER : ACME ディレクトリリソースの URI を指定

を利用し、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も定義されている模様。

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

このウェブサイトはクッキーを使用しています。 Webサイトを使用することで、あなたはあなたのコンピュータにクッキーを保存することに同意します。 また、あなたはあなたが私たちのプライバシーポリシーを読んで理解したことを認めます。 同意しない場合はウェブサイトを離れてください。クッキーに関する詳細情報
tweet/2017/0131_01.txt · 最終更新: 2018/05/14 13:51 (外部編集)