116 lines
2.6 KiB
Bash
116 lines
2.6 KiB
Bash
|
#!/bin/bash
|
||
|
|
||
|
set -euo pipefail
|
||
|
|
||
|
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 link add "$name" type gretap local "$local_ip" remote "$remote_ip"
|
||
|
$DEBUG ip link set up "$name"
|
||
|
}
|
||
|
|
||
|
add_gre_to_br() {
|
||
|
local br_name gre_name
|
||
|
br_name="$1"
|
||
|
gre_name="$2"
|
||
|
|
||
|
$DEBUG ip link set "$gre_name" master "$br_name"
|
||
|
}
|
||
|
|
||
|
finish_br() {
|
||
|
local name local_ip
|
||
|
name="$1"
|
||
|
local_ip="$2"
|
||
|
|
||
|
$DEBUG ip addr add "$local_ip" dev "$name"
|
||
|
$DEBUG ip 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"
|
||
|
}
|
||
|
|
||
|
main() {
|
||
|
local filepath translation_filepath
|
||
|
local r local_ip remote_ips local_ip_trans
|
||
|
filepath="$1"
|
||
|
if [[ "$filepath" =~ .*/.* ]]; then
|
||
|
# path, not a name, leave as is
|
||
|
:
|
||
|
else
|
||
|
filepath="/etc/wireguard/$filepath"
|
||
|
fi
|
||
|
translation_filepath="$(sort <<< "$2" | uniq)"
|
||
|
|
||
|
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"
|
||
|
}
|
||
|
|
||
|
main "$@"
|