Nginx

Dockerを使ってローカルに立てたNginxでHTTPS通信する方法

Dockerを使ってローカルに立てたNginxでHTTPS通信する方法

この記事では、ローカルにDockerで立てたNginx(エンジンエックス)でHTTPS通信する方法を解説します。

記事の内容を実践すれば、ローカルにDockerで立てたNginxへのHTTPS通信が可能となるので、ぜひ参考にして頂けると嬉しいです。

環境情報

nginx:1.21.3

HTTPS通信(SSL/TLS暗号化通信)の流れ

まずは、実際にNginxでどのような流れでHTTPS通信が行われるかを説明します。

クライアント・サーバ間のHTTPS通信(SSL/TLS暗号化通信)は以下の流れで行われます。

NginxでのHTTPS通信(SSL/TLS暗号化通信)の流れ
  1. クライアントがサーバに対してHTTPSでリクエストを送る
  2. サーバは公開鍵付きの証明書をクライアントに送付する(秘密鍵と違い、公開鍵は全世界にばら撒いて問題ない)
  3. クライアント側で生成した共通鍵を、公開鍵を使って暗号化する
  4. 暗号化した共通鍵をサーバに送付する
  5. 暗号化された共通鍵を秘密鍵で復号する
  6. クライアント・サーバ共に共通鍵を持っている状態となったので、共通鍵を使ったクライアント・サーバ間での暗号化通信が可能となる

 

事前にこのイメージを掴んでいたら、以降の実際の作業が理解しやすくなるはずです。

 

ちなみに、暗号化技術(共通鍵暗号方式と公開鍵暗号方式)については、以下の記事にまとめてあるので気になる方は読んでみて下さい。

共通鍵暗号方式と公開鍵暗号方式について分かりやすく解説します【図解】
共通鍵暗号方式と公開鍵暗号方式について分かりやすく解説します【図解】共通鍵暗号方式と公開鍵暗号方式について図を用いて解説しました。...

 

Dockerを使ってローカルに立てたNginxでHTTPS通信する方法

HTTPS通信の流れが分かったところで、具体的にローカルにDockerで立てたNginxでHTTPS通信(SSL/TLS暗号化通信)するための手順を解説します。

 

まずはDockerでNginxを起動します。

treeコマンドでディレクトリ構成を表示
version: '3.8'
services:
  server:
    container_name: server
    build: ./docker
    ports:
      - 8081:80

 

FROM nginx

 

 

現状だと、http://localhost:8081にアクセスすると、以下のNginxのデフォルトページが表示されます。

Nginxのデフォルトページ

 

しかしHTTPSには対応していないため、https://localhost:8081にアクセスしても何も表示されません。

httpsではアクセスできない

 

ここからコードに設定を追加していくことで、https://localhost:8081でアクセスした際にNginxのデフォルト画面を表示させることを目指します。

 

NginxでHTTPSを利用するために必要なモジュールを追加

NginxでHTTPSを利用するためには、ngx_http_ssl_moduleが必要です。

しかし、Dockerイメージの場合は最初からこのモジュールは入っているため、新たにインストールする必要はありません。

ngx_http_ssl_moduleはインストールされている

 

公開鍵・秘密鍵・サーバ証明書をサーバ側で用意

次に、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です。

 

server.password(秘密鍵用のパスワードを配置したファイル)の作成

最後に、以下のコマンドで秘密鍵用のパスワードを配置したファイルを作成して下さい。(hoge123@の部分は自身の秘密鍵用のパスワードに書き換え)

echo hoge123@ > server.password

 

あとでHTTPS通信用のサーバー設定をする際に使います。

 

Nginxに秘密鍵と公開鍵を含んだサーバ証明書を配置する

証明書と秘密鍵の作成が終わったら、それらをコンテナ内に配置する処理を追加します。

また、HTTPS通信用にDockerfileやdocker-compose.yamlの記述も書き換えます。

 

最終的なディレクトリ構成は以下になる想定です。

treeコマンドで最終的なディレクトリ構成を示す

 

最初にDockerfileを以下のように書き換えて下さい。

FROM nginx

COPY nginx/ssl/server.crt /etc/nginx/ssl/server.crt
COPY nginx/ssl/server.key /etc/nginx/ssl/server.key
COPY nginx/ssl/server.password /etc/nginx/ssl/server.password

 

