Let’s say you are a bit crazy and you abuse WireGuard tunnels. And you are crazy enough (or dumb) to use a Ubuntu machine as a router.

Let’s now say that you have a public IP traffic delivered over a tunnel to your Ubuntu router, and you must ensure that traffic leaves from the correct interface (e.g. source routing).

You can add complex lines in your WireGuard configuration file.

Or, in a more integrated way, exploiting Canonical’s netplan support, some lines can be added directly with the other network configuration.

A simple tunnel

tunnels:
  tun0:
     mode: wireguard
      addresses: [10.12.12.2/24]
      key:
        private: aaaaa.....aaaaaa
      peers:
        - keys:
            public: bbbbb.....bbbbb
          allowed-ips: [0.0.0.0/0, "::/0"]
          keepalive: 90
          endpoint: 199.199.1.1:51820

Source routing

To send response traffic correctly over the tunnel, we need to use source routing.

We mark incoming traffic with a firewall mark (12 in this case).

Then traffic marked as 12 will be routed using the table 12, and will use the gateway 10.12.12.1 for it. Since this is the remote address on the tunnel, it will force outgoing response traffic to be sent over the tunnel.

tunnels:
  tun0:
     mode: wireguard
       addresses: [10.12.12.2/24]
       mark: 12
       key:
         private: aaaaa.....aaaaaa
       peers:
         - keys:
             public: bbbbb.....bbbbb
           allowed-ips: [0.0.0.0/0, "::/0"]
           keepalive: 90
           endpoint: 199.199.1.1:51820
      routes:
        - to: 0.0.0.0/0
          via: 10.12.12.1
          table: 12
      routing-policy:
        - from: 10.12.12.2
          table: 12

My use case

As licensed radioamateur, I have a AMPRnet allocation.

44Net is shorthand for Internet network 44 (44.0.0.0/9 & 44.128.0.0/10), also known as AMPRNet. Since its allocation to amateur radio in the mid-1980s, the network has been used by amateur radio operators to conduct scientific research and to experiment with digital communications over radio. The goals are to of advance the state of the art of Amateur Radio networking, and to educate amateur radio operators in these techniques.

Since I cannot connect directly (e.g, through a wireless link) to the network, my allocation is delivered over a WireGuard tunnel to a AMPRnet router (specifically, through SK0BU, the main node for Stockholm region).

The tunnel configuration becomes thus something like the following:

      addresses: [10.12.12.2/24, 44.5.xx.yy/16]
      mark: 44
      [...]
      routes:
        - to: 0.0.0.0/0
          via: 10.12.12.1
          table: 44
      routing-policy:
        - from: 10.12.12.2
          table: 44
        - from: 44.5.xx.yy
          table: 44

This would add a second IP to the tunnel interface, and replying traffic would be routed over the tunnel.

But now an issue arises: all 44.5.0.0/16 IPs would be reached through the tunnel, and if (as in my case) your tunnel endpoint is also a 44.5.x.y address, a loop happens.

We solve this by adding a static route for this IP under the interface handling the main uplink connection (so, the main way to the Internet):

    wan:
      [...]
      routes:
        - to: 44.5.x.y
          via: 10.1.1.1
          metric: 101

10.1.1.1 is my usual gateway (router) to the Internet.