With the Raspberry Pi 4, it’s possible to set up a container to handle a VPN connection, Transmission for playing with Torrents and a web proxy with decent performance and speed.

Samba container

Using the SD card to store the torrents is probably not a good idea and it’s better to use an old external drive. Start by formatting the drive with ext4 filesystem without allocating any space for the root user and add it to your /etc/fstab

$ export SSD_PARTITION=/dev/sda1
$ export SSD_MOUNTPOINT=/mnt/lexar

$ sudo mkfs.ext4 -m 0 ${SSD_PARTITION}
$ export SSD_PARTITION_UUID=$(blkid ${SSD_PARTITION} -o export | grep "^UUID=")
$ echo "${SSD_PARTITION_UUID} ${SSD_MOUNTPOINT} ext4 noatime,defaults 0 2" | sudo tee -a /etc/fstab > /dev/null

$ sudo mkdir ${SSD_MOUNTPOINT}
$ sudo mount ${SSD_MOUNTPOINT}

Configure a docker-compose.yml file to expose a Samba share

$ export SAMBA_USER=user
$ export SAMBA_PASSWORD=password

$ mkdir /opt/docker/samba && cd /opt/docker/samba
$ tee docker-compose.yml > /dev/null << EOF
version: "3"

services:
  samba:
    image: stefanscherer/rpi-samba:4.7.6
    hostname: $(hostname)
    ports:
      - 137:137/udp
      - 138:138/udp
      - 139:139
      - 445:445
    restart: unless-stopped
    volumes:
      - ${SSD_MOUNTPOINT}:/share/ssd
    command: '-s "SSD:/share/ssd:rw:${SAMBA_USER}" -u "${SAMBA_USER}:${SAMBA_PASSWORD}"'

networks:
  default:
    external:
      name: br0
EOF

$ chmod o-r docker-compose.yml

Express VPN

I use Express VPN and this provider is not supported out of the box by docker-transmission-openvpn container (supported providers). The first step is to retrieve the required credentials and an OpenVPN profile to configure the container.

Visit Express VPN setup page on https://www.expressvpn.com/setup (you can subscribe to Express VPN using this referral link)

  1. Click on Manual config

  2. Select OpenVPN (should be the default)

  3. Copy the username in a secure place

  4. Copy the password in a secure place

  5. Download the ovpn profile for the location you want to use

Express VPN setup

Container configuration

Create a docker-compose.yml file with the complete configuration.

$ export EXPRESS_VPN_PROFILE=DOWNLOADED_OVPN_PROFILE.ovpn
$ export TORRENTS_STORAGE=/mnt/lexar/Torrents

$ mkdir /opt/docker/vpn-torrent-proxy && cd /opt/docker/vpn-torrent-proxy
$ tee docker-compose.yml > /dev/null << EOF
version: "3"

services:
  transmission:
    image: haugene/transmission-openvpn:latest-armhf
    ports:
      - 3128:3128
    environment:
      - OPENVPN_PROVIDER=CUSTOM
      - OPENVPN_USERNAME=NONE
      - OPENVPN_PASSWORD=NONE
      - LOCAL_NETWORK=192.168.1.0/24
      - CREATE_TUN_DEVICE=true
      - OPENVPN_OPTS=--inactive 3600 --ping 10 --ping-exit 60
      - WEBPROXY_ENABLED=true
      - WEBPROXY_PORT=3128
      - TRANSMISSION_RATIO_LIMIT_ENABLED=true
      - TRANSMISSION_RATIO_LIMIT=2
    volumes:
      - /etc/localtime:/etc/localtime:ro
      - ./${EXPRESS_VPN_PROFILE}:/etc/openvpn/custom/default.ovpn
      - ./${EXPRESS_VPN_PROFILE}_credentials:/etc/openvpn/custom/${EXPRESS_VPN_PROFILE}_credentials
      - ${TORRENTS_STORAGE}:/data
    cap_add:
      - NET_ADMIN
    # Disable ipv6 inside the container to avoid any address leak
    sysctls:
      - net.ipv6.conf.all.disable_ipv6=1
    restart: always # Always required for autoreload when connection is lost

networks:
  default:
    external:
      name: br0
EOF

Copy the ovpn profile to /opt/docker/vpn-torrent-proxy/ and add the auth-user-pass option to enable autoconnect.

$ export EXPRESSVPN_USERNAME=username
$ export EXPRESSVPN_PASSWORD=password

$ echo "auth-user-pass /etc/openvpn/custom/${EXPRESS_VPN_PROFILE}_credentials" >> ${EXPRESS_VPN_PROFILE}
$ echo -e "${EXPRESSVPN_USERNAME}\n${EXPRESSVPN_PASSWORD}" > ${EXPRESS_VPN_PROFILE}_credentials
$  chmod o-r ${EXPRESS_VPN_PROFILE}_credentials

Launch the container with

$ docker-compose up -d

The webproxy is available on pisin:3128.

To get access to the transmission GUI you can add the following configuration to the docker-compose.yml file or configure Nginx as a proxy (part6).

  proxy:
    image: haugene/transmission-openvpn-proxy:latest-armhf
    ports:
      - 8080:8080
    volumes:
      - /etc/localtime:/etc/localtime:ro
    restart: unless-stopped