xpra icon
Bug tracker and wiki

Opened 10 months ago

Closed 6 months ago

#1213 closed defect (fixed)

http / websockify ssl support

Reported by: Antoine Martin Owned by: Antoine Martin
Priority: blocker Milestone: 1.0
Component: server Version: trunk
Keywords: ssl websockify Cc:


Split from #1136, see attachment/ticket/1136/web-ssl.patch.

Could be related to #1211, there's something fishy going on with non-blocking sockets (they're blocking).

Attachments (2)

websockify-ssl.patch (6.6 KB) - added by Antoine Martin 7 months ago.
attempts at passing an ssl socket to websockify after we have read from it
https.patch (9.1 KB) - added by Antoine Martin 7 months ago.
very hackish patch which sort of works for https but not for wss

Download all attachments as: .zip

Change History (9)

comment:1 Changed 9 months ago by Antoine Martin

Milestone: 0.181.0

Milestone renamed

comment:2 Changed 8 months ago by Antoine Martin

Status: newassigned

Worth revisiting now that #1252 is done.

Changed 7 months ago by Antoine Martin

Attachment: websockify-ssl.patch added

attempts at passing an ssl socket to websockify after we have read from it

comment:3 Changed 7 months ago by Antoine Martin

AFAICT, the big problem with SSL sockets (#1252) is that we cannot peek at the data:

ValueError: non-zero flags not allowed in calls to recv() on <class 'ssl.SSLSocket'>

That's unfortunate since openssl does have a:

/usr/include/openssl/ssl.h:int SSL_peek(SSL *ssl, void *buf, int num);

And pyOpenSSL does have support for it: Add support for SSL_peek.
But this is not exposed in the python ssl module, and we cannot access the underlying SSL object to use via ctypes.
So we cannot decide immediately if the SSL socket is being used by the client for xpra's protocol or for https / wss, we have to read some data from the socket by starting the IO protocol threads first.

If the SSL connection is for xpra's protocol, all is well and we just process it like normal socket data.
For https / wss traffic, we have to re-inject the data we've already written into the socket buffers somehow so that websockify and the python http server can process it.

Last edited 7 months ago by Antoine Martin (previous) (diff)

Changed 7 months ago by Antoine Martin

Attachment: https.patch added

very hackish patch which sort of works for https but not for wss

comment:4 Changed 7 months ago by Antoine Martin

Priority: majorblocker

Also a blocker for wss client support: ticket:1271#comment:4.

comment:5 Changed 7 months ago by Antoine Martin

Owner: changed from Antoine Martin to alas
Status: assignednew

Workaround in r13606: we look for the protocol string in the ssl header and wrap it again with websockify if we find "http/1.1".
r13610 + r13612 also makes it possible to specify what type of ssl traffic we want to handle, for the cases where the initial ssl header does not contain enough information to decide what to do with it, as is the case with the websocket client (#1271).

Examples based on the self signed CA from wiki/Encryption/SSL:
The server is started with (replace MODE):

xpra start --start=xterm --bind-tcp= \
    --ssl=on --ssl-cert=`pwd`/server.crt --ssl-key=`pwd`/server.key --ssl=MODE

Clients can then connect with:

Connection Example Command
ssl xpra attach ssl: --ssl-ca-cert=./ca.crt
tcp xpra attach tcp:
ws xpra attach ws:
wss xpra attach ws: --ssl-ca-cert=./ca.crt
http xdg-open
https xdg-open

(with the self signed CA, the browser will complain when opening with https unless you add the ca.crt to your list of certificates)

Results for each MODE:

  • auto: all work except for wss (as we cannot determine from the ssl header that the connection is websocket / https traffic)
  • tcp: only tcp and ssl connections can be used, for the other connection types the server shows an error, ie for ws: Error: tcp connection failed: invalid packet header, HTTP GET request
  • www: all work except for ssl (both the client and server log a large error message)

comment:6 Changed 6 months ago by alas

Owner: changed from alas to Antoine Martin

Tested with 1.0 r13673 win32 client against 1.0 r13742 fedora 23 server.

Installed a self-signed cert per instructions at wiki/Encryption/SSL, then grabbed the generated ca.crt to my client windows machine (and ran the wizard to install, just in case).

Server starts as expected with the command line specified there

 xpra --no-daemon --bind-tcp= --start-child=xterm --start-child=xterm --mdns=no --start-new-commands=yes --ssl=on --ssl-cert=/home/jimador/ticket-land/ticket1213/server.crt --ssl-key=/home/jimador/ticket-land/ticket1213/server.key start :13

... and the client errors as expected if not using --ssl-server-verify-mode=none when using the ssl:[IP]:[port]

xpra_cmd.exe attach ssl: --ssl-ca-cert=\Users\hassenpfeffer\Desktop\random-ticket-info-repository\ca.crt


  • Starting the server with MODE=auto or MODE=tcp, and connecting the client with the same --ssl-ca-cert= file path, however, works as expected.
xpra --no-daemon --bind-tcp= --start-child=xterm --start-child=xterm --mdns=no --start-new-commands=yes --ssl=on --ssl-cert=/home/jimador/ticket-land/ticket1213/server.crt --ssl-key=/home/jimador/ticket-land/ticket1213/server.key start :13 --ssl=tcp
xpra_cmd.exe attach tcp: --ssl-ca-cert=\Users\hassenpfeffer\Desktop\random-ticket-info-repository\ca.crt

As does using ssl:[IP]:[port] client side with the --ssl-server-verify-mode=none flag, though using the ssl:[IP]:[port] with the file path still errors out.

  • As you mentioned, with MODE=www I am able to connect with the tcp:[IP]:[port] with the cert file path, but the ssl:[IP]:[port] fails with a large error message even when trying to use the --ssl-server-verify-mode=none flag (and with the same behavior when trying to pass the cert path on the client).
  • Likewise, I was able to easily enough connect with http, though I think I bungled the signature as far as https in a browser is concerned (chrome might be mad that it was not generated as a sha-1 or sha-256 or something... I'll pursue a little more later).

Looks like everything's working as expected so far though. I'll pass back to you to take a look and see if there's anything else you need tested.

comment:7 Changed 6 months ago by Antoine Martin

Resolution: fixed
Status: newclosed

SSL closed at last. Thanks!

As for sha1, see https://security.googleblog.com/2014/09/gradually-sunsetting-sha-1.html - I believe this change should fix things (untested): wiki/Encryption/SSL.

Note: See TracTickets for help on using tickets.