Gutza / test-openssl-https-client

Test openssl as a client for HTTPS connections

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

OpenSSL Test Client Workbench

I built this workbench while investigating a bug in Azure which stumped me for a few frustrating days. I wanted to be able to test making HTTPS requests to servers using various versions of OpenSSL without messing up my computer's default libraries.

This is only tested on Linux/WSL. The proxy should run on anything, and the shell script should be easily adapted to be portable; the only real trick in the shell script are the parameters for config, everything else is just convenience.

Hello world

  1. Clone the repo locally;
  2. Start the proxy: node proxy.js
  3. Visit http://localhost:8080/.

Notice that you're using http://localhost:8080 to access https://www.google.com/ using the openssl binary specified in variable openssl_binary to handle the TLS layer.

Using other versions of OpenSSL

  1. Clone the repo locally, if you haven't already;

  2. Download and build any official version of OpenSSL by running ./setup-openssl.sh 1.1.1n (or any other version number, including 3.x).

    This is safe, the script doesn't attempt to actually install the new version in your OS – it just downloads, configures, and builds the binary; it never even attemps to escalate privileges, and everything happens locally.

    IMPORTANT! Despite my best efforts to properly handle paths with spaces in the shell script, I found it's impossible to build some versions of openssl out of the box if your path contains spaces (I know for a fact this doesn't work for 1.1.1o, not sure about other versions.) Caveat emptor.

    You can also supply magic word github instead of a valid version number; that will cause it to clone the master branch from https://github.com/openssl/openssl, and it will try to build that. You can even run that several times, and it will download the newest version every time (as opposed to providing a version number, which it refuses to re-download). Be advised this take ages – but that's life on the cutting edge.

  3. Assuming everything works out well, you'll get a confirmation message at the end of the script which includes instructions on how to use your new binary.

  4. (Optional) Confirm that your new binary is actually linked against the local libraries: compare the output of ldd when executed against your new binary versus the output of ldd $(which openssl);

  5. Start the proxy: node proxy.js

  6. Visit http://localhost:8080/

Notice that you're now using the newly-compiled openssl to handle the TLS layer.

Other scenarios

You'll typically want to test your own website. Edit remoteHost and remotePort in proxy.js to indicate where you want the proxy to connect.

If you want to use mutual TLS authentication or any other openssl option just append stuff to the openssl_params array in proxy.js (there's already an example commented out in there). Whatever you do, don't remove parameter -ign_eof.

If you want to bind locally to another port just change the value of localPort in proxy.js.

You can of course use curl, wget, or any other thing which understands HTTP in order to send requests and parse responses, instead of your browser; use tunnels or VPNs to expose the endpoint wherever.

Known limitations

I implemented this as a one-off investigative tool, so there are tons of limitations:

  • you can't set up anything dynamically, or even at runtime (the path to the local port, remote host, and remote port are all hardcoded);
  • the code is really poorly optimized and not robust enough (there are a few scenarios where the whole thing comes crashing down; I never had the time, nor the interest to investigate and fix that);
  • you can't bind to specific local interfaces or IP addresses;
  • connections are not handled elegantly at all – the proxy has extremely limited understanding of what it's doing, so it just keeps sockets laying around until something dies;
  • the way I'm injecting the Host header will bring shame to my family for generations to come.

About

Test openssl as a client for HTTPS connections

License:MIT License


Languages

Language:JavaScript 50.7%Language:Shell 49.3%