anchor.diff:  
     cfg = config.services.fail2ban;
   
  -  fail2banConf = pkgs.writeText "fail2ban.conf" cfg.daemonConfig;
  +  fail2banConf = pkgs.writeText "fail2ban.local" cfg.daemonConfig;
   
  -  jailConf = pkgs.writeText "jail.conf"
  -    (concatStringsSep "\n" (attrValues (flip mapAttrs cfg.jails (name: def:
  +  jailConf = pkgs.writeText "jail.local" ''
  +    [INCLUDES]
  +
  +    before = paths-nixos.conf
  +
  +    ${concatStringsSep "\n" (attrValues (flip mapAttrs cfg.jails (name: def:
         optionalString (def != "")
           ''
             [${name}]
             ${def}
  -        ''))));
  +        '')))}
  +  '';
  +
  +  pathsConf = pkgs.writeText "paths-nixos.conf" ''
  +    # NixOS
  +
  +    [INCLUDES]
  +
  +    before = paths-common.conf
  +
  +    after  = paths-overrides.local
  +
  +    [DEFAULT]
  +  '';
   
   in
   
  
positive.code:           }
          '';
          type = types.attrsOf types.lines;
          description =
            ''
              The configuration of each Fail2ban “jail”.  A jail
              consists of an action (such as blocking a port using
              <command>iptables</command>) that is triggered when a
              filter applied to a log file triggers more than a certain
              number of times in a certain time period.  Actions are
              defined in <filename>/etc/fail2ban/action.d</filename>,
              while filters are defined in
              <filename>/etc/fail2ban/filter.d</filename>.
            '';
        };
  
      };
  
negative.code: 
    config = mkIf cfg.enable {
  
      environment.systemPackages = [ cfg.package ];
  
      environment.etc = {
        "fail2ban/fail2ban.local".source = fail2banConf;
        "fail2ban/jail.local".source = jailConf;
        "fail2ban/fail2ban.conf".source = "${cfg.package}/etc/fail2ban/fail2ban.conf";
        "fail2ban/jail.conf".source = "${cfg.package}/etc/fail2ban/jail.conf";
        "fail2ban/paths-common.conf".source = "${cfg.package}/etc/fail2ban/paths-common.conf";
        "fail2ban/paths-nixos.conf".source = pathsConf;
        "fail2ban/action.d".source = "${cfg.package}/etc/fail2ban/action.d/*.conf";
        "fail2ban/filter.d".source = "${cfg.package}/etc/fail2ban/filter.d/*.conf";
      };
  
      systemd.services.fail2ban = {
        description = "Fail2ban Intrusion Prevention System";
  
        wantedBy = [ "multi-user.target" ];
        after = [ "network.target" ];
        partOf = optional config.networking.firewall.enable "firewall.service";
  
        restartTriggers = [ fail2banConf jailConf pathsConf ];
        reloadIfChanged = true;
  
        path = [ cfg.package pkgs.iptables pkgs.iproute ];
  
        preStart = ''
          mkdir -p /var/lib/fail2ban
        '';
  
        unitConfig.Documentation = "man:fail2ban(1)";
  
        serviceConfig = {
          Type = "forking";
          ExecStart = "${cfg.package}/bin/fail2ban-server -xf start";
          ExecStop = "${cfg.package}/bin/fail2ban-server stop";
          ExecReload = "${cfg.package}/bin/fail2ban-server reload";
          PIDFile = "/run/fail2ban/fail2ban.pid";
          Restart = "always";
  
          ReadOnlyDirectories = "/";
          ReadWriteDirectories = "/run/fail2ban /var/tmp /var/lib";
          PrivateTmp = "true";
          RuntimeDirectory = "fail2ban";
          CapabilityBoundingSet = "CAP_DAC_READ_SEARCH CAP_NET_ADMIN CAP_NET_RAW";
        };
      };
  
      # Add some reasonable default jails.  The special "DEFAULT" jail
      # sets default values for all other jails.
      services.fail2ban.jails.DEFAULT = ''
        # Miscellaneous options
        ignoreip    = 127.0.0.1/8 ${optionalString config.networking.enableIPv6 "::1"}
        maxretry    = 3
        backend     = systemd
      '';
      # Block SSH if there are too many failing connection attempts.
      services.fail2ban.jails.sshd = mkDefault ''
        enabled = true
        port    = ${concatMapStringsSep "," (p: toString p) config.services.openssh.ports}
      '';
    };
  }
  