thrnz / docker-wireguard-pia

A Docker container for using Wireguard with PIA.
276 stars 54 forks source link

PORT_SCRIPT ENV variable does not work. #62

Open patel-jeel92 opened 1 year ago

patel-jeel92 commented 1 year ago

I am trying to use port_script env to run a script to set the open port to my torrent client. However, when inspecting the container, i dont see the script being run.

Here is my docker compose file

version: "3.7"
services:
  vpn:
    image: thrnz/docker-wireguard-pia
    volumes:
      # Auth token is stored here
      - ${CONFIG_ROOT}/pia:/pia
      # If enabled, the forwarded port is dumped to /pia-shared/port.dat for potential use in other containers
      - ${CONFIG_ROOT}/pia-shared:/pia-shared
    cap_add:
      - NET_ADMIN
      # SYS_MODULE might not be needed with a 5.6+ kernel?
      - SYS_MODULE
    # Mounting the tun device may be necessary for userspace implementations
    #devices:
    #  - /dev/net/tun:/dev/net/tun
    ports:
      # Deluge
      - 8112:8112
      - 58846:58846
      - 58946:58946
      - 58946:58946/udp

      # qBittorrent
      - 8113:8113
      - 6881:6881
      - 6881:6881/udp

      # transmission
      - 9091:9091
      - 51413:51413
      - 51413:51413/udp
    environment:
      # The following env vars are required:
      - LOC=swiss
      - USER=${PIA_USERNAME}
      - PASS=${PIA_PASSWORD}
      # The rest are optional:
      - LOCAL_NETWORK=192.168.1.0/24
      - KEEPALIVE=25
      #- VPNDNS=8.8.8.8,8.8.4.4
      - PORT_FORWARDING=1
      - WG_USERSPACE=1
      - PORT_SCRIPT=${CONFIG_ROOT}/scripts/script.sh
    sysctls:
      # wg-quick fails to set this without --privileged, so set it here instead if needed
      - net.ipv4.conf.all.src_valid_mark=1
      # May as well disable ipv6. Should be blocked anyway.
      - net.ipv6.conf.default.disable_ipv6=1
      - net.ipv6.conf.all.disable_ipv6=1
      - net.ipv6.conf.lo.disable_ipv6=1
    # The container has no recovery logic. Use a healthcheck to catch disconnects.
    healthcheck:
      test: ping -c 1 www.google.com || exit 1
      interval: 30s
      timeout: 10s
      retries: 3

  transmission:
    image: linuxserver/transmission:latest
    network_mode: service:vpn
    depends_on:
      - vpn
    environment:
      - PUID=${PUID}
      - PGID=${PGID}
      - TZ=${TZ}
    volumes:
      - ${CONFIG_ROOT}/transmission:/config
      - ${MEDIA_ROOT}:/downloads
      - ${MEDIA_ROOT}/autoadd:/watch
    restart: unless-stopped

Here is the dump from the container

Sun Feb 12 16:10:00 UTC 2023: Allowing incoming traffic on port 42426

Sun Feb 12 16:10:00 UTC 2023: Rebind interval: 900 seconds

Sun Feb 12 16:10:00 UTC 2023: Port dumped to /pia-shared/port.dat

Sun Feb 12 16:10:00 UTC 2023: This script should remain running to keep the forwarded port alive

Sun Feb 12 16:10:00 UTC 2023: Press Ctrl+C to exit
thrnz commented 1 year ago

https://github.com/thrnz/docker-wireguard-pia/blob/d55b299fe4e6acadf20a76e36aa9e4f82d36a62f/pf_success.sh#L24-L25

Is the custom script executable? That's the only thing that comes to mind. The custom script is only run if set -n, exists and has permission to execute -x.

It might be worth running ls -l /path/to/script.sh in the container just to make sure it's where it should be and permissions are set.

patel-jeel92 commented 1 year ago

The script resides on the host path. The POST_SCRIPT env points to the location to where the script is on the host path. Does the dockerfile copy the file inside the container?

thrnz commented 1 year ago

PORT_SCRIPT should point to where the script has been mounted inside the container - its run from within the container after the port is successfully forwarded. If I'm reading the volumes section of that docker-compose correctly, then it might not be currently mounted within the container itself. Something like this should work:

version: '3'
services:
    vpn:
        image: thrnz/docker-wireguard-pia
        volumes:
            - pia-dat:/pia
            - /host/path/to/script.sh:/script.sh
        cap_add:
            - NET_ADMIN
        environment:
            - LOC=swiss
            - USER=xxxx
            - PASS=xxxx
            - PORT_FORWARDING=1
            - PORT_SCRIPT=/script.sh

I should probably update the docs a bit to clarify that.

jpw4dev commented 1 year ago

I'm actually encountering this same issue, but I've included my the script within the already mounted /pia-shared volume.

This is the log from docker-wireguard-pia:

Tue May  2 01:43:15 UTC 2023: Server accepted PF bind
Tue May  2 01:43:15 UTC 2023: Forwarding on port 38376
Tue May  2 01:43:15 UTC 2023: Running /scripts/pf_success.sh
Tue May  2 01:43:15 UTC 2023: Allowing incoming traffic on port 38376
Tue May  2 01:43:15 UTC 2023: Rebind interval: 900 seconds
Tue May  2 01:43:15 UTC 2023: Port dumped to /pia-shared/port.dat
Tue May  2 01:43:15 UTC 2023: This script should remain running to keep the forwarded port alive

Logging into container (docker exec -it wireguard /bin/bash) to view the script permissions it appears to be executable?:

