🐡

ローカル環境でEC CUBEのSSLを有効にする

2022/06/15に公開

案件での技術検証としてEC CUBEのgraphqlをローカルで試したいと思ったのですが、
EC CUBEのgraphqlの要件として、SSLの環境をローカルに用意する必要がありました。

ただ公式のdockerイメージだとコンテナを起動しただけでは、SSLは有効になっておらず、リファレンスにも載っていないので、EC CUBEのdockerで、SSLを有効にする方法を紹介します。

https://doc.ec-cube.net/eccube-api4/

前提

システム構成、バージョン

ミドルウェア、ソフトウェア バージョン
EC CUBE 4.1.2
docker Docker version 20.10.14,
Mac(OS) Big Sur, バージョン11.6

コンテナの構成(docker-compose.yml)

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証明書を発行することができるということがググっていると分かりました。

https://symfony.com/doc/current/setup/symfony_server.html#enabling-tls

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

https://github.com/FiloSottile/mkcert

もともと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認証ができていたら完了です。
お疲れ様でした。

参考にしたサイト

https://qiita.com/ucan-lab/items/c7f0690227ce7da4a172

https://amidaike.hatenablog.com/entry/2018/12/15/121816

https://qiita.com/gologo13/items/7e4e404af80377b48fd5

https://re-engines.com/2019/02/28/mkcertで簡単にオレオレ証明書を発行する/

補足

このあとにgraphqlを試してみましたが、graphqlのクライアントとしてつかっていたInsomniaだと、うまく認証ができませんでした。
とはいえ、案件ではいろいろな点を鑑みるとgraphqlを利用しない方針になりました。

トラブルシューティング) https://localhostにリダイレクトされてしまう

https://www.pluve.work/blog/2020-01-16-mkcertをアンインストールしたら、localhostがhttpsから戻らなくなった問題(htst)/

Discussion