Previously in part 1, we have deployed the qBittorrent with Wireguard VPN on docker swarm. In this part, we will test the deployment, configure qBittorrent and finish the blog with the kill switch configuration

Testing

Below are the tests to make sure qBittorrent has access to the Internet through Wireguard VPN

  • ➡️Make sure Wireguard and qBittorrent containers are up and running.

  • ➡️Check you are able to ping Wireguard container from qBittorrent

    $ docker ps | grep qbittorrent | awk '{print $1, $2}'
    cd33f2b203c2 linuxserver/qbittorrent:arm64v8-4.5.2
    
    $ docker exec -it cd33f2b203c2 /bin/bash
    root@qbittorrent:/# ping wireguard
    PING wireguard (172.16.204.53): 56 data bytes
    64 bytes from 172.16.204.53: seq=0 ttl=64 time=0.312 ms
    64 bytes from 172.16.204.53: seq=1 ttl=64 time=0.375 ms
    ^C
    
  • ➡️As mentioned before, qBittorrent should not able to reach the Internet

    root@qbittorrent:/# ping google.com
    ping: bad address 'google.com'
    
    root@qbittorrent:/# ping 1.1.1.1
    PING 1.1.1.1 (1.1.1.1): 56 data bytes
    ping: sendto: Network unreachable
    
  • ➡️But should be able to access the Internet via SOCKS5 proxy

    root@qbittorrent:/# curl -v -s -x socks5://wireguard:1080 google.com
    *   Trying 172.16.204.54:1080...
    * Connected to wireguard (172.16.204.54) port 1080 (#0)
    * Could not resolve host: google.com
    * Closing connection 0
    

    Hmm, what just happened?! it has connected to the proxy(172.16.204.54:1080), but can’t resolve google.com. That’s because the Bittorrent container doesn’t have DNS config and it can’t resolve via curl which is a good thing and making sure the container doesn’t have direct access to the Internet. Then, how do we test?

    root@qbittorrent:/# curl -v -s -x socks5://wireguard:1080 1.1.1.1
    *   Trying 172.16.204.54:1080...
    * Connected to wireguard (172.16.204.54) port 1080 (#0)
    * SOCKS5 connect to IPv4 1.1.1.1:80 (locally resolved)
    * SOCKS5 request granted.
    * Connected to wireguard (172.16.204.54) port 1080 (#0)
    > GET / HTTP/1.1
    > Host: 1.1.1.1
    > User-Agent: curl/8.0.1
    > Accept: */*
    >
    < HTTP/1.1 301 Moved Permanently
    < Server: cloudflare
    < Date: Sun, 02 Apr 2023 20:03:31 GMT
    < Content-Type: text/html
    < Content-Length: 167
    < Connection: keep-alive
    < Location: https://1.1.1.1/
    < CF-RAY: 7b1bacfxxxxx4ae6-xx
    <
    <html>
    <head><title>301 Moved Permanently</title></head>
    <body>
    <center><h1>301 Moved Permanently</h1></center>
    <hr><center>cloudflare</center>
    </body>
    </html>
    * Connection #0 to host wireguard left intact
    

    Simply use IP address instead of name. Voila, it worked!!

  • ➡️Check your public. You should see, the IP address of Wireguard VPN server

    root@qbittorrent:/# HTTPBIN_ORG_IP=107.22.139.22
    root@qbittorrent:/# curl -s -x socks5://wireguard:1080 http://$HTTPBIN_ORG_IP/ip
    {
      "origin": "XX.XX.XX.XX"
    }
    

    Since we don’t have DNS config, can only use IP address. we can use httpbin.org’s IP address which is 107.22.139.22 and run curl like above and my our public IP.

Configuration

We are not done yet!, we need to configure the qBittorent client to use SOCKS5 proxy.

Go to qBittorrent UI, in my case https://192.168.0.120/qbittorent as traefik setup the reverse proxy route.

Tools -> Options

blog-14-3

Then click Connection tab and add below

  • Proxy server type SOCKS5
  • Host: wireguard (As we tested earlier, we are able to resolve and ping Wiregaurd container. So, we can use the host name here)
  • Port: 1080 (danted daemon listening port)

And select rest options you can see below

blog-14-4

Testing

We already checked our public IP address using a simple curl request to httpbin.org. Now, this test means to test the visibility of your public IP address in a torrent swarm. For this, we need to find an online service that displays our torrent public IP address just like the httpbin.org

Google “torrent ip checker”, in my case, I found https://torguard.net/checkmytorrentipaddress.php

Open the link, copy the magnet link like below and keep the tab open, we need to come back and check the out public IP address blog-14-5

And paste in qBittorrent and click download

blog-14-6 blog-14-7

Now go back to torguard.net tab, check your public IP address

blog-14-8

If you are able to see your Wireguard VPN server’s IP address, you are good to go!

Kill switch

A kill switch, also known as an emergency brake, emergency stop (E-stop), emergency off (EMO) and as an emergency power off (EPO), is a safety mechanism used to shut off machinery in an emergency, when it cannot be shut down in the usual manner.

https://en.wikipedia.org/wiki/Kill_switch

blog-14-1

In our case, qBittorent should not be able to access the Internet if the public IP address is not the Wireguard VPN server’s IP address. For this I have created to simple shell script and run as docker healthcheck

HTTPBIN_ORG_IP=107.22.139.22
MY_IP=`curl -s -x socks5://wireguard:1080 http://$HTTPBIN_ORG_IP/ip | jq --raw-output .origin`

if [ "$MY_IP" == "$VPN_IP" ];
then
  echo "$MY_IP and $VPN_IP are matched"
  exit 0
else
  echo "$MY_IP and $VPN_IP are not matched"
  exit 1
fi

To run this script, you need to pass the VPN_IP environmental variable to qBittorrent container. You can create a file .vpn_ip and add as env_file in services/torrent/docker-stack.yml#L69

cat .vpn_ip
VPN_IP=xx.xx.xx.xx

Mount the script in qBittorrent container like services/torrent/docker-stack.yml#L75

...
    volumes:
      - ./ip-test.sh:/opt/ip-test.sh
...

Add healthcheck like services/torrent/docker-stack.yml#L77-L81

...
healthcheck:
  test: ["CMD", "/opt/ip-test.sh"]
  interval: 2m
  timeout: 10s
  retries: 3
...

Ta-da!!🎉 The script will run every 2 minutes with time out of 10 seconds and 3 retries on failure. If the script exits with non-zero, the qBittorrent container will be stopped.

The issue I see with docker healthcheck is that it will only start the first healthcheck after the interval period passes. There is an open GitHub issue #33410, that’s I had to keep the interval very short i.e. 2m

Conclusion

In this post, I have shown how to route BitTorrent traffic via Wireguard VPN on the docker swarm cluster. Let’s summarize what have seen so far

In Part 1

  • Motivations to use VPN for BitTorent
  • Challenges on docker swarm with alternate options
  • Architecture and deployment of Wireguard VPN client and qBittorrent on Docker swarm

In Part 2

  • Test connection is secure
  • Configuration of qBittorrent proxy configuration
  • Configuration of kill switch