Docker container for Nginx with Naxsi based on Ubuntu 16.04

This is an upgrade of my proxy container from Building a small server for photography website. I wanted to get latest versions of Nginx and Naxsi. Unfortunately there is no nginx-naxsi package available like it was in Ubuntu 14.04. And even though Nginx now allows dynamically loaded modules, Naxsi hasn’t been converted to a loadable module yet and needs to be compiled. Luckily the process is not complicated. I will replicate method 1 from this article and adapt it for Docker container.

We need to get configure arguments that standard package nginx binary was compiled with:

$ docker run --rm -it ubuntu:16.04
# apt-get update
# apt-get install nginx
# nginx -V

You should see a very long line starting with “configure arguments”, those are our options:

root@3be344efcae8:/# nginx -V
nginx version: nginx/1.10.0 (Ubuntu)
built with OpenSSL 1.0.2g 1 Mar 2016
TLS SNI support enabled
configure arguments: --with-cc-opt='-g -O2 -fPIE -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2' --with-ld-opt='-Wl,-Bsymbolic-functions -fPIE -pie -Wl,-z,relro -Wl,-z,now' --prefix=/usr/share/nginx --conf-path=/etc/nginx/nginx.conf --http-log-path=/var/log/nginx/access.log --error-log-path=/var/log/nginx/error.log --lock-path=/var/lock/nginx.lock --pid-path=/run/nginx.pid --http-client-body-temp-path=/var/lib/nginx/body --http-fastcgi-temp-path=/var/lib/nginx/fastcgi --http-proxy-temp-path=/var/lib/nginx/proxy --http-scgi-temp-path=/var/lib/nginx/scgi --http-uwsgi-temp-path=/var/lib/nginx/uwsgi --with-debug --with-pcre-jit --with-ipv6 --with-http_ssl_module --with-http_stub_status_module --with-http_realip_module --with-http_auth_request_module --with-http_addition_module --with-http_dav_module --with-http_geoip_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_image_filter_module --with-http_v2_module --with-http_sub_module --with-http_xslt_module --with-stream --with-stream_ssl_module --with-mail --with-mail_ssl_module --with-threads

Exit from the container. Now we need to check for latest Nginx and Naxsi source code. Make sure you also read any release notes provided:

In my case I found Nginx 1.10.3 and Naxsi 0.55.3. I need to download them first:

cd /data/proxy/build
wget https://nginx.org/download/nginx-1.10.3.tar.gz
wget https://github.com/nbs-system/naxsi/archive/0.55.3.tar.gz

Now create a Dockerfile using the above compile arguments and our freshly downloaded source code:

FROM ubuntu:16.04

# Install the relevant packages:
RUN apt-get update
RUN apt-get install -y nginx build-essential libpcre3-dev libssl-dev libxml2-dev libxslt-dev libgd-dev libgeoip-dev

# copy source code into /opt and unpack
ADD 0.55.3.tar.gz /opt
ADD nginx-1.10.3.tar.gz /opt

# build nginx with naxsi
WORKDIR /opt/nginx-1.10.3/
RUN ./configure --add-module=../naxsi-0.55.3/naxsi_src/ --sbin-path=/usr/sbin/nginx --with-cc-opt='-g -O2 -fPIE -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2' --with-ld-opt='-Wl,-Bsymbolic-functions -fPIE -pie -Wl,-z,relro -Wl,-z,now' --prefix=/usr/share/nginx --conf-path=/etc/nginx/nginx.conf --http-log-path=/var/log/nginx/access.log --error-log-path=/var/log/nginx/error.log --lock-path=/var/lock/nginx.lock --pid-path=/run/nginx.pid --http-client-body-temp-path=/var/lib/nginx/body --http-fastcgi-temp-path=/var/lib/nginx/fastcgi --http-proxy-temp-path=/var/lib/nginx/proxy --http-scgi-temp-path=/var/lib/nginx/scgi --http-uwsgi-temp-path=/var/lib/nginx/uwsgi --with-debug --with-pcre-jit --with-ipv6 --with-http_ssl_module --with-http_stub_status_module --with-http_realip_module --with-http_auth_request_module --with-http_addition_module --with-http_dav_module --with-http_geoip_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_image_filter_module --with-http_v2_module --with-http_sub_module --with-http_xslt_module --with-stream --with-stream_ssl_module --with-mail --with-mail_ssl_module --with-threads
RUN make
RUN make install

# lock nginx package
RUN apt-mark hold nginx

# remove debugging symbols etc.
RUN strip -s /usr/sbin/nginx

# cleanup (move out of deleted directory first)
WORKDIR /
RUN rm -rf /opt/*

# Set the same timezone as my host server
RUN ln -sf /usr/share/zoneinfo/Pacific/Auckland /etc/localtime

# expose port 80 so that our proxy server can respond to requests
EXPOSE 80 443

# Start nginx
CMD ["nginx", "-g", "daemon off;"]

Notes on the Dockerfile:

  • On the line starting with “RUN ./configure” we first list two new arguments “–add-module=../naxsi-0.55.3/naxsi_src/ –sbin-path=/usr/sbin/nginx” followed by what we found when running nginx -V above.
  • Adjust version numbers based on the source code downloaded.

Now build the docker image:

cd /data/proxy/build
docker build -t proxy .

If everything worked correctly, you should be able to create a container based on your new image, for example like this (provided you have created all those config files as per my article):

docker run --name proxy --link web:web \
-v /data/proxy/conf/nginx.conf:/etc/nginx/nginx.conf:ro \
-v /data/proxy/conf/naxsi_core.rules:/etc/nginx/naxsi_core.rules:ro \
-v /data/proxy/conf/naxsi.rules:/etc/nginx/naxsi.rules:ro \
-v /data/proxy/logs:/var/log/nginx \
-v /data/web/www:/var/www/html:ro \
-d -p 80:80 --restart=always proxy

Note: New Naxsi version comes with new naxsi_core.rules files so make sure you extract it from the image and use instead of the old one.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s