DEV Community

Alireza Akrami
Alireza Akrami

Posted on • Originally published at iakrami.ir on

Use NGINX To Build A Reverse Proxy

a proxy server is a mediator server that will forward every request from clients to different destinations. destination server does not see clients directly, so they don't know anything about those clients.

after accepting a request from a client, the proxy server will assign a port to that request and forwards the request to its destination. after receiving the reply on that port, the response will be forwarded to the client through the previous connection.

proxy server

unlike proxy servers, a reverse proxy server resides beside web servers. clients see web servers behind a reverse proxy as one server and can not distinguish them.

reverse proxy server

Reverse proxies forward requests to one or more ordinary servers that handle them. The response from the proxy server is returned as if it came directly from the original server, leaving the client with no knowledge of the origin servers.

Common Uses For A Reverse Proxy Server:

Load Balancing

A reverse proxy server can act as a load-balancer in front of backend servers and distributing client requests across a group of servers in a manner that maximizes speed and capacity utilization while ensuring none of them is overloaded. If one goes down, the load balancer redirects traffic to the remaining active ones.

Web Acceleration

Reverse proxies can compress requests, as well as cache commonly requested content, which speeds up the flow of traffic between clients and servers.

Encryption / SSL Acceleration

the SSL encryption is often not done by web servers, and instead reverse proxy will handle it. by this, all services across web servers are encrypted and secured just by one configuration.

Installing NGINX

as we write this article current version of NGINX is 1.14.2.

CentOS/RHEL:

  1. Install the EPEL repository:
$ sudo yum install epel-release
Enter fullscreen mode Exit fullscreen mode
  1. Update the repository:
$ sudo yum update
Enter fullscreen mode Exit fullscreen mode
  1. Install NGINX Open Source:
$ sudo yum install nginx
Enter fullscreen mode Exit fullscreen mode
  1. Verify the installation:
$ sudo nginx -v
Enter fullscreen mode Exit fullscreen mode

Debian/Ubuntu:

  1. Update the Debian repository information:
$ sudo apt-get update
Enter fullscreen mode Exit fullscreen mode
  1. Install the NGINX Open Source package:
$ sudo apt-get install nginx
Enter fullscreen mode Exit fullscreen mode
  1. Verify the installation:
$ sudo nginx -v
Enter fullscreen mode Exit fullscreen mode

other installation methods and operating systems are available on this link: Installing NGINX Open Source

Configure NGINX

assume that we have two main services on the server. one is hosted by apache on port 8080 and another one is a nodejs service on port 8090.

URLs for the first service are as follow:

http://localhost:8080/login
http://localhost:8080/home
http://localhost:8080/assets/css/home.css
http://localhost:8080/assets/js/home.js
Enter fullscreen mode Exit fullscreen mode

and here are URLs for the second service:

http://localhost:8090/api
http://localhost:8090/api/getAll
http://localhost:8090/api/set
Enter fullscreen mode Exit fullscreen mode

ok, now let's look at our configuration. the main location of this file is /etc/nginx/nginx.conf. if you can not find that just create it:

server {
    listen 80;
    listen [::]:80;

    server_name example.com; 
}

Enter fullscreen mode Exit fullscreen mode

you should replace example.com with your own domain name.

we have defined a new server on port 80 on line 2. server_name is our domain name. now we want to define our rules for URLs in reverse proxy. just add these lines after server_name.

location /app {
    proxy_pass http://localhost:8080/;
}
location /api {
    proxy_pass http://localhost:8090/api/;
}

Enter fullscreen mode Exit fullscreen mode

as you can see if the URL starts with /app, the request will be forwarded to the first service.

http://localhost/app/login => http://localhost:8080/login
http://localhost/app/home => http://localhost:8080/home
http://localhost/api/getAll => http://localhost:8090/api/getAll
http://localhost/app/xxxx => http://localhost:8080/xxxx
http://localhost/api/xxxx => http://localhost:8090/api/xxxx
Enter fullscreen mode Exit fullscreen mode

Advanced Configuration

real-time web applications often do not buffer data, so we may also want to disable it on the reverse proxy server.

location /api {
    proxy_pass http://localhost:8090/api/;
    proxy_buffering off;
}

Enter fullscreen mode Exit fullscreen mode

you may also need to set or add headers to the requests:

location /app {
    proxy_pass http://localhost:8080/;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header Host $host;
}

Enter fullscreen mode Exit fullscreen mode

This configuration uses the built-in $remote_addr variable to send the IP address of the original client to the proxy host.

By default, the Host header from the request is not forwarded but is set based on the proxy_pass statement.

you can use regular expressions for defining custom locations:

location ~ ^/app/css/(.*)$ {
    proxy_pass http://localhost:8080/assets/css/$1;
}
Enter fullscreen mode Exit fullscreen mode
http://localhost/app/css/home.css => http://localhost:8080/assets/css/home.css
Enter fullscreen mode Exit fullscreen mode

We also can use rewrite:

location /app/ {
    rewrite ^/app/dashboard/(.*)$ /app/home?path=$1 break;
    proxy_pass http://localhost:8080/;
}

Enter fullscreen mode Exit fullscreen mode

If the rewrite rule is hit, the URI specified in the directive is ignored and the full changed request URI is passed to the server:

http://localhost/app/dashboard/addUser => http://localhost:8080/home?path=addUser
http://localhost/app/assets/css/home.css => http://localhost:8080/assets/css/home.css
Enter fullscreen mode Exit fullscreen mode

Using NGINX Load Balancer

Define servers that you want to balance request loads on them:

upstream backend {
    server 10.1.0.101; 
    server 10.1.0.102;
    server 10.1.0.103;
}

Enter fullscreen mode Exit fullscreen mode

now we can use load balancer in location parameter of reverse proxy:

server {
    listen 80; 

    location / {
       proxy_pass http://backend;
    }
}

Enter fullscreen mode Exit fullscreen mode

SSL Encryption With NGINX

First of all, define certifications like this:

http {
    ssl_certificate /root/certs/example.com/example.com.crt;
    ssl_certificate_key /root/certs/example.com/example.com.key;
    ssl_ciphers EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH;
    ssl_protocols TLSv1.1 TLSv1.2;

Enter fullscreen mode Exit fullscreen mode

now you can enable HTTPS for your servers by this:

server {
    listen 203.0.113.30:443 ssl;
    listen [2001:DB8::5]:443 ssl;
    server_name example1.com www.example1.com;
    root /var/www/example1.com;
}
server {
    listen 203.0.113.40:443 ssl;
    listen [2001:DB8::6]:443 ssl;
    server_name example2.com www.example2.com;
    root /var/www/example2.com;
}

Enter fullscreen mode Exit fullscreen mode

Top comments (0)