Setting Up Nginx Reverse Proxy Server on Ubuntu/Debian

A reverse proxy server is a type of server that sits in front of web servers and forwards client (e.g., web browser) requests to those web servers. Reverse proxies are typically installed to increase security, performance, and reliability. This tutorial will guide you through the process of setting up Nginx, a high-performance and highly scalable web server, as a reverse proxy on a system running Ubuntu or Debian.

In this tutorial you will learn:

  • How to install Nginx and necessary packages
  • How to configure Nginx as a reverse proxy with SSL
  • How to generate SSL certificates and secure Nginx
  • How to test and verify your Nginx configuration
Setting Up Nginx Reverse Proxy Server on Ubuntu/Debian
Setting Up Nginx Reverse Proxy Server on Ubuntu/Debian
Software Requirements and Linux Command Line Conventions
Category Requirements, Conventions or Software Version Used
System Ubuntu 24.04 LTS or Debian 12 or above
Software Nginx
Other Internet connection, access to a terminal
Conventions # – requires given linux commands to be executed with root privileges either directly as a root user or by use of sudo command
$ – requires given linux commands to be executed as a regular non-privileged user

Installation and Initial Configuration

Before configuring Nginx as a reverse proxy, it must be installed along with other necessary packages. This section will cover the installation process.

  1. Update Your System: Begin by updating your package lists and system.
    $ sudo apt update && sudo apt upgrade

    Updating your system ensures that you have the latest security patches and dependencies required for Nginx.

  2. Install Nginx: Install Nginx using the package manager.
    $ sudo apt install nginx

    Once installed, the Nginx service should start automatically. You can check its status with sudo systemctl status nginx.

Configuring Nginx as a Reverse Proxy

With Nginx installed, the next step is to configure it as a reverse proxy to forward requests to one or more backend web servers.

  1. Configure the Proxy Settings: Begin by editing the Nginx configuration file to establish the reverse proxy settings.
    $ sudo nano /etc/nginx/sites-available/default

    Insert the following configuration snippet inside the server block. This setup forwards incoming requests to a backend server operating on port 3000:

    location / {
        proxy_pass http://localhost:3000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
    }
    

    This configuration defines a location block that matches all requests (denoted by “/”). The proxy_pass directive sends these requests to the specified backend server. The proxy_http_version 1.1 directive specifies HTTP/1.1 for the connection to the proxied server. The proxy_set_header lines modify request headers passed to the proxied server: Upgrade and Connection headers support upgraded connections such as websockets, while the Host header preserves the original host requested by the client. The proxy_cache_bypass directive ensures that the cache is bypassed if the value of the $http_upgrade variable is non-empty, maintaining the integrity of upgrades and ensuring direct server communication.

    Below is a complete example of how your /etc/nginx/sites-available/default file might look, which includes this configuration within a secure HTTPS setup:

    server {
        listen 80;
        server_name yourdomain.com www.yourdomain.com;
        return 301 https://$server_name$request_uri;
    }
    
    server {
        listen 443 ssl;
        server_name yourdomain.com www.yourdomain.com;
    
        ssl_certificate /etc/ssl/certs/your_ssl_certificate.crt;
        ssl_certificate_key /etc/ssl/private/your_private_key.key;
        ssl_protocols TLSv1.2 TLSv1.3;
        ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384';
        ssl_prefer_server_ciphers on;
        ssl_session_cache shared:SSL:10m;
    
        location / {
            proxy_pass http://localhost:3000;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection 'upgrade';
            proxy_set_header Host $host;
            proxy_cache_bypass $http_upgrade;
        }
    
        access_log /var/log/nginx/yourdomain_access.log;
        error_log /var/log/nginx/yourdomain_error.log;
    }
    

    To generate an SSL certificate for this configuration using Let’s Encrypt, you can install certbot and generate certificates. Run the following commands:

    $ sudo apt install certbot python3-certbot-nginx
    $ sudo certbot --nginx -d yourdomain.com -d www.yourdomain.com

    Running these commands will prompt Certbot to automatically modify your Nginx configuration, replacing the paths to the SSL certificate and key with the paths to the new certificates it generates. This is an automated process that adjusts your Nginx setup to utilize the Let’s Encrypt certificates, ensuring they are renewed automatically before they expire. If you have previously specified paths for self-signed certificates or other SSL certificates in your configuration, Certbot will overwrite these with the new, trusted certificate paths.

    If you prefer to use a self-signed SSL certificate instead of obtaining one from Let’s Encrypt, you can generate one with OpenSSL. This approach is particularly useful for testing or internal usage. Execute the following command to generate a self-signed certificate and key:

    $ sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/ssl/private/your_private_key.key -out /etc/ssl/certs/your_ssl_certificate.crt -subj "/CN=*.yourdomain.com"

    This command creates an RSA key and a certificate valid for 365 days, with the common name “*.yourdomain.com” to cover all subdomains of your domain. The certificate and key are stored at the designated locations. Keep in mind that since this certificate is self-signed, browsers may present a warning about the certificate’s trustworthiness when users access your site.

  2. Validate your Nginx configuration:
    $ sudo nginx -t

    This command checks for syntax errors and confirms if the configuration file is correct, ready for service reloading.



  3. Reload Nginx: If the configuration test is successful, reload Nginx to apply the changes.
    $ sudo systemctl reload nginx

    Reloading applies all configuration changes without disrupting ongoing connections.

  4. Test Your Configuration: Verify that the reverse proxy is functioning correctly by accessing your domain in a web browser or using a tool like curl.
    $ curl -I http://yourdomain.com

    This command should return HTTP headers from the backend server, confirming that the reverse proxy is active and operational.

Conclusion

Setting up Nginx as a reverse proxy on Ubuntu or Debian enhances your server’s security and efficiency. By following these steps, you have learned how to install Nginx, configure it as a reverse proxy, and manage its service. You can now extend your setup by adding SSL/TLS encryption or by optimizing cache settings for improved performance.