Skip to content

Instantly share code, notes, and snippets.

@koveseb
Forked from triffid/openrc-init-pia
Created March 29, 2021 13:49
Show Gist options
  • Select an option

  • Save koveseb/d6a2e3f709e15b1c1c996dcb2a7d527d to your computer and use it in GitHub Desktop.

Select an option

Save koveseb/d6a2e3f709e15b1c1c996dcb2a7d527d to your computer and use it in GitHub Desktop.

Revisions

  1. @triffid triffid revised this gist Mar 1, 2021. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion pia-check.sh
    Original file line number Diff line number Diff line change
    @@ -14,4 +14,4 @@ source "$PIA_CONFIG"

    SERVER_VIP="$(jq -r .server_vip "$REMOTEINFO")"

    ping -n -w5 -W0.5 -c5 "$SERVER_VIP"
    ping -I$PIA_INTERFACE -n -w5 -W0.5 -c5 "$SERVER_VIP"
  2. @triffid triffid revised this gist Feb 11, 2021. 1 changed file with 17 additions and 0 deletions.
    17 changes: 17 additions & 0 deletions pia-check.sh
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,17 @@
    #!/bin/bash

    PIA_CONFIG="$(dirname "$(realpath "$(which "$0")")")/pia-config.sh"

    if ! [ -r "$PIA_CONFIG" ]
    then
    echo "Can't find pia-config.sh at $PIA_CONFIG - if you've symlinked pia-wg.sh, please also symlink that file"
    EXIT=1
    fi

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

    source "$PIA_CONFIG"

    SERVER_VIP="$(jq -r .server_vip "$REMOTEINFO")"

    ping -n -w5 -W0.5 -c5 "$SERVER_VIP"
  3. @triffid triffid revised this gist Feb 10, 2021. 2 changed files with 21 additions and 8 deletions.
    11 changes: 9 additions & 2 deletions pia-config.sh
    Original file line number Diff line number Diff line change
    @@ -1,5 +1,12 @@
    #!/bin/bash

    if [ -t 1 ]
    then
    BOLD=$'\e[1m'
    NORMAL=$'\e[0m'
    fi
    TAB=$'\t'

    if [ -z "$CONFIGDIR" ]
    then
    if [ $EUID -eq 0 ]
    @@ -45,13 +52,13 @@ fi

    if [ -z "$LOC" ]
    then
    echo "Setting default location: any"
    echo "Setting default location: ${BOLD}any${NORMAL}"
    LOC="."
    fi

    if [ -z "$PIA_INTERFACE" ]
    then
    echo "Setting default wireguard interface name: pia"
    echo "Setting default wireguard interface name: ${BOLD}pia${NORMAL}"
    PIA_INTERFACE="pia"
    fi

    18 changes: 12 additions & 6 deletions pia-wg.sh
    Original file line number Diff line number Diff line change
    @@ -149,7 +149,11 @@ 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 "${BOLD}Location${TAB}Region${TAB}Port Forward${TAB}Geolocated${NORMAL}"
    echo "----------------${TAB}------------------${TAB}------------${TAB}----------"
    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 "${TAB}"
    echo "${PORTFORWARD:+'Note: only port-forwarding regions displayed'}"
    echo "Please edit $CONFIG and change your desired location, then try again"
    exit 1
    @@ -198,7 +202,7 @@ if [ -z "$WG_HOST$WG_PORT" ]; then
    exit 1
    fi

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

    if ! curl -GsS \
    @@ -225,7 +229,7 @@ then
    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"
    echo " you may need to ${BOLD}ip link del dev $PIA_INTERFACE${NORMAL} and try this script again"
    fi
    exit 1
    fi
    @@ -283,7 +287,9 @@ then
    sh <<< "$ROUTES_ADD"
    fi
    echo "Table $HARDWARE_ROUTE_TABLE (hardware network links) now contains:"
    ip route show table $HARDWARE_ROUTE_TABLE | sed -e $'s/^/\t/'
    ip route show table $HARDWARE_ROUTE_TABLE | sed -e "s/^/${TAB}/"
    echo
    echo "${BOLD}*** PLEASE NOTE: if this table isn't updated by your network post-connect hooks, your connection cannot remain up if your network links change${NORMAL}"
    fi

    # echo "Bringing up wireguard interface $PIA_INTERFACE... "
    @@ -297,7 +303,7 @@ then

    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)"
    OLD_ENDPOINT="$(wg show "$PIA_INTERFACE" endpoints | grep "$OLD_KEY" | cut "-d${TAB}" -f2 | cut -d: -f1)"

    # Note: unnecessary if Table != off above, but doesn't hurt.
    # ensure we don't get a packet storm loop
    @@ -366,7 +372,7 @@ else
    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)"
    OLD_ENDPOINT="$(wg show "$PIA_INTERFACE" endpoints | grep "$OLD_KEY" | cut "-d${TAB}" -f2 | cut -d: -f1)"

    echo wg set "$PIA_INTERFACE" peer "$OLD_KEY" remove
    sudo wg set "$PIA_INTERFACE" peer "$OLD_KEY" remove
  4. @triffid triffid revised this gist Feb 10, 2021. 4 changed files with 178 additions and 252 deletions.
    118 changes: 118 additions & 0 deletions pia-config.sh
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,118 @@
    #!/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 "$CLIENT_PRIVATE_KEY" ]
    then
    echo "Generating new private key"
    CLIENT_PRIVATE_KEY="$(wg genkey)"
    fi

    if [ -z "$CLIENT_PUBLIC_KEY" ]
    then
    CLIENT_PUBLIC_KEY=$(wg pubkey <<< "$CLIENT_PRIVATE_KEY")
    fi

    if [ -z "$CLIENT_PUBLIC_KEY" ]
    then
    echo "Failed to generate client public key, check your config!"
    exit 1
    fi

    if [ -z "$LOC" ]
    then
    echo "Setting default location: any"
    LOC="."
    fi

    if [ -z "$PIA_INTERFACE" ]
    then
    echo "Setting default wireguard interface name: pia"
    PIA_INTERFACE="pia"
    fi

    if [ -z "$WGCONF" ]
    then
    WGCONF="$CONFIGDIR/${PIA_INTERFACE}.conf"
    fi

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

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

    if [ -z "$TOK" ] && [ -r "$TOKENFILE" ]
    then
    TOK=$(< "$TOKENFILE")
    fi

    if [ -z "$DATAFILE" ]
    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"
    fi

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

    if [ -z "$HARDWARE_ROUTE_TABLE" ]
    then
    # 0xca6c
    HARDWARE_ROUTE_TABLE=51820
    fi

    if [ -z "$VPNONLY_ROUTE_TABLE" ]
    then
    # 0xca6d
    VPNONLY_ROUTE_TABLE=51821
    fi

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

    if [ -z "$PF_BINDFILE" ]
    then
    PF_BINDFILE="$CONFIGDIR/pf-bind"
    fi
    48 changes: 8 additions & 40 deletions pia-currentserver.sh
    Original file line number Diff line number Diff line change
    @@ -1,55 +1,23 @@
    #!/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
    PIA_CONFIG="$(dirname "$(realpath "$(which "$0")")")/pia-config.sh"

    if [ -z "$DATAFILE_NEW" ]
    if ! [ -r "$PIA_CONFIG" ]
    then
    DATAFILE_NEW="$CONFIGDIR/data_new.json"
    echo "Can't find pia-config.sh at $PIA_CONFIG - if you've symlinked pia-wg.sh, please also symlink that file"
    EXIT=1
    fi

    if [ -z "$REMOTEINFO" ]
    then
    REMOTEINFO="$CONFIGDIR/remote.info"
    fi
    [ -n "$EXIT" ] && exit 1

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

    if [ -z "$CONNCACHE" ]
    then
    CONNCACHE="$CONFIGDIR/cache.json"
    fi
    SERVER_IP="$(jq -r .server_ip "$REMOTEINFO")"

    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")" ]
    elif [ -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"
    87 changes: 6 additions & 81 deletions pia-portforward.sh
    Original file line number Diff line number Diff line change
    @@ -1,98 +1,23 @@
    #!/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
    PIA_CONFIG="$(dirname "$(realpath "$(which "$0")")")/pia-config.sh"

    if [ -z "$TOK" ] && [ -r "$TOKENFILE" ]
    if ! [ -r "$PIA_CONFIG" ]
    then
    TOK="$(< "$TOKENFILE")"
    else
    echo "Can't find token $TOKENFILE"
    exit 1
    echo "Can't find pia-config.sh at $PIA_CONFIG - if you've symlinked pia-wg.sh, please also symlink that file"
    EXIT=1
    fi

    if [ -z "$PIA_INTERFACE" ]
    then
    PIA_INTERFACE="pia"
    fi
    [ -n "$EXIT" ] && exit 1

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

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

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

    if [ -r "$CONNCACHE" ]
    then
    WG_INFO="$(jq -r . "$CONNCACHE")"

    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

    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 "$WG_INFO" ]
    then
    177 changes: 46 additions & 131 deletions pia-wg.sh
    Original file line number Diff line number Diff line change
    @@ -37,100 +37,17 @@ then
    EXIT=1
    fi

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

    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 "$CLIENT_PRIVATE_KEY" ]
    then
    echo "Generating new private key"
    CLIENT_PRIVATE_KEY="$(wg genkey)"
    fi

    if [ -z "$CLIENT_PUBLIC_KEY" ]
    then
    CLIENT_PUBLIC_KEY=$(wg pubkey <<< "$CLIENT_PRIVATE_KEY")
    fi

    if [ -z "$CLIENT_PUBLIC_KEY" ]
    then
    echo "Failed to generate client public key, check your config!"
    exit 1
    fi

    if [ -z "$LOC" ]
    then
    echo "Setting default location: any"
    LOC="."
    fi

    if [ -z "$PIA_INTERFACE" ]
    then
    echo "Setting default wireguard interface name: pia"
    PIA_INTERFACE="pia"
    fi

    if [ -z "$PIA_CERT" ]
    then
    PIA_CERT="$CONFIGDIR/rsa_4096.crt"
    fi
    PIA_CONFIG="$(dirname "$(realpath "$(which "$0")")")/pia-config.sh"

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

    if [ -z "$DATAFILE" ]
    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"
    fi

    if [ -z "$CONNCACHE" ]
    then
    CONNCACHE="$CONFIGDIR/cache.json"
    echo "Can't find pia-config.sh at $PIA_CONFIG - if you've symlinked pia-wg.sh, please also symlink that file"
    EXIT=1
    fi

    # get token
    if [ -z "$TOK" ] && [ -r "$TOKENFILE" ]
    then
    TOK=$(< "$TOKENFILE")
    fi
    [ -n "$EXIT" ] && exit 1

    # echo "$TOK"
    source "$PIA_CONFIG"

    if [ -z "$TOK" ] && ([ -z "$PIA_USERNAME" ] || [ -z "$PASS" ])
    then
    @@ -295,7 +212,7 @@ then
    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
    # in testing I find that sometimes one works, sometimes the other works
    if ! curl -GsS \
    --max-time 5 \
    --data-urlencode "pubkey=$CLIENT_PUBLIC_KEY" \
    @@ -330,30 +247,45 @@ 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
    WGCONF="$CONFIGDIR/${PIA_INTERFACE}.conf"
    fi

    # echo "Generating $WGCONF"
    # echo

    cat > "$WGCONF" <<ENDWG
    [Interface]
    PrivateKey = $CLIENT_PRIVATE_KEY
    Address = $PEER_IP
    Table = off
    DNS = $(jq -r '.dns_servers[0:2]' "$REMOTEINFO" | grep ^\ | cut -d\" -f2 | xargs echo | sed -e 's/ /,/g')
    [Peer]
    PublicKey = $SERVER_PUBLIC_KEY
    AllowedIPs = 0.0.0.0/0, ::/0
    Endpoint = $SERVER_IP:$SERVER_PORT
    ENDWG
    # cat > "$WGCONF" <<ENDWG
    # [Interface]
    # PrivateKey = $CLIENT_PRIVATE_KEY
    # Address = $PEER_IP
    # Table = off
    # DNS = $(jq -r '.dns_servers[0:2]' "$REMOTEINFO" | grep ^\ | cut -d\" -f2 | xargs echo | sed -e 's/ /,/g')
    #
    # [Peer]
    # PublicKey = $SERVER_PUBLIC_KEY
    # AllowedIPs = 0.0.0.0/0, ::/0
    # Endpoint = $SERVER_IP:$SERVER_PORT
    # ENDWG

    # echo
    # echo "OK"

    if ! ip route show table $HARDWARE_ROUTE_TABLE 2>/dev/null | grep -q .
    then
    ROUTES_ADD=$(
    for IF in $(ip link show | grep -B1 'link/ether' | grep '^[0-9]' | cut -d: -f2)
    do
    ip route show | grep "dev $IF" | sed -e 's/linkdown//' | sed -e "s/^/ip route add table $HARDWARE_ROUTE_TABLE /"
    done
    )
    if [ "$EUID" -eq 0 ]
    then
    echo "Build a routing table with only hardware links to stop wireguard packets going back through the VPN:"
    echo sudo sh '<<<' "$ROUTES_ADD"
    sudo sh <<< "$ROUTES_ADD"
    else
    sh <<< "$ROUTES_ADD"
    fi
    echo "Table $HARDWARE_ROUTE_TABLE (hardware network links) now contains:"
    ip route show table $HARDWARE_ROUTE_TABLE | sed -e $'s/^/\t/'
    fi

    # echo "Bringing up wireguard interface $PIA_INTERFACE... "
    if [ "$EUID" -eq 0 ]
    then
    @@ -369,8 +301,7 @@ 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 fwmark 51820 lookup china pref 10
    ip rule add fwmark 51820 lookup $HARDWARE_ROUTE_TABLE pref 10

    if [ "$OLD_KEY" != "$SERVER_PUBLIC_KEY" ]
    then
    @@ -388,49 +319,36 @@ then
    ip addr del "$OLD_PEER_IP/32" dev "$PIA_INTERFACE"

    # remove old route
    ip rule del to "$OLD_PEER_IP" lookup china 2>/dev/null
    ip rule del to "$OLD_PEER_IP" lookup $HARDWARE_ROUTE_TABLE 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"
    ip route add default table $VPNONLY_ROUTE_TABLE dev "$PIA_INTERFACE"
    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 pref 10
    ip rule add fwmark 51820 lookup china pref 10
    ip rule add fwmark 51820 lookup $HARDWARE_ROUTE_TABLE 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" 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

    # 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"

    # 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 route add default table $VPNONLY_ROUTE_TABLE dev "$PIA_INTERFACE"

    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 fwmark 51820 lookup china pref 10
    sudo ip rule add fwmark 51820 lookup china pref 10
    echo ip rule add fwmark 51820 lookup $HARDWARE_ROUTE_TABLE pref 10
    sudo ip rule add fwmark 51820 lookup $HARDWARE_ROUTE_TABLE pref 10

    if ! ip link list "$PIA_INTERFACE" > /dev/null
    then
    @@ -452,9 +370,6 @@ 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
    fi

    echo ip route add default dev "$PIA_INTERFACE"
  5. @triffid triffid revised this gist Jan 26, 2021. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion openrc-init-pia
    Original file line number Diff line number Diff line change
    @@ -52,5 +52,5 @@ restart() {

    stop() {
    source "$CONFIG"
    ip link del "$PIA_INTERFACE"
    ip link del "${PIA_INTERFACE:-pia}"
    }
  6. @triffid triffid revised this gist Jan 26, 2021. 1 changed file with 23 additions and 1 deletion.
    24 changes: 23 additions & 1 deletion pia-portforward.sh
    Original file line number Diff line number Diff line change
    @@ -69,13 +69,35 @@ then
    PF_BINDFILE="$CONFIGDIR/pf-bind"
    fi

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

    if [ -r "$CONNCACHE" ]
    then
    WG_INFO="$(jq -r . "$CONNCACHE")"

    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

    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
    WG_INFO="$(jq '.regions | .[] | select(.servers.wg[0].ip == "'"$SERVER_IP"'")' "$DATAFILE_NEW")"
    fi

    if [ -z "$WG_INFO" ]
    then
  7. @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 \
  8. @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
  9. @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"

    ###############################################################################
    # #
  10. @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"
  11. @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
  12. @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" ]
  13. @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"
  14. @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"
  15. @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/
  16. @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

  17. @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
  18. @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"
  19. @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
  20. @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
  21. @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 ))
  22. @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

  23. @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" ]
  24. @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
  25. @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
  26. @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
  27. @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"

  28. @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"
    }
  29. @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"

  30. @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"