Complete guide to Install LEMP with Brotli, Pagespeed, FastCGI and Naxsi on Ubuntu 16.04

share on:
Install lemp on Ubuntu 16.04

NGINX is a free, open-source, high-performance HTTP server and reverse proxy, as well as an IMAP/POP3 proxy server. NGINX is known for its high performance, stability, rich feature set, simple configuration, and low resource consumption. we will Install lemp on Ubuntu 16.04 on our server.

NGINX accelerates content and application delivery, improves security, facilitates availability and scalability for the busiest websites on the Internet.

NGINX is one of a handful of servers written to address the C10K problem. Click here to know more about the C10K problem.

Compiling Nginx with various third party modules requires many steps. Here’s a brief summary of all the steps we will take in this tutorial.

Let’s begin with Backing up of previous Nginx configuration.

 

STEP 1. Backup Previous nginx configuration.

Take a backup of your old Nginx configuration, If you’ve already installed Nginx before removing any previous installation of nginx.

shell> cd /etc/nginx
shell> tar -czvf /root/nginx-dir-org-backup.tar.gz *
shell> sudo apt remove nginx nginx-common nginx-full

 

First of all, Download  the important Packages.

shell> sudo apt-get install libgoogle-perftools-dev libgeoip-dev unzip wget curl uuid-dev -y

 

 

Step 2. Download Latest nginx on Ubuntu 16.04.

We will install latest Nginx-1.15.3 from their official Repository.

  • Install GPG key for Nginx.
shell> wget http://nginx.org/keys/nginx_signing.key

shell> sudo apt-key add nginx_signing.key

 

  • Add following lines at the end of /etc/apt/sources.list file/.

For Ubuntu 16.04, use these lines:

shell> echo "deb http://nginx.org/packages/mainline/ubuntu/ xenial nginx" >>  /etc/apt/sources.list
shell> echo "deb-src http://nginx.org/packages/mainline/ubuntu/ xenial nginx" >>  /etc/apt/sources.list
shell> sudo apt-get update

 

For Ubuntu 18.04, use these lines:

shell> echo "deb http://nginx.org/packages/mainline/ubuntu/ bionic nginx" >>  /etc/apt/sources.list
shell> echo "deb-src http://nginx.org/packages/mainline/ubuntu/ bionic nginx" >>  /etc/apt/sources.list
shell> sudo apt-get update

 

Now we can download latest Nginx package later .

 

  • Make a new directory named nginx directory within the home directory. we will use it to store the Nginx sources.
shell> mkdir -p /usr/share/nginx && cd /usr/share/nginx

 

  • We will install a package named dpkg-dev. This package provides the development tools required to build and upload Debian source packages.
[email protected]:/usr/share/nginx# sudo apt install dpkg-dev

 

Download Nginx source.

[email protected]:/usr/share/nginx# sudo apt source nginx

 

List of downloaded files.

shell> ls  /usr/share/nginx/
Output:
drwxr-xr-x   3 root root    4096 Sep  4 11:51 ./
drwxr-xr-x 110 root root    4096 Sep  4 11:51 ../
drwxr-xr-x  10 root root    4096 Sep  4 11:51 nginx-1.15.3/
-rw-r--r--   1 root root  112372 Aug 28 16:07 nginx_1.15.3-1~bionic.debian.tar.xz
-rw-r--r--   1 root root    1510 Aug 28 16:07 nginx_1.15.3-1~bionic.dsc
-rw-r--r--   1 root root 1022881 Aug 28 16:07 nginx_1.15.3.orig.tar.gz

 

Nginx version here is 1.15.3 (stable). It can be different on your server like 1.14 or 1.16 depending on the latest release at that time.

 

STEP 3. Add Modules in Nginx

We will add few useful third party modules in our Nginx Build.

  • Pagespeed
  • Naxsi Web Application Firewall
  • NGINX_CACHE_PURGE module

Create a Directory to store downloaded modules.

Create a directory to store third party modules which we will download later. we will create a directory named “modules” within /usr/share/nginx .

shell> mkdir /usr/share/nginx/modules && cd /usr/share/nginx/modules

 

Make sure you’re in the right directory.

[email protected]:/usr/share/nginx/modules# pwd
/usr/share/nginx/modules

 

Now Start downloading Modules.

 

************ Download NGINX_CACHE_PURGE module  ************

Nginx module which adds the ability to purge content from FastCGI, proxy, SCGI and uWSGI caches. 
wget https://github.com/FRiCKLE/ngx_cache_purge/archive/master.zip -O nginx_purge_module.zip 
unzip nginx_purge_module.zip

 

************ Install Nginx with Brotli ************

Brotli allows us to get 20–26% higher compression ratios over Gzip compression.

 

git clone https://github.com/google/ngx_brotli.git
cd /usr/share/nginx/modules/ngx_brotli && git submodule update --init
cd /usr/share/nginx/modules

 

************ Download NAXSI FIREWALL for NGINX  ************

NAXSI means Nginx Anti XSS & SQL Injection.

It is a third party nginx module, available as a package for many UNIX-like platforms. Nginx with NAXSI can operate as a high-performance standalone WAF.

wget https://github.com/nbs-system/naxsi/archive/master.zip -O naxsi.zip 
unzip naxsi.zip

 

 

************ Download PAGESPEED module for NGINX   ************

