How to create reverse proxy using NGINX?

NGINX is the perfect solution for system load balancing, as well as the ideal proxy solution to run web services via those machines through a host’s single public IP address. NGINX is particularly good because it manages static content extremely well. Additionally, it can manage and execute requests and host the static content way quicker, making sure that your page loading time is effectively cut in half.
Another major advantage of NGINX is its compact memory footprint, optimizing servers to stretch out every megabyte. It allows for fast and seamless migration of services, like Apache, on to another server, and you can specify your server’s IP address and port via the configuration files.

What do you need to create reverse proxy using NGINX?

  • CentOS 6.4 and above, or Debian/Ubuntu OS installed within the server
  • Secure Shell (SSH) access & admin root privileges
  • Nginx and Apache HTTP services installed within your server

Steps to create reverse proxy using NGINX

Step 1: Configure NGINX

The first step is to configure the Nginx service, using the following code:
 


sudo nano /etc/nginx/nginx.conf
worker_processes 4;
pid /var/run/nginx.pid;
events {
worker_connections 768;
}

http {
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
include /etc/nginx/mime.types;
default_type application/octet-stream;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
gzip on;
gzip_disable "msie6";
gzip_min_length  1100;
gzip_buffers  4 32k;
gzip_types    text/plain application/x-javascript text/xml text/css;
open_file_cache          max=10000 inactive=10m;
open_file_cache_valid    2m;
open_file_cache_min_uses 1;
open_file_cache_errors   on;
ignore_invalid_headers on;
client_max_body_size    8m;
client_header_timeout  3m;
client_body_timeout 3m;
send_timeout     3m;
connection_pool_size  256;
client_header_buffer_size 4k;
large_client_header_buffers 4 32k;
request_pool_size  4k;
output_buffers   4 32k;
postpone_output  1460;
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}

Entering the above code gives your server a unique configuration that will help you drastically increase your site’s loading speed. NGINX will now host the static content such as CSS, JS files, images, HTML, and so on. Consequently, the dynamic files within your site will be managed by the web server. NGINX will listen on HTTP port 80 (default), while the server needs to be configured to port 8080.
Once you’ve modified the ports, you’ll have to create a new virtual host file. Here’s how you can do it for the CentOS & Debian OS, respectively:

For CentOS:

 


sudo nano /etc/nginx/conf.d/newdomain.com.conf
server {
listen    80;
server_name  newdomain.com www.newdomain.com;
access_log off;
error_log  /var/log/httpd/newdomain.com-error_log crit;
location ~* .(gif|jpg|jpeg|png|ico|wmv|3gp|avi|mpg|mpeg|mp4|flv|mp3|mid|js|css|html|htm|wml)$ {
root /var/www/html/newdomain.com;
expires max;
}
location / {
client_max_body_size    10m;
client_body_buffer_size 128k;
proxy_send_timeout   90;
proxy_read_timeout   90;
proxy_buffer_size    128k;
proxy_buffers     4 256k;
proxy_busy_buffers_size 256k;
proxy_temp_file_write_size 256k;
proxy_connect_timeout 30s;
 
proxy_redirect  https://www.newdomain.com:8080   https://www.newdomain.com;
proxy_redirect  https://newdomain.com:8080   https://newdomain.com;
 
proxy_pass   https://127.0.0.1:8080/;
 
proxy_set_header   Host   $host;
proxy_set_header   X-Real-IP  $remote_addr;
proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
}
}

For Debian/Ubuntu:
In order to create a new virtual host file on Ubuntu, first open the nginx configuration file and modify the code inside to reflect the illustration below:
 


sudo nano /etc/nginx/nginx.conf
 
worker_processes 4;
pid /var/run/nginx.pid;
 
events {
worker_connections 768;
}
 
http {
 
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
 
include /etc/nginx/mime.types;
default_type application/octet-stream;
 
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
 
gzip on;
gzip_disable "msie6";
gzip_min_length  1100;
gzip_buffers  4 32k;
gzip_types    text/plain application/x-javascript text/xml text/css;
 
open_file_cache          max=10000 inactive=10m;
open_file_cache_valid    2m;
open_file_cache_min_uses 1;
open_file_cache_errors   on;
 
ignore_invalid_headers on;
client_max_body_size    8m;
client_header_timeout  3m;
client_body_timeout 3m;
send_timeout     3m;
connection_pool_size  256;
client_header_buffer_size 4k;
large_client_header_buffers 4 32k;
request_pool_size  4k;
output_buffers   4 32k;
postpone_output  1460;
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}

Creating the new virtual host file:
 


sudo nano /etc/nginx/sites-available/yourwebsite.com.conf
 
server {
listen    80;
server_name  newdomain.com www.newdomain.com;
access_log off;
error_log  /var/log/apache2/newdomain.com-error_log crit;
 
location ~* .(gif|jpg|jpeg|png|ico|wmv|3gp|avi|mpg|mpeg|mp4|flv|mp3|mid|js|css|html|htm|wml)$ {
root /var/www/newdomain.com;
expires 30d;
}
 
location / {
client_max_body_size    10m;
client_body_buffer_size 128k;
 
proxy_send_timeout   90;
proxy_read_timeout   90;
proxy_buffer_size    128k;
proxy_buffers     4 256k;
proxy_busy_buffers_size 256k;
proxy_temp_file_write_size 256k;
proxy_connect_timeout 30s;
 
proxy_redirect  https://www.newdomain.com:8080   https://www.newdomain.com;
proxy_redirect  https://newdomain.com:8080   https://newdomain.com;
 
proxy_pass   https://127.0.0.1:8080/;
 
proxy_set_header   Host   $host;
proxy_set_header   X-Real-IP  $remote_addr;
proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
}
}

