Secure OBS Websocket with nginx

The OBS websocket developer has a pretty weird point of view regarding listening on private network addresses vs the current state of it listening on a public IP or IPs.
What OBS websocket currently does is listening on 0.0.0.0 which is an alias for all available IP addresses.
But if you’re controlling OBS via Websocket from the outside, it’s no one’s business what you do there.

I will explain how to turn the ws:0.0.0.0:4455 into a wss:domain.tld:443 .

It’s very simple. You need to have nginx installed and somewhere “production ready” configured.
You probably have your config files in /etc/nginx/conf.d or similar.
Create a vhost there.

server {
        listen 80;
        listen [::]:80;
        server_name domain.tld;
        include /etc/nginx/acme.conf;
        error_log /var/log/nginx/domain.tld.error.log;
        access_log /var/log/nginx/domain.tld.access.log;
        location / {
                return 301 https://domain.tld$request_uri;
        }
}

server {
        listen 443 ssl;
        listen [::]:443 ssl;
        http2 on;

        server_name domain.tld;

        ssl_certificate /etc/letsencrypt/live/domain.tld/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/domain.tld/privkey.pem;

        error_log /var/log/nginx/domain.tld.error.log;
        access_log /var/log/nginx/domain.tld.access.log;

        location / {
                proxy_pass http://127.0.0.1:4455;
                proxy_http_version 1.1;
                proxy_set_header Upgrade $http_upgrade;
                proxy_set_header Connection "Upgrade";
                proxy_set_header Host $host;
                proxy_read_timeout 10;
                proxy_connect_timeout 10;
                proxy_redirect off;
        }
}

save it as /etc/nginx/conf.d/domain.tld.conf

Replace all instances of domain.tld with your domain and/or subdomain combination/name.

/etc/nginx/acme.conf

location /.well-known {
        alias /var/www/acme/.well-known;

        location ~ /.well-known/(.*) {
                default_type text/plain;
        }
}
mkdir -p /var/www/acme/.well-known
chown nginx:nginx /var/www/acme/.well-known

request a new certificate from letsencrypt

certbot certonly -d domain.tld -w /var/www/acme/ --webroot

and restart nginx

systemctl restart nginx

If you can’t generate a certificate, or nginx fails to start,
comment everything in the 2nd server block, aka add a # at the beginning of each line there, restart nginx, request a cert, uncomment again, restart nginx.

Connect to OBS websocket via wss://domain.tld:443

Ideally you would have a firewall on your obs server, but this is out of scope.# of this post.

Any questions, comments are below.