Linux desktop application sandbox.
Go to file
Ophestra Umiker 45fead18c3
cmd/fshim: set no_new_privs flag
Signed-off-by: Ophestra Umiker <cat@ophivana.moe>
2024-11-09 11:50:56 +09:00
.gitea/workflows workflows: build all packages with full ldflags 2024-11-04 13:43:57 +09:00
acl add package doc comments 2024-10-28 20:57:59 +09:00
cmd cmd/fshim: set no_new_privs flag 2024-11-09 11:50:56 +09:00
dbus add package doc comments 2024-10-28 20:57:59 +09:00
helper add package doc comments 2024-10-28 20:57:59 +09:00
internal app: support full /dev access 2024-11-06 03:49:39 +09:00
ldd add package doc comments 2024-10-28 20:57:59 +09:00
xcb add package doc comments 2024-10-28 20:57:59 +09:00
.gitignore rename to fortify and restructure 2024-09-04 01:20:12 +09:00
LICENSE apply MIT license 2024-07-16 20:49:00 +09:00
README.md nix: improve start script 2024-11-06 14:09:41 +09:00
error.go fmsg: support temporarily withholding output 2024-10-26 23:09:32 +09:00
flake.lock nix: implement nixos module 2024-09-04 17:03:21 +09:00
flake.nix fsu: implement simple setuid user switcher 2024-10-28 00:02:34 +09:00
go.mod migrate to git.ophivana.moe/security/fortify 2024-10-20 19:50:13 +09:00
main.go fortify: root check before command handling 2024-11-05 12:57:03 +09:00
nixos.nix nix: remove absolute Exec paths 2024-11-08 02:05:47 +09:00
package.nix nix: keep fshim and finit names 2024-11-06 14:59:28 +09:00

README.md

Fortify

Go Reference Go Report Card

Lets you run graphical applications as another user in a confined environment with a nice NixOS module to configure target users and provide launchers and desktop files for your privileged user.

Why would you want this?

  • It protects the desktop environment from applications.

  • It protects applications from each other.

  • It provides UID isolation on top of the standard application sandbox.

There are a few different things to set up for this to work:

  • A set of users, each for a group of applications that should be allowed access to each other

  • A tool to switch users, currently sudo and machinectl are supported.

  • If you are running NixOS, the module in this repository can take care of launchers and desktop files in the privileged user's environment, as well as packages and extra home-manager configuration for target users.

If you have a flakes-enabled nix environment, you can try out the tool by running:

nix run git+https://git.ophivana.moe/security/fortify -- -h

Module usage

The NixOS module currently requires home-manager and impermanence to function correctly.

To use the module, import it into your configuration with

{
  inputs = {
    nixpkgs.url = "github:NixOS/nixpkgs/nixos-24.05";

    fortify = {
      url = "git+https://git.ophivana.moe/security/fortify";

      # Optional but recommended to limit the size of your system closure.
      inputs.nixpkgs.follows = "nixpkgs";
    };
  };

  outputs = { self, nixpkgs, fortify, ... }:
  {
    nixosConfigurations.fortify = nixpkgs.lib.nixosSystem {
      system = "x86_64-linux";
      modules = [
        fortify.nixosModules.fortify
      ];
    };
  };
}

This adds the environment.fortify option:

{ pkgs, ... }:

{
  environment.fortify = {
    enable = true;
    user = "nixos";
    stateDir = "/var/lib/persist/module";
    target = {
      chronos = {
        launchers = {
          weechat.method = "sudo";
          claws-mail.capability.pulse = false;

          discord = {
            id = "dev.vencord.Vesktop";
            command = "vesktop --ozone-platform-hint=wayland";
            userns = true;
            useRealUid = true;
            dbus = {
              session =
                f:
                f {
                  talk = [ "org.kde.StatusNotifierWatcher" ];
                  own = [ ];
                  call = { };
                  broadcast = { };
                };
              system.filter = true;
            };
            share = pkgs.vesktop;
          };

          chromium = {
            id = "org.chromium.Chromium";
            userns = true;
            useRealUid = true;
            dbus = {
              system = {
                filter = true;
                talk = [
                  "org.bluez"
                  "org.freedesktop.Avahi"
                  "org.freedesktop.UPower"
                ];
              };
              session = f: f {
                talk = [
                  "org.freedesktop.DBus"
                  "org.freedesktop.FileManager1"
                  "org.freedesktop.Notifications"
                  "org.freedesktop.ScreenSaver"
                  "org.freedesktop.secrets"
                  "org.kde.kwalletd5"    
                  "org.kde.kwalletd6"
                ];   
                own = [
                  "org.chromium.Chromium.*"
                  "org.mpris.MediaPlayer2.org.chromium.Chromium.*"
                  "org.mpris.MediaPlayer2.chromium.*"
                ];
                call = { };
                broadcast = { };
              };
            };
          };
        };
        packages = with pkgs; [
          weechat
          claws-mail
          vesktop
          chromium
        ];
        persistence.directories = [
          ".config/weechat"
          ".claws-mail"
          ".config/vesktop"
        ];
        extraConfig = {
          programs.looking-glass-client.enable = true;
        };
      };
    };
  };
}
  • enable determines whether the module should be enabled or not. Useful when sharing configurations between graphical and headless systems. Defaults to false.

  • user specifies the privileged user with access to fortified applications.

  • stateDir is the path to your persistent storage location. It is directly passed through to the impermanence module.

  • target is an attribute set of submodules, where the attribute name is the username of the unprivileged target user.

    The available options are:

    • packages, the list of packages to make available in the target user's environment.

    • persistence, user persistence attribute set passed to impermanence.

    • extraConfig, extra home-manager configuration for the target user.

    • launchers, attribute set where the attribute name is the name of the launcher.

      The available options are:

      • id, the freedesktop application ID, primarily used by dbus, null to disable.

      • script, application launch script.

      • command, the command to run as the target user. Defaults to launcher name. Has no effect when script is set.

      • dbus.session, D-Bus session proxy custom configuration.

      • dbus.configSystem, D-Bus system proxy custom configuration, null to disable.

      • env, attrset of environment variables to set for the initial process in the sandbox.

      • nix, whether to allow nix daemon connections from within the sandbox.

      • userns, whether to allow userns within the sandbox.

      • useRealUid, whether to map to the real UID within the sandbox.

      • net, whether to allow network access within the sandbox.

      • gpu, target process GPU and driver access, null to follow Wayland or X capability.

      • dev, whether to allow full device access within the sandbox.

      • extraPaths, a list of extra paths to make available inside the sandbox.

      • capability.wayland, whether to share the Wayland socket.

      • capability.x11, whether to share the X11 socket and allow connection.

      • capability.dbus, whether to proxy D-Bus.

      • capability.pulse, whether to share the PulseAudio socket and cookie.

      • share, package containing desktop/icon files. Defaults to launcher name.

      • method, the launch method for the sandboxed program, can be "sudo", "systemd", "simple".