LoginSignup
8
7

More than 5 years have passed since last update.

ModSecurity with Nginx の Audit Log にエラー (Failed to lock global mutex: Permission denied)

Last updated at Posted at 2014-05-18

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

修正前はやたらと数が多かったし、
多分直すまではセマフォの削除にも失敗していたと思われる。

8
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
7