3

I have a Wireguard server S and two clients : A & B. All are on different networks. Only S is reachable. A and B can only connect to S. I want to route the Internet traffic of B (an optionnaly S) through A.

I tried several things such as :

https://serverfault.com/questions/1074729/route-all-traffic-through-wireguard-peer/1074734#1074734?newreg=7692f5689bcb449883a05c1f72cdd012

Routing WireGuard peer's traffic via another peer

Thanks for your help.

1
  • Please clarify your specific problem or provide additional details to highlight exactly what you need. As it's currently written, it's hard to tell exactly what you're asking.
    – Community Bot
    Commented Aug 1, 2023 at 16:33

1 Answer 1

2

Internet Gateway as a Spoke

We have an endpoint with WireGuard running on it, Endpoint A, from which we want to access the Internet. To get from Endpoint A to the Internet in this scenario, however, WireGuard traffic needs to go through two hops: one through the VPN hub, Host C; and the second through a spoke of the hub, Host β. However, while we want to use Host β as the Internet gateway for Endpoint A, we don’t want that for Host C — Host C itself can use the default routes at Site C to access the Internet as needed. Hub with an Internet Gateway Spoke

Details of the network used in this explanation

Within our WireGuard network, Endpoint A has an IPv4 address of 10.0.0.1 and an IPv6 address of fd10:0:0:1::1; Host C has an IPv4 address of 10.0.0.3, and an IPv6 address of fd10:0:0:3::1; and Host β has an IPv4 address of 10.0.0.2 and an IPv6 address of fd10:0:0:2::1. Host C has a public IP address of 192.0.2.3, allowing Endpoint A and Host β to each establish a WireGuard tunnel to it.

Endpoint A

On Endpoint A, when the WireGuard network is up, we want to send all Internet traffic through Host C, so we configure AllowedIPs = 0.0.0.0/0, ::/0 for Host C in Endpoint A’s WireGuard config:

# /etc/wireguard/wg0.conf

# local settings for Endpoint A
[Interface]
PrivateKey = AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEE=
Address = 10.0.0.1/32, fd10:0:0:1::1/64
ListenPort = 51821

# remote settings for Host C
[Peer]
PublicKey = jUd41n3XYa3yXBzyBvWqlLhYgRef5RiBD7jwo70U+Rw=
Endpoint = 192.0.2.3:51823
AllowedIPs = 0.0.0.0/0, ::/0

0.0.0.0/0 is the entire IPv4 space, and ::/0 is the entire IPv6 space. (If you don’t care about IPv6 traffic, you can omit the IPv6 addresses and address blocks from this and the other WireGuard configurations.)

Host C

On Host C, we want to send all the traffic destined for 10.0.0.1 or fd10:0:0:1::/64 to Endpoint A, and all other traffic that comes through our WireGuard network on to Host β. So we configure WireGuard on Host C with AllowedIPs = 10.0.0.1/32, fd10:0:0:1::/64 for its Endpoint A [Peer] section, and AllowedIPs = 0.0.0.0/0, ::/0 for its Host β [Peer] section.

But since we don’t want all of Host C’s traffic to go to Host β — just traffic forwarded through the WireGuard network — we configure the routes for this WireGuard interface to use a custom routing table, via the interface’s Table = 123 setting. And we use a PreUp command to add a policy routing rule that directs the host to use this table only for traffic coming in from this WireGuard interface (ip rule add iif wg0 table 123 priority 456):

# /etc/wireguard/wg0.conf

# local settings for Host C
[Interface]
PrivateKey = CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCGA=
Address = 10.0.0.3/32, fd10:0:0:3::1/64
ListenPort = 51823
Table = 123

# IPv4 forwarding & routing
PreUp = sysctl -w net.ipv4.ip_forward=1
PreUp = ip rule add iif wg0 table 123 priority 456
PostDown = ip rule del iif wg0 table 123 priority 456

# IPv6 forwarding & routing
PreUp = sysctl -w net.ipv6.conf.all.forwarding=1
PreUp = ip -6 rule add iif wg0 table 123 priority 456
PostDown = ip -6 rule del iif wg0 table 123 priority 456

