CentOS 6.5 + ModSecurity 2.8.0 + Nginx 1.6.0 でテスト
ModSecurity と Nginx をコンパイルして動かしたら audit log に妙なメッセージが。
Message: Audit log: Failed to lock global mutex: Permission denied
strace すると semop(2) で失敗していることが分かる。
3770 17:40:24.018266 semop(655372, {{0, -1, SEM_UNDO}}, 1) = -1 EACCES (Permission denied)
ipcs コマンドで確認すると owner がおかしい。
------ Semaphore Arrays --------
key semid owner perms nsems
0x00000000 0 root 600 1
0x00000000 32769 root 600 1
0x00000000 131074 4294967295 600 1
0x00000000 163843 4294967295 600 1
0x00000000 458756 4294967295 600 1
0x00000000 491525 4294967295 600 1
0x00000000 262150 4294967295 600 1
0x00000000 294919 4294967295 600 1
0x00000000 393224 4294967295 600 1
0x00000000 425993 4294967295 600 1
0x00000000 524298 4294967295 600 1
0x00000000 557067 4294967295 600 1
0x00000000 655372 4294967295 600 1
0x00000000 688141 4294967295 600 1
Nginx を root で動かせば解決するだろうが、それは避けたい
ソースを grep して探していくと、DEFAULT_USER なるものが見つかる
[host]$ grep -r semctl *
standalone/server.c: if (semctl(ospmutex.crossproc, 0, IPC_SET, ick) < 0) {
standalone/server.c: if (semctl(ospmutex.crossproc, 0, IPC_SET, ick) < 0) {
standalone/server.c
# if AP_SERVER_MAJORVERSION_NUMBER > 1 && AP_SERVER_MINORVERSION_NUMBER < 3
unixd_config.user_name = DEFAULT_USER;
unixd_config.user_id = ap_uname2id(DEFAULT_USER);
unixd_config.group_id = ap_gname2id(DEFAULT_GROUP);
unixd_config.suexec_enabled = 0;
# else
ap_unixd_config.user_name = DEFAULT_USER;
ap_unixd_config.user_id = ap_uname2id(DEFAULT_USER);
ap_unixd_config.group_id = ap_gname2id(DEFAULT_GROUP);
ap_unixd_config.suexec_enabled = 0;
# endif
standalone/server.c
apr_os_proc_mutex_get(&ospmutex, pmutex);
buf.sem_perm.uid = unixd_config.user_id;
buf.sem_perm.gid = unixd_config.group_id;
buf.sem_perm.mode = 0600;
ick.buf = &buf;
if (semctl(ospmutex.crossproc, 0, IPC_SET, ick) < 0) {
return errno;
}
DEFAULT_USER を探す
[host]$ grep -r DEFAULT_USER /usr/include/httpd/*
/usr/include/httpd/unixd.h:#ifndef DEFAULT_USER
/usr/include/httpd/unixd.h:#define DEFAULT_USER "#-1"
/usr/include/httpd/unixd.h
# ifndef DEFAULT_USER
# define DEFAULT_USER "#-1"
# endif
# ifndef DEFAULT_GROUP
# define DEFAULT_GROUP "#-1"
# endif
DEFAULT_USER などを定義してやればいいので、ModSecurity からコンパイルし直す。以下は一例で、オプションは各環境で適切に設定する。
[host]# CFLAGS="-DDEFAULT_USER=\\\"nginx\\\" -DDEFAULT_GROUP=\\\"nginx\\\"" \
CPPFLAGS="-I/usr/include/apr-1 -I/usr/include/httpd" \
./configure \
--disable-apache2-module \
--disable-mlogc \
--enable-standalone-module
[host]# make
[host]# make install
Nginx もコンパイルし直す。以下は一例で、オプションは各環境ごとに適切に設定する
[host]# ./configure \
--add-module=../modsecurity-2.8.0/nginx/modsecurity \
--user=nginx --group=nginx \
--without-mail_pop3_module \
--without-mail_imap_module \
--without-mail_smtp_module \
--with-cc-opt="-I/usr/include/apr-1 -I/usr/include/httpd" \
--with-ld-opt="-lapr-1 -laprutil-1"
[host]# make
[host]# make install
修正完了。
[host]# service nginx start
[host]# ipcs -s
------ Semaphore Arrays --------
key semid owner perms nsems
0x00000000 0 root 600 1
0x00000000 32769 root 600 1
0x00000000 131074 nginx 600 1
0x00000000 163843 nginx 600 1
修正前はやたらと数が多かったし、
多分直すまではセマフォの削除にも失敗していたと思われる。