割と良く見る間違いです
builder {
enable "ServerStatus::Lite",
path => '/server-status',
allow => [ '127.0.0.1', '192.168.9.0/24'],
scoreboard => ..;
enable 'ReverseProxy';
$app;
};
これは間違いです。リバースプロキシ配下にてアプリケーションサーバを起動すると、/server-statusに対して全世界からアクセス可能になります
Plack::Middleware::ReverseProxyがX-Forwarded-Forヘッダをみて、REMOTE_ADDRを書き換える前、上の図の状態でPlack::Middleware::ServerStatus::Liteが実行されてしまうので、/server-statusへのアクセスが許可されてしまいます。
どうすれば良いかというと
use Plack::Builder::Conditional;
builder {
enable match_if addr(['192.168.0.0/24','127.0.0.1']),
'ReverseProxy';
enable "ServerStatus::Lite",
path => '/server-status',
allow => [ '127.0.0.1', '192.168.9.0/24'],
scoreboard => ..;
$app;
};
このように、ReverseProxyはServer::Statusよりも先において、REMOTE_ADDRを書き換えてから、アクセス制限に用いてください。あと、必ず書き換える前にリモートホストを確認するようにしましょう
同様に AccessLog ミドルウェアも
builder {
enable "AccessLog";
enable match_if addr(['192.168.0.0/24','127.0.0.1']),
'ReverseProxy';
$app;
};
これでは、記録されるIPアドレスが全てアプリケーションサーバにアクセスするリバースプロキシのIPアドレスになります。クライアントのIPアドレスを記録するのであれば、
builder {
enable match_if addr(['192.168.0.0/24','127.0.0.1']),
'ReverseProxy';
enable "AccessLog";
$app;
};
としましょう。
このようにPlack::Middleware::ReverseProxyは、IPアドレスを使う他のミドルウェアよりも先に指定するのが基本です。
以前も紹介していますが、Plackのmiddlewareを指定する場合は以下の図をイメージすると良いでしょう。
Plack::Builder で
builder {
enable 'A';
enable 'B';
enable 'C';
$app
};
と指定した場合、Aが外側、Cが内側になります