I have a VPN access that uses the openconnect stack. I want to access a machine on the private network via SSH. However, I don’t want to route all my traffic network through VPN. Here is the solution.
You need openconnect, netcat (nc) and ocproxy:
aptitude install openconnect ocproxy
Commands
The core idea is to combine VPN with Socks, such as only the traffic going through a Socks server goes to the VPN, and the rest remained untouched. Then, only simply tell SSH to use Socks. The combination VPN/Socks is done thanks to ocproxy.
Let’s start, we run the VPN/Socks proxy on port 9052:
$ /usr/sbin/openconnect --script-tun --script "ocproxy -D 9052" vpn.yourdomain.fr
Then, we configure SSH to use the Socks server using a proxy command.
// in $HOME/.ssh/config
Host myserver
User martin
ProxyCommand nc -X 5 -x 127.0.0.1:9052 %h %p
And finally, we can ssh over VPN on port 443:
$ ssh myserver
Refinements
If you want to connect automatically, you have to use in input pipe where the password is given by another program (eg taking the password in a safe or keyring):
/usr/sbin/openconnect --no-cert-check -u mmonperr --script-tun --script "ocproxy -D 9052" \
vpn.inria.fr < <(mycommand-giving-the-vpn-password)
By default, openconnect does the VPN over UDP datagrams using DTLS. If you want to use TCP (or if you are forced to in a network where UDP is blocked), there is the option --no-dtls
.
/usr/sbin/openconnect --no-dtls --no-cert-check -u mmonperr --script-tun --script "ocproxy -D 9052" \
vpn.inria.fr < <(mycommand-giving-the-vpn-password)
Automation
This can be fully automated, for this, create a script called nc-openconnect
to be used in SSH’s config.
The script contains:
#!/bin/bash
# connects to SSH through openconnect and VPN
# for use iwth ProxyCommand in SSH
# first run openconnect
/sbin/start-stop-daemon --pidfile /tmp/openconnect.pid --make-pidfile -b -S --startas /bin/bash -- -c 'exec /usr/sbin/openconnect --reconnect-timeout 60 --no-dtls -u mmonperr --script-tun --script "ocproxy -D 9052" vpn3-sop.national.inria.fr < <(mycommand-giving-the-vpn-password)' &
sleep 2
# kill connection on exit
function cleanup {
/sbin/start-stop-daemon --stop --pidfile /tmp/openconnect.pid
}
trap cleanup EXIT
# redirect traffic (standard input and output) through VPN
nc -X 5 -x 127.0.0.1:9052 $1 $2
Then, in .ssh/config
,
Host foobar
HostName 91.4.243.27
User martin
ProxyCommand nc-openconnect %h %p