Chrony: Difference between revisions

From NixOS Wiki
imported>Mweinelt
Explain how to set up chrony with NTS
 
Add instructions to configure chrony as an NTP server
 
(6 intermediate revisions by 4 users not shown)
Line 1: Line 1:
Chrony is an NTP and NTS client and server implementation. This means it can synchronize the time of your local machine, as well as provide services to clients on the attached network segments.
Chrony is an NTP and NTS client and server implementation. This means it can synchronize the time of your local machine, as well as provide services to clients on the attached network segments.
== NTP ==
This protocol is slowly being phased out due it security concerns, using a more secure method like NTS is recommended. To enable NTP, enable the chrony service and add whichever NTP servers you wish to use. If you don't set a serverlist here, the value of <code>networking.timeServers</code> will be used.
<syntaxhighlight lang="nix">
{ config
, ...
};
{
  services.chrony = {
    enable = true;
    servers = [ "ntp-example.com" ];
  };
}
</syntaxhighlight>


== NTS ==
== NTS ==


To enable NTS (Network Time Security), a certificate needs to be provided. You can rely on the ACME service to acquire one, but make sure that the certificate group gets assigned to <code>chrony</code>, or else the service will not be able to read the certificate and key after it drops its privileges.
To enable NTS (Network Time Security), typically all that needs to be provided is a NTP server capable of NTS.
 
<syntaxhighlight lang="nix">
{ config
, ...
};
{
  services.chrony = {
    enable = true;
    enableNTS = true;
    servers = [ "nts-example.com" ];
  };
}
</syntaxhighlight>
You can verify that NTS is being used via observing the output of <code>sudo chronyc -N authdata</code> and reading the value under mode, it should read NTS.
 
This will not work with the default timeservers of NixOS, as they do not support NTS!
 
=== Troubleshooting ===
It is possible that a certificate may need to be manually provided. You can rely on the ACME service to acquire one, but make sure that the certificate group gets assigned to <code>chrony</code>, or else the service will not be able to read the certificate and key after it drops its privileges.


<syntaxhighlight lang="nix">
<syntaxhighlight lang="nix">
Line 10: Line 43:
};
};
let
let
   acmePath = config.security.acme.certs."nts.example.com".directory;
   acmePath = config.security.acme.certs."foo-example.com".directory;
in
in
{
{
   security.acme.certs."nts.example.com" = {
   security.acme.certs."foo-example.com" = {
     group = "chrony";
     group = "chrony";
    # One of the following challenge method options will need to be provided
    # to obtain a self signed cert
    webroot = "";
    s3bucket = '"";
    dnsProvider = "";
    listenHTTP = "";
   };
   };


   services.chrony = {
   services.chrony = {
     enable = true:
     enable = true;
     enableNTS = true:
     enableNTS = true;
     extraConfig = ''
     extraConfig = ''
       [...]
       [...]
Line 28: Line 67:
}
}
</syntaxhighlight>
</syntaxhighlight>
== Hosting an NTP server ==
The simplest config to make chrony act as an NTP server is this configuration:<syntaxhighlight lang="nix">
{ ... }:
{
  services.chrony = {
    enable = true;
    extraConfig = ''
      allow
    '';
  };
  networking.firewall.allowedUDPPorts = [ 123 ];
}
</syntaxhighlight>This allows any external client to request time via NTP. You can also limit the allowed clients to certain subnets like so:<syntaxhighlight lang="nix">
{ ... }:
{
  services.chrony = {
    enable = true;
    extraConfig = ''
      allow 10.100.0.0/24
      allow 192.168.178.0/24
    '';
  };
  networking.firewall.allowedUDPPorts = [ 123 ];
}
</syntaxhighlight>
=== NTS while hosting ===
If you want to enable NTS, you need to also add <code>networking.firewall.allowedTCPPorts = [ 4460 ];</code> as this port is used for the NTS key-exchange before the encrypted connection via port 123.
Currently (as of NixOS 24.05), <code>enableNTS</code> is an all-or-nothing setting; it will require all servers to support NTS as well as all clients. If you need more granularity, use <code>extraConfig</code>and refer to [https://chrony-project.org/documentation.html the chrony documentation].
[[Category:Applications]]
[[Category:Server]]

Latest revision as of 09:25, 30 August 2024

Chrony is an NTP and NTS client and server implementation. This means it can synchronize the time of your local machine, as well as provide services to clients on the attached network segments.

NTP

This protocol is slowly being phased out due it security concerns, using a more secure method like NTS is recommended. To enable NTP, enable the chrony service and add whichever NTP servers you wish to use. If you don't set a serverlist here, the value of networking.timeServers will be used.

{ config
, ...
};
{
  services.chrony = {
    enable = true;
    servers = [ "ntp-example.com" ];
  };
}

NTS

To enable NTS (Network Time Security), typically all that needs to be provided is a NTP server capable of NTS.

{ config
, ...
};
{
  services.chrony = {
    enable = true;
    enableNTS = true;
    servers = [ "nts-example.com" ];
  };
}

You can verify that NTS is being used via observing the output of sudo chronyc -N authdata and reading the value under mode, it should read NTS.

This will not work with the default timeservers of NixOS, as they do not support NTS!

Troubleshooting

It is possible that a certificate may need to be manually provided. You can rely on the ACME service to acquire one, but make sure that the certificate group gets assigned to chrony, or else the service will not be able to read the certificate and key after it drops its privileges.

{ config
, ...
};
let
  acmePath = config.security.acme.certs."foo-example.com".directory;
in
{
  security.acme.certs."foo-example.com" = {
    group = "chrony";
    # One of the following challenge method options will need to be provided
    # to obtain a self signed cert
    webroot = "";
    s3bucket = '"";
    dnsProvider = "";
    listenHTTP = "";
  };

   services.chrony = {
     enable = true;
     enableNTS = true;
     extraConfig = ''
      [...]
      ntsservercert ${acmePath}/fullchain.pem
      ntsserverkey ${acmePath}/key.pem
    '';
  };
}

Hosting an NTP server

The simplest config to make chrony act as an NTP server is this configuration:

{ ... }:
{
  services.chrony = {
    enable = true;
    extraConfig = ''
      allow
    '';
  };

  networking.firewall.allowedUDPPorts = [ 123 ];
}

This allows any external client to request time via NTP. You can also limit the allowed clients to certain subnets like so:

{ ... }:
{
  services.chrony = {
    enable = true;
    extraConfig = ''
      allow 10.100.0.0/24
      allow 192.168.178.0/24
    '';
  };

  networking.firewall.allowedUDPPorts = [ 123 ];
}

NTS while hosting

If you want to enable NTS, you need to also add networking.firewall.allowedTCPPorts = [ 4460 ]; as this port is used for the NTS key-exchange before the encrypted connection via port 123.

Currently (as of NixOS 24.05), enableNTS is an all-or-nothing setting; it will require all servers to support NTS as well as all clients. If you need more granularity, use extraConfigand refer to the chrony documentation.