this post was submitted on 06 May 2024
497 points (98.3% liked)

Technology

58155 readers
3603 users here now

This is a most excellent place for technology news and articles.


Our Rules


  1. Follow the lemmy.world rules.
  2. Only tech related content.
  3. Be excellent to each another!
  4. Mod approved content bots can post up to 10 articles per day.
  5. Threads asking for personal tech support may be deleted.
  6. Politics threads may be removed.
  7. No memes allowed as posts, OK to post as comments.
  8. Only approved bots from the list below, to ask if your bot can be added please contact us.
  9. Check for duplicates before posting, duplicates may be removed

Approved Bots


founded 1 year ago
MODERATORS
you are viewing a single comment's thread
view the rest of the comments
[–] [email protected] 4 points 4 months ago* (last edited 4 months ago) (1 children)

When I design something, critical applications get their own network namespace with only the VPN interface inside anyway. So, yeah.

[–] [email protected] 2 points 4 months ago (3 children)
[–] [email protected] 3 points 4 months ago

i think docker allows for this configuration. i use a gluetun container for the network definition of the torrent container to prevent leaking. the torrent container knows of no other network than the vpn container.

[–] [email protected] 2 points 4 months ago (2 children)

There's readily available docker containers for it but I wanted to build it by hand. Well, more or less, Extremely hacky but it works, so fine for me.

I started out with cheating and used this wrapper around wg-quick that gives us a persistent network namespace with the tunnel interface in it:

https://github.com/dadevel/wg-netns

cat /etc/systemd/system/wg-qbittorrent.service
[Unit]
Description=WireGuard Network Namespace for qBittorrent
Wants=network-online.target nss-lookup.target
After=network-online.target nss-lookup.target

[Service]
Type=oneshot
Environment=WG_ENDPOINT_RESOLUTION_RETRIES=infinity
Environment=WG_VERBOSE=1
ExecStart=/opt/wg-netns/bin/wg-netns up /etc/wireguard/wgconfig.yaml
ExecStop=/opt/wg-netns/bin/wg-netns down /etc/wireguard/wgconfig.yaml
RemainAfterExit=yes

WorkingDirectory=%E/wireguard
ConfigurationDirectory=wireguard
ConfigurationDirectoryMode=0700

CapabilityBoundingSet=CAP_NET_ADMIN CAP_SYS_ADMIN
LimitNOFILE=4096
LimitNPROC=512
LockPersonality=true
MemoryDenyWriteExecute=true
NoNewPrivileges=true
ProtectClock=true
ProtectHostname=true
RemoveIPC=true
RestrictAddressFamilies=AF_INET AF_INET6 AF_NETLINK
RestrictNamespaces=mnt net
RestrictRealtime=true
RestrictSUIDSGID=true
SystemCallArchitectures=native

[Install]
WantedBy=multi-user.target

Then I built a static binary of qbittorrent using this really neat docker image: https://github.com/userdocs/qbittorrent-nox-static

...and stuffed the result into a systemd service that runs it in the namespace wg-netns provides:

cat /etc/systemd/system/qbittorrent-nox.service 

[Unit]
Description=qBittorrent-nox service
Wants=network-online.target wg-qbittorrent.service 
After=local-fs.target network-online.target nss-lookup.target wg-qbittorrent.service 

[Service]
Type=simple
PrivateTmp=false
#User=qbittorrent
ExecStart=/usr/sbin/ip netns exec ns-qbittorrent sudo -u qbittorrent /opt/qbittorrent/qbittorrent-nox
TimeoutStopSec=1800
RestartSec=15
RestartMaxDelaySec=600
RestartSteps=10
Restart=always

[Install]
WantedBy=multi-user.target

To get the webui out of that I stuck two instances of socat together at the stdout and from there it depends on whatever you want to use as a reverse proxy on the host - or you bind to a network interface if you trust the network:

cat /etc/systemd/system/qbittorrent-webui.service 
[Unit]
Description=qBittorrent-nox webui forwarding into its namespace
Wants=network-online.target wg-qbittorrent.service 
After=local-fs.target network-online.target nss-lookup.target wg-qbittorrent.service 

[Service]
Type=simple
PrivateTmp=false
ExecStart=/opt/qbittorrent/forward-webinterface.sh
TimeoutStopSec=1800
Restart=always
RestartSec=10

[Install]
WantedBy=multi-user.target
cat /opt/qbittorrent/forward-webinterface.sh
#!/bin/sh
set -eu

exec socat tcp6-listen:"8080",reuseaddr,fork,range=[::1]/128 "exec:ip netns exec ns-qbittorrent socat stdio 'tcp-connect:127.0.0.1:8080',nofork"

Works, is reboot safe, stopped caring about beauty at that point.

[–] [email protected] 1 points 4 months ago

This is so cool, thank you!

[–] [email protected] 1 points 4 months ago (1 children)

Do you know how to make it so all the host's traffic is sent through the VPN namespace? I couldn't figure out how to do this so I ended up just writing my own firewall. Network namespaces seems like a better solution.

[–] [email protected] 1 points 4 months ago (1 children)

I haven't found the time to research an answer for you, sorry. The way I'd go is: create a veth of your physical uplink and stuff it into its own namespace with dhcp client and wg userspace tools. Do not configure the original interface in your initial namespace. Use the approach wg-netns uses to spawn the tunnel interface in initial network ns. Done.

[–] [email protected] 1 points 4 months ago

No worries, and thanks for providing a response nonetheless. I'll look into your suggestion when I have the time. The official Wireguard website also had some guide on network namespaces here but afaik it didn't explain how to set it up persistently