Using ssl.wrap_socket() in chroot jail

G

Grant Edwards

Let's say you have a server/daemon application written in python that
accepts incoming SSL connections.

You want to run that application in a chroot jail.

The last thing you want in that jail is your SSL certificate private
key file.

But, it appears the ssl module won't accept SSL certificates and keys
as data strings, or as stringio file objects. It will only accept a
filename, and it has to open/read that file every time a connection is
accepted.

So how do you avoid having your certificate key file sitting, readable,
in the chroot jail?
 
C

Chris Angelico

But, it appears the ssl module won't accept SSL certificates and keys
as data strings, or as stringio file objects. It will only accept a
filename, and it has to open/read that file every time a connection is
accepted.

So how do you avoid having your certificate key file sitting, readable,
in the chroot jail?

I was going to say "if all else fails, monkey-patch", but the source
code shows that the Python ssl module just passes the file name
straight on to _ssl... and, what's more, that _ssl.c just passes it
right along to SSL_CTX_use_PrivateKey_file which I presume is part of
OpenSSL.

Is it possible for you to initialize an SSLContext before chrooting,
and just hold that in memory? You can then use its wrap_socket instead
of the default wrap_socket. According to the docstring for SSLContext,
it can hold "... possibly a private key", but I don't see a parameter
for that; that's probably just indicative of my lack of experience
with Python's ssl module, though.

If you invoke Python entirely within the chroot jail, though, I don't
know of a way around it.

ChrisA
 
G

Grant Edwards

Let's say you have a server/daemon application written in python that
accepts incoming SSL connections.

You want to run that application in a chroot jail.

The last thing you want in that jail is your SSL certificate private
key file.
[...]

Python's SSL module can't load private key from memory. I wanted to
implement that feature for 3.4 but the feature wasn't ready by then.
You have multiple options:

* create a SSLContext, then chroot()
* use pyOpenSSL / cryptography als TLS library
* don't do SSL in your daemon and let some proxy or load balancer do TLS
offloading, e.g. NGinx or Apache + mod_proxy

Unfortunately, the actual SSL wrapping stuff isn't being done in my
code. It's being done by the secure-smtpd module, which will pass
whatever cert/key params I give it to ssl.wrap_socket(). That still
leaves the third option (e.g. stunnel).

Thanks.
 
C

Chris Angelico

Unfortunately, the actual SSL wrapping stuff isn't being done in my
code. It's being done by the secure-smtpd module, which will pass
whatever cert/key params I give it to ssl.wrap_socket(). That still
leaves the third option (e.g. stunnel).

I'll go back to the naughty-crazy idea of monkey-patching, then: can
you create an SSLContext prior to chrooting, then stuff its
wrap_socket back into the ssl module?

ChrisA
 
G

Grant Edwards

I'll go back to the naughty-crazy idea of monkey-patching, then: can
you create an SSLContext prior to chrooting, then stuff its
wrap_socket back into the ssl module?

Probably. I'll have to give that a try after I figure out some of the
other "Unix daemon" issues. Any imports that happen after chroot()ing
are going to fail (I think), and I'm not sure if that's going to be a
problem or not...
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,995
Messages
2,570,230
Members
46,819
Latest member
masterdaster

Latest Threads

Top