Now also available via Tor
http://iwccx6ebuapto7dlkd4m5fooud6nqn2z7go7aass5c4q6vl6gzs5htad.onion/
Einträge
DN42: Put it in a box (Linux network namespace)
What did I do the previous week? What robbed me of my sleep at night, keeping my thoughts churning? Let’s look at “doing containers the hard way”.
For some time, I had CPU usage problems on my VPS. Looking at
htop
, I always saw two bird instances and dnsmasq as “offenders”. (I run both my clearnet AS as well as my DN42 AS on this box) 1. I was originally going to write a blog article about that, but it’s still in my drafts folder. Here’s the gist:- All these processes receive “netlink messages”.
- Probably the IBGP session for my AS generates lots of these netlink messages.
- The other bird process (for DN42) and dnsmasq suffer from it.
One possible solution is to put the processes into a container (Docker, Podman, LXC, LXD, Incus, …). However, I’m on a budget. I have only 40 GB of storage on my Hetzner VPS and don’t want to waste it with duplicate file systems. However, I can use the technology these container (runtimes/engines) use: Linux namespaces.
I won’t cover the basics here. There are other blog articles from other people who are far better at explaining that (e.g. from anracon).
Suffice to say, I can put DN42 in a box, which put the network in isolation. To a degree. I still need to communicate with the outside world. I dumped my setup in a git repo.
jamesits provides some nice templates for setting up a network namespace. I used that template, but tweaked some parts to they suit me better 2. Also, using the Debian systemd files, I manually created new ones and made sure the processes use the separate namespace. I admit to never having particularly liked systemd, but at least the service manager is pretty nice.
I also felt pretty clever coming up with this setup script which gets called by systemd and then calls itself again, but in the newly created namespace.
Inside the namespace run:
- The Wireguard interfaces to my peers,
- Tinc (which I only have because I want to have a broadcast-capable VPN),
- PowerDNS (a separate instance from “the outer VPS one”, serving my DN42 domain),
- BIRD2,
- And a looking glass
Outside the namespace run:
- dnsmasq, which allows me to resolve my DN42 domains “from the clearnet” (from within a Wireguard net)
- Nginx, which serves my DN42 website
It took me a while and some internet searches to come up with the firewall rules. On my VPS itself I use ufw, for the network namespace, I could probably make this work as well, but I decided to use “iptables”, or rather, the wrapper scripts which provide the same syntax but use nftables in the background. This is because with this namespace separation, I don’t have to worry about “cross-leaking” network traffic between DN42 and the clearnet. So the rules get a lot simpler
I was happy that both DNS and the website work, when I realized that the default policy for FORWARD was ALLOW. I found it suitable to set it to DROP, and suddenly, it didn’t work anymore, because I was employing destination NAT:
*nat -A PREROUTING -d fd3e:bc05:2d6::80/128 -p tcp --dport 80 -j DNAT --to-destination fcee::1 -A PREROUTING -d fd3e:bc05:2d6::80/128 -p tcp --dport 443 -j DNAT --to-destination fcee::1
This is because the webserver is running on the “outer” VPS, not in the network namespace (hey, it took me long enough to finish this up as it is). This is probably a relatively small adjustment.
With an additional forward rule, everything is happy again:
*filter -A FORWARD -s fd00::/8 -d fcee::1/128 -j ACCEPT -A FORWARD -s fcee::1/128 -d fd00::/8 -j ACCEPT
Also, I also feel pretty clever for making sure I can access DN42 from my clearnet:
*mangle -A PREROUTING -i eth0 -j MARK --set-mark 0x4242 COMMIT *nat -A POSTROUTING -d fd00::/8 -m mark --mark 0x4242 -j MASQUERADE COMMIT
I am actually not sure if the latter needs an “-i (all wg interfaces)” or “! -i (internal interfaces)” to avoid unnecessary NATting for when I access a service in the namespace. But nevertheless, I achieved a working state. Best of all, I can reuse some of the work if I ever want to put my clearnet AS in a namespace, too.
-
An AS is in “autonomous system”, DN42 is a “lab environment” for networking. ↩
-
For example, I have no idea why they unmount and mount the netns path manually. Probably this fixes some bug of an old systemd version? ↩