zrok/docs/guides/self-hosting/nginx_tls_guide.md
Beau Collins 1fdcac13ea
Update nginx_tls_guide.md with websocket support
Adds websocket support to the nginx proxy config.

Signed-off-by: Beau Collins <beau@collins.pub>
2023-11-04 17:53:41 -07:00

4.0 KiB

sidebar_position sidebar_label
50 Nginx TLS

Nginx Reverse Proxy for zrok

Walkthrough Video

Before You Begin

I'll assume you have a running zrok controller and public frontend and wish to front both with Nginx providing server TLS. Go back to Self-Hosting Guide if you still need to spin those up.

Choose a Reverse Proxy Address

I'll use https://api.zrok.quigley.com:443 in this example, and assume you already set up wildcard DNS like *.zrok.quigley.com. This lets us elect api.zrok.quigley.com as the controller DNS name, and forward any other incoming requests to the zrok public frontend.

Obtain a Wildcard Server Certificate

You must complete a DNS challenge to obtain a wildcard certificate from Let's Encrypt. I'll assume you know how to create the necessary TXT record in the DNS zone you're using with zrok.

  1. Install certbot: https://eff-certbot.readthedocs.io/en/stable/install.html

  2. Run certbot with the manual plugin: https://certbot.eff.org/docs/using.html#manual

    # install cert for *.zrok.quigley.com in /etc/letsencrypt
    sudo certbot certonly --manual
    

Install Nginx

Configure Nginx

server {
    listen              443 ssl;
    server_name         api.zrok.quigley.com;
    ssl_certificate     /etc/letsencrypt/live/zrok.quigley.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/zrok.quigley.com/privkey.pem;
    ssl_protocols       TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers         HIGH:!aNULL:!MD5;

    location / {
      proxy_pass      http://127.0.0.1:18080;
      error_log       /var/log/nginx/zrok-controller.log;
    }

}

map $http_upgrade $connection_upgrade {
    default      keep-alive;
    'websocket'  upgrade;
    ''           close;
}

server {
    listen              443 ssl;
    server_name         *.zrok.quigley.com;
    ssl_certificate     /etc/letsencrypt/live/zrok.quigley.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/zrok.quigley.com/privkey.pem;
    ssl_protocols       TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers         HIGH:!aNULL:!MD5;

    location / {
      proxy_pass       http://127.0.0.1:8080;
      proxy_set_header Host $host;
      error_log        /var/log/nginx/zrok-frontend.log;
      proxy_busy_buffers_size   512k;
      proxy_buffers    4 512k;
      proxy_buffer_size   256k;

      proxy_http_version 1.1;
      proxy_set_header Upgrade $http_upgrade;
      proxy_set_header Connection "upgrade";
    }
}

Restart Nginx

Load the new configuration by restarting Nginx. Check the logs to make sure it's happy.

Started A high performance web server and a reverse proxy server.

Check the Firewall

If you followed the non-TLS quickstart then you may have opened 8080,108080/tcp in your firewall. You can go ahead and replace those exceptions with 443/tcp because only Nginx needs to be reachable for zrok to function.

Update the zrok Frontend

List available frontends to obtain the token identifier of the frontend named "public". You may need to set ZROK_ADMIN_TOKEN or ZROK_API_ENDPOINT before running zrok admin.

$ zrok admin list frontends

 TOKEN         ZID        PUBLIC NAME  URL TEMPLATE                              CREATED AT                         UPDATED AT                    
 2NiDTRYUww18  7DsLh9DXG  public       http://{token}.zrok.quigley.com:8080  2023-01-19 05:29:20.793 +0000 UTC  2023-01-19 06:17:25 +0000 UTC 

Update the URL template to use Nginx.

$ zrok admin update frontend 2NiDTRYUww18 --url-template https://{token}.zrok.quigley.com:443
[   0.028]    INFO main.(*adminUpdateFrontendCommand).run: updated global frontend '2NiDTRYUww18'