at 23.11-pre 3.4 kB view raw
1{ config, lib, pkgs, ... }: 2 3with lib; 4 5let 6 cfg = config.programs.firejail; 7 8 wrappedBins = pkgs.runCommand "firejail-wrapped-binaries" 9 { preferLocalBuild = true; 10 allowSubstitutes = false; 11 # take precedence over non-firejailed versions 12 meta.priority = -1; 13 } 14 '' 15 mkdir -p $out/bin 16 mkdir -p $out/share/applications 17 ${lib.concatStringsSep "\n" (lib.mapAttrsToList (command: value: 18 let 19 opts = if builtins.isAttrs value 20 then value 21 else { executable = value; desktop = null; profile = null; extraArgs = []; }; 22 args = lib.escapeShellArgs ( 23 opts.extraArgs 24 ++ (optional (opts.profile != null) "--profile=${toString opts.profile}") 25 ); 26 in 27 '' 28 cat <<_EOF >$out/bin/${command} 29 #! ${pkgs.runtimeShell} -e 30 exec /run/wrappers/bin/firejail ${args} -- ${toString opts.executable} "\$@" 31 _EOF 32 chmod 0755 $out/bin/${command} 33 34 ${lib.optionalString (opts.desktop != null) '' 35 substitute ${opts.desktop} $out/share/applications/$(basename ${opts.desktop}) \ 36 --replace ${opts.executable} $out/bin/${command} 37 ''} 38 '') cfg.wrappedBinaries)} 39 ''; 40 41in { 42 options.programs.firejail = { 43 enable = mkEnableOption (lib.mdDoc "firejail"); 44 45 wrappedBinaries = mkOption { 46 type = types.attrsOf (types.either types.path (types.submodule { 47 options = { 48 executable = mkOption { 49 type = types.path; 50 description = lib.mdDoc "Executable to run sandboxed"; 51 example = literalExpression ''"''${lib.getBin pkgs.firefox}/bin/firefox"''; 52 }; 53 desktop = mkOption { 54 type = types.nullOr types.path; 55 default = null; 56 description = lib.mkDoc ".desktop file to modify. Only necessary if it uses the absolute path to the executable."; 57 example = literalExpression ''"''${pkgs.firefox}/share/applications/firefox.desktop"''; 58 }; 59 profile = mkOption { 60 type = types.nullOr types.path; 61 default = null; 62 description = lib.mdDoc "Profile to use"; 63 example = literalExpression ''"''${pkgs.firejail}/etc/firejail/firefox.profile"''; 64 }; 65 extraArgs = mkOption { 66 type = types.listOf types.str; 67 default = []; 68 description = lib.mdDoc "Extra arguments to pass to firejail"; 69 example = [ "--private=~/.firejail_home" ]; 70 }; 71 }; 72 })); 73 default = {}; 74 example = literalExpression '' 75 { 76 firefox = { 77 executable = "''${lib.getBin pkgs.firefox}/bin/firefox"; 78 profile = "''${pkgs.firejail}/etc/firejail/firefox.profile"; 79 }; 80 mpv = { 81 executable = "''${lib.getBin pkgs.mpv}/bin/mpv"; 82 profile = "''${pkgs.firejail}/etc/firejail/mpv.profile"; 83 }; 84 } 85 ''; 86 description = lib.mdDoc '' 87 Wrap the binaries in firejail and place them in the global path. 88 ''; 89 }; 90 }; 91 92 config = mkIf cfg.enable { 93 security.wrappers.firejail = 94 { setuid = true; 95 owner = "root"; 96 group = "root"; 97 source = "${lib.getBin pkgs.firejail}/bin/firejail"; 98 }; 99 100 environment.systemPackages = [ pkgs.firejail ] ++ [ wrappedBins ]; 101 }; 102 103 meta.maintainers = with maintainers; [ peterhoeg ]; 104}