Tuesday, May 13, 2014

Install nginx with naxsi and doxi rules

Install nginx with naxsi and doxi rules
apt-get install nginx nginx-naxsi

Enable naxsi core rules

nano /etc/nginx/nginx.conf
Uncomment
#include /etc/nginx/naxsi_core.rules;

to
include /etc/nginx/naxsi_core.rules;

Enable naxsi basic rule and check rule
nano /etc/nginx/sites-enabled/default

Under location /
Uncomment
#include /etc/nginx/naxsi.rules;

to
include /etc/nginx/naxsi.rules;

You've enabled naxsi for nginx, now look at the file /etc/nginx/naxsi.rules
cat, this is sample configuration
# Sample rules file for default vhost.

#LearningMode;
SecRulesEnabled;
#SecRulesDisabled;
#DeniedUrl "/RequestDenied";
DeniedUrl "/denied.html";

## check rules
CheckRule "$SQL >= 8" BLOCK;
CheckRule "$RFI >= 8" BLOCK;
CheckRule "$TRAVERSAL >= 4" BLOCK;
CheckRule "$EVADE >= 4" BLOCK;
CheckRule "$XSS >= 8" BLOCK;


There are 2 mode, Learning mode and Normal mode, uncomment LearningMode; then your naxsi will automatically learn rule. All violate action will be logged to error.log 

of nginx but the request will not be blocked.

If you want naxsi to run in NormalMode then comment out #LearningMode; naxsi will block violated requests matchs the naxsi rules and redirect it to DeniedUrl 

"/denied.html"; You can create a denied.html with content match your need to inform user.

With LearningMode, you can analyse the violated request and in some cases you want to allow it, then you could use nx_util 
Download nx_util from https://code.google.com/p/naxsi/downloads/detail?name=nx_util-1.1.tgz&can=1&q=
tar -xzvf nx_util...tar.gz
cd nx_util...
python setup.py build
python setup.py install

If you don't have python, install it with
apt-get install python

Analyse violated requests
nx_util -l /var/log/nginx/error.log -o
Deleting old database :naxsi_sig
List of imported files :['/var/log/nginx/error.log']
Importing file /var/log/nginx/error.log
        Successful events :8349
        Filtered out events :0
        Non-naxsi lines :0
        Malformed/incomplete lines 72
End of db commit...
Count (lines) success:8349
########### Optimized Rules Suggestion ##################
# total_count:3455 (41.38%), peer_count:1 (100.0%) | ?
BasicRule wl:42000004 "mz:URL";
# total_count:1488 (17.82%), peer_count:1 (100.0%) | ?
BasicRule wl:42000334 "mz:URL";
# total_count:299 (3.58%), peer_count:1 (100.0%) | Content is neither mulipart/x-www-form..
BasicRule wl:1402 "mz:$HEADERS_VAR:content-type";
# total_count:246 (2.95%), peer_count:1 (100.0%) | ?
BasicRule wl:42000244 "mz:URL";
# total_count:246 (2.95%), peer_count:1 (100.0%) | ?
BasicRule wl:42000082 "mz:URL";
# total_count:244 (2.92%), peer_count:1 (100.0%) | ?
BasicRule wl:42000358 "mz:URL";
# total_count:244 (2.92%), peer_count:1 (100.0%) | ?
BasicRule wl:42000083 "mz:URL";
# total_count:169 (2.02%), peer_count:1 (100.0%) | html open tag
BasicRule wl:1302 "mz:URL";

Then you can add these rules to whitelist

Doxi: naxsi rules from snort signature
Download doxi-rules from https://bitbucket.org/lazy_dogtown/doxi-rules/overview and put it to /etc/nginx/doxi-rules/
Example you have "app_server.rules  malware.rules  scanner.rules  web_apps.rules  web_server.rules"

To enable these rules, then go to /etc/nginx/nginx.html. Add the following line inside http

