Server Fault is a question and answer site for system and network administrators. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I use a dynamic DNS service which is sent ip address updates from my router. In router settings, ports 22 and 80 are forwarded to my server at I have a webserver and sshd running on my server. From outside my local network, I can go to, or ssh into my server. This works fine until I connect to OpenVPN. When I connect my server to my OpenVPN provider, I can no longer ssh into my server from outside my local network. Both http and ssh timeout. Even if I cut out the dyndns stuff and just use the WAN IP, it still times out with OpenVPN connected, and works when I stop OpenVPN.

My OpenVPN provider (I do not control) that pushes routes to me (the client). Specifically, when connecting to the openvpn, the following commands are run:

/sbin/ifconfig tun0 pointopoint mtu 1500
/sbin/route add -net netmask gw
/sbin/route add -net netmask gw
/sbin/route add -net netmask gw
/sbin/route add -net netmask gw

and the added routes are removed with del when the vpn connection closes.

The problem is, this routes everything though the VPN. Instead, I would like my server to use the openvpn for all traffic other than ports 80 and 22 (inbound and outbound). i.e. I'd like to be able to connect to my server using http and ssh.

I believe similar questions have been asked, but they seem to be all routing specific ports throught the VPN and everything else, not though the vpn. I have not been able to adapt them for my purposes.


My router is (a dd-wrt router). My guess is that ssh/http traffic should be marked and set to use as the default gateway. However, im not sure how.


Following advice of leucos, I tried the following:

root@FILESERVER:~# curl; echo
root@FILESERVER:~# echo "Connecting to OpenVPN in other terminal"
Connecting to OpenVPN in other terminal
root@FILESERVER:~# curl; echo
root@FILESERVER:~# echo "1 NOVPN" >> /etc/iproute2/rt_tables
root@FILESERVER:~# ip route add default via dev p4p1 table NOVPN
root@FILESERVER:~# ip route show table NOVPN
default via dev p4p1 
root@FILESERVER:~# ip rule add from all fwmark 0x1 lookup NOVPN
root@FILESERVER:~# iptables -t mangle -I PREROUTING -p tcp --dport 22 -j MARK --set-mark 1
root@FILESERVER:~# iptables -t mangle -I PREROUTING -p tcp --dport 80 -j MARK --set-mark 1
root@FILESERVER:~# curl; echo

Now I'm not exactly sure how works, but my guess is that it has received something from ###.###.164.93, which (I guess) means port 80 traffic was not routed through p4p1 (my native interface), but instead was routed through tun0 (setup by OpenVPN). Trying to connect from outside my network also continued to timeout.

share|improve this question

closed as off-topic by EEAA, Ward, Katherine Villyard, mdpc, Falcon Momot Feb 26 '14 at 0:56

This question appears to be off-topic. The users who voted to close gave this specific reason:

  • "Questions must be relevant to professional system administration. Server Fault is dedicated to professional system and network administrators. End user and enthusiast questions are off-topic (contact your system administrator or hire a professional to help you out). Please see the Help Center for more information." – EEAA, Ward, Katherine Villyard, mdpc
If this question can be reworded to fit the rules in the help center, please edit the question.

Ask the provider to not push the default route? – Michael Hampton Feb 23 '14 at 19:01
@MichaelHampton Yes, I can use route-nopull for that. Then what? :-) – bkanuka Feb 23 '14 at 19:04
What is the actual problem you are trying to solve? – Michael Hampton Feb 23 '14 at 19:16
I would like my server to use the openvpn for all traffic other than ports 80 and 22 (inbound and outbound). – bkanuka Feb 23 '14 at 19:28
You said that already, and it doesn't answer the question. – Michael Hampton Feb 23 '14 at 19:53

"Normal" routing decisions are based on destination and routing table prefixes and masks. If you want to make routing decisons based on other data (e.g. TCP ports), you have to use ip rule.

With ip rule, you can basically ask the kernel to use an alternative routing table when some condition occurs. You typically use packet marking in iptables for this.

Here is an example, untested, you might want to try this (don't play with this if you only have a remote connection to your server !).

# Create an alternate routing table
echo "1 NOVPN" >> /etc/iproute2/rt_tables

# Create the routes for this table
# Actually, you just want to set the default gateway
ip route add default via dev eth0 table NOVPN

# Check results with
ip route show table NOVPN

# Now tell the kernel that this routing table should be used when 
# a packet waiting to be routed has a specific "mark"
ip rule add from all fwmark 0x1 lookup NOVPN

# Then mark all the required packets with the same mark use above
iptables -t mangle -I OUTPUT -p tcp --sport 22 -j MARK --set-mark 1 
iptables -t mangle -I OUTPUT -p tcp --sport 80 -j MARK --set-mark 1 

Good luck.


You might need to adjust your source address too :

iptables -t nat -A POSTROUTING -o eth0 -j SNAT --to-source

If it doesn't work, check what happens with :

tcpdump -enieth0 port 80

(I assume in my replies that the proper outbount Ethernet interface is eth0)

share|improve this answer
Thank you for the explanation, however it did not work. I will post more in the OP. – bkanuka Feb 23 '14 at 21:19
Sorry, I used the wrong chain... Answer edited, can you try again ? – leucos Feb 23 '14 at 21:35
I rebooted, and then tried again with the changes. Exactly the same results as before. – bkanuka Feb 23 '14 at 22:34
Sorry, probably wrong chain again. POSTROUTING, as the name suggests, happens after the routing decision has been taken ! Answer edited. – leucos Feb 24 '14 at 5:18
Same results - doesn't work. I will post the tcpdump when I'm not at work (I don't want to mess with this stuff remotely) – bkanuka Feb 24 '14 at 14:42

This causes all traffic to go via the VPN

/sbin/route add -net netmask gw
/sbin/route add -net netmask gw

Did you perhaps specify this in the configuration file? According to the OpenVPN documents the relevant configuration directive is redirect-gateway

share|improve this answer
I do not have control of the vpn server, and did not set it up. I can reject the route directives from the server, but then what? – bkanuka Feb 23 '14 at 19:31

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