Using NGINX as a Reverse Proxy

A reverse proxy allows you to run a Solid server on a local port and let the proxy handle traffic to public HTTP and HTTPS ports. The instructions below are for the Community Solid Server.

Prerequisites

In this example, we assume that:

  • your server is running on http://localhost:3000/
  • the public URL of your reverse proxy is https://solid.example/
  • you have installed NGINX and its configuration folder is /etc/nginx/
  • you have obtained (free) TLS certificates, stored at /etc/letsencrypt/live/solid.example/

Configuration

Add a new site to your NGINX configuration by creating a file such as /etc/nginx/sites-available/solid.example with the following contents:

# The local Solid server instance
upstream solid-community-server {
  server 127.0.0.1:3000;
}

# Redirect HTTP to HTTPS
server {
  server_name solid.example;
  listen 80;
  return 301 https://$host$request_uri;
}

# Proxy traffic for https://solid.example/ to http://localhost:3000/
server {
  server_name solid.example;
  listen 443 ssl http2;
  ssl_certificate         /etc/letsencrypt/live/solid.example/fullchain.pem;
  ssl_certificate_key     /etc/letsencrypt/live/solid.example/privkey.pem;
  ssl_trusted_certificate /etc/ssl/certs/lets-encrypt-x3-cross-signed.pem;

  # Include this for certificate renewal if you are using Let's Encrypt
  include snippets/https.conf;
    location ^~ /.well-known/acme-challenge/ {
    root /var/www/solid.example; # or a folder of your choice
  }

  # Proxy all other trafic to the Solid server
  location / {
    # Delegate to the Solid server, passing the original host and protocol
    proxy_pass http://solid-community-server$request_uri;
    proxy_set_header X-Forwarded-Host $host;
    proxy_set_header X-Forwarded-Proto $scheme;

    # Pass these headers from the Solid server back to the client
    proxy_pass_header Server;
    proxy_pass_header Set-Cookie;

    # Enable Websocket support
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
  }
}

HTTPS configuration

We are reusing an HTTPS configuration file at /etc/nginx/snippets/https.conf, which you should create if it does not exist:

# Generated by https://ssl-config.mozilla.org/

ssl_session_timeout 1d;
ssl_session_cache shared:SSL:10m;
ssl_session_tickets off;

# Diffie-Hellman parameter for DHE ciphersuites, recommended 2048 bits
ssl_dhparam /etc/ssl/certs/dhparam.pem;

# intermediate configuration
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:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers off;

# HSTS (ngx_http_headers_module is required) (63072000 seconds)
add_header Strict-Transport-Security "max-age=63072000" always;

# OCSP stapling
ssl_stapling on;
ssl_stapling_verify on;

Activating the configuration

Restart NGINX to activate the new configuration:

sudo systemctl restart nginx