Merge pull request #129980 from mweinelt/nixos/kea

This commit is contained in:
Martin Weinelt 2021-07-18 00:26:35 +02:00 committed by GitHub
commit d9a3a54b73
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 473 additions and 34 deletions

View file

@ -47,6 +47,13 @@
<link xlink:href="options.html#opt-services.geoipupdate.enable">services.geoipupdate</link>.
</para>
</listitem>
<listitem>
<para>
<link xlink:href="https://www.isc.org/kea/">Kea</link>, ISCs
2nd generation DHCP and DDNS server suite. Available at
<link xlink:href="options.html#opt-services.kea">services.kea</link>.
</para>
</listitem>
<listitem>
<para>
<link xlink:href="https://sr.ht">sourcehut</link>, a

View file

@ -15,6 +15,8 @@ In addition to numerous new and upgraded packages, this release has the followin
- [geoipupdate](https://github.com/maxmind/geoipupdate), a GeoIP database updater from MaxMind. Available as [services.geoipupdate](options.html#opt-services.geoipupdate.enable).
- [Kea](https://www.isc.org/kea/), ISCs 2nd generation DHCP and DDNS server suite. Available at [services.kea](options.html#opt-services.kea).
- [sourcehut](https://sr.ht), a collection of tools useful for software development. Available as [services.sourcehut](options.html#opt-services.sourcehut.enable).
- [ucarp](https://download.pureftpd.org/pub/ucarp/README), an userspace implementation of the Common Address Redundancy Protocol (CARP). Available as [networking.ucarp](options.html#opt-networking.ucarp.enable).

View file

@ -727,6 +727,7 @@
./services/networking/iwd.nix
./services/networking/jicofo.nix
./services/networking/jitsi-videobridge.nix
./services/networking/kea.nix
./services/networking/keepalived/default.nix
./services/networking/keybase.nix
./services/networking/kippo.nix

View file

@ -180,7 +180,7 @@ let
serviceConfig.PrivateTmp = mkDefault true;
serviceConfig.WorkingDirectory = mkDefault /tmp;
serviceConfig.DynamicUser = mkDefault enableDynamicUser;
serviceConfig.User = conf.user;
serviceConfig.User = mkDefault conf.user;
serviceConfig.Group = conf.group;
} serviceOpts ]);
};

View file

