Initial commit.
This commit is contained in:
commit
804008933d
3 changed files with 176 additions and 0 deletions
10
Makefile
Normal file
10
Makefile
Normal file
|
@ -0,0 +1,10 @@
|
|||
SCRIPT := gre-on-wg.sh
|
||||
SCRIPT_NAME := $(SCRIPT:.sh=)
|
||||
PREFIX ?= /usr/local
|
||||
|
||||
install: install-bin
|
||||
|
||||
install-bin: $(SCRIPT)
|
||||
install -D -m 0755 -o root -g root -T $(SCRIPT) $(PREFIX)/bin/$(SCRIPT_NAME)
|
||||
|
||||
.PHONY: install install-bin
|
51
README.md
Normal file
51
README.md
Normal file
|
@ -0,0 +1,51 @@
|
|||
# gre-on-wg
|
||||
|
||||
Create a GRETAP mesh network on top of wireguard.
|
||||
|
||||
## Usage
|
||||
|
||||
`gre-on-wg WG_QUICK_CONFIG_FILE ADDRESS_TRANSLATIONS`
|
||||
|
||||
The first argument is the path to a wg-quick config file, while the
|
||||
second argument provides address translations for wireguard internal ip
|
||||
addresses to the new addresses.
|
||||
|
||||
The wireguard configuration must have the `Address` config in the
|
||||
`[Interface]` section set to exactly **one** address, similarly every
|
||||
`[Peer]` section may only contain **one** AllowedIPs entry with **one**
|
||||
addresss.
|
||||
|
||||
The translation file should contain lines of the following format:
|
||||
`<wireguard private ip> <space> <new bridge network ip>`
|
||||
|
||||
### Example
|
||||
|
||||
Consider the following wg0.conf file
|
||||
|
||||
```
|
||||
[Interface]
|
||||
Address = 192.168.3.100/24
|
||||
|
||||
[Peer]
|
||||
AllowedIPs = 192.168.3.101/32
|
||||
|
||||
[Peer]
|
||||
AllowedIPs = 192.168.3.102/32
|
||||
|
||||
[Peer]
|
||||
AllowedIPs = 192.168.3.103/32
|
||||
```
|
||||
|
||||
And the following translation file
|
||||
|
||||
```
|
||||
192.168.3.100/24 192.168.4.100/24
|
||||
192.168.3.101/24 192.168.4.101/24
|
||||
192.168.3.102/24 192.168.4.102/24
|
||||
192.168.3.103/24 192.168.4.103/24
|
||||
```
|
||||
|
||||
This would result in the creation of the bridge network `wg0br1` on host
|
||||
`192.168.3.100` where the different peers have the addresses
|
||||
`192.168.4.10[0123]`. Additionally the point-to-point networks
|
||||
`wg0gre[1234]` would be created.
|
115
gre-on-wg.sh
Executable file
115
gre-on-wg.sh
Executable file
|
@ -0,0 +1,115 @@
|
|||
#!/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 "$@"
|
Loading…
Reference in a new issue