From ffd18cc1b19fbf08d0a72341061b63a33ba51eaf Mon Sep 17 00:00:00 2001 From: Philipp Bartsch Date: Thu, 23 Jul 2020 18:12:58 +0200 Subject: nixos/usbguard: rework Use StateDirectory to create necessary directories and hardcode some paths. Also drop file based audit logs, they can be found in the journal. And add module option deprecation messages. --- nixos/doc/manual/release-notes/rl-2009.xml | 5 ++ nixos/modules/services/security/usbguard.nix | 124 +++++++++++---------------- 2 files changed, 56 insertions(+), 73 deletions(-) diff --git a/nixos/doc/manual/release-notes/rl-2009.xml b/nixos/doc/manual/release-notes/rl-2009.xml index d97e810b94c..3a411808953 100644 --- a/nixos/doc/manual/release-notes/rl-2009.xml +++ b/nixos/doc/manual/release-notes/rl-2009.xml @@ -629,6 +629,11 @@ services.postgresql.dataDir = "/var/db/postgresql"; + + + The USBGuard module now removes options and instead hardcodes values for IPCAccessControlFiles, ruleFiles, and auditFilePath. Audit logs can be found in the journal. + + diff --git a/nixos/modules/services/security/usbguard.nix b/nixos/modules/services/security/usbguard.nix index f4118eb87fc..16a90da5231 100644 --- a/nixos/modules/services/security/usbguard.nix +++ b/nixos/modules/services/security/usbguard.nix @@ -1,37 +1,39 @@ -{config, lib, pkgs, ... }: +{ config, lib, pkgs, ... }: with lib; - let - cfg = config.services.usbguard; # valid policy options policy = (types.enum [ "allow" "block" "reject" "keep" "apply-policy" ]); + defaultRuleFile = "/var/lib/usbguard/rules.conf"; + # decide what file to use for rules - ruleFile = if cfg.rules != null then pkgs.writeText "usbguard-rules" cfg.rules else cfg.ruleFile; + ruleFile = if cfg.rules != null then pkgs.writeText "usbguard-rules" cfg.rules else defaultRuleFile; daemonConf = '' - # generated by nixos/modules/services/security/usbguard.nix - RuleFile=${ruleFile} - ImplicitPolicyTarget=${cfg.implictPolicyTarget} - PresentDevicePolicy=${cfg.presentDevicePolicy} - PresentControllerPolicy=${cfg.presentControllerPolicy} - InsertedDevicePolicy=${cfg.insertedDevicePolicy} - RestoreControllerDeviceState=${if cfg.restoreControllerDeviceState then "true" else "false"} - # this does not seem useful for endusers to change - DeviceManagerBackend=uevent - IPCAllowedUsers=${concatStringsSep " " cfg.IPCAllowedUsers} - IPCAllowedGroups=${concatStringsSep " " cfg.IPCAllowedGroups} - IPCAccessControlFiles=${cfg.IPCAccessControlFiles} - DeviceRulesWithPort=${if cfg.deviceRulesWithPort then "true" else "false"} - AuditFilePath=${cfg.auditFilePath} - ''; - - daemonConfFile = pkgs.writeText "usbguard-daemon-conf" daemonConf; - -in { + # generated by nixos/modules/services/security/usbguard.nix + RuleFile=${ruleFile} + ImplicitPolicyTarget=${cfg.implictPolicyTarget} + PresentDevicePolicy=${cfg.presentDevicePolicy} + PresentControllerPolicy=${cfg.presentControllerPolicy} + InsertedDevicePolicy=${cfg.insertedDevicePolicy} + RestoreControllerDeviceState=${if cfg.restoreControllerDeviceState then "true" else "false"} + # this does not seem useful for endusers to change + DeviceManagerBackend=uevent + IPCAllowedUsers=${concatStringsSep " " cfg.IPCAllowedUsers} + IPCAllowedGroups=${concatStringsSep " " cfg.IPCAllowedGroups} + IPCAccessControlFiles=/var/lib/usbguard/IPCAccessControl.d/ + DeviceRulesWithPort=${if cfg.deviceRulesWithPort then "true" else "false"} + # HACK: that way audit logs still land in the journal + AuditFilePath=/dev/null + ''; + + daemonConfFile = pkgs.writeText "usbguard-daemon-conf" daemonConf; + +in +{ ###### interface @@ -49,22 +51,6 @@ in { ''; }; - ruleFile = mkOption { - type = types.path; - default = "/var/lib/usbguard/rules.conf"; - description = '' - The USBGuard daemon will use this file to load the policy rule set - from it and to write new rules received via the IPC interface. - - Running the command usbguard generate-policy as - root will generate a config for your currently plugged in devices. - For a in depth guide consult the official documentation. - - Setting the rules option will ignore the - ruleFile option. - ''; - }; - rules = mkOption { type = types.nullOr types.lines; default = null; @@ -72,16 +58,20 @@ in { allow with-interface equals { 08:*:* } ''; description = '' - The USBGuard daemon will load this policy rule set. Modifying it via - the IPC interface won't work if you use this option, since the - contents of this option will be written into the nix-store it will be - read-only. + The USBGuard daemon will load this as the policy rule set. + As these rules are NixOS managed they are immutable and can't + be changed by the IPC interface. + + If you do not set this option, the USBGuard daemon will load + it's policy rule set from ${defaultRuleFile}. + This file can be changed manually or via the IPC interface. - You can still use usbguard generate-policy to - generate rules, but you would have to insert them here. + Running usbguard generate-policy as root will + generate a config for your currently plugged in devices. - Setting the rules option will ignore the - ruleFile option. + For more details see + usbguard-rules.conf + 5. ''; }; @@ -155,17 +145,6 @@ in { ''; }; - IPCAccessControlFiles = mkOption { - type = types.path; - default = "/var/lib/usbguard/IPCAccessControl.d/"; - description = '' - The files at this location will be interpreted by the daemon as IPC - access control definition files. See the IPC ACCESS CONTROL section - in usbguard-daemon.conf - 5 for more details. - ''; - }; - deviceRulesWithPort = mkOption { type = types.bool; default = false; @@ -173,14 +152,6 @@ in { Generate device specific rules including the "via-port" attribute. ''; }; - - auditFilePath = mkOption { - type = types.path; - default = "/var/log/usbguard/usbguard-audit.log"; - description = '' - USBGuard audit events log file path. - ''; - }; }; }; @@ -197,17 +168,19 @@ in { wantedBy = [ "basic.target" ]; wants = [ "systemd-udevd.service" ]; - # make sure an empty rule file and required directories exist - preStart = '' - mkdir -p $(dirname "${cfg.ruleFile}") $(dirname "${cfg.auditFilePath}") "${cfg.IPCAccessControlFiles}" \ - && ([ -f "${cfg.ruleFile}" ] || touch ${cfg.ruleFile}) - ''; + # 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"; @@ -223,8 +196,8 @@ in { ProtectKernelModules = true; ProtectSystem = true; ReadOnlyPaths = "-/"; - ReadWritePaths = "-/dev/shm -${dirOf cfg.auditFilePath} -/tmp -${dirOf cfg.ruleFile}"; - RestrictAddressFamilies = "AF_UNIX AF_NETLINK"; + ReadWritePaths = "-/dev/shm -/tmp"; + RestrictAddressFamilies = [ "AF_UNIX" "AF_NETLINK" ]; RestrictNamespaces = true; RestrictRealtime = true; SystemCallArchitectures = "native"; @@ -233,4 +206,9 @@ in { }; }; }; + imports = [ + (mkRemovedOptionModule [ "services" "usbguard" "ruleFile" ] "The usbguard module now uses ${defaultRuleFile} as ruleFile. Alternatively, use services.usbguard.rules to configure rules.") + (mkRemovedOptionModule [ "services" "usbguard" "IPCAccessControlFiles" ] "The usbguard module now hardcodes IPCAccessControlFiles to /var/lib/usbguard/IPCAccessControl.d.") + (mkRemovedOptionModule [ "services" "usbguard" "auditFilePath" ] "Removed usbguard module audit log files. Audit logs can be found in the systemd journal.") + ]; } -- cgit 1.4.1