ローカル環境でEC CUBEのSSLを有効にする
案件での技術検証としてEC CUBEのgraphqlをローカルで試したいと思ったのですが、
EC CUBEのgraphqlの要件として、SSLの環境をローカルに用意する必要がありました。
ただ公式のdockerイメージだとコンテナを起動しただけでは、SSLは有効になっておらず、リファレンスにも載っていないので、EC CUBEのdockerで、SSLを有効にする方法を紹介します。
前提
システム構成、バージョン
ミドルウェア、ソフトウェア | バージョン | |
---|---|---|
EC CUBE | 4.1.2 | |
docker | Docker version 20.10.14, | |
Mac(OS) | Big Sur, バージョン11.6 |
コンテナの構成(docker-compose.yml)
services:
### ECCube4 ##################################
ec-cube:
build:
context: .
args:
# ビルド時のECCubeインストールスクリプトをスキップする場合にtrueを指定する。
# ビルド時点でDBサーバの起動や接続が出来ない、という場合等にエラーとなるため。
SKIP_INSTALL_SCRIPT_ON_DOCKER_BUILD: "true"
ports:
- 8099:80
## ビルトインサーバで利用するポート
- 9000:8000
- 4430:443
volumes:
- ".:/var/www/html:cached"
- "./dockerbuild/xdebug.ini:/usr/local/etc/php/conf.d/xdebug.ini"
### 同期対象からコストの重いフォルダを除外 #####################
- "var:/var/www/html/var"
- "vendor:/var/www/html/vendor"
方針1) symfony cliを使ってSSLを有効にする
方針1は、symfony cliでSSLの設定ファイルを生成して、Mac(ホストOS)で認証するという方法です。
具体的には以下の方針ですすめます。
- symfony cliのコマンドをインストールする
- symfony cliでSSLを発行する
- sslで使うファイルをボリュームマウントする
- Mac(ホストOS)でそのSSLを認証する(オレオレ証明書)
そして結論から言うと、この方法は途中で諦めました。
理由としては最初からEC CUBEのDockerイメージの中でSSLの設定のファイルが生成されているのを発見したからです。
eccubeのコンテナにsymfony cliをインストールする
symfony cliというsymfonyのツールがあり、次のコマンド実行するとSSL証明書を発行することができるということがググっていると分かりました。
EC CUBEのDockerfileに以下を追記します。これでsymfony cliをインストールすることができます。
RUN curl -sS https://get.symfony.com/cli/installer | bash
RUN mv /root/.symfony/bin/symfony /usr/local/bin/symfony
Dockerイメージをビルドしてコンテナを起動できたら、コンテナの中で以下のコマンドを実行します。
するとよしなにSSLが有効になります。
symfony server:ca:install
ここまででSSLの設定については完了です。
Mac(ホストOS)にmkcertをインストールする
Mac側でコンテナに設置したSSLを認証します。そのためにmkcertというアプリ?を使います。
以下のコマンドをmacのターミナルに入力するとインストールできます。
brew install mkcert
インストールできたら、以下のような感じでコマンドを実行するとSSLを認証することができます。
// localhostへの認証ファイルとしてlocalhost-cert.pem, localhost-cert.keyを指定しています
mkcert -cert-file localhost-cert.pem -key-file localhost-cert.key localhost
もともとSSLの設定ファイルが生成されていることに気づく
ここまで作業したところで、Dockerfileを眺めていると、もともとdockerイメージに含まれていることに気づきました。
RUN ln -s /etc/apache2/sites-available/default-ssl.conf /etc/apache2/sites-enabled/default-ssl.conf
EXPOSE 443
設定ファイル(default-ssl.conf)を見てみると、以下のような記述がありました。
# A self-signed (snakeoil) certificate can be created by installing
# the ssl-cert package. See
# /usr/share/doc/apache2/README.Debian.gz for more info.
# If both key and certificate are stored in the same file, only the
# SSLCertificateFile directive is needed.
SSLCertificateFile /etc/ssl/certs/ssl-cert-snakeoil.pem
SSLCertificateKeyFile /etc/ssl/private/ssl-cert-snakeoil.key
更にそれぞれのディレクトリにもファイルが存在することも確認しました。
root@e8d2025d158d:/var/www/html# ls /etc/ssl/certs/ssl-cert-snakeoil.pem
/etc/ssl/certs/ssl-cert-snakeoil.pem
root@e8d2025d158d:/var/www/html# ls /etc/ssl/private/ssl-cert-snakeoil.key
/etc/ssl/private/ssl-cert-snakeoil.key
なので、この時点でsymfony cliでの証明書は使わない判断をしました。
方針2) EC CUBEのDockerイメージのSSLを利用する
前述した通り、EC CUBEのdockerイメージにSSLの設定ファイルがすでにあったのでこれを利用します。
少し動作確認をしてみると毎回SSLの設定ファイルの内容が都度生成されていることがわかりました。
チェックしたコンテナのディレクトリはここです。
SSLCertificateFile /etc/ssl/certs/ssl-cert-snakeoil.pem
SSLCertificateKeyFile /etc/ssl/private/ssl-cert-snakeoil.key
Dockerイメージのなかで毎回SSLの設定ファイルが新しいものができてしまうのは、Mac側としては都合が悪いのでSSLの設定ファイルはホストからコピーするように工夫する。
- コンテナ内のSSLの設定ファイルをMac側(ホストOS)にコピーする
- Mac側にコピーしたSSLの設定ファイルを、再度、コンテナ内にコピーする
- Mac(ホストOS)でそのSSLを認証する(オレオレ証明書)
コンテナのSSLのファイルをmac(ホストOS)にコピーする
コンテナのSSLの設定ファイルをmac側にコピーします。
docker cp <container ID>:/etc/ssl/certs/ssl-cert-snakeoil.pem ssl-cert-snakeoil.pem
docker cp <container ID>:/etc/ssl/private/ssl-cert-snakeoil.key ssl-cert-snakeoil.key
Mac側にコピーしたSSLの設定ファイルを、再度、コンテナ内にコピーする
mac側にコピーしたファイルをコンテナ内にSSLの設定ファイルをコピーします。
ファイルのコピーはdockerイメージビルド時にするため、Dockerfileに次の記述を追記します。
COPY ssl-cert-snakeoil.pem /etc/ssl/certs/
COPY ssl-cert-snakeoil.key /etc/ssl/private/
mac(ホストOS)からmkcertでSSLを認証する
ホストOSのMacをSSLの認証局として、コンテナのSSLを認証します。
Mac(ホストOS)におとしておいた、SSLの認証のファイルをmkcertで認証する
localhostというアクセスに対して、コマンドに指定したSSLの設定ファイルで認証するようにします。
mkcert -cert-file ssl-cert-snakeoil.pem -key-file ssl-cert-snakeoil.key localhost
ここまできたらhttps://localhost にアクセスします。以下のようにSSL認証ができていたら完了です。
お疲れ様でした。
参考にしたサイト
補足
このあとにgraphqlを試してみましたが、graphqlのクライアントとしてつかっていたInsomniaだと、うまく認証ができませんでした。
とはいえ、案件ではいろいろな点を鑑みるとgraphqlを利用しない方針になりました。
https://localhostにリダイレクトされてしまう
トラブルシューティング)https://www.pluve.work/blog/2020-01-16-mkcertをアンインストールしたら、localhostがhttpsから戻らなくなった問題(htst)/
Discussion