• the_third@feddit.de
    link
    fedilink
    English
    arrow-up
    2
    ·
    6 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
      1
      ·
      6 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
        1
        ·
        6 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.