What is a reverse proxy?

A reverse proxy server is a type of proxy server that typically sits behind the firewall and directs client requests to the appropriate back-end server. A reverse proxy provides an additional level of abstraction and control to ensure the smooth flow of network traffic between clients and servers.

For example:

Let’s take three computers connected to the internet.

X = your computer, or “client” computer on the internet

Y = the reverse proxy web site, proxy.example.com

Z = the web site you want to visit, www.example.net

Normally, one would connect directly from X –> Z.

new2

 

However, in some scenarios, it is better for the administrator of Z to restrict or disallow direct access, and force visitors to go through Y first. So, as before, we have data being retrieved by Y –> Z on behalf of X, which chains as follows: X –> Y –> Z.

 

new3

Now the user X does not know he is accessing Z, because X only sees he is communicating with Y. The server Z is invisible to clients and only Y is visible externally.

The client X thinks he is only communicating with Y (X –> Y), but the reality is that Y forwarding all communication (X –> Y –> Z again).

Common uses for a reverse proxy server include:

  • Load Balancing
  • Web Acceleration
  • Security and Anonymity
  • SSL Termination
  • Centralized logging and auditing
  • Caching

 

How does NGINX forward requests ?

First of all we need to understand what Nginx is. So Nginx (pronounced “engine x”) is a web server with a strong focus on high concurrency, performance and low memory usage. It can also act as a reverse proxy server for HTTP, HTTPS, SMTP, POP3, and IMAP protocols, as well as a load balancer and an HTTP cache.

When Nginx  proxies a request, it sends the request to a specified proxied server, fetches the response, and sends it back to the client. It is possible to proxy requests to an HTTP server (another Nginx server or any other server) or a non-HTTP server (which can run an application developed with a specific framework, such as PHP or Python) using a specified protocol. Supported protocols include FastCGI, uwsgi, SCGI, and memcached.

This configuration can be done in Nginx’s config file. To pass a request to an HTTP proxied server, the proxy_pass directive is specified inside a location. For example:

location /some/path/ {
proxy_pass http://www.example.com/link/;
}

 

This example results in passing all requests processed in this location to the proxied server at the specified address. This address can be specified as a domain name or an IP address. The address may also include a port if it’s not running on the default HTTP port:

location ~ \.php {
proxy_pass http://127.0.0.1:8000;
}

To pass a request to a non-HTTP proxied server, the appropriate **_pass directive should be used:

 

Some useful rewrites for Nginx:

Rewrite Old Domain to New Domain:

Lets say you have changed the domain name from old.com to new.com. Then you don’t need to worry it’s very easy to handle in nginx. The below listed Rewrite will do the trick for you.

server {
listen 80;
server_name old.com www.old.com;
rewrite ^ $scheme://www.new.com ;

#or
#rewrite ^ $scheme://www.new.com$request_uri permanent;

}

It is a simpler block that redirect everything to the homepage of new.com. Whereas the second one which is commented out do match the domain name having old.com and redirect it to the new.com with a $request_uri means “when we redirect, copy the URL part” so when they visit http://www.old.com/about they will be redirected to http://www.new.com/about. The permanent means for the browser to remember this redirect forever (status 301).

 

Add Or Remove www from Domain:

Adding www:

server {
listen 80;
server_name arun.com;
rewrite ^(.*)$ $scheme://www.arun.com$1;
}

 

Removing www:

server {
listen 80;
server_name www.arun.com;
rewrite ^(.*)$ $scheme://arun.com$1;
}

 

More information about Nginx rewrites:

https://www.nginx.com/blog/creating-nginx-rewrite-rules

 

The challenge in this particular problem:

The URL that we had was like

https://example.com?a=https%3A%2F%2Fgoogle%2Fwp-login.php

We had to change the value of the argument by adding a .com

?a=https%3A%2F%2Fgoogle%2Fwp-login.php

to

?a=https%3A%2F%2Fgoogle.com%2Fwp-login.php

So to accomplish this we had created a rewrite rule like below:

location / {

if ($args ~* (.*)(a=https%3A%2F%2Fgoogle%2F)(.*)) {

set $args $1a=https://google.com/$3;

rewrite ^(.*)$ $1;

}

proxy_pass https://backends;

}

The above rule matches the argument service which has a value https%3A%2F%2Fgoogle%2F.  The regex matches the arguments in parts ($1, $2…). The “set $args” replaces the original args with the ones following the set $args call, where we append a “.com” followed by the remaining arguments ($3). One more thing to notice here is we have taken $1 and $3 in the arg matching section so that any leading and trailing arguments are not lost.

Conclusion:

This is a brief introduction to some common challenges and their solutions that you might use in your site. Rewrites are powerful and can be complex, but even a few simple ones can make a difference to your site.