10

I have a Linux machine on the intranet which I can only access via SSH. This machine needs to connect to a VPN using OpenConnect; however when I do that, I get disconnected from the SSH session since the intranet's IP is no longer valid.

I can reconnect to it from within the VPN using the IP it got assigned, but that IP changes every time the VPN is connected. I don't have control over any of the networks, only this machine.

Is there a way to keep the SSH connection alive while connecting to the VPN?


openconnect requires a --script argument which takes a script to configure routing. Without it the connection succeeds, but no names are resolved and the intranet's IP remains valid.

I'm currently using Ubuntu's default /etc/vpnc/vpnc-script. I'm good with shell scripting but I know very little about networking. If I have to modify that, I'll need some reference about what or how to change it.

8
  • I don't know openconnect but "I get disconnected from ssh since the intranet's IP is no longer valid" doesn't make sense to me. You have to find out what exactly is happening there. Maybe openconnect reconfigures the firewall. Is the intranet IP the only IP this system has (except for lo)? Jun 8, 2013 at 18:45
  • For security, the vpn software will often set up the packet filtering to only go out the vpn interface. Therefore there is no routing on the original interface back to the SSH client server. That can be handled by adding static routes and clearing the iptables.
    – Arcege
    Jun 8, 2013 at 19:16
  • @MichaelMrozek the question is on-topic for both forums and I can't create a link there to redirect here.
    – Samus_
    Jun 8, 2013 at 23:51
  • @HaukeLaging the openconnect command takes a --script argument which takes a vpnc-script which configures routing, without it the connection suceeds but no names can be resolved, I don't lose the intranet's IP if I don't use that script but the connection is useless without it; I'm currently using /etc/vpnc/vpnc-script in Ubuntu, chances are I'll have to tweak it but I need some pointers about what and how to chage.
    – Samus_
    Jun 8, 2013 at 23:54
  • 1
    Sorry but that's too much to check and change for me. If you find out what the problem is (e.g. Netfilter or routing) then it would be easier to find the respective part in the script. Jun 10, 2013 at 0:33

7 Answers 7

5

is there a way to keep the SSH connection alive while connecting to the VPN?

No. That system's routing changes dramatically when you connect to the VPN, which breaks all established TCP sockets.

You should look into using a terminal multiplexer like screen or tmux in your ssh session - that way you can have a persistent shell that you can re-connect to.

4
  • but I can't reconnect to since the intranet's IP is no longer available when connected to the VPN and the VPN's IP is dynamic.
    – Samus_
    Jun 8, 2013 at 18:46
  • You said "I can reconnect to it from within the VPN using the IP it got assigned". So do that, and if you were previously using a screen session, then you just reconnect and run $ screen -R and whammo, you're back to the shell session you had before you connected the VPN.
    – EEAA
    Jun 8, 2013 at 19:29
  • "I can reconnect to it from within the VPN using the IP it got assigned" BUT it's a new one everytime it connects so it's not an option.
    – Samus_
    Jun 8, 2013 at 21:59
  • ...and in case you wonder how do I know I can connect using that IP I had to craft a script to run openconnect in the background and send the output of ifconfig to another machine within the VPN that I had netcat listening to a specific port, that's enough to prove it but absolutely impractical and fragile, I need a better way.
    – Samus_
    Jun 8, 2013 at 22:02
5

General Answer

You should use --script and --script-tun options of openconnect and provide a custom vpnc-script. A good starting point is the vpnc-script distributed already with your openconnect, For Example on OSX(HomeBrewed openconnect) it is located at /usr/local/etc/vpnc-script.

Note that according to openconnect official documentation:

OpenConnect just handles the communication with the VPN server; it does not know how to configure the network routing and name service on all the various operating systems that it runs on.

To set the routing and name service up, it uses an external script which is usually called vpnc-script.


Better Solution

There is already a good project called ocproxy which acts as a proxy server for openconnect, hence the name ocproxy(OpenConnectProxy).

