I'm trying to solve this problem I've been experiencing wherein I've been unable to connect to my SurrealDB backend over HTTPS/WSS. When attempting to connect via HTTP or WS, things work just fine, but adding any sort of SSL seems to break everything. My current stack looks like this:
My nginx configuration looks like this:
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
upstream websocket {
server 127.0.0.1:4321;
}
sendfile on;
keepalive_timeout 65;
# HTTP server
server {
listen 443 ssl;
server_name [...].com;
ssl_certificate C:\Certbot\live\[...].com\fullchain.pem;
ssl_certificate_key C:\Certbot\live\[...].com\privkey.pem;
location / {
proxy_pass http://127.0.0.1:3000;
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;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
# Secure WebWocket (WSS) server
server {
listen 443;
server_name dev.db.[...].com;
ssl_certificate C:\Certbot\live\[...].com\fullchain.pem;
ssl_certificate_key C:\Certbot\live\[...].com\privkey.pem;
location / {
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_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_http_version 1.1;
proxy_pass http://websocket;
proxy_redirect off;
proxy_pass_request_headers on;
}
}
}
Cloudflare is setup to forward traffic to the main domain and all subdomains to the same server (everything is currently hosted from the same machine.) Both configuration options (A records) are set to the same IP address and are proxied.
The proxy to port 3000 works and the Next.js instance is accessible via HTTPS, so I don't imagine that nginx itself is messed up, but I might be wrong.
I have tried various solutions to this problem, including the following:
Issuing separate SSL certificates for the subdomain and the primary domain (using certbot),
Sharing the same SSL certificate for both domains (using certbot),
Pointing proxy-pass
to an upstream
as well as a direct 127.0.0.1:8000
approach,
Ensuring the following:
proxy_http_version
is set to 1.1
.proxy_set_header Upgrade
is set to $http_upgrade
or upgrade
.Listening on both 443 and 80, including and excluding the ssl
suffix on the listen
directive.
Changing the server_name
from dev.db.[...].com
to various other options, with no success,
Port-forwarding port 8000, 443, 80, and 8080.
Adding firewall rules (TCP/UDP + incoming/outgoing) for the aforementioned ports, as well as port 3000 (for the Next.js instance).
Changing SurrealDB's address and port binding (--bind
) to something else. Note that the --addr
flag available when starting SurrealDB is something I have not yet tried as I cannot quite seem to figure out the proper way to manipulate it. Could this be the issue?
Attempted connection via local network and external WSS port testing tool, both failures,
Reordered nginx configuration to use a location /ws
instead of a server
directive just to see if that might work (unfortunately it did not).
This is the error I get every single time I attempt to connect from any medium:
Console log error "WebSocket connection to wss://dev.db.censored.com/' failed
Are there any suggestions? Am I perhaps missing something, or maybe I did this incorrectly?
(Note that the [...] in the examples provided is the censored domain name, not literal characters.)
I solved my own problem! The issue was that I was not proxying the /rpc
endpoint properly in my nginx.conf
. The fix was to add this to my default server entry in the configuration:
location /rpc {
proxy_pass http://127.0.0.1:8000;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# WebSocket support
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
This allows the JavaScript library to access the correct SurrealDB endpoint and fixed my problem right away. In hindsight, I feel like it should have been obvious, but oh well! If anyone else has a similar problem getting SurrealDB to work with your nginx configuration, I hope this helps!