Skip to content

Commit c14efe1

Browse files
committed
feat(chrony): introducing the chrony module
This new module relies on chrony to add support for NTP in the initrd. By default, it also uses NTP sources from DHCP. It provides two new kernel command line options: - `rd.ntp`: it can be used multiple times to specify server, pool and peer time sources. - `rd.ntp.nodhcp`: it disables the use of NTP sources from DHCP. In some environments, it's necessary to fetch live images from HTTPS URLs. The problem is that the hardware clock may be off, so the validation of the SSL certificates may fail if the time is out of sync. Also, some systems may not have access to DHCP for security reasons, that's why we need a way to configure them on the kernel command line.
1 parent 58af3a9 commit c14efe1

13 files changed

Lines changed: 488 additions & 0 deletions

File tree

.github/labeler.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,10 @@ caps:
8888
- changed-files:
8989
- any-glob-to-any-file: 'modules.d/[0-9][0-9]caps/*'
9090

91+
chrony:
92+
- changed-files:
93+
- any-glob-to-any-file: 'modules.d/[0-9][0-9]chrony/*'
94+
9195
cifs:
9296
- changed-files:
9397
- any-glob-to-any-file: 'modules.d/[0-9][0-9]cifs/*'

.github/workflows/daily-network.yml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ jobs:
3939
test:
4040
- "31"
4141
- "60"
42+
- "61"
4243
exclude:
4344
- container: arch:latest
4445
architecture: {runner: 'ubuntu-24.04-arm', tag: 'arm'}
@@ -47,6 +48,17 @@ jobs:
4748
# https://github.com/dracut-ng/dracut-ng/issues/1988
4849
- container: debian:sid
4950
architecture: {runner: 'ubuntu-24.04-arm', tag: 'arm'}
51+
# In Debian/Ubuntu both chrony and systemd-timesyncd provide
52+
# the virtual package time-daemon, so systemd-timesyncd
53+
# would have to be removed, breaking test 41.
54+
- container: debian:latest
55+
test: "61"
56+
- container: debian:sid
57+
test: "61"
58+
- container: ubuntu:devel
59+
test: "61"
60+
- container: ubuntu:rolling
61+
test: "61"
5062
container:
5163
image: ghcr.io/dracut-ng/${{ matrix.container }}
5264
options: '--device=/dev/kvm --privileged'

.github/workflows/integration.yml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,13 @@ jobs:
189189
test:
190190
- "31"
191191
- "60"
192+
- "61"
193+
exclude:
194+
# In Debian/Ubuntu both chrony and systemd-timesyncd provide
195+
# the virtual package time-daemon, so systemd-timesyncd
196+
# would have to be removed, breaking test 41.
197+
- container: ubuntu:devel
198+
test: "61"
192199
container:
193200
image: ghcr.io/dracut-ng/${{ matrix.container }}
194201
options: '--device=/dev/kvm'

doc_site/modules/ROOT/pages/modules/network.adoc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@
66
|===
77
| Module | Description
88

9+
| chrony
10+
| Adds support for synchronizing the internal clock via Network Time Protocol (NTP)
11+
912
| cifs
1013
| https://docs.kernel.org/admin-guide/cifs/index.html[CIFS], https://repology.org/project/cifs-utils[cifs-utils]
1114

