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  /
         ||-----------------\   cloud    /----<--- me@myhome
         |                |                  /           \
         ||                 /             \
         +----------------+                 \              \
                        :                    \_____________/
                        :                           :
                        :                           :
                        :                           :
                        :                           :
                  +------------------+              :
                  |  |              :
                  |               \  |              :
                  |                \ |              :
                  |       .....      |

------ 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 to, when VPN is active, so VPN is working fine

OpenVPN logs show these:

UDPv4 link remote: [AF_INET]
[ProviderName] Peer Connection Initiated with [AF_INET]
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 peer

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 ?

  • 3
    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... Aug 29, 2020 at 20:34

4 Answers 4


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

Lets assume your server's:

  • Public IP is (as per your example setup)
  • Public IP Subnet is
  • Default Gateway is probably
  • eth0 is device to gateway

Do the following using iproute2:

ip rule add table 128 from
ip route add table 128 to dev eth0
ip route add table 128 default via

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.

To understand these commands in details, see the related answers.

  • This worked beautifully. Apr 25, 2017 at 4:25
  • 6
    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?
    – Ailef
    Mar 22, 2018 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, 2018 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, 2019 at 22:45
  • For those asking: this tool ultratools.com/tools/netMask allows you to get your network equivalent of in the example Aug 29, 2020 at 20:35

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



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.

  • 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, 2019 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, 2019 at 20:14

In addition to hcb's answer, If you want to make these changes permanent across reboots, you can use this Network Manager commands:

nmcli connection modify ens192 +ipv4.routing-rules "priority 100 from table 128"
nmcli connection modify ens192 +ipv4.routes " table=128, onlink=true table=128"

The first line is to create the rule, and the second line creates both routes. Note that is the equivalent to default in the original answer


Assuming you have a client PC that is connected to a OpenVPN host.

For SSH through the VPN tunnel: https://askubuntu.com/questions/1069846/connected-to-openvpn-server-but-cant-ssh

On the Openvpn host:

$ sudo ufw enable
$ sudo ufw allow 1194/udp comment "Allowing OpenVPN Connections"
$ sudo ufw allow from to any port 22 proto tcp comment "SSH allowed for VPN clients"

On the client side:

Make sure OpenSSH is installed and running and port 22 is open on the firewall.

Then: $ ssh [email protected] (change “user” to your login name on the server/host).

You must log in to answer this question.

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