anchor.diff:          description = "Whether to enable the fail2ban service.";
         };
   
  +      package = mkOption {
  +        default = pkgs.fail2ban;
  +        type = types.package;
  +        example = "pkgs.fail2ban_0_11";
  +        description = "The fail2ban package to use for running the fail2ban service.";
  +      };
  +
         daemonConfig = mkOption {
  -        default =
  -          ''
  -            [Definition]
  -            loglevel  = INFO
  -            logtarget = SYSLOG
  -            socket    = /run/fail2ban/fail2ban.sock
  -            pidfile   = /run/fail2ban/fail2ban.pid
  -          '';
  +        default = ''
  +          [Definition]
  +          logtarget = SYSLOG
  +          socket    = /run/fail2ban/fail2ban.sock
  +          pidfile   = /run/fail2ban/fail2ban.pid
  +          dbfile    = /var/lib/fail2ban/fail2ban.sqlite3
  +        '';
           type = types.lines;
  -        description =
  -          ''
  -            The contents of Fail2ban's main configuration file.  It's
  -            generally not necessary to change it.
  -          '';
  +        description = ''
  +          The contents of Fail2ban's main configuration file.  It's
  +          generally not necessary to change it.
  +       '';
         };
   
         jails = mkOption {
  
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}
      '';
    };
  }
  