1
0
Fork 0
mirror of https://github.com/NixOS/nixpkgs.git synced 2025-06-28 03:56:48 +03:00
nixpkgs/nixos/modules/services/networking/ndppd.nix
Silvan Mosberger 374e6bcc40 treewide: Format all Nix files
Format all Nix files using the officially approved formatter,
making the CI check introduced in the previous commit succeed:

  nix-build ci -A fmt.check

This is the next step of the of the [implementation](https://github.com/NixOS/nixfmt/issues/153)
of the accepted [RFC 166](https://github.com/NixOS/rfcs/pull/166).

This commit will lead to merge conflicts for a number of PRs,
up to an estimated ~1100 (~33%) among the PRs with activity in the past 2
months, but that should be lower than what it would be without the previous
[partial treewide format](https://github.com/NixOS/nixpkgs/pull/322537).

Merge conflicts caused by this commit can now automatically be resolved while rebasing using the
[auto-rebase script](8616af08d9/maintainers/scripts/auto-rebase).

If you run into any problems regarding any of this, please reach out to the
[formatting team](https://nixos.org/community/teams/formatting/) by
pinging @NixOS/nix-formatting.
2025-04-01 20:10:43 +02:00

210 lines
6.2 KiB
Nix

{
config,
lib,
pkgs,
...
}:
with lib;
let
cfg = config.services.ndppd;
render = s: f: concatStringsSep "\n" (mapAttrsToList f s);
prefer = a: b: if a != null then a else b;
ndppdConf = prefer cfg.configFile (
pkgs.writeText "ndppd.conf" ''
route-ttl ${toString cfg.routeTTL}
${render cfg.proxies (
proxyInterfaceName: proxy: ''
proxy ${prefer proxy.interface proxyInterfaceName} {
router ${boolToString proxy.router}
timeout ${toString proxy.timeout}
ttl ${toString proxy.ttl}
${render proxy.rules (
ruleNetworkName: rule: ''
rule ${prefer rule.network ruleNetworkName} {
${rule.method}${optionalString (rule.method == "iface") " ${rule.interface}"}
}''
)}
}''
)}
''
);
proxy = types.submodule {
options = {
interface = mkOption {
type = types.nullOr types.str;
description = ''
Listen for any Neighbor Solicitation messages on this interface,
and respond to them according to a set of rules.
Defaults to the name of the attrset.
'';
default = null;
};
router = mkOption {
type = types.bool;
description = ''
Turns on or off the router flag for Neighbor Advertisement Messages.
'';
default = true;
};
timeout = mkOption {
type = types.int;
description = ''
Controls how long to wait for a Neighbor Advertisement Message before
invalidating the entry, in milliseconds.
'';
default = 500;
};
ttl = mkOption {
type = types.int;
description = ''
Controls how long a valid or invalid entry remains in the cache, in
milliseconds.
'';
default = 30000;
};
rules = mkOption {
type = types.attrsOf rule;
description = ''
This is a rule that the target address is to match against. If no netmask
is provided, /128 is assumed. You may have several rule sections, and the
addresses may or may not overlap.
'';
default = { };
};
};
};
rule = types.submodule {
options = {
network = mkOption {
type = types.nullOr types.str;
description = ''
This is the target address is to match against. If no netmask
is provided, /128 is assumed. The addresses of several rules
may or may not overlap.
Defaults to the name of the attrset.
'';
default = null;
};
method = mkOption {
type = types.enum [
"static"
"iface"
"auto"
];
description = ''
static: Immediately answer any Neighbor Solicitation Messages
(if they match the IP rule).
iface: Forward the Neighbor Solicitation Message through the specified
interface and only respond if a matching Neighbor Advertisement
Message is received.
auto: Same as iface, but instead of manually specifying the outgoing
interface, check for a matching route in /proc/net/ipv6_route.
'';
default = "auto";
};
interface = mkOption {
type = types.nullOr types.str;
description = "Interface to use when method is iface.";
default = null;
};
};
};
in
{
options.services.ndppd = {
enable = mkEnableOption "daemon that proxies NDP (Neighbor Discovery Protocol) messages between interfaces";
interface = mkOption {
type = types.nullOr types.str;
description = ''
Interface which is on link-level with router.
(Legacy option, use services.ndppd.proxies.\<interface\>.rules.\<network\> instead)
'';
default = null;
example = "eth0";
};
network = mkOption {
type = types.nullOr types.str;
description = ''
Network that we proxy.
(Legacy option, use services.ndppd.proxies.\<interface\>.rules.\<network\> instead)
'';
default = null;
example = "1111::/64";
};
configFile = mkOption {
type = types.nullOr types.path;
description = "Path to configuration file.";
default = null;
};
routeTTL = mkOption {
type = types.int;
description = ''
This tells 'ndppd' how often to reload the route file /proc/net/ipv6_route,
in milliseconds.
'';
default = 30000;
};
proxies = mkOption {
type = types.attrsOf proxy;
description = ''
This sets up a listener, that will listen for any Neighbor Solicitation
messages, and respond to them according to a set of rules.
'';
default = { };
example = literalExpression ''
{
eth0.rules."1111::/64" = {};
}
'';
};
};
config = mkIf cfg.enable {
warnings = mkIf (cfg.interface != null && cfg.network != null) [
''
The options services.ndppd.interface and services.ndppd.network will probably be removed soon,
please use services.ndppd.proxies.<interface>.rules.<network> instead.
''
];
services.ndppd.proxies = mkIf (cfg.interface != null && cfg.network != null) {
${cfg.interface}.rules.${cfg.network} = { };
};
systemd.services.ndppd = {
description = "NDP Proxy Daemon";
documentation = [
"man:ndppd(1)"
"man:ndppd.conf(5)"
];
after = [ "network-pre.target" ];
wantedBy = [ "multi-user.target" ];
serviceConfig = {
ExecStart = "${pkgs.ndppd}/bin/ndppd -c ${ndppdConf}";
# Sandboxing
CapabilityBoundingSet = "CAP_NET_RAW CAP_NET_ADMIN";
ProtectSystem = "strict";
ProtectHome = true;
PrivateTmp = true;
PrivateDevices = true;
ProtectKernelTunables = true;
ProtectKernelModules = true;
ProtectControlGroups = true;
RestrictAddressFamilies = "AF_INET6 AF_PACKET AF_NETLINK";
RestrictNamespaces = true;
LockPersonality = true;
MemoryDenyWriteExecute = true;
RestrictRealtime = true;
RestrictSUIDSGID = true;
};
};
};
}