initial commit

This commit is contained in:
Matthew Saunders Brown 2021-01-25 15:37:53 -08:00
commit 3d841a76aa
12 changed files with 811 additions and 0 deletions

19
LICENSE Normal file
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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