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