好奇心を追いかけて

Chasing My Curiosities

Dockerでnginxサーバを構築して自己証明書でHTTPS通信を実現する方法

やりたいこと

  • Dockerでnginxサーバを構築(Port 80, 443)
  • 証明書はオレオレ(自己証明書)を使用
  • nginxはリバースプロキシの用途

方法

手順についてまとめます。

コンテナ作成

以下のdockerコマンドを叩きます。ポートは「ホストのポート番号:コンテナのポート番号」で記述します。例として、8080:80に変更するとhttp://localhost:8080でnginxのサンプルページが表示されるようになります。-dを付け忘れるとコンテナがupにならないので注意。

% sudo docker run --name my-nginx -p 80:80 -p 443:443 -d nginx:latest
% sudo docker exec -it my-nginx bash

default.confの書き換え

OSはdebianを想定しています。

% apt update
% apt install vim
% cd /etc/nginx 
% vim conf.d/default.conf

confファイルを別に作る場合には/etc/nginx/nginx.confのimportを変更するのを忘れずに。

default.confに以下を記載します。

server {
    listen      80;
    listen 443 ssl;  # SSL
    ssl_certificate     /etc/nginx/ssl/server.crt;  # サーバ証明書
    ssl_certificate_key /etc/nginx/ssl/server.key;  # 秘密鍵
    server_name  localhost;

    access_log /var/log/nginx/nginx.vhost.access.log;
    error_log /var/log/nginx/nginx.vhost.error.log;

    # リバースプロキシ
    location / {
        proxy_pass https://www.google.com:443/;
    }

    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }
}

今回はリバースプロキシとしての役割を持たせるためにlocationを指定して別のURLにアクセスさせています。飛ばす先がないので適当にgoogle.comを記載。

ssl on;を記述すると80番もSSL扱いになるので注意してください。listenディレクティブの443でsslパラメータを指定しているため不要です。

OpenSSLで自己証明書を発行

nginxコンテナ内で直接証明書を発行します。

% mkdir ssl
% cd ssl
% openssl genrsa 4096 > server.key  # 秘密鍵
% openssl req -new -key server.key > server.csr  # 証明書著名要求
% openssl x509 -req -days 3650 -signkey server.key < server.csr > server.crt  # サーバ証明書

確認

通常のnginxであればsystemctl restart nginxで再起動しますが、今回はdockerコンテナなのでコンテナを再起動します。

% nginx -t  # 重要 : ここでエラーを吐く場合、コンテナが再起動できなくなる
% exit
% sudo docker restart [コンテナID]

動確

ブラウザでhttpやhttpsでアクセスできればOKです。

オプション

CentOSのコンテナにnginxを入れる

上記のようにdebianを使いたくない場合。

% sudo docker run --name my-centos7 -p 80:80 -p 443:443 -d centos:centos7
% sudo docker exec -it my-centos7 bash 

以下の内容で/etc/yun.repos.d/nginx.repoを追加します。

[nginx]
name=nginx repo
baseurl=http://nginx.org/packages/centos/7/$basearch/
gpgcheck=0
enabled=1

nginxをyumでインストールします。

% yum update
% yum install nginx
% systemctl enable nginx
% systemctl start nginx

dockerコンテナでSystemctlを使う (非推奨)

上記ではsystemctlではなくdocker restartでnginxの再起動を行っていますが、dockerコンテナ内でsystemctlを使用する方法は一応あるようです。privilegedを有効かつ/sbin/initで起動実行することで特権モードでコンテナが立ち上がります。

% sudo docker run -d --privileged --name my-centos centos:centos7 /sbin/init
% sudo docker exec -it my-centos bash

ただしプロセスが暴走する可能性があったり、そもそもコンテナの使い方としてよろしくないため非推奨ですのでご注意を。