making netbsd wg(4) sing

#author_luna #sysadmin-notes #netbsd #wireguard

read netbsd's docs first

i wanted to make our ephemeral vpn tool work with netbsd 10.0 RC1's new wg(4) interface that is wireguard compatible. while the instructions on the manual page work for tunneling any range, it doesn't work for full tunneling AKA 0.0.0.0/0.

i did not know how network routing actually worked, which made this process take a couple of hours spread over 3 days, but i got something!

the approach linux and freebsd take is to have "two default routes with different weights", in linux's case, that's achieved through multiple routing tables (source on reddit, wg-quick permalink), for freebsd, that's achieved through a mechanism i don't actually understand yet. i only see 0.0.0.0/1 and default as routes in the main routing table, and somehow that works. that doesn't work for netbsd, as 0.0.0.0/1 cuts off half of the v4 addresses, and trying to keep both default and 0.0.0.0/0 routes causes the system to lock up for 1~2 minutes (i wonder if we could create a netbsd patch that prevents that type of routing table to be created... don't know how, but still).

after having a realization on the last couple of hours, i attempted to switch out the default route:

and that works!

luna@agent47 ~/bbv-cli (netbsd-support)> uname -a
NetBSD agent47.agent47 10.0_RC1 NetBSD 10.0_RC1 (GENERIC) <a href="/wiki/_/tags/0.html">#0</a>: Sun Nov  5 18:30:08 UTC 2023  mkrepro@mkrepro.NetBSD.org:/usr/src/sys/arch/amd64/compile/GENERIC amd64

without vpn

luna@agent47 ~/bbv-cli (netbsd-support)> curl ipinfo.io
{
  "org": "... my ISP ...",
}⏎

with vpn


luna@agent47 ~/bbv-cli (netbsd-support)> curl ipinfo.io
{
  "org": "AS24940 Hetzner Online GmbH",
}⏎

since the tool that creates the ephemeral vpn spits out a wg-quick file, i wrote a simple tool that turns it into netbsd commands, and does the relevant routing table switch: https://gitlab.com/bigbigvpn/bbv-cli/-/blob/e328eaa26a9e9dc35eeb55568639df9c2fa405ed/wg4-quick. just in case, here it is as well (replace 1.1.1.1 with your endpoint, and 8.8.8.8 with the address of the wg interface)

# prevent dhcpcd from switching out the default
/etc/rc.d/dhcpcd stop
current_default=$(route show | grep default | awk '{print $2;}')
# move the default ONLY to the endpoint
route add -net "1.1.1.1" -netmask 255.255.255.255 "$current_default"
# then switch defaults :)
route delete default "$current_default"
route add default "8.8.8.8"

# enjoy your full tunnel!

# then, when you're done, revert the tables back to normal
ifconfig wg0 destroy
/etc/rc.d/dhcpcd start
route delete -net "1.1.1.1" -netmask 255.255.255.255