Files
roowho2/nix/module.nix
T

255 lines
8.3 KiB
Nix

{ config, pkgs, lib, utils, ... }:
let
cfg = config.services.roowho2;
format = pkgs.formats.toml { };
in {
options.services.roowho2 = {
enable = lib.mkEnableOption "the roowho2 daemon, replacement for multiple linux netkit services";
package = lib.mkPackageOption pkgs "roowho2" { };
settings = lib.mkOption {
type = lib.types.submodule {
freeformType = format.type;
options = {
log_level = lib.mkOption {
type = lib.types.enum [ "info" "debug" "trace" ];
default = "info";
description = "Log level for the roowho2 daemon.";
};
rwhod = {
enable = lib.mkEnableOption "the rwhod service" // {
default = true;
};
ignore_list_path = lib.mkOption {
type = lib.types.nullOr lib.types.path;
default = null;
example = lib.literalExpression ''
pkgs.writeText "rwhod-ignore-list" '''
# Ignore the following users from rwhod
user:user1
user:user2
uid:1001
'''
'';
description = "Path to the ignore list for users that should be hidden from rwhod.";
};
interfaces = lib.mkOption {
type = with lib.types; nullOr (listOf str);
default = null;
example = [ "eth0" "wlan0" ];
description = ''
List of network interfaces to broadcast rwhod packets on.
If set to `null`, rwhod will try to autodetect all reasonable interfaces
to broadcast on, and use all of them.
If set to an empty list, rwhod will not broadcast on any interfaces,
and will only listen for incoming packets.
'';
};
socketConfig = lib.mkOption {
type = utils.systemdUtils.unitOptions.unitOption;
default = { };
description = ''
Config for the systemd socket's `[Socket]` section.
See {manpage}`systemd.socket(5)` for details.
'';
example = {
IPAddressDeny = "any";
IPAddressAllow = [
"127.0.0.1"
];
};
};
};
fingerd = {
enable = lib.mkEnableOption "the fingerd service" // {
default = true;
};
ignore_list_path = lib.mkOption {
type = lib.types.nullOr lib.types.path;
default = null;
example = lib.literalExpression ''
pkgs.writeText "fingerd-ignore-list" '''
# Ignore the following users from rwhod
user:user1
user:user2
uid:1001
'''
'';
description = "Path to the ignore list for users that should be hidden from fingerd.";
};
# enable_remote_finger = lib.mkOption {
# type = lib.types.bool;
# default = false;
# example = true;
# description = ''
# Whether to allow remote finger requests.
# If set to false, only local finger requests will be served.
# '';
# };
# socketConfig = lib.mkOption {
# type = utils.systemdUtils.unitOptions.unitOption;
# default = { };
# description = ''
# Config for the systemd socket's `[Socket]` section.
# See {manpage}`systemd.socket(5)` for details.
# ::: {.note}
# This is only relevant if `enableRemoteFinger` is `true`.
# :::
# '';
# example = {
# IPAddressDeny = "any";
# IPAddressAllow = [
# "127.0.0.1"
# ];
# };
# };
};
};
};
default = { };
description = "Configuration settings for Roowho2.";
};
};
config = lib.mkIf cfg.enable {
systemd.sockets.roowho2-client = {
wantedBy = [ "sockets.target" ];
description = "Roowho2 Client Communication Socket";
listenStreams = [ "/run/roowho2/roowho2.varlink" ];
socketConfig = {
Service = "roowho2.service";
FileDescriptorName = "client_socket";
};
};
systemd.sockets.roowho2-rwhod = lib.mkIf cfg.settings.rwhod.enable {
wantedBy = [ "sockets.target" ];
description = "Roowho2 Rwhod Socket";
listenDatagrams = [ "0.0.0.0:513" ];
socketConfig = {
Service = "roowho2.service";
FileDescriptorName = "rwhod_socket";
Broadcast = true;
} // cfg.settings.rwhod.socketConfig;
};
# systemd.sockets.roowho2-fingerd = lib.mkIf cfg.settings.fingerd.enable && cfg.settings.fingerd.enableRemoteFinger {
# wantedBy = [ "sockets.target" ];
# description = "Roowho2 Fingerd Socket";
# listenStreams = [ "0.0.0.0:79" ];
# socketConfig = {
# Service = "roowho2.service";
# FileDescriptorName = "fingerd_socket";
# } // cfg.settings.fingerd.socketConfig;
# };
systemd.services.roowho2 = {
serviceConfig = {
Type = "notify";
ExecStart = let
configFile = lib.pipe cfg.settings [
(lib.filterAttrsRecursive (n: v: v != null))
(settings: lib.recursiveUpdate settings {
rwhod = lib.removeAttrs settings.rwhod [ "socketConfig" ];
fingerd = lib.removeAttrs settings.fingerd [ "socketConfig" ];
})
(format.generate "roowho2-config.toml")
];
in "${lib.getExe' cfg.package "roowhod"} --config ${configFile}";
Restart = "on-failure";
DynamicUser = true;
# NOTE: roowho2 might at some point need to read from home directories
# to get user settings, so let's keep these disabled for now.
# PrivateUsers = true;
# ProtectHome = true;
# NOTE: We need this capability to be able to read inside the home directories of users without
# them needing to open their homedirs to the rest of the system.
AmbientCapabilities = [ "CAP_DAC_READ_SEARCH" ];
CapabilityBoundingSet = [ "CAP_DAC_READ_SEARCH" ];
DeviceAllow = "";
DevicePolicy = "closed";
LockPersonality = true;
MemoryDenyWriteExecute = true;
NoNewPrivileges = true;
PrivateDevices = true;
# NOTE: all ipc traffic is served through the socket activation fds or provided by systemd
PrivateIPC = true;
PrivateMounts = true;
PrivateTmp = true;
ProcSubset = "pid";
ProtectClock = true;
ProtectControlGroups = "strict";
ProtectHostname = true;
ProtectKernelLogs = true;
ProtectKernelModules = true;
ProtectKernelTunables = true;
ProtectProc = "invisible";
RemoveIPC = true;
RestrictAddressFamilies = [
"AF_INET"
"AF_INET6"
"AF_UNIX"
"AF_NETLINK"
];
RestrictNamespaces = true;
RestrictRealtime = true;
RestrictSUIDSGID = true;
SocketBindDeny = "any";
SystemCallArchitectures = "native";
SystemCallFilter = [
"@system-service"
"~@privileged"
"~@resources"
];
RuntimeDirectory = "roowho2/root-mnt";
RuntimeDirectoryMode = "0700";
RootDirectory = "/run/roowho2/root-mnt";
BindReadOnlyPaths = lib.filter (x: x != null) ([
builtins.storeDir
"/etc"
# NOTE: need logind socket for utmp entries
"/run/systemd"
"/home"
# NOTE: finger might need access to mail directories
"-/var/spool"
"-/var/mail"
# NOTE: finger needs access to stat tty devices
"/dev"
] ++ lib.optionals cfg.settings.rwhod.enable [
cfg.settings.rwhod.ignore_list_path
] ++ lib.optionals cfg.settings.fingerd.enable [
cfg.settings.fingerd.ignore_list_path
]);
UMask = "0077";
};
};
networking.firewall.allowedUDPPorts = lib.mkIf cfg.settings.rwhod.enable [ 513 ];
environment.systemPackages = [ cfg.package ];
};
}