If you are behind a firewall and forced to use some HTTP proxy that allows you only HTTP/HTTPS protocols, then you probably interested how to traverse it.
You will need two things:
sslh Applicative protocol multiplexer
Your own server you can SSH to sslh accepts connections on specified ports, and forwards them further based on tests performed on the first data packet sent by the remote client.
sslh and iptables configuration below is done on your private server that you will use as a hopserver.
# cat /etc/default/sslh
RUN=yes
DAEMON=/usr/sbin/sslh
DAEMON_OPTS="--user sslh --listen 0.0.0.0:443 --ssh 127.0.0.1:22 --pidfile /var/run/sslh/sslh.pid"
# /etc/init.d/sslh start
Now sslh is going to listen over *:443 port and will forward incoming SSH connections to localhost:22 port. Besides that you can also reconfigure your webserver to listen only over localhost and add ‘’–ssl 127.0.0.1:443’’ argument after the ‘’–ssh’’ (Order is important!)
In this case sslh will decide whether to forward the connection to SSH daemon or to a WebServer which will depend on what is the client trying to access.
Make sure you are not filtering HTTPS port at your hopserver
# For the SSLH
-A INPUT -p tcp -m state --state NEW --dport 443 -j ACCEPT
Now you can try to access your server via HTTPS port.
With netcat-openbsd
$ ssh -o ProxyCommand="nc -X connect -x proxy.net:8080 %h %p" -p 443 user1@myhopserver.com
The same can be achieved with connect-proxy or corkscrew, e.g.:
$ ssh -o ProxyCommand="corkscrew proxy.net 8080 %h %p" -p 443 user1@myhopserver.com
You can access any target server via your hopserver(s).
$ ~/.ssh/config
Host myhopserver.com
User user1
HostName myhopserver.com
Port 443
ServerAliveInterval 30
ProxyCommand /bin/nc -X connect -x proxy.net:8080 %h %p
Host mysecondserver.com
User user1
HostName mysecondserver.com
Port 22
ServerAliveInterval 30
ProxyCommand /usr/bin/ssh myhopserver.com /bin/nc -w 600 %h %p
$ ssh mysecondserver.com
Use PuTTYgen to generate your public/private key pair.
Copy Public key and insert to ~/.ssh/authorized_keys on your servers where you will connect.
Save Private key as C:\Users\wuser1\Desktop\pka-putty\privatekey.ppk
IMPORTANT NOTE DO NOT set key passphrase, otherwise plink will just hang (it doesn’t ask for password prompt when using with PuTTy)
Remember, if it prompts for user name or password at any of the intermediate steps it will fail.
Session: myhopserver.com
Host: myhopserver.com
Port: 443
Auto-login username: user1
Proxy type: HTTP
Proxy hostname: proxy.net
Proxy port: 8080
Telnet command, or
local proxy command: connect %host %port\n
Private key file for
authentication: C:\Users\wuser1\Desktop\pka-putty\privatekey.ppk
Connection - Seconds between keepalives (0 to turn off): 30
Session: mysecondserver.com
Host: mysecondserver.com
Port: 22
Auto-login username: user1
Proxy type: Local
Telnet command, or
local proxy command: plink.exe -load myhopserver.com -nc %host:%port
Private key file for
authentication: C:\Users\wuser1\Desktop\pka-putty\privatekey.ppk
Connection - Seconds between keepalives (0 to turn off): 30
Make your own SOCKS proxy out of your SSH over HTTPS connection.
You can make it with OpenSSH or PuTTy, depending what you prefer.
$ ssh -fN -D127.0.0.1:1080 myhopserver.com
Connection -> SSH -> [x] Don't start a shell or command at all
Connection -> SSH -> Tunnels
Add new forwarded port
Source port: 1080
Dynamic
Voila! Now you have your own SOCKS proxy: 127.0.0.1:1080
To enable the keep alive system-wide (root access required), edit /etc/ssh/ssh_config; to set the settings for just your user, edit ~/.ssh/config (create the file if it doesn’t exist). Insert the following:
Host *
ServerAliveInterval 30
ServerAliveCountMax 2
You can also make your OpenSSH server keep alive all connections with clients by adding the following to /etc/ssh/sshd_config:
ClientAliveInterval 30
ClientAliveCountMax 2
If you also have DNS port 53 (udp/tcp) blocked, then you have only the HTTP proxy to get connected to a server using hostname.
$ telnet proxy.net 8080
CONNECT google.com:443 HTTP/1.1
Host: google.com:443
...
$ curl --proxy http://proxy.net:8080 ftp://ftp.mozilla.org/pub/mozilla.org
In your ~/.ssh/config it is done with netcat-openbsd
/bin/nc -X connect -x proxy.net:8080 %h %p
If you are connecting through a proxy that checks that the outgoing connection really is SSL and rejects SSH, you can encapsulate all your traffic in SSL using stunnel & proxytunnel.
For more, see Using proxytunnel with sslh at the https://github.com/yrutschle/sslh
stunnel will be configured on a server side and proxytunnel on a client side.
# cd /etc/stunnel/
# touch stunnel.pem && chmod 600 stunnel.pem
# openssl req -new -x509 -days 365 -nodes -out stunnel.pem -keyout stunnel.pem
# openssl gendh 2048 >> stunnel.pem
# openssl x509 -subject -dates -fingerprint -in stunnel.pem
Manually in foreground to see how it works
# stunnel -f -p /etc/stunnel/stunnel.pem -d 0.0.0.0:443 -l /usr/sbin/sslh -- sslh -i -p 127.0.0.1:443 --user sslh --ssh 127.0.0.1:22
If you want to restart it (it will drop your connection for about 1-2 seconds)
# echo "\$(killall stunnel4; killall sslh; sleep 1; stunnel -p /etc/stunnel/stunnel.pem -d 0.0.0.0:443 -l /usr/sbin/sslh -- sslh -i -p 127.0.0.1:443 --user sslh --ssh 127.0.0.1:22)" |at now + 1 minute
To kill stunnel/sslh and start only sslh (without SSH request encapsulation by HTTPS at the client side - first network packets)
# echo "\$(killall stunnel4; killall sslh; sleep 1; sslh --user sslh --listen 0.0.0.0:443 --ssh 127.0.0.1:22)" | at now + 1 minute
$ cat .ssh/config
Host myhopserver.com
User user1
HostName myhopserver.com
Port 443
ServerAliveInterval 30
# ProxyCommand /bin/nc -X connect -x proxy.net:8080 %h %p
ProxyCommand /usr/bin/proxytunnel -e -p proxy.net:8080 -d %h:%p -H "User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Win32)\n"
# grep stunnel /etc/rc.local
/usr/bin/stunnel -p /etc/stunnel/stunnel.pem -d 0.0.0.0:443 -l /usr/sbin/sslh -- sslh -i -p 127.0.0.1:443 --user sslh --ssh 127.0.0.1:22 &
You may also want to disable sslh if prefer only the encapsulated by HTTPS connection.
# update-rc.d sslh disable
# grep ^RUN /etc/default/sslh
RUN=no