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.
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 proxies forward requests to one or more ordinary servers which 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.
-
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.
Common Uses For A Reverse Proxy Server:
Installing NGINX
as we write this article current version of NGINX is 1.14.2
.
-
Install the EPEL repository:
-
Update the repository:
-
Install NGINX Open Source:
-
Verify the installation:
CentOS/RHEL:
-
Update the Debian repository information:
-
Install the NGINX Open Source package:
-
Verify the installation:
Debian/Ubuntu:
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:
and here are URLs for the second service:
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:
1
2
3
4
5
6
server {
listen 80;
listen [::]:80;
server_name example.com;
}
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
.
1
2
3
4
5
6
location /app {
proxy_pass http://localhost:8080/;
}
location /api {
proxy_pass http://localhost:8090/api/;
}
as you can see if URL starts with /app
, the request will be forwarded to first service.
Advanced Configuration
real-time web applications often do not buffer data, so we may also want to disable it on the reverse proxy server.
1
2
3
4
location /api {
proxy_pass http://localhost:8090/api/;
proxy_buffering off;
}
you may also need to set or add headers to the requests:
1
2
3
4
5
location /app {
proxy_pass http://localhost:8080/;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
}
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:
1
2
3
location ~ ^/app/css/(.*)$ {
proxy_pass http://localhost:8080/assets/css/$1;
}
We also can use rewrite
:
1
2
3
4
location /app/ {
rewrite ^/app/dashboard/(.*)$ /app/home?path=$1 break;
proxy_pass http://localhost:8080/;
}
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:
Using NGINX Load Balancer
Define servers that you want to balance request loads on them:
1
2
3
4
5
upstream backend {
server 10.1.0.101;
server 10.1.0.102;
server 10.1.0.103;
}
now we can use load balancer in location
parameter of reverse proxy:
1
2
3
4
5
6
7
server {
listen 80;
location / {
proxy_pass http://backend;
}
}
SSL Encryption With NGINX
First of all define certifications like this:
1
2
3
4
5
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;
now you can enable https for your servers by this:
1
2
3
4
5
6
7
8
9
10
11
12
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;
}