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.
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.
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?
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.
Edit