ipfw for gateway to share a openvpn client

I have an older working instance of ipfw with working VPN tunnel as a client of a commercial OpenVPN service and all traffic on this machine seems to be successfully going through the tunnel interface tun0. Is there a resource showing how to configure ipfw to have this machine act as a gateway so that multiple local machines can share the vpn connection. I tcpdump -i tun0 and I see the tun0 interfaces sees gateway routed traffic destined of external IPs but I do not see any responses. I think i need a ipfw nat rule but my

ipfw -q add 00100 nat 1 ip from any to any via tun0 out keep-state

Local traffic using the gateway is routed to the gateway external interface.
 
Is there a resource showing how to configure ipfw to have this machine act as a gateway
Routing is not a job for a firewall. A firewall transforms (source and/or destination NAT for example) and filters (allow or block based on certain criteria) packets, it does NOT route packets. Routing is done by the OS. You can enable (IPv4) routing by adding gateway_enable="YES" to rc.conf.
 
Is there a resource showing how to configure ipfw to have this machine act as a gateway so that multiple local machines can share the vpn connection.

The FreeBSD docs contain a pretty good guide on routing here: https://docs.freebsd.org/en/books/handbook/advanced-networking/#network-routing
+1 to SirDice, routing is not configured in the firewall.

I think i need a ipfw nat rule
Indeed, you need NAT.
If you set gateway_enable="YES" as described above, the host will forward packets to the VPN network. However, the Source IP field of the packets will contain IP addresses from your local network and the VPN server would not know where to send the response to (it does not know your LAN's IP addresses).
To work around this, when you configure NAT with ipfw, the Source IP will be replaced by your host's VPN client IP address and the VPN server knows that the response should go back to your host. When the response is received, it will again overwrite the relevant IP address in the packet so that the response is ultimately delivered to the machine that sent the initial packet.

Microsoft docs explaining how NAT works: https://docs.microsoft.com/en-us/azure/rtos/netx-duo/netx-duo-nat/chapter1
This is documentation on in-kernel NAT with ipfw: https://docs.freebsd.org/en/books/handbook/firewalls/#in-kernel-nat
 
I run an Ubuntu VM for mail on my freebsd server and am trying to setup a hub spoke vpn because my home provider doesn't support any incoming connections. I managed to get OpenVPN working and passing traffic by adding a few rules. I have not tried passing traffic between two clients yet, but so far got the client to connect and pass traffic out the server and what is my IP now shows my OpenVPN server IP when connected. I have setup my OpenVPN network to 192.168.33.0/24.

Note if you want to run a VM mail server and need to send host emails to the VM use dnsmasq and add VM IP address to hosts like...
/etc/hosts
10.33.33.33 mx.domain.net
and in
/etc/resolv.conf
nameserver 127.0.0.1

# back to OpenVPN
First do not enable redirect-gateway on the client side, a few routes are good enough, also I am using Microtik so using tcp

relevant part of client.ovpn
# explicit-exit-notify # only works with udp
verb 3
route 192.168.33.0 255.255.255.0
route 10.33.33.0 255.255.255.0
#route 192.168.0.0 255.255.0.0
#redirect-gateway local def1

relevant part of server openvpn.conf
# for the server do not enable any push routes use this line
push "redirect-gateway def1 bypass-dhcp"

/etc/sysctl.conf
#security.bsd.see_other_uids=0
vfs.zfs.min_auto_ashift=12
net.inet.ip.fw.enable=1
net.inet.ip.forwarding=1
net.inet.tcp.tso="0"
#net.inet.ip.fastforwarding=1
net.inet6.ip6.fw.enable=1

# see the last 3 lines in boot loader.conf .. I default to accept but deny in my ipfw.rules file .. been locked out too many times
relevant part of for VM and ipfw nat /boot/loader.conf
vmm_load="YES"
nmdm_load="YES"
ipfw_load="YES"
ipfw_nat_load="YES"
net.inet.ip.fw.default_to_accept="1"

relevant part of /etc/rc.conf
# IPFW FIREWALL ENABLE
firewall_enable="YES" # Set to YES to enable firewall functionality
firewall_client_net="mynetwork/mynetmask"
firewall_type="open" # Firewall type (see /etc/rc.firewall)
firewall_script="/etc/ipfw4.rules"
firewall_quiet="YES" # Set to YES to suppress rule display
firewall_logging="YES" # Set to YES to enable events logging
gateway_enable="YES"
firewall_nat_enable="YES"
firewall_nat_interface="em0"

# relevant parts of /etc/ipfw4.rules, I try to avoid disabling onepass and keep state and since the server gets heavy web traffic
#!/bin/sh
fwcmd="ipfw -q"
oif="em0"
net="myexternalnetwork/myexternalnetmask"
natnet="10.33.33.0/24"

# openvpn
vpnif="tun0"
vpnnet="192.168.33.0/24"
vpnmask="255.255.255.0"

# some loopback rules restricting to lo0

# reassemble inbound packets
# ${fwcmd} add reass all from any to any in

# redirect configuration to pass mail services to VM on 10.33.33.33
# you probably won't need this
ipfw -q nat 1 config if ${oif} same_ports unreg_only reset \
redirect_port tcp 10.33.33.33:22 55522 \
redirect_port tcp 10.33.33.33:25 25 \
redirect_port tcp 10.33.33.33:81 81 \
redirect_port tcp 10.33.33.33:143 143 \
redirect_port tcp 10.33.33.33:444 444 \
redirect_port tcp 10.33.33.33:465 465 \
redirect_port tcp 10.33.33.33:587 587 \
redirect_port tcp 10.33.33.33:993 993 \
redirect_port tcp 10.33.33.33:7071 7071

# NAT
${fwcmd} add nat 1 ip from ${natnet} to any out via ${oif}
${fwcmd} add nat 1 ip from ${vpnnet} to any out via ${oif}
${fwcmd} add nat 1 ip from any to me in via ${oif}

# Allow limited broadcast traffic from my own net.
${fwcmd} add pass all from ${net} to 255.255.255.255

# Allow any traffic to or from my own net.
${fwcmd} add pass all from me to ${net}
${fwcmd} add pass all from ${net} to me

# OPENVPN
${fwcmd} add pass all from any to ${vpnnet}
${fwcmd} add pass all from ${vpnnet} to any

# more rules like allow port 80 for the main web server
# more rules like allow ssh on port 22 from trusted addresses
# some rule to deny 22 from natnet if you don't trust the VM

# openvpn allow - use one of these depending if your using udp or tcp
${fwcmd} add pass tcp from any to me 1194 in via ${oif}
# ${fwcmd} add pass udp from any to me 1194 in via ${oif}

# Allow TCP through if setup succeeded
${fwcmd} add pass tcp from any to any established

# Allow IP fragments to pass through
${fwcmd} add pass all from any to any frag

# NATNET
${fwcmd} add allow ip from ${natnet} to any
${fwcmd} add allow ip from any to ${natnet}

# OUT OLD STYLE - probably I can get rid of keep-state here? any comments?
${fwcmd} add allow tcp from me to any setup keep-state
${fwcmd} add allow udp from me to any keep-state
${fwcmd} add allow icmp from me to any keep-state

# Global Deny
${fwcmd} add deny ip from any to any

sjohn
 
Back
Top