Setting Up an Nginx Reverse Proxy

Introduction

Before we begin talking setting up a Nginx Reverse Proxy, let's briefly understand – What is a Reverse Proxy ?

A reverse proxy is a service that receives a client request, routes it to one or more proxied servers, retrieves the response, and returns it to the client.

NGINX is frequently used as a reverse proxy for HTTP and non-HTTP servers due to its performance and scalability. Nginx is commonly used as a reverse proxy in front of Node.js, Python, or Java applications.

In this tutorial, you will set up a Nginx Reverse Proxy. We will also address a few FAQs on how to set up a Nginx Reverse Proxy.

Advantages of Reverse Proxy

  1. Enhanced security: Reverse proxies act as a shield by hiding server details and providing additional security layers.
  2. Load balancing: Efficiently distribute traffic across multiple servers, optimizing performance and preventing server overload.
  3. Caching: Speed up web requests by storing frequently accessed content, reducing server load and improving response times.
  4. SSL termination: Handle SSL encryption on behalf of servers, reducing server processing requirements and simplifying certificate management.
  5. Simplified architecture: Allows for seamless integration of multiple servers and services behind a single entry point, simplifying infrastructure management.

Prerequisites

We'll assume you've installed Nginx on your Ubuntu, CentOS, or Debian server.

Using Nginx as a Reverse Proxy

Open the domain's server block configuration file and specify a location and a proxied server inside it to configure Nginx as a reverse proxy to an HTTP server:

server {
    listen 80;
    server_name www.example.com example.com;

    location /app {
       proxy_pass http://127.0.0.1:8080;
    }
}

The proxy pass directive specifies the proxied server URL, which can utilize HTTP or HTTPS as a protocol, a domain name or IP address as a domain, and an optional port and URI as an address.

The preceding setup instructs Nginx to forward all /app queries to the proxied server at http://127.0.0.1:8080.

💡
Server block files are saved in the /etc/nginx/sites-available directory on Ubuntu and Debian-based distributions, and in the /etc/nginx/conf.d directory on CentOS.

Take the following example to better understand how the location and proxy pass directives work:

server {
    listen 80;
    server_name www.example.com example.com;

    location /blog {
       proxy_pass http://node1.com:8000/wordpress/;
    }
}

If someone visits http://example.com/blog/my-post, Nginx will redirect them to http://node1.com:8000/wordpress/my-post.

The request URI that is provided to the proxied server is substituted by a URI specified in the directive when the proxied server's address contains a URI (/wordpress/). The whole request URI is provided to the proxied server if the proxied server's address is specified without a URI.

Passing Request Headers

Nginx automatically defines two header fields in proxied requests from the client, Host, and Connection, and eliminates empty headers when it proxies a request. The connection is set to close, and the Host is set to the $proxy host variable.

Use the proxy set header directive, followed by the header value, to change or set headers for proxied connections. A list of all accessible Request Headers and their permissible values may be found here. Set it to an empty string "" to prevent a header from being sent to the proxied server.

The value of the Host header field is changed to $host in the following example. The Accept-Encoding header field is removed by altering its value to an empty string.

location / {
    proxy_set_header Host $host;
    proxy_set_header Accept-Encoding "";
    proxy_pass http://localhost:3000;
}

If you make changes to the configuration file, you must restart the Nginx service for them to take effect.

Configuring Nginx as a Reverse Proxy to a non-HTTP proxied server

The following directives can be used to configure Nginx as a reverse proxy to a non-HTTP proxied server:

  • fastcgi_pass is a reverse proxy that connects to a FastCGI server.
  • uwsgi_pass - uwsgi server reverse proxy.
  • scgi_pass - a SCGI server's reverse proxy.
  • memcached_pass - Memcached server reverse proxy.

One of the most typical uses of Nginx as a reverse proxy for PHP-FPM is as follows:

server {

    # ... other directives

    location ~ \.php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/run/php/php7.2-fpm.sock;
    }
}

Common Nginx Reverse Proxy Options

Nowadays, serving material through HTTPS has become the norm. In this section, we'll show you how to configure HTTPS Nginx reverse proxy, as well as the recommended Nginx proxy options and headers.

location/ {
    proxy_pass http://127.0.0.1:3000;
    proxy_http_version  1.1;
    proxy_cache_bypass  $http_upgrade;

    proxy_set_header Upgrade           $http_upgrade;
    proxy_set_header Connection        "upgrade";
    proxy_set_header Host              $host;
    proxy_set_header X-Real-IP         $remote_addr;
    proxy_set_header X-Forwarded-For   $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header X-Forwarded-Host  $host;
    proxy_set_header X-Forwarded-Port  $server_port;
  }
  • proxy_http_version 1.1 - Defines the proxying HTTP protocol version, which is set to 1.0 by default. Version 1.1 is required for Websockets and keepalive connections.
  • proxy_cache_bypass $http_upgrade - Defines the circumstances in which the answer will not be cached.
  • Upgrade $http_upgrade and Connection "upgrade" - If your application uses Websockets, these header elements are required.
  • Host $host - The $host variable contains the hostname from the request line, the hostname from the Host request header field, or the server name matching a request, in that order.
  • X-Real-IP $remote_addr - The real visitor's remote IP address is forwarded to the proxied server.
  • X-Forwarded-For $proxy_add_x_forwarded_for - A list of IP addresses for each server through which the client has been proxied.
  • X-Forwarded-Proto $scheme - Each HTTP answer from the proxied server is transformed to HTTPS when used inside an HTTPS server block.
  • X-Forwarded-Host $host - Defines the client's original host request.
  • X-Forwarded-Port $server_port - Defines the client's original port request.

If your Ubuntu 18.04, CentOS 7, or Debian server doesn't already have an SSL/TLS certificate, use certbot to get a free Let's Encrypt SSL certificate.

FAQs to Set Up a Nginx Reverse Proxy

Why should I use Nginx as a reverse proxy?

Nginx offers high performance, scalability, and advanced features like load balancing, SSL termination, caching, and easy configuration.

How do I configure Nginx as a reverse proxy?

Nginx configuration involves defining proxy_pass directives to specify backend servers, setting up server blocks, configuring SSL, and enabling other desired features.

Can I use Nginx reverse proxy for load balancing?

Yes, Nginx offers various load balancing algorithms like round-robin, IP hash, and more. You can configure upstream servers to distribute traffic effectively.

How can I enable SSL termination with Nginx reverse proxy?

Nginx supports SSL termination by configuring SSL certificates on the reverse proxy server, allowing encrypted connections between clients and the proxy.

Can Nginx reverse proxy cache content?

 Yes, Nginx provides caching capabilities. By configuring caching directives, you can store frequently accessed content, reducing server load and improving performance.

How can I secure my Nginx reverse proxy?

Implement security measures like limiting allowed IP addresses, setting up authentication, enabling security headers, and regularly updating Nginx to enhance security.

How do I troubleshoot issues with Nginx reverse proxy?

Nginx provides comprehensive error logs for debugging. Checking error logs, verifying configurations, and testing connectivity helps diagnose and resolve issues.

Conclusion

You now know how to utilize Nginx as a reverse proxy server. We've also shown you how to edit and set different header fields in proxied requests, as well as give additional parameters to the server.

If you have any queries, please leave a comment below and we’ll be happy to respond to them.