リバースプロキシを通したアクセスや、シングルサインオンなどでリダイレクトとかやっているときにHTTPのヘッダ情報などの内部変数を知りたいときがありますが(デバッグ情報表示 /dinfo)、それを自前モジュールで表示できるようにしてみました。表示するだけでは物足りないので、Coolkieを使った簡単な認証もしてみました(/dauth)。(セキュリティ的にはNG)
Webページ、Webアプリを一切作成せず、Cのコードだけを用いて実装し、Apacheモジュールの動きの確認をしました。
ちなみにApacheの話題はなんと8年ぶりです。
環境) Apache 2.4.41 / Ubuntu 20.04
インストール)
sudo apt install apache2 apache2-dev
モジュールスケルトンプログラムの作成・インストール
$ apxs -g -n dinfo
Creating [DIR] dinfo
Creating [FILE] dinfo/Makefile
Creating [FILE] dinfo/modules.mk
Creating [FILE] dinfo/mod_dinfo.c
Creating [FILE] dinfo/.deps
$ cd dinfo
$ make
$ sudo make install$ ls /usr/lib/apache2/modules/mod_dinfo*
/usr/lib/apache2/modules/mod_dinfo.so
モジュール定義ファイルの作成・有効化
$ cat /etc/apache2/mods-available/dinfo.load
LoadModule dinfo_module /usr/lib/apache2/modules/mod_dinfo.so
$ cat /etc/apache2/mods-available/dinfo.conf
SetHandler dinfo
$ sudo a2enmod dinfo
$ sudo service apache2 restart
上記同様にmod_dauthについても行います。
$ cat /etc/apache2/mods-available/dauth.load
LoadModule dauth_module /usr/lib/apache2/modules/mod_dauth.so
$ cat /etc/apache2/mods-available/dauth.conf
SetHandler dauth
モジュールのコードを修正するたびに、make installとapache2 restartをします。
mod_dinfo.c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
#include "httpd.h" #include "http_config.h" #include "http_protocol.h" #include "ap_config.h" #include "util_script.h" /* The sample content handler */ static int dinfo_handler(request_rec *r) { if (strcmp(r->handler, "dinfo")) { return DECLINED; } r->content_type = "text/html"; ap_add_cgi_vars(r); ap_add_common_vars(r); const char *cookie = apr_table_get(r->headers_in, "Cookie"); if(cookie!=NULL && strstr(cookie, "dauth=true")!=0) { ; } else { return HTTP_FORBIDDEN; } const apr_array_header_t *arr_env = apr_table_elts(r->subprocess_env); for (int i = 0; i < arr_env->nelts; i++) { apr_table_entry_t *entry = (apr_table_entry_t *)(arr_env->elts + (arr_env->elt_size * i)); ap_rprintf(r, "%s = %s<br>\n", entry->key, entry->val); } if (!r->header_only) ap_rputs("<h3>The sample page from mod_dinfo.c<h3>\n", r); return OK; //return DECLINED; } static void dinfo_register_hooks(apr_pool_t *p) { ap_hook_handler(dinfo_handler, NULL, NULL, APR_HOOK_MIDDLE); } /* Dispatch list for API hooks */ module AP_MODULE_DECLARE_DATA dinfo_module = { STANDARD20_MODULE_STUFF, NULL, /* create per-dir config structures */ NULL, /* merge per-dir config structures */ NULL, /* create per-server config structures */ NULL, /* merge per-server config structures */ NULL, /* table of config file commands */ dinfo_register_hooks /* register hooks */ }; |
mod_dauth.c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
#include "httpd.h" #include "http_config.h" #include "http_protocol.h" #include "ap_config.h" #include "util_script.h" /* The sample content handler */ static int dauth_handler(request_rec *r) { if (strcmp(r->handler, "dauth")) { return DECLINED; } ap_add_cgi_vars(r); ap_add_common_vars(r); const char *qstr = apr_table_get(r->subprocess_env, "QUERY_STRING"); if(strcmp(qstr, "pass=abc")==0){ apr_table_set(r->headers_out, "Set-Cookie","dauth=true;"); if (!r->header_only) ap_rputs("<h3>Valid Password!<h3>\n", r); } else{ apr_table_set(r->headers_out, "Set-Cookie","dauth=false;"); if (!r->header_only) ap_rputs("<h3>Invalid Password</h3>\n", r); } r->content_type = "text/html"; return OK; } static void dauth_register_hooks(apr_pool_t *p) { ap_hook_handler(dauth_handler, NULL, NULL, APR_HOOK_MIDDLE); } /* Dispatch list for API hooks */ module AP_MODULE_DECLARE_DATA dauth_module = { STANDARD20_MODULE_STUFF, NULL, /* create per-dir config structures */ NULL, /* merge per-dir config structures */ NULL, /* create per-server config structures */ NULL, /* merge per-server config structures */ NULL, /* table of config file commands */ dauth_register_hooks /* register hooks */ }; |
(curlで表示させるときのために<br>とともに改行コードを追加しておく)
passはパスワードを想定していますが、まずは間違ったパスワードでアクセスします。
そして/dinfoにアクセスするとFobiddenになります。
既存ページのアクセス時にこのような情報を表示したい場合は、dinfo_handler関数の最後の”return OK”を”return DECLINED”に変更します。これにより次のモジュールの処理にうつることができます。
下記のようにページを作成しておくと、続いて表示されます。
$ cat /var/www/html/dinfo/page.html
<h3>Web Page</h3>
モジュールの理解を深めるためのメモでした。
参考)
「手軽に出来るApacheモジュール開発」
https://blog.asial.co.jp/715
「apacheのモジュールを作ってみる」
https://qiita.com/saoyagi2/items/7fd374851a36fa671b17