For this guide I will be using a Digital Ocean VM but any VM or local virtual machine installation of Ubuntu 18.04 should work. Please make sure that this is a fresh install of Ubuntu 18.04 before carrying on.
You will also need to be logged in as root user in order to follow this guide so if you are not already logged in as root then do so with:
sudo su
Update Ubuntu
apt -y update && apt -y upgrade
We also need to make sure that port 80 and 443 can access the server as these are the ports we will be using for the nginx webserver. Let’s open these ports:
sudo ufw allow http
sudo ufw allow https
After each of the above command you should see
Rules updated
Rules updated (v6)
Install nginx
Let’s get started by installing and configuring nginx which will serve as a cache and front end of our site. We will install nginx with apt-get:
apt-get install nginx
On my VM when I entered the above command I got the following response. Just type Y and press enter to continue installing nginx
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following package was automatically installed and is no longer required:
grub-pc-bin
Use 'apt autoremove' to remove it.
The following additional packages will be installed:
fontconfig-config fonts-dejavu-core libfontconfig1 libgd3 libjbig0 libjpeg-turbo8 libjpeg8 libnginx-mod-http-geoip libnginx-mod-http-image-filter
libnginx-mod-http-xslt-filter libnginx-mod-mail libnginx-mod-stream libtiff5 libwebp6 libxpm4 nginx-common nginx-core
Suggested packages:
libgd-tools fcgiwrap nginx-doc ssl-cert
The following NEW packages will be installed:
fontconfig-config fonts-dejavu-core libfontconfig1 libgd3 libjbig0 libjpeg-turbo8 libjpeg8 libnginx-mod-http-geoip libnginx-mod-http-image-filter
libnginx-mod-http-xslt-filter libnginx-mod-mail libnginx-mod-stream libtiff5 libwebp6 libxpm4 nginx nginx-common nginx-core
0 upgraded, 18 newly installed, 0 to remove and 46 not upgraded.
Need to get 2461 kB of archives.
After this operation, 8194 kB of additional disk space will be used.
Do you want to continue? [Y/n]
Once installation is complete we need to go ahead and configure the virtual host to run on the front end. We will create a new vhost file and I will be using wpsite.eu for this example vhost template, so please amend this to your own domain.
nano /etc/nginx/sites-available/wpsite.eu
The wpsite.eu configuration will be as follow:
server {
listen 80;
root /var/www/sites/wpsite.eu/public_html;
index index.php index.html index.htm;
server_name wpsite.eu www.wpsite.eu;
location / {
try_files $uri $uri/ /index.php;
}
location ~ \.php$ {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $host;
proxy_pass https://wpsite.eu:8080;
}
location ~ /\.ht {
deny all;
}
}
To save these changes we need to use keyboard shortcuts when using nano.
CTRL + O then enter to write the file
CTRL + X to close the app
We made the following changes to the nginx configuration:
- Setup the website document root /var/www/sites/wpsite.eu/public_html
- Added index.php to the index line
- try_files attempts to serve whatever page the visitor requests. If nginx is unable, then the file is passed to the proxy
- proxy_pass lets nginx proxy the request to apache of the proxied server
- Finally the “location ~ /\.ht {” location block denies access to .htaccess files, if Apache’s document root concurs with nginx’s one
This configuration will route all php requests to the apache backend which we will run on port 8080.
Activate the newly create virtual host and delete the current default nginx server block
ln -s /etc/nginx/sites-available/wpsite.eu /etc/nginx/sites-enabled/wpsite.eu
rm /etc/nginx/sites-enabled/default
Now lets create the directory for our web application as specified in the nginx vhost file we create
mkdir -p /var/www/sites/wpsite.eu/public_html
Create the index.php file in the newly created directory
nano /var/www/sites/wpsite.eu/public_html/index.php
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>My Proxy Site</title>
</head>
<body>
<h1>Welcome to my Proxy Website</h1>
</body>
</html>
Let’s restart nginx to use the new configuration
service nginx restart
Let’s make sure that nginx is listening on port 80
netstat -tulpn | grep LISTEN
As there are other instances that may be listening on ports we are only interested in port 80 nginx. You should see something similar to
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 2902/nginx: master
Install Apache
Nginx is now ready so lets install and configure the apache backend webserver.
apt-get install apache2
Mar 13 14:49:09 authenticatz systemd[1]: Starting The Apache HTTP Server...
Mar 13 14:49:09 authenticatz apachectl[3579]: (98)Address already in use: AH00072: make_sock: could not bind to address [::]:80
Mar 13 14:49:09 authenticatz apachectl[3579]: (98)Address already in use: AH00072: make_sock: could not bind to address 0.0.0.0:80
Mar 13 14:49:09 authenticatz apachectl[3579]: no listening sockets available, shutting down
Mar 13 14:49:09 authenticatz apachectl[3579]: AH00015: Unable to open logs
Mar 13 14:49:09 authenticatz apachectl[3579]: Action 'start' failed.
Mar 13 14:49:09 authenticatz apachectl[3579]: The Apache error log may have more information.
Mar 13 14:49:09 authenticatz systemd[1]: apache2.service: Control process exited, code=exited status=1
Mar 13 14:49:09 authenticatz systemd[1]: apache2.service: Failed with result 'exit-code'.
Mar 13 14:49:09 authenticatz systemd[1]: Failed to start The Apache HTTP Server.
This is expected as Nginx is already installed and Apache will throw an error when the install completes due to the fact that Apache cannot bind to port 80. This is because nginx is already listening to port 80, so we will need to configure Apache.
Configure Apache
As configured in the nginx vhost configuration file for our domain we need to change the apache port to 8080 as this will be running as the backend of our proxy setup. Lets change this on the ports.conf file located at /etc/apache2/ports.conf
nano /etc/apache2/ports.conf
Listen 8080
<IfModule ssl_module>
Listen 8443
</IfModule>
<IfModule mod_gnutls.c>
Listen 8443
</IfModule>
Lets restart Apache
service apache2 restart
As we changed the port for Apache we should not get any errors. Lets now check to see if apache is listening on port 8080.
netstat -tulpn | grep LISTEN
tcp6 0 0 :::8080 :::* LISTEN 3820/apache2
Now we need to create the configuration file for the apache backend to process the PHP request.
nano /etc/apache2/sites-available/wpsite.eu.conf
<VirtualHost *:8080>
ServerName wpsite.eu
ServerAlias www.wpsite.eu
ServerAdmin [email protected]
DocumentRoot /var/www/sites/wpsite.eu/public_html
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
we should now disable the default apache configuration file and enable the newly created apache configuration file
a2dissite 000-default.conf
Site 000-default disabled.
To activate the new configuration, you need to run:
systemctl reload apache2
a2ensite wpsite.eu.conf
Enabling site wpsite.eu.
To activate the new configuration, you need to run:
systemctl reload apache2
systemctl reload apache2
Let’s now check that apache is running properly with curl
curl wpsite.eu:8080
You should see the html contents of the index.php file we created earlier as a response
<html lang="en">
<head>
<meta charset="utf-8">
<title>My Proxy Site</title>
</head>
<body>
<h1>Welcome to my Proxy Website</h1>
</body>
</html>
This completes the basic Nginx Apache reverse proxy. I will be writing an additional article to compliment this article which will focus on PHP-FPM, LetsEncrypt certificates and writing a BASH script to automate new vhosts for our reverse proxy setup. If you have any questions then leave a comment below.