c376d7f98240:/scripts# ls -l ../pia-shared/
total 8
-rw-r--r--    1 root     root             6 May  2 01:43 port.dat
-rwxr-xr-x    1 root     root           663 May  2 00:47 portforward.sh

But if I test the file it does not think that it is:

c376d7f98240:/scripts# [ -x $PORT_SCRIPT ] && echo "true"
c376d7f98240:/scripts# [ -n $PORT_SCRIPT ] && echo "true"
true
c376d7f98240:/scripts#

But if I just manually execute the script from within the container it does run just fine:

c376d7f98240:/scripts# ../pia-shared/portforward.sh $(cat ../pia-shared/port.dat)
Setting qBittorrent port settings (38376)...
Ok.Qbittorrent port updated successfully (38376)...
c376d7f98240:/scripts#

Relevant section of the docker-compose.yml:

version: '3'
services:
    vpn:
        image: thrnz/docker-wireguard-pia
        container_name: wireguard
        networks:
            - shared
        volumes:
            - ./config/pia:/pia
            - ./config/pia/shared:/pia-shared
        ports:
            - 127.0.0.1:8081:8081
            - 127.0.0.1:3001:3000
        cap_add:
            - NET_ADMIN
        environment:
            - LOCAL_NETWORK=192.168.1.0/24
            - LOC=location
            - USER=user
            - PASS=pass
            - PORT_FORWARDING=1
            - PORT_SCRIPT=/pia-shared/portfoward.sh
        sysctls:
            - net.ipv4.conf.all.src_valid_mark=1
            - net.ipv6.conf.default.disable_ipv6=1
            - net.ipv6.conf.all.disable_ipv6=1
            - net.ipv6.conf.lo.disable_ipv6=1
        healthcheck:
            test: ping -c 1 www.google.com || exit 1
            interval: 30s
            timeout: 10s
            retries: 3

Any thoughts? I'm not sure what to make of this at the moment.

thrnz commented 1 year ago
c376d7f98240:/scripts# [ -x $PORT_SCRIPT ] && echo "true"
c376d7f98240:/scripts# [ -n $PORT_SCRIPT ] && echo "true"
true
c376d7f98240:/scripts#

That reminds be a bit of another issue - #28 - where a mounted file existed and was readable, but the test was still failing.

In this case I could probably just remove the check that the file exists and is executable before running it. That way at least it might throw more descriptive error if something goes wrong.

jpw4dev commented 1 year ago

Interesting, yeah, that looks like a very similar problem in nature. This is running on Ubuntu as well, albeit Ubuntu 22.04.2 LTS.

I did a similar test with -x outside the container and that does pass as executable, so its from the container only that the test fails for execute. It makes me wonder about a problem with the user/group somehow, but its owned by root:root.

I did an inspect on the container and the mounts look normal too I think.

"Mounts": [
            {
                "Type": "bind",
                "Source": "/docker/vpn/config/pia/shared",
                "Destination": "/pia-shared",
                "Mode": "rw",
                "RW": true,
                "Propagation": "rprivate"
            },
            {
                "Type": "bind",
                "Source": "/docker/vpn/config/pia",
                "Destination": "/pia",
                "Mode": "rw",
                "RW": true,
                "Propagation": "rprivate"
            }
        ]
thrnz commented 1 year ago

Is #74 enough to work around it? I can stick it on Docker hub and tag it as testing if it's more convenient than manually building it.

jpw4dev commented 1 year ago

Hey, thanks for that. I actually just learned that with docker-compose you can just replace the image: thrnz/docker-wireguard-pia with build: https://github.com/thrnz/docker-wireguard-pia.git#pf-custom-cmd to build a branch. I didn't know that was a thing, but that is really useful!

Using the new branch without the [ -x $PORT_SCRIPT ] check for execute appears to now work for my setup. It ends up logging a little oddly, probably because of the retry logic in the portforward.sh but that's not a concern.

Tue May  2 14:29:53 UTC 2023: Server accepted PF bind
Tue May  2 14:29:53 UTC 2023: Forwarding on port 59296
Tue May  2 14:29:53 UTC 2023: Running /scripts/pf_success.sh
Tue May  2 14:29:53 UTC 2023: Allowing incoming traffic on port 59296
Tue May  2 14:29:53 UTC 2023: Running user-defined command: /pia-shared/portforward.sh
Tue May  2 14:29:53 UTC 2023: Rebind interval: 900 seconds
Tue May  2 14:29:53 UTC 2023: Port dumped to /pia-shared/port.dat
Setting qBittorrent port settings (59296)...
Tue May  2 14:29:53 UTC 2023: This script should remain running to keep the forwarded port alive
Tue May  2 14:29:53 UTC 2023: Press Ctrl+C to exit
Ok.Qbittorrent port updated successfully (59296)...

Thanks for the quick help on this!

thrnz commented 1 year ago

I actually just learned that with docker-compose you can just replace the image: thrnz/docker-wireguard-pia with build: https://github.com/thrnz/docker-wireguard-pia.git#pf-custom-cmd to build a branch.

TIL! That's actually looks really handy.

It ends up logging a little oddly, probably because of the retry logic in the portforward.sh but that's not a concern.

The custom script gets forked and run in the background just in case it needs to stays running so any log messages will just come out as they happen. I could probably re-order things slightly though just to tidy that up.

Belphemur commented 1 year ago

@jordanpatrick Could you share the script you made that update the qbittorent port on port-forwarding change ?

jpw4dev commented 1 year ago

@Belphemur Oh sure, I can't even take credit for it, as I am using the script thrnz posted here

Belphemur commented 1 year ago

Thanks @jordanpatrick