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
- If user is using Pro server, they will get a web console at port
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
}
}
}
}