ocproxy is a user-level SOCKS and port forwarding proxy for OpenConnect based on lwIP. When using ocproxy, OpenConnect only handles network activity that the user specifically asks from proxy, so the VPN interface no longer "hijacks" all network traffic on the host.

Example OpenConnect Command:

echo $1 | sudo openconnect -u $2 -d --timestamp -v --passwd-on-stdin --script-tun --script "ocproxy -D $3 -v" $4

Replace:

  • $1 with: OpenConnect Password
  • $2 with: OpenConnect Username
  • $3 with: Desired Socks5 Proxy Port
  • $4 with: OpenConnect Server Address
3

You may want to look into what is in the iptables, which handles packet filtering within the kernel. I use openconnect from the other direction, and the default setting is to remove access to the standard interfaces in favor of the newly created VPN interface. The first thing to do is figure out what routes are being created by the VPN connection. Then you can write a script to handle the gateway and routes, and then finally flush the iptables and clear the VPN "chain" (term used in iptables). I have a script that looks something like:

IPADDR=NN.NN.NN.N
DESIREDNET1=MM.MM.MM.MM
GATEWAY_LINE=$(netstat -rn | grep ${IPADDR})
GATEWAY=$(echo "$GATEWAY_LINE" | awk '{print $2}')
GATEWAY_DEV=gw
if [ "$GATEWAY" = "*" ]; then
    GATEWAY=$(echo "$GATEWAY_LINE" | awk '{print $8}')
    GATEWAY_DEV=''
fi
# add custom routes
route add -net $DESIREDNET1 netmask 255.255.0.0 dev cscotun0
...
# reset the default route
route del default
route add default $GATEWAY_DEV $GATEWAY

# flush iptables to clear the ciscovpn chain
iptables --flush
iptables --delete-chain
# Add out own nameservers back
if [ -f /etc/resolv.conf.vpnbackup ]
then
   cat /etc/resolf.conf /etc/resolv.conf.vpnbackup > /etc/resolv.conf
   echo "nameserver $GATEWAY" >> /etc/resolv.conf
fi

You'll need to copy the /etc/resolv.conf to /etc/resolf.conf while off the VPN to be able to add back the 'normal' settings.

Good luck.

1

I think the reason is that when your linux server make VPN connection, it routes all traffic through gateway in remote network. You can make your SSH alive if you config your VPN client only use remote gateway for communication with remote network.

I don't use openconnect, but in openvpn, you can tick in use this connection only for resources on its network in VPN configuration.

1

A workaround this issue is connecting to the same VPN server on both machines involved in the terminal connection.

It works for me.

0

If you are for example in a VPS and you able to create a mini VPS in the same datacenter, and also to provide a local IP in each of the two VPSs, you can make a tunneled SSH connection using the mini VPS as the tunnel. This way you can connect to the target VPS even when it is connected to a VPN.

To connect remotely using SSH:

  • connect the internal (LAN IP) of the target VPS (the one that connects to the VPN)
  • using as a tunnel the mini VPS - so connect to the external IP of the mini VPS

So the prerequisites for this is:

  1. to be able to create an additional VPS in the same network
  2. to assign to both machines a local additional IP

This is easy and feasible in popular Clouds like DigitalOcean, Linode etc

0

I've had success using vpn-slice. It is made for the exact purpose of limiting what gets routed over the VPN: https://github.com/dlenski/vpn-slice

sudo pip3 install vpn-slice or brew install vpn-slice

The vpn-slice command takes as arguments the specific hosts and/or subnets which you want to route through the VPN. Everything else is left intact.

sudo openconnect https://vpn.example.org --script 'vpn-slice --dump --verbose vpn-specific.host 10.13.37.0/24'

This is really useful when I need to connect to only a handful of services over a VPN, but want regular internet & LAN access to keep working. And it has the added benefit of not breaking my SSH connection (although you may want to tweak the settings locally first).

You can also exclude subnets like %10.13.37.0/24, automatically route the VPN's default subnet with --route-internal, etc. See vpn-slice --help for more.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .