thrnz / docker-wireguard-pia

A Docker container for using Wireguard with PIA.
250 stars 55 forks source link

Unclear how to use port.dat with Transmission #3

Open ScottESanDiego opened 3 years ago

ScottESanDiego commented 3 years ago

I have wireguard-pia and transmission working fine, but I'm not sure what the best practice is for using the port.dat to allow incoming connections to Transmission. My Docker-compose is like this (slightly redacted):

version: '3.8'
services:

  vpn:
    networks:
      wg-vpn:
    image: thrnz/docker-wireguard-pia
    container_name: wireguard-pia
    volumes:
      # Auth token
      - /data/software/wireguard-pia/:/pia
      # Forwarded port
      - /data/software/wireguard-pia/:/pia-shared
      # Edited wg-quick script
      - /data/software/wireguard-pia/wg-quick:/usr/bin/wg-quick
    cap_add:
      - NET_ADMIN
    environment:
      - LOC=Blah
      - USER=Blah
      - PASS=Blah
      - USEMODERN=1
      - PORT_FORWARDING=1
      - LOCAL_NETWORK=10.10.10.0/24
    ports:
      - 9091:9091
      - 51413:51413
      - 51413:51413/udp

transmission:
    image: linuxserver/transmission
    container_name: transmission
    environment:
      - PUID=00002
      - PGID=00002
      - TZ="US/Pacific"
      - USER=Blah
      - PASS=Blah
    volumes:
      - /data/software/transmission:/config
      - /var/torrents:/downloads/complete
    network_mode: "service:vpn"
    depends_on:
      - vpn

I get a port.dat file with a port number in it...should I setup a transmission-remote to push that as the port into Transmission? If so, what's a good programmatic way to do that? (I don't see a Transmission way to invoke a script on start, and making a container just to do the RPC call to push the port seems..overkill, and I don't want to override any of the entrypoints...)

thrnz commented 3 years ago

I run a short script in a bare-bones 'helper' container to keep an eye on port.dat and do what it needs to when it changes. It might be a bit overkill separating such a small job out to its own container, but it's worked well enough and is easier than having to modify the underlying container to handle it by itself.

I'm not familiar with Transmission, but for Deluge I'm using something like this and then adding the following service to the compose file:

deluge-port-helper:
    build: /path/to/port-helper
    volumes:
      - /path/to/pia-shared/:/pia-shared
      - /path/to/deluge/conf:/deluge/conf
    network_mode: "service:vpn"
    depends_on:
      - vpn
      - deluge
ScottESanDiego commented 3 years ago

Thanks - I guess I'll do something similar for Transmission. Feels like we should be able to take some kind of input as a hook to run in the wireguard-pia container to do this, but I haven't had cycles to look at your run script enough to see where we'd hook that in.

Appreciate the clues and Deluge examples, thanks!

ScottESanDiego commented 3 years ago

FYI, this works for Transmission (along with minor edit of your Dockerfile to install transmission-cli and inotify-tools):

#!/bin/bash

trap 'exit 0' SIGTERM

OLDPORT=0
PORT=0

while true
do
        [ -r "/pia-shared/port.dat" ] && PORT=$(cat /pia-shared/port.dat)

        if [ $OLDPORT -ne $PORT ]; then
                echo "Setting Transmission port to ($PORT)."
                transmission-remote -n $USER:$PASS -p $PORT
                OLDPORT=$PORT
        fi

        inotifywait --event modify --event create /pia-shared
done

I prefer to wait on the file being touched vs waking up every 30s, but that's just personal preference.

ceyo14 commented 3 years ago

I have this Docker Running on UNRAID and this is what I used.


!/bin/bash

trap 'exit 0' SIGTERM

OLDPORT=0 PORT=0

while true do [ -r "/mnt/user/appdata/WireGuard_PIA/pia-shared/port.dat" ] && PORT=$(cat /mnt/user/appdata/WireGuard_PIA/pia-shared/port.dat) [ -r "/mnt/user/appdata/WireGuard_PIA/pia-shared/oldport.dat" ] && OLDPORT=$(cat /mnt/user/appdata/WireGuard_PIA/pia-shared/oldport.dat)

    if [ $OLDPORT -ne "$PORT" ]; then

cp "/mnt/user/appdata/WireGuard_PIA/pia-shared/port.dat" "/mnt/user/appdata/WireGuard_PIA/pia-shared/oldport.dat" echo "Setting qBittorrent port to ($PORT)."

Update port in QBittorent

            sed -i "s%PortRangeMin=$OLDPORT%PortRangeMin=$PORT%" "/mnt/user/appdata/binhex-qbittorrentvpn/qBittorrent/config/qBittorrent.conf"
            echo "Port has been changed from ($OLDPORT) to ($PORT)."
            OLDPORT=$PORT

    fi

done


Using the userscripts plugin started at array. It may be improved but it is working for me. just make sure to set qbittorrent to start with plenty delay so it gives the other docker time to start and get the port forward.

zilexa commented 3 years ago

@ScottESanDiego What triggers this script? Or do you leave it running continuously, or as a (systemd) service? And did you add containers for transmission-cli and ionotify-tools to your Compose file?

ScottESanDiego commented 3 years ago

@zilexa I made a new container which runs the script. The Dockerfile is trivial:

FROM alpine:latest
RUN echo "http://dl-cdn.alpinelinux.org/alpine/edge/testing/" >> /etc/apk/repositories && \
    echo "http://dl-cdn.alpinelinux.org/alpine/edge/community/" >> /etc/apk/repositories && \
    echo "http://dl-cdn.alpinelinux.org/alpine/edge/main/" >> /etc/apk/repositories && \
    apk add --no-cache bash transmission-cli inotify-tools

