前書き
この記事では、ロードバランサー上でSSL証明書を1つだけ使用して、SSL終了でNginxロードバランシングを設定する方法を示します。 これにより、OpenSSLの更新とキーと証明書をロードバランサー自体から管理できるようになるため、SSL管理のオーバーヘッドが削減されます。
SSL終了について
Nginxは、複数のバックエンドサーバーに着信トラフィックを分散するロードバランサーとして構成できます。 SSL終了とは、ロードバランサーとバックエンドサーバー間のトラフィックがHTTPになるようにSSL暗号化/復号化を処理するロードバランサーで発生するプロセスです。 バックエンドは、ロードバランサーのIPへのアクセスを制限することで保護する必要があります。これについては、この記事で後述します。
前提条件
このチュートリアルでは、コマンドはrootユーザーまたはsudo特権を持つユーザーとして実行する必要があります。 Users Tutorialでそれを設定する方法を見ることができます。
次のガイドを参照として使用できます。
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
Domain name-example.com
これらのすべてのドロップレットでは、private networkingを有効にする必要があります。
3つのサーバーすべてでソフトウェアを更新およびアップグレードします。
apt-get update && apt-get upgrade -y
Reboot each server to apply the upgrades. 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
詳細については、this articleを参照してください。
キーを生成してSSL証明書を作成する
このセクションでは、SSL証明書の作成に必要な手順を実行します。 This articleは、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を使用して、a certificate authorityから有効な証明書を取得するか、次のコマンドで自己署名証明書を生成します。
openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt
これが完了すると、このディレクトリには次のファイルが含まれます。
-
server.key - The private key
-
ca-certs.pem - A collection of your CA’s root and intermediate certificates. CAから有効な証明書を取得した場合にのみ存在します。
-
server.crt - The SSL certificate for your domain name
仮想ホストファイルとアップストリームモジュール
Nginxディレクトリ内に仮想ホストファイルを作成します
nano /etc/nginx/sites-available/example.com
バックエンドサーバーのプライベートIPアドレスを含むアップストリームモジュールを追加します
upstream mywebapp1 {
server 10.130.227.11;
server 10.130.227.22;
}
この行でサーバーブロックafterを開始します。 このブロックには、ドメイン名、上流サーバーへの参照、およびバックエンドに渡す必要のあるヘッダーが含まれています。
server {
listen 80;
server_name example.com www.example.com;
location / {
proxy_pass http://mywebapp1;
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 /etc/nginx/ssl/example.com/server.crt;
ssl_certificate_key /etc/nginx/ssl/example.com/server.key;
ssl_trusted_certificate /etc/nginx/ssl/example.com/ca-certs.pem;
自己署名証明書を使用している場合は、ssl_trusted_certificate
ディレクティブを無視してください。 これで、server
ブロックは次のようになります。
server {
listen 80;
listen 443 ssl;
server_name example.com www.example.com;
ssl on;
ssl_certificate /etc/nginx/ssl/example.com/server.crt;
ssl_certificate_key /etc/nginx/ssl/example.com/server.key;
ssl_trusted_certificate /etc/nginx/ssl/example.com/ca-certs.pem;
location / {
proxy_pass http://mywebapp1;
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
backend server’s自身のプライベートIPアドレスに置き換えます。
Listen 10.130.227.22:80
すべてのバックエンドサーバーでこれを行い、Apacheを再起動します。
service apache2 restart
次のステップは、load balancer’sのプライベートIPへのHTTPアクセスを制限することです。 次のファイアウォールルールはこれを実現します。
iptables -I INPUT -m state --state NEW -p tcp --dport 80 ! -s 10.130.227.33 -j DROP
例をロードバランサーのプライベートIPアドレスに置き換え、すべてのバックエンドサーバーでこのルールを実行します。
セットアップのテスト
すべてのバックエンドサーバー(この例ではweb1とweb2)でPHPファイルを作成します。 これはテスト用であり、セットアップが完了したら削除できます。
nano /var/www/html/test.php
アクセスしたドメイン名、サーバーのIPアドレス、ユーザーのIPアドレス、アクセスしたポートを印刷する必要があります。
ブラウザまたはcurl
を使用して、このファイルに数回アクセスします。 自己署名証明書の設定でcurl -k
を使用して、curlがSSLエラーを無視するようにします。
curl https://example.com/test.php https://example.com/test.php https://example.com/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サイトのパフォーマンスが向上します。 次のディレクティブは、afterssl_trusted_certificate
に配置する必要があります。 これらは、10 minutesのキャッシュライフタイムでサイズ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/example.com
upstream mywebapp1 {
server 10.130.227.11;
server 10.130.227.22;
}
server {
listen 80;
listen 443 ssl;
server_name example.com www.emxaple.com;
ssl on;
ssl_certificate /etc/nginx/ssl/example.com/server.crt;
ssl_certificate_key /etc/nginx/ssl/example.com/server.key;
ssl_trusted_certificate /etc/nginx/ssl/example.com/ca-certs.pem;
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://mywebapp1;
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://example.com/test.php https://example.com/test.php https://example.com/test.php
参考文献
負荷分散アルゴリズムの詳細については、this articleをお読みください。