IPFW Route all traffic to vpn

I'm running Freebsd 13.1 on raspbery pi and trying to setup it as router server for home network. Pi box has two network cards
ue0 and ue1. First one connected to internet and second is for lan users. When openvpn up on eu0 it suppose to go to ue1 too, therefore lan users getting openvpn connection ip. I was able to achieve desired aim on Linux with iptables, and wish to do the same on freebsd with ipfw.
Linux
Code:
#!/bin/bash
IPTABLES="/sbin/iptables"


$IPTABLES -t nat -A POSTROUTING -o ue0 -j MASQUERADE
$IPTABLES -A FORWARD -i ue0 -o ue1 -m state --state RELATED,ESTABLISHED -j ACCEPT
$IPTABLES -A FORWARD -i ue1 -o ue0 -j ACCEPT

#VPN
$IPTABLES -t nat -A POSTROUTING -o tun0 -j MASQUERADE
$IPTABLES -A FORWARD -i tun0 -o ue1 -m state --state RELATED,ESTABLISHED -j ACCEPT
$IPTABLES -A FORWARD -i ue1 -o tun0 -j ACCEPT

How to adapt it to ipw?
 

SirDice

Administrator
Staff member
Administrator
Moderator
 

cy@

Developer
Rather than policy based routing do the following:

Code:
route add default YOUR_VPN_IP -fib 1
ifconfig INTERNAL_IF fib 1

This creates a second routing table at fib 1, which is assigne d to your internal interface.

To display FIB 1,

Code:
setfib 1 netstat -nr4

To display your default FIB (routing table, FIB 0), simply use netstat.

Before you can use alternate FIBs (routing tables), you will need to add net.fibs to loader.conf and reboot. My firewall uses net.fibs="5".
 
This creates a second routing table at fib 1, which is assigne d to your internal interface.
I tried to set another routing table. Network is working and tun0 up, anyway getting
Code:
route add default 10.8.0.1 -fib 1
route: writing to routing socket: Network is unreachable
add net default: gateway 10.8.0.1 fib 1: Network is unreachable

/boot/loader.conf
Code:
net.fibs="2"



ifconfig -a
Code:
ue0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
        options=80009<RXCSUM,VLAN_MTU,LINKSTATE>
        ether b8:27:eb:9f:19:56
        inet 192.168.1.15 netmask 0xffffff00 broadcast 192.168.1.255
        media: Ethernet autoselect (100baseTX <full-duplex>)
        status: active
        nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL>
ue1: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
        options=80008<VLAN_MTU,LINKSTATE>
        ether 34:76:c5:08:0b:3f
        inet 172.16.1.1 netmask 0xffffff00 broadcast 172.16.1.255
        media: Ethernet autoselect (100baseTX <full-duplex>)
        status: active
        nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL>
tun0: flags=8051<UP,POINTOPOINT,RUNNING,MULTICAST> metric 0 mtu 1500
        options=80000<LINKSTATE>
        inet 10.8.0.3 --> 10.8.0.1 netmask 0xffffff00
        inet6 fddd:1194:1194:1194::1001 prefixlen 64
        inet6 fe80::ba27:ebff:fe9f:1956%tun0 prefixlen 64 scopeid 0x4
        groups: tun
        nd6 options=21<PERFORMNUD,AUTO_LINKLOCAL>
        Opened by PID 1267

netstat -nr

Routing tables

Code:
Internet:
Destination        Gateway            Flags     Netif Expire
0.0.0.0/1          10.8.0.1           UGS        tun0
default            192.168.1.1        UGS         ue0
10.8.0.0/24        10.8.0.1           UGS        tun0
10.8.0.1           link#4             UH         tun0
10.8.0.3           link#4             UHS         lo0
127.0.0.1          link#1             UH          lo0
128.0.0.0/1        10.8.0.1           UGS        tun0
172.16.1.0/24      link#3             U           ue1
172.16.1.1         link#3             UHS         lo0
178.30.200.90      192.168.1.1        UGHS        ue0
192.168.1.0/24     link#2             U           ue0
192.168.1.15       link#2             UHS         lo0
Internet6:
Destination                       Gateway                       Flags     Netif Expire
::/96                             ::1                           UGRS        lo0
::/3                              link#4                        US         tun0
::1                               link#1                        UHS         lo0
::ffff:0.0.0.0/96                 ::1                           UGRS        lo0
2000::/4                          link#4                        US         tun0
3000::/4                          link#4                        US         tun0
fc00::/7                          link#4                        US         tun0
fddd:1194:1194:1194::/64          link#4                        U          tun0
fddd:1194:1194:1194::1001         link#4                        UHS         lo0
fe80::/10                         ::1                           UGRS        lo0
fe80::%lo0/64                     link#1                        U           lo0
fe80::1%lo0                       link#1                        UHS         lo0
fe80::%tun0/64                    link#4                        U          tun0
fe80::ba27:ebff:fe9f:1956%tun0    link#4                        UHS         lo0
ff02::/16                         ::1                           UGRS        lo0

