1{ config, lib, pkgs, ... }:
2with lib;
3let
4 cfg = config.services.tang;
5in
6{
7 options.services.tang = {
8 enable = mkEnableOption "tang";
9
10 package = mkOption {
11 type = types.package;
12 default = pkgs.tang;
13 defaultText = literalExpression "pkgs.tang";
14 description = "The tang package to use.";
15 };
16
17 listenStream = mkOption {
18 type = with types; listOf str;
19 default = [ "7654" ];
20 example = [ "198.168.100.1:7654" "[2001:db8::1]:7654" "7654" ];
21 description = ''
22 Addresses and/or ports on which tang should listen.
23 For detailed syntax see ListenStream in {manpage}`systemd.socket(5)`.
24 '';
25 };
26
27 ipAddressAllow = mkOption {
28 example = [ "192.168.1.0/24" ];
29 type = types.listOf types.str;
30 description = ''
31 Whitelist a list of address prefixes.
32 Preferably, internal addresses should be used.
33 '';
34 };
35
36 };
37 config = mkIf cfg.enable {
38 environment.systemPackages = [ cfg.package ];
39
40 systemd.services."tangd@" = {
41 description = "Tang server";
42 path = [ cfg.package ];
43 serviceConfig = {
44 StandardInput = "socket";
45 StandardOutput = "socket";
46 StandardError = "journal";
47 DynamicUser = true;
48 StateDirectory = "tang";
49 RuntimeDirectory = "tang";
50 StateDirectoryMode = "700";
51 UMask = "0077";
52 CapabilityBoundingSet = [ "" ];
53 ExecStart = "${cfg.package}/libexec/tangd %S/tang";
54 LockPersonality = true;
55 MemoryDenyWriteExecute = true;
56 NoNewPrivileges = true;
57 DeviceAllow = [ "/dev/stdin" ];
58 RestrictAddressFamilies = [ "AF_UNIX" ];
59 DevicePolicy = "strict";
60 PrivateDevices = true;
61 PrivateTmp = true;
62 PrivateUsers = true;
63 ProcSubset = "pid";
64 ProtectClock = true;
65 ProtectControlGroups = true;
66 ProtectHome = true;
67 ProtectHostname = true;
68 ProtectKernelLogs = true;
69 ProtectKernelModules = true;
70 ProtectKernelTunables = true;
71 ProtectProc = "invisible";
72 ProtectSystem = "strict";
73 RestrictNamespaces = true;
74 RestrictRealtime = true;
75 RestrictSUIDSGID = true;
76 SystemCallArchitectures = "native";
77 SystemCallFilter = [ "@system-service" "~@privileged" "~@resources" ];
78 IPAddressDeny = "any";
79 IPAddressAllow = cfg.ipAddressAllow;
80 };
81 };
82
83 systemd.sockets.tangd = {
84 description = "Tang server";
85 wantedBy = [ "sockets.target" ];
86 socketConfig = {
87 ListenStream = cfg.listenStream;
88 Accept = "yes";
89 IPAddressDeny = "any";
90 IPAddressAllow = cfg.ipAddressAllow;
91 };
92 };
93 };
94 meta.maintainers = with lib.maintainers; [ jfroche julienmalka ];
95}