First commit of reworked installer

This commit is contained in:
Kaladin Light 2016-04-19 14:01:55 -04:00
parent 3fb4f4e995
commit 53565dd4fe
13 changed files with 1116 additions and 2 deletions

15
Default.txt Normal file
View file

@ -0,0 +1,15 @@
client
dev tun
proto udp
remote IPv4pub 1194
resolv-retry infinite
nobind
persist-key
persist-tun
mute-replay-warnings
ns-cert-type server
key-direction 1
cipher AES-128-CBC
comp-lzo
verb 1
mute 20

156
README.md
View file

@ -1,2 +1,154 @@
# pivpn
Simple OpenVPN installer, designed for raspberry pi.
PiVPN
============
About
-----
Visit the [PiVPN](http://pivpn.io) site for more information.
This is a set of shell scripts that server to easily turn your Raspberry Pi (TM)
into a VPN server using the free, open-source [OpenVPN](https://openvpn.net) software.
The master branch of this script installs and configures OpenVPN on Raspbian
Jessie, and should be used if you are running Jessie or Jessie Lite. Jessie Lite
is recommended if this will just be a server. The goal is for this to also work
on Debian Jessie built on a free-tier Amazon AWS server for those that want thier
tunneled traffic to be encrypted out of their home ISP.
Prerequisites
-------------
To follow this guide and use the script to setup OpenVPN, you will need to have
a Raspberry Pi Model B or later with an ethernet port, an SD or microSD card
(depending on the model) with Raspbian installed, a power adapter appropriate to
the power needs of your model, and an ethernet cable or wifi adapter to connect your Pi to your
router or gateway. It is recommended that you use a fresh image of Raspbian
Jessie 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 forward UPD port 1194
(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).
Installation
-----------------
```shell
curl -L install.pivpn.io | bash
```
The script will first update your APT repositories, upgrade packages, and install OpenVPN,
which will take some time.
It will ask which encryption method you wish the guts of your server to use, 1024-bit or 2048-bit.
2048-bit is more secure, but will take much longer to set up. If you're unsure or don't
have a convincing reason one way or the other I'd use 2048 today.
After this, the script will go back to the command line as it builds the server's own
certificate authority. If you wish to enter identifying information for the
CA, replace the default values in the file ca_info.txt (CO for country, ST for
state/province/territory, ORG for organization, etc.) before executing the setup script;
however, this is not required, and you may leave the ca_info.txt file as-is. After this,
the script will prompt you in the command line for input in similar identifying information
fields as it generates your server certificate. Enter whatever you like, or if you do not
desire to fill them out, skip them by pressing enter; make sure to skip the challenge field
and leave it blank. After these fields, you will be asked whether you want to sign the
certificate; you must press 'y'. You'll also be asked if you want to commit - press 'y'
again.
Finally, the script will take some time to build the server's Diffie-Hellman key
exchange. If you chose 1024-bit encryption, this will just take a few minutes, but if you
chose 2048-bit, it will take much longer (anywhere from 40 minutes to several hours on a
Model B+). 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 OpenVPN, reboot the system to apply the
changes, and the VPN server-side setup will be complete!
Managing the PiVPN
----------------------
After the installation is complete you can use the command 'pivpn' to manage the server.
"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.
You'll then be prompted for input in more identification fields, which you can again ignore if
you like; make sure you again leave the challenge field blank. The script will then ask if you
want to sign the client certificate and commit; press 'y' for both. You'll then be asked to enter
the pass phrase you just chose in order to encrypt the client key, and immediately after to choose
another pass phrase for the encrypted key - if you're normal, just use the same one. After this,
the script will assemble the client .ovpn file and place it in the directory 'ovpns' within your
home directory.
Importing .ovpn Profiles on Client Machines
--------------------------------------------
To move a client .ovpn profile to 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. To move a profile to 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.
To import the profile to OpenVPN on Windows, download the OpenVPN GUI from the community downloads
section of openvpn.net, install it, and place the profile in the 'config' folder of your OpenVPN
directory, i.e., in 'C:\Program Files\OpenVPN\config'. To import the profile on Android, install
the OpenVPN Connect app, 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.
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',
or on Android by selecting the profile under 'OpenVPN Profile' and pressing 'Connect'. You'll be
asked to enter the pass phrase you chose. Do so, and you're in! Enjoy your ~$50 USD private VPN.
Removing OpenVPN
----------------
If at any point you wish to remove OpenVPN 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 OpenVPN without installing a fresh Raspbian image, just run
'pivpn uninstall'
Feedback & Support
--------
I am interested in making this script work for as many people as possible, so I
welcome any feedback on your experience. If you have problems using it, feel
free to post an issue here on github. I'll classify the issues the best I can
to keep things sorted.
I also encourage discussion of issues, solutions, and ideas on the RaspberryPi.org forum thread for the project [here.](https://www.raspberrypi.org/forums/viewtopic.php?f=36&t=137240&p=911599&hilit=OpenVPN#p911599) I'd love for users to have the opportunity to discuss their ideas with each other!
Contributions
-------------
I'm also interested in improving this script, and will be adding features to it
over time to make it easier, more intuitive, and more versatile. If you have any
feature ideas or requests, or are interested in adding your ideas to it,
testing it on other platforms, or localizing it to another language, please
comment or leave a pull request. I will be happy to work with you!
If you have found this tool to be useful and want to use
[this PayPal link](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=K99QGVL7KA6ZL)
to buy me a gallon of gas, I would be very grateful!
If you decide to do so, please also consider supporting OpenVPN; they
have produced a wonderful open-source product, and all credit for it goes to
their community and their hard work. All I did was write a little automated
front-end for its installation on Raspbian.
Sources
-------
1: [ModMyPi: How to give your Raspberry Pi a Static IP Address](https://www.modmypi.com/blog/tutorial-how-to-give-your-raspberry-pi-a-static-ip-address)
2: [ReadWrite: 5 Pointers To Supercharge Your Raspberry Pi Projects](http://readwrite.com/2014/04/09/raspberry-pi-projects-ssh-remote-desktop-static-ip-tutorial?utm_content=readwrite3-orionautotweet&awesm=readwr.it_b1UN&utm_campaign=&utm_medium=readwr.it-twitter&utm_source=t.co#awesm=~oAXilI0BMOHsS3)
3: [ReadWrite: Building A Raspberry Pi VPN Part 1](http://readwrite.com/2014/04/10/raspberry-pi-vpn-tutorial-server-secure-web-browsing)
4: [ReadWrite: Building A Raspberry Pi VPN Part 2](http://readwrite.com/2014/04/11/building-a-raspberry-pi-vpn-part-two-creating-an-encrypted-client-side#awesm=~oB89WBfWrt21bV)

531
auto_install/install.sh Normal file
View file

@ -0,0 +1,531 @@
#!/usr/bin/env bash
# PiVPN: Trivial openvpn setup and configuration
# Easiest setup and mangement of openvpn on Raspberry Pi
# https://github.com/StarshipEngineer/OpenVPN-Setup/
# Installs pivpn
# Heavily adapted from the pi-hole project
#
# Install with this command (from your Pi):
#
# curl -L vigilcode.com/pivpnsetup | bash
######## VARIABLES #########
tmpLog=/tmp/pivpn-install.log
instalLogLoc=/etc/pivpn/install.log
pivpnGitUrl="https://github.com/0-kaladin/OpenVPN-Setup.git"
pivpnFilesDir="/etc/.pivpn"
# Find the rows and columns
rows=$(tput lines)
columns=$(tput cols)
# Divide by two so the dialogs take up half of the screen, which looks nice.
r=$(( rows / 2 ))
c=$(( columns / 2 ))
# Find IP used to route to outside world
IPv4dev=$(ip route get 8.8.8.8 | awk '{for(i=1;i<=NF;i++)if($i~/dev/)print $(i+1)}')
IPv4addr=$(ip -o -f inet addr show dev "$IPv4dev" | awk '{print $4}' | awk 'END {print}')
IPv4gw=$(ip route get 8.8.8.8 | awk '{print $3}')
availableInterfaces=$(ip -o link | awk '{print $2}' | grep -v "lo" | cut -d':' -f1)
availableUsers=$(awk -F':' '$3>=500 && $3<=60000 {print $1}' /etc/passwd)
dhcpcdFile=/etc/dhcpcd.conf
######## FIRST CHECK ########
# Must be root to install
echo ":::"
if [[ $EUID -eq 0 ]];then
echo "::: You are root."
else
echo "::: sudo will be used for the install."
# Check if it is actually installed
# If it isn't, exit because the install cannot complete
if [[ $(dpkg-query -s sudo) ]];then
export SUDO="sudo"
else
echo "::: Please install sudo or run this as root."
exit 1
fi
fi
####### FUNCTIONS ##########
spinner()
{
local pid=$1
local delay=0.50
local spinstr='/-\|'
while [ "$(ps a | awk '{print $1}' | grep "$pid")" ]; do
local temp=${spinstr#?}
printf " [%c] " "$spinstr"
local spinstr=$temp${spinstr%"$temp"}
sleep $delay
printf "\b\b\b\b\b\b"
done
printf " \b\b\b\b"
}
welcomeDialogs() {
# Display the welcome dialog
whiptail --msgbox --backtitle "Welcome" --title "PiVPN Automated Installer" "This installer will transform your Raspberry Pi into an openvpn server!" $r $c
# Explain the need for a static address
whiptail --msgbox --backtitle "Initiating network interface" --title "Static IP Needed" "The PiVPN is a SERVER so it needs a STATIC IP ADDRESS to function properly.
In the next section, you can choose to use your current network settings (DHCP) or to manually edit them." $r $c
}
chooseUser() {
# Explain the local user
whiptail --msgbox --backtitle "Parsing User List" --title "Local Users" "Choose a local user that will hold your ovpn configurations." $r $c
userArray=()
firstloop=1
while read -r line
do
mode="OFF"
if [[ $firstloop -eq 1 ]]; then
firstloop=0
mode="ON"
fi
userArray+=("$line" "available" "$mode")
done <<< "$availableUsers"
# Find out how many users are available to choose from
userCount=$(echo "$availableUsers" | wc -l)
chooseUserCmd=(whiptail --title "Choose A User" --separate-output --radiolist "Choose:" $r $c $userCount)
chooseUserOptions=$("${chooseUserCmd[@]}" "${userArray[@]}" 2>&1 >/dev/tty)
if [[ $? = 0 ]]; then
for desiredUser in $chooseUserOptions
do
pivpnUser=$desiredUser
echo "::: Using User: $pivpnUser"
echo "${pivpnUser}" > /tmp/pivpnUSR
done
else
echo "::: Cancel selected, exiting...."
exit 1
fi
}
verifyFreeDiskSpace() {
# I have no idea what the minimum space needed is, but checking for at least 50MB sounds like a good idea.
requiredFreeBytes=51200
existingFreeBytes=$(df -lk / 2>&1 | awk '{print $4}' | head -2 | tail -1)
if ! [[ "$existingFreeBytes" =~ ^([0-9])+$ ]]; then
existingFreeBytes=$(df -lk /dev 2>&1 | awk '{print $4}' | head -2 | tail -1)
fi
if [[ $existingFreeBytes -lt $requiredFreeBytes ]]; then
whiptail --msgbox --backtitle "Insufficient Disk Space" --title "Insufficient Disk Space" "\nYour system appears to be low on disk space. PiVPN recomends a minimum of $requiredFreeBytes Bytes.\nYou only have $existingFreeBytes Free.\n\nIf this is a new install you may need to expand your disk.\n\nTry running:\n 'sudo raspi-config'\nChoose the 'expand file system option'\n\nAfter rebooting, run this installation again.\n\ncurl -L vigilcode.com/pivpnsetup | bash\n" $r $c
echo "$existingFreeBytes is less than $requiredFreeBytes"
echo "Insufficient free space, exiting..."
exit 1
fi
}
chooseInterface() {
# Turn the available interfaces into an array so it can be used with a whiptail dialog
interfacesArray=()
firstloop=1
while read -r line
do
mode="OFF"
if [[ $firstloop -eq 1 ]]; then
firstloop=0
mode="ON"
fi
interfacesArray+=("$line" "available" "$mode")
done <<< "$availableInterfaces"
# Find out how many interfaces are available to choose from
interfaceCount=$(echo "$availableInterfaces" | wc -l)
chooseInterfaceCmd=(whiptail --separate-output --radiolist "Choose An Interface" $r $c $interfaceCount)
chooseInterfaceOptions=$("${chooseInterfaceCmd[@]}" "${interfacesArray[@]}" 2>&1 >/dev/tty)
if [[ $? = 0 ]]; then
for desiredInterface in $chooseInterfaceOptions
do
pivpnInterface=$desiredInterface
echo "::: Using interface: $pivpnInterface"
echo "${pivpnInterface}" > /tmp/pivpnINT
done
else
echo "::: Cancel selected, exiting...."
exit 1
fi
}
getStaticIPv4Settings() {
# Ask if the user wants to use DHCP settings as their static IP
if (whiptail --backtitle "Calibrating network interface" --title "Static IP Address" --yesno "Do you want to use your current network settings as a static address?
IP address: $IPv4addr
Gateway: $IPv4gw" $r $c) then
# If they choose yes, let the user know that the IP address will not be available via DHCP and may cause a conflict.
whiptail --msgbox --backtitle "IP information" --title "FYI: IP Conflict" "It is possible your router could still try to assign this IP to a device, which would cause a conflict. But in most cases the router is smart enough to not do that.
If you are worried, either manually set the address, or modify the DHCP reservation pool so it does not include the IP you want.
It is also possible to use a DHCP reservation, but if you are going to do that, you might as well set a static address." $r $c
# Nothing else to do since the variables are already set above
else
# Otherwise, we need to ask the user to input their desired settings.
# Start by getting the IPv4 address (pre-filling it with info gathered from DHCP)
# Start a loop to let the user enter their information with the chance to go back and edit it if necessary
until [[ $ipSettingsCorrect = True ]]
do
# Ask for the IPv4 address
IPv4addr=$(whiptail --backtitle "Calibrating network interface" --title "IPv4 address" --inputbox "Enter your desired IPv4 address" $r $c "$IPv4addr" 3>&1 1>&2 2>&3)
if [[ $? = 0 ]];then
echo "::: Your static IPv4 address: $IPv4addr"
# Ask for the gateway
IPv4gw=$(whiptail --backtitle "Calibrating network interface" --title "IPv4 gateway (router)" --inputbox "Enter your desired IPv4 default gateway" $r $c "$IPv4gw" 3>&1 1>&2 2>&3)
if [[ $? = 0 ]];then
echo "::: Your static IPv4 gateway: $IPv4gw"
# Give the user a chance to review their settings before moving on
if (whiptail --backtitle "Calibrating network interface" --title "Static IP Address" --yesno "Are these settings correct?
IP address: $IPv4addr
Gateway: $IPv4gw" $r $c)then
# If the settings are correct, then we need to set the piVPNIP
# Saving it to a temporary file us to retrieve it later when we run the gravity.sh script
echo "${IPv4addr%/*}" > /tmp/pivpnIP
echo "$pivpnInterface" > /tmp/pivpnINT
# After that's done, the loop ends and we move on
ipSettingsCorrect=True
else
# If the settings are wrong, the loop continues
ipSettingsCorrect=False
fi
else
# Cancelling gateway settings window
ipSettingsCorrect=False
echo "::: Cancel selected. Exiting..."
exit 1
fi
else
# Cancelling IPv4 settings window
ipSettingsCorrect=False
echo "::: Cancel selected. Exiting..."
exit 1
fi
done
# End the if statement for DHCP vs. static
fi
}
setDHCPCD() {
# Append these lines to dhcpcd.conf to enable a static IP
echo "::: interface $pivpnInterface
static ip_address=$IPv4addr
static routers=$IPv4gw
static domain_name_servers=$IPv4gw" | $SUDO tee -a $dhcpcdFile >/dev/null
}
setStaticIPv4() {
# Tries to set the IPv4 address
if grep -q "$IPv4addr" $dhcpcdFile; then
# address already set, noop
:
else
setDHCPCD
$SUDO ip addr replace dev "$pivpnInterface" "$IPv4addr"
echo ":::"
echo "::: Setting IP to $IPv4addr. You may need to restart after the install is complete."
echo ":::"
fi
}
function valid_ip()
{
local ip=$1
local stat=1
if [[ $ip =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then
OIFS=$IFS
IFS='.'
ip=($ip)
IFS=$OIFS
[[ ${ip[0]} -le 255 && ${ip[1]} -le 255 \
&& ${ip[2]} -le 255 && ${ip[3]} -le 255 ]]
stat=$?
fi
return $stat
}
installScripts() {
# Install the scripts from /etc/.pivpn to their various locations
$SUDO echo ":::"
$SUDO echo -n "::: Installing scripts to /opt/pivpn..."
if [ ! -d /opt/pivpn ]; then
$SUDO mkdir /opt/pivpn
$SUDO chown "$pivpnUser":root /opt/pivpn
$SUDO chmod u+srwx /opt/pivpn
fi
$SUDO cp /etc/.pivpn/scripts/makeOVPN.sh /opt/pivpn/makeOVPN.sh
$SUDO cp /etc/.pivpn/scripts/listOVPN.sh /opt/pivpn/listOVPN.sh
$SUDO cp /etc/.pivpn/scripts/removeOVPN.sh /opt/pivpn/removeOVPN.sh
$SUDO cp /etc/.pivpn/scripts/uninstall.sh /opt/pivpn/uninstall.sh
$SUDO cp /etc/.pivpn/scripts/pivpnDebug.sh /opt/pivpn/pivpnDebug.sh
$SUDO chmod 0755 /opt/pivpn/{makeOVPN,listOVPN,removeOVPN,uninstall,pivpnDebug}.sh
$SUDO cp /etc/.pivpn/pivpn /usr/local/bin/pivpn
$SUDO chmod 0755 /usr/local/bin/pivpn
$SUDO cp /etc/.pivpn/scripts/bash-completion /etc/bash_completion.d/pivpn
source /etc/bash_completion.d/pivpn
$SUDO echo " done."
}
stopServices() {
# Stop openvpn
$SUDO echo ":::"
$SUDO echo -n "::: Stopping openvpn service..."
$SUDO service openvpn stop || true
$SUDO echo " done."
}
checkForDependencies() {
#Running apt-get update/upgrade with minimal output can cause some issues with
#requiring user input (e.g password for phpmyadmin see #218)
#We'll change the logic up here, to check to see if there are any updates availible and
# if so, advise the user to run apt-get update/upgrade at their own discretion
#Check to see if apt-get update has already been run today
# it needs to have been run at least once on new installs!
timestamp=$(stat -c %Y /var/cache/apt/)
timestampAsDate=$(date -d @"$timestamp" "+%b %e")
today=$(date "+%b %e")
if [ ! "$today" == "$timestampAsDate" ]; then
#update package lists
echo ":::"
echo -n "::: apt-get update has not been run today. Running now..."
$SUDO apt-get -qq update & spinner $!
echo " done!"
fi
echo ":::"
echo -n "::: Checking apt-get for upgraded packages...."
updatesToInstall=$($SUDO apt-get -s -o Debug::NoLocking=true upgrade | grep -c ^Inst)
echo " done!"
echo ":::"
if [[ $updatesToInstall -eq "0" ]]; then
echo "::: Your pi is up to date! Continuing with PiVPN installation..."
else
echo "::: There are $updatesToInstall updates availible for your pi!"
echo "::: We recommend you run 'sudo apt-get upgrade' after installing PiVPN! "
echo ":::"
fi
echo ":::"
echo "::: Checking dependencies:"
dependencies=( openvpn easy-rsa git iptables-persistent dnsutils )
for i in "${dependencies[@]}"; do
echo -n "::: Checking for $i..."
if [ "$(dpkg-query -W -f='${Status}' "$i" 2>/dev/null | grep -c "ok installed")" -eq 0 ]; then
echo -n " Not found! Installing...."
#Supply answers to the questions so we don't prompt user
if [[ $i -eq "iptables-persistent" ]]; then
echo iptables-persistent iptables-persistent/autosave_v4 boolean true | $SUDO debconf-set-selections
echo iptables-persistent iptables-persistent/autosave_v6 boolean false | $SUDO debconf-set-selections
fi
$SUDO apt-get -y -qq install "$i" > /dev/null & spinner $!
echo " done!"
else
echo " already installed!"
fi
done
}
getGitFiles() {
# Setup git repos for base files
echo ":::"
echo "::: Checking for existing base files..."
if is_repo $pivpnFilesDir; then
make_repo $pivpnFilesDir $pivpnGitUrl
else
update_repo $pivpnFilesDir
fi
}
is_repo() {
# If the directory does not have a .git folder it is not a repo
echo -n "::: Checking $1 is a repo..."
if [ -d "$1/.git" ]; then
echo " OK!"
return 1
fi
echo " not found!!"
return 0
}
make_repo() {
# Remove the non-repos interface and clone the interface
echo -n "::: Cloning $2 into $1..."
$SUDO rm -rf "$1"
$SUDO git clone -q "$2" "$1" > /dev/null & spinner $!
echo " done!"
}
update_repo() {
# Pull the latest commits
echo -n "::: Updating repo in $1..."
cd "$1" || exit
$SUDO git pull -q > /dev/null & spinner $!
echo " done!"
}
confOpenVPN () {
# Ask user for desired level of encryption
ENCRYPT=$(whiptail --backtitle "Setup OpenVPN" --title "Encryption Strength" --radiolist \
"Choose your desired level of encryption:" $r $c 2 \
"2048" "Use 2048-bit encryption. Slower to set up, but more secure." ON \
"1024" "Use 1024-bit encryption. Faster to set up, but less secure." OFF 3>&1 1>&2 2>&3)
exitstatus=$?
if [ $exitstatus != 0 ]; then
echo "::: Cancel selected. Exiting..."
exit 1
fi
# Copy the easy-rsa files to a directory inside the new openvpn directory
cp -r /usr/share/easy-rsa /etc/openvpn
# Edit the EASY_RSA variable in the vars file to point to the new easy-rsa directory,
# And change from default 1024 encryption if desired
cd /etc/openvpn/easy-rsa
sed -i 's:"`pwd`":"/etc/openvpn/easy-rsa":' vars
if [[ $ENCRYPT -eq "1024" ]]; then
sed -i 's:KEY_SIZE=2048:KEY_SIZE=1024:' vars
fi
# source the vars file just edited
source ./vars
# Remove any previous keys
./clean-all
# Build the certificate authority
./build-ca < /etc/.pivpn/ca_info.txt
whiptail --msgbox --backtitle "Setup OpenVPN" --title "Server Information" "You will now be asked for identifying information for the server. Press 'Enter' to skip a field." $r $c
# can export env variables here for users to provide. export KEY_EMAIL will set email field for example.
# Build the server
./build-key-server --batch server
# Generate Diffie-Hellman key exchange
./build-dh
# Generate static HMAC key to defend against DDoS
openvpn --genkey --secret keys/ta.key
# Write config file for server using the template .txt file
LOCALIP=$(ifconfig $pivpnInterface | grep -Eo 'inet (addr:)?([0-9]*\.){3}[0-9]*' | grep -Eo '([0-9]*\.){3}[0-9]*')
sed 's/LOCALIP/'$LOCALIP'/' </etc/.pivpn/server_config.txt >/etc/openvpn/server.conf
if [ $ENCRYPT = 2048 ]; then
sed -i 's:dh1024:dh2048:' /etc/openvpn/server.conf
fi
}
confNetwork() {
# Enable forwarding of internet traffic
sed -i '/#net.ipv4.ip_forward=1/c\net.ipv4.ip_forward=1' /etc/sysctl.conf
$SUDO sysctl -p
# Write script to run openvpn and allow it through firewall on boot using the template .txt file
$SUDO iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o $IPv4dev -j MASQUERADE
$SUDO netfilter-persistent save
}
confOVPN() {
IPv4pub=$(dig +short myip.opendns.com @resolver1.opendns.com)
$SUDO cp /tmp/pivpnUSR /etc/pivpn/INSTALL_USER
# Set status that no certs have been revoked
$SUDO echo 0 > /etc/pivpn/REVOKE_STATUS
METH=$(whiptail --title "Public IP or DNS" --radiolist "Will clients use a Public IP or DNS?" $r $c 2 \
"$IPv4pub" "Use this public IP" "ON" \
"DNS Entry" "Use a public DNS" "OFF" 3>&1 1>&2 2>&3)
exitstatus=$?
if [ $exitstatus != 0 ]; then
echo "::: Cancel selected. Exiting..."
exit 1
fi
if [ "$METH" == "$IPv4pub" ]; then
sed 's/IPv4pub/'$IPv4pub'/' </etc/.pivpn/Default.txt >/etc/openvpn/easy-rsa/keys/Default.txt
else
PUBLICDNS=$(whiptail --title "PiVPN Setup" --inputbox "What is the public DNS name of this Raspberry Pi?" $r $c 3>&1 1>&2 2>&3)
exitstatus=$?
if [ $exitstatus = 0 ]; then
sed 's/IPv4pub/'$PUBLICDNS'/' </etc/.pivpn/Default.txt >/etc/openvpn/easy-rsa/keys/Default.txt
whiptail --title "Setup OpenVPN" --infobox "Using PUBLIC DNS: $PUBLICDNS" $r $c
else
whiptail --title "Setup OpenVPN" --infobox "Cancelled" $r $c
exit 1
fi
fi
mkdir /home/$pivpnUser/ovpns
chmod 0777 -R /home/$pivpnUser/ovpns
}
installPiVPN() {
checkForDependencies
stopServices
$SUDO mkdir -p /etc/pivpn/
getGitFiles
installScripts
confOpenVPN
confNetwork
confOVPN
}
displayFinalMessage() {
# Final completion message to user
$SUDO systemctl enable openvpn.service
$SUDO systemctl start openvpn.service
whiptail --msgbox --backtitle "Make it so." --title "Installation Complete!" "Now run 'pivpn add' to create the ovpn profiles.
Run 'pivpn help' to see what else you can do!
The install log is in /etc/pivpn." $r $c
if (whiptail --title "Reboot" --yesno --defaultno "It is strongly recommended you reboot after installation. Would you like to reboot now?" $r $c); then
whiptail --title "Rebooting" --msgbox "The system will now reboot." $r $c
printf "\nRebooting system...\n"
sleep 3
shutdown -r now
fi
}
######## SCRIPT ############
# Start the installer
welcomeDialogs
# Verify there is enough disk space for the install
verifyFreeDiskSpace
# Find interfaces and let the user choose one
chooseInterface
getStaticIPv4Settings
setStaticIPv4
# Choose the user for the ovpns
chooseUser
# Install and log everything to a file
installPiVPN
# Move the log file into /etc/pivpn for storage
#$SUDO mv $tmpLog $installLogLoc
displayFinalMessage
echo "::: Install Complete..."

8
ca_info.txt Normal file
View file

@ -0,0 +1,8 @@
CO
ST
CITY
ORG
ORG-UNIT
COMMON-NAME
NAME
EMAIL

View file

@ -0,0 +1,3 @@
#!/bin/sh
iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o IPv4dev -j MASQUERADE

71
pivpn Normal file
View file

@ -0,0 +1,71 @@
#!/bin/bash
# Must be root to use this tool
if [[ ! $EUID -eq 0 ]];then
#echo "::: You are root."
#else
#echo "::: Sudo will be used for this tool."
# Check if it is actually installed
# If it isn't, exit because the pivpn cannot be invoked without privileges.
if [[ $(dpkg-query -s sudo) ]];then
export SUDO="sudo"
else
echo "::: Please install sudo or run this as root."
exit 1
fi
fi
function makeOVPNFunc {
$SUDO /opt/pivpn/makeOVPN.sh
exit 1
}
function listOVPNFunc {
$SUDO /opt/pivpn/listOVPN.sh
exit 1
}
function debugFunc {
$SUDO /opt/pivpn/pivpnDebug.sh
exit 1
}
function removeOVPNFunc {
$SUDO /opt/pivpn/removeOVPN.sh
exit 1
}
function uninstallFunc {
$SUDO /opt/pivpn/uninstall.sh
exit 1
}
function helpFunc {
echo "::: Control all PiVPN specific functions!"
echo ":::"
echo "::: Usage: pivpn [options]"
echo ":::"
echo "::: Options:"
echo "::: -a, add Create a client ovpn profile"
echo "::: -d, debug Start a debugging session if having trouble"
echo "::: -l, list List all valid and revoked certificates"
echo "::: -r, revoke Revoke a client ovpn profile"
echo "::: -h, help Show this help dialog"
echo "::: -u, uninstall Uninstall PiVPN from your system!"
exit 1
}
if [[ $# = 0 ]]; then
helpFunc
fi
# Handle redirecting to specific functions based on arguments
case "$1" in
"-a" | "add" ) makeOVPNFunc;;
"-d" | "debug" ) debugFunc;;
"-l" | "list" ) listOVPNFunc;;
"-r" | "revoke" ) removeOVPNFunc;;
"-h" | "help" ) helpFunc;;
"-u" | "uninstall" ) uninstallFunc;;
* ) helpFunc;;
esac

18
scripts/bash-completion Normal file
View file

@ -0,0 +1,18 @@
_pivpn()
{
local cur prev opts
COMPREPLY=()
cur="${COMP_WORDS[COMP_CWORD]}"
prev="${COMP_WORDS[COMP_CWORD-1]}"
opts="debug add list revoke uninstall help"
if [[ ${cur} == -* ]] ; then
opts="-a -d -l -r -h -u"
COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
return 0
fi
COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
return 0
}
complete -F _pivpn pivpn

32
scripts/listOVPN.sh Normal file
View file

@ -0,0 +1,32 @@
#!/usr/bin/env bash
# PiVPN: list clients script
INDEX="/etc/openvpn/easy-rsa/keys/index.txt"
printf "\n"
if [ ! -f $INDEX ]; then
printf "The file: $INDEX \n"
printf "Was not Found!\n"
exit 1
fi
printf ": NOTE : You should always have a valid server entry below!\n"
printf "\n"
printf "\e[1m::: Certificate Status List :::\e[0m\n"
printf " ::\e[4m Status \e[0m||\e[4m Name \e[0m:: \n"
while read -r line || [[ -n "$line" ]]; do
status=$(echo $line | awk '{print $1}')
if [[ $status = "V" ]]; then
printf " Valid :: "
var=$(echo $line | awk '{print $5}' | cut -d'/' -f7)
var=${var#CN=}
printf " $var\n"
fi
if [[ $status = "R" ]]; then
printf " Revoked :: "
var=$(echo $line | awk '{print $6}' | cut -d'/' -f7)
var=${var#CN=}
printf " $var\n"
fi
done <$INDEX
printf "\n"

81
scripts/makeOVPN.sh Normal file
View file

@ -0,0 +1,81 @@
#!/bin/bash
# Create OVPN Client
# Default Variable Declarations
DEFAULT="Default.txt"
FILEEXT=".ovpn"
CRT=".crt"
OKEY=".key"
KEY=".3des.key"
CA="ca.crt"
TA="ta.key"
INSTALL_USER=$(cat /etc/pivpn/INSTALL_USER)
echo "Please enter a Name for the Client:"
read NAME
#Build the client key and then encrypt the key
cd /etc/openvpn/easy-rsa
source /etc/openvpn/easy-rsa/vars
./build-key-pass $NAME
cd keys
openssl rsa -in $NAME$OKEY -des3 -out $NAME$KEY
#1st Verify that clients Public Key Exists
if [ ! -f $NAME$CRT ]; then
echo "[ERROR]: Client Public Key Certificate not found: $NAME$CRT"
exit
fi
echo "Client's cert found: $NAME$CRT"
#Then, verify that there is a private key for that client
if [ ! -f $NAME$KEY ]; then
echo "[ERROR]: Client 3des Private Key not found: $NAME$KEY"
exit
fi
echo "Client's Private Key found: $NAME$KEY"
#Confirm the CA public key exists
if [ ! -f $CA ]; then
echo "[ERROR]: CA Public Key not found: $CA"
exit
fi
echo "CA public Key found: $CA"
#Confirm the tls-auth ta key file exists
if [ ! -f $TA ]; then
echo "[ERROR]: tls-auth Key not found: $TA"
exit
fi
echo "tls-auth Private Key found: $TA"
#Ready to make a new .ovpn file - Start by populating with the
#default file
cat $DEFAULT > $NAME$FILEEXT
#Now, append the CA Public Cert
echo "<ca>" >> $NAME$FILEEXT
cat $CA >> $NAME$FILEEXT
echo "</ca>" >> $NAME$FILEEXT
#Next append the client Public Cert
echo "<cert>" >> $NAME$FILEEXT
cat $NAME$CRT | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' >> $NAME$FILEEXT
echo "</cert>" >> $NAME$FILEEXT
#Then, append the client Private Key
echo "<key>" >> $NAME$FILEEXT
cat $NAME$KEY >> $NAME$FILEEXT
echo "</key>" >> $NAME$FILEEXT
#Finally, append the TA Private Key
echo "<tls-auth>" >> $NAME$FILEEXT
cat $TA >> $NAME$FILEEXT
echo "</tls-auth>" >> $NAME$FILEEXT
# Copy the .ovpn profile to the home directory for convenient remote access
cp /etc/openvpn/easy-rsa/keys/$NAME$FILEEXT /home/$INSTALL_USER/ovpns/$NAME$FILEEXT
echo "$NAME$FILEEXT moved to home directory."
whiptail --title "MakeOVPN" --msgbox "Done! $NAME$FILEEXT successfully created and \
moved to directory /home/$INSTALL_USER/ovpns." 8 78
# Original script written by Eric Jodoin.

2
scripts/pivpnDebug.sh Normal file
View file

@ -0,0 +1,2 @@
#!/usr/bin/env bash
echo "::: This feature is not yet implemented... stay tuned!"

47
scripts/removeOVPN.sh Normal file
View file

@ -0,0 +1,47 @@
#!/usr/bin/env bash
# PiVPN: revoke client script
INSTALL_USER=$(cat /etc/pivpn/INSTALL_USER)
REVOKE_STATUS=$(cat /etc/pivpn/REVOKE_STATUS)
INDEX="/etc/openvpn/easy-rsa/keys/index.txt"
if [ ! -f $INDEX ]; then
printf "The file: $INDEX \n"
printf "Was not Found!\n"
exit 1
fi
printf "\n"
printf " ::\e[4m Certificate List \e[0m:: \n"
while read -r line || [[ -n "$line" ]]; do
status=$(echo $line | awk '{print $1}')
if [[ $status = "V" ]]; then
var=$(echo $line | awk '{print $5}' | cut -d'/' -f7)
var=${var#CN=}
if [ "$var" != "server" ]; then
printf " $var\n"
fi
fi
done <$INDEX
printf "\n"
echo "::: Please enter the Name of the client to be revoked from the list above:"
read NAME
cd /etc/openvpn/easy-rsa
source /etc/openvpn/easy-rsa/vars
./revoke-full $NAME
echo "::: Certificate revoked, removing ovpns from /home/$INSTALL_USER/ovpns"
rm /home/$INSTALL_USER/ovpns/$NAME.ovpn
cp /etc/openvpn/easy-rsa/keys/crl.pem /etc/openvpn/crl.pem
echo "::: Completed!"
if [ $REVOKE_STATUS == 0 ]; then
echo 1 > /etc/pivpn/REVOKE_STATUS
printf "\nThis seems to be the first time you have revoked a cert.\n"
printf "We are adding the CRL to the server.conf and restarting openvpn.\n"
sed -i '/#crl-verify/c\crl-verify /etc/openvpn/crl.pem' /etc/openvpn/server.conf
systemctl restart openvpn.service
fi

117
scripts/uninstall.sh Normal file
View file

@ -0,0 +1,117 @@
#!/usr/bin/env bash
# PiVPN: Uninstall Script
# Must be root to uninstall
if [[ $EUID -eq 0 ]];then
echo "::: You are root."
else
echo "::: Sudo will be used for the uninstall."
# Check if it is actually installed
# If it isn't, exit because the unnstall cannot complete
if [[ $(dpkg-query -s sudo) ]];then
export SUDO="sudo"
else
echo "::: Please install sudo or run this as root."
exit 1
fi
fi
INSTALL_USER=$(cat /etc/pivpn/INSTALL_USER)
# Find the rows and columns
rows=$(tput lines)
columns=$(tput cols)
# Divide by two so the dialogs take up half of the screen, which looks nice.
r=$(( rows / 2 ))
c=$(( columns / 2 ))
spinner()
{
local pid=$1
local delay=0.50
local spinstr='/-\|'
while [ "$(ps a | awk '{print $1}' | grep "$pid")" ]; do
local temp=${spinstr#?}
printf " [%c] " "$spinstr"
local spinstr=$temp${spinstr%"$temp"}
sleep $delay
printf "\b\b\b\b\b\b"
done
printf " \b\b\b\b"
}
function removeAll {
# Purge dependencies
echo ":::"
dependencies=( openvpn easy-rsa git iptables-persistent dnsutils )
for i in "${dependencies[@]}"; do
if [ "$(dpkg-query -W --showformat='${Status}\n' "$i" 2> /dev/null | grep -c "ok installed")" -eq 1 ]; then
while true; do
read -rp "::: Do you wish to remove $i from your system? [y/n]: " yn
case $yn in
[Yy]* ) printf ":::\tRemoving %s..." "$i"; $SUDO apt-get -y remove --purge "$i" &> /dev/null & spinner $!; printf "done!\n";
if [ "$i" == "openvpn" ]; then UINST_OVPN=1 ; fi
break;;
[Nn]* ) printf ":::\tSkipping %s" "$i\n"; break;;
* ) printf "::: You must answer yes or no!\n";;
esac
done
else
printf ":::\tPackage %s not installed... Not removing.\n" "$i"
fi
done
# Take care of any additional package cleaning
printf "::: Auto removing remaining dependencies..."
$SUDO apt-get -y autoremove &> /dev/null & spinner $!; printf "done!\n";
printf "::: Auto cleaning remaining dependencies..."
$SUDO apt-get -y autoclean &> /dev/null & spinner $!; printf "done!\n";
echo ":::"
# Removing pivpn files
echo "::: Removing pivpn system files..."
$SUDO rm -rf /opt/pivpn &> /dev/null
$SUDO rm -rf /etc/.pivpn &> /dev/null
$SUDO rm -rf /etc/pivpn &> /dev/null
$SUDO rm -rf /home/$INSTALL_USER/ovpns &> /dev/null
$SUDO rm -rf /var/log/*pivpn* &> /dev/null
$SUDO rm -rf /var/log/*openvpn* &> /dev/null
if [[ $UINST_OVPN = 1 ]]; then
$SUDO rm -rf /etc/openvpn &> /dev/null
fi
$SUDO rm /usr/local/bin/pivpn &> /dev/null
$SUDO rm /etc/bash_completion.d/pivpn
# Disable IPv4 forwarding
sed -i '/net.ipv4.ip_forward=1/c\#net.ipv4.ip_forward=1' /etc/sysctl.conf
sysctl -p
echo ":::"
printf "::: Finished removing PiVPN from your system.\n"
printf "::: Reinstall by simpling running\n:::\n:::\tcurl -L vigilcode.com/pivpnsetup | bash\n:::\n::: at any time!\n:::\n"
}
function askreboot() {
printf "It is \e[1mstrongly\e[0m recommended to reboot after un-installation.\n"
read -p "Would you like to reboot now (y/n)? " -n 1 -r
echo
if [[ $REPLY =~ ^[Yy]$ ]]; then
printf "\nRebooting system...\n"
sleep 3
shutdown -r now
fi
}
######### SCRIPT ###########
echo "::: Preparing to remove packages, be sure that each may be safely removed depending on your operating system."
echo "::: (SAFE TO REMOVE ALL ON RASPBIAN)"
while true; do
read -rp "::: Do you wish to completely remove PiVPN configuration and installed packages from your system? (You will be prompted for each package) [y/n]: " yn
case $yn in
[Yy]* ) removeAll; askreboot; break;;
[Nn]* ) printf "::: Not removing anything, exiting...\n"; break;;
esac
done

37
server_config.txt Normal file
View file

@ -0,0 +1,37 @@
dev tun
proto udp
port 1194
ca /etc/openvpn/easy-rsa/keys/ca.crt
cert /etc/openvpn/easy-rsa/keys/server.crt
key /etc/openvpn/easy-rsa/keys/server.key
dh /etc/openvpn/easy-rsa/keys/dh1024.pem
server 10.8.0.0 255.255.255.0
# server and remote endpoints
ifconfig 10.8.0.1 10.8.0.2
# Add route to Client routing table for the OpenVPN Server
push "route 10.8.0.1 255.255.255.255"
# Add route to Client routing table for the OPenVPN Subnet
push "route 10.8.0.0 255.255.255.0"
# your local subnet
push "route LOCALIP 255.255.255.0"
# Set your primary domain name server address to Google DNS 8.8.8.8
push "dhcp-option DNS 8.8.8.8"
# Override the Client default gateway by using 0.0.0.0/1 and
# 128.0.0.0/1 rather than 0.0.0.0/0. This has the benefit of
# overriding but not wiping out the original default gateway.
push "redirect-gateway def1"
client-to-client
duplicate-cn
keepalive 10 120
tls-auth /etc/openvpn/easy-rsa/keys/ta.key 0
cipher AES-128-CBC
comp-lzo
user nobody
group nogroup
persist-key
persist-tun
#crl-verify /etc/openvpn/crl.pem
status /var/log/openvpn-status.log 20
log /var/log/openvpn.log
verb 1
# This configuration file was originally written by Lauren Orsini at ReadWrite.