I ran into an interesting problem while recently checking over my blog. I noticed that the RSS feed from the discussion forums was failing to load in the HTML footer of my blog. It was returning the error “RSS Error: WP HTTP ERROR: SSL connect error”. So I started digging into trying to figure out what had broken.
I quickly found that cURL was having issues connecting to https://forums.networkinfrastructure.info without any parameters;
[root@mars certs]# curl -v https://forums.networkinfrastructure.info/.xml/?type=rss * About to connect() to forums.networkinfrastructure.info port 443 (#0) * Trying 126.96.36.199... connected * Connected to forums.networkinfrastructure.info (188.8.131.52) port 443 (#0) * Initializing NSS with certpath: sql:/etc/pki/nssdb * CAfile: /etc/pki/tls/certs/ca-bundle.crt CApath: none * NSS error -5961 * Closing connection #0 * SSL connect error curl: (35) SSL connect error
Initially I thought I had a certificate issue, concerned that either the GEO Trust root certificate and/or intermediate RapidSSL SHA256 certificate might be missing from /etc/pki/tls/certs/ca-bundle.crt but I was able to quickly rule that problem out using the -k flag on cURL. I noticed that if I tell cURL to use TLS 1.2 then it can connect without issue;
[root@mars certs]# curl -v --tlsv1.2 https://forums.networkinfrastructure.info/.xml/?type=rss * About to connect() to forums.networkinfrastructure.info port 443 (#0) * Trying 184.108.40.206... connected * Connected to forums.networkinfrastructure.info (220.127.116.11) port 443 (#0) * Initializing NSS with certpath: sql:/etc/pki/nssdb * CAfile: /etc/pki/tls/certs/ca-bundle.crt CApath: none * SSL connection using TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 * Server certificate: * subject: CN=forums.networkinfrastructure.info,OU=Domain Control Validated - RapidSSL(R),OU=See www.rapidssl.com/resources/cps (c)14,OU=GT54191003 * start date: Jul 16 16:20:24 2015 GMT * expire date: Nov 26 12:10:44 2016 GMT * common name: forums.networkinfrastructure.info * issuer: CN=RapidSSL SHA256 CA - G3,O=GeoTrust Inc.,C=US > GET /.xml/?type=rss HTTP/1.1 > User-Agent: curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.19.1 Basic ECC zlib/1.2.3 libidn/1.18 libssh2/1.4.2 > Host: forums.networkinfrastructure.info > Accept: */* > < HTTP/1.1 200 OK < Server: nginx/1.0.15 < Date: Sat, 26 Dec 2015 14:23:13 GMT < Content-Type: application/rss+xml; charset=ISO-8859-1 < Transfer-Encoding: chunked < Connection: keep-alive < X-Powered-By: PHP/5.3.3 < X-Frame-Options: SAMEORIGIN < X-XSS-Protection: 1 < X-Content-Type-Options: nosniff < Set-Cookie: PHPSESSID=tfvh4sti8ks08l6n6o61sd46n5; path=/ < Expires: Thu, 19 Nov 1981 08:52:00 GMT < Pragma: no-cache < Cache-Control: private < Network Infrastructure Forums https://forums.networkinfrastructure.info/index.php ... ...
So there’s some issue with cURL negotiating between SSLv3, TLS 1.0, TLS 1.1 and TLS 1.2. I turned to Google and found way to many bug reports and issues with how cURL tries to negotiate the transport layer security protocol. There’s a lengthy discussion regarding bug 1170339 concerning cURL’s default behavior on a RedHat/CentOS client and covers the exact scenario I’m experiencing.
I decided to turn my attention to the server configuration, perhaps I could find a quick fix in the server configuration, because a client fix might work for this specific client but would still be present for anyone else on the Internet using the same client software.
Here’s what my ngnix configuration looks like on the server side;
#SSL ssl_certificate /etc/ssl/certs/bundle-forums.networkinfrastructure.info.sha256.crt; ssl_certificate_key /etc/ssl/certs/private.key; ssl_session_timeout 5m; ssl_protocols TLSv1.1 TLSv1.2; ssl_ciphers ALL:!EXPORT:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv3:+EXP; ssl_prefer_server_ciphers on;
I recall recently removing TLS 1.0 support from the Nginx configuration file so I’m guessing I broke it myself (funny how that’s usually the case).
I went back and did some additional research around best practices for SSL protocols and ciphers and modified my Nginx configuration file with the following settings;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_ciphers EECDH+AESGCM:EDH+AESGCM:ECDHE-RSA-AES128-GCM-SHA256:AES256+EECDH:DHE-RSA-AES128-GCM-S HA256:AES256+EDH:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-R SA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256 :DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES256-GCM-SHA384:A ES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!EX PORT:!DES:!MD5:!PSK:!RC4;
I restarted Nginx and then ran a quick test from Qualys SSL Labs to validate the changes and found that I needed to make an additional config tweak to close a Diffie-Hellman issue. With that complete I the server was now scoring an A from the Qualys SSL Lab testing and it was answering TLS 1.0 requests from cURL.
Another 5 minute problem closed 2+ hours later.