2022-10-22 17:37:56 +00:00
|
|
|
lib: pkgs: config:
|
2019-04-27 23:53:26 +00:00
|
|
|
|
|
|
|
with lib;
|
2021-02-03 21:44:41 +00:00
|
|
|
|
|
|
|
# See `man systemd.exec` and `man systemd.resource-control` for an explanation
|
2021-08-15 09:28:44 +00:00
|
|
|
# of the systemd-related options available through this file.
|
2020-09-08 12:25:33 +00:00
|
|
|
let self = {
|
2020-05-06 08:57:48 +00:00
|
|
|
# These settings roughly follow systemd's "strict" security profile
|
2019-04-27 19:21:45 +00:00
|
|
|
defaultHardening = {
|
2023-01-20 12:45:07 +00:00
|
|
|
PrivateTmp = true;
|
2020-05-05 15:15:16 +00:00
|
|
|
ProtectSystem = "strict";
|
2023-01-20 12:45:07 +00:00
|
|
|
ProtectHome = true;
|
|
|
|
NoNewPrivileges = true;
|
|
|
|
PrivateDevices = true;
|
|
|
|
MemoryDenyWriteExecute = true;
|
|
|
|
ProtectKernelTunables = true;
|
|
|
|
ProtectKernelModules = true;
|
|
|
|
ProtectKernelLogs = true;
|
|
|
|
ProtectClock = true;
|
2021-08-04 22:49:01 +00:00
|
|
|
ProtectProc = "invisible";
|
|
|
|
ProcSubset = "pid";
|
2023-01-20 12:45:07 +00:00
|
|
|
ProtectControlGroups = true;
|
2019-04-27 22:27:25 +00:00
|
|
|
RestrictAddressFamilies = "AF_UNIX AF_INET AF_INET6";
|
2023-01-20 12:45:07 +00:00
|
|
|
RestrictNamespaces = true;
|
|
|
|
LockPersonality = true;
|
2019-04-27 23:53:26 +00:00
|
|
|
IPAddressDeny = "any";
|
2023-01-20 12:45:07 +00:00
|
|
|
PrivateUsers = true;
|
|
|
|
RestrictSUIDSGID = true;
|
|
|
|
RemoveIPC = true;
|
|
|
|
RestrictRealtime = true;
|
|
|
|
ProtectHostname = true;
|
2020-05-05 13:27:07 +00:00
|
|
|
CapabilityBoundingSet = "";
|
2020-05-06 08:57:48 +00:00
|
|
|
# @system-service whitelist and docker seccomp blacklist (except for "clone"
|
|
|
|
# which is a core requirement for systemd services)
|
2021-02-01 21:53:08 +00:00
|
|
|
# @system-service is defined in src/shared/seccomp-util.c (systemd source)
|
2022-10-22 21:52:59 +00:00
|
|
|
SystemCallFilter = [ "@system-service" "~add_key kcmp keyctl mbind move_pages name_to_handle_at personality process_vm_readv process_vm_writev request_key setns unshare userfaultfd" ];
|
2021-02-01 21:53:10 +00:00
|
|
|
SystemCallArchitectures = "native";
|
2019-04-27 19:21:45 +00:00
|
|
|
};
|
2019-11-27 13:04:22 +00:00
|
|
|
|
2021-03-22 12:19:46 +00:00
|
|
|
allowNetlink = {
|
|
|
|
RestrictAddressFamilies = self.defaultHardening.RestrictAddressFamilies + " AF_NETLINK";
|
|
|
|
};
|
|
|
|
|
2022-07-14 21:45:27 +00:00
|
|
|
# nodejs applications require memory write execute for JIT compilation
|
2023-01-20 12:45:07 +00:00
|
|
|
nodejs = { MemoryDenyWriteExecute = false; };
|
2021-03-22 12:19:45 +00:00
|
|
|
|
|
|
|
# Allow takes precedence over Deny.
|
|
|
|
allowLocalIPAddresses = {
|
2022-05-07 18:34:21 +00:00
|
|
|
IPAddressAllow = [
|
|
|
|
"127.0.0.1/32"
|
|
|
|
"::1/128"
|
|
|
|
"169.254.0.0/16"
|
|
|
|
];
|
2019-04-28 18:54:13 +00:00
|
|
|
};
|
2021-03-22 12:19:45 +00:00
|
|
|
allowAllIPAddresses = { IPAddressAllow = "any"; };
|
|
|
|
allowTor = self.allowLocalIPAddresses;
|
|
|
|
allowedIPAddresses = onlyLocal:
|
|
|
|
if onlyLocal
|
|
|
|
then self.allowLocalIPAddresses
|
|
|
|
else self.allowAllIPAddresses;
|
2019-04-27 23:53:26 +00:00
|
|
|
|
2021-11-28 20:24:49 +00:00
|
|
|
tor = {
|
|
|
|
proxy = mkOption {
|
|
|
|
type = types.bool;
|
|
|
|
default = false;
|
|
|
|
description = "Whether to proxy outgoing connections with Tor.";
|
|
|
|
};
|
|
|
|
enforce = mkOption {
|
|
|
|
type = types.bool;
|
|
|
|
default = false;
|
|
|
|
description = ''
|
2022-07-14 21:45:27 +00:00
|
|
|
Whether to enforce Tor on this service by only allowing connections
|
2021-11-28 20:24:49 +00:00
|
|
|
from and to localhost and link-local addresses.
|
|
|
|
'';
|
|
|
|
};
|
2019-08-07 12:52:34 +00:00
|
|
|
};
|
2020-05-22 13:59:18 +00:00
|
|
|
|
2021-02-01 21:53:23 +00:00
|
|
|
script = name: src: pkgs.writers.writeBash name ''
|
2020-05-22 13:59:18 +00:00
|
|
|
set -eo pipefail
|
|
|
|
${src}
|
|
|
|
'';
|
2020-08-21 20:36:00 +00:00
|
|
|
|
2020-09-08 12:25:33 +00:00
|
|
|
# Used for ExecStart*
|
2021-08-15 09:28:34 +00:00
|
|
|
rootScript = name: src: "+${self.script name src}";
|
2020-09-08 12:25:33 +00:00
|
|
|
|
2020-08-21 20:36:00 +00:00
|
|
|
cliExec = mkOption {
|
|
|
|
# Used by netns-isolation to execute the cli in the service's private netns
|
|
|
|
internal = true;
|
|
|
|
type = types.str;
|
|
|
|
default = "exec";
|
|
|
|
};
|
2021-02-03 21:44:42 +00:00
|
|
|
|
2021-08-04 22:49:00 +00:00
|
|
|
mkOnionService = map: {
|
2021-02-03 21:44:42 +00:00
|
|
|
map = [ map ];
|
|
|
|
version = 3;
|
|
|
|
};
|
2021-10-01 09:51:57 +00:00
|
|
|
|
|
|
|
# Convert a bind address, which may be a special INADDR_ANY address,
|
|
|
|
# to an actual IP address
|
|
|
|
address = addr:
|
|
|
|
if addr == "0.0.0.0" then
|
|
|
|
"127.0.0.1"
|
|
|
|
else if addr == "::" then
|
|
|
|
"::1"
|
|
|
|
else
|
|
|
|
addr;
|
|
|
|
|
|
|
|
addressWithPort = addr: port: "${self.address addr}:${toString port}";
|
|
|
|
|
2022-05-14 13:21:37 +00:00
|
|
|
optionalAttr = cond: name: if cond then name else null;
|
|
|
|
|
2022-07-07 14:08:27 +00:00
|
|
|
mkCertExtraAltNames = cert:
|
|
|
|
builtins.concatStringsSep "," (
|
|
|
|
(map (domain: "DNS:${domain}") cert.extraDomains) ++
|
|
|
|
(map (ip: "IP:${ip}") cert.extraIPs)
|
|
|
|
);
|
|
|
|
|
2022-10-22 17:37:56 +00:00
|
|
|
test = {
|
|
|
|
mkIfTest = test: mkIf (config.tests.${test} or false);
|
|
|
|
};
|
|
|
|
|
2020-09-08 12:25:33 +00:00
|
|
|
}; in self
|