initial commit
This commit is contained in:
commit
3d841a76aa
19
LICENSE
Normal file
19
LICENSE
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
MIT License Copyright (c) 2021 Matthew Saunders Brown
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is furnished
|
||||||
|
to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice (including the next
|
||||||
|
paragraph) shall be included in all copies or substantial portions of the
|
||||||
|
Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
|
||||||
|
OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||||
|
OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
40
README.md
Normal file
40
README.md
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
# wireguard-stack
|
||||||
|
|
||||||
|
A set of bash scripts for installing and managing a WireGuard VPN server.
|
||||||
|
|
||||||
|
## Download & Install
|
||||||
|
|
||||||
|
Start with basic Ubuntu 20.04 install with no extra services or packages installed.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd /usr/local/src/
|
||||||
|
wget https://git.stack-source.com/stackaas/stack-vpn/archive/master.tar.gz
|
||||||
|
tar zxvf master.tar.gz
|
||||||
|
cd stack-vpn
|
||||||
|
chmod 750 wg-*.sh
|
||||||
|
mv wg-*.sh /usr/local/sbin/
|
||||||
|
/usr/local/sbin/wg-install.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
## Configure Clients
|
||||||
|
|
||||||
|
Download and install client software from [wireguard.com](https://www.wireguard.com/install/).
|
||||||
|
|
||||||
|
Add a client configuration to the server and display a qr code that can be scanned by a client. If the
|
||||||
|
|
||||||
|
```bash
|
||||||
|
wg-client-add.sh username [device]
|
||||||
|
wg-client-qr-display.sh username [device]
|
||||||
|
```
|
||||||
|
|
||||||
|
If the device option is left off then a "default" device will be added for that client/username.
|
||||||
|
For example, to add a client config for a user named joe and display the qr code on the console screen run:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
wg-client-add.sh joe
|
||||||
|
wg-client-qr-display.sh joe
|
||||||
|
```
|
||||||
|
|
||||||
|
# Todo
|
||||||
|
|
||||||
|
Complete documentation that describes in detail the configuration of the WireGuard server coming next. In the meantime review the comments in wg-install.sh to see details.
|
146
wg-client-add.sh
Executable file
146
wg-client-add.sh
Executable file
|
@ -0,0 +1,146 @@
|
||||||
|
#!/bin/bash
|
||||||
|
#
|
||||||
|
# wireguard-stack
|
||||||
|
# A set of bash scripts for installing and managing a WireGuard VPN server.
|
||||||
|
# https://git.stack-source.com/msb/wireguard-stack
|
||||||
|
# MIT License Copyright (c) 2021 Matthew Saunders Brown
|
||||||
|
|
||||||
|
# require root
|
||||||
|
if [ "${EUID}" -ne 0 ]; then
|
||||||
|
echo "This script must be run as root"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# check for and set client name
|
||||||
|
if [ -n "$1" ]; then
|
||||||
|
client=$1
|
||||||
|
# set beginning of config file name
|
||||||
|
config=$client
|
||||||
|
else
|
||||||
|
echo "client name not set"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# check if device name was set
|
||||||
|
if [ -n "$2" ]; then
|
||||||
|
device=$2
|
||||||
|
else
|
||||||
|
device=default
|
||||||
|
fi
|
||||||
|
|
||||||
|
# add device name & .conf to config file name
|
||||||
|
config=$config.$device.conf
|
||||||
|
|
||||||
|
# check for existing config
|
||||||
|
if [ -f /etc/wireguard/clients/$config ] || [ -f /etc/wireguard/peers/$config ]; then
|
||||||
|
echo "config for $client $device already exists"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# set Endpoint to FQDN of this server
|
||||||
|
endpoint=`hostname -f`
|
||||||
|
|
||||||
|
# alternatively set Endpoint to primary IPv4 of this server
|
||||||
|
# assumes a single IP on a /24 subnet is provisioned on the server
|
||||||
|
# you can change this to fit your network, or just set to a specific IP
|
||||||
|
# this is the IP that clients use to establish vpn connection
|
||||||
|
# endpoint=`ip -4 -o addr show | awk '{ print $4 }' | grep '/24$' | cut -d / -f 1`
|
||||||
|
|
||||||
|
# get next available IP
|
||||||
|
# note that tests show this code is quick with a few hundred to low thousands of assigned client IPs
|
||||||
|
# but can take serveral minutes when assigned client IPs gets in to the 10s or 100s of thousands
|
||||||
|
|
||||||
|
# get array of assigned IPs - no longer used, memory usage too high when larger number of IPs assigned
|
||||||
|
# addresses=($(grep Address /etc/wireguard/clients/*.conf | cut -d ' ' -f 3 | cut -d "/" -f 1))
|
||||||
|
|
||||||
|
# address unassigned
|
||||||
|
address=0
|
||||||
|
|
||||||
|
# Network: 10.96.0.0/12
|
||||||
|
# HostMin: 10.96.0.1
|
||||||
|
# HostMax: 10.111.255.254
|
||||||
|
|
||||||
|
# 06 - 111
|
||||||
|
secondoctet=96
|
||||||
|
while [ $secondoctet -lt 112 ] && [ $address = 0 ]; do
|
||||||
|
|
||||||
|
# 0 - 255
|
||||||
|
thirdoctet=0
|
||||||
|
while [ $thirdoctet -lt 256 ] && [ $address = 0 ]; do
|
||||||
|
|
||||||
|
fourthoctet=1
|
||||||
|
while [ $fourthoctet -lt 256 ] && [ $address = 0 ]; do
|
||||||
|
|
||||||
|
testaddress=10.$secondoctet.$thirdoctet.$fourthoctet
|
||||||
|
|
||||||
|
# skip reserved addresses
|
||||||
|
if [ $testaddress = "10.96.0.1" ]; then
|
||||||
|
fourthoctet=$[$fourthoctet+1]
|
||||||
|
elif [ $testaddress = "10.111.255.255" ]; then
|
||||||
|
echo "all available addresses used, can not add more clients"
|
||||||
|
exit 1
|
||||||
|
elif `grep -qr "$testaddress/" /etc/wireguard/clients/`; then
|
||||||
|
fourthoctet=$[$fourthoctet+1]
|
||||||
|
else
|
||||||
|
address=$testaddress
|
||||||
|
fi
|
||||||
|
|
||||||
|
done
|
||||||
|
|
||||||
|
thirdoctet=$[$thirdoctet+1]
|
||||||
|
|
||||||
|
done
|
||||||
|
|
||||||
|
secondoctet=$[$secondoctet+1]
|
||||||
|
|
||||||
|
done
|
||||||
|
|
||||||
|
# set temp umask for creating wiregaurd configs
|
||||||
|
UMASK=`umask`
|
||||||
|
umask 0077
|
||||||
|
|
||||||
|
# make sure clients config dir exists
|
||||||
|
if [[ ! -d /etc/wireguard/clients ]]; then
|
||||||
|
install --owner=root --group=root --mode=700 --directory /etc/wireguard/clients
|
||||||
|
fi
|
||||||
|
|
||||||
|
# make sure peers config dir exists
|
||||||
|
if [[ ! -d /etc/wireguard/peers ]]; then
|
||||||
|
install --owner=root --group=root --mode=700 --directory /etc/wireguard/peers
|
||||||
|
fi
|
||||||
|
|
||||||
|
key=$(wg genkey)
|
||||||
|
psk=$(wg genpsk)
|
||||||
|
publickey_server=$(cat /etc/wireguard/.publickey)
|
||||||
|
publickey_client=$(wg pubkey <<< $key)
|
||||||
|
|
||||||
|
# create server config for client (peer)
|
||||||
|
cat << EOF >> /etc/wireguard/peers/"$config"
|
||||||
|
[Peer]
|
||||||
|
PublicKey = $publickey_client
|
||||||
|
PresharedKey = $psk
|
||||||
|
AllowedIPs = $address/32
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# enable client on server
|
||||||
|
wg addconf wg0 /etc/wireguard/peers/"$config"
|
||||||
|
# save newly added client to server config
|
||||||
|
wg-quick save wg0
|
||||||
|
|
||||||
|
# create config for client
|
||||||
|
cat << EOF > /etc/wireguard/clients/"$config"
|
||||||
|
[Interface]
|
||||||
|
Address = $address/32
|
||||||
|
DNS = 10.96.0.1
|
||||||
|
PrivateKey = $key
|
||||||
|
|
||||||
|
[Peer]
|
||||||
|
PublicKey = $publickey_server
|
||||||
|
PresharedKey = $psk
|
||||||
|
AllowedIPs = 0.0.0.0/0
|
||||||
|
Endpoint = $endpoint:51820
|
||||||
|
PersistentKeepalive = 25
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# revert umask setting
|
||||||
|
umask $UMASK
|
46
wg-client-create-zip.sh
Executable file
46
wg-client-create-zip.sh
Executable file
|
@ -0,0 +1,46 @@
|
||||||
|
#!/bin/bash
|
||||||
|
#
|
||||||
|
# wireguard-stack
|
||||||
|
# A set of bash scripts for installing and managing a WireGuard VPN server.
|
||||||
|
# https://git.stack-source.com/msb/wireguard-stack
|
||||||
|
# MIT License Copyright (c) 2021 Matthew Saunders Brown
|
||||||
|
|
||||||
|
# require root
|
||||||
|
if [ "${EUID}" -ne 0 ]; then
|
||||||
|
echo "This script must be run as root"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# check for and set client name
|
||||||
|
if [ -n "$1" ]; then
|
||||||
|
client=$1
|
||||||
|
# set beginning of config file name
|
||||||
|
config=$client
|
||||||
|
else
|
||||||
|
echo "client name not set"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# check if device name was set
|
||||||
|
if [ -n "$2" ]; then
|
||||||
|
device=$2
|
||||||
|
else
|
||||||
|
device=default
|
||||||
|
fi
|
||||||
|
|
||||||
|
# add device name & .conf to config file name
|
||||||
|
config=$config.$device.conf
|
||||||
|
image=$config.$device.png
|
||||||
|
|
||||||
|
# check for existing config
|
||||||
|
if [ -f /etc/wireguard/clients/$config ]; then
|
||||||
|
|
||||||
|
if [ ! -d /var/lib/wireguard ]; then
|
||||||
|
install --owner=root --group=root --mode=700 --directory /var/lib/wireguard
|
||||||
|
fi
|
||||||
|
cd /var/lib/wireguard/
|
||||||
|
/usr/bin/zip -j $config.zip /etc/wireguard/clients/$config
|
||||||
|
|
||||||
|
else
|
||||||
|
echo "config for $client $device does not exist"
|
||||||
|
fi
|
47
wg-client-del.sh
Executable file
47
wg-client-del.sh
Executable file
|
@ -0,0 +1,47 @@
|
||||||
|
#!/bin/bash
|
||||||
|
#
|
||||||
|
# wireguard-stack
|
||||||
|
# A set of bash scripts for installing and managing a WireGuard VPN server.
|
||||||
|
# https://git.stack-source.com/msb/wireguard-stack
|
||||||
|
# MIT License Copyright (c) 2021 Matthew Saunders Brown
|
||||||
|
|
||||||
|
# require root
|
||||||
|
if [ "${EUID}" -ne 0 ]; then
|
||||||
|
echo "This script must be run as root"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# check for and set client name
|
||||||
|
if [ -n "$1" ]; then
|
||||||
|
client=$1
|
||||||
|
# set beginning of config file name
|
||||||
|
config=$client
|
||||||
|
else
|
||||||
|
echo "client name not set"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# check if device name was set
|
||||||
|
if [ -n "$2" ]; then
|
||||||
|
device=$2
|
||||||
|
else
|
||||||
|
device=default
|
||||||
|
fi
|
||||||
|
|
||||||
|
# add device name & .conf to config file name
|
||||||
|
config=$config.$device.conf
|
||||||
|
|
||||||
|
# check for server config
|
||||||
|
if [ -f /etc/wireguard/peers/$config ]; then
|
||||||
|
peer=$(grep PublicKey /etc/wireguard/peers/$config|cut -d ' ' -f 3)
|
||||||
|
wg set wg0 peer $peer remove
|
||||||
|
wg-quick save wg0
|
||||||
|
rm /etc/wireguard/peers/$config
|
||||||
|
echo "peer and server config for $client $device removed"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# check for client config
|
||||||
|
if [ -f /etc/wireguard/clients/$config ]; then
|
||||||
|
rm /etc/wireguard/clients/$config
|
||||||
|
echo "client config for $client $device removed"
|
||||||
|
fi
|
40
wg-client-disable.sh
Executable file
40
wg-client-disable.sh
Executable file
|
@ -0,0 +1,40 @@
|
||||||
|
#!/bin/bash
|
||||||
|
#
|
||||||
|
# wireguard-stack
|
||||||
|
# A set of bash scripts for installing and managing a WireGuard VPN server.
|
||||||
|
# https://git.stack-source.com/msb/wireguard-stack
|
||||||
|
# MIT License Copyright (c) 2021 Matthew Saunders Brown
|
||||||
|
|
||||||
|
# require root
|
||||||
|
if [ "${EUID}" -ne 0 ]; then
|
||||||
|
echo "This script must be run as root"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# check for and set client name
|
||||||
|
if [ -n "$1" ]; then
|
||||||
|
client=$1
|
||||||
|
# set beginning of config file name
|
||||||
|
config=$client
|
||||||
|
else
|
||||||
|
echo "client name not set"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# check if device name was set
|
||||||
|
if [ -n "$2" ]; then
|
||||||
|
device=$2
|
||||||
|
else
|
||||||
|
device=default
|
||||||
|
fi
|
||||||
|
|
||||||
|
# add device name & .conf to config file name
|
||||||
|
config=$config.$device.conf
|
||||||
|
|
||||||
|
# check for server config
|
||||||
|
if [ -f /etc/wireguard/peers/$config ]; then
|
||||||
|
peer=$(grep PublicKey /etc/wireguard/peers/$config|cut -d ' ' -f 3)
|
||||||
|
wg set wg0 peer $peer remove
|
||||||
|
wg-quick save wg0
|
||||||
|
echo "peer for $client $device disabled"
|
||||||
|
fi
|
54
wg-client-enable.sh
Executable file
54
wg-client-enable.sh
Executable file
|
@ -0,0 +1,54 @@
|
||||||
|
#!/bin/bash
|
||||||
|
#
|
||||||
|
# wireguard-stack
|
||||||
|
# A set of bash scripts for installing and managing a WireGuard VPN server.
|
||||||
|
# https://git.stack-source.com/msb/wireguard-stack
|
||||||
|
# MIT License Copyright (c) 2021 Matthew Saunders Brown
|
||||||
|
|
||||||
|
# require root
|
||||||
|
if [ "${EUID}" -ne 0 ]; then
|
||||||
|
echo "This script must be run as root"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# check for and set client name
|
||||||
|
if [ -n "$1" ]; then
|
||||||
|
client=$1
|
||||||
|
# set beginning of config file name
|
||||||
|
config=$client
|
||||||
|
else
|
||||||
|
echo "client name not set"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# check if device name was set
|
||||||
|
if [ -n "$2" ]; then
|
||||||
|
device=$2
|
||||||
|
else
|
||||||
|
device=default
|
||||||
|
fi
|
||||||
|
|
||||||
|
# add device name & .conf to config file name
|
||||||
|
config=$config.$device.conf
|
||||||
|
|
||||||
|
# check for server config
|
||||||
|
if [ -f /etc/wireguard/peers/$config ]; then
|
||||||
|
peer=$(grep PublicKey /etc/wireguard/peers/$config|cut -d ' ' -f 3)
|
||||||
|
status=$(wg |grep -c $peer)
|
||||||
|
if [ $status = 0 ]; then
|
||||||
|
wg addconf wg0 /etc/wireguard/peers/$config
|
||||||
|
wg-quick save wg0
|
||||||
|
echo "peer for $client $device enabled"
|
||||||
|
elif [ $status = 1 ]; then
|
||||||
|
echo "peer for $client $device already enabled"
|
||||||
|
else
|
||||||
|
echo "unexpected status for peer $client $device ($status)"
|
||||||
|
fi
|
||||||
|
elif [ -f /etc/wireguard/clients/$config ]; then
|
||||||
|
# create server config
|
||||||
|
# enable server config
|
||||||
|
echo "server config for $client $device not found, but client config exists."
|
||||||
|
echo "add programming here to create server config and enable"
|
||||||
|
else
|
||||||
|
echo "no configs for $client $device found"
|
||||||
|
fi
|
45
wg-client-qr-create-png.sh
Executable file
45
wg-client-qr-create-png.sh
Executable file
|
@ -0,0 +1,45 @@
|
||||||
|
#!/bin/bash
|
||||||
|
#
|
||||||
|
# wireguard-stack
|
||||||
|
# A set of bash scripts for installing and managing a WireGuard VPN server.
|
||||||
|
# https://git.stack-source.com/msb/wireguard-stack
|
||||||
|
# MIT License Copyright (c) 2021 Matthew Saunders Brown
|
||||||
|
|
||||||
|
# require root
|
||||||
|
if [ "${EUID}" -ne 0 ]; then
|
||||||
|
echo "This script must be run as root"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# check for and set client name
|
||||||
|
if [ -n "$1" ]; then
|
||||||
|
client=$1
|
||||||
|
# set beginning of config file name
|
||||||
|
config=$client
|
||||||
|
else
|
||||||
|
echo "client name not set"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# check if device name was set
|
||||||
|
if [ -n "$2" ]; then
|
||||||
|
device=$2
|
||||||
|
else
|
||||||
|
device=default
|
||||||
|
fi
|
||||||
|
|
||||||
|
# add device name & .conf to config file name
|
||||||
|
config=$config.$device.conf
|
||||||
|
image=$config.$device.png
|
||||||
|
|
||||||
|
# check for existing config
|
||||||
|
if [ -f /etc/wireguard/clients/$config ]; then
|
||||||
|
|
||||||
|
if [ ! -d /var/lib/wireguard ]; then
|
||||||
|
install --owner=root --group=root --mode=700 --directory /var/lib/wireguard
|
||||||
|
fi
|
||||||
|
qrencode -t png -r /etc/wireguard/clients/$config -o /var/lib/wireguard/$image
|
||||||
|
|
||||||
|
else
|
||||||
|
echo "config for $client $device does not exist"
|
||||||
|
fi
|
39
wg-client-qr-display.sh
Executable file
39
wg-client-qr-display.sh
Executable file
|
@ -0,0 +1,39 @@
|
||||||
|
#!/bin/bash
|
||||||
|
#
|
||||||
|
# wireguard-stack
|
||||||
|
# A set of bash scripts for installing and managing a WireGuard VPN server.
|
||||||
|
# https://git.stack-source.com/msb/wireguard-stack
|
||||||
|
# MIT License Copyright (c) 2021 Matthew Saunders Brown
|
||||||
|
|
||||||
|
# require root
|
||||||
|
if [ "${EUID}" -ne 0 ]; then
|
||||||
|
echo "This script must be run as root"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# check for and set client name
|
||||||
|
if [ -n "$1" ]; then
|
||||||
|
client=$1
|
||||||
|
# set beginning of config file name
|
||||||
|
config=$client
|
||||||
|
else
|
||||||
|
echo "client name not set"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# check if device name was set
|
||||||
|
if [ -n "$2" ]; then
|
||||||
|
device=$2
|
||||||
|
else
|
||||||
|
device=default
|
||||||
|
fi
|
||||||
|
|
||||||
|
# add device name & .conf to config file name
|
||||||
|
config=$config.$device.conf
|
||||||
|
|
||||||
|
# check for existing config
|
||||||
|
if [ -f /etc/wireguard/clients/$config ]; then
|
||||||
|
qrencode -t ansiutf8 < /etc/wireguard/clients/$config
|
||||||
|
else
|
||||||
|
echo "config for $client $device does not exist"
|
||||||
|
fi
|
40
wg-cron.sh
Executable file
40
wg-cron.sh
Executable file
|
@ -0,0 +1,40 @@
|
||||||
|
#!/bin/bash
|
||||||
|
#
|
||||||
|
# wireguard-stack
|
||||||
|
# A set of bash scripts for installing and managing a WireGuard VPN server.
|
||||||
|
# https://git.stack-source.com/msb/wireguard-stack
|
||||||
|
# MIT License Copyright (c) 2021 Matthew Saunders Brown
|
||||||
|
#
|
||||||
|
# wg-cron.sh
|
||||||
|
# check for peers (clients) with connections older that two minutes
|
||||||
|
# remove them then add them back to wireguard
|
||||||
|
# this removes the endpoint (last connected IP) and transfer stats
|
||||||
|
|
||||||
|
# require root
|
||||||
|
if [ "${EUID}" -ne 0 ]; then
|
||||||
|
echo "This script must be run as root"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# get peer of clients with "minutes" in their last handshake
|
||||||
|
clients=($(wg|grep -B 4 minutes|grep peer|cut -d ' ' -f 2))
|
||||||
|
|
||||||
|
# get number of peers found above
|
||||||
|
clientCount=${#clients[@]}
|
||||||
|
|
||||||
|
# if any peers found cycle through them
|
||||||
|
if [ $clientCount -gt 0 ]; then
|
||||||
|
|
||||||
|
for (( i=0; i<${clientCount}; i++ ));
|
||||||
|
do
|
||||||
|
# remove peer from wireguard
|
||||||
|
wg set wg0 peer ${clients[$i]} remove
|
||||||
|
config=$(grep ${clients[$i]} /etc/wireguard/peers/*.conf|cut -d : -f 1)
|
||||||
|
# add peer back to wireguard
|
||||||
|
wg addconf wg0 $config
|
||||||
|
done
|
||||||
|
|
||||||
|
# save to config so that changes survive wireguard restart
|
||||||
|
wg-quick save wg0
|
||||||
|
|
||||||
|
fi
|
255
wg-install.sh
Executable file
255
wg-install.sh
Executable file
|
@ -0,0 +1,255 @@
|
||||||
|
#!/bin/bash
|
||||||
|
#
|
||||||
|
# wireguard-stack
|
||||||
|
# A set of bash scripts for installing and managing a WireGuard VPN server.
|
||||||
|
# https://git.stack-source.com/msb/wireguard-stack
|
||||||
|
# MIT License Copyright (c) 2021 Matthew Saunders Brown
|
||||||
|
#
|
||||||
|
# wireguard installer for Ubuntu 20.04
|
||||||
|
#
|
||||||
|
# this installer expects a clean Ubuntu 20.04 install with
|
||||||
|
# wireguard, stubby & dnsmasq *not* previously installed
|
||||||
|
|
||||||
|
# require root
|
||||||
|
if [ "${EUID}" -ne 0 ]; then
|
||||||
|
echo "This script must be run as root"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# do some basic pre-install checks - these are *not* exhaustive
|
||||||
|
os_id=`lsb_release -is`
|
||||||
|
os_release=`lsb_release -rs`
|
||||||
|
if [ $os_id != Ubuntu ] || [ $os_release != 20.04 ]; then
|
||||||
|
echo "this installer only runs on Ubuntu 20.04, bailing out"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -d /etc/wiregaurd ]; then
|
||||||
|
echo "looks like wireguard is already installed, bailing out"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -d /etc/stubby/ ]; then
|
||||||
|
echo "looks like stubby is already installed, bailing out"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -d /etc/dnsmasq.d ]; then
|
||||||
|
echo "looks like dnsmasq is already installed, bailing out"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# assumes a single IP on a /24 subnet is provisioned on the server
|
||||||
|
# you can change this to fit your network, or just set to a specific IP
|
||||||
|
# used by wireguard for vpn connections & stubby for DNS queries
|
||||||
|
IPv4=`ip -4 -o addr show | awk '{ print $4 }' | grep '/24$' | cut -d / -f 1`
|
||||||
|
|
||||||
|
# update system
|
||||||
|
apt -y update
|
||||||
|
# update grub first, by itself, as it requires special overrides to run unattended
|
||||||
|
DEBIAN_FRONTEND=noninteractive apt-get -y -o Dpkg::Options::="--force-confdef" -o Dpkg::Options::="--force-confold" install grub-common grub2-common grub-pc grub-pc-bin
|
||||||
|
DEBIAN_FRONTEND=noninteractive apt-get -y dist-upgrade
|
||||||
|
DEBIAN_FRONTEND=noninteractive apt-get -y autoremove
|
||||||
|
|
||||||
|
# set system variables
|
||||||
|
echo "# for wireguard vpn" > /etc/sysctl.d/60-wireguard.conf
|
||||||
|
echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.d/60-wireguard.conf
|
||||||
|
echo "net.ipv6.conf.all.forwarding = 1" >> /etc/sysctl.d/60-wireguard.conf
|
||||||
|
echo "# for dnsmasq (dns)" >> /etc/sysctl.d/60-wireguard.conf
|
||||||
|
echo "net.ipv4.ip_nonlocal_bind = 1" >> /etc/sysctl.d/60-wireguard.conf
|
||||||
|
echo "net.ipv6.ip_nonlocal_bind = 1" >> /etc/sysctl.d/60-wireguard.conf
|
||||||
|
/sbin/sysctl --system
|
||||||
|
|
||||||
|
# DNS over TLS (DoT) for OS
|
||||||
|
sed -i 's|#DNS=|DNS=1.1.1.1#one.one.one.one|g' /etc/systemd/resolved.conf
|
||||||
|
sed -i 's|#FallbackDNS=|FallbackDNS=1.0.0.1#one.one.one.one|g' /etc/systemd/resolved.conf
|
||||||
|
sed -i "s|#Domains=|Domains=`hostname -d`|g" /etc/systemd/resolved.conf
|
||||||
|
sed -i 's|#DNSOverTLS=no|DNSOverTLS=yes|g' /etc/systemd/resolved.conf
|
||||||
|
sed -i 's|#Cache=yes|Cache=no|g' /etc/systemd/resolved.conf
|
||||||
|
systemctl restart systemd-resolved
|
||||||
|
|
||||||
|
# configure a minimal smtp server so automated emails (cron etc) can be sent
|
||||||
|
apt -y install exim4-daemon-light mailutils
|
||||||
|
sed -i "s|dc_eximconfig_configtype='local'|dc_eximconfig_configtype='internet'|g" /etc/exim4/update-exim4.conf.conf
|
||||||
|
/usr/sbin/update-exim4.conf
|
||||||
|
systemctl restart exim4
|
||||||
|
|
||||||
|
# configure automatic updates
|
||||||
|
apt -y install --no-install-recommends mailutils
|
||||||
|
apt -y install unattended-upgrades
|
||||||
|
sed -i 's|APT::Periodic::Download-Upgradeable-Packages "0";|APT::Periodic::Download-Upgradeable-Packages "1";|g' /apt/apt.conf.d/10periodic
|
||||||
|
sed -i 's|APT::Periodic::AutocleanInterval "0";|APT::Periodic::AutocleanInterval "7";|g' /apt/apt.conf.d/10periodic
|
||||||
|
echo 'APT::Periodic::Unattended-Upgrade "1";' >> /apt/apt.conf.d/10periodic
|
||||||
|
sed -i 's|// "${distro_id}:${distro_codename}-updates";| "${distro_id}:${distro_codename}-updates";|g' /etc/apt/apt.conf.d/50unattended-upgrades
|
||||||
|
sed -i 's|//Unattended-Upgrade::Remove-Unused-Kernel-Packages "true";|Unattended-Upgrade::Remove-Unused-Kernel-Packages "true";|g' /etc/apt/apt.conf.d/50unattended-upgrades
|
||||||
|
sed -i 's|//Unattended-Upgrade::Remove-Unused-Dependencies "false";|Unattended-Upgrade::Remove-Unused-Dependencies "true";|g' /etc/apt/apt.conf.d/50unattended-upgrades
|
||||||
|
sed -i 's|//Unattended-Upgrade::Automatic-Reboot "false";|Unattended-Upgrade::Automatic-Reboot "true";|g' /etc/apt/apt.conf.d/50unattended-upgrades
|
||||||
|
# between 8:00 and 9:59am UTC, change to suit your needs
|
||||||
|
REBOOT_TIME=$(printf "%02d" $((8 + RANDOM % 2))):$(printf "%02d" $((0 + RANDOM % 60)))
|
||||||
|
sed -i "s|//Unattended-Upgrade::Automatic-Reboot-Time \"02:00\";|Unattended-Upgrade::Automatic-Reboot-Time \"$REBOOT_TIME\";|g" /etc/apt/apt.conf.d/50unattended-upgrades
|
||||||
|
|
||||||
|
# stubby DNS Privacy stub resolver for wireguard clients
|
||||||
|
apt -y install stubby
|
||||||
|
cp /etc/stubby/stubby.yml /etc/stubby/stubby.yml.default
|
||||||
|
echo 'resolution_type: GETDNS_RESOLUTION_STUB' > /etc/stubby/stubby.yml
|
||||||
|
echo 'dns_transport_list:' >> /etc/stubby/stubby.yml
|
||||||
|
echo ' - GETDNS_TRANSPORT_TLS' >> /etc/stubby/stubby.yml
|
||||||
|
echo 'tls_authentication: GETDNS_AUTHENTICATION_REQUIRED' >> /etc/stubby/stubby.yml
|
||||||
|
echo 'tls_query_padding_blocksize: 128' >> /etc/stubby/stubby.yml
|
||||||
|
echo 'edns_client_subnet_private : 1' >> /etc/stubby/stubby.yml
|
||||||
|
echo 'round_robin_upstreams: 1' >> /etc/stubby/stubby.yml
|
||||||
|
echo 'idle_timeout: 10000' >> /etc/stubby/stubby.yml
|
||||||
|
echo 'listen_addresses:' >> /etc/stubby/stubby.yml
|
||||||
|
echo ' - 127.0.0.1' >> /etc/stubby/stubby.yml
|
||||||
|
echo ' - 0::1' >> /etc/stubby/stubby.yml
|
||||||
|
echo " - $IPv4" >> /etc/stubby/stubby.yml
|
||||||
|
echo 'upstream_recursive_servers:' >> /etc/stubby/stubby.yml
|
||||||
|
echo ' - address_data: 1.1.1.1' >> /etc/stubby/stubby.yml
|
||||||
|
echo ' tls_auth_name: "one.one.one.one"' >> /etc/stubby/stubby.yml
|
||||||
|
echo ' - address_data: 1.0.0.1' >> /etc/stubby/stubby.yml
|
||||||
|
echo ' tls_auth_name: "one.one.one.one"' >> /etc/stubby/stubby.yml
|
||||||
|
echo ' - address_data: 2606:4700:4700::1111' >> /etc/stubby/stubby.yml
|
||||||
|
echo ' tls_auth_name: "one.one.one.one"' >> /etc/stubby/stubby.yml
|
||||||
|
echo ' - address_data: 2606:4700:4700::1001' >> /etc/stubby/stubby.yml
|
||||||
|
echo ' tls_auth_name: "one.one.one.one"' >> /etc/stubby/stubby.yml
|
||||||
|
systemctl restart stubby.service
|
||||||
|
|
||||||
|
# download adware + malware hosts file, used by dnsmasq
|
||||||
|
wget --output-document=/usr/local/etc/hosts https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts
|
||||||
|
|
||||||
|
# dnsmasq will use adware + malware hosts file
|
||||||
|
# and listen on wireguard server private lan IP
|
||||||
|
# can be used by clients for adblocking
|
||||||
|
apt -y install dnsmasq
|
||||||
|
echo "domain-needed" > /etc/dnsmasq.d/local.conf
|
||||||
|
echo "bogus-priv" >> /etc/dnsmasq.d/local.conf
|
||||||
|
echo "no-resolv" >> /etc/dnsmasq.d/local.conf
|
||||||
|
echo "no-poll" >> /etc/dnsmasq.d/local.conf
|
||||||
|
echo "server=127.0.0.1" >> /etc/dnsmasq.d/local.conf
|
||||||
|
echo "addn-hosts=/usr/local/etc/hosts" >> /etc/dnsmasq.d/local.conf
|
||||||
|
# cache is disabled for extra privacy, but this impacts performance
|
||||||
|
# enable cache for increased performance, at the expense of privacy
|
||||||
|
echo "cache-size=0" >> /etc/dnsmasq.d/local.conf
|
||||||
|
echo "no-negcache" >> /etc/dnsmasq.d/local.conf
|
||||||
|
echo "listen-address=10.96.0.1" >> /etc/dnsmasq.d/local.conf
|
||||||
|
echo "no-dhcp-interface=10.96.0.1" >> /etc/dnsmasq.d/local.conf
|
||||||
|
echo "bind-interfaces" >> /etc/dnsmasq.d/local.conf
|
||||||
|
systemctl restart dnsmasq.service
|
||||||
|
|
||||||
|
# install and configure ufw firewall
|
||||||
|
apt -y install ufw
|
||||||
|
# enable wireguard port
|
||||||
|
ufw allow from any to $IPv4 port 51820 proto udp
|
||||||
|
# allow dns queries for wireguard clients
|
||||||
|
ufw allow from 10.96.0.0/12 to any port 53 proto udp
|
||||||
|
ufw allow from 10.96.0.0/12 to any port 53 proto tcp
|
||||||
|
# enable ssh for remote server management
|
||||||
|
# consider restricting this to specific IP(s) if you can
|
||||||
|
ufw allow 22/tcp
|
||||||
|
# nat/fowaring/masquerade rules for wireguard
|
||||||
|
# taken from https://www.linuxbabe.com/ubuntu/wireguard-vpn-server-ubuntu
|
||||||
|
# get line number of last ufw-before-forward entry in ufw before.rules config file
|
||||||
|
BRLINE=`grep -n 'ufw-before-forward' /etc/ufw/before.rules |tail -1|cut -f1 -d':'`
|
||||||
|
# insert/append after before.rules line number and increment
|
||||||
|
sed -i "$BRLINE""a # allow forwarding for trusted network, for wireguard" /etc/ufw/before.rules
|
||||||
|
BRLINE=$((BRLINE+1))
|
||||||
|
sed -i "$BRLINE""a -A ufw-before-forward -s 10.96.0.0/12 -j ACCEPT" /etc/ufw/before.rules
|
||||||
|
BRLINE=$((BRLINE+1))
|
||||||
|
sed -i "$BRLINE""a -A ufw-before-forward -d 10.96.0.0/12 -j ACCEPT" /etc/ufw/before.rules
|
||||||
|
# append to the end of before.rules
|
||||||
|
echo >> /etc/ufw/before.rules
|
||||||
|
echo "# NAT table rules" >> /etc/ufw/before.rules
|
||||||
|
echo "*nat" >> /etc/ufw/before.rules
|
||||||
|
echo ":POSTROUTING ACCEPT [0:0]" >> /etc/ufw/before.rules
|
||||||
|
echo "-A POSTROUTING -o eth0 -j MASQUERADE" >> /etc/ufw/before.rules
|
||||||
|
echo >> /etc/ufw/before.rules
|
||||||
|
echo "# End each table with the 'COMMIT' line or these rules won't be processed" >> /etc/ufw/before.rules
|
||||||
|
echo "COMMIT" >> /etc/ufw/before.rules
|
||||||
|
|
||||||
|
ufw enable
|
||||||
|
|
||||||
|
# install & configure wireguard
|
||||||
|
apt -y install net-tools wireguard wireguard-tools qrencode
|
||||||
|
|
||||||
|
# this will be the private network used by wireguard server & clients
|
||||||
|
# Network: 10.96.0.0/12
|
||||||
|
# Address: 10.96.0.1
|
||||||
|
# Netmask: 255.240.0.0 = 12
|
||||||
|
# Wildcard: 0.15.255.255
|
||||||
|
# Broadcast: 10.111.255.255
|
||||||
|
# HostMin: 10.96.0.1
|
||||||
|
# HostMax: 10.111.255.254
|
||||||
|
# Hosts/Net: 1048574 (Private Internet)
|
||||||
|
|
||||||
|
# set temp umask for creating wiregaurd configs
|
||||||
|
UMASK=`umask`
|
||||||
|
umask 0077
|
||||||
|
# create keys
|
||||||
|
wg genkey > /etc/wireguard/.privatekey
|
||||||
|
cat /etc/wireguard/.privatekey | wg pubkey > /etc/wireguard/.publickey
|
||||||
|
# Generate wg0.conf
|
||||||
|
echo "[Interface]" >> /etc/wireguard/wg0.conf
|
||||||
|
echo "Address = 10.96.0.1/12" >> /etc/wireguard/wg0.conf
|
||||||
|
echo "ListenPort = 51820" >> /etc/wireguard/wg0.conf
|
||||||
|
echo "PrivateKey = "$(cat /etc/wireguard/.privatekey) >> /etc/wireguard/wg0.conf
|
||||||
|
echo "SaveConfig = true" >> /etc/wireguard/wg0.conf
|
||||||
|
echo >> /etc/wireguard/wg0.conf
|
||||||
|
# make backup copy of initial wg0.conf. can be used to reset server config
|
||||||
|
# and optionally re-enable peers if anything gets fubared
|
||||||
|
cp /etc/wireguard/wg0.conf /etc/wireguard/.wg0.conf
|
||||||
|
# make sure perms are correct. redundant, umask should have taken care of this
|
||||||
|
chmod 600 /etc/wireguard/*
|
||||||
|
chmod 600 /etc/wireguard/.wg0.conf
|
||||||
|
|
||||||
|
# create dirs for client & peer configs
|
||||||
|
install --owner=root --group=root --mode=700 --directory /etc/wireguard/clients
|
||||||
|
install --owner=root --group=root --mode=700 --directory /etc/wireguard/peers
|
||||||
|
|
||||||
|
# revert umask setting
|
||||||
|
umask $UMASK
|
||||||
|
|
||||||
|
systemctl enable wg-quick@wg0.service
|
||||||
|
systemctl start wg-quick@wg0.service
|
||||||
|
|
||||||
|
# set up wireguard timer for wg-cron.sh
|
||||||
|
# removes inactive peers (clients) endpoint (last connected IP) data from wireguard
|
||||||
|
# /usr/lib/systemd/system/wg-cron.timer
|
||||||
|
echo '[Unit]' > /usr/lib/systemd/system/wg-cron.timer
|
||||||
|
echo 'Description=wiregaurd cron every 5 minutes' >> /usr/lib/systemd/system/wg-cron.timer
|
||||||
|
echo '' >> /usr/lib/systemd/system/wg-cron.timer
|
||||||
|
echo '[Timer]' >> /usr/lib/systemd/system/wg-cron.timer
|
||||||
|
echo 'OnCalendar=*:0/5' >> /usr/lib/systemd/system/wg-cron.timer
|
||||||
|
echo 'Unit=wg-cron.service' >> /usr/lib/systemd/system/wg-cron.timer
|
||||||
|
echo '' >> /usr/lib/systemd/system/wg-cron.timer
|
||||||
|
echo '[Install]' >> /usr/lib/systemd/system/wg-cron.timer
|
||||||
|
echo 'WantedBy=multi-user.target' >> /usr/lib/systemd/system/wg-cron.timer
|
||||||
|
# /usr/lib/systemd/system/wg-cron.service
|
||||||
|
echo '[Unit]' > /usr/lib/systemd/system/wg-cron.service
|
||||||
|
echo 'Description=wireguard cron' >> /usr/lib/systemd/system/wg-cron.service
|
||||||
|
echo '' >> /usr/lib/systemd/system/wg-cron.service
|
||||||
|
echo '[Service]' >> /usr/lib/systemd/system/wg-cron.service
|
||||||
|
echo 'Type=simple' >> /usr/lib/systemd/system/wg-cron.service
|
||||||
|
echo 'ExecStart=/usr/local/sbin/wg-cron.sh' >> /usr/lib/systemd/system/wg-cron.service
|
||||||
|
echo '' >> /usr/lib/systemd/system/wg-cron.service
|
||||||
|
echo '[Install]' >> /usr/lib/systemd/system/wg-cron.service
|
||||||
|
echo 'WantedBy=multi-user.target' >> /usr/lib/systemd/system/wg-cron.service
|
||||||
|
# enable wg-cront.timer
|
||||||
|
systemctl daemon-reload
|
||||||
|
systemctl enable wg-cron.timer
|
||||||
|
systemctl start wg-cron.timer
|
||||||
|
|
||||||
|
# install wg-*.sh scripts in to /usr/local/sbin/
|
||||||
|
cp wg-*.sh /usr/local/sbin/
|
||||||
|
chmod 755 /usr/local/sbin/wg-*.sh
|
||||||
|
|
||||||
|
# display installation confirmation message
|
||||||
|
echo "WireGuard is now installed and configured and running."
|
||||||
|
echo "You can begin adding clients with the wg-client-add.sh script."
|
||||||
|
|
||||||
|
# display instructions for enabling email notifications
|
||||||
|
echo ""
|
||||||
|
echo "To route system emails and to enable unattended upgrade notifications"
|
||||||
|
echo "run these two commands, replacing user@example.com with your email address."
|
||||||
|
echo ""
|
||||||
|
echo "echo \"root: user@example.com\" >> /etc/aliases"
|
||||||
|
echo "sed -i 's|//Unattended-Upgrade::Mail \"\";|Unattended-Upgrade::Mail \"user@example.com\";|g' /etc/apt/apt.conf.d/50unattended-upgrades"
|
40
wg-peer-audit.sh
Executable file
40
wg-peer-audit.sh
Executable file
|
@ -0,0 +1,40 @@
|
||||||
|
#!/bin/bash
|
||||||
|
#
|
||||||
|
# wireguard-stack
|
||||||
|
# A set of bash scripts for installing and managing a WireGuard VPN server.
|
||||||
|
# https://git.stack-source.com/msb/wireguard-stack
|
||||||
|
# MIT License Copyright (c) 2021 Matthew Saunders Brown
|
||||||
|
#
|
||||||
|
# wg-peer-audit.sh
|
||||||
|
# check that peer config file exists for all currently active peers
|
||||||
|
# this is basis of a "cleanup" script to remove configs for invalid
|
||||||
|
# old or deleted clients
|
||||||
|
|
||||||
|
# require root
|
||||||
|
if [ "${EUID}" -ne 0 ]; then
|
||||||
|
echo "This script must be run as root"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# get all peers in running wireguard server
|
||||||
|
peers=($(wg|grep peer|cut -d ' ' -f 2))
|
||||||
|
|
||||||
|
# get number of peers found above
|
||||||
|
peersCount=${#peers[@]}
|
||||||
|
|
||||||
|
# if any peers found cycle through them
|
||||||
|
if [ $peersCount -gt 0 ]; then
|
||||||
|
|
||||||
|
for (( i=0; i<${peersCount}; i++ ));
|
||||||
|
do
|
||||||
|
grep -q ${peers[$i]} /etc/wireguard/peers/*.conf
|
||||||
|
match=$?
|
||||||
|
if [[ $match != 0 ]]; then
|
||||||
|
echo "did not find peer config for: ${peers[$i]}"
|
||||||
|
echo "consider removing peer now"
|
||||||
|
#wg set wg0 peer ${peers[$i]} remove
|
||||||
|
#wg-quick save wg0
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
fi
|
Loading…
Reference in New Issue
Block a user