diff --git a/openvpn/pia/update-port.sh b/openvpn/pia/update-port.sh index 3b9ce1348..95ded08df 100755 --- a/openvpn/pia/update-port.sh +++ b/openvpn/pia/update-port.sh @@ -1,9 +1,9 @@ -#! /bin/bash - -echo "Wait for tunnel to be fully initialized and PIA is ready to give us a port" -sleep 15 - +#!/bin/bash +#export PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin:/root/bin # Source our persisted env variables from container startup +## this is an amalgamation of two scripts to keep my PIA working, credit to the main authors, the original scripts linked in the READ.ME +#v0.2 + . /etc/transmission/environment-variables.sh # Settings @@ -14,49 +14,76 @@ transmission_passwd=$(tail -1 ${TRANSMISSION_PASSWD_FILE}) pia_client_id_file=/etc/transmission/pia_client_id transmission_settings_file=${TRANSMISSION_HOME}/settings.json -# -# First get a port from PIA -# +sleep 5 -new_client_id() { - head -n 100 /dev/urandom | sha256sum | tr -d " -" | tee ${pia_client_id_file} +###### PIA Variables ###### +curl_max_time=15 +curl_retry=5 +curl_retry_delay=15 +user=$(sed -n 1p /config/openvpn-credentials.txt) +pass=$(sed -n 2p /config/openvpn-credentials.txt) +pf_host=$(ip route | head -1 | grep tun | awk '{ print $3 }') +###### Nextgen PIA port forwarding ################## + +get_auth_token () { + tok=$(curl --insecure --silent --show-error --request POST --max-time $curl_max_time \ + --header "Content-Type: application/json" \ + --data "{\"username\":\"$user\",\"password\":\"$pass\"}" \ + "https://www.privateinternetaccess.com/api/client/v2/token" | jq -r '.token') + [ $? -ne 0 ] && echo "Failed to acquire new auth token" && exit 1 + #echo "$tok" + } + +get_auth_token + +yes '' | sed 3q + +get_sig () { + pf_getsig=$(curl --insecure --get --silent --show-error \ + --retry $curl_retry --retry-delay $curl_retry_delay --max-time $curl_max_time \ + --data-urlencode "token=$tok" \ + $verify \ + "https://$pf_host:19999/getSignature") + if [ "$(echo $pf_getsig | jq -r .status)" != "OK" ]; then + echo "$(date): getSignature error" + echo $pf_getsig + echo "the has been a fatal_error" + fi + pf_payload=$(echo $pf_getsig | jq -r .payload) + pf_getsignature=$(echo $pf_getsig | jq -r .signature) + pf_port=$(echo $pf_payload | base64 -d | jq -r .port) + pf_token_expiry_raw=$(echo $pf_payload | base64 -d | jq -r .expires_at) + if date --help 2>&1 /dev/null | grep -i 'busybox' > /dev/null; then + pf_token_expiry=$(date -D %Y-%m-%dT%H:%M:%S --date="$pf_token_expiry_raw" +%s) + else + pf_token_expiry=$(date --date="$pf_token_expiry_raw" +%s) + fi } -pia_client_id="$(cat ${pia_client_id_file} 2>/dev/null)" -if [[ -z "${pia_client_id}" ]]; then - echo "Generating new client id for PIA" - pia_client_id=$(new_client_id) -fi +bind_port () { + pf_bind=$(curl --insecure --get --silent --show-error \ + --retry $curl_retry --retry-delay $curl_retry_delay --max-time $curl_max_time \ + --data-urlencode "payload=$pf_payload" \ + --data-urlencode "signature=$pf_getsignature" \ + $verify \ + "https://$pf_host:19999/bindPort") + if [ "$(echo $pf_bind | jq -r .status)" = "OK" ]; then + echo "the port has been bound to $pf_port $(date)" + else + echo "$(date): bindPort error" + echo $pf_bind + echo "the has been a fatal_error" + fi +} -# Get the port -port_assignment_url="http://209.222.18.222:2000/?client_id=$pia_client_id" -pia_response=$(curl -s -f "$port_assignment_url") -pia_curl_exit_code=$? +get_sig -if [[ -z "$pia_response" ]]; then - echo "Port forwarding is already activated on this connection, has expired, or you are not connected to a PIA region that supports port forwarding" -fi +#echo "sig is $pf_getsig" +echo "port is $pf_port" -# Check for curl error (curl will fail on HTTP errors with -f flag) -if [[ ${pia_curl_exit_code} -ne 0 ]]; then - echo "curl encountered an error looking up new port: $pia_curl_exit_code" - exit -fi - -# Check for errors in PIA response -error=$(echo "$pia_response" | grep -oE "\"error\".*\"") -if [[ ! -z "$error" ]]; then - echo "PIA returned an error: $error" - exit -fi - -# Get new port, check if empty -new_port=$(echo "$pia_response" | grep -oE "[0-9]+") -if [[ -z "$new_port" ]]; then - echo "Could not find new port from PIA" - exit -fi -echo "Got new port $new_port from PIA" +bind_port +#echo "pf bind is $pf_bind" +new_port="$pf_port" # # Now, set port in Transmission @@ -65,6 +92,8 @@ echo "Got new port $new_port from PIA" # Check if transmission remote is set up with authentication auth_enabled=$(grep 'rpc-authentication-required\"' "$transmission_settings_file" \ | grep -oE 'true|false') + + if [[ "true" = "$auth_enabled" ]] then echo "transmission auth required" @@ -103,3 +132,44 @@ if [[ "$new_port" != "$transmission_peer_port" ]]; then else echo "No action needed, port hasn't changed" fi + +echo "" +echo "initial setup complete!" +echo "" +echo "waiting for rebind loop................." + +echo "token expiry $pf_token_expiry" +pf_remaining=$(( $pf_token_expiry - $(date +%s) )) +echo "remaining = $pf_remaining" +pf_bindinterval=$(( 30 * 60)) +# Get a new token when the current one has less than this remaining +# Defaults to 7 days (same as desktop app) +pf_minreuse=$(( 60 * 60 * 24 * 7 )) + +pf_remaining=0 +pf_firstrun=1 +vpn_ip=$(ip route | head -1 | grep tun | awk '{ print $3 }') +pf_host="$vpn_ip" + +while true; do + pf_remaining=$(( $pf_token_expiry - $(date +%s) )) + # Get a new pf token as the previous one will expire soon + if [ $pf_remaining -lt $pf_minreuse ]; then + if [ $pf_firstrun -ne 1 ]; then + echo "$(date): PF token will expire soon. Getting new one." + else + echo "$(date): Getting PF token" + pf_firstrun=0 + fi + get_sig + echo "$(date): Obtained PF token. Expires at $pf_token_expiry_raw" + bind_port + echo "$(date): Server accepted PF bind" + echo "$(date): Forwarding on port $pf_port" + echo "$(date): Rebind interval: $pf_bindinterval seconds" + fi + sleep $pf_bindinterval & + wait $! + +bind_port +done