From cbb69aa1c1e69720233e26eda2abf578a53128b8 Mon Sep 17 00:00:00 2001 From: Archit Gupta Date: Mon, 12 Jun 2023 20:57:07 -0700 Subject: nixos/usbguard: add USBGuard dbus daemon option The usbguard package includes the dbus daemon, but the NixOS config option does not provide a service file or its necessary polkit rules. Enabling the dbus daemon allows use of Gnome's USBGuard support. --- nixos/modules/services/security/usbguard.nix | 125 ++++++++++++++++++--------- 1 file changed, 84 insertions(+), 41 deletions(-) (limited to 'nixos/modules/services/security') diff --git a/nixos/modules/services/security/usbguard.nix b/nixos/modules/services/security/usbguard.nix index 1d846b194077..651f5255ac83 100644 --- a/nixos/modules/services/security/usbguard.nix +++ b/nixos/modules/services/security/usbguard.nix @@ -150,6 +150,8 @@ in Generate device specific rules including the "via-port" attribute. ''; }; + + dbus.enable = mkEnableOption (lib.mdDoc "USBGuard dbus daemon"); }; }; @@ -160,49 +162,90 @@ in environment.systemPackages = [ cfg.package ]; - systemd.services.usbguard = { - description = "USBGuard daemon"; - - wantedBy = [ "basic.target" ]; - wants = [ "systemd-udevd.service" ]; - - # make sure an empty rule file exists - preStart = ''[ -f "${ruleFile}" ] || touch ${ruleFile}''; - - serviceConfig = { - Type = "simple"; - ExecStart = "${cfg.package}/bin/usbguard-daemon -P -k -c ${daemonConfFile}"; - Restart = "on-failure"; - - StateDirectory = [ - "usbguard" - "usbguard/IPCAccessControl.d" - ]; - - AmbientCapabilities = ""; - CapabilityBoundingSet = "CAP_CHOWN CAP_FOWNER"; - DeviceAllow = "/dev/null rw"; - DevicePolicy = "strict"; - IPAddressDeny = "any"; - LockPersonality = true; - MemoryDenyWriteExecute = true; - NoNewPrivileges = true; - PrivateDevices = true; - PrivateTmp = true; - ProtectControlGroups = true; - ProtectHome = true; - ProtectKernelModules = true; - ProtectSystem = true; - ReadOnlyPaths = "-/"; - ReadWritePaths = "-/dev/shm -/tmp"; - RestrictAddressFamilies = [ "AF_UNIX" "AF_NETLINK" ]; - RestrictNamespaces = true; - RestrictRealtime = true; - SystemCallArchitectures = "native"; - SystemCallFilter = "@system-service"; - UMask = "0077"; + systemd.services = { + usbguard = { + description = "USBGuard daemon"; + + wantedBy = [ "basic.target" ]; + wants = [ "systemd-udevd.service" ]; + + # make sure an empty rule file exists + preStart = ''[ -f "${ruleFile}" ] || touch ${ruleFile}''; + + serviceConfig = { + Type = "simple"; + ExecStart = "${cfg.package}/bin/usbguard-daemon -P -k -c ${daemonConfFile}"; + Restart = "on-failure"; + + StateDirectory = [ + "usbguard" + "usbguard/IPCAccessControl.d" + ]; + + AmbientCapabilities = ""; + CapabilityBoundingSet = "CAP_CHOWN CAP_FOWNER"; + DeviceAllow = "/dev/null rw"; + DevicePolicy = "strict"; + IPAddressDeny = "any"; + LockPersonality = true; + MemoryDenyWriteExecute = true; + NoNewPrivileges = true; + PrivateDevices = true; + PrivateTmp = true; + ProtectControlGroups = true; + ProtectHome = true; + ProtectKernelModules = true; + ProtectSystem = true; + ReadOnlyPaths = "-/"; + ReadWritePaths = "-/dev/shm -/tmp"; + RestrictAddressFamilies = [ "AF_UNIX" "AF_NETLINK" ]; + RestrictNamespaces = true; + RestrictRealtime = true; + SystemCallArchitectures = "native"; + SystemCallFilter = "@system-service"; + UMask = "0077"; + }; + }; + + usbguard-dbus = mkIf cfg.dbus.enable { + description = "USBGuard D-Bus Service"; + + wantedBy = [ "multi-user.target" ]; + requires = [ "usbguard.service" ]; + + serviceConfig = { + Type = "dbus"; + BusName = "org.usbguard1"; + ExecStart = "${cfg.package}/bin/usbguard-dbus --system"; + Restart = "on-failure"; + }; + + aliases = [ "dbus-org.usbguard.service" ]; }; }; + + security.polkit.extraConfig = + let + groupCheck = (lib.concatStrings (map + (g: "subject.isInGroup(\"${g}\") || ") + cfg.IPCAllowedGroups)) + + "false"; + in + optionalString cfg.dbus.enable '' + polkit.addRule(function(action, subject) { + if ((action.id == "org.usbguard.Policy1.listRules" || + action.id == "org.usbguard.Policy1.appendRule" || + action.id == "org.usbguard.Policy1.removeRule" || + action.id == "org.usbguard.Devices1.applyDevicePolicy" || + action.id == "org.usbguard.Devices1.listDevices" || + action.id == "org.usbguard1.getParameter" || + action.id == "org.usbguard1.setParameter") && + subject.active == true && subject.local == true && + (${groupCheck})) { + return polkit.Result.YES; + } + }); + ''; }; imports = [ (mkRemovedOptionModule [ "services" "usbguard" "ruleFile" ] "The usbguard module now uses ${defaultRuleFile} as ruleFile. Alternatively, use services.usbguard.rules to configure rules.") -- cgit 1.4.1