Switch from Ubuntu to Debian compatibility with signifant reworking of code and installer.
Installer now expects Debian 12 and requires base-stack repo installed first New systemd files New wg-client-zip-email.sh script Moved bash scripts into sbin dir Install & configure firewalld instead of ufw wg.sh now has configurable options - DNS nameserver settings - endpoint (FQDN or IP) - AllowedIPs (defaults to 0.0.0.0/0) Change the client network from 10.96.0.0/12 (1,048,574 max clients / IPs) to 10.96.0.0/16 (65,025 max clients / IPs)
This commit is contained in:
parent
c5df21b0f3
commit
ebc32cae86
32
README.md
32
README.md
|
@ -2,42 +2,40 @@
|
||||||
|
|
||||||
A set of bash scripts for installing and managing a WireGuard VPN server.
|
A set of bash scripts for installing and managing a WireGuard VPN server.
|
||||||
|
|
||||||
## Download & Install
|
## Requirements
|
||||||
|
A minimal Debian 12 server install with no extra services or packages installed.
|
||||||
|
It is recommended to first install base-stack which will configure a basic server set up including firewald & fail2ban to secure the server:
|
||||||
|
https://git.stack-source.com/msb/base-stack
|
||||||
|
|
||||||
Start with basic Ubuntu 22.04 install with no extra services or packages installed.
|
## Install
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cd /usr/local/src/
|
cd /usr/local/src/
|
||||||
wget https://git.stack-source.com/msb/vpn-stack/archive/master.tar.gz
|
git clone https://git.stack-source.com/msb/vpn-stack.git
|
||||||
tar zxvf master.tar.gz
|
|
||||||
cd vpn-stack
|
cd vpn-stack
|
||||||
bash install.sh
|
bash install.sh
|
||||||
reboot
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Configure Clients
|
## Configure Clients
|
||||||
|
|
||||||
Download and install client software from [wireguard.com](https://www.wireguard.com/install/).
|
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.
|
Add a client configuration to the server, display a qr code that can be scanned by a client, and email a zipped copy of the config.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
wg-client-add.sh username [device]
|
wg-client-add.sh -c <client>
|
||||||
wg-client-qr-display.sh username [device]
|
wg-client-qr-display.sh -c <client>
|
||||||
|
wg-client-zip-email.sh -c <client> -e <email>
|
||||||
```
|
```
|
||||||
|
|
||||||
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, display the qr code on the console screen, and then email a zipped copy of the config run:
|
||||||
For example, to add a client config for a user named joe and display the qr code on the console screen run:
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
wg-client-add.sh joe
|
wg-client-add.sh -c joe
|
||||||
wg-client-qr-display.sh joe
|
wg-client-qr-display.sh -c joe
|
||||||
|
wg-client-zip-email.sh -c joe -e joe@example.com
|
||||||
```
|
```
|
||||||
|
|
||||||
## 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.
|
|
||||||
|
|
||||||
## License
|
## License
|
||||||
Copyright (c) 2022 Matthew Saunders Brown <matthewsaundersbrown@gmail.com>\
|
Copyright (c) 2024 Matthew Saunders Brown <matthewsaundersbrown@gmail.com>\
|
||||||
GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||||
|
|
165
install.sh
165
install.sh
|
@ -6,9 +6,9 @@
|
||||||
# Copyright (c) 2022 Matthew Saunders Brown <matthewsaundersbrown@gmail.com>
|
# Copyright (c) 2022 Matthew Saunders Brown <matthewsaundersbrown@gmail.com>
|
||||||
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||||
#
|
#
|
||||||
# wireguard installer for Ubuntu 22.04
|
# wireguard installer for Debian 12
|
||||||
#
|
#
|
||||||
# this installer expects a clean Ubuntu 22.04 install with
|
# this installer expects a clean Debian 12 install with
|
||||||
# wireguard, stubby & dnsmasq *not* previously installed
|
# wireguard, stubby & dnsmasq *not* previously installed
|
||||||
|
|
||||||
# require root
|
# require root
|
||||||
|
@ -18,10 +18,10 @@ if [ "${EUID}" -ne 0 ]; then
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# do some basic pre-install checks - these are *not* exhaustive
|
# do some basic pre-install checks - these are *not* exhaustive
|
||||||
os_id=`lsb_release -is`
|
os_id=`lsb_release -is 2>/dev/null`
|
||||||
os_release=`lsb_release -rs`
|
os_release=`lsb_release -rs 2>/dev/null`
|
||||||
if [ $os_id != Ubuntu ] || [ $os_release != 22.04 ]; then
|
if [ $os_id != Debian ] || [ $os_release != 12 ]; then
|
||||||
echo "this installer only runs on Ubuntu 22.04, bailing out"
|
echo "this installer only runs on Debian 12, bailing out"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
@ -42,28 +42,16 @@ fi
|
||||||
|
|
||||||
# check for / set hostname
|
# check for / set hostname
|
||||||
|
|
||||||
# autodetection that should work on Ubuntu 22.04
|
# autodetection that should work on Debian 12
|
||||||
# you can change this to fit your network, or just set to a specific IP
|
# 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
|
# used by wireguard for vpn connections & stubby for DNS queries
|
||||||
IPv4=`ip route get 1.1.1.1| head -n 1 | cut -d ' ' -f 7`
|
IPv4=`ip route get 1.1.1.1| head -n 1 | cut -d ' ' -f 7`
|
||||||
|
|
||||||
# update system
|
# make sure systemd-resolved is installed, and resolvconf is not installed
|
||||||
apt -y update
|
DEBIAN_FRONTEND=noninteractive apt-get -y purge resolvconf
|
||||||
# update grub first, by itself, as it requires special overrides to run unattended
|
DEBIAN_FRONTEND=noninteractive apt-get -y install systemd-resolved
|
||||||
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
|
# 1.1.1.1 (Cloudflare) DNS w/ DNS over TLS (DoT) for OS
|
||||||
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|g' /etc/systemd/resolved.conf
|
sed -i 's|#DNS=|DNS=1.1.1.1|g' /etc/systemd/resolved.conf
|
||||||
sed -i 's|#FallbackDNS=|FallbackDNS=1.0.0.1|g' /etc/systemd/resolved.conf
|
sed -i 's|#FallbackDNS=|FallbackDNS=1.0.0.1|g' /etc/systemd/resolved.conf
|
||||||
sed -i "s|#Domains=|Domains=`hostname -d`|g" /etc/systemd/resolved.conf
|
sed -i "s|#Domains=|Domains=`hostname -d`|g" /etc/systemd/resolved.conf
|
||||||
|
@ -77,19 +65,6 @@ sed -i "s|dc_eximconfig_configtype='local'|dc_eximconfig_configtype='internet'|g
|
||||||
/usr/sbin/update-exim4.conf
|
/usr/sbin/update-exim4.conf
|
||||||
systemctl restart exim4
|
systemctl restart exim4
|
||||||
|
|
||||||
# configure automatic updates
|
|
||||||
DEBIAN_FRONTEND=noninteractive apt-get -y install unattended-upgrades
|
|
||||||
sed -i 's|APT::Periodic::Download-Upgradeable-Packages "0";|APT::Periodic::Download-Upgradeable-Packages "1";|g' /etc/apt/apt.conf.d/10periodic
|
|
||||||
sed -i 's|APT::Periodic::AutocleanInterval "0";|APT::Periodic::AutocleanInterval "7";|g' /etc/apt/apt.conf.d/10periodic
|
|
||||||
echo 'APT::Periodic::Unattended-Upgrade "1";' >> /etc/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
|
# stubby DNS Privacy stub resolver for wireguard clients
|
||||||
DEBIAN_FRONTEND=noninteractive apt-get -y install stubby
|
DEBIAN_FRONTEND=noninteractive apt-get -y install stubby
|
||||||
cp /etc/stubby/stubby.yml /etc/stubby/stubby.yml.default
|
cp /etc/stubby/stubby.yml /etc/stubby/stubby.yml.default
|
||||||
|
@ -118,6 +93,8 @@ systemctl restart stubby.service
|
||||||
|
|
||||||
# download adware + malware hosts file, used by dnsmasq
|
# download adware + malware hosts file, used by dnsmasq
|
||||||
wget --output-document=/usr/local/etc/hosts https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts
|
wget --output-document=/usr/local/etc/hosts https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts
|
||||||
|
# remove ipv6 records
|
||||||
|
sed -i '/::/d' /usr/local/etc/hosts
|
||||||
|
|
||||||
# dnsmasq will use adware + malware hosts file
|
# dnsmasq will use adware + malware hosts file
|
||||||
# and listen on wireguard server private lan IP
|
# and listen on wireguard server private lan IP
|
||||||
|
@ -146,44 +123,22 @@ echo "no-dhcp-interface=10.96.0.1" >> /etc/dnsmasq.d/local.conf
|
||||||
echo "bind-interfaces" >> /etc/dnsmasq.d/local.conf
|
echo "bind-interfaces" >> /etc/dnsmasq.d/local.conf
|
||||||
# remove temporary policy-rc.d
|
# remove temporary policy-rc.d
|
||||||
rm -f /usr/sbin/policy-rc.d
|
rm -f /usr/sbin/policy-rc.d
|
||||||
systemctl restart dnsmasq.service
|
sed -i 's|After=network.target|After=wg-quick@wg0.service|g' /lib/systemd/system/dnsmasq.service
|
||||||
|
systemctl daemon-reload
|
||||||
# install and configure ufw firewall
|
|
||||||
DEBIAN_FRONTEND=noninteractive apt-get -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 --force enable
|
|
||||||
|
|
||||||
# install & configure wireguard
|
# install & configure wireguard
|
||||||
DEBIAN_FRONTEND=noninteractive apt-get -y install net-tools wireguard wireguard-tools qrencode
|
DEBIAN_FRONTEND=noninteractive apt-get -y install net-tools wireguard wireguard-tools qrencode zip
|
||||||
|
|
||||||
# this will be the private network used by wireguard server & clients
|
# this will be the private network used by wireguard server & clients
|
||||||
|
# Network: 10.96.0.0/16
|
||||||
|
# Address: 10.96.0.1
|
||||||
|
# Netmask: 255.255.0.0
|
||||||
|
# Wildcard: 0.0.255.255
|
||||||
|
# Broadcast: 10.96.255.255
|
||||||
|
# HostMin: 10.96.0.1
|
||||||
|
# HostMax: 10.96.255.254
|
||||||
|
# Hosts/Net: 65025 (Private Internet)
|
||||||
|
|
||||||
# Network: 10.96.0.0/12
|
# Network: 10.96.0.0/12
|
||||||
# Address: 10.96.0.1
|
# Address: 10.96.0.1
|
||||||
# Netmask: 255.240.0.0 = 12
|
# Netmask: 255.240.0.0 = 12
|
||||||
|
@ -201,7 +156,7 @@ wg genkey > /etc/wireguard/.privatekey
|
||||||
cat /etc/wireguard/.privatekey | wg pubkey > /etc/wireguard/.publickey
|
cat /etc/wireguard/.privatekey | wg pubkey > /etc/wireguard/.publickey
|
||||||
# Generate wg0.conf
|
# Generate wg0.conf
|
||||||
echo "[Interface]" >> /etc/wireguard/wg0.conf
|
echo "[Interface]" >> /etc/wireguard/wg0.conf
|
||||||
echo "Address = 10.96.0.1/12" >> /etc/wireguard/wg0.conf
|
echo "Address = 10.96.0.1/16" >> /etc/wireguard/wg0.conf
|
||||||
echo "ListenPort = 51820" >> /etc/wireguard/wg0.conf
|
echo "ListenPort = 51820" >> /etc/wireguard/wg0.conf
|
||||||
echo "PrivateKey = "$(cat /etc/wireguard/.privatekey) >> /etc/wireguard/wg0.conf
|
echo "PrivateKey = "$(cat /etc/wireguard/.privatekey) >> /etc/wireguard/wg0.conf
|
||||||
echo "SaveConfig = true" >> /etc/wireguard/wg0.conf
|
echo "SaveConfig = true" >> /etc/wireguard/wg0.conf
|
||||||
|
@ -222,55 +177,53 @@ umask $UMASK
|
||||||
|
|
||||||
systemctl enable wg-quick@wg0.service
|
systemctl enable wg-quick@wg0.service
|
||||||
systemctl start wg-quick@wg0.service
|
systemctl start wg-quick@wg0.service
|
||||||
|
systemctl restart dnsmasq.service
|
||||||
|
|
||||||
# install wg*.sh scripts in to /usr/local/sbin/
|
# install wg*.sh scripts in to /usr/local/sbin/
|
||||||
cp wg*.sh /usr/local/sbin/
|
cp sbin/wg*.sh /usr/local/sbin/
|
||||||
chmod 755 /usr/local/sbin/wg*.sh
|
chmod 755 /usr/local/sbin/wg*.sh
|
||||||
|
|
||||||
# set up wireguard timer for wg-cron.sh
|
# set up wireguard timer for wg-cron.sh
|
||||||
# removes inactive peers (clients) endpoint (last connected IP) data from wireguard
|
# removes inactive peers (clients) endpoint (last connected IP) data from wireguard
|
||||||
mkdir -p /usr/local/lib/systemd/system/
|
mkdir -p /usr/local/lib/systemd/system
|
||||||
echo '[Unit]' > /usr/lib/systemd/system/wg-cron.timer
|
cp systemd/wg-cron.* /usr/local/lib/systemd/system/
|
||||||
echo 'Description=wiregaurd cron every 5 minutes' >> /usr/lib/systemd/system/wg-cron.timer
|
chmod 644 /usr/local/lib/systemd/system/wg-cron.*
|
||||||
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-cron.timer
|
|
||||||
systemctl daemon-reload
|
systemctl daemon-reload
|
||||||
systemctl enable wg-cron.timer
|
systemctl enable wg-cron.timer
|
||||||
systemctl start wg-cron.timer
|
systemctl start wg-cron.timer
|
||||||
|
|
||||||
# install fail2ban. configure draconian ssh failure blocking
|
# get public interface (e.g. eth0, enp0s10, etc.) for adding to firewall config
|
||||||
DEBIAN_FRONTEND=noninteractive apt-get -y install fail2ban
|
INTERFACE=$(ip route get 1.1.1.1 | sed -n 's/.*dev \([^\ ]*\).*/\1/p')
|
||||||
echo "[Definition]" > /etc/fail2ban/fail2ban.local
|
|
||||||
echo "dbfile = :memory:" >> /etc/fail2ban/fail2ban.local
|
# configure firewalld
|
||||||
echo "[DEFAULT]" > /etc/fail2ban/jail.local
|
if [[ -f /etc/firewalld/zones/public.xml ]]; then
|
||||||
echo "ignoreip = 127.0.0.1/8" >> /etc/fail2ban/jail.local
|
rm /etc/firewalld/zones/public.xml
|
||||||
echo "banaction = ufw" >> /etc/fail2ban/jail.local
|
firewall-cmd --reload
|
||||||
echo "bantime = 24h" >> /etc/fail2ban/jail.d/defaults-debian.conf
|
fi
|
||||||
echo "maxretry = 1" >> /etc/fail2ban/jail.d/defaults-debian.conf
|
firewall-cmd --permanent --zone=external --add-interface=$INTERFACE
|
||||||
systemctl enable fail2ban
|
firewall-cmd --permanent --zone=external --add-service=wireguard
|
||||||
systemctl start fail2ban
|
firewall-cmd --permanent --zone=internal --add-interface=wg0
|
||||||
|
firewall-cmd --permanent --zone=internal --add-service=dns
|
||||||
|
firewall-cmd --permanent --zone=internal --remove-service=mdns
|
||||||
|
firewall-cmd --permanent --zone=internal --remove-service=samba-client
|
||||||
|
firewall-cmd --permanent --zone=internal --remove-service=dhcpv6-client
|
||||||
|
# configure cross-zone forwarding
|
||||||
|
firewall-cmd --permanent --new-policy=internal2external
|
||||||
|
firewall-cmd --permanent --policy=internal2external --set-target=ACCEPT
|
||||||
|
firewall-cmd --permanent --policy=internal2external --add-ingress-zone=internal
|
||||||
|
firewall-cmd --permanent --policy=internal2external --add-egress-zone=external
|
||||||
|
firewall-cmd --reload
|
||||||
|
|
||||||
|
# configure draconian ssh failure blocking
|
||||||
|
sed -i "s|maxretry.*|maxretry = 1|g" /etc/fail2ban/jail.d/defaults-debian.conf
|
||||||
|
systemctl restart fail2ban
|
||||||
|
|
||||||
# display installation confirmation message
|
# display installation confirmation message
|
||||||
echo "WireGuard is now installed and configured and running."
|
echo "WireGuard is now installed and configured and running."
|
||||||
echo "You can begin adding clients with the wg-client-add.sh script."
|
echo "You can begin adding clients with the wg-client-add.sh script."
|
||||||
|
echo ""
|
||||||
# display instructions for enabling email notifications
|
echo "Reasonable defaults have been set. There are a couple of adjustable"
|
||||||
|
echo "settings in /usr/local/sbin/wg.sh if you need to customize your installation."
|
||||||
echo ""
|
echo ""
|
||||||
echo "To route system emails and to enable unattended upgrade notifications"
|
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 "run these two commands, replacing user@example.com with your email address."
|
||||||
|
|
|
@ -14,10 +14,15 @@ help()
|
||||||
thisfilename=$(basename -- "$0")
|
thisfilename=$(basename -- "$0")
|
||||||
echo "Add VPN client config."
|
echo "Add VPN client config."
|
||||||
echo ""
|
echo ""
|
||||||
echo "usage: $thisfilename -c <client> [-h]"
|
echo "usage: $thisfilename -c <client> [ -d <dnsconfig> ] [-h]"
|
||||||
echo ""
|
echo ""
|
||||||
echo " -h Print this help."
|
echo " -h Print this help."
|
||||||
echo " -c <client> Name of the client configuration."
|
echo " -c <client> Name of the client configuration."
|
||||||
|
echo " -d <dnsconfig> Optional. Can be one of the following:"
|
||||||
|
echo " none: Do not use VPN for DNS."
|
||||||
|
echo " stubby: Use the DNS Privacy Stub Resolver on the VPN."
|
||||||
|
echo " dnsmasq: Use the DNS Proxy on the VPN that provides both Privacy with Ad Blocking."
|
||||||
|
echo " Default is dnsmasq and can be changed in wg.sh."
|
||||||
}
|
}
|
||||||
|
|
||||||
wg::getoptions "$@"
|
wg::getoptions "$@"
|
||||||
|
@ -37,46 +42,40 @@ if [ -f /etc/wireguard/clients/$config ] || [ -f /etc/wireguard/peers/$config ];
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# set Endpoint to FQDN of this server
|
# set DNS to be used by config
|
||||||
endpoint=`hostname -f`
|
if [[ $dnsconfig = dnsmasq ]]; then
|
||||||
|
DNS="DNS = 10.96.0.1"
|
||||||
# alternatively set Endpoint to primary IPv4 of this server
|
elif [[ $dnsconfig = stubby ]]; then
|
||||||
# assumes a single IP on a /24 subnet is provisioned on the server
|
primaryip=`ip route get 1.1.1.1| head -n 1 | cut -d ' ' -f 7`
|
||||||
# you can change this to fit your network, or just set to a specific IP
|
DNS="DNS = $primaryip"
|
||||||
# this is the IP that clients use to establish vpn connection
|
else
|
||||||
# endpoint=`ip -4 -o addr show | awk '{ print $4 }' | grep '/24$' | cut -d / -f 1`
|
DNS=""
|
||||||
|
fi
|
||||||
|
|
||||||
# get next available IP
|
# get next available IP
|
||||||
# note that tests show this code is quick with a few hundred to low thousands of assigned client IPs
|
# 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
|
# but can take serveral minutes when assigned client IPs gets in to the 10s 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 unassigned
|
||||||
address=0
|
address=0
|
||||||
|
|
||||||
# Network: 10.96.0.0/12
|
# Network: 10.96.0.0/16
|
||||||
# HostMin: 10.96.0.1
|
# HostMin: 10.96.0.1
|
||||||
# HostMax: 10.111.255.254
|
# HostMax: 10.96.255.254
|
||||||
|
|
||||||
# 06 - 111
|
# 0 - 255
|
||||||
secondoctet=96
|
thirdoctet=0
|
||||||
while [ $secondoctet -lt 112 ] && [ $address = 0 ]; do
|
while [ $thirdoctet -lt 256 ] && [ $address = 0 ]; do
|
||||||
|
|
||||||
# 0 - 255
|
|
||||||
thirdoctet=0
|
|
||||||
while [ $thirdoctet -lt 256 ] && [ $address = 0 ]; do
|
|
||||||
|
|
||||||
fourthoctet=1
|
fourthoctet=1
|
||||||
while [ $fourthoctet -lt 256 ] && [ $address = 0 ]; do
|
while [ $fourthoctet -lt 256 ] && [ $address = 0 ]; do
|
||||||
|
|
||||||
testaddress=10.$secondoctet.$thirdoctet.$fourthoctet
|
testaddress=10.96.$thirdoctet.$fourthoctet
|
||||||
|
|
||||||
# skip reserved addresses
|
# skip reserved addresses
|
||||||
if [ $testaddress = "10.96.0.1" ]; then
|
if [ $testaddress = "10.96.0.1" ]; then
|
||||||
fourthoctet=$[$fourthoctet+1]
|
fourthoctet=$[$fourthoctet+1]
|
||||||
elif [ $testaddress = "10.111.255.255" ]; then
|
elif [ $testaddress = "10.96.255.255" ]; then
|
||||||
echo "all available addresses used, can not add more clients"
|
echo "all available addresses used, can not add more clients"
|
||||||
exit 1
|
exit 1
|
||||||
elif `grep -qr "$testaddress/" /etc/wireguard/clients/`; then
|
elif `grep -qr "$testaddress/" /etc/wireguard/clients/`; then
|
||||||
|
@ -89,10 +88,6 @@ while [ $secondoctet -lt 112 ] && [ $address = 0 ]; do
|
||||||
|
|
||||||
thirdoctet=$[$thirdoctet+1]
|
thirdoctet=$[$thirdoctet+1]
|
||||||
|
|
||||||
done
|
|
||||||
|
|
||||||
secondoctet=$[$secondoctet+1]
|
|
||||||
|
|
||||||
done
|
done
|
||||||
|
|
||||||
# set temp umask for creating wiregaurd configs
|
# set temp umask for creating wiregaurd configs
|
||||||
|
@ -131,13 +126,13 @@ wg-quick save wg0
|
||||||
cat << EOF > /etc/wireguard/clients/"$config"
|
cat << EOF > /etc/wireguard/clients/"$config"
|
||||||
[Interface]
|
[Interface]
|
||||||
Address = $address/32
|
Address = $address/32
|
||||||
DNS = 10.96.0.1
|
|
||||||
PrivateKey = $key
|
PrivateKey = $key
|
||||||
|
$DNS
|
||||||
|
|
||||||
[Peer]
|
[Peer]
|
||||||
PublicKey = $publickey_server
|
PublicKey = $publickey_server
|
||||||
PresharedKey = $psk
|
PresharedKey = $psk
|
||||||
AllowedIPs = 0.0.0.0/0
|
AllowedIPs = $AllowedIPs
|
||||||
Endpoint = $endpoint:51820
|
Endpoint = $endpoint:51820
|
||||||
PersistentKeepalive = 25
|
PersistentKeepalive = 25
|
||||||
EOF
|
EOF
|
|
@ -45,3 +45,13 @@ if [ -f /etc/wireguard/clients/$config ]; then
|
||||||
rm /etc/wireguard/clients/$config
|
rm /etc/wireguard/clients/$config
|
||||||
echo "client config for $client removed"
|
echo "client config for $client removed"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# check for png & zip files
|
||||||
|
if [[ -f /var/lib/wireguard/$config.png ]]; then
|
||||||
|
rm /var/lib/wireguard/$config.png
|
||||||
|
echo "png image for $client removed"
|
||||||
|
fi
|
||||||
|
if [[ -f /var/lib/wireguard/$config.zip ]]; then
|
||||||
|
echo "zip file for $client removed"
|
||||||
|
rm /var/lib/wireguard/$config.zip
|
||||||
|
fi
|
53
sbin/wg-client-zip-email.sh
Executable file
53
sbin/wg-client-zip-email.sh
Executable file
|
@ -0,0 +1,53 @@
|
||||||
|
#!/bin/bash
|
||||||
|
#
|
||||||
|
# vpn-stack
|
||||||
|
# A set of bash scripts for installing and managing a WireGuard VPN server.
|
||||||
|
# https://git.stack-source.com/msb/vpn-stack
|
||||||
|
# Copyright (c) 2022 Matthew Saunders Brown <matthewsaundersbrown@gmail.com>
|
||||||
|
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||||
|
|
||||||
|
# load include file
|
||||||
|
source $(dirname $0)/wg.sh
|
||||||
|
|
||||||
|
help()
|
||||||
|
{
|
||||||
|
thisfilename=$(basename -- "$0")
|
||||||
|
echo "Email client config."
|
||||||
|
echo ""
|
||||||
|
echo "usage: $thisfilename -c <client> -e <email> [-h]"
|
||||||
|
echo ""
|
||||||
|
echo " -h Print this help."
|
||||||
|
echo " -c <client> Name of the client configuration."
|
||||||
|
echo " -e <email> Email address to send config to."
|
||||||
|
}
|
||||||
|
|
||||||
|
wg::getoptions "$@"
|
||||||
|
|
||||||
|
# check for client config name
|
||||||
|
if [[ -z $client ]]; then
|
||||||
|
echo "client name is required"
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
|
||||||
|
# check for email address
|
||||||
|
if [[ -z $email ]]; then
|
||||||
|
echo "email address is required"
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
|
||||||
|
# set config file name
|
||||||
|
config=$client.conf
|
||||||
|
|
||||||
|
# check for existing config
|
||||||
|
if [ -f /etc/wireguard/clients/$config ]; then
|
||||||
|
|
||||||
|
# check for zip, create if it doesn't already exist
|
||||||
|
if [[ ! -f /var/lib/wireguard/$config.zip ]]; then
|
||||||
|
wg-client-zip-create.sh -c $client
|
||||||
|
fi
|
||||||
|
|
||||||
|
mail -s "WireGuard config for $client" --attach=/var/lib/wireguard/$config.zip $email <<< "Please find attached the WireGuard config for $client"
|
||||||
|
|
||||||
|
else
|
||||||
|
echo "config for $client $device does not exist"
|
||||||
|
fi
|
|
@ -13,6 +13,33 @@ fi
|
||||||
|
|
||||||
# constants
|
# constants
|
||||||
|
|
||||||
|
# Set Endpoint. Hard code value here, or leave blank for automatic configuration below
|
||||||
|
endpoint=
|
||||||
|
|
||||||
|
# Check if endpoint is hard coded above, configure automatically if not.
|
||||||
|
if [[ -z $endpoint ]]; then
|
||||||
|
fqdn=`hostname -f`
|
||||||
|
primaryip=`ip route get 1.1.1.1| head -n 1 | cut -d ' ' -f 7`
|
||||||
|
reversedns=`dig -x $primaryip +short | sed 's|.$||'`
|
||||||
|
# If forward & reverse DNS are configured and match use the FQDN, otherwise use primary IP.
|
||||||
|
if [[ $fqdn = $reversedns ]]; then
|
||||||
|
endpoint=$fqdn
|
||||||
|
else
|
||||||
|
endpoint=$primaryip
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# DNS. 3 options:
|
||||||
|
# - none: do not change client DNS settings
|
||||||
|
# - stubby: DNS Privacy
|
||||||
|
# - dnsmasq: DNS Privacy with Ad Blocking
|
||||||
|
# Default listed here, can be overriden via wg-client-add.sh
|
||||||
|
dnsconfig=dnsmasq
|
||||||
|
|
||||||
|
# IPs to route through the VPN. By default all traffic is routed through VPN. Alternatively you can specify a comma separated list of IPs/networks.
|
||||||
|
AllowedIPs=0.0.0.0/0
|
||||||
|
# AllowedIPs="10.96.0.0/16, 1.1.1.1, 1.0.0.1"
|
||||||
|
|
||||||
# functions
|
# functions
|
||||||
|
|
||||||
# crude but good enough domain name format validation
|
# crude but good enough domain name format validation
|
||||||
|
@ -25,9 +52,18 @@ function wg::validate_domain () {
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function wg::validate_client () {
|
||||||
|
local my_client=$1
|
||||||
|
if [[ $my_client =~ ^[[:alnum:]][-_[:alnum:]]{1,30}[[:alnum:]]$ ]] ; then
|
||||||
|
return 0;
|
||||||
|
else
|
||||||
|
return 1;
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
function wg::getoptions () {
|
function wg::getoptions () {
|
||||||
local OPTIND
|
local OPTIND
|
||||||
while getopts "c:e:h" opt ; do
|
while getopts "c:d:e:h" opt ; do
|
||||||
case "${opt}" in
|
case "${opt}" in
|
||||||
h ) # display help and exit
|
h ) # display help and exit
|
||||||
help
|
help
|
||||||
|
@ -35,6 +71,16 @@ function wg::getoptions () {
|
||||||
;;
|
;;
|
||||||
c ) # client/config name
|
c ) # client/config name
|
||||||
client=${OPTARG,,}
|
client=${OPTARG,,}
|
||||||
|
if ! wg::validate_client $client; then
|
||||||
|
echo "ERROR: '$client' is not a valid client config name."
|
||||||
|
echo "Client config name must begin & end with a letter or number,"
|
||||||
|
echo "can only contain letters numbers dashes and underscores,"
|
||||||
|
echo "and must be 3 to 32 characters in length."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
d ) # DNS config
|
||||||
|
dnsconfig=${OPTARG,,}
|
||||||
;;
|
;;
|
||||||
e ) # email address
|
e ) # email address
|
||||||
email=${OPTARG,,}
|
email=${OPTARG,,}
|
9
systemd/wg-cron.service
Normal file
9
systemd/wg-cron.service
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
[Unit]
|
||||||
|
Description=wireguard cron
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=simple
|
||||||
|
ExecStart=/usr/local/sbin/wg-cron.sh
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
9
systemd/wg-cron.timer
Normal file
9
systemd/wg-cron.timer
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
[Unit]
|
||||||
|
Description=wiregaurd cron every 5 minutes
|
||||||
|
|
||||||
|
[Timer]
|
||||||
|
OnCalendar=*:0/5
|
||||||
|
Unit=wg-cron.service
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
Loading…
Reference in New Issue
Block a user