[Apache] mod_rpafをApache2.4系で使う

Apache2.4系では2.2系からオブジェクト構造などに一部変更があったらしく、メンテされてないモジュールなどで、コンパイルが通らないことがあります。

今回は、バランサを前においたApacheで、X-Forwarded-Forをアクセス元ホストとして使うためのモジュール「mod_rpaf」のコンパイルをする際に問題がでました。

 

調べてみたところ、対象モジュールは違いますが、以下で紹介されている「remote_ip」「remote_addr」の名称変更がビンゴっぽい。

apache2.4.1リリース

 

mod_rpaf-2.0.cファイルの対象箇所を修正します(gistはこちら)。

--- mod_rpaf-2.0.c.org  2012-05-17 12:05:34.082130109 +0900
+++ mod_rpaf-2.0.c      2012-05-17 12:16:41.648138252 +0900
@@ -147,8 +147,8 @@

 static apr_status_t rpaf_cleanup(void *data) {
     rpaf_cleanup_rec *rcr = (rpaf_cleanup_rec *)data;
-    rcr->r->connection->remote_ip   = apr_pstrdup(rcr->r->connection->pool, rcr->old_ip);
-    rcr->r->connection->remote_addr->sa.sin.sin_addr.s_addr = apr_inet_addr(rcr->r->connection->remote_ip);
+    rcr->r->connection->client_ip   = apr_pstrdup(rcr->r->connection->pool, rcr->old_ip);
+    rcr->r->connection->client_addr->sa.sin.sin_addr.s_addr = apr_inet_addr(rcr->r->connection->client_ip);
     return APR_SUCCESS;
 }

@@ -161,7 +161,7 @@
     if (!cfg->enable)
         return DECLINED;

-    if (is_in_array(r->connection->remote_ip, cfg->proxy_ips) == 1) {
+    if (is_in_array(r->connection->client_ip, cfg->proxy_ips) == 1) {
         /* check if cfg->headername is set and if it is use
            that instead of X-Forwarded-For by default */
         if (cfg->headername && (fwdvalue = apr_table_get(r->headers_in, cfg->headername))) {
@@ -180,11 +180,11 @@
                 if (*fwdvalue != '\0')
                     ++fwdvalue;
             }
-            rcr->old_ip = apr_pstrdup(r->connection->pool, r->connection->remote_ip);
+            rcr->old_ip = apr_pstrdup(r->connection->pool, r->connection->client_ip);
             rcr->r = r;
             apr_pool_cleanup_register(r->pool, (void *)rcr, rpaf_cleanup, apr_pool_cleanup_null);
-            r->connection->remote_ip = apr_pstrdup(r->connection->pool, ((char **)arr->elts)[((arr->nelts)-1)]);
-            r->connection->remote_addr->sa.sin.sin_addr.s_addr = apr_inet_addr(r->connection->remote_ip);
+            r->connection->client_ip = apr_pstrdup(r->connection->pool, ((char **)arr->elts)[((arr->nelts)-1)]);
+            r->connection->client_addr->sa.sin.sin_addr.s_addr = apr_inet_addr(r->connection->client_ip);
             if (cfg->sethostname) {
                 const char *hostvalue;
                 if (hostvalue = apr_table_get(r->headers_in, "X-Forwarded-Host")) {

 

パッチ当て&インストール手順をまとめるとこんな感じです。
(自前環境ではapxsにパスを通してなかったので、Makefileも一部書き換えてます)

wget http://stderr.net/apache/rpaf/download/mod_rpaf-0.6.tar.gz
tar xvzf mod_rpaf-0.6.tar.gz
cd mod_rpaf-0.6
vi Makefile
> APXS2=$(shell which apxs2)
>  ↓ ↓
> #APXS2=$(shell which apxs2)
> APXS2=/usr/local/apache/bin/apxs

git clone git://gist.github.com/2716030.git
patch < 2716030/mod_rpaf-2.0.c.patch

make rpaf-2.0
make install-2.0

 

mod_rpafはバランサのIPアドレスを決め打ちでしか指定できず、ELBのようにIPが固定されないケースなどではかなりつらい仕様なので、以下のような事例を参考にコンパイル前に少し動きをいじってあげると幸せです。

mod_rpaf の RPAFproxy_ips に 192.0.2. とか書きたい

 

毎回同じローカルIPがログに出力されてもうれしくないので、バランサを使う際は、これ系のモジュールを入れるかログ出力内容の書き換えは必須っぽいですね。