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
proxyroot@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 viacurl
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
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
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
And paste in qBittorrent and click download
Now go back to torguard.net
tab, check your public IP address
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.
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