Nginx (SSL-Proxy)

BlueOnyx は既定では Apache Web サーバーを使用します。通常のウェブ配信では十分に優秀で、.htaccess、mod_rewrite、suPHP、mod_ruid2 など需要の高い Apache 関連機能もすべて利用できますが、HTTPS 配信に関してはいくつか弱点があります。

最大の問題は Apache 自体の世代の古さと、それがリンクしている OpenSSL の古さです。さらに厄介なのは、RedHat が「特許上の理由」で一部の暗号スイートを OpenSSL から意図的に削っている点です。こちらとして使いたい ChaCha や Poly1305 などの暗号も、後の OpenSSL でようやく導入されたものです。

要するに、RedHat/CentOS では便利な暗号スイートの一部が使えず、Apache と OpenSSL が古いため HTTP/2 も TLSv1.3 も利用できません。HTTP/2 は HTTP ネットワークプロトコルの大きな改訂版で、ブラウザが最初の応答を解析するのを待たず、必要になると分かっているデータをサーバー側から先回りして送れます。そのため一般に HTTP/1.1 より高速です。TLSv1.3 も最新の安全なプロトコルであり、今後ますます重要になります。だからこそ、BlueOnyx 5209R でもこれらを使いたいのです。

そこで Nginx の出番です。

SSL プロキシとしての Nginx

Nginx ( /ˌɛndʒɪnˈɛks/ EN-jin-EKS) は、リバースプロキシ、ロードバランサー、HTTP キャッシュとしても使える Web サーバーです。Nginx は非同期・イベント駆動型でリクエストを処理するため、高負荷時でもより予測しやすい性能を示します。

Nginx と Apache は設計思想が異なります。Apache が何でも一通りできるスイスアーミーナイフだとすれば、Nginx は軽量で無駄がなく、それでいて非常に強力です。標準状態の Nginx は静的ページ配信が中心で、必要な機能は自分で組み込む前提ですが、そのぶん特定用途では非常に高い性能を発揮します。

ただし、Nginx をそのまま Apache の置き換えとして使うと、いくつかの機能を失ってしまいます。そこで私たちは別の方法を取りました。既存機能を削らず、Nginx を追加機能として使う方法です。

新しく得られる機能:

  • TLS/SSL 経由での HTTP/2 対応
  • Vsite 単位の HSTS
  • OpenSSL が提供する最新暗号スイートの利用
  • TLSv1.3 と TLSv1.2
  • 単一の設定ファイル編集でプロトコルや暗号を自分で調整可能

仕組み:

この機能を追加する更新をインストールすると、「Network Services」 / 「Web」に 2 つのタブが表示されます。従来の「Apache」と、新しい「Nginx」です。

ここで Nginx を SSL Proxy として有効化できます。有効にすると GUI が Apache 設定を変更し、Apache が SSL ポート(443)を直接バインドしないようにします。同時に Nginx を SSL プロキシとして設定し、SSL が有効なすべての Vsite 向けに Nginx 設定ファイルを生成します。

Nginx 設定ファイルのディレクトリ構造は、たとえば次のようになります。