ADD pia-port.sh /scripts/pia-port.sh
RUN chmod +x /scripts/*.sh
CMD ["/scripts/pia-port.sh"]

That pia-port.sh is the script I put a few comments above.

Basically I start the transmission & my new container via Docker Compose. The new container runs continuously, but is tiny and largely idle (blocking on the inotifywait), so it doesn't take many resources.

zilexa commented 3 years ago

@ScottESanDiego I just came across this post on reddit, instead of modifying the qbittorrent.conf file (which would require to stop and start qbittorrent), apperently you should be able to use the API: https://www.reddit.com/r/qBittorrent/comments/h03mbx/automatically_update_listening_port_by_shell/ftkkler

curl -s -b /tmp/.cookies.txt -c /tmp/.cookies.txt --header "Referer: http://localhost:8080" --data "username=admin&password=adminadmin" http://localhost:8080/api/v2/auth/login        
curl -s -b /tmp/.cookies.txt -c /tmp/.cookies.txt "http://localhost:8080/api/v2/app/setPreferences" -d 'json={"listen_port": "'"$PORT"'"}'

I will see if I can create a script based on yours but with the API.

zilexa commented 3 years ago

For Qbittorrent, this is how to use the API: It works.. But I have no clue how to properly automate this, as you need to obtain a cookie ID first and use that in the second command.

  1. authentication: curl -i --header 'Referer: http://localhost:9090' --data "username=USER&password=PASS" http://localhost:9090/api/v2/auth/login

output should be:

HTTP/1.1 200 OK
connection: keep-alive
content-length: 3
content-security-policy: default-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; script-src 'self' 'unsafe-inline'; object-src 'none'; form-action 'self';
content-type: text/plain; charset=UTF-8
date: Thu, 24 Jun 2021 15:27:34 GMT
referrer-policy: same-origin
set-cookie: SID=4uW5s+Gv7AkuMERuWGMytz1woBkZ75fp; HttpOnly; path=/
x-content-type-options: nosniff
x-xss-protection: 1; mode=block
  1. change settings: then copy the unique cookie id into the command to change the listening port: curl -i --data "json={"listen_port":44950}" http://localhost:9090/api/v2/app/setPreferences --cookie "SID=4uW5s+Gv7AkuMERuWGMytz1woBkZ75fp" \ Output should be 200 OK.

Notice you have a green icon in the webUI now, even though in Settings you still see the old port.

ScottESanDiego commented 2 years ago

It's a pretty basic Dockerfile. You can see the script get added in the Dockerfile at https://github.com/thrnz/docker-wireguard-pia/issues/3#issuecomment-740770698

On Sat, Dec 25, 2021 at 6:41 AM Rick @.***> wrote:

@ScottESanDiego https://github.com/ScottESanDiego How do you add the script to the dockerfile? where does the script have to be located in order for it to find it? I am using portainer but also tried it in terminal. Can you explain how you created this dockerfile and where the scripts should be located?

— Reply to this email directly, view it on GitHub https://github.com/thrnz/docker-wireguard-pia/issues/3#issuecomment-1001026958, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABQKP4CXAIHUMT5D2KKCKILUSXJ2TANCNFSM4RMJP5UQ . Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.

You are receiving this because you were mentioned.Message ID: @.***>

dereulenspiegel commented 1 year ago

In case you want to run with this in kubernetes, I build a small project which can be used as a sidecar. It reads the port.dat from this container and updates transmission running in the same pod. It also provides a health check so k8s can restart the pod in case the vpn port forwarding is not working properly. You can find it here https://codeberg.org/dereulenspiegel/transmission-buddy

mrbc42 commented 7 months ago

FYI, this works for Transmission (along with minor edit of your Dockerfile to install transmission-cli and inotify-tools):

#!/bin/bash

trap 'exit 0' SIGTERM

OLDPORT=0
PORT=0

while true
do
        [ -r "/pia-shared/port.dat" ] && PORT=$(cat /pia-shared/port.dat)

        if [ $OLDPORT -ne $PORT ]; then
                echo "Setting Transmission port to ($PORT)."
                transmission-remote -n $USER:$PASS -p $PORT
                OLDPORT=$PORT
        fi

        inotifywait --event modify --event create /pia-shared
done

I prefer to wait on the file being touched vs waking up every 30s, but that's just personal preference.

ok, so 3ish years later, this did not work for me exactly but after a few changes, it does now. (Thanks to Scott for his ideas and work on this) The two changes are changing OLDPORT to 1 instead of zero which means the port change will work first time instead of the second. Also, adding the transmission URL to the transmission-remote command.

#!/bin/bash

trap 'exit 0' SIGTERM

OLDPORT=1
PORT=0

while true
do
        [ -r "/pia-shared/port.dat" ] && PORT=$(cat /pia-shared/port.dat)

        if [ $OLDPORT -ne $PORT ]; then
                echo "Setting Transmission port to ($PORT)."
                transmission-remote http://192.168.xx.xx:9091/transmission -n $USER:$PASS -p $PORT
                OLDPORT=$PORT
        fi

        inotifywait --event modify --event create /pia-shared
done

The compose section looks like the below, the VPN port.dat file is mounted to the host OS and picked up by the container in the post by @ScottESanDiego listed above.

  transport:
     image: trans-port:latest
     container_name: transport
     volumes: 
       - /var/lib/docker/volumes/wireguard_port/_data:/pia-shared/
     restart: unless-stopped