Setup NGINX with mod-security on Linux
Dec-17-2016
This was tested on ubuntu 17.04
There is a bug - if you forward to another address, nginx core dumps when modsecurity is enabled.
I disabled ModSecurity for my forwarded sites
in the <server> section of sites...
location /LOCAL/ {
ModSecurityEnabled off;
rewrite ^/LOCAL(.*)$ $1 break;
proxy_pass http://fx6100 ;
}
See also (I used these as references: ... shoulders of giants ...):
Prepare the build environment
install all reqd. build components (you probably have most of them)
sudo apt-get install build-essential libpcre3 libpcre3-dev libssl-dev libtool autoconf apache2-dev libxml2-dev libcurl4-openssl-dev
setup a directory in which to build (we'll refer to this in the later steps)
mkdir ~/src
cd ~/src
Download the sources
Get mod-security
check for the latest version here. At time of writing 2.9.1 was the most recent stable.
cd ~/src
wget https://www.modsecurity.org/tarball/2.9.0/modsecurity-2.9.1.tar.gz
tar -zxvf modsecurity*.tar.gz
rm modsecurity*.tar.gz
MOD_SEC_DIR=$(ls -rtd ~/src/modsecurity-* | tail -1 )
$MOD_SEC_DIR is determined from the most recently changed directory in the downloads area. It's used below to save time in the following scripts. Verify by :
echo $MOD_SEC_DIR
Get nginx
check for the latest [NB not an https URL] version here. At time of writing 1.11.7 was the most recent stable.
cd ~/src
wget http://nginx.org/download/nginx-1.11.7.tar.gz
tar -zxvf nginx*.tar.gz
rm nginx*.tar.gz
NGINX_DIR=$(ls -rtd ~/src/nginx-* | tail -1 )
If I (and I should!) want to verify the download was secure:
gpg --recv-keys A1C052F8
wget -O/tmp/xxx -nv http://nginx.org/download/nginx-1.11.7.tar.gz.asc
gpg --verify /tmp/xxx nginx-1.11.7.tar.gz
You should see this :
gpg: Signature made Tue 17 Nov 2015 09:55:05 AM EST using RSA key ID A1C052F8
gpg: Good signature from "Maxim Dounin "
gpg: WARNING: This key is not certified with a trusted signature!
gpg: There is no indication that the signature belongs to the owner.
Primary key fingerprint: B0F4 2533 73F8 F6F5 10D4 2178 520A 9993 A1C0 52F8
Build mod-security
cd ${MOD_SEC_DIR}
./autogen.sh
./configure --enable-standalone-module
make
Config nginx build
This config below works
Look for extensions here
This is configured to use /etc/nginx as the base directory (similar to standard ubuntu pkg)
cd ${NGINX_DIR}
./configure \
--user=www-data \
--group=www-data \
--prefix=/etc/nginx/tmp \
--conf-path=/etc/nginx/nginx.conf \
--pid-path=/etc/nginx/nginx.pid \
--http-log-path=/var/log/nginx/access.log \
--error-log-path=/var/log/nginx/error.log \
--with-pcre-jit \
--with-http_ssl_module \
--add-module=${MOD_SEC_DIR}/nginx/modsecurity
Build nginx
All the hard work was just done ! Build it.
make
Deploy nginx
I deploy non-standard items to /opt/install and link the preferred version to /opt. Change the systemd service file to reflect your preferred deployment location.
cd /opt/install
sudo cp $NGINX_DIR/objs/nginx .
cd ..
sudo ln -fs install/nginx .
Configure modsecurity
I put the public modsecurity rules (refer to owasp) into /etc/modsecurity
sudo mkdir -p /etc/modsecurity
cd /etc/modsecurity
wget https://github.com/SpiderLabs/owasp-modsecurity-crs/tarball/master -O rules.tar.gz
tar -zvxf rules.tar.gz
Enable mod-security in the nginx server (e.g. in sites-enabled )
server {
ModSecurityEnabled on;
ModSecurityConfig modsecurity.conf;
listen 80;
...
}
Now nginx can't include patterns (yet), so we will build the config file (modsecurity.conf) on the fly and copy required data files to the nginx directory
In addition, we enable modsecurity and use /tmp as the scratch directory
echo Removing old data links
rm /etc/nginx/*.data 2>/dev/null
echo Resetting mapping to unicode mappings
ln -sf /etc/modsecurity/unicode.mapping /etc/nginx 2>/dev/null
echo Creating new data links
for d in /etc/modsecurity/base_rules/*.data
do
ln -s $d /etc/nginx
done
echo Building combined config file
echo "#SecStatusEngine On" > /etc/nginx/modsecurity.conf
echo "SecRuleEngine On" >> /etc/nginx/modsecurity.conf
echo "SecDataDir /tmp" >> /etc/nginx/modsecurity.conf
cat /etc/modsecurity/modsecurity_crs_10_setup.conf.example >> /etc/nginx/modsecurity.conf
for c in /etc/modsecurity/base_rules/*.conf
do
cat $c >> /etc/nginx/modsecurity.conf
done
systemd setup
I am using Ubuntu 15.10 - systemd
variant
I setup the service file as simply as possible. Note data is copied from between the << marker (EOF in this case)
sudo cat /etc/systemd/system/nginx.service << EOF
[Unit]
Description=nginx server
[Service]
PIDFile=/run/nginx.pid
ExecStart=/opt/nginx
ExecReload=/bin/kill -HUP $MAINPID
ExecStop=/bin/kill -QUIT $MAINPID
KillMode=process
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
Then enabled the service
sudo systemctl enable nginx.service