Allow only VPN & LAN network for client

Hello,

I setup proxmox on my homeserver to virtualize my OpenWrt installation and some linux clients.
One of those linux clients will act as a download-vm, which should only be allowed to...

  1. access the NAS in my LAN, hosted on the OpenWrt vm ==> WORKING
  2. get internet access via OpenVPN, running on the OpenWrt vm
  3. block WAN access ==> WORKING

3. To block WAN access I created the following rule

block-wan
config rule
    option name 'Block-Download-VM-WAN'
    list proto 'all'
    option src 'lan'
    list src_mac 'XX:XX:XX:XX:XX:XX'
    option dest 'wan'
    option target 'REJECT'

Which is working perfectly fine!
Is there anything else I could do to make sure the download-vm is unable to ever access the WAN interface?

2. route client via VPN
The OpenVPN instance has option route_nopull '1' in its config, because I only want specific clients to use the VPN.
To route the download-vm trough the VPN I use @stangri's vpn-pbr package.

config policy
	option name 'download-vm'
	option src_addr 'ho.me.ip.client'
	option proto 'all'
	option interface 'vpn'

The package works very well!
But... for safety reasons and to minimize errors I would like to achieve this without the vpn-pbr package.
How can I do this?

Best Regards
TheHellSite

A set of rules/routes for the device via vpn.

Perfect, thank you!!!
Is there also a way to use a mac adress as src instead of the IP?

EDIT: it is not working
I added the following to my network config and restarted the network service

network
#my vpn interface
config interface 'airvpn'
    option ifname 'tun_airvpn'
    option proto 'none'

config route
    option interface 'airvpn'
    option target '0.0.0.0'
    option netmask '0.0.0.0'
    option metric '200'
    option table '100'

config rule
    option in 'lan'
    option src 'xx.xx.xx.249/32'
    option lookup '100'

Not using the rules, but you can mark in iptables and route according to the packet marking.

If the tunnel is not point to point you may need to add a gateway in the route.

1 Like

Okay, thanks. Sounds a bit to overkill for one client.

network
config interface 'airvpn'
    option ifname 'tun_airvpn'
    option proto 'none'

config route
    option interface 'airvpn'
    option target '0.0.0.0'
    option netmask '0.0.0.0'
    option gateway '0.0.0.0'
    option metric '200'
    option table '100'

config rule
    option in 'lan'
    option src 'xx.xx.xx.249/32'
    option lookup '100'

Still nothing.

This is an invalid gateway. You'll have to use the gateway of airvpn. You can find it with ip -4 ro | grep tun

1 Like

Okay, I already thought of that.
I could do this but the IPs of the tun interface will never be the same!

I can not specify any pointer to the gw address of that tun interface, right?
How could I do this automatically?

Make a script to detect the gateway and run the route.
Or use vpn-pbr.

1 Like

... which does exactly what I need.
I understand. :smile:

But just out of interest, how would this script look?
I know there is a route_up option in openvpn, which I could use for this.

route_up
#!/bin/sh
#
################################
# route clients via tun_airvpn #
################################

# wait for the tun interface to be up
sleep 5

# get ip address of vpn interface
VPN_ADDR="${ifconfig_local}"

    if [ -z "${VPN_ADDR}" ]
    then
        VPN_ADDR="127.0.0.1"
    fi

# add static route for clients

?????????

How do I add a static route?
Also which settings in /etc/network would be obsolete then?
The route, the rule or both?

config route
    option interface 'airvpn'
    option target '0.0.0.0'
    option netmask '0.0.0.0'
    option gateway '0.0.0.0'
    option metric '200'
    option table '100'

config rule
    option in 'lan'
    option src 'xx.xx.xx.249/32'
    option lookup '100'

Something like this:

VPN_GW="${ifconfig_remote}"
ip -4 route add default via $VPN_GW dev tun0 table 100

OpenVPN source based routing | Tchut-Tchut Blog

I created a route up and down script based on the guide above...
But it doesn't seem to work.

running it via console gives this output.

root@OPENWRT-ROUTER:/etc/openvpn/client/airvpn# ./route_airvpn_up.sh
Routing client xx.xx.xx.249 traffic trough AirVPN
RTNETLINK answers: File exists
Error: either "to" is duplicate, or "airvpn" is a garbage.
Error: any valid address is expected rather than "dev".

up
#!/bin/sh
#
############################
# route_up script          #
############################
# add static AirVPN routes #
############################
#
# this script adds static routes that route specific clients through AirVPN

# define clients
client_1=xx.xx.xx.249

# get tun interface config
tun_dev=$1
tun_mtu=$2
link_mtu=$3
ifconfig_local_ip=$4
ifconfig_remote_ip=$5

# add routes
# client_1
echo "Routing client $client_1 traffic trough AirVPN"
ip rule add from $client_1 priority 10 table airvpn
ip route add $client_1 dev $tun_dev table airvpn
ip route add default via $ifconfig_remote_ip dev $tun_dev table airvpn
ip route flush cache
down
#!/bin/sh
#
###############################
# route_down script           #
###############################
# remove static AirVPN routes #
###############################
#
# this script removes static routes that route specific clients through AirVPN

# define clients
client_1=xx.xx.xx.249

# get tun interface config
tun_dev=$1
tun_mtu=$2
link_mtu=$3
ifconfig_local_ip=$4
ifconfig_remote_ip=$5

# remove routes
# client_1
echo "Delete client $client_1 traffic routing through AirVPN"
ip rule del from $client_1 priority 10 table airvpn
ip route del $client_1 dev $tun_dev table airvpn
ip route del default via $ifconfig_remote_ip dev $tun_dev table airvpn
ip route flush cache

Have you declared table airvpn already in /etc/iproute2/rt_tables ?

Yes I have.

Is this a lan host?

yes it is.

Why do you route it via the tunnel?

Because it is my download-vm and I want it to route it trough my vpn provider.

What you are trying to do is to route packets towards the lan host via the tunnel.
Unless you have other networks apart from lan on the router, there is no need for adding a route other than the default.

Okay, I understand but how would my correct rule look like?

You have a rule already there.