refactoring and readme improvements

This commit is contained in:
gunix 2020-09-19 00:08:43 +03:00
parent 09dee21d40
commit b88e135b89
4 changed files with 165 additions and 101 deletions

View File

@ -6,14 +6,28 @@ This repository contains documentation on how to create native WireGuard connect
You will find a lot of information bellow. However if you prefer a hands-on approach, here is the __TL/DR__: You will find a lot of information bellow. However if you prefer a hands-on approach, here is the __TL/DR__:
* clone this repo: `git clone https://github.com/pia-foss/manual-connections.git` * clone this repo: `git clone https://github.com/pia-foss/manual-connections.git`
* use `get_region_and_token.sh` to get the best region and a token * use `get_region_and_token.sh` to get the best region and a token
* use `wireguard_and_pf.sh` to create a WireGuard connection with/without PF * use `connect_to_wireguard_with_token.sh` to create a WireGuard connection with/without PF
Here is a oneliner example:
```
sudo PIA_AUTOCONNECT=wireguard PIA_USER=p0123456 PIA_PASS=xxxxxxxxxx ./get_region_and_token.sh
```
### Dependencies ### Dependencies
In order for the scripts to work (probably even if you do a manual setup), you will need the following packages: In order for the scripts to work (probably even if you do a manual setup), you will need the following packages:
* `curl` * `curl`
* `jq` * `jq`
* `wireguard-tools` (which give you the `wg-quick` utility) * (only for WireGuard) `wireguard-tools` and wireguard kernel module
* (only for OpenVPN) `openvpn`
### Confirmed distributions
The functionality of the scripts within this repository has been tested and confirmed on the following distributions:
* Arch
* Artix
* Fedora 32
* Ubuntu 20.04
## PIA Port Forwarding ## PIA Port Forwarding
@ -26,9 +40,10 @@ This service can be used only AFTER establishing a VPN connection.
In order to help you use VPN services and PF on any device, we have prepare a few bash scripts that should help you through the process of setting everything up. The scripts also contain a lot of comments, just in case you require detailed information regarding how the technology works. In order to help you use VPN services and PF on any device, we have prepare a few bash scripts that should help you through the process of setting everything up. The scripts also contain a lot of comments, just in case you require detailed information regarding how the technology works.
Here is a list of scripts you could find useful: Here is a list of scripts you could find useful:
* [region and token script](get_region_and_token.sh): This script helps you to get the best region and also to get a token for VPN authentication. The script will extend it's functionality if you add extra environment variables. Adding your PIA credentials will allow the script to also get a VPN token. The script can also trigger the WireGuard script to create a connection, if you specify `WG_AUTOCONNECT=true`. * [Get the best region and a token](get_region_and_token.sh): This script helps you to get the best region and also to get a token for VPN authentication. The script will extend it's functionality if you add extra environment variables. Adding your PIA credentials will allow the script to also get a VPN token. The script can also trigger the WireGuard script to create a connection, if you specify `WG_AUTOCONNECT=true`.
* [wireguard and pf script](wireguard_and_pf.sh): This script allow you to connect to the VPN server via WireGuard. You can specify `PIA_PF=true` if you also wish to get Port Forwarding for your connection. * [Connect to WireGuard](connect_to_wireguard_with_token.sh): This script allow you to connect to the VPN server via WireGuard. You can specify `PIA_PF=true` if you also wish to get Port Forwarding for your connection.
* OpenVPN automation is not ready yet, however will be available soon enough. * Connect to OpenVPN: We are still working on this script.
* [Enable Port Forwarding](port_forwarding.sh): Enables you to add Port Forwarding to an existing VPN connection.
## Manual setup of PF ## Manual setup of PF
@ -90,3 +105,6 @@ listening on any, link-type LINUX_SLL (Linux cooked v1), capture size 262144 byt
22:44:01.510804 IP 81.180.227.170.33884 > 10.4.143.34.47047: Flags [S], seq 906854496, win 64860, options [mss 1380,sackOK,TS val 2608022390 ecr 0,nop,wscale 7], length 0 22:44:01.510804 IP 81.180.227.170.33884 > 10.4.143.34.47047: Flags [S], seq 906854496, win 64860, options [mss 1380,sackOK,TS val 2608022390 ecr 0,nop,wscale 7], length 0
22:44:01.510895 IP 10.4.143.34.47047 > 81.180.227.170.33884: Flags [R.], seq 0, ack 906854497, win 0, length 0 22:44:01.510895 IP 10.4.143.34.47047 > 81.180.227.170.33884: Flags [R.], seq 0, ack 906854497, win 0, length 0
``` ```
## License
This project is licensed under the [MIT (Expat) license](https://choosealicense.com/licenses/mit/), which can be found [here](/LICENSE).

View File

@ -127,93 +127,14 @@ fi
echo " echo "
This script got started with PIA_PF=true. This script got started with PIA_PF=true.
Starting procedure to enable port forwarding." Starting procedure to enable port forwarding by running the following command:
PIA_TOKEN=$WG_TOKEN \\
PF_GATEWAY=\"$(echo "$wireguard_json" | jq -r '.server_vip')\" \\
PF_HOSTNAME=\"$WG_HOSTNAME\" \\
./port_forwarding.sh
"
# The port forwarding system has required two variables: PIA_TOKEN=$WG_TOKEN \
# PAYLOAD: contains the token, the port and the expiration date PF_GATEWAY="$(echo "$wireguard_json" | jq -r '.server_vip')" \
# SIGNATURE: certifies the payload originates from the PIA network. PF_HOSTNAME="$WG_HOSTNAME" \
./port_forwarding.sh
# Basically PAYLOAD+SIGNATURE=PORT. You can use the same PORT on all servers.
# The system has been designed to be completely decentralized, so that your
# privacy is protected even if you want to host services on your systems.
# You can get your PAYLOAD+SIGNATURE with a simple curl request to any VPN
# gateway, no matter what protocol you are using.
# Since this is the script for wireguard, you can just get the gateway
# from the JSON response you got at the previous step from the Wireguard API.
gateway="$(echo "$wireguard_json" | jq -r '.server_vip')"
# Get the payload and the signature from the PF API. This will grant you
# access to a random port, which you can activate on any server you connect to.
# If you already have a signature, and you would like to re-use that port,
# save the payload_and_signature received from your previous request
# in the env var PAYLOAD_AND_SIGNATURE, and that will be used instead.
if [[ ! $PAYLOAD_AND_SIGNATURE ]]; then
echo "Getting new signature..."
payload_and_signature="$(curl -s -m 5 \
--connect-to "$WG_HOSTNAME::$gateway:" \
--cacert "ca.rsa.4096.crt" \
-G --data-urlencode "token=${WG_TOKEN}" \
"https://${WG_HOSTNAME}:19999/getSignature")"
else
payload_and_signature="$PAYLOAD_AND_SIGNATURE"
echo "Using the following payload_and_signature from the env var:"
fi
echo "$payload_and_signature"
export payload_and_signature
# Check if the payload and the signature are OK.
# If they are not OK, just stop the script.
if [ "$(echo "$payload_and_signature" | jq -r '.status')" != "OK" ]; then
echo "The payload_and_signature variable does not contain an OK status."
exit 1
fi
# We need to get the signature out of the previous response.
# The signature will allow the us to bind the port on the server.
signature="$(echo "$payload_and_signature" | jq -r '.signature')"
# The payload has a base64 format. We need to extract it from the
# previous reponse and also get the following information out:
# - port: This is the port you got access to
# - expires_at: this is the date+time when the port expires
payload="$(echo "$payload_and_signature" | jq -r '.payload')"
port="$(echo "$payload" | base64 -d | jq -r '.port')"
# The port normally expires after 2 months. If you consider
# 2 months is not enough for your setup, please open a ticket.
expires_at="$(echo "$payload" | base64 -d | jq -r '.expires_at')"
# Display some information on the screen for the user.
echo "The signature is OK.
--> The port is $port and it will expire on $expires_at. <--
Trying to bind the port..."
# Now we have all required data to create a request to bind the port.
# We will repeat this request every 15 minutes, in order to keep the port
# alive. The servers have no mechanism to track your activity, so they
# will just delete the port forwarding if you don't send keepalives.
while true; do
bind_port_response="$(curl -Gs -m 5 \
--connect-to "$WG_HOSTNAME::$gateway:" \
--cacert "ca.rsa.4096.crt" \
--data-urlencode "payload=${payload}" \
--data-urlencode "signature=${signature}" \
"https://${WG_HOSTNAME}:19999/bindPort")"
echo "$bind_port_response"
# If port did not bind, just exit the script.
# This script will exit in 2 months, since the port will expire.
export bind_port_response
if [ "$(echo "$bind_port_response" | jq -r '.status')" != "OK" ]; then
echo "The API did not return OK when trying to bind port. Exiting."
exit 1
fi
echo Port $port refreshed on $(date). \
This port will expire on $(date --date="$expires_at")
# sleep 15 minutes
sleep 900
done

View File

@ -136,16 +136,16 @@ token="$(echo "$generateTokenResponse" | jq -r '.token')"
echo "This token will expire in 24 hours. echo "This token will expire in 24 hours.
" "
if [ "$WG_AUTOCONNECT" != true ]; then if [ "$PIA_AUTOCONNECT" != wireguard ]; then
echo If you wish to automatically connect to WireGuard after detecting the best echo If you wish to automatically connect to WireGuard after detecting the best
echo region, please run the script with the env var WG_AUTOCONNECT=true. You can echo region, please run the script with the env var PIA_AUTOCONNECT=wireguard. You can
echo also specify the env var PIA_PF=true to get port forwarding. Example: echo also specify the env var PIA_PF=true to get port forwarding. Example:
echo $ PIA_USER=p0123456 PIA_PASS=xxx \ echo $ PIA_USER=p0123456 PIA_PASS=xxx \
WG_AUTOCONNECT=true PIA_PF=true ./sort_regions_by_latency.sh PIA_AUTOCONNECT=true PIA_PF=true ./sort_regions_by_latency.sh
echo echo
echo You can connect by running: echo You can also connect manually by running:
echo WG_TOKEN=\"$token\" WG_SERVER_IP=$bestServer_WG_IP \ echo WG_TOKEN=\"$token\" WG_SERVER_IP=$bestServer_WG_IP \
WG_HOSTNAME=$bestServer_WG_hostname ./wireguard_and_pf.sh WG_HOSTNAME=$bestServer_WG_hostname ./connect_to_wireguard_with_token.sh
exit exit
fi fi
@ -153,7 +153,7 @@ if [ "$PIA_PF" != true ]; then
PIA_PF="false" PIA_PF="false"
fi fi
echo "The ./get_region_and_token.sh script got started with WG_AUTOCONNECT=true, echo "The ./get_region_and_token.sh script got started with PIA_AUTOCONNECT=wireguard,
so we will automatically connect to WireGuard, by running this command: so we will automatically connect to WireGuard, by running this command:
$ WG_TOKEN=\"$token\" \\ $ WG_TOKEN=\"$token\" \\
WG_SERVER_IP=$bestServer_WG_IP WG_HOSTNAME=$bestServer_WG_hostname \\ WG_SERVER_IP=$bestServer_WG_IP WG_HOSTNAME=$bestServer_WG_hostname \\
@ -161,4 +161,4 @@ $ WG_TOKEN=\"$token\" \\
" "
PIA_PF=$PIA_PF WG_TOKEN="$token" WG_SERVER_IP=$bestServer_WG_IP \ PIA_PF=$PIA_PF WG_TOKEN="$token" WG_SERVER_IP=$bestServer_WG_IP \
WG_HOSTNAME=$bestServer_WG_hostname ./wireguard_and_pf.sh WG_HOSTNAME=$bestServer_WG_hostname ./connect_to_wireguard_with_token.sh

125
port_forwarding.sh Executable file
View File

@ -0,0 +1,125 @@
#!/bin/bash
# Copyright (C) 2020 Private Internet Access, Inc.
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
# Check if the mandatory environment variables are set.
if [[ ! $PF_GATEWAY || ! $PIA_TOKEN ]]; then
echo This script requires 2 env vars:
echo PF_GATEWAY - the IP of your gateway
echo PF_HOSTNAME - name of the host used for SSL/TLS certificate verification
echo PIA_TOKEN - the token you use to connect to the vpn services
echo
echo An easy solution is to just run get_region_and_token.sh
echo as it will guide you through getting the best server and
echo also a token. Detailed information can be found here:
echo https://github.com/pia-foss/manual-connections
exit 1
fi
# The port forwarding system has required two variables:
# PAYLOAD: contains the token, the port and the expiration date
# SIGNATURE: certifies the payload originates from the PIA network.
# Basically PAYLOAD+SIGNATURE=PORT. You can use the same PORT on all servers.
# The system has been designed to be completely decentralized, so that your
# privacy is protected even if you want to host services on your systems.
# You can get your PAYLOAD+SIGNATURE with a simple curl request to any VPN
# gateway, no matter what protocol you are using. Considering WireGuard has
# already been automated in this repo, here is a command to help you get
# your gateway if you have an active OpenVPN connection:
# $ ip route | head -1 | grep tun | awk '{ print $3 }'
# This section will get updated as soon as we created the OpenVPN script.
# Get the payload and the signature from the PF API. This will grant you
# access to a random port, which you can activate on any server you connect to.
# If you already have a signature, and you would like to re-use that port,
# save the payload_and_signature received from your previous request
# in the env var PAYLOAD_AND_SIGNATURE, and that will be used instead.
if [[ ! $PAYLOAD_AND_SIGNATURE ]]; then
echo "Getting new signature..."
payload_and_signature="$(curl -s -m 5 \
--connect-to "$PF_HOSTNAME::$PF_GATEWAY:" \
--cacert "ca.rsa.4096.crt" \
-G --data-urlencode "token=${WG_TOKEN}" \
"https://${PF_HOSTNAME}:19999/getSignature")"
else
payload_and_signature="$PAYLOAD_AND_SIGNATURE"
echo "Using the following payload_and_signature from the env var:"
fi
echo "$payload_and_signature"
export payload_and_signature
# Check if the payload and the signature are OK.
# If they are not OK, just stop the script.
if [ "$(echo "$payload_and_signature" | jq -r '.status')" != "OK" ]; then
echo "The payload_and_signature variable does not contain an OK status."
exit 1
fi
# We need to get the signature out of the previous response.
# The signature will allow the us to bind the port on the server.
signature="$(echo "$payload_and_signature" | jq -r '.signature')"
# The payload has a base64 format. We need to extract it from the
# previous reponse and also get the following information out:
# - port: This is the port you got access to
# - expires_at: this is the date+time when the port expires
payload="$(echo "$payload_and_signature" | jq -r '.payload')"
port="$(echo "$payload" | base64 -d | jq -r '.port')"
# The port normally expires after 2 months. If you consider
# 2 months is not enough for your setup, please open a ticket.
expires_at="$(echo "$payload" | base64 -d | jq -r '.expires_at')"
# Display some information on the screen for the user.
echo "The signature is OK.
--> The port is $port and it will expire on $expires_at. <--
Trying to bind the port..."
# Now we have all required data to create a request to bind the port.
# We will repeat this request every 15 minutes, in order to keep the port
# alive. The servers have no mechanism to track your activity, so they
# will just delete the port forwarding if you don't send keepalives.
while true; do
bind_port_response="$(curl -Gs -m 5 \
--connect-to "$PF_HOSTNAME::$PF_GATEWAY:" \
--cacert "ca.rsa.4096.crt" \
--data-urlencode "payload=${payload}" \
--data-urlencode "signature=${signature}" \
"https://${PF_HOSTNAME}:19999/bindPort")"
echo "$bind_port_response"
# If port did not bind, just exit the script.
# This script will exit in 2 months, since the port will expire.
export bind_port_response
if [ "$(echo "$bind_port_response" | jq -r '.status')" != "OK" ]; then
echo "The API did not return OK when trying to bind port. Exiting."
exit 1
fi
echo Port $port refreshed on $(date). \
This port will expire on $(date --date="$expires_at")
# sleep 15 minutes
sleep 900
done