@ -26,6 +26,7 @@ in {
};
serviceOpts = {
serviceConfig = {
User = "kea";
ExecStart = ''
${pkgs.prometheus-kea-exporter}/bin/kea-exporter \
--address ${cfg.listenAddress} \

View file

@ -0,0 +1,361 @@
{ config
, lib
, pkgs
, ...
}:
with lib;
let
cfg = config.services.kea;
format = pkgs.formats.json {};
ctrlAgentConfig = format.generate "kea-ctrl-agent.conf" {
Control-agent = cfg.ctrl-agent.settings;
};
dhcp4Config = format.generate "kea-dhcp4.conf" {
Dhcp4 = cfg.dhcp4.settings;
};
dhcp6Config = format.generate "kea-dhcp6.conf" {
Dhcp6 = cfg.dhcp6.settings;
};
dhcpDdnsConfig = format.generate "kea-dhcp-ddns.conf" {
DhcpDdns = cfg.dhcp-ddns.settings;
};
package = pkgs.kea;
in
{
options.services.kea = with types; {
ctrl-agent = mkOption {
description = ''
Kea Control Agent configuration
'';
default = {};
type = submodule {
options = {
enable = mkEnableOption "Kea Control Agent";
extraArgs = mkOption {
type = listOf str;
default = [];
description = ''
List of additonal arguments to pass to the daemon.
'';
};
settings = mkOption {
type = format.type;
default = null;
description = ''
Kea Control Agent configuration as an attribute set, see <link xlink:href="https://kea.readthedocs.io/en/kea-${package.version}/arm/agent.html"/>.
'';
};
};
};
};
dhcp4 = mkOption {
description = ''
DHCP4 Server configuration
'';
default = {};
type = submodule {
options = {
enable = mkEnableOption "Kea DHCP4 server";
extraArgs = mkOption {
type = listOf str;
default = [];
description = ''
List of additonal arguments to pass to the daemon.
'';
};
settings = mkOption {
type = format.type;
default = null;
example = {
valid-lifetime = 4000;
renew-timer = 1000;
rebind-timer = 2000;
interfaces-config = {
interfaces = [
"eth0"
];
};
lease-database = {
type = "memfile";
persist = true;
name = "/var/lib/kea/dhcp4.leases";
};
subnet4 = [ {
subnet = "192.0.2.0/24";
pools = [ {
pool = "192.0.2.100 - 192.0.2.240";
} ];
} ];
};
description = ''
Kea DHCP4 configuration as an attribute set, see <link xlink:href="https://kea.readthedocs.io/en/kea-${package.version}/arm/dhcp4-srv.html"/>.
'';
};
};
};
};
dhcp6 = mkOption {
description = ''
DHCP6 Server configuration
'';
default = {};
type = submodule {
options = {
enable = mkEnableOption "Kea DHCP6 server";
extraArgs = mkOption {
type = listOf str;
default = [];
description = ''
List of additonal arguments to pass to the daemon.
'';
};
settings = mkOption {
type = format.type;
default = null;
example = {
valid-lifetime = 4000;
renew-timer = 1000;
rebind-timer = 2000;
preferred-lifetime = 3000;
interfaces-config = {
interfaces = [
"eth0"
];
};
lease-database = {
type = "memfile";
persist = true;
name = "/var/lib/kea/dhcp6.leases";
};
subnet6 = [ {
subnet = "2001:db8:1::/64";
pools = [ {
pool = "2001:db8:1::1-2001:db8:1::ffff";
} ];
} ];
};
description = ''
Kea DHCP6 configuration as an attribute set, see <link xlink:href="https://kea.readthedocs.io/en/kea-${package.version}/arm/dhcp6-srv.html"/>.
'';
};
};
};
};
dhcp-ddns = mkOption {
description = ''
Kea DHCP-DDNS configuration
'';
default = {};
type = submodule {
options = {
enable = mkEnableOption "Kea DDNS server";
extraArgs = mkOption {
type = listOf str;
default = [];
description = ''
List of additonal arguments to pass to the daemon.
'';
};
settings = mkOption {
type = format.type;
default = null;
example = {
ip-address = "127.0.0.1";
port = 53001;
dns-server-timeout = 100;
ncr-protocol = "UDP";
ncr-format = "JSON";
tsig-keys = [ ];
forward-ddns = {
ddns-domains = [ ];
};
reverse-ddns = {
ddns-domains = [ ];
};
};
description = ''
Kea DHCP-DDNS configuration as an attribute set, see <link xlink:href="https://kea.readthedocs.io/en/kea-${package.version}/arm/ddns.html"/>.
'';
};
};
};
};
};
config = let
commonServiceConfig = {
ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID";
DynamicUser = true;
User = "kea";
ConfigurationDirectory = "kea";
RuntimeDirectory = "kea";
StateDirectory = "kea";
UMask = "0077";
};
in mkIf (cfg.ctrl-agent.enable || cfg.dhcp4.enable || cfg.dhcp6.enable || cfg.dhcp-ddns.enable) (mkMerge [
{
environment.systemPackages = [ package ];
}
(mkIf cfg.ctrl-agent.enable {
environment.etc."kea/ctrl-agent.conf".source = ctrlAgentConfig;
systemd.services.kea-ctrl-agent = {
description = "Kea Control Agent";
documentation = [
"man:kea-ctrl-agent(8)"
"https://kea.readthedocs.io/en/kea-${package.version}/arm/agent.html"
];
after = [
"network-online.target"
"time-sync.target"
];
wantedBy = [
"kea-dhcp4-server.service"
"kea-dhcp6-server.service"
"kea-dhcp-ddns-server.service"
];
environment = {
KEA_PIDFILE_DIR = "/run/kea";
};
serviceConfig = {
ExecStart = "${package}/bin/kea-ctrl-agent -c /etc/kea/ctrl-agent.conf ${lib.escapeShellArgs cfg.dhcp4.extraArgs}";
KillMode = "process";
Restart = "on-failure";
} // commonServiceConfig;
};
})
(mkIf cfg.dhcp4.enable {
environment.etc."kea/dhcp4-server.conf".source = dhcp4Config;
systemd.services.kea-dhcp4-server = {
description = "Kea DHCP4 Server";
documentation = [
"man:kea-dhcp4(8)"
"https://kea.readthedocs.io/en/kea-${package.version}/arm/dhcp4-srv.html"
];
after = [
"network-online.target"
"time-sync.target"
];
wantedBy = [
"multi-user.target"
];
environment = {
KEA_PIDFILE_DIR = "/run/kea";
};
serviceConfig = {
ExecStart = "${package}/bin/kea-dhcp4 -c /etc/kea/dhcp4-server.conf ${lib.escapeShellArgs cfg.dhcp4.extraArgs}";
# Kea does not request capabilities by itself
AmbientCapabilities = [
"CAP_NET_BIND_SERVICE"
"CAP_NET_RAW"
];
CapabilityBoundingSet = [
"CAP_NET_BIND_SERVICE"
"CAP_NET_RAW"
];
} // commonServiceConfig;
};
})
(mkIf cfg.dhcp6.enable {
environment.etc."kea/dhcp6-server.conf".source = dhcp6Config;
systemd.services.kea-dhcp6-server = {
description = "Kea DHCP6 Server";
documentation = [
"man:kea-dhcp6(8)"
"https://kea.readthedocs.io/en/kea-${package.version}/arm/dhcp6-srv.html"
];
after = [
"network-online.target"
"time-sync.target"
];
wantedBy = [
"multi-user.target"
];
environment = {
KEA_PIDFILE_DIR = "/run/kea";
};
serviceConfig = {
ExecStart = "${package}/bin/kea-dhcp6 -c /etc/kea/dhcp6-server.conf ${lib.escapeShellArgs cfg.dhcp6.extraArgs}";
# Kea does not request capabilities by itself
AmbientCapabilities = [
"CAP_NET_BIND_SERVICE"
];
CapabilityBoundingSet = [
"CAP_NET_BIND_SERVICE"
];
} // commonServiceConfig;
};
})
(mkIf cfg.dhcp-ddns.enable {
environment.etc."kea/dhcp-ddns.conf".source = dhcpDdnsConfig;
systemd.services.kea-dhcp-ddns-server = {
description = "Kea DHCP-DDNS Server";
documentation = [
"man:kea-dhcp-ddns(8)"
"https://kea.readthedocs.io/en/kea-${package.version}/arm/ddns.html"
];
after = [
"network-online.target"
"time-sync.target"
];
wantedBy = [
"multi-user.target"
];
environment = {
KEA_PIDFILE_DIR = "/run/kea";
};
serviceConfig = {
ExecStart = "${package}/bin/kea-dhcp-ddns -c /etc/kea/dhcp-ddns.conf ${lib.escapeShellArgs cfg.dhcp-ddns.extraArgs}";
AmbientCapabilites = [
"CAP_NET_BIND_SERVICE"
];
CapabilityBoundingSet = [
"CAP_NET_BIND_SERVICE"
];
} // commonServiceConfig;
};
})
]);
meta.maintainers = with maintainers; [ hexa ];
}

View file

@ -203,6 +203,7 @@ in
k3s = handleTest ./k3s.nix {};
kafka = handleTest ./kafka.nix {};
kbd-setfont-decompress = handleTest ./kbd-setfont-decompress.nix {};
kea = handleTest ./kea.nix {};
keepalived = handleTest ./keepalived.nix {};
keepassxc = handleTest ./keepassxc.nix {};
kerberos = handleTest ./kerberos/default.nix {};

73
nixos/tests/kea.nix Normal file
View file

@ -0,0 +1,73 @@
import ./make-test-python.nix ({ pkgs, lib, ...}: {
meta.maintainers = with lib.maintainers; [ hexa ];
nodes = {
router = { config, pkgs, ... }: {
virtualisation.vlans = [ 1 ];
networking = {
useNetworkd = true;
useDHCP = false;
firewall.allowedUDPPorts = [ 67 ];
};
systemd.network = {
networks = {
"01-eth1" = {
name = "eth1";
networkConfig = {
Address = "10.0.0.1/30";
};
};
};
};
services.kea.dhcp4 = {
enable = true;
settings = {
valid-lifetime = 3600;
renew-timer = 900;
rebind-timer = 1800;
lease-database = {
type = "memfile";
persist = true;
name = "/var/lib/kea/dhcp4.leases";
};
interfaces-config = {
dhcp-socket-type = "raw";
interfaces = [
"eth1"
];
};
subnet4 = [ {
subnet = "10.0.0.0/30";
pools = [ {
pool = "10.0.0.2 - 10.0.0.2";
} ];
} ];
};
};
};
client = { config, pkgs, ... }: {
virtualisation.vlans = [ 1 ];
systemd.services.systemd-networkd.environment.SYSTEMD_LOG_LEVEL = "debug";
networking = {
useNetworkd = true;
useDHCP = false;
firewall.enable = false;
interfaces.eth1.useDHCP = true;
};
};
};
testScript = { ... }: ''
start_all()
router.wait_for_unit("kea-dhcp4-server.service")
client.wait_for_unit("systemd-networkd-wait-online.service")
client.wait_until_succeeds("ping -c 5 10.0.0.1")
router.wait_until_succeeds("ping -c 5 10.0.0.2")
'';
})

View file

@ -326,49 +326,36 @@ let
'';
};
kea = {
kea = let
controlSocketPath = "/run/kea/dhcp6.sock";
in
{
exporterConfig = {
enable = true;
controlSocketPaths = [
"/run/kea/kea-dhcp6.sock"
controlSocketPath
];
};
metricProvider = {
users.users.kea = {
isSystemUser = true;
};
users.groups.kea = {};
systemd.services.prometheus-kea-exporter.after = [ "kea-dhcp6-server.service" ];
systemd.services.prometheus-kea-exporter.after = [ "kea-dhcp6.service" ];
systemd.services.kea-dhcp6 = let
configFile = pkgs.writeText "kea-dhcp6.conf" (builtins.toJSON {
Dhcp6 = {
"control-socket" = {
"socket-type" = "unix";
"socket-name" = "/run/kea/kea-dhcp6.sock";
services.kea = {
enable = true;
dhcp6 = {
enable = true;
settings = {
control-socket = {
socket-type = "unix";
socket-name = controlSocketPath;
};
};
});
in
{
after = [ "network.target" ];
wantedBy = [ "multi-user.target" ];
serviceConfig = {
DynamicUser = false;
User = "kea";
Group = "kea";
ExecStart = "${pkgs.kea}/bin/kea-dhcp6 -c ${configFile}";
StateDirectory = "kea";
RuntimeDirectory = "kea";
UMask = "0007";
};
};
};
exporterTest = ''
wait_for_unit("kea-dhcp6.service")
wait_for_file("/run/kea/kea-dhcp6.sock")
wait_for_unit("kea-dhcp6-server.service")
wait_for_file("${controlSocketPath}")
wait_for_unit("prometheus-kea-exporter.service")
wait_for_open_port(9547)
succeed(

View file

@ -8,7 +8,9 @@
, libmysqlclient
, log4cplus
, postgresql
, python3 }:
, python3
, nixosTests
}:
stdenv.mkDerivation rec {
pname = "kea";
@ -48,11 +50,15 @@ stdenv.mkDerivation rec {
enableParallelBuilding = true;
passthru.tests = {
inherit (nixosTests) kea;
};
meta = with lib; {
homepage = "https://kea.isc.org/";
description = "High-performance, extensible DHCP server by ISC";
longDescription = ''
KEA is a new open source DHCPv4/DHCPv6 server being developed by
Kea is a new open source DHCPv4/DHCPv6 server being developed by
Internet Systems Consortium. The objective of this project is to
provide a very high-performance, extensible DHCP server engine for
use by enterprises and service providers, either as is or with
@ -60,6 +66,6 @@ stdenv.mkDerivation rec {
'';
license = licenses.mpl20;
platforms = platforms.unix;
maintainers = with maintainers; [ fpletz ];
maintainers = with maintainers; [ fpletz hexa ];
};
}