mod_rpaf は、RPAFproxy_ips に書かれているIPアドレスからアクセスがあったときのみ、リクエストヘッダ中の X-Forwarded-For: に書かれている内容を信用し、 Apache内部の r->connection->remote_ip のアドレスを書き換えるといった処理を実行してくれます。
Pound などのリバースプロキシを使った場合、ウェブサーバへアクセスをプロ棋士サーバが肩代わりするため、先のような構成だとたとえばアクセスログのリモートホストのアドレスがすべて 127.0.0.1 になってしまうといった問題があります。
このとき、X-Forwarded-For という環境変数に本来のリモートアドレスが記録されているので、これを使うことで問題を解決できます。それを実現するのが mod_rpaf。早速導入しました。
いい具合に動いてるなと思ったのですが、どうもときどきリモートアドレスが
<DL>\n <DT><SAMP>example_post_read_request()</SAMP>\n
となぞの文字列が入ることがあります。
PC関係のメモによると、KeepAlive が On な環境でこの現象が発生するそうですが、そもそも KeepAlive を On に設定したいがために Pound を導入したというのもあるので、Off にすることは避けたいなあ。
mod_rpaf.c の 143 行目からの
if (fwdvalue = ap_table_get(r->headers_in, "X-Forwarded-For")) {
array_header *arr = ap_make_array(r->pool, 0, sizeof(char*));
while (*fwdvalue && (val = ap_get_token(r->pool, &fwdvalue, 1))) {
*(char **)ap_push_array(arr) = ap_pstrdup(r->pool, val);
if (*fwdvalue != '\0')
++fwdvalue;
}
r->connection->remote_ip = ap_pstrdup(r->pool, ((char **)arr->elts)[((arr->nelts)-1)]);
r->connection->remote_addr.sin_addr.s_addr = inet_addr(r->connection->remote_ip);
if (cfg->sethostname) {
const char *hostvalue;
if (hostvalue = ap_table_get(r->headers_in, "X-Forwarded-Host")) {
/* 2.0 proxy frontend or 1.3 => 1.3.25 proxy frontend */
ap_table_set(r->headers_in, "Host", ap_pstrdup(r->pool, hostvalue));
r->hostname = ap_pstrdup(r->pool, hostvalue);
ap_update_vhost_from_headers(r);
} else if (hostvalue = ap_table_get(r->headers_in, "X-Host")) {
/* 1.3 proxy frontend with mod_proxy_add_forward */
ap_table_set(r->headers_in, "Host", ap_pstrdup(r->pool, hostvalue));
r->hostname = ap_pstrdup(r->pool, hostvalue);
ap_update_vhost_from_headers(r);
}
}
}
のコードが X-Forwarded-For を取得して云々という処理なんだと思うのですが、Apache API に詳しくないのでちょっとよくわからず。
そういえば mod_proxy でリバースプロキシした場合はアドレスは生IPが記録されていたような。mod_proxy は mod_rpaf と同じようなことを内部で実行しているのかな。