1

I have a FreeNAS 11.3 system and followed iXsystems' instructions on setting up WireGuard. With a simple wg0.conf I'm now able to connect successfully. I'd like to be able to use this setup as a proper VPN, meaning that I can use the tunnel to browse the local network as well as the internet.

On Linux the solution is to use iptables to set up a NAT:

PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE

What is the FreeNAS/FreeBSD equivalent?

1

In addition to WireGuard also enable the FreeBSD packet filter pf using rc.conf tunables:

  • wireguard_enable="YES"
  • wireguard_interfaces="wg0"

  • pf_enable="YES"

  • pf_rules="/usr/local/etc/pf.conf"
  • pflog_enable="YES"
  • gateway_enable="YES"
  • ipv6_gateway_enable="YES"

Final set of Tunables

  • iXsystems recommends wg0.conf to live in /root and a Post Init Script to copy it to a system location then start WireGuard:

    mkdir -p /usr/local/etc/wireguard && cp /root/wg0.conf /usr/local/etc/wireguard/wg0.conf && /usr/local/etc/rc.d/wireguard start
    

By default pf is configured via /etc/pf.conf, but we need to follow the above pattern and copy /root/pf.conf to /usr/local/etc/pf.conf on startup and have pf use that.

  • Add another Post Init Script to feed pf our configuration:

    cp /root/pf.conf /usr/local/etc/pf.conf && service pf start
    

Final scripts

My pf.conf follows. WireGuard IP addresses are arbitrary on an arbitrary subnet. pf will route and NAT from this subnet to the rest of the network. I don't know of a way to do this without these arbitrary, but static, IP addresses.

# Interfaces
ext_if = "igb0"
wireguard_if = "wg0"

# Wireguard Settings
wireguard_net_v4 = "192.168.222.0/24"
wireguard_net_v6 = "fc::0/64"

# Rules must be in order: options, normalization, queueing, translation, filtering

# Options
set skip on lo

# Translation
# Nat all wireguard to non-wireguard traffic
nat on $ext_if inet  from $wireguard_net_v4 to { any, !$wireguard_net_v4 } -> ($ext_if)
#nat on $ext_if inet6 from $wireguard_net_v6 to { any, !$wireguard_net_v6 } -> {$ext_if}

# Filtering
pass inet all
pass inet6 all 

(uncomment the ipv6 NAT if your ipv6 works)

My FreeNAS server's wg0.conf:

[Interface]
PrivateKey = foofafi
ListenPort = 51820
Address = 192.168.222.1/32, fc::1/64

[Peer]
PublicKey = CLIENT1_PUBLIC_KEY
AllowedIPs = 192.168.222.2/32, fc::2/128

Laptop client configuration:

[Interface]
PrivateKey = blahblahblah
Address = 192.168.222.2/32
DNS = 1.1.1.1

[Peer]
PublicKey = SERVER_PUBLIC_KEY
AllowedIPs = 0.0.0.0/0, ::/0
Endpoint = dynamicdns.example.com:51820
PersistentKeepalive = 25

Thanks to https://gist.github.com/apearson/168b244b4735cceff9809ef3d07f4df5 for a nearly working config!

See also pf docs and this.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.