Python requests and Nginx SSL problems

I recently updated my SSL certificates to SHA-2. At the same time I also updated my Nginx SSL settings and configurations. A lot of useful best practices and recommendation is located at the Mozilla wiki.

One of the settings for Nginx is ssl_protocols. I choose the Non-Backward Compatible Ciphersuite at the wiki where they recommend using TLSv1.1, TLSv1.2 as ssl_protocols. This is all fine when you use a modern browser but this setting caused problem with a couple of Python scripts I've got who uses the request library to connect to my Nginx server. After my Nginx settings changes I started to get failed requests with the following Python error

SSLError: [Errno 8] _ssl.c:504: EOF occurred in violation of protocol

and also

requests.exceptions.SSLError: [Errno 8] _ssl.c:507: EOF occurred in violation of protocol

After a bit of digging around I found out that this seems to be a problem with Python 2 not using TLS correctly.

Python 2.x tries to establish a connection with PROTOCOL_SSLv23 by default.

According to it looks like you can monkey path this problem and tell Python to use TLS instead of SSLv23.

Since I've got quite a few places to patch and fix I went with the solution to add SSLv3 to my Nginx configuration instead. This solves the problem and let's my script connect with SSLv3. I guess this is an okay tradeoff since the browser will choose the best available protocol. Since I use the following settings it should be fine to leave SSLv3 active for now.

ssl_protocols       SSLv3 TLSv1 TLSv1.1 TLSv1.2;

One more problem I encountered was that my Nginx settings for ssl_protocols never seemed to change no matter what I changed them to. I've to my Nginx setup using multiple files/vhosts with server {} sections. When I changed my settings in the correct vhost file nothing changed after Nginx was restarted. It turned out that I had to change these settings on the default vhost. When I did and restarted Nginx again the settings changed correctly for my other vhosts as well.

This OpenSSL command was really useful when debugging SSL connections

openssl s_client -connect HOST:443

This shows a lot of useful information about the connection and what protocols and ciphers are used.