I'm trying to setup a VPN router using Ubuntu Server 16.04.
I'm configuring the router to be secure so that no traffic can leak or if the VPN fails it will fail closed.
The router has a wireless interface (wlp2s0) that connects to my wireless network for internet connectivity and an ethernet interface (enp1s0) where I plug my laptop into.
Ideally, openvpn would run on startup and use wlp2s0 to create a tun0 interface and then some iptable rules would forward enp1s0 traffic to tun0.
To accomplish my goal of preventing traffic leakage I made a startup script that flushes all routes and then adds a local subnet route for wlp2s0 to the MAIN table. It also adds a default route out wlp2s0 for table 100.
I added an iptables mangle rule that marks openvpn traffic and then a fw rule that makes the marked traffic use table 100.
So basically, I only want openvpn traffic to be able to use the wireless default route (table 100) so that it can create the tunnel. All other traffic will be local or through the tunnel.
My startup script works fine, it creates the proper routes on startup. My iptable rules and fw rule seem to be correct as well.
The issue is that openvpn traffic just doesn't seem to hit the iptables mangle rule.
iptable rule that marks the openvpn traffic.
iptables -t mangle -A OUTPUT -p tcp --dport 501 -j MARK --set-mark 2
Startup script.
ip route add table 100 default via 192.168.0.1 dev wlp2s0
ip rule add fwmark 0x2 table 100
ip route flush table main
ip route add 192.168.0.0/24 dev wlp2s0
Output of various commands that most of you will ask for
administrator@ubuntu-svr:~$ sudo iptables -t mangle -L -v
Chain PREROUTING (policy ACCEPT 6153 packets, 1859K bytes)
pkts bytes target prot opt in out source destination
Chain INPUT (policy ACCEPT 1961 packets, 297K bytes)
pkts bytes target prot opt in out source destination
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 1348 packets, 128K bytes)
pkts bytes target prot opt in out source destination
0 0 MARK tcp -- any any anywhere anywhere tcp dpt:501 MARK set 0x2
Chain POSTROUTING (policy ACCEPT 1348 packets, 128K bytes)
pkts bytes target prot opt in out source destination
administrator@ubuntu-svr:~$ ip rule
0: from all lookup local
32765: from all fwmark 0x2 lookup 100
32766: from all lookup main
32767: from all lookup default
administrator@ubuntu-svr:~$ ip route show table main
192.168.0.0/24 dev wlp2s0 scope link
administrator@ubuntu-svr:~$ ip route show table 100
default via 192.168.0.1 dev wlp2s0
administrator@ubuntu-svr:~$ ip route get 8.8.8.8 mark 0x2
8.8.8.8 via 192.168.0.1 dev wlp2s0 src 192.168.0.209 mark 2
So from the above output you can see that the proper routes, iptable mangle rule, and fw rule are all in place.
When I issue the "ip route get" get command you can see that the proper route is selected for marked traffic.
However, the iptables mangle rule is NOT getting hit. I issued "telnet 8.8.8.8 501" and still the rule is not hit! Even though the traffic is locally generated and hits tcp 501, which should match the rule.
The openvpn traffic is generated from the router itself. Per, the man page for iptables the OUTPUT chain for mangle is for modifying LOCALLY generated traffic PREROUTE decision.
I'm at a complete loss here. I've read other posts of people having similar issues but can't seem to find a solution.