エンジニアブログ Lets Encryptを用いたロードバランサ環境におけるSSL証明書自動更新手法とは

近年、セキュリティの重要性は高まり常時SSL(Always On SSL)が一般的となってきました。
しかしながら、SSL化を行うにはSSL証明書発行を認証局に依頼する必要があり、コストが発生します。
また、SSL証明書には有効期限があるため、定期的に更新を行う運用が必須となります。
今回は、この2つの課題解決を目的として、ロードバランサへ無償でSSL証明書を取得できるLet's Encryptを適用してみました。

加藤 和樹

ITスペシャリストとして従事
領域は、ネットワーク全般と自動化を担当
ネットワーク自動化定着に向けて邁進中

1. はじめに

近年、セキュリティの重要性は高まり常時SSL(Always On SSL)が一般的となってきました。
WebサイトをSSL化するためには、ロードバランサまたはWebサーバーにSSLの設定やSSL証明書を投入する必要があり、下記2つの課題がございます。
課題1:SSL証明書取得にはコストがかかる
課題2:SSL証明書は定期的に更新が必要となり、運用負荷が増える

通常、SSL証明書を投入するには認証局(CA:Certificate Authority)に対して、自身で発行したCSRを送付するだけではなく、
発行費用をお支払いして証明書(Certificate)を取得する必要があります。
また、SSL証明書には有効期限があるため、有効期限が切れないように定期的にSSL証明書更新を実施する必要があります。
今回は、この2つの課題解決を目的として、ロードバランサへ無償かつ自動でSSL証明書を取得できるLet's Encryptを適用してみました。

2. Let's Encryptとは

課題1のコスト面は、SSL証明書の発行にLet's Encryptを用いることで解決することが出来ます。
Let's Encryptは、インターネット・セキュリティ・研究グループ (ISRG:Internet Security Research Group) が提供する無償かつ自動化された認証局です。
Let's Encryptは、ドメインを保持している人であれば誰でも無償で使用することが出来、Let's Encryptは自動化されているためスムーズに証明書発行を受けることが出来ます。
また、Let's Encryptが発行に使用しているルート証明書は、ChromeやEdgeなど多くのブラウザーにプリインストールされているため、
自己証明書のようなエラーも表示されず、安心かつセキュアに使用することが出来ます。
注意点としては、Let's Encryptで発行できるSSL証明書はDV(Domain Validation)認証のみとなりますので用途には注意が必要です。

SSL証明書タイプ

証明書タイプ

DV(Domain Validation)証明書

OV(Organization Validation)証明書

EV(Extended Validation)証明書

認証方式

ドメイン認証

企業認証

企業認証

確認項目

ドメインを保持しているか確認

ドメインを保持しているか確認

企業が第三者データベースに実在するか確認

データベース登録電話番号に確認

ドメインを保持しているか確認

企業が法的(登記簿)に実在するか確認
企業が
第三者データベースかつ物理的に存在するか確認

データベース登録電話番号に確認

用途

企業認証不要なサイト

ドメインが信頼されているサイト

企業の証明が必要なサイト

ログインを求めるサイト

オンラインショッピング

金融系サイト

信頼度

価格

安価 or 無償

中間

高価

Let's Encrypt対応

常時SSL化を行っていく上では、必ずしもOV証明書やEV証明書のような企業認証が必要ではないサイトも暗号化するようになるかと思います。
このようなサイトには、Let's Encryptを用いることでコスト面の課題解決を行うことが出来ます。
次の章では、課題2の運用負荷を軽減させるための方法として、Let's Encryptのロードバランサ連携手法をご紹介します。

3. Let's Encryptのロードバランサ連携手法

Let's Encryptをロードバランサと連携させるためには、以下の3つの項目ができるロードバランサを使用する必要があります。

1. ロードバランサ単体で特定のURLパスに対して任意のWebページ応答ができること

2. ロードバランサオペレーションがAPIで操作できること

3. SSLオフロードができること

今回連携するロードバランサは、上記要件を満たした日商エレクトロニクスで取り扱っているNetScalerを用いて実装しました。

netscaler_letsencrypt_architecture.png

Let's EncryptとNetScalerを連携させるコードは、Pythonを用いて記述し証明書自動更新サーバーに実装しました。
各システムとの接続には以下のプロトコルを用いております。
①Let's Encrypt:ACME(Automated Certificate Management Environment)プロトコル
②NetScaler:NITRO API (REST API)、SCP

