SSL終了を使用したNginxロードバランシングのセットアップ方法

前書き

この記事では、ロードバランサー上でSSL証明書を1つだけ使用して、SSL終了でNginxロードバランシングを設定する方法を示します。 これにより、SSL管理のオーバーヘッドが削減されます。これは、OpenSSLの更新とキーと証明書がロードバランサー自体から管理できるようになったためです。

SSL終了について

Nginxは、複数のバックエンドサーバーに着信トラフィックを分散するロードバランサーとして構成できます。 SSL終了は、ロードバランサーとバックエンドサーバー間のトラフィックがHTTPになるように、SSL暗号化/復号化を処理するロードバランサーで発生するプロセスです。 バックエンドは、ロードバランサーのIPへのアクセスを制限することで保護する必要があります。これについては、この記事で後述します。

image:https://assets.digitalocean.com/articles/nginx_ssl_termination_load_balancing/nginx_ssl.png [SSL終了図]

前提条件

このチュートリアルでは、コマンドをrootユーザーまたはsudo特権を持つユーザーとして実行する必要があります。 設定方法はhttps://www.digitalocean.com/community/articles/how-to-add-and-delete-users-on-ubuntu-12-04-and-centos-6 [ユーザーチュートリアル]。

次のガイドを参照として使用できます。

LAMPサーバーは必須ではありませんが、このチュートリアルでは例として使用します。

セットアップ

このチュートリアルでは、次の3つのドロップレットを使用します。

ドロップレット1(フロントエンド)

  • 画像:Ubuntu 14.04

  • ホスト名:loadbalancer

  • プライベートIP:10.130.227.33

ドロップレット2(バックエンド)

  • 画像:Ubuntu 14.04

  • ホスト名:web1

  • プライベートIP:10.130.227.11

ドロップレット3(バックエンド)

  • 画像:Ubuntu 14.04

  • ホスト名:web2

  • プライベートIP:10.130.227.22

ドメイン名-example.com

これらのすべてのドロップレットでは、https://www.digitalocean.com/community/tutorials/how-to-set-up-and-use-digitalocean-private-networking [プライベートネットワーク]を有効にする必要があります。

3つのサーバーすべてでソフトウェアを更新およびアップグレードします。

apt-get update && apt-get upgrade -y

*各サーバーを再起動してアップグレードを適用します。*これは重要です。OpenSSLをセキュリティで保護するには最新バージョンが必要であるためです。

アップストリームモジュールがバックエンドの負荷分散を行うドメイン名の新しいNginx仮想ホストをセットアップします。

Nginxの負荷分散を設定する前に、VPSにNginxをインストールする必要があります。 `+ apt-get`で素早くインストールできます:

apt-get install nginx

2つのバックエンドサーバーで、リポジトリを更新し、Apacheをインストールします。

apt-get install apache2

両方のバックエンドサーバーにPHPをインストールします。

apt-get install php5 libapache2-mod-php5 php5-mcrypt

詳細については、https://www.digitalocean.com/community/tutorials/how-to-install-linux-apache-mysql-php-lamp-stack-on-ubuntu-14-04 [この記事]を参照してください。

キーを生成してSSL証明書を作成する

このセクションでは、SSL証明書の作成に必要な手順を実行します。 https://www.digitalocean.com/community/tutorials/how-to-set-up-multiple-ssl-certificates-on-one-ip-with-nginx-on-ubuntu-12-04 [この記事]では説明していますNginxのSSL証明書の詳細。

SSL証明書ディレクトリを作成して、切り替えます。

mkdir -p /etc/nginx/ssl/example.com
cd /etc/nginx/ssl/example.com

秘密鍵を作成します。

openssl genrsa -des3 -out server.key 2048

パスフレーズを削除します。

openssl rsa -in server.key -out server.key

CSR(証明書署名要求)を作成します。

openssl req -new -key server.key -out server.csr

このCSRを使用して、https://www.digitalocean.com/community/tutorials/how-to-set-up-apache-with-a-free-signed-ssl-certificate-on-a-vpsから有効な証明書を取得します[認証局]または次のコマンドで自己署名証明書を生成します。

openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt

