My network looks like this:
I'm trying configure my router so that the subnet (192.168.2.0/24) is routed over the VPN tunnel (tun0) on the gateway/router.
While at the same time clients on the subnet (192.168.1.0/24) are routed directly out over ppp0, ie not through the VPN.
I don't want to run VPN software clients, and certain clients on the network need direct access. eg a windows gaming computer, voip phone etc.
My router also runs an unbound DNS server that forwards DNS lookups to dnscrypt-proxy.
The network interfaces on the router are configured like:
auto lo
iface lo inet loopback
auto lo:1
iface lo:1 inet static
address 127.0.0.2
netmask 255.0.0.0
auto eth0
iface eth0 inet static
address 192.168.1.1
netmask 255.255.255.0
# Virtual interface
auto eth0:2
iface eth0:2 inet static
address 192.168.2.1
netmask 255.255.255.0
auto eth1
iface eth1 inet static
address 192.168.0.2
netmask 255.255.255.252
auto ppp0
iface ppp0 inet ppp
pre-up ip link set dev eth1 up
provider <isp>
post-down ip link set dev eth1 down
For the moment I'm using a virtual interface ie eth0:2. I am also wondering if this is appropriate or should that be a VLAN ie eth0.2?
As far as I was aware the only difference would be that clients would then require a VLAN interface eg:
/etc/systemd/network/MyEth.network
[Match]
Name=enp10s0
[Network]
DHCP=v4
DNS=192.168.2.1
Address=192.168.2.30/24
Gateway=192.168.2.1
VLAN=vlan2
/etc/systemd/network/MyEth.netdev
[NetDev]
Name=vlan2
Kind=vlan
[VLAN]
Id=2
and be unable to cross over subnets eg 192.168.1.10 would be unable to talk to 192.168.2.10.
The iptables rules I've attempted to get this working with are as follows:
iptables -F
iptables -t nat -F
export WAN=ppp0 # Link to ISP
export INT_IF=eth0 # Interface that serves internal network
export EXT_IF=eth1 # Interface between router and modem
export WAN_TUNNEL=tun0 # VPN tunnel created by OpenVPN
export VPN_VLAN_IF=eth0:2 # Interface internal clients have as their gateway
# Allows internet access on gateway
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -m conntrack --ctstate INVALID -j DROP
#############
# NAT Rules #
###############################################################################
# VPN
iptables -I FORWARD -i ${VPN_VLAN_IF} -d 192.168.2.0/24 -j DROP
iptables -A FORWARD -i ${VPN_VLAN_IF} -s 192.168.2.0/24 -j ACCEPT
iptables -A FORWARD -i ${WAN_TUNNEL} -d 192.168.2.0/24 -j ACCEPT
iptables -t nat -A POSTROUTING -s 192.168.2.0/24 -o ${WAN_TUNNEL} -j MASQUERADE
###############################################################################
###############################################################################
# NO VPN
iptables -I FORWARD -i ${INT_IF} -d 192.168.1.0/24 -j DROP
iptables -A FORWARD -i ${INT_IF} -s 192.168.1.0/24 -j ACCEPT
iptables -A FORWARD -i ${WAN} -d 192.168.1.0/24 -j ACCEPT
iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -o ${WAN} -j MASQUERADE
###############################################################################
iptables -P INPUT DROP
iptables -P OUTPUT ACCEPT
iptables -P FORWARD DROP
echo 1 > /proc/sys/net/ipv4/ip_forward
for f in /proc/sys/net/ipv4/conf/*/rp_filter ; do echo 1 > $f ; done
/etc/init.d/iptables save
I also expect that I would need to use route-nopull in my openvpn configuration, otherwise everything on the gateway would be routed over the VPN?
By default when I connect to the OpenVPN server I see:
openvpn[3469]: /sbin/ip route add <ip_of_vpn> dev ppp0
openvpn[3469]: /sbin/ip route add 0.0.0.0/1 via 172.16.32.1
openvpn[3469]: /sbin/ip route add 128.0.0.0/1 via 172.16.32.1
which results in a route like:
ip route
0.0.0.0/1 via 172.16.32.1 dev tun0
default dev ppp0 scope link metric 300
<ip_of_vpn> dev ppp0 scope link
128.0.0.0/1 via 172.16.32.1 dev tun0
172.16.32.0/20 dev tun0 proto kernel scope link src 172.16.39.64
192.168.0.0/30 dev eth1 proto kernel scope link src 192.168.0.2
192.168.1.0/24 dev eth0 proto kernel scope link src 192.168.1.1
192.168.2.0/24 dev eth0 proto kernel scope link src 192.168.2.1
<ip_from_isp> dev ppp0 proto kernel scope link src X.X.X.X
Would I need a static route to route 192.168.2.0/24 to the VPN ie to tun0
Best Answer
This can be achieved using a custom routing table and policy (I recently did something very similar myself)
Firstly create a custom routing table for your VPN
Tell iproute2 to use this routing table for traffic to and from your 192.168.2.0 network
Set up NAT masquerading for the 192.168.2.0 network
Enable IP forwarding if it's not enabled (required for NAT)
In your OpenVPN config add the following lines
Create a custom shell script in /etc/openvpn/route-up.sh and chmod +x it
Steps 2 and 3 will not persist across reboots so you will need to add those parts to your init scripts as required.