Initial migration
This commit is contained in:
parent
1f823e556e
commit
163ccbd03f
17 changed files with 1369 additions and 0 deletions
35
README.md
Normal file
35
README.md
Normal 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
8
client-tools/startvpn.desktop
Executable 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
400
client-tools/wg-rapid
Executable 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
15
config.dist
Normal 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
44
gen-ip-database.sh
Executable 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
257
init.sh
Executable 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
171
ldapsync.py
Executable 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
20
mail.md
Normal 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
167
peer_add.sh
Executable 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
12
peer_addall.sh
Executable 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
62
peer_del.sh
Executable 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
50
peer_disable.sh
Executable 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
69
peer_mail.sh
Executable 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
5
wgldap.sh
Executable file
|
@ -0,0 +1,5 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
__dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
|
||||||
|
journalctl -u wgldapsync -f
|
7
wgldapsync.service
Normal file
7
wgldapsync.service
Normal 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
9
wgldapsync.timer
Normal 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
38
wgstats.sh
Executable 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
|
Loading…
Reference in a new issue