これが完了すると、このディレクトリには次のファイルが含まれます。

  • server.key-秘密鍵

  • ca-certs.pem-CAのルート証明書と中間証明書のコレクション。 CAから有効な証明書を取得した場合にのみ存在します。

  • server.crt-ドメイン名のSSL証明書

仮想ホストファイルとアップストリームモジュール

Nginxディレクトリ内に仮想ホストファイルを作成します

nano /etc/nginx/sites-available/

バックエンドサーバーのプライベートIPアドレスを含むアップストリームモジュールを追加します

upstream  {
   server ;
   server ;
}

この行の*後に*サーバーブロックを開始します。 このブロックには、ドメイン名、上流サーバーへの参照、およびバックエンドに渡す必要のあるヘッダーが含まれています。

server {
   listen 80;
   server_name ;

   location / {
       proxy_pass http://;
       proxy_set_header Host $host;
       proxy_set_header X-Real-IP $remote_addr;
       proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
       proxy_set_header X-Forwarded-Proto $scheme;
   }
}

`+ proxy_set_header +`ディレクティブは、リクエストに関する重要な情報を上流のサーバーに渡すために使用されます。

このファイルを保存し、 `+ sites-enabled +`ディレクトリへのシンボリックリンクを作成します。

ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/example.com

構成テストを実行して、エラーを確認します。

service nginx configtest

エラーが表示されない場合は、nginxサービスをリロードします。

service nginx reload

ロードバランシングがHTTP用に設定されました。

SSLを有効にする

`+ server {} +`ブロック内の仮想ホストファイル(/etc/nginx/sites-available/example.com)に次のディレクティブを追加します。 これらの行は、次の例でコンテキストで表示されます。

listen 443 ssl;
ssl on;
ssl_certificate         ;
ssl_certificate_key     ;
ssl_trusted_certificate ;

自己署名証明書を使用している場合は、「+ ssl_trusted_certificate 」ディレクティブを無視します。 これで、 ` server +`ブロックは次のようになります。

server {
   listen 80;
   listen 443 ssl;
   server_name ;

   ssl on;
   ssl_certificate         /etc/nginx/ssl//server.crt;
   ssl_certificate_key     /etc/nginx/ssl//server.key;
   ssl_trusted_certificate /etc/nginx/ssl//ca-certs.pem;

   location / {
       proxy_pass http://;
       proxy_set_header Host $host;
       proxy_set_header X-Real-IP $remote_addr;
       proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
       proxy_set_header X-Forwarded-Proto $scheme;
   }
}

構成エラーを確認し、Nginxサービスをリロードします。

service nginx configtest && service nginx reload

バックエンドサーバーのセキュリティ保護

現在、バックエンドサーバーでホストされているWebサイトには、パブリックIPアドレスを知っている人なら誰でも直接アクセスできます。 これは、プライベートインターフェイスでのみリッスンするようにバックエンドのWebサーバーを構成することで防止できます。 Apacheでこれを行う手順は次のとおりです。

`+ ports.conf +`ファイルを編集します。

nano /etc/apache2/ports.conf

次の行を見つけます。

Listen 80

これを*バックエンドサーバーの*プライベートIPアドレスに置き換えます。

Listen :80

すべてのバックエンドサーバーでこれを行い、Apacheを再起動します。

service apache2 restart

次のステップは、HTTPアクセスを*ロードバランサーの*プライベートIPに制限することです。 次のファイアウォールルールはこれを実現します。

iptables -I INPUT -m state --state NEW -p tcp --dport 80 ! -s  -j DROP

例をロードバランサーのプライベートIPアドレスに置き換え、すべてのバックエンドサーバーでこのルールを実行します。

セットアップのテスト

すべてのバックエンドサーバー(この例ではweb1とweb2)でPHPファイルを作成します。 これはテスト用であり、セットアップが完了したら削除できます。

nano /var/www/html/test.php

アクセスしたドメイン名、サーバーのIPアドレス、ユーザーのIPアドレス、アクセスしたポートを印刷する必要があります。

