Docker で nginx の https を設定する方法

Docker で nginx の https を設定する方法

https をサポートしていない Web サイトは、ブラウザによって徐々に安全でないとマークされるため、Web サイトに https を追加することが急務となっています。商用ウェブサイトの場合、SSL/TLS 証明書にお金をかけることは問題ではありません。しかし、個人ユーザーにとっては、無料の SSL/TLS 証明書が利用可能であればありがたいでしょう。 Let's Encrypt は、無料の SSL/TLS 証明書を提供する Web サイトです。証明書の有効期間は 3 か月のみなので、自動的に証明書を更新する必要があります。この記事では、docker 経由で実行されている nginx のサイトに https サポートを追加し、証明書の更新を自動的に完了する方法を紹介します。この記事のデモ環境は、Azure 上で実行されている Ubuntu 16.04 ホストです (この画像はインターネットから取得したものです)。

環境を整える

Azure 上で Ubuntu 仮想マシンを作成するのは非常に簡単で、Docker のインストールも簡単です。見落とされがちなのが、ポート 80 と 443 を開くなど、適切なネットワーク セキュリティ グループ ルールを構成することです。

DNS の設定もあります:

通常のhttpサイトを作成する

簡単にするために、ミラー内の Node.js アプリケーションを Web サイトとして使用します。

$ docker pull ljfpower/nodedemo
$ docker ネットワーク作成 -d ブリッジ webnet
$ docker run -d --restart=always --expose=3000 \
   --network=webnet --name=myweb \
   ljfpower/ノードデモ

ユーザーのホーム ディレクトリに nginx ディレクトリとそのサブディレクトリ conf.d、conf.crt、html を作成し、logs ディレクトリとそのサブディレクトリ nginx および letsencrypt を作成します。

$ mkdir -p nginx/{conf.d,conf.crt,html}
$ mkdir -p ログ/{nginx,letsencrypt}

この記事で紹介した例で手動で作成する必要があるファイルとディレクトリ構造は次のようになります。

次の内容で nginx/nginx.conf ファイルを作成します。

ユーザー nginx;
ワーカープロセスは自動です。

error_log /var/log/nginx/error.log 警告;
pid /var/run/nginx.pid;

イベント {
 ワーカー接続数 2048;
}

