Blog — nicoco.fr

How I use WireGuard selectively

2023-09-10 subscribe to my blog's atom feed

There are quite a number of online guides about how to hide your real IP and/or access online services your network provider normally does not allow (but it needs to allow WireGuard, which is not always the case). Most of them focus on 2 use cases: either routing all your traffic through WireGuard or accessing a private network from outside of it.

How about using WireGuard for certain softwares or websites only? If you know your way through iptables, network-manager and the likes, there are probably many options, but I'll share here what my setup is.

No table!

This is probably trivial to some of you, but my first issue was that I wanted to set up the WireGuard network interface, but not use it by default. I am not alone, and found out that the key was to add "Table = off" to the [interface] section of the config, eg:

[Interface]
PrivateKey = ***
Address = x.x.x.x/32,x:x:x:x::x:x/128
Table = off  # <- this is the important part

[Peer]
PublicKey = ***
AllowedIPs = 0.0.0.0/0,::0/0
Endpoint = wireguard-server.example.lol:51820

NB: unlike in most example setups you can find online, I also removed the DNS line because I'm fine not making DNS requests through wireguard but depending on what you are trying to achieve, this might not be OK for you.

If you use a software that allows you to choose which network inteface it uses, like curl or qbittorrent, this is all you need! But wait, most software do not let you choose it, so what to do for others? I do not have a general answer to that, but apparently it is possible with black magic/network namespaces incantations. But I didn´t really need that, instead what I needed was to make a container use the WireGuard interface exclusively.

Awesome internet strangers to the rescue

It turns out this is not easily doable with podman, but the internet is a wonderful place (sometimes). When I asked on unix.stackexchange, an awesome stranger came up with a little C program to use in conjunction with LD_PRELOAD to achieve what I wanted.

After downloading and building it following the instructions given by this awesome stranger, place bindtodevicewrapper.so in /usr/local/lib, save the following script as /usr/local/bin/podman-wg and make it executable.

#!/bin/sh
INTERFACE=$1
shift

WRAPPER_BINDTODEVICE=$INTERFACE \
WRAPPER_INET=$(ip -4 -json addr show dev $INTERFACE | jq -r '.[].addr_info[0].local') \
LD_PRELOAD=/usr/local/lib/bindtodevicewrapper.so \
podman run --network=slirp4netns:outbound_addr=$INTERFACE "$@"

You can now launch a container that will use the WireGuard interface wg0 to communicate with the outside world using podman-wg wg0 [podman-options…].

Now, what if we want to access certain websites exclusively through this network interface?

FoxyProxy is your friend

With the FoxyProxy Firefox extension, you can define rules to use a proxy for certain websites. But how do you turn your network interface into a proxy for Firefox?

There is wireproxy, which seems nice but as far as I understood, this does not re-use your existing interface. I looked for something simpler and found soks. It does not look maintained anymore, but it may be because it's simple and just works? Anyway, it seemed to work fine for my use-case, so after building it with make, I placed the soks binary in /usr/local/bin and built a minimal systemd unit like this:

[Unit]
Description=Soks

[Service]
# replace wg0 with the wireguard interface you want,
# and the ip with your local network IP (eg 192.168.0.1)
# if you want other devices in your local network to be
# able to use this proxy
ExecStart=/opt/soks/soks -i wg0 -l 127.0.0.1 -p 9784

[Install]
WantedBy=multi-user.target

A little systemctl start --enable soks, add a new proxy SOCKS5 in FoxyProxy with the address 127.0.0.1:9784, define rules for some websites, and you're good to go!

It took me a little time to gather wrap my head around all of these, and I hope some of you will find it useful. I am not a security expert at all, so if something's bad in these advice, please contact me so I can correct this page and try to limit the damage I've done.