summaryrefslogtreecommitdiffstats
path: root/nixos/modules/security/isolate.nix
diff options
context:
space:
mode:
Diffstat (limited to 'nixos/modules/security/isolate.nix')
-rw-r--r--nixos/modules/security/isolate.nix133
1 files changed, 133 insertions, 0 deletions
diff --git a/nixos/modules/security/isolate.nix b/nixos/modules/security/isolate.nix
new file mode 100644
index 000000000000..3cc0176f3db3
--- /dev/null
+++ b/nixos/modules/security/isolate.nix
@@ -0,0 +1,133 @@
+{ config, lib, pkgs, ... }:
+
+let
+ inherit (lib) mkEnableOption mkPackageOption mkOption types mkIf maintainers;
+
+ cfg = config.security.isolate;
+ configFile = pkgs.writeText "isolate-config.cf" ''
+ box_root=${cfg.boxRoot}
+ lock_root=${cfg.lockRoot}
+ cg_root=${cfg.cgRoot}
+ first_uid=${toString cfg.firstUid}
+ first_gid=${toString cfg.firstGid}
+ num_boxes=${toString cfg.numBoxes}
+ restricted_init=${if cfg.restrictedInit then "1" else "0"}
+ ${cfg.extraConfig}
+ '';
+ isolate = pkgs.symlinkJoin {
+ name = "isolate-wrapped-${pkgs.isolate.version}";
+
+ paths = [ pkgs.isolate ];
+
+ nativeBuildInputs = [ pkgs.makeWrapper ];
+
+ postBuild = ''
+ wrapProgram $out/bin/isolate \
+ --set ISOLATE_CONFIG_FILE ${configFile}
+
+ wrapProgram $out/bin/isolate-cg-keeper \
+ --set ISOLATE_CONFIG_FILE ${configFile}
+ '';
+ };
+in
+{
+ options.security.isolate = {
+ enable = mkEnableOption ''
+ Sandbox for securely executing untrusted programs
+ '';
+
+ package = mkPackageOption pkgs "isolate-unwrapped" { };
+
+ boxRoot = mkOption {
+ type = types.path;
+ default = "/var/lib/isolate/boxes";
+ description = ''
+ All sandboxes are created under this directory.
+ To avoid symlink attacks, this directory and all its ancestors
+ must be writeable only by root.
+ '';
+ };
+
+ lockRoot = mkOption {
+ type = types.path;
+ default = "/run/isolate/locks";
+ description = ''
+ Directory where lock files are created.
+ '';
+ };
+
+ cgRoot = mkOption {
+ type = types.str;
+ default = "auto:/run/isolate/cgroup";
+ description = ''
+ Control group which subgroups are placed under.
+ Either an explicit path to a subdirectory in cgroupfs, or "auto:file" to read
+ the path from "file", where it is put by `isolate-cg-helper`.
+ '';
+ };
+
+ firstUid = mkOption {
+ type = types.numbers.between 1000 65533;
+ default = 60000;
+ description = ''
+ Start of block of UIDs reserved for sandboxes.
+ '';
+ };
+
+ firstGid = mkOption {
+ type = types.numbers.between 1000 65533;
+ default = 60000;
+ description = ''
+ Start of block of GIDs reserved for sandboxes.
+ '';
+ };
+
+ numBoxes = mkOption {
+ type = types.numbers.between 1000 65533;
+ default = 1000;
+ description = ''
+ Number of UIDs and GIDs to reserve, starting from
+ {option}`firstUid` and {option}`firstGid`.
+ '';
+ };
+
+ restrictedInit = mkOption {
+ type = types.bool;
+ default = false;
+ description = ''
+ If true, only root can create sandboxes.
+ '';
+ };
+
+ extraConfig = mkOption {
+ type = types.str;
+ default = "";
+ description = ''
+ Extra configuration to append to the configuration file.
+ '';
+ };
+ };
+
+ config = mkIf cfg.enable {
+ environment.systemPackages = [
+ isolate
+ ];
+
+ systemd.services.isolate = {
+ description = "Isolate control group hierarchy daemon";
+ wantedBy = [ "multi-user.target" ];
+ serviceConfig = {
+ Type = "notify";
+ ExecStart = "${isolate}/bin/isolate-cg-keeper";
+ Slice = "isolate.slice";
+ Delegate = true;
+ };
+ };
+
+ systemd.slices.isolate = {
+ description = "Isolate sandbox slice";
+ };
+
+ meta.maintainers = with maintainers; [ virchau13 ];
+ };
+}