lib.packagesFromDirectoryRecursive: Improved documentation (#359898)
[NixPkgs.git] / nixos / modules / services / security / endlessh-go.nix
blob9f9225994c7ff5c1f4491225eaa8d9cfb7b056ce
1 { config, lib, pkgs, ... }:
3 with lib;
5 let
6   cfg = config.services.endlessh-go;
7 in
9   options.services.endlessh-go = {
10     enable = mkEnableOption "endlessh-go service";
12     package = mkPackageOption pkgs "endlessh-go" { };
14     listenAddress = mkOption {
15       type = types.str;
16       default = "0.0.0.0";
17       example = "[::]";
18       description = ''
19         Interface address to bind the endlessh-go daemon to SSH connections.
20       '';
21     };
23     port = mkOption {
24       type = types.port;
25       default = 2222;
26       example = 22;
27       description = ''
28         Specifies on which port the endlessh-go daemon listens for SSH
29         connections.
31         Setting this to `22` may conflict with {option}`services.openssh`.
32       '';
33     };
35     prometheus = {
36       enable = mkEnableOption "Prometheus integration";
38       listenAddress = mkOption {
39         type = types.str;
40         default = "0.0.0.0";
41         example = "[::]";
42         description = ''
43           Interface address to bind the endlessh-go daemon to answer Prometheus
44           queries.
45         '';
46       };
48       port = mkOption {
49         type = types.port;
50         default = 2112;
51         example = 9119;
52         description = ''
53           Specifies on which port the endlessh-go daemon listens for Prometheus
54           queries.
55         '';
56       };
57     };
59     extraOptions = mkOption {
60       type = with types; listOf str;
61       default = [ ];
62       example = [ "-conn_type=tcp4" "-max_clients=8192" ];
63       description = ''
64         Additional command line options to pass to the endlessh-go daemon.
65       '';
66     };
68     openFirewall = mkOption {
69       type = types.bool;
70       default = false;
71       description = ''
72         Whether to open a firewall port for the SSH listener.
73       '';
74     };
75   };
77   config = mkIf cfg.enable {
78     systemd.services.endlessh-go = {
79       description = "SSH tarpit";
80       requires = [ "network.target" ];
81       wantedBy = [ "multi-user.target" ];
82       serviceConfig =
83         let
84           needsPrivileges = cfg.port < 1024 || cfg.prometheus.port < 1024;
85           capabilities = [ "" ] ++ optionals needsPrivileges [ "CAP_NET_BIND_SERVICE" ];
86           rootDirectory = "/run/endlessh-go";
87         in
88         {
89           Restart = "always";
90           ExecStart = with cfg; concatStringsSep " " ([
91             (lib.getExe cfg.package)
92             "-logtostderr"
93             "-host=${listenAddress}"
94             "-port=${toString port}"
95           ] ++ optionals prometheus.enable [
96             "-enable_prometheus"
97             "-prometheus_host=${prometheus.listenAddress}"
98             "-prometheus_port=${toString prometheus.port}"
99           ] ++ extraOptions);
100           DynamicUser = true;
101           RootDirectory = rootDirectory;
102           BindReadOnlyPaths = [ builtins.storeDir ];
103           InaccessiblePaths = [ "-+${rootDirectory}" ];
104           RuntimeDirectory = baseNameOf rootDirectory;
105           RuntimeDirectoryMode = "700";
106           AmbientCapabilities = capabilities;
107           CapabilityBoundingSet = capabilities;
108           UMask = "0077";
109           LockPersonality = true;
110           MemoryDenyWriteExecute = true;
111           NoNewPrivileges = true;
112           PrivateDevices = true;
113           PrivateTmp = true;
114           PrivateUsers = !needsPrivileges;
115           ProtectClock = true;
116           ProtectControlGroups = true;
117           ProtectHome = true;
118           ProtectHostname = true;
119           ProtectKernelLogs = true;
120           ProtectKernelModules = true;
121           ProtectKernelTunables = true;
122           ProtectSystem = "strict";
123           ProtectProc = "noaccess";
124           ProcSubset = "pid";
125           RemoveIPC = true;
126           RestrictAddressFamilies = [ "AF_INET" "AF_INET6" ];
127           RestrictNamespaces = true;
128           RestrictRealtime = true;
129           RestrictSUIDSGID = true;
130           SystemCallArchitectures = "native";
131           SystemCallFilter = [ "@system-service" "~@privileged" ];
132         };
133     };
135     networking.firewall.allowedTCPPorts = with cfg;
136       optionals openFirewall [ port ];
137   };
139   meta.maintainers = with maintainers; [ azahi ];