Xpra: Ticket #1252: native ssl support

The python ssl module makes it trivial to wrap tcp sockets.

As part of fixing websockify + ssl (#1213), it would be nice to re-use the same code for supporting SSL natively in our TCP sockets and the websockify code.

Something like:

xpra start --bind-ssl=IP:PORT

And client side:

xpra attach ssl:HOST:PORT

Other arguments we will need for configuring SSL, mirroring websockify and the ssl module but with a "ssl" prefix:

Tue, 12 Jul 2016 16:50:09 GMT - Antoine Martin: status changed

Or maybe we can support ssl on all tcp server sockets with a --ssl=on switch in the same way that we support websockets for --html=on.

Tue, 12 Jul 2016 16:52:22 GMT - Antoine Martin: milestone changed

Milestone renamed

See also: #1255 for smartcard integration which is possible in openssl.

Sat, 23 Jul 2016 22:44:20 GMT - Antoine Martin: attachment set

work in progress - ugly but working

Sat, 23 Jul 2016 22:48:58 GMT - Antoine Martin:

The patch above needs work and testing, but kinda works.

Still todo:

Wed, 27 Jul 2016 15:35:26 GMT - Antoine Martin:

Mostly done in r13100 + r13101, this includes the ssl flag (defaults to "auto") for multiplexing ssl traffic through the same tcp socket. So this is now enough to start a server with both TCP and SSL support on the same port:

xpra start --start=xterm --bind-tcp= --ssl-cert=`pwd`/cert.pem

Still todo:

Thu, 28 Jul 2016 09:34:27 GMT - Antoine Martin:

Still todo:

Thu, 28 Jul 2016 17:00:09 GMT - Antoine Martin: owner, status changed

sslcontext done in r13114.

That's enough for a first round of testing and feedback.

Still todo:

Mon, 01 Aug 2016 17:08:03 GMT - Antoine Martin:

Some more minor tweaks: r13151, r13152, r13155, r13156, r13157, r13160.

Tested the latest beta on centos 6.x and 7.x, without problems. But on centos6, you need one more thing configured to workaround the limitations of the old / narrower API: unless the client provides a certificate, add --ssl-client-verify=none to prevent the server from trying to load the CA certs used to validate the client connection (and failing).

Some notes on interoperability with stunnel. You can easily wrap a regular TCP server with stunnel:

xpra start --start=xterm --bind-tcp=
cat > stunnel.conf <<EOF
accept = 10001
connect = 10000
cert = cert.pem
verify = 0

You can then connect to the SSL server on port 10001 using the connection string ssl: Or you could start another stunnel instance at the client end, and connect to that via TCP.

The SSL wiki page has been moved here: wiki/Encryption/SSL.

Tue, 09 Aug 2016 14:14:16 GMT - Antoine Martin:

See wiki/Encryption/SSL.

Mon, 05 Sep 2016 04:53:27 GMT - Antoine Martin:

r13544 allows us to use "xor" authentication mode with ssl connections, so now we can also use the "sys" authentication modules (pam / win32) with ssl.

Thu, 08 Sep 2016 08:35:59 GMT - Antoine Martin:

The "ssl" config option can now contain the following values: "on", "off", "auto", "tcp", "www". See ticket:1213#comment:5.

Sat, 03 Jun 2017 00:17:28 GMT - alas:

Hmm, trying with a self-signed cert as mentioned above, with a 1.0.7 r16004 fedora 25 server, I keep getting an SSL socket create error.

[jimador@Fedora25-Server-415 ~]$ xpra --no-daemon --bind-tcp= --ssl-cert=/home/jimador/cert/jimador.pem --ssl=on --start-child=xterm  start :13
using systemd-run to wrap 'start' server command
'systemd-run' '--description' 'xpra-start' '--scope' '--user' '/usr/bin/xpra' '--bind-tcp=' '--ssl-cert=/home/jimador/cert/jimador.pem' '--ssl=on' '--start-child=xterm' 'start' ':13' '--daemon=no' '--systemd-run=no'
Running scope as unit: run-r31c9b2bc84104066ab6bf45382d4e6f9.scope
xpra initialization error:
 cannot create SSL socket (check your certificate paths): [SSL] PEM lib (_ssl.c:2718)

The absolute path is correct though.

[jimador@Fedora25-Server-415 ~]$ ls /home/jimador/cert/
csr-maker  jimador.key  jimador.pem  simple-jimador

I'm getting the same error even when the absolute path is wrong, however, so I feel like maybe there's a detail I overlooked in enabling the ssl on this VM?

I dnf installed mod_ssl openssl, and restarted /bin/systemctl httpd.service, but saw no sign of anything else that looked required.

Thinking that the above method of generating certs might be the issue, since I took so long to find time to test this and as of Chrome 58 subjectAltName is required for the browser to deem a cert as secure (I'm having the problems just launching, so it seemed unlikely, but just in case) I also tried a number of experiments along the lines of the following: https://serverfault.com/questions/707458/self-signed-cert-with-subject-alternative-names).

Is there something I'm missing in the fedora 25 to enable the handling of ssl?

Sat, 03 Jun 2017 09:45:15 GMT - Antoine Martin:

I dnf installed mod_ssl openssl, and restarted /bin/systemctl httpd.service, but saw no sign of anything else that looked required.

We don't use apache or mod ssl at all.

I followed the steps in comment:3 and it worked fine. Tested with both 1.0 branch and trunk.

Here it is again, fully scripted:

cat > cert-params.conf <<EOF
default_bits = 2048
prompt = no
default_md = sha256
distinguished_name = dn
[ dn ]
O=End Point
OU=Testing Domain
CN = localhost
openssl req -new -x509 -nodes -out cert.pem -keyout cert.pem -config ./cert-params.conf
xpra start --start=xterm --bind-ssl= --ssl-cert=./cert.pem --no-daemon

(PS: ssl does support relative paths - I had fixed that already)

Note: if you want to connect with a browser rather than the client in ssl mode, see comment:10.

Tue, 06 Jun 2017 23:41:12 GMT - alas:

The cert-params.cnf that I generated using your example still shows no sujectAltName in the cert that is generated, but I just gave up and re-installed chrome 57.

As long as I read the instructions and use --ssl=www, rather than =on, that worked with the html5 client (against the same 1.0.7 r16004 fedora 25 server).

Likewise, as long as I use the --ssl-server-verify-mode=none parameter with the 1.0.2 r14780 windows client, the client connects with --ssl=on (attempts to import the .pem created with your instructions fail with windows 7, it insists that 'This file is invalid for use as the following: Security Certificate', but I was able to import it with a 10.12 OSX client to go with the chrome 57 connection).

At this point I suspect that the issues I'm seeing are more related to my lack of knowledge of the fine points of cert generation/installation rather than with the xpra use of the certs... so I think this can probably be closed and new tickets opened for any issues that come up.

Thu, 08 Jun 2017 22:35:30 GMT - alas:

Since I seem to have forgotten to re-assign this back to you to close, I figured I'd try some of the less obvious combinations you'd listed before correcting that oversight.

... and then trying to connect with ./xpra attach tcp: -d auth

The client fails to connect with the following message:

2017-06-08 15:00:29,775 Error: failed to receive anything, not an xpra server?
2017-06-08 15:00:29,775   could also be the wrong protocol, username, password or port
2017-06-08 15:00:29,775 Connection lost

... and trying to connect instead with ./xpra attach ssl: -d auth, I get a cert error - connection failed: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:661).

This isn't really very surprising, but it does make me wonder what the --ssl=off flag is meant to do? (Maybe just a warning about bind-ssl use in conjunction with --ssl=off?).

Seeing the same behavior with bind-ssl and ssl=tcp, just in case that strange combination ought to be accounted for.

And, as one last interesting note - it looks like the bind-tcp with --ssl=www works for both the client and the html client (to my mild surprise, that was the only combination that allowed me, with the client, to connect without using the --ssl-server-verify-mode=none client-side flag).

And, with those last details, I'll pass this back to you to (probably) close.

Thu, 08 Jun 2017 22:36:05 GMT - alas: owner changed

Fri, 09 Jun 2017 20:58:07 GMT - Antoine Martin: status changed; resolution set

This isn't really very surprising, but it does make me wonder what the --ssl=off flag is meant to do?

The ssl flag is fully documented in the man page:

Whether to enable SSL on TCP sockets and for what purpose.  The TCP sockets will automatically be upgraded to SSL when SSL packets are received.
* auto: The server will try to guess what protocol to use for each new SSL connection: either xpra's native protocol or https / websocket (wss)
* tcp: The SSL sockets will only be used for xpra's native protocol
* www: The SSL sockets will only be used for https and websocket (wss)

it looks like the bind-tcp with --ssl=www works for both the client and the html client (to my mild surprise, that was the only combination that allowed me, with the client, to connect without using the --ssl-server-verify-mode=none client-side flag

Then my guess is that you connected with a plain tcp client connection string, not an ssl one.

Thu, 03 Aug 2017 10:14:44 GMT - Antoine Martin:

See also #1213, #1504

Thu, 23 Aug 2018 13:27:42 GMT - Antoine Martin:

Addendum: wiki/Encryption/SSL has been updated, here's the simplest way of using SSL safely without a CA:

OR convert this cert data into a string and use that:

CADATA=`python -c "import sys,base64;print(base64.b64encode(open(sys.argv[1]).read()))" cert.pem`
xpra attach ssl://server:10000 --ssl-ca-data=$CADATA -d ssl

This option is much more useful for using SSL with xpra URLs (#1894) or .xpra connection files.

We now generate split cert and key: r20177.

Sat, 23 Jan 2021 05:19:10 GMT - migration script:

this ticket has been moved to: https://github.com/Xpra-org/xpra/issues/1252