make this repo public again

This commit is contained in:
2025-04-02 13:46:33 -07:00
parent a9825f94a2
commit 950877862e
17 changed files with 282 additions and 172 deletions

View File

@@ -5,6 +5,9 @@ on:
branches:
- 'master'
- 'testing'
paths-ignore:
- 'README.md'
- 'docker-compose.yml'
# Rebuild monthly to keep packages up to date
schedule:
- cron: '0 0 1 * *'

1
.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
*~

View File

@@ -8,7 +8,15 @@ RUN apk add --no-cache \
iptables-legacy \
jq \
openssl \
wireguard-tools
wireguard-tools \
transmission-daemon \
transmission-cli \
transmission-extra \
transmission-remote \
joe \
tzdata
ENV TZDATA=UTC
# Modify wg-quick so it doesn't die without --privileged
# Set net.ipv4.conf.all.src_valid_mark=1 on container creation using --sysctl if required instead
@@ -29,7 +37,7 @@ COPY ./RegionsListPubKey.pem /RegionsListPubKey.pem
WORKDIR /scripts
# Copy scripts to containers
COPY run pf_success.sh ./extra/pf.sh ./extra/pia-auth.sh ./extra/wg-gen.sh /scripts/
COPY launch.sh launch-transmission.sh run pf_success.sh ./extra/pf.sh ./extra/pia-auth.sh ./extra/wg-gen.sh /scripts/
RUN chmod 755 /scripts/*
# Store persistent PIA stuff here (auth token, server list)
@@ -38,4 +46,9 @@ VOLUME /pia
# Store stuff that might be shared with another container here (eg forwarded port)
VOLUME /pia-shared
CMD ["/scripts/run"]
CMD ["/scripts/launch.sh"]
EXPOSE 9091
VOLUME /config
VOLUME /watch
VOLUME /downloads

147
README.md
View File

@@ -1,64 +1,83 @@
# docker-wireguard-pia
A Docker container for using WireGuard with PIA.
## Requirements
* Ideally the host must already support WireGuard. Pre 5.6 kernels may need to have the module manually installed. `wg-quick` should automatically fall back to a userspace implementation (`wireguard-go`) if the kernel module is missing, however the container may need access to the `/dev/net/tun` device for this to work.
* An active [PIA](https://www.privateinternetaccess.com) subscription.
## Config
The following ENV vars are required:
| ENV Var | Function |
|-------|------|
|```LOC=swiss```|Location id to connect to. Available server location ids are listed [here](https://serverlist.piaservers.net/vpninfo/servers/v6). Example values include ```us_california```, ```ca_ontario```, and ```swiss```. If left empty the container will print out all currently available location ids and exit. <br />Multiple ids can be listed, separated by either a space or a comma, and are used as fallback if the initial endpoint registration fails.
|```USER=xxxxxxxx```|PIA username
|```PASS=xxxxxxxx```|PIA password
The rest are optional:
| ENV Var | Function |
|-------|------|
|```LOCAL_NETWORK=192.168.1.0/24```|Whether to route and allow input/output traffic to the LAN. LAN access is blocked by default if not specified. Multiple ranges can be specified, separated by a comma or space. Note that there may be DNS issues if this overlaps with PIA's default DNS servers (`10.0.0.243` and `10.0.0.242` as of July 2022). Custom DNS servers can be defined using `VPNDNS` (see below) if this is an issue.
|```KEEPALIVE=25```|If defined, PersistentKeepalive will be set to this in the WireGuard config.
|```MTU=1420```|This can be used to override ```wg-quick```'s automatic MTU setting on the Wireguard interface if needed. By default this remains unset (ie. let ```wg-quick``` choose).
|```VPNDNS=8.8.8.8, 8.8.4.4```|Use these DNS servers in the WireGuard config. PIA's DNS servers will be used if not specified. Use 0 to disable making any changes to the default container DNS settings. (Note: Using any DNS servers other than PIA's may lead to DNS queries being leaked outside the VPN connection.)
|```PORT_FORWARDING=0/1```|Whether to enable port forwarding. Requires a supported server. Defaults to 0 if not specified.
|```PORT_FILE=/pia-shared/port.dat```|The forwarded port number is dumped here for possible access by scripts in other containers. By default this is ```/pia-shared/port.dat```.
|```PORT_FILE_CLEANUP=0/1```|Remove the file containing the forwarded port number on exit. Defaults to 0 if not specified.
|```PORT_PERSIST=0/1```|Set to 1 to attempt to keep the same port forwarded when the container is restarted. The port number may persist for up to two months. Defaults to 0 (always acquire a new port number) if not specified.
|`PORT_FATAL=0/1`|Whether to consider port forwarding errors as fatal or not. May be useful when combined with `EXIT_ON_FATAL` if needed. Defaults to 0 if not specified.
|```PORT_SCRIPT=/path/to/script.sh```|A mounted custom script can be run inside the container once a port is successfully forwarded if needed. The forwarded port number is passed as the first command line argument. By default this remains unset. See [issue #26](https://github.com/thrnz/docker-wireguard-pia/issues/26) for more info.
|```FIREWALL=0/1```|Whether to block non-WireGuard traffic. Defaults to 1 if not specified.
|```EXIT_ON_FATAL=0/1```|There is no error recovery logic at this stage. If something goes wrong we simply go to sleep. By default the container will continue running until manually stopped. Set this to 1 to force the container to exit when an error occurs. Exiting on an error may not be desirable behaviour if other containers are sharing the connection.
|```FATAL_SCRIPT=/path/to/script.sh```|A mounted custom script can be run inside the container if a fatal error occurs. By default this remains unset.
|```USER_FILE=/run/secrets/pia-username``` ```PASS_FILE=/run/secrets/pia-password```|PIA credentials can also be read in from existing files (eg for use with Docker secrets)
|```PIA_IP=x.x.x.x``` ```PIA_CN=hostname401``` ```PIA_PORT=1337```|Connect to a specific server by manually setting all three of these. This will override whatever ```LOC``` is set to.
|```FWD_IFACE``` ```PF_DEST_IP```|If needed, the container can be used as a gateway for other containers or devices by setting these. See [issue #20](https://github.com/thrnz/docker-wireguard-pia/issues/20) for more info. Note that these are for a specific use case, and in many cases using Docker's ```--net=container:xyz``` or docker-compose's ```network_mode: service:xyz``` instead, and leaving these vars unset, would be an easier way of accessing the VPN and forwarded port from other containers.
|`PRE_UP` `POST_UP` `PRE_DOWN` `POST_DOWN`|Custom commands and/or scripts can be run at certain stages if needed. See [below](#scripting) for more info.
|`PIA_DIP_TOKEN`|A dedicated ip token can be used by setting this. When set, `LOC` is not used.
## Scripting
Custom commands and/or scripts can be run at certain stages of the container's life-cycle by setting the `PRE_UP`, `POST_UP`, `PRE_DOWN`, and `POST_DOWN` env vars. `PRE_UP` is run prior to generating the WireGuard config, `POST_UP` is run after the WireGuard interface is brought up, and `PRE_DOWN` and `POST_DOWN` are run before and after the interface is brought down again when the container exits.
In addition, scripts mounted in `/pia/scripts` named `pre-up.sh`, `post-up.sh`, `pre-down.sh` and `post-down.sh` will be run at the appropriate stage if present. See [issue #33](https://github.com/thrnz/docker-wireguard-pia/issues/33) for more info.
## Notes
* Generating WireGuard configs and port forwarding was based on what was found in the source code to the PIA desktop app.
* As of Sep 2020, PIA have released [scripts](https://github.com/pia-foss/manual-connections) for using WireGuard outside of their app.
* For simplicity, most of the network setup is handled by `wg-quick`.
* Persistent data is stored in ```/pia```.
* IPv4 only. IPv6 traffic is blocked unless using ```FIREWALL=0``` but you may want to disable IPv6 on the container anyway.
* If strict reverse path filtering is used, then the `net.ipv4.conf.all.src_valid_mark=1` sysctl should be set on container creation to prevent incoming packets being dropped. See [issue #96](https://github.com/thrnz/docker-wireguard-pia/issues/96) for more info.
* An example [docker-compose.yml](https://github.com/thrnz/docker-wireguard-pia/blob/master/docker-compose.yml) is included. Some more working examples can be found [here](https://github.com/thrnz/docker-wireguard-pia/wiki/Examples).
* Other containers can share the VPN connection using Docker's [```--net=container:xyz```](https://docs.docker.com/engine/reference/run/#network-settings) or docker-compose's [```network_mode: service:xyz```](https://github.com/compose-spec/compose-spec/blob/master/spec.md#network_mode).
* Standalone [Bash scripts](https://github.com/thrnz/docker-wireguard-pia/tree/master/extra) are available for use outside of Docker.
* The userspace implementation through wireguard-go is very stable but lacks in performance. Looking into supporting ([boringtun](https://github.com/cloudflare/boringtun)) might be beneficial.
## Credits
Some bits and pieces and ideas have been borrowed from the following:
* https://github.com/activeeos/wireguard-docker
* https://github.com/cmulk/wireguard-docker
* https://github.com/dperson/openvpn-client
* https://github.com/pia-foss/desktop
* https://gist.github.com/triffid/da48f3c99f1ff334571ae49be80d591b
# transmission-wireguard-pia
This is a fork of https://github.com/thrnz/docker-wireguard-pia to which transmission-daemon has been added. It takes the same environment variables as thrnz/docker-wireguard-pia to configure the (Private Internet Access) VPN, and uses /config, /downloads, and /watch to set up the Transmission BitTorrent client. Use something like this to get it up and running:
```docker run -d --name transmission --privileged --cap-add NET_ADMIN --cap-add SYS_MODULE -e LOC=nl_amsterdam -e USER=[PIA user] -e PASS=[PIA password] -e PORT_FORWARDING=1 -e FIREWALL=1 -e PF_DEST_IP=127.0.0.1 -e LOCAL_NETWORK=192.168.1.0/24 -p 9091:9091 -v /mnt/ssd/container-state/transmission/config:/config -v /mnt/storage/files/torrents:/downloads -v /mnt/storage/files/torrent-watch:/watch salfter/transmission-wireguard-pia```
Important variables to set are LOC (to set the VPN endpoint, preferably to one that supports port forwarding), USER, PASS, and LOCAL_NETWORK. Once it's started, wait 20 seconds before accessing the Transmission web interface on port 9091. LOCAL_NETWORK is set so that the web interface can be accessed without using port forwarding through the VPN. Use https://whatismyip.net/tools/torrent-ip-checker/ to verify that BitTorrent traffic is going through the VPN.
The README for docker-wireguard-pia follows:
# docker-wireguard-pia
A Docker container for using WireGuard with PIA.
## Requirements
* Ideally the host should already support WireGuard. Pre 5.6 kernels may need to have the module manually installed. `wg-quick` should automatically fall back to a userspace implementation (`wireguard-go`) if needed, however the container may need access to the `/dev/net/tun` device for this to work.
* The container requires the `NET_ADMIN` [capability](https://docs.docker.com/compose/compose-file/05-services/#cap_add). `SYS_MODULE` may also be needed in some cases, especially when WireGuard support is provided via kernel module.
* An active [PIA](https://www.privateinternetaccess.com) subscription.
## Examples
An example [docker-compose.yml](https://github.com/thrnz/docker-wireguard-pia/blob/master/docker-compose.yml) is available. Some more working examples can be found [here](https://github.com/thrnz/docker-wireguard-pia/wiki/Examples).
## Config
The following ENV vars are required:
| ENV Var | Function |
|-------|------|
|```LOC=swiss```|Location id to connect to. Available server location ids are listed [here](https://serverlist.piaservers.net/vpninfo/servers/v6). Example values include ```us_california```, ```ca_ontario```, and ```swiss```. If left empty the container will print out all currently available location ids and exit. <br />Multiple ids can be listed, separated by either a space or a comma, and are used as fallback if the initial endpoint registration fails.
|```USER=xxxxxxxx```|PIA username
|```PASS=xxxxxxxx```|PIA password
The rest are optional:
| ENV Var | Function |
|-------|------|
|```LOCAL_NETWORK=192.168.1.0/24```|Whether to route and allow input/output traffic to the LAN. LAN access will be unavailable if not specified. Multiple ranges can be specified, separated by a comma or space. Note that there may be DNS issues if this overlaps with PIA's default DNS servers (`10.0.0.243` and `10.0.0.242` as of July 2022). Custom DNS servers can be defined using `VPNDNS` (see below) if this is an issue.
|```KEEPALIVE=25```|If defined, PersistentKeepalive will be set to this in the WireGuard config.
|```MTU=1420```|This can be used to override ```wg-quick```'s automatic MTU setting on the Wireguard interface if needed. By default this remains unset (ie. let ```wg-quick``` choose).
|```VPNDNS=8.8.8.8, 8.8.4.4```|Use these DNS servers in the WireGuard config. PIA's DNS servers will be used if not specified. Use 0 to disable making any changes to the default container DNS settings. (Note: Using any DNS servers other than PIA's may lead to DNS queries being leaked outside the VPN connection.)
|```PORT_FORWARDING=0/1```|Whether to enable port forwarding. Requires a supported server. Defaults to 0 if not specified.
|```PORT_FILE=/pia-shared/port.dat```|The forwarded port number is dumped here for possible access by scripts in other containers. By default this is ```/pia-shared/port.dat```.
|```PORT_FILE_CLEANUP=0/1```|Remove the file containing the forwarded port number on exit. Defaults to 0 if not specified.
|```PORT_PERSIST=0/1```|Set to 1 to attempt to keep the same port forwarded when the container is restarted. The port number may persist for up to two months. Defaults to 0 (always acquire a new port number) if not specified.
|`PORT_FATAL=0/1`|Whether to consider port forwarding errors as fatal or not. May be useful when combined with `EXIT_ON_FATAL` if needed. Defaults to 0 if not specified.
|```PORT_SCRIPT=/path/to/script.sh```|A mounted custom script can be run inside the container once a port is successfully forwarded if needed. The forwarded port number is passed as the first command line argument. By default this remains unset. See [issue #26](https://github.com/thrnz/docker-wireguard-pia/issues/26) for more info.
|```FIREWALL=0/1```|Whether to block non-WireGuard traffic. Defaults to 1 if not specified.
|```EXIT_ON_FATAL=0/1```|There is no error recovery logic at this stage. If something goes wrong we simply go to sleep. By default the container will continue running until manually stopped. Set this to 1 to force the container to exit when an error occurs. Exiting on an error may not be desirable behaviour if other containers are sharing the connection.
|```FATAL_SCRIPT=/path/to/script.sh```|A mounted custom script can be run inside the container if a fatal error occurs. By default this remains unset.
|```USER_FILE=/run/secrets/pia-username``` ```PASS_FILE=/run/secrets/pia-password```|PIA credentials can also be read in from existing files (eg for use with Docker secrets)
|```PIA_IP=x.x.x.x``` ```PIA_CN=hostname401``` ```PIA_PORT=1337```|Connect to a specific server by manually setting all three of these. This will override whatever ```LOC``` is set to.
|```FWD_IFACE``` ```PF_DEST_IP```|If needed, the container can be used as a gateway for other containers or devices by setting these. See [issue #20](https://github.com/thrnz/docker-wireguard-pia/issues/20) for more info. Note that these are for a specific use case, and in many cases using Docker's ```--net=container:xyz``` or docker-compose's ```network_mode: service:xyz``` instead, and leaving these vars unset, would be an easier way of accessing the VPN and forwarded port from other containers.
|`PRE_UP` `POST_UP` `PRE_DOWN` `POST_DOWN`|Custom commands and/or scripts can be run at certain stages if needed. See [below](#scripting) for more info.
|`PIA_DIP_TOKEN`|A dedicated ip token can be used by setting this. When set, `LOC` is not used.
|`META_IP=x.x.x.x` `META_CN=hostname401` `META_PORT=443`|On startup, the container needs untunnelled access to PIA's API in order to download the server list and to generate a persistent auth token if needed. Optionally, PIA's 'meta' servers (found in PIA's [server list](https://serverlist.piaservers.net/vpninfo/servers/v6)) can be used instead of the default API endpoints by setting `META_IP` and `META_CN`. These can be set to a different location than `LOC`. `META_PORT` is optional and defaults to 443, although 8080 also appears to be available. See [issue #109](https://github.com/thrnz/docker-wireguard-pia/issues/109) for more info.
## Scripting
Custom commands and/or scripts can be run at certain stages of the container's life-cycle by setting the `PRE_UP`, `POST_UP`, `PRE_DOWN`, and `POST_DOWN` env vars. `PRE_UP` is run prior to generating the WireGuard config, `POST_UP` is run after the WireGuard interface is brought up, and `PRE_DOWN` and `POST_DOWN` are run before and after the interface is brought down again when the container exits.
In addition, scripts mounted in `/pia/scripts` named `pre-up.sh`, `post-up.sh`, `pre-down.sh` and `post-down.sh` will be run at the appropriate stage if present. See [issue #33](https://github.com/thrnz/docker-wireguard-pia/issues/33) for more info.
## Networking
To keep things simple, network setup is mostly handled by `wg-quick`. All traffic is routed down the WireGuard tunnel, with exceptions added for any ranges manually defined by `LOCAL_NETWORK`. Note that `LOCAL_NETWORK` must be set correctly if LAN access is needed.
Firewall rules are added dropping all traffic by default, and only encrypted/tunneled traffic, attached Docker network traffic, and `LOCAL_NETWORK` traffic is explicitly allowed. This can be disabled by setting the `FIREWALL=0` env var if desired.
Other containers can access the VPN connection using Docker's [`--net=container:xyz`](https://docs.docker.com/engine/network/#container-networks) or docker-compose's [`network_mode: service:xyz`](https://docs.docker.com/reference/compose-file/services/#network_mode). Note that network related settings for other containers (such as exposing ports) need to be set on the VPN container itself.
The container doesn't support IPv6. Any IPv6 traffic is dropped unless using `FIREWALL=0`, though it might be worth disabling IPv6 on container creation anyway.
## Notes
* WireGuard config generation and port forwarding was based on what was found in the source code to the PIA desktop app. The standalone [Bash scripts](https://github.com/thrnz/docker-wireguard-pia/tree/master/extra) used by the container are available for use outside of Docker.
* As of Sep 2020, PIA have released their own [scripts](https://github.com/pia-foss/manual-connections) for using WireGuard and port forwarding outside of their app.
* Persistent data is stored in ```/pia```.
* If strict reverse path filtering is used, then the `net.ipv4.conf.all.src_valid_mark=1` sysctl should be set on container creation to prevent incoming packets being dropped. See [issue #96](https://github.com/thrnz/docker-wireguard-pia/issues/96) for more info.
* The userspace implementation through wireguard-go is very stable but lacks in performance. Looking into supporting ([boringtun](https://github.com/cloudflare/boringtun)) might be beneficial.
## Credits
Some bits and pieces and ideas have been borrowed from the following:
* https://github.com/activeeos/wireguard-docker
* https://github.com/cmulk/wireguard-docker
* https://github.com/dperson/openvpn-client
* https://github.com/pia-foss/desktop
* https://gist.github.com/triffid/da48f3c99f1ff334571ae49be80d591b

2
backup.sh Executable file
View File

@@ -0,0 +1,2 @@
#!/usr/bin/env bash
docker run --rm -v transmission-config:/v alpine tar -C v -cf - . | zstd -19 | sudo tee /mnt/storage/backup/transmission-config.tar.zstd >/dev/null

5
build.sh Executable file
View File

@@ -0,0 +1,5 @@
#!/usr/bin/env bash
docker build -t cr.gitlab.alfter.us/salfter/transmission-wireguard-pia:latest .
docker image tag cr.gitlab.alfter.us/salfter/transmission-wireguard-pia:latest salfter/transmission-wireguard-pia:latest
docker push cr.gitlab.alfter.us/salfter/transmission-wireguard-pia:latest
docker push salfter/transmission-wireguard-pia:latest

View File

@@ -1,71 +1,39 @@
version: '3'
services:
vpn:
image: thrnz/docker-wireguard-pia
volumes:
# Auth token is stored here
- pia:/pia
# If enabled, the forwarded port is dumped to /pia-shared/port.dat for potential use in other containers
- pia-shared:/pia-shared
cap_add:
- NET_ADMIN
# SYS_MODULE might not be needed with a 5.6+ kernel?
- SYS_MODULE
# If the kernel module isn't available, mounting the tun device may be necessary for userspace implementations
#devices:
# - /dev/net/tun:/dev/net/tun
environment:
# The following env vars are required:
- LOC=swiss
- USER=xxxxxxxxxxxxxxxx
- PASS=xxxxxxxxxxxxxxxx
# 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
sysctls:
# The wg-quick script tries to set this when setting up routing, however this requires running the container
# with the --privileged flag set. Setting it here instead if needed means the container can be run with lower
# privileges. This only needs setting if strict reverse path filtering (rp_filter=1) is used.
- 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
# Example of another service sharing the VPN
# If this service needs LAN access then LOCAL_NETWORK must be set appropriatley on the vpn container
# Forwared ports should also be set on the vpn container if needed rather than this one in
# order to access from the LAN
# It may be preferable to use a reverse proxy connected via the docker bridge network instead
# to keep the vpn isolated from the LAN
other-service:
image: some-other-image
# Other services can share the VPN using 'network_mode'
# See https://docs.docker.com/engine/reference/run/#network-container and
# https://docs.docker.com/compose/compose-file/compose-file-v3/#network_mode
network_mode: "service:vpn"
# Other containers can access the forwarded port number via /pia-shared/port.dat
# Here's an example of a bare-bones 'helper' container that passes the forwarded port to Deluge
# See https://gist.github.com/thrnz/dcbaa0af66c70af8e302a1c7eb75484a
deluge-port-helper:
build: /path/to/deluge-port-helper
volumes:
- pia-shared:/pia-shared:ro
- /path/to/deluge/conf:/deluge/conf
network_mode: "service:vpn"
depends_on:
- vpn
- other-service
volumes:
pia:
pia-shared:
services:
transmission:
build: .
container_name: transmission
restart: unless-stopped
env_file: ./pia-credentials.env
environment:
LOCAL_NETWORK: 192.168.1.0/24
PF_DEST_IP: 127.0.0.1
FIREWALL: 1
PORT_FORWARDING: 1
TZ: US/Pacific
ports:
- '9091:9091'
volumes:
- '/mnt/storage/torrent-watch:/watch'
- '/mnt/storage/torrents:/downloads'
- 'transmission-config:/config'
cap_add:
- SYS_MODULE
- NET_ADMIN
privileged: true
networks:
- www
labels:
caddy: transmission.alfter.us
caddy.reverse_proxy: http://transmission.www:9091
caddy.log: transmission
caddy.log.format: json
networks:
www:
name: www
external: true
volumes:
transmission-config:
name: transmission-config
external: true

View File

@@ -7,9 +7,17 @@
# Options:
# -u <username>
# -p <password>
# -i <meta server ip> (Optional)
# -o <meta server port> (Optional)
# -n <meta server cn> (Optional)
# -c <cacert path> (Optional) Path to ca cert used to secure communication with "meta" servers
#
# Example:
# pia-auth.sh -u myusername -p mypassword > ~/.pia-token
# Examples:
# ./pia-auth.sh -u myusername -p mypassword > ~/.pia-token
# ./pia-auth.sh -u myusername -p mypassword -i 12.34.56.78 -n location401 -p 443 -c /path/to/ca.crt > ~/.pia-token
#
# By default, the www.privateinternetaccess.com API endpoint is used.
# If needed, 'meta' services on the VPN servers themselves can be used instead.
#
# deauth using:
# curl --silent --show-error --request POST \
@@ -20,36 +28,62 @@
[ -n "$DEBUG" ] && set -o xtrace
while getopts ":u:p:" args; do
while getopts ":u:p:i:c:o:n:" args; do
case ${args} in
u)
user=$OPTARG
user="$OPTARG"
;;
p)
pass=$OPTARG
pass="$OPTARG"
;;
i)
meta_ip="$OPTARG"
;;
c)
cacert="$OPTARG"
;;
o)
meta_port="$OPTARG"
;;
n)
meta_cn="$OPTARG"
;;
esac
done
usage() {
echo "Options:"
echo " -u <username>"
echo " -p <password>"
echo 'Options:
-u <username>
-p <password>
-i <meta-server ip> (Optional)
-o <meta-server port> (Optional)
-n <meta-server cn> (Optional)
-c <cacert path> (Optional) Path to ca cert used to secure communication with "meta" servers'
exit 1
}
get_auth_token () {
if [ -n "$meta_port" ] && [ -n "$meta_ip" ] && [ -n "$meta_cn" ] && [ -n "$cacert" ]; then
# https://github.com/pia-foss/desktop/blob/master/daemon/src/metaserviceapibase.h
token_response=$(curl --silent --location --show-error --request POST --max-time "$curl_max_time" \
--resolve "$meta_cn:$meta_port:$meta_ip" \
--data-urlencode "username=$user" \
--data-urlencode "password=$pass" \
--cacert "$cacert" \
"https://$meta_cn:$meta_port/api/client/v2/token")
else
token_response=$(curl --silent --location --show-error --request POST --max-time "$curl_max_time" \
'https://www.privateinternetaccess.com/api/client/v2/token' \
--form "username=$user" \
--form "password=$pass")
TOK=$(jq -r .'token' <<< "$token_response")
if [ -z "$TOK" ]; then
echo "Failed to acquire new auth token. Response:" >&2
echo "$token_response" >&2
exit 1
fi
echo "$TOK"
--data-urlencode "username=$user" \
--data-urlencode "password=$pass")
fi
TOK=$(jq -r .'token' <<< "$token_response")
if [ -z "$TOK" ] || [ "$TOK" == "null" ]; then
echo "Failed to acquire new auth token. Response:" >&2
echo "$token_response" >&2
exit 1
fi
echo "$TOK"
}
if [ -z "$pass" ] || [ -z "$user" ]; then

View File

@@ -26,8 +26,11 @@
# To use a dedicated ip, the PIA_DIP_TOKEN env var must be set
# eg: $ PIA_DIP_TOKEN=DIPabc123 wg-gen.sh -t ~/.token -o ~/wg.conf
#
# API requests can be sent via PIA's 'meta' servers by setting the META_IP META_CN and META_PORT env vars
# eg: $ META_IP=123.45.67.89 META_CN=hostname401 META_PORT=443 ./wg-gen.sh -t ~/.token ~/wg.conf
#
# Available servers can be found here:
# https://serverlist.piaservers.net/vpninfo/servers/v4
# https://serverlist.piaservers.net/vpninfo/servers/v6
# The public key for verifying the server list can be found here:
# https://github.com/pia-foss/desktop/blob/122710c6ada5db83620c63faff2d805ea52d7f40/daemon/src/environment.cpp#L30
# The PIA ca cert can be found here:
@@ -43,6 +46,8 @@
# 3: Invalid server location
# 4: Registration failed
[ -n "$DEBUG" ] && set -o xtrace
fatal_error () {
cleanup
[ -n "$1" ] && exit "$1"
@@ -115,14 +120,26 @@ verify_serverlist ()
get_dip_serverinfo ()
{
echo "$(date): Fetching dedicated ip server info"
dip_response=$(curl --silent --show-error $curl_params --location --request POST \
'https://www.privateinternetaccess.com/api/client/v2/dedicated_ip' \
--header 'Content-Type: application/json' \
--header "Authorization: Token $(cat $tokenfile)" \
--data-raw '{
"tokens":["'"$PIA_DIP_TOKEN"'"]
}')
if [ -n "$META_IP" ] && [ -n "$META_CN" ] && [ -n "$META_PORT" ]; then
echo "$(date): Fetching dedicated ip server info via meta server: ip: $META_IP, cn: $META_CN, port: $META_PORT"
dip_response=$(curl --silent --show-error $curl_params --location --request POST \
"https://$META_CN:$META_PORT/api/client/v2/dedicated_ip" \
--header 'Content-Type: application/json' \
--header "Authorization: Token $(cat $tokenfile)" \
--cacert "$pia_cacert" --resolve "$META_CN:$META_PORT:$META_IP" \
--data-raw '{
"tokens":["'"$PIA_DIP_TOKEN"'"]
}')
else
echo "$(date): Fetching dedicated ip server info"
dip_response=$(curl --silent --show-error $curl_params --location --request POST \
'https://www.privateinternetaccess.com/api/client/v2/dedicated_ip' \
--header 'Content-Type: application/json' \
--header "Authorization: Token $(cat $tokenfile)" \
--data-raw '{
"tokens":["'"$PIA_DIP_TOKEN"'"]
}')
fi
[ "$dip_response" == "HTTP Token: Access denied." ] && echo "Auth failed" && fatal_error 2
@@ -143,9 +160,15 @@ get_dip_serverinfo ()
}
get_servers() {
echo "Fetching next-gen PIA server list"
curl --silent --show-error $curl_params \
"https://serverlist.piaservers.net/vpninfo/servers/v6" > "$servers_raw"
if [ -n "$META_IP" ] && [ -n "$META_CN" ] && [ -n "$META_PORT" ]; then
echo "Fetching next-gen PIA server list via meta server: ip: $META_IP, cn: $META_CN, port: $META_PORT"
curl --silent --show-error $curl_params --cacert "$pia_cacert" --resolve "$META_CN:$META_PORT:$META_IP" \
"https://$META_CN:$META_PORT/vpninfo/servers/v6" > "$servers_raw"
else
echo "Fetching next-gen PIA server list"
curl --silent --show-error $curl_params \
"https://serverlist.piaservers.net/vpninfo/servers/v6" > "$servers_raw"
fi
head -n 1 "$servers_raw" | tr -d '\n' > "$servers_json"
tail -n +3 "$servers_raw" | base64 -d > "$servers_sig"
[ -n "$pia_pubkey" ] && verify_serverlist
@@ -202,7 +225,7 @@ get_wgconf () {
"https://$wg_cn:$wg_port/addKey" > "$addkey_response"
fi
[ "$(jq -r .status "$addkey_response")" == "ERROR" ] && [ "$(jq -r .message "$addkey_response")" == "Login failed!" ] && echo "Auth failed" && fatal_error 2
[ "$(jq -r .status "$addkey_response")" == "ERROR" ] && [ "$(jq -r .message "$addkey_response")" == "Login failed!" ] && echo "Auth failed" && cat "$addkey_response" && fatal_error 2
[ "$(jq -r .status "$addkey_response")" != "OK" ] && echo "WG key registration failed" && cat "$addkey_response" && fatal_error 4
peer_ip="$(jq -r .peer_ip "$addkey_response")"

3
get-port.sh Executable file
View File

@@ -0,0 +1,3 @@
#!/usr/bin/env bash
docker exec transmission cat /pia-shared/port.dat

7
launch-transmission.sh Normal file
View File

@@ -0,0 +1,7 @@
#!/usr/bin/env ash
sleep 15
if [ -e /pia-shared/port.dat ]
then
sed -i "s/\"peer-port\": [0-9]*,/\"peer-port\": $(cat /pia-shared/port.dat),/" /config/settings.json
fi
transmission-daemon -g /config

5
launch.sh Normal file
View File

@@ -0,0 +1,5 @@
#!/usr/bin/env ash
./launch-transmission.sh &
exec /scripts/run

View File

@@ -0,0 +1,3 @@
PASS=<password>
USER=<user>
LOC=nl_amsterdam

16
run
View File

@@ -12,6 +12,7 @@
[[ "$PORT_FATAL" =~ ^[0-1]$ ]] || PORT_FATAL=0
# Should be a positive integer
[[ "$KEEPALIVE" =~ ^[0-9]+$ ]] || KEEPALIVE=0
[[ "$META_PORT" =~ ^[0-9]+$ ]] || export META_PORT=443
# Maybe also check the following. They are all blank by default.
# LOCAL_NETWORK=
# PIA_CN=
@@ -56,12 +57,15 @@ firewall_init () {
iptables -A INPUT -i lo -j ACCEPT
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
# Temporarily allow DNS queries
# We also need to temporarily allow the following:
# DNS queries
iptables -A OUTPUT -p udp --dport 53 -j ACCEPT
# We also need to temporarily allow the following
# HTTPS to download the server list and access API for generating auth token
iptables -A OUTPUT -p tcp --dport 443 -j ACCEPT
# API access to register the public WireGuard key
iptables -A OUTPUT -p tcp --dport 1337 -j ACCEPT
# Non-default API port if set
[ "$META_PORT" -ne 443 ] && iptables -A OUTPUT -p tcp --dport "$META_PORT" -j ACCEPT
}
# Alpine 3.19 changed the default iptables backend to iptables-nft
@@ -136,9 +140,11 @@ get_auth_token () {
[ -z "$PASS" ] && echo "$(date): PIA password not set. Unable to retrieve new auth token." && fatal_error
[ -z "$USER" ] && echo "$(date): PIA username not set. Unable to retrieve new auth token." && fatal_error
echo "$(date): Generating auth token"
if ! /scripts/pia-auth.sh -u "$USER" -p "$PASS" > "$tokenfile"; then
local token
if ! token=$(/scripts/pia-auth.sh -u "$USER" -p "$PASS" -n "$META_CN" -i "$META_IP" -o "$META_PORT" -c "$pia_cacrt"); then
echo "$(date): Failed to acquire new auth token" && fatal_error
fi
echo "$token" > "$tokenfile"
chmod 600 "$tokenfile"
}
@@ -171,6 +177,7 @@ for location in ${LOC//,/ }; do
if [ "$result" -eq 2 ]; then
# Reauth and retry if auth failed
# An auth error implies that the location id is valid and the endpoint responsive
rm "$tokenfile"
get_auth_token
gen_wgconf "$location" || fatal_error
elif [ "$result" -eq 3 ]; then
@@ -223,6 +230,7 @@ if [ $FIREWALL -eq 1 ]; then
iptables -D OUTPUT -p udp --dport 53 -j ACCEPT
iptables -D OUTPUT -p tcp --dport 443 -j ACCEPT
iptables -D OUTPUT -p tcp --dport 1337 -j ACCEPT
[ "$META_PORT" -ne 443 ] && iptables -D OUTPUT -p tcp --dport "$META_PORT" -j ACCEPT
# Allow docker network input/output
for iface in /sys/class/net/*; do

View File

@@ -0,0 +1,6 @@
[Unit]
Description=update Transmission blocklist daily
[Service]
Type=oneshot
ExecStart=/bin/sh -c 'docker ps | grep transmission >/dev/null && docker exec transmission transmission-remote -n salfter:rea5hXVH3acBVGFSfZwHxap9 --blocklist-update >/dev/null || true'

View File

@@ -0,0 +1,6 @@
[Unit]
Description=update Transmission blocklist daily
[Timer]
OnCalendar=*-*-* 01:00:00
[Install]
WantedBy=timers.target

4
update-blocklist.sh Executable file
View File

@@ -0,0 +1,4 @@
#!/usr/bin/env bash
docker ps | grep transmission >/dev/null && \
docker exec transmission transmission-remote -n salfter:rea5hXVH3acBVGFSfZwHxap9 --blocklist-update >/dev/null