Merge branch 'test' into test

This commit is contained in:
mquirin 2020-12-26 23:39:48 +00:00 committed by GitHub
commit 6448cc268a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
28 changed files with 1520 additions and 699 deletions

17
.github/stale.yml vendored Normal file
View file

@ -0,0 +1,17 @@
daysUntilStale: 15
daysUntilClose: 7
exemptLabels:
- On Hold
- Fix in Test Branch
- Broken Dependency
- bug
- Good First Issue
- help wanted
- "status: In Progress"
- Waiting For Merge
staleLabel: Inactive
markComment: >
This issue has been automatically marked as stale because it has not had
recent activity. It will be closed if no further activity occurs. Thank you
for your contributions.
closeComment: true

View file

@ -1,10 +1,33 @@
# Information of Latest updates
This file has the objective of describing the major changes for each merge from test to master in a similar way as a
patch release notes.
This file has the objective of describing the major changes for each merge from test to master in a similar way as a patch release notes.
Everytime Test branch is merged into master, a new entry should be created with the date and changes being merged.
## Nov 4th 2020
- Official support for Ubuntu Server 20.04 on Raspberry Pi (32-bit and 64-bit).
- Handle special characters better when managing OpenVPN clients.
- Show expired OpenVPN certificates as such when using 'pivpn -l'.
- Improved OpenVPN and WireGuard availability detection.
- Reload WireGuard instead of restarting so it doesn't kick existing clients.
## Jul 24th 2020
- Added ability to remove client by index. For example, when the user is presented with '2) phone' he can remove the client by typing either '2' or 'phone'.
- Added ability to remove a client non-interactively with 'pivpn -r phone -y'.
- When choosing to use Pi-hole, do not whitelist the specific VPN interface. Instead, use Pi-hole's built-in command 'pihole -a -i local' to allow listening from on the VPN interface. DNS resolution on the LAN shouldn't break anymore in some circumstances if the user changes Pi-hole's listening behavior after installing PiVPN.
## Jun 9th 2020
- Dual VPN mode, use both WireGuard and OpenVPN by running the installer script over an existing installation.
- Generate a unique pre-shared key for each client as per the WireGuard protocol to improve post-quantum resistance.
- Added the ability to regenerate the .ovpn config when the client template changes (issue #281). Use 'pivpn -a -o'.
- Added the '--show-unsupported-nics' argument to the install script for those who need PiVPN on virtual servers where the available network interfaces may not be detected reliably (issue #994).
- Clone the git repo to '/usr/local/src/pivpn' and replace all other locations with symlinks (issue #695).
- Simplified the OpenVPN installation flow by moving some settings behind a "customize" dialog.
- Temporarily disable 'pivpn -up' until a proper update strategy is defined. See [this commit](https://github.com/pivpn/pivpn/commit/f06f6d79203c29ebd785f860a81a15e9caac4fc9) for more information.
## Mar 17th 2020
- Switch to Bullseye repository on Debian/Raspbian. The bullseye repository is less likely to offer broken packages and it's also supported by Raspbian, meaning there is no need to manually compile WireGuard on older Raspberry Pis.

133
README.md
View file

@ -1,6 +1,6 @@
![WireGuard + OpenVPN logo](logos.jpg)
**[Is pivpn.io down?](https://p.datadoghq.com/sb/od1t7p4rmqi6x1fm-cd513e61b0eb77a5d5f6a52fe0662205?theme=dark)**
**[Is pivpn.io down?](https://status.pivpn.io)**
About
-----
@ -14,7 +14,7 @@ into a VPN server using two free, open-source protocols:
Have you been looking for a good guide or tutorial for setting up a VPN server on a Raspberry Pi or Ubuntu based server?
Run this script and you don't need a guide or tutorial, this will do it all for you, in a fraction of the time and with hardened security settings in place by default.
The master branch of this script installs and configures either WireGuard or OpenVPN on Raspbian, Debian or Ubuntu and it as been tested to run not only on Raspberry Pi but also in any Cloud Provider VPS.
The master branch of this script installs and configures either WireGuard or OpenVPN (or both) on Raspbian, Debian or Ubuntu and it as been tested to run not only on Raspberry Pi but also in any Cloud Provider VPS.
We recommend using the latest Raspbian Lite image on a Raspberry Pi in your home so you can VPN into your home from a unsecure remote locations and safely use the internet.
However, the scripts do try to detect different distributions and make adjustments accordingly.
They should work on the majority of Ubuntu and Debian based distributions including those using UFW by default instead of raw iptables.
@ -38,14 +38,13 @@ It is recommended that you use a fresh image of the latest Raspbian Lite from
https://raspberrypi.org/downloads, but if you don't, be sure to make a backup
image of your existing installation before proceeding.
You should also setup your Pi with a static IP address
(see either source 1 or 2 at the bottom of this Readme)
but it is not required as the script can do this for you.
You will need to have your router forwarding UDP port 1194 or whatever custom
port you may have chose in the installer
(varies by model & manufacturer; consult your router manufacturer's documentation to do this).
Enabling SSH on your Pi is also highly recommended, so that you can run a very
compact headless server without a monitor or keyboard and be able to access it
even more conveniently (This is also covered by source 2).
even more conveniently.
Installation
@ -56,22 +55,17 @@ Installation
curl -L https://install.pivpn.io | bash
```
**Method 2**
**Method 2 (direct link)**
```Shell
curl -L https://install.pivpn.io > pivpn.sh
sudo bash pivpn.sh
curl https://raw.githubusercontent.com/pivpn/pivpn/master/auto_install/install.sh | bash
```
**Method 3**
**Method 3 (clone repo)**
```Shell
git clone https://github.com/pivpn/pivpn.git
sudo bash pivpn/auto_install/install.sh
bash pivpn/auto_install/install.sh
```
**OBS:**
In alternative to install.pivpn.io you can use the raw github link:
https://raw.githubusercontent.com/pivpn/pivpn/master/auto_install/install.sh
**To install from Test/Development branch**
Check our [Wiki Page](https://github.com/pivpn/pivpn/wiki#testing)
@ -80,7 +74,9 @@ Check our [Wiki Page](https://github.com/pivpn/pivpn/wiki#testing)
The script will first update your APT repositories, upgrade packages, and install WireGuard (default) or OpenVPN, which will take some time.
It will ask which authentication method you wish the guts of your server to use. If you go for WireGuard, you don't get to choose: you will use a Curve25519 public key, which provides 128-bit security. On the other end, if you prefer OpenVPN, you can choose between a 2048-bit, 3072-bit, or 4096-bit RSA certificate. If you're unsure or don't have a convincing reason one way or the other I'd use 2048 today (provides 112-bit security).
It will ask which authentication method you wish the guts of your server to use. If you go for WireGuard, you don't get to choose: you will use a Curve25519 public key, which provides 128-bit security. On the other end, if you prefer OpenVPN, default settings will generate ECDSA certificates, which are based on Elliptic Curves, allowing much smaller keys while providing an equivalent security level to traditional RSA (256 bit long, equivalent to 3072 bit RSA). You can also use 384-bit and 521-bit, even though they are quite overkill.
If you decide to customize settings, you will still be able to use RSA certificates if you need backward compatibility with older gear. You can choose between a 2048-bit, 3072-bit, or 4096-bit certificate. If you're unsure or don't have a convincing reason one way or the other I'd use 2048 today (provides 112-bit security).
From the OpenVPN site:
@ -88,119 +84,16 @@ From the OpenVPN site:
> Up to 4096-bit is accepted by nearly all RSA systems (including OpenVPN), but use of keys this large will dramatically increase generation time, TLS handshake delays, and CPU usage for TLS operations; the benefit beyond 2048-bit keys is small enough not to be of great use at the current time. It is often a larger benefit to consider lower validity times than more bits past 2048, but that is for you to decide.
After this, the script will go back to the command line as it builds the server's own certificate authority (OpenVPN only). The script will ask you if you'd like to change the default port, protocol, client's DNS server, etc. If you know you want to change these things, feel free, and the script will put all the information where it needs to go in the various config files.
If you aren't sure, it has been designed that you can simply hit 'Enter' through all the questions and have a working configuration at the end.
Finally, the script will take some time to build the server's Diffie-Hellman key exchange (OpenVPN only). If you chose 2048-bit encryption, it will take about 40 minutes on a Model B+, and several hours if you choose a larger size.
Finally, if you are using RSA, the script will take some time to build the server's Diffie-Hellman key exchange (OpenVPN only). If you chose 2048-bit encryption, it will take about 40 minutes on a Model B+, and several hours if you choose a larger size.
The script will also make some changes to your system to allow it to forward internet traffic and allow VPN connections through the Pi's firewall. When the script informs you that it has finished configuring PiVPN, it will ask if you want to reboot. I have it where you do not need to reboot when done but it also can't hurt.
After the installation is complete you can use the command `pivpn` to manage the server. The commands below are just to get started, run `pivpn -h` to see the full list of options.
Managing the PiVPN (WireGuard)
----------------------
`pivpn add`
You will be prompted to enter a name for your client. Pick anything you like and hit 'enter'.
The script will assemble the client .conf file and place it in the directory 'configs' within your
home directory.
`pivpn remove`
Asks you for the name of the client to remove. Once you remove a client, it will no longer allow you to use
the given client config (specifically its public key) to connect. This is useful for many reasons but some ex:
You have a profile on a mobile phone and it was lost or stolen. Remove its key and generate a new
one for your new phone. Or even if you suspect that a key may have been compromised in any way,
just remove it and generate a new one.
`pivpn list`
If you add more than a few clients, this gives you a nice list of their names and associated keys.
Managing the PiVPN (OpenVPN)
----------------------
`pivpn add`
You will be prompted to enter a name for your client. Pick anything you like and hit 'enter'.
You will be asked to enter a pass phrase for the client key; make sure it's one you'll remember.
The script will assemble the client .ovpn file and place it in the directory 'ovpns' within your
home directory.
If you need to create a client certificate that is not password protected (IE for use on a router),
then you can use the 'pivpn add nopass' option to generate that.
`pivpn revoke`
Asks you for the name of the client to revoke. Once you revoke a client, it will no longer allow you to use
the given client certificate (ovpn config) to connect. This is useful for many reasons but some ex:
You have a profile on a mobile phone and it was lost or stolen. Revoke its cert and generate a new
one for your new phone. Or even if you suspect that a cert may have been compromised in any way,
just revoke it and generate a new one.
`pivpn list`
If you add more than a few clients, this gives you a nice list of their names and whether their certificate
is still valid or has been revoked. Great way to keep track of what you did with 'pivpn add' and 'pivpn revoke'.
Importing Profiles on Client Machines
--------------------------------------------
**Windows**: Use a program like WinSCP or Cyberduck. Note that you may need administrator permission to move files to some folders on your Windows machine, so if you have trouble transferring the profile to a particular folder with your chosen file transfer program, try moving it to your desktop.
**Mac/Linux**: Open the Terminal app and copy the config from the Raspberry Pi using `scp pi-user@ip-of-your-raspberry:configs/whatever.conf .` (if using WireGuard) or `scp pi-user@ip-of-your-raspberry:ovpns/whatever.ovpn .` (if using OpenVPN). The file will be downloaded in the current working directory, which usually is the home folder of your PC.
**Android/iOS** (WireGuard only): Just skip to _Connecting to the PiVPN server (WireGuard)_
**Android**: You can either retrieve it on PC and then move it to your device via USB, or you can use an app like Turbo FTP & SFTP client to retrieve it directly from your Android device.
**iOS**: You can use an app that supports SFTP like Documents by Readdle to retrieve it directly from your iOS device.
Connecting to the PiVPN server (WireGuard)
--------------------------------------------
**Windows/Mac**: Download the [WireGuard GUI app](https://www.wireguard.com/install/), import the configuration and activate the tunnel.
**Linux**: Install [WireGuard](https://www.wireguard.com/install/) following the instructions for your distribution. Now, as root user, create the /etc/wireguard folder and prevent anyone but root to enter it (you only need to do this the first time):
```
mkdir -p /etc/wireguard
chown root:root /etc/wireguard
chmod 700 /etc/wireguard
```
Move the config and activate the tunnel:
```
mv whatever.conf /etc/wireguard/
wg-quick up whatever
```
Run `wg-quick down whatever` to deactivate the tunnel.
**Android/iOS:** Run `pivpn -qr` on the PiVPN server to generate a QR code of your config, download the Wireguard app [Android link](https://play.google.com/store/apps/details?id=com.wireguard.android) / [iOS link](https://apps.apple.com/it/app/wireguard/id1441195209), click the '+' sign and scan the QR code with your phone's camera. Flip the switch to activate the tunnel.
Connecting to the PiVPN server (OpenVPN)
--------------------------------------------
**Windows**: Download the [OpenVPN GUI](https://openvpn.net/community-downloads/), install it, and place the profile in the 'config' folder of your OpenVPN directory, i.e., in 'C:\Program Files\OpenVPN\config'. After importing, connect to the VPN server on Windows by running the OpenVPN GUI with administrator permissions, right-clicking on the icon in the system tray, and clicking 'Connect'.
**Linux**: Install OpenVPN using your package manager (APT in this example). Now, as root user, create the /etc/openvpn/client folder and prevent anyone but root to enter it (you only need to do this the first time):
```
apt install openvpn
mkdir -p /etc/openvpn/client
chown root:root /etc/openvpn/client
chmod 700 /etc/openvpn/client
```
Move the config and connect (input the pass phrase if you set one):
```
mv whatever.ovpn /etc/openvpn/client/
openvpn /etc/openvpn/client/whatever.ovpn
```
Press CTRL-C to disconnect.
**Mac**: You can use an OpenVPN client like [Tunnelblick](https://tunnelblick.net/downloads.html). Here's a [guide](https://tunnelblick.net/czUsing.html) to import the configuration.
**Android**: Install the [OpenVPN Connect app](https://play.google.com/store/apps/details?id=net.openvpn.openvpn), select 'Import' from the drop-down menu in the upper right corner of the main screen, choose the directory on your device where you stored the .ovpn file, and select the file. Connect by selecting the profile under 'OpenVPN Profile' and pressing 'Connect'.
**iOS**: Install the [OpenVPN Connect app](https://apps.apple.com/it/app/openvpn-connect/id590379981). Then go to the app where you copied the .ovpn file to, select the file, find an icon or button to 'Share' or 'Open with', and choose to open with the OpenVPN app.
Removing PiVPN
----------------
If at any point you wish to remove PiVPN from your Pi and revert it to a pre-installation state, such as if you want to undo a failed installation to try again or you want to remove PiVPN without installing a fresh Raspbian image, just run `pivpn uninstall`.
After the installation is complete you can use the command `pivpn` to manage the server. Have a look at the [OpenVPN](https://github.com/pivpn/pivpn/wiki/OpenVPN) or [WireGuard](https://github.com/pivpn/pivpn/wiki/WireGuard) wiki for some example commands, connection instructions, FAQs, [troubleshooting steps](https://github.com/pivpn/pivpn/wiki/FAQ#how-do-i-troubleshoot-connection-issues).
Feedback & Support
--------

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,152 @@
// Unattended-Upgrade::Origins-Pattern controls which packages are
// upgraded.
//
// Lines below have the format "keyword=value,...". A
// package will be upgraded only if the values in its metadata match
// all the supplied keywords in a line. (In other words, omitted
// keywords are wild cards.) The keywords originate from the Release
// file, but several aliases are accepted. The accepted keywords are:
// a,archive,suite (eg, "stable")
// c,component (eg, "main", "contrib", "non-free")
// l,label (eg, "Rapsbian", "Raspbian")
// o,origin (eg, "Raspbian", "Unofficial Multimedia Packages")
// n,codename (eg, "jessie", "jessie-updates")
// site (eg, "http.debian.net")
// The available values on the system are printed by the command
// "apt-cache policy", and can be debugged by running
// "unattended-upgrades -d" and looking at the log file.
//
// Within lines unattended-upgrades allows 2 macros whose values are
// derived from /etc/debian_version:
// ${distro_id} Installed origin.
// ${distro_codename} Installed codename (eg, "jessie")
Unattended-Upgrade::Origins-Pattern {
// Codename based matching:
// This will follow the migration of a release through different
// archives (e.g. from testing to stable and later oldstable).
// "o=Raspbian,n=jessie";
// "o=Raspbian,n=jessie-updates";
// "o=Raspbian,n=jessie-proposed-updates";
// "o=Raspbian,n=jessie,l=Raspbian";
// Archive or Suite based matching:
// Note that this will silently match a different release after
// migration to the specified archive (e.g. testing becomes the
// new stable).
// "o=Raspbian,a=stable";
// "o=Raspbian,a=testing";
"origin=Raspbian,codename=${distro_codename},label=Raspbian";
// Additionally, for those running Raspbian on a Raspberry Pi,
// match packages from the Raspberry Pi Foundation as well.
"origin=Raspberry Pi Foundation,codename=${distro_codename},label=Raspberry Pi Foundation";
};
// Python regular expressions, matching packages to exclude from upgrading
Unattended-Upgrade::Package-Blacklist {
// The following matches all packages starting with linux-
// "linux-";
// Use $ to explicitely define the end of a package name. Without
// the $, "libc6" would match all of them.
// "libc6$";
// "libc6-dev$";
// "libc6-i686$";
// Special characters need escaping
// "libstdc\+\+6$";
// The following matches packages like xen-system-amd64, xen-utils-4.1,
// xenstore-utils and libxenstore3.0
// "(lib)?xen(store)?";
// For more information about Python regular expressions, see
// https://docs.python.org/3/howto/regex.html
};
// This option allows you to control if on a unclean dpkg exit
// unattended-upgrades will automatically run
// dpkg --force-confold --configure -a
// The default is true, to ensure updates keep getting installed
//Unattended-Upgrade::AutoFixInterruptedDpkg "true";
// Split the upgrade into the smallest possible chunks so that
// they can be interrupted with SIGTERM. This makes the upgrade
// a bit slower but it has the benefit that shutdown while a upgrade
// is running is possible (with a small delay)
//Unattended-Upgrade::MinimalSteps "true";
// Install all updates when the machine is shutting down
// instead of doing it in the background while the machine is running.
// This will (obviously) make shutdown slower.
// Unattended-upgrades increases logind's InhibitDelayMaxSec to 30s.
// This allows more time for unattended-upgrades to shut down gracefully
// or even install a few packages in InstallOnShutdown mode, but is still a
// big step back from the 30 minutes allowed for InstallOnShutdown previously.
// Users enabling InstallOnShutdown mode are advised to increase
// InhibitDelayMaxSec even further, possibly to 30 minutes.
//Unattended-Upgrade::InstallOnShutdown "false";
// Send email to this address for problems or packages upgrades
// If empty or unset then no email is sent, make sure that you
// have a working mail setup on your system. A package that provides
// 'mailx' must be installed. E.g. "user@example.com"
//Unattended-Upgrade::Mail "";
// Set this value to one of:
// "always", "only-on-error" or "on-change"
// If this is not set, then any legacy MailOnlyOnError (boolean) value
// is used to chose between "only-on-error" and "on-change"
//Unattended-Upgrade::MailReport "on-change";
// Remove unused automatically installed kernel-related packages
// (kernel images, kernel headers and kernel version locked tools).
//Unattended-Upgrade::Remove-Unused-Kernel-Packages "true";
// Do automatic removal of newly unused dependencies after the upgrade
//Unattended-Upgrade::Remove-New-Unused-Dependencies "true";
// Do automatic removal of unused packages after the upgrade
// (equivalent to apt-get autoremove)
//Unattended-Upgrade::Remove-Unused-Dependencies "false";
// Automatically reboot *WITHOUT CONFIRMATION* if
// the file /var/run/reboot-required is found after the upgrade
//Unattended-Upgrade::Automatic-Reboot "false";
// Automatically reboot even if there are users currently logged in
// when Unattended-Upgrade::Automatic-Reboot is set to true
//Unattended-Upgrade::Automatic-Reboot-WithUsers "true";
// If automatic reboot is enabled and needed, reboot at the specific
// time instead of immediately
// Default: "now"
//Unattended-Upgrade::Automatic-Reboot-Time "02:00";
// Use apt bandwidth limit feature, this example limits the download
// speed to 70kb/sec
//Acquire::http::Dl-Limit "70";
// Enable logging to syslog. Default is False
// Unattended-Upgrade::SyslogEnable "false";
// Specify syslog facility. Default is daemon
// Unattended-Upgrade::SyslogFacility "daemon";
// Download and install upgrades only on AC power
// (i.e. skip or gracefully stop updates on battery)
// Unattended-Upgrade::OnlyOnACPower "true";
// Download and install upgrades only on non-metered connection
// (i.e. skip or gracefully stop updates on a metered connection)
// Unattended-Upgrade::Skip-Updates-On-Metered-Connections "true";
// Verbose logging
// Unattended-Upgrade::Verbose "false";
// Print debugging information both in unattended-upgrades and
// in unattended-upgrade-shutdown
// Unattended-Upgrade::Debug "false";
// Allow package downgrade if Pin-Priority exceeds 1000
// Unattended-Upgrade::Allow-downgrade "false";

View file

@ -0,0 +1,162 @@
-----BEGIN PGP PUBLIC KEY BLOCK-----
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
VHxVxJNKrv1//EX/
=qIrL
-----END PGP PUBLIC KEY BLOCK-----

View file

@ -0,0 +1,2 @@
[Service]
ExecReload=/bin/bash -c 'exec /usr/bin/wg syncconf %i <(exec /usr/bin/wg-quick strip %i)'

View file

@ -1,12 +1,57 @@
#!/bin/bash
# PiVPN: Backup Script
# Find the rows and columns. Will default to 80x24 if it can not be detected.
screen_size=$(stty size 2>/dev/null || echo 24 80)
rows=$(echo "$screen_size" | awk '{print $1}')
columns=$(echo "$screen_size" | awk '{print $2}')
# Divide by two so the dialogs take up half of the screen, which looks nice.
r=$(( rows / 2 ))
c=$(( columns / 2 ))
# Unless the screen is tiny
r=$(( r < 20 ? 20 : r ))
c=$(( c < 70 ? 70 : c ))
backupdir=pivpnbackup
date=$(date +%Y%m%d-%H%M%S)
setupVars="/etc/pivpn/setupVars.conf"
setupVarsFile="setupVars.conf"
setupConfigDir="/etc/pivpn"
if [ -r "${setupConfigDir}/wireguard/${setupVarsFile}" ] && [ -r "${setupConfigDir}/openvpn/${setupVarsFile}" ]; then
# Two protocols have been installed, check if the script has passed
# an argument, otherwise ask the user which one he wants to remove
if [ $# -ge 1 ]; then
VPN="$1"
echo "::: Backing up VPN: $VPN"
else
chooseVPNCmd=(whiptail --backtitle "Setup PiVPN" --title "Backup" --separate-output --radiolist "Both OpenVPN and WireGuard are installed, choose a VPN to backup (press space to select):" "${r}" "${c}" 2)
VPNChooseOptions=(WireGuard "" on
OpenVPN "" off)
if VPN=$("${chooseVPNCmd[@]}" "${VPNChooseOptions[@]}" 2>&1 >/dev/tty) ; then
echo "::: Backing up VPN: $VPN"
VPN="${VPN,,}"
else
echo "::: Cancel selected, exiting...."
exit 1
fi
fi
setupVars="${setupConfigDir}/${VPN}/${setupVarsFile}"
else
if [ -r "${setupConfigDir}/wireguard/${setupVarsFile}" ]; then
setupVars="${setupConfigDir}/wireguard/${setupVarsFile}"
elif [ -r "${setupConfigDir}/openvpn/${setupVarsFile}" ]; then
setupVars="${setupConfigDir}/openvpn/${setupVarsFile}"
fi
fi
if [ ! -f "${setupVars}" ]; then
echo "::: Missing setup vars file!"
exit 1
echo "::: Missing setup vars file!"
exit 1
fi
# shellcheck disable=SC1090
@ -28,7 +73,7 @@ backup_openvpn(){
backupzip=$date-pivpnovpnbackup.tgz
# shellcheck disable=SC2210
tar czpf "$install_home"/"$backupdir"/"$backupzip" "$openvpndir" "$ovpnsdir" > /dev/null 2>&1
echo -e "Backup crated to $install_home/$backupdir/$backupzip \nTo restore the backup, follow instructions at:\nhttps://github.com/pivpn/pivpn/wiki/FAQ#how-can-i-migrate-my-configs-to-another-pivpn-instance"
echo -e "Backup created in $install_home/$backupdir/$backupzip \nTo restore the backup, follow instructions at:\nhttps://github.com/pivpn/pivpn/wiki/OpenVPN#how-can-i-migrate-my-configs-to-another-pivpn-instance"
}
@ -39,7 +84,7 @@ backup_wireguard(){
checkbackupdir
backupzip=$date-pivpnwgbackup.tgz
tar czpf "$install_home"/"$backupdir"/"$backupzip" "$wireguarddir" "$configsdir" > /dev/null 2>&1
echo -e "Backup crated to $install_home/$backupdir/$backupzip \nTo restore the backup, follow instructions at:\nhttps://github.com/pivpn/pivpn/wiki/FAQ#how-can-i-migrate-my-configs-to-another-pivpn-instance"
echo -e "Backup created in $install_home/$backupdir/$backupzip \nTo restore the backup, follow instructions at:\nhttps://github.com/pivpn/pivpn/wiki/WireGuard#how-can-i-migrate-my-configs-to-another-pivpn-instance"
}

View file

@ -8,7 +8,15 @@ if [ ! -f "${INDEX}" ]; then
exit 1
fi
printf ": NOTE : The first entry should always be your valid server!\n"
EASYRSA="/etc/openvpn/easy-rsa/easyrsa"
if [ ! -f "${EASYRSA}" ]; then
echo "The file: $EASYRSA was not found!"
exit 1
fi
$EASYRSA update-db >> /dev/null 2>&1
printf ": NOTE : The first entry is your server, which should always be valid!\n"
printf "\\n"
printf "\\e[1m::: Certificate Status List :::\\e[0m\\n"
{
@ -16,15 +24,17 @@ printf "\\e[4mStatus\\e[0m \t \\e[4mName\\e[0m\\e[0m \t \\e[4mExpiration\\e[
while read -r line || [ -n "$line" ]; do
STATUS=$(echo "$line" | awk '{print $1}')
NAME=$(echo "$line" | awk '{print $5}' | awk -FCN= '{print $2}')
NAME=$(echo "$line" | awk -FCN= '{print $2}')
EXPD=$(echo "$line" | awk '{if (length($2) == 15) print $2; else print "20"$2}' | cut -b 1-8 | date +"%b %d %Y" -f -)
if [ "${STATUS}" == "V" ]; then
printf "Valid \t %s \t %s\\n" "$NAME" "$EXPD"
printf "Valid \t %s \t %s\\n" "$(echo -e "$NAME")" "$EXPD"
elif [ "${STATUS}" == "R" ]; then
printf "Revoked \t %s \t %s\\n" "$NAME" "$EXPD"
printf "Revoked \t %s \t %s\\n" "$(echo -e "$NAME")" "$EXPD"
elif [ "${STATUS}" == "E" ]; then
printf "Expired \t %s \t %s\\n" "$(echo -e "$NAME")" "$EXPD"
else
printf "Unknown \t %s \t %s\\n" "$NAME" "$EXPD"
printf "Unknown \t %s \t %s\\n" "$(echo -e "$NAME")" "$EXPD"
fi
done <${INDEX}

View file

@ -1,7 +1,7 @@
#!/bin/bash
# Create OVPN Client
# Default Variable Declarations
setupVars="/etc/pivpn/setupVars.conf"
setupVars="/etc/pivpn/openvpn/setupVars.conf"
DEFAULT="Default.txt"
FILEEXT=".ovpn"
CRT=".crt"
@ -20,7 +20,7 @@ source "${setupVars}"
helpFunc() {
echo "::: Create a client ovpn profile, optional nopass"
echo ":::"
echo "::: Usage: pivpn <-a|add> [-n|--name <arg>] [-p|--password <arg>]|[nopass] [-d|--days <number>] [-b|--bitwarden] [-i|--iOS] [-h|--help]"
echo "::: Usage: pivpn <-a|add> [-n|--name <arg>] [-p|--password <arg>]|[nopass] [-d|--days <number>] [-b|--bitwarden] [-i|--iOS] [-o|--ovpn] [-h|--help]"
echo ":::"
echo "::: Commands:"
echo "::: [none] Interactive mode"
@ -30,6 +30,7 @@ helpFunc() {
echo "::: -d,--days Expire the certificate after specified number of days (default: 1080)"
echo "::: -b,--bitwarden Create and save a client through Bitwarden"
echo "::: -i,--iOS Generate a certificate that leverages iOS keychain"
echo "::: -o,--ovpn Regenerate a .ovpn config file for an existing client"
echo "::: -h,--help Show this help dialog"
}
@ -97,6 +98,10 @@ do
echo "Bitwarden not found, please install bitwarden"
exit 1
fi
;;
-o|--ovpn)
GENOVPNONLY=1
;;
*)
echo "Error: Got an unexpected argument '$1'"
@ -208,8 +213,8 @@ function keyPASS() {
set timeout -1
set env(EASYRSA_CERT_EXPIRE) "${DAYS}"
spawn ./easyrsa build-client-full "${NAME}"
expect "Enter PEM pass phrase" { send -- "${PASSWD}\r" }
expect "Verifying - Enter PEM pass phrase" { send -- "${PASSWD}\r" }
expect "Enter PEM pass phrase" { sleep 0.1; send -- "${PASSWD}\r" }
expect "Verifying - Enter PEM pass phrase" { sleep 0.1; send -- "${PASSWD}\r" }
expect eof
EOF
cd pki || exit
@ -243,59 +248,68 @@ if [[ "${NAME}" =~ [^a-zA-Z0-9.@_-] ]]; then
exit 1
fi
if [[ "${NAME}" =~ ^[0-9]+$ ]]; then
echo "Names cannot be integers."
exit 1
fi
if [[ -z "${NAME}" ]]; then
echo "You cannot leave the name blank."
exit 1
fi
# Check if name is already in use
while read -r line || [ -n "${line}" ]; do
STATUS=$(echo "$line" | awk '{print $1}')
if [ "${STATUS}" == "V" ]; then
CERT=$(echo "$line" | sed -e 's:.*/CN=::')
if [ "${CERT}" == "${NAME}" ]; then
INUSE="1"
break
fi
fi
done <${INDEX}
if [ "${INUSE}" == "1" ]; then
printf "\n!! This name is already in use by a Valid Certificate."
printf "\nPlease choose another name or revoke this certificate first.\n"
exit 1
fi
# Check if name is reserved
if [ "${NAME}" == "ta" ] || [ "${NAME}" == "server" ] || [ "${NAME}" == "ca" ]; then
echo "Sorry, this is in use by the server and cannot be used by clients."
exit 1
fi
#As of EasyRSA 3.0.6, by default certificates last 1080 days, see https://github.com/OpenVPN/easy-rsa/blob/6b7b6bf1f0d3c9362b5618ad18c66677351cacd1/easyrsa3/vars.example
if [ -z "${DAYS}" ]; then
read -r -e -p "How many days should the certificate last? " -i 1080 DAYS
fi
if [[ ! "$DAYS" =~ ^[0-9]+$ ]] || [ "$DAYS" -lt 1 ] || [ "$DAYS" -gt 3650 ]; then
#The CRL lasts 3650 days so it doesn't make much sense that certificates would last longer
echo "Please input a valid number of days, between 1 and 3650 inclusive."
exit 1
fi
cd /etc/openvpn/easy-rsa || exit
if [[ "${NO_PASS}" =~ "1" ]]; then
if [[ -n "${PASSWD}" ]]; then
echo "Both nopass and password arguments passed to the script. Please use either one."
exit 1
else
keynoPASS
fi
if [ "${GENOVPNONLY}" == "1" ]; then
# Generate .ovpn configuration file
cd /etc/openvpn/easy-rsa/pki || exit
else
keyPASS
# Check if name is already in use
while read -r line || [ -n "${line}" ]; do
STATUS=$(echo "$line" | awk '{print $1}')
if [ "${STATUS}" == "V" ]; then
CERT=$(echo "$line" | sed -e 's:.*/CN=::')
if [ "${CERT}" == "${NAME}" ]; then
INUSE="1"
break
fi
fi
done <${INDEX}
if [ "${INUSE}" == "1" ]; then
printf "\n!! This name is already in use by a Valid Certificate."
printf "\nPlease choose another name or revoke this certificate first.\n"
exit 1
fi
# Check if name is reserved
if [ "${NAME}" == "ta" ] || [ "${NAME}" == "server" ] || [ "${NAME}" == "ca" ]; then
echo "Sorry, this is in use by the server and cannot be used by clients."
exit 1
fi
#As of EasyRSA 3.0.6, by default certificates last 1080 days, see https://github.com/OpenVPN/easy-rsa/blob/6b7b6bf1f0d3c9362b5618ad18c66677351cacd1/easyrsa3/vars.example
if [ -z "${DAYS}" ]; then
read -r -e -p "How many days should the certificate last? " -i 1080 DAYS
fi
if [[ ! "$DAYS" =~ ^[0-9]+$ ]] || [ "$DAYS" -lt 1 ] || [ "$DAYS" -gt 3650 ]; then
#The CRL lasts 3650 days so it doesn't make much sense that certificates would last longer
echo "Please input a valid number of days, between 1 and 3650 inclusive."
exit 1
fi
cd /etc/openvpn/easy-rsa || exit
if [[ "${NO_PASS}" =~ "1" ]]; then
if [[ -n "${PASSWD}" ]]; then
echo "Both nopass and password arguments passed to the script. Please use either one."
exit 1
else
keynoPASS
fi
else
keyPASS
fi
fi
#1st Verify that clients Public Key Exists

View file

@ -10,62 +10,56 @@ if [[ ! $EUID -eq 0 ]];then
fi
fi
scriptDir="/opt/pivpn"
vpn="openvpn"
function makeOVPNFunc {
shift
$SUDO /opt/pivpn/makeOVPN.sh "$@"
$SUDO ${scriptDir}/${vpn}/makeOVPN.sh "$@"
exit 0
}
function listClientsFunc {
shift
$SUDO /opt/pivpn/clientStat.sh "$@"
$SUDO ${scriptDir}/${vpn}/clientStat.sh "$@"
exit 0
}
function listOVPNFunc {
$SUDO /opt/pivpn/listOVPN.sh
$SUDO ${scriptDir}/${vpn}/listOVPN.sh
exit 0
}
function debugFunc {
echo "::: Generating Debug Output"
$SUDO /opt/pivpn/pivpnDebug.sh | tee /tmp/debug.txt
$SUDO ${scriptDir}/${vpn}/pivpnDebug.sh | tee /tmp/debug.log
echo "::: "
echo "::: Debug output completed above."
echo "::: Copy saved to /tmp/debug.txt"
echo "::: Copy saved to /tmp/debug.log"
echo "::: "
exit 0
}
function removeOVPNFunc {
shift
$SUDO /opt/pivpn/removeOVPN.sh "$@"
$SUDO ${scriptDir}/${vpn}/removeOVPN.sh "$@"
exit 0
}
function uninstallFunc {
$SUDO /opt/pivpn/uninstall.sh
$SUDO ${scriptDir}/uninstall.sh "${vpn}"
exit 0
}
function versionFunc {
printf "\e[1mVersion 1.9\e[0m\n"
}
function update {
shift
$SUDO /opt/pivpn/update.sh "$@"
$SUDO ${scriptDir}/update.sh "$@"
exit 0
}
function backup {
$SUDO /opt/pivpn/backup.sh
$SUDO ${scriptDir}/backup.sh "${vpn}"
exit 0
}
@ -100,7 +94,6 @@ case "$1" in
"-r" | "revoke" ) removeOVPNFunc "$@";;
"-h" | "help" ) helpFunc;;
"-u" | "uninstall" ) uninstallFunc;;
"-v" ) versionFunc;;
"-up"| "update" ) update "$@" ;;
"-bk"| "backup" ) backup;;
* ) helpFunc;;

View file

@ -1,7 +1,7 @@
#!/usr/bin/env bash
# This scripts runs as root
setupVars="/etc/pivpn/setupVars.conf"
setupVars="/etc/pivpn/openvpn/setupVars.conf"
if [ ! -f "${setupVars}" ]; then
echo "::: Missing setup vars file!"
@ -13,10 +13,10 @@ source "${setupVars}"
echo -e "::::\t\t\e[4mPiVPN debug\e[0m\t\t ::::"
printf "=============================================\n"
echo -e "::::\t\t\e[4mLatest commit\e[0m\t\t ::::"
git --git-dir /etc/.pivpn/.git log -n 1
git --git-dir /usr/local/src/pivpn/.git log -n 1
printf "=============================================\n"
echo -e "::::\t \e[4mInstallation settings\e[0m \t ::::"
sed "s/$pivpnHOST/REDACTED/" < /etc/pivpn/setupVars.conf
sed "s/$pivpnHOST/REDACTED/" < ${setupVars}
printf "=============================================\n"
echo -e ":::: \e[4mServer configuration shown below\e[0m ::::"
cat /etc/openvpn/server.conf
@ -28,35 +28,21 @@ echo -e ":::: \t\e[4mRecursive list of files in\e[0m\t ::::\n::: \e[4m/etc/openv
ls -LR /etc/openvpn/easy-rsa/pki/ -Ireqs -Icerts_by_serial
printf "=============================================\n"
echo -e "::::\t\t\e[4mSelf check\e[0m\t\t ::::"
/opt/pivpn/self_check.sh
/opt/pivpn/self_check.sh ${VPN}
printf "=============================================\n"
echo -e ":::: Having trouble connecting? Take a look at the FAQ:"
echo -e ":::: \e[1mhttps://github.com/pivpn/pivpn/wiki/FAQ\e[0m"
printf "=============================================\n"
echo -e ":::: \e[4mSnippet of the server log\e[0m ::::"
tail -20 /var/log/openvpn.log > /tmp/snippet
OVPNLOG="$(tail -n 20 /var/log/openvpn.log)"
# Regular expession taken from https://superuser.com/a/202835, it will match invalid IPs
# like 123.456.789.012 but it's fine since the log only contains valid ones.
declare -a IPS_TO_HIDE=($(grepcidr -v 10.0.0.0/8,172.16.0.0/12,192.168.0.0/16 /tmp/snippet | grep -oE '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | uniq))
declare -a IPS_TO_HIDE=($(grepcidr -v 10.0.0.0/8,172.16.0.0/12,192.168.0.0/16 <<< "$OVPNLOG" | grep -oE '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | uniq))
for IP in "${IPS_TO_HIDE[@]}"; do
sed -i "s/$IP/REDACTED/g" /tmp/snippet
OVPNLOG="${OVPNLOG//"$IP"/REDACTED}"
done
cat /tmp/snippet
rm /tmp/snippet
echo "$OVPNLOG"
printf "=============================================\n"
echo -e "::::\t\t\e[4mDebug complete\e[0m\t\t ::::"
# Telekom Hybrid Check
wget -O /tmp/hybcheck http://speedport.ip &>/dev/null
if grep -Fq "Speedport Pro" /tmp/hybcheck || grep -Fq "Speedport Hybrid" /tmp/hybcheck
then
printf ":::\t\t\t\t\t:::\n::\tTelekom Hybrid Check\t\t ::\n:::\t\t\t\t\t:::\n"
echo "Are you using Telekom Hybrid (found a hybrid compatible router)?"
echo "If yes and you have problems with the connections you can test the following:"
echo "Add 'tun-mtu 1316' in /etc/openvpn/easy-rsa/pki/Default.txt to set a hybrid compatible MTU size (new .ovpn files)."
echo "For already existing .ovpn files 'tun-mtu 1316' can also be inserted there manually."
echo "With Telekom hybrid connections, you may have to experiment a little with MTU (tun-mtu, link-mtu and mssfix)."
fi
rm /tmp/hybcheck

View file

@ -1,7 +1,7 @@
#!/usr/bin/env bash
# PiVPN: revoke client script
setupVars="/etc/pivpn/setupVars.conf"
setupVars="/etc/pivpn/openvpn/setupVars.conf"
INDEX="/etc/openvpn/easy-rsa/pki/index.txt"
if [ ! -f "${setupVars}" ]; then
@ -14,11 +14,12 @@ source "${setupVars}"
helpFunc() {
echo "::: Revoke a client ovpn profile"
echo ":::"
echo "::: Usage: pivpn <-r|revoke> [-h|--help] [<client-1>] ... [<client-n>] ..."
echo "::: Usage: pivpn <-r|revoke> [-y|--yes] [-h|--help] [<client-1>] ... [<client-n>] ..."
echo ":::"
echo "::: Commands:"
echo "::: [none] Interactive mode"
echo "::: <client> Client(s) to to revoke"
echo "::: -y,--yes Remove Client(s) without confirmation"
echo "::: -h,--help Show this help dialog"
}
@ -31,6 +32,9 @@ do
helpFunc
exit 0
;;
-y|--yes)
CONFIRM=true
;;
*)
CERTS_TO_REVOKE+=("$1")
;;
@ -52,17 +56,23 @@ if [[ -z "${CERTS_TO_REVOKE}" ]]; then
STATUS=$(echo "$line" | awk '{print $1}')
if [[ "${STATUS}" = "V" ]]; then
NAME=$(echo "$line" | sed -e 's:.*/CN=::')
CERTS[$i]=${NAME}
if [ "$i" != 0 ]; then
# Prevent printing "server" certificate
printf " %s\n" "$NAME"
CERTS[$i]=$(echo -e "${NAME}")
fi
let i=i+1
fi
done <${INDEX}
i=1
len=${#CERTS[@]}
while [ $i -le ${len} ]; do
printf "%0${#len}s) %s\r\n" ${i} ${CERTS[(($i))]}
((i++))
done
printf "\n"
echo -n "::: Please enter the Name of the client to be revoked from the list above: "
echo -n "::: Please enter the Index/Name of the client to be revoked from the list above: "
read -r NAME
if [[ -z "${NAME}" ]]; then
@ -70,6 +80,11 @@ if [[ -z "${CERTS_TO_REVOKE}" ]]; then
exit 1
fi
re='^[0-9]+$'
if [[ ${NAME} =~ $re ]] ; then
NAME=${CERTS[$(($NAME))]}
fi
for((x=1;x<=i;++x)); do
if [ "${CERTS[$x]}" = "${NAME}" ]; then
VALID=1
@ -87,7 +102,7 @@ else
while read -r line || [ -n "$line" ]; do
STATUS=$(echo "$line" | awk '{print $1}')
if [[ "${STATUS}" = "V" ]]; then
NAME=$(echo "$line" | sed -e 's:.*/CN=::')
NAME=$(echo -e "$line" | sed -e 's:.*/CN=::')
CERTS[$i]=${NAME}
let i=i+1
fi
@ -111,31 +126,38 @@ fi
cd /etc/openvpn/easy-rsa || exit
for (( ii = 0; ii < ${#CERTS_TO_REVOKE[@]}; ii++)); do
printf "\n::: Revoking certificate '"%s"'.\n" "${CERTS_TO_REVOKE[ii]}"
./easyrsa --batch revoke "${CERTS_TO_REVOKE[ii]}"
./easyrsa gen-crl
printf "\n::: Certificate revoked, and CRL file updated.\n"
printf "::: Removing certs and client configuration for this profile.\n"
rm -rf "pki/reqs/${CERTS_TO_REVOKE[ii]}.req"
rm -rf "pki/private/${CERTS_TO_REVOKE[ii]}.key"
rm -rf "pki/issued/${CERTS_TO_REVOKE[ii]}.crt"
if [ -n "$CONFIRM" ]; then
REPLY="y"
else
read -r -p "Do you really want to revoke ${CERTS_TO_REVOKE[ii]}? [Y/n] "
fi
if [[ $REPLY =~ ^[Yy]$ ]]; then
printf "\n::: Revoking certificate '"%s"'.\n" "${CERTS_TO_REVOKE[ii]}"
./easyrsa --batch revoke "${CERTS_TO_REVOKE[ii]}"
./easyrsa gen-crl
printf "\n::: Certificate revoked, and CRL file updated.\n"
printf "::: Removing certs and client configuration for this profile.\n"
rm -rf "pki/reqs/${CERTS_TO_REVOKE[ii]}.req"
rm -rf "pki/private/${CERTS_TO_REVOKE[ii]}.key"
rm -rf "pki/issued/${CERTS_TO_REVOKE[ii]}.crt"
# Grab the client IP address
NET_REDUCED="${pivpnNET::-2}"
STATIC_IP=$(grep -v "^#" /etc/openvpn/ccd/"${CERTS_TO_REVOKE[ii]}" | grep -w ifconfig-push | grep -oE "${NET_REDUCED}\.[0-9]{1,3}")
rm -rf /etc/openvpn/ccd/"${CERTS_TO_REVOKE[ii]}"
# Grab the client IP address
NET_REDUCED="${pivpnNET::-2}"
STATIC_IP=$(grep -v "^#" /etc/openvpn/ccd/"${CERTS_TO_REVOKE[ii]}" | grep -w ifconfig-push | grep -oE "${NET_REDUCED}\.[0-9]{1,3}")
rm -rf /etc/openvpn/ccd/"${CERTS_TO_REVOKE[ii]}"
rm -rf "${install_home}/ovpns/${CERTS_TO_REVOKE[ii]}.ovpn"
rm -rf "/etc/openvpn/easy-rsa/pki/${CERTS_TO_REVOKE[ii]}.ovpn"
cp /etc/openvpn/easy-rsa/pki/crl.pem /etc/openvpn/crl.pem
rm -rf "${install_home}/ovpns/${CERTS_TO_REVOKE[ii]}.ovpn"
rm -rf "/etc/openvpn/easy-rsa/pki/${CERTS_TO_REVOKE[ii]}.ovpn"
cp /etc/openvpn/easy-rsa/pki/crl.pem /etc/openvpn/crl.pem
# If using Pi-hole, remove the client from the hosts file
if [ -f /etc/pivpn/hosts.openvpn ]; then
sed "\#${STATIC_IP} ${CERTS_TO_REVOKE[ii]}.pivpn#d" -i /etc/pivpn/hosts.openvpn
if killall -SIGHUP pihole-FTL; then
echo "::: Updated hosts file for Pi-hole"
else
echo "::: Failed to reload pihole-FTL configuration"
# If using Pi-hole, remove the client from the hosts file
if [ -f /etc/pivpn/hosts.openvpn ]; then
sed "\#${STATIC_IP} ${CERTS_TO_REVOKE[ii]}.pivpn#d" -i /etc/pivpn/hosts.openvpn
if killall -SIGHUP pihole-FTL; then
echo "::: Updated hosts file for Pi-hole"
else
echo "::: Failed to reload pihole-FTL configuration"
fi
fi
fi
done

49
scripts/pivpn Executable file
View file

@ -0,0 +1,49 @@
#!/bin/bash
# Must be root to use this tool
if [ $EUID -ne 0 ];then
if dpkg-query -s sudo &> /dev/null; then
export SUDO="sudo"
else
echo "::: Please install sudo or run this as root."
exit 1
fi
fi
scriptDir="/opt/pivpn"
uninstallServer(){
$SUDO ${scriptDir}/uninstall.sh
exit 0
}
backup(){
$SUDO ${scriptDir}/backup.sh
exit 0
}
showHelp(){
echo "::: To pass off to the pivpn command for each protocol"
echo ":::"
echo "::: Usage: pivpn wg <command> [option]"
echo "::: Usage: pivpn ovpn <command> [option]"
echo ":::"
echo "::: -h, help Show this help dialog"
echo "::: -u, uninstall Uninstall pivpn from your system!"
echo "::: -bk, backup Backup VPN configs and user profiles"
exit 0
}
if [ $# = 0 ]; then
showHelp
fi
# Handle redirecting to specific functions based on arguments
case "$1" in
wg ) "${scriptDir}/wireguard/pivpn.sh" "${@:2}";;
ovpn ) "${scriptDir}/openvpn/pivpn.sh" "${@:2}";;
"-h" | "help" ) showHelp;;
"-u" | "uninstall" ) uninstallServer;;
"-bk" | "backup" ) backup ;;
* ) showHelp;;
esac

View file

@ -1,6 +1,8 @@
#!/bin/bash
setupVars="/etc/pivpn/setupVars.conf"
# dual protocol, VPN type supplied as $1
VPN=$1
setupVars="/etc/pivpn/${VPN}/setupVars.conf"
ERR=0
if [ ! -f "${setupVars}" ]; then

View file

@ -4,19 +4,6 @@
### FIXME: global: config storage, refactor all scripts to adhere to the storage
### FIXME: use variables where appropriate, reduce magic numbers by 99.9%, at least.
PKG_MANAGER="apt-get"
UPDATE_PKG_CACHE="${PKG_MANAGER} update"
dnsmasqConfig="/etc/dnsmasq.d/02-pivpn.conf"
setupVars="/etc/pivpn/setupVars.conf"
if [ ! -f "${setupVars}" ]; then
echo "::: Missing setup vars file!"
exit 1
fi
# shellcheck disable=SC1090
source "${setupVars}"
# Find the rows and columns. Will default to 80x24 if it can not be detected.
screen_size=$(stty size 2>/dev/null || echo 24 80)
rows=$(echo "$screen_size" | awk '{print $1}')
@ -29,6 +16,55 @@ c=$(( columns / 2 ))
r=$(( r < 20 ? 20 : r ))
c=$(( c < 70 ? 70 : c ))
PKG_MANAGER="apt-get"
UPDATE_PKG_CACHE="${PKG_MANAGER} update"
dnsmasqConfig="/etc/dnsmasq.d/02-pivpn.conf"
setupVarsFile="setupVars.conf"
setupConfigDir="/etc/pivpn"
pivpnFilesDir="/usr/local/src/pivpn"
pivpnScriptDir="/opt/pivpn"
if [ -r "${setupConfigDir}/wireguard/${setupVarsFile}" ] && [ -r "${setupConfigDir}/openvpn/${setupVarsFile}" ]; then
vpnStillExists=1
# Two protocols have been installed, check if the script has passed
# an argument, otherwise ask the user which one he wants to remove
if [ $# -ge 1 ]; then
VPN="$1"
echo "::: Uninstalling VPN: $VPN"
else
chooseVPNCmd=(whiptail --backtitle "Setup PiVPN" --title "Uninstall" --separate-output --radiolist "Both OpenVPN and WireGuard are installed, choose a VPN to uninstall (press space to select):" "${r}" "${c}" 2)
VPNChooseOptions=(WireGuard "" on
OpenVPN "" off)
if VPN=$("${chooseVPNCmd[@]}" "${VPNChooseOptions[@]}" 2>&1 >/dev/tty) ; then
echo "::: Uninstalling VPN: $VPN"
VPN="${VPN,,}"
else
echo "::: Cancel selected, exiting...."
exit 1
fi
fi
setupVars="${setupConfigDir}/${VPN}/${setupVarsFile}"
else
vpnStillExists=0
if [ -r "${setupConfigDir}/wireguard/${setupVarsFile}" ]; then
setupVars="${setupConfigDir}/wireguard/${setupVarsFile}"
elif [ -r "${setupConfigDir}/openvpn/${setupVarsFile}" ]; then
setupVars="${setupConfigDir}/openvpn/${setupVarsFile}"
fi
fi
if [ ! -f "${setupVars}" ]; then
echo "::: Missing setup vars file!"
exit 1
fi
# shellcheck disable=SC1090
source "${setupVars}"
### FIXME: introduce global lib
spinner(){
local pid=$1
@ -65,7 +101,7 @@ removeAll(){
ufw delete allow "${pivpnPORT}"/"${pivpnPROTO}" > /dev/null
### FIXME: SC2154
ufw route delete allow in on "${pivpnDEV}" from "${pivpnNET}/${subnetClass}" out on "${IPv4dev}" to any > /dev/null
sed -z "s/*nat\\n:POSTROUTING ACCEPT \\[0:0\\]\\n-I POSTROUTING -s ${pivpnNET}\\/${subnetClass} -o ${IPv4dev} -j MASQUERADE -m comment --comment ${VPN}-nat-rule\\nCOMMIT\\n\\n//" -i /etc/ufw/before.rules
sed "/-I POSTROUTING -s ${pivpnNET}\\/${subnetClass} -o ${IPv4dev} -j MASQUERADE -m comment --comment ${VPN}-nat-rule/d" -i /etc/ufw/before.rules
iptables -t nat -D POSTROUTING -s "${pivpnNET}/${subnetClass}" -o "${IPv4dev}" -j MASQUERADE -m comment --comment "${VPN}-nat-rule"
ufw reload &> /dev/null
@ -86,8 +122,10 @@ removeAll(){
fi
# Disable IPv4 forwarding
sed -i '/net.ipv4.ip_forward=1/c\#net.ipv4.ip_forward=1' /etc/sysctl.conf
sysctl -p
if [ "${vpnStillExists}" -eq 0 ]; then
sed -i '/net.ipv4.ip_forward=1/c\#net.ipv4.ip_forward=1' /etc/sysctl.conf
sysctl -p
fi
# Purge dependencies
echo "::: Purge dependencies..."
@ -96,17 +134,21 @@ removeAll(){
while true; do
read -rp "::: Do you wish to remove $i from your system? [Y/n]: " yn
case $yn in
[Yy]* ) if [ "${i}" = "wireguard" ]; then
[Yy]* ) if [ "${i}" = "wireguard-tools" ]; then
# On Debian and Raspbian, remove the bullseye repo. On Ubuntu, remove the PPA.
if [ "$PLAT" = "Debian" ] || [ "$PLAT" = "Raspbian" ]; then
rm -f /etc/apt/sources.list.d/pivpn-bullseye.list
# The bullseye repo may not exist if wireguard was available at the
# time of installation.
if [ -f /etc/apt/sources.list.d/pivpn-bullseye-repo.list ]; then
echo "::: Removing Debian Bullseye repo..."
rm -f /etc/apt/sources.list.d/pivpn-bullseye-repo.list
rm -f /etc/apt/preferences.d/pivpn-limit-bullseye
elif [ "$PLAT" = "Ubuntu" ]; then
add-apt-repository ppa:wireguard/wireguard -r -y
echo "::: Updating package cache..."
${UPDATE_PKG_CACHE} &> /dev/null & spinner $!
fi
if [ -f /etc/systemd/system/wg-quick@.service.d/override.conf ]; then
rm -f /etc/systemd/system/wg-quick@.service.d/override.conf
fi
echo "::: Updating package cache..."
${UPDATE_PKG_CACHE} &> /dev/null & spinner $!
elif [ "${i}" = "unattended-upgrades" ]; then
@ -116,7 +158,8 @@ removeAll(){
elif [ "${i}" = "openvpn" ]; then
if [ "$PLAT" = "Debian" ] || [ "$PLAT" = "Ubuntu" ]; then
if [ -f /etc/apt/sources.list.d/pivpn-openvpn-repo.list ]; then
echo "::: Removing OpenVPN software repo..."
rm -f /etc/apt/sources.list.d/pivpn-openvpn-repo.list
echo "::: Updating package cache..."
${UPDATE_PKG_CACHE} &> /dev/null & spinner $!
@ -143,22 +186,12 @@ removeAll(){
printf "::: Auto cleaning remaining dependencies..."
$PKG_MANAGER -y autoclean &> /dev/null & spinner $!; printf "done!\\n";
echo ":::"
# Removing pivpn files
echo "::: Removing pivpn system files..."
if [ -f "$dnsmasqConfig" ]; then
rm -f "$dnsmasqConfig"
pihole restartdns
fi
rm -rf /opt/pivpn
rm -rf /etc/.pivpn
rm -rf /etc/pivpn
rm -f /var/log/*pivpn*
rm -f /usr/local/bin/pivpn
rm -f /etc/bash_completion.d/pivpn
echo ":::"
echo "::: Removing VPN configuration files..."
@ -177,6 +210,35 @@ removeAll(){
rm -rf "$install_home/ovpns"
fi
if [ "${vpnStillExists}" -eq 0 ]; then
echo ":::"
echo "::: Removing pivpn system files..."
rm -rf "${setupConfigDir}"
rm -rf "${pivpnFilesDir}"
rm -f /var/log/*pivpn*
rm -f /etc/bash_completion.d/pivpn
unlink "${pivpnScriptDir}"
unlink /usr/local/bin/pivpn
else
if [[ ${VPN} == 'wireguard' ]]; then
othervpn='openvpn'
else
othervpn='wireguard'
fi
echo ":::"
echo "::: Other VPN ${othervpn} still present, so not"
echo "::: removing pivpn system files"
rm -f "${setupConfigDir}/${VPN}/${setupVarsFile}"
# Restore single pivpn script and bash completion for the remaining VPN
$SUDO unlink /usr/local/bin/pivpn
$SUDO ln -s -T "${pivpnFilesDir}/scripts/${othervpn}/pivpn.sh" /usr/local/bin/pivpn
$SUDO ln -s -T "${pivpnFilesDir}/scripts/${othervpn}/bash-completion" /etc/bash_completion.d/pivpn
# shellcheck disable=SC1091
. /etc/bash_completion.d/pivpn
fi
echo ":::"
printf "::: Finished removing PiVPN from your system.\\n"
printf "::: Reinstall by simpling running\\n:::\\n:::\\tcurl -L https://install.pivpn.io | bash\\n:::\\n::: at any time!\\n:::\\n"

View file

@ -6,7 +6,36 @@ pivpnrepo="https://github.com/pivpn/pivpn.git"
pivpnlocalpath="/etc/.pivpn"
pivpnscripts="/opt/pivpn/"
bashcompletiondir="/etc/bash_completion.d/"
setupVars="/etc/pivpn/setupVars.conf"
# Find the rows and columns. Will default to 80x24 if it can not be detected.
screen_size=$(stty size 2>/dev/null || echo 24 80)
rows=$(echo "$screen_size" | awk '{print $1}')
columns=$(echo "$screen_size" | awk '{print $2}')
# Divide by two so the dialogs take up half of the screen, which looks nice.
r=$(( rows / 2 ))
c=$(( columns / 2 ))
# Unless the screen is tiny
r=$(( r < 20 ? 20 : r ))
c=$(( c < 70 ? 70 : c ))
echo "::: The updating functionality for PiVPN scripts is temporarily disabled"
echo "::: To keep the VPN (and the system) up to date, use 'apt update' and 'apt upgrade'"
exit 0
chooseVPNCmd=(whiptail --backtitle "Setup PiVPN" --title "Installation mode" --separate-output --radiolist "Choose a VPN to update (press space to select):" "${r}" "${c}" 2)
VPNChooseOptions=(WireGuard "" on
OpenVPN "" off)
if VPN=$("${chooseVPNCmd[@]}" "${VPNChooseOptions[@]}" 2>&1 >/dev/tty) ; then
echo "::: Using VPN: $VPN"
VPN="${VPN,,}"
else
echo "::: Cancel selected, exiting...."
exit 1
fi
setupVars="/etc/pivpn/${VPN}/setupVars.conf"
if [ ! -f "${setupVars}" ]; then
echo "::: Missing setup vars file!"

View file

@ -4,8 +4,8 @@ _pivpn()
COMPREPLY=()
cur="${COMP_WORDS[COMP_CWORD]}"
prev="${COMP_WORDS[COMP_CWORD-1]}"
dashopts="-a -c -d -l -qr -r -h -u -up -wg -bk"
opts="add clients debug list qrcode remove help uninstall update wgupdate backup"
dashopts="-a -c -d -l -qr -r -h -u -up -bk -off -on"
opts="add clients debug list qrcode remove help uninstall update backup (temp) off (temp) on"
if [ "${#COMP_WORDS[@]}" -eq 2 ]
then
if [[ ${cur} == -* ]] ; then

View file

@ -2,6 +2,7 @@
# PiVPN: client status script
CLIENTS_FILE="/etc/wireguard/configs/clients.txt"
CONF_FILE="/etc/wireguard/wg0.conf"
if [ ! -s "$CLIENTS_FILE" ]; then
echo "::: There are no clients to list"
@ -36,33 +37,37 @@ listClients(){
printf "\e[4mName\e[0m \t \e[4mRemote IP\e[0m \t \e[4mVirtual IP\e[0m \t \e[4mBytes Received\e[0m \t \e[4mBytes Sent\e[0m \t \e[4mLast Seen\e[0m\n"
while IFS= read -r LINE; do
PUBLIC_KEY="$(awk '{ print $1 }' <<< "$LINE")"
REMOTE_IP="$(awk '{ print $3 }' <<< "$LINE")"
VIRTUAL_IP="$(awk '{ print $4 }' <<< "$LINE")"
BYTES_RECEIVED="$(awk '{ print $6 }' <<< "$LINE")"
BYTES_SENT="$(awk '{ print $7 }' <<< "$LINE")"
LAST_SEEN="$(awk '{ print $5 }' <<< "$LINE")"
CLIENT_NAME="$(grep "$PUBLIC_KEY" "$CLIENTS_FILE" | awk '{ print $1 }')"
if [ "$HR" = 1 ]; then
if [ "$LAST_SEEN" -ne 0 ]; then
printf "%s \t %s \t %s \t %s \t %s \t %s\n" "$CLIENT_NAME" "$REMOTE_IP" "${VIRTUAL_IP/\/32/}" "$(hr "$BYTES_RECEIVED")" "$(hr "$BYTES_SENT")" "$(date -d @"$LAST_SEEN" '+%b %d %Y - %T')"
if [ -n "${LINE}" ]; then
PUBLIC_KEY="$(awk '{ print $1 }' <<< "$LINE")"
REMOTE_IP="$(awk '{ print $3 }' <<< "$LINE")"
VIRTUAL_IP="$(awk '{ print $4 }' <<< "$LINE")"
BYTES_RECEIVED="$(awk '{ print $6 }' <<< "$LINE")"
BYTES_SENT="$(awk '{ print $7 }' <<< "$LINE")"
LAST_SEEN="$(awk '{ print $5 }' <<< "$LINE")"
CLIENT_NAME="$(grep "$PUBLIC_KEY" "$CLIENTS_FILE" | awk '{ print $1 }')"
if [ "$HR" = 1 ]; then
if [ "$LAST_SEEN" -ne 0 ]; then
printf "%s \t %s \t %s \t %s \t %s \t %s\n" "$CLIENT_NAME" "$REMOTE_IP" "${VIRTUAL_IP/\/32/}" "$(hr "$BYTES_RECEIVED")" "$(hr "$BYTES_SENT")" "$(date -d @"$LAST_SEEN" '+%b %d %Y - %T')"
else
printf "%s \t %s \t %s \t %s \t %s \t %s\n" "$CLIENT_NAME" "$REMOTE_IP" "${VIRTUAL_IP/\/32/}" "$(hr "$BYTES_RECEIVED")" "$(hr "$BYTES_SENT")" "(not yet)"
fi
else
printf "%s \t %s \t %s \t %s \t %s \t %s\n" "$CLIENT_NAME" "$REMOTE_IP" "${VIRTUAL_IP/\/32/}" "$(hr "$BYTES_RECEIVED")" "$(hr "$BYTES_SENT")" "(not yet)"
fi
else
if [ "$LAST_SEEN" -ne 0 ]; then
printf "%s \t %s \t %s \t %'d \t %'d \t %s\n" "$CLIENT_NAME" "$REMOTE_IP" "${VIRTUAL_IP/\/32/}" "$BYTES_RECEIVED" "$BYTES_SENT" "$(date -d @"$LAST_SEEN" '+%b %d %Y - %T')"
else
printf "%s \t %s \t %s \t %'d \t %'d \t %s\n" "$CLIENT_NAME" "$REMOTE_IP" "${VIRTUAL_IP/\/32/}" "$BYTES_RECEIVED" "$BYTES_SENT" "(not yet)"
if [ "$LAST_SEEN" -ne 0 ]; then
printf "%s \t %s \t %s \t %'d \t %'d \t %s\n" "$CLIENT_NAME" "$REMOTE_IP" "${VIRTUAL_IP/\/32/}" "$BYTES_RECEIVED" "$BYTES_SENT" "$(date -d @"$LAST_SEEN" '+%b %d %Y - %T')"
else
printf "%s \t %s \t %s \t %'d \t %'d \t %s\n" "$CLIENT_NAME" "$REMOTE_IP" "${VIRTUAL_IP/\/32/}" "$BYTES_RECEIVED" "$BYTES_SENT" "(not yet)"
fi
fi
fi
done <<< "$DUMP"
printf "\n"
} | column -t -s $'\t'
cd /etc/wireguard || return
echo "::: Disabled clients :::"
grep '\[disabled\] ### begin' wg0.conf | sed 's/#//g; s/begin//'
}
if [[ $# -eq 0 ]]; then

120
scripts/wireguard/disableCONF.sh Executable file
View file

@ -0,0 +1,120 @@
#!/bin/bash
setupVars="/etc/pivpn/wireguard/setupVars.conf"
if [ ! -f "${setupVars}" ]; then
echo "::: Missing setup vars file!"
exit 1
fi
source "${setupVars}"
helpFunc(){
echo "::: Disable client conf profiles"
echo ":::"
echo "::: Usage: pivpn <-off|off> [-h|--help] [-v] [<client-1> ... [<client-2>] ...] "
echo ":::"
echo "::: Commands:"
echo "::: [none] Interactive mode"
echo "::: <client> Client"
echo "::: -y,--yes Disable client(s) without confirmation"
echo "::: -v Show disabled clients only"
echo "::: -h,--help Show this help dialog"
}
# Parse input arguments
while test $# -gt 0
do
_key="$1"
case "$_key" in
-h|--help)
helpFunc
exit 0
;;
-y|--yes)
CONFIRM=true
;;
-v)
DISPLAY_DISABLED=true
;;
*)
CLIENTS_TO_CHANGE+=("$1")
;;
esac
shift
done
cd /etc/wireguard
if [ ! -s configs/clients.txt ]; then
echo "::: There are no clients to change"
exit 1
fi
if [ "$DISPLAY_DISABLED" ]; then
grep '\[disabled\] ### begin' wg0.conf | sed 's/#//g; s/begin//'
exit 1
fi
LIST=($(awk '{print $1}' configs/clients.txt))
if [ "${#CLIENTS_TO_CHANGE[@]}" -eq 0 ]; then
echo -e "::\e[4m Client list \e[0m::"
len=${#LIST[@]}
COUNTER=1
while [ $COUNTER -le ${len} ]; do
printf "%0${#len}s) %s\r\n" ${COUNTER} ${LIST[(($COUNTER-1))]}
((COUNTER++))
done
read -r -p "Please enter the Index/Name of the Client to be removed from the list above: " CLIENTS_TO_CHANGE
if [ -z "${CLIENTS_TO_CHANGE}" ]; then
echo "::: You can not leave this blank!"
exit 1
fi
fi
CHANGED_COUNT=0
for CLIENT_NAME in "${CLIENTS_TO_CHANGE[@]}"; do
re='^[0-9]+$'
if [[ ${CLIENT_NAME} =~ $re ]] ; then
CLIENT_NAME=${LIST[$(($CLIENT_NAME -1))]}
fi
if ! grep -q "^${CLIENT_NAME} " configs/clients.txt; then
echo -e "::: \e[1m${CLIENT_NAME}\e[0m does not exist"
elif grep -q "#\[disabled\] ### begin ${CLIENT_NAME}" wg0.conf; then
echo -e "::: \e[1m${CLIENT_NAME}\e[0m is already disabled"
else
if [ -n "$CONFIRM" ]; then
REPLY="y"
else
read -r -p "Confirm you want to disable $CLIENT_NAME? [Y/n] "
fi
if [[ $REPLY =~ ^[Yy]$ ]]; then
# Disable the peer section from the server config
echo "${CLIENT_NAME}"
sed -e "/### begin ${CLIENT_NAME}/,/end ${CLIENT_NAME}/ s/^/#\[disabled\] /" -i wg0.conf
echo "::: Updated server config"
((CHANGED_COUNT++))
echo "::: Successfully disabled ${CLIENT_NAME}"
fi
fi
done
# Restart WireGuard only if some clients were actually deleted
if [ "${CHANGED_COUNT}" -gt 0 ]; then
if systemctl reload wg-quick@wg0; then
echo "::: WireGuard reloaded"
else
echo "::: Failed to reload WireGuard"
fi
fi

116
scripts/wireguard/enableCONF.sh Executable file
View file

@ -0,0 +1,116 @@
#!/bin/bash
setupVars="/etc/pivpn/wireguard/setupVars.conf"
if [ ! -f "${setupVars}" ]; then
echo "::: Missing setup vars file!"
exit 1
fi
source "${setupVars}"
helpFunc(){
echo "::: Enables client conf profiles"
echo ":::"
echo "::: Usage: pivpn <-on|on> [-h|--help] [-v] [<client-1> ... [<client-2>] ...] "
echo ":::"
echo "::: Commands:"
echo "::: [none] Interactive mode"
echo "::: <client> Client"
echo "::: -y,--yes Enable client(s) without confirmation"
echo "::: -v Show disabled clients only"
echo "::: -h,--help Show this help dialog"
}
# Parse input arguments
while test $# -gt 0
do
_key="$1"
case "$_key" in
-h|--help)
helpFunc
exit 0
;;
-y|--yes)
CONFIRM=true
;;
-v)
DISPLAY_DISABLED=true
;;
*)
CLIENTS_TO_CHANGE+=("$1")
;;
esac
shift
done
cd /etc/wireguard
if [ ! -s configs/clients.txt ]; then
echo "::: There are no clients to change"
exit 1
fi
if [ "$DISPLAY_DISABLED" ]; then
grep '\[disabled\] ### begin' wg0.conf | sed 's/#//g; s/begin//'
exit 1
fi
LIST=($(awk '{print $1}' configs/clients.txt))
if [ "${#CLIENTS_TO_CHANGE[@]}" -eq 0 ]; then
echo -e "::\e[4m Client list \e[0m::"
len=${#LIST[@]}
COUNTER=1
while [ $COUNTER -le ${len} ]; do
printf "%0${#len}s) %s\r\n" ${COUNTER} ${LIST[(($COUNTER-1))]}
((COUNTER++))
done
read -r -p "Please enter the Index/Name of the Client to be enabled from the list above: " CLIENTS_TO_CHANGE
if [ -z "${CLIENTS_TO_CHANGE}" ]; then
echo "::: You can not leave this blank!"
exit 1
fi
fi
CHANGED_COUNT=0
for CLIENT_NAME in "${CLIENTS_TO_CHANGE[@]}"; do
re='^[0-9]+$'
if [[ ${CLIENT_NAME} =~ $re ]] ; then
CLIENT_NAME=${LIST[$(($CLIENT_NAME -1))]}
fi
if ! grep -q "^${CLIENT_NAME} " configs/clients.txt; then
echo -e "::: \e[1m${CLIENT_NAME}\e[0m does not exist"
else
if [ -n "$CONFIRM" ]; then
REPLY="y"
else
read -r -p "Confirm you want to enable $CLIENT_NAME? [Y/n] "
fi
if [[ $REPLY =~ ^[Yy]$ ]]; then
# Enable the peer section from the server config
echo "${CLIENT_NAME}"
sed -e "/begin ${CLIENT_NAME}/,/end ${CLIENT_NAME}/ s/#\[disabled\] //" -i wg0.conf
echo "::: Updated server config"
((CHANGED_COUNT++))
echo "::: Successfully enabled ${CLIENT_NAME}"
fi
fi
done
# Restart WireGuard only if some clients were actually deleted
if [ "${CHANGED_COUNT}" -gt 0 ]; then
if systemctl reload wg-quick@wg0; then
echo "::: WireGuard reloaded"
else
echo "::: Failed to reload WireGuard"
fi
fi

View file

@ -25,4 +25,9 @@ while read -r LINE; do
echo -e "$CLIENT_NAME \t $PUBLIC_KEY \t $CD_FORMAT"
done < clients.txt
} | column -t -s $'\t'
} | column -t -s $'\t'
cd /etc/wireguard || return
echo "::: Disabled clients :::"
grep '\[disabled\] ### begin' wg0.conf | sed 's/#//g; s/begin//'

View file

@ -1,6 +1,6 @@
#!/bin/bash
setupVars="/etc/pivpn/setupVars.conf"
setupVars="/etc/pivpn/wireguard/setupVars.conf"
if [ ! -f "${setupVars}" ]; then
echo "::: Missing setup vars file!"
@ -64,6 +64,11 @@ if [[ "${CLIENT_NAME}" =~ [^a-zA-Z0-9.@_-] ]]; then
exit 1
fi
if [[ "${CLIENT_NAME}" =~ ^[0-9]+$ ]]; then
echo "Names cannot be integers."
exit 1
fi
if [ -z "${CLIENT_NAME}" ]; then
echo "::: You cannot leave the name blank."
exit 1
@ -75,6 +80,7 @@ if [ -f "configs/${CLIENT_NAME}.conf" ]; then
fi
wg genkey | tee "keys/${CLIENT_NAME}_priv" | wg pubkey > "keys/${CLIENT_NAME}_pub"
wg genpsk | tee "keys/${CLIENT_NAME}_psk" &> /dev/null
echo "::: Client Keys generated"
# Find an unused number for the last octet of the client IP
@ -102,17 +108,17 @@ echo >> "configs/${CLIENT_NAME}.conf"
echo "[Peer]
PublicKey = $(cat keys/server_pub)
PresharedKey = $(cat keys/psk)
PresharedKey = $(cat "keys/${CLIENT_NAME}_psk")
Endpoint = ${pivpnHOST}:${pivpnPORT}
AllowedIPs = 0.0.0.0/0, ::0/0" >> "configs/${CLIENT_NAME}.conf"
AllowedIPs = ${ALLOWED_IPS}" >> "configs/${CLIENT_NAME}.conf"
echo "::: Client config generated"
echo "# begin ${CLIENT_NAME}
echo "### begin ${CLIENT_NAME} ###
[Peer]
PublicKey = $(cat "keys/${CLIENT_NAME}_pub")
PresharedKey = $(cat keys/psk)
PresharedKey = $(cat "keys/${CLIENT_NAME}_psk")
AllowedIPs = ${NET_REDUCED}.${COUNT}/32
# end ${CLIENT_NAME}" >> wg0.conf
### end ${CLIENT_NAME} ###" >> wg0.conf
echo "::: Updated server config"
if [ -f /etc/pivpn/hosts.wireguard ]; then
@ -124,10 +130,10 @@ if [ -f /etc/pivpn/hosts.wireguard ]; then
fi
fi
if systemctl restart wg-quick@wg0; then
echo "::: WireGuard restarted"
if systemctl reload wg-quick@wg0; then
echo "::: WireGuard reloaded"
else
echo "::: Failed to restart WireGuard"
echo "::: Failed to reload WireGuard"
fi
cp "configs/${CLIENT_NAME}.conf" "${install_home}/configs/${CLIENT_NAME}.conf"

View file

@ -1,99 +0,0 @@
#!/bin/bash
# Must be root to use this tool
if [ $EUID -ne 0 ];then
if dpkg-query -s sudo &> /dev/null; then
export SUDO="sudo"
else
echo "::: Please install sudo or run this as root."
exit 1
fi
fi
makeConf(){
shift
$SUDO /opt/pivpn/makeCONF.sh "$@"
exit 0
}
listConnected(){
shift
$SUDO /opt/pivpn/clientSTAT.sh "$@"
exit 0
}
debug(){
$SUDO /opt/pivpn/pivpnDEBUG.sh
exit 0
}
listClients(){
$SUDO /opt/pivpn/listCONF.sh
exit 0
}
showQrcode(){
shift
$SUDO /opt/pivpn/qrcodeCONF.sh "$@"
exit 0
}
removeClient(){
shift
$SUDO /opt/pivpn/removeCONF.sh "$@"
exit 0
}
uninstallServer(){
$SUDO /opt/pivpn/uninstall.sh
exit 0
}
updateScripts(){
shift
$SUDO /opt/pivpn/update.sh "$@"
exit 0
}
backup(){
$SUDO /opt/pivpn/backup.sh
}
showHelp(){
echo "::: Control all PiVPN specific functions!"
echo ":::"
echo "::: Usage: pivpn <command> [option]"
echo ":::"
echo "::: Commands:"
echo "::: -a, add Create a client conf profile"
echo "::: -c, clients List any connected clients to the server"
echo "::: -d, debug Start a debugging session if having trouble"
echo "::: -l, list List all clients"
echo "::: -qr, qrcode Show the qrcode of a client for use with the mobile app"
echo "::: -r, remove Remove a client"
echo "::: -h, help Show this help dialog"
echo "::: -u, uninstall Uninstall pivpn from your system!"
echo "::: -up, update Updates PiVPN Scripts"
echo "::: -bk, backup Backup VPN configs and user profiles"
exit 0
}
if [ $# = 0 ]; then
showHelp
fi
# Handle redirecting to specific functions based on arguments
case "$1" in
"-a" | "add" ) makeConf "$@";;
"-c" | "clients" ) listConnected "$@";;
"-d" | "debug" ) debug;;
"-l" | "list" ) listClients;;
"-qr" | "qrcode" ) showQrcode "$@";;
"-r" | "remove" ) removeClient "$@";;
"-h" | "help" ) showHelp;;
"-u" | "uninstall" ) uninstallServer;;
"-up" | "update" ) updateScripts "$@" ;;
"-wg" | "wgupdate" ) updateWireGuard ;;
"-bk" | "backup" ) backup ;;
* ) showHelp;;
esac

123
scripts/wireguard/pivpn.sh Executable file
View file

@ -0,0 +1,123 @@
#!/bin/bash
# Must be root to use this tool
if [ $EUID -ne 0 ];then
if dpkg-query -s sudo &> /dev/null; then
export SUDO="sudo"
else
echo "::: Please install sudo or run this as root."
exit 1
fi
fi
scriptdir="/opt/pivpn"
vpn="wireguard"
makeConf(){
shift
$SUDO ${scriptdir}/${vpn}/makeCONF.sh "$@"
exit 0
}
listConnected(){
shift
$SUDO ${scriptdir}/${vpn}/clientSTAT.sh "$@"
exit 0
}
debug(){
echo "::: Generating Debug Output"
$SUDO ${scriptdir}/${vpn}/pivpnDEBUG.sh | tee /tmp/debug.log
echo "::: "
echo "::: Debug output completed above."
echo "::: Copy saved to /tmp/debug.log"
echo "::: "
exit 0
}
listClients(){
$SUDO ${scriptdir}/${vpn}/listCONF.sh
exit 0
}
showQrcode(){
shift
$SUDO ${scriptdir}/${vpn}/qrcodeCONF.sh "$@"
exit 0
}
removeClient(){
shift
$SUDO ${scriptdir}/${vpn}/removeCONF.sh "$@"
exit 0
}
disableClient(){
shift
$SUDO ${scriptdir}/${vpn}/disableCONF.sh "$@"
exit 0
}
enableClient(){
shift
$SUDO ${scriptdir}/${vpn}/enableCONF.sh "$@"
exit 0
}
uninstallServer(){
$SUDO ${scriptdir}/uninstall.sh "${vpn}"
exit 0
}
updateScripts(){
shift
$SUDO ${scriptdir}/update.sh "$@"
exit 0
}
backup(){
$SUDO ${scriptdir}/backup.sh "${vpn}"
exit 0
}
showHelp(){
echo "::: Control all PiVPN specific functions!"
echo ":::"
echo "::: Usage: pivpn <command> [option]"
echo ":::"
echo "::: Commands:"
echo "::: -a, add Create a client conf profile"
echo "::: -c, clients List any connected clients to the server"
echo "::: -d, debug Start a debugging session if having trouble"
echo "::: -l, list List all clients"
echo "::: -qr, qrcode Show the qrcode of a client for use with the mobile app"
echo "::: -r, remove Remove a client"
echo "::: -off, off Disable a user"
echo "::: -on, on Enable a user"
echo "::: -h, help Show this help dialog"
echo "::: -u, uninstall Uninstall pivpn from your system!"
echo "::: -up, update Updates PiVPN Scripts"
echo "::: -bk, backup Backup VPN configs and user profiles"
exit 0
}
if [ $# = 0 ]; then
showHelp
fi
# Handle redirecting to specific functions based on arguments
case "$1" in
"-a" | "add" ) makeConf "$@";;
"-c" | "clients" ) listConnected "$@";;
"-d" | "debug" ) debug;;
"-l" | "list" ) listClients;;
"-qr" | "qrcode" ) showQrcode "$@";;
"-r" | "remove" ) removeClient "$@";;
"-off" | "off" ) disableClient "$@";;
"-on" | "on" ) enableClient "$@";;
"-h" | "help" ) showHelp;;
"-u" | "uninstall" ) uninstallServer;;
"-up" | "update" ) updateScripts "$@" ;;
"-bk" | "backup" ) backup ;;
* ) showHelp;;
esac

View file

@ -1,7 +1,7 @@
#!/usr/bin/env bash
# This scripts runs as root
setupVars="/etc/pivpn/setupVars.conf"
setupVars="/etc/pivpn/wireguard/setupVars.conf"
if [ ! -f "${setupVars}" ]; then
echo "::: Missing setup vars file!"
@ -13,10 +13,10 @@ source "${setupVars}"
echo -e "::::\t\t\e[4mPiVPN debug\e[0m\t\t ::::"
printf "=============================================\n"
echo -e "::::\t\t\e[4mLatest commit\e[0m\t\t ::::"
git --git-dir /etc/.pivpn/.git log -n 1
git --git-dir /usr/local/src/pivpn/.git log -n 1
printf "=============================================\n"
echo -e "::::\t \e[4mInstallation settings\e[0m \t ::::"
sed "s/$pivpnHOST/REDACTED/" < /etc/pivpn/setupVars.conf
sed "s/$pivpnHOST/REDACTED/" < ${setupVars}
printf "=============================================\n"
echo -e ":::: \e[4mServer configuration shown below\e[0m ::::"
cd /etc/wireguard/keys
@ -46,7 +46,7 @@ echo -e ":::: \t\e[4mRecursive list of files in\e[0m\t ::::\n::::\e\t[4m/etc/wir
ls -LR /etc/wireguard
printf "=============================================\n"
echo -e "::::\t\t\e[4mSelf check\e[0m\t\t ::::"
/opt/pivpn/self_check.sh
/opt/pivpn/self_check.sh ${VPN}
printf "=============================================\n"
echo -e ":::: Having trouble connecting? Take a look at the FAQ:"
echo -e ":::: \e[1mhttps://github.com/pivpn/pivpn/wiki/FAQ\e[0m"

View file

@ -33,17 +33,18 @@ if [ ! -s clients.txt ]; then
exit 1
fi
LIST=($(awk '{print $1}' clients.txt))
if [ "${#CLIENTS_TO_SHOW[@]}" -eq 0 ]; then
echo -e "::\e[4m Client list \e[0m::"
LIST=($(awk '{print $1}' clients.txt))
len=${#LIST[@]}
COUNTER=1
while [ $COUNTER -le ${#LIST[@]} ]; do
echo "${LIST[(($COUNTER-1))]}"
while [ $COUNTER -le ${len} ]; do
printf "%0${#len}s) %s\r\n" ${COUNTER} ${LIST[(($COUNTER-1))]}
((COUNTER++))
done
read -r -p "Please enter the Name of the Client to show: " CLIENTS_TO_SHOW
read -r -p "Please enter the Index/Name of the Client to show: " CLIENTS_TO_SHOW
if [ -z "${CLIENTS_TO_SHOW}" ]; then
echo "::: You can not leave this blank!"
@ -52,6 +53,10 @@ if [ "${#CLIENTS_TO_SHOW[@]}" -eq 0 ]; then
fi
for CLIENT_NAME in "${CLIENTS_TO_SHOW[@]}"; do
re='^[0-9]+$'
if [[ ${CLIENT_NAME} =~ $re ]] ; then
CLIENT_NAME=${LIST[$(($CLIENT_NAME -1))]}
fi
if grep -qw "${CLIENT_NAME}" clients.txt; then
echo -e "::: Showing client \e[1m${CLIENT_NAME}\e[0m below"
echo "====================================================================="
@ -60,4 +65,4 @@ for CLIENT_NAME in "${CLIENTS_TO_SHOW[@]}"; do
else
echo -e "::: \e[1m${CLIENT_NAME}\e[0m does not exist"
fi
done
done

View file

@ -1,6 +1,6 @@
#!/bin/bash
setupVars="/etc/pivpn/setupVars.conf"
setupVars="/etc/pivpn/wireguard/setupVars.conf"
if [ ! -f "${setupVars}" ]; then
echo "::: Missing setup vars file!"
@ -12,11 +12,12 @@ source "${setupVars}"
helpFunc(){
echo "::: Remove a client conf profile"
echo ":::"
echo "::: Usage: pivpn <-r|remove> [-h|--help] [<client-1>] ... [<client-n>] ..."
echo "::: Usage: pivpn <-r|remove> [-y|--yes] [-h|--help] [<client-1>] ... [<client-n>] ..."
echo ":::"
echo "::: Commands:"
echo "::: [none] Interactive mode"
echo "::: <client> Client(s) to remove"
echo "::: -y,--yes Remove Client(s) without confirmation"
echo "::: -h,--help Show this help dialog"
}
@ -29,6 +30,9 @@ do
helpFunc
exit 0
;;
-y|--yes)
CONFIRM=true
;;
*)
CLIENTS_TO_REMOVE+=("$1")
;;
@ -42,17 +46,17 @@ if [ ! -s configs/clients.txt ]; then
exit 1
fi
LIST=($(awk '{print $1}' configs/clients.txt))
if [ "${#CLIENTS_TO_REMOVE[@]}" -eq 0 ]; then
echo -e "::\e[4m Client list \e[0m::"
LIST=($(awk '{print $1}' configs/clients.txt))
len=${#LIST[@]}
COUNTER=1
while [ $COUNTER -le ${#LIST[@]} ]; do
echo "${LIST[(($COUNTER-1))]}"
while [ $COUNTER -le ${len} ]; do
printf "%0${#len}s) %s\r\n" ${COUNTER} ${LIST[(($COUNTER-1))]}
((COUNTER++))
done
read -r -p "Please enter the Name of the Client to be removed from the list above: " CLIENTS_TO_REMOVE
read -r -p "Please enter the Index/Name of the Client to be removed from the list above: " CLIENTS_TO_REMOVE
if [ -z "${CLIENTS_TO_REMOVE}" ]; then
echo "::: You can not leave this blank!"
@ -64,26 +68,35 @@ DELETED_COUNT=0
for CLIENT_NAME in "${CLIENTS_TO_REMOVE[@]}"; do
if ! grep -qw "${CLIENT_NAME}" configs/clients.txt; then
re='^[0-9]+$'
if [[ ${CLIENT_NAME} =~ $re ]] ; then
CLIENT_NAME=${LIST[$(($CLIENT_NAME -1))]}
fi
if ! grep -q "^${CLIENT_NAME} " configs/clients.txt; then
echo -e "::: \e[1m${CLIENT_NAME}\e[0m does not exist"
else
REQUESTED="$(sha256sum "configs/${CLIENT_NAME}.conf" | cut -c 1-64)"
read -r -p "Do you really want to delete $CLIENT_NAME? [y/N] "
if [ -n "$CONFIRM" ]; then
REPLY="y"
else
read -r -p "Do you really want to delete $CLIENT_NAME? [y/N] "
fi
if [[ $REPLY =~ ^[Yy]$ ]]; then
# Grab the least significant octed of the client IP address
COUNT=$(grep "${CLIENT_NAME}" configs/clients.txt | awk '{print $4}')
COUNT=$(grep "^${CLIENT_NAME} " configs/clients.txt | awk '{print $4}')
# The creation date of the client
CREATION_DATE="$(grep "${CLIENT_NAME}" configs/clients.txt | awk '{print $3}')"
CREATION_DATE="$(grep "^${CLIENT_NAME} " configs/clients.txt | awk '{print $3}')"
# And its public key
PUBLIC_KEY="$(grep "${CLIENT_NAME}" configs/clients.txt | awk '{print $2}')"
PUBLIC_KEY="$(grep "^${CLIENT_NAME} " configs/clients.txt | awk '{print $2}')"
# Then remove the client matching the variables above
sed "\#${CLIENT_NAME} ${PUBLIC_KEY} ${CREATION_DATE} ${COUNT}#d" -i configs/clients.txt
# Remove the peer section from the server config
sed "/# begin ${CLIENT_NAME}/,/# end ${CLIENT_NAME}/d" -i wg0.conf
sed "/### begin ${CLIENT_NAME} ###/,/### end ${CLIENT_NAME} ###/d" -i wg0.conf
echo "::: Updated server config"
rm "configs/${CLIENT_NAME}.conf"
@ -91,6 +104,7 @@ for CLIENT_NAME in "${CLIENTS_TO_REMOVE[@]}"; do
rm "keys/${CLIENT_NAME}_priv"
rm "keys/${CLIENT_NAME}_pub"
rm "keys/${CLIENT_NAME}_psk"
echo "::: Client Keys for ${CLIENT_NAME} removed"
# Find all .conf files in the home folder of the user matching the checksum of the
@ -125,9 +139,9 @@ done
# Restart WireGuard only if some clients were actually deleted
if [ "${DELETED_COUNT}" -gt 0 ]; then
if systemctl restart wg-quick@wg0; then
echo "::: WireGuard restarted"
if systemctl reload wg-quick@wg0; then
echo "::: WireGuard reloaded"
else
echo "::: Failed to restart WireGuard"
echo "::: Failed to reload WireGuard"
fi
fi