Dockerのapache環境でHTTPSの設定

Dockerのapache環境でHTTPSの設定をしてアクセスできるようにしてみます。

SSL証明書(オレオレ証明書)の作成

まず、SSL証明書を作成します。

コマンド

コマンドはapacheのサイトに記載されている以下のコマンドを使います。

openssl req -new -x509 -nodes -out server.crt -keyout server.key

https://httpd.apache.org/docs/2.4/ssl/ssl_faq.html

実行

実行結果が以下です。

$ openssl req -new -x509 -nodes -out server.crt -keyout server.key
Generating a 2048 bit RSA private key
........................+++
..........................................+++
writing new private key to 'server.key'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) []:
State or Province Name (full name) []:
Locality Name (eg, city) []:
Organization Name (eg, company) []:
Organizational Unit Name (eg, section) []:
Common Name (eg, fully qualified host name) []:localhost
Email Address []:
$

コマンドを実行すると入力が求められます。ここでは「Common Name」だけ入力しています。

全てデフォルトでOKとの記事もありましたが、私の環境では全てデフォルトだとエラーになりファイルが作成されませんでした。

Docker関連作業

Dockerfile作成

Dockerfileを作成します。記載する内容は以下です。

COPY ./confssl/*    /usr/local/apache2/conf/

RUN sed -i \
        -e 's/^#\(Include .*httpd-ssl.conf\)/\1/' \
        -e 's/^#\(LoadModule .*mod_ssl.so\)/\1/' \
        -e 's/^#\(LoadModule .*mod_socache_shmcb.so\)/\1/' \
        conf/httpd.conf

先ほど作成したSSL証明書のファイルを「confssl」に置いているので、それらのファイルを「/usr/local/apache2/conf/」にコピーしするようになっています。

また、RUNの部分は、httpd(docker)の公式に記載のものと同じになっています。このRUNコマンドはデフォルトの「conf/httpd.conf」ではhttps(ssl)関連の設定がコメントアウト(#始まり)になっているので、そのコメントアウトを外すようになっています。

Dockerイメージ作成(ビルド)

作成したDockerfileを元にDockerイメージを作成します。

$ docker build -t my-apache2-https .
Sending build context to Docker daemon  11.78kB
Step 1/3 : FROM httpd:2.4
 ---> c562eeace183
Step 2/3 : COPY ./confssl/*    /usr/local/apache2/conf/
 ---> Using cache
 ---> a79fcc1ccc82
Step 3/3 : RUN sed -i         -e 's/^#\(Include .*httpd-ssl.conf\)/\1/'         -e 's/^#\(LoadModule .*mod_ssl.so\)/\1/'         -e 's/^#\(LoadModule .*mod_socache_shmcb.so\)/\1/'         conf/httpd.conf
 ---> Using cache
 ---> 5d31961793c6
Successfully built 5d31961793c6
Successfully tagged my-apache2-https:latest
$

無事に成功しました。イメージ名は適当に「my-apache2-https」としています。

コンテナ起動

作成したDockerイメージを起動します。

$ docker run -dit --name my-https-app -p 80:80 -p 443:443 my-apache2-https
f7e29729cf2c69fbc0f2c3cd53adcc960d44b6e1401b3a14fce16200abbb67a0
$

無事に起動できました。ここではhttpとhttpsの両方でアクセスできるように、80番ポートと443番ポートの両方を割り当てています。

アクセス(動作確認)

httpでアクセス

まずは普通にhttpでアクセスしてみます。

$ curl http://localhost
<html><body><h1>It works!</h1></body></html>
$

無事にアクセスできました。

httpsでアクセス

次にhttpsでアクセスしてみます。

$ curl --cacert confssl/server.crt https://localhost:443
<html><body><h1>It works!</h1></body></html>
$

こちらもアクセスできました。なお、アクセスの際には作成したSSL証明書を使ってアクセスしています。(「–cacert confssl/server.crt」の部分)

補足(エラーなど)

オプションなしでのhttpsアクセス

–cacert のオプションを外してアクセスすると以下のようになります。

$ curl https://localhost
curl: (60) SSL certificate problem: self signed certificate
More details here: https://curl.haxx.se/docs/sslcerts.html

curl performs SSL certificate verification by default, using a "bundle"
 of Certificate Authority (CA) public keys (CA certs). If the default
 bundle file isn't adequate, you can specify an alternate file
 using the --cacert option.
If this HTTPS server uses a certificate signed by a CA represented in
 the bundle, the certificate verification probably failed due to a
 problem with the certificate (it might be expired, or the name might
 not match the domain name in the URL).
If you'd like to turn off curl's verification of the certificate, use
 the -k (or --insecure) option.
HTTPS-proxy has similar options --proxy-cacert and --proxy-insecure.
$

SSL証明書作成時の名前と一致しない場合

SSL証明書作成時の「Common Name」とアクセスする際のドメインが一致しない場合は以下のようになります。(以下は「masaki-blog.net」を指定した例になります。)

$ curl --cacert confssl/server.crt https://localhost
curl: (51) SSL: certificate subject name 'masaki-blog.net' does not match target host name 'localhost'
$

SSL証明書の検証を無視

curlのアクセスでSSL証明書の検証を無視する場合は「-k」オプションをつければOKです。

$ curl -k https://localhost
<html><body><h1>It works!</h1></body></html>
$

作成物

今回作成したものは以下に置いています。

https://github.com/masaki-code/docker/tree/master/apache/https

コメント

タイトルとURLをコピーしました