tlsrpt-reporter: init at 0.5.0 (#415483)

This commit is contained in:
Martin Weinelt
2025-06-18 03:47:15 +02:00
committed by GitHub
6 changed files with 434 additions and 0 deletions
@@ -24,6 +24,8 @@
- [LACT](https://github.com/ilya-zlobintsev/LACT), a GPU monitoring and configuration tool, can now be enabled through [services.lact.enable](#opt-services.lact.enable).
Note that for LACT to work properly on AMD GPU systems, you need to enable [hardware.amdgpu.overdrive.enable](#opt-hardware.amdgpu.overdrive.enable).
- [tlsrpt-reporter], an application suite to generate and deliver TLSRPT reports. Available as [services.tlsrpt](#opt-services.tlsrpt.enable).
- [Broadcast Box](https://github.com/Glimesh/broadcast-box), a WebRTC broadcast server. Available as [services.broadcast-box](options.html#opt-services.broadcast-box.enable).
- Docker now defaults to 28.x, because version 27.x stopped receiving security updates and bug fixes after [May 2, 2025](https://github.com/moby/moby/pull/49910).
+1
View File
@@ -754,6 +754,7 @@
./services/mail/spamassassin.nix
./services/mail/stalwart-mail.nix
./services/mail/sympa.nix
./services/mail/tlsrpt.nix
./services/mail/zeyple.nix
./services/matrix/appservice-discord.nix
./services/matrix/appservice-irc.nix
+324
View File
@@ -0,0 +1,324 @@
{
config,
lib,
pkgs,
...
}:
let
inherit (lib)
mkEnableOption
mkIf
mkOption
mkPackageOption
types
;
cfg = config.services.tlsrpt;
format = pkgs.formats.ini { };
dropNullValues = lib.filterAttrsRecursive (_: value: value != null);
commonServiceSettings = {
DynamicUser = true;
User = "tlsrpt";
Restart = "always";
StateDirectory = "tlsrpt";
StateDirectoryMode = "0700";
# Hardening
CapabilityBoundingSet = [ "" ];
LockPersonality = true;
MemoryDenyWriteExecute = true;
PrivateDevices = true;
PrivateUsers = false;
ProcSubset = "pid";
ProtectControlGroups = true;
ProtectClock = true;
ProtectHome = true;
ProtectHostname = true;
ProtectKernelLogs = true;
ProtectKernelModules = true;
ProtectKernelTunables = true;
ProtectProc = "noaccess";
RestrictNamespaces = true;
RestrictRealtime = true;
SystemCallArchitectures = "native";
SystemCallFilter = [
"@system-service"
"~@privileged @resources"
];
};
in
{
options.services.tlsrpt = {
enable = mkEnableOption "the TLSRPT services";
package = mkPackageOption pkgs "tlsrpt-reporter" { };
collectd = {
settings = mkOption {
type = types.submodule {
freeformType = format.type;
options = {
storage = mkOption {
type = types.str;
default = "sqlite:///var/lib/tlsrpt/collectd.sqlite";
description = ''
Storage backend definition.
'';
};
socketname = mkOption {
type = types.path;
default = "/run/tlsrpt/collectd.sock";
description = ''
Path at which the UNIX socket will be created.
'';
};
socketmode = mkOption {
type = types.str;
default = "0220";
description = ''
Permissions on the UNIX socket.
'';
};
log_level = mkOption {
type = types.enum [
"debug"
"info"
"warning"
"error"
"critical"
];
default = "info";
description = ''
Level of log messages to emit.
'';
};
};
};
default = { };
description = ''
Flags from {manpage}`tlsrpt-collectd(1)` as key-value pairs.
'';
};
extraFlags = mkOption {
type = with types; listOf str;
default = [ ];
description = ''
List of extra flags to pass to the tlsrpt-reportd executable.
See {manpage}`tlsrpt-collectd(1)` for possible flags.
'';
};
configurePostfix = mkOption {
type = types.bool;
default = true;
description = ''
Whether to modify the local Postfix service to grant access to the collectd socket.
'';
};
};
fetcher = {
settings = mkOption {
type = types.submodule {
freeformType = format.type;
options = {
storage = mkOption {
type = types.str;
default = config.services.tlsrpt.collectd.settings.storage;
defaultText = lib.literalExpression ''
config.services.tlsrpt.collectd.settings.storage
'';
description = ''
Path to the collectd sqlite database.
'';
};
log_level = mkOption {
type = types.enum [
"debug"
"info"
"warning"
"error"
"critical"
];
default = "info";
description = ''
Level of log messages to emit.
'';
};
};
};
default = { };
description = ''
Flags from {manpage}`tlsrpt-fetcher(1)` as key-value pairs.
'';
};
};
reportd = {
settings = mkOption {
type = types.submodule {
freeformType = format.type;
options = {
dbname = mkOption {
type = types.str;
default = "/var/lib/tlsrpt/reportd.sqlite";
description = ''
Path to the sqlite database.
'';
};
fetchers = mkOption {
type = types.str;
default = lib.getExe' cfg.package "tlsrpt-fetcher";
defaultText = lib.literalExpression ''
lib.getExe' cfg.package "tlsrpt-fetcher"
'';
description = ''
Comma-separated list of fetcher programs that retrieve collectd data.
'';
};
log_level = mkOption {
type = types.enum [
"debug"
"info"
"warning"
"error"
"critical"
];
default = "info";
description = ''
Level of log messages to emit.
'';
};
organization_name = mkOption {
type = types.str;
example = "ACME Corp.";
description = ''
Name of the organization sending out the reports.
'';
};
contact_info = mkOption {
type = types.str;
example = "smtp-tls-reporting@example.com";
description = ''
Contact information embedded into the reports.
'';
};
sender_address = mkOption {
type = types.str;
example = "noreply@example.com";
description = ''
Sender address used for reports.
'';
};
sendmail_script = mkOption {
type = with types; nullOr str;
default = if config.services.postfix.enable then "sendmail" else null;
defaultText = lib.literalExpression ''
if any [ config.services.postfix.enable ] then "sendmail" else null
'';
description = ''
Path to a sendmail-compatible executable for delivery reports.
'';
};
};
};
default = { };
description = ''
Flags from {manpage}`tlsrpt-reportd(1)` as key-value pairs.
'';
};
extraFlags = mkOption {
type = with types; listOf str;
default = [ ];
description = ''
List of extra flags to pass to the tlsrpt-reportd executable.
See {manpage}`tlsrpt-report(1)` for possible flags.
'';
};
};
};
config = mkIf cfg.enable {
environment.etc = {
"tlsrpt/collectd.cfg".source = format.generate "tlsrpt-collectd.cfg" {
tlsrpt_collectd = dropNullValues cfg.collectd.settings;
};
"tlsrpt/fetcher.cfg".source = format.generate "tlsrpt-fetcher.cfg" {
tlsrpt_fetcher = dropNullValues cfg.fetcher.settings;
};
"tlsrpt/reportd.cfg".source = format.generate "tlsrpt-reportd.cfg" {
tlsrpt_reportd = dropNullValues cfg.reportd.settings;
};
};
systemd.services.postfix.serviceConfig.SupplementaryGroups = mkIf (
config.services.postfix.enable && cfg.collectd.configurePostfix
) [ "tlsrpt" ];
systemd.services.tlsrpt-collectd = {
description = "TLSRPT datagram collector";
documentation = [ "man:tlsrpt-collectd(1)" ];
wantedBy = [ "multi-user.target" ];
restartTriggers = [ "/etc/tlsrpt/collectd.cfg" ];
serviceConfig = commonServiceSettings // {
ExecStart = toString (
[
(lib.getExe' cfg.package "tlsrpt-collectd")
]
++ cfg.collectd.extraFlags
);
IPAddressDeny = "any";
PrivateNetwork = true;
RestrictAddressFamilies = [ "AF_UNIX" ];
RuntimeDirectory = "tlsrpt";
RuntimeDirectoryMode = "0750";
UMask = "0157";
};
};
systemd.services.tlsrpt-reportd = {
description = "TLSRPT report generator";
documentation = [ "man:tlsrpt-reportd(1)" ];
wantedBy = [ "multi-user.target" ];
restartTriggers = [ "/etc/tlsrpt/reportd.cfg" ];
serviceConfig = commonServiceSettings // {
ExecStart = toString (
[
(lib.getExe' cfg.package "tlsrpt-reportd")
]
++ cfg.reportd.extraFlags
);
RestrictAddressFamilies = [
"AF_INET"
"AF_INET6"
];
UMask = "0077";
};
};
};
}
+1
View File
@@ -1398,6 +1398,7 @@ in
tinydns = runTest ./tinydns.nix;
tinyproxy = runTest ./tinyproxy.nix;
tinywl = runTest ./tinywl.nix;
tlsrpt = runTest ./tlsrpt.nix;
tmate-ssh-server = runTest ./tmate-ssh-server.nix;
tomcat = runTest ./tomcat.nix;
tor = runTest ./tor.nix;
+41
View File
@@ -0,0 +1,41 @@
{
pkgs,
...
}:
{
name = "tlsrpt";
meta = {
inherit (pkgs.tlsrpt-reporter.meta) maintainers;
};
nodes.machine = {
services.tlsrpt = {
enable = true;
reportd.settings = {
organization_name = "NixOS Testers United";
contact_info = "smtp-tls-report@localhost";
sender_address = "noreply@localhost";
};
};
# To test the postfix integration
services.postfix.enable = true;
};
testScript = ''
machine.wait_for_unit("tlsrpt-collectd.service")
machine.wait_for_unit("tlsrpt-reportd.service")
machine.wait_for_file("/run/tlsrpt/collectd.sock")
machine.wait_until_succeeds("journalctl -o cat -u tlsrpt-collectd | grep -Pq 'Database .* setup finished'")
machine.wait_until_succeeds("journalctl -o cat -u tlsrpt-reportd | grep -Pq 'Database .* setup finished'")
# Enabling postfix should put sendmail as the sendmail setting
machine.succeed("grep -q sendmail_script=sendmail /etc/tlsrpt/reportd.cfg")
machine.succeed("systemctl show --property SupplementaryGroups postfix.service | grep tlsrpt")
machine.log(machine.succeed("systemd-analyze security tlsrpt-collectd.service tlsrpt-reportd.service | grep -v "))
'';
}
@@ -0,0 +1,65 @@
{
lib,
asciidoctor,
automake,
installShellFiles,
python3,
fetchFromGitHub,
nixosTests,
}:
python3.pkgs.buildPythonApplication rec {
pname = "tlsrpt-reporter";
version = "0.5.0";
pyproject = true;
outputs = [
"out"
"man"
];
src = fetchFromGitHub {
owner = "sys4";
repo = "tlsrpt-reporter";
tag = "v${version}";
hash = "sha256-IH8hJX9l+YonqOuszcMome4mjdIaedgGNIptxTyH1ng=";
};
nativeBuildInputs = [
asciidoctor
automake
installShellFiles
];
build-system = [
python3.pkgs.hatchling
];
postBuild = ''
make -C doc
'';
postInstall = ''
installManPage doc/*.1
'';
nativeCheckInputs = [
python3.pkgs.pytestCheckHook
];
pythonImportsCheck = [
"tlsrpt_reporter"
];
passthru.tests = {
inherit (nixosTests) tlsrpt;
};
meta = {
description = "Application suite to receive TLSRPT datagrams and to generate and deliver TLSRPT reports";
homepage = "https://github.com/sys4/tlsrpt-reporter";
changelog = "https://github.com/sys4/tlsrpt-reporter/blob/${src.tag}/CHANGELOG.md";
license = lib.licenses.gpl3Only;
maintainers = with lib.maintainers; [ hexa ];
};
}