diff --git a/modules/services/security/fail2ban.nix b/modules/services/security/fail2ban.nix
index 12f7b020eaa..48756fbeebc 100644
--- a/modules/services/security/fail2ban.nix
+++ b/modules/services/security/fail2ban.nix
@@ -4,38 +4,76 @@ with pkgs.lib;
let
- fail2banConf = pkgs.writeText "fail2ban.conf"
- ''
- [Definition]
- loglevel = 3
- logtarget = SYSLOG
- socket = /var/run/fail2ban/fail2ban.sock
- '';
+ cfg = config.services.fail2ban;
+
+ fail2banConf = pkgs.writeText "fail2ban.conf" cfg.daemonConfig;
jailConf = pkgs.writeText "jail.conf"
- ''
- [DEFAULT]
- bantime = 120
- findtime = 120
- maxretry = 3
- backend = auto
-
- [ssh-iptables]
- enabled = true
- filter = sshd
- action = iptables[name=SSH, port=ssh, protocol=tcp]
- logpath = /var/log/warn
- maxretry = 5
- '';
+ (concatStringsSep "\n" (attrValues (flip mapAttrs cfg.jails (name: def:
+ optionalString (def != "")
+ ''
+ [${name}]
+ ${def}
+ ''))));
in
-
+
{
###### interface
options = {
+ services.fail2ban = {
+
+ daemonConfig = mkOption {
+ default =
+ ''
+ [Definition]
+ loglevel = 3
+ logtarget = SYSLOG
+ socket = /var/run/fail2ban/fail2ban.sock
+ '';
+ type = types.string;
+ description =
+ ''
+ The contents of Fail2ban's main configuration file. It's
+ generally not necessary to change it.
+ '';
+ };
+
+ jails = mkOption {
+ default = { };
+ example =
+ { "apache-nohome-iptables" =
+ ''
+ # Block an IP address if it accesses a non-existent
+ # home directory more than 5 times in 10 minutes,
+ # since that indicates that it's scanning.
+ filter = apache-nohome
+ action = iptables-multiport[name=HTTP, port="http,https"]
+ logpath = /var/log/httpd/error_log*
+ findtime = 600
+ bantime = 600
+ maxretry = 5
+ '';
+ };
+ type = types.attrsOf types.string;
+ description =
+ ''
+ The configuration of each Fail2ban “jail”. A jail
+ consists of an action (such as blocking a port using
+ iptables) 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 /etc/fail2ban/action.d,
+ while filters are defined in
+ /etc/fail2ban/filter.d.
+ '';
+ };
+
+ };
+
};
@@ -69,6 +107,8 @@ in
preStart =
''
+ # FIXME: this won't detect changes to
+ # /etc/fail2ban/{filter.d,action.d}.
# ${fail2banConf} ${jailConf}
mkdir -p /var/run/fail2ban -m 0755
'';
@@ -79,10 +119,28 @@ in
''
fail2ban-client reload
'';
-
- respawn = false;
};
-
+
+ # Add some reasonable default jails. The special "DEFAULT" jail
+ # sets default values for all other jails.
+ services.fail2ban.jails.DEFAULT =
+ ''
+ ignoreip = 127.0.0.1/8
+ bantime = 600
+ findtime = 600
+ maxretry = 3
+ backend = auto
+ '';
+
+ # Block SSH if there are too many failing connection attempts.
+ services.fail2ban.jails."ssh-iptables" =
+ ''
+ filter = sshd
+ action = iptables[name=SSH, port=ssh, protocol=tcp]
+ logpath = /var/log/warn
+ maxretry = 5
+ '';
+
};
}