ACMEプロトコルは、Webサーバーと認証局との間で証明書を自動化する一般的なプロトコルとなり、
ApacheやNginxなどのサーバーに向けたクライアントは豊富に存在します。
しかしながら、ロードバランサとの連携に対応したクライアントは少ないまたは存在しないため、個々に実装が必要となります。
今回は、ACMEクライアントの中でも、ロードバランサに適用するために改変可能なacme-tinyクライアントをベースに実装することにしました。
https://github.com/diafygi/acme-tiny
選定基準は以下のとおりです。
・プログラムコードで提供されていること
・Pythonで記述されていること
・商用・改変利用が可能なライセンスであること

acme-tinyのソースコードをベースに、NetScalerのAPIを用いてCSR発行から証明書の取得、適用までを自動で行えるPythonコードを記述しました。
主な機能は以下のとおりです。
・opensslを用いて動的にkey,csrを発行
・ACMEプロトコルを用いてLet's Encryptから証明書(cert)を取得 (acme-tinyをベースに使用)
・Let's Encryptのドメイン認証時にNetScalerのResponderポリシーへチャレンジコードを連携し認証
・Let's Encryptから取得した証明書とKeyをSCPでNetScalerへアップロード
・NetScalerのSSL VIPの証明書へアップロードした証明書とKeyを更新

作成したPythonコードは、以下の通りです。

netscaler_letsencrypt_code_overview.png

本Pythonコード利用するには以下の前提条件が必要となります。
【Virtual Server設定について】
Virtual Serverは、同一IPアドレスにてHTTPとSSLの2つを構成する必要があります
HTTP Virtual Serverは、通常時はPriority 100のResponder PolicyをもとにSSL Virtual Serverへリダイレクトさせます。
証明書更新時は、「acme_netscaler.py」がリダイレクト用Responder Policyより高いPriority値(90)で
チャレンジ認証を行うためのResponder Policyを設定いたします。

netscaler_letsencrypt_lbsetting.png

「acme_netscaler.py」で証明書更新を実行する際に必要なパラメーターは、Python実行時の引数で設定する必要があります。
実行コマンド:
python3 acme_netscaler.py [NSIP] [Username] [Password] [HTTP VIP名] [SSLペア名] [Common Name] [Let's EncryptアカウントKeyファイル ]

実際のサンプル結果は以下のとおりです。

netscaler_letsencrypt_samplelog.png

※requests実行時のNSIP宛のCertificateワーニングログは割愛、一部環境固有情報は置換

上記より、CSR発行から証明書取得、適用までをPythonコードで自動化することが出来ました。
では、このコードを用いてどの用に運用するのが良いのでしょうか。
Let's Encryptは、SSL証明書の有効期限が90日間となっており、以下のFAQの通り60日ごとに更新するのが推奨されております。
https://letsencrypt.org/ja/docs/faq/

よって、本スクリプトをcronを用いて2カ月に1回実行することで、SSL証明書更新を完全に自動化することが出来ます。

cronの参考設定
2カ月に1回、1日の1時にSSL証明書更新を実行する
* 01 01 */2 * python3 /[配置した任意のディレクトリ]/acme_netscaler.py [NSIP] [Username] [Password] [HTTP VIP名] [SSLペア名] [Common Name] [Let's EncryptアカウントKeyファイル ]

crontab -e
* 01 01 */2 * python3 /home/nelco/auto_letsencrypt/acme_netscaler.py 192.168.1.1 nsroot nsroot testHTTP example_cert www.example.net account.key

4. 最後に

本記事では、ロードバランサであるNetScalerにLet's Encryptでの証明書更新を適用し、2つの課題を解決してみました。
課題1:SSL証明書取得にはコストがかかる
Let's Encryptは、ドメインを保持している人であれば誰でも無償で利用することが出来ます。
無償だからといって、自己証明書のようなエラーも表示されず、安心かつセキュアに使用することが出来ます。

課題2:SSL証明書は定期的に更新が必要となり、運用負荷が増える
Let's Encryptは、SSL証明書発行のオペレーションが完全に自動化されております。
今回ご紹介したロードバランサとPythonコードを合わせることで、ユーザー側のオペレーションも完全に自動化し、
日々のSSL証明書更新の手間から解放されます。

SSL化にお悩みの方やロードバランサ設計にお困りの方など、お気軽に以下のフォームまたは担当営業までご相談ください。

エンジニアブログ

NELabに関するお問い合わせは、
こちらのフォームからご連絡ください。