diff options
Diffstat (limited to 'nixos/modules/services/security/fail2ban.nix')
-rw-r--r-- | nixos/modules/services/security/fail2ban.nix | 148 |
1 files changed, 148 insertions, 0 deletions
diff --git a/nixos/modules/services/security/fail2ban.nix b/nixos/modules/services/security/fail2ban.nix new file mode 100644 index 000000000000..395a5df8af07 --- /dev/null +++ b/nixos/modules/services/security/fail2ban.nix @@ -0,0 +1,148 @@ +{ config, pkgs, ... }: + +with pkgs.lib; + +let + + cfg = config.services.fail2ban; + + fail2banConf = pkgs.writeText "fail2ban.conf" cfg.daemonConfig; + + jailConf = pkgs.writeText "jail.conf" + (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 = /run/fail2ban/fail2ban.sock + pidfile = /run/fail2ban/fail2ban.pid + ''; + 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 + <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>. + ''; + }; + + }; + + }; + + + ###### implementation + + config = { + + environment.systemPackages = [ pkgs.fail2ban ]; + + environment.etc."fail2ban/fail2ban.conf".source = fail2banConf; + environment.etc."fail2ban/jail.conf".source = jailConf; + environment.etc."fail2ban/action.d".source = "${pkgs.fail2ban}/etc/fail2ban/action.d/*.conf"; + environment.etc."fail2ban/filter.d".source = "${pkgs.fail2ban}/etc/fail2ban/filter.d/*.conf"; + + systemd.services.fail2ban = + { description = "Fail2ban intrusion prevention system"; + + wantedBy = [ "multi-user.target" ]; + after = [ "network.target" ]; + + restartTriggers = [ fail2banConf jailConf ]; + path = [ pkgs.fail2ban pkgs.iptables ]; + + preStart = + '' + mkdir -p /run/fail2ban -m 0755 + ''; + + serviceConfig = + { ExecStart = "${pkgs.fail2ban}/bin/fail2ban-server -f"; + ReadOnlyDirectories = "/"; + ReadWriteDirectories = "/run/fail2ban /var/tmp"; + CapabilityBoundingSet = "CAP_DAC_READ_SEARCH CAP_NET_ADMIN CAP_NET_RAW"; + }; + + postStart = + '' + # Wait for the server to start listening. + for ((n = 0; n < 20; n++)); do + if fail2ban-client ping; then break; fi + sleep 0.5 + done + + # Reload its configuration. + fail2ban-client reload + ''; + }; + + # 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 + ''; + + }; + +} |