Skip to content

Instantly share code, notes, and snippets.

@NickHollow
Forked from triffid/openrc-init-pia
Created January 26, 2021 10:29
Show Gist options
  • Select an option

  • Save NickHollow/c540bb6ca3207ca89b15557047ce62a7 to your computer and use it in GitHub Desktop.

Select an option

Save NickHollow/c540bb6ca3207ca89b15557047ce62a7 to your computer and use it in GitHub Desktop.

Revisions

  1. @triffid triffid revised this gist Jan 12, 2021. 3 changed files with 75 additions and 46 deletions.
    4 changes: 2 additions & 2 deletions openrc-init-pia
    Original file line number Diff line number Diff line change
    @@ -31,7 +31,7 @@ start() {
    (
    export CONFIGDIR="$CONFIGDIR"
    export CONFIG="$CONFIG"
    while "$command" 2>&1 | tee /var/log/pia-wg.log && [ ${PIPESTATUS[0]} -ne 0 ]
    while "$command" "$@" 2>&1 | tee /var/log/pia-wg.log && [ ${PIPESTATUS[0]} -ne 0 ]
    do
    ewarn "Failed, retrying"
    sleep 1
    @@ -42,7 +42,7 @@ start() {
    }

    reload() {
    start
    start -n
    }

    restart() {
    11 changes: 11 additions & 0 deletions pia-currentserver.sh
    Original file line number Diff line number Diff line change
    @@ -36,6 +36,17 @@ then
    source "$CONFIG"
    fi

    if [ -z "$CONNCACHE" ]
    then
    CONNCACHE="$CONFIGDIR/cache.json"
    fi

    if [ -r "$CONNCACHE" ]
    then
    jq . "$CONNCACHE"
    exit 0
    fi

    SERVER_IP="$(jq -r .server_ip "$REMOTEINFO")"

    if [ -z "$(jq '.regions | .[] | select(.servers.wg[0].ip == "'"$SERVER_IP"'")' "$DATAFILE_NEW")" ]
    106 changes: 62 additions & 44 deletions pia-wg.sh
    Original file line number Diff line number Diff line change
    @@ -84,8 +84,8 @@ fi

    if [ -z "$LOC" ]
    then
    echo "Setting default location: US (any, using pattern match)"
    LOC="us"
    echo "Setting default location: any"
    LOC="."
    fi

    if [ -z "$PIA_INTERFACE" ]
    @@ -119,6 +119,11 @@ then
    REMOTEINFO="$CONFIGDIR/remote.info"
    fi

    if [ -z "$CONNCACHE" ]
    then
    CONNCACHE="$CONFIGDIR/cache.json"
    fi

    # get token
    if [ -z "$TOK" ] && [ -r "$TOKENFILE" ]
    then
    @@ -198,72 +203,85 @@ then
    curl --max-time 15 'https://raw.githubusercontent.com/pia-foss/desktop/master/daemon/res/ca/rsa_4096.crt' > "$PIA_CERT" || exit 1
    fi

    if [ "$(jq -r ".regions | .[] | select(.id == \"$LOC\")" "$DATAFILE_NEW")" == "" ]
    if [ "$1" == "-n" ]
    then
    LOC=$(jq -r '.regions | .[] | select(.id | test("^'"$LOC"'")) '${PORTFORWARD:+'| select(.port_forward) '}'| .id' "$DATAFILE_NEW" | shuf -n 1)
    rm "$CONNCACHE"
    fi

    if [ "$(jq -r ".regions | .[] | select(.id == \"$LOC\")" "$DATAFILE_NEW")" == "" ]
    if [ -r "$CONNCACHE" ]
    then
    echo "Location $LOC not found!"
    echo "Options are:"
    # jq '.regions | .[] | .id' "$DATAFILE_NEW" | sort | sed -e 's/^/ * /'
    ( echo $'\e[1mLocation\e[1m\tRegion\tPort Forward\tGeolocated'; echo $'\e[0m----------------\e[0m\t------------------\t------------\t----------'; jq -r '.regions | .[] | '${PORTFORWARD:+'| select(.port_forward)'}' [.id, .name, .port_forward, .geo] | "'$'\e''[1m\(.[0])'$'\e''[0m\t\(.[1])\t\(.[2])\t\(.[3])"' "$DATAFILE_NEW"; ) | column -t -s $'\t'
    echo "${PORTFORWARD:+'Note: only port-forwarding regions displayed'}"
    echo "Please edit $CONFIG and change your desired location, then try again"
    exit 1
    WG_NAME="$(jq -r ".name" "$CONNCACHE")"
    WG_DNS="$(jq -r ".dns" "$CONNCACHE")"

    WG_HOST="$(jq -r ".servers.wg[0].ip" "$CONNCACHE")"
    WG_CN="$(jq -r ".servers.wg[0].cn" "$CONNCACHE")"
    WG_PORT="$(jq -r '.groups.wg[0].ports[]' "$DATAFILE_NEW" | sort -r | head -n1)"

    WG_SN="$(cut -d. -f1 <<< "$WG_DNS")"
    fi

    if [ -z "$TOK" ]
    if [ -z "$WG_HOST" ] || [ -z "$WG_CN" ] || [ -z "$WG_PORT" ]
    then
    if [ -z "$PASS" ]
    if [ "$(jq -r ".regions | .[] | select(.id == \"$LOC\")" "$DATAFILE_NEW")" == "" ]
    then
    echo "A new auth token is required, and you have not saved your password."
    echo "Your password will NOT be saved if you enter it now."
    read -p "Please enter your privateinternetaccess.com password for $PIA_USERNAME: " -s PASS
    LOC=$(jq -r '.regions | .[] | select(.id | test("^'"$LOC"'")) '${PORTFORWARD:+'| select(.port_forward) '}'| .id' "$DATAFILE_NEW" | shuf -n 1)
    fi
    TOK=$(curl -X POST \
    -H "Content-Type: application/json" \
    -d "{\"username\":\"$PIA_USERNAME\",\"password\":\"$PASS\"}" \
    "https://www.privateinternetaccess.com/api/client/v2/token" | jq -r '.token')

    # echo "got token: $TOK"

    if [ -z "$TOK" ]; then
    echo "Failed to authenticate with privateinternetaccess"
    echo "Check your user/pass and try again"
    if [ "$(jq -r ".regions | .[] | select(.id == \"$LOC\")" "$DATAFILE_NEW")" == "" ]
    then
    echo "Location $LOC not found!"
    echo "Options are:"
    # jq '.regions | .[] | .id' "$DATAFILE_NEW" | sort | sed -e 's/^/ * /'
    ( echo $'\e[1mLocation\e[1m\tRegion\tPort Forward\tGeolocated'; echo $'\e[0m----------------\e[0m\t------------------\t------------\t----------'; jq -r '.regions | .[] | '${PORTFORWARD:+'| select(.port_forward)'}' [.id, .name, .port_forward, .geo] | "'$'\e''[1m\(.[0])'$'\e''[0m\t\(.[1])\t\(.[2])\t\(.[3])"' "$DATAFILE_NEW"; ) | column -t -s $'\t'
    echo "${PORTFORWARD:+'Note: only port-forwarding regions displayed'}"
    echo "Please edit $CONFIG and change your desired location, then try again"
    exit 1
    fi

    touch "$TOKENFILE"
    chmod 600 "$TOKENFILE"
    echo "$TOK" > "$TOKENFILE"
    fi
    if [ -z "$TOK" ]
    then
    if [ -z "$PASS" ]
    then
    echo "A new auth token is required, and you have not saved your password."
    echo "Your password will NOT be saved if you enter it now."
    read -p "Please enter your privateinternetaccess.com password for $PIA_USERNAME: " -s PASS
    fi
    TOK=$(curl -X POST \
    -H "Content-Type: application/json" \
    -d "{\"username\":\"$PIA_USERNAME\",\"password\":\"$PASS\"}" \
    "https://www.privateinternetaccess.com/api/client/v2/token" | jq -r '.token')

    # WG_NAME="$(jq -r ".$LOC.name" "$DATAFILE")"
    # WG_DNS="$(jq -r ".$LOC.dns" "$DATAFILE")"
    # WG_URL="$(jq -r ".$LOC.wireguard.host" "$DATAFILE")"
    # WG_CN="$(jq -r ".$LOC.wireguard.serial" "$DATAFILE")"
    # echo "got token: $TOK"

    WG_NAME="$(jq -r ".regions | .[] | select(.id == \"$LOC\") | .name" "$DATAFILE_NEW")"
    WG_DNS="$(jq -r ".regions | .[] | select(.id == \"$LOC\") | .dns" "$DATAFILE_NEW")"
    if [ -z "$TOK" ]; then
    echo "Failed to authenticate with privateinternetaccess"
    echo "Check your user/pass and try again"
    exit 1
    fi

    WG_HOST="$(jq -r ".regions | .[] | select(.id == \"$LOC\") | .servers.wg[0].ip" "$DATAFILE_NEW")"
    WG_CN="$(jq -r ".regions | .[] | select(.id == \"$LOC\") | .servers.wg[0].cn" "$DATAFILE_NEW")"
    # WG_PORT=1337
    WG_PORT="$(jq -r '.groups.wg[0].ports[]' "$DATAFILE_NEW" | sort -r | head -n1)"
    touch "$TOKENFILE"
    chmod 600 "$TOKENFILE"
    echo "$TOK" > "$TOKENFILE"
    fi

    jq -r ".regions | .[] | select(.id == \"$LOC\")" "$DATAFILE_NEW" > "$CONNCACHE"

    WG_SN="$(cut -d. -f1 <<< "$WG_DNS")"
    # WG_HOST="$(cut -d: -f1 <<< "$WG_URL")"
    # WG_PORT="$(cut -d: -f2 <<< "$WG_URL")"
    WG_NAME="$(jq -r ".name" "$CONNCACHE")"
    WG_DNS="$(jq -r ".dns" "$CONNCACHE")"

    WG_HOST="$(jq -r ".servers.wg[0].ip" "$CONNCACHE")"
    WG_CN="$(jq -r ".servers.wg[0].cn" "$CONNCACHE")"
    WG_PORT="$(jq -r '.groups.wg[0].ports[]' "$DATAFILE_NEW" | sort -r | head -n1)"

    WG_SN="$(cut -d. -f1 <<< "$WG_DNS")"
    fi

    if [ -z "$WG_HOST$WG_PORT" ]; then
    echo "no wg region, exiting"
    exit 1
    fi

    echo "Registering public key with $WG_NAME ($WG_HOST)"
    echo "Registering public key with "$'\e[1m'"$WG_NAME"$'\e[0m (\e[1m'"$WG_HOST"$'\e[0m)'
    ip rule add to "$WG_HOST" lookup china pref 10

    if ! curl -GsS \
  2. @triffid triffid revised this gist Nov 14, 2020. 1 changed file with 12 additions and 3 deletions.
    15 changes: 12 additions & 3 deletions pia-wg.sh
    Original file line number Diff line number Diff line change
    @@ -181,7 +181,7 @@ if ! [ -r "$DATAFILE_NEW" ]
    then
    echo "Fetching new generation server list from PIA"
    # wget -O "$DATAFILE" 'https://raw.githubusercontent.com/pia-foss/desktop/master/tests/res/openssl/payload1/payload' || exit 1
    curl 'https://serverlist.piaservers.net/vpninfo/servers/new' -o "$DATAFILE_NEW.temp" || exit 1
    curl --max-time 15 'https://serverlist.piaservers.net/vpninfo/servers/new' -o "$DATAFILE_NEW.temp" || exit 1
    if [ "$(jq '.regions | map_values(select(.servers.wg)) | keys' "$DATAFILE_NEW.temp" 2>/dev/null | wc -l)" -le 30 ]
    then
    echo "Bad serverlist retrieved to $DATAFILE_NEW.temp, exiting"
    @@ -195,7 +195,7 @@ fi
    if ! [ -r "$PIA_CERT" ]
    then
    echo "Fetching PIA self-signed cert from github"
    curl 'https://raw.githubusercontent.com/pia-foss/desktop/master/daemon/res/ca/rsa_4096.crt' > "$PIA_CERT" || exit 1
    curl --max-time 15 'https://raw.githubusercontent.com/pia-foss/desktop/master/daemon/res/ca/rsa_4096.crt' > "$PIA_CERT" || exit 1
    fi

    if [ "$(jq -r ".regions | .[] | select(.id == \"$LOC\")" "$DATAFILE_NEW")" == "" ]
    @@ -372,6 +372,12 @@ then
    # remove old route
    ip rule del to "$OLD_PEER_IP" lookup china 2>/dev/null
    fi

    # Note: only if Table = off in wireguard config file above
    ip route add default dev "$PIA_INTERFACE"

    # Specific to my setup
    ip route add default table vpnonly dev "$PIA_INTERFACE"
    else
    echo "Bringing up interface '$PIA_INTERFACE'"

    @@ -458,8 +464,11 @@ if find "$DATAFILE_NEW" -mtime -3 -exec false {} +
    then
    echo "PIA endpoint list is stale, Fetching new generation wireguard server list"

    echo curl --max-time 15 --interface "$PIA_INTERFACE" --CAcert "$PIA_CERT" --resolve "$WG_CN:443:10.0.0.1" "https://$WG_CN:443/vpninfo/servers/v4"
    # curl 'https://serverlist.piaservers.net/vpninfo/servers/new' > "$DATAFILE_NEW.temp" || exit 1
    curl --interface "$PIA_INTERFACE" --CAcert "$PIA_CERT" --resolve "$WG_CN:443:10.0.0.1" "https://$WG_CN:443/vpninfo/servers/v4" > "$DATAFILE_NEW.temp" || exit 1
    curl --max-time 15 --interface "$PIA_INTERFACE" --CAcert "$PIA_CERT" --resolve "$WG_CN:443:10.0.0.1" "https://$WG_CN:443/vpninfo/servers/v4" > "$DATAFILE_NEW.temp" ||
    curl --max-time 15 'https://serverlist.piaservers.net/vpninfo/servers/new' > "$DATAFILE_NEW.temp" ||
    exit 0

    if [ "$(jq '.regions | map_values(select(.servers.wg)) | keys' "$DATAFILE_NEW.temp" 2>/dev/null | wc -l)" -le 30 ]
    then
  3. @triffid triffid revised this gist Nov 14, 2020. 1 changed file with 3 additions and 3 deletions.
    6 changes: 3 additions & 3 deletions pia-portforward.sh
    Original file line number Diff line number Diff line change
    @@ -119,7 +119,6 @@ fi
    if [ $(( "$PF_TOKEN_EXPIRY" - $(date -u +%s) )) -le 900 ]
    then
    echo "Signature stale, refetching"
    exit 1

    # Very strange - must connect via 10.0/8 private VPN link to the server's public IP - why?
    # I tried SERVER_VIP (10.0/8 private IP) instead of SERVER_IP (public IP) but it won't connect
    @@ -137,7 +136,7 @@ then
    PF_PAYLOAD_RAW=$(jq -r .payload <<< "$PF_SIG")
    PF_PAYLOAD=$(base64 -d <<< "$PF_PAYLOAD_RAW")
    PF_TOKEN_EXPIRY_RAW=$(jq -r .expires_at <<< "$PF_PAYLOAD")
    PF_TOKEN_EXPIRY=$(date -D %Y-%m-%dT%H:%M:%S --date="$PF_TOKEN_EXPIRY_RAW" +%s)
    PF_TOKEN_EXPIRY=$(date +%Y-%m-%dT%H:%M:%S --date="$PF_TOKEN_EXPIRY_RAW" +%s)
    fi

    PF_GETSIGNATURE=$(jq -r .signature <<< "$PF_SIG")
    @@ -166,7 +165,8 @@ echo > /dev/stderr
    # #
    ###############################################################################

    transmission-remote -p "$PF_PORT" -pt
    echo "To test if your port has successfully been forwarded, execute:"
    echo "transmission-remote -p "$PF_PORT" -pt"

    ###############################################################################
    # #
  4. @triffid triffid revised this gist Sep 30, 2020. 1 changed file with 12 additions and 1 deletion.
    13 changes: 12 additions & 1 deletion pia-wg.sh
    Original file line number Diff line number Diff line change
    @@ -474,7 +474,18 @@ fi
    if [ -n "$PORTFORWARD" ]
    then
    echo "Requesting forwarded port..."
    pia-portforward.sh
    if which pia-portforward.sh &>/dev/null
    then
    pia-portforward.sh
    else
    if [ -r "${0%/*}/pia-portforward.sh" ]
    then
    "${0%/*}/pia-portforward.sh"
    else
    echo "pia-portforward.sh couldn't be found!"
    exit 1
    fi
    fi
    echo "Note: pia-portforward.sh should be called every ~5 minutes to maintain your forward."
    echo "You could try:"
    echo " while sleep 5m; do pia-portforward.sh; done"
  5. @triffid triffid revised this gist Sep 26, 2020. 1 changed file with 26 additions and 23 deletions.
    49 changes: 26 additions & 23 deletions pia-wg.sh
    Original file line number Diff line number Diff line change
    @@ -23,10 +23,17 @@ then
    EXIT=1
    fi

    if ! which curl &>/dev/null
    then
    echo "The 'curl' utility is required"
    echo " Most package managers should have a 'curl' package available"
    EXIT=1
    fi

    if ! which wg &>/dev/null
    then
    echo "The 'wg' utility from wireguard/wireguard-tools is required"
    echo " Most package managers should have 'wireguard' or 'wireguard-tools' packages available"
    echo "The 'wg' utility from wireguard-tools is required"
    echo " Most package managers should have a 'wireguard-tools' package available"
    EXIT=1
    fi

    @@ -146,6 +153,9 @@ LOC="$LOC"
    # wireguard client-side private key (new key generated every invocation if not specified)
    CLIENT_PRIVATE_KEY="$CLIENT_PRIVATE_KEY"
    # if PORTFORWARD is set, pia-wg will only connect to port-forward capable servers, and will invoke pia-portforward.sh after connection
    # PORTFORWARD="literally anything"
    ENDCONFIG
    echo "Config saved"
    fi
    @@ -171,7 +181,7 @@ if ! [ -r "$DATAFILE_NEW" ]
    then
    echo "Fetching new generation server list from PIA"
    # wget -O "$DATAFILE" 'https://raw.githubusercontent.com/pia-foss/desktop/master/tests/res/openssl/payload1/payload' || exit 1
    curl 'https://serverlist.piaservers.net/vpninfo/servers/new' > "$DATAFILE_NEW.temp" || exit 1
    curl 'https://serverlist.piaservers.net/vpninfo/servers/new' -o "$DATAFILE_NEW.temp" || exit 1
    if [ "$(jq '.regions | map_values(select(.servers.wg)) | keys' "$DATAFILE_NEW.temp" 2>/dev/null | wc -l)" -le 30 ]
    then
    echo "Bad serverlist retrieved to $DATAFILE_NEW.temp, exiting"
    @@ -190,33 +200,16 @@ fi

    if [ "$(jq -r ".regions | .[] | select(.id == \"$LOC\")" "$DATAFILE_NEW")" == "" ]
    then
    LOC=$(jq -r '.regions | .[] | select(.id | test("^'"$LOC"'")) | .id' "$DATAFILE_NEW" | shuf -n 1)
    LOC=$(jq -r '.regions | .[] | select(.id | test("^'"$LOC"'")) '${PORTFORWARD:+'| select(.port_forward) '}'| .id' "$DATAFILE_NEW" | shuf -n 1)
    fi

    # if [ "$(jq -r ".$LOC.wireguard" "$DATAFILE")" == "null" ]
    # then
    # # echo "No exact match for location \"$LOC\" trying pattern"
    # # from https://unix.stackexchange.com/questions/443884/match-keys-with-regex-in-jq/443927#443927
    # LOC=$(jq 'with_entries(if (.key|test("^'"$LOC"'")) then ( {key: .key, value: .value } ) else empty end ) | keys' "$DATAFILE" | grep ^\ | cut -d\" -f2 | shuf -n 1)
    # fi

    # if [ "$(jq -r ".$LOC.wireguard" "$DATAFILE")" == "null" ]
    # then
    # echo "Location $LOC not found!"
    # echo "Options are:"
    # jq 'map_values(select(.wireguard)) | keys' "$DATAFILE"
    # echo
    # echo "Please edit $CONFIG and change your desired location, then try again"
    # exit 1
    # fi

    if [ "$(jq -r ".regions | .[] | select(.id == \"$LOC\")" "$DATAFILE_NEW")" == "" ]
    then
    echo "Location $LOC not found!"
    echo "Options are:"
    # jq '.regions | .[] | .id' "$DATAFILE_NEW" | sort | sed -e 's/^/ * /'
    ( echo $'\e[1mLocation\e[1m\tRegion\tPort Forward\tGeolocated'; echo $'\e[0m----------------\e[0m\t------------------\t------------\t----------'; jq -r '.regions | .[] | [.id, .name, .port_forward, .geo] | "'$'\e''[1m\(.[0])'$'\e''[0m\t\(.[1])\t\(.[2])\t\(.[3])"' "$DATAFILE_NEW"; ) | column -t -s $'\t'
    echo
    ( echo $'\e[1mLocation\e[1m\tRegion\tPort Forward\tGeolocated'; echo $'\e[0m----------------\e[0m\t------------------\t------------\t----------'; jq -r '.regions | .[] | '${PORTFORWARD:+'| select(.port_forward)'}' [.id, .name, .port_forward, .geo] | "'$'\e''[1m\(.[0])'$'\e''[0m\t\(.[1])\t\(.[2])\t\(.[3])"' "$DATAFILE_NEW"; ) | column -t -s $'\t'
    echo "${PORTFORWARD:+'Note: only port-forwarding regions displayed'}"
    echo "Please edit $CONFIG and change your desired location, then try again"
    exit 1
    fi
    @@ -478,4 +471,14 @@ then
    fi
    fi

    if [ -n "$PORTFORWARD" ]
    then
    echo "Requesting forwarded port..."
    pia-portforward.sh
    echo "Note: pia-portforward.sh should be called every ~5 minutes to maintain your forward."
    echo "You could try:"
    echo " while sleep 5m; do pia-portforward.sh; done"
    echo "or alternately add a cronjob with crontab -e"
    fi

    exit 0
  6. @triffid triffid revised this gist Sep 24, 2020. 1 changed file with 2 additions and 2 deletions.
    4 changes: 2 additions & 2 deletions pia-portforward.sh
    Original file line number Diff line number Diff line change
    @@ -124,7 +124,7 @@ then
    # Very strange - must connect via 10.0/8 private VPN link to the server's public IP - why?
    # I tried SERVER_VIP (10.0/8 private IP) instead of SERVER_IP (public IP) but it won't connect
    # It also won't connect if you try to connect from the internet, hence needing --interface "$PIA_INTERFACE"
    PF_SIG="$(curl --interface "$PIA_INTERFACE" --CAcert "$PIA_CERT" --get --silent --show-error --retry 5 --retry-delay 5 --max-time 15 --data-urlencode "token=$TOK" --resolve "$WG_CN:19999:$SERVER_IP" "https://$WG_CN:19999/getSignature" | tee "$PF_SIGFILE")"
    PF_SIG="$(curl --interface "$PIA_INTERFACE" --CAcert "$PIA_CERT" --get --silent --show-error --retry 5 --retry-delay 5 --max-time 15 --data-urlencode token@/dev/fd/3 --resolve "$WG_CN:19999:$SERVER_IP" "https://$WG_CN:19999/getSignature" 3< <(echo -n "$TOK") | tee "$PF_SIGFILE")"

    PF_STATUS="$(jq -r .status <<< "$PF_SIG")"
    if [ "$PF_STATUS" != "OK" ]
    @@ -143,7 +143,7 @@ fi
    PF_GETSIGNATURE=$(jq -r .signature <<< "$PF_SIG")
    PF_PORT=$(jq -r .port <<< "$PF_PAYLOAD")

    PF_BIND="$(curl --interface "$PIA_INTERFACE" --CAcert "$PIA_CERT" --get --silent --show-error --retry 5 --retry-delay 5 --max-time 15 --data-urlencode "payload=$PF_PAYLOAD_RAW" --data-urlencode "signature=$PF_GETSIGNATURE" --resolve "$WG_CN:19999:$SERVER_IP" "https://$WG_CN:19999/bindPort")"
    PF_BIND="$(curl --interface "$PIA_INTERFACE" --CAcert "$PIA_CERT" --get --silent --show-error --retry 5 --retry-delay 5 --max-time 15 --data-urlencode payload@/dev/fd/3 --data-urlencode signature@/dev/fd/4 --resolve "$WG_CN:19999:$SERVER_IP" "https://$WG_CN:19999/bindPort" 3< <(echo -n "$PF_PAYLOAD_RAW") 4< <(echo -n "$PF_GETSIGNATURE") )"

    PF_STATUS="$(jq -r .status <<< "$PF_BIND")"
    if [ "$PF_STATUS" != "OK" ]
  7. @triffid triffid revised this gist Sep 14, 2020. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion pia-wg.sh
    Original file line number Diff line number Diff line change
    @@ -135,7 +135,7 @@ then
    # your privateinternetaccess.com username (not needed if you already have an auth token)
    PIA_USERNAME="$PIA_USERNAME"
    # your privateinternetaccess.com password (not needed if you already have an auth token)
    PASS="$PASS"
    PASS='$PASS'
    # your desired endpoint location
    LOC="$LOC"
  8. @triffid triffid revised this gist Sep 14, 2020. 1 changed file with 6 additions and 6 deletions.
    12 changes: 6 additions & 6 deletions pia-wg.sh
    Original file line number Diff line number Diff line change
    @@ -120,11 +120,11 @@ fi

    # echo "$TOK"

    if [ -z "$TOK" ] && ([ -z "$USER" ] || [ -z "$PASS" ])
    if [ -z "$TOK" ] && ([ -z "$PIA_USERNAME" ] || [ -z "$PASS" ])
    then
    if [ -z "$USER" ]
    if [ -z "$PIA_USERNAME" ]
    then
    read -p "Please enter your privateinternetaccess.com username: " USER
    read -p "Please enter your privateinternetaccess.com username: " PIA_USERNAME
    fi
    if [ -z "$PASS" ]
    then
    @@ -133,7 +133,7 @@ then
    fi
    cat <<ENDCONFIG > "$CONFIG"
    # your privateinternetaccess.com username (not needed if you already have an auth token)
    USER="$USER"
    PIA_USERNAME="$PIA_USERNAME"
    # your privateinternetaccess.com password (not needed if you already have an auth token)
    PASS="$PASS"
    @@ -227,11 +227,11 @@ then
    then
    echo "A new auth token is required, and you have not saved your password."
    echo "Your password will NOT be saved if you enter it now."
    read -p "Please enter your privateinternetaccess.com password for $USER: " -s PASS
    read -p "Please enter your privateinternetaccess.com password for $PIA_USERNAME: " -s PASS
    fi
    TOK=$(curl -X POST \
    -H "Content-Type: application/json" \
    -d "{\"username\":\"$USER\",\"password\":\"$PASS\"}" \
    -d "{\"username\":\"$PIA_USERNAME\",\"password\":\"$PASS\"}" \
    "https://www.privateinternetaccess.com/api/client/v2/token" | jq -r '.token')

    # echo "got token: $TOK"
  9. @triffid triffid revised this gist Sep 14, 2020. 2 changed files with 30 additions and 8 deletions.
    12 changes: 11 additions & 1 deletion pia-currentserver.sh
    Original file line number Diff line number Diff line change
    @@ -36,4 +36,14 @@ then
    source "$CONFIG"
    fi

    jq '.regions | .[] | select(.servers.wg[0].ip == "'"$(jq -r .server_ip "$REMOTEINFO")"'")' "$DATAFILE_NEW"
    SERVER_IP="$(jq -r .server_ip "$REMOTEINFO")"

    if [ -z "$(jq '.regions | .[] | select(.servers.wg[0].ip == "'"$SERVER_IP"'")' "$DATAFILE_NEW")" ]
    then
    SERVER_IP_S="$(cut -d. -f1-3 <<< $SERVER_IP)"
    jq '.regions | .[] | select(.servers.wg[0].ip | test("^'"$SERVER_IP_S"'"))' "$DATAFILE_NEW"

    echo "Note: Inexact match for $SERVER_IP_S.* ($SERVER_IP not found)" >/dev/stderr
    else
    jq '.regions | .[] | select(.servers.wg[0].ip == "'"$SERVER_IP"'")' "$DATAFILE_NEW"
    fi
    26 changes: 19 additions & 7 deletions pia-portforward.sh
    Original file line number Diff line number Diff line change
    @@ -69,7 +69,25 @@ then
    PF_BINDFILE="$CONFIGDIR/pf-bind"
    fi

    WG_INFO="$(jq -r '.regions | .[] | select(.servers.wg[0].ip == "'"$(jq -r .server_ip "$REMOTEINFO")"'")' "$DATAFILE_NEW")"
    PEER_IP="$(jq -r .peer_ip "$REMOTEINFO")"
    SERVER_PUBLIC_KEY="$(jq -r .server_key "$REMOTEINFO")"
    SERVER_IP="$(jq -r .server_ip "$REMOTEINFO")"
    SERVER_PORT="$(jq -r .server_port "$REMOTEINFO")"
    SERVER_VIP="$(jq -r .server_vip "$REMOTEINFO")"

    WG_INFO="$(jq '.regions | .[] | select(.servers.wg[0].ip == "'"$SERVER_IP"'")' "$DATAFILE_NEW")"

    if [ -z "$WG_INFO" ]
    then
    SERVER_IP_S="$(cut -d. -f1-3 <<< $SERVER_IP)"
    WG_INFO="$(jq '.regions | .[] | select(.servers.wg[0].ip | test("^'"$SERVER_IP_S"'"))' "$DATAFILE_NEW")"
    fi

    if [ -z "$WG_INFO" ]
    then
    echo "Couldn't determine server information even with fuzzy search, is your $DATAFILE_NEW ok?" >/dev/stderr
    exit 1
    fi

    if [ "$(jq -r .port_forward <<< "$WG_INFO")" != true ]
    then
    @@ -84,12 +102,6 @@ WG_DNS="$(jq -r .dns <<< "$WG_INFO")"
    WG_HOST="$(jq -r '.servers.wg[0].ip' <<< "$WG_INFO")"
    WG_CN="$(jq -r '.servers.wg[0].cn' <<< "$WG_INFO")"

    PEER_IP="$(jq -r .peer_ip "$REMOTEINFO")"
    SERVER_PUBLIC_KEY="$(jq -r .server_key "$REMOTEINFO")"
    SERVER_IP="$(jq -r .server_ip "$REMOTEINFO")"
    SERVER_PORT="$(jq -r .server_port "$REMOTEINFO")"
    SERVER_VIP="$(jq -r .server_vip "$REMOTEINFO")"

    # sections of the below adapted from Threarah's work at
    # https://github.com/thrnz/docker-wireguard-pia/blob/003f79f3b6ba24387e10d7de63ec62e98e6518a5/run#L233-L270 with permission
    # Also see https://www.reddit.com/r/PrivateInternetAccess/comments/h9y4da/is_there_any_way_to_generate_wireguard_config/fxhkpjt/
  10. @triffid triffid revised this gist Sep 11, 2020. 1 changed file with 4 additions and 4 deletions.
    8 changes: 4 additions & 4 deletions pia-portforward.sh
    Original file line number Diff line number Diff line change
    @@ -112,7 +112,7 @@ then
    # Very strange - must connect via 10.0/8 private VPN link to the server's public IP - why?
    # I tried SERVER_VIP (10.0/8 private IP) instead of SERVER_IP (public IP) but it won't connect
    # It also won't connect if you try to connect from the internet, hence needing --interface "$PIA_INTERFACE"
    PF_SIG="$(curl --interface "$PIA_INTERFACE" --CAcert "$PIA_CERT" --get --silent --show-error --retry 5 --retry-delay 5 --max-time 15 --data-urlencode "token=$TOK" --resolve "$WG_DNS:19999:$SERVER_IP" "https://$WG_DNS:19999/getSignature" | tee "$PF_SIGFILE")"
    PF_SIG="$(curl --interface "$PIA_INTERFACE" --CAcert "$PIA_CERT" --get --silent --show-error --retry 5 --retry-delay 5 --max-time 15 --data-urlencode "token=$TOK" --resolve "$WG_CN:19999:$SERVER_IP" "https://$WG_CN:19999/getSignature" | tee "$PF_SIGFILE")"

    PF_STATUS="$(jq -r .status <<< "$PF_SIG")"
    if [ "$PF_STATUS" != "OK" ]
    @@ -131,7 +131,7 @@ fi
    PF_GETSIGNATURE=$(jq -r .signature <<< "$PF_SIG")
    PF_PORT=$(jq -r .port <<< "$PF_PAYLOAD")

    PF_BIND="$(curl --interface "$PIA_INTERFACE" --CAcert "$PIA_CERT" --get --silent --show-error --retry 5 --retry-delay 5 --max-time 15 --data-urlencode "payload=$PF_PAYLOAD_RAW" --data-urlencode "signature=$PF_GETSIGNATURE" --resolve "$WG_DNS:19999:$SERVER_IP" "https://$WG_DNS:19999/bindPort")"
    PF_BIND="$(curl --interface "$PIA_INTERFACE" --CAcert "$PIA_CERT" --get --silent --show-error --retry 5 --retry-delay 5 --max-time 15 --data-urlencode "payload=$PF_PAYLOAD_RAW" --data-urlencode "signature=$PF_GETSIGNATURE" --resolve "$WG_CN:19999:$SERVER_IP" "https://$WG_CN:19999/bindPort")"

    PF_STATUS="$(jq -r .status <<< "$PF_BIND")"
    if [ "$PF_STATUS" != "OK" ]
    @@ -141,10 +141,10 @@ then
    exit 1
    fi

    ( echo -n "Bind: "; jq -r .message <<< "$PF_BIND"; ) > /dev/stderr
    ( echo -n "PIA Server->Bind: "; jq -r .message <<< "$PF_BIND"; ) > /dev/stderr

    echo > /dev/stderr
    echo "Bound port: " > /dev/stderr
    echo -n "Bound port: " > /dev/stderr
    echo "$PF_PORT"
    echo > /dev/stderr

  11. @triffid triffid revised this gist Sep 9, 2020. 1 changed file with 165 additions and 0 deletions.
    165 changes: 165 additions & 0 deletions pia-portforward.sh
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,165 @@
    #!/bin/bash

    if [ -z "$CONFIGDIR" ]
    then
    if [ $EUID -eq 0 ]
    then
    CONFIGDIR="/var/cache/pia-wg"
    else
    CONFIGDIR="$HOME/.config/pia-wg"
    fi
    mkdir -p "$CONFIGDIR"
    fi

    if [ -z "$CONFIG" ]
    then
    if [ $EUID -eq 0 ]
    then
    CONFIG="/etc/pia-wg/pia-wg.conf"
    else
    CONFIG="$CONFIGDIR/pia-wg.conf"
    fi
    fi

    if [ -r "$CONFIG" ]
    then
    source "$CONFIG"
    fi

    if [ -z "$DATAFILE_NEW" ]
    then
    DATAFILE_NEW="$CONFIGDIR/data_new.json"
    fi

    if [ -z "$REMOTEINFO" ]
    then
    REMOTEINFO="$CONFIGDIR/remote.info"
    fi

    if [ -z "$TOKENFILE" ]
    then
    TOKENFILE="$CONFIGDIR/token"
    fi

    if [ -z "$PIA_CERT" ]
    then
    PIA_CERT="$CONFIGDIR/rsa_4096.crt"
    fi

    if [ -z "$TOK" ] && [ -r "$TOKENFILE" ]
    then
    TOK="$(< "$TOKENFILE")"
    else
    echo "Can't find token $TOKENFILE"
    exit 1
    fi

    if [ -z "$PIA_INTERFACE" ]
    then
    PIA_INTERFACE="pia"
    fi

    if [ -z "$PF_SIGFILE" ]
    then
    PF_SIGFILE="$CONFIGDIR/pf-sig"
    fi

    if [ -z "$PF_BINDFILE" ]
    then
    PF_BINDFILE="$CONFIGDIR/pf-bind"
    fi

    WG_INFO="$(jq -r '.regions | .[] | select(.servers.wg[0].ip == "'"$(jq -r .server_ip "$REMOTEINFO")"'")' "$DATAFILE_NEW")"

    if [ "$(jq -r .port_forward <<< "$WG_INFO")" != true ]
    then
    echo "Current server doesn't support port forwarding:"
    jq . <<< "$WG_INFO"
    exit 1
    fi

    WG_NAME="$(jq -r .name <<< "$WG_INFO")"
    WG_DNS="$(jq -r .dns <<< "$WG_INFO")"

    WG_HOST="$(jq -r '.servers.wg[0].ip' <<< "$WG_INFO")"
    WG_CN="$(jq -r '.servers.wg[0].cn' <<< "$WG_INFO")"

    PEER_IP="$(jq -r .peer_ip "$REMOTEINFO")"
    SERVER_PUBLIC_KEY="$(jq -r .server_key "$REMOTEINFO")"
    SERVER_IP="$(jq -r .server_ip "$REMOTEINFO")"
    SERVER_PORT="$(jq -r .server_port "$REMOTEINFO")"
    SERVER_VIP="$(jq -r .server_vip "$REMOTEINFO")"

    # sections of the below adapted from Threarah's work at
    # https://github.com/thrnz/docker-wireguard-pia/blob/003f79f3b6ba24387e10d7de63ec62e98e6518a5/run#L233-L270 with permission
    # Also see https://www.reddit.com/r/PrivateInternetAccess/comments/h9y4da/is_there_any_way_to_generate_wireguard_config/fxhkpjt/

    if [ -r "$PF_SIGFILE" ]
    then
    PF_SIG="$(< "$PF_SIGFILE")"

    PF_PAYLOAD_RAW=$(jq -r .payload <<< "$PF_SIG")
    PF_PAYLOAD=$(base64 -d <<< "$PF_PAYLOAD_RAW")
    PF_TOKEN_EXPIRY_RAW=$(jq -r .expires_at <<< "$PF_PAYLOAD")
    PF_TOKEN_EXPIRY=$(date --date="$PF_TOKEN_EXPIRY_RAW" +%s)
    fi

    if [ $(( "$PF_TOKEN_EXPIRY" - $(date -u +%s) )) -le 900 ]
    then
    echo "Signature stale, refetching"
    exit 1

    # Very strange - must connect via 10.0/8 private VPN link to the server's public IP - why?
    # I tried SERVER_VIP (10.0/8 private IP) instead of SERVER_IP (public IP) but it won't connect
    # It also won't connect if you try to connect from the internet, hence needing --interface "$PIA_INTERFACE"
    PF_SIG="$(curl --interface "$PIA_INTERFACE" --CAcert "$PIA_CERT" --get --silent --show-error --retry 5 --retry-delay 5 --max-time 15 --data-urlencode "token=$TOK" --resolve "$WG_DNS:19999:$SERVER_IP" "https://$WG_DNS:19999/getSignature" | tee "$PF_SIGFILE")"

    PF_STATUS="$(jq -r .status <<< "$PF_SIG")"
    if [ "$PF_STATUS" != "OK" ]
    then
    echo "Signature retrieval failed: $PF_STATUS"
    jq . <<< "$PF_SIG"
    exit 1
    fi

    PF_PAYLOAD_RAW=$(jq -r .payload <<< "$PF_SIG")
    PF_PAYLOAD=$(base64 -d <<< "$PF_PAYLOAD_RAW")
    PF_TOKEN_EXPIRY_RAW=$(jq -r .expires_at <<< "$PF_PAYLOAD")
    PF_TOKEN_EXPIRY=$(date -D %Y-%m-%dT%H:%M:%S --date="$PF_TOKEN_EXPIRY_RAW" +%s)
    fi

    PF_GETSIGNATURE=$(jq -r .signature <<< "$PF_SIG")
    PF_PORT=$(jq -r .port <<< "$PF_PAYLOAD")

    PF_BIND="$(curl --interface "$PIA_INTERFACE" --CAcert "$PIA_CERT" --get --silent --show-error --retry 5 --retry-delay 5 --max-time 15 --data-urlencode "payload=$PF_PAYLOAD_RAW" --data-urlencode "signature=$PF_GETSIGNATURE" --resolve "$WG_DNS:19999:$SERVER_IP" "https://$WG_DNS:19999/bindPort")"

    PF_STATUS="$(jq -r .status <<< "$PF_BIND")"
    if [ "$PF_STATUS" != "OK" ]
    then
    echo "Bind failed: $PF_STATUS"
    jq . <<< "$PF_BIND"
    exit 1
    fi

    ( echo -n "Bind: "; jq -r .message <<< "$PF_BIND"; ) > /dev/stderr

    echo > /dev/stderr
    echo "Bound port: " > /dev/stderr
    echo "$PF_PORT"
    echo > /dev/stderr

    ###############################################################################
    # #
    # TODO: make this more flexible for others' systems #
    # #
    ###############################################################################

    transmission-remote -p "$PF_PORT" -pt

    ###############################################################################
    # #
    # #
    # #
    ###############################################################################

    exit 0
  12. @triffid triffid revised this gist Aug 25, 2020. 1 changed file with 39 additions and 0 deletions.
    39 changes: 39 additions & 0 deletions pia-currentserver.sh
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,39 @@
    #!/bin/bash

    if [ -z "$CONFIGDIR" ]
    then
    if [ $EUID -eq 0 ]
    then
    CONFIGDIR="/var/cache/pia-wg"
    else
    CONFIGDIR="$HOME/.config/pia-wg"
    fi
    mkdir -p "$CONFIGDIR"
    fi

    if [ -z "$CONFIG" ]
    then
    if [ $EUID -eq 0 ]
    then
    CONFIG="/etc/pia-wg/pia-wg.conf"
    else
    CONFIG="$CONFIGDIR/pia-wg.conf"
    fi
    fi

    if [ -z "$DATAFILE_NEW" ]
    then
    DATAFILE_NEW="$CONFIGDIR/data_new.json"
    fi

    if [ -z "$REMOTEINFO" ]
    then
    REMOTEINFO="$CONFIGDIR/remote.info"
    fi

    if [ -r "$CONFIG" ]
    then
    source "$CONFIG"
    fi

    jq '.regions | .[] | select(.servers.wg[0].ip == "'"$(jq -r .server_ip "$REMOTEINFO")"'")' "$DATAFILE_NEW"
  13. @triffid triffid revised this gist Aug 25, 2020. 1 changed file with 3 additions and 16 deletions.
    19 changes: 3 additions & 16 deletions pia-wg.sh
    Original file line number Diff line number Diff line change
    @@ -169,7 +169,7 @@ fi
    # fetch data-new.json if missing
    if ! [ -r "$DATAFILE_NEW" ]
    then
    echo "Fetching new generation wireguard server list from PIA"
    echo "Fetching new generation server list from PIA"
    # wget -O "$DATAFILE" 'https://raw.githubusercontent.com/pia-foss/desktop/master/tests/res/openssl/payload1/payload' || exit 1
    curl 'https://serverlist.piaservers.net/vpninfo/servers/new' > "$DATAFILE_NEW.temp" || exit 1
    if [ "$(jq '.regions | map_values(select(.servers.wg)) | keys' "$DATAFILE_NEW.temp" 2>/dev/null | wc -l)" -le 30 ]
    @@ -461,25 +461,12 @@ do
    done
    echo " OK"

    # if find "$DATAFILE" -mtime -3 -exec false {} +
    # then
    # echo
    # echo "PIA endpoint cache is stale, fetching new list.."
    # curl 'https://www.privateinternetaccess.com/vpninfo/servers?version=1001&client=x-alpha' > "$DATAFILE.temp" || exit 1
    # if [ "$(jq 'map_values(select(.wireguard)) | keys' "$DATAFILE.temp" 2>/dev/null | wc -l)" -le 50 ]
    # then
    # echo "Bad serverlist retrieved to $DATAFILE.temp, ignoring"
    # else
    # jq -cM 'map_values(select(.wireguard))' "$DATAFILE.temp" > "$DATAFILE" 2>/dev/null
    # echo "Success"
    # fi
    # fi

    if find "$DATAFILE_NEW" -mtime -3 -exec false {} +
    then
    echo "PIA endpoint list is stale, Fetching new generation wireguard server list"

    curl 'https://serverlist.piaservers.net/vpninfo/servers/new' > "$DATAFILE_NEW.temp" || exit 1
    # curl 'https://serverlist.piaservers.net/vpninfo/servers/new' > "$DATAFILE_NEW.temp" || exit 1
    curl --interface "$PIA_INTERFACE" --CAcert "$PIA_CERT" --resolve "$WG_CN:443:10.0.0.1" "https://$WG_CN:443/vpninfo/servers/v4" > "$DATAFILE_NEW.temp" || exit 1

    if [ "$(jq '.regions | map_values(select(.servers.wg)) | keys' "$DATAFILE_NEW.temp" 2>/dev/null | wc -l)" -le 30 ]
    then
  14. @triffid triffid revised this gist Aug 20, 2020. 1 changed file with 3 additions and 1 deletion.
    4 changes: 3 additions & 1 deletion openrc-init-pia
    Original file line number Diff line number Diff line change
    @@ -5,6 +5,8 @@ command="/root/bin/pia-wg.sh"
    CONFIGDIR="${CONFIGDIR:-/var/cache/pia-wg}"
    CONFIG="${CONFIG:-/etc/pia-wg/pia-wg.conf}"

    extra_started_commands="reload"

    depend() {
    need net sysfs
    after modules ip-rules
    @@ -29,7 +31,7 @@ start() {
    (
    export CONFIGDIR="$CONFIGDIR"
    export CONFIG="$CONFIG"
    while ! "$command"
    while "$command" 2>&1 | tee /var/log/pia-wg.log && [ ${PIPESTATUS[0]} -ne 0 ]
    do
    ewarn "Failed, retrying"
    sleep 1
  15. @triffid triffid revised this gist Aug 20, 2020. 1 changed file with 23 additions and 14 deletions.
    37 changes: 23 additions & 14 deletions pia-wg.sh
    Original file line number Diff line number Diff line change
    @@ -214,7 +214,8 @@ if [ "$(jq -r ".regions | .[] | select(.id == \"$LOC\")" "$DATAFILE_NEW")" == ""
    then
    echo "Location $LOC not found!"
    echo "Options are:"
    jq '.regions | .[] | .id' "$DATAFILE_NEW" | sort | sed -e 's/^/ * /'
    # jq '.regions | .[] | .id' "$DATAFILE_NEW" | sort | sed -e 's/^/ * /'
    ( echo $'\e[1mLocation\e[1m\tRegion\tPort Forward\tGeolocated'; echo $'\e[0m----------------\e[0m\t------------------\t------------\t----------'; jq -r '.regions | .[] | [.id, .name, .port_forward, .geo] | "'$'\e''[1m\(.[0])'$'\e''[0m\t\(.[1])\t\(.[2])\t\(.[3])"' "$DATAFILE_NEW"; ) | column -t -s $'\t'
    echo
    echo "Please edit $CONFIG and change your desired location, then try again"
    exit 1
    @@ -357,12 +358,13 @@ then

    # Note: unnecessary if Table != off above, but doesn't hurt.
    # ensure we don't get a packet storm loop
    ip rule add to "$SERVER_IP" lookup china pref 10
    # ip rule add to "$SERVER_IP" lookup china pref 10
    ip rule add fwmark 51820 lookup china pref 10

    if [ "$OLD_KEY" != "$SERVER_PUBLIC_KEY" ]
    then
    echo " [Change Peer from $OLD_KEY to $SERVER_PUBLIC_KEY]"
    wg set "$PIA_INTERFACE" private-key <(echo "$CLIENT_PRIVATE_KEY") peer "$SERVER_PUBLIC_KEY" endpoint "$SERVER_IP:$SERVER_PORT" allowed-ips "0.0.0.0/0,::/0" || exit 1
    wg set "$PIA_INTERFACE" fwmark 51820 private-key <(echo "$CLIENT_PRIVATE_KEY") peer "$SERVER_PUBLIC_KEY" endpoint "$SERVER_IP:$SERVER_PORT" allowed-ips "0.0.0.0/0,::/0" || exit 1
    # remove old key
    wg set "$PIA_INTERFACE" peer "$OLD_KEY" remove
    fi
    @@ -381,18 +383,19 @@ then
    echo "Bringing up interface '$PIA_INTERFACE'"

    # Note: unnecessary if Table != off above, but doesn't hurt.
    ip rule add to "$SERVER_IP" lookup china pref 10
    # ip rule add to "$SERVER_IP" lookup china pref 10
    ip rule add fwmark 51820 lookup china pref 10

    # bring up wireguard interface
    # wg-quick up "$WGCONF"
    ip link add "$PIA_INTERFACE" type wireguard || exit 1
    ip link set dev "$PIA_INTERFACE" up || exit 1
    wg set "$PIA_INTERFACE" private-key <(echo "$CLIENT_PRIVATE_KEY") peer "$SERVER_PUBLIC_KEY" endpoint "$SERVER_IP:$SERVER_PORT" allowed-ips "0.0.0.0/0,::/0" || exit 1
    wg set "$PIA_INTERFACE" fwmark 51820 private-key <(echo "$CLIENT_PRIVATE_KEY") peer "$SERVER_PUBLIC_KEY" endpoint "$SERVER_IP:$SERVER_PORT" allowed-ips "0.0.0.0/0,::/0" || exit 1
    ip addr replace "$PEER_IP" dev "$PIA_INTERFACE" || exit 1

    # Note: unnecessary if Table != off above, but doesn't hurt.
    # doubled because this listing appears to disappear sometimes
    ip rule add to "$SERVER_IP" lookup china pref 10
    # ip rule add to "$SERVER_IP" lookup china pref 10

    # Note: only if Table = off in wireguard config file above
    ip route add default dev "$PIA_INTERFACE"
    @@ -402,21 +405,24 @@ then

    # Note: unnecessary if Table != off above, but doesn't hurt.
    # tripled because this listing appears to disappear sometimes
    ip rule add to "$SERVER_IP" lookup china pref 10
    # ip rule add to "$SERVER_IP" lookup china pref 10

    fi
    else
    echo ip rule add to "$SERVER_IP" lookup china pref 10
    sudo ip rule add to "$SERVER_IP" lookup china pref 10
    # echo ip rule add to "$SERVER_IP" lookup china pref 10
    # sudo ip rule add to "$SERVER_IP" lookup china pref 10

    echo ip rule add fwmark 51820 lookup china pref 10
    sudo ip rule add fwmark 51820 lookup china pref 10

    if ! ip link list "$PIA_INTERFACE" > /dev/null
    then
    echo ip link add "$PIA_INTERFACE" type wireguard
    sudo ip link add "$PIA_INTERFACE" type wireguard
    fi

    echo wg set "$PIA_INTERFACE" private-key "$CLIENT_PRIVATE_KEY" peer "$SERVER_PUBLIC_KEY" endpoint "$SERVER_IP:$SERVER_PORT" allowed-ips "0.0.0.0/0,::/0"
    sudo wg set "$PIA_INTERFACE" private-key <(echo "$CLIENT_PRIVATE_KEY") peer "$SERVER_PUBLIC_KEY" endpoint "$SERVER_IP:$SERVER_PORT" allowed-ips "0.0.0.0/0,::/0"
    echo wg set "$PIA_INTERFACE" fwmark 51820 private-key "$CLIENT_PRIVATE_KEY" peer "$SERVER_PUBLIC_KEY" endpoint "$SERVER_IP:$SERVER_PORT" allowed-ips "0.0.0.0/0,::/0"
    sudo wg set "$PIA_INTERFACE" fwmark 51820 private-key <(echo "$CLIENT_PRIVATE_KEY") peer "$SERVER_PUBLIC_KEY" endpoint "$SERVER_IP:$SERVER_PORT" allowed-ips "0.0.0.0/0,::/0"

    echo ip addr replace "$PEER_IP" dev "$PIA_INTERFACE"
    sudo ip addr replace "$PEER_IP" dev "$PIA_INTERFACE"
    @@ -430,16 +436,19 @@ else
    echo wg set "$PIA_INTERFACE" peer "$OLD_KEY" remove
    sudo wg set "$PIA_INTERFACE" peer "$OLD_KEY" remove

    echo ip rule del to "$OLD_PEER_IP" lookup china
    sudo ip rule del to "$OLD_PEER_IP" lookup china
    # echo ip rule del to "$OLD_PEER_IP" lookup china
    # sudo ip rule del to "$OLD_PEER_IP" lookup china
    fi

    echo ip route add default dev "$PIA_INTERFACE"
    sudo ip route add default dev "$PIA_INTERFACE"
    fi

    echo "PIA Wireguard '$PIA_INTERFACE' configured successfully"

    TRIES=0
    echo -n "Waiting for connection to stabilise..."
    while ! ping -n -c1 -w 5 -I "$PIA_INTERFACE" "$SERVER_VIP" &>/dev/null
    while ! ping -n -c1 -w 5 -s 1280 -I "$PIA_INTERFACE" "$SERVER_VIP" &>/dev/null
    do
    echo -n "."
    TRIES=$(( $TRIES + 1 ))
  16. @triffid triffid revised this gist Jul 21, 2020. 2 changed files with 13 additions and 13 deletions.
    8 changes: 4 additions & 4 deletions openrc-init-pia
    Original file line number Diff line number Diff line change
    @@ -2,12 +2,12 @@

    command="/root/bin/pia-wg.sh"

    CONFIGDIR="${CONFIGDIR:-/etc/pia-wg}"
    CONFIG="${CONFIG:-$CONFIGDIR/pia-wg.conf}"
    CONFIGDIR="${CONFIGDIR:-/var/cache/pia-wg}"
    CONFIG="${CONFIG:-/etc/pia-wg/pia-wg.conf}"

    depend() {
    need net sysfs
    after modules
    after modules ip-rules
    use logger
    }

    @@ -50,5 +50,5 @@ restart() {

    stop() {
    source "$CONFIG"
    wg-quick down "$PIA_INTERFACE"
    ip link del "$PIA_INTERFACE"
    }
    18 changes: 9 additions & 9 deletions pia-wg.sh
    Original file line number Diff line number Diff line change
    @@ -182,9 +182,15 @@ then
    fi
    fi

    if ! [ -r "$PIA_CERT" ]
    then
    echo "Fetching PIA self-signed cert from github"
    curl 'https://raw.githubusercontent.com/pia-foss/desktop/master/daemon/res/ca/rsa_4096.crt' > "$PIA_CERT" || exit 1
    fi

    if [ "$(jq -r ".regions | .[] | select(.id == \"$LOC\")" "$DATAFILE_NEW")" == "" ]
    then
    LOC=$(jq -r '.regions | .[] | select(.id | test("^us")) | .id' "$DATAFILE_NEW" | shuf -n 1)
    LOC=$(jq -r '.regions | .[] | select(.id | test("^'"$LOC"'")) | .id' "$DATAFILE_NEW" | shuf -n 1)
    fi

    # if [ "$(jq -r ".$LOC.wireguard" "$DATAFILE")" == "null" ]
    @@ -194,12 +200,6 @@ fi
    # LOC=$(jq 'with_entries(if (.key|test("^'"$LOC"'")) then ( {key: .key, value: .value } ) else empty end ) | keys' "$DATAFILE" | grep ^\ | cut -d\" -f2 | shuf -n 1)
    # fi

    if ! [ -r "$PIA_CERT" ]
    then
    echo "Fetching PIA self-signed cert from github"
    curl 'https://raw.githubusercontent.com/pia-foss/desktop/master/daemon/res/ca/rsa_4096.crt' > "$PIA_CERT" || exit 1
    fi

    # if [ "$(jq -r ".$LOC.wireguard" "$DATAFILE")" == "null" ]
    # then
    # echo "Location $LOC not found!"
    @@ -214,7 +214,7 @@ if [ "$(jq -r ".regions | .[] | select(.id == \"$LOC\")" "$DATAFILE_NEW")" == ""
    then
    echo "Location $LOC not found!"
    echo "Options are:"
    jq '.[] | .id' "$DATAFILE_NEW" | sort
    jq '.regions | .[] | .id' "$DATAFILE_NEW" | sort | sed -e 's/^/ * /'
    echo
    echo "Please edit $CONFIG and change your desired location, then try again"
    exit 1
    @@ -478,7 +478,7 @@ then
    echo "You can try again if there was a transient error"
    exit 1
    else
    jq -cM '.regions | map_values(select(.servers.wg))' "$DATAFILE_NEW.temp" > "$DATAFILE_NEW" 2>/dev/null
    jq -cM '.' "$DATAFILE_NEW.temp" > "$DATAFILE_NEW" 2>/dev/null
    fi
    fi

  17. @triffid triffid revised this gist Jul 20, 2020. 1 changed file with 13 additions and 3 deletions.
    16 changes: 13 additions & 3 deletions pia-wg.sh
    Original file line number Diff line number Diff line change
    @@ -34,13 +34,23 @@ fi

    if [ -z "$CONFIGDIR" ]
    then
    CONFIGDIR="$HOME/.config/pia-wg"
    if [ $EUID -eq 0 ]
    then
    CONFIGDIR="/var/cache/pia-wg"
    else
    CONFIGDIR="$HOME/.config/pia-wg"
    fi
    mkdir -p "$CONFIGDIR"
    fi

    if [ -z "$CONFIG" ]
    then
    CONFIG="$CONFIGDIR/pia-wg.conf"
    if [ $EUID -eq 0 ]
    then
    CONFIG="/etc/pia-wg/pia-wg.conf"
    else
    CONFIG="$CONFIGDIR/pia-wg.conf"
    fi
    fi

    if [ -r "$CONFIG" ]
    @@ -84,7 +94,7 @@ fi

    if [ -z "$TOKENFILE" ]
    then
    TOKENFILE="$CONFIGDIR/.token"
    TOKENFILE="$CONFIGDIR/token"
    fi

    if [ -z "$DATAFILE" ]
  18. @triffid triffid revised this gist Jul 18, 2020. 1 changed file with 32 additions and 19 deletions.
    51 changes: 32 additions & 19 deletions pia-wg.sh
    Original file line number Diff line number Diff line change
    @@ -168,13 +168,13 @@ then
    echo "You can try again if there was a transient error"
    exit 1
    else
    jq -cM '.regions | map_values(select(.servers.wg))' "$DATAFILE_NEW.temp" > "$DATAFILE_NEW" 2>/dev/null
    jq -cM '.' "$DATAFILE_NEW.temp" > "$DATAFILE_NEW" 2>/dev/null
    fi
    fi

    if [ "$(jq -r ".[] | select(.id == \"$LOC\")" "$DATAFILE_NEW")" == "" ]
    if [ "$(jq -r ".regions | .[] | select(.id == \"$LOC\")" "$DATAFILE_NEW")" == "" ]
    then
    LOC=$(jq -r '.[] | select(.id | test("^us")) | .id' "$DATAFILE_NEW" | shuf -n 1)
    LOC=$(jq -r '.regions | .[] | select(.id | test("^us")) | .id' "$DATAFILE_NEW" | shuf -n 1)
    fi

    # if [ "$(jq -r ".$LOC.wireguard" "$DATAFILE")" == "null" ]
    @@ -200,7 +200,7 @@ fi
    # exit 1
    # fi

    if [ "$(jq -r ".[] | select(.id == \"$LOC\")" "$DATAFILE_NEW")" == "" ]
    if [ "$(jq -r ".regions | .[] | select(.id == \"$LOC\")" "$DATAFILE_NEW")" == "" ]
    then
    echo "Location $LOC not found!"
    echo "Options are:"
    @@ -239,15 +239,15 @@ fi
    # WG_NAME="$(jq -r ".$LOC.name" "$DATAFILE")"
    # WG_DNS="$(jq -r ".$LOC.dns" "$DATAFILE")"
    # WG_URL="$(jq -r ".$LOC.wireguard.host" "$DATAFILE")"
    # WG_SERIAL="$(jq -r ".$LOC.wireguard.serial" "$DATAFILE")"

    WG_NAME="$(jq -r ".[] | select(.id == \"$LOC\") | .name" "$DATAFILE_NEW")"
    WG_DNS="$(jq -r ".[] | select(.id == \"$LOC\") | .dns" "$DATAFILE_NEW")"
    # WG_CN="$(jq -r ".$LOC.wireguard.serial" "$DATAFILE")"

    WG_HOST="$(jq -r ".[] | select(.id == \"$LOC\") | .servers.wg[0].ip" "$DATAFILE_NEW")"
    WG_PORT=1337
    WG_NAME="$(jq -r ".regions | .[] | select(.id == \"$LOC\") | .name" "$DATAFILE_NEW")"
    WG_DNS="$(jq -r ".regions | .[] | select(.id == \"$LOC\") | .dns" "$DATAFILE_NEW")"

    WG_SERIAL="$WG_DNS"
    WG_HOST="$(jq -r ".regions | .[] | select(.id == \"$LOC\") | .servers.wg[0].ip" "$DATAFILE_NEW")"
    WG_CN="$(jq -r ".regions | .[] | select(.id == \"$LOC\") | .servers.wg[0].cn" "$DATAFILE_NEW")"
    # WG_PORT=1337
    WG_PORT="$(jq -r '.groups.wg[0].ports[]' "$DATAFILE_NEW" | sort -r | head -n1)"

    WG_SN="$(cut -d. -f1 <<< "$WG_DNS")"
    # WG_HOST="$(cut -d: -f1 <<< "$WG_URL")"
    @@ -267,16 +267,29 @@ if ! curl -GsS \
    --data-urlencode "pubkey=$CLIENT_PUBLIC_KEY" \
    --data-urlencode "pt=$TOK" \
    --cacert "$PIA_CERT" \
    --resolve "$WG_SERIAL:$WG_PORT:$WG_HOST" \
    "https://$WG_SERIAL:$WG_PORT/addKey" > "$REMOTEINFO.temp"
    --resolve "$WG_DNS:$WG_PORT:$WG_HOST" \
    "https://$WG_DNS:$WG_PORT/addKey" > "$REMOTEINFO.temp"
    then
    echo "Failed to register key with $WG_SN ($WG_HOST)"
    if ! [ -e "/sys/class/net/$PIA_INTERFACE" ]
    echo "Registering with $WG_DNS failed, trying $WG_CN"
    # fall back to trying 'cn' certificate if DNS fails
    # /u/dean_oz reported that this works better for them at https://www.reddit.com/r/PrivateInternetAccess/comments/h9y4da/is_there_any_way_to_generate_wireguard_config/fyfqjf7/
    # however in testing I find that the 'cn' certificate has no trust anchor, and curl won't accept it
    if ! curl -GsS \
    --max-time 5 \
    --data-urlencode "pubkey=$CLIENT_PUBLIC_KEY" \
    --data-urlencode "pt=$TOK" \
    --cacert "$PIA_CERT" \
    --resolve "$WG_CN:$WG_PORT:$WG_HOST" \
    "https://$WG_CN:$WG_PORT/addKey" > "$REMOTEINFO.temp"
    then
    echo "If you're trying to change hosts because your link has stopped working,"
    echo " you may need to "$'\x1b[1m'"ip link del dev $PIA_INTERFACE"$'\x1b[0m'" and try this script again"
    echo "Failed to register key with $WG_SN ($WG_HOST)"
    if ! [ -e "/sys/class/net/$PIA_INTERFACE" ]
    then
    echo "If you're trying to change hosts because your link has stopped working,"
    echo " you may need to "$'\x1b[1m'"ip link del dev $PIA_INTERFACE"$'\x1b[0m'" and try this script again"
    fi
    exit 1
    fi
    exit 1
    fi

    if [ "$(jq -r .status "$REMOTEINFO.temp")" != "OK" ]
    @@ -459,4 +472,4 @@ then
    fi
    fi

    exit 0
    exit 0
  19. @triffid triffid revised this gist Jul 16, 2020. 1 changed file with 3 additions and 1 deletion.
    4 changes: 3 additions & 1 deletion pia-wg.sh
    Original file line number Diff line number Diff line change
    @@ -443,7 +443,7 @@ echo " OK"
    # fi
    # fi

    if find "$DATAFILE_NEW" -mtime 3 -exec false {} +
    if find "$DATAFILE_NEW" -mtime -3 -exec false {} +
    then
    echo "PIA endpoint list is stale, Fetching new generation wireguard server list"

    @@ -458,3 +458,5 @@ then
    jq -cM '.regions | map_values(select(.servers.wg))' "$DATAFILE_NEW.temp" > "$DATAFILE_NEW" 2>/dev/null
    fi
    fi

    exit 0
  20. @triffid triffid revised this gist Jul 15, 2020. 1 changed file with 90 additions and 27 deletions.
    117 changes: 90 additions & 27 deletions pia-wg.sh
    Original file line number Diff line number Diff line change
    @@ -92,6 +92,11 @@ then
    DATAFILE="$CONFIGDIR/data.json"
    fi

    if [ -z "$DATAFILE_NEW" ]
    then
    DATAFILE_NEW="$CONFIGDIR/data_new.json"
    fi

    if [ -z "$REMOTEINFO" ]
    then
    REMOTEINFO="$CONFIGDIR/remote.info"
    @@ -136,39 +141,70 @@ ENDCONFIG
    fi

    # fetch data.json if missing
    if ! [ -r "$DATAFILE" ]
    # if ! [ -r "$DATAFILE" ]
    # then
    # echo "Fetching wireguard server list from PIA"
    # # wget -O "$DATAFILE" 'https://raw.githubusercontent.com/pia-foss/desktop/master/tests/res/openssl/payload1/payload' || exit 1
    # curl 'https://www.privateinternetaccess.com/vpninfo/servers?version=1001&client=x-alpha' > "$DATAFILE.temp" || exit 1
    # if [ "$(jq 'map_values(select(.wireguard)) | keys' "$DATAFILE.temp" 2>/dev/null | wc -l)" -le 50 ]
    # then
    # echo "Bad serverlist retrieved to $DATAFILE.temp, exiting"
    # echo "You can try again if there was a transient error"
    # exit 1
    # else
    # jq -cM 'map_values(select(.wireguard))' "$DATAFILE.temp" > "$DATAFILE" 2>/dev/null
    # fi
    # fi

    # fetch data-new.json if missing
    if ! [ -r "$DATAFILE_NEW" ]
    then
    echo "Fetching wireguard server list from PIA"
    echo "Fetching new generation wireguard server list from PIA"
    # wget -O "$DATAFILE" 'https://raw.githubusercontent.com/pia-foss/desktop/master/tests/res/openssl/payload1/payload' || exit 1
    curl 'https://www.privateinternetaccess.com/vpninfo/servers?version=1001&client=x-alpha' > "$DATAFILE.temp" || exit 1
    if [ "$(jq 'map_values(select(.wireguard)) | keys' "$DATAFILE.temp" 2>/dev/null | wc -l)" -le 50 ]
    curl 'https://serverlist.piaservers.net/vpninfo/servers/new' > "$DATAFILE_NEW.temp" || exit 1
    if [ "$(jq '.regions | map_values(select(.servers.wg)) | keys' "$DATAFILE_NEW.temp" 2>/dev/null | wc -l)" -le 30 ]
    then
    echo "Bad serverlist retrieved to $DATAFILE.temp, exiting"
    echo "Bad serverlist retrieved to $DATAFILE_NEW.temp, exiting"
    echo "You can try again if there was a transient error"
    exit 1
    else
    jq -cM 'map_values(select(.wireguard))' "$DATAFILE.temp" > "$DATAFILE" 2>/dev/null
    jq -cM '.regions | map_values(select(.servers.wg))' "$DATAFILE_NEW.temp" > "$DATAFILE_NEW" 2>/dev/null
    fi
    fi

    if [ "$(jq -r ".$LOC.wireguard" "$DATAFILE")" == "null" ]
    if [ "$(jq -r ".[] | select(.id == \"$LOC\")" "$DATAFILE_NEW")" == "" ]
    then
    # echo "No exact match for location \"$LOC\" trying pattern"
    # from https://unix.stackexchange.com/questions/443884/match-keys-with-regex-in-jq/443927#443927
    LOC=$(jq 'with_entries(if (.key|test("^'"$LOC"'")) then ( {key: .key, value: .value } ) else empty end ) | keys' "$DATAFILE" | grep ^\ | cut -d\" -f2 | shuf -n 1)
    LOC=$(jq -r '.[] | select(.id | test("^us")) | .id' "$DATAFILE_NEW" | shuf -n 1)
    fi

    # if [ "$(jq -r ".$LOC.wireguard" "$DATAFILE")" == "null" ]
    # then
    # # echo "No exact match for location \"$LOC\" trying pattern"
    # # from https://unix.stackexchange.com/questions/443884/match-keys-with-regex-in-jq/443927#443927
    # LOC=$(jq 'with_entries(if (.key|test("^'"$LOC"'")) then ( {key: .key, value: .value } ) else empty end ) | keys' "$DATAFILE" | grep ^\ | cut -d\" -f2 | shuf -n 1)
    # fi

    if ! [ -r "$PIA_CERT" ]
    then
    echo "Fetching PIA self-signed cert from github"
    curl 'https://raw.githubusercontent.com/pia-foss/desktop/master/daemon/res/ca/rsa_4096.crt' > "$PIA_CERT" || exit 1
    fi

    if [ "$(jq -r ".$LOC.wireguard" "$DATAFILE")" == "null" ]
    # if [ "$(jq -r ".$LOC.wireguard" "$DATAFILE")" == "null" ]
    # then
    # echo "Location $LOC not found!"
    # echo "Options are:"
    # jq 'map_values(select(.wireguard)) | keys' "$DATAFILE"
    # echo
    # echo "Please edit $CONFIG and change your desired location, then try again"
    # exit 1
    # fi

    if [ "$(jq -r ".[] | select(.id == \"$LOC\")" "$DATAFILE_NEW")" == "" ]
    then
    echo "Location $LOC not found!"
    echo "Options are:"
    jq 'map_values(select(.wireguard)) | keys' "$DATAFILE"
    jq '.[] | .id' "$DATAFILE_NEW" | sort
    echo
    echo "Please edit $CONFIG and change your desired location, then try again"
    exit 1
    @@ -200,20 +236,31 @@ then
    echo "$TOK" > "$TOKENFILE"
    fi

    WG_NAME="$(jq -r ".$LOC.name" "$DATAFILE")"
    WG_DNS="$(jq -r ".$LOC.dns" "$DATAFILE")"
    WG_URL="$(jq -r ".$LOC.wireguard.host" "$DATAFILE")"
    WG_SERIAL="$(jq -r ".$LOC.wireguard.serial" "$DATAFILE")"
    # WG_NAME="$(jq -r ".$LOC.name" "$DATAFILE")"
    # WG_DNS="$(jq -r ".$LOC.dns" "$DATAFILE")"
    # WG_URL="$(jq -r ".$LOC.wireguard.host" "$DATAFILE")"
    # WG_SERIAL="$(jq -r ".$LOC.wireguard.serial" "$DATAFILE")"

    WG_NAME="$(jq -r ".[] | select(.id == \"$LOC\") | .name" "$DATAFILE_NEW")"
    WG_DNS="$(jq -r ".[] | select(.id == \"$LOC\") | .dns" "$DATAFILE_NEW")"

    WG_HOST="$(jq -r ".[] | select(.id == \"$LOC\") | .servers.wg[0].ip" "$DATAFILE_NEW")"
    WG_PORT=1337

    WG_SERIAL="$WG_DNS"

    WG_SN="$(cut -d. -f1 <<< "$WG_DNS")"
    WG_HOST="$(cut -d: -f1 <<< "$WG_URL")"
    WG_PORT="$(cut -d: -f2 <<< "$WG_URL")"
    # WG_HOST="$(cut -d: -f1 <<< "$WG_URL")"
    # WG_PORT="$(cut -d: -f2 <<< "$WG_URL")"


    if [ -z "$WG_URL" ]; then
    if [ -z "$WG_HOST$WG_PORT" ]; then
    echo "no wg region, exiting"
    exit 1
    fi

    echo "Registering public key with $WG_NAME ($WG_HOST)"
    ip rule add to "$WG_HOST" lookup china pref 10

    if ! curl -GsS \
    --max-time 5 \
    @@ -382,16 +429,32 @@ do
    done
    echo " OK"

    if find "$DATAFILE" -mtime -3 -exec false {} +
    # if find "$DATAFILE" -mtime -3 -exec false {} +
    # then
    # echo
    # echo "PIA endpoint cache is stale, fetching new list.."
    # curl 'https://www.privateinternetaccess.com/vpninfo/servers?version=1001&client=x-alpha' > "$DATAFILE.temp" || exit 1
    # if [ "$(jq 'map_values(select(.wireguard)) | keys' "$DATAFILE.temp" 2>/dev/null | wc -l)" -le 50 ]
    # then
    # echo "Bad serverlist retrieved to $DATAFILE.temp, ignoring"
    # else
    # jq -cM 'map_values(select(.wireguard))' "$DATAFILE.temp" > "$DATAFILE" 2>/dev/null
    # echo "Success"
    # fi
    # fi

    if find "$DATAFILE_NEW" -mtime 3 -exec false {} +
    then
    echo
    echo "PIA endpoint cache is stale, fetching new list.."
    curl 'https://www.privateinternetaccess.com/vpninfo/servers?version=1001&client=x-alpha' > "$DATAFILE.temp" || exit 1
    if [ "$(jq 'map_values(select(.wireguard)) | keys' "$DATAFILE.temp" 2>/dev/null | wc -l)" -le 50 ]
    echo "PIA endpoint list is stale, Fetching new generation wireguard server list"

    curl 'https://serverlist.piaservers.net/vpninfo/servers/new' > "$DATAFILE_NEW.temp" || exit 1

    if [ "$(jq '.regions | map_values(select(.servers.wg)) | keys' "$DATAFILE_NEW.temp" 2>/dev/null | wc -l)" -le 30 ]
    then
    echo "Bad serverlist retrieved to $DATAFILE.temp, ignoring"
    echo "Bad serverlist retrieved to $DATAFILE_NEW.temp, exiting"
    echo "You can try again if there was a transient error"
    exit 1
    else
    jq -cM 'map_values(select(.wireguard))' "$DATAFILE.temp" > "$DATAFILE" 2>/dev/null
    echo "Success"
    jq -cM '.regions | map_values(select(.servers.wg))' "$DATAFILE_NEW.temp" > "$DATAFILE_NEW" 2>/dev/null
    fi
    fi
  21. @triffid triffid revised this gist Jul 15, 2020. 1 changed file with 13 additions and 1 deletion.
    14 changes: 13 additions & 1 deletion pia-wg.sh
    Original file line number Diff line number Diff line change
    @@ -329,6 +329,11 @@ then

    # Specific to my setup
    ip route add default table vpnonly dev "$PIA_INTERFACE"

    # Note: unnecessary if Table != off above, but doesn't hurt.
    # tripled because this listing appears to disappear sometimes
    ip rule add to "$SERVER_IP" lookup china pref 10

    fi
    else
    echo ip rule add to "$SERVER_IP" lookup china pref 10
    @@ -362,11 +367,18 @@ fi

    echo "PIA Wireguard '$PIA_INTERFACE' configured successfully"

    TRIES=0
    echo -n "Waiting for connection to stabilise..."
    while ! ping -n -c1 -w 5 -I "$PIA_INTERFACE" "$SERVER_VIP" &>/dev/null
    do
    echo -n "."
    sleep 0.1 # so we can catch ctrl+c
    TRIES=$(( $TRIES + 1 ))
    if [[ $TRIES -ge 20 ]]
    then
    echo "Connection failed to stabilise, try again"
    exit 1
    fi
    sleep 0.5 # so we can catch ctrl+c
    done
    echo " OK"

  22. @triffid triffid revised this gist Jun 30, 2020. 1 changed file with 54 additions and 0 deletions.
    54 changes: 54 additions & 0 deletions openrc-init-pia
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,54 @@
    #!/sbin/openrc-run

    command="/root/bin/pia-wg.sh"

    CONFIGDIR="${CONFIGDIR:-/etc/pia-wg}"
    CONFIG="${CONFIG:-$CONFIGDIR/pia-wg.conf}"

    depend() {
    need net sysfs
    after modules
    use logger
    }

    start_pre() {
    if ! [ -e "$CONFIG" ]
    then
    echo "Please generate a config with pia-wg.sh and copy it to $CONFIG"
    return 1
    fi
    if ! [ -w "$CONFIGDIR" ] || ! [ -d "$CONFIGDIR" ]
    then
    echo "$CONFIGDIR is not a writable directory"
    return 1
    fi
    return 0
    }

    start() {
    (
    export CONFIGDIR="$CONFIGDIR"
    export CONFIG="$CONFIG"
    while ! "$command"
    do
    ewarn "Failed, retrying"
    sleep 1
    done
    einfo "OK"
    );
    return 0
    }

    reload() {
    start
    }

    restart() {
    stop
    start
    }

    stop() {
    source "$CONFIG"
    wg-quick down "$PIA_INTERFACE"
    }
  23. @triffid triffid revised this gist Jun 30, 2020. 1 changed file with 5 additions and 1 deletion.
    6 changes: 5 additions & 1 deletion pia-wg.sh
    Original file line number Diff line number Diff line change
    @@ -224,7 +224,7 @@ if ! curl -GsS \
    "https://$WG_SERIAL:$WG_PORT/addKey" > "$REMOTEINFO.temp"
    then
    echo "Failed to register key with $WG_SN ($WG_HOST)"
    if ip link list "$PIA_INTERFACE" > /dev/null
    if ! [ -e "/sys/class/net/$PIA_INTERFACE" ]
    then
    echo "If you're trying to change hosts because your link has stopped working,"
    echo " you may need to "$'\x1b[1m'"ip link del dev $PIA_INTERFACE"$'\x1b[0m'" and try this script again"
    @@ -320,6 +320,10 @@ then
    wg set "$PIA_INTERFACE" private-key <(echo "$CLIENT_PRIVATE_KEY") peer "$SERVER_PUBLIC_KEY" endpoint "$SERVER_IP:$SERVER_PORT" allowed-ips "0.0.0.0/0,::/0" || exit 1
    ip addr replace "$PEER_IP" dev "$PIA_INTERFACE" || exit 1

    # Note: unnecessary if Table != off above, but doesn't hurt.
    # doubled because this listing appears to disappear sometimes
    ip rule add to "$SERVER_IP" lookup china pref 10

    # Note: only if Table = off in wireguard config file above
    ip route add default dev "$PIA_INTERFACE"

  24. @triffid triffid revised this gist Jun 25, 2020. 1 changed file with 15 additions and 13 deletions.
    28 changes: 15 additions & 13 deletions pia-wg.sh
    Original file line number Diff line number Diff line change
    @@ -187,17 +187,18 @@ then
    -d "{\"username\":\"$USER\",\"password\":\"$PASS\"}" \
    "https://www.privateinternetaccess.com/api/client/v2/token" | jq -r '.token')

    echo "got token: $TOK"
    fi
    # echo "got token: $TOK"

    if [ -z "$TOK" ]; then
    echo "Failed to authenticate with privateinternetaccess"
    exit 1
    fi
    if [ -z "$TOK" ]; then
    echo "Failed to authenticate with privateinternetaccess"
    echo "Check your user/pass and try again"
    exit 1
    fi

    touch "$TOKENFILE"
    chmod 600 "$TOKENFILE"
    echo "$TOK" > "$TOKENFILE"
    touch "$TOKENFILE"
    chmod 600 "$TOKENFILE"
    echo "$TOK" > "$TOKENFILE"
    fi

    WG_NAME="$(jq -r ".$LOC.name" "$DATAFILE")"
    WG_DNS="$(jq -r ".$LOC.dns" "$DATAFILE")"
    @@ -214,22 +215,22 @@ fi

    echo "Registering public key with $WG_NAME ($WG_HOST)"

    curl -GsS \
    if ! curl -GsS \
    --max-time 5 \
    --data-urlencode "pubkey=$CLIENT_PUBLIC_KEY" \
    --data-urlencode "pt=$TOK" \
    --cacert "$PIA_CERT" \
    --resolve "$WG_SERIAL:$WG_PORT:$WG_HOST" \
    "https://$WG_SERIAL:$WG_PORT/addKey" > "$REMOTEINFO.temp" \
    || (
    "https://$WG_SERIAL:$WG_PORT/addKey" > "$REMOTEINFO.temp"
    then
    echo "Failed to register key with $WG_SN ($WG_HOST)"
    if ip link list "$PIA_INTERFACE" > /dev/null
    then
    echo "If you're trying to change hosts because your link has stopped working,"
    echo " you may need to "$'\x1b[1m'"ip link del dev $PIA_INTERFACE"$'\x1b[0m'" and try this script again"
    fi
    exit 1
    )
    fi

    if [ "$(jq -r .status "$REMOTEINFO.temp")" != "OK" ]
    then
    @@ -361,6 +362,7 @@ echo -n "Waiting for connection to stabilise..."
    while ! ping -n -c1 -w 5 -I "$PIA_INTERFACE" "$SERVER_VIP" &>/dev/null
    do
    echo -n "."
    sleep 0.1 # so we can catch ctrl+c
    done
    echo " OK"

  25. @triffid triffid revised this gist Jun 25, 2020. 1 changed file with 4 additions and 2 deletions.
    6 changes: 4 additions & 2 deletions pia-wg.sh
    Original file line number Diff line number Diff line change
    @@ -215,6 +215,7 @@ fi
    echo "Registering public key with $WG_NAME ($WG_HOST)"

    curl -GsS \
    --max-time 5 \
    --data-urlencode "pubkey=$CLIENT_PUBLIC_KEY" \
    --data-urlencode "pt=$TOK" \
    --cacert "$PIA_CERT" \
    @@ -283,6 +284,7 @@ then
    OLD_KEY="$(echo $(wg showconf "$PIA_INTERFACE" | grep ^PublicKey | cut -d= -f2-))"
    OLD_ENDPOINT="$(wg show "$PIA_INTERFACE" endpoints | grep "$OLD_KEY" | cut -d$'\t' -f2 | cut -d: -f1)"

    # Note: unnecessary if Table != off above, but doesn't hurt.
    # ensure we don't get a packet storm loop
    ip rule add to "$SERVER_IP" lookup china pref 10

    @@ -308,7 +310,7 @@ then
    echo "Bringing up interface '$PIA_INTERFACE'"

    # Note: unnecessary if Table != off above, but doesn't hurt.
    ip rule add to "$SERVER_IP" lookup china
    ip rule add to "$SERVER_IP" lookup china pref 10

    # bring up wireguard interface
    # wg-quick up "$WGCONF"
    @@ -356,7 +358,7 @@ fi
    echo "PIA Wireguard '$PIA_INTERFACE' configured successfully"

    echo -n "Waiting for connection to stabilise..."
    while ! ping -n -c1 -w 5 "$SERVER_VIP" &>/dev/null
    while ! ping -n -c1 -w 5 -I "$PIA_INTERFACE" "$SERVER_VIP" &>/dev/null
    do
    echo -n "."
    done
  26. @triffid triffid revised this gist Jun 17, 2020. 1 changed file with 19 additions and 5 deletions.
    24 changes: 19 additions & 5 deletions pia-wg.sh
    Original file line number Diff line number Diff line change
    @@ -77,6 +77,11 @@ then
    PIA_INTERFACE="pia"
    fi

    if [ -z "$PIA_CERT" ]
    then
    PIA_CERT="$CONFIGDIR/rsa_4096.crt"
    fi

    if [ -z "$TOKENFILE" ]
    then
    TOKENFILE="$CONFIGDIR/.token"
    @@ -153,6 +158,12 @@ then
    LOC=$(jq 'with_entries(if (.key|test("^'"$LOC"'")) then ( {key: .key, value: .value } ) else empty end ) | keys' "$DATAFILE" | grep ^\ | cut -d\" -f2 | shuf -n 1)
    fi

    if ! [ -r "$PIA_CERT" ]
    then
    echo "Fetching PIA self-signed cert from github"
    curl 'https://raw.githubusercontent.com/pia-foss/desktop/master/daemon/res/ca/rsa_4096.crt' > "$PIA_CERT" || exit 1
    fi

    if [ "$(jq -r ".$LOC.wireguard" "$DATAFILE")" == "null" ]
    then
    echo "Location $LOC not found!"
    @@ -191,7 +202,7 @@ echo "$TOK" > "$TOKENFILE"
    WG_NAME="$(jq -r ".$LOC.name" "$DATAFILE")"
    WG_DNS="$(jq -r ".$LOC.dns" "$DATAFILE")"
    WG_URL="$(jq -r ".$LOC.wireguard.host" "$DATAFILE")"
    # WG_SERIAL="$(jq -r ".$LOC.wireguard.serial" "$DATAFILE")"
    WG_SERIAL="$(jq -r ".$LOC.wireguard.serial" "$DATAFILE")"
    WG_SN="$(cut -d. -f1 <<< "$WG_DNS")"
    WG_HOST="$(cut -d: -f1 <<< "$WG_URL")"
    WG_PORT="$(cut -d: -f2 <<< "$WG_URL")"
    @@ -206,8 +217,10 @@ echo "Registering public key with $WG_NAME ($WG_HOST)"
    curl -GsS \
    --data-urlencode "pubkey=$CLIENT_PUBLIC_KEY" \
    --data-urlencode "pt=$TOK" \
    --resolve "$WG_DNS:$WG_PORT:$WG_HOST" \
    "https://$WG_DNS:$WG_PORT/addKey" > "$REMOTEINFO.temp" || (
    --cacert "$PIA_CERT" \
    --resolve "$WG_SERIAL:$WG_PORT:$WG_HOST" \
    "https://$WG_SERIAL:$WG_PORT/addKey" > "$REMOTEINFO.temp" \
    || (
    echo "Failed to register key with $WG_SN ($WG_HOST)"
    if ip link list "$PIA_INTERFACE" > /dev/null
    then
    @@ -281,14 +294,15 @@ then
    wg set "$PIA_INTERFACE" peer "$OLD_KEY" remove
    fi

    if [ "$PEER_IP" != "$OLD_PEER_IP" ]
    if [ "$PEER_IP" != "$OLD_PEER_IP/32" ]
    then
    echo " [Change $PIA_INTERFACE ipaddr from $OLD_PEER_IP to $PEER_IP]"
    # update link ip address in case
    ip addr replace "$PEER_IP" dev "$PIA_INTERFACE"
    ip addr del "$OLD_PEER_IP/32" dev "$PIA_INTERFACE"

    # remove old route
    ip rule del to "$OLD_PEER_IP" lookup china
    ip rule del to "$OLD_PEER_IP" lookup china 2>/dev/null
    fi
    else
    echo "Bringing up interface '$PIA_INTERFACE'"
  27. @triffid triffid revised this gist Jun 17, 2020. 1 changed file with 102 additions and 35 deletions.
    137 changes: 102 additions & 35 deletions pia-wg.sh
    Original file line number Diff line number Diff line change
    @@ -1,12 +1,37 @@
    #!/bin/bash

    # original scrpt posted by tpretz at https://www.reddit.com/r/PrivateInternetAccess/comments/g08ojr/is_wireguard_available_yet/fnvs20c/
    # original script posted by tpretz at https://www.reddit.com/r/PrivateInternetAccess/comments/g08ojr/is_wireguard_available_yet/fnvs20c/
    # and at https://gist.github.com/tpretz/5ea1226517d95361f063f621e45de0a6
    #
    # significantly modified by Triffid_Hunter
    #
    # Improved with suggestions from Threarah at https://www.reddit.com/r/PrivateInternetAccess/comments/h9y4da/is_there_any_way_to_generate_wireguard_config/fv3cgi9/
    #
    # After the first run to fetch various data files and an auth token, this script does not require the ability to DNS resolve privateinternetaccess.com

    if ! which jq &>/dev/null
    then
    echo "The 'jq' utility is required"
    echo " Most package managers should have a 'jq' package available"
    EXIT=1
    fi

    if ! which ip &>/dev/null
    then
    echo "The 'ip' utility from iproute2 is required"
    echo " Most package managers should have a 'iproute2' package available"
    EXIT=1
    fi

    if ! which wg &>/dev/null
    then
    echo "The 'wg' utility from wireguard/wireguard-tools is required"
    echo " Most package managers should have 'wireguard' or 'wireguard-tools' packages available"
    EXIT=1
    fi

    [ -n "$EXIT" ] && exit 1

    if [ -z "$CONFIGDIR" ]
    then
    CONFIGDIR="$HOME/.config/pia-wg"
    @@ -108,22 +133,31 @@ fi
    # fetch data.json if missing
    if ! [ -r "$DATAFILE" ]
    then
    echo "Fetching wireguard server list from github"
    wget -O "$DATAFILE" 'https://raw.githubusercontent.com/pia-foss/desktop/master/tests/res/openssl/payload1/payload' || exit 1
    echo "Fetching wireguard server list from PIA"
    # wget -O "$DATAFILE" 'https://raw.githubusercontent.com/pia-foss/desktop/master/tests/res/openssl/payload1/payload' || exit 1
    curl 'https://www.privateinternetaccess.com/vpninfo/servers?version=1001&client=x-alpha' > "$DATAFILE.temp" || exit 1
    if [ "$(jq 'map_values(select(.wireguard)) | keys' "$DATAFILE.temp" 2>/dev/null | wc -l)" -le 50 ]
    then
    echo "Bad serverlist retrieved to $DATAFILE.temp, exiting"
    echo "You can try again if there was a transient error"
    exit 1
    else
    jq -cM 'map_values(select(.wireguard))' "$DATAFILE.temp" > "$DATAFILE" 2>/dev/null
    fi
    fi

    if [ "$(jq -r ".$LOC" "$DATAFILE")" == "null" ]
    if [ "$(jq -r ".$LOC.wireguard" "$DATAFILE")" == "null" ]
    then
    # echo "No exact match for location \"$LOC\" trying pattern"
    # from https://unix.stackexchange.com/questions/443884/match-keys-with-regex-in-jq/443927#443927
    LOC=$(jq 'with_entries(if (.key|test("^'"$LOC"'")) then ( {key: .key, value: .value } ) else empty end ) | keys' "$DATAFILE" | grep ^\ | cut -d\" -f2 | shuf -n 1)
    fi

    if [ "$(jq -r .$LOC "$DATAFILE")" == "null" ]
    if [ "$(jq -r ".$LOC.wireguard" "$DATAFILE")" == "null" ]
    then
    echo "Location $LOC not found!"
    echo "Options are:"
    jq keys "$DATAFILE"
    jq 'map_values(select(.wireguard)) | keys' "$DATAFILE"
    echo
    echo "Please edit $CONFIG and change your desired location, then try again"
    exit 1
    @@ -154,26 +188,27 @@ touch "$TOKENFILE"
    chmod 600 "$TOKENFILE"
    echo "$TOK" > "$TOKENFILE"

    WG_URL=$(jq -r ".$LOC.wireguard.host" "$DATAFILE")
    WG_SERIAL=$(jq -r ".$LOC.wireguard.serial" "$DATAFILE")
    WG_HOST=$(cut -d: -f1 <<< "$WG_URL")
    WG_PORT=$(cut -d: -f2 <<< "$WG_URL")
    WG_NAME="$(jq -r ".$LOC.name" "$DATAFILE")"
    WG_DNS="$(jq -r ".$LOC.dns" "$DATAFILE")"
    WG_URL="$(jq -r ".$LOC.wireguard.host" "$DATAFILE")"
    # WG_SERIAL="$(jq -r ".$LOC.wireguard.serial" "$DATAFILE")"
    WG_SN="$(cut -d. -f1 <<< "$WG_DNS")"
    WG_HOST="$(cut -d: -f1 <<< "$WG_URL")"
    WG_PORT="$(cut -d: -f2 <<< "$WG_URL")"

    if [ -z "$WG_URL" ]; then
    echo "no wg region, exiting"
    exit 1
    fi

    echo "Registering public key with PIA endpoint $LOC ($WG_HOST)"
    echo "Registering public key with $WG_NAME ($WG_HOST)"

    # should TLS verify here
    # can't verify fully as PIA's wireguard endpoint certs don't have a chain back to a root CA
    curl -GksS \
    curl -GsS \
    --data-urlencode "pubkey=$CLIENT_PUBLIC_KEY" \
    --data-urlencode "pt=$TOK" \
    --resolve "$WG_SERIAL:$WG_PORT:$WG_HOST" \
    "https://$WG_SERIAL:$WG_PORT/addKey" > "$REMOTEINFO.temp" || (
    echo "Failed to register key with PIA endpoint $LOC ($WG_HOST)"
    --resolve "$WG_DNS:$WG_PORT:$WG_HOST" \
    "https://$WG_DNS:$WG_PORT/addKey" > "$REMOTEINFO.temp" || (
    echo "Failed to register key with $WG_SN ($WG_HOST)"
    if ip link list "$PIA_INTERFACE" > /dev/null
    then
    echo "If you're trying to change hosts because your link has stopped working,"
    @@ -196,6 +231,7 @@ PEER_IP="$(jq -r .peer_ip "$REMOTEINFO")"
    SERVER_PUBLIC_KEY="$(jq -r .server_key "$REMOTEINFO")"
    SERVER_IP="$(jq -r .server_ip "$REMOTEINFO")"
    SERVER_PORT="$(jq -r .server_port "$REMOTEINFO")"
    SERVER_VIP="$(jq -r .server_vip "$REMOTEINFO")"

    if [ -z "$WGCONF" ]
    then
    @@ -226,39 +262,46 @@ if [ "$EUID" -eq 0 ]
    then
    # scratch current config if any
    # put new settings into existing interface instead of teardown/re-up to prevent leaks
    if ip link list $PIA_INTERFACE > /dev/null
    if ip link list "$PIA_INTERFACE" > /dev/null
    then
    echo "Updating existing interface '$PIA_INTERFACE'"

    OLD_PEER_IP="$(ip -j addr show dev pia | jq '.[].addr_info[].local')"
    OLD_PEER_IP="$(ip -j addr show dev pia | jq -r '.[].addr_info[].local')"
    OLD_KEY="$(echo $(wg showconf "$PIA_INTERFACE" | grep ^PublicKey | cut -d= -f2-))"
    OLD_ENDPOINT="$(wg show "$PIA_INTERFACE" endpoints | grep "$OLD_KEY" | cut -d$'\t' -f2 | cut -d: -f1)"

    # ensure we don't get a packet storm loop
    ip rule add to "$SERVER_IP" lookup china pref 10

    echo " [Change Peer from $OLD_KEY to $SERVER_PUBLIC_KEY]"
    wg set "$PIA_INTERFACE" peer "$SERVER_PUBLIC_KEY" endpoint "$SERVER_IP:$SERVER_PORT" allowed-ips "0.0.0.0/0,::/0" || exit 1
    if [ "$OLD_KEY" != "$SERVER_PUBLIC_KEY" ]
    then
    echo " [Change Peer from $OLD_KEY to $SERVER_PUBLIC_KEY]"
    wg set "$PIA_INTERFACE" private-key <(echo "$CLIENT_PRIVATE_KEY") peer "$SERVER_PUBLIC_KEY" endpoint "$SERVER_IP:$SERVER_PORT" allowed-ips "0.0.0.0/0,::/0" || exit 1
    # remove old key
    wg set "$PIA_INTERFACE" peer "$OLD_KEY" remove
    fi

    if [ "$PEER_IP" != "$OLD_PEER_IP" ]
    then
    echo " [Change $PIA_INTERFACE ipaddr from $OLD_PEER_IP to $PEER_IP]"
    # update link ip address in case
    ip addr replace "$PEER_IP" dev "$PIA_INTERFACE"
    fi

    # remove old key
    wg set "$PIA_INTERFACE" peer "$OLD_KEY" remove
    # remove old route
    ip rule del to "$OLD_PEER_IP" lookup china
    # remove old route
    ip rule del to "$OLD_PEER_IP" lookup china
    fi
    else
    echo "Bringing up interface '$PIA_INTERFACE'"

    # Note: unnecessary if Table != off above, but doesn't hurt.
    ip rule add to "$SERVER_IP" lookup china

    # bring up wireguard interface
    wg-quick up "$WGCONF"
    # wg-quick up "$WGCONF"
    ip link add "$PIA_INTERFACE" type wireguard || exit 1
    ip link set dev "$PIA_INTERFACE" up || exit 1
    wg set "$PIA_INTERFACE" private-key <(echo "$CLIENT_PRIVATE_KEY") peer "$SERVER_PUBLIC_KEY" endpoint "$SERVER_IP:$SERVER_PORT" allowed-ips "0.0.0.0/0,::/0" || exit 1
    ip addr replace "$PEER_IP" dev "$PIA_INTERFACE" || exit 1

    # Note: only if Table = off in wireguard config file above
    ip route add default dev "$PIA_INTERFACE"
    @@ -270,8 +313,17 @@ else
    echo ip rule add to "$SERVER_IP" lookup china pref 10
    sudo ip rule add to "$SERVER_IP" lookup china pref 10

    echo wg set "$PIA_INTERFACE" peer "$SERVER_PUBLIC_KEY" endpoint "$SERVER_IP:$SERVER_PORT" allowed-ips "0.0.0.0/0,::/0"
    sudo wg set "$PIA_INTERFACE" peer "$SERVER_PUBLIC_KEY" endpoint "$SERVER_IP:$SERVER_PORT" allowed-ips "0.0.0.0/0,::/0"
    if ! ip link list "$PIA_INTERFACE" > /dev/null
    then
    echo ip link add "$PIA_INTERFACE" type wireguard
    sudo ip link add "$PIA_INTERFACE" type wireguard
    fi

    echo wg set "$PIA_INTERFACE" private-key "$CLIENT_PRIVATE_KEY" peer "$SERVER_PUBLIC_KEY" endpoint "$SERVER_IP:$SERVER_PORT" allowed-ips "0.0.0.0/0,::/0"
    sudo wg set "$PIA_INTERFACE" private-key <(echo "$CLIENT_PRIVATE_KEY") peer "$SERVER_PUBLIC_KEY" endpoint "$SERVER_IP:$SERVER_PORT" allowed-ips "0.0.0.0/0,::/0"

    echo ip addr replace "$PEER_IP" dev "$PIA_INTERFACE"
    sudo ip addr replace "$PEER_IP" dev "$PIA_INTERFACE"

    if ip link list $PIA_INTERFACE > /dev/null
    then
    @@ -285,12 +337,27 @@ else
    echo ip rule del to "$OLD_PEER_IP" lookup china
    sudo ip rule del to "$OLD_PEER_IP" lookup china
    fi
    fi

    echo ip route add "$SERVER_IP" via "$GATEWAY_IP" dev "$GATEWAY_DEV"
    sudo ip route add "$SERVER_IP" via "$GATEWAY_IP" dev "$GATEWAY_DEV"
    echo "PIA Wireguard '$PIA_INTERFACE' configured successfully"

    echo wg-quick up "$WGCONF"
    sudo wg-quick up "$WGCONF"
    fi
    echo -n "Waiting for connection to stabilise..."
    while ! ping -n -c1 -w 5 "$SERVER_VIP" &>/dev/null
    do
    echo -n "."
    done
    echo " OK"

    echo "Done"
    if find "$DATAFILE" -mtime -3 -exec false {} +
    then
    echo
    echo "PIA endpoint cache is stale, fetching new list.."
    curl 'https://www.privateinternetaccess.com/vpninfo/servers?version=1001&client=x-alpha' > "$DATAFILE.temp" || exit 1
    if [ "$(jq 'map_values(select(.wireguard)) | keys' "$DATAFILE.temp" 2>/dev/null | wc -l)" -le 50 ]
    then
    echo "Bad serverlist retrieved to $DATAFILE.temp, ignoring"
    else
    jq -cM 'map_values(select(.wireguard))' "$DATAFILE.temp" > "$DATAFILE" 2>/dev/null
    echo "Success"
    fi
    fi
  28. @triffid triffid revised this gist Jun 16, 2020. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion pia-wg.sh
    Original file line number Diff line number Diff line change
    @@ -185,7 +185,7 @@ curl -GksS \
    if [ "$(jq -r .status "$REMOTEINFO.temp")" != "OK" ]
    then
    echo "WG key registration failed - bad token?"
    echo "If you get an auth error, consider deleting .token and getting a new one"
    echo "If you see an auth error, consider deleting $TOKENFILE and getting a new token"
    exit 1
    fi

  29. @triffid triffid revised this gist Jun 9, 2020. 1 changed file with 2 additions and 2 deletions.
    4 changes: 2 additions & 2 deletions pia-wg.sh
    Original file line number Diff line number Diff line change
    @@ -231,14 +231,14 @@ then
    echo "Updating existing interface '$PIA_INTERFACE'"

    OLD_PEER_IP="$(ip -j addr show dev pia | jq '.[].addr_info[].local')"
    OLD_KEY="$(echo $(wg showconf "$PIA_INTERFACE" | grep ^PublicKey | cut -d= -f2))"
    OLD_KEY="$(echo $(wg showconf "$PIA_INTERFACE" | grep ^PublicKey | cut -d= -f2-))"
    OLD_ENDPOINT="$(wg show "$PIA_INTERFACE" endpoints | grep "$OLD_KEY" | cut -d$'\t' -f2 | cut -d: -f1)"

    # ensure we don't get a packet storm loop
    ip rule add to "$SERVER_IP" lookup china pref 10

    echo " [Change Peer from $OLD_KEY to $SERVER_PUBLIC_KEY]"
    wg set "$PIA_INTERFACE" peer "$SERVER_PUBLIC_KEY" endpoint "$SERVER_IP:$SERVER_PORT" allowed-ips "0.0.0.0/0,::/0"
    wg set "$PIA_INTERFACE" peer "$SERVER_PUBLIC_KEY" endpoint "$SERVER_IP:$SERVER_PORT" allowed-ips "0.0.0.0/0,::/0" || exit 1

    if [ "$PEER_IP" != "$OLD_PEER_IP" ]
    then
  30. @triffid triffid revised this gist Jun 4, 2020. 1 changed file with 71 additions and 26 deletions.
    97 changes: 71 additions & 26 deletions pia-wg.sh
    Original file line number Diff line number Diff line change
    @@ -112,11 +112,11 @@ then
    wget -O "$DATAFILE" 'https://raw.githubusercontent.com/pia-foss/desktop/master/tests/res/openssl/payload1/payload' || exit 1
    fi

    if [ "$(jq -r .$LOC "$DATAFILE")" == "null" ]
    if [ "$(jq -r ".$LOC" "$DATAFILE")" == "null" ]
    then
    echo "No exact match for location \"$LOC\" trying pattern"
    # echo "No exact match for location \"$LOC\" trying pattern"
    # from https://unix.stackexchange.com/questions/443884/match-keys-with-regex-in-jq/443927#443927
    LOC=$(jq 'with_entries(if (.key|test("^'$LOC'")) then ( {key: .key, value: .value } ) else empty end ) | keys' "$DATAFILE" | grep ^\ | cut -d\" -f2 | shuf -n 1)
    LOC=$(jq 'with_entries(if (.key|test("^'"$LOC"'")) then ( {key: .key, value: .value } ) else empty end ) | keys' "$DATAFILE" | grep ^\ | cut -d\" -f2 | shuf -n 1)
    fi

    if [ "$(jq -r .$LOC "$DATAFILE")" == "null" ]
    @@ -172,7 +172,15 @@ curl -GksS \
    --data-urlencode "pubkey=$CLIENT_PUBLIC_KEY" \
    --data-urlencode "pt=$TOK" \
    --resolve "$WG_SERIAL:$WG_PORT:$WG_HOST" \
    "https://$WG_SERIAL:$WG_PORT/addKey" | tee "$REMOTEINFO.temp" || exit 1
    "https://$WG_SERIAL:$WG_PORT/addKey" > "$REMOTEINFO.temp" || (
    echo "Failed to register key with PIA endpoint $LOC ($WG_HOST)"
    if ip link list "$PIA_INTERFACE" > /dev/null
    then
    echo "If you're trying to change hosts because your link has stopped working,"
    echo " you may need to "$'\x1b[1m'"ip link del dev $PIA_INTERFACE"$'\x1b[0m'" and try this script again"
    fi
    exit 1
    )

    if [ "$(jq -r .status "$REMOTEINFO.temp")" != "OK" ]
    then
    @@ -194,10 +202,10 @@ then
    WGCONF="$CONFIGDIR/${PIA_INTERFACE}.conf"
    fi

    echo "Generating $WGCONF"
    echo
    # echo "Generating $WGCONF"
    # echo

    tee "$WGCONF" <<ENDWG
    cat > "$WGCONF" <<ENDWG
    [Interface]
    PrivateKey = $CLIENT_PRIVATE_KEY
    Address = $PEER_IP
    @@ -210,36 +218,73 @@ AllowedIPs = 0.0.0.0/0, ::/0
    Endpoint = $SERVER_IP:$SERVER_PORT
    ENDWG

    echo
    echo "OK"
    # echo
    # echo "OK"

    echo "Bringing up wireguard interface $PIA_INTERFACE... "
    # echo "Bringing up wireguard interface $PIA_INTERFACE... "
    if [ "$EUID" -eq 0 ]
    then
    # scratch current config if any
    # TODO: put new settings into existing interface instead of teardown/re-up to prevent leaks
    wg-quick down "$WGCONF"
    # put new settings into existing interface instead of teardown/re-up to prevent leaks
    if ip link list $PIA_INTERFACE > /dev/null
    then
    echo "Updating existing interface '$PIA_INTERFACE'"

    OLD_PEER_IP="$(ip -j addr show dev pia | jq '.[].addr_info[].local')"
    OLD_KEY="$(echo $(wg showconf "$PIA_INTERFACE" | grep ^PublicKey | cut -d= -f2))"
    OLD_ENDPOINT="$(wg show "$PIA_INTERFACE" endpoints | grep "$OLD_KEY" | cut -d$'\t' -f2 | cut -d: -f1)"

    # ensure we don't get a packet storm loop
    ip rule add to "$SERVER_IP" lookup china pref 10

    echo " [Change Peer from $OLD_KEY to $SERVER_PUBLIC_KEY]"
    wg set "$PIA_INTERFACE" peer "$SERVER_PUBLIC_KEY" endpoint "$SERVER_IP:$SERVER_PORT" allowed-ips "0.0.0.0/0,::/0"

    GATEWAY_IP=$(ip route get "$SERVER_IP" | head -n1 | grep -oP 'via\s+\K\S+')
    GATEWAY_DEV=$(ip route get "$SERVER_IP" | head -n1 | grep -oP 'dev\s+\K\S+')
    if [ "$PEER_IP" != "$OLD_PEER_IP" ]
    then
    echo " [Change $PIA_INTERFACE ipaddr from $OLD_PEER_IP to $PEER_IP]"
    # update link ip address in case
    ip addr replace "$PEER_IP" dev "$PIA_INTERFACE"
    fi

    # Note: unnecessary if Table != off above, but doesn't hurt.
    ip route add "$SERVER_IP" via "$GATEWAY_IP" dev "$GATEWAY_DEV"
    # remove old key
    wg set "$PIA_INTERFACE" peer "$OLD_KEY" remove
    # remove old route
    ip rule del to "$OLD_PEER_IP" lookup china
    else
    echo "Bringing up interface '$PIA_INTERFACE'"

    # bring up wireguard interface
    wg-quick up "$WGCONF"
    # Note: unnecessary if Table != off above, but doesn't hurt.
    ip rule add to "$SERVER_IP" lookup china

    # Note: only if Table = off in wireguard config file above
    ip route add default dev "$PIA_INTERFACE"
    # bring up wireguard interface
    wg-quick up "$WGCONF"

    # Specific to my setup
    ip route add default table vpnonly dev "$PIA_INTERFACE"
    # Note: only if Table = off in wireguard config file above
    ip route add default dev "$PIA_INTERFACE"

    # Specific to my setup
    ip route add default table vpnonly dev "$PIA_INTERFACE"
    fi
    else
    echo wg-quick down "$WGCONF"
    sudo wg-quick down "$WGCONF"
    echo ip rule add to "$SERVER_IP" lookup china pref 10
    sudo ip rule add to "$SERVER_IP" lookup china pref 10

    GATEWAY_IP=$(ip route get "$SERVER_IP" | head -n1 | grep -oP 'via\s+\K\S+')
    GATEWAY_DEV=$(ip route get "$SERVER_IP" | head -n1 | grep -oP 'dev\s+\K\S+')
    echo wg set "$PIA_INTERFACE" peer "$SERVER_PUBLIC_KEY" endpoint "$SERVER_IP:$SERVER_PORT" allowed-ips "0.0.0.0/0,::/0"
    sudo wg set "$PIA_INTERFACE" peer "$SERVER_PUBLIC_KEY" endpoint "$SERVER_IP:$SERVER_PORT" allowed-ips "0.0.0.0/0,::/0"

    if ip link list $PIA_INTERFACE > /dev/null
    then
    OLD_PEER_IP="$(ip -j addr show dev pia | jq '.[].addr_info[].local')"
    OLD_KEY="$(echo $(wg showconf "$PIA_INTERFACE" | grep ^PublicKey | cut -d= -f2))"
    OLD_ENDPOINT="$(wg show "$PIA_INTERFACE" endpoints | grep "$OLD_KEY" | cut -d$'\t' -f2 | cut -d: -f1)"

    echo wg set "$PIA_INTERFACE" peer "$OLD_KEY" remove
    sudo wg set "$PIA_INTERFACE" peer "$OLD_KEY" remove

    echo ip rule del to "$OLD_PEER_IP" lookup china
    sudo ip rule del to "$OLD_PEER_IP" lookup china
    fi

    echo ip route add "$SERVER_IP" via "$GATEWAY_IP" dev "$GATEWAY_DEV"
    sudo ip route add "$SERVER_IP" via "$GATEWAY_IP" dev "$GATEWAY_DEV"