katekichiのゆるブログ

普段の作業メモや日常の出来事とか

docker for mac + nginx + オレオレ証明書でローカルSSL環境を作ったメモ

nginxのローカルSSL環境が必要になり、docker for macオレオレ証明書で作ったので備忘録としてまとめました。

以下の記事を参考に構築してみました。

docker の nginx イメージの設定ファイルを眺めながら、独自ページを表示します。 - Qiita


nginxのdokcerイメージを取得

Docker Hubから最新のnginxイメージを取得する

詳細は、以下の記事を参照

$ docker pull nginx:latest

docker コマンド 基本のキ(nginx のコンテナを実行してみる) - Qiita

環境構築

$ mkdir nginx; cd $ _
$ touch Dockerfile
$ mkdir html; cd $_
$ touch index.html

$ tree
.
├── Dockerfile
└── html
    └── index.html

index.html

<html>
  <head>
     <meta charset="UTF-8">
     <title>SSL Test</title>
  </head>
  <body>
    <h1>SSL Test</h1>
  </body>
</html>

DockerFile作成

FROM nginx
COPY ./html /usr/share/nginx/html

Dockerイメージの作成とコンテナ立ち上げ

$ docker build --tag ssl-nginx .
Sending build context to Docker daemon 4.096 kB
Step 1/2 : FROM nginx
 ---> cc1b61406712
Step 2/2 : COPY ./html /usr/share/nginx/html
 ---> Using cache
 ---> 2cc22a506a12
Successfully built 2cc22a506a12

$ docker run -d --name ssl-nginx-container -p 80:80 ssl-nginx
651eb9b5642d13274aed51f535d7014754bb001bdcfdf90d7e194bcd5c188b74

ブラウザで確認(http://localhost/


SSL対応するためにオレオレ証明書の作成をします。 この辺りは、こちらを参考にしました。 DockerでNginxのコンテナを作成し、https化してWebページやサービスを公開する方法 | Black Everyday Company

$ brew list openssl 

$ mkdir keys; cd $ _
### 秘密鍵を暗号化してしまうと、コンテナ起動時(Nginx起動時)に
「Enter PEM pass phrase」とパスワードが求められ起動できないようなので暗号化はしない。###
$ openssl genrsa 2048 > server.key

### XXXXは適当に入力 ###
$ openssl req -new -key server.key > server.csr

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) [AU]:JP
State or Province Name (full name) [Some-State]:XXXX
Locality Name (eg, city) []:XXXX
Organization Name (eg, company) [Internet Widgits Pty Ltd]:XXXX
Organizational Unit Name (eg, section) []:XXXX
Common Name (e.g. server FQDN or YOUR name) []:example.com
Email Address []:hoge@example.com

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []: <--- パスワードは空白でOK
An optional company name []:

# 有効期限はざっくり100日で
$ openssl x509 -in server.csr -days 100 -req -signkey server.key > server.crt

# 現状の構成
$ tree
.
├── Dockerfile
├── html
│   └── index.html
└── keys
    ├── server.crt
    ├── server.csr
    └── server.key

nginx.confの設定

HTTP(ポート80)で受けたリクエストはHTTPS(ポート443)にリダイレクトする設定にしておきます。

server {
  listen      80;
  server_name localhost;

  return 301 https://$host$request_uri;
}

server {
  server_tokens off;

  access_log    /var/logs/access.log;
  error_log     /var/logs/error.log;

  listen      443;
  server_name localhost;

  ssl                  on;
  ssl_protocols        TLSv1 TLSv1.1 TLSv1.2;
  ssl_certificate      /etc/nginx/server.crt;
  ssl_certificate_key  /etc/nginx/server.key;

  location / {
    alias /var/www/;
  }
}

DockerFileの変更

FROM nginx

ADD ./html /var/www/html
ADD ./app.conf /etc/nginx/conf.d/app.conf
ADD ./keys/server.crt /etc/nginx/server.crt
ADD ./keys/server.key /etc/nginx/server.key

RUN chmod 755 -R /var
RUN chmod 400 /etc/nginx/server.key

EXPOSE 443
CMD ["nginx", "-g", "daemon off;"]

Dockerイメージの作成とコンテナ立ち上げ

$ docker build --tag webapp .
Sending build context to Docker daemon 12.29 kB
Step 1/9 : FROM nginx
 ---> cc1b61406712
Step 2/9 : ADD ./html /var/www/html
 ---> Using cache
 ---> 102243bc267d
Step 3/9 : ADD ./app.conf /etc/nginx/conf.d/app.conf
 ---> Using cache
 ---> 00668c5641b7
Step 4/9 : ADD ./keys/server.crt /etc/nginx/server.crt
 ---> Using cache
 ---> 85ee3c0da89a
Step 5/9 : ADD ./keys/server.key /etc/nginx/server.key
 ---> Using cache
 ---> f3095cadf8a3
Step 6/9 : RUN chmod 755 -R /var
 ---> Running in 8eab56aefa1c
 ---> 565d1f1e9f07
Removing intermediate container 8eab56aefa1c
Step 7/9 : RUN chmod 400 /etc/nginx/server.key
 ---> Running in fe5c00f05409
 ---> 02c65246caec
Removing intermediate container fe5c00f05409
Step 8/9 : EXPOSE 443
 ---> Running in 1e67a2a92994
 ---> d95cc7a21aa0
Removing intermediate container 1e67a2a92994
Step 9/9 : CMD nginx -g daemon off;
 ---> Running in 0efbccec8be8
 ---> 437f35b60db0
Removing intermediate container 0efbccec8be8
Successfully built 437f35b60db0

$ docker run -d --name webapp -p 443:443 -p 80:80 webapp
2e389797c84eb2162c0f67ab13eb865966ea70ecead1077a61055eadd869e952

ブラウザで確認(https://localhost/

f:id:katekichi:20170614162035p:plain

とりあえずできました。


最後にログは、コンテナ外に出したいのでその辺を試します。

ホストのディレクトリにマウントする

以下のように-v でホストのディレクトリにマウントするのが まずは、手っ取り早い方法かなと思いした。

$ docker run -d -p 443:443 -p 80:80 -v /tmp/sslnginx-log:/var/log/nginx webapp

Syslogで吐き出す方法もありますが、こちらは別の機会に試そうと思います。 nginx-1.7.1でsyslogにログを飛ばせるようになったので試してみた - Dマイナー志向


まとめ

最近、手を動かすことが少なくなってきているように感じたのでローカルの SSLテスト環境を作ろうと思ってやってみましたが、Dockerの理解がまだ浅かったので 良い勉強になりました。

あと普段の業務では、SSL証明書AWSのELBに配置してしまっているため、直接nginxに 設定する良い機会になりました。

今回作成した環境は、githubにあります。 GitHub - y-nakazawa/docker-sslnginx

nginx実践入門 (WEB+DB PRESS plus)

nginx実践入門 (WEB+DB PRESS plus)

nginx実践ガイド impress top gearシリーズ

nginx実践ガイド impress top gearシリーズ

ハイパフォーマンスHTTPサーバ Nginx入門

ハイパフォーマンスHTTPサーバ Nginx入門

マスタリングNginx

マスタリングNginx

Nginx ポケットリファレンス

Nginx ポケットリファレンス