Modsecurity nginx failed to work

General Discussion of atomic repo and development projects.

Ask for help here with anything else not covered by other forums.
DarkF@der
Forum Regular
Forum Regular
Posts: 313
Joined: Thu May 07, 2009 12:46 pm

Modsecurity nginx failed to work

Unread post by DarkF@der »

Hello,

I build a machine without plesk and want to use modsecurity on nginx
But i don't get it working somehow..... :x i have complied nginx with modsecurity like this

Code: Select all

[root@xxxxxxxxxxxxx modsecurity-2.9.0]#./configure --enable-standalone-module --disable-mlogc
[root@xxxxxxxxxxxxx modsecurity-2.9.0]#make

Code: Select all

[root@xxxxxxxxx nginx-1.7.10]#./configure --sbin-path=/usr/sbin/nginx --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-
path=/var/log/nginx/access.log --user=nginx --group=nginx --with-http_ssl_module --with-file-aio --with-ipv6 --with-http_ssl_module --with-http_spdy_module --with-http_realip_module --with-http_addition_module --with-http_xslt_module --with-http_image_filter_module --with-http_geoip_module --with-http_sub_module --with-http_dav_module --with-http_flv_module --with-http_mp4_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_random_index_module --with-http_secure_link_module --with-http_degradation_module --with-http_stub_status_module --with-http_perl_module --with-ld-opt="-Wl,-E" --with-mail --with-mail_ssl_module --with-pcre --with-debug --add-module=/usr/local/src/modsecurity-2.9.0/nginx/modsecurity/
[root@xxxxxxxxx nginx-1.7.10]#make && make install
Looks like itis succesfully complied:

Code: Select all

[root@xxxxxxxxxxx nginx-1.7.10]# nginx -V
nginx version: nginx/1.7.10
built by gcc 4.8.2 20140120 (Red Hat 4.8.2-16) (GCC)
TLS SNI support enabled
configure arguments: --sbin-path=/usr/sbin/nginx --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --user=nginx --group=nginx --with-http_ssl_module --with-file-aio --with-ipv6 --with-http_ssl_module --with-http_spdy_module --with-http_realip_module --with-http_addition_module --with-http_xslt_module --with-http_image_filter_module --with-http_geoip_module --with-http_sub_module --with-http_dav_module --with-http_flv_module --with-http_mp4_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_random_index_module --with-http_secure_link_module --with-http_degradation_module --with-http_stub_status_module --with-http_perl_module --with-ld-opt=-Wl,-E --with-mail --with-mail_ssl_module --with-pcre --with-debug --add-module=/usr/local/src/modsecurity-2.9.0/nginx/modsecurity/
It seems that it's running correctly:

Code: Select all

2015/03/03 02:36:18 [notice] 13470#0: ModSecurity: LIBXML compiled version="2.9.1"
2015/03/03 02:36:18 [notice] 13470#0: ModSecurity: StatusEngine call: "2.9.0,nginx,1.4.8/1.4.8,8.32/8.32 2012-11-30,(null),2.9.1,773edf94bd698ebf7d8bb75e9cbbd281bdeece0f"
2015/03/03 02:36:18 [notice] 13470#0: ModSecurity: StatusEngine call successfully sent. For more information visit: http://status.modsecurity.org/
2015/03/03 02:36:18 [notice] 13470#0: using the "epoll" event method
2015/03/03 02:36:18 [notice] 13470#0: using the "epoll" event method
2015/03/03 02:36:18 [notice] 13470#0: nginx/1.7.10
2015/03/03 02:36:18 [notice] 13470#0: nginx/1.7.10
2015/03/03 02:36:18 [notice] 13470#0: built by gcc 4.8.2 20140120 (Red Hat 4.8.2-16) (GCC)
2015/03/03 02:36:18 [notice] 13470#0: built by gcc 4.8.2 20140120 (Red Hat 4.8.2-16) (GCC)
2015/03/03 02:36:18 [notice] 13470#0: OS: Linux 3.10.0-123.20.1.el7.x86_64
2015/03/03 02:36:18 [notice] 13470#0: OS: Linux 3.10.0-123.20.1.el7.x86_64
2015/03/03 02:36:18 [notice] 13470#0: getrlimit(RLIMIT_NOFILE): 1024:4096
2015/03/03 02:36:18 [notice] 13470#0: getrlimit(RLIMIT_NOFILE): 1024:4096
2015/03/03 02:36:18 [notice] 13471#0: start worker processes
2015/03/03 02:36:18 [notice] 13471#0: start worker processes
2015/03/03 02:36:18 [notice] 13471#0: start worker process 13472
2015/03/03 02:36:18 [notice] 13471#0: start worker process 13472
2015/03/03 02:36:18 [notice] 13471#0: start worker process 13473
2015/03/03 02:36:18 [notice] 13471#0: start worker process 13473
2015/03/03 02:36:18 [notice] 13471#0: start worker process 13474
2015/03/03 02:36:18 [notice] 13471#0: start worker process 13474
2015/03/03 02:36:18 [notice] 13471#0: start worker process 13475
2015/03/03 02:36:18 [notice] 13471#0: start worker process 13475
2015/03/03 02:36:18 [notice] 13471#0: start worker process 13476
2015/03/03 02:36:18 [notice] 13471#0: start worker process 13476
2015/03/03 02:36:18 [notice] 13471#0: start worker process 13477
2015/03/03 02:36:18 [notice] 13471#0: start worker process 13477
2015/03/03 02:36:18 [notice] 13471#0: start worker process 13478
2015/03/03 02:36:18 [notice] 13471#0: start worker process 13478
2015/03/03 02:36:18 [notice] 13471#0: start worker process 13479
2015/03/03 02:36:18 [notice] 13471#0: start worker process 13479
2015/03/03 02:36:18 [notice] 13471#0: start cache manager process 13480
2015/03/03 02:36:18 [notice] 13471#0: start cache manager process 13480
2015/03/03 02:36:18 [notice] 13471#0: start cache loader process 13481
2015/03/03 02:36:18 [notice] 13471#0: start cache loader process 13481
I have build my nginx config like this:

