Closed micrology closed 9 months ago
Apologies - I had intended to assign this issue to myself, but it seems that this is not something I can do.
NP, only I can do that :wink:
Is there are real need for y-websocket to do the TLS stuff by itself? In real production, I'd expect everybody to run haproxy in front of y-websocket anyway so a good documentation to do that should be enough.
I use nginx (with certbot doing the SSL configuration) in front of y-websocket and it works well.
Yes, AFAIK, that would also be a good way of doing it - and I agree that documentation would be very helpful. I've added some hints for apache in the README for this branch - maybe you could add more relating to nginx?
Here is my nginx proxy setup:
server {
listen 80 ;
# listen [::]:80 ipv6only=on;
root /var/www/html;
index index.php index.html index.htm;
server_name y.relm.us;
location / {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_pass http://localhost:1235;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_connect_timeout 7d;
proxy_send_timeout 7d;
proxy_read_timeout 7d;
client_max_body_size 10m;
}
error_page 413 @filetoobig;
error_page 404 /404.html;
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
location @filetoobig {
add_header Access-Control-Allow-Origin * always;
}
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/y.relm.us/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/y.relm.us/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
}
Example config for Apache reverse-proxy doing TLS termination (if you use Ubuntu, you need to do sudo a2enmod proxy_wstunnel
to enable websocket proxying because it's not enabled by default):
<VirtualHost _default_:443>
SSLEngine on
SSLCertificateChainFile /path/to/cert/chain.crt
SSLCertificateFile /path/to/cert/public.crt
SSLCertificateKeyFile /path/to/private.key
RewriteEngine On
RewriteRule ^/path/prefix/for/websocket/traffic(.*)$ ws://example.localdomain:1234$1 [P]
</VirtualHost>
If you want to use encrypted connection from reverse proxy to backend server, too, replace the ws://
above with wss://
.
As an additional note, if you use HTTP Basic Auth, you'll find that Safari cannot access your websocket because of bug https://bugs.webkit.org/show_bug.cgi?id=80362
well, for testing at home in one's local network between several PCs, being capable of using wss
can come in quite handy - I had to do so today. If interested, look into my own fork of y-websocket
@rozek I tried out your modifications to server.js
, but couldn't get it to run. I simply can't connect to anything. This is what I'm seeing in the console:
WebSocket connection to 'wss://localhost:1234/6d17a764-980d-4f6f-b53d-e42491e5f067' failed
In my case no proxies are in use.
well, since you are using localhost
I assume that you did not prepare any certificate for your server.
I recommend installing "wscat":
npm install -g wscat
wscat -c "wss://localhost:1234/6d17a764-980d-4f6f-b53d-e42491e5f067"
to see what it reports.
If I am right, please, follow the instructions found in rozek/y-websocket to install proper certificates.
I highly recommend running nodejs servers in production behind a proxy. nodejs is not good at handling connections directly. A proxy is also much better suited for handling certificates. If you use something like heroku, they will actually create a certificate for you using let's encrypt
. Also, all proxies support let's encrypt
using some kind of extension. The advantage is that you don't have to copy-paste certificates manually. Also, let's encrypt
certificates are free. I you buy a certificate, you have to remember exchanging it every 1-2 years.
For local development, I've never seen a use-case where you need encryption. Of course, Chrome's Lighthouse will complain. But you should run Lighthouse on production anyway (which hopefully runs behind an encrypted proxy).
If you still want to add encryption to y-websocket directly, you can extend the server part of y-websocket quite easily. There is an example in yjs-demos where I add a static file server:
The default is quite plain and simple and does nothing but websocket:
You only need to adapt server.js
and switch out require('http')
with require('https')
. Also, you have to generate and supply the certificates as described here:
I don't think I want to add this feature upstream though. I want to keep it minimalistic.
Both for additional security and because if one is running a https:// server, it is essential, it would be good if y-websocket could provide websocket services using TLS as an option.
Huly®: YJS-561