COPYコマンドで、先ほど作成した「証明書・秘密鍵・秘密鍵用のパスワードが書かれたファイル」をそれぞれコンテナ内にコピーしています。

 

次に、ssl.conf(HTTPS通信用のサーバー設定ファイル)を作成して下さい。

server {
    listen 443 ssl;
    root /usr/share/nginx/html;
    index index.html;

    ssl_certificate /etc/nginx/ssl/server.crt;
    ssl_certificate_key /etc/nginx/ssl/server.key;
    ssl_password_file /etc/nginx/ssl/server.password;
}

 

listenはこのサーバーが受け入れるポートです。HTTPS通信なので443を指定しています。

また、後ろの「ssl」は、指定した443番ポートでHTTPS通信を有効にするための設定です。

これが無いとHTTPSで通信できないので、しっかりと指定するようにしましょう。

 

rootとindexは、通信が上手くいった場合に画面に表示するNginxのデフォルトファイルを指定しています。

 

ssl_certificateにはサーバ証明書が配置していある場所のパス(先ほどDockerfileで指定したコンテナ側のパス)を指定しています。

 

ssl_certificateは秘密鍵が配置してある場所のパスです。

 

ssl_password_fileには秘密鍵用のパスワードが書かれたファイルのパスを指定しています。

nginxで秘密鍵を使用するためには、事前にパスフレーズを解除しておくか、ssl_password_fileディレクティブを用いてパスワードが書かれたファイルを指定する必要があるため、今回はパスワードが書かれたファイルを指定しています。

 

最後にdocker-compose.yamlです。以下のように記述して下さい。

version: '3.8'
services:
  server:
    container_name: server
    build: ./docker
    ports:
      - 8081:443
    volumes:
      - ./docker/nginx/ssl.conf:/etc/nginx/conf.d/ssl.conf

 

HTTPS通信のため、コンテナ側のポートには443を指定しています。

また、volumesで先ほど作成したssl.confをコンテナ内に配置しています。

 

HTTPS通信をするために必要な設定は以上です。

 

Dockerコンテナを立ち上げてHTTPSでアクセスする

最後に、docker-compose up -d --buildでコンテナを立ち上げ直して、HTTPS通信ができるか確認しましょう。

 

https://localhost:8081でアクセスしてNginxのデフォルト画面を表示させることができました。(URLの部分に鍵マークが付いています)

https通信でnginxのデフォルト画面にアクセス

 

最終的なソースコードまとめ(証明書以外)

最後に、今回作成した(証明書や秘密鍵以外の)ファイルをまとめておきます。

最終的なディレクトリ構成をtreeコマンドで表示

 

基本的には、暗号化通信に必要なファイル(server.crt/server.key/server.password)を配置した上で以下のファイルをコピペしたら動くと思います。

version: '3.8'
services:
  server:
    container_name: server
    build: ./docker
    ports:
      - 8081:443
    volumes:
      - ./docker/nginx/ssl.conf:/etc/nginx/conf.d/ssl.conf

 

FROM nginx

COPY nginx/ssl/server.crt /etc/nginx/ssl/server.crt
COPY nginx/ssl/server.key /etc/nginx/ssl/server.key
COPY nginx/ssl/server.password /etc/nginx/ssl/server.password

 

server {
    listen 443 ssl;
    root /usr/share/nginx/html;
    index index.html;

    ssl_certificate /etc/nginx/ssl/server.crt;
    ssl_certificate_key /etc/nginx/ssl/server.key;
    ssl_password_file /etc/nginx/ssl/server.password;
}

 

【Nginx】ローカルに立てたDockerコンテナでHTTPS通信する方法 おわりに

今回はNginxでのHTTPS通信(SSL/TLS暗号化通信)の流れと、ローカルDocker環境のNginxでHTTPS通信する手順を解説しました。

この記事が少しでも参考になっていれば幸いです。

Nginx参考書籍

関連記事

【Apache】ローカルに立てたDockerコンテナでHTTPS通信する方法
【Apache】ローカルに立てたDockerコンテナでHTTPS通信する方法ローカルに立てたApacheのDockerコンテナでHTTPS通信する方法を解説します。...

COMMENT

メールアドレスが公開されることはありません。

CAPTCHA