extend chrony-helper to allow using servers from DNS SRV records (#1234406)
This commit is contained in:
parent
6861b98b52
commit
7715352a8a
8
chrony-dnssrv@.service
Normal file
8
chrony-dnssrv@.service
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
[Unit]
|
||||||
|
Description=DNS SRV lookup of %I for chrony
|
||||||
|
After=chronyd.service network-online.target
|
||||||
|
Wants=network-online.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=oneshot
|
||||||
|
ExecStart=/usr/libexec/chrony-helper update-dnssrv-servers %I
|
9
chrony-dnssrv@.timer
Normal file
9
chrony-dnssrv@.timer
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
[Unit]
|
||||||
|
Description=Periodic DNS SRV lookup of %I for chrony
|
||||||
|
|
||||||
|
[Timer]
|
||||||
|
OnActiveSec=0
|
||||||
|
OnUnitInactiveSec=1h
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=timers.target
|
@ -5,7 +5,7 @@ diff -up chrony-1.31/examples/chronyd.service.service-helper chrony-1.31/example
|
|||||||
PIDFile=/var/run/chronyd.pid
|
PIDFile=/var/run/chronyd.pid
|
||||||
EnvironmentFile=-/etc/sysconfig/chronyd
|
EnvironmentFile=-/etc/sysconfig/chronyd
|
||||||
ExecStart=/usr/sbin/chronyd $OPTIONS
|
ExecStart=/usr/sbin/chronyd $OPTIONS
|
||||||
+ExecStartPost=/usr/libexec/chrony-helper add-dhclient-servers
|
+ExecStartPost=/usr/libexec/chrony-helper update-daemon
|
||||||
|
|
||||||
[Install]
|
[Install]
|
||||||
WantedBy=multi-user.target
|
WantedBy=multi-user.target
|
||||||
|
@ -8,16 +8,13 @@ chrony_config() {
|
|||||||
for server in $new_ntp_servers; do
|
for server in $new_ntp_servers; do
|
||||||
echo "$server ${NTPSERVERARGS:-iburst}" >> $SERVERFILE
|
echo "$server ${NTPSERVERARGS:-iburst}" >> $SERVERFILE
|
||||||
done
|
done
|
||||||
/usr/libexec/chrony-helper is-running &&
|
/usr/libexec/chrony-helper update-daemon || :
|
||||||
/usr/libexec/chrony-helper add-dhclient-servers &&
|
|
||||||
/usr/libexec/chrony-helper remove-dhclient-servers || :
|
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
chrony_restore() {
|
chrony_restore() {
|
||||||
if [ -f $SERVERFILE ]; then
|
if [ -f $SERVERFILE ]; then
|
||||||
rm -f $SERVERFILE
|
rm -f $SERVERFILE
|
||||||
/usr/libexec/chrony-helper is-running &&
|
/usr/libexec/chrony-helper update-daemon || :
|
||||||
/usr/libexec/chrony-helper remove-dhclient-servers || :
|
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
208
chrony.helper
208
chrony.helper
@ -1,62 +1,176 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
# This script configures running chronyd to use NTP servers obtained from
|
||||||
|
# DHCP and _ntp._udp DNS SRV records. Files with servers from DHCP are managed
|
||||||
|
# externally (e.g. by a dhclient script). Files with servers from DNS SRV
|
||||||
|
# records are updated here using the dig utility.
|
||||||
|
|
||||||
chronyc=/usr/bin/chronyc
|
chronyc=/usr/bin/chronyc
|
||||||
dhclient_servers=/var/lib/dhclient/chrony.servers.*
|
helper_dir=/var/run/chrony-helper
|
||||||
dhclient_added_servers=/var/lib/dhclient/chrony.added_servers
|
added_servers_file=$helper_dir/added_servers
|
||||||
|
|
||||||
|
network_sysconfig_file=/etc/sysconfig/network
|
||||||
|
dhclient_servers_files=/var/lib/dhclient/chrony.servers.*
|
||||||
|
dnssrv_servers_files=$helper_dir/dnssrv@*
|
||||||
|
dnssrv_timer_prefix=chrony-dnssrv@
|
||||||
|
|
||||||
chrony_command() {
|
chrony_command() {
|
||||||
$chronyc -a -n -m "$1"
|
$chronyc -a -n -m "$1"
|
||||||
}
|
}
|
||||||
|
|
||||||
update_dhclient_added_servers() {
|
|
||||||
new_servers=$(echo "$1" | sort -u)
|
|
||||||
old_servers=$(cat $dhclient_added_servers 2> /dev/null)
|
|
||||||
[ "$old_servers" = "$new_servers" ] && return 0
|
|
||||||
[ -n "$new_servers" ] && echo "$new_servers" > $dhclient_added_servers ||
|
|
||||||
rm -f $dhclient_added_servers
|
|
||||||
}
|
|
||||||
|
|
||||||
add_dhclient_servers() {
|
|
||||||
shopt -s nullglob
|
|
||||||
servers_files=($dhclient_servers)
|
|
||||||
shopt -u nullglob
|
|
||||||
(( ${#servers_files[*]} )) || return 0
|
|
||||||
|
|
||||||
added_servers=$(
|
|
||||||
cat $dhclient_added_servers 2> /dev/null
|
|
||||||
cat ${servers_files[*]} |
|
|
||||||
while read server serverargs; do
|
|
||||||
chrony_command "add server $server $serverargs" &> /dev/null &&
|
|
||||||
echo "$server"
|
|
||||||
done)
|
|
||||||
update_dhclient_added_servers "$added_servers"
|
|
||||||
}
|
|
||||||
|
|
||||||
remove_dhclient_servers() {
|
|
||||||
[ -f $dhclient_added_servers ] || return 0
|
|
||||||
all_servers=$(
|
|
||||||
cat $dhclient_servers 2> /dev/null |
|
|
||||||
while read server serverargs; do
|
|
||||||
echo "$server"
|
|
||||||
done | sort -u)
|
|
||||||
echo "$all_servers" | comm -23 $dhclient_added_servers - |
|
|
||||||
while read server; do
|
|
||||||
chrony_command "delete $server" &> /dev/null
|
|
||||||
done
|
|
||||||
added_servers=$(echo "$all_servers" | comm -12 $dhclient_added_servers -)
|
|
||||||
update_dhclient_added_servers "$added_servers"
|
|
||||||
}
|
|
||||||
|
|
||||||
is_running() {
|
is_running() {
|
||||||
chrony_command "tracking" &> /dev/null
|
chrony_command "tracking" &> /dev/null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
is_update_needed() {
|
||||||
|
for file in $dhclient_servers_files $dnssrv_servers_files \
|
||||||
|
$added_servers_file; do
|
||||||
|
[ -e "$file" ] && return 0
|
||||||
|
done
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
update_daemon() {
|
||||||
|
local all_servers_with_args all_servers added_servers
|
||||||
|
|
||||||
|
if ! is_running; then
|
||||||
|
rm -f $added_servers_file
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
all_servers_with_args=$(
|
||||||
|
cat $dhclient_servers_files $dnssrv_servers_files 2> /dev/null)
|
||||||
|
|
||||||
|
all_servers=$(
|
||||||
|
echo "$all_servers_with_args" |
|
||||||
|
while read server serverargs; do
|
||||||
|
echo "$server"
|
||||||
|
done | sort -u)
|
||||||
|
added_servers=$( (
|
||||||
|
cat $added_servers_file 2> /dev/null
|
||||||
|
echo "$all_servers_with_args" |
|
||||||
|
while read server serverargs; do
|
||||||
|
[ -z "$server" ] && continue
|
||||||
|
chrony_command "add server $server $serverargs" &> /dev/null &&
|
||||||
|
echo "$server"
|
||||||
|
done) | sort -u)
|
||||||
|
|
||||||
|
comm -23 <(echo -n "$added_servers") <(echo -n "$all_servers") |
|
||||||
|
while read server; do
|
||||||
|
chrony_command "delete $server" &> /dev/null
|
||||||
|
done
|
||||||
|
|
||||||
|
added_servers=$(comm -12 <(echo -n "$added_servers") <(echo -n "$all_servers"))
|
||||||
|
|
||||||
|
[ -n "$added_servers" ] && echo "$added_servers" > $added_servers_file ||
|
||||||
|
rm -f $added_servers_file
|
||||||
|
}
|
||||||
|
|
||||||
|
get_dnssrv_servers() {
|
||||||
|
local name=$1
|
||||||
|
|
||||||
|
if ! command -v dig &> /dev/null; then
|
||||||
|
echo "Missing dig (DNS lookup utility)" >&2
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
(
|
||||||
|
. $network_sysconfig_file &> /dev/null
|
||||||
|
|
||||||
|
output=$(dig "$name" srv +short +ndots=2 +search 2> /dev/null)
|
||||||
|
[ $? -ne 0 ] && return 0
|
||||||
|
|
||||||
|
echo "$output" | while read prio weight port target; do
|
||||||
|
server=${target%.}
|
||||||
|
[ -z "$server" ] && continue
|
||||||
|
echo "$server port $port ${NTPSERVERARGS:-iburst}"
|
||||||
|
done
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
check_dnssrv_name() {
|
||||||
|
local name=$1
|
||||||
|
|
||||||
|
if [ -z "$name" ]; then
|
||||||
|
echo "No DNS SRV name specified" >&2
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "${name:0:9}" != _ntp._udp ]; then
|
||||||
|
echo "DNS SRV name $name doesn't start with _ntp._udp" >&2
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
update_dnssrv_servers() {
|
||||||
|
local name=$1
|
||||||
|
local srv_file=$helper_dir/dnssrv@$name servers
|
||||||
|
|
||||||
|
check_dnssrv_name "$name" || return 1
|
||||||
|
|
||||||
|
servers=$(get_dnssrv_servers "$name")
|
||||||
|
[ -n "$servers" ] && echo "$servers" > "$srv_file" || rm -f "$srv_file"
|
||||||
|
}
|
||||||
|
|
||||||
|
set_dnssrv_timer() {
|
||||||
|
local state=$1 name=$2
|
||||||
|
local srv_file=$helper_dir/dnssrv@$name servers
|
||||||
|
local timer=$dnssrv_timer_prefix$name.timer
|
||||||
|
|
||||||
|
check_dnssrv_name "$name" || return 1
|
||||||
|
|
||||||
|
if [ "$state" = enable ]; then
|
||||||
|
systemctl enable "$timer"
|
||||||
|
systemctl start "$timer"
|
||||||
|
elif [ "$state" = disable ]; then
|
||||||
|
systemctl stop "$timer"
|
||||||
|
systemctl disable "$timer"
|
||||||
|
rm -f "$srv_file"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
list_dnssrv_timers() {
|
||||||
|
systemctl --all --full -t timer list-units | grep "^$dnssrv_timer_prefix" | \
|
||||||
|
sed "s|^$dnssrv_timer_prefix\(.*\)\.timer.*|\1|"
|
||||||
|
}
|
||||||
|
|
||||||
|
prepare_helper_dir() {
|
||||||
|
mkdir -p $helper_dir
|
||||||
|
exec 100> $helper_dir/lock
|
||||||
|
if ! flock -w 20 100; then
|
||||||
|
echo "Failed to lock $helper_dir" >&2
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
print_help() {
|
||||||
|
echo "Usage: $0 COMMAND"
|
||||||
|
echo
|
||||||
|
echo "Commands:"
|
||||||
|
echo " update-daemon"
|
||||||
|
echo " update-dnssrv-servers NAME"
|
||||||
|
echo " enable-dnssrv NAME"
|
||||||
|
echo " disable-dnssrv NAME"
|
||||||
|
echo " list-dnssrv"
|
||||||
|
echo " is-running"
|
||||||
|
echo " command CHRONYC-COMMAND"
|
||||||
|
}
|
||||||
|
|
||||||
case "$1" in
|
case "$1" in
|
||||||
add-dhclient-servers)
|
update-daemon|add-dhclient-servers|remove-dhclient-servers)
|
||||||
add_dhclient_servers
|
is_update_needed || exit 0
|
||||||
|
prepare_helper_dir && update_daemon
|
||||||
;;
|
;;
|
||||||
remove-dhclient-servers)
|
update-dnssrv-servers)
|
||||||
remove_dhclient_servers
|
prepare_helper_dir && update_dnssrv_servers "$2" && update_daemon
|
||||||
|
;;
|
||||||
|
enable-dnssrv)
|
||||||
|
set_dnssrv_timer enable "$2"
|
||||||
|
;;
|
||||||
|
disable-dnssrv)
|
||||||
|
set_dnssrv_timer disable "$2" && prepare_helper_dir && update_daemon
|
||||||
|
;;
|
||||||
|
list-dnssrv)
|
||||||
|
list_dnssrv_timers
|
||||||
;;
|
;;
|
||||||
is-running)
|
is-running)
|
||||||
is_running
|
is_running
|
||||||
@ -65,8 +179,8 @@ case "$1" in
|
|||||||
chrony_command "$2"
|
chrony_command "$2"
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
echo $"Usage: $0 {add-dhclient-servers|remove-dhclient-servers|is-running|command|forced-command}"
|
print_help
|
||||||
exit 2
|
exit 2
|
||||||
esac
|
esac
|
||||||
exit $?
|
|
||||||
|
|
||||||
|
exit $?
|
||||||
|
@ -13,6 +13,8 @@ URL: http://chrony.tuxfamily.org
|
|||||||
Source0: http://download.tuxfamily.org/chrony/chrony-%{version}%{?prerelease}.tar.gz
|
Source0: http://download.tuxfamily.org/chrony/chrony-%{version}%{?prerelease}.tar.gz
|
||||||
Source1: chrony.dhclient
|
Source1: chrony.dhclient
|
||||||
Source2: chrony.helper
|
Source2: chrony.helper
|
||||||
|
Source3: chrony-dnssrv@.service
|
||||||
|
Source4: chrony-dnssrv@.timer
|
||||||
# simulator for test suite
|
# simulator for test suite
|
||||||
Source10: https://github.com/mlichvar/clknetsim/archive/%{clknetsim_ver}/clknetsim-%{clknetsim_ver}.tar.gz
|
Source10: https://github.com/mlichvar/clknetsim/archive/%{clknetsim_ver}/clknetsim-%{clknetsim_ver}.tar.gz
|
||||||
%{?gitpatch:Patch0: chrony-%{version}%{?prerelease}-%{gitpatch}.patch.gz}
|
%{?gitpatch:Patch0: chrony-%{version}%{?prerelease}-%{gitpatch}.patch.gz}
|
||||||
@ -58,7 +60,7 @@ md5sum -c <<-EOF | (! grep -v 'OK$')
|
|||||||
3a5a49a9fdc344cd31893571215c2c74 examples/chrony.conf.example2
|
3a5a49a9fdc344cd31893571215c2c74 examples/chrony.conf.example2
|
||||||
2e9fe409a17de5d53a65f9869c4119f5 examples/chrony.logrotate
|
2e9fe409a17de5d53a65f9869c4119f5 examples/chrony.logrotate
|
||||||
d7d323d0ea7ccc258710371ea79563d1 examples/chrony.nm-dispatcher
|
d7d323d0ea7ccc258710371ea79563d1 examples/chrony.nm-dispatcher
|
||||||
1a5122f7f40446596777a6c69431c415 examples/chronyd.service
|
d65acc66bd53844a6fe72b62dfae42bd examples/chronyd.service
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
# use our vendor zone (2.*pool.ntp.org names include IPv6 addresses)
|
# use our vendor zone (2.*pool.ntp.org names include IPv6 addresses)
|
||||||
@ -108,6 +110,8 @@ install -m 644 -p examples/chronyd.service \
|
|||||||
$RPM_BUILD_ROOT%{_unitdir}/chronyd.service
|
$RPM_BUILD_ROOT%{_unitdir}/chronyd.service
|
||||||
install -m 644 -p examples/chrony-wait.service \
|
install -m 644 -p examples/chrony-wait.service \
|
||||||
$RPM_BUILD_ROOT%{_unitdir}/chrony-wait.service
|
$RPM_BUILD_ROOT%{_unitdir}/chrony-wait.service
|
||||||
|
install -m 644 -p %{SOURCE3} $RPM_BUILD_ROOT%{_unitdir}/chrony-dnssrv@.service
|
||||||
|
install -m 644 -p %{SOURCE4} $RPM_BUILD_ROOT%{_unitdir}/chrony-dnssrv@.timer
|
||||||
|
|
||||||
install -m 755 -p %{SOURCE2} $RPM_BUILD_ROOT%{_libexecdir}/chrony-helper
|
install -m 755 -p %{SOURCE2} $RPM_BUILD_ROOT%{_libexecdir}/chrony-helper
|
||||||
|
|
||||||
@ -161,6 +165,7 @@ fi
|
|||||||
%{_infodir}/chrony.info*
|
%{_infodir}/chrony.info*
|
||||||
%{_prefix}/lib/systemd/ntp-units.d/*.list
|
%{_prefix}/lib/systemd/ntp-units.d/*.list
|
||||||
%{_unitdir}/chrony*.service
|
%{_unitdir}/chrony*.service
|
||||||
|
%{_unitdir}/chrony*.timer
|
||||||
%{_mandir}/man[158]/%{name}*.[158]*
|
%{_mandir}/man[158]/%{name}*.[158]*
|
||||||
%dir %attr(-,chrony,chrony) %{_localstatedir}/lib/chrony
|
%dir %attr(-,chrony,chrony) %{_localstatedir}/lib/chrony
|
||||||
%ghost %attr(-,chrony,chrony) %{_localstatedir}/lib/chrony/drift
|
%ghost %attr(-,chrony,chrony) %{_localstatedir}/lib/chrony/drift
|
||||||
|
Loading…
Reference in New Issue
Block a user