Reverse Proxy SSL証明書の集中管理

Webサーバー サイトの管理
Reverse Proxy サーバーで
SSL証明書を集中管理する
 
リバースプロキシとWebサーバー間も【HTTPS】通信にしていたが、「SSL証明書」の更新に手間がかかるので、リバースプロキシでの一括管理に変更する。
 
リバースプロキシとWebサーバー間を【HTTP】通信にした設定
 
以下、Reverse Proxy で、SSL証明書を集中管理する方式に切り替えた記録。
 
 

 

スポンサー リンク

 

 
 
 
 
 
1. リバースプロキシの構成と nginx の設定
 
リバースプロキシ構成に於ける、nginx の設定一覧。
 
リバースプロキシにおけるnginxの設定要件
 
 
 
2. リバースプロキシとWebサーバー間を【HTTPS】通信にした設定
 
上図、リバースプロキシ内の【wordpress.conf】と、バックエンドのドメイン別Webサーバー【arakan60.conf】の設定例。
 
 
リバースプロキシとWebサーバー間を【HTTPS】通信にした設定
 
 
この場合、「リバースプロキシとWebサーバー」双方に「SSL証明書」を配置する必要がある。この為に、①.「SSL証明書」の更新は、Webサーバーで行い、②.証明書のコピーをリバースプロキシにもアップロードする、という手間がかかる。
 
1. リバースプロキシでの、バックエンドサーバー(Webサーバー)設定。
上図、リバースプロキシ内の【wordpress.conf】。
server {
    listen 80;
    server_name arakan60.com;
    rewrite ^(.*)$ https://$host$1 permanent;
}

