ブログはかなり久々。
会社での実装でいいものが生まれたりするのが、なかなかそれを社外に公開するわけにはいかず、あまり技術的な創作物をブログに書くことができなかった。今は、会社2割大学8割のような比率で研究しているので、最近作ったpatchでも紹介する。
実装対象は、DSO版PHPなどでもsuEXECのようなアクセス制御が行えるmod_ruid2に対してpatchを書いてみた。
mod_ruid2は実装上、モジュールとしてApacheに読み込んだ場合、すべての動的コンテンツ実行時にサーバプロセスをsetuid、setgidしてしまう。しかし、ある特定の環境下では、任意の拡張子(.phpや.py)においてのみモジュールの処理を実行させたい場合がある。Filesディレクティブ等を用いて、ファイルを指定するやり方もあるが、mod_ruid2等ではそういう設定記述は禁止されている。
そこで、mod_ruid2に2つの機能を実装した。
- RExAll [On/Off]
mod_ruid2はモジュールをロードしてしまうと、すべてのサーバプロセスでset[u,g]id機能が動作してしまう。そこで、そもそも機能を動作させるかどうかをOnとOffで切り替えられるようにした。また、DefaultはOffにしているので、モジュールをロードしただけでは、mod_ruid2の機能が勝手に動作してしまわないようにした。
- RExtensions [.php .pl .py ……..]
RExALLがOffの場合、ある任意の拡張子のみmod_ruid2を動作させるようにできるようにした。例えば、下記のように
RExtensions .php .pl
と設定すると、.phpと.plの実行時のみ該当のサーバプロセスをset[u,g]idさせて、その他のファイルは動作しない。これによって、.cgiは別のアクセス制御モジュールを使い、.plはmod_ruid2を使うなどの設定が可能となる。
以上が今回のpatchである。ソースは以下。
--- mod_ruid2.c.orig 2011-02-24 23:25:28.000000000 +0900
+++ mod_ruid2.c 2011-10-12 17:45:59.000000000 +0900
@@ -64,6 +64,10 @@
#define UNSET -1
#define SET 1
+#define RU_MAXEXTENSIONS 16
+#define ON 1
+#define OFF 0
+
typedef struct
{
@@ -78,6 +82,7 @@
typedef struct
{
+ int all_ext_enable;
uid_t default_uid;
gid_t default_gid;
uid_t min_uid;
@@ -85,6 +90,7 @@
int8_t stat_used;
const char *chroot_dir;
const char *document_root;
+ apr_array_header_t *extensions;
} ruid_config_t;
@@ -150,6 +156,8 @@
conf->stat_used=UNSET;
conf->chroot_dir=NULL;
conf->document_root=NULL;
+ conf->extensions=apr_array_make(p, RU_MAXEXTENSIONS, sizeof(char *));
+ conf->all_ext_enable = OFF;
return conf;
}
@@ -260,6 +268,32 @@
return NULL;
}
+
+static const char * set_extensions(cmd_parms *cmd, void *mconfig, const char *arg)
+{
+ ruid_config_t *conf = ap_get_module_config (cmd->server->module_config, &ruid2_module);
+ const char *err = ap_check_cmd_context (cmd, NOT_IN_FILES | NOT_IN_LIMIT);
+
+ if (err != NULL)
+ return err;
+
+ *(const char **)apr_array_push(conf->extensions) = arg;
+
+ return NULL;
+}
+
+static const char * set_all_ext(cmd_parms *cmd, void *mconfig, int flag)
+{
+ ruid_config_t *conf = ap_get_module_config (cmd->server->module_config, &ruid2_module);
+ const char *err = ap_check_cmd_context (cmd, NOT_IN_FILES | NOT_IN_LIMIT);
+
+ if (err != NULL)
+ return err;
+
+ conf->all_ext_enable = flag;
+
+ return NULL;
+}
/* configure options in httpd.conf */
@@ -271,6 +305,8 @@
AP_INIT_TAKE2 ("RDefaultUidGid", set_defuidgid, NULL, RSRC_CONF, "If uid or gid is < than RMinUidGid set[ug]id to this uid gid"),
AP_INIT_TAKE2 ("RUidGid", set_uidgid, NULL, RSRC_CONF | ACCESS_CONF, "Minimal uid or gid file/dir, else set[ug]id to default (User,Group)"),
AP_INIT_TAKE2 ("RDocumentChRoot", set_documentchroot, NULL, RSRC_CONF, "Set chroot directory and the document root inside"),
+ AP_INIT_ITERATE("RExtensions", set_extensions, NULL, ACCESS_CONF | RSRC_CONF, "Set Enable Extensions."),
+ AP_INIT_FLAG("RExAll", set_all_ext, NULL, ACCESS_CONF | RSRC_CONF, "Set Enable All Extensions On / Off. (default Off)"),
{NULL}
};
@@ -445,6 +481,25 @@
cap_t cap;
cap_value_t capval[4];
+ const char *extension;
+
+ int enable = 0;
+ int name_len = 0;
+
+ if (conf->all_ext_enable) {
+ enable = ON;
+ } else {
+ for (i = 0; i < conf->extensions->nelts; i++) {
+ extension = ((char **)conf->extensions->elts)[i];
+ name_len = strlen(r->filename) - strlen(extension);
+ if (name_len >= 0 && strcmp(&r->filename[name_len], extension) == 0)
+ enable = ON;
+ }
+ }
+
+ if (!enable)
+ return DECLINED;
+
cap=cap_get_proc();
capval[0]=CAP_SETUID;
capval[1]=CAP_SETGID;
「拡張子によってApacheモジュールの処理を適応するか判断するpatch(mod_ruid2版)」への1件のフィードバック
コメントは受け付けていません。