The PageSpeed module is an open-source server module that optimizes your site. It automatically applies chosen filters to pages and associated assets, such as style sheets, JavaScript, and HTML files, as well as to images and website cache requirements. To know more about PageSpeed, click here.

NPS_VERSION=1.13.35.2
wget https://github.com/apache/incubator-pagespeed-ngx/archive/v${NPS_VERSION}-stable.zip -O release-${NPS_VERSION}-stable.zip
unzip release-${NPS_VERSION}-stable.zip
rm release-${NPS_VERSION}-stable.zip
cd incubator-pagespeed-ngx-${NPS_VERSION}-stable/
psol_url=https://dl.google.com/dl/page-speed/psol/${NPS_VERSION}-x64.tar.gz
[ -e scripts/format_binary_url.sh ] && psol_url=$(scripts/format_binary_url.sh PSOL_BINARY_URL)
wget ${psol_url}
tar -xzvf $(basename ${psol_url})

 

A view of modules directory:

[email protected]:/usr/share/nginx/modules# ls -l
total 384
drwxr-xr-x 6 root root   4096 Sep 16 14:56 naxsi-master
-rw-r--r-- 1 root root 218174 Sep 28 17:53 naxsi.zip
-rw-r--r-- 1 root root  16771 Sep 28 17:53 nginx_purge_module.zip
drwxr-xr-x 3 root root   4096 Dec 23  2014 ngx_cache_purge-master
drwxr-xr-x 6 root root   4096 Sep 28 17:50 incubator-pagespeed-ngx-1.13.35.2-stable
-rw-r--r-- 1 root root 136753 Sep 28 17:49 ngx_brotli

 

 

STEP 4. Compile Nginx.

Also, Add these Modules in Compilation Rules of Nginx.

We need to edit our  /usr/share/nginx/nginx-1.15.3/debian/rules  file and also add these lines into it.

[email protected]:/usr/share/nginx/modules# cd /usr/share/nginx/nginx-1.15.3/
[email protected]:/usr/share/nginx/nginx-1.15.3/#
[email protected]:/usr/share/nginx/nginx-1.15.3/# vi debian/rules

 

Lines we need to add are as follows.

--add-module=/usr/share/nginx/modules/naxsi-master/naxsi_src/ 
--add-module=/usr/share/nginx/modules/incubator-pagespeed-ngx-1.13.35.2-stable 
--add-module=/usr/share/nginx/modules/ngx_cache_purge-master 
--add-module=/usr/share/nginx/modules/ngx_brotli

 

UPDATE:

For Nginx version 1.15.3 , Add modules in the section config.env.nginx. like shown in this image below.

 

Install Nginx with Brotli module
Install Nginx with Brotli module

 

Again making sure we are in the right directory.

[email protected]:/usr/share/nginx/nginx-1.15.3# pwd
/usr/share/nginx/nginx-1.15.3
[email protected]:/usr/share/nginx/nginx-1.15.3# ls -l
total 712
drwxr-xr-x 10 root root   4096 Sep  4 11:51 .
drwxr-xr-x  4 root root   4096 Sep  4 11:56 ..
drwxr-xr-x  2 root root   4096 Sep  4 11:51 .pc
-rw-r--r--  1 root root 290941 Aug 28 15:36 CHANGES
-rw-r--r--  1 root root 443800 Aug 28 15:36 CHANGES.ru
-rw-r--r--  1 root root   1397 Aug 28 15:36 LICENSE
-rw-r--r--  1 root root     49 Aug 28 15:36 README
drwxr-xr-x  6 root root   4096 Sep  4 11:51 auto
drwxr-xr-x  2 root root   4096 Sep  4 11:51 conf
-rwxr-xr-x  1 root root   2502 Aug 28 15:36 configure
drwxr-xr-x  4 root root   4096 Sep  4 11:51 contrib
drwxr-xr-x  3 root root   4096 Sep  4 12:32 debian
drwxr-xr-x  2 root root   4096 Sep  4 11:51 html
drwxr-xr-x  2 root root   4096 Sep  4 11:51 man

[email protected]:/usr/share/nginx/nginx-1.15.3/# sudo apt build-dep nginx

 

Finally, everything is now ready for compilation.

 

IMPORTANT: For server’s with 512 MB RAM : Create Swap Space

we need to make sure we have enough memory for compilation process.

For server’s with 512 MB RAM, you need to add more swap space for compilation process.

[email protected]:/usr/share/nginx/nginx-1.15.3# sudo install -o root -g root -m 0600 /dev/null /tmp-swap
[email protected]:/usr/share/nginx/nginx-1.15.3# dd if=/dev/zero of=/tmp-swap bs=1M count=1024 
[email protected]:/usr/share/nginx/nginx-1.15.3# mkswap /tmp-swap 
[email protected]:/usr/share/nginx/nginx-1.15.3# swapon /tmp-swap 
[email protected]:/usr/share/nginx/nginx-1.15.3# echo "/tmp-swap swap swap auto 0 0" | sudo tee -a /etc/fstab 
[email protected]:/usr/share/nginx/nginx-1.15.3# sudo sysctl -w vm.swappiness=10

 

This will add a swap space of 1 GB in a minute. you can delete it if you want after this setup.

 

STEP 5: Build and install Nginx.

Building Deb Package for Nginx.

