Compiling nginx with PageSpeed and naxsi

Today we are going to compile nginx web server with naxsi WAF (Web Application Firewall), Google PageSpeed modules and HTTP/2 support.

Unlike Apache where modules are dynamically loaded, adding modules to nginx requires recompiling the software. In this case we want to add naxsi for security and mod_pagespeed (ngx_pagespeed) for performance reasons.

At the time of writing the latest versions of software used were:

  • Nginx 1.13.5
  • ngx_pagespeed 1.12.34.3-stable
  • OpenSSL 1.0.2l
  • naxsi 0.55.3

I’m compiling this on CentOS 7.

 

Preparing the environment

Assuming we already have build tools installed for our specific distribution, we can start by downloading all the required software:

# Create our build environment
mkdir -p ~/build
cd ~/build

# Download naxsi
wget https://github.com/nbs-system/naxsi/archive/0.55.3.tar.gz
tar xvzf 0.55.3.tar.gz

# Download ngx_pagespeed
wget https://github.com/pagespeed/ngx_pagespeed/archive/v1.12.34.3-stable.tar.gz
tar xvzf v1.12.34.3-stable.tar.gz

# Download OpenSSL
wget https://www.openssl.org/source/openssl-1.0.2l.tar.gz
tar xvzf openssl-1.0.2l.tar.gz

# Download nginx
wget https://nginx.org/download/nginx-1.13.5.tar.gz
tar xvzf nginx-1.13.5.tar.gz

# Switch to nginx directory
cd nginx-1.13.5

 

Configuring the software

Here’s where it all comes together – we specify our compile options here. Adding and enabling modules, setting paths etc…

./configure --prefix=/etc/nginx --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 --pid-path=/var/run/nginx.pid \
--lock-path=/var/run/nginx.lock --http-client-body-temp-path=/var/cache/nginx/client_temp \
--http-proxy-temp-path=/var/cache/nginx/proxy_temp --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp \
--http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp --http-scgi-temp-path=/var/cache/nginx/scgi_temp \
--user=nginx --group=nginx \
--with-http_ssl_module --with-http_realip_module --with-http_addition_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_stub_status_module --with-http_auth_request_module --with-http_geoip_module \
--with-threads --with-stream --with-stream_ssl_module --with-mail --with-mail_ssl_module \
--with-file-aio --with-http_v2_module \
--with-cc-opt='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic' \
--add-module=../ngx_pagespeed-1.12.34.3-stable --add-module=../naxsi-0.55.3/naxsi_src --with-openssl=../openssl-1.0.2l

The configure script sets the custom options we want, in addition to making sure everything that’s needed is present – various libraries, compilers… If you encounter any errors, you are probably missing some library, which you will need to install using your distribution’s package manager.

Modify the script to your requirements. You probably don’t need mail module nor mp4 and flv streaming modules. You might also want to change the paths and user/group combination to better suit your environment.

 

Building the software

Now that we have our build options set we need to actually build the software:

make

This will take several minutes. If no errors are encountered during this process we can call this a successful custom nginx build!

 

Installing the software

Now to actually use it, we need to install it. There are two ways:

  • make it a package (rpm, deb…) – RECOMMENDED
  • run make install

For the sake of simplicity we are just going to run make install and call it a day, but you never want to do this on a server – you lose track of what’s installed and what version it is, which can be a security risk. Package is also really easily distributable between multiple computers.

 

Verifying everything works

No matter what install method you chose, running nginx -V should now return the version of the software installed, along with all configure arguments we have specified earlier.

nginx version: nginx/1.13.5
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-16) (GCC) 
built with OpenSSL 1.0.2l  25 May 2017
TLS SNI support enabled
configure arguments: --prefix=/etc/nginx --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 --pid-path=/var/run/nginx.pid --lock-path=/var/run/nginx.lock --http-client-body-temp-path=/var/cache/nginx/client_temp
--http-proxy-temp-path=/var/cache/nginx/proxy_temp --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp
--http-scgi-temp-path=/var/cache/nginx/scgi_temp --user=nginx --group=nginx --with-http_ssl_module --with-http_realip_module --with-http_addition_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_stub_status_module --with-http_auth_request_module --with-http_geoip_module
--with-threads --with-stream --with-stream_ssl_module --with-mail --with-mail_ssl_module --with-file-aio --with-http_v2_module
--with-cc-opt='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches
-m64 -mtune=generic' --add-module=../ngx_pagespeed-1.12.34.3-stable --add-module=../naxsi-0.55.3/naxsi_src --with-openssl=../openssl-1.0.2l

 

Warning: For all software that you build yourself you need to follow its update stream. Whenever a bug or a vulnerability is found in the software (and that includes dependencies (like OpenSSL) too!), you need to rebuild with the patched version. Unpatched software poses a security risk!

1 Comment

Add yours

  1. Thanks straight to the point.

Leave a Reply...