13
6

More than 1 year has passed since last update.

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

Last updated at Posted at 2021-12-17

この記事は、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さんです。お楽しみに!

参考

13
6
0

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
  3. You can use dark theme
What you can do with signing up
13
6