Double-hop setup to share remote VPN?

Hi! We need to connect multiple clients to a single endpoint VPN A which is itself connected to another VPN B and route all traffic (or just some traffic :slight_smile: from clients to A to B and back again.

This seems like something that WireGuard would be perfect for but we can’t quite get over the hump. If anyone could point us at some resources or drop a few breadcrumbs for us to follow it would be greatly appreciated.

This is more of a routing question than a VPN question. Layout a network like this and setup the routes.

Client Network - 10.0.1.0/24
  :
  : (WG VPN 1)
  :
Network A - 10.0.2.0/24
  :
  : (WG VPN 2)
  :
Network B - 10.0.3.0/24

The key issue is probably routing especially if you want to route “all traffic” because that basically requires you to deal with two default routes, the “native” one and the “Wireguard” one.

Possible puzzle pieces are:

  • wg-quick’s Table = off option (to setup routing on your own)
  • Wireguard’s FwMark = 1234 option (to tell Wireguard to mark its UDP packets)
  • ip rule (policy-based routing to switch routing tables based on, for example, the FwMark)
  • ip route

What are your constraints? Do you control endpoint B? Or do you just have a “client config” for B to use on A? I guess A is under your control?

Also, what exact traffic on endpoint A should be routed to B? just A’s clients’ traffic? Or do you also want, for example, endpoint A to download system updates through B?

If you have two Wireguard interfaces on endpoint A for this, be sure to use the same FwMark because they both (more specifically the UDP packets they create) need to bypass the “new default route” pointing to one of the Wireguard interfaces. wg-quick by default sets up policy based routing (ip rule) to avoid a routing loop by setting an FwMark and switching routing tables based on the FwMark.

If you show more of what you’ve tried (e.g. configs), the more I could help with specific suggestions.

Thanks very much for your reply.

Thanks for the very helpful reply! We are under control of endpoint A but not B - correct. We only want traffic that comes from A’s clients to be auto-routed through B. A may want to route all of their traffic through B in future, but at present it’s not a requirement - only the clients connected to A.

We are all on Mac M1’s if that makes a difference. Any other tips or pointers to documentation are very much appreciated.

Hi, I need to create the same scenario as op, except my endpoint a is an OpenBSD machine, and I’m gonna try the configuration you suggested, thanks!

Table = off

Is probably useful too. This prevents WireGuard from creating routes so you can do it manually.

We are all on Mac M1’s

Does this include endpoint A? I just assumed endpoint A to be a Linux box.

Good luck! I’m not sure whether it’ll work on OpenBSD. The packet marking and policy-based routing might be rather Linux specific. So, be warned. :slight_smile:

Great tip - thank you

It does yes - both M1s.

Yesterday I discovered that on OpenBSD, instead of marking the packets through FwMark, you can make it work directly through pf.conf rules

int_wg = <internal wireguard interface>
int_wg_port = <internal wireguard listening port>
ext_wg = <external wireguard interface>
server_ip = <my public ip>
wg_subnet = <my internal wireguard subnet>

pass in on $int_wg from $wg_subnet to !server_ip
pass out on $ext_wg from $wg_subnet nat-to $ext_wg

pass out on $int_wg proto {udp} from wg1 port $int_wg_port route-to $int_wg

Now when a client connects to my “internal wireguard” at the address <server_ip>:<int_wg_port> it can access to other devices connected to the internal wireguard, and results to have the IP provided by ext_wg. It’s not ok yet (this works only if the device is in the same LAN of the openbsd server, and for some reason every time i connect my smartphone to the vpn, even if it’s in the same LAN, literally everything stops working), but I think that i’m in the right path.

Guess I’ll have to ask for some help on r/OpenBSD. Thanks anyway, guess that “FwMark” was the right keyword to find something useful for my use-case :slight_smile:

OK. Then I can’t help you with this. Sorry.

Here’s a sneak peek of /r/openbsd using the top posts of the year!

#1: OpenBSD 7.1 has been released!
#2: OpenBSD 7.2 has been released!
#3: CDE on openbsd 7.1 | 39 comments


^^I’m ^^a ^^bot, ^^beep ^^boop ^^| ^^Downvote ^^to ^^remove ^^| ^[1](https://www.reddit.com/message/compose/?to=sneakpeekbot) ^^| ^[2](https://np.reddit.com/r/sneakpeekbot/) ^^| ^[3](https://np.reddit.com/r/sneakpeekbot/comments/o8wk1r/blacklist_ix/) ^^| ^[4](GitHub - ghnr/sneakpeekbot: sneakpeekbot from reddit)


  1. Contact ↩︎

  2. Info ↩︎

  3. Opt-out ↩︎

  4. GitHub ↩︎

Ok thanks very much anyway!