Featured image of post wg-quick network namespace

wg-quick network namespace

Customizing wg-quick to create net namespaces

TL;DR

1
2
3
PreUp = ip netns list | grep -qF -- %i && ip netns delete %i || true
PostUp = (ip netns list | grep -qF -- %i || ip netns add %i) && ip -n %i link set up lo && IPS="$(ip address save dev %i | base64)" && ip link set %i netns %i && echo "$IPS" | base64 -d | ip -n %i address restore dev %i && ip -n %i link set up %i && (ip -n %i route show default | grep -qF default || ip -n %i route add default dev %i) && echo  'IyEvdXNyL2Jpbi9lbnYgc2gKc2V0IC1lCgpORVROUz0nJXMnCgpjYXQgPDxFT0YgfCB4YXJncyAtMCBzdWRvIC1FIG5zZW50ZXIgIi0tbmV0PS92YXIvcnVuL25ldG5zLyRORVROUyIgdW5zaGFyZSAtLW1vdW50IHNoIC1jCm1vdW50IC0tYmluZCAiL3Zhci9ydW4vcmVzb2x2Y29uZi9pbnRlcmZhY2VzLyRORVROUyIgL2V0Yy9yZXNvbHYuY29uZiB8fCBcCm1vdW50IC0tYmluZCAiL3Zhci9ydW4vcmVzb2x2Y29uZi9pbnRlcmZhY2UvdHVuLiRORVROUyIgL2V0Yy9yZXNvbHYuY29uZiAmJiBcCmV4cG9ydCBEQlVTX1NFU1NJT05fQlVTX0FERFJFU1M9dW5peDpwYXRoPS9kZXYvbnVsbCAmJiBcCnN1ZG8gLUUgLXUgJyMke1NVRE9fVUlEOi0kKGlkIC11KX0nIC1nICcjJHtTVURPX0dJRDotJChpZCAtZyl9JyAtLSAkQApFT0YK' | base64 -d | xargs -0 -I{} printf {} %i > /usr/local/bin/wg-%i-exec && echo  'IyEvdXNyL2Jpbi9lbnYgc2gKc2V0IC1lCgpORVROUz0nJXMnCgpjYXQgPDxFT0YgfCB4YXJncyAtMCBzdWRvIC1FIG5zZW50ZXIgIi0tbmV0PS92YXIvcnVuL25ldG5zLyRORVROUyIgdW5zaGFyZSAtLW1vdW50IHNoIC1jCm1vdW50IC0tYmluZCAiL3Zhci9ydW4vcmVzb2x2Y29uZi9pbnRlcmZhY2VzLyRORVROUyIgL2V0Yy9yZXNvbHYuY29uZiB8fCBcCm1vdW50IC0tYmluZCAiL3Zhci9ydW4vcmVzb2x2Y29uZi9pbnRlcmZhY2UvdHVuLiRORVROUyIgL2V0Yy9yZXNvbHYuY29uZiAmJiBcCnN1ZG8gLUUgLXUgJyMke1NVRE9fVUlEOi0kKGlkIC11KX0nIC1nICcjJHtTVURPX0dJRDotJChpZCAtZyl9JyAtLSB3Zy1xdWljayBkb3duICIke05FVE5TfSIKRU9GCg==' | base64 -d | xargs -0 -I{} printf {} %i > /usr/local/bin/wg-%i-down && chmod 0755 /usr/local/bin/wg-%i-* && chown root:root /usr/local/bin/wg-%i-* && echo 'TkFNRT0nJXMnCmNhdCA8PEVPRgojICDilJAg4pSsb+KUrOKUgOKUkOKUrOKUgOKUkOKUjOKUgOKUkOKUrCDilJDilKzilIDilJDilKzilIDilJDilKzilIDilJAgIOKUjOKUkOKUkOKUrOKUgOKUkOKUjOKUkOKUkOKUjOKUkOKUkOKUkOKUgOKUkAojICDilILilILilILilILilILilKzilJjilJzilIAg4pSCIOKUrOKUgiDilILilILilIDilKTilILilKzilJjilIIg4pSCICDilILilILilILilJzilIAgIOKUgiDilILilILilILilJTilIDilJAKIyAg4pSU4pS04pSY4pSY4pSY4pSU4pSY4pS04pSA4pSY4pSY4pSA4pSY4pSY4pSA4pSY4pSYIOKUmOKUmOKUlOKUmOKUmOKUgOKUmCAg4pSY4pSU4pSY4pS04pSA4pSYIOKUmCDilJjilJTilJjilIDilIDilJgKVGhhbmtzIGZvciB1c2luZyBuZXRucyB3Zy1xdWljayB3cmFwcGVyIQoKL3Vzci9sb2NhbC9iaW4vd2ctJHtOQU1FfS1leGVjIENPTU1BTkQgICAtIGV4ZWN1dGUgc2hlbGwgY29tbWFuZCBpbiAke05BTUV9IG5ldHdvcmsgbmFtZXNwYWNlCi91c3IvbG9jYWwvYmluL3dnLSR7TkFNRX0tZG93biAgICAgICAgICAgLSB1c2UgaXQgaW5zdGVhZCBvZiB3Zy1xdWljayBkb3duICR7TkFNRX0KRU9G' | base64 -d | xargs -0 -I{} printf {} %i | sh - 
PreDown = rm -f /usr/local/bin/wg-%i-* || true

Introduction

Wireguard is an amazing, simple VPN that is already included in the kernel. It’s a very powerful and straightforward tool. It is much easier to set up than OpenVPN. The utility wg-quick, which is part of the Wireguard tools, is used for its simple configuration. For a better understanding, I would like to clarify that in my experience, most solutions, such as WGDashboard and wireguard-ui, generate client configs specifically for wg-quick.

Problem Statement

To transfer the Wireguard interface into a separate network namespace for running applications. Why do this? It eliminates the need to proxy traffic to blocked websites through Wireguard using complex solutions. If you need to access somewhere, just launch another browser in the Wireguard namespace, and that’s it! For instance, I modified the Exec line in the shortcut for Thunderbird, which currently lacks a similarly functional alternative, so it always launches through the VPN and can easily collect mail from any SMTP server.

You need to use the vanilla wg-quick without modifications for this to work out of the box.

Solution Breakdown

In the documentation, there are four ways to customize the wg-quick interface: PreUp, PostUp, PreDown, PostDown. Therefore, we need to write scripts in such a way that they perform all necessary tasks. The complete solution is presented at the beginning of this article, and now let’s break it down. I will transform this compact code into a more human-readable format; it will look different but will be word-for-word identical. Note: In the code, you will find %i, which is a macro of wg

-quick that substitutes the name of the interface with the name of the configuration file.

Deleting Existing Network Namespaces

1
PreUp = ip netns list | grep -qF -- %i && ip netns delete %i || true

This line will check for existing network namespaces and delete them before creating a new one.

Creating a New Namespace

1
PostUp = (ip netns list | grep -qF -- %i || ip netns add %i)

If a new interface is defined, we create a new network namespace. We need to check first to avoid errors if the namespace already exists.

Setting Up Loopback Interface

1
&& ip -n %i link set up lo

After adding a new namespace, it’s necessary to enable the loopback interface inside the namespace so that network traffic can be handled correctly.

Restore IP Address Configuration

1
&& IPS="$(ip address save dev %i | base64)" && ip link set %i netns %i && echo "$IPS" | base64 -d | ip -n %i address restore dev %i

This command saves the interface address and restores it inside the new network namespace.

Enabling Interface and Default Route

1
&& ip -n %i link set up %i && (ip -n %i route show default | grep -qF default || ip -n %i route add default dev %i)

Here, we activate the interface inside the namespace and set up the default route for network traffic.

Running Additional Commands

1
&& echo 'IyEvdXNyL2Jpbi9lbnYgc2gKc2V0IC1lCgpORVROUz0nJXMnCgpjYXQgPDxFT0YgfCB4YXJncyAtMCBzdWRvIC1FIG5zZW50ZXIgIi0tbmV0PS92YXIvcnVuL25ldG5zLyRORVROUyIgdW5zaGFyZSAtLW1vdW50IHNoIC1jCm1vdW50IC0tYmluZCAiL3Zhci9ydW4vcmVzb2x2Y29uZi9pbnRlcmZhY2VzLyRORVROUyIgL2V0Yy9yZXNvbHYuY29uZiB8fCBcCm1vdW50IC0tYmluZCAiL3Zhci9ydW4vcmVzb2x2Y29uZi9pbnRlcmZhY2UvdHVuLiRORVROUyIgL2V0Yy9yZXNvbHYuY29uZiAmJiBcCnN1ZG8gLUUgLXUgJyMke1NVRE9fVUlEOi0kKGlkIC11KX0nIC1nICcjJHtTVURPX0dJRDotJChpZCAtZyl9JyAtLSAkQApFT0YK' | base64 -d | xargs -0 -I{} printf {} %i > /usr/local/bin/wg-%i-exec

This command will run the custom script inside the created namespace.

Cleanup

1
PreDown = rm -f /usr/local/bin/wg-%i-* || true

Finally, this command removes any scripts created during the process when the interface is brought down.

Conclusion

The provided setup allows for the convenient use of Wireguard in separate network namespaces. With this, you can easily manage connections and ensure that applications can operate within their own isolated environments. Enjoy exploring the possibilities that come with Wireguard and its integration into your networking stack!

All rights reserved
Built with Hugo
Theme Stack designed by Jimmy