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.
This commit is contained in:
Philipp Bartsch 2020-07-23 18:12:58 +02:00
parent b01106127c
commit ffd18cc1b1
2 changed files with 54 additions and 71 deletions

View file

@ -629,6 +629,11 @@ services.postgresql.dataDir = "/var/db/postgresql";
</programlisting>
</para>
</listitem>
<listitem>
<para>
The USBGuard module now removes options and instead hardcodes values for <literal>IPCAccessControlFiles</literal>, <literal>ruleFiles</literal>, and <literal>auditFilePath</literal>. Audit logs can be found in the journal.
</para>
</listitem>
</itemizedlist>
</section>

View file

@ -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}
'';
# 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;
daemonConfFile = pkgs.writeText "usbguard-daemon-conf" daemonConf;
in {
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 <literal>usbguard generate-policy</literal> as
root will generate a config for your currently plugged in devices.
For a in depth guide consult the official documentation.
Setting the <literal>rules</literal> option will ignore the
<literal>ruleFile</literal> 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.
You can still use <literal> usbguard generate-policy</literal> to
generate rules, but you would have to insert them here.
If you do not set this option, the USBGuard daemon will load
it's policy rule set from <literal>${defaultRuleFile}</literal>.
This file can be changed manually or via the IPC interface.
Setting the <literal>rules</literal> option will ignore the
<literal>ruleFile</literal> option.
Running <literal>usbguard generate-policy</literal> as root will
generate a config for your currently plugged in devices.
For more details see <citerefentry>
<refentrytitle>usbguard-rules.conf</refentrytitle>
<manvolnum>5</manvolnum></citerefentry>.
'';
};
@ -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 <citerefentry><refentrytitle>usbguard-daemon.conf</refentrytitle>
<manvolnum>5</manvolnum></citerefentry> 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.")
];
}