# remote settings for Endpoint A
[Peer]
PublicKey = /TOE4TKtAqVsePRVR+5AA43HkAK5DSntkOCO7nYq5xU=
AllowedIPs = 10.0.0.1/32, fd10:0:0:1::/64

# remote settings for Host β
[Peer]
PublicKey = fE/wdxzl0klVp/IR8UcaoGUMjqaWi3jAd7KzHKFS6Ds=
AllowedIPs = 0.0.0.0/0, ::/0

Host B

Similar to the previous Site Gateway as a Spoke scenario, on Host β, we want to send all the traffic destined for the 10.0.0.0/24 and fd10::/56 networks back through Host C — so that’s what we use as the AllowedIPs setting for Host C in Host β’s WireGuard config:

# /etc/wireguard/wg0.conf

# local settings for Host β
[Interface]
PrivateKey = ABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBFA=
Address = 10.0.0.2/32, fd10:0:0:2::1/64
ListenPort = 51822

# IPv4 forwarding
PreUp = sysctl -w net.ipv4.ip_forward=1
# IPv4 masquerading
PreUp = iptables -t mangle -A PREROUTING -i wg0 -j MARK --set-mark 0x30
PreUp = iptables -t nat -A POSTROUTING ! -o wg0 -m mark --mark 0x30 -j MASQUERADE
PostDown = iptables -t mangle -D PREROUTING -i wg0 -j MARK --set-mark 0x30
PostDown = iptables -t nat -D POSTROUTING ! -o wg0 -m mark --mark 0x30 -j MASQUERADE

# IPv6 forwarding
PreUp = sysctl -w net.ipv6.conf.all.forwarding=1
# IPv6 masquerading
PreUp = ip6tables -t mangle -A PREROUTING -i wg0 -j MARK --set-mark 0x30
PreUp = ip6tables -t nat -A POSTROUTING ! -o wg0 -m mark --mark 0x30 -j MASQUERADE
PostDown = ip6tables -t mangle -D PREROUTING -i wg0 -j MARK --set-mark 0x30
PostDown = ip6tables -t nat -D POSTROUTING ! -o wg0 -m mark --mark 0x30 -j MASQUERADE

# remote settings for Host C
[Peer]
PublicKey = jUd41n3XYa3yXBzyBvWqlLhYgRef5RiBD7jwo70U+Rw=
Endpoint = 192.0.2.3:51823
AllowedIPs = 10.0.0.0/24, fd10::/56
PersistentKeepalive = 25

Note that in Host β’s configuration for Host C, we’ve also included a PersistentKeepalive = 25 setting. This ensures that Host β pokes a hole through any NAT (or egress-only) firewalls between Host C and Host β, allowing Endpoint A to initiate connections through the WireGuard network to Host β. You can omit this setting if there are no NAT or egress-only firewalls between Host C and Host β (but if you do that, make sure you instead set up Host C’s WireGuard config to include the public IP address of Host β in its Endpoint setting for Host β).

Also note that we’ve included some iptables rules in Host β’s WireGuard configuration. These iptables rules masquerade packets from the WireGuard network when Host β forwards them out to Site B. You can omit these rules if the LAN router (or each individual endpoint) at Site B is already configured to route traffic destined for the WireGuard network (10.0.0.0/24) back through Host β.

Test It Out

After starting up our configured WireGuard interfaces on each host (Endpoint A, Host C, and Host β), we can run cURL (or a regular webrowser) from Endpoint A to access Google (or any other Internet site) through our WireGuard network: `` $ curl google.com

301 Moved ... ```

Reference :

copy-pasted from https://www.procustodibus.com/blog/2022/06/multi-hop-wireguard/#internet-gateway-as-a-spoke (saved me from 2 weeks of unsuccessful search...)

1
  • 2
    Welcome to Super User! Whilst this may theoretically answer the question, it would be preferable to include the essential parts of the answer here, and provide the link for reference.
    – Mokubai
    Commented Aug 7, 2023 at 17:21

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .