Help vaild configs for RustDesk Server, CORS, WebSocket, headers

1. The problem I’m having:

Hi, I want to submitting Caddy configurations for RustDesk server, RustDesk is a remote desktop software that allowed you to self-hosted your own server, one of the feature of it is Web Client, which rely on WebSocket behind a reverse proxy to handle TLS connections.

I have “okay” knowledges about Caddy, but I want to make sure everything is right before I submitting.

Requirements

First, let me explain RustDesk Server’s basic architectures:

There are two separate binaries/containers, on is hbbs, the other is hbbr

  • hbbs means “signal” server, act as coordination server for all clients, like hole punch or provide peer’s IP and port to try to establish direct connections
    • If user is using Pro server, they will get a web console at port 21114
  • hbbr means “relay” server, if direct connection isn’t possible, it can act as relay

The WebSocket ports for those two:

  • hbbs: 21118
    • Also required if having Pro Server: 21114, not WebSocket
  • hbbr: 21119

The path required for those two:

  • hbbs: /ws/id
  • hbbr: /ws/relay

This is the Nginx configurations provided by RustDesk official docs:

server {
    server_name YOUR_DOMAIN;
    location / {
        proxy_set_header        X-Real-IP       $remote_addr;
        proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_pass http://127.0.0.1:21114/;
    }

    location /ws/id {
        proxy_pass http://127.0.0.1:21118;
        proxy_http_version 1.1;
        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_read_timeout 120s;
    }

    location /ws/relay {
        proxy_pass http://127.0.0.1:21119;
        proxy_http_version 1.1;
        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_read_timeout 120s;
    }

    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/YOUR_DOMAIN/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/YOUR_DOMAIN/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}

server {
    if ($host = YOUR_DOMAIN) {
        return 301 https://$host$request_uri;
    } # managed by Certbot

    server_name YOUR_DOMAIN;
    listen 80;
    return 404; # managed by Certbot
}

And the CORS config, because for OSS user, the only available way to access Web Client is https://rustdesk.com/web/

        if ($http_origin ~* (https?://(www\.)?rustdesk\.com)) {
            add_header 'Access-Control-Allow-Origin' "$http_origin" always;
            add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, PATCH, OPTIONS' always;
            add_header 'Access-Control-Allow-Headers' 'Origin, Content-Type, Accept, Authorization' always;
            add_header 'Access-Control-Allow-Credentials' 'true' always;
        }
        if ($request_method = 'OPTIONS') {
            add_header 'Access-Control-Allow-Origin' "$http_origin" always;
            add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, PATCH, OPTIONS' always;
            add_header 'Access-Control-Allow-Headers' 'Origin, Content-Type, Accept, Authorization' always;
            add_header 'Access-Control-Allow-Credentials' 'true' always;
            add_header 'Content-Length' 0;
            add_header 'Content-Type' 'text/plain charset=UTF-8';
            return 204;
        }

Ignore weird Allow-Methods… They seems don’t know what it is…

2. Caddyfile

I use ChatGPT to generated and manually modified with me, like both realip header and WebSocket are not required additional setup for Caddy, the header_common is the headers that my existing Caddy using.

I have vaildated that it is working.

B2w, is read_timeout 120s needed for Caddy? Docs said it in unlimited for Caddy.

Suggestions for comments are also welcome, because this will be shared for everyone.

(header_common) {
	header {
		# HSTS, very recommend to enable, for details, check https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Strict-Transport-Security
		# Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
		X-Content-Type-Options "nosniff"
		Referrer-Policy "same-origin"
		Content-Security-Policy "base-uri 'self';"
		X-Frame-Options "SAMEORIGIN"
		X-XSS-Protection "1; mode=block"
		# Remove reverse proxy header
		-Server
		-via
	}
}

(cors) {
	@origin header Origin {args[0]}
	header @origin Access-Control-Allow-Origin "{args[0]}"
	header @origin Access-Control-Allow-Methods "OPTIONS,GET,POST"
}

rustdesk.example.com {
	# Put reverse proxy to same route to import shared header
	route {
		import header_common
		import cors rustdesk.com
		encode zstd gzip

		# >>> Only for Pro Server
		# reverse_proxy / 127.0.0.1:21114 {} # Haven't test because I don't have
		# <<< Only for Pro Server

		# ID Server
		reverse_proxy /ws/id http://127.0.0.1:21118 {
			transport http {
				read_timeout 120s
			}
		}

		# Relay Server
		reverse_proxy /ws/relay http://127.0.0.1:21119 {
			transport http {
				read_timeout 120s
			}
		}
	}
}

Note: I’m not intend to guide users to setup DNS ACME challenges, or ECH etc… Because it needs additional setup and compile (Or use pre-compiled Caddy from 3rd party, which not okay for official docs) which will confuse end users, and this server will absolutely will exposed to internet, so HTTP or TLS ACME challenge should work as expected.

So the global setting what I may put are only debug or log, I didn’t put it at my Caddyfile that I posted, I will include it when submitting.

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.