/etc/nginx/
|-- conf
| `-- 00-default.conf
|-- conf.d
| `-- default.conf
|-- fastcgi_params
|-- headers.d
| |-- https_headers.conf
| `-- security.conf
|-- koi-utf
|-- koi-win
|-- mime.types
|-- modules ->../../usr/lib64/nginx/modules
|-- nginx.conf
|-- scgi_params
|-- ssl_defaults.conf
|-- ssl_proto_chiffres.conf
|-- uwsgi_params
|-- vsites
| |-- site1
| |-- site2
| `-- site5
`-- win-utf

このように /etc/nginx/vsites/ には、たとえば 'site1'、'site2'、'site5' 向けの SSL プロキシ設定が入ります。内容は概ね次のようなものです。

# Do NOT edit this file. The GUI will replace this file on edits.
server {

 listen [::]:443 ssl http2;
 listen 443 ssl http2;
 server_name test.blueonyx.it;

 include /etc/nginx/headers.d/*.conf;

 ssl_certificate /home/.sites/143/site2/certs/nginx_cert_ca_combined;
 ssl_certificate_key /home/.sites/143/site2/certs/key;
 ssl_trusted_certificate /home/.sites/143/site2/certs/nginx_cert_ca_combined;

 # Insert external protocols and chiffres for SSL:
 include /etc/nginx/ssl_proto_chiffres.conf;

 # Insert external SSL Session cfg, resolver and OSCP-Stapling:
 include /etc/nginx/ssl_defaults.conf;

 error_page 502 /502-bad-gateway.html;
 location = /502-bad-gateway.html {
 internal;
 root /var/www/html/error/;
 }

 # Special provisions for /libImage/ for error page gfx:
 location ~ ^/libImage/*.*$ {
 root /usr/sausalito/ui/web/;
 }

 location / {
 proxy_http_version 1.1;
 proxy_set_header Connection "";
 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_pass http://test.blueonyx.it:80/;
 proxy_read_timeout 90;
 }
}

見てのとおり非常にシンプルです。PHP、Perl、SSI の処理は含まれていません。これはあくまでプロキシだからです。ブラウザが HTTPS で接続すると、Nginx が安全に接続を受け、ローカルの 80 番ポートへ接続して Apache からコンテンツを取得します。それを暗号化してブラウザへ返します。ブラウザが HTTP/2 に対応していれば、HTTP/2 が使われます。

もし細かくプロトコルや暗号を調整したい場合は、/etc/nginx/ssl_proto_chiffres.conf を自由に編集してください。既定では次のようになっています。

 ssl_protocols TLSv1.3 TLSv1.2;
ssl_ciphers ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:EECDH+AESGCM:EDH+AESGCM;
ssl_prefer_server_ciphers on;
ssl_ecdh_curve secp384r1;

このファイルを編集しても、GUI や今後の更新で上書きされることはありません。編集後に単に「systemctl restart nginx」を実行すれば、変更が有効になり、SSL を有効にしたすべての Vsite に適用されます。

Vsite 単位の HSTS 対応:

HSTS は、サイトをできるだけ HTTP ではなく HTTPS で訪問すべきだとブラウザへ伝える仕組みです。ブラウザはそれを記憶し、一定期間は今後のアクセスでも HTTPS を優先するようになります。

Apache でも HSTS は使えますが、かなり大味です。全 Vsite 一括でオンにするか、全 Vsite 一括でオフにするかしかありません。BlueOnyx では SSL あり/なしが混在した Vsite を多数運用するケースが多いため、必要な一部だけに HSTS を有効化することが難しかったのです。

そこで Nginx です。Nginx を使えば、個別 Vsite だけに HSTS を有効化したり、逆にサーバー全体へ適用したりできます。選択は自由です。Nginx を SSL プロキシとして使っている場合、各 Vsite の「SSL」設定内に、下図のような新しいチェックボックス「Nginx HSTS」が現れます。

ただし: この 実装には注意点があります。

思い出してください。HTTP 側はまだ Apache を使っており、Nginx は HTTPS 専用です。ある Vsite で個別に Nginx HSTS を有効にしていても、訪問者がそのサイトを常に HTTP でしか見ないなら、HSTS ヘッダを見る機会がありません。HSTS が効き始めるのは、少なくとも 1 つのリソース(ページ、スクリプト、画像など)を HTTPS 経由で読み込んだ場合です。

したがって、HSTS を選択的に使いたい場合は、テンプレート画像やスタイルシートなど、最低 1 つのリソースを HTTPS で読み込むようにしておくのが実務上の回避策です。それだけでも、訪問者のブラウザに HSTS を覚えさせるには十分です。

トラブルが増えるのでは?

「また監視すべきサービスが増えるのか」と思うかもしれません。それは半分だけ正しいです。GUI が大部分を面倒見ます。Nginx 側で普段触る必要はほとんどありません。設定ファイルを編集する必要も通常はありません(したければ可能ですが)。やっていることも、かなり単純なプロキシです。サービスが有効なら、ActiveMonitor が Nginx も監視します。

万一停止しても、他のサービスと同じように「systemctl restart nginx」で再起動できます。問題があれば、その際にコマンドラインで内容が分かります。必要なら GUI のチェックボックスを外して、Apache に HTTPS 配信を戻すこともできます。

実運用で Nginx を HTTPS プロキシとして使った感触が気になるなら、答えは簡単です。このサイト自身がそうして動いています。リソースの多いページでも読み込み時間は大きく短縮され、ピーク時でもサーバー負荷は目立って増えていません。全体として HTTP/2 は体感できるほど速くなります。