Once completed, save the edited file and copy them into the “sites-enabled” folder.


Sudo cp /etc/nginx/sites-available/yourwebsite.com.conf /etc/nginx/sites-enabled/yourwebsite.com.conf

Step 2: Configure Apache

For CentOS:

Open the Apache configuration file and set the values to the following:


sudo nano /etc/httpd/conf/httpd.conf
 
Set the Apache port to 8080
 
Listen: 8080
NameVirtualHost *:8080 ;

Once that’s done, add the following lines of code at the very end of your file:


ServerAdmin webmaster@newdomain.com
DocumentRoot /var/www/html/newdomain.com
ServerName newdomain.com
ServerAlias www.newdomain.com
ErrorLog logs/newdomain.com-error_log
CustomLog logs/newdomain.com-access_log common

Subdomain

 

In case you have a subdomain, you’ll have to add a new server if you expect Nginx to host your site’s static files. Your subdomain might only host static files, in which case you won’t have to setup a proxy_pass server:


server {
listen 80;
server_name subdomain.example.com;
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /var/www/nginx-default;
}
access_log /var/www/subdomain.example.com/log/nginx.access.log;
error_log /var/www/subdomain.example.com/log/nginx.error.log;
index index.html;
location / {
expires     max;
root /var/www/subdomain.example.com/htdocs/;
}
}

The critical variables in this execution are:

  • DocumentRoot – This represents the default web root folder; the default location to store your website files.
  • ServerName – This is the domain name that has been assigned to your newly set-up virtual host
  • ServerAlias – An alias will be assigned to your virtual host, which can contain more than one domain name, aliases.

 

For Debian/Ubuntu:

On Ubuntu, you’ll first have to configure the Apache service file so that it listens on port 8080:


sudo nano /etc/apache2/ports.conf

Once you access the service, just change the default port values from 80 to 8080. Just would also want to change the listen line and modify it to 127.0.0.1:8080 as it will prevent the apache server from receiving external requests. And even if you’re not worried about external access, you should block port 8080 just to be safe.


NameVirtualHost *:8080
Listen 8080

Once you’ve modified the file, make sure to save all your changes and the close the file.

 
The next file you’ll have to modify is:


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

 

Repeat the same operation within the file and set the port 8080, as default. Once that’s done, save and close the file.

Step 3: Configure Virtual Host

Once the Web server has been configured, you have to create a file that will contain the settings for your virtual host:


sudo nano /etc/apache2/sites-available/newdomain.com.conf
ServerAdmin webmaster@localhost
ServerName newdomain.com
ServerAlias www.newdomain.com
DocumentRoot /var/www/newdomain.com
 
Options FollowSymLinks
AllowOverride None
Options Indexes FollowSymLinks MultiViews
AllowOverride None
Order allow,deny
allow from all
 
ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/
<Directory "/usr/lib/cgi-bin">
AllowOverride None
Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
Order allow,deny
Allow from all
 
ErrorLog ${APACHE_LOG_DIR}/error.log
 
# Possible values include: debug, info, notice, warn, error, crit,
# alert, emerg.
LogLevel warn
 
CustomLog ${APACHE_LOG_DIR}/access.log combined

After you’ve made the changes, copy the entire code onto this location:
 


sudo cp /etc/apache2/sites-available/newdomain.com.conf /etc/apache2/sites-enabled/

Now that you have both services configured with the settings that will enable them to be connected, restart both NGINX and Apache so that the changes are permanently applied:

For CentOS 6.4:
 


sudo /etc/init.d/httpd restart

sudo /etc/init.d/nginx restart

Debian/Ubuntu:
 


sudo /etc/init.d/apache2 restart

sudo /etc/init.d/nginx restart

Step 4: Test Reverse Proxy Functionality

If you want to check whether the changes have been implemented and that they are working, the first thing you should do is open a web page on your site and look for any signs for errors. Alternately, you can also view the logs of Apache and Nginx, which should contain the PHP request data and your assets, respectively. Your Apache (Web Server) logs should also need to contain a HTTP 1.0 request when accessing the reverse proxy.
You can test the functionality of the reverse proxy service using the following command:
 


curl -I https://newdomain.com

The response should look something like this:
 


HTTP/1.1 200 OK
Server: nginx/0.7.67
Date: Fri, 23 May 2014 09:02:43 GMT
Content-Type: text/html
Content-Length: 21
Last-Modified: Thu, 22 May 2014 14:35:05 GMT
Connection: keep-alive
Expires: Sun, 22 Jun 2014 09:02:43 GMT
Cache-Control: max-age=259200
Accept-Ranges: bytes

Other checks

  1. If you want to check whether your site’s dynamic content is being passed on to the Web server, in this case Apache, you can create your own personal PHP data file within your site’s default web root folder:

 


sudo nano info.php
<?php
phpinfo();
?>
  1. If the newdomain.com is being redirected to the server’s IP address, you could access the file from this location:

 


https://newdomain.com/info.php

This should be the data displayed on the PHP info page:
Server API
Apache 2.0 Handler

  1. A quick and simple method of identifying your server’s IP address is by executing the following command:

 


ip addr show eth0|grep inet|awk '{print $2}'|cut -d / -f1

Author: Rahul Sharma


FileCloud - The fastest growing enterprise file sharing and sync solution!