Linux – Route all network traffic through an openvpn connection and also accepting incoming requests on the hosts’ real IP-address

linuxnetworkingopenvpnubuntu-15.10

I am searching for a solution to route all traffic from a server through OpenVPN but keep it possible to host applications on the server which can be accessed outside of the local area network.

To be a little more specific: There are two applications hosted on the server. There is one application that binds port 80 and one that binds port 8080. All traffic to and from these services have to go direct, all other traffic has to go through the VPN tunnel.

At the moment, requests are being received directly but not answered when the VPN is running. All services can be reached when I disable the VPN:

Wireshark

How can I configure OpenVPN, for example with an up script, so that these routes will be routed correctly?

An overview of my network interfaces:

lo Link encap:Local Loopback 
inet addr:127.0.0.1 Mask:255.0.0.0 
inet6 addr: ::1/128 Scope:Host 
UP LOOPBACK RUNNING MTU:65536 Metric:1 
RX packets:537169 errors:0 dropped:0 overruns:0 frame:0 
TX packets:537169 errors:0 dropped:0 overruns:0 carrier:0 
collisions:0 txqueuelen:0 
RX bytes:147901148 (147.9 MB) TX bytes:147901148 (147.9 MB) 

p4p1 Link encap:Ethernet HWaddr xx:xx:xx:xx:xx:xx 
inet addr:192.168.2.201 Bcast:192.168.2.255 Mask:255.255.255.0 
inet6 addr: xxx/64 Scope:Global 
inet6 addr: xxx/64 Scope:Link 
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 
RX packets:8062700 errors:0 dropped:180 overruns:0 frame:0 
TX packets:10937639 errors:0 dropped:0 overruns:0 carrier:0 
collisions:0 txqueuelen:1000 
RX bytes:7942028079 (7.9 GB) TX bytes:12229412785 (12.2 GB) 

tun0 Link encap:UNSPEC HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00 
inet addr:XX P-t-P:XX Mask:255.255.255.255 
UP POINTOPOINT RUNNING NOARP MULTICAST MTU:1500 Metric:1 
RX packets:6382168 errors:0 dropped:0 overruns:0 frame:0 
TX packets:6004894 errors:0 dropped:46397 overruns:0 carrier:0 
collisions:0 txqueuelen:100 
RX bytes:7066816609 (7.0 GB) TX bytes:4808493953 (4.8 GB) 

Routing tables before connection with the VPN:

ip route show
default via 192.168.2.254 dev p4p1
192.168.2.0/24 dev p4p1  proto kernel  scope link  src 192.168.2.201

Routing tables after connection with the VPN:

ip route show
0.0.0.0/1 via 10.124.1.5 dev tun0
default via 192.168.2.254 dev p4p1
10.124.1.1 via 10.124.1.5 dev tun0
10.124.1.5 dev tun0  proto kernel  scope link  src 10.124.1.6
109.201.154.152 via 192.168.2.254 dev p4p1
128.0.0.0/1 via 10.124.1.5 dev tun0
192.168.2.0/24 dev p4p1  proto kernel  scope link  src 192.168.2.201

Best Answer

I had the same issue as you had. You have to disable rp_filter and redirect all traffic with destination port 80 and 8080 to your normal interface.

Disable reverse path filtering

for i in /proc/sys/net/ipv4/conf/*/rp_filter ; do
echo 0 > $i
done

We are going to use table 100. Make sure it is not used by anything else! We are going to flush it

ip route flush table 100
ip route del default table 100
ip rule del fwmark 1 table 100
ip route flush cache
iptables -t mangle -F PREROUTING

Create the table for all connections (Not the VPN tunnel)

ip route show table main | grep -Ev ^default | grep -Ev tun0 \
| while read ROUTE ; do
ip route add table 100 $ROUTE
done
ip route add default table 100 via 192.168.2.254
ip rule add fwmark 1 table 100 
ip route flush cache

Bypass port 80 and 8080

iptables -t mangle -A PREROUTING -i p4p1 -p tcp -m multiport --dports 80,8080 -j MARK --set-mark 1