at 24.11-pre 3.4 kB view raw
1{ config, lib, pkgs, ... }: 2 3let 4 inherit (lib) mkEnableOption mkPackageOption mkOption types mkIf maintainers; 5 6 cfg = config.security.isolate; 7 configFile = pkgs.writeText "isolate-config.cf" '' 8 box_root=${cfg.boxRoot} 9 lock_root=${cfg.lockRoot} 10 cg_root=${cfg.cgRoot} 11 first_uid=${toString cfg.firstUid} 12 first_gid=${toString cfg.firstGid} 13 num_boxes=${toString cfg.numBoxes} 14 restricted_init=${if cfg.restrictedInit then "1" else "0"} 15 ${cfg.extraConfig} 16 ''; 17 isolate = pkgs.symlinkJoin { 18 name = "isolate-wrapped-${pkgs.isolate.version}"; 19 20 paths = [ pkgs.isolate ]; 21 22 nativeBuildInputs = [ pkgs.makeWrapper ]; 23 24 postBuild = '' 25 wrapProgram $out/bin/isolate \ 26 --set ISOLATE_CONFIG_FILE ${configFile} 27 28 wrapProgram $out/bin/isolate-cg-keeper \ 29 --set ISOLATE_CONFIG_FILE ${configFile} 30 ''; 31 }; 32in 33{ 34 options.security.isolate = { 35 enable = mkEnableOption '' 36 Sandbox for securely executing untrusted programs 37 ''; 38 39 package = mkPackageOption pkgs "isolate-unwrapped" { }; 40 41 boxRoot = mkOption { 42 type = types.path; 43 default = "/var/lib/isolate/boxes"; 44 description = '' 45 All sandboxes are created under this directory. 46 To avoid symlink attacks, this directory and all its ancestors 47 must be writeable only by root. 48 ''; 49 }; 50 51 lockRoot = mkOption { 52 type = types.path; 53 default = "/run/isolate/locks"; 54 description = '' 55 Directory where lock files are created. 56 ''; 57 }; 58 59 cgRoot = mkOption { 60 type = types.str; 61 default = "auto:/run/isolate/cgroup"; 62 description = '' 63 Control group which subgroups are placed under. 64 Either an explicit path to a subdirectory in cgroupfs, or "auto:file" to read 65 the path from "file", where it is put by `isolate-cg-helper`. 66 ''; 67 }; 68 69 firstUid = mkOption { 70 type = types.numbers.between 1000 65533; 71 default = 60000; 72 description = '' 73 Start of block of UIDs reserved for sandboxes. 74 ''; 75 }; 76 77 firstGid = mkOption { 78 type = types.numbers.between 1000 65533; 79 default = 60000; 80 description = '' 81 Start of block of GIDs reserved for sandboxes. 82 ''; 83 }; 84 85 numBoxes = mkOption { 86 type = types.numbers.between 1000 65533; 87 default = 1000; 88 description = '' 89 Number of UIDs and GIDs to reserve, starting from 90 {option}`firstUid` and {option}`firstGid`. 91 ''; 92 }; 93 94 restrictedInit = mkOption { 95 type = types.bool; 96 default = false; 97 description = '' 98 If true, only root can create sandboxes. 99 ''; 100 }; 101 102 extraConfig = mkOption { 103 type = types.str; 104 default = ""; 105 description = '' 106 Extra configuration to append to the configuration file. 107 ''; 108 }; 109 }; 110 111 config = mkIf cfg.enable { 112 environment.systemPackages = [ 113 isolate 114 ]; 115 116 systemd.services.isolate = { 117 description = "Isolate control group hierarchy daemon"; 118 wantedBy = [ "multi-user.target" ]; 119 serviceConfig = { 120 Type = "notify"; 121 ExecStart = "${isolate}/bin/isolate-cg-keeper"; 122 Slice = "isolate.slice"; 123 Delegate = true; 124 }; 125 }; 126 127 systemd.slices.isolate = { 128 description = "Isolate sandbox slice"; 129 }; 130 131 meta.maintainers = with maintainers; [ virchau13 ]; 132 }; 133}