• the_third@feddit.de
    link
    fedilink
    English
    arrow-up
    0
    ·
    edit-2
    8 months ago

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

      • the_third@feddit.de
        link
        fedilink
        English
        arrow-up
        0
        ·
        8 months ago

        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.

        • xabadak@lemmings.world
          link
          fedilink
          English
          arrow-up
          0
          ·
          8 months ago

          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.

          • the_third@feddit.de
            link
            fedilink
            English
            arrow-up
            0
            ·
            8 months ago

            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.