📜 ⬆️ ⬇️

Linux Routing: VRF Lite

Usually VRF (Virtual Routing and Forwarding, VPN Routing and Forwarding) is used in conjunction with MPLS, but without that in Cisco terminology it is called VRF-Lite. The essence of this technology is that route information belonging to different classes (for example, routes of one client) is isolated from each other. It is believed that only “adult” iron solutions have such opportunities, but this is not quite so. Due to the presence of multiple routing tables, flexible routing policies, all this can be done in Linux. Who cares, welcome under cat.

Types of routes, routing tables and PBR in Linux

Before we understand the essence of what is happening, let's get acquainted with some of the hallmarks of the Linux network stack.

The first distinguishing point is the special types of routes. When the ip-package comes from any interface, you need to determine whether it is addressed to this host, or another. This is determined to be quite elegant - just for the destination address, the desired route is searched for in the routing tables. If a packet falls on a “local” route, then it is addressed directly to the host, if not, then it must be routed further (the further route is already known) or do something else, depending on the type of routes.

At the moment, several types of routes are supported (for more information about them, see the ip-route mane, if it says that there is no such mana, then update the iproute package to a more recent one). We are currently only interested in routes of the following types:

Thus, for routing transit packets, it is enough for us to have a route of the unicast type, and in order for the host to respond to the packets, we also need routes of the types local and, optionally, broadcast. Another thing to keep in mind is that we also need routes of direct-connected networks in order to ensure connectivity with neighboring routers.
')
Routes are grouped into routing tables. By default, initially there are three tables in the system:


Table names are stored in the / etc / iproute2 / rt_tables file. Under the table number, 32 bits are given, but the maximum number of tables at the moment is strictly limited to 256. How to add / delete / edit routes can be read in mana to ip-route.

The table in which to look for routes is determined by the routing policies. This technology is called Policy Based Routing. Its essence is that based on any criteria of the network packet, we either choose the table in which to look for the route, or determine the action that needs to be performed on the packet. Each policy has a number (it may not even be unique), it also determines the priority. Policies are viewed in order of increasing their priorities. New policies are added before existing ones.

Currently, the “criteria” of the policy are

Each policy has a type that determines the action on the package if it falls under it:


We lock routes in the table


Now a small practical example after a boring introduction. To begin with, we will implement the scheme with vrf-lite manually, and then complicate the example of dynamic routing.

Suppose we have this scheme:


The challenge is to isolate traffic of different "colors" from each other. At the same time, the address spaces of colors can intersect, which makes the task even more interesting. Informally, we formulate a goal: to make sure that packets of each color do not go beyond the limits of their routing table and are transmitted only via interfaces of their own color.

To do this, we will create our own routing table for each color, and for convenience we give them a name. Then, add routes belonging to the color of the interfaces to the direct-connected tables. And finally, add routing policies so that the packets use only their table.

First we assign the addresses to the interfaces. At the same time, the connected routes will go to the main table, and local and broadcast routes will go to the local table.
ip address add 192.168.0.1/24 dev eth0 ip address add 192.168.1.1/24 dev eth1 ip address add 192.168.2.1/24 dev eth2 ip address add 192.168.3.1/24 dev eth3 

Add for convenience the names of the routing tables.
 echo "10 RED" >> /etc/iproute2/rt_tables echo "20 GREEN" >> /etc/iproute2/rt_tables 

We add direct routes to the corresponding tables. We need this so that neighboring routers are available to us.
 ip route add 192.168.0.0/24 dev eth0 proto static scope link table RED ip route add 192.168.1.0/24 dev eth1 proto static scope link table GREEN ip route add 192.168.2.0/24 dev eth2 proto static scope link table GREEN ip route add 192.168.3.0/24 dev eth3 proto static scope link table RED 

Add the remaining routes.
 ip route add 10.0.0.0/24 via 192.168.2.10 dev eth2 proto static table GREEN 

We add policies.
 ip rule add iif eth0 pref 10 lookup RED ip rule add iif eth3 pref 10 lookup RED ip rule add iif eth1 pref 20 lookup GREEN ip rule add iif eth2 pref 20 lookup GREEN 

There is one caveat: what happens if a package of the same color does not find a route in its table? This means that the search for the route in other tables will continue, which is not very good for us. To lock a packet within its color, we can add a default route (either unicast or deny) to each isolated table or add a deny policy after each route search policy within the color. Let's make the first option for one color, and the second one for another.
 ip route add unreachable default proto static table RED ip rule add unreachable iif eth1 pref 21 ip rule add unreachable iif eth2 pref 21 

It is also desirable to transfer all local and broadcast routes from the local table to the tables of the corresponding colors so that it is impossible to access the local interfaces of the router from an “alien” color. To do this, it is best to write a script so that it is not so tiring.

As a result, our routing tables and policies will look something like this:
 ip route list table RED unreachable default proto static broadcast 192.168.0.0 dev eth0 proto static scope link 192.168.0.0/24 dev eth0 proto static scope link local 192.168.0.1 dev eth0 proto static scope host src 192.168.0.1 broadcast 192.168.0.255 dev eth0 proto static scope link broadcast 192.168.3.0 dev eth3 proto static scope link 192.168.3.0/24 dev eth3 proto static scope link local 192.168.3.1 dev eth3 proto static scope host src 192.168.3.1 broadcast 192.168.3.255 dev eth3 proto static scope link ip route list table GREEN 10.0.0.0/8 via 192.168.2.10 dev eth2 proto static broadcast 192.168.1.0 dev eth1 proto static scope link 192.168.1.0/24 dev eth1 proto static scope link local 192.168.1.1 dev eth1 proto static scope host src 192.168.1.1 broadcast 192.168.1.255 dev eth1 proto static scope link broadcast 192.168.2.0 dev eth2 proto static scope link 192.168.2.0/24 dev eth2 proto static scope link local 192.168.2.1 dev eth2 proto static scope host src 192.168.2.1 broadcast 192.168.2.255 dev eth2 proto static scope link ip rule list 0: from all lookup local 10: from all iif eth0 lookup 10 10: from all iif eth3 lookup 10 20: from all iif eth1 lookup 20 20: from all iif eth2 lookup 20 21: from all iif eth1 unreachable 21: from all iif eth2 unreachable 32766: from all lookup main 32767: from all lookup default 

Assembled in GNS3 booth showed the correct operation of the scheme. When referring to someone else's color, the sender receives a message about the unavailability of the destination, as it was intended.

That's all for now, but to be continued. In it I will try to tell about dynamic routing with reference to vrf with the help of the bird routing daemon, and the exchange of routes between tables (vrf leaking).

Source: https://habr.com/ru/post/138698/


All Articles