178.30.200.90 external ip address obtained via tun0
192.168.1.1 ue0 gateway ip connected to Internet
172.16.1.1 ue1 internal lan ip

/etc/rc.conf
Code:
hostname="freebsdPI"
ifconfig_ue0="DHCP"
ifconfig_ue1="inet 172.16.1.1 netmask 255.255.255.0"

#
gateway_enable="YES"
firewall_enable="YES"
firewall_nat_enable="YES"
firewall_logging="YES"
natd_enable="YES"
natd_interface="ue0"

##
dnsmasq_enable="YES"
sshd_enable="YES"

Actually i was able to do simple NAT with below ipfw rules. But i need ue1 clients pass through tun0 without knowing about vpn.

Code:
#!/bin/sh
wan="ue0"
lan="ue1"
wan_int="dhcpd"
lan_int="172.16.1.1"
ipfw="/sbin/ipfw -q"

#Reset all rules:
${ipfw} -f flush
${ipfw} -f pipe flush
${ipfw} -f queue flush

${ipfw} add allow ip from any to any via lo0
${ipfw} add deny ip from any to 127.0.0.0/8
${ipfw} add deny ip from 127.0.0.0/8 to any

${ipfw} add divert natd ip from any to any via ue0
${ipfw} add allow ip from any to any
 
Rebooted box, started openvpn connection.

Code:
# setfib 1 netstat -nr4
Routing tables (fib: 1)

Internet:
Destination        Gateway            Flags     Netif Expire
127.0.0.1          link#1             UHS         lo0

# setfib 0 netstat -nr4
Routing tables

Internet:
Destination        Gateway            Flags     Netif Expire
0.0.0.0/1          10.8.0.1           UGS        tun0
default            192.168.1.1        UGS         ue0
10.8.0.0/24        10.8.0.1           UGS        tun0
10.8.0.1           link#4             UH         tun0
10.8.0.3           link#4             UHS         lo0
127.0.0.1          link#1             UH          lo0
128.0.0.0/1        10.8.0.1           UGS        tun0
172.16.1.0/24      link#3             U           ue1
172.16.1.1         link#3             UHS         lo0
178.30.200.90      192.168.1.1        UGHS        ue0
192.168.1.0/24     link#2             U           ue0
192.168.1.15       link#2             UHS         lo0

# route add default 10.8.0.1 -fib 1
route: writing to routing socket: Network is unreachable
add net default: gateway 10.8.0.1 fib 1: Network is unreachable
 
If the subnet of your local network doesn't overlap with the subnet of the remote network it will be easy to create site-to-site vpn with routing instead of using NAT.
 
If the subnet of your local network doesn't overlap with the subnet of the remote network it will be easy to create site-to-site vpn with routing instead of using NAT.
it's good to have both options. Subnet of my local network is not overlapped with remote one.
 
you don't need fibs
you just need a route + iroute on the server end for your lan ips (or nat on the vpn client side over tun0)
openvpn server already pushes default route thru vpn (see the /1) entries
the problem is the server end hosts dont know how to reply to your vpn client LAN ips (there is no route/iroute to them)
 
you don't need fibs
Yes, the working ipfw rules below. No need enable natd, no need second fib.

Code:
${ipfw} nat 1 config log if tun0 reset same_ports deny_in
${ipfw} add allow ip from me to any via ue0
${ipfw} add allow ip from any to me via ue0
${ipfw} add deny ip from 172.16.1.0/24 to any via ue0
${ipfw} add deny ip from any to 172.16.1.0/24 via ue0
${ipfw} add nat 1 ip from any to any via tun0

Removed these lines from rc.conf

Code:
natd_enable="YES"
natd_interface="ue0"

ipfw show

Code:
# ipfw show
00100  703 122599 allow ip from me to any via ue0
00200  769 254365 allow ip from any to me via ue0
00300    0      0 deny ip from 172.16.1.0/24 to any via ue0
00400    0      0 deny ip from any to 172.16.1.0/24 via ue0
00500 1004 281632 nat 1 ip from any to any via tun0
65535 1847 448672 allow ip from any to any

Now its working as expected, ue1 clients getting internet via tun0 and freebsd server also.

The only culprit i found that i need to apply ipfw rule set after tun0 is up otherwise getting error
Code:
# ./firewall.sh
ipfw: unknown interface name tun0

Also i tested autoload ipfw rules after system boot by adding firewall_script="/root/firewall.sh" to rc.conf. IPFW rules apply but it blocks all traffic, for instance ping
Code:
# ping 8.8.8.8 PING 8.8.8.8 (8.8.8.8): 56 data bytes
ping: sendto: Permission denied

To overcome this behavior i added ipfw script to crontab with delayed start after vpn connection.
Code:
@reboot /usr/local/sbin/openvpn --daemon --config /root/kimsufi.ovpn && sleep 5 && /root/firewall.sh
 
you can add/remove rules from openvpn if-up / if-down scripts
then you can switch nat from tun to ethernet and vice/versa
those scripts may need sudo/doas as im not sure they are run as root or as the openvpn user
 
Top