man/dracut.cmdline.7.adoc

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -729,6 +729,27 @@ interface name. Better name it "bootnet" or "bluesocket".
729729
list of physical (ethernet) interfaces. Bridge without parameters assumes
730730
bridge=br0:eth0
731731
732+
NTP
733+
~~~
734+
Requires the dracut 'chrony' module.
735+
736+
**rd.ntp=**__{server|pool|peer}__:__<hostname-or-ip>__[:__<option>__[,<option>...]]::
737+
This parameter can be specified multiple times.
738+
IPv6 addresses have to be put in brackets.
739+
See man:chrony.conf[5,external] for more information about server, pool and
740+
peer options.
741+
+
742+
[listing]
743+
.Examples
744+
--
745+
rd.ntp=pool:2.europe.pool.ntp.org:iburst
746+
rd.ntp=server:185.177.150.95:iburst,prefer
747+
rd.ntp=server:[2600:1f18:631e:db00:363d:d9d7:5c80:d560]:iburst,maxdelay,0.3
748+
--
749+
750+
**rd.ntp.nodhcp**::
751+
Disable using NTP sources from DHCP.
752+
732753
NFS
733754
~~~
734755
Requires the dracut 'nfs' module.
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
#!/bin/sh
2+
3+
command -v getargbool > /dev/null || . /lib/dracut-lib.sh
4+
5+
if getargbool 0 rd.ntp.nodhcp; then
6+
info "rd.ntp.nodhcp=1: not adding NTP sources from DHCP."
7+
return 0
8+
fi
9+
10+
_ifname=$1
11+
[ -n "$_ifname" ] || return 0
12+
13+
_dhcpopts_file="/tmp/dhclient.$_ifname.dhcpopts"
14+
[ -s "$_dhcpopts_file" ] || return 0
15+
16+
(
17+
# shellcheck disable=SC1090
18+
. "$_dhcpopts_file"
19+
[ -n "$new_ntp_servers" ] || [ -n "$new_dhcp6_ntp_servers" ] || return 0
20+
21+
info "Adding NTP sources from DHCP ($_ifname)."
22+
23+
[ -d /run/chrony-dhcp ] || mkdir -p /run/chrony-dhcp
24+
for _srv in $new_ntp_servers $new_dhcp6_ntp_servers; do
25+
echo "server $_srv iburst" >> "/run/chrony-dhcp/$_ifname.sources"
26+
done
27+
28+
chronyc reload sources > /dev/null 2>&1 \
29+
|| warn "chronyc failed to reload NTP sources"
30+
)
31+
32+
unset _ifname _dhcpopts_file
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
[Unit]
2+
Description=Wait for chrony to synchronize system clock (initrd)
3+
AssertPathExists=/etc/initrd-release
4+
DefaultDependencies=no
5+
After=chronyd.service
6+
Requires=chronyd.service
7+
Before=time-sync.target
8+
Wants=time-sync.target
9+
10+
[Service]
11+
Type=oneshot
12+
# Wait for chronyd to update the clock and the remaining
13+
# correction to be less than 0.1 seconds
14+
ExecStart=/usr/bin/chronyc -h 127.0.0.1,::1 waitsync 0 0.1 0.0 1
15+
# Wait for at most 3 minutes
16+
TimeoutStartSec=180
17+
RemainAfterExit=yes
18+
StandardOutput=null
19+
20+
CapabilityBoundingSet=
21+
DevicePolicy=closed
22+
DynamicUser=yes
23+
IPAddressAllow=localhost
24+
IPAddressDeny=any
25+
LockPersonality=yes
26+
MemoryDenyWriteExecute=yes
27+
PrivateDevices=yes
28+
PrivateUsers=yes
29+
ProtectClock=yes
30+
ProtectControlGroups=yes
31+
ProtectHome=yes
32+
ProtectHostname=yes
33+
ProtectKernelLogs=yes
34+
ProtectKernelModules=yes
35+
ProtectKernelTunables=yes
36+
ProtectProc=invisible
37+
ProtectSystem=strict
38+
RestrictAddressFamilies=AF_INET AF_INET6
39+
RestrictNamespaces=yes
40+
RestrictRealtime=yes
41+
SystemCallArchitectures=native
42+
SystemCallFilter=@system-service
43+
SystemCallFilter=~@privileged @resources
44+
UMask=0777

modules.d/74chrony/chrony.conf

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# This file is part of dracut chrony module.
2+
# SPDX-License-Identifier: GPL-2.0-or-later
3+
4+
# Record the rate at which the system clock gains/losses time.
5+
driftfile /run/chrony/drift
6+
7+
# Allow the system clock to be stepped in the first three updates
8+
# if its offset is larger than 1 second.
9+
makestep 1.0 3
10+
11+
# Enable kernel synchronization of the real-time clock (RTC).
12+
rtcsync
13+
14+
# Save NTS keys and cookies.
15+
ntsdumpdir /run/chrony
16+
17+
# Specify directory for log files.
18+
logdir /run/chrony/log
19+
20+
# First, use NTP sources parsed by dracut from the kernel command line.
21+
sourcedir /run/chrony/dracut.sources.d
22+
23+
# Second, use NTP sources from DHCP.
24+
sourcedir /run/chrony-dhcp

modules.d/74chrony/chronyd.service

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
[Unit]
2+
Description=NTP client/server (initrd)
3+
AssertPathExists=/etc/initrd-release
4+
DefaultDependencies=no
5+
After=dracut-cmdline.service network.target nss-lookup.target
6+
Before=time-sync.target
7+
Conflicts=ntpd.service systemd-timesyncd.service
8+
Wants=network.target time-sync.target
9+
ConditionCapability=CAP_SYS_TIME
10+
11+
[Service]
12+
Type=notify
13+
PIDFile=/run/chrony/chronyd.pid
14+
Environment="OPTIONS="
15+
EnvironmentFile=-/etc/sysconfig/chronyd
16+
# The default location for chrony.conf can be set at build with the
17+
# --sysconfdir configuration option, so force /etc/chrony.conf with -f
18+
ExecStart=/usr/sbin/chronyd -f /etc/chrony.conf -n $OPTIONS
19+
20+
CapabilityBoundingSet=~CAP_AUDIT_CONTROL CAP_AUDIT_READ CAP_AUDIT_WRITE
21+
CapabilityBoundingSet=~CAP_BLOCK_SUSPEND CAP_KILL CAP_LEASE CAP_LINUX_IMMUTABLE
22+
CapabilityBoundingSet=~CAP_MAC_ADMIN CAP_MAC_OVERRIDE CAP_MKNOD CAP_SYS_ADMIN
23+
CapabilityBoundingSet=~CAP_SYS_BOOT CAP_SYS_CHROOT CAP_SYS_MODULE CAP_SYS_PACCT
24+
CapabilityBoundingSet=~CAP_SYS_PTRACE CAP_SYS_RAWIO CAP_SYS_TTY_CONFIG CAP_WAKE_ALARM
25+
DeviceAllow=char-pps rw
26+
DeviceAllow=char-ptp rw
27+
DeviceAllow=char-rtc rw
28+
DevicePolicy=closed
29+
LockPersonality=yes
30+
MemoryDenyWriteExecute=yes
31+
NoNewPrivileges=yes
32+
PrivateTmp=yes
33+
ProtectControlGroups=yes
34+
ProtectHome=yes
35+
ProtectHostname=yes
36+
ProtectKernelLogs=yes
37+
ProtectKernelModules=yes
38+
ProtectKernelTunables=yes
39+
ProtectProc=invisible
40+
ProtectSystem=strict
41+
ReadWritePaths=/run
42+
RestrictAddressFamilies=AF_INET AF_INET6 AF_UNIX
43+
RestrictNamespaces=yes
44+
RestrictSUIDSGID=yes
45+
SystemCallArchitectures=native
46+
SystemCallFilter=~@cpu-emulation @debug @module @mount @obsolete @raw-io @reboot @swap

