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