<?php
   header( 'Content-Type: text/plain' );
   echo 'Host: ' . $_SERVER['HTTP_HOST'] . "\n";
   echo 'Remote Address: ' . $_SERVER['REMOTE_ADDR'] . "\n";
   echo 'X-Forwarded-For: ' . $_SERVER['HTTP_X_FORWARDED_FOR'] . "\n";
   echo 'X-Forwarded-Proto: ' . $_SERVER['HTTP_X_FORWARDED_PROTO'] . "\n";
   echo 'Server Address: ' . $_SERVER['SERVER_ADDR'] . "\n";
   echo 'Server Port: ' . $_SERVER['SERVER_PORT'] . "\n\n";
?>

ブラウザまたは `+ curl `を使用して、このファイルに数回アクセスします。 自己署名証明書セットアップで ` curl -k +`を使用して、curlがSSLエラーを無視するようにします。

curl https:///test.php https:///test.php https:///test.php

出力は次のようになります。

  Host: example.com
  Remote Address: 10.130.245.116
  X-Forwarded-For: 117.193.105.174
  X-Forwarded-Proto: https
  Server Address: 10.130.227.11
  Server Port: 80

  Host: example.com
  Remote Address: 10.130.245.116
  X-Forwarded-For: 117.193.105.174
  X-Forwarded-Proto: https
  Server Address: 10.130.227.22
  Server Port: 80

  Host: example.com
  Remote Address: 10.130.245.116
  X-Forwarded-For: 117.193.105.174
  X-Forwarded-Proto: https
  Server Address: 10.130.227.11
  Server Port: 80
  • Server Address *はリクエストごとに変化し、異なるサーバーが各リクエストに応答していることを示していることに注意してください。

SSL設定の強化

このセクションでは、古い暗号とプロトコルの脆弱性を排除するためのベストプラクティスに従ってSSLを構成する方法について説明します。 このセクションには個々の行が示されており、このチュートリアルの最後のセクションに完全な構成ファイルが示されています。

SSLセッションキャッシュを有効にすると、HTTPS Webサイトのパフォーマンスが向上します。 次のディレクティブは、 `+ ssl_trusted_certificate +`の*後に*配置する必要があります。 _10MB_のキャッシュライフタイムでサイズ_20MB_の共有キャッシュを有効にします。

ssl_session_cache shared:SSL:20m;
ssl_session_timeout 10m;

SSL接続で使用されるプロトコルと暗号を指定します。 ここでは、SSLv2を省略し、MD5やDSSなどの安全でない暗号を無効にしました。

ssl_prefer_server_ciphers       on;
ssl_protocols                   TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers                     ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+3DES:!aNULL:!MD5:!DSS;

Strict Transport Securityは、すべてのサポートWebブラウザーにHTTPSのみを使用するよう指示します。 `+ add_header +`ディレクティブで有効にします。

add_header Strict-Transport-Security "max-age=31536000";

構成エラーを確認し、Nginxサービスをリロードします。

service nginx configtest && service nginx reload

完全な構成

SSLターミネーションを構成して強化すると、完全な構成ファイルは次のようになります。

+ / etc / nginx / sites-available / +

upstream  {
   server ;
   server ;
}

server {
   listen 80;
   listen 443 ssl;
   server_name ;

   ssl on;
   ssl_certificate         ;
   ssl_certificate_key     ;
   ssl_trusted_certificate ;

   ssl_session_cache shared:SSL:20m;
   ssl_session_timeout 10m;

   ssl_prefer_server_ciphers       on;
   ssl_protocols                   TLSv1 TLSv1.1 TLSv1.2;
   ssl_ciphers                     ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+3DES:!aNULL:!MD5:!DSS;

   add_header Strict-Transport-Security "max-age=31536000";

   location / {
       proxy_pass http://;
       proxy_set_header Host $host;
       proxy_set_header X-Real-IP $remote_addr;
       proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
       proxy_set_header X-Forwarded-Proto $scheme;
   }
}

SSL Server Testを実行すると、このセットアップはA +グレードになります。 カールテストを再度実行して、すべてが正常に機能しているかどうかを確認します。

curl https:///test.php https:///test.php https:///test.php

参考文献

負荷分散アルゴリズムの詳細については、https://www.digitalocean.com/community/tutorials/how-to-set-up-nginx-load-balancing [この記事]をご覧ください。

Related