とあるウェブサービスのサーバー負荷状況が思わしく無く、非常に重い状態が続いていました。
そこで話題の高速ウェブサーバーの nginx を利用してみました。
構成は次の通り。(同サーバー上)
フロントエンド(nginx) ... 主に画像処理
バックエンド(httpd) ... アプリケーション
まずは、nginx を 80番 で、httpd を 8080番 で設定して開通。
もちろん、アクセス元IPを記録するので mod_rpaf を httpd 側に設定。
mod_rpaf の設定は次の通り。
しかし、ここで問題発生。
一向に外部IPが記録されず、mod_rpaf が機能していない...。
そういえば、フロントは nginx なんだということを思い出し、proxy 関連の設定についてググる。
解決方法がありました。次の設定を nginx.conf に入れておきましょう。
さて、これでサーバーの負荷が下がると思いきや、中々状況が改善されません。
詳細調査の為に、バックエンド側で /server-status を確認していると何やら OPTIONS の文字が。
まさか、TRACE 関連の脆弱性を突かれているのかと思ったのですが、そもそもフロントエンドの nginx は何をしているんだと。調べてみたところ、nginx は TRACE method に関しては、問答無用で拒否していることが分かりました。
ですが、telnet を利用して会話してみると、OPTIONS が素通りして、バックエンドに行ってしまっているでは無いですか...。
httpd のログで言うとこれですよ、これ。
仕方が無いので、nginx 側で request method を制限することにしました。
いいね! nginx 。
そこで話題の高速ウェブサーバーの nginx を利用してみました。
構成は次の通り。(同サーバー上)
フロントエンド(nginx) ... 主に画像処理
バックエンド(httpd) ... アプリケーション
まずは、nginx を 80番 で、httpd を 8080番 で設定して開通。
もちろん、アクセス元IPを記録するので mod_rpaf を httpd 側に設定。
mod_rpaf の設定は次の通り。
1. ファイルのダウンロード※綺麗にまとまっていたので、mod_rpafをインストールし、リバースプロキシのローカルのIPを取得しないようにする を参照。
% cd /usr/local/src
% wget http://stderr.net/apache/rpaf/download/mod_rpaf-0.6.tar.gz
2. ファイルを解凍
% tar xvfz mod_rpaf-0.6.tar.gz
3. ディレクトリを移動
% cd mod_rpaf-0.6
4. MakeFileの編集
APXS2にapxsのパスを入れる
% vi Makefile
#APXS2=$(shell which apxs2)
APXS2=/usr/sbin/apxs
5. コンパイル
% make rpaf-2.0
% make install-2.0
6. httpd.confの編集
以下を追記
% vi /etc/httpd/conf/httpd.conf
--
LoadModule rpaf_module modules/mod_rpaf-2.0.so
RPAFenable On
RPAFsethostname off
RPAFproxy_ips xxx.xxx.xxx
しかし、ここで問題発生。
一向に外部IPが記録されず、mod_rpaf が機能していない...。
そういえば、フロントは nginx なんだということを思い出し、proxy 関連の設定についてググる。
解決方法がありました。次の設定を nginx.conf に入れておきましょう。
proxy_set_header X-Real-IP $remote_addr;これでアクセス元のIPをバックエンド側でも取得できるようになりました。
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
さて、これでサーバーの負荷が下がると思いきや、中々状況が改善されません。
詳細調査の為に、バックエンド側で /server-status を確認していると何やら OPTIONS の文字が。
まさか、TRACE 関連の脆弱性を突かれているのかと思ったのですが、そもそもフロントエンドの nginx は何をしているんだと。調べてみたところ、nginx は TRACE method に関しては、問答無用で拒否していることが分かりました。
if (r->method & NGX_HTTP_TRACE) {※ 【ソース解析】アクセス受けつけ5 参照
ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
"client sent TRACE method");
ngx_http_finalize_request(r, NGX_HTTP_NOT_ALLOWED);
return NGX_ERROR;
}
ですが、telnet を利用して会話してみると、OPTIONS が素通りして、バックエンドに行ってしまっているでは無いですか...。
httpd のログで言うとこれですよ、これ。
"OPTIONS * HTTP/1.0" 200 - "-" "Apache/2.2.17 (EL) (internal dummy connection)"
仕方が無いので、nginx 側で request method を制限することにしました。
if ($request_method !~ ^(GET|HEAD|POST)$) { return 444; }というわけでサーバーの高負荷状態も収まり、一件落着です。
いいね! nginx 。