server {
    listen 443 ssl;
    server_name arakan60.com;

    ssl_certificate /etc/letsencrypt/live/arakan60.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/arakan60.com/privkey.pem; 

    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $http_host;

    proxy_max_temp_file_size 0;

    location / {
        proxy_pass https://192.168.11.106;

    --- 以下省略 ---
 
http://url 】でのアクセスを、全て【 https://url 】にリダイレクトし、SSLの暗号化処理を行う設定になっている。
 
バックエンドのWebサーバーを指定する、【proxy_pass】のURLを【https】で設定する。
 → 【proxy_pass https://192.168.11.xxx;】。
 
 
2. Webサーバーでの、nginx 設定。
上図、バックエンドのWebサーバーの【arakan60.conf】。
server {
        listen 80;
	server_name arakan60.com;
        return 301 https://arakan60.com$request_uri;
}

server {
	listen 443 ssl;
	server_name arakan60.com;
	root /home/yaopi/www/wordpress;
	index index.htm index.php;
	
	# ssl on;
	ssl_certificate /etc/letsencrypt/live/arakan60.com/fullchain.pem;
	ssl_certificate_key /etc/letsencrypt/live/arakan60.com/privkey.pem; 

	# クライアントのIPアドレス取得
        set_real_ip_from    192.168.11.104; 
        real_ip_header      X-Forwarded-For;

    --- 以下省略 ---
 
Webサーバー側でも同じように【 http://url 】のアクセスを、全て【 https://url 】にリダイレクトし、SSLの暗号化処理を行う設定になっている。
 
 
 
3. リバースプロキシとWebサーバー間を【HTTP】通信にした設定
 
リバースプロキシとWebサーバー間は、【HTTP】通信にする。
 
但し、バックエンドのWebサーバーにアクセスするURLは、【https】のままで良い。
 
 
リバースプロキシとWebサーバー間を【HTTP】通信にした設定
 
 
「SSL証明書」は、リバースプロキシにのみ配置すればよく、集中管理が可能となる。従って「SSL証明書」の更新も、リバースプロキシ側だけで行える。
 
1. リバースプロキシでの、バックエンドサーバー(Webサーバー)設定。
上図、リバースプロキシ内の【wordpress.conf】。
server {
    listen 80;
    server_name arakan60.com;

    location ^~ /.well-known {
        root /home/yaopi/www/wordpress; ← ①
    }

    rewrite ^(.*)$ https://$host$1 permanent;
}

server {
    listen 443 ssl ssl http2;
    server_name arakan60.com;

    location ^~ /.well-known {
        root /home/yaopi/www/wordpress; ← ①’
    }

    ssl_certificate /etc/letsencrypt/live/arakan60.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/arakan60.com/privkey.pem; 

    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $http_host;

    proxy_max_temp_file_size 0;

    location / {
        proxy_pass http://192.168.11.106; ← ②

    --- 以下省略 ---
 
①.80ポート接続を、全て443ポート(https)にリダイレクトさせていたが、SSL証明書を更新する場面で、Let's Encrypt がポート80に接続に来るので、ポート80に /.well-known の locationディレクティブを設けて、rootでトークンへのパスを明示する。
 
①’
※:証明書の更新(2020.10.02 追記)
https://arakan60.com/.well-known/acme-challenge/xxxxx
 で、トークンにアクセスされるので、
ポート 443 に /.well-known の locationディレクティブが必要。
 
 
②.バックエンドのWebサーバーを指定する、【proxy_pass】として設定するURLを【http】にする。
 → 【proxy_pass http://192.168.11.xxx;】。
 
 
2. Webサーバーでの、nginx 設定。
上図、バックエンドのWebサーバーの【arakan60.conf】。
server {
        listen 80;
	server_name arakan60.com;
	root /home/yaopi/www/wordpress;
	index index.htm index.php;
	
	# クライアントのIPアドレス取得
        set_real_ip_from    192.168.11.104; 
        real_ip_header      X-Forwarded-For;

    --- 以下省略 ---
 
「server」ディレクティブが「listen 80;」のみになり、WebサーバーにSSLの暗号化負荷がかからなくなる。
 
 
3. WordPressでの設定。(wp-config.php に追記。)
注意: FORCE_SSL_LOGIN は、Version 4.0 で廃止されたので設定不要。
次の2行を「wp-config.php」の先頭位置に追記。
 * @package WordPress

 */

define('FORCE_SSL_ADMIN', true);
$_SERVER['HTTPS'] = 'on';
 
WordPressを強制的にSSL化することで、WordPressが吐き出す絶対URLが
<script src="https://..." ></script>
となる。
 
参考にした WordPress.ORG:

 管理画面へのアクセスを簡単にかつ強制的に SSL 接続にするには

 リバースプロキシの使用 #

SSL を提供するリバースプロキシにより WordPress がホストされ、自身は SSL なしでホストされる場合、このオプションを設定すると当初すべてのリクエストが無限リダイレクトループに陥ります。これを避けるには HTTP_X_FORWARDED_PROTO ヘッダーを認識するように WordPress を構成してください。ここでリバースプロキシは適切に構成されており、ヘッダーを設定するものとします。

define('FORCE_SSL_ADMIN', true);
if ( ! empty( $_SERVER['HTTP_X_FORWARDED_PROTO'] ) && $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https' ) {
       $_SERVER['HTTPS']='on';
}
 
 
 
4. SSL Server Test(Qualys SSL Labs)結果
 
「リバースプロキシ」のSSL脆弱性診断結果。
「リバースプロキシ」のSSL脆弱性診断結果
 
グレードは「A+」で、問題なし。
 
「Webサーバー」のSSL脆弱性診断結果。
「Webサーバー」のSSL脆弱性診断結果
 
グレードは「A」で、
This site works only in browsers with SNI support.
という、但し書きがある。
 
参考:nginx.conf に於ける、SSL に関する設定。
	#
	# SSL に関する設定 ここから
	#

	#SSLセッションをキャッシュさせる
        ssl_session_cache shared:SSL:50m;

	#SSLセッションのタイムアウト
        ssl_session_timeout 1d;	

	#SSLセッションチケットは使わない
	ssl_session_tickets off;
	
	#利用するプロトコルを指定する
	ssl_protocols TLSv1.2 TLSv1.3;

	#サーバ指定のcipherにする
        ssl_prefer_server_ciphers on;

	#利用するcipherを指定
	ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
	
	#鍵長を 2048ビットにする
	ssl_dhparam /etc/ssl/dhparam.pem;

	#Strict Transport Security を長期(1年)に指定
	add_header Strict-Transport-Security 'max-age=31536000; includeSubDomains; preload';	
	
	#
	# SSL ここまで
	#
 
 
 
5. SNI support とは
 
「Reverse Proxy で、SSL証明書を集中管理する方式」に切り替えたため、一つのサーバーで【複数のSSL証明書】を運用する事になった。
 
 

 SNI(Server Name Indication)とは
 一つのサーバーで複数のドメイン名を使用する場合に、 複数のSSL証明書を運用できるようにするSSL/TLSの拡張仕様です。

 
 

 1つのサーバーに複数のドメインが設定されている際の問題点
 SSL証明書は基本的に、1つのサーバー(1つのグローバルIPアドレス)に対して1ドメイン分しか利用できません。
 HTTPSプロトコルは、そのWebサイトにアクセスする前にまず特定のクライアントと、SSL証明書が設定されたサーバーとの間でSSLセッションを確立し、その中で暗号化通信を行います。
 セッションを確立する際にはまだクライアントがアクセスしたいドメインをサーバーは予測することが出来ないので、例えば1つのサーバーに複数のドメインが設定されていたとしても、ドメインごとにSSL証明書を使い分けることが出来ませんでした。
 例えばHTTPS通信を行いたいWebサイトを、複数のユーザーが利用しているレンタルサーバーで運用していて、全員が独自ドメインを取得していた場合はどうなるでしょう。あるサーバーに対してSSL証明書は1枚1ドメイン分しか利用できないので、ユーザー全員が同じドメインを使ってSSL通信を行わなければいけないことになります。

 
 

 名前ベースバーチャルホスト
 1つのサーバー(1つのグローバルIPアドレス)で複数のドメインを利用する技術のことを「名前ベースバーチャルホスト」と呼びます。
 一方、1つのサーバーに複数のグローバルIPアドレスを割り当てる技術のことを「IPベースバーチャルホスト」と呼びますが、この場合であれば各グローバルIPアドレスに対してユニークなSSL証明書を設定することが可能です。 ただし1つのサーバーに対して複数のグローバルIPアドレスを割り当てるには技術的にも金銭的にもコストが高くなり、HTTPS通信の実現に対するハードルは高まってしまいます。

 
 

 この問題を解決するためにSNI(Server Name Indication)が登場
 名前ベースバーチャルホストの技術が使われている場合において、SNIはドメインごとに異なるSSL証明書の運用を実現します。
 具体的にはSSLセッションを確立する際、クライアントブラウザがHTTPリクエストのHostヘッダを利用して、アクセスしたいドメインをサーバーへ通知します。するとサーバーも応答すべきドメインを理解することが出来るので、名前ベースバーチャルホストの場合でも正しいドメインでHTTPS通信が出来るという仕組みです。
 SNIはSSL/TLSの拡張的な仕様としてRFC(Request for Comments)にも記載されており、現在では多くのブラウザ、サーバーで対応しています。

 
 
 
6. Duplicator の installer.phpでの引越についての注意点
 
HTTP】通信にしたWebサーバーで稼働している「WordPress」を、バージョンアップ等で引越をする必要に迫られる時がある。
 
Duplicator を使って引越す場合、installer.php で「デプロイ」を行う際に、【wp-config.php】が存在するとエラーが出るので、【wp-config.php】をリネームするか削除する。
 
 
この状態で、installer.php での「デプロイ」は、問題なく動く。
 
 
但し、installer.php の最後のステップで、「Admin Login」をクリックすると、
installer.php の最後のステップで、「Admin Login」をクリックする
 
「wp-login.php」へのアクセスで、無限リダイレクトループに陥る
「wp-login.php」へのアクセスで、無限リダイレクトループに陥る
 
 
「Admin Login」をクリックする前に、
【wp-config.php】を編集して強制的にSSL化すれば、
問題なくログインできる。
 
 
参考:WordPressを強制的にSSL化せずにインストールを実行すると、画面が崩れるがインストールは可能である。
WordPressを強制的にSSL化せずにインストールを実行すると、画面が崩れるがインストールは可能
 
 
参考:
 
以上。
(2020.09.12)
 

 

スポンサー リンク

 

             

 

 

 

コメントを残す

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

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください