qBitMF: Use qBittorrent over multiple VPN connections at once in Docker!

qBittorrent running over THREE Mullvad connections!

I’ve built a tool some people might be interested in called qBitMF (qBittorrent-MultiFace): https://github.com/qBitMF/qBitMF

It’s a modified version of qBittorrent that balances torrent connections over multiple VPN servers, which means if you have a fast internet connection, this stops you from being limited by the speed of one (potentially overloaded) VPN server. And because qBitMF uses qBittorrent and WireGuard, both of which are very efficient, you should be able to max out even the fastest internet connections with this!

-–

(overly nerdy stuff follows)

This started out as an experiment to see if it was possible to get any torrent client to run over multiple VPN connections at once. After much research and exploration, I discovered two features in Linux that enabled this: network namespaces, and multipath routing.

Network namespaces completely isolate qBittorrent from the internet, and thus no kill switch is required: it has no access to any “real” interfaces, including DNS or even the ability to figure out a local IP address. It only has access to WireGuard network interfaces and that’s it.

Multipath routing balances outgoing connections between multiple interfaces, and chooses the interface based on the IPs and ports of a given connection via hashing, which both balances usage of interfaces, but also makes sure the packets of any specific connection always goes through the same interface.

Incoming connections was another issue to overcome. Since a listening port only exists on one interface, the multipath routing would often try to respond on a different interface, which would break connections. I found that by using a specific network setting in libtorrent (SO_BINDTODEVICE), I could make incoming connections ignore the hashing that multipath routing uses. That way, if an incoming connection comes in on one interface, it stays on that interface.

Finally, I put it all in docker because that’s the easiest way to distribute a fully-functioning system. Of course, due to all the OS-specific functionality being used, this will only work on Linux. I wouldn’t even know where to begin building something like this for Windows.

-–

Anyways, hope people find this tool to be useful!

If I have to summarize, you can combine multiple networks using vanilla wireguard to create one gigantic bandwidth pool for qbit consumption, right?

Very cool :folded_hands: what kind of speed gains are you seeing with this?

also, I know you recommended 2-3 interfaces to begin with - but have you tried more?

How does this work with private trackers that limit users to one IP?

This is very slick

I might have to give this a try

On a side note with Mullvad - do you find that you’re unable to connect to the RARBG trackers?

I can’t connect to them from any Mullvad IP

For the sake of security I hope you change https://github.com/qBitMF/qBitMF/blob/master/README.md?plain=1#L29 that doesn’t display the key, or generate a new one if you have that key in production.

KDE user eh? Me too (EndeavourOS)

I wouldn’t even know where to begin building something like this for Windows

I don’t think you could. Even if you go through the headache of setting up WSL and so forth I think even that has limitations.

It’s a bit messy to shove everything into one docker container like it’s a vm or something. Would be much cleaner to isolate wireguard and qbittorrent to their own containers and use docker network to connect them. This way you can also plug in more containers if needed to the same wireguard, which is nice.

Does it work with open vpn? Also im noob can you guide me

This is exactly the kind of thing I’ve been looking for! Configuring a Docker container with a VPN and qBittorrent is a pain

This is really awesome, would you be up for seeing if it’s possible to add compatibility with other popular VPN services like Proton, Nord, etc.?

Amazing work, I’d love to test it and already share with some friends.

Question, Are you thinking in publish the docker image?

This is excellent. Maybe you can add a proxy server in docker image, like tiny proxy or similar. This way you can configure web browser for example, and surf the internet through VPN connection.

Really cool stuff. I’ve been experimenting with isolated qbittorrent using docker + netns too very recently. Your setup seems nice, but I was wondering whether it would be feasible to alter it such that you wouldn’t have to run the container in privileged mode? For my setup specifically I’m launching the container with --network=none and then creating and moving the wg interface into that container’s namespace from the host. To connect to the webui, I’m simply creating a veth interface. This seems safer to me since, as far as I can tell (feel free to correct me), without --privileged the container would not be able to break itself out of its namespace.
And the veth interfaces don’t get any traffic routed through them apart from the webui access (no special routes and no firewall entries for nat so packets shouldn’t be able to escape the container through veth).

Another idea for portability reasons would be to have the privileged container launch another one that is not privileged if that’s possible.

Edit: I’ve noticed that you were running start-unpriv as abc. I guess that alleviates the problem for the most part, but still. Also I think I prefer your solution with socat over mine with a veth interface next to wg.

Maybe I’m missing something but this is all within docker, So why wouldn’t it work within docker under windows?

Whoa this seems like really good work and could probably have ever wider implications for use!

I have a few questions though:

  1. would this work inside a Linux VM?

  2. is there even any benefit to running torrents inside a VM?

  3. will this work with other VPN’s?

Do you find it improving seeding speeds also?

This is very cool but I would want to know why you chose this way with multipath?

Ideally libtorrent would support binding to and listening on multiple interfaces. Since it appears to generate separate random peer IDs for IPv4 and IPv6, some of the required steps were already done. Then libtorrent would need to treat different interfaces as equal and parallelize network transfers across them.

Since a listening port only exists on one interface

This is sort of what I meant above. To extend libtorrent to work flawlessly on more than one interface.

Cool! Never thought of that.

Regarding incoming traffic and routing, I think this could also be handled using a combination of connection tracking + marking (iptables/netfilter) and policy-based routing. And you could also adjust the multipath route weights to compensate for the fact that the interface over which incoming connections are established is used more because of that. So, maybe a 40/40/20 split makes sense.

Would qBT try to connect to itself over the other IP addresses? :thinking: I guess so. But there’s no harm because it cannot offer itself a block that it’s interested in. :rofl:

been looking for something like this!!

Thanks!

I am assuming this will fail if your VPN provider does not offer a method to specify an incoming port (I am not aware of a wireguard way with PIA)?