mirror of
https://gitlab.com/d3tn/ud3tn.git
synced 2026-08-13 12:33:27 +02:00
This function is used to: 1. open firewall ports for configured CLAs 2. check for misconfigurations caused by duplicate ports However, there was a logical issue that caused false-positives. Signed-off-by: Maximilian Nitsch <maximilian.nitsch@d3tn.com>
339 lines
9.6 KiB
Nix
339 lines
9.6 KiB
Nix
# SPDX-License-Identifier: BSD-3-Clause OR Apache-2.0
|
|
|
|
{
|
|
config,
|
|
lib,
|
|
pkgs,
|
|
...
|
|
}:
|
|
|
|
let
|
|
cfg = config.services.ud3tn;
|
|
|
|
mkClaOptions =
|
|
{
|
|
defaultPort,
|
|
enable ? true,
|
|
addActiveOption ? false,
|
|
}:
|
|
{
|
|
enable = lib.mkOption {
|
|
description = "Whether to enable the CLA.";
|
|
default = enable;
|
|
type = lib.types.bool;
|
|
};
|
|
|
|
host = lib.mkOption {
|
|
description = "IP address / host name that the CLA should listen on.";
|
|
default = "*";
|
|
type = lib.types.str;
|
|
};
|
|
|
|
port = lib.mkOption {
|
|
description = "Port number that the CLA should listen on.";
|
|
default = defaultPort;
|
|
type = lib.types.port;
|
|
};
|
|
}
|
|
// lib.optionalAttrs addActiveOption {
|
|
active = lib.mkOption {
|
|
description = ''
|
|
If true the provided host name or IP address and port number are used for initiating a TCP
|
|
connection.
|
|
'';
|
|
default = false;
|
|
type = lib.types.bool;
|
|
};
|
|
};
|
|
|
|
ud3tnOptions = {
|
|
options = {
|
|
enable = lib.mkEnableOption "μD3TN";
|
|
|
|
aap = {
|
|
host = lib.mkOption {
|
|
description = "IP / hostname of the application agent service.";
|
|
default = null;
|
|
example = [
|
|
"127.0.0.1"
|
|
"localhost"
|
|
"::"
|
|
"::1"
|
|
"dtn.example"
|
|
];
|
|
type = with lib.types; nullOr str;
|
|
};
|
|
|
|
port = lib.mkOption {
|
|
description = "Port number of the application agent service.";
|
|
default = null;
|
|
type = with lib.types; nullOr port;
|
|
};
|
|
};
|
|
|
|
aap2 = {
|
|
host = lib.mkOption {
|
|
description = "IP / hostname of the application agent v2 service.";
|
|
default = null;
|
|
example = [
|
|
"127.0.0.1"
|
|
"localhost"
|
|
"::"
|
|
"::1"
|
|
"dtn.example"
|
|
];
|
|
type = with lib.types; nullOr str;
|
|
};
|
|
|
|
port = lib.mkOption {
|
|
description = "Port number of the application agent v2 service.";
|
|
default = null;
|
|
type = with lib.types; nullOr port;
|
|
};
|
|
};
|
|
|
|
allowRemoteConfig = lib.mkOption {
|
|
description = ''
|
|
Allow configuration via bundles received from CLAs or from unauthorized AAP clients.
|
|
'';
|
|
default = false;
|
|
type = lib.types.bool;
|
|
};
|
|
|
|
bdmSecretFile = lib.mkOption {
|
|
description = ''
|
|
Restrict AAP 2.0 BDM functions to clients providing the secret in the give file."
|
|
'';
|
|
type = lib.types.path;
|
|
};
|
|
|
|
bpVersion = lib.mkOption {
|
|
description = "Bundle protocol version of bundles created via AAP/AAP2.";
|
|
default = 7;
|
|
type = lib.types.enum [
|
|
6
|
|
7
|
|
];
|
|
};
|
|
|
|
cla = {
|
|
mtcp = mkClaOptions { defaultPort = 4224; };
|
|
smtcp = mkClaOptions {
|
|
defaultPort = 4222;
|
|
addActiveOption = true;
|
|
};
|
|
sqlite = {
|
|
enable = lib.mkOption {
|
|
description = "Whether to enable the SQLiteCLA.";
|
|
default = true;
|
|
type = lib.types.bool;
|
|
};
|
|
};
|
|
tcpclv3 = mkClaOptions { defaultPort = 4556; };
|
|
tcpspp = mkClaOptions {
|
|
defaultPort = 4223;
|
|
enable = false;
|
|
addActiveOption = true;
|
|
};
|
|
};
|
|
|
|
nodeId = lib.mkOption {
|
|
description = "Local node identifier.";
|
|
default = "dtn://ud3tn.dtn/";
|
|
example = [
|
|
"dtn://ud3tn.dtn/"
|
|
"ipn:1.0"
|
|
];
|
|
type = lib.types.str;
|
|
};
|
|
|
|
externalDispatch = lib.mkOption {
|
|
description = "Do not load the internal minimal router, allow for using an AAP 2.0 BDM.";
|
|
default = false;
|
|
type = lib.types.bool;
|
|
};
|
|
|
|
lifetime = lib.mkOption {
|
|
description = "Lifetime in seconds of bundles created via AAP.";
|
|
default = 86400;
|
|
type = lib.types.ints.positive;
|
|
};
|
|
|
|
logLevel = lib.mkOption {
|
|
description = "Higher or lower log level 1|2|3 specifies more or less detailed output.";
|
|
default = 1;
|
|
type = lib.types.enum [
|
|
1
|
|
2
|
|
3
|
|
];
|
|
};
|
|
|
|
maxBundleSize = lib.mkOption {
|
|
description = ''
|
|
Threshold used to determine if a bundle has to be fragmented.
|
|
The effective threshold will be determined as the minimum of this argument and all
|
|
maximum bundle sizes reported by the activated CLAs. A value of zero means "unlimited"
|
|
(2^64 bytes).
|
|
'';
|
|
default = 0;
|
|
type = lib.types.ints.unsigned;
|
|
};
|
|
|
|
openFirewall = lib.mkOption {
|
|
description = "Open firewall ports.";
|
|
default = false;
|
|
type = lib.types.bool;
|
|
};
|
|
|
|
statusReports = lib.mkOption {
|
|
description = "Enable status reporting.";
|
|
default = false;
|
|
type = lib.types.bool;
|
|
};
|
|
};
|
|
};
|
|
|
|
mkPortList =
|
|
_: cfg:
|
|
lib.mapAttrsToList (_: cla: cla.port) (lib.filterAttrs (_: cla: cla.enable && cla ? port) cfg.cla);
|
|
|
|
mkNetworkingConfig = _: cfg: {
|
|
firewall.allowedTCPPorts = lib.mkIf cfg.openFirewall (mkPortList _ cfg);
|
|
};
|
|
|
|
mkServiceConfig =
|
|
name: cfg:
|
|
let
|
|
mkClaStr =
|
|
clas:
|
|
(lib.concatStrings (
|
|
lib.attrsets.mapAttrsToList (
|
|
name:
|
|
cla@{
|
|
enable,
|
|
host,
|
|
port,
|
|
...
|
|
}:
|
|
(lib.optionalString enable (
|
|
"${name}:${host},${toString port}"
|
|
+ lib.optionalString (cla ? "active") ",${lib.boolToString cla.active}"
|
|
+ ";"
|
|
))
|
|
) (lib.attrsets.filterAttrs (_: v: v ? "host" && v ? "port") clas)
|
|
++ lib.optional (clas.sqlite.enable) "sqlite:/var/lib/ud3tn@${name}/u3dtn.sqlite;"
|
|
));
|
|
in
|
|
{
|
|
"ud3tn@${name}" = lib.mkIf cfg.enable {
|
|
wantedBy = [ "multi-user.target" ];
|
|
environment."UD3TN_BDM_SECRET" = (builtins.readFile cfg.bdmSecretFile);
|
|
serviceConfig = {
|
|
RuntimeDirectory = "ud3tn@${name}"; # created in /run/
|
|
StateDirectory = "ud3tn@${name}"; # created in /var/lib/
|
|
ExecStart = lib.concatStringsSep " " (
|
|
[
|
|
"${pkgs.ud3tn}/bin/ud3tn"
|
|
"--bdm-secret-var UD3TN_BDM_SECRET"
|
|
"--bp-version ${toString cfg.bpVersion}"
|
|
"--cla ${mkClaStr cfg.cla}"
|
|
"--node-id ${cfg.nodeId}"
|
|
"--lifetime ${toString cfg.lifetime}"
|
|
"--log-level ${toString cfg.logLevel}"
|
|
"--max-bundle-size ${toString cfg.maxBundleSize}"
|
|
]
|
|
# If a UNIX and a TCP socket parameter is provided, μD3TN favours the UNIX socket, so
|
|
# the --aap-socket parameter is only set if neither aap.host nor aap.port is defined
|
|
++ lib.optional (
|
|
cfg.aap.host == null && cfg.aap.port == null
|
|
) "--aap-socket /run/ud3tn@${name}/aap.socket"
|
|
++ lib.optional (cfg.aap.host != null) "--aap-host ${cfg.aap.host}"
|
|
++ lib.optional (cfg.aap.port != null) "--aap-port ${toString cfg.aap.port}"
|
|
++ lib.optional (
|
|
cfg.aap2.host == null && cfg.aap2.port == null
|
|
) "--aap2-socket /run/ud3tn@${name}/aap2.socket"
|
|
++ lib.optional (cfg.aap2.host != null) "--aap2-host ${cfg.aap2.host}"
|
|
++ lib.optional (cfg.aap2.port != null) "--aap2-port ${toString cfg.aap2.port}"
|
|
++ lib.optional cfg.allowRemoteConfig "--allow-remote-config"
|
|
++ lib.optional cfg.externalDispatch "--external-dispatch"
|
|
++ lib.optional cfg.statusReports "--status-reports"
|
|
);
|
|
};
|
|
};
|
|
};
|
|
in
|
|
|
|
{
|
|
options.services.ud3tn = lib.mkOption {
|
|
type = lib.types.attrsOf (lib.types.submodule ud3tnOptions);
|
|
default = { };
|
|
description = "Attribute set to configure multiple μD3TN instances";
|
|
example = lib.literalExpression ''
|
|
{
|
|
services.ud3tn.a = {
|
|
enable = true;
|
|
bdmSecretFile = /var/lib/ud3tn@a/bdm-secret;
|
|
};
|
|
|
|
services.ud3tn.b = {
|
|
enable = true;
|
|
openFirewall = true;
|
|
aap = {
|
|
host = "0.0.0.0";
|
|
port = 2345;
|
|
};
|
|
aap2 = {
|
|
host = "::0";
|
|
port = 5432;
|
|
};
|
|
allowRemoteConfig = true;
|
|
bdmSecretFile = /var/lib/ud3tn@b/bdm-secret;
|
|
bpVersion = 6;
|
|
cla = {
|
|
mtcp = {
|
|
host = "0.0.0.0";
|
|
port = 3456;
|
|
};
|
|
smtcp = {
|
|
host = "localhost";
|
|
port = 4567;
|
|
active = true;
|
|
};
|
|
tcpclv3 = {
|
|
host = "::";
|
|
port = 5678;
|
|
};
|
|
tcpspp = {
|
|
host = "::1";
|
|
port = 6789;
|
|
active = true;
|
|
};
|
|
};
|
|
nodeId = "dtn://ud3tn-b.dtn/";
|
|
externalDispatch = true;
|
|
lifetime = 43200;
|
|
logLevel = 3;
|
|
maxBundleSize = 4294967295; # u32_max
|
|
statusReports = true;
|
|
};
|
|
}
|
|
'';
|
|
};
|
|
|
|
config = {
|
|
assertions = [
|
|
{
|
|
assertion = (lib.lists.allUnique (lib.lists.flatten (lib.attrsets.mapAttrsToList mkPortList cfg)));
|
|
message = ''
|
|
Colliding port definitions.
|
|
Make sure that you configure different ports when operating multiple μD3TN instances.
|
|
'';
|
|
}
|
|
];
|
|
|
|
networking = lib.mkMerge (lib.attrsets.mapAttrsToList mkNetworkingConfig cfg);
|
|
|
|
systemd.services = lib.mkMerge (lib.attrsets.mapAttrsToList mkServiceConfig cfg);
|
|
};
|
|
}
|