この記事では、「ローカルにDockerで立てたApacheでHTTPS通信する手順」を解説します。
この記事の内容を実践すれば、ローカルでApacheでのHTTPS通信が可能となるので、ぜひ参考にして頂けると嬉しいです。
- Apache:2.4.38(Debian)
- PHP:8.0.6
- Laravel:8.40.0
HTTPS通信(SSL/TLS暗号化通信)の流れ
ApacheでHTTPS通信をする手順を解説する前に、実際にApacheでどのような流れでHTTPS通信が行われるかを説明します。(処理の流れのイメージを持っておいた方が何のための作業かが分かりやすいと思うので)
クライアント・サーバ間のHTTPS通信(SSL/TLS暗号化通信)は以下の流れで行われます。
- クライアントがサーバに対してHTTPSでリクエストを送ります
- サーバは公開鍵付きの証明書をクライアントに送付します(秘密鍵と違い、公開鍵は全世界にばら撒いて問題ありません)
- クライアント側で生成した共通鍵を、公開鍵を使って暗号化します
- 暗号化した共通鍵をサーバに送付します
- 暗号化された共通鍵を秘密鍵で復号化します
- クライアント・サーバ共に共通鍵を持っている状態となったので、共通鍵を使ったクライアント・サーバ間での暗号化通信が可能となります
事前にこのイメージを持っておいたら、以降の作業も理解しやすいと思います。
ちなみに、暗号化技術(共通鍵暗号方式と公開鍵暗号方式)については、以下の記事にまとめてあるので読んでみて下さい。
【Apache】ローカルに立てたDockerコンテナでHTTPS通信する方法
HTTPS通信の流れが分かったところで、具体的にローカルのApacheでHTTPS通信(SSL/TLS暗号化通信)するための手順を解説します。
今回は、Apacheで動作しているLaravelの画面をHTTPS通信経由で表示する流れを解説します。
前提として、以下のDockerfileとdocker-compose.yamlでLaravelのデフォルト画面が表示されているものとします。
FROM php:8.0-apache COPY --from=composer:latest /usr/bin/composer /usr/bin/composer RUN apt-get update && apt-get install -y \ git \ && docker-php-ext-install pdo_mysql RUN sed -i 's!/var/www/html!/var/www/app/public!g' /etc/apache2/sites-available/000-default.conf
version: '3' services: app: build: ./docker ports: - ${APP_PORT:-80}:80 volumes: - ./app:/var/www/app working_dir: /var/www/app
Laravelのローカル環境構築については、以下の記事をご参照下さい。
現状だと、https://localhostにアクセスしても何も表示されません。
これからコードに設定を追加していくことで、https://localhostでアクセスした際にLaravelのデフォルト画面を表示させることを目指します。
公開鍵・秘密鍵・サーバ証明書をサーバ側で用意
まずは、HTTPS通信で必要な公開鍵・秘密鍵・サーバ証明書をサーバ側で生成します。
実際に運用(本番環境等)でHTTPS通信を実現したい場合は、証明書は認証局(Certificate Authority/CA)の署名が入ったものを使用する必要があります。
しかし、ローカルでHTTPS通信を試したい程度なら、自分で生成した証明書を使っても問題ありません。
公開鍵・秘密鍵・サーバ証明書の生成には、OpenSSLコマンドを使います。このコマンドを使うことで、暗号化通信に必要なリソースを自分で用意することができます。
サーバ側では以下の3つのファイルを準備します。
- server.key(秘密鍵)
- server.csr(公開鍵+認証局での署名に必要な情報)
- server.crt(サーバ証明書)
それぞれのファイルを生成する際には、パスフレーズが必要です。任意の値を準備しておきましょう。
server.key(秘密鍵)の作成
まずは秘密鍵を作成します。
以下のコマンドを打って下さい。
openssl genrsa -aes128 2048 > server.key
- genrsa:RSA形式の秘密鍵を作成する
- -aes128:128ビットのAES形式で暗号化
- 2048:2048バイト長の鍵を作成
server.keyファイルが作成されたらOKです。
server.csr(公開鍵+認証局での署名に必要な情報)の作成
CSR(Certificate Signing Request)ファイルの作成には、以下のコマンドを使います。
openssl req -new -key server.key > server.csr
- req:CSRファイルを作成する際に指定
- -new:CSRを新規作成
- -key:秘密鍵ファイルを指定
ここでは、様々な情報の入力が求められると思います。
ほとんど何も入力しなくていいですが、Country Nameには国内ならJPを、Common nameにはドメイン名を含んだFQDN形式のホスト名(例:hoge.example.com)もしくはIPアドレスを指定しましょう。
あとは全部EnterでOKです。
server.crt(サーバ証明書)の作成
最後にサーバ証明書を作成します。
ここでは、公的機関ではなく、プライベートCAを使って証明書を発行します。
以下のコマンドを打って下さい。
openssl x509 -in server.csr -days 365 -req -signkey server.key > server.crt
- x509:X.509形式の証明書を発行
- -in server.csr:CSRファイルを指定
- -days 365:証明書の有効期限を指定
- -req:入力ファイルがCSRファイルであることを示す
- -signkey server.key:秘密鍵ファイルを指定
server.crtが作成されたらOKです。
Apache起動時のパスフレーズ入力を省略する(任意)
何も設定しない場合、Apacheの起動時にパスフレーズの入力が求められます。
この操作を回避するには、以下のコマンドで秘密鍵からパスプレーズを削除しておきましょう。
mv server.key server.key.org
openssl rsa -in server.key.org > server.key
Apacheに秘密鍵と公開鍵を含んだサーバ証明書を配置する
次に、Apacheの設定ファイルに秘密鍵ファイルとサーバ証明書を配置します。
今回使用するDocker環境(Debian)の場合はdefault-ssl.confに設定を追加します。
Dockerfileの設定を以下のように変更して下さい。
FROM php:8.0-apache COPY --from=composer:latest /usr/bin/composer /usr/bin/composer RUN apt-get update && apt-get install -y \ git \ && docker-php-ext-install pdo_mysql # ここから下を追加・変更 COPY ssl/server.crt /etc/ssl/certs/ COPY ssl/server.key /etc/ssl/private/ RUN sed -i 's!/var/www/html!/var/www/app/public!g' /etc/apache2/sites-available/default-ssl.conf \ && sed -i 's!/etc/ssl/certs/ssl-cert-snakeoil.pem!/etc/ssl/certs/server.crt!g' /etc/apache2/sites-available/default-ssl.conf \ && sed -i 's!/etc/ssl/private/ssl-cert-snakeoil.key!/etc/ssl/private/server.key!g' /etc/apache2/sites-available/default-ssl.conf RUN a2enmod ssl \ && a2ensite default-ssl.conf
COPYでは作成したサーバ証明書ファイル・秘密鍵ファイルをコンテナ内に配置しています。
RUNの一つ目は、ドキュメントルートの設定です。二つ目、三つ目はそれぞれサーバ証明書・秘密鍵ファイルの指定を今回配置した場所・ファイル名に合うよう書き換えています。これにより、サーバ内でサーバ証明書・秘密鍵を扱うことが可能となります。
最後のRUNでは、HTTPS通信に必要なApacheのモジュール(mod_ssl)の有効化と、default-ssl.confの有効化(sites-enabledからのシンボリックリンクを貼る)を行なっています。
次に、docker-compose.yamlを修正します。
以下のように設定を書き換えて下さい。
version: '3' services: app: build: ./docker ports: - ${APP_PORT:-443}:443 volumes: - ./app:/var/www/app working_dir: /var/www/app
ポートをHTTPのポート(80)からHTTPSのポート(443)に書き換えています。
以上で設定ファイルの準備は完了です。
Dockerコンテナを立ち上げてHTTPSでアクセスする
実際にDockerコンテナを立ち上げて、HTTPSでアクセスしてみましょう。
docker-compose up -d --build app
https://localhostでアクセスしてLaravelのデフォルト画面を表示させることができました。(URLの部分に鍵マークが付いています)
最終的なソースコードまとめ
ApacheでSSL暗号化通信をする際に必要なDockerのソースコードをまとめました。
基本的には、暗号化通信に必要なファイル(server.crt・server.key)を配置した上で以下のファイルをコピペしたら動くと思います。
FROM php:8.0-apache COPY --from=composer:latest /usr/bin/composer /usr/bin/composer RUN apt-get update && apt-get install -y \ git \ && docker-php-ext-install pdo_mysql COPY ssl/server.crt /etc/ssl/certs/ COPY ssl/server.key /etc/ssl/private/ RUN sed -i 's!/var/www/html!/var/www/app/public!g' /etc/apache2/sites-available/default-ssl.conf \ && sed -i 's!/etc/ssl/certs/ssl-cert-snakeoil.pem!/etc/ssl/certs/server.crt!g' /etc/apache2/sites-available/default-ssl.conf \ && sed -i 's!/etc/ssl/private/ssl-cert-snakeoil.key!/etc/ssl/private/server.key!g' /etc/apache2/sites-available/default-ssl.conf RUN a2enmod ssl \ && a2ensite default-ssl.conf
version: '3' services: app: build: ./docker ports: - ${APP_PORT:-443}:443 volumes: - ./app:/var/www/app working_dir: /var/www/app
【Apache】ローカルに立てたDockerコンテナでHTTPS通信する方法まとめ
今回はApacheでのHTTPS通信(SSL/TLS暗号化通信)の流れと、ローカル環境のApacheでHTTPS通信する手順を解説しました。
この記事が少しでも参考になっていれば幸いです。