[email protected]:/usr/share/nginx/nginx-1.15.3# sudo dpkg-buildpackage -b

 

It’s a lengthy process and usually takes 10-20 minutes to finish.

 

After it finishes compiling let’s take a look at the /usr/share/nginx directory.

 

In Ubuntu 16.04, the directory contents should look like:

[email protected]:/usr/share/nginx# ls -l
total 42164
drwxr-xr-x   4 root root    4096 Sep  4 12:57 .
drwxr-xr-x 123 root root    4096 Sep  4 12:34 ..
drwxr-xr-x   4 root root    4096 Sep  4 12:40 modules
drwxr-xr-x  10 root root    4096 Sep  4 12:57 nginx-1.15.3
-rw-r--r--   1 root root 7699624 Sep  4 12:57 nginx-dbg_1.15.3-1~xenial_amd64.deb
-rw-r--r--   1 root root  112372 Aug 28 16:07 nginx_1.15.3-1~xenial.debian.tar.xz
-rw-r--r--   1 root root    1510 Aug 28 16:07 nginx_1.15.3-1~xenial.dsc
-rw-r--r--   1 root root    6025 Sep  4 12:57 nginx_1.15.3-1~xenial_amd64.buildinfo
-rw-r--r--   1 root root    1309 Sep  4 12:57 nginx_1.15.3-1~xenial_amd64.changes
-rw-r--r--   1 root root 4752520 Sep  4 12:57 nginx_1.15.3-1~xenial_amd64.deb
-rw-r--r--   1 root root 1022881 Aug 28 16:07 nginx_1.15.3.orig.tar.gz

 

 

In Ubuntu 18.04, the directory contents should look like:

[email protected]:/usr/share/nginx# ls -l
total 42164
drwxr-xr-x   4 root root    4096 Sep  4 12:57 .
drwxr-xr-x 123 root root    4096 Sep  4 12:34 ..
drwxr-xr-x   4 root root    4096 Sep  4 12:40 modules
drwxr-xr-x  10 root root    4096 Sep  4 12:57 nginx-1.15.3
-rw-r--r--   1 root root 7699624 Sep  4 12:57 nginx-dbg_1.15.3-1~bionic_amd64.deb
-rw-r--r--   1 root root  112372 Aug 28 16:07 nginx_1.15.3-1~bionic.debian.tar.xz
-rw-r--r--   1 root root    1510 Aug 28 16:07 nginx_1.15.3-1~bionic.dsc
-rw-r--r--   1 root root    6025 Sep  4 12:57 nginx_1.15.3-1~bionic_amd64.buildinfo
-rw-r--r--   1 root root    1309 Sep  4 12:57 nginx_1.15.3-1~bionic_amd64.changes
-rw-r--r--   1 root root 4752520 Sep  4 12:57 nginx_1.15.3-1~bionic_amd64.deb
-rw-r--r--   1 root root 1022881 Aug 28 16:07 nginx_1.15.3.orig.tar.gz

 

For Ubuntu 16.04:

 

We only need to install  nginx_1.15.3-1~xenial_amd64.deb package .

For 32-bit system, your package name will be  nginx_1.15.3.1~xenial_i386.deb

 

For Ubuntu 18.04:

 

We only need to install  nginx_1.15.3-1~bionic_amd64.deb package .

For 32-bit system, your package name will be  nginx_1.15.3.1~bionic_i386.deb

 

 

We can install any .deb package using dpkg with -i flag. Take a closer look at directory ( /usr/share/nginx ).

[email protected]:/usr/share/nginx# cd /usr/share/nginx
[email protected]:/usr/share/nginx# dpkg -i nginx_1.15.3-1~bionic_amd64.deb

 

Also, start the nginx service.

[email protected]:/usr/share/nginx# sudo systemctl start nginx

 

In addition, enable Nginx service to start automatically at reboot.

[email protected]:/usr/share/nginx# sudo systemctl enable nginx

 

Check nginx version.

[email protected]:/usr/share/nginx# nginx -v
nginx version: nginx/1.15.3

 

Check Nginx Configuration arguments used while compiling Nginx.

[email protected]:/usr/share/nginx# nginx -V
.....
.... --add-module=/usr/share/nginx/modules/naxsi-master/naxsi_src --add-module=/usr/share/nginx/modules/incubator-pagespeed-ngx-1.13.35.2-stable --add-module=/usr/share/nginx/modules/ngx_cache_purge-master

 

The --add-module line shows that NAXSI, Pagespeed and NGINX_CACHE_PURGE module has been successfully installed.

 

In the Next Page, we will Discuss in Detail about how to enable and configure Pagespeed, NAXSI WAF & FastCGI cache with Examples.

 

STEP 6. Configure Pagespeed for Nginx.

PageSpeed is  disabled by default. To configure it, we will create a pagespeed.conf file and then put our pagespeed configuration in that file. After that, we will include that file in our main configuration. This method allows us flexibility and ease while dealing with Nginx configuration.

So, Follow these steps one by one.

1: Create  a folder for Storing Pagespeed cache data.

shell> mkdir -p /var/cache/pagespeed_cache

 

2: Change the ownership

Change the ownership of pagespeed_cache to Nginx user.For example,change it to www-data or apache so that it can be written by Nginx.

check nginx.conf -> user    www-data;

