If you need to quickly standup a secure HTTPS server on a machine, perhaps to validate that a client is sending the proper method or parameters, the socat utility can assist.
In this article we will use “socat.local” as the FQDN of our certificate and host.
Maybe you already have a pem key+certificate for this host, but if not then you can quickly create a self-signed certificate.
FQDN="mysocat.local" PORT=9443 # create private key for TLS openssl genrsa -out $FQDN.key 2048 # create public certificate for TLS openssl req -new -key $FQDN.key -x509 -days 3653 -out $FQDN.crt -subj "/C=US/ST=CA/L=SFO/O=myorg/CN=$FQDN" # create pem format key+cert cat $FQDN.key $FQDN.crt >$FQDN.pem # limit permissions chmod 600 $FQDN.key $FQDN.pem chmod 644 $FQDN.crt # if running OS level firewall, make sure port is open sudo ufw status sudo -E ufw allow $PORT/tcp
Start secure socat web server
Then start socat listening on the port using the pem certificate for secure TLS.
# ensure socat is installed
sudo apt install socat curl -y
# incoming communication will be output to console
socat -v -ls OPENSSL-LISTEN:${PORT},reuseaddr,cert=${FQDN}.pem,verify=0,crlf,fork SYSTEM:"echo HTTP/1.0 200; echo Content-Type\: text/plain; echo; echo \"hello from $(hostname) at \$(date)\""
The “-v” flag on socat will take care of outputting the incoming data coming from client calls.
Test client access with curl
We are going to test using curl on the same host, but a different terminal session.
FQDN="mysocat.local"
PORT=9443
cacert="${FQDN}.crt"
# tells curl that mysocat.local resolves to localhost
resolvestr="${FQDN}:${PORT}:127.0.0.1"
# basic curl
curl --cacert $cacert --resolve $resolvestr https://${FQDN}:${PORT}/
# curl with urlencoded params
curl --cacert $cacert --resolve $resolvestr -X POST -d 'foo=bar&email=me@mydomain.com' https://${FQDN}:${PORT}/test
# curl with uploaded file
echo "this is going up">toupload.txt
curl --cacert $cacert --resolve $resolvestr -X POST -F 'image=@toupload.txt' https://${FQDN}:${PORT}/test
Github code
You can find the commands above wrapped up as scripts on my github.
REFERENCES
github epitron, socat examples
dest-unreach.org, socat for SSL tunnel, mutual TLS
NOTES
If instead of secure HTTPS, you just wanted plain HTTP
PORT=8080
socat -v -ls TCP-LISTEN:${PORT},reuseaddr,crlf,fork SYSTEM:"echo HTTP/1.0 200; echo Content-Type\: text/plain; echo; echo \"hello from $(hostname) at \$(date)\""