python3Packages.orjson: Disable failing tests on 32 bit
[NixPkgs.git] / nixos / modules / services / security / aesmd.nix
blob7b0a46d6d029c8dca7fec96fc7a0448fb40f6116
1 { config, options, pkgs, lib, ... }:
2 with lib;
3 let
4   cfg = config.services.aesmd;
5   opt = options.services.aesmd;
7   sgx-psw = pkgs.sgx-psw.override { inherit (cfg) debug; };
9   configFile = with cfg.settings; pkgs.writeText "aesmd.conf" (
10     concatStringsSep "\n" (
11       optional (whitelistUrl != null) "whitelist url = ${whitelistUrl}" ++
12       optional (proxy != null) "aesm proxy = ${proxy}" ++
13       optional (proxyType != null) "proxy type = ${proxyType}" ++
14       optional (defaultQuotingType != null) "default quoting type = ${defaultQuotingType}" ++
15       # Newline at end of file
16       [ "" ]
17     )
18   );
21   options.services.aesmd = {
22     enable = mkEnableOption (lib.mdDoc "Intel's Architectural Enclave Service Manager (AESM) for Intel SGX");
23     debug = mkOption {
24       type = types.bool;
25       default = false;
26       description = lib.mdDoc "Whether to build the PSW package in debug mode.";
27     };
28     settings = mkOption {
29       description = lib.mdDoc "AESM configuration";
30       default = { };
31       type = types.submodule {
32         options.whitelistUrl = mkOption {
33           type = with types; nullOr str;
34           default = null;
35           example = "http://whitelist.trustedservices.intel.com/SGX/LCWL/Linux/sgx_white_list_cert.bin";
36           description = lib.mdDoc "URL to retrieve authorized Intel SGX enclave signers.";
37         };
38         options.proxy = mkOption {
39           type = with types; nullOr str;
40           default = null;
41           example = "http://proxy_url:1234";
42           description = lib.mdDoc "HTTP network proxy.";
43         };
44         options.proxyType = mkOption {
45           type = with types; nullOr (enum [ "default" "direct" "manual" ]);
46           default = if (cfg.settings.proxy != null) then "manual" else null;
47           defaultText = literalExpression ''
48             if (config.${opt.settings}.proxy != null) then "manual" else null
49           '';
50           example = "default";
51           description = lib.mdDoc ''
52             Type of proxy to use. The `default` uses the system's default proxy.
53             If `direct` is given, uses no proxy.
54             A value of `manual` uses the proxy from
55             {option}`services.aesmd.settings.proxy`.
56           '';
57         };
58         options.defaultQuotingType = mkOption {
59           type = with types; nullOr (enum [ "ecdsa_256" "epid_linkable" "epid_unlinkable" ]);
60           default = null;
61           example = "ecdsa_256";
62           description = lib.mdDoc "Attestation quote type.";
63         };
64       };
65     };
66   };
68   config = mkIf cfg.enable {
69     assertions = [{
70       assertion = !(config.boot.specialFileSystems."/dev".options ? "noexec");
71       message = "SGX requires exec permission for /dev";
72     }];
74     hardware.cpu.intel.sgx.provision.enable = true;
76     # Make sure the AESM service can find the SGX devices until
77     # https://github.com/intel/linux-sgx/issues/772 is resolved
78     # and updated in nixpkgs.
79     hardware.cpu.intel.sgx.enableDcapCompat = mkForce true;
81     systemd.services.aesmd =
82       let
83         storeAesmFolder = "${sgx-psw}/aesm";
84         # Hardcoded path AESM_DATA_FOLDER in psw/ae/aesm_service/source/oal/linux/aesm_util.cpp
85         aesmDataFolder = "/var/opt/aesmd/data";
86         aesmStateDirSystemd = "%S/aesmd";
87       in
88       {
89         description = "Intel Architectural Enclave Service Manager";
90         wantedBy = [ "multi-user.target" ];
92         after = [
93           "auditd.service"
94           "network.target"
95           "syslog.target"
96         ];
98         environment = {
99           NAME = "aesm_service";
100           AESM_PATH = storeAesmFolder;
101           LD_LIBRARY_PATH = storeAesmFolder;
102         };
104         # Make sure any of the SGX application enclave devices is available
105         unitConfig.AssertPathExists = [
106           # legacy out-of-tree driver
107           "|/dev/isgx"
108           # DCAP driver
109           "|/dev/sgx/enclave"
110           # in-tree driver
111           "|/dev/sgx_enclave"
112         ];
114         serviceConfig = rec {
115           ExecStartPre = pkgs.writeShellScript "copy-aesmd-data-files.sh" ''
116             set -euo pipefail
117             whiteListFile="${aesmDataFolder}/white_list_cert_to_be_verify.bin"
118             if [[ ! -f "$whiteListFile" ]]; then
119               ${pkgs.coreutils}/bin/install -m 644 -D \
120                 "${storeAesmFolder}/data/white_list_cert_to_be_verify.bin" \
121                 "$whiteListFile"
122             fi
123           '';
124           ExecStart = "${sgx-psw}/bin/aesm_service --no-daemon";
125           ExecReload = ''${pkgs.coreutils}/bin/kill -SIGHUP "$MAINPID"'';
127           Restart = "on-failure";
128           RestartSec = "15s";
130           DynamicUser = true;
131           Group = "sgx";
132           SupplementaryGroups = [
133             config.hardware.cpu.intel.sgx.provision.group
134           ];
136           Type = "simple";
138           WorkingDirectory = storeAesmFolder;
139           StateDirectory = "aesmd";
140           StateDirectoryMode = "0700";
141           RuntimeDirectory = "aesmd";
142           RuntimeDirectoryMode = "0750";
144           # Hardening
146           # chroot into the runtime directory
147           RootDirectory = "%t/aesmd";
148           BindReadOnlyPaths = [
149             builtins.storeDir
150             # Hardcoded path AESM_CONFIG_FILE in psw/ae/aesm_service/source/utils/aesm_config.cpp
151             "${configFile}:/etc/aesmd.conf"
152           ];
153           BindPaths = [
154             # Hardcoded path CONFIG_SOCKET_PATH in psw/ae/aesm_service/source/core/ipc/SocketConfig.h
155             "%t/aesmd:/var/run/aesmd"
156             "%S/aesmd:/var/opt/aesmd"
157           ];
159           # PrivateDevices=true will mount /dev noexec which breaks AESM
160           PrivateDevices = false;
161           DevicePolicy = "closed";
162           DeviceAllow = [
163             # legacy out-of-tree driver
164             "/dev/isgx rw"
165             # DCAP driver
166             "/dev/sgx rw"
167             # in-tree driver
168             "/dev/sgx_enclave rw"
169             "/dev/sgx_provision rw"
170           ];
172           # Requires Internet access for attestation
173           PrivateNetwork = false;
175           RestrictAddressFamilies = [
176             # Allocates the socket /var/run/aesmd/aesm.socket
177             "AF_UNIX"
178             # Uses the HTTP protocol to initialize some services
179             "AF_INET"
180             "AF_INET6"
181           ];
183           # True breaks stuff
184           MemoryDenyWriteExecute = false;
186           # needs the ipc syscall in order to run
187           SystemCallFilter = [
188             "@system-service"
189             "~@aio"
190             "~@chown"
191             "~@clock"
192             "~@cpu-emulation"
193             "~@debug"
194             "~@keyring"
195             "~@memlock"
196             "~@module"
197             "~@mount"
198             "~@privileged"
199             "~@raw-io"
200             "~@reboot"
201             "~@resources"
202             "~@setuid"
203             "~@swap"
204             "~@sync"
205             "~@timer"
206           ];
207           SystemCallArchitectures = "native";
208           SystemCallErrorNumber = "EPERM";
210           CapabilityBoundingSet = "";
211           KeyringMode = "private";
212           LockPersonality = true;
213           NoNewPrivileges = true;
214           NotifyAccess = "none";
215           PrivateMounts = true;
216           PrivateTmp = true;
217           PrivateUsers = true;
218           ProcSubset = "pid";
219           ProtectClock = true;
220           ProtectControlGroups = true;
221           ProtectHome = true;
222           ProtectHostname = true;
223           ProtectKernelLogs = true;
224           ProtectKernelModules = true;
225           ProtectKernelTunables = true;
226           ProtectProc = "invisible";
227           ProtectSystem = "strict";
228           RemoveIPC = true;
229           RestrictNamespaces = true;
230           RestrictRealtime = true;
231           RestrictSUIDSGID = true;
232           UMask = "0066";
233         };
234       };
235   };