When I started thinking about running my site on my own server instead of using Blogger or Medium, etc… And after tried to use Apache, Nginx,… I realized that combining Apache and Nginx could be the best choice for me, because I want to use .htaccess
of Apache and speed of Nginx. There come my architecture:
In this post, I will use private IP range for Nginx reverse proxy server and Apache web server. Both of them are running Ubuntu 18.04 LTS.
Apache webserver: 10.128.0.2
Nginx reverse proxy: 10.128.0.3
1. Install and configure Apache web server
Install apache webserver:
1
$ sudo apt install apache2
Next we create a place where to storage source code:
1
$ sudo mkdir -p /var/www/html/example.com/public_html
Change permission:
1
2
$ sudo chown -R <user>:<group> /var/www/html/example.com/public_html
$ sudo chmod -R 744 /var/www/html/example.com/public_html
With user and *group you can use command
1
$ apachectl -S
Usually, it’s www-data
Now let’s config virutal host and port:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
$ sudo vim /etc/apache2/ports.conf
Listen 8080
<IfModule ssl_module>
Listen 443
</IfModule>
<IfModule mod_gnutls.c>
Listen 443
</IfModule>
$ sudo cp /etc/apache2/sites-available/000-default.conf /etc/apache2/sites-available/example.com.conf
$ sudo vim /etc/apache2/sites-available/example.com.conf
<VirtualHost 10.128.0.2:8080>
ServerAdmin webmaster@example.com
DocumentRoot /var/www/html/example.com/public_html/
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
ErrorDocument 404 /404.html
</VirtualHost>
Active your website:
1
2
$ sudo a2dissite 000-default.conf
$ sudo a2ensite example.com.conf
2. Install and configure Nginx
2.1 Install Nginx package
Install the prerequisites:
1
$ sudo apt install curl gnupg2 ca-certificates lsb-release
Add repository for stable nginx packages:
1
2
$ echo "deb http://nginx.org/packages/ubuntu `lsb_release -cs` nginx" \
| sudo tee /etc/apt/sources.list.d/nginx.list
Import an official nginx signing key so apt could verify the packages authenticity:
1
$ curl -fsSL https://nginx.org/keys/nginx_signing.key | sudo apt-key add -
Verify that you now have the proper key:
1
$ sudo apt-key fingerprint ABF5BD827BD9BF62
The output should contain the full fingerprint 573B FD6B 3D8F BC64 1079 A6AB ABF5 BD82 7BD9 BF62 as follows:
1
2
3
pub rsa2048 2011-08-19 [SC] [expires: 2024-06-14]
573B FD6B 3D8F BC64 1079 A6AB ABF5 BD82 7BD9 BF62
uid [ unknown] nginx signing key <signing-key@nginx.com>
Finally, install Nginx:
1
2
$ sudo apt update
$ sudo apt install nginx
2.2 Configure Nginx reverse proxy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
$ sudo cp /etc/nginx/conf.d/default.conf /etc/nginx/conf.d/example.com.conf
$ sudo vim /etc/nginx/conf.d/example.com.conf
server {
listen 80;
server_name example.com;
port_in_redirect off;
location / {
proxy_redirect off;
proxy_set_header Host $host:$server_port;
proxy_set_header X-Forwarded-Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://10.128.0.2:8080;
}
location ~ /\.ht {
deny all;
}
}
2.3 Install and configure Modsecurity
Install the prerequisites:
1
$ sudo apt-get install -y apt-utils autoconf automake build-essential git libcurl4-openssl-dev libgeoip-dev liblmdb-dev libpcre++-dev libtool libxml2-dev libyajl-dev pkgconf wget zlib1g-dev
Download Modsecurity source:
1
$ git clone --depth 1 -b v3/master --single-branch https://github.com/SpiderLabs/ModSecurity
Compile Modsecurity:
1
2
3
4
5
6
7
$ cd ModSecurity
$ git submodule init
$ git submodule update
$ ./build.sh
$ ./configure
$ make
$ sudo make install
If you see this notification on your terminal, just ignore it and take a coffee because the process might take about 15 minutes to complete.
fatal: No names found, cannot describe anything.
2.4 Download the NGINX Connector for ModSecurity and Compile It as a Dynamic Module
1
$ git clone --depth 1 https://github.com/SpiderLabs/ModSecurity-nginx.git
Check your nginx version:
1
2
3
$ nginx -v
nginx version: nginx/1.17.9
Download source code:
1
2
3
4
5
6
$ wget http://nginx.org/download/nginx-1.17.9.tar.gz
$ tar -xvzf nginx-1.17.9.tar.gz
$ cd nginx-1.17.9
$ ./configure --with-compat --add-dynamic-module=../ModSecurity-nginx
$ make modules
$ sudo cp objs/ngx_http_modsecurity_module.so /etc/nginx/modules/
Load Nginx Modsecurity Connector by add the load_module following to the top of /etc/nginx/nginx.conf
load_module modules/ngx_http_modsecurity_module.so;
Configure and Enable Modsecurity:
1
2
3
$ sudo mkdir /etc/nginx/modsec
$ sudo wget -P /etc/nginx/modsec/ https://raw.githubusercontent.com/SpiderLabs/ModSecurity/v3/master/modsecurity.conf-recommended
$ sudo mv /etc/nginx/modsec/modsecurity.conf-recommended /etc/nginx/modsec/modsecurity.conf
Active dropping malicious mode:
1
$ sudo sed -i 's/SecRuleEngine DetectionOnly/SecRuleEngine On/' /etc/nginx/modsec/modsecurity.conf
Add modsecurity rule and config your test rule:
1
2
3
4
5
6
7
$ sudo vim /etc/nginx/modsec/main.conf
Include "/etc/nginx/modsec/modsecurity.conf"
# Basic test rule
SecRule ARGS:testparam "@contains test" "id:1234,deny,status:403"
Then turn on the modsecurity in your server config:
1
2
3
4
5
6
7
$ sudo vim /etc/nginx/conf.d/example.com.conf
server {
# ...
modsecurity on;
modsecurity_rules_file /etc/nginx/modsec/main.conf;
}
Check everything ok yet by command:
1
$ sudo nginx -t
If the output are:
1
2
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
We completed 99%, if there is an error about unicode.mapping, you can fix it by the following commands:
1
2
$ cd /path/to/Modsecurity
$ sudo cp unicode.mapping /etc/nginx/modsec/
Check if the waf is active or not by curl. The 403
status confirmed that the rule worked:
1
2
3
4
5
6
7
8
$ curl example.com/?testparam=test
<html>
<head><title>403 Forbidden</title></head>
<body bgcolor="white">
<center><h1>403 Forbidden</h1></center>
<hr><center>nginx/1.17.9</center>
</body>
</html>
This is the basic configuration, if you have any problem, just let me know and I will help you!
Cheers!
P/S: Thank you GinaTU aka Tứ Diệp Thảo to help me edit this post