include /etc/nginx/doxi-rules/*.rules;

Enable CheckRule UnWantedAccess and Identified Attacks

Add the following to /etc/nginx/naxsi.rules

# UnWantedAccess
CheckRule "$UWA >= 8" BLOCK;

# Identified Attacks

CheckRule "$ATTACK >= 8" BLOCK;

Restart nginx to use new rules. 

For testing, you can install nessus and scan your website. During this, check your nginx_error_log
tail -f /var/log/nginx/error.log

2014/05/13 13:03:15 [error] 5489#0: *2737 NAXSI_FMT: 

ip=192.168.1.10&server=edge.blogspot.com&uri=/typo3/SZT8mWfN.htm&learning=0&total_processed=3657&total_blocked=2025&zone0=URL&id0=42000358&var_name0=, client: 

192.168.1.10, server: localhost, request: "CHECKIN /typo3/SZT8mWfN.htm HTTP/1.1", host: "edge.blogspot.com"
2014/05/13 13:03:15 [error] 5489#0: *2737 NAXSI_FMT: 

ip=192.168.1.10&server=edge.blogspot.com&uri=/typo3/SZT8mWfN.htm&learning=0&total_processed=3658&total_blocked=2026&zone0=URL&id0=42000358&var_name0=, client: 

192.168.1.10, server: localhost, request: "CHECKOUT /typo3/SZT8mWfN.htm HTTP/1.1", host: "edge.blogspot.com"
2014/05/13 13:03:15 [error] 5489#0: *2737 NAXSI_FMT: 

ip=192.168.1.10&server=edge.blogspot.com&uri=/typo3/SZT8mWfN.htm&learning=0&total_processed=3659&total_blocked=2027&zone0=URL&id0=42000358&var_name0=, client: 

192.168.1.10, server: localhost, request: "CONNECT /typo3/SZT8mWfN.htm HTTP/1.1", host: "edge.blogspot.com"
2014/05/13 13:03:15 [error] 5489#0: *2737 NAXSI_FMT: 

ip=192.168.1.10&server=edge.blogspot.com&uri=/typo3/SZT8mWfN.htm&learning=0&total_processed=3660&total_blocked=2028&zone0=URL&id0=42000358&var_name0=, client: 

192.168.1.10, server: localhost, request: "COPY /typo3/SZT8mWfN.htm HTTP/1.1", host: "edge.blogspot.com"
2014/05/13 13:03:15 [error] 5489#0: *2737 NAXSI_FMT: 

ip=192.168.1.10&server=edge.blogspot.com&uri=/typo3/SZT8mWfN.htm&learning=0&total_processed=3661&total_blocked=2029&zone0=URL&id0=42000358&var_name0=, client: 

192.168.1.10, server: localhost, request: "DEBUG /typo3/SZT8mWfN.htm HTTP/1.1", host: "edge.blogspot.com"
2014/05/13 13:03:15 [error] 5489#0: *2737 NAXSI_FMT: 

ip=192.168.1.10&server=edge.blogspot.com&uri=/typo3/SZT8mWfN.htm&learning=0&total_processed=3662&total_blocked=2030&zone0=URL&id0=42000358&var_name0=, client: 

192.168.1.10, server: localhost, request: "DELETE /typo3/SZT8mWfN.htm HTTP/1.1", host: "edge.blogspot.com"
2014/05/13 13:03:15 [error] 5489#0: *2737 NAXSI_FMT: 

ip=192.168.1.10&server=edge.blogspot.com&uri=/typo3/SZT8mWfN.htm&learning=0&total_processed=3663&total_blocked=2031&zone0=URL&id0=42000358&var_name0=, client: 

192.168.1.10, server: localhost, request: "GET /typo3/SZT8mWfN.htm HTTP/1.1", host: "edge.blogspot.com"
2014/05/13 13:03:15 [error] 5489#0: *2737 NAXSI_FMT: 

ip=192.168.1.10&server=edge.blogspot.com&uri=/typo3/SZT8mWfN.htm&learning=0&total_processed=3664&total_blocked=2032&zone0=URL&id0=42000358&var_name0=, client: 

192.168.1.10, server: localhost, request: "HEAD /typo3/SZT8mWfN.htm HTTP/1.1", host: "edge.blogspot.com"
2014/05/13 13:03:20 [error] 5489#0: *2738 NAXSI_FMT: 

ip=192.168.1.10&server=edge.blogspot.com&uri=/typo3/SZT8mWfN.htm&learning=0&total_processed=3665&total_blocked=2033&zone0=URL&id0=42000358&var_name0=, client: 

192.168.1.10, server: localhost, request: "INDEX /typo3/SZT8mWfN.htm HTTP/1.1", host: "edge.blogspot.com"
2014/05/13 13:03:20 [error] 5489#0: *2738 NAXSI_FMT: 

ip=192.168.1.10&server=edge.blogspot.com&uri=/typo3/SZT8mWfN.htm&learning=0&total_processed=3666&total_blocked=2034&zone0=URL&id0=42000358&var_name0=, client: 

192.168.1.10, server: localhost, request: "LABEL /typo3/SZT8mWfN.htm HTTP/1.1", host: "edge.blogspot.com"
2014/05/13 13:03:20 [error] 5489#0: *2738 NAXSI_FMT: 

ip=192.168.1.10&server=edge.blogspot.com&uri=/typo3/SZT8mWfN.htm&learning=0&total_processed=3667&total_blocked=2035&zone0=URL&id0=42000358&var_name0=, client: 

192.168.1.10, server: localhost, request: "LOCK /typo3/SZT8mWfN.htm HTTP/1.1", host: "edge.blogspot.com"
2014/05/13 13:03:20 [error] 5489#0: *2738 NAXSI_FMT: 

ip=192.168.1.10&server=edge.blogspot.com&uri=/typo3/SZT8mWfN.htm&learning=0&total_processed=3668&total_blocked=2036&zone0=URL&id0=42000358&var_name0=, client: 

192.168.1.10, server: localhost, request: "MERGE /typo3/SZT8mWfN.htm HTTP/1.1", host: "edge.blogspot.com"
2014/05/13 13:03:20 [error] 5489#0: *2738 NAXSI_FMT: 

ip=192.168.1.10&server=edge.blogspot.com&uri=/typo3/SZT8mWfN.htm&learning=0&total_processed=3669&total_blocked=2037&zone0=URL&id0=42000358&var_name0=, client: 

192.168.1.10, server: localhost, request: "MKACTIVITY /typo3/SZT8mWfN.htm HTTP/1.1", host: "edge.blogspot.com"
2014/05/13 13:03:20 [error] 5489#0: *2738 NAXSI_FMT: 

ip=192.168.1.10&server=edge.blogspot.com&uri=/typo3/SZT8mWfN.htm&learning=0&total_processed=3670&total_blocked=2038&zone0=URL&id0=42000358&var_name0=, client: 

192.168.1.10, server: localhost, request: "MKCOL /typo3/SZT8mWfN.htm HTTP/1.1", host: "edge.blogspot.com"
2014/05/13 13:03:20 [error] 5489#0: *2738 NAXSI_FMT: 

ip=192.168.1.10&server=edge.blogspot.com&uri=/typo3/SZT8mWfN.htm&learning=0&total_processed=3671&total_blocked=2039&zone0=URL&id0=42000358&var_name0=, client: 

192.168.1.10, server: localhost, request: "MKWORKSPACE /typo3/SZT8mWfN.htm HTTP/1.1", host: "edge.blogspot.com"

Sample nginx.conf
user www-data;
worker_processes                4;      # one(1) worker or equal the number of _real_ cpu cores. 4=4 core cpu
worker_priority                 15;     # renice workers to reduce priority compared to system processes for
                                        # machine health. worst case nginx will get ~25% system resources at nice=15
# worker_rlimit_nofile          1024;   # maximum number of open files

pid /run/nginx.pid;

events {
worker_connections              768;    # number of parallel or concurrent connections per worker_processes
# multi_accept                  on;
# accept_mutex                  on;     # serially accept() connections and pass to workers, efficient if workers gt 1
# accept_mutex_delay            500ms;  # worker process will accept mutex after this delay if not assigned. (default 500ms)
}

http {
## Size Limits
# client_body_buffer_size       8k;
# client_header_buffer_size     1k;
# client_max_body_size          1m;
# large_client_header_buffers   4 4k/8k;

# Timeouts, do not keep connections open longer then necessary to reduce
# resource usage and deny Slowloris type attacks.
client_body_timeout             5s;     # maximum time between packets the client can pause when sending nginx any data
client_header_timeout           5s;     # maximum time the client has to send the entire header to nginx
keepalive_timeout               75s;    # timeout which a single keep-alive client connection will stay open
send_timeout                    15s;    # maximum time between packets nginx is allowed to pause when sending the client data

## General Options
# aio                           on;     # asynchronous file I/O, fast with ZFS, make sure sendfile=off
charset                         utf-8;  # adds the line "Content-Type" into response-header, same as "source_charset"
default_type                    application/octet-stream;
gzip                            off;    # disable on the fly gzip compression due to higher latency, only use gzip_static
# gzip_disable                  "msie6";
# gzip_static                   on;     # precompress content (gzip -9) with an external script
# gzip_vary                     on;     # send response header "Vary: Accept-Encoding"
# gzip_proxied                  any;    # allows compressed responses for any request even from proxies
# gzip_comp_level 6;
# gzip_buffers 16 8k;
# gzip_http_version 1.1;
# gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;
ignore_invalid_headers          on;
include                         /etc/nginx/mime.types;
include                         /etc/nginx/conf.d/*.conf;
include                         /etc/nginx/sites-enabled/*;
keepalive_requests              50;     # number of requests per connection, does not affect SPDY
keepalive_disable               none;   # allow all browsers to use keepalive connections
max_ranges                      1;      # allow a single range header for resumed downloads and to stop large range header DoS attacks
msie_padding                    off;
open_file_cache                 max=1000 inactive=2h;
open_file_cache_errors          on;
open_file_cache_min_uses        1;
open_file_cache_valid           1h;
output_buffers                  1 512;
postpone_output                 1440;   # postpone sends to match our machine's MSS
read_ahead                      512K;   # kernel read head set to the output_buffers
recursive_error_pages           on;
reset_timedout_connection       on;     # reset timed out connections freeing ram
sendfile                        on;     # on for decent direct disk I/O
server_tokens                   off;    # version number in error pages
# server_names_hash_bucket_size 64;
server_name_in_redirect         off;    # if off, nginx will use the requested Host header
source_charset                  utf-8;  # same value as "charset"
tcp_nodelay                     on;     # Nagle buffering algorithm, used for keepalive only
tcp_nopush                      off;
types_hash_max_size             2048;

## Request limits
limit_req_zone  $binary_remote_addr  zone=gulag:1m   rate=60r/m;

# Logging Settings
log_format  main  '$remote_addr $host $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent" $ssl_cipher $request_time';
access_log /var/log/nginx/access.log main;
error_log /var/log/nginx/error.log;

# NAXSI
include /etc/nginx/naxsi_core.rules;
include /etc/nginx/doxi-rules/*.rules;

# PASSENGER
# passenger_root /usr;
# passenger_ruby /usr/bin/ruby;

}

Sample default site:
server {
        listen 80 default_server;
        root /usr/share/nginx/html;
        index index.php index.html index.html index.htm;
        server_name _;

        rewrite ^/(.*\.php)(/)(.*)$ /$1?file=/$3 last;  # For Moodle running
#       client_max_body_size 10000M;                    # For Moodle installation

        location / {
                try_files $uri $uri/ =404;
                # Uncomment to enable naxsi on this location
                include /etc/nginx/naxsi.rules;
        }

        # Only for nginx-naxsi used with nginx-naxsi-ui : process denied requests
        #location /RequestDenied {
        #       proxy_pass http://127.0.0.1:8080;
        #}

        error_page 404 /404.html;

        # redirect server error pages to the static page /50x.html
        #
        error_page 500 502 503 504 /50x.html;
        location = /50x.html {
                root /usr/share/nginx/html;
        }

        location ~ \.php$ {
                fastcgi_split_path_info ^(.+\.php)(/.+)$;
                # NOTE: You should have "cgi.fix_pathinfo = 0;" in php.ini

                fastcgi_pass unix:/var/run/php5-fpm.sock;
                fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
                fastcgi_index index.php;
                include fastcgi_params;
#               fastcgi_read_timeout 600;               # For Moodle installation
        }

}

Link:
https://code.google.com/p/naxsi/
http://www.proteansec.com/linux/naxsi/
http://allthelittlebits.com/naxsi-doxi-detailed-review/

No comments:

Post a Comment