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