I was faced with a firewall denying access to the outside world using ssh. All I had was http/https access via a proxy server which required authentication. I had an Ubuntu jump host outside the network connected to the internet with a free 443 port. I tried accessing that with httptunnel and proxytunnel, but could get neither to work with this proxy server.
The solution that worked in this particular case was stunnel. It can wrap any TCP connection into an https session which was not rejected by the proxy server I was facing.
Client
Install stunnel on laptop (mine is Ubuntu 18.04), and use openssl to generate a key and a certificate:
1 2 3 4 5 6 7 |
sudo su - apt-get install stunnel4 cd /etc/stunnel openssl genrsa 1024 > stunnel.key openssl req -new -key stunnel.key -x509 -days 1000 -out stunnel.crt # (you can accept openssl defaults) cat stunnel.crt stunnel.key >stunnel.pem |
The values you enter in the client certificate request do not matter.
Next, create stunnel configuration. You should replace the variables with your own values.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
PROXY_ADDRESS="<your proxy_address:proxy_port>" PROXY_USERNAME="<your proxy username>" PROXY_PASSWORD="<your proxy password>" JUMP_HOST_ADDRESS="<your jump host address>" cat >/etc/stunnel/stunnel.conf <<EOF pid=/var/run/stunnel.pid cert=/etc/stunnel/stunnel.pem [ssh] client=yes libwrap=no accept=2222 connect=$PROXY_ADDRESS protocolUsername=$PROXY_USERNAME protocolPassword=$PROXY_PASSWORD protocolHost=$JUMP_HOST_ADDRESS:443 EOF systemctl start stunnel4 |
Stunnel should now be running on your laptop. It will forward any connection you make to localhost:2222 to your $JUMP_HOST port 443 and wrap it in an https request.
Jump host
The proxy server did not accept self-signed certificates, so I installed certbot to get a working certificate on the jump host (mine is Ubuntu 19.10):
1 2 3 4 5 6 7 |
sudo su - add-apt-repository ppa:certbot/certbot apt-get install certbot certbot certonly --standalone # Make note where certbot installs the private key # and the full certificate chain |
Install stunnel on server and configure it:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
JUMP_HOST_DNS_NAME="<your jump host DNS name>" apt-get install stunnel4 cat >/etc/stunnel/stunnel.conf <<EOF pid=/var/run/stunnel.pid key=/etc/letsencrypt/live/$JUMP_HOST_DNS_NAME/privkey.pem cert=/etc/letsencrypt/live/$JUMP_HOST_DNS_NAME/fullchain.pem [ssh] accept=443 connect=127.0.0.1:22 EOF systemctl start stunnel4 |
Make sure the key and cert paths are pointing to correct certbot files.
Stunnel should now be running on the jump host as well. It will listen on port 443, unwrap the https and redirect the connection to localhost port 22, where sshd should be listening.
Test From Client
Now you should be able to ssh to your jump host by connecting to the local stunnel instance:
1 |
ssh localhost -p 2222 |
Good post! However you mixed connect host and protocolHost in the client config. But I learned the fact that stunnel can speak HTTP CONNECT, which is great. Tnx!