http {
 /etc/nginx/mime.types を含めます。
 デフォルトタイプ アプリケーション/オクテットストリーム;

 ファイル送信オン;
 キープアライブタイムアウト65;
 クライアントの最大ボディサイズは10Mです。

 /etc/nginx/conf.d/*.conf を含めます。
}

次に、次の内容の nginx/conf.d/default.conf ファイルを作成します。

上流ウェブ{
 サーバー myweb:3000;
}
サーバー{
 聞く 80;
 聞く [::]:80;
 サーバー名 filterinto.com www.filterinto.com;

 場所 ^~ /.well-known/acme-challenge/ {
  デフォルトタイプ "text/plain";
  ルート /usr/share/nginx/html;
 }
 場所 = /.well-known/acme-challenge/ {
  404 を返します。
 }
 位置 / {
  proxy_pass http://web;
 }
}

/.well-known/acme-challenge/ ディレクトリは、証明書を生成するときに certbot ツールによって作成されます。次に、次の内容の nginx/html/index.html ファイルを作成します。

<!DOCTYPE html>
<html>
<ヘッド>
 <メタ文字セット="utf-8" />
 <title>Let's Encrypt 初回証明書発行サイト</title>
</head>
<本文>
 <h1>こんにちは、HTTPS!</h1>
 <p>
  SSL証明書はLet's Encryptの
  証明書ボット。
 </p>
</本文>
</html>

このページは、certbot が証明書を生成するときに使用する必要があるものでもあります。最後に、コンテナを起動しましょう (ユーザーのホーム ディレクトリで次のコマンドを実行します)。

$ docker run -d \
 -p 80:80 \
 -v $(pwd)/nginx/conf.d:/etc/nginx/conf.d:ro \
 -v $(pwd)/nginx/nginx.conf:/etc/nginx/nginx.conf:ro \
 -v $(pwd)/logs/nginx:/var/log/nginx \
 -v $(pwd)/nginx/html:/usr/share/nginx/html \
 --restart=常に\
 --name=ゲートウェイ\
 --network=ウェブネット\
 nginx:1.14

注意: 現時点では、ポート 443 はマップされておらず、証明書を格納するディレクトリはマウントされていません。当サイトへは http: 経由でのみアクセスできます。

サイトのSSL/TLS証明書を生成する

Let's Encrypt は、無料の SSL/TLS 証明書を提供する Web サイトです。ユーザーに SSL/TLS 証明書を生成するための certbot ツールを提供します。便宜上、certbot をコンテナにカプセル化します。ユーザーのホーム ディレクトリに certbot ディレクトリを作成し、certbot ディレクトリに移動して、次のコンテンツを Dockerfile ファイルに保存します。

アルパインから:3.4
apk add --update bash certbot を実行します。
ボリューム ["/etc/letsencrypt"]

次に、次のコマンドを実行して certbot イメージを作成します。

certbot をビルドします。

次に、certbot ディレクトリに renew_cert.sh というスクリプトを作成し、証明書を自動的に更新します。内容は次のとおりです。

#!/bin/bash
WEBDIR="$1"
リスト=('filterinto.com' 'www.filterinto.com')
LED_LIST=()
WWW_ROOT=/usr/share/nginx/html
${LIST[@]}内のドメインに対して
 docker 実行 \
  --rm \
  -v ${WEBDIR}/nginx/conf.crt:/etc/letsencrypt \
  -v ${WEBDIR}/logs/letsencrypt:/var/log/letsencrypt \
  -v ${WEBDIR}/nginx/html:${WWW_ROOT} \
  証明書ボット:1.0 \
  certbot certonly --verbose --noninteractive --quiet --agree-tos \
  --webroot -w ${WWW_ROOT} \
  --email="[email protected]" \
  -d "$ドメイン"
 コード=$?
 [ $CODE -ne 0 ]の場合;
  失敗したリスト+=($domain)
 フィ
終わり

# 失敗したドメインを出力
[ ${#FAILED_LIST[@]} -ne 0 ]の場合;
 echo '失敗したドメイン:'
 (( i=0; i<${#FAILED_LIST[@]}; i++ ));
 する
  ${FAILED_LIST[$i]}をエコーし​​ます
 終わり
フィ

新しい証明書を生成するには、ユーザーのホーム ディレクトリで ./renew_cert.sh /home/nick コマンドを実行します (/home/nick は現在のユーザーのホーム ディレクトリです)。生成された証明書は、/home/nick/nginx/conf.crt/live ディレクトリに保存されます。ドメイン名の証明書は、ドメイン名にちなんで名付けられたディレクトリに保存されます。

次に、nginx/html ディレクトリを確認し、非表示の .well-known ディレクトリを見つけます。このディレクトリは、証明書が生成されるときに作成されます。

SSL/TLS 証明書を使用すると、https サイトを構成できます。

サイトのSSL/TLS証明書を構成する

SSL/TLS 証明書ができたら、次のステップは nginx 構成ファイルを更新することです。nginx/conf.d/default.conf の内容を次のように更新します。

上流ウェブ{
 サーバー myweb:3000;
}

サーバー{
 聞く 80;
 聞く [::]:80;
 サーバー名 filterinto.com www.filterinto.com;

 場所 ^~ /.well-known/acme-challenge/ {
  デフォルトタイプ "text/plain";
  ルート /usr/share/nginx/html;
 }
 場所 = /.well-known/acme-challenge/ {
  404 を返します。
 }
 301 https://$server_name$request_uri を返します。
}
サーバー{
 聞く 443;
 聞く [::]:443;
 サーバー名 filterinto.com;

 # SSLを有効にする
 sslオン;
 ssl_プロトコル TLSv1 TLSv1.1 TLSv1.2;
 ssl_prefer_server_ciphers をオン;
 ssl_ciphers "EECDH+ECDSA+AESGCM EECDH+aRSA+AESGCM EECDH+ECDSA+SHA384 EECDH+ECDSA+SHA256 EECDH+aRSA+SHA384 EECDH+aRSA+SHA256 EECDH EDH+aRSA !aNULL !eNULL !LOW !3DES !MD5 !EXP !PSK !SRP !DSS !RC4";

 # SSL証明書の設定
 ssl_certificate conf.crt/live/filterinto.com/fullchain.pem;
 ssl_certificate_key conf.crt/live/filterinto.com/privkey.pem;

 場所 ^~ /.well-known/acme-challenge/ {
  デフォルトタイプ "text/plain";
  ルート /usr/share/nginx/html;
 }
 場所 = /.well-known/acme-challenge/ {
   404 を返します。
 }
 位置 / {
  proxy_pass http://web;
 }
}
サーバー{
 聞く 443;
 聞く [::]:443;
 サーバー名 www.filterinto.com;

 # SSLを有効にする
 sslオン;
 ssl_プロトコル TLSv1 TLSv1.1 TLSv1.2;
 ssl_prefer_server_ciphers をオン;
 ssl_ciphers "EECDH+ECDSA+AESGCM EECDH+aRSA+AESGCM EECDH+ECDSA+SHA384 EECDH+ECDSA+SHA256 EECDH+aRSA+SHA384 EECDH+aRSA+SHA256 EECDH EDH+aRSA !aNULL !eNULL !LOW !3DES !MD5 !EXP !PSK !SRP !DSS !RC4";

 # SSL証明書の設定
 ssl_certificate conf.crt/live/www.filterinto.com/fullchain.pem;
 ssl_certificate_key conf.crt/live/www.filterinto.com/privkey.pem;

 場所 ^~ /.well-known/acme-challenge/ {
  デフォルトタイプ "text/plain";
  ルート /usr/share/nginx/html;
 }
 場所 = /.well-known/acme-challenge/ {
   404 を返します。
 }
 位置 / {
  proxy_pass http://web;
 }
}

次に、ゲートウェイ コンテナーを削除し、次のスクリプトを使用して再作成します。

$ docker run -d \
 -p 80:80 \
 -p 443:443 \
 -v $(pwd)/nginx/conf.d:/etc/nginx/conf.d:ro \
 -v $(pwd)/nginx/conf.crt:/etc/nginx/conf.crt:ro \
 -v $(pwd)/nginx/nginx.conf:/etc/nginx/nginx.conf:ro \
 -v $(pwd)/logs/nginx:/var/log/nginx \
 -v $(pwd)/nginx/html:/usr/share/nginx/html \
 --restart=常に\
 --name=ゲートウェイ\
 --network=ウェブネット\
 nginx:1.14

現在、このサイトには https 経由でのみアクセスできます。

自動証明書更新

Let's Encrypt が提供する SSL/TLS 証明書の有効期間は 3 か月です。3 か月ごとに手動で証明書を更新するのは非常に困難です。ここでは証明書を自動で更新する方法を紹介します。

実際、私たちの構成は自動証明書更新に最大の利便性をもたらしました (実際には、これは Docker を使用することでもたらされる利便性です)。スケジュールされたタスクに次の 2 つのレコードを追加するだけです。

0 0 1 * * /home/nick/certbot/renew_cert.sh /home/nick >> /home/nick/logs/cert.log 2>> /home/nick/logs/cert.error.log
0 1 1 * * docker exec ゲートウェイ nginx -s リロード

毎月 1 日の 0:00 に証明書を更新し、1 時間後に nginx 構成を再読み込みします。

要約する

Let's Encrypt は、初心者や個人が HTTPS サイトを簡単に (無料で) 実装するのに役立つ優れた Web サイトです。便利な反面、隠れた危険性も明らかです。SSL/TLS 証明書は誰でも何の障壁もなく取得できるため、違法な Web サイトがそれを使用して正規のサイトを装うこともできます。 したがって、HTTPS サイトが安全であると単純に想定しないでください。

以上がこの記事の全内容です。皆様の勉強のお役に立てれば幸いです。また、123WORDPRESS.COM を応援していただければ幸いです。

以下もご興味があるかもしれません:
  • Docker に nginx をインストールし、https 経由でアクセスを構成する方法
  • Dockerでnginxをデプロイし、設定ファイルを変更する方法
  • nginxはdockerコンテナ内に設定ファイルを自動的に生成します
  • docker で nginx+php+mysql を設定する方法
  • Docker nginxのインストールと設定方法
  • Dockerでnginxを実行し、ローカルディレクトリをイメージにマウントする方法
  • Docker nginx + https サブドメイン設定の詳細なチュートリアル

<<:  ログインフォームを実装するためのReactサンプルコード

>>:  Windows 10 で MySQL を完全に削除してアンインストールする方法

推薦する

Ubuntu 18.04 に MySQL をインストールする (グラフィカル チュートリアル)

ヒント: 以下の操作はすべて root 権限で実行されます。 # MySQL がインストールされてい...

フローティング要素が親要素の高さを崩す原因と解決策の詳細な説明

フローティング要素は、親要素の高さを縮小します。要素を float float:left/right...

Dockerイメージとコンテナの一般的な操作の詳細な説明

画像アクセラレータ中国の Docker Hub からイメージをプルすることが難しい場合があります。こ...

17の広告効果測定の解釈

1. 広告の 85% は未読です<br />解釈: 成功する広告の 15% にどうやって...

Vue-cli4 ルーティング構成の詳細な理解

目次序文 - Vue ルーティング1. 最も基本的なルーティング構成1. router/index....

Vue+flaskで動画合成機能を実現(ドラッグ&ドロップアップロード)

目次ドラッグアンドドロップアップロードについては以前の記事で書きました。ファイルをアップロードするF...

MySQLの始め方から諦め方まで徹底解説 - インストール

学ぶ内容1. ソフトウェアのインストールとサーバーの設定。 2. (オプションですが、強くお勧めしま...

React における useEffect と useLayoutEffect の違い

目次前提条件使用効果コミット前ミューテーション効果コミットミューテーション効果コミットレイアウト効果...

HTML コード作成ガイド

共通コンベンションタグ自己終了タグ。閉じる必要はありません (例: img input br hr ...

JSは写真の自動再生効果を実現します

この記事では、写真の自動再生効果を実現するためのJSの具体的なコードを参考までに紹介します。具体的な...

HTML テーブル マークアップ チュートリアル (38): ヘッダーの境界線の色属性 BORDERCOLOR

テーブルを美しくするために、ヘッダーに異なる境界線の色を設定できます。基本的な構文<TH 境界...

MySQL の左結合操作における on 条件と where 条件の違いの紹介

優先度両方のケースで同じ条件を設定すると、異なる結果セットが生成される可能性があるのは、優先順位のた...

MySQL グローバルロックとテーブルレベルロックの具体的な使用法

目次序文グローバルロックテーブルロックテーブルロックメタデータ ロック (MDL ロック)要約する参...

JavaScript の Set データ構造の詳細な説明

目次1. セットとは何か2. セットコンストラクタ2.1) 配列2.2) 文字列2.3) 議論2.4...

MySQLのページング制限のパフォーマンス問題についての簡単な説明

MySQL ページング クエリは通常、制限を通じて実装されます。 limit は 1 つまたは 2 ...