This is a simple point-to-point tunnel between two hosts with no address
restrictions on traffic routed through it. Fixed link-local addresses of
fe80::1 and fe80::2 are assigned to the endpoints, suitable for running
RFC 5549 link-local BGP.
On host 1:
SK1=$(wg genkey)
PK1=$(wg pubkey <<< $SK1)
On host 2:
SK2=$(wg genkey)
PK2=$(wg pubkey <<< $SK2)
Host 1 will need $PK2 and host 2 will need $PK1.
On host 1:
ip link add wg0 type wireguard
wg set wg0 listen-port 51280 private-key /dev/stdin <<< $SK1
wg set wg0 peer $PK2 allowed-ips 0.0.0.0/0,::/0 endpoint $HOST2:51280
ip address add fe80::1/64 dev wg0
ip link set wg0 addrgenmode none up
On host 2:
ip link add wg0 type wireguard
wg set wg0 listen-port 51280 private-key /dev/stdin <<< $SK2
wg set wg0 peer $PK1 allowed-ips 0.0.0.0/0,::/0 endpoint $HOST1:51280
ip address add fe80::2/64 dev wg0
ip link set wg0 addrgenmode none up
One of the hosts can omit endpoint $HOST:51280 if required; it will
then wait passively for the other host to connect. Hostnames are
resolved only once, when the wg command is run. Once the tunnel is up,
either host can change address and its peer will follow it.
Add routes through the tunnel with (for example)
ip route add 192.168.32.0/24 via inet6 fe80::1 dev wg0 or even
ip route add 192.168.32.0/24 dev wg0 as this is a layer 3 tunnel.
Take care that the preferred route from each host to its peer does not go through the tunnel: adding a specific host route for the remote endpoint is generally the correct answer.
Using nftables:
nft -f - <<EOF
flush ruleset
table inet filter {
chain clamp {
type filter hook forward priority mangle
iifname wg0 tcp flags syn tcp option maxseg size set rt mtu
oifname wg0 tcp flags syn tcp option maxseg size set rt mtu
}
}
EOF
On host 1:
protocol bgp {
interface "wg0";
local fe80::1 as NNN;
neighbor fe80::2 as NNN;
ipv4 {
export ...;
import ...;
extended next hop;
};
ipv6 {
export ...;
import ...;
};
}
and similarly on host 2, with the local and neighbor addresses exchanged.