diff --git a/examples/rotuer.nix b/examples/rotuer.nix index 7c0c23a..8ec9695 100644 --- a/examples/rotuer.nix +++ b/examples/rotuer.nix @@ -38,6 +38,7 @@ in rec { ../modules/firewall ../modules/hostapd ../modules/bridge + ../modules/ntp ]; rootfsType = "jffs2"; hostname = "rotuer"; @@ -95,16 +96,10 @@ in rec { ]; }; - services.ntp = - let config = writeText "chrony.conf" '' - pool pool.ntp.org iburst - dumpdir /run/chrony - makestep 1.0 3 - ''; - in longrun { - name = "ntp"; - run = "${pkgs.chrony}/bin/chronyd -f ${config} -d"; - }; + services.ntp = svc.ntp { + pools = { "pool.ntp.org" = ["iburst"]; }; + makestep = { threshold = 1.0; limit = 3; }; + }; services.sshd = longrun { name = "sshd"; diff --git a/modules/ntp/default.nix b/modules/ntp/default.nix new file mode 100644 index 0000000..2a4e6b3 --- /dev/null +++ b/modules/ntp/default.nix @@ -0,0 +1,19 @@ +{ lib, pkgs, config, ...}: +let + inherit (lib) mkOption types; +in { + options = { + system.service.ntp = mkOption { + type = types.functionTo types.package; + }; + }; + config = { + system.service.ntp = pkgs.callPackage ./service.nix {}; + users.ntp = { + uid = 52; gid= 52; gecos = "Unprivileged NTP user"; + dir = "/run/ntp"; + shell = "/bin/false"; + }; + # groups.system.usernames = ["ntp"]; + }; +} diff --git a/modules/ntp/service.nix b/modules/ntp/service.nix new file mode 100644 index 0000000..6b2b6e4 --- /dev/null +++ b/modules/ntp/service.nix @@ -0,0 +1,75 @@ +{ + liminix +, chrony +, serviceFns +, lib +, writeText +}: +let + inherit (liminix.services) longrun; + inherit (lib) concatStringsSep mapAttrsToList; + inherit (liminix.lib) typeChecked; + inherit (lib) mkOption types; + + serverOpts = types.listOf types.str; + t = { + user = mkOption { + type = types.str; + default = "ntp"; + }; + servers = mkOption { type = types.attrsOf serverOpts; default = {}; }; + pools = mkOption { type = types.attrsOf serverOpts; default = {}; }; + peers = mkOption { type = types.attrsOf serverOpts; default = {}; }; + makestep = { + threshold = mkOption { type = types.number; }; + limit = mkOption { type = types.number; }; + }; + allow = mkOption { + description = "subnets from which NTP clients are allowed to access the server"; + type = types.listOf types.str; + default = []; + }; + bindaddress = mkOption { + type = types.nullOr types.str; + default = null; + }; + binddevice = mkOption { + type = types.nullOr types.str; + default = null; + }; + dumpdir = mkOption { + internal = true; + type = types.path; + default = "/run/chrony"; + }; + extraConfig = mkOption { + type = types.lines; + default = ""; + }; + }; + configFile = p: + (mapAttrsToList (name: opts: "server ${name} ${concatStringsSep "" opts}") + p.servers) + ++ + (mapAttrsToList (name: opts: "pool ${name} ${concatStringsSep "" opts}") + p.pools) + ++ + (mapAttrsToList (name: opts: "peer ${name} ${concatStringsSep "" opts}") + p.peers) + ++ [ "user #{p.user}" ] + ++ (lib.optional (p.makestep != null) "makestep ${toString p.makestep.threshold} ${toString p.makestep.limit}") + ++ (map (n: "allow ${n}") p.allow) + ++ (lib.optional (p.bindaddress != null) "bindaddress ${p.bindaddress}") + ++ (lib.optional (p.binddevice != null) "binddevice ${p.binddevice}") + ++ (lib.optional (p.dumpdir != null) "dumpdir ${p.dumpdir}") + ++ [p.extraConfig]; +in +params: +let + config = writeText "chrony.conf" + (concatStringsSep "\n" + (configFile (typeChecked "" t params))); +in longrun { + name = "ntp"; # bad name, needs to be unique + run = "${chrony}/bin/chronyd -f ${config} -d"; +} diff --git a/vanilla-configuration.nix b/vanilla-configuration.nix index c8ebc56..29c5731 100644 --- a/vanilla-configuration.nix +++ b/vanilla-configuration.nix @@ -7,6 +7,7 @@ in rec { imports = [ ./modules/tftpboot.nix ./modules/wlan.nix + ./modules/ntp ]; services.loopback = config.hardware.networkInterfaces.lo; @@ -36,16 +37,9 @@ in rec { dependencies = [iface]; }; - services.ntp = - let config = writeText "chrony.conf" '' - pool pool.ntp.org iburst - dumpdir /run/chrony - makestep 1.0 3 - ''; - in longrun { - name = "ntp"; - run = "${pkgs.chrony}/bin/chronyd -f ${config} -d"; - }; + services.ntp = config.system.service.ntp { + pools = { "pool.ntp.org" = ["iburst"] ; }; + }; services.default = target { name = "default";