Initial migration

This commit is contained in:
deflax 2023-11-10 02:03:18 +02:00
parent 1f823e556e
commit 163ccbd03f
17 changed files with 1369 additions and 0 deletions

35
README.md Normal file
View file

@ -0,0 +1,35 @@
\ \ /_) ___| |
\ \ \ / | __| _ \ | _` | __| _ \
\ \ \ / | | __/ | | ( | | __/
\_/\_/ _|_| \___|\____|\__,_|\__|\___|
Wireguard based VPN server endpoint with LDAP support
Tested on Debian 12 bookworm
# Server Commands
./init.sh - setup system services (wireguard, unbound, iptables, sysctl)
./peer_add.sh - define new peer for a new remote device. generates config and QR code inside /etc/wireguard/clients
./peer_del.sh - delete a peer and salvage its ip address back to the ip pool
./peer_addall.sh - recreates wireguard state using existing clients in /etc/wireguard/clients dir
./peer_mail.sh - send the generated profile to the client and remove the sensitive data from server
# Server Tools
./gen-ip-database.sh - generate an ip pool for wireguard peers
./wgstats.sh - show peer stats similar based on wg show all dump
./wgldap.sh - tail the log of the wgldapsync service
# Client Side Tools
./client-tools/wg-rapid - modified wireguard client based on wg-quick that works with systemd-resolv
./client-tools/startvpn.desktop - shortcut for wg-rapid. update the parameter with peer filename

8
client-tools/startvpn.desktop Executable file
View file

@ -0,0 +1,8 @@
[Desktop Entry]
Name=startvpn
Exec=/usr/local/bin/wg-rapid profile
Comment=
Terminal=true
Icon=network-vpn
Type=Application
Name[en_US]=startvpn

400
client-tools/wg-rapid Executable file
View file

@ -0,0 +1,400 @@
#!/bin/bash
# SPDX-License-Identifier: GPL-2.0
#
# Copyright (C) 2015-2020 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
# Copyright (C) 2021-2022 Daniel afx <daniel@deflax.net>
#
#set -e -o pipefail
shopt -s extglob
export LC_ALL=C
SELF="$(readlink -f "${BASH_SOURCE[0]}")"
export PATH="${SELF%/*}:$PATH"
WG_CONFIG=""
CONFIG_FILE=""
PROGRAM="${0##*/}"
ARGS=( "$@" )
EXTERNAL_NETWORK_TEST_IP="1.1.1.1"
cmd_usage() {
cat >&2 <<-_EOF
Usage: $PROGRAM [ CONFIG_NAME ]
CONFIG_NAME is the name of a configuration file, which is also the interface
name followed by \`.conf'. It should be a configuration found at
/etc/wireguard/INTERFACE.conf. It is to be readable by wg(8)'s \`setconf'
sub-command, with the exception of the following additions
to the [Interface] section, which are handled by $PROGRAM:
- Address: may be specified one or more times and contains one or more
IP addresses (with an optional CIDR mask) to be set for the interface.
- DNS: an optional DNS server to use while the device is up.
- MTU: an optional MTU for the interface; if unspecified, auto-calculated.
- Table: an optional routing table to which routes will be added; if
unspecified or \`auto', the default table is used. If \`off', no routes
are added.
- PreUp, PostUp, PreDown, PostDown: script snippets which will be executed
by bash(1) at the corresponding phases of the link, most commonly used
to configure DNS. The string \`%i' is expanded to INTERFACE.
If for some reason the interface is already up, you could use:
$PROGRAM [ CONFIG_NAME ] down
_EOF
}
# Helper Functions
auto_su() {
[[ $UID == 0 ]] || exec sudo -p "$PROGRAM must be run as root. Please enter the password for %u to continue: " -- "$BASH" -- "$SELF" "${ARGS[@]}"
}
say() {
echo " ] $*"
}
die() {
echo "!] $*" >&2
exit 1
}
cmd() {
echo "#] $*" >&2
"$@"
}
execute_hooks() {
local hook
for hook in "$@"; do
hook="${hook//%i/$INTERFACE}"
echo "#] $hook" >&2
(eval "$hook")
done
}
parse_options() {
INTERFACE=""
ADDRESSES=( )
MTU=""
DNS=( )
DNS_SEARCH=( )
TABLE=""
PRE_UP=( )
POST_UP=( )
PRE_DOWN=( )
POST_DOWN=( )
local interface_section=0 line key value stripped v
CONFIG_FILE="$1"
[[ $CONFIG_FILE =~ ^[a-zA-Z0-9_=+.-]{1,15}$ ]] && CONFIG_FILE="/etc/wireguard/$CONFIG_FILE.conf"
[[ -e $CONFIG_FILE ]] || die "\`$CONFIG_FILE' does not exist"
[[ $CONFIG_FILE =~ (^|/)([a-zA-Z0-9_=+.-]{1,15})\.conf$ ]] || die "The config file must be a valid interface name, followed by .conf"
CONFIG_FILE="$(readlink -f "$CONFIG_FILE")"
((($(stat -c '0%#a' "$CONFIG_FILE") & $(stat -c '0%#a' "${CONFIG_FILE%/*}") & 0007) == 0)) || echo "Warning: \`$CONFIG_FILE' is world accessible" >&2
INTERFACE="${BASH_REMATCH[2]}"
shopt -s nocasematch
while read -r line || [[ -n $line ]]; do
stripped="${line%%\#*}"
key="${stripped%%=*}"; key="${key##*([[:space:]])}"; key="${key%%*([[:space:]])}"
value="${stripped#*=}"; value="${value##*([[:space:]])}"; value="${value%%*([[:space:]])}"
[[ $key == "["* ]] && interface_section=0
[[ $key == "[Interface]" ]] && interface_section=1
if [[ $interface_section -eq 1 ]]; then
case "$key" in
Address) ADDRESSES+=( ${value//,/ } ); continue ;;
MTU) MTU="$value"; continue ;;
DNS) for v in ${value//,/ }; do
[[ $v =~ (^[0-9.]+$)|(^.*:.*$) ]] && DNS+=( $v ) || DNS_SEARCH+=( $v )
done; continue ;;
Table) TABLE="$value"; continue ;;
PreUp) PRE_UP+=( "$value" ); continue ;;
PreDown) PRE_DOWN+=( "$value" ); continue ;;
PostUp) POST_UP+=( "$value" ); continue ;;
PostDown) POST_DOWN+=( "$value" ); continue ;;
esac
fi
WG_CONFIG+="$line"$'\n'
done < "$CONFIG_FILE"
shopt -u nocasematch
}
set_config() {
cmd wg setconf "$INTERFACE" <(echo "$WG_CONFIG")
}
# Setup Interface and Address
add_if() {
local ret
if ! cmd ip link add "$INTERFACE" type wireguard; then
ret=$?
[[ -e /sys/module/wireguard ]] || ! command -v "${WG_QUICK_USERSPACE_IMPLEMENTATION:-wireguard-go}" >/dev/null && exit $ret
echo "!] Missing WireGuard kernel module. Falling back to slow userspace implementation." >&2
cmd "${WG_QUICK_USERSPACE_IMPLEMENTATION:-wireguard-go}" "$INTERFACE"
fi
}
del_if() {
local table
#[[ $HAVE_SET_DNS -eq 0 ]] || unset_dns
#[[ $HAVE_SET_FIREWALL -eq 0 ]] || remove_firewall
if [[ -z $TABLE || $TABLE == auto ]] && get_fwmark table && [[ $(wg show "$INTERFACE" allowed-ips) =~ /0(\ |$'\n'|$) ]]; then
while [[ $(ip -4 rule show 2>/dev/null) == *"lookup $table"* ]]; do
cmd ip -4 rule delete table $table
done
while [[ $(ip -4 rule show 2>/dev/null) == *"from all lookup main suppress_prefixlength 0"* ]]; do
cmd ip -4 rule delete table main suppress_prefixlength 0
done
while [[ $(ip -6 rule show 2>/dev/null) == *"lookup $table"* ]]; do
cmd ip -6 rule delete table $table
done
while [[ $(ip -6 rule show 2>/dev/null) == *"from all lookup main suppress_prefixlength 0"* ]]; do
cmd ip -6 rule delete table main suppress_prefixlength 0
done
fi
cmd ip link delete dev "$INTERFACE"
}
add_addr() {
local proto=-4
[[ $1 == *:* ]] && proto=-6
cmd ip $proto address add "$1" dev "$INTERFACE"
}
set_mtu_up() {
local mtu=0 endpoint output
if [[ -n $MTU ]]; then
cmd ip link set mtu "$MTU" up dev "$INTERFACE"
return
fi
while read -r _ endpoint; do
[[ $endpoint =~ ^\[?([a-z0-9:.]+)\]?:[0-9]+$ ]] || continue
output="$(ip route get "${BASH_REMATCH[1]}" || true)"
[[ ( $output =~ mtu\ ([0-9]+) || ( $output =~ dev\ ([^ ]+) && $(ip link show dev "${BASH_REMATCH[1]}") =~ mtu\ ([0-9]+) ) ) && ${BASH_REMATCH[1]} -gt $mtu ]] && mtu="${BASH_REMATCH[1]}"
done < <(wg show "$INTERFACE" endpoints)
if [[ $mtu -eq 0 ]]; then
read -r output < <(ip route show default || true) || true
[[ ( $output =~ mtu\ ([0-9]+) || ( $output =~ dev\ ([^ ]+) && $(ip link show dev "${BASH_REMATCH[1]}") =~ mtu\ ([0-9]+) ) ) && ${BASH_REMATCH[1]} -gt $mtu ]] && mtu="${BASH_REMATCH[1]}"
fi
[[ $mtu -gt 0 ]] || mtu=1500
cmd ip link set mtu $(( mtu - 80 )) up dev "$INTERFACE"
}
# Checks the active internet connection interface
transport_interface() {
local netiface
netiface=$(ip route get ${EXTERNAL_NETWORK_TEST_IP} | grep -Po '(?<=dev\s)\w+' | cut -f1 -d ' ')
if [ -z ${netiface} ]; then
die "Unable to reach ${EXTERNAL_NETWORK_TEST_IP}. Check the Internet connection"
exit 1
else
echo "${netiface}"
fi
}
# Setup DNS
HAVE_SET_DNS=0
set_dns() {
[[ ${#DNS[@]} -gt 0 ]] || return 0
#{ printf 'nameserver %s\n' "${DNS[@]}"
# [[ ${#DNS_SEARCH[@]} -eq 0 ]] || printf 'search %s\n' "${DNS_SEARCH[*]}"
#} | cmd resolvconf -a "$(resolvconf_iface_prefix)$INTERFACE" -m 0 -x
cmd resolvectl dns ${INTERFACE} "${DNS[@]}"
cmd resolvectl domain ${INTERFACE} "~."
cmd resolvectl domain $(transport_interface) "lan"
HAVE_SET_DNS=1
}
unset_dns() {
[[ ${#DNS[@]} -gt 0 ]] || return 0
cmd resolvectl domain $(transport_interface) "lan"
cmd resolvectl domain $(transport_interface) "~."
}
# Setup Routes and Firewall
add_route() {
local proto=-4
[[ $1 == *:* ]] && proto=-6
[[ $TABLE != off ]] || return 0
if [[ -n $TABLE && $TABLE != auto ]]; then
cmd ip $proto route add "$1" dev "$INTERFACE" table "$TABLE"
elif [[ $1 == */0 ]]; then
add_default "$1"
else
[[ -n $(ip $proto route show dev "$INTERFACE" match "$1" 2>/dev/null) ]] || cmd ip $proto route add "$1" dev "$INTERFACE"
fi
}
get_fwmark() {
local fwmark
fwmark="$(wg show "$INTERFACE" fwmark)" || return 1
[[ -n $fwmark && $fwmark != off ]] || return 1
printf -v "$1" "%d" "$fwmark"
return 0
}
HAVE_SET_FIREWALL=0
add_default() {
local table line
if ! get_fwmark table; then
table=51820
while [[ -n $(ip -4 route show table $table 2>/dev/null) || -n $(ip -6 route show table $table 2>/dev/null) ]]; do
((table++))
done
cmd wg set "$INTERFACE" fwmark $table
fi
local proto=-4 iptables=iptables pf=ip
[[ $1 == *:* ]] && proto=-6 iptables=ip6tables pf=ip6
cmd ip $proto route add "$1" dev "$INTERFACE" table $table
cmd ip $proto rule add not fwmark $table table $table
cmd ip $proto rule add table main suppress_prefixlength 0
local marker="-m comment --comment \"wg-quick(8) rule for $INTERFACE\"" restore=$'*raw\n' nftable="wg-quick-$INTERFACE" nftcmd
printf -v nftcmd '%sadd table %s %s\n' "$nftcmd" "$pf" "$nftable"
printf -v nftcmd '%sadd chain %s %s preraw { type filter hook prerouting priority -300; }\n' "$nftcmd" "$pf" "$nftable"
printf -v nftcmd '%sadd chain %s %s premangle { type filter hook prerouting priority -150; }\n' "$nftcmd" "$pf" "$nftable"
printf -v nftcmd '%sadd chain %s %s postmangle { type filter hook postrouting priority -150; }\n' "$nftcmd" "$pf" "$nftable"
while read -r line; do
[[ $line =~ .*inet6?\ ([0-9a-f:.]+)/[0-9]+.* ]] || continue
printf -v restore '%s-I PREROUTING ! -i %s -d %s -m addrtype ! --src-type LOCAL -j DROP %s\n' "$restore" "$INTERFACE" "${BASH_REMATCH[1]}" "$marker"
printf -v nftcmd '%sadd rule %s %s preraw iifname != "%s" %s daddr %s fib saddr type != local drop\n' "$nftcmd" "$pf" "$nftable" "$INTERFACE" "$pf" "${BASH_REMATCH[1]}"
done < <(ip -o $proto addr show dev "$INTERFACE" 2>/dev/null)
printf -v restore '%sCOMMIT\n*mangle\n-I POSTROUTING -m mark --mark %d -p udp -j CONNMARK --save-mark %s\n-I PREROUTING -p udp -j CONNMARK --restore-mark %s\nCOMMIT\n' "$restore" $table "$marker" "$marker"
printf -v nftcmd '%sadd rule %s %s postmangle meta l4proto udp mark %d ct mark set mark \n' "$nftcmd" "$pf" "$nftable" $table
printf -v nftcmd '%sadd rule %s %s premangle meta l4proto udp meta mark set ct mark \n' "$nftcmd" "$pf" "$nftable"
[[ $proto == -4 ]] && cmd sysctl -q net.ipv4.conf.all.src_valid_mark=1
if type -p nft >/dev/null; then
cmd nft -f <(echo -n "$nftcmd")
else
echo -n "$restore" | cmd $iptables-restore -n
fi
HAVE_SET_FIREWALL=1
return 0
}
remove_firewall() {
if type -p nft >/dev/null; then
local table nftcmd
while read -r table; do
[[ $table == *" wg-quick-$INTERFACE" ]] && printf -v nftcmd '%sdelete %s\n' "$nftcmd" "$table"
done < <(nft list tables 2>/dev/null)
[[ -z $nftcmd ]] || cmd nft -f <(echo -n "$nftcmd")
fi
if type -p iptables >/dev/null; then
local line iptables found restore
for iptables in iptables ip6tables; do
restore="" found=0
while read -r line; do
[[ $line == "*"* || $line == COMMIT || $line == "-A "*"-m comment --comment \"wg-quick(8) rule for $INTERFACE\""* ]] || continue
[[ $line == "-A"* ]] && found=1
printf -v restore '%s%s\n' "$restore" "${line/#-A/-D}"
done < <($iptables-save 2>/dev/null)
[[ $found -ne 1 ]] || echo -n "$restore" | cmd $iptables-restore -n
done
fi
}
# Up/Down Functions
cmd_up() {
local i
#[[ -z $(ip link show dev "$INTERFACE" 2>/dev/null) ]] || die "\`$INTERFACE' already exists"
[[ -z $(ip link show dev "$INTERFACE" 2>/dev/null) ]] || cmd_down
trap 'del_if; exit' INT TERM EXIT
say "Starting UP the ${INTERFACE} interface ..."
execute_hooks "${PRE_UP[@]}"
add_if
set_config
for i in "${ADDRESSES[@]}"; do
add_addr "$i"
done
set_mtu_up
set_dns
for i in $(while read -r _ i; do for i in $i; do [[ $i =~ ^[0-9a-z:.]+/[0-9]+$ ]] && echo "$i"; done; done < <(wg show "$INTERFACE" allowed-ips) | sort -nr -k 2 -t /); do
add_route "$i"
done
execute_hooks "${POST_UP[@]}"
trap - INT TERM EXIT
sleep 3
}
cmd_down() {
say "Bringing DOWN the ${INTERFACE} interface ..."
[[ " $(wg show interfaces) " == *" $INTERFACE "* ]] || die "$INTERFACE is not a WireGuard interface"
execute_hooks "${PRE_DOWN[@]}"
del_if
[[ $HAVE_SET_DNS -eq 0 ]] || unset_dns
[[ $HAVE_SET_FIREWALL -eq 0 ]] || remove_firewall
#unset_dns || true
#remove_firewall || true
execute_hooks "${POST_DOWN[@]}"
sleep 1
}
# Main
if [[ $# -eq 0 ]]; then
cmd_usage
exit 1
elif [[ $# -eq 1 ]]; then
auto_su
parse_options "$1"
cmd_up
while true; do
clear
say "wg-rapid by afx. ver.2204"
echo " "
say "[q] to stop the VPN connection."
say "[d] or close the terminal window to keep the VPN connection setup configured"
say "[o] forward all networking through the VPN tunnel"
say "[p] forward the predefined routes only through the VPN tunnel"
echo " "
wg show
echo " "
read -t 1 -N 1 input
if [[ $input = "q" ]] || [[ $input = "Q" ]]; then
echo
break
fi
if [[ $input = "d" ]] || [[ $input = "D" ]]; then
echo
say "$PROGRAM detached."
exit 0
fi
if [[ $input = "p" ]] || [[ $input = "P" ]]; then
cmd_down
LINE_ROUTE_LOCAL=`grep -n 'Route only vpn trafic through vpn' /etc/wireguard/$1.conf | cut -d ':' -f 1`
((LINE_ROUTE_LOCAL=LINE_ROUTE_LOCAL+1))
LINE_ROUTE_ALL=`grep -n 'Route ALL traffic through vpn' /etc/wireguard/$1.conf | cut -d ':' -f 1`
((LINE_ROUTE_ALL=LINE_ROUTE_ALL+1))
sed -i "${LINE_ROUTE_LOCAL} s/^##*//" /etc/wireguard/$1.conf
sed -i "${LINE_ROUTE_ALL} s/^/#/" /etc/wireguard/$1.conf
parse_options "$1"
cmd_up
fi
if [[ $input = "o" ]] || [[ $input = "O" ]]; then
cmd_down
sleep 1
LINE_ROUTE_LOCAL=`grep -n 'Route only vpn trafic through vpn' /etc/wireguard/$1.conf | cut -d ':' -f 1`
((LINE_ROUTE_LOCAL=LINE_ROUTE_LOCAL+1))
LINE_ROUTE_ALL=`grep -n 'Route ALL traffic through vpn' /etc/wireguard/$1.conf | cut -d ':' -f 1`
((LINE_ROUTE_ALL=LINE_ROUTE_ALL+1))
sed -i "${LINE_ROUTE_LOCAL} s/^/#/" /etc/wireguard/$1.conf
sed -i "${LINE_ROUTE_ALL} s/^##*//" /etc/wireguard/$1.conf
parse_options "$1"
cmd_up
fi
done
cmd_down
elif [[ $# -eq 2 ]]; then
auto_su
parse_options "$1"
if [ "$2" == "down" ]; then
cmd_down
exit 0
else
say "$PROGRAM [ CONFIG_NAME ] [ down ]"
fi
fi
exit 0

15
config.dist Normal file
View file

@ -0,0 +1,15 @@
public_ifname=ens3
ip_db=/etc/wireguard/ipdb.pool
server_endpoint_address=wire.example.com
net_prefix=69
allowed_routes="10.15.0.0/16, 192.168.0.0/24"
monitor_host=10.15.0.15
email_origin=wire.example.com
email_host=email-smtp.eu-west-1.amazonaws.com
email_user=AUSER
email_pass=APASS
email_destination=admin@domain
ldap_server=ldap://idm.example.com
ldap_login=cn=admin
ldap_password=PASS
ldap_basedn=dc=admin,dc=com

44
gen-ip-database.sh Executable file
View file

@ -0,0 +1,44 @@
#!/usr/bin/env bash
source config
check_root() {
if [ "$EUID" -ne 0 ]; then
printf %b\\n "] Please run the script as root."
exit 1
fi
}
gen_cidr() {
base=${1%/*}
masksize=${1#*/}
[ $masksize -lt 8 ] && { echo "] Max range is /8."; exit 1;}
mask=$(( 0xFFFFFFFF << (32 - $masksize) ))
IFS=. read a b c d <<< $base
ip=$(( ($b << 16) + ($c << 8) + $d ))
ipstart=$(( $ip & $mask ))
ipend=$(( ($ipstart | ~$mask ) & 0x7FFFFFFF ))
seq $ipstart $ipend | while read i; do
echo $a.$(( ($i & 0xFF0000) >> 16 )).$(( ($i & 0xFF00) >> 8 )).$(( $i & 0x00FF ))
done
}
check_root
# This generates all host address for our vpn subnet but skips the following:
# - vpn server address, which ends with .0.1
# - the network address and the broadcast address
# - all host addresses in between that looks like /24 net and mask, they should work but they are
# misleading in that regard, and we do have enough addresses already
if [ -f $ip_db ]; then
echo "] IP pool exists at $ip_db. Remove it first."
exit 1
else
gen_cidr 10.${net_prefix}.0.0/20 | grep -v \\.0$ | grep -v .255$ | grep -v \\.0\\.1$ > $ip_db
fi

257
init.sh Executable file
View file

@ -0,0 +1,257 @@
#!/usr/bin/env bash
source config
check_root() {
if [ "$EUID" -ne 0 ]; then
printf %b\\n "] Please run the script as root."
exit 1
fi
}
# Welcome
echo ""
cat README.md
echo ""
check_root
# enable IPv4 forwarding
sed -i 's/\#net.ipv4.ip_forward=1/net.ipv4.ip_forward=1/g' /etc/sysctl.conf
# negate the need to reboot after the above change
sysctl -p
# update/upgrade server and refresh repo
apt update -y && apt upgrade -y && apt autoremove -y
# remove the default firewall
ufw disable
apt remove --purge ufw -y
apt install iptables netfilter-persistent -y
# install fail2ban
apt install fail2ban -y
# install python-ldap
apt install python3-dev python3-pip python3-ldap -y
# install wireguard
systemctl stop wg-quick@wg0.service
systemctl disable wg-quick@wg0.service
apt install wireguard -y
apt install qrencode -y
# install jq
apt install jq -y
# install curl
apt install curl -y
# create Wireguard interface config
bash -c "cat > /etc/wireguard/wg0.conf" << ENDOFFILE
[Interface]
PrivateKey = server_private_key
Address = 10.net_prefix.0.1/20
ListenPort = 550net_prefix
PostUp = iptables -A FORWARD -i ${public_ifname} -o wg0 -j ACCEPT; iptables -A FORWARD -i wg0 -o ${public_ifname} -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT; iptables -t nat -A POSTROUTING -o ${public_ifname} -j MASQUERADE
PostDown = iptables -D FORWARD -i ${public_ifname} -o wg0 -j ACCEPT; iptables -D FORWARD -i wg0 -o ${public_ifname} -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT; iptables -t nat -D POSTROUTING -o ${public_ifname} -j MASQUERADE
SaveConfig = true
ENDOFFILE
cat << EOF | bash
cd /etc/wireguard/
umask 077
[ ! -f server_private.key ] && wg genkey | tee server_private.key | wg pubkey > server_public.key
EOF
sed -i "s/net_prefix/${net_prefix}/g" /etc/wireguard/wg0.conf
sed -i "s/server_private_key/$(sed 's:/:\\/:g' /etc/wireguard/server_private.key)/" /etc/wireguard/wg0.conf
# make root owner of the Wireguard config file
chown -v root:root /etc/wireguard/wg0.conf
chmod -v 600 /etc/wireguard/wg0.conf
# make Wireguard interface start at boot
systemctl enable wg-quick@wg0.service
# flush all chains
iptables -P INPUT ACCEPT
iptables -P FORWARD ACCEPT
iptables -P OUTPUT ACCEPT
iptables -t nat -F
iptables -t mangle -F
iptables -F
# delete all chains
iptables -X
# configure the firewall and make it persistent
DEBIAN_FRONTEND=noninteractive apt install iptables-persistent -y
systemctl enable netfilter-persistent
iptables -P INPUT DROP
iptables -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
iptables -A INPUT -p all -s localhost -j ACCEPT
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
iptables -A INPUT -p tcp --dport 655 -j ACCEPT
iptables -A INPUT -p udp --dport 655 -j ACCEPT
iptables -A INPUT -p tcp -s ${monitor_host} --dport 10050 -j ACCEPT
iptables -A INPUT -p udp --dport 550${net_prefix} -j ACCEPT
iptables -A INPUT -p all -i wg0 -j ACCEPT
iptables -P FORWARD ACCEPT
iptables -A FORWARD -i wg0 -o wg0 -j REJECT
iptables -P OUTPUT ACCEPT
netfilter-persistent save
# install Unbound DNS
systemctl stop unbound.service
systemctl disable unbound.service
apt install unbound unbound-host -y
# download list of DNS root servers
curl -o /var/lib/unbound/root.hints https://www.internic.net/domain/named.cache
# create unbound log file
mkdir -p /var/log/unbound
chown unbound:unbound /var/log/unbound/
touch /var/log/unbound/unbound.log
chown unbound:unbound /var/log/unbound/unbound.log
echo "/var/log/unbound/unbound.log rw," > /etc/apparmor.d/local/usr.sbin.unbound
apparmor_parser -r /etc/apparmor.d/usr.sbin.unbound
# create custom conf
touch /etc/unbound/custom.conf
chown unbound:unbound /etc/unbound/custom.conf
# create Unbound config file
bash -c "cat > /etc/unbound/unbound.conf" << ENDOFFILE
server:
num-threads: 4
# enable logs
verbosity: 1
logfile: /var/log/unbound/unbound.log
chroot: ""
log-queries: yes
# list of root DNS servers
root-hints: "/var/lib/unbound/root.hints"
# use the root server's key for DNSSEC
auto-trust-anchor-file: "/var/lib/unbound/root.key"
# respond to DNS requests on all interfaces
interface: 0.0.0.0
max-udp-size: 3072
# IPs authorised to access the DNS Server
access-control: 0.0.0.0/0 refuse
access-control: 127.0.0.1 allow
access-control: 10.net_prefix.0.0/20 allow
# not allowed to be returned for public Internet names
private-address: 10.net_prefix.0.0/20
#hide DNS Server info
hide-identity: yes
hide-version: yes
# limit DNS fraud and use DNSSEC
harden-glue: yes
harden-dnssec-stripped: yes
harden-referral-path: yes
# add an unwanted reply threshold to clean the cache and avoid, when possible, DNS poisoning
unwanted-reply-threshold: 10000000
# have the validator print validation failures to the log
val-log-level: 1
# minimum lifetime of cache entries in seconds
cache-min-ttl: 1800
# maximum lifetime of cached entries in seconds
cache-max-ttl: 14400
prefetch: yes
prefetch-key: yes
# additional entries
include: /etc/unbound/custom.conf
ENDOFFILE
sed -i "s/net_prefix/${net_prefix}/g" /etc/unbound/unbound.conf
# give root ownership of the Unbound config
chown -R unbound:unbound /var/lib/unbound
# enable Unbound in place of systemd-resovled
systemctl enable unbound-resolvconf
systemctl enable unbound
systemctl start unbound
# disable systemd-resolved
systemctl stop systemd-resolved
systemctl disable systemd-resolved
unlink /etc/resolv.conf
bash -c "cat > /etc/resolv.conf" << ENDOFFILE
nameserver 127.0.0.1
ENDOFFILE
# Initial database generation
bash -c "./gen-ip-database.sh"
#provide scripts in /usr/local/bin
__dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
cp -v ${__dir}/wgstats.sh /usr/local/bin/
cp -v ${__dir}/wgldap.sh /usr/local/bin/
#install Postfix mailserver
if [ $email_origin == "wire.example.com" ]; then
echo "] WARN: Mailing is disabled!"
else
echo "] Setting up mail server $email_origin ..."
if [ ! -f /etc/postfix/main.cf ]; then
echo "] Mail server config does not exist. Installing..."
# install postfix
echo "postfix postfix/mailname string ${email_origin}" | debconf-set-selections
echo "postfix postfix/main_mailer_type string 'Internet Site'" | debconf-set-selections
apt install -y postfix mailutils libsasl2-2 ca-certificates libsasl2-modules mutt zip
# setup mail server for email reports
/usr/sbin/postconf -e "relayhost = [${email_host}]:587" \
"smtp_sasl_auth_enable = yes" \
"smtp_sasl_security_options = noanonymous" \
"smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd" \
"smtp_use_tls = yes" \
"smtp_tls_security_level = encrypt" \
"smtp_tls_note_starttls_offer = yes"
echo "[${email_host}]:587 ${email_user}:${email_pass}" > /etc/postfix/sasl_passwd
/usr/sbin/postmap hash:/etc/postfix/sasl_passwd
chown root:root /etc/postfix/sasl_passwd /etc/postfix/sasl_passwd.db
chmod 0600 /etc/postfix/sasl_passwd /etc/postfix/sasl_passwd.db
/usr/sbin/postconf -e "smtp_tls_CAfile = /etc/ssl/certs/ca-certificates.crt"
/usr/sbin/postconf -e "myorigin = ${email_origin}"
sleep 2
service postfix restart
fi
fi
# Setup LDAP sync service
if [ $ldap_server == "ldap://idm.example.com" ]; then
echo "] WARN: LDAP disabled!"
else
echo "] Setting up LDAP server $ldap_server"
cp -v ${__dir}/wgldapsync.service /etc/systemd/system/wgldapsync.service
cp -v ${__dir}/wgldapsync.timer /etc/systemd/system/wgldapsync.timer
systemctl daemon-reload
systemctl enable wgldapsync.timer
systemctl status wgldapsync.service
systemctl status wgldapsync.timer
fi
# reboot to make changes effective
echo "] System reboot after 30 seconds..."
sleep 30
reboot

171
ldapsync.py Executable file
View file

@ -0,0 +1,171 @@
#!/usr/bin/python3
import os
import sys
import configparser
import pprint
import socket
import ldap
import subprocess
DEBUG = False
DEBUG_LDAP = False
CONFIG_PATH = "/root/wiregate/"
LOCAL_DB_PATH = '/etc/wireguard/clients/'
# parse config
cds = 'wiregate' #ConfigParser dummy section
with open(CONFIG_PATH + '/config', 'r') as f:
config_string = '[' + cds + ']\n' + f.read()
config = configparser.ConfigParser()
config.read_string(config_string)
baseDN = config.get(cds, 'ldap_basedn')
LDAP_SERVER = config.get(cds, 'ldap_server')
LDAP_LOGIN = config.get(cds, 'ldap_login') + ',' + baseDN
LDAP_PASSWORD = config.get(cds, 'ldap_password')
serverhost = socket.gethostname()
searchScope = ldap.SCOPE_SUBTREE
def LdapQuery(searchFilter, searchAttrs):
ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, ldap.OPT_X_TLS_NEVER)
if DEBUG_LDAP:
print("Connecting to " + LDAP_SERVER)
l = ldap.initialize(LDAP_SERVER)
try:
#l.set_option(ldap.OPT_REFERRALS, 0)
#l.set_option(ldap.OPT_PROTOCOL_VERSION, 3)
#l.set_option(ldap.OPT_X_TLS, ldap.OPT_X_TLS_DEMAND)
#l.set_option(ldap.OPT_X_TLS_DEMAND, True)
#l.set_option(ldap.OPT_DEBUG_LEVEL, 255)
l.set_option(ldap.OPT_NETWORK_TIMEOUT, 10.0)
l.simple_bind_s(LDAP_LOGIN, LDAP_PASSWORD)
query = {}
ldap_result_id = l.search(baseDN, searchScope, searchFilter, searchAttrs)
while 1:
rType, rData = l.result(ldap_result_id, 0)
if (rData == []):
break
else:
if rType == ldap.RES_SEARCH_ENTRY:
cn = rData[0][0]
data = rData[0][1]
#Flatten, just for more easy access
for (k, v) in data.items():
if len(v) == 1:
data[k] = v[0]
#uid = data["uid"]
query[cn] = data
return query
except ldap.LDAPError as e:
print(e)
sys.exit(2)
finally:
if DEBUG_LDAP:
print('Server unbind.')
l.unbind_s()
return 0
def main():
print("] WireGate LDAP sync")
# query ldap server and gather list of REMOTE peers which belong to cn=<HOSTNAME>,ou=Groups,baseDN
ldapGroups = LdapQuery('(|(&(objectClass=groupOfUniqueNames)(cn=' + serverhost + ')))', ['uniqueMember'])
if ldapGroups == {}:
print('] Group ' + serverhost + ' not found')
sys.exit(1)
if ldapGroups != 0:
members = ldapGroups['cn=' + serverhost + ',ou=Groups,' + baseDN]['uniqueMember']
if not isinstance(members, list):
members = [members]
print('] Group: ' + serverhost)
print('] Remote members: ' + str(len(members)))
remote_peers = []
for member in members:
d_member = member.decode('ascii')
if DEBUG:
print('] Processing ' + str(d_member))
searchFilterUser='(' + d_member.split(',')[0] + ')'
ldapUser = LdapQuery(searchFilterUser, ['mail', 'l'])
user = ldapUser[d_member]
#get attributes
#mail
m_mail = str(user['mail'].decode('ascii'))
m_domain = m_mail.split('@')[1]
m_user = m_mail.split('@')[0]
m_peername = m_domain + '-' + m_user
#get additional peers provided with the l attribute
if 'l' in user:
labels = user['l']
if not isinstance(labels, list):
labels = [labels]
for label in labels:
peer = m_peername + '-' + str(label.decode('ascii'))
remote_peers.append({ 'mail': m_mail, 'peer': peer })
#get the parent peer
peer = m_peername
remote_peers.append({ 'mail': m_mail, 'peer': peer })
#searchFilterUserSubs='(|(&(objectClass=*)(member=uid=%s,cn=users,ou=Groups,' + baseDN + ')))'
user_subscriptions= LdapQuery('(|(&(objectClass=groupOfUniqueNames)(uniqueMember=' + str(d_member) + ')))', ['cn'])
if DEBUG:
pp = pprint.PrettyPrinter(depth=3)
pp.pprint(user_subscriptions)
print("] Remote peers: " + str(len(remote_peers)))
if DEBUG:
pp = pprint.PrettyPrinter(depth=3)
pp.pprint(remote_peers)
# query LOCAL peers database
local_peers = []
for file in os.listdir(LOCAL_DB_PATH):
if file.endswith(".info"):
try:
cds = 'localdata' #ConfigParser dummy section
with open(LOCAL_DB_PATH + '/' + file, 'r') as f:
data_string = '[' + cds + ']\n' + f.read()
local_peer_data = configparser.ConfigParser()
local_peer_data.read_string(data_string)
local_mail = local_peer_data.get(cds, 'email')
local_peer = local_peer_data.get(cds, 'peer')
local_peers.append({ 'mail': local_mail, 'peer': local_peer })
except Exception as e:
print(e)
sys.exit(2)
print("] Local peers: " + str(len(local_peers)))
if DEBUG:
pp = pprint.PrettyPrinter(depth=3)
pp.pprint(local_peers)
# add / enable REMOTE peers if they DO NOT exist in the local database
for r_peer in remote_peers:
#print('add peer ' + r_peer['peer'] + ' - ' + r_peer['mail'])
process = subprocess.Popen([CONFIG_PATH + "peer_add.sh", "-p", r_peer['peer'], "-e", r_peer['mail']])
process.wait()
# disable (do not remove) LOCAL peers which DO NOT exist in the remote database
for l_peer in local_peers:
if l_peer not in remote_peers:
#print('rem peer ' + l_peer['peer'] + ' - ' + l_peer['mail'])
process = subprocess.Popen([CONFIG_PATH + "peer_disable.sh", "-p", l_peer['peer']])
process.wait()
if __name__ == "__main__":
sys.exit(main())

20
mail.md Normal file
View file

@ -0,0 +1,20 @@
Hello,
To be able to access the resources on our development infrastructure, you will need to set up a VPN profile.
To install the necessary client application, please visit the following page to obtain packages for the operating system your device is currently using:
https://www.wireguard.com/install/
Please take care of the configuration files and QR images as equivalent to a secure password.
For Windows, MacOS, Android and iOS simply import profile.conf or profile_alltraffic.conf file using the import tunnel function of the Wireguard software.
You may choose to import both versions and switch between them, where the `alltraffic` version pushes all network routes through the endpoint, which is useful for example if a third party system requires a whitelisted company address or to switch geographic policy. The tradeoff is the limited bandwidth and delay of the endpoint for every network request, which could affect some resource intensive applications.
The connected device follows the remote network policy for the routed traffic and DNS requests.
For Linux you may use the wg-rapid script `sudo cp linux/wg-rapid /usr/local/bin`. Then copy either profile.conf file or the profile_alltraffic.conf version of it as /etc/wireguard/office.conf and start with `wg-rapid office` Please not that the linux script has built-in capability to switch between preselected routes, so it doesn't matter which one of them you choose to copy in this case.
Using a VPN client is somewhat platform and infrastructure specific, you may always contact #team-sysops for further assistance.

167
peer_add.sh Executable file
View file

@ -0,0 +1,167 @@
#!/usr/bin/env bash
source config
check_root() {
if [ "$EUID" -ne 0 ]; then
printf %b\\n "] Please run the script as root."
exit 1
fi
}
usage()
{
echo "Usage: peer_add.sh -p <peer name> -e <email address>"
}
random_ip_pickup() {
# Randomly select an IP and remove it from the pool
local ipsleft=`cat ${ip_db} | wc -l`
if [[ "${ipsleft}" -eq 0 ]]; then
echo "empty"
else
local random_ip=$(shuf -n 1 ${ip_db})
grep -v "${random_ip}$" ${ip_db} > ${ip_db}.tmp
mv ${ip_db}.tmp ${ip_db}
echo "${random_ip}"
fi
}
check_root
no_args="true"
while getopts p:e: option
do
case $option in
(p)
name=${OPTARG};;
(e)
email=${OPTARG};;
(*)
usage
exit;;
esac
no_args="false"
done
[[ "$no_args" == "true" ]] && { usage; exit 1; }
# Check if IP pool exist
if [ ! -f ${ip_db} ]; then
echo "] IP pool does not exists at ${ip_db}. Generate it first."
exit 3
fi
# Check if both arguments exist
if [ -z ${name} ] || [ -z ${email} ]; then
echo "] Not enough arguments"
exit 1
fi
# Check if peer config exist
if [ -f /etc/wireguard/clients/${name}_public.key ]; then
peer_exists_in_wg=$(wg show wg0 dump | grep $(cat /etc/wireguard/clients/${name}_public.key) | wc -l)
if [ ! ${peer_exists_in_wg} -eq 0 ]; then
#echo "] ${name} already activated"
exit 2
fi
fi
# Generate wireguard peer keys and config
if [ -z ${server_endpoint_address} ]; then
server_endpoint_address=$(ip addr show ${public_ifname} | grep -o "inet [0-9]*\.[0-9]*\.[0-9]*\.[0-9]*" | grep -o "[0-9]*\.[0-9]*\.[0-9]*\.[0-9]*")
fi
# Creating clients subdir
mkdir -p /etc/wireguard/clients
if [ ! -f /etc/wireguard/clients/${name}.info ]; then
echo "] ${name} config will be generated."
peer_address_from_pool=$(random_ip_pickup)
if [ ${peer_address_from_pool} = "empty" ]; then
echo "] IP Pool is empty"
exit 5
fi
bash -c "cat > /etc/wireguard/clients/${name}_wg0.conf" << ENDOFFILE
[Interface]
PrivateKey = client_private_key
Address = selected_peer_address/32
DNS = 10.net_prefix.0.1
[Peer]
PublicKey = server_public_key
Endpoint = server_endpoint:550net_prefix
# Route only vpn trafic through vpn
AllowedIPs = 10.net_prefix.0.0/20, allowed_routes
# Route ALL traffic through vpn
#AllowedIPs = 0.0.0.0/0
PersistentKeepalive = 21
ENDOFFILE
bash -c "cat > /etc/wireguard/clients/${name}_alltraffic_wg0.conf" << ENDOFFILE
[Interface]
PrivateKey = client_private_key
Address = selected_peer_address/32
DNS = 10.net_prefix.0.1
[Peer]
PublicKey = server_public_key
Endpoint = server_endpoint:550net_prefix
# Route only vpn trafic through vpn
#AllowedIPs = 10.net_prefix.0.0/20, allowed_routes
# Route ALL traffic through vpn
AllowedIPs = 0.0.0.0/0
PersistentKeepalive = 21
ENDOFFILE
cat << EOF | bash
cd /etc/wireguard/clients
umask 077
[ ! -f ${name}_private.key ] && wg genkey | tee ${name}_private.key | wg pubkey > ${name}_public.key
EOF
sed -i "s/net_prefix/${net_prefix}/g" /etc/wireguard/clients/${name}_wg0.conf
sed -i "s#allowed_routes#${allowed_routes}#g" /etc/wireguard/clients/${name}_wg0.conf
sed -i "s/selected_peer_address/${peer_address_from_pool}/g" /etc/wireguard/clients/${name}_wg0.conf
sed -i "s/server_endpoint/${server_endpoint_address}/g" /etc/wireguard/clients/${name}_wg0.conf
sed -i "s/server_public_key/$(sed 's:/:\\/:g' /etc/wireguard/server_public.key)/" /etc/wireguard/clients/${name}_wg0.conf
sed -i "s/client_private_key/$(sed 's:/:\\/:g' /etc/wireguard/clients/${name}_private.key)/" /etc/wireguard/clients/${name}_wg0.conf
sed -i "s/net_prefix/${net_prefix}/g" /etc/wireguard/clients/${name}_alltraffic_wg0.conf
sed -i "s#allowed_routes#${allowed_routes}#g" /etc/wireguard/clients/${name}_alltraffic_wg0.conf
sed -i "s/selected_peer_address/${peer_address_from_pool}/g" /etc/wireguard/clients/${name}_alltraffic_wg0.conf
sed -i "s/server_endpoint/${server_endpoint_address}/g" /etc/wireguard/clients/${name}_alltraffic_wg0.conf
sed -i "s/server_public_key/$(sed 's:/:\\/:g' /etc/wireguard/server_public.key)/" /etc/wireguard/clients/${name}_alltraffic_wg0.conf
sed -i "s/client_private_key/$(sed 's:/:\\/:g' /etc/wireguard/clients/${name}_private.key)/" /etc/wireguard/clients/${name}_alltraffic_wg0.conf
qrencode -t PNG -o /etc/wireguard/clients/${name}_alltraffic_qr.png < /etc/wireguard/clients/${name}_alltraffic_wg0.conf
echo "peer=${name}" > /etc/wireguard/clients/${name}.info
echo "email=${email}" >> /etc/wireguard/clients/${name}.info
echo "ip=${peer_address_from_pool}" >> /etc/wireguard/clients/${name}.info
peer_ip=$(cat /etc/wireguard/clients/${name}.info | grep "^ip=" | cut -d '=' -f 2)
#send mail with the generated config
bash -c "./peer_mail.sh -p ${name}"
else
echo "] ${name} config already exists."
peer_ip=$(cat /etc/wireguard/clients/${name}.info | grep "^ip=" | cut -d '=' -f 2)
#check if private key was previously disabled
if [ -f /etc/wireguard/clients/${name}_public.disabled ]; then
echo "] ${name} was previously disabled."
mv /etc/wireguard/clients/${name}_public.disabled /etc/wireguard/clients/${name}_public.key
fi
#check if peer ip already exist in the database
ip_exists_in_pool=$(grep "${peer_ip}$" ${ip_db} | wc -l)
if [ ${ip_exists_in_pool} -eq 1 ]; then
echo "] ${peer_ip} exists in pool. Removing to avoid duplicates."
grep -v "${peer_ip}$" ${ip_db} > ${ip_db}.tmp
mv ${ip_db}.tmp ${ip_db}
fi
fi
echo "] ${name} (${email}) config set. Endpoint address is ${server_endpoint_address}. Selected user VPN IP is ${peer_ip}"
wg set wg0 peer $(cat /etc/wireguard/clients/${name}_public.key) allowed-ips ${peer_ip}/32 persistent-keepalive 21

12
peer_addall.sh Executable file
View file

@ -0,0 +1,12 @@
#!/bin/bash
ALLCLIENTS=/etc/wireguard/clients/*.info
__dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
for client in $ALLCLIENTS; do
peer=$(cat ${client} | grep '^peer=' | cut -d '=' -f 2)
email=$(cat ${client} | grep '^email=' | cut -d '=' -f 2)
echo "] peer_add.sh - peer: $peer - email: $email"
bash ${__dir}/peer_add.sh -p ${peer} -e ${email}
done

62
peer_del.sh Executable file
View file

@ -0,0 +1,62 @@
#!/usr/bin/env bash
source config
check_root() {
if [ "$EUID" -ne 0 ]; then
printf %b\\n "] Please run the script as root."
exit 1
fi
}
usage()
{
echo "Usage: peer_del.sh -p <peer name>"
}
check_root
no_args="true"
while getopts p: option
do
case $option in
(p)
name=${OPTARG};;
(*)
usage
exit;;
esac
no_args="false"
done
[[ "$no_args" == "true" ]] && { usage; exit 1; }
# Check if peer config exist
if [ ! -f /etc/wireguard/clients/${name}.info ]; then
echo "] Peer ${name} does not exists"
exit 2
fi
echo "] Removing wireguard config for ${name}"
salvaged_ip=$(cat /etc/wireguard/clients/${name}.info | grep "^ip=" | cut -d '=' -f 2)
echo "] Salvaged IP is ${salvaged_ip} and will be returned back to ${ip_db}"
echo ${salvaged_ip} >> ${ip_db}
#check if config is previously disabled
if [ -f /etc/wireguard/clients/${name}_public.disabled ]; then
echo "] ${name} was previously disabled."
mv /etc/wireguard/clients/${name}_public.disabled /etc/wireguard/clients/${name}_public.key
fi
wg set wg0 peer $(cat /etc/wireguard/clients/${name}_public.key) remove
rm /etc/wireguard/clients/${name}_public.key
rm /etc/wireguard/clients/${name}.info
# remove additional sensitive info
rm -f /etc/wireguard/clients/${name}_wg0.conf
rm -f /etc/wireguard/clients/${name}_qr.png
rm -f /etc/wireguard/clients/${name}_alltraffic_wg0.conf
rm -f /etc/wireguard/clients/${name}_alltraffic_qr.png
rm -f /etc/wireguard/clients/${name}_private.key
exit 0

50
peer_disable.sh Executable file
View file

@ -0,0 +1,50 @@
#!/usr/bin/env bash
source config
check_root() {
if [ "$EUID" -ne 0 ]; then
printf %b\\n "] Please run the script as root."
exit 1
fi
}
usage()
{
echo "Usage: peer_disable.sh -p <peer name>"
}
check_root
no_args="true"
while getopts p: option
do
case $option in
(p)
name=${OPTARG};;
(*)
usage
exit;;
esac
no_args="false"
done
[[ "$no_args" == "true" ]] && { usage; exit 1; }
# Check if peer config exist
if [ ! -f /etc/wireguard/clients/${name}.info ]; then
echo "] Peer ${name} does not exists"
exit 2
fi
#check if config is previously disabled
if [ -f /etc/wireguard/clients/${name}_public.disabled ]; then
#echo "] ${name} is already disabled."
exit 0
fi
echo "] Disable wireguard config for ${name}"
wg set wg0 peer $(cat /etc/wireguard/clients/${name}_public.key) remove
mv /etc/wireguard/clients/${name}_public.key /etc/wireguard/clients/${name}_public.disabled
exit 0

69
peer_mail.sh Executable file
View file

@ -0,0 +1,69 @@
#!/usr/bin/env bash
source config
check_root() {
if [ "$EUID" -ne 0 ]; then
printf %b\\n "] Please run the script as root."
exit 1
fi
}
usage()
{
echo "Usage: peer_mail.sh -p <peer name>"
}
check_root
no_args="true"
while getopts p: option
do
case $option in
(p)
name=${OPTARG};;
(*)
usage
exit;;
esac
no_args="false"
done
[[ "$no_args" == "true" ]] && { usage; exit 1; }
email_client=$(cat /etc/wireguard/clients/${name}.info | grep "^email=" | cut -d '=' -f 2)
if [ -z ${email_client} ]; then
echo "] Peer not found."
exit 2
fi
echo "] Sending the profile data to $email_destination"
# strip non alphanumeric characters from peer name
stname=$(echo ${name} | sed "s/[^[:alnum:]-]//g")
# fill profile tmp dir with data
mkdir payload
mkdir payload/mobile
cp -v /etc/wireguard/clients/${name}_wg0.conf payload/profile.conf
cp -v /etc/wireguard/clients/${name}_alltraffic_wg0.conf payload/profile_alltraffic.conf
cp -v /etc/wireguard/clients/${name}_alltraffic_qr.png payload/mobile/profile_alltraffic_QR.png
mkdir payload/linux
cp -v client-tools/wg-rapid payload/linux/wg-rapid
cp -v client-tools/startvpn.desktop payload/linux/startvpn.desktop
chmod +x payload/linux/startvpn.desktop
# pack the attachment
cd payload
zip -r ../payload.zip .
cd ..
mv payload.zip ${stname}_profile.zip
# sent the message
mutt -s "WireGate VPN for ${email_client}" ${email_destination} -a ${stname}_profile.zip < mail.md
#mutt -s "WireGate VPN for ${email_client}" ${email_client} -a ${stname}_profile.zip < mail.md
rm -f -r -v payload
exit 0

5
wgldap.sh Executable file
View file

@ -0,0 +1,5 @@
#!/bin/bash
__dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
journalctl -u wgldapsync -f

7
wgldapsync.service Normal file
View file

@ -0,0 +1,7 @@
[Unit]
Description=WireGate LDAP auto-sync service
[Service]
Type=simple
WorkingDirectory=/root/wiregate
ExecStart=/usr/bin/python3 /root/wiregate/ldapsync.py

9
wgldapsync.timer Normal file
View file

@ -0,0 +1,9 @@
[Unit]
Description=WireGate LDAP auto-sync timer
[Timer]
OnUnitActiveSec=30min
OnBootSec=30min
[Install]
WantedBy=timers.target

38
wgstats.sh Executable file
View file

@ -0,0 +1,38 @@
#!/bin/bash
__dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
echo "] WireGate plugins:"
systemctl list-timers --all | grep 'ACTIVATES\|wgldapsync'
echo ""
echo "] WireGate peers:"
tmpfile1=$(mktemp /tmp/wgstats.1.XXXXXX)
tmpfile2=$(mktemp /tmp/wgstats.2.XXXXXX)
ALLPEERS=$(wg show all dump | grep -v off)
echo "$ALLPEERS" | while IFS= read -r peer ; do
peerkey=$(echo "$peer" | cut -d $'\t' -f 2)
peerfile=$(basename $(grep -l "${peerkey}" /etc/wireguard/clients/*_public.key))
peername=$(echo ${peerfile} | cut -d '_' -f 1)
clientip=$(echo "$peer" | cut -d $'\t' -f 4)
peerip=$(echo "$peer" | cut -d $'\t' -f 5)
peerlatesths=$(echo "$peer" | cut -d $'\t' -f 6)
if [ ${peerlatesths} -eq 0 ]; then
peerlatesthsfmt="Never"
else
peerlatesthsfmt=$(date -d@${peerlatesths})
fi
peerrx=$(echo "$peer" | cut -d $'\t' -f 7 | numfmt --to=iec-i --suffix=B)
peertx=$(echo "$peer" | cut -d $'\t' -f 8 | numfmt --to=iec-i --suffix=B)
echo "${peerlatesths},$peername,$clientip,$peerip,${peerlatesthsfmt},$peerrx,$peertx" >> $tmpfile1
done
sort -k1 -n -t "," $tmpfile1 | cut -d "," -f 2- > $tmpfile2
sed -i '1s/^/Peer,Client Address,Peer Address,Latest Handshake,Data Recieved,Data Sent\n/' $tmpfile2
column -e -t -s "," $tmpfile2
rm $tmpfile1
rm $tmpfile2
exit 0