I'd like to setup OpenVPN between a FreeBSD client and an (Arch) Linux server such that

  • All Internet-bound traffic explicitly sent from FreeBSD over the tunnel device is routed through OpenVPN


  • The default gateway/route on the FreeBSD side remains untouched.

In other words, if I do something like curl --interface tun0 example.com on FreeBSD, I want the request to example.com to be routed through OpenVPN, but if I just do curl example.com I want that to ignore the VPN tunnel.

Thus far, I've successfully established a basic connection between the two machines, and both sides can see each other.

I can go through the tunnel to fetch data from the Web server running on the remote machine:

$ curl
<!DOCTYPE html>

For completeness, I also tested what happens if I explicitly specify the interface, and it works:

$ curl --interface
<!DOCTYPE html>

$ curl --interface tun0
<!DOCTYPE html>

However, using the interface for any other host/IP fails:

$ curl --interface tun0 example.com

$ curl --interface tun0  # (the IP I got for example.com)

OpenVPN (on the FreeBSD side) doesn't print any RwRw when I do this, so I assume (and I think correctly) that FreeBSD's network stack is insufficiently configured to know how to route arbitrary traffic on tun0 through OpenVPN properly.

All the examples I've found to configure this kind of routing are Linux-specific; what do I do for FreeBSD?

I can make arbitrary changes on both the FreeBSD and Linux sides, if that makes configuration easier.

I initially intended to post this to networkengineering.stackexchange.com, but the freebsd and openvpn tags aren't defined there so I'm posting here instead.


See this answer.

For a more detailed explanation on multiple gateways see here.

The gist is to use a new routing table.

This is what I used - server being and client

echo "10 vpn" >> /etc/iproute2/rt_tables
ip route add default via dev tun0 table vpn
ip rule add from table vpn
ip rule add to table vpn
ip route flush cache

The first line should stick across reboots, but the rules will not.

Edit: A much better way to run the commands when openvpn connects is to use the up directive in the openvpn config file:

up /etc/openvpn/tun0_up.sh
  • 1
    The question is specifically about FreeBSD (which has no ip command)
    – guntbert
    Aug 4 '20 at 19:36

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.