From 46c61d1fefe21b2f611e8cc2073e71a185c21011 Mon Sep 17 00:00:00 2001 From: Yevhen Fastiuk Date: Wed, 22 Feb 2023 19:50:11 +0200 Subject: [PATCH 01/21] Add NTP YANG model Signed-off-by: Yevhen Fastiuk --- .../yang-models/sonic-ntp.yang | 147 ++++++++++++++++++ .../yang-templates/sonic-types.yang.j2 | 16 ++ 2 files changed, 163 insertions(+) diff --git a/src/sonic-yang-models/yang-models/sonic-ntp.yang b/src/sonic-yang-models/yang-models/sonic-ntp.yang index f28e1052096a..2624e27c58f2 100644 --- a/src/sonic-yang-models/yang-models/sonic-ntp.yang +++ b/src/sonic-yang-models/yang-models/sonic-ntp.yang @@ -33,6 +33,10 @@ module sonic-ntp { prefix mprt; } + import sonic-types { + prefix stypes; + } + description "NTP yang Module for SONiC OS"; @@ -41,6 +45,39 @@ module sonic-ntp { "First revision"; } + revision 2023-03-20 { + description + "Add extended configuration options"; + } + + typedef association-type { + description "NTP server association type"; + type enumeration { + enum server; + enum pool; + } + } + + typedef key-type { + description "NTP key encryption type"; + type enumeration { + enum md5; + enum sha1; + enum sha256; + enum sha384; + enum sha512; + } + } + + typedef key-id { + description "NTP key ID"; + type uint16 { + range 1..65535 { + error-message "Failed NTP key ID"; + } + } + } + container sonic-ntp { container NTP { @@ -92,6 +129,30 @@ module sonic-ntp { default VRF or Management VRF."; } + leaf authentication { + type stypes:admin_mode; + default disabled; + description "NTP authentication state"; + } + + leaf dhcp { + type stypes:admin_mode; + default enabled; + description "Use NTP servers distributed by DHCP"; + } + + leaf server_role { + type stypes:admin_mode; + default enabled; + description "NTP server functionality state"; + } + + leaf admin_state { + type stypes:admin_mode; + default enabled; + description "NTP feature state"; + } + } /* end of container global */ } /* end of container NTP */ @@ -112,10 +173,96 @@ module sonic-ntp { leaf server_address { type inet:host; } + + leaf association_type { + type association-type; + default server; + description "NTP remote association type. Server, pool, or + peer."; + } + + leaf iburst { + type stypes:on-off; + default on; + description "NTP aggressive polling"; + } + + leaf key { + description "NTP server key ID"; + type leafref { + path /ntp:sonic-ntp/ntp:NTP_KEY/ntp:NTP_KEYS_LIST/ntp:id; + } + } + + leaf resolve_as { + type inet:host; + description "Server resolved IP address"; + } + + leaf admin_state { + type stypes:admin_mode; + default enabled; + description "NTP server state"; + } + + leaf trusted { + type stypes:yes-no; + default no; + description "Trust this server. It will force time + synchronization only to this server when + authentication is enabled"; + } + + leaf version { + type uint8 { + range "3..4" { + error-message "Failed NTP version"; + } + } + default 4; + description "NTP proto version to communicate with NTP + server"; + } + } /* end of list NTP_SERVER_LIST */ } /* end of container NTP_SERVER */ + container NTP_KEY { + + description "NTP authentication keys inventory"; + + list NTP_KEYS_LIST { + description "NTP authentication keys inventory"; + key "id"; + + leaf id { + type key-id; + description "NTP key ID"; + } + + leaf trusted { + type stypes:yes-no; + default no; + description "Trust this NTP key"; + } + + leaf value { + type string { + length 1..64; + } + description "NTP encrypted authentication key"; + } + + leaf type { + type key-type; + default md5; + description "NTP authentication key type"; + } + } /* end of list NTP_KEYS_LIST */ + + } /* end of container NTP_KEY */ + } /* end of container sonic-ntp */ } /* end of module sonic-ntp */ diff --git a/src/sonic-yang-models/yang-templates/sonic-types.yang.j2 b/src/sonic-yang-models/yang-templates/sonic-types.yang.j2 index 4a81da6ed31d..c767ef2cb1e2 100644 --- a/src/sonic-yang-models/yang-templates/sonic-types.yang.j2 +++ b/src/sonic-yang-models/yang-templates/sonic-types.yang.j2 @@ -347,6 +347,22 @@ module sonic-types { "BCP 175: Procedures for Maintaining the Time Zone Database"; } + typedef yes-no { + description "Yes/No configuration"; + type enumeration { + enum yes; + enum no; + } + } + + typedef on-off { + description "On/Off configuration"; + type enumeration { + enum on; + enum off; + } + } + {% if yang_model_type == "cvl" %} /* Required for CVL */ container operation { From e0fa6a7f9fb8d36e5d0e7cd6bd5572fe105f4445 Mon Sep 17 00:00:00 2001 From: Yevhen Fastiuk Date: Wed, 22 Feb 2023 19:49:21 +0200 Subject: [PATCH 02/21] Extend NTP config generation mechanism Signed-off-by: Yevhen Fastiuk --- files/build_templates/init_cfg.json.j2 | 9 ++ .../build_templates/sonic_debian_extension.j2 | 1 + files/image_config/ntp/ntp | 100 ------------- files/image_config/ntp/ntp-config.sh | 3 + files/image_config/ntp/ntp-systemd-wrapper | 17 ++- files/image_config/ntp/ntp.conf.j2 | 132 +++++++++++------- files/image_config/ntp/ntp.keys.j2 | 17 +++ 7 files changed, 128 insertions(+), 151 deletions(-) delete mode 100755 files/image_config/ntp/ntp create mode 100644 files/image_config/ntp/ntp.keys.j2 diff --git a/files/build_templates/init_cfg.json.j2 b/files/build_templates/init_cfg.json.j2 index 827eca04d695..6f208a6f83f9 100644 --- a/files/build_templates/init_cfg.json.j2 +++ b/files/build_templates/init_cfg.json.j2 @@ -145,5 +145,14 @@ {% endif %} } {% endif %} + }, + "NTP": { + "global": { + "authentication": "disabled", + "dhcp": "enabled", + "server_role": "disabled", + "admin_state": "enabled", + "vrf": "default" + } } } diff --git a/files/build_templates/sonic_debian_extension.j2 b/files/build_templates/sonic_debian_extension.j2 index 2849437ad8d8..9fd22636f961 100644 --- a/files/build_templates/sonic_debian_extension.j2 +++ b/files/build_templates/sonic_debian_extension.j2 @@ -369,6 +369,7 @@ sudo cp $IMAGE_CONFIGS/ntp/ntp-config.service $FILESYSTEM_ROOT_USR_LIB_SYSTEMD_S echo "ntp-config.service" | sudo tee -a $GENERATED_SERVICE_FILE sudo cp $IMAGE_CONFIGS/ntp/ntp-config.sh $FILESYSTEM_ROOT/usr/bin/ sudo cp $IMAGE_CONFIGS/ntp/ntp.conf.j2 $FILESYSTEM_ROOT_USR_SHARE_SONIC_TEMPLATES/ +sudo cp $IMAGE_CONFIGS/ntp/ntp.keys.j2 $FILESYSTEM_ROOT_USR_SHARE_SONIC_TEMPLATES/ sudo cp $IMAGE_CONFIGS/ntp/ntp-systemd-wrapper $FILESYSTEM_ROOT/usr/lib/ntp/ sudo cp $IMAGE_CONFIGS/ntp/ntp.service $FILESYSTEM_ROOT_USR_LIB_SYSTEMD_SYSTEM echo "ntp.service" | sudo tee -a $GENERATED_SERVICE_FILE diff --git a/files/image_config/ntp/ntp b/files/image_config/ntp/ntp deleted file mode 100755 index f0ca500fb8f3..000000000000 --- a/files/image_config/ntp/ntp +++ /dev/null @@ -1,100 +0,0 @@ -#!/bin/sh - -# This file was originally created automatically as part of default NTP application installation from debian package. -# This is now manually modified for supporting NTP in management VRF. -# When management VRF is enabled, the NTP application should be started using "cgexec -g l3mdev:mgmt". -# Check has been added to verify the management VRF enabled status and use cgexec when it is enabled. -# This file will be copied on top of the etc/init.d/ntp file that gets created during build process. - -### BEGIN INIT INFO -# Provides: ntp -# Required-Start: $network $remote_fs $syslog -# Required-Stop: $network $remote_fs $syslog -# Default-Start: 2 3 4 5 -# Default-Stop: -# Short-Description: Start NTP daemon -### END INIT INFO - -PATH=/sbin:/bin:/usr/sbin:/usr/bin - -. /lib/lsb/init-functions - -DAEMON=/usr/sbin/ntpd -PIDFILE=/var/run/ntpd.pid - -test -x $DAEMON || exit 5 - -if [ -r /etc/default/ntp ]; then - . /etc/default/ntp -fi - -if [ -e /run/ntp.conf.dhcp ]; then - NTPD_OPTS="$NTPD_OPTS -c /run/ntp.conf.dhcp" -fi - - -LOCKFILE=/run/lock/ntpdate - -RUNASUSER=ntp -UGID=$(getent passwd $RUNASUSER | cut -f 3,4 -d:) || true -if test "$(uname -s)" = "Linux"; then - NTPD_OPTS="$NTPD_OPTS -u $UGID" -fi - -case $1 in - start) - log_daemon_msg "Starting NTP server" "ntpd" - if [ -z "$UGID" ]; then - log_failure_msg "user \"$RUNASUSER\" does not exist" - exit 1 - fi - ( - flock -w 180 9 - - # when mgmt vrf is configured, ntp starts in mgmt vrf by default unless user configures otherwise - vrfEnabled=$(/usr/local/bin/sonic-cfggen -d -v 'MGMT_VRF_CONFIG["vrf_global"]["mgmtVrfEnabled"]' 2> /dev/null) - vrfConfigured=$(/usr/local/bin/sonic-cfggen -d -v 'NTP["global"]["vrf"]' 2> /dev/null) - if [ "$vrfEnabled" = "true" ] - then - if [ "$vrfConfigured" = "default" ] - then - log_daemon_msg "Starting NTP server in default-vrf for default set as NTP vrf" "ntpd" - start-stop-daemon --start --quiet --oknodo --pidfile $PIDFILE --startas $DAEMON -- -p $PIDFILE $NTPD_OPTS - else - log_daemon_msg "Starting NTP server in mgmt-vrf" "ntpd" - cgexec -g l3mdev:mgmt start-stop-daemon --start --quiet --oknodo --pidfile $PIDFILE --startas $DAEMON -- -p $PIDFILE $NTPD_OPTS - fi - else - log_daemon_msg "Starting NTP server in default-vrf" "ntpd" - start-stop-daemon --start --quiet --oknodo --pidfile $PIDFILE --startas $DAEMON -- -p $PIDFILE $NTPD_OPTS - fi - ) 9>$LOCKFILE - log_end_msg $? - ;; - stop) - log_daemon_msg "Stopping NTP server" "ntpd" - start-stop-daemon --stop --quiet --oknodo --pidfile $PIDFILE --retry=TERM/30/KILL/5 --exec $DAEMON - log_end_msg $? - rm -f $PIDFILE - ;; - restart|force-reload) - $0 stop && sleep 2 && $0 start - ;; - try-restart) - if $0 status >/dev/null; then - $0 restart - else - exit 0 - fi - ;; - reload) - exit 3 - ;; - status) - status_of_proc $DAEMON "NTP server" - ;; - *) - echo "Usage: $0 {start|stop|restart|try-restart|force-reload|status}" - exit 2 - ;; -esac diff --git a/files/image_config/ntp/ntp-config.sh b/files/image_config/ntp/ntp-config.sh index ace9ad1c8a42..b15b7c39d573 100755 --- a/files/image_config/ntp/ntp-config.sh +++ b/files/image_config/ntp/ntp-config.sh @@ -24,6 +24,9 @@ function modify_ntp_default } sonic-cfggen -d -t /usr/share/sonic/templates/ntp.conf.j2 >/etc/ntp.conf +sonic-cfggen -d -t /usr/share/sonic/templates/ntp.keys.j2 >/etc/ntp.keys + +chown ntp:ntp /etc/ntp.keys get_database_reboot_type echo "Disabling NTP long jump for reboot type ${reboot_type} ..." diff --git a/files/image_config/ntp/ntp-systemd-wrapper b/files/image_config/ntp/ntp-systemd-wrapper index 1e646f39369d..b1e027b9cd5d 100644 --- a/files/image_config/ntp/ntp-systemd-wrapper +++ b/files/image_config/ntp/ntp-systemd-wrapper @@ -13,7 +13,8 @@ if [ -r /etc/default/ntp ]; then . /etc/default/ntp fi -if [ -e /run/ntp.conf.dhcp ]; then +dhcp=$(/usr/local/bin/sonic-cfggen -d -v 'NTP["global"]["dhcp"]' 2> /dev/null) +if [ -e /run/ntp.conf.dhcp ] && [ "$dhcp" = "enabled" ]; then NTPD_OPTS="$NTPD_OPTS -c /run/ntp.conf.dhcp" fi @@ -27,6 +28,14 @@ fi ( flock -w 180 9 + ntpEnabled=$(/usr/local/bin/sonic-cfggen -d -v 'NTP["global"]["admin_state"]' 2> /dev/null) + if [ "$ntpEnabled" = "disabled" ] + then + logger -p INFO -t "ntpd" "Stopping NTP daemon" + start-stop-daemon --stop --quiet --oknodo --pidfile $PIDFILE + exit 0 + fi + # when mgmt vrf is configured, ntp starts in mgmt vrf by default unless user configures otherwise vrfEnabled=$(/usr/local/bin/sonic-cfggen -d -v 'MGMT_VRF_CONFIG["vrf_global"]["mgmtVrfEnabled"]' 2> /dev/null) vrfConfigured=$(/usr/local/bin/sonic-cfggen -d -v 'NTP["global"]["vrf"]' 2> /dev/null) @@ -34,14 +43,14 @@ fi then if [ "$vrfConfigured" = "default" ] then - log_daemon_msg "Starting NTP server in default-vrf for default set as NTP vrf" "ntpd" + logger -p INFO -t "ntpd" "Starting NTP server in default-vrf for default set as NTP vrf" "ntpd" start-stop-daemon --start --quiet --oknodo --pidfile $PIDFILE --startas $DAEMON -- -p $PIDFILE $NTPD_OPTS else - log_daemon_msg "Starting NTP server in mgmt-vrf" "ntpd" + logger -p INFO -t "ntpd" "Starting NTP server in mgmt-vrf" ip vrf exec mgmt start-stop-daemon --start --quiet --oknodo --pidfile $PIDFILE --startas $DAEMON -- -p $PIDFILE $NTPD_OPTS fi else - log_daemon_msg "Starting NTP server in default-vrf" "ntpd" + logger -p INFO -t "ntpd" "Starting NTP server in default-vrf" start-stop-daemon --start --quiet --oknodo --pidfile $PIDFILE --startas $DAEMON -- -p $PIDFILE $NTPD_OPTS fi ) 9>$LOCKFILE diff --git a/files/image_config/ntp/ntp.conf.j2 b/files/image_config/ntp/ntp.conf.j2 index 280b46a426d8..d2b11827e3ed 100644 --- a/files/image_config/ntp/ntp.conf.j2 +++ b/files/image_config/ntp/ntp.conf.j2 @@ -1,45 +1,91 @@ ############################################################################### -# Managed by Ansible -# file: ansible/roles/acs/templates/ntp.conf.j2 +# This file was AUTOMATICALLY GENERATED. DO NOT MODIFY. +# Controlled by ntp-config.service ############################################################################### -# /etc/ntp.conf, configuration for ntpd; see ntp.conf(5) for help - # To avoid ntpd from panic and exit if the drift between new time and # current system time is large. tinker panic 0 driftfile /var/lib/ntp/ntp.drift - -# Enable this if you want statistics to be logged. -#statsdir /var/log/ntpstats/ - statistics loopstats peerstats clockstats filegen loopstats file loopstats type day enable filegen peerstats file peerstats type day enable filegen clockstats file clockstats type day enable +{# Getting NTP global configuration -#} +{% set global = (NTP | d({})).get('global', {}) -%} + +{# Adding NTP servers. We need to know if we have some pools, to set proper +config -#} +{% set is_pools = False %} +{% for server in NTP_SERVER if NTP_SERVER[server].admin_state != 'disabled' and + NTP_SERVER[server].resolve_as and + NTP_SERVER[server].association_type -%} + {% set config = NTP_SERVER[server] -%} + {# Server options -#} + {% set soptions = '' -%} + {# Server access control options -#} + {% set aoptions = '' -%} + + {# Authentication key -#} + {% if config.key -%} + {% set soptions = soptions ~ ' key ' ~ config.key -%} + {% endif -%} + + {# Aggressive polling -#} + {% if config.iburst -%} + {% set soptions = soptions ~ ' iburst' -%} + {% endif -%} + + {# Protocol version -#} + {% if config.version -%} + {% set soptions = soptions ~ ' version ' ~ config.version -%} + {% endif -%} + + {# Check if there are any pool configured. BTW it doesn't matter what was + configured as "resolve_as" for pools. If they were configured with FQDN they + must remain like that -#} + {% set config_as = config.resolve_as -%} + {% if config.association_type == 'pool' -%} + {% set is_pools = True -%} + {% set config_as = server -%} + {% else -%} + {% set aoptions = aoptions ~ ' nopeer' -%} + {% endif -%} + +{{ config.association_type }} {{ config_as }}{{ soptions }} +{% if global.server_role == 'disabled' %} +restrict {{ config_as }} kod nomodify notrap noquery{{ aoptions }} +{% endif %} -# You do need to talk to an NTP server or two (or three). -#server ntp.your-provider.example +{% endfor -%} -# pool.ntp.org maps to about 1000 low-stratum NTP servers. Your server will -# pick a different set every time it starts up. Please consider joining the -# pool: -{% for ntp_server in NTP_SERVER %} -server {{ ntp_server }} iburst +{% set trusted_keys_arr = [] -%} +{% for key in NTP_KEY -%} + {% set keydata = NTP_KEY[key] -%} + {% if keydata.trusted == 'yes' -%} + {% set trusted_keys_arr = trusted_keys_arr.append(key) -%} + {% endif -%} {% endfor %} -#listen on source interface if configured, else -#only listen on MGMT_INTERFACE, LOOPBACK_INTERFACE ip when MGMT_INTERFACE is not defined, or eth0 -# if we don't have both of them (default is to listen on all ip addresses) +{% if global.authentication == 'enabled' %} +keys /etc/ntp.keys +{% if trusted_keys_arr != [] %} +trustedkey {{ trusted_keys_arr|join(' ') }} +{% endif %} +{% endif %} + +{# listen on source interface if configured, else only listen on MGMT_INTERFACE, +LOOPBACK_INTERFACE ip when MGMT_INTERFACE is not defined, or eth0 if we don't +have both of them (default is to listen on all ip addresses) -#} interface ignore wildcard -# set global variable for configured source interface name -# set global boolean to indicate if the ip of the configured source interface is configured -# if the source interface is configured but no ip on that interface, then listen on another -# interface based on existing logic +{# Set interface to listen on set global variable for configured source +interface name set global boolean to indicate if the ip of the configured source +interface is configured if the source interface is configured but no ip on that +interface, then listen on another interface based on existing logic. -#} {%- macro check_ip_on_interface(interface_name, table_name) %} {%- set ns = namespace(valid_intf = 'false') %} {%- if table_name %} @@ -54,8 +100,8 @@ interface ignore wildcard {% set ns = namespace(source_intf = "") %} {% set ns = namespace(source_intf_ip = 'false') %} -{% if (NTP) and (NTP['global']['src_intf']) %} - {% set ns.source_intf = (NTP['global']['src_intf']) %} +{% if global.src_intf %} + {% set ns.source_intf = global.src_intf %} {% if ns.source_intf != "" %} {% if ns.source_intf == "eth0" %} {% set ns.source_intf_ip = 'true' %} @@ -90,32 +136,24 @@ interface listen eth0 {% endif %} interface listen 127.0.0.1 -# Access control configuration; see /usr/share/doc/ntp-doc/html/accopt.html for -# details. The web page -# might also be helpful. -# -# Note that "restrict" applies to both servers and clients, so a configuration -# that might be intended to block requests from certain clients could also end -# up blocking replies from your own upstream servers. +{# Access control options -#} +{% set options = '' -%} + +{# Allow additional servers mobilization from the pool. Otherwise we don't need +that -#} +{% if is_pools == False -%} + {% set options = options ~ ' nopeer' -%} +{% endif -%} +{# Disable NTP server functionality. Should stay on when dhcp is enabled -#} +{# {% if global.server_role == 'disabled' and global.dhcp == 'disabled' -%} + {% set options = options ~ ' ignore' -%} +{% endif -%} #} +# Access control configuration # By default, exchange time with everybody, but don't allow configuration. -restrict -4 default kod notrap nomodify nopeer noquery -restrict -6 default kod notrap nomodify nopeer noquery +restrict -4 default kod notrap nomodify noquery{{ options }} +restrict -6 default kod notrap nomodify noquery{{ options }} # Local users may interrogate the ntp server more closely. restrict 127.0.0.1 restrict ::1 - -# Clients from this (example!) subnet have unlimited access, but only if -# cryptographically authenticated. -#restrict 192.168.123.0 mask 255.255.255.0 notrust - - -# If you want to provide time to your local subnet, change the next line. -# (Again, the address is an example only.) -#broadcast 192.168.123.255 - -# If you want to listen to time broadcasts on your local subnet, de-comment the -# next lines. Please do this only if you trust everybody on the network! -#disable auth -#broadcastclient diff --git a/files/image_config/ntp/ntp.keys.j2 b/files/image_config/ntp/ntp.keys.j2 new file mode 100644 index 000000000000..539bf1b431f1 --- /dev/null +++ b/files/image_config/ntp/ntp.keys.j2 @@ -0,0 +1,17 @@ +############################################################################### +# This file was AUTOMATICALLY GENERATED. DO NOT MODIFY. +# Controlled by ntp-config.service +############################################################################### + +{# We can connect only to the servers we trust. Determine those servers -#} +{% set trusted_arr = [] -%} +{% for server in NTP_SERVER if NTP_SERVER[server].trusted == 'yes' and + NTP_SERVER[server].resolve_as -%} + {% set _ = trusted_arr.append(NTP_SERVER[server].resolve_as) -%} +{% endfor -%} + +{# Define authentication keys inventory -#} +{% set trusted_str = ' ' ~ trusted_arr|join(',') -%} +{% for keyid in NTP_KEY if NTP_KEY[keyid].type and NTP_KEY[keyid].value %} +{{ keyid }} {{ NTP_KEY[keyid].type }} {{ NTP_KEY[keyid].value }}{{trusted_str}} +{% endfor -%} From 235e111abc9fd2e2d43e84a5b4f004622b507fe5 Mon Sep 17 00:00:00 2001 From: Yevhen Fastiuk Date: Wed, 22 Feb 2023 19:43:40 +0200 Subject: [PATCH 03/21] Add NTP YANG nodel tests Signed-off-by: Yevhen Fastiuk --- .../tests/yang_model_tests/tests/ntp.json | 77 ++++++ .../yang_model_tests/tests_config/ntp.json | 260 +++++++++++++++++- 2 files changed, 334 insertions(+), 3 deletions(-) diff --git a/src/sonic-yang-models/tests/yang_model_tests/tests/ntp.json b/src/sonic-yang-models/tests/yang_model_tests/tests/ntp.json index c798de7d832e..f380162b83db 100644 --- a/src/sonic-yang-models/tests/yang_model_tests/tests/ntp.json +++ b/src/sonic-yang-models/tests/yang_model_tests/tests/ntp.json @@ -58,5 +58,82 @@ "desc": "CONFIGURE NON-EXISTING MGMT INTERFACE AS NTP SOURCE INTERFACE.", "eStrKey": "InvalidValue", "eStr": ["src"] + }, + "NTP_GLOB_VALID1": { + "desc": "NTP global params valid config 1" + }, + "NTP_GLOB_VALID2": { + "desc": "NTP global params valid config 2" + }, + "NTP_AUTH_INVALID1": { + "desc": "NTP authentication state invalid 1", + "eStrKey": "InvalidValue" + }, + "NTP_AUTH_INVALID2": { + "desc": "NTP authentication state invalid 2", + "eStrKey": "InvalidValue" + }, + "NTP_DHCP_INVALID1": { + "desc": "NTP DHCP state invalid 1", + "eStrKey": "InvalidValue" + }, + "NTP_DHCP_INVALID2": { + "desc": "NTP DHCP state invalid 2", + "eStrKey": "InvalidValue" + }, + "NTP_SERVER_ROLE_INVALID1": { + "desc": "NTP server role state invalid 1", + "eStrKey": "InvalidValue" + }, + "NTP_SERVER_ROLE_INVALID2": { + "desc": "NTP server role state invalid 2", + "eStrKey": "InvalidValue" + }, + "NTP_STATE_INVALID1": { + "desc": "NTP daemon state invalid 1", + "eStrKey": "InvalidValue" + }, + "NTP_STATE_INVALID2": { + "desc": "NTP daemon state invalid 2", + "eStrKey": "InvalidValue" + }, + "NTP_SERVER_ASSOCIATION_INVALID": { + "desc": "NTP server type invalid", + "eStrKey": "InvalidValue" + }, + "NTP_SERVER_IBURST_INVALID": { + "desc": "NTP server aggressive mode invalid", + "eStrKey": "InvalidValue" + }, + "NTP_SERVER_KEY_INVALID": { + "desc": "NTP server authentication key invalid", + "eStrKey": "InvalidValue" + }, + "NTP_SERVER_STATE_INVALID": { + "desc": "NTP server state invalid", + "eStrKey": "InvalidValue" + }, + "NTP_SERVER_TRUSTED_INVALID": { + "desc": "NTP server trusted mode invalid", + "eStrKey": "InvalidValue" + }, + "NTP_KEY_VALID": { + "desc": "NTP authentication keys inventory" + }, + "NTP_KEY_ID_INVALID": { + "desc": "NTP authentication keys invalid key id", + "eStrKey": "InvalidValue" + }, + "NTP_KEY_TRUSTED_INVALID": { + "desc": "NTP authentication keys invalid trustiness", + "eStrKey": "InvalidValue" + }, + "NTP_KEY_TYPE_INVALID": { + "desc": "NTP authentication keys invalid key type", + "eStrKey": "InvalidValue" + }, + "NTP_KEY_VALUE_INVALID": { + "desc": "NTP authentication keys bad key value", + "eStrKey": "Range" } } diff --git a/src/sonic-yang-models/tests/yang_model_tests/tests_config/ntp.json b/src/sonic-yang-models/tests/yang_model_tests/tests_config/ntp.json index 5b9ab1495afc..d39b6ef2d018 100644 --- a/src/sonic-yang-models/tests/yang_model_tests/tests_config/ntp.json +++ b/src/sonic-yang-models/tests/yang_model_tests/tests_config/ntp.json @@ -4,13 +4,38 @@ "sonic-ntp:NTP_SERVER": { "NTP_SERVER_LIST": [ { - "server_address": "10.11.12.13" + "server_address": "10.11.12.13", + "association_type": "server", + "iburst": "on", + "key": 10, + "admin_state": "enabled", + "trusted": "no" }, { - "server_address": "2001:aa:aa::aa" + "server_address": "2001:aa:aa::aa", + "association_type": "server", + "iburst": "off", + "key": 15, + "admin_state": "disabled", + "trusted": "yes" }, { - "server_address": "pool.ntp.org" + "server_address": "pool.ntp.org", + "association_type": "pool", + "iburst": "on", + "admin_state": "enabled" + } + ] + }, + "sonic-ntp:NTP_KEY": { + "NTP_KEYS_LIST": [ + { + "id": 10, + "value": "lumos" + }, + { + "id": 15, + "value": "bombarda" } ] } @@ -237,5 +262,234 @@ ] } } + }, + "NTP_GLOB_VALID1": { + "sonic-ntp:sonic-ntp": { + "sonic-ntp:NTP": { + "sonic-ntp:global": { + "authentication": "enabled", + "dhcp": "enabled", + "server_role": "enabled", + "admin_state": "enabled" + } + } + } + }, + "NTP_GLOB_VALID2": { + "sonic-ntp:sonic-ntp": { + "sonic-ntp:NTP": { + "sonic-ntp:global": { + "authentication": "disabled", + "dhcp": "disabled", + "server_role": "disabled", + "admin_state": "disabled" + } + } + } + }, + "NTP_AUTH_INVALID1": { + "sonic-ntp:sonic-ntp": { + "sonic-ntp:NTP": { + "sonic-ntp:global": { + "authentication": "" + } + } + } + }, + "NTP_AUTH_INVALID2": { + "sonic-ntp:sonic-ntp": { + "sonic-ntp:NTP": { + "sonic-ntp:global": { + "authentication": "blahblah" + } + } + } + }, + "NTP_DHCP_INVALID1": { + "sonic-ntp:sonic-ntp": { + "sonic-ntp:NTP": { + "sonic-ntp:global": { + "dhcp": "" + } + } + } + }, + "NTP_DHCP_INVALID2": { + "sonic-ntp:sonic-ntp": { + "sonic-ntp:NTP": { + "sonic-ntp:global": { + "dhcp": "abracadabra" + } + } + } + }, + "NTP_SERVER_ROLE_INVALID1": { + "sonic-ntp:sonic-ntp": { + "sonic-ntp:NTP": { + "sonic-ntp:global": { + "server_role": "" + } + } + } + }, + "NTP_SERVER_ROLE_INVALID2": { + "sonic-ntp:sonic-ntp": { + "sonic-ntp:NTP": { + "sonic-ntp:global": { + "server_role": "olololo" + } + } + } + }, + "NTP_STATE_INVALID1": { + "sonic-ntp:sonic-ntp": { + "sonic-ntp:NTP": { + "sonic-ntp:global": { + "admin_state": "" + } + } + } + }, + "NTP_STATE_INVALID2": { + "sonic-ntp:sonic-ntp": { + "sonic-ntp:NTP": { + "sonic-ntp:global": { + "admin_state": "azazaza" + } + } + } + }, + "NTP_SERVER_ASSOCIATION_INVALID": { + "sonic-ntp:sonic-ntp": { + "sonic-ntp:NTP_SERVER": { + "NTP_SERVER_LIST": [ + { + "server_address": "2001:aa:aa:aa", + "association_type": "puul" + } + ] + } + } + }, + "NTP_SERVER_IBURST_INVALID": { + "sonic-ntp:sonic-ntp": { + "sonic-ntp:NTP_SERVER": { + "NTP_SERVER_LIST": [ + { + "server_address": "2001:aa:aa:aa", + "iburst": "of" + } + ] + } + } + }, + "NTP_SERVER_KEY_INVALID": { + "sonic-ntp:sonic-ntp": { + "sonic-ntp:NTP_SERVER": { + "NTP_SERVER_LIST": [ + { + "server_address": "2001:aa:aa:aa", + "key": 0 + } + ] + } + } + }, + "NTP_SERVER_STATE_INVALID": { + "sonic-ntp:sonic-ntp": { + "sonic-ntp:NTP_SERVER": { + "NTP_SERVER_LIST": [ + { + "server_address": "2001:aa:aa:aa", + "admin_state": "enable" + } + ] + } + } + }, + "NTP_SERVER_TRUSTED_INVALID": { + "sonic-ntp:sonic-ntp": { + "sonic-ntp:NTP_SERVER": { + "NTP_SERVER_LIST": [ + { + "server_address": "2001:aa:aa:aa", + "trusted": "not" + } + ] + } + } + }, + "NTP_KEY_VALID": { + "sonic-ntp:sonic-ntp": { + "sonic-ntp:NTP_KEY": { + "NTP_KEYS_LIST": [ + { + "id": 20, + "type": "md5", + "value": "jsdf88320fsd2@@445", + "trusted": "no" + }, + { + "id": 30, + "type": "sha1", + "value": "aabbccddeeff", + "trusted": "yes" + }, + { + "id": 42, + "type": "md5", + "value": "theanswer", + "trusted": "yes" + } + ] + } + } + }, + "NTP_KEY_ID_INVALID": { + "sonic-ntp:sonic-ntp": { + "sonic-ntp:NTP_KEY": { + "NTP_KEYS_LIST": [ + { + "id": 100000 + } + ] + } + } + }, + "NTP_KEY_TRUSTED_INVALID": { + "sonic-ntp:sonic-ntp": { + "sonic-ntp:NTP_KEY": { + "NTP_KEYS_LIST": [ + { + "id": 20, + "trusted": "nope" + } + ] + } + } + }, + "NTP_KEY_TYPE_INVALID": { + "sonic-ntp:sonic-ntp": { + "sonic-ntp:NTP_KEY": { + "NTP_KEYS_LIST": [ + { + "id": 20, + "type": "md6" + } + ] + } + } + }, + "NTP_KEY_VALUE_INVALID": { + "sonic-ntp:sonic-ntp": { + "sonic-ntp:NTP_KEY": { + "NTP_KEYS_LIST": [ + { + "id": 20, + "value": "" + } + ] + } + } } } From 4d271f4eec8775835aab7a1773f8fc8a7d28541d Mon Sep 17 00:00:00 2001 From: Yevhen Fastiuk Date: Wed, 22 Feb 2023 21:27:24 +0200 Subject: [PATCH 04/21] Add test for NTP Jinja templates Signed-off-by: Yevhen Fastiuk --- .../tests/data/ntp/ntp_interfaces.json | 44 ++++++++++- src/sonic-config-engine/tests/ntp.keys.j2 | 1 + .../tests/sample_output/py2/ntp.conf | 73 +------------------ .../tests/sample_output/py2/ntp.keys | 1 + .../tests/sample_output/py3/ntp.conf | 58 ++++----------- .../tests/sample_output/py3/ntp.keys | 8 ++ src/sonic-config-engine/tests/test_j2files.py | 13 +++- 7 files changed, 79 insertions(+), 119 deletions(-) create mode 120000 src/sonic-config-engine/tests/ntp.keys.j2 mode change 100644 => 120000 src/sonic-config-engine/tests/sample_output/py2/ntp.conf create mode 120000 src/sonic-config-engine/tests/sample_output/py2/ntp.keys create mode 100644 src/sonic-config-engine/tests/sample_output/py3/ntp.keys diff --git a/src/sonic-config-engine/tests/data/ntp/ntp_interfaces.json b/src/sonic-config-engine/tests/data/ntp/ntp_interfaces.json index 284758301411..a8da7f1331ff 100644 --- a/src/sonic-config-engine/tests/data/ntp/ntp_interfaces.json +++ b/src/sonic-config-engine/tests/data/ntp/ntp_interfaces.json @@ -1,7 +1,49 @@ { "NTP": { "global": { - "src_intf": "Ethernet0" + "src_intf": "eth0", + "vrf": "default", + "authentication": "enabled", + "dhcp": "disabled", + "server_role": "disabled", + "admin_state": "enabled" + } + }, + "NTP_SERVER": { + "my_ntp_server": { + "association_type": "server", + "iburst": "off", + "admin_state": "disabled", + "version": 3, + "resolve_as": "10.20.30.40" + }, + "server2": { + "association_type": "server", + "iburst": "off", + "admin_state": "enabled", + "version": 3, + "resolve_as": "10.20.30.50", + "key": 42, + "trusted": "no" + }, + "pool.ntp.org": { + "association_type": "pool", + "iburst": "on", + "admin_state": "enabled", + "version": 3, + "resolve_as": "pool.ntp.org" + } + }, + "NTP_KEY": { + "1": { + "type": "md5", + "trusted": "no", + "value": "blabla" + }, + "42": { + "type": "sha1", + "trusted": "yes", + "value": "the_answer" } }, "INTERFACE": { diff --git a/src/sonic-config-engine/tests/ntp.keys.j2 b/src/sonic-config-engine/tests/ntp.keys.j2 new file mode 120000 index 000000000000..a95603db8be2 --- /dev/null +++ b/src/sonic-config-engine/tests/ntp.keys.j2 @@ -0,0 +1 @@ +../../../files/image_config/ntp/ntp.keys.j2 \ No newline at end of file diff --git a/src/sonic-config-engine/tests/sample_output/py2/ntp.conf b/src/sonic-config-engine/tests/sample_output/py2/ntp.conf deleted file mode 100644 index bc98019e88f7..000000000000 --- a/src/sonic-config-engine/tests/sample_output/py2/ntp.conf +++ /dev/null @@ -1,72 +0,0 @@ -############################################################################### -# Managed by Ansible -# file: ansible/roles/acs/templates/ntp.conf.j2 -############################################################################### - -# /etc/ntp.conf, configuration for ntpd; see ntp.conf(5) for help - -# To avoid ntpd from panic and exit if the drift between new time and -# current system time is large. -tinker panic 0 - -driftfile /var/lib/ntp/ntp.drift - - -# Enable this if you want statistics to be logged. -#statsdir /var/log/ntpstats/ - -statistics loopstats peerstats clockstats -filegen loopstats file loopstats type day enable -filegen peerstats file peerstats type day enable -filegen clockstats file clockstats type day enable - - -# You do need to talk to an NTP server or two (or three). -#server ntp.your-provider.example - -# pool.ntp.org maps to about 1000 low-stratum NTP servers. Your server will -# pick a different set every time it starts up. Please consider joining the -# pool: - -#listen on source interface if configured, else -#only listen on MGMT_INTERFACE, LOOPBACK_INTERFACE ip when MGMT_INTERFACE is not defined, or eth0 -# if we don't have both of them (default is to listen on all ip addresses) -interface ignore wildcard - -# set global variable for configured source interface name -# set global boolean to indicate if the ip of the configured source interface is configured -# if the source interface is configured but no ip on that interface, then listen on another -# interface based on existing logic - -interface listen Ethernet0 -interface listen 127.0.0.1 - -# Access control configuration; see /usr/share/doc/ntp-doc/html/accopt.html for -# details. The web page -# might also be helpful. -# -# Note that "restrict" applies to both servers and clients, so a configuration -# that might be intended to block requests from certain clients could also end -# up blocking replies from your own upstream servers. - -# By default, exchange time with everybody, but don't allow configuration. -restrict -4 default kod notrap nomodify nopeer noquery -restrict -6 default kod notrap nomodify nopeer noquery - -# Local users may interrogate the ntp server more closely. -restrict 127.0.0.1 -restrict ::1 - -# Clients from this (example!) subnet have unlimited access, but only if -# cryptographically authenticated. -#restrict 192.168.123.0 mask 255.255.255.0 notrust - - -# If you want to provide time to your local subnet, change the next line. -# (Again, the address is an example only.) -#broadcast 192.168.123.255 - -# If you want to listen to time broadcasts on your local subnet, de-comment the -# next lines. Please do this only if you trust everybody on the network! -#disable auth -#broadcastclient diff --git a/src/sonic-config-engine/tests/sample_output/py2/ntp.conf b/src/sonic-config-engine/tests/sample_output/py2/ntp.conf new file mode 120000 index 000000000000..5ebe399367a6 --- /dev/null +++ b/src/sonic-config-engine/tests/sample_output/py2/ntp.conf @@ -0,0 +1 @@ +../py3/ntp.conf \ No newline at end of file diff --git a/src/sonic-config-engine/tests/sample_output/py2/ntp.keys b/src/sonic-config-engine/tests/sample_output/py2/ntp.keys new file mode 120000 index 000000000000..5f1ab315e5a5 --- /dev/null +++ b/src/sonic-config-engine/tests/sample_output/py2/ntp.keys @@ -0,0 +1 @@ +../py3/ntp.keys \ No newline at end of file diff --git a/src/sonic-config-engine/tests/sample_output/py3/ntp.conf b/src/sonic-config-engine/tests/sample_output/py3/ntp.conf index bc98019e88f7..97d363b2715e 100644 --- a/src/sonic-config-engine/tests/sample_output/py3/ntp.conf +++ b/src/sonic-config-engine/tests/sample_output/py3/ntp.conf @@ -1,72 +1,42 @@ ############################################################################### -# Managed by Ansible -# file: ansible/roles/acs/templates/ntp.conf.j2 +# This file was AUTOMATICALLY GENERATED. DO NOT MODIFY. +# Controlled by ntp-config.service ############################################################################### -# /etc/ntp.conf, configuration for ntpd; see ntp.conf(5) for help - # To avoid ntpd from panic and exit if the drift between new time and # current system time is large. tinker panic 0 driftfile /var/lib/ntp/ntp.drift - -# Enable this if you want statistics to be logged. -#statsdir /var/log/ntpstats/ - statistics loopstats peerstats clockstats filegen loopstats file loopstats type day enable filegen peerstats file peerstats type day enable filegen clockstats file clockstats type day enable +server 10.20.30.50 key 42 iburst version 3 +restrict 10.20.30.50 kod limited nomodify notrap noquery nopeer -# You do need to talk to an NTP server or two (or three). -#server ntp.your-provider.example +pool pool.ntp.org iburst version 3 +restrict pool.ntp.org kod nomodify notrap noquery -# pool.ntp.org maps to about 1000 low-stratum NTP servers. Your server will -# pick a different set every time it starts up. Please consider joining the -# pool: -#listen on source interface if configured, else -#only listen on MGMT_INTERFACE, LOOPBACK_INTERFACE ip when MGMT_INTERFACE is not defined, or eth0 -# if we don't have both of them (default is to listen on all ip addresses) +keys /etc/ntp.keys +trustedkey 42 + interface ignore wildcard -# set global variable for configured source interface name -# set global boolean to indicate if the ip of the configured source interface is configured -# if the source interface is configured but no ip on that interface, then listen on another -# interface based on existing logic + -interface listen Ethernet0 +interface listen eth0 interface listen 127.0.0.1 -# Access control configuration; see /usr/share/doc/ntp-doc/html/accopt.html for -# details. The web page -# might also be helpful. -# -# Note that "restrict" applies to both servers and clients, so a configuration -# that might be intended to block requests from certain clients could also end -# up blocking replies from your own upstream servers. +# Access control configuration # By default, exchange time with everybody, but don't allow configuration. -restrict -4 default kod notrap nomodify nopeer noquery -restrict -6 default kod notrap nomodify nopeer noquery +restrict -4 default kod notrap nomodify noquery nopeer +restrict -6 default kod notrap nomodify noquery nopeer # Local users may interrogate the ntp server more closely. restrict 127.0.0.1 restrict ::1 - -# Clients from this (example!) subnet have unlimited access, but only if -# cryptographically authenticated. -#restrict 192.168.123.0 mask 255.255.255.0 notrust - - -# If you want to provide time to your local subnet, change the next line. -# (Again, the address is an example only.) -#broadcast 192.168.123.255 - -# If you want to listen to time broadcasts on your local subnet, de-comment the -# next lines. Please do this only if you trust everybody on the network! -#disable auth -#broadcastclient diff --git a/src/sonic-config-engine/tests/sample_output/py3/ntp.keys b/src/sonic-config-engine/tests/sample_output/py3/ntp.keys new file mode 100644 index 000000000000..4a1a37b693eb --- /dev/null +++ b/src/sonic-config-engine/tests/sample_output/py3/ntp.keys @@ -0,0 +1,8 @@ +############################################################################### +# This file was AUTOMATICALLY GENERATED. DO NOT MODIFY. +# Controlled by ntp-config.service +############################################################################### + +1 md5 blabla +42 sha1 the_answer + diff --git a/src/sonic-config-engine/tests/test_j2files.py b/src/sonic-config-engine/tests/test_j2files.py index 50e5df4a4660..817f36d38b30 100644 --- a/src/sonic-config-engine/tests/test_j2files.py +++ b/src/sonic-config-engine/tests/test_j2files.py @@ -662,10 +662,19 @@ def test_ndppd_conf(self): def test_ntp_conf(self): conf_template = os.path.join(self.test_dir, "ntp.conf.j2") - ntp_interfaces_json = os.path.join(self.test_dir, "data", "ntp", "ntp_interfaces.json") + config_db_ntp_json = os.path.join(self.test_dir, "data", "ntp", "ntp_interfaces.json") expected = os.path.join(self.test_dir, "sample_output", utils.PYvX_DIR, "ntp.conf") - argument = ['-j', ntp_interfaces_json, '-t', conf_template] + argument = ['-j', config_db_ntp_json, '-t', conf_template] + self.run_script(argument, output_file=self.output_file) + assert utils.cmp(expected, self.output_file), self.run_diff(expected, self.output_file) + + def test_ntp_keys(self): + conf_template = os.path.join(self.test_dir, "ntp.keys.j2") + config_db_ntp_json = os.path.join(self.test_dir, "data", "ntp", "ntp_interfaces.json") + expected = os.path.join(self.test_dir, "sample_output", utils.PYvX_DIR, "ntp.keys") + + argument = ['-j', config_db_ntp_json, '-t', conf_template] self.run_script(argument, output_file=self.output_file) assert utils.cmp(expected, self.output_file), self.run_diff(expected, self.output_file) From f4e82783d7994c00fc51cd17b7dcd5401f8bc565 Mon Sep 17 00:00:00 2001 From: Yevhen Fastiuk Date: Sun, 26 Feb 2023 01:58:17 +0200 Subject: [PATCH 05/21] Add ntpdate package Signed-off-by: Yevhen Fastiuk --- files/build_templates/sonic_debian_extension.j2 | 2 ++ 1 file changed, 2 insertions(+) diff --git a/files/build_templates/sonic_debian_extension.j2 b/files/build_templates/sonic_debian_extension.j2 index 9fd22636f961..ca454c1e1c91 100644 --- a/files/build_templates/sonic_debian_extension.j2 +++ b/files/build_templates/sonic_debian_extension.j2 @@ -365,6 +365,8 @@ sudo dpkg --root=$FILESYSTEM_ROOT -i $debs_path/flashrom_*.deb sudo cp -f $IMAGE_CONFIGS/cron.d/* $FILESYSTEM_ROOT/etc/cron.d/ # Copy NTP configuration files and templates +sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT \ + apt-get -y install ntpdate sudo cp $IMAGE_CONFIGS/ntp/ntp-config.service $FILESYSTEM_ROOT_USR_LIB_SYSTEMD_SYSTEM echo "ntp-config.service" | sudo tee -a $GENERATED_SERVICE_FILE sudo cp $IMAGE_CONFIGS/ntp/ntp-config.sh $FILESYSTEM_ROOT/usr/bin/ From 1171ae41c9fe42f2a46a8ebf4bb6bd33b49ec2e4 Mon Sep 17 00:00:00 2001 From: Yevhen Fastiuk Date: Fri, 17 Mar 2023 02:37:00 +0200 Subject: [PATCH 06/21] Fix 'bad' when auth disabled Signed-off-by: Yevhen Fastiuk --- files/image_config/ntp/ntp.conf.j2 | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/files/image_config/ntp/ntp.conf.j2 b/files/image_config/ntp/ntp.conf.j2 index d2b11827e3ed..5d1bf99d9485 100644 --- a/files/image_config/ntp/ntp.conf.j2 +++ b/files/image_config/ntp/ntp.conf.j2 @@ -30,8 +30,10 @@ config -#} {% set aoptions = '' -%} {# Authentication key -#} - {% if config.key -%} - {% set soptions = soptions ~ ' key ' ~ config.key -%} + {% if global.authentication == 'enabled' -%} + {% if config.key -%} + {% set soptions = soptions ~ ' key ' ~ config.key -%} + {% endif -%} {% endif -%} {# Aggressive polling -#} From 3f6a693f53a885da860d549a426a51e4837d72c1 Mon Sep 17 00:00:00 2001 From: Yevhen Fastiuk Date: Wed, 22 Mar 2023 16:36:33 +0200 Subject: [PATCH 07/21] [NTP] Changed owner for ntp keys config file to root and remove read access for other. Signed-off-by: Yevhen Fastiuk --- files/image_config/ntp/ntp-config.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/files/image_config/ntp/ntp-config.sh b/files/image_config/ntp/ntp-config.sh index b15b7c39d573..3a2a667d802e 100755 --- a/files/image_config/ntp/ntp-config.sh +++ b/files/image_config/ntp/ntp-config.sh @@ -26,7 +26,8 @@ function modify_ntp_default sonic-cfggen -d -t /usr/share/sonic/templates/ntp.conf.j2 >/etc/ntp.conf sonic-cfggen -d -t /usr/share/sonic/templates/ntp.keys.j2 >/etc/ntp.keys -chown ntp:ntp /etc/ntp.keys +chown root:ntp /etc/ntp.keys +chmod o-r /etc/ntp.keys get_database_reboot_type echo "Disabling NTP long jump for reboot type ${reboot_type} ..." From 6f46ee716a81d95feb3bf539c8c18b9290475353 Mon Sep 17 00:00:00 2001 From: Yevhen Fastiuk Date: Wed, 5 Apr 2023 19:14:15 +0300 Subject: [PATCH 08/21] Fix NTP warnings after restarting the service Signed-off-by: Yevhen Fastiuk --- files/image_config/ntp/ntp.conf.j2 | 6 +++--- src/sonic-config-engine/tests/sample_output/py3/ntp.conf | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/files/image_config/ntp/ntp.conf.j2 b/files/image_config/ntp/ntp.conf.j2 index 5d1bf99d9485..a0ce3ac99e69 100644 --- a/files/image_config/ntp/ntp.conf.j2 +++ b/files/image_config/ntp/ntp.conf.j2 @@ -59,7 +59,7 @@ config -#} {{ config.association_type }} {{ config_as }}{{ soptions }} {% if global.server_role == 'disabled' %} -restrict {{ config_as }} kod nomodify notrap noquery{{ aoptions }} +restrict {{ config_as }} kod limited nomodify notrap noquery{{ aoptions }} {% endif %} {% endfor -%} @@ -153,8 +153,8 @@ that -#} # Access control configuration # By default, exchange time with everybody, but don't allow configuration. -restrict -4 default kod notrap nomodify noquery{{ options }} -restrict -6 default kod notrap nomodify noquery{{ options }} +restrict -4 default kod limited notrap nomodify noquery{{ options }} +restrict -6 default kod limited notrap nomodify noquery{{ options }} # Local users may interrogate the ntp server more closely. restrict 127.0.0.1 diff --git a/src/sonic-config-engine/tests/sample_output/py3/ntp.conf b/src/sonic-config-engine/tests/sample_output/py3/ntp.conf index 97d363b2715e..1fb8fdcc6787 100644 --- a/src/sonic-config-engine/tests/sample_output/py3/ntp.conf +++ b/src/sonic-config-engine/tests/sample_output/py3/ntp.conf @@ -18,7 +18,7 @@ server 10.20.30.50 key 42 iburst version 3 restrict 10.20.30.50 kod limited nomodify notrap noquery nopeer pool pool.ntp.org iburst version 3 -restrict pool.ntp.org kod nomodify notrap noquery +restrict pool.ntp.org kod limited nomodify notrap noquery keys /etc/ntp.keys @@ -34,8 +34,8 @@ interface listen 127.0.0.1 # Access control configuration # By default, exchange time with everybody, but don't allow configuration. -restrict -4 default kod notrap nomodify noquery nopeer -restrict -6 default kod notrap nomodify noquery nopeer +restrict -4 default kod limited notrap nomodify noquery nopeer +restrict -6 default kod limited notrap nomodify noquery nopeer # Local users may interrogate the ntp server more closely. restrict 127.0.0.1 From ee6ee4d00a480c697df32b4da509eca1b079f307 Mon Sep 17 00:00:00 2001 From: Yevhen Fastiuk Date: Sun, 7 May 2023 01:52:39 +0300 Subject: [PATCH 09/21] Add ability to encrypt/decrypt NTP keys Signed-off-by: Yevhen Fastiuk --- files/image_config/ntp/ntp.keys.j2 | 3 ++- src/sonic-config-engine/sonic-cfggen | 30 ++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/files/image_config/ntp/ntp.keys.j2 b/files/image_config/ntp/ntp.keys.j2 index 539bf1b431f1..961fc7532694 100644 --- a/files/image_config/ntp/ntp.keys.j2 +++ b/files/image_config/ntp/ntp.keys.j2 @@ -13,5 +13,6 @@ {# Define authentication keys inventory -#} {% set trusted_str = ' ' ~ trusted_arr|join(',') -%} {% for keyid in NTP_KEY if NTP_KEY[keyid].type and NTP_KEY[keyid].value %} -{{ keyid }} {{ NTP_KEY[keyid].type }} {{ NTP_KEY[keyid].value }}{{trusted_str}} +{% set keyval = NTP_KEY[keyid].value | b64decode %} +{{ keyid }} {{ NTP_KEY[keyid].type }} {{ keyval }}{{trusted_str}} {% endfor -%} diff --git a/src/sonic-config-engine/sonic-cfggen b/src/sonic-config-engine/sonic-cfggen index 287640d8a119..2e48c881afdc 100755 --- a/src/sonic-config-engine/sonic-cfggen +++ b/src/sonic-config-engine/sonic-cfggen @@ -25,6 +25,7 @@ import netaddr import os import sys import yaml +import base64 from collections import OrderedDict from config_samples import generate_sample_config, get_available_config @@ -137,6 +138,31 @@ def ip_network(value): return "Invalid ip address %s" % value return r_v.network + +def b64encode(value): + """Base64 encoder + Return: + encoded string or the same value in case of error + """ + try: + ret = base64.b64encode(value.encode()).decode() + except: + return value + return ret + + +def b64decode(value): + """Base64 decoder + Return: + decoded string or the same value in case of error + """ + try: + ret = base64.b64decode(value.encode()).decode() + except: + return value + return ret + + def load_namespace_config(asic_name): if not SonicDBConfig.isInit(): if is_multi_asic(): @@ -250,6 +276,10 @@ def _get_jinja2_env(paths): for attr in ['ip', 'network', 'prefixlen', 'netmask', 'broadcast']: env.filters[attr] = partial(prefix_attr, attr) + # Base64 encoder/decoder + env.filters['b64encode'] = b64encode + env.filters['b64decode'] = b64decode + return env def main(): From 2cbcae981c10ed1fa1e21b0d424b53c2b9888267 Mon Sep 17 00:00:00 2001 From: Yevhen Fastiuk Date: Sat, 13 May 2023 16:04:59 +0300 Subject: [PATCH 10/21] Update Configuration reference Signed-off-by: Yevhen Fastiuk --- src/sonic-yang-models/doc/Configuration.md | 130 ++++++++++++++++++++- 1 file changed, 124 insertions(+), 6 deletions(-) diff --git a/src/sonic-yang-models/doc/Configuration.md b/src/sonic-yang-models/doc/Configuration.md index ab633a715850..e222b6725c2e 100644 --- a/src/sonic-yang-models/doc/Configuration.md +++ b/src/sonic-yang-models/doc/Configuration.md @@ -1474,6 +1474,35 @@ These configuration options are used to modify the way that ntp binds to the ports on the switch and which port it uses to make ntp update requests from. +***NTP Admin state*** + +If this option is set to `enabled` then ntp client will try to sync system time with configured NTP servers. +Otherwise, NTP client feature will be disabled. +``` +{ + "NTP": { + "global": { + "admin_state": "enabled" + } + } +} +``` + +***NTP Server role*** + +This option is used to control NTP server state on the switch. +If this option is set to `enabled` switch will act as NTP server. +By default `server_role` is `disabled`. +``` +{ + "NTP": { + "global": { + "server_role": "enabled" + } + } +} +``` + ***NTP VRF*** If this option is set to `default` then ntp will run within the default vrf @@ -1511,6 +1540,36 @@ for that address. } ``` +***NTP Authentication*** + +If this option is set to `enabled` then ntp will try to verify NTP servers it connects to. +This option **has no effect** if key is not set for NTP server. +By default it is `disabled` +``` +{ + "NTP": { + "global": { + "authentication": "enabled" + } + } +} +``` + +***NTP DHCP leases*** + +If this option is set to `enabled` then ntp client will try to use NTP servers provided by DHCP server. +If this option is set to `disabled` you will be able to use the user-configured NTP servers. +By default it is `enabled` +``` +{ + "NTP": { + "global": { + "dhcp": "enabled" + } + } +} +``` + ### NTP and SYSLOG servers These information are configured in individual tables. Domain name or IP @@ -1521,18 +1580,77 @@ attributes in those objects. ``` { "NTP_SERVER": { - "2.debian.pool.ntp.org": {}, - "1.debian.pool.ntp.org": {}, - "3.debian.pool.ntp.org": {}, - "0.debian.pool.ntp.org": {} + "2.debian.pool.ntp.org": { + "association_type": "pool", + "iburst": "on", + "admin_state": "enabled", + "version": 4 + }, + "1.debian.pool.ntp.org": { + "association_type": "pool", + "iburst": "off", + "admin_state": "enabled", + "version": 3 + }, + "3.debian.pool.ntp.org": { + "association_type": "pool", + "iburst": "on", + "admin_state": "disabled", + "version": 4 + }, + "0.debian.pool.ntp.org": { + "association_type": "pool", + "iburst": "off", + "admin_state": "disabled", + "version": 3 + } }, "NTP_SERVER": { - "23.92.29.245": {}, - "204.2.134.164": {} + "23.92.29.245": { + "association_type": "server", + "iburst": "on", + "admin_state": "enabled", + "version": 4, + "key": 3, + "trusted": "yes" + }, + "204.2.134.164": { + "association_type": "server", + "iburst": "on", + "admin_state": "enabled", + "version": 3 + } + } +} +``` +* `association_type` - is used to control the type of the server. It can be `server` or `pool`. +* `iburst` - agressive server polling `{on, off}`. +* `version` - NTP protool version to use `[3..4]`. +* `key` - authentication key id `[1..65535]` to use to auth the server. +* `admin_state` - enable or disable specific server. +* `trusted` - trust this server when auth is enabled. + +***NTP keys*** +``` +{ + "NTP_KEY": { + "1": { + "type": "md5", + "value": "bXlwYXNzd29yZA==", + "trusted": "yes" + }, + "42": { + "type": "sha1", + "value": "dGhlYW5zd2Vy", + "trusted": "no" + } } } ``` +* `type` - key type to use `{md5, sha1, sha256, sha384, sha512}`. +* `value` - base64 encoded key value. +* `trusted` - trust this NTP key `{yes, no}`. ***Syslog server*** ``` From 80fa8020f2a6222b4f4721c763636d556a965096 Mon Sep 17 00:00:00 2001 From: Yevhen Fastiuk Date: Tue, 5 Sep 2023 02:08:34 +0300 Subject: [PATCH 11/21] Fix NTP configuration template * Align the description for setting interface * Fix the usage of scoped variable Signed-off-by: Yevhen Fastiuk --- files/image_config/ntp/ntp.conf.j2 | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/files/image_config/ntp/ntp.conf.j2 b/files/image_config/ntp/ntp.conf.j2 index a0ce3ac99e69..ff25367f1e16 100644 --- a/files/image_config/ntp/ntp.conf.j2 +++ b/files/image_config/ntp/ntp.conf.j2 @@ -19,7 +19,7 @@ filegen clockstats file clockstats type day enable {# Adding NTP servers. We need to know if we have some pools, to set proper config -#} -{% set is_pools = False %} +{% set ns = namespace(is_pools=false) %} {% for server in NTP_SERVER if NTP_SERVER[server].admin_state != 'disabled' and NTP_SERVER[server].resolve_as and NTP_SERVER[server].association_type -%} @@ -51,7 +51,7 @@ config -#} must remain like that -#} {% set config_as = config.resolve_as -%} {% if config.association_type == 'pool' -%} - {% set is_pools = True -%} + {% set ns.is_pools = true -%} {% set config_as = server -%} {% else -%} {% set aoptions = aoptions ~ ' nopeer' -%} @@ -84,10 +84,12 @@ LOOPBACK_INTERFACE ip when MGMT_INTERFACE is not defined, or eth0 if we don't have both of them (default is to listen on all ip addresses) -#} interface ignore wildcard -{# Set interface to listen on set global variable for configured source -interface name set global boolean to indicate if the ip of the configured source -interface is configured if the source interface is configured but no ip on that -interface, then listen on another interface based on existing logic. -#} +{# Set interface to listen on: + * Set global variable for configured source interface name. + * Set global boolean to indicate if the ip of the configured source + interface is configured. + * If the source interface is configured but no ip on that + interface, then listen on another interface based on existing logic. -#} {%- macro check_ip_on_interface(interface_name, table_name) %} {%- set ns = namespace(valid_intf = 'false') %} {%- if table_name %} @@ -143,7 +145,7 @@ interface listen 127.0.0.1 {# Allow additional servers mobilization from the pool. Otherwise we don't need that -#} -{% if is_pools == False -%} +{% if ns.is_pools == false -%} {% set options = options ~ ' nopeer' -%} {% endif -%} {# Disable NTP server functionality. Should stay on when dhcp is enabled -#} From eac4a88e2732dd0e95782b575911c3b5226846ed Mon Sep 17 00:00:00 2001 From: Yevhen Fastiuk Date: Tue, 5 Sep 2023 02:10:13 +0300 Subject: [PATCH 12/21] Fix YANG model description and tests Signed-off-by: Yevhen Fastiuk --- .../tests/yang_model_tests/tests_config/ntp.json | 10 +++++----- src/sonic-yang-models/yang-models/sonic-ntp.yang | 3 +-- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/sonic-yang-models/tests/yang_model_tests/tests_config/ntp.json b/src/sonic-yang-models/tests/yang_model_tests/tests_config/ntp.json index d39b6ef2d018..c886bec3d200 100644 --- a/src/sonic-yang-models/tests/yang_model_tests/tests_config/ntp.json +++ b/src/sonic-yang-models/tests/yang_model_tests/tests_config/ntp.json @@ -31,11 +31,11 @@ "NTP_KEYS_LIST": [ { "id": 10, - "value": "lumos" + "value": "bHVtb3M=" }, { "id": 15, - "value": "bombarda" + "value": "Ym9tYmFyZGE=" } ] } @@ -426,19 +426,19 @@ { "id": 20, "type": "md5", - "value": "jsdf88320fsd2@@445", + "value": "anNkZjg4MzIwZnNkMkBANDQ1", "trusted": "no" }, { "id": 30, "type": "sha1", - "value": "aabbccddeeff", + "value": "YWFiYmNjZGRlZWZm", "trusted": "yes" }, { "id": 42, "type": "md5", - "value": "theanswer", + "value": "dGhlYW5zd2Vy", "trusted": "yes" } ] diff --git a/src/sonic-yang-models/yang-models/sonic-ntp.yang b/src/sonic-yang-models/yang-models/sonic-ntp.yang index 2624e27c58f2..5f7e080cb6c4 100644 --- a/src/sonic-yang-models/yang-models/sonic-ntp.yang +++ b/src/sonic-yang-models/yang-models/sonic-ntp.yang @@ -177,8 +177,7 @@ module sonic-ntp { leaf association_type { type association-type; default server; - description "NTP remote association type. Server, pool, or - peer."; + description "NTP remote association type: server or pool."; } leaf iburst { From f7216152ec2c05679609ff2f2aa7901e6abc8af7 Mon Sep 17 00:00:00 2001 From: Yevhen Fastiuk Date: Tue, 5 Sep 2023 11:35:56 +0300 Subject: [PATCH 13/21] Align NTP test according to fixed condition Signed-off-by: Yevhen Fastiuk --- src/sonic-config-engine/tests/sample_output/py3/ntp.conf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sonic-config-engine/tests/sample_output/py3/ntp.conf b/src/sonic-config-engine/tests/sample_output/py3/ntp.conf index 1fb8fdcc6787..56f18e3ca13b 100644 --- a/src/sonic-config-engine/tests/sample_output/py3/ntp.conf +++ b/src/sonic-config-engine/tests/sample_output/py3/ntp.conf @@ -34,8 +34,8 @@ interface listen 127.0.0.1 # Access control configuration # By default, exchange time with everybody, but don't allow configuration. -restrict -4 default kod limited notrap nomodify noquery nopeer -restrict -6 default kod limited notrap nomodify noquery nopeer +restrict -4 default kod limited notrap nomodify noquery +restrict -6 default kod limited notrap nomodify noquery # Local users may interrogate the ntp server more closely. restrict 127.0.0.1 From 63a830a8f0a0fd5da60c58f16780111893bfb70f Mon Sep 17 00:00:00 2001 From: Yevhen Fastiuk Date: Mon, 13 Nov 2023 21:49:34 +0200 Subject: [PATCH 14/21] [submodule] Update submodule sonic-utilities --- src/sonic-utilities | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-utilities b/src/sonic-utilities index 6833e6cac8ca..62fcd77a0e7e 160000 --- a/src/sonic-utilities +++ b/src/sonic-utilities @@ -1 +1 @@ -Subproject commit 6833e6cac8ca0879fde6f5462a994abfa685716d +Subproject commit 62fcd77a0e7e4e0b8a5474fb7545b128aad4f0be From 97d19e7b8e857488adfebcb2722eb788047544b9 Mon Sep 17 00:00:00 2001 From: Yevhen Fastiuk Date: Mon, 13 Nov 2023 21:49:34 +0200 Subject: [PATCH 15/21] [submodule] Update submodule sonic-utilities --- src/sonic-utilities | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-utilities b/src/sonic-utilities index 9018f3aca3ad..02a588b7f548 160000 --- a/src/sonic-utilities +++ b/src/sonic-utilities @@ -1 +1 @@ -Subproject commit 9018f3aca3adc959f3f372c04ee62d04241fc244 +Subproject commit 02a588b7f5488b75c933e18313028bfb0664376c From 63c3dd06003551d5ce7b2a60d8380b4196237d2a Mon Sep 17 00:00:00 2001 From: Yevhen Fastiuk Date: Sat, 25 Nov 2023 00:44:42 +0200 Subject: [PATCH 16/21] Allow eth0 to be as source ifc without defining it Signed-off-by: Yevhen Fastiuk --- src/sonic-yang-models/yang-models/sonic-ntp.yang | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/sonic-yang-models/yang-models/sonic-ntp.yang b/src/sonic-yang-models/yang-models/sonic-ntp.yang index 5f7e080cb6c4..2591f8c7a58b 100644 --- a/src/sonic-yang-models/yang-models/sonic-ntp.yang +++ b/src/sonic-yang-models/yang-models/sonic-ntp.yang @@ -105,6 +105,9 @@ module sonic-ntp { type leafref { path /mprt:sonic-mgmt_port/mprt:MGMT_PORT/mprt:MGMT_PORT_LIST/mprt:name; } + type string { + pattern 'eth0'; + } } description From 5eadcfadf268ee6c45091be98c8d83971b1820ca Mon Sep 17 00:00:00 2001 From: Yevhen Fastiuk Date: Sat, 25 Nov 2023 02:01:47 +0200 Subject: [PATCH 17/21] Align NTP keys file for bookworm Signed-off-by: Yevhen Fastiuk --- files/image_config/ntp/ntp-config.sh | 2 -- files/image_config/ntp/ntp.conf.j2 | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/files/image_config/ntp/ntp-config.sh b/files/image_config/ntp/ntp-config.sh index 7d1c4890b87c..13469c58966b 100755 --- a/files/image_config/ntp/ntp-config.sh +++ b/files/image_config/ntp/ntp-config.sh @@ -25,8 +25,6 @@ function modify_ntp_default sonic-cfggen -d -t /usr/share/sonic/templates/ntp.conf.j2 >/etc/ntpsec/ntp.conf sonic-cfggen -d -t /usr/share/sonic/templates/ntp.keys.j2 >/etc/ntpsec/ntp.keys - -chown root:ntp /etc/ntp.keys chmod o-r /etc/ntp.keys get_database_reboot_type diff --git a/files/image_config/ntp/ntp.conf.j2 b/files/image_config/ntp/ntp.conf.j2 index 37cf484f5beb..7c1ace96ae3e 100644 --- a/files/image_config/ntp/ntp.conf.j2 +++ b/files/image_config/ntp/ntp.conf.j2 @@ -71,7 +71,7 @@ restrict {{ config_as }} kod limited nomodify notrap noquery{{ aoptions }} {% endfor %} {% if global.authentication == 'enabled' %} -keys /etc/ntp.keys +keys /etc/ntpsec/ntp.keys {% if trusted_keys_arr != [] %} trustedkey {{ trusted_keys_arr|join(' ') }} {% endif %} From 99e779dcf2af7d6351bcd4247d7059470bbd6975 Mon Sep 17 00:00:00 2001 From: Yevhen Fastiuk Date: Sat, 25 Nov 2023 02:09:11 +0200 Subject: [PATCH 18/21] Remowe the WA for collision between pool and nopeer * The notorious collision between pool and nopeer in older implementations has been fixed; the pool keyword is now fully usable. Signed-off-by: Yevhen Fastiuk --- files/image_config/ntp/ntp.conf.j2 | 5 ----- 1 file changed, 5 deletions(-) diff --git a/files/image_config/ntp/ntp.conf.j2 b/files/image_config/ntp/ntp.conf.j2 index 7c1ace96ae3e..0563e5044476 100644 --- a/files/image_config/ntp/ntp.conf.j2 +++ b/files/image_config/ntp/ntp.conf.j2 @@ -141,11 +141,6 @@ interface listen 127.0.0.1 {# Access control options -#} {% set options = '' -%} -{# Allow additional servers mobilization from the pool. Otherwise we don't need -that -#} -{% if ns.is_pools == false -%} - {% set options = options ~ ' nopeer' -%} -{% endif -%} {# Disable NTP server functionality. Should stay on when dhcp is enabled -#} {# {% if global.server_role == 'disabled' and global.dhcp == 'disabled' -%} {% set options = options ~ ' ignore' -%} From f2edb44be6ded1a94bdc0915cba7fee8ba8a4312 Mon Sep 17 00:00:00 2001 From: Yevhen Fastiuk Date: Sat, 25 Nov 2023 02:18:29 +0200 Subject: [PATCH 19/21] Update NTP config test according to new path Signed-off-by: Yevhen Fastiuk --- src/sonic-config-engine/tests/sample_output/py3/ntp.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-config-engine/tests/sample_output/py3/ntp.conf b/src/sonic-config-engine/tests/sample_output/py3/ntp.conf index 0d681a3dfaf0..41361573949b 100644 --- a/src/sonic-config-engine/tests/sample_output/py3/ntp.conf +++ b/src/sonic-config-engine/tests/sample_output/py3/ntp.conf @@ -19,7 +19,7 @@ pool pool.ntp.org iburst version 3 restrict pool.ntp.org kod limited nomodify notrap noquery -keys /etc/ntp.keys +keys /etc/ntpsec/ntp.keys trustedkey 42 interface ignore wildcard From 5a16d6d3ae8eb2e6216a911e5798f2d6054f8faf Mon Sep 17 00:00:00 2001 From: Yevhen Fastiuk Date: Thu, 30 Nov 2023 17:48:54 +0200 Subject: [PATCH 20/21] Remove ntpsec-ntpdate if-up.d script * The script came with ntpdate package we are installing * It tries to bring up ntpsec service when calling to if-up, but since ntpsec depends on networking service it deadlocks itself Signed-off-by: Yevhen Fastiuk --- files/build_templates/sonic_debian_extension.j2 | 1 + 1 file changed, 1 insertion(+) diff --git a/files/build_templates/sonic_debian_extension.j2 b/files/build_templates/sonic_debian_extension.j2 index 0419671178a2..2fa11e191007 100644 --- a/files/build_templates/sonic_debian_extension.j2 +++ b/files/build_templates/sonic_debian_extension.j2 @@ -374,6 +374,7 @@ sudo cp -f $IMAGE_CONFIGS/cron.d/* $FILESYSTEM_ROOT/etc/cron.d/ # Copy NTP configuration files and templates sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT \ apt-get -y install ntpdate +sudo rm -f $FILESYSTEM_ROOT/etc/network/if-up.d/ntpsec-ntpdate sudo cp $IMAGE_CONFIGS/ntp/ntp-config.service $FILESYSTEM_ROOT_USR_LIB_SYSTEMD_SYSTEM echo "ntp-config.service" | sudo tee -a $GENERATED_SERVICE_FILE sudo cp $IMAGE_CONFIGS/ntp/ntp-config.sh $FILESYSTEM_ROOT/usr/bin/ From e2e8d97ce39e561c76a39c23dd009ac7f7baec09 Mon Sep 17 00:00:00 2001 From: Yevhen Fastiuk Date: Sun, 3 Dec 2023 00:13:33 +0200 Subject: [PATCH 21/21] Update sample config with NTP config Signed-off-by: Yevhen Fastiuk --- .../tests/files/sample_config_db.json | 28 +++++++++++++++++-- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/src/sonic-yang-models/tests/files/sample_config_db.json b/src/sonic-yang-models/tests/files/sample_config_db.json index 4eba94e72f1c..b0e3f5f589a7 100644 --- a/src/sonic-yang-models/tests/files/sample_config_db.json +++ b/src/sonic-yang-models/tests/files/sample_config_db.json @@ -477,14 +477,36 @@ }, "NTP": { "global": { + "authentication": "disabled", + "dhcp": "enabled", + "server_role": "disabled", + "admin_state": "enabled", "vrf": "mgmt", "src_intf": "eth0;Loopback0" } }, "NTP_SERVER": { - "0.debian.pool.ntp.org": {}, - "23.92.29.245": {}, - "2001:aa:aa::aa": {} + "0.debian.pool.ntp.org": { + "association_type": "pool", + "resolve_as": "0.debian.pool.ntp.org" + }, + "time.google.com": { + "association_type": "server", + "resolve_as": "216.239.35.4" + }, + "23.92.29.245": { + "admin_state": "enabled", + "association_type": "server", + "resolve_as": "23.92.29.245", + "iburst": "off", + "trusted": "yes" + }, + "2001:aa:aa::aa": { + "admin_state": "disabled", + "iburst": "on", + "association_type": "server", + "resolve_as": "2001:aa:aa::aa" + } }, "SYSLOG_SERVER" : { "10.13.14.17": {