152 lines
3.5 KiB
Bash
Executable file
152 lines
3.5 KiB
Bash
Executable file
#!/bin/bash
|
|
|
|
set -euo pipefail
|
|
|
|
_="${DEBUG:=}"
|
|
_="${GOW_IP_DELAY:=0}"
|
|
|
|
ip_hook() {
|
|
ip "$@"
|
|
sleep "$GOW_IP_DELAY"
|
|
}
|
|
|
|
strstrip() {
|
|
sed -E -e 's/^\s*//' -e 's/\s*$//'
|
|
}
|
|
|
|
create_br() {
|
|
local name
|
|
name="$1"
|
|
|
|
$DEBUG ip link add "$name" type bridge
|
|
}
|
|
|
|
create_gre() {
|
|
local name local_ip remote_ip
|
|
name="$1"
|
|
local_ip="$(sed 's_/.*$__' <<< "$2")"
|
|
remote_ip="$(sed 's_/.*$__' <<< "$3")"
|
|
|
|
$DEBUG ip_hook link add "$name" type gretap local "$local_ip" remote "$remote_ip"
|
|
$DEBUG ip_hook link set up "$name"
|
|
}
|
|
|
|
add_gre_to_br() {
|
|
local br_name gre_name
|
|
br_name="$1"
|
|
gre_name="$2"
|
|
|
|
$DEBUG ip_hook link set "$gre_name" master "$br_name"
|
|
}
|
|
|
|
finish_br() {
|
|
local name local_ip
|
|
name="$1"
|
|
local_ip="$2"
|
|
|
|
$DEBUG ip_hook addr add "$local_ip" dev "$name"
|
|
$DEBUG ip_hook link set up "$name"
|
|
}
|
|
|
|
read_wg_conf() {
|
|
local filepath
|
|
local local_ip remote_ips mode line
|
|
filepath="$1"
|
|
|
|
local_ip=
|
|
remote_ips=
|
|
mode=
|
|
while read -r line; do
|
|
line="$(strstrip <<< "$line")"
|
|
if [[ "$line" = '[Interface]' ]]; then
|
|
mode=interface
|
|
continue
|
|
elif [[ "$line" = '[Peer]' ]]; then
|
|
mode=peer
|
|
continue
|
|
fi
|
|
if [[ "$mode" = 'interface' ]] && [[ "$line" =~ ^Address\ *=\ * ]]; then
|
|
local_ip="$(awk -F= '{print $2}' <<< "$line" | strstrip)"
|
|
elif [[ "$mode" = 'peer' ]] && [[ "$line" =~ ^AllowedIPs\ *=\ * ]]; then
|
|
remote_ips="$remote_ips $(awk -F= '{print $2}' <<< "$line" | strstrip)"
|
|
fi
|
|
done < "$filepath"
|
|
remote_ips="$(strstrip <<< "$remote_ips")"
|
|
|
|
echo "$local_ip"
|
|
echo "$remote_ips"
|
|
}
|
|
|
|
create_networks() {
|
|
local wg_name local_ip local_ip_trans remote_ips
|
|
local br_name n
|
|
wg_name="$1"
|
|
local_ip="$2"
|
|
local_ip_trans="$3"
|
|
remote_ips="$4"
|
|
|
|
br_name="${wg_name}br1"
|
|
n=1
|
|
|
|
create_br "$br_name"
|
|
for remote_ip in $remote_ips ; do
|
|
create_gre "${wg_name}gre$n" "$local_ip" "$remote_ip"
|
|
add_gre_to_br "$br_name" "${wg_name}gre$n"
|
|
n=$((n+1))
|
|
done
|
|
|
|
finish_br "$br_name" "$local_ip_trans"
|
|
}
|
|
|
|
up() {
|
|
local filepath translation_filepath
|
|
local r local_ip remote_ips local_ip_trans
|
|
filepath="$1"
|
|
translation_filepath=
|
|
if [[ "$filepath" =~ .*/.* ]]; then
|
|
# path, not a name, leave as is
|
|
:
|
|
else
|
|
if [[ $# -eq 1 ]]; then
|
|
translation_filepath="$filepath"
|
|
fi
|
|
filepath="/etc/wireguard/$filepath.conf"
|
|
fi
|
|
|
|
if [[ -z "$translation_filepath" ]]; then
|
|
translation_filepath="$2"
|
|
fi
|
|
if [[ "$translation_filepath" =~ .*/.* ]]; then
|
|
# path, not a name, leave as is
|
|
:
|
|
else
|
|
translation_filepath="/etc/gre-on-wg/$translation_filepath.conf"
|
|
fi
|
|
|
|
r="$(read_wg_conf "$filepath")"
|
|
local_ip="$(head -n1 <<< "$r")"
|
|
remote_ips="$(tail -n1 <<< "$r")"
|
|
unset r
|
|
|
|
local_ip_trans="$(grep -E "$(sed 's_\._\\._g' <<< "$local_ip")" "$translation_filepath" | awk '{print $2}')"
|
|
|
|
create_networks "$(basename --suffix='.conf' "$filepath")" "$local_ip" "$local_ip_trans" "$remote_ips"
|
|
}
|
|
|
|
down() {
|
|
local filepath
|
|
local wg_name link
|
|
filepath="$1"
|
|
if [[ "$filepath" =~ .*/.* ]]; then
|
|
# path, not a name, leave as is
|
|
:
|
|
else
|
|
filepath="/etc/wireguard/$filepath.conf"
|
|
fi
|
|
wg_name="$(basename --suffix=.conf "$filepath")"
|
|
for link in $(ip_hook link list | grep -Eo '^[0-9]+:\s+'"$wg_name"'[^:@]+' | sed -E 's/[0-9]+:\s+//' | tac); do
|
|
$DEBUG ip_hook link del "$link"
|
|
done
|
|
}
|
|
|
|
"$@"
|