shell> chown -R www-data:www-data /var/cache/pagespeed_cache

 

3: Create a configuration file for PageSpeed.

Here’s an example configuration file for pagespeed.

vi /etc/nginx/pagespeed.conf
    # Pagespeed main settings

    pagespeed on;

    # Needs to exist and be writable by nginx.
    pagespeed FileCachePath /var/cache/pagespeed_cache;

    pagespeed RespectVary on;
    pagespeed LowercaseHtmlNames on;

    # optional
    pagespeed XHeaderValue "Using ngx_pagespeed";

    # filter
    pagespeed RewriteLevel PassThrough;

    # image
    pagespeed EnableFilters rewrite_images,responsive_images_zoom;

    # css
    pagespeed EnableFilters inline_import_to_link;
    pagespeed EnableFilters outline_css;
    pagespeed CssOutlineMinBytes 1000;
    pagespeed EnableFilters combine_css,rewrite_css,rewrite_style_attributes,flatten_css_imports,prioritize_critical_css,sprite_images;
    
    # js
    pagespeed EnableFilters rewrite_javascript,combine_javascript;
    pagespeed UseExperimentalJsMinifier on;
    pagespeed EnableFilters insert_dns_prefetch;

    pagespeed EnableFilters remove_comments;
    pagespeed EnableFilters collapse_whitespace;
    pagespeed EnableFilters elide_attributes;
    pagespeed EnableFilters extend_cache;
    pagespeed EnableFilters trim_urls;

    pagespeed EnableFilters local_storage_cache;

 

