1

This question is about configuring a WireGuard relay that routes all its peer's traffic to another WireGuard server, but the relay itself does not use that WireGuard server as the default gateway.

I am doing some self-hosting stuff. Currently my network contains three nodes, a gateway, an ownCloud server and my mobile phone. These nodes connected in mesh. The gateway is hosted on a VPS, and the mobile will use it to access the Internet.

Everything is working. But the problem comes when I add a Windows node to this network because the kill-switch function of the WireGuard Windows client requires the configuration to have exactly one peer and the allowed IP is 0.0.0.0/0. For security reason, I don't want the VPS sit between the Windows node and ownCloud server, so the route should be:

Windows node -> ownCloud server -> Gateway -> Internet

Moreover, the ownCloud server will run hourly restic backup. I don't want this traffic to route to the gateway because of speed.

I have been trying policy-based routing for around a few hours, but still cannot make it work. Could anyone help? Thanks. Below are the running configurations.

Gateway

wg0

[Interface]
Address = 10.0.0.1/32
ListenPort = 51820

[Peer]
PublicKey = (ownCloud server's public key)
AllowedIPs = 10.0.0.2/32

[Peer]
PublicKey = (mobile's public key)
AllowedIPs = 10.0.0.3/32

nftables

    chain postrouting {
        type nat hook postrouting priority srcnat;
        ip saddr 10.0.0.0/24 oif eth0 masquerade
    }
    chain forward {
        type filter hook forward priority filter; policy drop;
        ct state established,related accept
        ip saddr 10.0.0.0/24 accept
    }

ownCloud server

[Interface]
Address = 10.0.0.2/32
ListenPort = 51820

[Peer]
PublicKey = (gateway's public key)
Endpoint = $gateway_ip_address:51820
AllowedIPs = 10.0.0.1/32
PersistentKeepalive = 25

[Peer]
PublicKey = (mobile's public key)
AllowedIPs = 10.0.0.3/32
PersistentKeepalive = 25

Mobile

[Interface]
Address = 10.0.0.3/32
ListenPort = 51820
DNS = 10.0.0.2

[Peer]
PublicKey = (gateway's public key)
Endpoint = $gateway_ip_address:51820
AllowedIPs = 0.0.0.0/0
PersistentKeepalive = 25

[Peer]
PublicKey = (ownCloud server's public key)
Endpoint = (ownCloud server's domain name):51820
AllowedIPs = 10.0.0.2/32
PersistentKeepalive = 25
Waiho
  • 13
  • 3

1 Answers1

0

Yes, policy routing is what you want for your ownCloud Server. Try the following WireGuard config for your ownCloud server:

[Interface]
PrivateKey = (ownCloud server's private key)
Address = 10.0.0.2/24
ListenPort = 51820
Table = 123

PreUp = sysctl -w net.ipv4.ip_forward=1
PreUp = ip rule add iif %i table 123 priority 456
PostDown = ip rule del iif %i table 123 priority 456

[Peer]
PublicKey = (gateway's public key)
Endpoint = $gateway_ip_address:51820
AllowedIPs = 0.0.0.0/0
PersistentKeepalive = 25

[Peer]
PublicKey = (mobile's public key)
AllowedIPs = 10.0.0.3/32

[Peer]
PublicKey = (windows node's public key)
AllowedIPs = 10.0.0.4/32
  • Using a /24 netmask for its WireGuard address will add a 10.0.0.0/24 route for your WireGuard network to its main routing table.
  • Specifying Table = 123 will trigger wg-quick to use the custom 123 routing table instead of the main table when it adds routes for the WireGuard peers.
  • The iff i% table 123 priority 456 policy routing rule will ensure that all traffic that comes in through the WireGuard interface will use this custom table instead of the main table (while outgoing traffic generated on the system itself will continue to use the main table).
  • Specifying AllowedIPs = 0.0.0.0/0 for the gateway peer means that all traffic that is sent through the WireGuard interface, and not designated for the other peers, will be sent to the gateway.

Also make sure you adjust the firewall on your ownCloud server to allow traffic to be forwarded from your WireGuard network, the same as you did for your gateway (but you don't need to masquerade it like you do on the gateway):

chain forward {
    type filter hook forward priority filter; policy drop;
    ct state established,related accept
    ip saddr 10.0.0.0/24 accept
}

Then you should be able to use a WireGuard config like the following on your Windows node, and access both the Internet and the rest of your WireGuard network through it:

[Interface]
PrivateKey = (windows node's private key)
Address = 10.0.0.4/32
ListenPort = 51820
DNS = 10.0.0.2

[Peer]
PublicKey = (ownCloud server's public key)
Endpoint = (ownCloud server's domain name):51820
AllowedIPs = 0.0.0.0/0
PersistentKeepalive = 25
Justin Ludwig
  • 1,006
  • 7
  • 8
  • wg-quick doesn't add routes of the tun to the main table anyway. Rather with the implicit default `Table=auto`, a set of ip rules will be added automatically so that the default route in the main table will be overriden (but not routes with prefix length > 0) – Tom Yan Jun 13 '22 at 04:26
  • @JustinLudwig A huge THANKS for your solution. I read some of your blog posts when I start learn WireGuard. Actually, I have figured it out already after two days I asked this question. But it makes me feel more confident in my script as it looks similar. The differences are at `iif %i` and `priority 456`, where I use `from 10.0.0.192/26` as I assigned this subnet for the trusted devices, and omited `priority` as I don't know this option at that time. – Waiho Jun 14 '22 at 02:22
  • @JustinLudwig Moreover, because the IP address of the VPS (the gateway) is exposed to the website, and the only visitor of my VPS is me, ISP and the government can easily identify me. I think it is not a real "VPN". So in my latest setup, I use two WireGuard interfaces, one for connecting my devices, and another is ProtonVPN for accessing the Internet. – Waiho Jun 14 '22 at 02:32