Code: Select all

user  nginx;
worker_processes  8;

error_log  /var/log/nginx/error.log;
error_log  /var/log/nginx/error.log  notice;
error_log  /var/log/nginx/error.log  info;


pid        /var/run/nginx.pid;


events {
    worker_connections  1024;
    multi_accept on;
    use epoll;
}


http {

    set_real_ip_from 127.0.0.1;
    real_ip_header X-Forwarded-For;

    include       mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log main;

    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
    keepalive_timeout 60;
    client_max_body_size 15m;
    client_body_timeout 60;
    client_header_timeout 60;
    client_body_buffer_size  1K;
    client_header_buffer_size 1k;
    large_client_header_buffers 4 8k;
    send_timeout 60;
    reset_timedout_connection on;
    types_hash_max_size 2048;
    server_tokens off;
    gzip on;
    gzip_static on;
    gzip_disable "msie6";
    gzip_vary on;
    gzip_proxied any;
    gzip_comp_level 6;
    gzip_min_length 512;
    gzip_buffers 16 8k;
    gzip_http_version 1.1;
    gzip_types text/css text/javascript text/xml text/plain text/x-component
    application/javascript application/x-javascript application/json
    application/xml  application/rss+xml font/truetype application/x-font-ttf
    font/opentype application/vnd.ms-fontobject image/svg+xml;

    fastcgi_cache_path /var/cache/nginx levels=1:2 keys_zone=WORDPRESS:100m inactive=60m;
    fastcgi_cache_key "$scheme$request_method$host$request_uri";
    fastcgi_cache_use_stale error timeout invalid_header http_500;
    fastcgi_ignore_headers Cache-Control Expires Set-Cookie;

     # HTTP server
    #

    server {

       listen 80;
       server_name  *.xxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxx;
       add_header Strict-Transport-Security "max-age=31536000; includeSubDomains";
       return 301 https://xxxxxxxxxxxxxxxxx$request_uri;

    }

    # HTTPS server
    #

    server {

        listen 443 ssl spdy;
        server_name *.xxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxx;

        ssl on;
        ssl_certificate      /etc/pki/tls/xxxxxxxxxxxxxx.pem;
        ssl_certificate_key  /etc/pki/tls/xxxxxxxxxxxxxxx.pem;
        ssl_trusted_certificate /etc/pki/tls/xxxxxxxxxxxxxx.pem;
        ssl_dhparam /etc/pki/tls/dhparam.pem;
        ssl_session_timeout  10m;
        ssl_prefer_server_ciphers on;
        ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
        ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256$
        ssl_session_cache shared:SSL:10m;

        ssl_stapling on;
        ssl_stapling_verify on;
        resolver 8.8.8.8 8.8.4.4 valid=300s;
        resolver_timeout 10s;

        error_page 404 /usr/local/nginx/html/error/forbidden.html;

        location  /404.html {
        internal;
        }

        set $skip_cache 0;

        # POST requests and urls with a query string should always go to PHP
        if ($request_method = POST) {
                set $skip_cache 1;
        }
        if ($query_string != "") {
                set $skip_cache 1;
        }

        # Don't cache uris containing the following segments
        if ($request_uri ~* "/wp-admin/|/xmlrpc.php|/bestellen/|/Klanten/|/Pro/|wp-.*.php|/feed/|index.php|sitemap(_index)?.xml") {
                set $skip_cache 1;
        }

        # Don't use the cache for logged in users or recent commenters
        if ($http_cookie ~* "comment_author|wordpress_[a-f0-9]+|wp-postpass|wordpress_no_cache|wordpress_logged_in") {
                set $skip_cache 1;
        }

        location / {

            root   html;
            index  index.html index.htm index.php;
            try_files $uri $uri/ /index.php?q=$request_uri;

            ModSecurityEnabled on;
            ModSecurityConfig /usr/local/src/modsecurity-2.9.0/modsecurity.conf;

        }

        location ~ \.php$ {

            add_header X-Cache $upstream_cache_status;
            add_header Strict-Transport-Security "max-age=31536000; includeSubDomains";
            add_header X-Content-Type-Options nosniff;

            fastcgi_pass   unix:/var/run/php-fpm.sock;
            fastcgi_index  index.php;
            fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
            include fastcgi_params;

            fastcgi_cache_bypass $skip_cache;
            fastcgi_no_cache $skip_cache;

            fastcgi_cache WORDPRESS;
            fastcgi_cache_valid  60m;

        }

        # location ~ /purge(/.*) {
        #
        # fastcgi_cache_purge WORDPRESS "$scheme$request_method$host$1";
        # }

        location ~ \.(css|js|htc)$ {

        expires 31536000s;
        add_header Pragma "public";
        add_header Cache-Control "public, must-revalidate, proxy-revalidate";

        }

        location ~ \.(html|htm|rtf|rtx|svg|svgz|txt|xsd|xsl|xml)$ {

        expires 3600s;
        add_header Pragma "public";
        add_header Cache-Control "public, must-revalidate, proxy-revalidate";

        }
        
        location ~ \.(asf|asx|wax|wmv|wmx|avi|bmp|class|divx|doc|docx|eot|exe|gif|gz|gzip|ico|jpg|jpeg|jpe|mdb|mid|midi|mov|qt|mp3|m4a|mp4|m4v|mpeg|mpg|mpe|mpp|otf|odb|odc|odf|odg|odp|ods|$

        expires 31536000s;
        add_header Pragma "public";
        add_header Cache-Control "public, must-revalidate, proxy-revalidate";

        }

        location = /robots.txt { access_log off; log_not_found off; }
        location ~ /\. { deny  all; access_log off; log_not_found off; }


    }

  }

But when i test it i get still Not Found error and not the 403:

Code: Select all

[root@xxxxxxxxxxxx nginx-1.7.10]# wget https://localhost/foo.php?foo=http://www.example.com 
--2015-03-03 10:07:14--  https://localhost/foo.php?foo=http://www.example.com
Resolving localhost (localhost)... ::1, 127.0.0.1
Connecting to localhost (localhost)|127.0.0.1|:443... connected.
HTTP request sent, awaiting response... 404 Not Found
2015-03-03 10:07:14 ERROR 404: Not Found.
the eror.log:

Code: Select all

2015/03/03 02:38:18 [error] 13472#0: *93 FastCGI sent in stderr: "Unable to open primary script: /usr/local/nginx/html/foo.php (No such file or directory)" while reading response header from upstream, client: 127.0.0.1, server: *.xxxxxxxxxxxxxxx, request: "GET /foo.php?foo=http://www.example.com HTTP/1.1", upstream: "fastcgi://unix:/var/run/php-fpm.sock:", host: "localhost"
the modsec_audit.log is empty...... :roll:


What i did wrong on this one, any help will be appreciated.

PS it's running on centos 7, nginx 1.7.10 , modsecurity 2.9.0, php-fpm (art)

EDIT:

i finnaly get modsecurity working on nginx only i see the in the error.log:

Code: Select all

ModSecurity: Access denied with code 403 (phase 2). Pattern match "([\\~\\!\\@\\#\\$\\%\\^\\&\\*\\(\\)\\-\\+\\=\\{\\}\\[\\]\\|\\:\\;\"\\'\\\xc2\xb4\\\xe2\x80\x99\\\xe2\x80\x98\\`\\<\\>].*?){8,$
ModSecurity: Audit log: Failed to lock global mutex: Permission denied [hostname ""] [uri "/"] [unique_id "wcAlAcccAclYA5AcAcAcARAS$
ModSecurity: Audit log: Failed to lock global mutex: Permission denied [hostname ""]
Anyone know's how to fix this:

ModSecurity: Audit log: Failed to lock global mutex: Permission denied [hostname ""]

PS: if i set user to root in /etc/nginx/nginx.conf it will be fixed but i don't wanna do that :roll:

Code: Select all

root     22547  0.0  0.0 277644 11848 ?        Ss   01:47   0:00 nginx: master process /usr/sbin/nginx -c /etc/nginx/nginx.conf
nginx    22548  0.0  0.0 278000 12816 ?        S    01:47   0:00  \_ nginx: worker process
nginx    22549  0.0  0.0 278000 12816 ?        S    01:47   0:00  \_ nginx: worker process

Greetz
DarkF@der
Forum Regular
Forum Regular
Posts: 313
Joined: Thu May 07, 2009 12:46 pm

Re: Modsecurity nginx failed to work

Unread post by DarkF@der »

Nobody? :oops:

EDIT:

The root cause appears to be related to the use of serial logging in modsecurity.conf:

Code: Select all

SecAuditLogType Serial
i changed to SecAuditLogType Concurrent and now it's working. :lol:
Post Reply