Custom Build Nginx

Warning: Draft Only, still work on this !!!

This walk-through is part of series of explicit step-by-step instruction to develop a WordPress based production platform. This document intended as learning points for beginner sysadmin and check list notes for experts.

If you are a web master, designer, blog writers, enterprise web admin, SME owner/manager, and you need a low cost system administrator to plan, create, secure, and maintain your WordPress production server, please contact us.

Installation walk-through performed on: Debian 8 on Digital Ocean Droplet. Same procedure should be work on AWS, Google Cloud, or other Cloud Instance / VPS with root privilege SSH access.

Scope of this walk-through is to make a custom build Nginx with PageSpeed and Naxsi on Debian 8 Jessie.

Nginx is a new trend of http server, replacing or proxying Apache web server. Nginx dynamic modules are currently very limited. Two important module is not included in the Debian repository build: Google PageSpeed and Naxsi. Debian Nginx-Naxsi was available on Wheezy (Debian 7) but dropped from Jessie (Debian 8). I cannot open Debian wiki to read the explanation since the website is often cannot be reached (403).

Google PageSpeed will increase Nginx speed quite significant. Naxsi provide protection from XSS, SQL Injection, and other threat. We’re watching close ModSecurity integration to Nginx, evaluating to replace Naxsi with ModSecurity. But probably it wont happen during Debian 8 lifecycle.

To deploy PageSpeed and Naxsi we need to make a custom build Nginx. This means we need to do the work each time there’s an important update on Nginx, PageSpeed, or Naxsi repository.

There’s also plan to complete this document with CertBot and HTTP/2 installation.

This walk-through will install:

  • Debian Jessie-Backports Nginx, currently 1.9.10-1
  • Nginx-mod PageSpeed, currently 1.11.33.3-beta
  • Nginx-mod Naxsi, currently 0.54

Related Readings

Parent Document:
Complete Walk-through to Create a WordPress Production Platform.

Requirements: Server hardware, server software, client software.

Spawning From: Installing LEMP on Debian 8

General Instruction:

  • Bold words are variables that should be change according to your setting / preference.
  • Line with text inside () is something that you have to do.
  • Instruction line can be copied with triple clicks, and paste with left click to Bitvise SSH Client shell prompt or nano editor.

