xpra icon
Bug tracker and wiki

Opened 14 months ago

Closed 3 months ago

Last modified 3 weeks ago

#1252 closed enhancement (fixed)

native ssl support

Reported by: Antoine Martin Owned by: Antoine Martin
Priority: major Milestone: 1.0
Component: network Version: trunk
Keywords: Cc:

Description

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:

  • --ssl-cert=CERT
  • --ssl-key=KEY
  • --ssl-version=VERSION
  • --ssl-cert-reqs=REQS
  • --ssl-ca-certs=FILE
  • --ssl-ciphers=CIPHERS

Attachments (1)

ssl-v4.patch (20.2 KB) - added by Antoine Martin 13 months ago.
work in progress - ugly but working

Download all attachments as: .zip

Change History (18)

comment:1 Changed 14 months ago by Antoine Martin

Status: newassigned

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.

comment:2 Changed 14 months ago by Antoine Martin

Milestone: 0.181.0

Milestone renamed

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

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

Changed 13 months ago by Antoine Martin

Attachment: ssl-v4.patch added

work in progress - ugly but working

comment:3 Changed 13 months ago by Antoine Martin

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

  • generate a cert:
    openssl req -new -x509 -nodes -out cert.pem -keyout cert.pem
    
  • start a server with an ssl socket:
    xpra start --start=xterm --bind-ssl=0.0.0.0:10000 --ssl-cert=./cert.pem
    
  • start a client:
    xpra attach ssl:127.0.0.1:10000 --ssl-server-verify-mode=none
    

Still todo:

  • python < 2.7.9 compat (no ciphers argument)
  • xpras://.../ url handler
  • ssl=on flag and divert ssl traffic to ssl handler from tcp sockets (same as html=on for http)
Last edited 13 months ago by Antoine Martin (previous) (diff)

comment:4 Changed 13 months ago by 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=0.0.0.0:10000 --ssl-cert=`pwd`/cert.pem

Still todo:

  • url handler
  • testing on osx / win32, centos6 (python 2.6)
  • testing with valid certs and ca chain
  • man page and wiki updates
  • use SSLContext to force compression off, etc..
Last edited 12 months ago by Antoine Martin (previous) (diff)

comment:5 Changed 13 months ago by Antoine Martin

  • minor rpm packaging fix r13105
  • url handler and packaging updates added in r13106 (tested on Fedora and win32)
  • tested ssl/username:password@HOST:PORT client connection string from win32 and osx
  • man page updates in r13112
  • wiki updated: wiki/Encryption

Still todo:

  • sslcontext and handling for extra options
Last edited 13 months ago by Antoine Martin (previous) (diff)

comment:6 Changed 13 months ago by Antoine Martin

Owner: changed from Antoine Martin to alas
Status: assignednew

sslcontext done in r13114.

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

Still todo:

  • win32 / osx and certification authorities: do we ship the ca cert file?
  • better debug logging?
  • auto-upgrade for clients (specify tcp but get ssl if server supports it)
Last edited 13 months ago by Antoine Martin (previous) (diff)

comment:7 Changed 13 months ago by 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=0.0.0.0:10000
cat > stunnel.conf <<EOF
[xpra]
accept = 10001
connect = 10000
cert = cert.pem
verify = 0
EOF

You can then connect to the SSL server on port 10001 using the connection string ssl:127.0.0.1:10001
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.

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

comment:8 Changed 13 months ago by Antoine Martin

  • more minor updates: r13285 + r13286 allow us to handle cadata using strings
  • r13288 does the same thing for the legacy python ssl module
  • r13287 makes it easier to test the legacy interface: XPRA_USE_SSL_CONTEXT=0 xpra attach ....
  • r13294 + r13295 fix some ssl bugs in the launcher

See wiki/Encryption/SSL.

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

comment:9 Changed 12 months ago by 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.

comment:10 Changed 12 months ago by Antoine Martin

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

comment:11 Changed 3 months ago by 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=0.0.0.0:1234 --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=0.0.0.0:1234' '--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:
http://blog.endpoint.com/2014/10/openssl-csr-with-alternative-names-one.html ... but to no avail (well, I was able to generate a .csr that had the subjectAltName, but never quite figured out how to then sign using -extfile {filename} appending along the lines of 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?

comment:12 Changed 3 months ago by 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
[req]
default_bits = 2048
prompt = no
default_md = sha256
distinguished_name = dn
 
[ dn ]
C=US
O=End Point
OU=Testing Domain
CN = localhost
EOF

openssl req -new -x509 -nodes -out cert.pem -keyout cert.pem -config ./cert-params.conf 
xpra start --start=xterm --bind-ssl=0.0.0.0:10000 --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.

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

comment:13 Changed 3 months ago by 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.

comment:14 Changed 3 months ago by 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.

  • Launching with
    xpra --no-daemon --bind-ssl=0.0.0.0:1234 --ssl-cert=/home/jimador/cert/jimador.pem --ssl=off --start-child=xterm  start :13
    

... and then trying to connect with
./xpra attach tcp:10.0.32.138:1234 -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:10.0.32.138:1234 -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.

comment:15 Changed 3 months ago by alas

Owner: changed from alas to Antoine Martin

comment:16 Changed 3 months ago by Antoine Martin

Resolution: fixed
Status: newclosed

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:

--ssl=on|auto|off|tcp|www
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.

comment:17 Changed 3 weeks ago by Antoine Martin

See also #1213, #1504

Note: See TracTickets for help on using tickets.