Changeset - 72af31a420be
[Not reviewed]
0 7 0
Branko Majic (branko) - 2 months ago 2024-02-26 21:24:32
branko@majic.rs
MAR-192: Switch to using NTPsec NTP server for increased security:

- This has for some time been a way better option, and it should also
provide for compatibility with Debian 12 Bookworm.
7 files changed with 74 insertions and 44 deletions:
0 comments (0 inline, 0 general)
roles/common/handlers/main.yml
Show inline comments
 
@@ -30,6 +30,6 @@
 

	
 
- name: Restart NTP server
 
  service:
 
    name: ntp
 
    name: ntpsec
 
    state: restarted
 
  when: ntp_servers | length > 0
roles/common/molecule/default/prepare.yml
Show inline comments
 
@@ -150,6 +150,13 @@
 
        group: root
 
        mode: 0644
 

	
 
    - name: Install the deprecated/obsolete NTP-related packages
 
      apt:
 
        name:
 
          - ntp
 
          - ntpdate
 
        state: present
 

	
 
- hosts: parameters-mandatory,parameters-optional
 
  become: true
 
  tasks:
roles/common/molecule/default/tests/test_deprecated.py
Show inline comments
 
@@ -13,6 +13,7 @@ testinfra_hosts = testinfra.utils.ansible_runner.AnsibleRunner(
 
    '/etc/pip_check_requirements_upgrades-py3/',
 
    '/var/lib/pipreqcheck/virtualenv-py3/',
 
    '/etc/cron.d/check_pip_requirements-py3',
 
    '/etc/ntp.conf',
 
])
 
def test_deprecated_paths_are_absent(host, path):
 
    """
 
@@ -21,3 +22,15 @@ def test_deprecated_paths_are_absent(host, path):
 

	
 
    with host.sudo():
 
        assert not host.file(path).exists
 

	
 

	
 
@pytest.mark.parametrize('package', [
 
    'ntp',
 
    'ntpdate',
 
])
 
def test_deprecated_packages_are_absent(host, package):
 
    """
 
    Tests if deprecated pacakges are absent.
 
    """
 

	
 
    assert not host.package(package).is_installed
roles/common/molecule/default/tests/test_parameters_mandatory.py
Show inline comments
 
@@ -121,8 +121,8 @@ def test_ntp_software_not_installed(host):
 
    Tests if NTP packages are absent.
 
    """
 

	
 
    assert not host.package('ntp').is_installed
 
    assert not host.package('ntpdate').is_installed
 
    assert not host.package('ntpsec').is_installed
 
    assert not host.package('ntpsec-ntpdate').is_installed
 

	
 

	
 
def test_ntp_listening_interfaces(host):
roles/common/molecule/default/tests/test_parameters_optional.py
Show inline comments
 
