1{ config, lib, pkgs, ... }:
2
3with lib;
4
5let
6 cfg = config.services.ferm;
7
8 configFile = pkgs.stdenv.mkDerivation {
9 name = "ferm.conf";
10 text = cfg.config;
11 preferLocalBuild = true;
12 buildCommand = ''
13 echo -n "$text" > $out
14 ${cfg.package}/bin/ferm --noexec $out
15 '';
16 };
17in {
18 options = {
19 services.ferm = {
20 enable = mkOption {
21 default = false;
22 type = types.bool;
23 description = lib.mdDoc ''
24 Whether to enable Ferm Firewall.
25 *Warning*: Enabling this service WILL disable the existing NixOS
26 firewall! Default firewall rules provided by packages are not
27 considered at the moment.
28 '';
29 };
30 config = mkOption {
31 description = lib.mdDoc "Verbatim ferm.conf configuration.";
32 default = "";
33 defaultText = literalMD "empty firewall, allows any traffic";
34 type = types.lines;
35 };
36 package = mkOption {
37 description = lib.mdDoc "The ferm package.";
38 type = types.package;
39 default = pkgs.ferm;
40 defaultText = literalExpression "pkgs.ferm";
41 };
42 };
43 };
44
45 config = mkIf cfg.enable {
46 systemd.services.firewall.enable = false;
47 systemd.services.ferm = {
48 description = "Ferm Firewall";
49 after = [ "ipset.target" ];
50 before = [ "network-pre.target" ];
51 wants = [ "network-pre.target" ];
52 wantedBy = [ "multi-user.target" ];
53 reloadIfChanged = true;
54 serviceConfig = {
55 Type="oneshot";
56 RemainAfterExit = "yes";
57 ExecStart = "${cfg.package}/bin/ferm ${configFile}";
58 ExecReload = "${cfg.package}/bin/ferm ${configFile}";
59 ExecStop = "${cfg.package}/bin/ferm -F ${configFile}";
60 };
61 };
62 };
63}