diff options
-rw-r--r-- | nixos/doc/manual/from_md/release-notes/rl-2305.section.xml | 5 | ||||
-rw-r--r-- | nixos/doc/manual/release-notes/rl-2305.section.md | 2 | ||||
-rw-r--r-- | nixos/modules/services/security/opensnitch.nix | 83 |
3 files changed, 74 insertions, 16 deletions
diff --git a/nixos/doc/manual/from_md/release-notes/rl-2305.section.xml b/nixos/doc/manual/from_md/release-notes/rl-2305.section.xml index da765edcd08..73ea0a9b919 100644 --- a/nixos/doc/manual/from_md/release-notes/rl-2305.section.xml +++ b/nixos/doc/manual/from_md/release-notes/rl-2305.section.xml @@ -83,7 +83,10 @@ <itemizedlist spacing="compact"> <listitem> <para> - Create the first release note entry in this section! + The module for the application firewall + <literal>opensnitch</literal> got the ability to configure + rules. Available as + <link linkend="opt-services.opensnitch.rules">services.opensnitch.rules</link> </para> </listitem> </itemizedlist> diff --git a/nixos/doc/manual/release-notes/rl-2305.section.md b/nixos/doc/manual/release-notes/rl-2305.section.md index 3cbf4621a78..7f42554f322 100644 --- a/nixos/doc/manual/release-notes/rl-2305.section.md +++ b/nixos/doc/manual/release-notes/rl-2305.section.md @@ -33,4 +33,4 @@ In addition to numerous new and upgraded packages, this release has the followin <!-- To avoid merge conflicts, consider adding your item at an arbitrary place in the list instead. --> -- Create the first release note entry in this section! +- The module for the application firewall `opensnitch` got the ability to configure rules. Available as [services.opensnitch.rules](#opt-services.opensnitch.rules) diff --git a/nixos/modules/services/security/opensnitch.nix b/nixos/modules/services/security/opensnitch.nix index 1612b0edf01..8f1407b555f 100644 --- a/nixos/modules/services/security/opensnitch.nix +++ b/nixos/modules/services/security/opensnitch.nix @@ -5,10 +5,47 @@ with lib; let cfg = config.services.opensnitch; format = pkgs.formats.json {}; + + predefinedRules = flip mapAttrs cfg.rules (name: cfg: { + file = pkgs.writeText "rule" (builtins.toJSON cfg); + }); + in { options = { services.opensnitch = { - enable = mkEnableOption (lib.mdDoc "Opensnitch application firewall"); + enable = mkEnableOption (mdDoc "Opensnitch application firewall"); + + rules = mkOption { + default = {}; + example = literalExpression '' + { + "tor" = { + "name" = "tor"; + "enabled" = true; + "action" = "allow"; + "duration" = "always"; + "operator" = { + "type" ="simple"; + "sensitive" = false; + "operand" = "process.path"; + "data" = "''${lib.getBin pkgs.tor}/bin/tor"; + }; + }; + }; + ''; + + description = mdDoc '' + Declarative configuration of firewall rules. + All rules will be stored in `/var/lib/opensnitch/rules`. + See [upstream documentation](https://github.com/evilsocket/opensnitch/wiki/Rules) + for available options. + ''; + + type = types.submodule { + freeformType = format.type; + }; + }; + settings = mkOption { type = types.submodule { freeformType = format.type; @@ -18,7 +55,7 @@ in { Address = mkOption { type = types.str; - description = lib.mdDoc '' + description = mdDoc '' Unix socket path (unix:///tmp/osui.sock, the "unix:///" part is mandatory) or TCP socket (192.168.1.100:50051). ''; @@ -26,7 +63,7 @@ in { LogFile = mkOption { type = types.path; - description = lib.mdDoc '' + description = mdDoc '' File to write logs to (use /dev/stdout to write logs to standard output). ''; @@ -36,7 +73,7 @@ in { DefaultAction = mkOption { type = types.enum [ "allow" "deny" ]; - description = lib.mdDoc '' + description = mdDoc '' Default action whether to block or allow application internet access. ''; @@ -46,28 +83,28 @@ in { type = types.enum [ "once" "always" "until restart" "30s" "5m" "15m" "30m" "1h" ]; - description = lib.mdDoc '' + description = mdDoc '' Default duration of firewall rule. ''; }; InterceptUnknown = mkOption { type = types.bool; - description = lib.mdDoc '' + description = mdDoc '' Wheter to intercept spare connections. ''; }; ProcMonitorMethod = mkOption { type = types.enum [ "ebpf" "proc" "ftrace" "audit" ]; - description = lib.mdDoc '' + description = mdDoc '' Which process monitoring method to use. ''; }; LogLevel = mkOption { type = types.enum [ 0 1 2 3 4 ]; - description = lib.mdDoc '' + description = mdDoc '' Default log level from 0 to 4 (debug, info, important, warning, error). ''; @@ -75,7 +112,7 @@ in { Firewall = mkOption { type = types.enum [ "iptables" "nftables" ]; - description = lib.mdDoc '' + description = mdDoc '' Which firewall backend to use. ''; }; @@ -84,14 +121,14 @@ in { MaxEvents = mkOption { type = types.int; - description = lib.mdDoc '' + description = mdDoc '' Max events to send to the GUI. ''; }; MaxStats = mkOption { type = types.int; - description = lib.mdDoc '' + description = mdDoc '' Max stats per item to keep in backlog. ''; }; @@ -99,9 +136,8 @@ in { }; }; }; - description = lib.mdDoc '' - opensnitchd configuration. Refer to - <https://github.com/evilsocket/opensnitch/wiki/Configurations> + description = mdDoc '' + opensnitchd configuration. Refer to [upstream documentation](https://github.com/evilsocket/opensnitch/wiki/Configurations) for details on supported values. ''; }; @@ -118,6 +154,25 @@ in { services.opensnitchd.wantedBy = [ "multi-user.target" ]; }; + systemd.services.opensnitchd.preStart = mkIf (cfg.rules != {}) (let + rules = flip mapAttrsToList predefinedRules (file: content: { + inherit (content) file; + local = "/var/lib/opensnitch/rules/${file}.json"; + }); + in '' + # Remove all firewall rules from `/var/lib/opensnitch/rules` that are symlinks to a store-path, + # but aren't declared in `cfg.rules` (i.e. all networks that were "removed" from + # `cfg.rules`). + find /var/lib/opensnitch/rules -type l -lname '${builtins.storeDir}/*' ${optionalString (rules != {}) '' + -not \( ${concatMapStringsSep " -o " ({ local, ... }: + "-name '${baseNameOf local}*'") + rules} \) \ + ''} -delete + ${concatMapStrings ({ file, local }: '' + ln -sf '${file}' "${local}" + '') rules} + ''); + environment.etc."opensnitchd/default-config.json".source = format.generate "default-config.json" cfg.settings; }; |