[TL;DR]
1. networkd-dispatcher uses specific environment variables for passing
interface state. (https://gitlab.com/craftyguy/networkd-dispatcher#usage)
2. script file(or symbolic link) must be located in
/usr/lib/networkd-dispatcher/configured.d because 'chronyc onoffline'
command sets sources offline when interface is in configuring state.

[Environment]
- OS: Ubuntu 20.04 LTS (focal)
- Chrony version: 3.5-6ubuntu6.2
- Network daemon: systemd-networkd



Hi,

I have noticed that on some servers using systemd-networkd, all the sources
are in the offline state after booting.

Running the 'chronyc online' command brought the sources online and they
were working fine, so there was nothing wrong with the configuration and
actual source state.

As it turns out, the networkd-dispatcher script that is configured when
chrony is installed is simply the symbolic link to a script for
NetworkManager, which did not work properly in the systemd-networkd
environment.

```
$ ll /usr/lib/networkd-dispatcher/routable.d/ | grep chrony
lrwxrwxrwx 1 root root   42 Aug 26  2020 chrony ->
/etc/NetworkManager/dispatcher.d/20-chrony*
```

Because networkd-dispatcher uses specific environment variables to pass
interface state, nothing exists in the shell argument of dispatcher script.

Because of this, the '[ $# -ge 2]' condition in the existing
NetworkManager-based script (20-chrony) was always FALSE, causing the
'chronyc onoffline' command to be executed regardless of the type of
interface event.

```
[ $# -ge 2 ] && [ "$2" != "up" ] && [ "$2" != "down" ] && exit 0
chronyc onoffline > /dev/null 2>&1
exit 0
```

Also, the values that networkd-dispatcher passes through environment
variables are different from NetworkManager-dispatcher: (configured,
routable...)

And crucially, the script did not exist in the
/usr/lib/networkd-dispatcher/configured.d/ directory, so the last time
'chronyc onoffline' was run when the interface was in the configuring
state, the source was taken offline.

Under the /usr/lib/networkd-dispatcher/configured.d/ directory, I created a
test networkd-dispatcher script as shown below and it worked fine.
(An additional consideration here is when the interface has been turned
off...)

```
#!/bin/sh
# This is a NetworkManager dispatcher / networkd-dispatcher script for
# chronyd to set its NTP sources online or offline when a network interface
# is configured or removed

export LC_ALL=C

# Note: for networkd-dispatcher routable.d ~= on and off.d ~= off

[ "$STATE" != "routable" ] && [ "$AdministrativeState" != "configured" ] &&
exit 0
chronyc onoffline > /dev/null 2>&1
exit 0
```

I haven't tested this in every case, but I've seen the same thing happen on
at least a few OS with systemd-networkd enabled.

Best regards

Reply via email to