5

On a Debian Stretch system with multiple interfaces, I need to define the default route via a specific interface ens3. This interface receives its ip address 10.33.34.2 through dhcp.

I adjusted the following guide to my needs:

5.3. The modern network configuration without GUI

Thus, I created a file /etc/systemd/network/route.network with the following content

[Match]
Name=ens3

[Network]
Gateway=10.33.34.1

However, the default route is not set correctly at startup.

I enabled debugging of systemd-networkd according to How to debug systemd-networkd?

After restarting systemd-networkd, I see the following in the logs:

Aug 21 13:43:13 vpn systemd-networkd[15671]: ens3: Setting routes
Aug 21 13:43:13 vpn systemd-networkd[15671]: ens3: Could not set route: Network is unreachable
Aug 21 13:43:13 vpn systemd-networkd[15671]: ens3: Routes set
Aug 21 13:43:13 vpn dhclient[15709]: Listening on LPF/ens3/52:54:00:3f:f1:d0
Aug 21 13:43:13 vpn dhclient[15709]: Sending on LPF/ens3/52:54:00:3f:f1:d0
Aug 21 13:43:13 vpn dhclient[15709]: Sending on Socket/fallback
Aug 21 13:43:13 vpn dhclient[15709]: DHCPDISCOVER on ens3 to 255.255.255.255 port 67 interval 8
Aug 21 13:43:13 vpn dhclient[15709]: DHCPREQUEST of 10.33.34.2 on ens3 to 255.255.255.255 port 67
Aug 21 13:43:13 vpn dhclient[15709]: DHCPOFFER of 10.33.34.2 from 10.33.34.1
Aug 21 13:43:13 vpn dhclient[15709]: DHCPACK of 10.33.34.2 from 10.33.34.1
Aug 21 13:43:13 vpn systemd-networkd[15671]: ens3: Adding address: 10.33.34.2/24 (valid forever)

It seems that networkd tries to set the route before the IP-address is assigned via dhcp.

How do I get the default route set to a specific interface with systemd?

== Edit ==

I was wrong in assuming that systemd-networkd brings up the interfaces. If I restart the system, I see

$ sudo service systemd-networkd status
● systemd-networkd.service - Network Service
   Loaded: loaded (/lib/systemd/system/systemd-networkd.service; disabled; vendor pres
  Drop-In: /etc/systemd/system/systemd-networkd.service.d
           └─10-debug.conf
   Active: inactive (dead)
     Docs: man:systemd-networkd.service(8)

Thus, configuration in /etc/systemd/network/route.network takes no effect when booting. Currently, I'm wondering what service is responsible to bring up all the network devices.

== Edit 2 ==

This article by Steven Iveson provides a good insight on how network devices are started by systemd-udevd and how to modify interface configuration.

By testing and further reading, I would also restate my problem: The multiple interfaces are brought up in random order. Each obtains a correct dhcp configuration. The first interface to be brought up will set the default route and therefore, 10.33.34.1 will not always be used as default route

Robotnik
  • 2,645
DoRe
  • 65

2 Answers2

3

If all interfaces receive valid DHCP offers with a default route, then there will be no way around configuring dhclient to ignore those -- that isn't something you can do with systemd, udev, or anything else connected the init system.

One way to do that is described here: You create (of course, you can also use an editor) a shell script fragment in one of the "hook" directories of dhclient,

cat << EOF > /etc/dhcp/dhclient-enter-hooks.d/restrict-default-route
## Only the DHCP server talking to ens3 is allowed to give us a default
## route.  Other interfaces only get local-segment configuration.
case ${interface} in
  ens3)
    ;;
  *)
    unset new_routers
    ;;
esac
EOF

which will only accept the routers option with the default route for ens3. No problems with timing, no problems with figuring out which systemd files to use, and the route will only be valid when ens3 is up and has received the DHCP offer.

dirkt
  • 17,461
0

For Debian Stretch, the interfaces are named by udev and basic configuration occurs in /etc/network/interfaces. As stated in edit 2, the multiple interfaces are brought up in random order. Each obtains a correct dhcp configuration. The first interface to be brought up will set the default route. We need to only accept the default route for the desired interface. This can be achieved by a hook to the dhcpclient

Add a new hook script /etc/dhcp/dhclient-enter-hooks.d/nodefaultroute:

#!/bin/sh
## Prevent DHCP server on eth0 from forcing a default route on us

case ${interface} in
  ens8|ens9)
     printf "executing ip route delete default via $new_routers\n" 
     ip route delete default via $new_routers
  ;;
     *)
  ;;
esac

Where ens8|ens9 can be extended to list all the interfaces for which the default route can not be accepted.

DoRe
  • 65