Linux P2P Podman
Jeroen  

VPN enabled podman container(s)

So you use for example a p2p bittorrent client and you want to be a good citizen so not just leeching but uploads also. Wouldn’t it be nice if you clould use p2p port forwarding with your favourite VPN provider.

Enter: gluetun

Gluetun works with a platoon of VPN providers both with openvpn and wireguard and even portforwarding is an option.

In this post I will focus on:

  • Podman
  • Proton VPN
  • Deluge bittorrent client

The trick is to use a special docker network, instead of giving deluge a dedicated or shared network you instruct it to use the network of another running container. In this case that is Gluetun configured to use:

  • a Proton VPN wireguard config you made through their website. This should provide you with a static anonymous ip address and a static port both available on the internet facing part of things and within the gluetun container.
  • P2P should be enabled
  • Bear in mind that the deluge container is exposed on the Gluetun network and also since the VPN tunnel is active there is also no need to expose any ports in Gluetun. You should however activate NAT-PMP in deluge:

In the end I made this simple docker-compose.yml to bind it all together, the most important part is this one, network_mode: “service:gluetun”:

---
services:
  gluetun:
    image: docker.io/qmcgaw/gluetun
    container_name: gluetun
    cap_add:
      - NET_ADMIN
    devices:
      - /dev/net/tun:/dev/net/tun
    environment:
      - VPN_SERVICE_PROVIDER=custom
      - VPN_TYPE=wireguard
      - VPN_ENDPOINT_IP=<vpn config public ip>
      - VPN_ENDPOINT_PORT=51820
      - VPN_PORT_FORWARDING_PROVIDER=protonvpn
      - WIREGUARD_PUBLIC_KEY=<vpn config public key>
      - WIREGUARD_PRIVATE_KEY=<vpn config private key>
      - WIREGUARD_ADDRESSES=10.2.0.2/32
      - FIREWALL_OUTBOUND_SUBNETS=192.168.0.0/16  # Internal network
      - VPN_PORT_FORWARDING=on
    networks:
      - traefik_default
    labels:
      - traefik.enable=true
      - traefik.docker.network=traefik_default
      - traefik.http.routers.deluge.rule=Host(`<your subdmomain>`)
      - traefik.http.routers.deluge.entrypoints=websecure
      - traefik.http.routers.deluge.tls=true
      - traefik.http.routers.deluge.tls.certresolver=myresolver
      - traefik.http.services.deluge.loadbalancer.server.port=8112
      - PODMAN_SYSTEMD_UNIT:gluetun.service
      - io.containers.autoupdate=registry
    healthcheck:
      test: "ping -c 1 10.2.0.1 || exit 1"
      timeout: 4s
      retries: 3    
    restart: always
  deluge:
    image: lscr.io/linuxserver/deluge:latest
    container_name: deluge
    network_mode: "service:gluetun"
    env-file: /root/secrets/deluge
    volumes:
      - /var/spool/docker-data/deluge:/config:Z
      - /data/deluge:/downloads:z
    depends_on:
      - gluetun
    labels:
      - PODMAN_SYSTEMD_UNIT:deluge.service
      - io.containers.autoupdate=registry
    restart: unless-stopped

networks:
  traefik_default:
    external:
      name: traefik_default

A couple of things to notice:

  • I use Podman and as such some options are Podman specific.
  • I use Traefik as my https loadbalancer and included that in this docker-compose.yml
  • Note: the Traefik labels are in the Gluetun section not in the Deluge one!
  • Although podman-auto-update should work just fine there is one catch: Gluetun container depends on the Deluge container, so after updating Gluetun bringing up the renewed Gluetun container again will fail if the Deluge container is still active.
  • I added a simple healthchaeck to the Gluetun service.

How you would run all of this is up to you but personally I still use:

# podman generate systemd --new <container_name> > /etc/systemd/system/<service_name>.service

I know quadlets are the way to go these days, but this still just works for me ™ 😉

Hope this can serve as a starting point for somebody out there!

Leave A Comment

n/a