35

I have a virtual private server, which I would like to run a web server while my server is connected to a VPN service

When the VPN connection to my provider is not up, I can do anything I want with this server, ssh, scp, http etc.

Once the openvpn is running and connected to the provider's VPN service, the server is not accessible by any means and of course for a good reason

The picture is something like this :

           My VPS                             ------------
         +----------------+                  /            \
         |                |                 /   Internet  /       101.11.12.13
         |        50.1.2.3|-----------------\   cloud    /----<--- me@myhome
         |                |                  /           \
         |     10.80.70.60|                 /             \
         +----------------+                 \              \
                        :                    \_____________/
                        :                           :
                        :                           :
                        :                           :
                        :                           :
                  +------------------+              :
                  |     10.80.70.61  |              :
                  |               \  |              :
                  |                \ |              :
                  | 175.41.42.43:1197|..............:
                  |   175.41.42.43:yy|   
                  |       .....      |
                  |   175.41.42.43:xx|
                  +------------------+



Legend                  
------ Line No VPN connection present
...... Line VPN connection established

Things to clarify:

  • All IP addresses and port numbers above and below are fictitious
  • The lines with port numbers xx, yy and anything in between are my assumption, not something that I know for a fact.
  • I set up a cron job which runs every minute pings another VPS of mine, running apache2 In the apache2 logs, I can see the origin IP address changing from 50.1.2.3 to 175.41.42.43, when VPN is active, so VPN is working fine

OpenVPN logs show these:

UDPv4 link remote: [AF_INET]175.41.42.43:1197
[ProviderName] Peer Connection Initiated with [AF_INET]175.41.42.43:1197
TUN/TAP device tun0 opened
do_ifconfig, tt->ipv6=0, tt->did_ifconfig_ipv6_setup=0
sbin/ip link set dev tun0 up mtu 1500
/sbin/ip addr add dev tun0 local 10.80.70.60 peer 10.80.70.61

At this point, I would like to be able to ssh from myhome to My VPS in the picture, while the VPN is up and using PuTTY.

In the past, in one of my workplaces, I have been given a very strange sequence to ssh into one extremely secure server which had three @ signs in the string. So, it was jumping from box to box as I imagine, but since the jump boxes were running some version of windows OS and a proprietary app on those, there was no visibility for me to see what was happening under the wraps. So I did not pay much attention. Now I am beginning to realize, I may be in the same or similar situation.

Using the IP addresses and ports in the diagram and/or log snippet, can someone tell me how I can traverse through this tunnel and access my server ?

1
  • I'm upvoting you both for the question (I've the same problem) and (expecially) for the time you took to create the network diagram in ASCII art. A day well spent, my friend... – Dr. Gianluigi Zane Zanettini Aug 29 '20 at 20:34
17

You get locked out of your VPS because once the VPN service is up, your ssh packets get routed via the VPN not your VPS's public IP 50.2.1.3.

Lets assume your server's:

  • Public IP is 50.1.2.3 (as per your example setup)
  • Public IP Subnet is 50.1.2.0/24
  • Default Gateway is probably 50.1.2.1
  • eth0 is device to gateway

Do the following using iproute2:

ip rule add table 128 from 50.1.2.3
ip route add table 128 to 50.1.2.0/24 dev eth0
ip route add table 128 default via 50.1.2.1

Then run your OpenVPN client config: openvpn --config youropenvpn-configfile.ovpn &

You will then be able to ssh into your server while your server is connected to the vpn service.

You would need to add the appropriate iptable filters to restrict access to your public IP from non-ssh:22 sessions.

7
  • This worked beautifully. – Anthony Giorgio Apr 25 '17 at 4:25
  • 5
    It worked for me as well. Still, I have trouble understanding what this does exactly; would you mind explaining what kind of connections does this allow/disallow? – The Coding Monk Mar 22 '18 at 20:21
  • 1
    Yeah I would like some more explanation as well. "Do the following using iproute2" doesn't explicitly explain what iproute2 is, or on what machine to perform this action. – deanresin Dec 18 '18 at 5:57
  • 1
    How do I get my Public IP Subnet? I've been searching the web for awhile and can't find it. What is it exactly? – Tony Friz Jan 15 '19 at 22:45
  • For those asking: this tool ultratools.com/tools/netMask allows you to get your network equivalent of 50.1.2.0/24 in the example – Dr. Gianluigi Zane Zanettini Aug 29 '20 at 20:35
5

This may be a bit late, but ...

The problem is that the default gateway gets changed by OpenVPN, and that breaks your current SSH connection unless you set up appropriate routes before you start OpenVPN.

What follows works for me. It uses iptables and ip (iproute2). Below, it is assumed that the default gateway interface before OpenVPN is started is "eth0". The idea is to ensure that when a connection to eth0 is made, even if eth0 is not the default gateway interface anymore, response packets for the connection go back on eth0 again.

You could use the same number for the connection mark, firewall mark and routing table. I used distinct numbers to make the diffences between them more apparent.

# set "connection" mark of connection from eth0 when first packet of connection arrives
sudo iptables -t mangle -A PREROUTING -i eth0 -m conntrack --ctstate NEW -j CONNMARK --set-mark 1234

# set "firewall" mark for response packets in connection with our connection mark
sudo iptables -t mangle -A OUTPUT -m connmark --mark 1234 -j MARK --set-mark 4321

# our routing table with eth0 as gateway interface
sudo ip route add default dev eth0 table 3412

# route packets with our firewall mark using our routing table
sudo ip rule add fwmark 4321 table 3412

===

UPDATE:

The above works fine for me on Debian Jessie. But on an older Wheezy system I have just found that I need to add "via" to the routing table entry:

# our routing table with eth0 as gateway interface
sudo ip route add default dev eth0 via 12.345.67.89 table 3412

There "12.345.67.89" must be the original non-VPN gateway.

2
  • Should this also work with ExpressVPN? They have an installer that comes with a command line tool "expressvpn" and you can call "connect" or "disconnect. I tried what you've posted and it didn't work. Does it have to be OpenVPN? – Tony Friz Jan 15 '19 at 23:34
  • i just can't get this to work... driving me nuts. The answer above by @hcb does work. But i'm really curious as to why your answer is not working for me! Something is missing, which i assume is causing the MANGLE rules to not being executed – Motsel Feb 13 '19 at 20:14

Not the answer you're looking for? Browse other questions tagged or ask your own question.