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 を完全に削除してアンインストールする方法

推薦する

上部の固定divは半透明効果に設定できます

コードをコピーコードは次のとおりです。 <!DOCTYPE html PUBLIC "...

個人的な意見: デザインについて語る

<br />最も実用的なものを選んで話しましょう。まず、勤務先の都市を慎重に選ぶ必要があ...

Vueはカスタム命令を使用してページの下部に透かしを追加します

プロジェクトシナリオプロジェクトの背景全体にカスタム透かしを追加します。透かしのテキスト、フォントの...

MySQLはinet_atonとinet_ntoaを使用してIPアドレスデータを処理します。

この記事では、適切な形式を使用して IP アドレス データをデータベースに保存し、IP アドレスを簡...

openlayers6のマップオーバーレイの詳細な説明

1. オーバーレイの概要オーバーレイとは、その名の通り、別の形で地図上に表示される、覆うことを指しま...

MySql マスタースレーブレプリケーションメカニズムの包括的な分析

目次マスタースレーブレプリケーションメカニズム非同期レプリケーション準同期レプリケーションマスタース...

Vue命令の動作原理と実装方法

Vue の紹介現在のビッグフロントエンドの時代は、混乱と衝突の時代です。世界は多くの派閥に分かれてお...

Nodejsはgitee実装コードに自動的に同期するドキュメント同期ツールを作成します

本来の意図このツールを作った理由は、コンピューターを使用しているときにいつでも毎日の仕事や生活を記録...

Sqoop エクスポート マップ 100% 削減 0% さまざまな理由と解決策でスタック

私はこのようなバグを典型的な「ハムレット」バグと呼んでいます。これは、「エラーメッセージは同じだが、...

MySQL マルチテーブル結合クエリの詳細な説明

目次複数テーブル結合クエリ内部結合左結合右結合サブクエリ要約する複数テーブル結合クエリテーブル間の接...

さまざまなターミナルで Mac が SSH 経由でリモート サーバーに接続する方法の説明

Macはシェル(ターミナル)SSHを使用してリモートサーバーに接続します前提条件: 接続する必要があ...

JavaScriptはクリックするとランダムなグラフィックを生成します

この記事では、クリックするとランダムグラフィックの生成を実現するJavaScriptの具体的なコード...

1 つの記事で JSON (JavaScript Object Notation) を理解する

目次JSONが登場JSON構造JSONオブジェクトJson オブジェクトと JavaScript オ...

MySQL における一般的な高度な SQL ステートメント

MySQL 高度な SQL ステートメント kgc を使用します。 テーブルlocation(Reg...

HTMLページでチェックボックスを操作する方法

チェックボックスは Web ページで非常によく使用されます。e コマースの Web サイトでもプラッ...