4. Include pagespeed.conf  in server{} block of main nginx configuration file (/etc/nginx/conf.d/*.conf) .

server {
    listen 80;
    server_name www.example.com  example.com;

    # Redirect all HTTP requests to HTTPS with a 301 Moved Permanently response.
    return 302 https://www.example.com$request_uri;
}

server {
    listen 443 ssl http2 default_server;
    # listen [::]:443 ssl http2 default_server;

    include /etc/nginx/conf-available/ssl.conf;

    include /etc/nginx/pagespeed.conf;

 

Finally, Check the working of Nginx Pagespeed Module.

[email protected]:/etc/nginx# curl -X GET -I http://45.5x.xx.xxx
HTTP/1.1 200 OK
Server: nginx/1.15.3
Content-Type: text/html
Transfer-Encoding: chunked
Connection: keep-alive
Vary: Accept-Encoding
Date: Tue, 04 Sep 20182018 09:32:01 GMT
X-Page-Speed: Using ngx_pagespeed
Cache-Control: max-age=0, no-cache

 

 

STEP 7. Configure Naxsi for Nginx.

1: First of all, we will create a separate folder for Naxsi.

 shell> mkdir -p /etc/nginx/naxsi

 

2: Copy the naxsi_core.rules into the newly created Naxsi folder.

[email protected]:/etc/nginx# find / -type f -name 'naxsi_core.rules'
 /usr/share/nginx/modules/naxsi-master/naxsi_config/naxsi_core.rules

[email protected]:/etc/nginx# cp /usr/share/nginx/modules/naxsi-master/naxsi_config/naxsi_core.rules /etc/nginx/

 

3: Also create a naxsi.rules file.

 vi /etc/nginx/naxsi/naxsi.rules
 LearningMode;
 SecRulesEnabled;
 #SecRulesDisabled;
 DeniedUrl "/RequestDenied";

## Check & Blocking Rules
 CheckRule "$SQL >= 8" BLOCK;
 CheckRule "$RFI >= 8" BLOCK;
 CheckRule "$TRAVERSAL >= 4" BLOCK;
 CheckRule "$EVADE >= 4" BLOCK;
 CheckRule "$XSS >= 8" BLOCK;

include /etc/nginx/naxsi/naxsi_relax.rules;

 

While in learning mode, Naxsi won’t block any requests. It can also be used to configure an attack pattern auto-learn mechanism inside Naxsi.

SecRulesEnabled enables the Naxsi Secure Rules.

DeniedUrl “/RequestDenied” be the returned URL while blocking.

 

Create Whitelisting Rules for allowing legitimate traffic

4: Create a naxsi_relax.rules files.
To prevent Default Naxsi rules from blocking some legitimate traffic on your site we will use a list of rules to allow legitimate traffic without any problem.

In addition, Here are Whitelist rules for WordPress. for more check https://github.com/nbs-system/naxsi-rules/blob/master/wordpress.rules

 

vi /etc/nginx/naxsi/naxsi_relax.rules
 # WordPress naxsi rules

### HEADERS
 BasicRule wl:1000,1001,1005,1007,1010,1011,1013,1100,1101,1200,1308,1309,1310,1311,1315 "mz:$HEADERS_VAR:cookie";
 # xmlrpc
 BasicRule wl:1402 "mz:$HEADERS_VAR:content-type";

simple BODY (POST)
 BasicRule wl:1001,1015,1009,1311,1310,1101,1016 "mz:$URL:/|$BODY_VAR:customized";


 # comments
 BasicRule wl:1000,1010,1011,1013,1015,1200,1310,1311 "mz:$BODY_VAR:post_title";
 BasicRule wl:1000 "mz:$BODY_VAR:original_publish";
 BasicRule wl:1000 "mz:$BODY_VAR:save";
 BasicRule wl:1008,1010,1011,1013,1015 "mz:$BODY_VAR:sk2_my_js_payload";
 BasicRule wl:1001,1009,1005,1016,1100,1101,1310 "mz:$BODY_VAR:url";
 BasicRule wl:1009,1100,1101 "mz:$BODY_VAR:referredby";
 BasicRule wl:1009,1100,1101 "mz:$BODY_VAR:_wp_original_http_referer";
 BasicRule wl:1000,1001,1005,1008,1007,1009,1010,1011,1013,1015,1016,1100,1101,1200,1302,1303,1310,1311,1315,1400 "mz:$BODY_VAR:comment";
 BasicRule wl:1100,1101 "mz:$BODY_VAR:redirect_to";
 BasicRule wl:1000,1009,1315 "mz:$BODY_VAR:_wp_http_referer";
 BasicRule wl:1000 "mz:$BODY_VAR:action";
 BasicRule wl:1001,1013 "mz:$BODY_VAR:blogname";
 BasicRule wl:1015,1013 "mz:$BODY_VAR:blogdescription";
 BasicRule wl:1015 "mz:$BODY_VAR:date_format_custom";
 BasicRule wl:1015 "mz:$BODY_VAR:date_format";
 BasicRule wl:1015 "mz:$BODY_VAR:tax_input%5bpost_tag%5d";
 BasicRule wl:1015 "mz:$BODY_VAR:tax_input[post_tag]";
 BasicRule wl:1100,1101 "mz:$BODY_VAR:siteurl";
 BasicRule wl:1100,1101 "mz:$BODY_VAR:home";
 BasicRule wl:1000,1015 "mz:$BODY_VAR:submit";


 # news content matches pretty much everything
 BasicRule wl:0 "mz:$BODY_VAR:content";
 BasicRule wl:1000 "mz:$BODY_VAR:delete_option";
 BasicRule wl:1000 "mz:$BODY_VAR:prowl-msg-message";
 BasicRule wl:1100,1101 "mz:$BODY_VAR:_url";
 BasicRule wl:1001,1009 "mz:$BODY_VAR:c2c_text_replace%5btext_to_replace%5d";
 BasicRule wl:1200 "mz:$BODY_VAR:ppn_post_note";
 BasicRule wl:1100,1101 "mz:$BODY_VAR:author";
 BasicRule wl:1001,1015 "mz:$BODY_VAR:excerpt";
 BasicRule wl:1015 "mz:$BODY_VAR:catslist";
 BasicRule wl:1005,1008,1009,1010,1011,1015,1315 "mz:$BODY_VAR:cookie";
 BasicRule wl:1101 "mz:$BODY_VAR:googleplus";
 BasicRule wl:1007 "mz:$BODY_VAR:name";
 BasicRule wl:1007 "mz:$BODY_VAR:action";
 BasicRule wl:1100,1101 "mz:$BODY_VAR:attachment%5burl%5d";
 BasicRule wl:1100,1101 "mz:$BODY_VAR:attachment_url";
 BasicRule wl:1001,1009,1100,1101,1302,1303,1310,1311 "mz:$BODY_VAR:html";
 BasicRule wl:1015 "mz:$BODY_VAR:title";
 BasicRule wl:1001,1009,1015 "mz:$BODY_VAR:recaptcha_challenge_field";
 BasicRule wl:1011 "mz:$BODY_VAR:pwd";
 BasicRule wl:1000 "mz:$BODY_VAR:excerpt";

### BODY|NAME
 BasicRule wl:1000 "mz:$BODY_VAR:delete_option|NAME";
 BasicRule wl:1000 "mz:$BODY_VAR:from|NAME";

Simple ARGS (GET)
 # WP login screen
 BasicRule wl:1100,1101 "mz:$ARGS_VAR:redirect_to";
 BasicRule wl:1000,1009 "mz:$ARGS_VAR:_wp_http_referer";
 BasicRule wl:1000 "mz:$ARGS_VAR:wp_http_referer";
 BasicRule wl:1000 "mz:$ARGS_VAR:action";
 BasicRule wl:1000 "mz:$ARGS_VAR:action2";


 # load and load[] GET variable
 BasicRule wl:1000,1015 "mz:$ARGS_VAR:load";
 BasicRule wl:1000,1015 "mz:$ARGS_VAR:load[]";
 BasicRule wl:1015 "mz:$ARGS_VAR:q";
 BasicRule wl:1000,1015 "mz:$ARGS_VAR:load%5b%5d";

URL
 BasicRule wl:1000 "mz:URL|$URL:/wp-admin/update-core.php";
 BasicRule wl:1000 "mz:URL|$URL:/wp-admin/update.php";
 BasicRule wl:1000 "mz:$URL:/wp-includes/js/imgareaselect/imgareaselect.css|URL";
 BasicRule wl:1002 "mz:$URL_X:/wp-content/uploads/[0-9]{4}/[0-9]{2}/[^/]+\.jpg$|URL";


 # URL|ARGS
 BasicRule wl:1015 "mz:$URL:/wp-admin/load-styles.php|$ARGS_VAR:dashicons,admin-bar,wp-admin,buttons,wp-auth-check";
 BasicRule wl:1000 "mz:$URL:/wp-admin/about.php|$ARGS_VAR:updated";
 BasicRule wl:1009 "mz:$URL:/wp-admin/customize.php|$ARGS_VAR:return";


 # URL|BODY
 BasicRule wl:1009,1100,1101 "mz:$URL:/wp-admin/post.php|$BODY_VAR:_wp_http_referer";
 BasicRule wl:1016 "mz:$URL:/wp-admin/post.php|$BODY_VAR:metakeyselect";
 BasicRule wl:11 "mz:$URL:/xmlrpc.php|BODY";
 BasicRule wl:11,16 "mz:$URL:/wp-cron.php|BODY";
 BasicRule wl:2 "mz:$URL:/wp-admin/async-upload.php|BODY";


 # URL|BODY|NAME
 BasicRule wl:1100,1101 "mz:$URL:/wp-admin/post.php|$BODY_VAR:_wp_original_http_referer|NAME";
 BasicRule wl:1000 "mz:$URL:/wp-admin/post.php|$BODY_VAR:metakeyselect|NAME";
 BasicRule wl:1000 "mz:$URL:/wp-admin/user-edit.php|$BODY_VAR:from|NAME";
 BasicRule wl:1100,1101 "mz:$URL:/wp-admin/admin-ajax.php|$BODY_VAR:attachment%5burl%5d|NAME";
 BasicRule wl:1100,1101 "mz:$URL:/wp-admin/post.php|$BODY_VAR:attachment_url|NAME";
 BasicRule wl:1000 "mz:$URL:/wp-admin/plugins.php|$BODY_VAR:verify-delete|NAME";
 BasicRule wl:1310,1311 "mz:$URL:/wp-admin/post.php|$BODY_VAR:post_category[]|NAME";
 BasicRule wl:1311 "mz:$URL:/wp-admin/post.php|$BODY_VAR:post_category|NAME";
 BasicRule wl:1310,1311 "mz:$URL:/wp-admin/post.php|$BODY_VAR:tax_input[post_tag]|NAME";
 BasicRule wl:1310,1311 "mz:$URL:/wp-admin/post.php|$BODY_VAR:newtag[post_tag]|NAME";
 BasicRule wl:1310,1311 "mz:$URL:/wp-admin/users.php|$BODY_VAR:users[]|NAME";
 BasicRule wl:1000 "mz:$URL:/wp-admin/update-core.php|$BODY_VAR:Update%2BTranslations|NAME";
 BasicRule wl:1000 "mz:$URL:/wp-admin/update-core.php|$BODY_VAR:Update%2BNow|NAME";


 # URL|ARGS|NAME
 BasicRule wl:1310,1311 "mz:$URL:/wp-admin/load-scripts.php|$ARGS_VAR:load[]|NAME";
 BasicRule wl:1000 "mz:$URL:/wp-admin/users.php|$ARGS_VAR:delete_count|NAME";
 BasicRule wl:1000 "mz:$URL:/wp-admin/users.php|$ARGS_VAR:update|NAME";
 BasicRule wl:1310,1311 "mz:$URL:/wp-admin/customize.php|$ARGS_VAR:autofocus[control]|NAME";

# plain WP site
 BasicRule wl:1000 "mz:URL|$URL:/wp-admin/update-core.php";
 BasicRule wl:1000 "mz:URL|$URL:/wp-admin/update.php";


 # URL|BODY
 BasicRule wl:1009,1100,1101 "mz:$URL:/wp-admin/post.php|$BODY_VAR:_wp_http_referer";
 BasicRule wl:1016 "mz:$URL:/wp-admin/post.php|$BODY_VAR:metakeyselect";
 BasicRule wl:11 "mz:$URL:/xmlrpc.php|BODY";
 BasicRule wl:11,16 "mz:$URL:/wp-cron.php|BODY";


 # URL|BODY|NAME
 BasicRule wl:1100,1101 "mz:$URL:/wp-admin/post.php|$BODY_VAR:_wp_original_http_referer|NAME";
 BasicRule wl:1000 "mz:$URL:/wp-admin/post.php|$BODY_VAR:metakeyselect|NAME";
 BasicRule wl:1000 "mz:$URL:/wp-admin/user-edit.php|$BODY_VAR:from|NAME";
 BasicRule wl:1100,1101 "mz:$URL:/wp-admin/admin-ajax.php|$BODY_VAR:attachment%5burl%5d|NAME";
 BasicRule wl:1310,1311 "mz:$URL:/wp-admin/admin-ajax.php|$BODY_VAR:data[wp-auth-check]|NAME";
 BasicRule wl:1310,1311 "mz:$URL:/wp-admin/admin-ajax.php|$BODY_VAR:data[wp-check-locked-posts][]|NAME";
 BasicRule wl:1310,1311 "mz:$URL:/wp-admin/admin-ajax.php|$BODY_VAR:data[wp-refresh-post-lock][post_id]|NAME";
 BasicRule wl:1310,1311 "mz:$URL:/wp-admin/admin-ajax.php|$BODY_VAR:data[wp-refresh-post-lock][lock]|NAME";
 BasicRule wl:1310,1311 "mz:$URL:/wp-admin/update-core.php|$BODY_VAR:checked[]|NAME";


 # URL|ARGS|NAME
 BasicRule wl:1310,1311 "mz:$URL:/wp-admin/load-scripts.php|$ARGS_VAR:load[]|NAME";
 BasicRule wl:1000 "mz:$URL:/wp-admin/users.php|$ARGS_VAR:delete_count|NAME";
 BasicRule wl:1000 "mz:$URL:/wp-admin/users.php|$ARGS_VAR:update|NAME";

Plugins
 #WP Minify
 BasicRule wl:1015 "mz:$URL:/wp-content/plugins/bwp-minify/min/|$ARGS_VAR:f";

 

5: Include this inside the http{} block in your nginx.conf file .

Add this to the first line:

http {
 include      /etc/nginx/naxsi_core.rules;
 include       mime.types;
 ...
 ...
 ...
 }

 

5: Add Location Block for Naxsi in the server {} section of domain configuration file basically in conf.d/*.conf or sites-enabled/*.conf.

 ....
 .....
 location / {
 include           /etc/nginx/naxsi/naxsi.rules;
 ....
 ....
 }

location /RequestDenied {
 return 406;
 }

 

Now Naxsi is configured and is in Learning mode. To disable learning mode LearningMode

 vi /etc/nginx/naxsi/naxsi.rules
 # LearningMode;

 

 

STEP 8. Configure FastCGI Cache.

 

To enable FastCGI cache  we will add these lines inside the http {} block section in nginx main config file.

 

http { 

    .......
    fastcgi_cache_path /var/cache/ngx_fastcgi levels=1:2 keys_zone=fastcgi_cache:10m inactive=10m max_size=64m;
    fastcgi_cache_key $scheme$request_method$host$request_uri;
    fastcgi_cache_lock on;
    fastcgi_cache_use_stale error timeout invalid_header updating http_500;
    fastcgi_cache_valid 5m;
    fastcgi_ignore_headers Cache-Control Expires Set-Cookie;

 

The fastcgi_cache_path directive defines the location of the cache.

levels define the subdirectory levels.

fastcgi_cache defines the name of memory zone.

It’s maximum size 64mb and the inactive time.

max_size must be less than your server’s Total  RAM + Swap.

 

Integrate the FastCGI cache with PHP-FPM.

Also, Add these lines inside the server {} block of your domain configuration file.

 

    location ~\.php$ {

    set $fastcgi_skipcache 0;
 
 
        if ($http_x_custom_header) {
            set $fastcgi_skipcache 0;
        }
 
        # Don't cache the following URL's
        if ($request_uri ~* "/wp-admin/|/xmlrpc.php|wp-.*.php|/feed/|index.php|sitemap(_index)?.xml") {
            set $fastcgi_skipcache 1;
        }   

        # Don't use the cache for logged in users or recent commenters
        if ($http_cookie ~* "comment_author|wordpress_[a-f0-9]+|wp-postpass|wordpress_no_cache|wordpress_logged_in") {
            set $fastcgi_skipcache 1;
        }

        #Don't cache if there is a cookie called PHPSESSID
        if ($http_cookie = "PHPSESSID")
        {
            set $fastcgi_skipcache 1;
        }

        # Bypass cache for POST requests
        if ($request_method = POST) { 
            set $fastcgi_skipcache 1; 
        }

        # Bypass cache for URL with query string
        if ($query_string != "")  { 
            set $fastcgi_skipcache 1; 
        }
 
        if ($http_cookie ~ "users_login_cookie") {
            set $fastcgi_skipcache 1;
        }


        include fastcgi_params;
        include fastcgi.conf;

        fastcgi_cache fastcgi_cache;
        fastcgi_cache_valid 200 60m;
        fastcgi_cache_methods GET HEAD;

        # note: adds a HTTP response header "X-Cache" returning HIT/MISS/BYPASS/EXPIRED for cache use status
        add_header X-Fastcgi-Cache $upstream_cache_status;
        fastcgi_cache_bypass $fastcgi_skipcache;
        fastcgi_no_cache $fastcgi_skipcache;

        fastcgi_buffer_size 128k;
        fastcgi_buffers 256 4k;
        fastcgi_busy_buffers_size 256k;
        fastcgi_temp_file_write_size 256k;
        
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;

        fastcgi_index index.php;
        fastcgi_pass    127.0.0.1:9000;
    }

 

 

Also, Check the nginx configuration file for syntax errors.

[[email protected] nginx]# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

 

Finally, Test the working of FastCGI cache.

[email protected]:~# curl -X GET -I http://45.55.64.233/hello.php
HTTP/1.1 200 OK
Server: nginx/1.15.3
Content-Type: text/html; charset=UTF-8
Transfer-Encoding: chunked
Connection: keep-alive
Vary: Accept-Encoding
X-Fastcgi-Cache: HIT
Date: Tue, 04 Sep 2018 12:16:13 GMT
X-Page-Speed: Using ngx_pagespeed
Cache-Control: max-age=0, no-cache

 

Now that we have installed and configured Nginx with Pagespeed, NAXSI WAF, and FastCGI Cache we will install MySQL and PHP-FPM  on the next page to finish this LEMP Setup.

 

STEP 9. Configure Brotli with Nginx.

 

To enable Brotli compression with Nginx, you will need to add following code in your nginx.conf under http {} directive.

 

http {
...
...
 ## Brotli compression.
brotli on;
brotli_static on;
brotli_buffers 16 8k;
brotli_comp_level 6;

.....

}

 

STEP 10. Install MySQL.

Use the following commands to install MySQL

[email protected]:~# sudo apt-get install mysql-server -y

 

Start Mysql server and also enable it to start at reboot.

[email protected]:~# systemctl enable mysql.service
[email protected]:~# systemctl start mysql.service

 

 

Securing the Database Server.

In addition, We also need to secure the Database server by running this script ( mysql_secure_installation ) in the shell.

[email protected]:~# mysql_secure_installation
Securing the MySQL server deployment.

Enter password for user root: 

VALIDATE PASSWORD PLUGIN can be used to test passwords
and improve security. It checks the strength of password
and allows the users to set only those passwords which are
secure enough. Would you like to setup VALIDATE PASSWORD plugin?

Press y|Y for Yes, any other key for No: k
Using existing password for root.
Change the password for root ? ((Press y|Y for Yes, any other key for No) : k

 ... skipping.
By default, a MySQL installation has an anonymous user,
allowing anyone to log into MySQL without having to have
a user account created for them. This is intended only for
testing, and to make the installation go a bit smoother.
You should remove them before moving into a production
environment.

Remove anonymous users? (Press y|Y for Yes, any other key for No) : y
Success.


Normally, root should only be allowed to connect from
'localhost'. This ensures that someone cannot guess at
the root password from the network.

Disallow root login remotely? (Press y|Y for Yes, any other key for No) : y
Success.

By default, MySQL comes with a database named 'test' that
anyone can access. This is also intended only for testing,
and should be removed before moving into a production
environment.


Remove test database and access to it? (Press y|Y for Yes, any other key for No) : y
 - Dropping test database...
Success.

 - Removing privileges on test database...
Success.

Reloading the privilege tables will ensure that all changes
made so far will take effect immediately.

Reload privilege tables now? (Press y|Y for Yes, any other key for No) : y
Success.

All done!

 

If you want to stop MySQL service use,

[email protected]:~# systemctl stop mysql.service

 

 

STEP 11. Install PHP-FPM

PHP-FPM (FastCGI Process Manager) is an alternative PHP FastCGI implementation with some additional features useful for sites of any size, especially busier sites.

Install PHP with following command:

shell> sudo apt-get install php-fpm php-gd php-mysqlnd php-mcrypt php-pdo php-mbstring php-xml

 

Change the value of cgi.fix_pathinfo=1 to 0 in php.ini.

Open php.ini file in any editor:

[email protected]:~# php -i | grep php.ini
Configuration File (php.ini) Path => /etc/php/7.0/cli
Loaded Configuration File => /etc/php/7.0/cli/php.ini

 

shell> vi /etc/php/7.0/cli/php.ini
cgi.fix_pathinfo=0

 

 

Enable PHP-FPM service.

[email protected]:~# systemctl list-unit-files | grep php
php7.0-fpm.service enabled
[email protected]:~# sudo systemctl enable php7.0-fpm.service 
[email protected]:~# sudo systemctl start php7.0-fpm.service

 

Also, To check the status of php7.0-fpm.service, use the command:

[email protected]:~# sudo systemctl status php7.0-fpm.service 
 php7.0-fpm.service - The PHP 7.0 FastCGI Process Manager
 Loaded: loaded (/lib/systemd/system/php7.0-fpm.service; enabled; vendor preset: enabled)
 Active: active (running) since Sun 2016-11-13 10:42:32 UTC; 34s ago
 Main PID: 26938 (php-fpm7.0)
 Status: "Processes active: 0,[email protected]:~# php -v
PHP 7.0.8-0ubuntu0.16.04.3 (cli) ( NTS )
Copyright (c) 1997-2016 The PHP Group
Zend Engine v3.0.0, Copyright (c) 1998-2016 Zend Technologies
 with Zend OPcache v7.0.8-0ubuntu0.16.04.3, Copyright (c) 1999-2016, by Zend Technologies idle: 2, Requests: 0, slow: 0, Traffic: 0req/sec"
 CGroup: /system.slice/php7.0-fpm.service
 ├─26938 php-fpm: master process (/etc/php/7.0/fpm/php-fpm.conf) 
 ├─26942 php-fpm: pool www 
 └─26943 php-fpm: pool www

Nov 13 10:42:32 debyum systemd[1]: Stopped The PHP 7.0 FastCGI Process Manager.
Nov 13 10:42:32 debyum systemd[1]: Starting The PHP 7.0 FastCGI Process Manager...
Nov 13 10:42:32 debyum systemd[1]: Started The PHP 7.0 FastCGI Process Manager.

 

Finally, Check PHP Version.

[email protected]:~# php -v
PHP 7.0.8-0ubuntu0.16.04.3 (cli) ( NTS )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.2.0, Copyright (c) 1998-2018 Zend Technologies
 with Zend OPcache v7.2.7-0ubuntu0.16.04.3, Copyright (c) 1999-2018, by Zend Technologies

 

 

Conclusion

With LAMP stack installed, you can now install different types of applications or CMS or run a simple website on your server.

I have tried to cover all the basic to advance concepts like NAXSI, PageSpeed and FastCGI cache with their examples. Still, if I have missed anything please update us through comment box. I will keep updating the same based on feedback’s received.Thanks and a Great DAY.

 

share on:
engy

engy

Hello there, My name is Rishi Guleria and I work as a Linux system administrator. I have created this blog to share what I have learned so far and to learn new things. Good Day. :)

Leave a Response

share on: