Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

what does 'ip -4 rule add table main suppress_prefixlength 0' meaning?

ip -4 rule add table main suppress_prefixlength 0 This command appears in the process of connecting to wireguard vpn.

like image 388
Wendell Ou Avatar asked Dec 07 '20 08:12

Wendell Ou


People also ask

What does ip rule do?

ip rule manipulates rules in the routing policy database control the route selection algorithm. Classic routing algorithms used in the Internet make routing decisions based only on the destination address of packets (and in theory, but not in practice, on the TOS field).

How do I check my ip rule?

To display the RPDB, use the command ip route show. The output of the command is a list of rules in the RPDB sorted by order of priority. The rules with the highest priority will be displayed at the top of the output.


1 Answers

It's perhaps easiest to explain this in terms of three potential route considerations for wireguard.

When you create a wireguard interface, you obviously want packets going to the IP ranges you want to access through wireguard to go through that interface. So if you're accessing, say, 10.2.0.0/16 via wireguard on wg0, you could just do ip route add 10.2.0.0/16 dev wg0.

That works if you're just connecting to a private network. But what if you want everything routed through wireguard, for it to be your default route? That poses a complexity, because when you want everything routed through a wireguard interface, you obviously don't want wireguard's own packets routed through that interface; otherwise, they'd never go anywhere at all. Try ip route add 0.0.0.0/0 dev wg0 and now nothing will work: packets transporting wg0 would try to go through wg0. You could add specific routes to each wireguard peer, but you might have many wireguard peers, so that would be inconvenient.

Instead, wg-quick uses a firewall mark (fwmark) so that routing can recognize packets for that interface, and handle them differently. By setting something like wg setconf wg0 fwmark 51820, wireguard can then add rules to treat wireguard packets and non-wireguard packets differently. Then, it creates a different routing table (eg, 51820, which you can see by ip route list table 51820), which non-wireguard packets go through, and routes them all through wg0, while wireguard packets go through the main table (what you see with ip route list). It uses a rule (not from all fwmark 0xca6c lookup 51820) to divert anything that isn't a wireguard packet to the 51820 table (you can see these rules with ip rule or ip -6 rule).

So now, why the from all lookup main suppress_prefixlength 0? You don't actually need this in many cases: wireguard packets will be routed on the main table, and non-wireguard packets will be routed on the table wg-quick creates. But what if your main routing table isn't just simply a default route? What if you've added other, more specific, routes, maybe for some private-address space VPN (the reason why I just had to figure out what this command did), or maybe to get to some of the peers in the first place: maybe they're on different interfaces?

To cover these situations, this third command adds a rule that first, looks up what the route for any packet (from all) would be on the main table (lookup main). Then, it sees how specific that route is, eg, what its prefix length is. If it's 0 (ie, a default route, 0.0.0.0/0 or ::/0), it suppresses that route (suppress_prefixlength 0, which suppresses anything with a prefix length of its argument or less), and continues looking at the next rules. If it's more than 0 (eg, 10.1.0.0/16), then it uses that route.

Thus, you end up with rules that look like these from ip rule list (annoyingly, ip rule shows the firmware mark as hexadecimal, so 0xca6c, while wireguard sets it as decimal, so 51820):

32764:  from all lookup main suppress_prefixlength 0
32765:  not from all fwmark 0xca6c lookup 51820
32766:  from all lookup main

A main table that might look something like this (ip route):

default via {gateway_ip} dev wlan0 proto dhcp metric 600
10.2.0.0/24 dev other_vpn proto kernel scope link src 10.2.0.210

And a "51820" table that looks like this (ip route list table 51820):

default dev wg0 scope link

So when a packet goes through these rules and tables:

  1. At 32764, we go to the main table.
    1. If the packet is going to, say, 10.2.0.5, then it will hit the 10.2.0.0/24 route, and with the 24 prefix, that's where it will go.
    2. If, on the other hand, matches default (0.0.0.0/0), then rather than going to gateway_ip on wlan0, it will get suppressed by the suppress_prefixlength 0, and we'll continue.
  2. At 32765, we check the fwmark. If it's not 0xca6c (ie, it's not a packet wireguard is sending to implement wg0), then we'll go to table 51820. And that's very simple: everything goes over wg0.
  3. If the fwmark is 0xca6c, and thus it is a wireguard packet, then we'll go to 32766. That will bring us back to the main table, where, in this case, we'll match the default route, and the wireguard packets will go out through wlan0, as we want: we do, eventually, need to use our physical connection.
like image 195
cge Avatar answered Oct 18 '22 21:10

cge