[Twisted-Python] SSL problem
![](https://secure.gravatar.com/avatar/3c4988f83703127d279406fc6eea7079.jpg?s=120&d=mm&r=g)
Hi all. I'm having trouble getting SSL working properly. I'm running a modified t.m.pop3.POP3 server and it was running peachy on port 110, no problems under real-world load, so I thought it'd be simple enough to add SSL support by changing this... INTERFACES = ('1.2.3.4','4.5.6.7', etc.) for iface in INTERFACES: reactor.listenTCP(110, myPop3server, interface=iface) reactor.run() ...to this: INTERFACES = ('1.2.3.4','4.5.6.7', etc.) sslContext = ssl.DefaultOpenSSLContextFactory(SSL_PRIVATE_KEY_FILE, SSL_CERTIFICATE_FILE) for iface in INTERFACES: reactor.listenTCP(110, myPop3server, interface=iface) reactor.listenSSL(995, myPop3server, interface=iface, contextFactory=sslContext) reactor.run() Which worked fine when hitting it with a single client from my machine, but failed miserably when hitting it from mail2web.com. Lots of errors loading the message list and the messages. The log showed mail2web connecting and then immediately dropping the connection. I tried changing the code so I instantiated one sslContext per call to listenSSL. That made it much better, but still not perfect. The errors persisted. So I tried dropping the calls to listenSSL, and wrapped the server with stunnel. That worked perfectly, except since my host doesn't support transparent proxying, my twisted app doesn't see the connecting client's IP, and I need that, so that's not an option. It does implicate twisted's particular flavor of SSL in my problems, though. I don't know much about SSL, but I searched the twisted list and couldn't find anything that helped, with the possible exception of a query about support for SSL session resumption. I don't know what it is, but it sounds useful. Anyway, if anybody could toss an idea or two my way, I'd appreciate it. Thanks, Steve P.S. for posterity: I got a tip from this list to use authbind when trying to bind my twisted server to a privileged port (e.g. < 1024). For those of you who might have trouble using authbind to allow your non-root user to bind to ports between 512-1023, you need to get the authbind source, then comment out helper.c:76 and libauthbind.c:151, at least for version 1.1.5.2, where it checks the requested port against IPPORT_RESERVED/2. The man page squawks about prohibiting these ports to avoid creating a security hole in conjunction with rsh, but since rsh _is_ a security hole, I'm not overly worried about that.
![](https://secure.gravatar.com/avatar/7ed9784cbb1ba1ef75454034b3a8e6a1.jpg?s=120&d=mm&r=g)
On Thu, 21 Dec 2006 00:49:44 -0600, Steve Freitas <sflist@ihonk.com> wrote:
Hi all.
I'm having trouble getting SSL working properly. I'm running a modified t.m.pop3.POP3 server and it was running peachy on port 110, no problems under real-world load, so I thought it'd be simple enough to add SSL support by changing this...
INTERFACES = ('1.2.3.4','4.5.6.7', etc.)
for iface in INTERFACES: reactor.listenTCP(110, myPop3server, interface=iface) reactor.run()
...to this:
INTERFACES = ('1.2.3.4','4.5.6.7', etc.)
sslContext = ssl.DefaultOpenSSLContextFactory(SSL_PRIVATE_KEY_FILE, SSL_CERTIFICATE_FILE)
for iface in INTERFACES: reactor.listenTCP(110, myPop3server, interface=iface) reactor.listenSSL(995, myPop3server, interface=iface, contextFactory=sslContext) reactor.run()
Which worked fine when hitting it with a single client from my machine, but failed miserably when hitting it from mail2web.com. Lots of errors loading the message list and the messages. The log showed mail2web connecting and then immediately dropping the connection. I tried changing the code so I instantiated one sslContext per call to listenSSL. That made it much better, but still not perfect. The errors persisted.
So I tried dropping the calls to listenSSL, and wrapped the server with stunnel. That worked perfectly, except since my host doesn't support transparent proxying, my twisted app doesn't see the connecting client's IP, and I need that, so that's not an option. It does implicate twisted's particular flavor of SSL in my problems, though.
I don't know much about SSL, but I searched the twisted list and couldn't find anything that helped, with the possible exception of a query about support for SSL session resumption. I don't know what it is, but it sounds useful. Anyway, if anybody could toss an idea or two my way, I'd appreciate it.
It's pretty difficult to say what the problem is without knowing the specific error which is occurring, or having a complete example which can reproduce it. I'd _guess_ your context object isn't configured quite right. If you can post a complete example which reproduces the problem, it would be much easier to diagnose. At the very least, you should share the SSL errors which are occurring. Jean-Paul
![](https://secure.gravatar.com/avatar/3c4988f83703127d279406fc6eea7079.jpg?s=120&d=mm&r=g)
Thanks for the response, JP. On Thu, 2006-12-21 at 09:54 -0500, Jean-Paul Calderone wrote:
It's pretty difficult to say what the problem is without knowing the specific error which is occurring, or having a complete example which can reproduce it.
Yeah, I understand that. I'm not sure where to go to get the errors, though. I was trying to avoid putting up a complete example, because it would be pretty involved, but I'll go that route if trying to dig up the errors doesn't yield anything.
I'd _guess_ your context object isn't configured quite right.
IOW, there's something wrong with the key/cert I'm feeding it? Calling ssl.DefaultOpenSSLContextFactory(SSL_PRIVATE_KEY_FILE,
SSL_CERTIFICATE_FILE) is so simple I'm not sure where I'd be going wrong. BTW, the cert was provided by RapidSSL, and it's what I used with stunnel as well.
At the very least, you should share the SSL errors which are occurring.
How do I get at these? I didn't see any tracebacks being tossed. I'm using 2.4.0. Steve
![](https://secure.gravatar.com/avatar/7ed9784cbb1ba1ef75454034b3a8e6a1.jpg?s=120&d=mm&r=g)
On Thu, 21 Dec 2006 09:32:22 -0600, Steve Freitas <sflist@ihonk.com> wrote:
Thanks for the response, JP.
On Thu, 2006-12-21 at 09:54 -0500, Jean-Paul Calderone wrote:
[snip]
I'd _guess_ your context object isn't configured quite right.
IOW, there's something wrong with the key/cert I'm feeding it? Calling ssl.DefaultOpenSSLContextFactory(SSL_PRIVATE_KEY_FILE,
SSL_CERTIFICATE_FILE) is so simple I'm not sure where I'd be going wrong. BTW, the cert was provided by RapidSSL, and it's what I used with stunnel as well.
It's possible (in fact, likely) you need to do something other than just create the DefaultOpenSSLContextFactory, too. There are a lot of dials and knobs here - the context factory you're using works okay for a lot of cases, but it isn't appropriate for all cases. You have two pieces of data which are yours - your private key and your certificate (which is a csr signed by RapidSSL). The client needs (at least) one more piece of information, though - RapidSSL's certificate. Try this. Put RapidSSL's certificate into a file, subclass DefaultOpenSSLContextFactory, override cacheContext, and on self._context, call use_certificate_chain_file with the name of the file you put RapidSSL's certificate into. This causes the server to include it in the handshake which is often required for clients to accept your certificate as valid.
At the very least, you should share the SSL errors which are occurring.
How do I get at these? I didn't see any tracebacks being tossed. I'm using 2.4.0.
At some point, I think connectionLost for SSL connections was adjusted so that the SSL exception would be available. However, the important information is going to be on the client side, so unless that is using Twisted as well (it sounds to me as though it is not), this won't help you. How to extract the extra information will depend on what software is acting as the client. Hopefully the above suggestion will resolve the problem, though. Jean-Paul
![](https://secure.gravatar.com/avatar/3c4988f83703127d279406fc6eea7079.jpg?s=120&d=mm&r=g)
Thanks JP. On Thu, 2006-12-21 at 11:04 -0500, Jean-Paul Calderone wrote:
You have two pieces of data which are yours - your private key and your certificate (which is a csr signed by RapidSSL). The client needs (at least) one more piece of information, though - RapidSSL's certificate.
I found it here: http://www.rapidssl.com/cps/rapidssl_01.cer At least, I believe that's right, since despite some looking around, I'm not sure how to verify by hand that my cert was signed by that CA. (I played with openssl verify but it gave the OK to my cert without pointing it at RapidSSL's root cert file, so I don't know that it's doing what I want.) I've attached my cert in case you're interested.
Try this. Put RapidSSL's certificate into a file, subclass DefaultOpenSSLContextFactory, override cacheContext, and on self._context, call use_certificate_chain_file with the name of the file you put RapidSSL's certificate into.
This causes the server to include it in the handshake which is often required for clients to accept your certificate as valid.
Okay, I tried that... class MyOpenSSLContextFactory(ssl.DefaultOpenSSLContextFactory): def cacheContext(self): ssl.DefaultOpenSSLContextFactory.cacheContext(self) self._context.use_certificate_chain_file(CA_CERT_FILE) ...and nothing at all would connect to it. But read on...
At some point, I think connectionLost for SSL connections was adjusted so that the SSL exception would be available. However, the important information is going to be on the client side <snip>
So based on this information, I whipped up a Twisted SSL client to hit it so see what's wrong, and it tossed this out: 2006/12/21 20:36 CST [POP3Client,client] Traceback (most recent call last): Failure: OpenSSL.SSL.Error: [('SSL routines', 'SSL3_READ_BYTES', 'sslv3 alert handshake failure'), ('SSL routines', 'SSL3_WRITE_BYTES', 'ssl handshake failure')] Not sure if that's informative enough to suggest a next step! Thanks for your help, Steve
![](https://secure.gravatar.com/avatar/3c4988f83703127d279406fc6eea7079.jpg?s=120&d=mm&r=g)
On Thu, 2006-12-21 at 20:55 -0600, Steve Freitas wrote:
At least, I believe that's right, since despite some looking around, I'm not sure how to verify by hand that my cert was signed by that CA. (I played with openssl verify but it gave the OK to my cert without pointing it at RapidSSL's root cert file, so I don't know that it's doing what I want.) I've attached my cert in case you're interested.
Never mind, I verified that was the correct root cert file, so now I'm back to wondering why chaining them didn't seem to work... Steve
![](https://secure.gravatar.com/avatar/d7875f8cfd8ba9262bfff2bf6f6f9b35.jpg?s=120&d=mm&r=g)
On Thu, 2006-12-21 at 09:32 -0600, Steve Freitas wrote:
IOW, there's something wrong with the key/cert I'm feeding it? Calling ssl.DefaultOpenSSLContextFactory(SSL_PRIVATE_KEY_FILE,
SSL_CERTIFICATE_FILE) is so simple I'm not sure where I'd be going wrong. BTW, the cert was provided by RapidSSL, and it's what I used with stunnel as well.
Perhaps you want TLSv1 instead of SSLv3?
![](https://secure.gravatar.com/avatar/3c4988f83703127d279406fc6eea7079.jpg?s=120&d=mm&r=g)
On Thu, 2006-12-21 at 12:47 -0500, Itamar Shtull-Trauring wrote:
On Thu, 2006-12-21 at 09:32 -0600, Steve Freitas wrote:
IOW, there's something wrong with the key/cert I'm feeding it? Calling ssl.DefaultOpenSSLContextFactory(SSL_PRIVATE_KEY_FILE,
SSL_CERTIFICATE_FILE) is so simple I'm not sure where I'd be going wrong. BTW, the cert was provided by RapidSSL, and it's what I used with stunnel as well.
Perhaps you want TLSv1 instead of SSLv3?
Thanks for the reply, Itamar. Gave it a try, and I don't think so -- mail2web simply wouldn't deal with it at all. Of course, all I did was pass in a third argument to DefaultOpenSSLContextFactory, SSL.TLSv1_METHOD. Should I have done any more than that? In the meantime, I'm gonna give JP's suggestions a try. Thanks, JP. Steve
participants (3)
-
Itamar Shtull-Trauring
-
Jean-Paul Calderone
-
Steve Freitas