以前「Dockerコンテナ上のファイルをローカルにコピーする」で紹介した、PHP と Apache がセットになった Docker イメージ。

サクっと PHP が動作するサーバを立てるなら、Nginx と php-fpm を導入するよりは楽です。
そこで今回は、このコンテナで SSL のサーバ認証をさせる方法を紹介します。
クライアント証明書を使った認証については別の機会にまとめます。
コンテナの用途
今回、このコンテナを使う目的はローカルや開発サーバの検証用を想定しています。
よって、サーバ証明書にオレオレ証明書(自己証明書)を使い、クライアント証明書も同様となります。
クライアント証明書を使うケースはそれほどないかもしれませんが、VPN を使うほどでもないけど IP 固定ができないからという状況では利用することがあります。
本番で利用するなら有償のサービスでクライアント証明書を発行というパターンが多いと思いますが、運用費を考えると開発環境やローカルで同じようにクライアント証明書の環境を用意する場合、自己証明書でカバーするのがベターでしょうね。
SSLサーバ証明書の導入
冒頭で紹介した Docker イメージではデフォルトで SSL が有効になっていないので、コンテナのビルド時に以下の処理もまとめて行ってみます。
サーバ証明書の作成
Apacheの設定
ローカルや開発サーバなら無理に SSL にすることはないって思う人もいるかも知れませんが、本番に近い環境に持っていった際にプロトコルの違いで挙動が異なることもあるので、証明書の違いはあれど少しは近い状態で開発を進めた方が無難です。
最近では Google のセキュリティー対策の啓蒙活動につられるように、SSL(https)化されたサイトが一気に増えました。
少し前まではレンタルサーバなどで Let’s Encrypt の導入がされていなかったので、やりたくてもできないユーザがいましたが、主要なブログサービスやレンタルサーバでサービスが開始されています。
ローカル環境でも Docker ならすぐに SSL 通信可能なコンテナが立ち上げられるので、なるべく環境の差異が少なくなるようにしておきましょう。
スクリプトの作成
Dockerfile にすべて定義できなくもないですが、後々クライアント証明書を設定することを想定して別スクリプトに抜き出します。
まずはサーバ証明書の設定から。これを entrypoint.sh として保存しておきます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | #!/bin/sh # サーバのホスト名(名前をつけてhostsファイルで解決させてもOK) SSL_HOST_NAME="localhost" # サーバ証明書や秘密鍵を配備するディレクトリ SSL_PKI_DIR="/etc/pki/ssl" # 証明書の所有者の情報 SERVER_SUBJECT="/C=JP/ST=Tokyo/L=Shibuya/O=Rilakkuma Ltd./OU=Dev/CN=${SSL_HOST_NAME}" # 証明書の有効期間(10年) DAYS=3650 mkdir -p ${SSL_PKI_DIR} openssl genrsa -out ${SSL_PKI_DIR}/server.key 2048 openssl req -new -key ${SSL_PKI_DIR}/server.key -out ${SSL_PKI_DIR}/server.csr -subj "${SERVER_SUBJECT}" openssl x509 -in ${SSL_PKI_DIR}/server.csr -days ${DAYS} -req -signkey ${SSL_PKI_DIR}/server.key -out ${SSL_PKI_DIR}/server.crt |
Dockerfileの作成
次に Dockerfile の作成です。
コンテナのビルド時に vi を使えるようにする記事を書いたときと同様に、ここにメインとなる処理を定義します。

実は、RUN についてはワンライナーで定義した方がイメージの容量節約になるようなのでバックスラッシュで改行しつつ && で繋ぐ方法がベターなようです。
COPY はどうなんだろうか。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | FROM php:7.1.9-apache ENV APACHE_DOCUMENT_ROOT /var/www/html COPY conf/apache2.conf /etc/apache2/apache2.conf COPY conf/ssl.conf /etc/apache2/sites-available/ssl.conf COPY conf/entrypoint.sh /tmp/ RUN mkdir -p /etc/pki/ssl RUN chmod a+x /tmp/entrypoint.sh RUN /bin/bash -c "source /opt/entrypoint.sh" RUN a2enmod ssl RUN a2ensite ssl CMD ["/usr/sbin/apache2ctl", "-D", "FOREGROUND"] |
apache2.conf や ssl.conf についてはあらかじめ必要な情報を書いておき、それをサーバにコピーする手段を今回は選択しました。
Dockerfile の書き方で注意しておきたいことは以下にまとめられているので参考にしてみましょう。
と言いつつ、上の Dockerfile はあえてわかりやすいように 1 行ずつ RUN も定義しています。
443番ポートをポートフォワードする
通常だとコンテナの 80 番ポートを localhost の特定のポートにポートフォワードしますが、今回は SSL に対応したので 443 番も忘れずに設定しておきます。
docker-compose の yaml ファイルでコンテナを定義している場合はそこに追記します。
1 2 3 | ports: - "10080:80" - "10443:443" |
これで https でアクセスが可能となりますが、サーバ証明書がオレオレ証明書なので、ブラウザでアクセスする際は警告を例外として扱うようにしましょう。
次回はクライアント証明書の認証も、コンテナビルド時に設定する方法を紹介していきます。