Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

nixos/security/sgx: init #129432

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions nixos/doc/manual/from_md/release-notes/rl-2111.section.xml
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,14 @@
<link xlink:href="options.html#opt-networking.ucarp.enable">networking.ucarp</link>.
</para>
</listitem>
<listitem>
<para>
<link xlink:href="https://software.intel.com/content/www/us/en/develop/topics/software-guard-extensions.html">sgx</link>,
support for Intel’s Software Guard Extensions (SGX) subsystem,
on supported platforms. Available as
<link xlink:href="options.html#opt-security.sgx.enable">security.sgx</link>.
</para>
</listitem>
<listitem>
<para>
Users of flashrom should migrate to
Expand Down
2 changes: 2 additions & 0 deletions nixos/doc/manual/release-notes/rl-2111.section.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ In addition to numerous new and upgraded packages, this release has the followin

- [ucarp](https://download.pureftpd.org/pub/ucarp/README), an userspace implementation of the Common Address Redundancy Protocol (CARP). Available as [networking.ucarp](options.html#opt-networking.ucarp.enable).

- [sgx](https://software.intel.com/content/www/us/en/develop/topics/software-guard-extensions.html), support for Intel's Software Guard Extensions (SGX) subsystem, on supported platforms. Available as [security.sgx](options.html#opt-security.sgx.enable).

- Users of flashrom should migrate to [programs.flashrom.enable](options.html#opt-programs.flashrom.enable) and add themselves to the `flashrom` group to be able to access programmers supported by flashrom.

## Backward Incompatibilities {#sec-release-21.11-incompatibilities}
Expand Down
1 change: 1 addition & 0 deletions nixos/modules/module-list.nix
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,7 @@
./security/polkit.nix
./security/rngd.nix
./security/rtkit.nix
./security/sgx.nix
./security/wrappers/default.nix
./security/sudo.nix
./security/doas.nix
Expand Down
167 changes: 167 additions & 0 deletions nixos/modules/security/sgx.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.security.sgx;
in
{
options.security.sgx = {
enable = mkEnableOption "Intel SGX";

config = mkOption {
type = types.lines;
default = "";
description = "Configuration for the SGX daemon.";
};

packages = {
psw = mkOption {
default = pkgs.intel-sgx-psw;
defaultText = "pkgs.intel-sgx-psw";
description = "The SGX PSW (platform software) package to use.";
};

sdk = mkOption {
default = pkgs.intel-sgx-sdk;
defaultText = "pkgs.intel-sgx-sdk";
description = "The SGX SDK (software development kit) package to use.";
};

driver = mkOption {
type = types.package;
default = pkgs.linuxPackages.isgx;
Copy link
Contributor

@blitz blitz Oct 14, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This needs to be config.boot.kernelPackages.isgx. Otherwise, it will mix up kernel modules and kernel with different versions.

As a side note: Newer kernels come with SGX support built-in, but I'm not sure whether this is a realistic option just yet.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using the in-tree SGX support works just fine! 🙂

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Then we could flip the SGX kernel option on for newer kernels by default and get rid of the third-party module.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll have a modern Atom to test this on next week or so.

defaultText = "pkgs.linuxPackages.isgx";
description = "The SGX driver package to use.";
};
};
};

config = mkIf cfg.enable {
boot.extraModulePackages = [ cfg.packages.driver ];
services.udev.packages = [ cfg.packages.psw ];

# aesmd depends on auditd
security.auditd.enable = true;

# write service config file
environment.etc."aesmd.conf".text = cfg.config;

# create service user and groups
users = {
users.aesmd = {
group = "aesmd";
isSystemUser = true;
extraGroups = [ "sgx_prv" ];
description = "Intel SGX Service Account";
};

groups = {
aesmd = { };
sgx_prv = { };
};
};

systemd.services.aesmd =
let
path = "${cfg.packages.psw}/aesm";
in
{
description = "Intel(R) Architectural Enclave Service Manager";
after = [ "syslog.target" "network.target" "auditd.service" ];
wantedBy = [ "multi-user.target" ];

# restart when config file changes
restartTriggers = [ config.environment.etc."aesmd.conf".source ];

environment = {
NAME = "aesm_service";
AESM_PATH = "/var/opt/aesmd";
LD_LIBRARY_PATH = "${cfg.packages.psw}/lib:${path}";
};

serviceConfig = {
ExecStart = "${path}/aesm_service --no-daemon";
ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID";
ExecStartPre = [ "${pkgs.coreutils}/bin/mkdir -p /var/opt/aesmd/data /var/opt/aesmd/fwdir/data" ];
Copy link
Member

@veehaitch veehaitch Aug 3, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could also leverage systemd sandboxing using StateDirectory and BindPaths to avoid the system-wide FHS path and tmpfiles.


Restart = "on-failure";
RestartSec = "15s";

# environment
User = "aesmd";
Group = "aesmd";

WorkingDirectory = "/var/opt/aesmd";
RuntimeDirectory = "aesmd";
RuntimeDirectoryMode = "0755";
ReadWritePaths = [ "/var/opt/aesmd" ];
Mic92 marked this conversation as resolved.
Show resolved Hide resolved

# Hardening
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I really appreciate all the effort you've put into hardening. We should definitely have that but I wonder how tried and tested this configuration is as the upstream service definition does not declare any hardening. Do you run this service in production somewhere or can you share any other experiences?

Copy link
Member

@Mic92 Mic92 Aug 4, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From my own experience with running aesmd and systemd hardening option, the option chosen here looks fine.
It looks scary of the high number but to be honest most services should not do the majority of options that were disabled here. I also prefer remove hardening afterwards rather than breaking existing setups by adding more hardening later.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Upstream probably don't care as much about adding them because they might target some old redhat linux that does not have those hardening options yet.

CapabilityBoundingSet = "";
DevicePolicy = "closed";
DeviceAllow = [
"/dev/isgx rw"
"/dev/sgx rw"
"/dev/sgx/enclave rw"
"/dev/sgx/provision rw"
];
IPAddressDeny = "any";
KeyringMode = "private";
LockPersonality = true;
MemoryDenyWriteExecute = false;
NoNewPrivileges = true;
NotifyAccess = "none";
ProcSubset = "pid";
RemoveIPC = true;

PrivateDevices = false;
PrivateMounts = true;
PrivateNetwork = false;
PrivateTmp = true;
PrivateUsers = true;

ProtectClock = true;
ProtectControlGroups = true;
ProtectHome = true;
ProtectKernelLogs = true;
ProtectKernelModules = true;
ProtectKernelTunables = true;
ProtectHostname = true;
ProtectProc = "invisible";
ProtectSystem = "strict";
RestrictAddressFamilies = [ "AF_UNIX" ];
Mic92 marked this conversation as resolved.
Show resolved Hide resolved
RestrictNamespaces = true;
RestrictRealtime = true;
RestrictSUIDSGID = true;

# needs the ipc syscall in order to run
SystemCallFilter = [
"@system-service"
"~@aio"
"~@clock"
"~@cpu-emulation"
"~@chown"
"~@debug"
"~@keyring"
"~@memlock"
"~@module"
"~@mount"
"~@raw-io"
"~@reboot"
"~@swap"
"~@privileged"
"~@resources"
"~@setuid"
"~@sync"
"~@timer"
];
SystemCallArchitectures = "native";
SystemCallErrorNumber = "EPERM";
};
};

systemd.tmpfiles.rules = [
"d /var/opt/aesmd 0750 aesmd aesmd - -"
"z /var/opt/aesmd 0750 aesmd aesmd - -"
];
};
}
Loading