Connecting to HTTPS using openssl
Sometimes I’ve found myself in the need of checking a website that works under HTTPS but didn’t want to use a browser for whatever reason. In those cases tools like telnet or httpie do not work, as they are unable to handle the underlying SSL protocol. We can use openssl in those cases in order to establish a connection à la telnet.
Say we have a Django project running on a Ubuntu Server. The server is using Nginx in order to reverse proxy requests to GUnicorn which is passing those requests to Django. Adding to that, Nginx is also the SSL terminating point, meaning it holds the certificate in order to establish a secure connection between the client and the server, and it redirects all
http requests to their
We’re good to go! Let’s see what happens if we use httpie to get an static asset from the server:
vagrant@trust-prod-ubuntu-1404-lts:~$ http http://localhost/static/css/test.txt HTTP/1.1 301 Moved Permanently Connection: keep-alive Content-Length: 184 Content-Type: text/html Date: Tue, 02 Aug 2016 10:51:50 GMT Location: https://localhost/static/css/test.txt Server: nginx/1.6.3 <html> <head><title>301 Moved Permanently</title></head> <body bgcolor="white"> <center><h1>301 Moved Permanently</h1></center> <hr><center>nginx/1.6.3</center> </body> </html>
As we can see Django response is a
301 Moved Permanently. So let’s try to get this resource with httpie:
vagrant@trust-prod-ubuntu-1404-lts:~$ http https://localhost/static/css/test.txt http: error: SSLError: [Errno 1] _ssl.c:510: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed
Oops! Doesn’t look like it worked!
And here it is when openssl comes to the rescue. Establishing a secure connection using openssl works a lot like using telnet. Let’s have a look at how to do it:
vagrant@trust-prod-ubuntu-1404-lts:~$ openssl s_client -connect localhost:443 ... Lots of stuff about the https certificate ... --- GET /static/css/test.txt HTTP/1.1 Host: localhost HTTP/1.1 200 OK Server: nginx/1.6.3 Date: Tue, 02 Aug 2016 10:57:17 GMT Content-Type: text/plain; charset=utf-8 Content-Length: 29 Last-Modified: Tue, 02 Aug 2016 10:51:15 GMT Connection: keep-alive ETag: "57a07b23-1d" Expires: Wed, 03 Aug 2016 10:57:17 GMT Cache-Control: max-age=86400 Pragma: public Cache-Control: public Accept-Ranges: bytes Hello! I am an static asset!
And here it is! We have been able to establish a secure communication channel with the server and get a resource.
I find that kind of things useful in order to test/debug certain aspects of web applications where I need to watch out for headers and more low-level stuff than the one you usually get from a web browser.
There are other reasons to do so. For example, wanna know if your server is vulnerable to POODLE? Long story short, POODLE leverages a flaw in the SSLv3 implementation so a malicious attacker could see in ‘plain text’ things that should be encrypted. Let’s check it out!
vagrant@trust-prod-ubuntu-1404-lts:~$ openssl s_client -connect localhost:443 -ssl3 ... 140659731752608:error:14094410:SSL routines:SSL3_READ_BYTES:sslv3 alert handshake failure:s3_pkt.c:1262:SSL alert number 40 140659731752608:error:1409E0E5:SSL routines:SSL3_WRITE_BYTES:ssl handshake failure:s3_pkt.c:598:
If the server was vulnerable the connection would’ve been successful and we should have had to take measures.
Ok! Enough for today. Now we have another tool for use in our tool belt!