search
LoginSignup
4

More than 1 year has passed since last update.

posted at

updated at

Dockerソフトウェアでも(お手軽に)SSL化対応したい

この記事は、NTTテクノクロス Advent Calendar 2021 の18日目です。
NTTテクノクロスの竹内 光治です。普段は AWS関連案件のマネージャーをしています。最近は GCPと Salesforceを中心に触っています。

はじめに

今回は、DockerソフトウェアでのSSL化対応方法についてのお話です。色々探したんですがしっくりくる記事が見つけられなかったので、ならば備忘録として書き残しておきます。

記事の要約

DockerのVolumeマウント設定を活用してSSL証明書(TLS証明書)を割り当てます。

  • 今回の環境条件
    • HOST OSはCentOS
    • コンテナにイメージとして(たまたま)mediawikiを使用
    • コンテナのOSはDebian
    • コンテナのWebサーバーはAapche2

記事の背景

WebサイトのSSL化について私がよく実施するのは次の方法です。

  • フロントにLBを配置しSSLを終端させる。LBからインスタンスへの通信は非SSLのプレーン通信。

しかし「そんなにアクセストラヒックが無いから冗長構成もLoad BalancerもKubernetesクラスタもいらないよ。ランニングコスト抑えたいし。」とのお題が。そうです、いつもの(?)節約プロジェクトからの打診です。であれば、Dockerコンテナ単品を立てて、直接 コンテナ内のWebサーバーをSSL化することで十分でしょう。

設定の手順

じゃ具体的にどうやるの?ということで、DebianにおけるApacheのSSL化の手順は次の通りです。
Figure1.png

(1) a2enmod にて SSLモジュールを有効にする

モジュールの有効化にはa2enmodコマンドを使用します。これにより、mods-availableに登録されているApacheモジュールに対し、mods-enabledにリンクが張られます。mods-availableに登録が無ければ、moduleをインストールする必要があります。今回のイメージには既にSSLモジュールが登録されてるので、そのまま利用しました。
このコマンドはDockerイメージをビルドするDockerfileに記述します。

RUN a2enmod ssl

(2) サイト設定と SSL証明書を配置する

この記事では証明書の準備には触れませんが、用意した証明書は以下の構成で配置しました。

(ホスト側)
 mediawiki/
  ├ mediawiki_ssl.conf ----- サイト設定config(SSL証明書へのPATHを記述)
  └ certs/
   ├ server.crt ----------- 設定するSSL証明書(サーバー証明書)
   └ server.key ----------- 設定するSSL証明書(SSL秘密鍵)

(3) a2ensite にて SSLサイトを有効にする

サイトの有効化にはa2ensiteコマンドを使用します。これにより、sites-availableに登録されている設定ファイルに対し、sites-enabledにリンクが張られます。sites-availableに登録が無ければ、設定を準備する必要があります。
素直に考えると、ホスト側で用意した証明書類をコンテナ内にコピーして、a2ensiteコマンドを発行する、と思うじゃないですか。いえいえ、もう少し簡単になります。ここがこの記事の主題でして、用意したサイト設定はHOST側には既に存在しているので、a2ensiteの代わりにDockerのボリュームマウントを使用してしまえば良いのです。

    volumes:
      - ./mediawiki/mediawiki_ssl.conf:/etc/apache2/site-enabled/mediawiki_ssl.conf
      - ./mediawiki/certs:/etc/ssl/mediawiki

(4) コンテナを起動し設定を確認する

さて、まずはcurlで接続確認をしてみます。「SSL certificate verify ok.」が返りました。 大丈夫ですね。

curl -s -v https://***.***.***.*** --proxy http://***.***.***.***:****
   :
(中略)
   :
* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384
* ALPN, server accepted to use http/1.1
* Server certificate:
*  subject: CN=***.***.***.***
*  start date: Jul 29 07:39:03 2021 GMT
*  expire date: Aug 30 07:39:03 2022 GMT
*  subjectAltName: host "***.***.***.***" matched cert's "***.***.***.***"
*  issuer: C=BE; O=GlobalSign nv-sa; CN=GlobalSign GCC R3 DV TLS CA 2020
*  SSL certificate verify ok.
* TLSv1.2 (OUT), TLS header, Supplemental data (23):

ブラウザからも確認してみます。「この証明書は問題ありません」と表示されました。大丈夫ですね。
figure2.png

まとめ

Dockerfile、docker-compose.yaml 全体像は以下のようになりました。これで無事にコンテナ内のApacheがSSL化されました。

Dockerfile
FROM mediawiki
ENV LANG C.UTF-8

RUN a2enmod ssl
docker-compose.yaml
# 関連個所を抜粋しています
service:
  mediawiki:
    container_name: myWiki
    build: .
    restart: always
    ports:
      - '8443:443'
    networks:
      - wiki-net
    volumes:
      - ./mediawiki/mediawiki_ssl.conf:/etc/apache2/site-enabled/mediawiki_ssl.conf
      - ./mediawiki/certs:/etc/ssl/mediawiki

おわりに

a2ensiteのコマンドを使用しても実態はsites-availableからsites-enabledへのリンク設定です。であればDockerのVolumeマウントを使用してHOST側のディレクトリを、コンテナのsites-enabledディレクトリにマウントすればa2ensiteと同様の効果が得られます。定期的に更新されるSSL証明書はHOST側に置くのが便利ですしね。今後は、SSL証明書の自動更新として ACMEプロトコルを組み込みたいと思います(できればお手軽に)。

NTTテクノクロス Advent Calendar 2021、明日は @subutakahiroさんです。お楽しみに!

参考

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
4