Walk-through:

  1. Download Nginx source from Debian repository

    1. Install dependencies
      sudo aptitude install build-essential zlib1g-dev libpcre3 libpcre3-dev

      Reject first solution, accept the second one:
      [N], [Y]

    2. Get nginx source
      • Edit source.list
        sudo nano /etc/apt/sources.list
      • Add following lines at the end of source.list file
        deb http://ftp.debian.org/debian jessie-backports main
        deb-src http://ftp.debian.org/debian jessie-backports main

        (Ctrl-x, y, Enter) to save and exit nano

        Refresh your repository:

        sudo apt-get update
      • Get nginx version to use:
        apt-cache policy nginx
      • Compare nginx backport version to nginx latest version
        http://nginx.org/en/download.html
      • Consider if you have to use nginx latest-stable version or Debian Jessie-updates version instead on Debian Backports. It is recommended to use Nginx from Debian Backports.
        • Current Jessie-updates Nginx version is: 1.6.2-5+deb8u2
        • Current Jessie Backports Nginx version is: 1.9.10-1~bpo8+3
        • Current latest-stable Nginx version is: 1.10.1
    3. Create mynginx source folder at your home directory if not yet exist. You can name it any name you like. The folder will store all version of Nginx that you build during your Debian 8 Jessie server lifetime (until 2020).
      mkdir ~/mynginx
      cd ~/mynginx
      mkdir nginx-backports
    4. Download nginx source to the source folder
      wget http://nginx.org/keys/nginx_signing.key
      sudo apt-key add nginx_signing.key
      gpg --import nginx_signing.key
      cd ~/mynginx/nginx-backports
      apt-get source nginx/jessie-backports
    5. Check your nginx source folder
      ls -lt

      The /mynginx/nginx-backports folder should contain:

      1. Folder nginx-1.9.10
      2. File .dsc
      3. File .debian.tar.xz
      4. File .orig.tar.gz
  2. Pagespeed source

    1. Check PageSpeed latest version number, browse to:
      https://developers.google.com/speed/pagespeed/module/release_notes
      Current version: 1.11.33.3-beta
    2. Download PageSpeed source and PSOL source
      cd ~/mynginx/nginx-backports
      wget https://github.com/pagespeed/ngx_pagespeed/archive/release-1.11.33.3-beta.zip
      unzip release-1.11.33.3-beta.zip -d nginx-1.9.10/
      cd nginx-1.9.10/ngx_pagespeed-release-1.11.33.3-beta/ 
      wget https://dl.google.com/dl/page-speed/psol/1.11.33.3.tar.gz 
      tar -xzvf 1.11.33.3.tar.gz
    3. Check PageSpeed source
       ls -lt ~/mynginx/nginx-backports/nginx-1.9.10/ngx_pagespeed-release-1.11.33.3-beta/

      the folder content should be:

       /psol
       /scripts
       /src
       /test
  3. Naxsi source

    1. Check Naxsi latest version number, browse to:
      https://github.com/nbs-system/naxsi/releases/latest
      Found current version: 0.54
    2. Download Naxsi source
      cd ~/mynginx/nginx-backports/ 
      wget https://github.com/nbs-system/naxsi/archive/0.54.tar.gz 
      tar -xvzf 0.54.tar.gz -C nginx-1.9.10/
    3. Check Naxsi source
      ls -lt ~/mynginx/nginx-backports/nginx-1.9.10/naxsi-0.54

      the folder content should be:

           /naxsi-config
           /naxsi-src
           /nxapi
           /t

  4. Compile Nginx

    1. Check folder content
      ls -lt ~/mynginx/nginx-backports/

      folder nginx-backports should have following content

      1. Folder /nginx-1.9.10 
      2. File nginx_1.9.10-1~bpo8+3.dsc
      3. File nginx_1.9.10-1~bpo8+3.debian.tar.xz
      4. File nginx_1.9.10.orig.tar.gz
      5. File 0.54.tar.gz
      6. File release-1.11.33.3-beta.zip
    2. Edit compile script
      nano ~/mynginx/nginx-backports/nginx-1.9.10/debian/rules

      Add Naxsi module on common_configure_flags before the –with-debug:

      --add-module=$(CURDIR)/naxsi-0.54/naxsi_src \

      Add PageSpeed module before the last add-module line on full_configure_flags and extra_configure_flags (that is 2 time paste), before other –add-module:

      --add-module=$(CURDIR)/ngx_pagespeed-release-1.11.33.3-beta \

      [Control-x], [y], [Enter] to save and exit nano.

    3. Change version number to avoid auto update/upgrade
      sudo nano ~/mynginx/nginx-backports/nginx-1.9.10/debian/changelog

      Edit the first line:

      nginx (1.9.10-1~bpo8+3) jessie-backports; urgency=medium

      Add your own version name, it will be the package name:

      nginx (1.9.10-1~bpo8+3-mynginx) jessie-backports; urgency=medium

      [Control-x], [y], [Enter] to save and exit nano.

    4. Obscure server header information for better security
      vi +49 ~/mynginx/nginx-backports/nginx-1.9.10/src/http/ngx_http_header_filter_module.c 

      Find the lines:

      static char ngx_http_server_string[] = "Server: nginx" CRLF;
      static char ngx_http_server_full_string[] = "Server: " NGINX_VER CRLF;
      

      and modify to (press Insert button):

      static char ngx_http_server_string[] = "Server: the-ocean" CRLF;
      static char ngx_http_server_full_string[] = "Server: the-ocean" CRLF;

      [Escape], [:], [x] to save and exit vi (that is Escape then : then x).

    5. Compile Custom NginxBefore compiling, remove all previously built file:
      rm -f ~/mynginx/nginx-backports/nginx-*.deb

      Run buildpackage

      cd ~/mynginx/nginx-backports/nginx-1.9.10
      sudo dpkg-buildpackage -b

      If shown dependency message, install all of required dependencies, copy them from the error message, remove words inside brackets, remove package before |, add “sudo aptitude install” before the line:

      sudo aptitude install autotools-dev debhelper dh-systemd libexpat-dev libgd-dev libgeoip-dev liblua5.1-0-dev libmhash-dev libpam0g-dev libperl-dev libssl-dev libxslt1-dev po-debconf
      Try to buld the package again:
      sudo dpkg-buildpackage -b

      Should any package still reported as dependency problem, install the jessie-backport version of that package:

      sudo aptitude -f jessie-backports install libssl-dev
      sudo apt-get update
      sudo apt-get upgrade

      The next build should start without problem:

      sudo dpkg-buildpackage -b

      The result is several new files. The most important are the deb packages:

      • nginx-full_1.9.10-1~bpo8+3mynginx_amd64.deb
      • nginx_1.9.10-1~bpo8+3mynginx_all.deb
      • nginx-common_1.9.10-1~bpo8+3mynginx_all.deb
    6. Install package
      If you are repeating or doing re-installation, first remove the existing nginx:

      sudo service nginx stop
      sudo apt-get remove nginx*
      sudo apt-get purge nginx*

      Confirm that no nginx or apache package installed:

      systemctl status nginx
      systemctl status apache

      Install the new package:

      sudo dpkg -i nginx-full_1.9.10-1~bpo8+3-mynginx_amd64.deb \
      nginx-common_1.9.10-1~bpo8+3-mynginx_all.deb \
      nginx_1.9.10-1~bpo8+3-mynginx_all.deb

      If there’s problem with dependencies:

      sudo apt-get -f install
    7. Check new Nginx version
      1. Check nginx version:
        sudo nginx -V
      2. Check header version obscurity:
        curl -I http://localhost

        Check that no information about Nginx server and its version.

    8. Save nginx original config
      sudo cp /etc/nginx/sites-available/default /etc/nginx/sites-available/default.original
      
      

      Avoid error 413 upload limit:

      sudo nano /etc/nginx/nginx.conf
      client_max_body_size 2M;
  5. Configure PageSpeed

    1. Edit Nginx Config to support PageSpeed
      sudo nano /etc/nginx/nginx.conf

      Add the following lines to the http {block}:

      ##
      #ngx_pagespeed module settings
      ##
      
      pagespeed on;
      pagespeed FileCachePath /var/ngx_pagespeed_cache;

      [Control-x], [y], [Enter] to save and exit nano.

    2. Activate PageSpeed for All Site Available (website’s virtual host)
      ls -lt /etc/nginx/sites-available

      Do it too all file on site-available. You might still only have one, default.

      sudo nano /etc/nginx/sites-available/default

      Add inside the server {}

      # PageSpeed configuration
      # Ensure requests for pagespeed optimized resources go to the pagespeed
      # handler and no extraneous headers get set.
      location ~ "\.pagespeed\.([a-z]\.)?[a-z]{2}\.[^.]{10}\.[^.]+" { add_header "" ""; }
      location ~ "^/ngx_pagespeed_static/" { }
      location ~ "^/ngx_pagespeed_beacon" { }
      location /ngx_pagespeed_statistics { allow 127.0.0.1; deny all; }
      location /ngx_pagespeed_global_statistics { allow 127.0.0.1; deny all; }
      location /ngx_pagespeed_message { allow 127.0.0.1; deny all; }
      location /pagespeed_console { allow 127.0.0.1; deny all; }

      [Control-x], [y], [Enter] to save and exit nano.

    3. Create cache directory and arrange privilege
      Check whether you use www-data or nginx as web server user.

      sudo mkdir -p /var/ngx_pagespeed_cache 
      sudo chown -R www-data:www-data /var/ngx_pagespeed_cache
    4. Check PageSpeed is Working
      sudo service nginx restart
      curl -I -p http://localhost|grep X-Page-Speed

      Should shown:
      X-Page-Speed: 1.11.33.3-0

  6. Configure Naxsi

    1. Configure naxsi_core.rules for nginx
      sudo cp ~/mynginx/nginx-backports/nginx-1.9.10/naxsi-0.54/naxsi_config/naxsi_core.rules /etc/nginx/
      sudo nano /etc/nginx/nginx.conf

      On http{} section add after PageSpeed settings:

      ##
      # Naxsi setting
      ##
      
      include /etc/nginx/naxsi_core.rules;

      [Control-x], [y], [Enter] to save and exit nano.

    2. Configure naxsi.rules for nginx
      sudo nano /etc/nginx/naxsi.rules

      Change the value for DeniedUrl to an error file that already exists by default,

      # Sample rules file for default vhost.
      LearningMode;
      SecRulesEnabled;
      #SecRulesDisabled;
      DeniedUrl "/50x.html";
      
      ## check rules
      CheckRule "$SQL >= 8" BLOCK;
      CheckRule "$RFI >= 8" BLOCK;
      CheckRule "$TRAVERSAL >= 4" BLOCK;
      CheckRule "$EVADE >= 4" BLOCK;
      CheckRule "$XSS >= 8" BLOCK;

      [Control-x], [y], [Enter] to save and exit nano.

    3. Activate Naxsi on Nginx enabled sites
      sudo nano /etc/nginx/sites-enabled/default

      Find the  location / and add:

      include /etc/nginx/naxsi.rules;

      [Control-x], [y], [Enter] to save and exit nano.

    4. Check Naxsi is protecting the web server
      sudo service nginx restart
      sudo tail -f /var/log/nginx/error.log

      Use browser to emulate unwanted request:

      http://yourip/index.html?asd=----

      Confirm that log tail block the request.
      Then exit tail with [Control]-[c].

  7. Clean up
    1. Pin myNginx version to avoid update/upgrade
      • Create a new file in /etc/apt/preferences.d:sudo nano /etc/apt/preferences.d/nginxPackage: nginx Pin: version 1.4.4-1~bpo70+1-custom Pin-Priority: 1001 (Ctrl-x – y – Enter)

 

Troubleshooting:

  • Remove Nginx

sudo service nginx stop
sudo apt-get remove nginx*
sudo apt-get purge nginx*
systemctl status nginx

 

 

Advertisements

2 thoughts on “Custom Build Nginx”

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 )

Google photo

You are commenting using your Google 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 )

Connecting to %s