From ebc32cae8622efe1da41361943ccb495e9a89d09 Mon Sep 17 00:00:00 2001 From: Matthew Saunders Brown Date: Wed, 24 Jul 2024 14:00:18 -0700 Subject: [PATCH] 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) --- README.md | 32 ++-- install.sh | 165 +++++++----------- wg-client-add.sh => sbin/wg-client-add.sh | 85 +++++---- wg-client-del.sh => sbin/wg-client-del.sh | 10 ++ .../wg-client-disable.sh | 0 .../wg-client-enable.sh | 0 wg-client-list.sh => sbin/wg-client-list.sh | 0 .../wg-client-qr-create-png.sh | 0 .../wg-client-qr-display.sh | 0 .../wg-client-zip-create.sh | 0 sbin/wg-client-zip-email.sh | 53 ++++++ wg-cron.sh => sbin/wg-cron.sh | 0 wg-peer-audit.sh => sbin/wg-peer-audit.sh | 0 wg.sh => sbin/wg.sh | 48 ++++- systemd/wg-cron.service | 9 + systemd/wg-cron.timer | 9 + 16 files changed, 242 insertions(+), 169 deletions(-) rename wg-client-add.sh => sbin/wg-client-add.sh (56%) rename wg-client-del.sh => sbin/wg-client-del.sh (81%) rename wg-client-disable.sh => sbin/wg-client-disable.sh (100%) rename wg-client-enable.sh => sbin/wg-client-enable.sh (100%) rename wg-client-list.sh => sbin/wg-client-list.sh (100%) rename wg-client-qr-create-png.sh => sbin/wg-client-qr-create-png.sh (100%) rename wg-client-qr-display.sh => sbin/wg-client-qr-display.sh (100%) rename wg-client-create-zip.sh => sbin/wg-client-zip-create.sh (100%) create mode 100755 sbin/wg-client-zip-email.sh rename wg-cron.sh => sbin/wg-cron.sh (100%) rename wg-peer-audit.sh => sbin/wg-peer-audit.sh (100%) rename wg.sh => sbin/wg.sh (52%) create mode 100644 systemd/wg-cron.service create mode 100644 systemd/wg-cron.timer diff --git a/README.md b/README.md index 754427e..9883995 100644 --- a/README.md +++ b/README.md @@ -2,42 +2,40 @@ 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 cd /usr/local/src/ -wget https://git.stack-source.com/msb/vpn-stack/archive/master.tar.gz -tar zxvf master.tar.gz +git clone https://git.stack-source.com/msb/vpn-stack.git cd vpn-stack bash install.sh -reboot ``` ## 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. +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 -wg-client-add.sh username [device] -wg-client-qr-display.sh username [device] +wg-client-add.sh -c +wg-client-qr-display.sh -c +wg-client-zip-email.sh -c -e ``` -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: +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: ```bash -wg-client-add.sh joe -wg-client-qr-display.sh joe +wg-client-add.sh -c 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 -Copyright (c) 2022 Matthew Saunders Brown \ +Copyright (c) 2024 Matthew Saunders Brown \ GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) diff --git a/install.sh b/install.sh index fc25436..99cb004 100755 --- a/install.sh +++ b/install.sh @@ -6,9 +6,9 @@ # Copyright (c) 2022 Matthew Saunders Brown # 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 # require root @@ -18,10 +18,10 @@ if [ "${EUID}" -ne 0 ]; then 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 != 22.04 ]; then - echo "this installer only runs on Ubuntu 22.04, bailing out" +os_id=`lsb_release -is 2>/dev/null` +os_release=`lsb_release -rs 2>/dev/null` +if [ $os_id != Debian ] || [ $os_release != 12 ]; then + echo "this installer only runs on Debian 12, bailing out" exit 1 fi @@ -42,28 +42,16 @@ fi # 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 # 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` -# 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 +# make sure systemd-resolved is installed, and resolvconf is not installed +DEBIAN_FRONTEND=noninteractive apt-get -y purge resolvconf +DEBIAN_FRONTEND=noninteractive apt-get -y install systemd-resolved -# 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 +# 1.1.1.1 (Cloudflare) DNS w/ DNS over TLS (DoT) for OS 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|#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 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 DEBIAN_FRONTEND=noninteractive apt-get -y install stubby 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 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 # 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 # remove temporary policy-rc.d rm -f /usr/sbin/policy-rc.d -systemctl restart dnsmasq.service - -# 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 +sed -i 's|After=network.target|After=wg-quick@wg0.service|g' /lib/systemd/system/dnsmasq.service +systemctl daemon-reload # 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 +# 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 # Address: 10.96.0.1 # Netmask: 255.240.0.0 = 12 @@ -201,7 +156,7 @@ 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 "Address = 10.96.0.1/16" >> /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 @@ -222,55 +177,53 @@ umask $UMASK systemctl enable wg-quick@wg0.service systemctl start wg-quick@wg0.service +systemctl restart dnsmasq.service # 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 # set up wireguard timer for wg-cron.sh # removes inactive peers (clients) endpoint (last connected IP) data from wireguard -mkdir -p /usr/local/lib/systemd/system/ -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-cron.timer +mkdir -p /usr/local/lib/systemd/system +cp systemd/wg-cron.* /usr/local/lib/systemd/system/ +chmod 644 /usr/local/lib/systemd/system/wg-cron.* systemctl daemon-reload systemctl enable wg-cron.timer systemctl start wg-cron.timer -# install fail2ban. configure draconian ssh failure blocking -DEBIAN_FRONTEND=noninteractive apt-get -y install fail2ban -echo "[Definition]" > /etc/fail2ban/fail2ban.local -echo "dbfile = :memory:" >> /etc/fail2ban/fail2ban.local -echo "[DEFAULT]" > /etc/fail2ban/jail.local -echo "ignoreip = 127.0.0.1/8" >> /etc/fail2ban/jail.local -echo "banaction = ufw" >> /etc/fail2ban/jail.local -echo "bantime = 24h" >> /etc/fail2ban/jail.d/defaults-debian.conf -echo "maxretry = 1" >> /etc/fail2ban/jail.d/defaults-debian.conf -systemctl enable fail2ban -systemctl start fail2ban +# get public interface (e.g. eth0, enp0s10, etc.) for adding to firewall config +INTERFACE=$(ip route get 1.1.1.1 | sed -n 's/.*dev \([^\ ]*\).*/\1/p') + +# configure firewalld +if [[ -f /etc/firewalld/zones/public.xml ]]; then + rm /etc/firewalld/zones/public.xml + firewall-cmd --reload +fi +firewall-cmd --permanent --zone=external --add-interface=$INTERFACE +firewall-cmd --permanent --zone=external --add-service=wireguard +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 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 "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 "To route system emails and to enable unattended upgrade notifications" echo "run these two commands, replacing user@example.com with your email address." diff --git a/wg-client-add.sh b/sbin/wg-client-add.sh similarity index 56% rename from wg-client-add.sh rename to sbin/wg-client-add.sh index c532ead..e48e338 100755 --- a/wg-client-add.sh +++ b/sbin/wg-client-add.sh @@ -14,10 +14,15 @@ help() thisfilename=$(basename -- "$0") echo "Add VPN client config." echo "" - echo "usage: $thisfilename -c [-h]" + echo "usage: $thisfilename -c [ -d ] [-h]" echo "" - echo " -h Print this help." - echo " -c Name of the client configuration." + echo " -h Print this help." + echo " -c Name of the client configuration." + echo " -d 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 "$@" @@ -37,61 +42,51 @@ if [ -f /etc/wireguard/clients/$config ] || [ -f /etc/wireguard/peers/$config ]; 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` +# set DNS to be used by config +if [[ $dnsconfig = dnsmasq ]]; then + DNS="DNS = 10.96.0.1" +elif [[ $dnsconfig = stubby ]]; then + primaryip=`ip route get 1.1.1.1| head -n 1 | cut -d ' ' -f 7` + DNS="DNS = $primaryip" +else + DNS="" +fi # 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)) +# but can take serveral minutes when assigned client IPs gets in to the 10s of thousands # address unassigned address=0 -# Network: 10.96.0.0/12 +# Network: 10.96.0.0/16 # HostMin: 10.96.0.1 -# HostMax: 10.111.255.254 +# HostMax: 10.96.255.254 -# 06 - 111 -secondoctet=96 -while [ $secondoctet -lt 112 ] && [ $address = 0 ]; do +# 0 - 255 +thirdoctet=0 +while [ $thirdoctet -lt 256 ] && [ $address = 0 ]; do - # 0 - 255 - thirdoctet=0 - while [ $thirdoctet -lt 256 ] && [ $address = 0 ]; do + fourthoctet=1 + while [ $fourthoctet -lt 256 ] && [ $address = 0 ]; do - fourthoctet=1 - while [ $fourthoctet -lt 256 ] && [ $address = 0 ]; do + testaddress=10.96.$thirdoctet.$fourthoctet - 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] + # skip reserved addresses + if [ $testaddress = "10.96.0.1" ]; then + fourthoctet=$[$fourthoctet+1] + elif [ $testaddress = "10.96.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 - secondoctet=$[$secondoctet+1] + thirdoctet=$[$thirdoctet+1] done @@ -131,13 +126,13 @@ wg-quick save wg0 cat << EOF > /etc/wireguard/clients/"$config" [Interface] Address = $address/32 -DNS = 10.96.0.1 PrivateKey = $key +$DNS [Peer] PublicKey = $publickey_server PresharedKey = $psk -AllowedIPs = 0.0.0.0/0 +AllowedIPs = $AllowedIPs Endpoint = $endpoint:51820 PersistentKeepalive = 25 EOF diff --git a/wg-client-del.sh b/sbin/wg-client-del.sh similarity index 81% rename from wg-client-del.sh rename to sbin/wg-client-del.sh index 31173be..bb58362 100755 --- a/wg-client-del.sh +++ b/sbin/wg-client-del.sh @@ -45,3 +45,13 @@ if [ -f /etc/wireguard/clients/$config ]; then rm /etc/wireguard/clients/$config echo "client config for $client removed" 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 diff --git a/wg-client-disable.sh b/sbin/wg-client-disable.sh similarity index 100% rename from wg-client-disable.sh rename to sbin/wg-client-disable.sh diff --git a/wg-client-enable.sh b/sbin/wg-client-enable.sh similarity index 100% rename from wg-client-enable.sh rename to sbin/wg-client-enable.sh diff --git a/wg-client-list.sh b/sbin/wg-client-list.sh similarity index 100% rename from wg-client-list.sh rename to sbin/wg-client-list.sh diff --git a/wg-client-qr-create-png.sh b/sbin/wg-client-qr-create-png.sh similarity index 100% rename from wg-client-qr-create-png.sh rename to sbin/wg-client-qr-create-png.sh diff --git a/wg-client-qr-display.sh b/sbin/wg-client-qr-display.sh similarity index 100% rename from wg-client-qr-display.sh rename to sbin/wg-client-qr-display.sh diff --git a/wg-client-create-zip.sh b/sbin/wg-client-zip-create.sh similarity index 100% rename from wg-client-create-zip.sh rename to sbin/wg-client-zip-create.sh diff --git a/sbin/wg-client-zip-email.sh b/sbin/wg-client-zip-email.sh new file mode 100755 index 0000000..5c87590 --- /dev/null +++ b/sbin/wg-client-zip-email.sh @@ -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 +# 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 -e [-h]" + echo "" + echo " -h Print this help." + echo " -c Name of the client configuration." + echo " -e 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 diff --git a/wg-cron.sh b/sbin/wg-cron.sh similarity index 100% rename from wg-cron.sh rename to sbin/wg-cron.sh diff --git a/wg-peer-audit.sh b/sbin/wg-peer-audit.sh similarity index 100% rename from wg-peer-audit.sh rename to sbin/wg-peer-audit.sh diff --git a/wg.sh b/sbin/wg.sh similarity index 52% rename from wg.sh rename to sbin/wg.sh index 2cdb097..790fc2a 100755 --- a/wg.sh +++ b/sbin/wg.sh @@ -13,6 +13,33 @@ fi # 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 # crude but good enough domain name format validation @@ -25,9 +52,18 @@ function wg::validate_domain () { 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 () { local OPTIND - while getopts "c:e:h" opt ; do + while getopts "c:d:e:h" opt ; do case "${opt}" in h ) # display help and exit help @@ -35,6 +71,16 @@ function wg::getoptions () { ;; c ) # client/config name 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 email=${OPTARG,,} diff --git a/systemd/wg-cron.service b/systemd/wg-cron.service new file mode 100644 index 0000000..a095675 --- /dev/null +++ b/systemd/wg-cron.service @@ -0,0 +1,9 @@ +[Unit] +Description=wireguard cron + +[Service] +Type=simple +ExecStart=/usr/local/sbin/wg-cron.sh + +[Install] +WantedBy=multi-user.target diff --git a/systemd/wg-cron.timer b/systemd/wg-cron.timer new file mode 100644 index 0000000..9865587 --- /dev/null +++ b/systemd/wg-cron.timer @@ -0,0 +1,9 @@ +[Unit] +Description=wiregaurd cron every 5 minutes + +[Timer] +OnCalendar=*:0/5 +Unit=wg-cron.service + +[Install] +WantedBy=multi-user.target