From f5ca3ea50f87477de4071cd46cdfe3bb9bfb0ddd Mon Sep 17 00:00:00 2001 From: Philip Prindeville Date: Wed, 26 Jul 2017 07:51:39 -0600 Subject: [PATCH] ntpd: use UCI to synthesize minimal conf file Borrowed code from Busybox's sysntpd. Signed-off-by: Philip Prindeville --- net/ntpd/README.md | 86 ++++++++++++++++++++++++++++++++++++++++ net/ntpd/files/ntpd.init | 64 +++++++++++++++++++++++++++++- 2 files changed, 149 insertions(+), 1 deletion(-) create mode 100644 net/ntpd/README.md diff --git a/net/ntpd/README.md b/net/ntpd/README.md new file mode 100644 index 000000000..70e11a6e3 --- /dev/null +++ b/net/ntpd/README.md @@ -0,0 +1,86 @@ +# Configuring NTPD with UCI + +## Precedent +Sysntpd is the lightweight implementation of the NTP protocol under +Busybox. It supports many (but not all) of the same parameters. + +It is configured as a `config timeserver ntp` section in `/etc/config/system`, +below. + +## Configuration + +A sample configuration looks like: + +**/etc/config/system**: + +``` +config timeserver ntp + option enabled 1 + option enable_server 1 + list server tick.udel.edu + list server tock.udel.edu + list interface eth0 + list interface eth1 + list interface eth2 +``` + +If you want to temporarily disable the service without deleting all of the +configuration state, this is done by clearing the `enabled` parameter. If +this parameter is `1` (the default), the service is enabled. + +The service can run as a stand-alone client (`enable_server 0`, the default) +or it can also operate as a server in turn to local clients, by setting this +parameter to `1`. + +The parameter(s) `server` enumerate a list of servers to be used for +reference NTP servers by the local daemon. At least one is required, +and two or more are recommended (unless you have an extremely available +local server). They should be picked to be geographically divergent, +and preferrably reachable via different network carriers to protect +against network partitions, etc. They should also be high-quality +time providers (i.e. having stable, accurate clock sources). + +The `interface` parameter enumerates the list of interfaces on which +the server is reachable (see `enable_server 1` above), and may be a +subset of all of the interfaces present on the system. For security +reasons, you may elect to only offer the service on internal networks. +If omitted, it defaults to _all_ interfaces. + +## Differences with `sysntpd` + +Busybox `sysntpd` supports configuring servers based on DHCP +provisioning (option 6, per the [DHCP and BOOTP +Parameter](https://www.iana.org/assignments/bootp-dhcp-parameters/bootp-dhcp-parameters.xhtml) +list from IANA). This functionality is enabled (in Busybox) with the +`use_dhcp` boolean parameter (default `1`), and the `dhcp_interface` +list parameter, which enumerates the interfaces whose provisioning +is to be utilized. + +### Considerations for DHCP-provisioned NTP servers + +Most terrestrial and satellite ISPs have access to very high-quality +clock sources (these are required to maintain synchronization on T3, +OC3, etc trunks or earth terminals) but seldom offer access to those +time sources via NTP in turn to their clients, mostly from a misplaced +fear that their time source might come under attack (a slave closely +tied to the master could also provide extremely high-quality time +without the risk of network desynchronization should it come under +sophisticated attack). + +As a result, the NTP servers that your ISP may point you at are +often of unknown/unverified quality, and you use them at your own +risk. + +Early millenial versions of Windows (2000, XP, etc) used NTP only +to _initially set_ the clock to approximately 100ms accuracy (and +not maintain sychronization), so the bar wasn't set very high. +Since then, requirements for higher-qualty timekeeping have +arisen (e.g. multi-master SQL database replication), but most ISPs +have not kept up with the needs of their users. + +Current releases of Windows use Domain Controllers for time +acquisition via the [NT5DS protocol](https://blogs.msdn.microsoft.com/w32time/2007/07/07/what-is-windows-time-service/) +when domain joined. + +Because of the unreliable quality of NTP servers DHCP-provisioned by +ISPs, support for this functionality was deemed unnecessary. diff --git a/net/ntpd/files/ntpd.init b/net/ntpd/files/ntpd.init index 55dd3e84f..0ed663750 100644 --- a/net/ntpd/files/ntpd.init +++ b/net/ntpd/files/ntpd.init @@ -8,12 +8,74 @@ USE_PROCD=1 PROG=/sbin/ntpd HOTPLUG_HELPER=/usr/sbin/ntpd.hotplug-helper +config_file=/var/run/ntpd.conf + +trunc() { + echo -n "" > $config_file +} + +emit() { + echo -e "$@" >> $config_file +} + +validate_ntp_section() { + uci_validate_section system timeserver "${1}" \ + 'server:list(host)' 'enabled:bool:1' 'enable_server:bool:0' \ + 'interface:list(string)' +} + start_service() { + local server enabled enable_server interface intf + + validate_ntp_section ntp || { + echo "validation failed" + return 1 + } + + [ "$enabled" = 0 ] && return + + [ -z "$server" -a "$enable_server" = 0 ] && return + + # not sure that the interfaces enumerated should be validated, + # since some of them might be dynamic interfaces (like IPsec + # tunnels) which aren't known by ubus. + + trunc + emit "driftfile /var/lib/ntp/ntp.drift\n" + + if [ "$enable_server" != 0 ]; then + emit "restrict default limited kod nomodify notrap nopeer" + emit "restrict -6 default limited kod nomodify notrap nopeer" + else + emit "restrict -4 default noserve" + emit "restrict -6 default noserve" + fi + emit "restrict source noquery" + + emit "\n# No limits for local monitoring" + emit "restrict 127.0.0.1" + emit "restrict -6 ::1\n" + + if [ -n "$interface" ]; then + local loopback=$(ubus call network.interface dump | jsonfilter -e "@.interface[@.interface='loopback']['device']") + + local saw_lo= + for intf in $interface; do + emit "interface listen $intf" + [ "$intf" = "$loopback" ] && saw_lo=1 + done + [ -z "$saw_lo" ] && emit "interface listen $loopback" + emit "" + fi + + emit "server $server iburst" + mkdir -p /var/lib/ntp chown -R ntp:ntp /var/lib/ntp procd_open_instance - procd_set_param command $PROG -g -u ntp:ntp -p /var/run/ntpd.pid -n + procd_set_param command $PROG -g -u ntp:ntp -p /var/run/ntpd.pid -n \ + -c $config_file procd_close_instance procd_open_instance