python3Packages.orjson: Disable failing tests on 32 bit
[NixPkgs.git] / nixos / modules / services / security / usbguard.nix
blob1b1fa84c4fa372341bcb4687bb51dc3cb2e8f826
1 { config, lib, pkgs, ... }:
3 with lib;
4 let
5   cfg = config.services.usbguard;
7   # valid policy options
8   policy = (types.enum [ "allow" "block" "reject" "keep" "apply-policy" ]);
10   defaultRuleFile = "/var/lib/usbguard/rules.conf";
12   # decide what file to use for rules
13   ruleFile = if cfg.rules != null then pkgs.writeText "usbguard-rules" cfg.rules else defaultRuleFile;
15   daemonConf = ''
16     # generated by nixos/modules/services/security/usbguard.nix
17     RuleFile=${ruleFile}
18     ImplicitPolicyTarget=${cfg.implictPolicyTarget}
19     PresentDevicePolicy=${cfg.presentDevicePolicy}
20     PresentControllerPolicy=${cfg.presentControllerPolicy}
21     InsertedDevicePolicy=${cfg.insertedDevicePolicy}
22     RestoreControllerDeviceState=${boolToString cfg.restoreControllerDeviceState}
23     # this does not seem useful for endusers to change
24     DeviceManagerBackend=uevent
25     IPCAllowedUsers=${concatStringsSep " " cfg.IPCAllowedUsers}
26     IPCAllowedGroups=${concatStringsSep " " cfg.IPCAllowedGroups}
27     IPCAccessControlFiles=/var/lib/usbguard/IPCAccessControl.d/
28     DeviceRulesWithPort=${boolToString cfg.deviceRulesWithPort}
29     # HACK: that way audit logs still land in the journal
30     AuditFilePath=/dev/null
31   '';
33   daemonConfFile = pkgs.writeText "usbguard-daemon-conf" daemonConf;
38   ###### interface
40   options = {
41     services.usbguard = {
42       enable = mkEnableOption (lib.mdDoc "USBGuard daemon");
44       package = mkOption {
45         type = types.package;
46         default = pkgs.usbguard;
47         defaultText = literalExpression "pkgs.usbguard";
48         description = lib.mdDoc ''
49           The usbguard package to use. If you do not need the Qt GUI, use
50           `pkgs.usbguard-nox` to save disk space.
51         '';
52       };
54       rules = mkOption {
55         type = types.nullOr types.lines;
56         default = null;
57         example = ''
58           allow with-interface equals { 08:*:* }
59         '';
60         description = lib.mdDoc ''
61           The USBGuard daemon will load this as the policy rule set.
62           As these rules are NixOS managed they are immutable and can't
63           be changed by the IPC interface.
65           If you do not set this option, the USBGuard daemon will load
66           it's policy rule set from `${defaultRuleFile}`.
67           This file can be changed manually or via the IPC interface.
69           Running `usbguard generate-policy` as root will
70           generate a config for your currently plugged in devices.
72           For more details see {manpage}`usbguard-rules.conf(5)`.
73         '';
74       };
76       implictPolicyTarget = mkOption {
77         type = policy;
78         default = "block";
79         description = lib.mdDoc ''
80           How to treat USB devices that don't match any rule in the policy.
81           Target should be one of allow, block or reject (logically remove the
82           device node from the system).
83         '';
84       };
86       presentDevicePolicy = mkOption {
87         type = policy;
88         default = "apply-policy";
89         description = lib.mdDoc ''
90           How to treat USB devices that are already connected when the daemon
91           starts. Policy should be one of allow, block, reject, keep (keep
92           whatever state the device is currently in) or apply-policy (evaluate
93           the rule set for every present device).
94         '';
95       };
97       presentControllerPolicy = mkOption {
98         type = policy;
99         default = "keep";
100         description = lib.mdDoc ''
101           How to treat USB controller devices that are already connected when
102           the daemon starts. One of allow, block, reject, keep or apply-policy.
103         '';
104       };
106       insertedDevicePolicy = mkOption {
107         type = policy;
108         default = "apply-policy";
109         description = lib.mdDoc ''
110           How to treat USB devices that are already connected after the daemon
111           starts. One of block, reject, apply-policy.
112         '';
113       };
115       restoreControllerDeviceState = mkOption {
116         type = types.bool;
117         default = false;
118         description = lib.mdDoc ''
119           The  USBGuard  daemon  modifies  some attributes of controller
120           devices like the default authorization state of new child device
121           instances. Using this setting, you can controll whether the daemon
122           will try to restore the attribute values to the state before
123           modificaton on shutdown.
124         '';
125       };
127       IPCAllowedUsers = mkOption {
128         type = types.listOf types.str;
129         default = [ "root" ];
130         example = [ "root" "yourusername" ];
131         description = lib.mdDoc ''
132           A list of usernames that the daemon will accept IPC connections from.
133         '';
134       };
136       IPCAllowedGroups = mkOption {
137         type = types.listOf types.str;
138         default = [ ];
139         example = [ "wheel" ];
140         description = lib.mdDoc ''
141           A list of groupnames that the daemon will accept IPC connections
142           from.
143         '';
144       };
146       deviceRulesWithPort = mkOption {
147         type = types.bool;
148         default = false;
149         description = lib.mdDoc ''
150           Generate device specific rules including the "via-port" attribute.
151         '';
152       };
153     };
154   };
157   ###### implementation
159   config = mkIf cfg.enable {
161     environment.systemPackages = [ cfg.package ];
163     systemd.services.usbguard = {
164       description = "USBGuard daemon";
166       wantedBy = [ "basic.target" ];
167       wants = [ "systemd-udevd.service" ];
169       # make sure an empty rule file exists
170       preStart = ''[ -f "${ruleFile}" ] || touch ${ruleFile}'';
172       serviceConfig = {
173         Type = "simple";
174         ExecStart = "${cfg.package}/bin/usbguard-daemon -P -k -c ${daemonConfFile}";
175         Restart = "on-failure";
177         StateDirectory = [
178           "usbguard"
179           "usbguard/IPCAccessControl.d"
180         ];
182         AmbientCapabilities = "";
183         CapabilityBoundingSet = "CAP_CHOWN CAP_FOWNER";
184         DeviceAllow = "/dev/null rw";
185         DevicePolicy = "strict";
186         IPAddressDeny = "any";
187         LockPersonality = true;
188         MemoryDenyWriteExecute = true;
189         NoNewPrivileges = true;
190         PrivateDevices = true;
191         PrivateTmp = true;
192         ProtectControlGroups = true;
193         ProtectHome = true;
194         ProtectKernelModules = true;
195         ProtectSystem = true;
196         ReadOnlyPaths = "-/";
197         ReadWritePaths = "-/dev/shm -/tmp";
198         RestrictAddressFamilies = [ "AF_UNIX" "AF_NETLINK" ];
199         RestrictNamespaces = true;
200         RestrictRealtime = true;
201         SystemCallArchitectures = "native";
202         SystemCallFilter = "@system-service";
203         UMask = "0077";
204       };
205     };
206   };
207   imports = [
208     (mkRemovedOptionModule [ "services" "usbguard" "ruleFile" ] "The usbguard module now uses ${defaultRuleFile} as ruleFile. Alternatively, use services.usbguard.rules to configure rules.")
209     (mkRemovedOptionModule [ "services" "usbguard" "IPCAccessControlFiles" ] "The usbguard module now hardcodes IPCAccessControlFiles to /var/lib/usbguard/IPCAccessControl.d.")
210     (mkRemovedOptionModule [ "services" "usbguard" "auditFilePath" ] "Removed usbguard module audit log files. Audit logs can be found in the systemd journal.")
211   ];