modules.d/74chrony/module-setup.sh

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
#!/bin/bash
2+
# SPDX-License-Identifier: GPL-2.0-or-later
3+
4+
check() {
5+
require_binaries \
6+
chronyd \
7+
|| return 1
8+
9+
return 255
10+
}
11+
12+
depends() {
13+
echo systemd network
14+
return 0
15+
}
16+
17+
install() {
18+
# openSUSE/Fedora: chrony
19+
# Ubuntu: _chrony
20+
grep -s -E '^(_chrony|chrony):' "${dracutsysrootdir-}"/etc/passwd \
21+
| sed 's/\/var\/lib\/chrony/\/run\/chrony/' >> "$initdir/etc/passwd"
22+
grep -s -E '^(_chrony|chrony):' "${dracutsysrootdir-}"/etc/group >> "$initdir/etc/group"
23+
24+
inst_hook cmdline 01 "$moddir/parse-ntp.sh"
25+
inst_hook initqueue/online 01 "$moddir/chrony-ntp-source.sh"
26+
27+
inst_multiple -o \
28+
"$systemdntpunits"/50-chronyd.list \
29+
"$systemdsystemunitdir"/time-sync.target \
30+
chronyd chronyc mkdir chown
31+
32+
inst_simple "$moddir/chrony.conf" /etc/chrony.conf
33+
34+
for i in \
35+
chronyd.service \
36+
chrony-wait.service; do
37+
inst_simple "$moddir/$i" "$systemdsystemunitdir/$i"
38+
$SYSTEMCTL -q --root "$initdir" add-wants initrd.target "$i"
39+
done
40+
41+
if [[ $hostonly ]]; then
42+
local _i _directives _keyfile _source_dirs=()
43+
44+
# Install the file pointed by the "keyfile" directive, used for NTP
45+
# authentication. This directive is intended to be unique, chrony would
46+
# end up using the last one processed.
47+
readarray -t _directives < <(grep -r -h '^keyfile ' "${dracutsysrootdir-}"/etc/chrony*)
48+
if ((${#_directives[@]})); then
49+
printf "\n# Specify file containing keys for NTP authentication.\n%s\n" "${_directives[-1]}" >> "$initdir/etc/chrony.conf"
50+
_keyfile="${_directives[-1]/#keyfile /}"
51+
fi
52+
53+
# chrony allows to configure directories with .sources files using the
54+
# "sourcedir" directive, used to specify NTP sources (server, pool, and
55+
# peer directives).
56+
readarray -t _directives < <(grep -r -h '^sourcedir /etc' "${dracutsysrootdir-}"/etc/chrony*)
57+
if ((${#_directives[@]})); then
58+
printf "\n# Use NTP sources configured on the host.\n" >> "$initdir/etc/chrony.conf"
59+
for _i in "${_directives[@]}"; do
60+
echo "$_i" >> "$initdir/etc/chrony.conf"
61+
_source_dirs+=("$(echo "$_i" | sed -e 's/sourcedir //' -e 's/$/\/*.sources/')")
62+
done
63+
fi
64+
65+
# We do not want to include /etc/chrony.conf or ".conf" files specified
66+
# with "include" or "confdir" directives from the host, because they
67+
# can override "driftfile", "ntsdumpdir" or "logdir" directives,
68+
# intended to point to /run in the initrd.
69+
70+
inst_multiple -H -o "$_keyfile" "${_source_dirs[@]}" \
71+
/etc/sysconfig/chronyd \
72+
"$systemdsystemconfdir"/time-sync.target \
73+
"$systemdsystemconfdir/time-sync.target.wants/*.target"
74+
fi
75+
}

0 commit comments

Comments
 (0)