Compare commits

...

35 Commits

Author SHA1 Message Date
RoboMagus e956c57849
Add: Option to only generate WG config file (#171)
See #171.
2023-02-06 12:45:34 +01:00
Joel Elkins e37693326d
Add jdelkins/pia-tools to list of 3rd party repos (#167) 2022-12-09 15:54:56 +01:00
kp-dragos-neagu 203fd68b75
Merge pull request #165 from faireOwl/master
Integration of One-Line Call for DIP
2022-08-30 09:35:56 +03:00
faireOwl 4e5714ecc5 Integration of One-Line Call for DIP
Integrated one-line call support for DIP_TOKEN=none

Fixed formatting issue introduced by longer server names of new servers

Fixed spacing to normalize output in all conditions

Updated readme to provide details about new one-line call example
2022-08-26 10:21:52 -05:00
faireOwl 9b42ad934a
Add: DIP Support (#159)
* Provision of DIP Support

Added dedicated IP support, including DIP_TOKEN for one-line calls and prompts through run_setup.sh.

Adjusted package dependency response for wireguard to list the necessary package (wireguard-tools) to utilize wg-quick.

Updated README.md to clarify package dependencies and include DIP_TOKEN.
2022-08-23 11:59:02 +02:00
gheorghe c7336e9e03 on wireguard switch back to 0.0.0.0/0 from 0.0.0.0/1, 128.0.0.0/1, as this is blocking connections on some devices 2022-02-20 13:53:02 +02:00
gheorghe 9ee75c4df1 fixed merge conflict on README.md 2022-02-19 04:06:29 +02:00
a1346054 2eaa262bbe make color definitions portable 2022-02-19 04:01:13 +02:00
a1346054 7d85dae095 move variable to the right place and use it 2022-02-19 04:01:13 +02:00
a1346054 775284eacb add color, just like for openvpn 2022-02-19 04:01:13 +02:00
a1346054 a5bd8532be unify quoting style for echo 2022-02-19 04:01:13 +02:00
a1346054 a534a3cc5f fix conditionals 2022-02-19 04:01:13 +02:00
a1346054 f47b320a4a use modern shell syntax and fix various warnings
This unifies the codestyle across all shell scripts, and fixes many
warnings reported through shellcheck. Additionally, it improves
readability for everyone wishing to see what is actually going on.
2022-02-19 04:01:13 +02:00
a1346054 27ed048374 fix spelling 2022-02-19 04:01:13 +02:00
a1346054 e2b9b733af use proper check for root privileges
The root user is not guaranteed to be named 'root'
2022-02-19 04:01:13 +02:00
T. Nowah f5653e2ed9 updated AllowedIPs to fix iptables errors 2022-02-19 03:32:12 +02:00
Doug 448502d767 Added powershell variant link 2022-02-19 03:23:58 +02:00
FingerlessGloves d65feb7def Update OPNsense script Scope to include DIP
Update OPNsense script now supports DIP (Dedicated IPs), so this commit is simply to advertise that fact.
2021-12-28 06:05:34 +02:00
g00n1x b89d7e0382 use www.privateinternetaccess.com instead of privateinternetaccess.com 2021-10-11 14:41:34 +03:00
Valery Kalesnik b04be889f0 Address some shellcheck reported issues 2021-09-12 20:19:21 +03:00
gunix 6d06b31af1 fix typo on readme 2021-09-12 14:29:32 +03:00
gunix b8f4116b2d add PowerShell scripts to README in the 3rd party section 2021-09-12 14:28:46 +03:00
John Parton 1e44d65aab Replace #!/bin/bash shebang with #!/usr/bin/env bash 2021-09-12 14:21:00 +03:00
g00n1x e7d4806a9e use the new v6 serverlist 2021-08-02 16:56:41 +03:00
goonix 1898303f44
add NetworkManager-GUI-Support to the 3rd party section of the readme 2021-06-30 22:15:13 +03:00
Derek Battams 24deb12c74
Add link to piawgcli project (#115) 2021-05-18 16:52:07 +03:00
Michael Moon 804b71f01e
Append triffid/pia-wg to 3rd party repository table (#111)
* Append triffid/pia-wg to 3rd party repository table
2021-04-20 23:14:31 +03:00
Derek Battams 912d606c50
Update my 3rd party repo (#104)
Since pfSense now supports WireGuard directly, Slugger has pivoted his efforts to a pfSense specific solution for PIA + WireGuard.
2021-03-27 13:26:55 +02:00
janranz dd381a35d5 Update README.md to adjust headers / typos
Minor adjustments to capitalization (for consistency), as well as adjusted spelling.
2021-02-21 02:55:50 +02:00
faireOwl 2e29ad2d8d Added notification about PF requirements
Added notification about requirements of PF to maintain an active script, and the refresh time to be expected.
2021-01-26 23:34:42 +02:00
faireOwl b8cb2c3684 Normalize spacing
Added a few \n to echos for invalid input notifications, normalizing spacing.
2021-01-26 21:40:20 +02:00
gunix 42db36b7c1 adding faireOwl to the readme as github somehow didn't show him as contributor though he worked a lot on this repo 2021-01-22 02:06:59 +02:00
gunix 742a492eee Region Selection and Other Improvements
- separated get_region and get_token into two separate scripts, allowing for independent calls to each if desired; this also allows the implementation of other features mentioned below
- implemented use of new centralized authentication server for easier automation; the new API is  located at https://privateinternetaccess.com/gtoken/generateToken
- added server selection capabilities to run_setup.sh, as requested by multiple users
- added one-line call capabilities to run_setup.sh to allow easy automation
- changed PIA_AUTOCONNECT to VPN_PROTOCOL for clarity
- added AUTOCONNECT for one-line calls
- added PREFERRED_REGION for one-line calls
- added colored output to highlight important details
- added input validation for prompts in run_setup.sh
2021-01-22 01:12:23 +02:00
Derek Battams d2d24808b5 Add 3rd party repo: piawgmgr 2020-12-14 20:24:00 +02:00
Zachary Murray b355c4c665 Fix unescaped quotes in manual debug curl command 2020-11-24 03:21:44 +02:00
13 changed files with 1324 additions and 580 deletions

View File

@ -1,11 +1,11 @@
# Manual PIA VPN Connections
This repository contains documentation on how to create native WireGuard and OpenVPN connections to our __NextGen network__, and also on how to enable Port Forwarding in case you require this feature. You will find a lot of information below. However if you prefer quick test, here is the __TL/DR__:
This repository contains documentation on how to create native WireGuard and OpenVPN connections, and also on how to enable Port Forwarding in case you require this feature. You will find a lot of information below. However if you prefer quick test, here is the __TL/DR__:
```
git clone https://github.com/pia-foss/manual-connections.git
cd manual-connections
./run_setup.sh
sudo ./run_setup.sh
```
The scripts were written so that they are easy to read and to modify. The code also has a lot of comments, so that you find all the information you might need. We hope you will enjoy forking the repo and customizing the scripts for your setup!
@ -19,6 +19,7 @@ The scripts were written so that they are easy to read and to modify. The code a
- [PIA Port Forwarding](#pia-port-forwarding)
- [Automated setup](#automated-setup)
- [Manual PF testing](#manual-pf-testing)
- [Thanks](#thanks)
- [License](#license)
## Dependencies
@ -26,7 +27,7 @@ The scripts were written so that they are easy to read and to modify. The code a
In order for the scripts to work (probably even if you do a manual setup), you will need the following packages:
* `curl`
* `jq`
* (only for WireGuard) `wg-quick` and `wireguard` kernel module
* (only for WireGuard) `wireguard-tools` (`wg-quick` and `wireguard` kernel module)
* (only for OpenVPN) `openvpn`
## Disclaimers
@ -37,7 +38,7 @@ In order for the scripts to work (probably even if you do a manual setup), you w
* This repo is really fresh at this moment, so please take into consideration the fact that you will probably be one of the first users that use the scripts.
* Though we support research of open source technologies, we can not provide official support for all FOSS platforms, as there are simply too many platforms (which is a good thing). That is why we link 3rd Party repos in this README. We can not guarantee the quality of the code in the 3rd Party Repos, so use them only if you understand the risks.
## Confirmed distributions
## Confirmed Distributions
The functionality of the scripts within this repository has been tested and confirmed on the following operating systems and GNU/Linux distributions:
* Arch
@ -56,12 +57,20 @@ Some users have created their own repositories for manual connections, based on
| System | Fork | Language | Scope | Repository |
|:-:|:-:|:-:|:-:|-|
| FreeBSD | Yes | Bash | Compatibility | [glorious1/manual-connections](https://github.com/glorious1/manual-connections) |
| OPNsense | No | Python | WireGuard, PF | [FingerlessGlov3s/OPNsensePIAWireguard](https://github.com/FingerlessGlov3s/OPNsensePIAWireguard) |
| Linux | No | Bash | NetworkManager <br> GUI integration | [ThePowerTool/PIA-NetworkManager-GUI-Support](https://github.com/ThePowerTool/PIA-NetworkManager-GUI-Support) |
| Linux | No | Python | WireGuard, PF | [milahu/python-piavpn](https://github.com/milahu/python-piavpn) |
| Linux | No | Bash | WireGuard, PF,<br/>router and android config | [triffid/pia-wg](https://github.com/triffid/pia-wg) |
| Linux | No | Go | WireGuard via systemd-networkd, PF | [jdelkins/pia-tools](https://github.com/jdelkins/pia-tools) |
| Linux/FreeBSD/Win | No | Go | WireGuard,<br />config generation | [ddb_db/piawgcli](https://gitlab.com/ddb_db/piawgcli) |
| OPNsense | No | Python | WireGuard, PF, DIP | [FingerlessGlov3s/OPNsensePIAWireguard](https://github.com/FingerlessGlov3s/OPNsensePIAWireguard) |
| pfSense | No | Sh | OpenVPN, PF | [fm407/PIA-NextGen-PortForwarding](https://github.com/fm407/PIA-NextGen-PortForwarding) |
| pfSense | No | Java/PHP | WireGuard, PF | [ddb_db/pfpiamgr](https://gitlab.com/ddb_db/pfpiamgr) |
| Synology | Yes | Bash | Compatibility | [steff2632/manual-connections](https://github.com/steff2632/manual-connections) |
| Synology | No | Python | PF | [stmty9/synology](https://github.com/stmty9/synology) |
| TrueNAS | No | Bash | PF | [dak180/TrueNAS-Scripts](https://github.com/dak180/TrueNAS-Scripts/blob/master/pia-port-forward.sh) |
| UFW | Yes | Bash | Firewall Rules | [iPherian/manual-connections](https://github.com/iPherian/manual-connections) |
| Windows | No | PowerShell | Windows comptaibility | [ImjuzCY/pia-posh](https://github.com/ImjuzCY/pia-posh) |
| Windows | No | Powershell | OpenVPN, PF | [dougbenham/PIA-OpenVPN-Script](https://github.com/dougbenham/PIA-OpenVPN-Script) |
## PIA Port Forwarding
@ -69,17 +78,37 @@ The PIA Port Forwarding service (a.k.a. PF) allows you run services on your own
This service can be used only AFTER establishing a VPN connection.
## Automated setup
## Automated Setup
In order to help you use VPN services and PF on any device, we have prepared 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. The functionality is controlled via environment variables, so that you have an easy time automating your setup.
The easiest way to trigger a fully automated connection is by running this oneliner:
```
sudo VPN_PROTOCOL=wireguard DISABLE_IPV6=yes DIP_TOKEN=no AUTOCONNECT=true PIA_PF=false PIA_DNS=true PIA_USER=p0123456 PIA_PASS=xxxxxxxx ./run_setup.sh
```
Here is a list of scripts you could find useful:
* [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. Adding your PIA credentials to env vars `PIA_USER` and `PIA_PASS` 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 `PIA_AUTOCONNECT=wireguard` or `PIA_AUTOCONNECT=openvpn_udp_standard`
* [Connect to WireGuard](connect_to_wireguard_with_token.sh): This script allows you to connect to the VPN server via WireGuard.
* [Prompt based connection](run_setup.sh): This script allows connections with a one-line call, or will prompt for any missing or invalid variables. Variables available for one-line calls include:
* `PIA_USER` - your PIA username
* `PIA_PASS` - your PIA password
* `DIP_TOKEN` - your PIA dedicated IP token (can be purchased in the client control panel)
* `PIA_DNS` - true/false
* `PIA_PF` - true/false
* `PIA_CONNECT` - true/false; connect to VPN after configuration has been created. Set to false to only create configuration file. Only effective for wireguard protocol. Default true.
* `PIA_CONF_PATH` - path of wireguard config file to be written. Used when only creating config file for wireguard.
* `MAX_LATENCY` - numeric value, in seconds
* `AUTOCONNECT` - true/false; this will test for and select the server with the lowest latency, it will override PREFERRED_REGION
* `PREFERRED_REGION` - the region ID for a PIA server
* `VPN_PROTOCOL` - wireguard or openvpn; openvpn will default to openvpn_udp_standard, but can also specify openvpn_tcp/udp_standad/strong
* `DISABLE_IPV6` - yes/no
* [Get region details](get_region.sh): This script will provide server details, validate `PREFERRED_REGION` input, and can determine the lowest latency location. The script can also trigger VPN connections, if you specify `VPN_PROTOCOL=wireguard` or `VPN_PROTOCOL=openvpn`; doing so requires a token. This script can reference `get_token.sh` with use of `PIA_USER` and `PIA_PASS`. If called without specifying `PREFERRED_REGION` this script writes a list of servers within lower than `MAX_LATENCY` to a `/opt/piavpn-manual/latencyList` for reference.
* [Get a token](get_token.sh): This script allows you to get an authentication token with a valid 'PIA_USER' and 'PIA_PASS'. It will write the token and its expiration date to `/opt/piavpn-manual/token` for reference.
* [Get DIP details](get_dip.sh): This script will provide necessary connection details to use a dedicated IP.
* [Connect to WireGuard](connect_to_wireguard_with_token.sh): This script allows you to connect to the VPN server via WireGuard, or create a WireGuard config file by setting environment variable `PIA_CONNECT=false`.
* [Connect to OpenVPN](connect_to_openvpn_with_token.sh): This script allows you to connect to the VPN server via OpenVPN.
* [Enable Port Forwarding](port_forwarding.sh): Enables you to add Port Forwarding to an existing VPN connection. Adding the environment variable `PIA_PF=true` to any of the previous scripts will also trigger this script.
## Manual PF tesing
## Manual PF Testing
To use port forwarding on the NextGen network, first of all establish a connection with your favorite protocol. After this, you will need to find the private IP of the gateway you are connected to. In case you are WireGuard, the gateway will be part of the JSON response you get from the server, as you can see in the [bash script](https://github.com/pia-foss/manual-connections/blob/master/wireguard_and_pf.sh#L119). In case you are using OpenVPN, you can find the gateway by checking the routing table with `ip route s t all`.
@ -97,7 +126,7 @@ bash-5.0# curl -k "https://10.4.128.1:19999/getSignature?token=$TOKEN"
The payload can be decoded with base64 to see your information:
```bash
$ echo eyJ0b2tlbiI6Inh4eHh4eHh4eCIsInBvcnQiOjQ3MDQ3LCJjcmVhdGVkX2F0IjoiMjAyMC0wNC0zMFQyMjozMzo0NC4xMTQzNjk5MDZaIn0= | base64 -d | jq
$ echo eyJ0b2tlbiI6Inh4eHh4eHh4eCIsInBvcnQiOjQ3MDQ3LCJjcmVhdGVkX2F0IjoiMjAyMC0wNC0zMFQyMjozMzo0NC4xMTQzNjk5MDZaIn0= | base64 -d | jq
{
"token": "xxxxxxxxx",
"port": 47047,
@ -113,12 +142,12 @@ bash-5.0# curl -sGk --data-urlencode "payload=${payload}" --data-urlencode "sign
"status": "OK",
"message": "port scheduled for add"
}
bash-5.0#
bash-5.0#
```
Call __/bindPort__ every 15 minutes, or the port will be deleted!
### Testing your new PF
### Testing Your New PF
To test that it works, you can tcpdump on the port you received:
@ -142,5 +171,9 @@ listening on any, link-type LINUX_SLL (Linux cooked v1), capture size 262144 byt
If you run curl on the same machine (the one that is connected to the VPN), you will see the traffic in tcpdump anyway and the test won't prove anything. At the same time, the request will get firewall so you will not be able to access the port from the same machine. This can only be tested properly by running curl on another system.
## Thanks
A big special thanks to [faireOwl](https://github.com/faireOwl) for his contributions to this repo.
## License
This project is licensed under the [MIT (Expat) license](https://choosealicense.com/licenses/mit/), which can be found [here](/LICENSE).

View File

@ -1,4 +1,4 @@
#!/bin/bash
#!/usr/bin/env bash
# Copyright (C) 2020 Private Internet Access, Inc.
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
@ -20,47 +20,68 @@
# SOFTWARE.
# This function allows you to check if the required tools have been installed.
function check_tool() {
check_tool() {
cmd=$1
if ! command -v $cmd &>/dev/null
then
if ! command -v "$cmd" >/dev/null; then
echo "$cmd could not be found"
echo "Please install $cmd"
exit 1
fi
}
# Now we call the function to make sure we can use wg-quick, curl and jq.
# Now we call the function to make sure we can use openvpn, curl and jq.
check_tool openvpn
check_tool curl
check_tool jq
check_tool openvpn
# Check if terminal allows output, if yes, define colors for output
if [[ -t 1 ]]; then
ncolors=$(tput colors)
if [[ -n $ncolors && $ncolors -ge 8 ]]; then
red=$(tput setaf 1) # ANSI red
green=$(tput setaf 2) # ANSI green
nc=$(tput sgr0) # No Color
else
red=''
green=''
nc='' # No Color
fi
fi
# Check if manual PIA OpenVPN connection is already initialized.
# Multi-hop is out of the scope of this repo, but you should be able to
# get multi-hop running with both OpenVPN and WireGuard.
adapter_check="$( ip a s tun06 2>&1 )"
adapter_check=$( ip a s tun06 2>&1 )
should_read="Device \"tun06\" does not exist"
pid_filepath="/opt/piavpn-manual/pia_pid"
if [[ "$adapter_check" != *"$should_read"* ]]; then
echo The tun06 adapter already exists, that interface is required
echo for this configuration.
if [ -f "$pid_filepath" ]; then
old_pid="$( cat "$pid_filepath" )"
old_pid_name="$( ps -p "$old_pid" -o comm= )"
if [[ $old_pid_name == 'openvpn' ]]; then
if [[ $adapter_check != *"$should_read"* ]]; then
echo -e "${red}The tun06 adapter already exists, that interface is required"
echo -e "for this configuration.${nc}"
if [[ -f $pid_filepath ]]; then
old_pid=$( cat "$pid_filepath" )
old_pid_name=$( ps -p "$old_pid" -o comm= )
if [[ $old_pid_name == "openvpn" ]]; then
echo
echo It seems likely that process $old_pid is an OpenVPN connection
echo that was established by using this script. Unless it is closed
echo you would not be able to get a new connection.
echo -n "Do you want to run $ kill $old_pid (Y/n): "
read close_connection
echo -e "It seems likely that process ${red}$old_pid${nc} is an OpenVPN connection"
echo "that was established by using this script. Unless it is closed"
echo "you would not be able to get a new connection."
echo -ne "Do you want to run ${red}$ kill $old_pid${nc} (Y/n): "
read -r close_connection
fi
if echo ${close_connection:0:1} | grep -iq n ; then
echo Closing script. Resolve tun06 adapter conflict and run the script again.
if echo "${close_connection:0:1}" | grep -iq n; then
echo -e "${red}Closing script. Resolve tun06 adapter conflict and run the script again."
exit 1
fi
echo Killing the existing OpenVPN process and waiting 5 seconds...
kill $old_pid
sleep 5
echo
echo -e "${green}Killing the existing OpenVPN process and waiting 5 seconds...${nc}"
kill "$old_pid"
echo
for i in {5..1}; do
echo -n "$i..."
sleep 1
done
echo
echo
fi
fi
@ -72,53 +93,62 @@ if [[ -f /proc/net/if_inet6 ]] &&
[[ $(sysctl -n net.ipv6.conf.all.disable_ipv6) -ne 1 ||
$(sysctl -n net.ipv6.conf.default.disable_ipv6) -ne 1 ]]
then
echo 'You should consider disabling IPv6 by running:'
echo 'sysctl -w net.ipv6.conf.all.disable_ipv6=1'
echo 'sysctl -w net.ipv6.conf.default.disable_ipv6=1'
echo -e "${red}You should consider disabling IPv6 by running:"
echo "sysctl -w net.ipv6.conf.all.disable_ipv6=1"
echo -e "sysctl -w net.ipv6.conf.default.disable_ipv6=1${nc}"
fi
# Check if the mandatory environment variables are set.
if [[ ! $OVPN_SERVER_IP ||
! $OVPN_HOSTNAME ||
! $PIA_TOKEN ||
! $CONNECTION_SETTINGS ]]; then
echo 'This script requires 4 env vars:'
echo 'PIA_TOKEN - the token used for authentication'
echo 'OVPN_SERVER_IP - IP that you want to connect to'
echo 'OVPN_HOSTNAME - name of the server, required for ssl'
echo 'CONNECTION_SETTINGS - the protocol and encryption specification'
echo ' - available options for CONNECTION_SETTINGS are:'
echo ' * openvpn_udp_standard'
echo ' * openvpn_udp_strong'
echo ' * openvpn_tcp_standard'
echo ' * openvpn_tcp_strong'
# Check if the mandatory environment variables are set.
if [[ -z $OVPN_SERVER_IP ||
-z $OVPN_HOSTNAME ||
-z $PIA_TOKEN ||
-z $CONNECTION_SETTINGS ]]; then
echo -e "${red}This script requires 4 env vars:"
echo "PIA_TOKEN - the token used for authentication"
echo "OVPN_SERVER_IP - IP that you want to connect to"
echo "OVPN_HOSTNAME - name of the server, required for ssl"
echo "CONNECTION_SETTINGS - the protocol and encryption specification"
echo " - available options for CONNECTION_SETTINGS are:"
echo " * openvpn_udp_standard"
echo " * openvpn_udp_strong"
echo " * openvpn_tcp_standard"
echo " * openvpn_tcp_strong"
echo
echo You can also specify optional env vars:
echo "You can also specify optional env vars:"
echo "PIA_PF - enable port forwarding"
echo "PAYLOAD_AND_SIGNATURE - In case you already have a port."
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
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 -e "https://github.com/pia-foss/manual-connections${nc}"
exit 1
fi
splitToken="dedicated_ip_$DIP_TOKEN"
# Create a credentials file with the login token
echo "Trying to write /opt/piavpn-manual/pia.ovpn...
"
echo -n "Trying to write /opt/piavpn-manual/pia.ovpn..."
mkdir -p /opt/piavpn-manual
rm -f /opt/piavpn-manual/credentials /opt/piavpn-manual/route_info
echo ${PIA_TOKEN:0:62}"
"${PIA_TOKEN:62} > /opt/piavpn-manual/credentials || exit 1
chmod 600 /opt/piavpn-manual/credentials
if [[ -z $DIP_TOKEN ]]; then
echo "${PIA_TOKEN:0:62}
${PIA_TOKEN:62}" > /opt/piavpn-manual/credentials || exit 1
chmod 600 /opt/piavpn-manual/credentials
else
echo "${splitToken:0:62}
${splitToken:62}" > /opt/piavpn-manual/credentials || exit 1
chmod 600 /opt/piavpn-manual/credentials
fi
echo -e "${green}OK!${nc}"
# Translate connection settings variable
IFS='_'
read -ra connection_settings <<< "$CONNECTION_SETTINGS"
IFS=' '
protocol="${connection_settings[1]}"
encryption="${connection_settings[2]}"
protocol=${connection_settings[1]}
encryption=${connection_settings[2]}
prefix_filepath="openvpn_config/standard.ovpn"
if [[ $encryption == "strong" ]]; then
@ -140,19 +170,19 @@ else
fi
# Create the OpenVPN config based on the settings specified
cat $prefix_filepath > /opt/piavpn-manual/pia.ovpn || exit 1
echo remote $OVPN_SERVER_IP $port $protocol >> /opt/piavpn-manual/pia.ovpn
cat "$prefix_filepath" > /opt/piavpn-manual/pia.ovpn || exit 1
echo "remote $OVPN_SERVER_IP $port $protocol" >> /opt/piavpn-manual/pia.ovpn
# Copy the up/down scripts to /opt/piavpn-manual/
# based upon use of PIA DNS
if [ "$PIA_DNS" != true ]; then
if [[ $PIA_DNS != "true" ]]; then
cp openvpn_config/openvpn_up.sh /opt/piavpn-manual/
cp openvpn_config/openvpn_down.sh /opt/piavpn-manual/
echo This configuration will not use PIA DNS.
echo If you want to also enable PIA DNS, please start the script
echo with the env var PIA_DNS=true. Example:
echo $ OVPN_SERVER_IP=\"$OVPN_SERVER_IP\" OVPN_HOSTNAME=\"$OVPN_HOSTNAME\" \
PIA_TOKEN=\"$PIA_TOKEN\" CONNECTION_SETTINGS=\"$CONNECTION_SETTINGS\" \
echo -e "${red}This configuration will not use PIA DNS.${nc}"
echo "If you want to also enable PIA DNS, please start the script"
echo "with the env var PIA_DNS=true. Example:"
echo $ OVPN_SERVER_IP=\""$OVPN_SERVER_IP"\" OVPN_HOSTNAME=\""$OVPN_HOSTNAME"\" \
PIA_TOKEN=\""$PIA_TOKEN"\" CONNECTION_SETTINGS=\""$CONNECTION_SETTINGS"\" \
PIA_PF=true PIA_DNS=true ./connect_to_openvpn_with_token.sh
else
cp openvpn_config/openvpn_up_dnsoverwrite.sh /opt/piavpn-manual/openvpn_up.sh
@ -171,17 +201,16 @@ openvpn --daemon \
--writepid "/opt/piavpn-manual/pia_pid" \
--log "/opt/piavpn-manual/debug_info" || exit 1
echo "
echo -n "
The OpenVPN connect command was issued.
Confirming OpenVPN connection state... "
Confirming OpenVPN connection state..."
# Check if manual PIA OpenVPN connection is initialized.
# Manually adjust the connection_wait_time if needed
connection_wait_time=10
confirmation="Initialization Sequence Complete"
for (( timeout=0; timeout <=$connection_wait_time; timeout++ ))
do
for (( timeout=0; timeout <= connection_wait_time; timeout++ )); do
sleep 1
if grep -q "$confirmation" /opt/piavpn-manual/debug_info; then
connected=true
@ -189,50 +218,59 @@ do
fi
done
ovpn_pid="$( cat /opt/piavpn-manual/pia_pid )"
gateway_ip="$( cat /opt/piavpn-manual/route_info )"
ovpn_pid=$( cat /opt/piavpn-manual/pia_pid )
gateway_ip=$( cat /opt/piavpn-manual/route_info )
# Report and exit if connection was not initialized within 10 seconds.
if [ "$connected" != true ]; then
echo "The VPN connection was not established within 10 seconds."
kill $ovpn_pid
if [[ $connected != "true" ]]; then
echo -e "${red}The VPN connection was not established within 10 seconds.${nc}"
kill "$ovpn_pid"
exit 1
fi
echo "Initialization Sequence Complete!
echo -e "${green}Initialization Sequence Complete!${nc}
At this point, internet should work via VPN.
"
echo "OpenVPN Process ID: $ovpn_pid
VPN route IP: $gateway_ip
echo -e "OpenVPN Process ID: ${green}$ovpn_pid${nc}
VPN route IP: ${green}$gateway_ip${nc}
To disconnect the VPN, run:
--> sudo kill $ovpn_pid <--
--> ${green}sudo kill $ovpn_pid${nc} <--
"
# This section will stop the script if PIA_PF is not set to "true".
if [ "$PIA_PF" != true ]; then
if [[ $PIA_PF != "true" ]]; then
echo "If you want to also enable port forwarding, you can start the script:"
echo -e "$ ${green}PIA_TOKEN=$PIA_TOKEN" \
"PF_GATEWAY=$gateway_ip" \
"PF_HOSTNAME=$OVPN_HOSTNAME" \
"./port_forwarding.sh${nc}"
echo
echo If you want to also enable port forwarding, please start the script
echo with the env var PIA_PF=true. Example:
echo $ OVPN_SERVER_IP=\"$OVPN_SERVER_IP\" OVPN_HOSTNAME=\"$OVPN_HOSTNAME\" \
PIA_TOKEN=\"$PIA_TOKEN\" CONNECTION_SETTINGS=\"$CONNECTION_SETTINGS\" \
PIA_PF=true ./connect_to_openvpn_with_token.sh
exit
echo "The location used must be port forwarding enabled, or this will fail."
echo "Calling the ./get_region script with PIA_PF=true will provide a filtered list."
exit 1
fi
echo "
This script got started with PIA_PF=true.
Starting procedure to enable port forwarding by running the following command:
$ PIA_TOKEN=\"$PIA_TOKEN\" \\
PF_GATEWAY=\"$gateway_ip\" \\
PF_HOSTNAME=\"$OVPN_HOSTNAME\" \\
./port_forwarding.sh
"
echo -ne "This script got started with ${green}PIA_PF=true${nc}.
Starting port forwarding in "
for i in {5..1}; do
echo -n "$i..."
sleep 1
done
echo
echo
echo -e "Starting procedure to enable port forwarding by running the following command:
$ ${green}PIA_TOKEN=$PIA_TOKEN \\
PF_GATEWAY=$gateway_ip \\
PF_HOSTNAME=$OVPN_HOSTNAME \\
./port_forwarding.sh${nc}"
PIA_TOKEN=$PIA_TOKEN \
PF_GATEWAY="$gateway_ip" \
PF_HOSTNAME="$OVPN_HOSTNAME" \
PF_GATEWAY=$gateway_ip \
PF_HOSTNAME=$OVPN_HOSTNAME \
./port_forwarding.sh

View File

@ -1,4 +1,4 @@
#!/bin/bash
#!/usr/bin/env bash
# Copyright (C) 2020 Private Internet Access, Inc.
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
@ -20,21 +20,40 @@
# SOFTWARE.
# This function allows you to check if the required tools have been installed.
function check_tool() {
check_tool() {
cmd=$1
package=$2
if ! command -v $cmd &>/dev/null
then
pkg=$2
if ! command -v "$cmd" >/dev/null; then
echo "$cmd could not be found"
echo "Please install $package"
echo "Please install $pkg"
exit 1
fi
}
# Now we call the function to make sure we can use wg-quick, curl and jq.
check_tool wg-quick wireguard-tools
check_tool curl curl
check_tool jq jq
# Check if terminal allows output, if yes, define colors for output
if [[ -t 1 ]]; then
ncolors=$(tput colors)
if [[ -n $ncolors && $ncolors -ge 8 ]]; then
red=$(tput setaf 1) # ANSI red
green=$(tput setaf 2) # ANSI green
nc=$(tput sgr0) # No Color
else
red=''
green=''
nc='' # No Color
fi
fi
: "${PIA_CONNECT=true}"
DEFAULT_PIA_CONF_PATH=/etc/wireguard/pia.conf
: "${PIA_CONF_PATH:=$DEFAULT_PIA_CONF_PATH}"
# PIA currently does not support IPv6. In order to be sure your VPN
# connection does not leak, it is best to disabled IPv6 altogether.
# IPv6 can also be disabled via kernel commandline param, so we must
@ -43,33 +62,35 @@ if [[ -f /proc/net/if_inet6 ]] &&
[[ $(sysctl -n net.ipv6.conf.all.disable_ipv6) -ne 1 ||
$(sysctl -n net.ipv6.conf.default.disable_ipv6) -ne 1 ]]
then
echo 'You should consider disabling IPv6 by running:'
echo 'sysctl -w net.ipv6.conf.all.disable_ipv6=1'
echo 'sysctl -w net.ipv6.conf.default.disable_ipv6=1'
echo -e "${red}You should consider disabling IPv6 by running:"
echo "sysctl -w net.ipv6.conf.all.disable_ipv6=1"
echo -e "sysctl -w net.ipv6.conf.default.disable_ipv6=1${nc}"
fi
# Check if the mandatory environment variables are set.
if [[ ! $WG_SERVER_IP || ! $WG_HOSTNAME || ! $PIA_TOKEN ]]; then
echo This script requires 3 env vars:
echo WG_SERVER_IP - IP that you want to connect to
echo WG_HOSTNAME - name of the server, required for ssl
echo PIA_TOKEN - your authentication token
if [[ -z $WG_SERVER_IP ||
-z $WG_HOSTNAME ||
-z $PIA_TOKEN ]]; then
echo -e "${red}This script requires 3 env vars:"
echo "WG_SERVER_IP - IP that you want to connect to"
echo "WG_HOSTNAME - name of the server, required for ssl"
echo "PIA_TOKEN - your authentication token"
echo
echo You can also specify optional env vars:
echo "You can also specify optional env vars:"
echo "PIA_PF - enable port forwarding"
echo "PAYLOAD_AND_SIGNATURE - In case you already have a port."
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
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 -e "https://github.com/pia-foss/manual-connections${nc}"
exit 1
fi
# Create ephemeral wireguard keys, that we don't need to save to disk.
privKey="$(wg genkey)"
privKey=$(wg genkey)
export privKey
pubKey="$( echo "$privKey" | wg pubkey)"
pubKey=$( echo "$privKey" | wg pubkey)
export pubKey
# Authenticate via the PIA WireGuard RESTful API.
@ -78,29 +99,41 @@ export pubKey
# In case you didn't clone the entire repo, get the certificate from:
# https://github.com/pia-foss/manual-connections/blob/master/ca.rsa.4096.crt
# In case you want to troubleshoot the script, replace -s with -v.
echo Trying to connect to the PIA WireGuard API on $WG_SERVER_IP...
wireguard_json="$(curl -s -G \
--connect-to "$WG_HOSTNAME::$WG_SERVER_IP:" \
--cacert "ca.rsa.4096.crt" \
--data-urlencode "pt=${PIA_TOKEN}" \
--data-urlencode "pubkey=$pubKey" \
"https://${WG_HOSTNAME}:1337/addKey" )"
echo "Trying to connect to the PIA WireGuard API on $WG_SERVER_IP..."
if [[ -z $DIP_TOKEN ]]; then
wireguard_json="$(curl -s -G \
--connect-to "$WG_HOSTNAME::$WG_SERVER_IP:" \
--cacert "ca.rsa.4096.crt" \
--data-urlencode "pt=${PIA_TOKEN}" \
--data-urlencode "pubkey=$pubKey" \
"https://${WG_HOSTNAME}:1337/addKey" )"
else
wireguard_json="$(curl -s -G \
--connect-to "$WG_HOSTNAME::$WG_SERVER_IP:" \
--cacert "ca.rsa.4096.crt" \
--user "dedicated_ip_$DIP_TOKEN:$WG_SERVER_IP" \
--data-urlencode "pubkey=$pubKey" \
"https://$WG_HOSTNAME:1337/addKey" )"
fi
export wireguard_json
echo "$wireguard_json"
# Check if the API returned OK and stop this script if it didn't.
if [ "$(echo "$wireguard_json" | jq -r '.status')" != "OK" ]; then
>&2 echo "Server did not return OK. Stopping now."
if [[ $(echo "$wireguard_json" | jq -r '.status') != "OK" ]]; then
>&2 echo -e "${red}Server did not return OK. Stopping now.${nc}"
exit 1
fi
# Multi-hop is out of the scope of this repo, but you should be able to
# get multi-hop running with both WireGuard and OpenVPN by playing with
# these scripts. Feel free to fork the project and test it out.
echo
echo Trying to disable a PIA WG connection in case it exists...
wg-quick down pia && echo Disconnected!
echo
if [[ $PIA_CONNECT == "true" ]]; then
# Ensure config file path is set to default used for WG connection
PIA_CONF_PATH=$DEFAULT_PIA_CONF_PATH
# Multi-hop is out of the scope of this repo, but you should be able to
# get multi-hop running with both WireGuard and OpenVPN by playing with
# these scripts. Feel free to fork the project and test it out.
echo
echo "Trying to disable a PIA WG connection in case it exists..."
wg-quick down pia && echo -e "${green}\nPIA WG connection disabled!${nc}"
echo
fi
# Create the WireGuard config based on the JSON received from the API
# In case you want this section to also add the DNS setting, please
@ -108,15 +141,16 @@ echo
# This uses a PersistentKeepalive of 25 seconds to keep the NAT active
# on firewalls. You can remove that line if your network does not
# require it.
echo -n "Trying to write /etc/wireguard/pia.conf... "
mkdir -p /etc/wireguard
if [ "$PIA_DNS" == true ]; then
dnsServer="$(echo "$wireguard_json" | jq -r '.dns_servers[0]')"
echo Trying to set up DNS to $dnsServer. In case you do not have resolvconf,
echo this operation will fail and you will not get a VPN. If you have issues,
echo start this script without PIA_DNS.
if [[ $PIA_DNS == "true" ]]; then
dnsServer=$(echo "$wireguard_json" | jq -r '.dns_servers[0]')
echo "Trying to set up DNS to $dnsServer. In case you do not have resolvconf,"
echo "this operation will fail and you will not get a VPN. If you have issues,"
echo "start this script without PIA_DNS."
echo
dnsSettingForVPN="DNS = $dnsServer"
fi
echo -n "Trying to write ${PIA_CONF_PATH}..."
mkdir -p "$(dirname "$PIA_CONF_PATH")"
echo "
[Interface]
Address = $(echo "$wireguard_json" | jq -r '.peer_ip')
@ -127,51 +161,59 @@ PersistentKeepalive = 25
PublicKey = $(echo "$wireguard_json" | jq -r '.server_key')
AllowedIPs = 0.0.0.0/0
Endpoint = ${WG_SERVER_IP}:$(echo "$wireguard_json" | jq -r '.server_port')
" > /etc/wireguard/pia.conf || exit 1
echo OK!
" > ${PIA_CONF_PATH} || exit 1
echo -e "${green}OK!${nc}"
# Start the WireGuard interface.
# If something failed, stop this script.
# If you get DNS errors because you miss some packages,
# just hardcode /etc/resolv.conf to "nameserver 10.0.0.242".
echo
echo Trying to create the wireguard interface...
wg-quick up pia || exit 1
echo "The WireGuard interface got created.
At this point, internet should work via VPN.
--> to disconnect the VPN, run:
$ wg-quick down pia"
# This section will stop the script if PIA_PF is not set to "true".
if [ "$PIA_PF" != true ]; then
if [[ $PIA_CONNECT == "true" ]]; then
# Start the WireGuard interface.
# If something failed, stop this script.
# If you get DNS errors because you miss some packages,
# just hardcode /etc/resolv.conf to "nameserver 10.0.0.242".
echo
echo If you want to also enable port forwarding, please start the script
echo with the env var PIA_PF=true. Example:
echo $ WG_SERVER_IP=10.0.0.3 WG_HOSTNAME=piaserver401 \
PIA_TOKEN=\"\$token\" PIA_PF=true \
./connect_to_wireguard_with_token.sh
exit
echo "Trying to create the wireguard interface..."
wg-quick up pia || exit 1
echo
echo -e "${green}The WireGuard interface got created.${nc}
At this point, internet should work via VPN.
To disconnect the VPN, run:
--> ${green}wg-quick down pia${nc} <--
"
# This section will stop the script if PIA_PF is not set to "true".
if [[ $PIA_PF != "true" ]]; then
echo "If you want to also enable port forwarding, you can start the script:"
echo -e "$ ${green}PIA_TOKEN=$PIA_TOKEN" \
"PF_GATEWAY=$WG_SERVER_IP" \
"PF_HOSTNAME=$WG_HOSTNAME" \
"./port_forwarding.sh${nc}"
echo
echo "The location used must be port forwarding enabled, or this will fail."
echo "Calling the ./get_region script with PIA_PF=true will provide a filtered list."
exit 1
fi
echo -ne "This script got started with ${green}PIA_PF=true${nc}.
Starting port forwarding in "
for i in {5..1}; do
echo -n "$i..."
sleep 1
done
echo
echo
echo -e "Starting procedure to enable port forwarding by running the following command:
$ ${green}PIA_TOKEN=$PIA_TOKEN \\
PF_GATEWAY=$WG_SERVER_IP \\
PF_HOSTNAME=$WG_HOSTNAME \\
./port_forwarding.sh${nc}"
PIA_TOKEN=$PIA_TOKEN \
PF_GATEWAY=$WG_SERVER_IP \
PF_HOSTNAME=$WG_HOSTNAME \
./port_forwarding.sh
fi
echo -n "
This script got started with PIA_PF=true. We will allow WireGuard to fully
initialize and after that we will try to enable PF by running the following
command:
$ PIA_TOKEN=$PIA_TOKEN \\
PF_GATEWAY=\"$(echo "$wireguard_json" | jq -r '.server_vip')\" \\
PF_HOSTNAME=\"$WG_HOSTNAME\" \\
./port_forwarding.sh
Starting PF in "
for i in {5..1}; do
echo -n "$i... "
sleep 1
done
echo
echo
PIA_TOKEN=$PIA_TOKEN \
PF_GATEWAY="$(echo "$wireguard_json" | jq -r '.server_vip')" \
PF_HOSTNAME="$WG_HOSTNAME" \
./port_forwarding.sh

109
get_dip.sh Executable file
View File

@ -0,0 +1,109 @@
#!/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.
# This function allows you to check if the required tools have been installed.
check_tool() {
cmd=$1
if ! command -v $cmd &>/dev/null; then
echo "$cmd could not be found"
echo "Please install $cmd"
exit 1
fi
}
# Now we call the function to make sure we can use curl and jq.
check_tool curl
check_tool jq
# Check if terminal allows output, if yes, define colors for output
if [[ -t 1 ]]; then
ncolors=$(tput colors)
if [[ -n $ncolors && $ncolors -ge 8 ]]; then
red=$(tput setaf 1) # ANSI red
green=$(tput setaf 2) # ANSI green
nc=$(tput sgr0) # No Color
else
red=''
green=''
nc='' # No Color
fi
fi
# Only allow script to run as root
if (( EUID != 0 )); then
echo -e "${red}This script needs to be run as root. Try again with 'sudo $0'${nc}"
exit 1
fi
mkdir -p /opt/piavpn-manual
if [[ -z $PIA_TOKEN ]]; then
echo "If you want this script to automatically retrieve dedicated IP location details"
echo "from the Meta service, please add the variables PIA_TOKEN and DIP_TOKEN. Example:"
echo "$ PIA_TOKEN DIP_TOKEN=DIP1a2b3c4d5e6f7g8h9i10j11k12l13 ./get_token.sh"
exit 1
fi
dipSavedLocation=/opt/piavpn-manual/dipAddress
echo -n "Checking DIP token..."
generateDIPResponse=$(curl -s --location --request POST \
'https://www.privateinternetaccess.com/api/client/v2/dedicated_ip' \
--header 'Content-Type: application/json' \
--header "Authorization: Token $PIA_TOKEN" \
--data-raw '{
"tokens":["'"$DIP_TOKEN"'"]
}')
if [ "$(echo "$generateDIPResponse" | jq -r '.[0].status')" != "active" ]; then
echo
echo
echo -e "${red}Could not validate the dedicated IP token provided!${nc}"
echo
exit
fi
echo -e ${green}OK!${nc}
echo
dipAddress=$(echo "$generateDIPResponse" | jq -r '.[0].ip')
dipHostname=$(echo "$generateDIPResponse" | jq -r '.[0].cn')
keyHostname=$(echo "dedicated_ip_$DIP_TOKEN")
dipExpiration=$(echo "$generateDIPResponse" | jq -r '.[0].dip_expire')
dipExpiration=$(date -d @$dipExpiration)
dipID=$(echo "$generateDIPResponse" | jq -r '.[0].id')
echo -e The hostname of your dedicated IP is ${green}$dipHostname${nc}
echo
echo -e The dedicated IP address is ${green}$dipAddress${nc}
echo
echo This dedicated IP is valid until $dipExpiration.
echo
pfCapable="true"
if [[ $dipID == us_* ]]; then
pfCapable="false"
echo This location does not have port forwarding capability.
echo
fi
echo $dipAddress > /opt/piavpn-manual/dipAddress || exit 1
echo $dipHostname >> /opt/piavpn-manual/dipAddress
echo $keyHostname >> /opt/piavpn-manual/dipAddress
echo $dipExpiration >> /opt/piavpn-manual/dipAddress
echo $pfCapable >> /opt/piavpn-manual/dipAddress

273
get_region.sh Executable file
View File

@ -0,0 +1,273 @@
#!/usr/bin/env 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.
# This function allows you to check if the required tools have been installed.
check_tool() {
cmd=$1
if ! command -v "$cmd" >/dev/null; then
echo "$cmd could not be found"
echo "Please install $cmd"
exit 1
fi
}
# Now we call the function to make sure we can use curl and jq.
check_tool curl
check_tool jq
# If the server list has less than 1000 characters, it means curl failed.
check_all_region_data() {
echo
echo -n "Getting the server list..."
if [[ ${#all_region_data} -lt 1000 ]]; then
echo -e "${red}Could not get correct region data. To debug this, run:"
echo "$ curl -v $serverlist_url"
echo -e "If it works, you will get a huge JSON as a response.${nc}"
exit 1
fi
# Notify the user that we got the server list.
echo -e "${green}OK!${nc}
"
}
# Get all data for the selected region
# Exit with code 1 if the REGION_ID provided is invalid
get_selected_region_data() {
regionData="$( echo "$all_region_data" |
jq --arg REGION_ID "$selectedRegion" -r \
'.regions[] | select(.id==$REGION_ID)')"
if [[ -z $regionData ]]; then
echo -e "${red}The REGION_ID $selectedRegion is not valid.${nc}
"
exit 1
fi
}
# Check if terminal allows output, if yes, define colors for output
if [[ -t 1 ]]; then
ncolors=$(tput colors)
if [[ -n $ncolors && $ncolors -ge 8 ]]; then
red=$(tput setaf 1) # ANSI red
green=$(tput setaf 2) # ANSI green
nc=$(tput sgr0) # No Color
else
red=''
green=''
nc='' # No Color
fi
fi
# Only allow script to run as root
if (( EUID != 0 )); then
echo -e "${red}This script needs to be run as root. Try again with 'sudo $0'${nc}"
exit 1
fi
mkdir -p /opt/piavpn-manual
# Erase old latencyList file
rm -f /opt/piavpn-manual/latencyList
touch /opt/piavpn-manual/latencyList
# This allows you to set the maximum allowed latency in seconds.
# All servers that respond slower than this will be ignored.
# You can inject this with the environment variable MAX_LATENCY.
# The default value is 50 milliseconds.
MAX_LATENCY=${MAX_LATENCY:-0.05}
export MAX_LATENCY
serverlist_url='https://serverlist.piaservers.net/vpninfo/servers/v6'
# This function checks the latency you have to a specific region.
# It will print a human-readable message to stderr,
# and it will print the variables to stdout
printServerLatency() {
serverIP=$1
regionID=$2
regionName="$(echo "${@:3}" |
sed 's/ false//' | sed 's/true/(geo)/')"
time=$(LC_NUMERIC=en_US.utf8 curl -o /dev/null -s \
--connect-timeout "$MAX_LATENCY" \
--write-out "%{time_connect}" \
"http://$serverIP:443")
if [[ $? -eq 0 ]]; then
>&2 echo "Got latency ${time}s for region: $regionName"
echo "$time $regionID $serverIP"
# Write a list of servers with acceptable latency
# to /opt/piavpn-manual/latencyList
echo -e "$time" "$regionID"'\t'"$serverIP"'\t'"$regionName" >> /opt/piavpn-manual/latencyList
fi
# Sort the latencyList, ordered by latency
sort -no /opt/piavpn-manual/latencyList /opt/piavpn-manual/latencyList
}
export -f printServerLatency
# If a server location or autoconnect isn't specified, set the variable to false/no.
if [[ -z $PREFERRED_REGION ]]; then
PREFERRED_REGION=none
fi
if [[ -z $VPN_PROTOCOL ]]; then
VPN_PROTOCOL=no
fi
# Get all region data
all_region_data=$(curl -s "$serverlist_url" | head -1)
# Set the region the user has specified
selectedRegion=$PREFERRED_REGION
# If a server isn't being specified, auto-select the server with the lowest latency
if [[ $selectedRegion == "none" ]]; then
selectedOrLowestLatency="lowest latency"
check_all_region_data
# Making sure this variable doesn't contain some strange string
if [[ $PIA_PF != "true" ]]; then
PIA_PF="false"
fi
# Test one server from each region to get the closest region.
# If port forwarding is enabled, filter out regions that don't support it.
if [[ $PIA_PF == "true" ]]; then
echo "Port Forwarding is enabled, non-PF servers excluded."
echo
summarized_region_data="$( echo "$all_region_data" |
jq -r '.regions[] | select(.port_forward==true) |
.servers.meta[0].ip+" "+.id+" "+.name+" "+(.geo|tostring)' )"
else
summarized_region_data="$( echo "$all_region_data" |
jq -r '.regions[] |
.servers.meta[0].ip+" "+.id+" "+.name+" "+(.geo|tostring)' )"
fi
echo -e Testing regions that respond \
faster than "${green}$MAX_LATENCY${nc}" seconds:
selectedRegion="$(echo "$summarized_region_data" |
xargs -I{} bash -c 'printServerLatency {}' |
sort | head -1 | awk '{ print $2 }')"
echo
if [[ -z $selectedRegion ]]; then
echo -e "${red}No region responded within ${MAX_LATENCY}s, consider using a higher timeout."
echo "For example, to wait 1 second for each region, inject MAX_LATENCY=1 like this:"
echo -e "$ MAX_LATENCY=1 ./get_region.sh${nc}"
exit 1
else
echo -e "A list of servers and connection details, ordered by latency can be
found in at : ${green}/opt/piavpn-manual/latencyList${nc}
"
fi
else
selectedOrLowestLatency="selected"
check_all_region_data
fi
get_selected_region_data
bestServer_meta_IP=$(echo "$regionData" | jq -r '.servers.meta[0].ip')
bestServer_meta_hostname=$(echo "$regionData" | jq -r '.servers.meta[0].cn')
bestServer_WG_IP=$(echo "$regionData" | jq -r '.servers.wg[0].ip')
bestServer_WG_hostname=$(echo "$regionData" | jq -r '.servers.wg[0].cn')
bestServer_OT_IP=$(echo "$regionData" | jq -r '.servers.ovpntcp[0].ip')
bestServer_OT_hostname=$(echo "$regionData" | jq -r '.servers.ovpntcp[0].cn')
bestServer_OU_IP=$(echo "$regionData" | jq -r '.servers.ovpnudp[0].ip')
bestServer_OU_hostname=$(echo "$regionData" | jq -r '.servers.ovpnudp[0].cn')
if [[ $VPN_PROTOCOL == "no" ]]; then
echo -ne "The $selectedOrLowestLatency region is ${green}$(echo "$regionData" | jq -r '.name')${nc}"
if echo "$regionData" | jq -r '.geo' | grep true > /dev/null; then
echo " (geolocated region)."
else
echo "."
fi
echo -e "
The script found the best servers from the region you selected.
When connecting to an IP (no matter which protocol), please verify
the SSL/TLS certificate actually contains the hostname so that you
are sure you are connecting to a secure server, validated by the
PIA authority. Please find below the list of best IPs and matching
hostnames for each protocol:
${green}Meta Services $bestServer_meta_IP\t- $bestServer_meta_hostname
WireGuard $bestServer_WG_IP\t- $bestServer_WG_hostname
OpenVPN TCP $bestServer_OT_IP\t- $bestServer_OT_hostname
OpenVPN UDP $bestServer_OU_IP\t- $bestServer_OU_hostname
${nc}"
fi
# The script will check for an authentication token, and use it if present
# If no token exists, the script will check for login credentials to generate one
if [[ -z $PIA_TOKEN ]]; then
if [[ -z $PIA_USER || -z $PIA_PASS ]]; then
echo -e "${red}If you want this script to automatically get an authentication"
echo "token, please add the variables PIA_USER and PIA_PASS. Example:"
echo -e "$ PIA_USER=p0123456 PIA_PASS=xxx ./get_region.sh${nc}"
exit 0
fi
./get_token.sh
PIA_TOKEN=$( awk 'NR == 1' /opt/piavpn-manual/token )
export PIA_TOKEN
rm -f /opt/piavpn-manual/token
else
echo -e "Using existing token ${green}$PIA_TOKEN${nc}."
echo
fi
# Connect with WireGuard and clear authentication token file and latencyList
if [[ $VPN_PROTOCOL == "wireguard" ]]; then
echo "The ./get_region.sh script got started with"
echo -e "${green}VPN_PROTOCOL=wireguard${nc}, so we will automatically connect to WireGuard,"
echo "by running this command:"
echo -e "$ ${green}PIA_TOKEN=$PIA_TOKEN \\"
echo "WG_SERVER_IP=$bestServer_WG_IP WG_HOSTNAME=$bestServer_WG_hostname \\"
echo -e "PIA_PF=$PIA_PF ./connect_to_wireguard_with_token.sh${nc}"
echo
PIA_PF=$PIA_PF PIA_TOKEN=$PIA_TOKEN WG_SERVER_IP=$bestServer_WG_IP \
WG_HOSTNAME=$bestServer_WG_hostname ./connect_to_wireguard_with_token.sh
rm -f /opt/piavpn-manual/latencyList
exit 0
fi
# Connect with OpenVPN and clear authentication token file and latencyList
if [[ $VPN_PROTOCOL == openvpn* ]]; then
serverIP=$bestServer_OU_IP
serverHostname=$bestServer_OU_hostname
if [[ $VPN_PROTOCOL == *tcp* ]]; then
serverIP=$bestServer_OT_IP
serverHostname=$bestServer_OT_hostname
fi
echo "The ./get_region.sh script got started with"
echo -e "${green}VPN_PROTOCOL=$VPN_PROTOCOL${nc}, so we will automatically"
echo "connect to OpenVPN, by running this command:"
echo -e "$ ${green}PIA_PF=$PIA_PF PIA_TOKEN=$PIA_TOKEN \\"
echo " OVPN_SERVER_IP=$serverIP \\"
echo " OVPN_HOSTNAME=$serverHostname \\"
echo " CONNECTION_SETTINGS=$VPN_PROTOCOL \\"
echo -e " ./connect_to_openvpn_with_token.sh${nc}"
echo
PIA_PF=$PIA_PF PIA_TOKEN=$PIA_TOKEN \
OVPN_SERVER_IP=$serverIP \
OVPN_HOSTNAME=$serverHostname \
CONNECTION_SETTINGS=$VPN_PROTOCOL \
./connect_to_openvpn_with_token.sh
rm -f /opt/piavpn-manual/latencyList
exit 0
fi

View File

@ -1,228 +0,0 @@
#!/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.
# This function allows you to check if the required tools have been installed.
function check_tool() {
cmd=$1
package=$2
if ! command -v $cmd &>/dev/null
then
echo "$cmd could not be found"
echo "Please install $package"
exit 1
fi
}
# Now we call the function to make sure we can use curl and jq.
check_tool curl curl
check_tool jq jq
# This allows you to set the maximum allowed latency in seconds.
# All servers that respond slower than this will be ignored.
# You can inject this with the environment variable MAX_LATENCY.
# The default value is 50 milliseconds.
MAX_LATENCY=${MAX_LATENCY:-0.05}
export MAX_LATENCY
serverlist_url='https://serverlist.piaservers.net/vpninfo/servers/v4'
# This function checks the latency you have to a specific region.
# It will print a human-readable message to stderr,
# and it will print the variables to stdout
printServerLatency() {
serverIP="$1"
regionID="$2"
regionName="$(echo ${@:3} |
sed 's/ false//' | sed 's/true/(geo)/')"
time=$(LC_NUMERIC=en_US.utf8 curl -o /dev/null -s \
--connect-timeout $MAX_LATENCY \
--write-out "%{time_connect}" \
http://$serverIP:443)
if [ $? -eq 0 ]; then
>&2 echo Got latency ${time}s for region: $regionName
echo $time $regionID $serverIP
fi
}
export -f printServerLatency
echo -n "Getting the server list... "
# Get all region data since we will need this on multiple occasions
all_region_data=$(curl -s "$serverlist_url" | head -1)
# If the server list has less than 1000 characters, it means curl failed.
if [[ ${#all_region_data} -lt 1000 ]]; then
echo "Could not get correct region data. To debug this, run:"
echo "$ curl -v $serverlist_url"
echo "If it works, you will get a huge JSON as a response."
exit 1
fi
# Notify the user that we got the server list.
echo "OK!"
# Test one server from each region to get the closest region.
# If port forwarding is enabled, filter out regions that don't support it.
if [[ $PIA_PF == "true" ]]; then
echo Port Forwarding is enabled, so regions that do not support
echo port forwarding will get filtered out.
summarized_region_data="$( echo $all_region_data |
jq -r '.regions[] | select(.port_forward==true) |
.servers.meta[0].ip+" "+.id+" "+.name+" "+(.geo|tostring)' )"
else
summarized_region_data="$( echo $all_region_data |
jq -r '.regions[] |
.servers.meta[0].ip+" "+.id+" "+.name+" "+(.geo|tostring)' )"
fi
echo Testing regions that respond \
faster than $MAX_LATENCY seconds:
bestRegion="$(echo "$summarized_region_data" |
xargs -I{} bash -c 'printServerLatency {}' |
sort | head -1 | awk '{ print $2 }')"
if [ -z "$bestRegion" ]; then
echo ...
echo No region responded within ${MAX_LATENCY}s, consider using a higher timeout.
echo For example, to wait 1 second for each region, inject MAX_LATENCY=1 like this:
echo $ MAX_LATENCY=1 ./get_region_and_token.sh
exit 1
fi
# Get all data for the best region
regionData="$( echo $all_region_data |
jq --arg REGION_ID "$bestRegion" -r \
'.regions[] | select(.id==$REGION_ID)')"
echo -n The closest region is "$(echo $regionData | jq -r '.name')"
if echo $regionData | jq -r '.geo' | grep true > /dev/null; then
echo " (geolocated region)."
else
echo "."
fi
echo
bestServer_meta_IP="$(echo $regionData | jq -r '.servers.meta[0].ip')"
bestServer_meta_hostname="$(echo $regionData | jq -r '.servers.meta[0].cn')"
bestServer_WG_IP="$(echo $regionData | jq -r '.servers.wg[0].ip')"
bestServer_WG_hostname="$(echo $regionData | jq -r '.servers.wg[0].cn')"
bestServer_OT_IP="$(echo $regionData | jq -r '.servers.ovpntcp[0].ip')"
bestServer_OT_hostname="$(echo $regionData | jq -r '.servers.ovpntcp[0].cn')"
bestServer_OU_IP="$(echo $regionData | jq -r '.servers.ovpnudp[0].ip')"
bestServer_OU_hostname="$(echo $regionData | jq -r '.servers.ovpnudp[0].cn')"
echo "The script found the best servers from the region closest to you.
When connecting to an IP (no matter which protocol), please verify
the SSL/TLS certificate actually contains the hostname so that you
are sure you are connecting to a secure server, validated by the
PIA authority. Please find below the list of best IPs and matching
hostnames for each protocol:
Meta Services: $bestServer_meta_IP // $bestServer_meta_hostname
WireGuard: $bestServer_WG_IP // $bestServer_WG_hostname
OpenVPN TCP: $bestServer_OT_IP // $bestServer_OT_hostname
OpenVPN UDP: $bestServer_OU_IP // $bestServer_OU_hostname
"
if [[ ! $PIA_USER || ! $PIA_PASS ]]; then
echo If you want this script to automatically get a token from the Meta
echo service, please add the variables PIA_USER and PIA_PASS. Example:
echo $ PIA_USER=p0123456 PIA_PASS=xxx ./get_region_and_token.sh
exit 1
fi
echo "The ./get_region_and_token.sh script got started with PIA_USER and PIA_PASS,
so we will also use a meta service to get a new VPN token."
echo "Trying to get a new token by authenticating with the meta service..."
generateTokenResponse=$(curl -s -u "$PIA_USER:$PIA_PASS" \
--connect-to "$bestServer_meta_hostname::$bestServer_meta_IP:" \
--cacert "ca.rsa.4096.crt" \
"https://$bestServer_meta_hostname/authv3/generateToken")
echo "$generateTokenResponse"
if [ "$(echo "$generateTokenResponse" | jq -r '.status')" != "OK" ]; then
echo "Could not get a token. Please check your account credentials."
echo
echo "You can also try debugging by manually running the curl command:"
echo $ curl -vs -u "$PIA_USER:$PIA_PASS" --cacert ca.rsa.4096.crt \
--connect-to "$bestServer_meta_hostname::$bestServer_meta_IP:" \
https://$bestServer_meta_hostname/authv3/generateToken
exit 1
fi
token="$(echo "$generateTokenResponse" | jq -r '.token')"
echo "This token will expire in 24 hours.
"
# just making sure this variable doesn't contain some strange string
if [ "$PIA_PF" != true ]; then
PIA_PF="false"
fi
if [[ $PIA_AUTOCONNECT == wireguard ]]; then
echo The ./get_region_and_token.sh script got started with
echo PIA_AUTOCONNECT=wireguard, so we will automatically connect to WireGuard,
echo by running this command:
echo $ PIA_TOKEN=\"$token\" \\
echo WG_SERVER_IP=$bestServer_WG_IP WG_HOSTNAME=$bestServer_WG_hostname \\
echo PIA_PF=$PIA_PF ./connect_to_wireguard_with_token.sh
echo
PIA_PF=$PIA_PF PIA_TOKEN="$token" WG_SERVER_IP=$bestServer_WG_IP \
WG_HOSTNAME=$bestServer_WG_hostname ./connect_to_wireguard_with_token.sh
exit 0
fi
if [[ $PIA_AUTOCONNECT == openvpn* ]]; then
serverIP=$bestServer_OU_IP
serverHostname=$bestServer_OU_hostname
if [[ $PIA_AUTOCONNECT == *tcp* ]]; then
serverIP=$bestServer_OT_IP
serverHostname=$bestServer_OT_hostname
fi
echo The ./get_region_and_token.sh script got started with
echo PIA_AUTOCONNECT=$PIA_AUTOCONNECT, so we will automatically
echo connect to OpenVPN, by running this command:
echo PIA_PF=$PIA_PF PIA_TOKEN=\"$token\" \\
echo OVPN_SERVER_IP=$serverIP \\
echo OVPN_HOSTNAME=$serverHostname \\
echo CONNECTION_SETTINGS=$PIA_AUTOCONNECT \\
echo ./connect_to_openvpn_with_token.sh
echo
PIA_PF=$PIA_PF PIA_TOKEN="$token" \
OVPN_SERVER_IP=$serverIP \
OVPN_HOSTNAME=$serverHostname \
CONNECTION_SETTINGS=$PIA_AUTOCONNECT \
./connect_to_openvpn_with_token.sh
exit 0
fi
echo If you wish to automatically connect to the VPN after detecting the best
echo region, please run the script with the env var PIA_AUTOCONNECT.
echo 'The available options for PIA_AUTOCONNECT are (from fastest to slowest):'
echo - wireguard
echo - openvpn_udp_standard
echo - openvpn_udp_strong
echo - openvpn_tcp_standard
echo - openvpn_tcp_strong
echo You can also specify the env var PIA_PF=true to get port forwarding.
echo
echo Example:
echo $ PIA_USER=p0123456 PIA_PASS=xxx \
PIA_AUTOCONNECT=wireguard PIA_PF=true ./get_region_and_token.sh
echo
echo You can also connect now by running this command:
echo $ PIA_TOKEN=\"$token\" WG_SERVER_IP=$bestServer_WG_IP \
WG_HOSTNAME=$bestServer_WG_hostname ./connect_to_wireguard_with_token.sh

95
get_token.sh Executable file
View File

@ -0,0 +1,95 @@
#!/usr/bin/env 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.
# This function allows you to check if the required tools have been installed.
check_tool() {
cmd=$1
if ! command -v "$cmd" >/dev/null; then
echo "$cmd could not be found"
echo "Please install $cmd"
exit 1
fi
}
# Now we call the function to make sure we can use curl and jq.
check_tool curl
check_tool jq
# This function creates a timestamp, to use for setting $TOKEN_EXPIRATION
timeout_timestamp() {
date +"%c" --date='1 day' # Timestamp 24 hours
}
# Check if terminal allows output, if yes, define colors for output
if [[ -t 1 ]]; then
ncolors=$(tput colors)
if [[ -n $ncolors && $ncolors -ge 8 ]]; then
red=$(tput setaf 1) # ANSI red
green=$(tput setaf 2) # ANSI green
nc=$(tput sgr0) # No Color
else
red=''
green=''
nc='' # No Color
fi
fi
# Only allow script to run as root
if (( EUID != 0 )); then
echo -e "${red}This script needs to be run as root. Try again with 'sudo $0'${nc}"
exit 1
fi
mkdir -p /opt/piavpn-manual
if [[ -z $PIA_USER || -z $PIA_PASS ]]; then
echo "If you want this script to automatically get a token from the Meta"
echo "service, please add the variables PIA_USER and PIA_PASS. Example:"
echo "$ PIA_USER=p0123456 PIA_PASS=xxx ./get_token.sh"
exit 1
fi
echo -n "Checking login credentials..."
generateTokenResponse=$(curl -s --location --request POST \
'https://www.privateinternetaccess.com/api/client/v2/token' \
--form "username=$PIA_USER" \
--form "password=$PIA_PASS" )
if [ "$(echo "$generateTokenResponse" | jq -r '.token')" == "" ]; then
echo
echo
echo -e "${red}Could not authenticate with the login credentials provided!${nc}"
echo
exit
fi
echo -e "${green}OK!"
echo
token=$(echo "$generateTokenResponse" | jq -r '.token')
tokenExpiration=$(timeout_timestamp)
tokenLocation=/opt/piavpn-manual/token
echo -e "PIA_TOKEN=$token${nc}"
echo "$token" > "$tokenLocation" || exit 1
echo "$tokenExpiration" >> "$tokenLocation"
echo
echo "This token will expire in 24 hours, on $tokenExpiration."
echo

View File

@ -1,4 +1,4 @@
#!/bin/bash
#!/usr/bin/env bash
# Remove process and route information when connection closes
rm -rf /opt/piavpn-manual/pia_pid /opt/pia-manual/route_info

View File

@ -1,4 +1,4 @@
#!/bin/bash
#!/usr/bin/env bash
# Remove process and route information when connection closes
rm -rf /opt/piavpn-manual/pia_pid /opt/pia-manual/route_info

View File

@ -1,4 +1,4 @@
#!/bin/bash
#!/usr/bin/env bash
# Write gateway IP for reference
echo $route_vpn_gateway > /opt/piavpn-manual/route_info
echo "$route_vpn_gateway" > /opt/piavpn-manual/route_info

View File

@ -1,9 +1,9 @@
#!/bin/bash
#!/usr/bin/env bash
# Write gateway IP for reference
echo $route_vpn_gateway > /opt/piavpn-manual/route_info
echo "$route_vpn_gateway" > /opt/piavpn-manual/route_info
# Back up resolv.conf and create new on with PIA DNS
# Back up resolv.conf and create new one with PIA DNS
cat /etc/resolv.conf > /opt/piavpn-manual/resolv_conf_backup
echo "# Generated by /connect_to_openvpn_with_token.sh
nameserver 10.0.0.241" > /etc/resolv.conf

View File

@ -1,4 +1,4 @@
#!/bin/bash
#!/usr/bin/env bash
# Copyright (C) 2020 Private Internet Access, Inc.
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
@ -19,21 +19,48 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
# This function allows you to check if the required tools have been installed.
check_tool() {
cmd=$1
if ! command -v "$cmd" >/dev/null; then
echo "$cmd could not be found"
echo "Please install $cmd"
exit 1
fi
}
# Now we call the function to make sure we can use curl and jq.
check_tool curl
check_tool jq
# Check if the mandatory environment variables are set.
if [[ ! $PF_GATEWAY || ! $PIA_TOKEN || ! $PF_HOSTNAME ]]; then
echo This script requires 3 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
if [[ -z $PF_GATEWAY || -z $PIA_TOKEN || -z $PF_HOSTNAME ]]; then
echo "This script requires 3 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
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
# Check if terminal allows output, if yes, define colors for output
if [[ -t 1 ]]; then
ncolors=$(tput colors)
if [[ -n $ncolors && $ncolors -ge 8 ]]; then
red=$(tput setaf 1) # ANSI red
green=$(tput setaf 2) # ANSI green
nc=$(tput sgr0) # No Color
else
red=''
green=''
nc='' # No Color
fi
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.
@ -54,48 +81,50 @@ fi
# 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..."
if [[ -z $PAYLOAD_AND_SIGNATURE ]]; then
echo
echo -n "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=${PIA_TOKEN}" \
"https://${PF_HOSTNAME}:19999/getSignature")"
else
payload_and_signature="$PAYLOAD_AND_SIGNATURE"
echo "Using the following payload_and_signature from the env var:"
payload_and_signature=$PAYLOAD_AND_SIGNATURE
echo -n "Checking the 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."
if [[ $(echo "$payload_and_signature" | jq -r '.status') != "OK" ]]; then
echo -e "${red}The payload_and_signature variable does not contain an OK status.${nc}"
exit 1
fi
echo -e "${green}OK!${nc}"
# 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')"
signature=$(echo "$payload_and_signature" | jq -r '.signature')
# The payload has a base64 format. We need to extract it from the
# previous response 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')"
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')"
expires_at=$(echo "$payload" | base64 -d | jq -r '.expires_at')
# Display some information on the screen for the user.
echo "The signature is OK.
echo -ne "
Signature ${green}$signature${nc}
Payload ${green}$payload${nc}
--> The port is $port and it will expire on $expires_at. <--
--> The port is ${green}$port${nc} and it will expire on ${red}$expires_at${nc}. <--
Trying to bind the port..."
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
@ -108,17 +137,19 @@ while true; do
--data-urlencode "payload=${payload}" \
--data-urlencode "signature=${signature}" \
"https://${PF_HOSTNAME}:19999/bindPort")"
echo "$bind_port_response"
echo -e "${green}OK!${nc}"
# 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."
if [[ $(echo "$bind_port_response" | jq -r '.status') != "OK" ]]; then
echo -e "${red}The API did not return OK when trying to bind port... Exiting.${nc}"
exit 1
fi
echo Port $port refreshed on $(date). \
This port will expire on $(date --date="$expires_at")
echo -e Forwarded port'\t'"${green}$port${nc}"
echo -e Refreshed on'\t'"${green}$(date)${nc}"
echo -e Expires on'\t'"${red}$(date --date="$expires_at")${nc}"
echo -e "\n${green}This script will need to remain active to use port forwarding, and will refresh every 15 minutes.${nc}\n"
# sleep 15 minutes
sleep 900

View File

@ -1,5 +1,4 @@
#!/bin/bash
#!/usr/bin/env bash
# Copyright (C) 2020 Private Internet Access, Inc.
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
@ -20,139 +19,491 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
# Only allow script to run as
if [ "$(whoami)" != "root" ]; then
echo "This script needs to be run as root. Try again with 'sudo $0'"
exit 1
fi
echo
echo -n "PIA username (pNNNNNNN): "
read PIA_USER
if [ -z "$PIA_USER" ]; then
echo Username is required, aborting.
exit 1
fi
echo
export PIA_USER
echo -n "PIA password: "
read -s PIA_PASS
echo
if [ -z "$PIA_PASS" ]; then
echo Password is required, aborting.
exit 1
fi
echo
export PIA_PASS
# This section asks for user connection preferences
# this is hard coded for now, but will become an input
# variable in the future.
echo -n "Connection method ([W]ireguard/[o]penvpn): "
read connection_method
echo
PIA_AUTOCONNECT="wireguard"
if echo ${connection_method:0:1} | grep -iq o; then
echo -n "Connection method ([U]dp/[t]cp): "
read protocolInput
echo
protocol="udp"
if echo ${protocolInput:0:1} | grep -iq t; then
protocol="tcp"
# Check if terminal allows output, if yes, define colors for output
if [[ -t 1 ]]; then
ncolors=$(tput colors)
if [[ -n $ncolors && $ncolors -ge 8 ]]; then
red=$(tput setaf 1) # ANSI red
green=$(tput setaf 2) # ANSI green
nc=$(tput sgr0) # No Color
else
red=''
green=''
nc='' # No Color
fi
echo "Higher levels of encryption trade performance for security. "
echo -n "Do you want to use strong encryption ([N]o/[y]es): "
read strongEncryption
echo
encryption="standard"
if echo ${strongEncryption:0:1} | grep -iq y; then
encryption="strong"
fi
PIA_AUTOCONNECT="openvpn_${protocol}_${encryption}"
fi
export PIA_AUTOCONNECT
echo PIA_AUTOCONNECT=$PIA_AUTOCONNECT"
# Variables to use for validating input
intCheck='^[0-9]+$'
floatCheck='^[0-9]+([.][0-9]+)?$'
# Only allow script to run as root
if (( EUID != 0 )); then
echo -e "${red}This script needs to be run as root. Try again with 'sudo $0'${nc}"
exit 1
fi
# Erase previous authentication token if present
rm -f /opt/piavpn-manual/token /opt/piavpn-manual/latencyList
# Retry login if no token is generated
while :; do
while :; do
# Check for in-line definition of $PIA_USER
if [[ -z $PIA_USER ]]; then
echo
read -r -p "PIA username (p#######): " PIA_USER
fi
# Confirm format of PIA_USER input
unPrefix=${PIA_USER:0:1}
unSuffix=${PIA_USER:1}
if [[ -z $PIA_USER ]]; then
echo -e "\n${red}You must provide input.${nc}"
elif [[ ${#PIA_USER} != 8 ]]; then
echo -e "\n${red}A PIA username is always 8 characters long.${nc}"
elif [[ $unPrefix != "P" ]] && [[ $unPrefix != "p" ]]; then
echo -e "\n${red}A PIA username must start with \"p\".${nc}"
elif ! [[ $unSuffix =~ $intCheck ]]; then
echo -e "\n${red}Username formatting is always p#######!${nc}"
else
echo -e "\n${green}PIA_USER=$PIA_USER${nc}"
break
fi
PIA_USER=""
done
export PIA_USER
while :; do
# Check for in-line definition of $PIA_PASS
if [[ -z $PIA_PASS ]]; then
echo
echo -n "PIA password: "
read -r -s PIA_PASS
echo
fi
# Confirm format of PIA_PASS input
if [[ -z $PIA_PASS ]]; then
echo -e "\n${red}You must provide input.${nc}"
elif [[ ${#PIA_PASS} -lt 8 ]]; then
echo -e "\n${red}A PIA password is always a minimum of 8 characters long.${nc}"
else
echo -e "\n${green}PIA_PASS input received.${nc}"
echo
break
fi
PIA_PASS=""
done
export PIA_PASS
# Confirm credentials and generate token
./get_token.sh
tokenLocation="/opt/piavpn-manual/token"
# If the script failed to generate an authentication token, the script will exit early.
if [[ ! -f $tokenLocation ]]; then
read -r -p "Do you want to try again ([N]o/[y]es): " tryAgain
if ! echo "${tryAgain:0:1}" | grep -iq y; then
exit 1
fi
PIA_USER=""
PIA_PASS=""
else
PIA_TOKEN=$( awk 'NR == 1' /opt/piavpn-manual/token )
export PIA_TOKEN
rm -f /opt/piavpn-manual/token
break
fi
done
# Check for in-line definition of $DIP_TOKEN
if [[ -z $DIP_TOKEN ]]; then
# Check for dedicated IP
echo -n "Do you want to use a dedicated IP token ([N]o/[y]es): "
read useDIP
echo
pfOption="true"
else
if echo ${DIP_TOKEN:0:1} | grep -iq n; then
useDIP="no"
echo -e "${red}Not using a dedicated IP.${nc}"
echo
DIP_TOKEN=""
else
useDIP="yes"
fi
fi
if echo ${useDIP:0:1} | grep -iq y; then
useDIP="true"
while :; do
while :; do
# Check for in-line definition of $DIP_TOKEN
if [[ -z $DIP_TOKEN ]]; then
read -p "Dedicated token (DIP#############################): " DIP_TOKEN
fi
# Confirm format of DIP_TOKEN input
dipPrefix=$( echo ${DIP_TOKEN:0:3} )
if [[ -z "$DIP_TOKEN" ]]; then
echo -e "\n${red}You must provide input.${nc}"
elif [[ ${#DIP_TOKEN} != 32 ]]; then
echo -e "\n${red}A dedicated IP token is always 32 characters long.${nc}"
elif [[ $dipPrefix != "DIP" ]]; then
echo -e "\n${red}A dedicated IP token must start with \"DIP\".${nc}"
else
break
fi
echo
DIP_TOKEN=""
done
export DIP_TOKEN
# Confirm DIP_TOKEN and retrieve connection details
./get_dip.sh
dipDetails="/opt/piavpn-manual/dipAddress"
# If the script failed to generate retrieve dedicated IP information, the script will exit early.
if [ ! -f "$dipDetails" ]; then
read -p "Do you want to try again ([N]o/[y]es): " tryAgain
echo
if ! echo ${tryAgain:0:1} | grep -iq y; then
exit 1
fi
DIP_TOKEN=""
else
dipAddress=$( awk 'NR == 1' /opt/piavpn-manual/dipAddress )
dipHostname=$( awk 'NR == 2' /opt/piavpn-manual/dipAddress)
dipKey=$( awk 'NR == 3' /opt/piavpn-manual/dipAddress )
pfOption=$( awk 'NR == 5' /opt/piavpn-manual/dipAddress )
rm -f /opt/piavpn-manual/dipAddress
break
fi
done
fi
if [[ -z $DIP_TOKEN ]]; then
echo "${green}DIP_TOKEN=none${nc}"
else
echo "${green}DIP_TOKEN=$DIP_TOKEN${nc}"
fi
echo
# Erase previous connection details if present
rm -f /opt/piavpn-manual/token /opt/piavpn-manual/latencyList
# Prompt for port forwarding if no DIP or DIP allows it
if [[ $pfOption = "false" ]]; then
PIA_PF="false"
fi
# Check for in-line definition of PIA_PF and prompt for input
if [[ -z $PIA_PF ]]; then
echo -n "Do you want a forwarding port assigned ([N]o/[y]es): "
read -r portForwarding
echo
if echo "${portForwarding:0:1}" | grep -iq y; then
PIA_PF="true"
fi
fi
if [[ $PIA_PF != "true" ]]; then
PIA_PF="false"
fi
export PIA_PF
echo -e "${green}PIA_PF=$PIA_PF${nc}"
echo
# Check for in-line definition of DISABLE_IPV6 and prompt for input
if [[ -z $DISABLE_IPV6 ]]; then
echo "Having active IPv6 connections might compromise security by allowing"
echo "split tunnel connections that run outside the VPN tunnel."
echo -n "Do you want to disable IPv6? (Y/n): "
read -r DISABLE_IPV6
echo
fi
if echo "${DISABLE_IPV6:0:1}" | grep -iq n; then
echo -e "${red}IPv6 settings have not been altered.
${nc}"
else
echo -e "The variable ${green}DISABLE_IPV6=$DISABLE_IPV6${nc}, does not start with 'n' for 'no'.
${green}Defaulting to yes.${nc}
"
sysctl -w net.ipv6.conf.all.disable_ipv6=1
sysctl -w net.ipv6.conf.default.disable_ipv6=1
echo
echo -e "${red}IPv6 has been disabled${nc}, you can ${green}enable it again with: "
echo "sysctl -w net.ipv6.conf.all.disable_ipv6=0"
echo "sysctl -w net.ipv6.conf.default.disable_ipv6=0"
echo -e "${nc}"
fi
# Check for the required presence of resolvconf for setting DNS on wireguard connections.
# Only prompt for server selection if no DIP has been specified
if [[ -z $DIP_TOKEN ]]; then
# Input validation and check for conflicting declarations of AUTOCONNECT and PREFERRED_REGION
# If both variables are set, AUTOCONNECT has superiority and PREFERRED_REGION is ignored
if [[ -z $AUTOCONNECT ]]; then
echo "AUTOCONNECT was not declared."
echo
selectServer="ask"
elif echo "${AUTOCONNECT:0:1}" | grep -iq f; then
if [[ $AUTOCONNECT != "false" ]]; then
echo -e "The variable ${green}AUTOCONNECT=$AUTOCONNECT${nc}, starts with 'f' for 'false'."
AUTOCONNECT="false"
echo -e "Updated ${green}AUTOCONNECT=$AUTOCONNECT${nc}"
echo
fi
selectServer="yes"
else
if [[ $AUTOCONNECT != "true" ]]; then
echo -e "The variable ${green}AUTOCONNECT=$AUTOCONNECT${nc}, does not start with 'f' for 'false'."
AUTOCONNECT="true"
echo -e "Updated ${green}AUTOCONNECT=$AUTOCONNECT${nc}"
echo
fi
if [[ -z $PREFERRED_REGION ]]; then
echo -e "${green}AUTOCONNECT=true${nc}"
echo
else
echo
echo "AUTOCONNECT supersedes in-line definitions of PREFERRED_REGION."
echo -e "${red}PREFERRED_REGION=$PREFERRED_REGION will be ignored.${nc}
"
PREFERRED_REGION=""
fi
selectServer="no"
fi
# Prompt the user to specify a server or auto-connect to the lowest latency
while :; do
if [[ -z $PREFERRED_REGION ]]; then
# If autoconnect is not set, prompt the user to specify a server or auto-connect to the lowest latency
if [[ $selectServer == "ask" ]]; then
echo -n "Do you want to manually select a server, instead of auto-connecting to the
server with the lowest latency ([N]o/[y]es): "
read -r selectServer
echo
fi
# Call the region script with input to create an ordered list based upon latency
# When $PREFERRED_REGION is set to none, get_region.sh will generate a list of servers
# that meet the latency requirements specified by $MAX_LATENCY.
# When $VPN_PROTOCOL is set to no, get_region.sh will sort that list of servers
# to allow for numeric selection, or an easy manual review of options.
if echo "${selectServer:0:1}" | grep -iq y; then
# This sets the maximum allowed latency in seconds.
# All servers that respond slower than this will be ignored.
if [[ -z $MAX_LATENCY ]]; then
echo -n "With no input, the maximum allowed latency will be set to 0.05s (50ms).
If your connection has high latency, you may need to increase this value.
For example, you can try 0.2 for 200ms allowed latency.
"
else
latencyInput=$MAX_LATENCY
fi
# Assure that input is numeric and properly formatted.
MAX_LATENCY=0.05 # default
while :; do
if [[ -z $latencyInput ]]; then
read -r -p "Custom latency (no input required for 50ms): " latencyInput
echo
fi
customLatency=0
customLatency+=$latencyInput
if [[ -z $latencyInput ]]; then
break
elif [[ $latencyInput == 0 ]]; then
echo -e "${red}Latency input must not be zero.${nc}\n"
elif ! [[ $customLatency =~ $floatCheck ]]; then
echo -e "${red}Latency input must be numeric.${nc}\n"
elif [[ $latencyInput =~ $intCheck ]]; then
MAX_LATENCY=$latencyInput
break
else
MAX_LATENCY=$customLatency
break
fi
latencyInput=""
done
export MAX_LATENCY
echo -e "${green}MAX_LATENCY=$MAX_LATENCY${nc}"
PREFERRED_REGION="none"
export PREFERRED_REGION
VPN_PROTOCOL="no"
export VPN_PROTOCOL
VPN_PROTOCOL=no ./get_region.sh
if [[ -s /opt/piavpn-manual/latencyList ]]; then
# Output the ordered list of servers that meet the latency specification $MAX_LATENCY
echo -e "Ordered list of servers with latency less than ${green}$MAX_LATENCY${nc} seconds:"
i=0
while read -r line; do
i=$((i+1))
time=$( awk 'NR == '$i' {print $1}' /opt/piavpn-manual/latencyList )
id=$( awk 'NR == '$i' {print $2}' /opt/piavpn-manual/latencyList )
ip=$( awk 'NR == '$i' {print $3}' /opt/piavpn-manual/latencyList )
location1=$( awk 'NR == '$i' {print $4}' /opt/piavpn-manual/latencyList )
location2=$( awk 'NR == '$i' {print $5}' /opt/piavpn-manual/latencyList )
location3=$( awk 'NR == '$i' {print $6}' /opt/piavpn-manual/latencyList )
location4=$( awk 'NR == '$i' {print $7}' /opt/piavpn-manual/latencyList )
location="$location1 $location2 $location3 $location4"
printf "%3s : %-8s %-15s %23s" $i "$time" "$ip" "$id"
echo " - $location"
done < /opt/piavpn-manual/latencyList
echo
# Receive input to specify the server to connect to manually
while :; do
read -r -p "Input the number of the server you want to connect to ([1]-[$i]) : " serverSelection
if [[ -z $serverSelection ]]; then
echo -e "\n${red}You must provide input.${nc}\n"
elif ! [[ $serverSelection =~ $intCheck ]]; then
echo -e "\n${red}You must enter a number.${nc}\n"
elif [[ $serverSelection -lt 1 ]]; then
echo -e "\n${red}You must enter a number greater than 1.${nc}\n"
elif [[ $serverSelection -gt $i ]]; then
echo -e "\n${red}You must enter a number between 1 and $i.${nc}\n"
else
PREFERRED_REGION=$( awk 'NR == '"$serverSelection"' {print $2}' /opt/piavpn-manual/latencyList )
echo
echo -e "${green}PREFERRED_REGION=$PREFERRED_REGION${nc}"
break
fi
done
# Write the serverID for use when connecting, and display the serverName for user confirmation
export PREFERRED_REGION
echo
break
else
exit 1
fi
else
echo -e "${green}You will auto-connect to the server with the lowest latency.${nc}"
echo
break
fi
else
# Validate in-line declaration of PREFERRED_REGION; if invalid remove input to initiate prompts
echo "Region input is : $PREFERRED_REGION"
export PREFERRED_REGION
VPN_PROTOCOL=no ./get_region.sh
if [[ $? != 1 ]]; then
break
fi
PREFERRED_REGION=""
fi
done
fi
if [[ -z $VPN_PROTOCOL ]]; then
VPN_PROTOCOL="none"
fi
# This section asks for user connection preferences
case $VPN_PROTOCOL in
openvpn)
VPN_PROTOCOL="openvpn_udp_standard"
;;
wireguard | openvpn_udp_standard | openvpn_udp_strong | openvpn_tcp_standard | openvpn_tcp_strong)
;;
none | *)
echo -n "Connection method ([W]ireguard/[o]penvpn): "
read -r connection_method
echo
VPN_PROTOCOL="wireguard"
if echo "${connection_method:0:1}" | grep -iq o; then
echo -n "Connection method ([U]dp/[t]cp): "
read -r protocolInput
echo
protocol="udp"
if echo "${protocolInput:0:1}" | grep -iq t; then
protocol="tcp"
fi
echo "Higher levels of encryption trade performance for security. "
echo -n "Do you want to use strong encryption ([N]o/[y]es): "
read -r strongEncryption
echo
encryption="standard"
if echo "${strongEncryption:0:1}" | grep -iq y; then
encryption="strong"
fi
VPN_PROTOCOL="openvpn_${protocol}_${encryption}"
fi
;;
esac
export VPN_PROTOCOL
echo -e "${green}VPN_PROTOCOL=$VPN_PROTOCOL
${nc}"
# Check for the required presence of resolvconf for setting DNS on wireguard connections
setDNS="yes"
if ! command -v resolvconf &>/dev/null && [ "$PIA_AUTOCONNECT" == wireguard ]; then
echo The resolvconf package could not be found.
echo This script can not set DNS for you and you will
echo need to invoke DNS protection some other way.
if ! command -v resolvconf &>/dev/null && [[ $VPN_PROTOCOL == "wireguard" ]]; then
echo -e "${red}The resolvconf package could not be found."
echo "This script can not set DNS for you and you will"
echo -e "need to invoke DNS protection some other way.${nc}"
echo
setDNS="no"
fi
if [ "$setDNS" != no ]; then
echo Using third party DNS could allow DNS monitoring.
echo -n "Do you want to force PIA DNS ([Y]es/[n]o): "
read setDNS
echo
fi
PIA_DNS="true"
if echo ${setDNS:0:1} | grep -iq n; then
# Check for in-line definition of PIA_DNS and prompt for input
if [[ $setDNS == "yes" ]]; then
if [[ -z $PIA_DNS ]]; then
echo "Using third party DNS could allow DNS monitoring."
echo -n "Do you want to force PIA DNS ([Y]es/[n]o): "
read -r setDNS
echo
PIA_DNS="true"
if echo "${setDNS:0:1}" | grep -iq n; then
PIA_DNS="false"
fi
fi
elif [[ $PIA_DNS != "true" || $setDNS == "no" ]]; then
PIA_DNS="false"
fi
export PIA_DNS
echo PIA_DNS=$PIA_DNS"
"
echo -e "${green}PIA_DNS=$PIA_DNS${nc}"
echo -n "Do you want a forwarding port assigned ([N]o/[y]es): "
read portForwarding
echo
CONNECTION_READY="true"
export CONNECTION_READY
PIA_PF="false"
if echo ${portForwarding:0:1} | grep -iq y; then
PIA_PF="true"
fi
export PIA_PF
echo PIA_PF=$PIA_PF
# Set this to the maximum allowed latency in seconds.
# All servers that respond slower than this will be ignored.
echo -n "
With no input, the maximum allowed latency will be set to 0.05s (50ms).
If your connection has high latency, you may need to increase this value.
For example, you can try 0.2 for 200ms allowed latency.
Custom latency (no input required for 50ms): "
read customLatency
echo
MAX_LATENCY=0.05
if [[ $customLatency != "" ]]; then
MAX_LATENCY=$customLatency
fi
export MAX_LATENCY
echo "MAX_LATENCY=\"$MAX_LATENCY\"
"
echo "Having active IPv6 connections might compromise security by allowing"
echo "split tunnel connections that run outside the VPN tunnel."
echo -n "Do you want to disable IPv6? (Y/n): "
read disable_IPv6
echo
if echo ${disable_IPv6:0:1} | grep -iq n; then
echo "IPv6 settings have not been altered.
"
else
sysctl -w net.ipv6.conf.all.disable_ipv6=1
sysctl -w net.ipv6.conf.default.disable_ipv6=1
if [[ -z $DIP_TOKEN ]]; then
./get_region.sh
elif [[ $VPN_PROTOCOL == wireguard ]]; then
echo
echo "IPv6 has been disabled, you can enable it again with: "
echo "sysctl -w net.ipv6.conf.all.disable_ipv6=0"
echo "sysctl -w net.ipv6.conf.default.disable_ipv6=0
"
echo -e "You will be connecting with ${green}WG_SERVER_IP=$dipAddress${nc} using"
echo -e "${green}VPN_PROTOCOL=wireguard${nc}, so we will automatically connect to WireGuard,"
echo "by running this command:"
echo -e "$ ${green}PIA_PF=$PIA_PF PIA_TOKEN=$PIA_TOKEN" \\
echo "DIP_TOKEN=$DIP_TOKEN" \\
echo "WG_SERVER_IP=$dipAddress WG_HOSTNAME=$dipHostname" \\
echo -e "./connect_to_wireguard_with_token.sh${nc}"
echo
PIA_PF=$PIA_PF PIA_TOKEN=$PIA_TOKEN DIP_TOKEN=$DIP_TOKEN \
WG_SERVER_IP=$dipAddress WG_HOSTNAME=$dipHostname \
./connect_to_wireguard_with_token.sh
rm -f /opt/piavpn-manual/latencyList
exit 0
elif [[ $VPN_PROTOCOL == openvpn* ]]; then
echo
echo "The dedicated IP connection will be started with"
echo -e "${green}VPN_PROTOCOL=$VPN_PROTOCOL${nc}, so we will automatically"
echo "connect to OpenVPN, by running this command:"
echo -e "$ ${green}PIA_PF=$PIA_PF PIA_TOKEN=$PIA_TOKEN" \\
echo "DIP_TOKEN=$DIP_TOKEN OVPN_SERVER_IP=$dipAddress" \\
echo "OVPN_HOSTNAME=$dipHostname" \\
echo "CONNECTION_SETTINGS=$VPN_PROTOCOL" \\
echo -e "./connect_to_openvpn_with_token.sh${nc}"
echo
PIA_PF=$PIA_PF PIA_TOKEN=$PIA_TOKEN \
DIP_TOKEN=$DIP_TOKEN OVPN_SERVER_IP=$dipAddress \
OVPN_HOSTNAME=$dipHostname \
CONNECTION_SETTINGS=$VPN_PROTOCOL \
./connect_to_openvpn_with_token.sh
rm -f /opt/piavpn-manual/latencyList
exit 0
fi
./get_region_and_token.sh