@@ -269,8 +269,8 @@ def test_ntp_software_installed(host):
 
    Tests if NTP packages are installed.
 
    """
 

	
 
    assert host.package('ntp').is_installed
 
    assert host.package('ntpdate').is_installed
 
    assert host.package('ntpsec').is_installed
 
    assert host.package('ntpsec-ntpdate').is_installed
 

	
 

	
 
def test_ntp_server_configuration(host):
 
@@ -280,11 +280,17 @@ def test_ntp_server_configuration(host):
 

	
 
    with host.sudo():
 

	
 
        # Read the configuration file.
 
        configuration = host.file("/etc/ntp.conf").content_string.split("\n")
 
        # Check for presence of the configuration file.
 
        configuration_file = host.file("/etc/ntpsec/ntp.conf")
 

	
 
        # Extract only the relevant sections of files (exculde empty
 
        assert configuration_file.exists
 
        assert configuration_file.user == 'root'
 
        assert configuration_file.group == 'root'
 
        assert configuration_file.mode == 0o644
 

	
 
        # Extract relevant sections of configuration (exclude empty
 
        # lines and comments).
 
        configuration = configuration_file.content_string.split("\n")
 
        configuration = [c.strip() for c in configuration if re.match(r'^\s*(|#.*)$', c) is None]
 

	
 
        # Ensure correct servers have been configured in the pool.
 
@@ -296,10 +302,9 @@ def test_ntp_server_configuration(host):
 

	
 
        assert sorted(servers) == sorted(expected_servers)
 

	
 
        # Ensure querying of server is disable for untrusted clients.
 
        # Ensure querying of server is disabled for untrusted clients.
 
        restrictions = [c for c in configuration if c.startswith('restrict')]
 
        expected_restrictions = ["restrict -4 default kod notrap nomodify nopeer noquery",
 
                                 "restrict -6 default kod notrap nomodify nopeer noquery",
 
        expected_restrictions = ["restrict default kod nomodify nopeer noquery limited",
 
                                 "restrict 127.0.0.1",
 
                                 "restrict ::1"]
 

	
roles/common/tasks/main.yml
Show inline comments
 
@@ -12,6 +12,14 @@
 
    - "/var/lib/pipreqcheck/virtualenv-py3"
 
    - "/etc/cron.d/check_pip_requirements-py3"
 

	
 
- name: Drop deprecated packages
 
  apt:
 
    name:
 
      - ntp
 
      - ntpdate
 
    state: absent
 
    purge: true
 

	
 
# Main implementation
 
# ===================
 

	
 
@@ -470,15 +478,15 @@
 
- name: Install NTP packages
 
  apt:
 
    name:
 
      - ntp
 
      - ntpdate
 
      - ntpsec
 
      - ntpsec-ntpdate
 
    state: present
 
  when: ntp_servers | length > 0
 

	
 
- name: Deploy NTP configuration
 
  template:
 
    src: "ntp.conf.j2"
 
    dest: "/etc/ntp.conf"
 
    dest: "/etc/ntpsec/ntp.conf"
 
    owner: root
 
    group: root
 
    mode: 0644
roles/common/templates/ntp.conf.j2
Show inline comments
 
# /etc/ntp.conf, configuration for ntpd; see ntp.conf(5) for help
 
# /etc/ntpsec/ntp.conf, configuration for ntpd; see ntp.conf(5) for help
 

	
 
driftfile /var/lib/ntp/ntp.drift
 
driftfile /var/lib/ntpsec/ntp.drift
 
leapfile /usr/share/zoneinfo/leap-seconds.list
 

	
 
# To enable Network Time Security support as a server, obtain a certificate
 
# (e.g. with Let's Encrypt), configure the paths below, and uncomment:
 
# nts cert CERT_FILE
 
# nts key KEY_FILE
 
# nts enable
 

	
 
# Enable this if you want statistics to be logged.
 
#statsdir /var/log/ntpstats/
 
# You must create /var/log/ntpsec (owned by ntpsec:ntpsec) to enable logging.
 
#statsdir /var/log/ntpsec/
 
#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
 

	
 
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
 
# This should be maxclock 7, but the pool entries count towards maxclock.
 
tos maxclock 11
 

	
 
# Comment this out if you have a refclock and want it to be able to discipline
 
# the clock by itself (e.g. if the system is not connected to the network).
 
tos minclock 4 minsane 3
 

	
 
# You do need to talk to an NTP server or two (or three).
 
#server ntp.your-provider.example
 
# Specify one or more NTP servers.
 

	
 
# Public NTP servers supporting Network Time Security:
 
# server time.cloudflare.com nts
 

	
 
# 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: <http://www.pool.ntp.org/join.html>
 
# pool: <https://www.pool.ntp.org/join.html>
 
{% for server in ntp_servers %}
 
server {{ server }} iburst
 
{% endfor %}
 

	
 
# Access control configuration; see /usr/share/doc/ntp-doc/html/accopt.html for
 
# details.  The web page <http://support.ntp.org/bin/view/Support/AccessRestrictions>
 
# might also be helpful.
 
# Access control configuration; see /usr/share/doc/ntpsec-doc/html/accopt.html
 
# for details.
 
#
 
# 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
 
restrict default kod nomodify nopeer noquery limited
 

	
 
# 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
0 comments (0 inline, 0 general)