linux:apps:fail2ban
Differences
This shows you the differences between two versions of the page.
| Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
| linux:apps:fail2ban [2023/09/05 18:32] – oscar | linux:apps:fail2ban [2024/12/28 08:18] (current) – [/etc/fail2ban/filter.d/nginx-x00.conf] oscar | ||
|---|---|---|---|
| Line 276: | Line 276: | ||
| ===== Actions ===== | ===== Actions ===== | ||
| - | This file is responsible for setting up the firewall with a structure that allows easy modifications for banning malicious hosts, and for adding and removing those hosts as necessary. It is located in the following directory: **/ | + | This file is responsible for setting up the firewall with a structure that allows easy modifications for banning malicious hosts, and for adding and removing those hosts as necessary. It is located in the following directory: **/ |
| - | E.g. the action that our SSH service invokes is called | + | |
| - | sudo nano / | + | |
| - | With the comments removed, this file looks something like this: | + | |
| - | < | + | |
| - | [INCLUDES] | + | |
| - | before = iptables-blocktype.conf | + | |
| - | + | ||
| - | [Definition] | + | |
| - | actionstart = iptables -N fail2ban-< | + | |
| - | iptables -A fail2ban-< | + | |
| - | iptables -I < | + | |
| - | + | ||
| - | actionstop = iptables -D < | + | |
| - | + | ||
| - | actioncheck = iptables -n -L < | + | |
| - | + | ||
| - | actionban = iptables -I fail2ban-< | + | |
| - | + | ||
| - | actionunban = iptables -D fail2ban-< | + | |
| - | + | ||
| - | [Init] | + | |
| - | name = default | + | |
| - | port = ssh | + | |
| - | protocol = tcp | + | |
| - | chain = INPUT | + | |
| - | </ | + | |
| ==== Ban IP Range (subnet) ==== | ==== Ban IP Range (subnet) ==== | ||
| In some cases spammers have several systems infected in a specific subnet. By using different alternating IP nummers in this subnet, they can avoid Fail2Ban detection. In these cases it could be helpful to block a whole subnet range at once. | In some cases spammers have several systems infected in a specific subnet. By using different alternating IP nummers in this subnet, they can avoid Fail2Ban detection. In these cases it could be helpful to block a whole subnet range at once. | ||
| Line 351: | Line 324: | ||
| </ | </ | ||
| If there is anything wrong with the fail or filter, an error would be reported. | If there is anything wrong with the fail or filter, an error would be reported. | ||
| - | |||
| - | ===== Test Configuration ===== | ||
| - | There are a few ways to verify the configuration and operation of fail2ban: | ||
| ===== Monitor Status ===== | ===== Monitor Status ===== | ||
| - | ==== IP-tables ==== | + | There are 2 options |
| - | You can look at iptables to see that fail2ban has modified your firewall rules to create a framework for banning | + | - fail2ban-client |
| - | | + | - nft list ruleset |
| - | Output | + | |
| - | < | + | |
| - | Output | + | |
| - | -P INPUT ACCEPT | + | |
| - | -P FORWARD ACCEPT | + | |
| - | -P OUTPUT ACCEPT | + | |
| - | -N fail2ban-nginx-badbots | + | |
| - | -N fail2ban-nginx-http-auth | + | |
| - | -N fail2ban-nginx-nohome | + | |
| - | -N fail2ban-nginx-noproxy | + | |
| - | -N fail2ban-nginx-noscript | + | |
| - | -N fail2ban-ssh | + | |
| - | -A INPUT -p tcp -m multiport --dports 80,443 -j fail2ban-nginx-noproxy | + | |
| - | -A INPUT -p tcp -m multiport --dports 80,443 -j fail2ban-nginx-nohome | + | |
| - | -A INPUT -p tcp -m multiport --dports 80,443 -j fail2ban-nginx-badbots | + | |
| - | -A INPUT -p tcp -m multiport --dports 80,443 -j fail2ban-nginx-noscript | + | |
| - | -A INPUT -p tcp -m multiport --dports 80,443 -j fail2ban-nginx-http-auth | + | |
| - | -A INPUT -p tcp -m multiport --dports 22 -j fail2ban-ssh | + | |
| - | -A fail2ban-nginx-badbots -j RETURN | + | |
| - | -A fail2ban-nginx-http-auth -j RETURN | + | |
| - | -A fail2ban-nginx-nohome -j RETURN | + | |
| - | -A fail2ban-nginx-noproxy -j RETURN | + | |
| - | -A fail2ban-nginx-noscript -j RETURN | + | |
| - | -A fail2ban-ssh -j RETURN | + | |
| - | </ | + | |
| ==== fail2ban-client ==== | ==== fail2ban-client ==== | ||
| - | You can see all of your enabled jails by using the fail2ban-client command: | + | You can see an overview |
| - | sudo fail2ban-client status | + | |
| - | You should see a list of all of the jails you enabled: | + | |
| < | < | ||
| + | # fail2ban-client status | ||
| + | ------------------------ | ||
| Status | Status | ||
| - | |- Number of jail: 1 | + | |- Number of jail: 5 |
| - | `- Jail list: sshd | + | `- Jail list: nextcloud, nginx-bad-request, |
| </ | </ | ||
| If you want to see the details of the bans being enforced by any one jail, it is probably easier to use the fail2ban-client again: | If you want to see the details of the bans being enforced by any one jail, it is probably easier to use the fail2ban-client again: | ||
| - | sudo fail2ban-client status nginx-http-auth | ||
| - | Output | ||
| < | < | ||
| - | Status for the jail: nginx-http-auth | + | # fail2ban-client status www-login-fail |
| - | |- filter | + | --------------------------------------- |
| - | | |- File list: / | + | Status for the jail: www-login-fail |
| - | | |- Currently | + | |- Filter |
| - | | `- Total failed: 12 | + | | |- Currently failed: 0 |
| - | `- action | + | | |- Total failed: 3 |
| - | |- Currently banned: | + | | `- File list: / |
| - | | + | `- Actions |
| - | | + | |- Currently banned: 0 |
| + | | ||
| + | | ||
| </ | </ | ||
| + | ==== NFtables ==== | ||
| + | You can look at nftables to see that fail2ban has modified your firewall rules to create a framework for banning clients. Even with no previous firewall rules, you would now have a framework enabled that allows fail2ban to selectively ban clients by adding them to purpose-built chains: | ||
| + | < | ||
| + | #nft list ruleset | ||
| + | ----------------- | ||
| + | table inet f2b-table { | ||
| + | set addr-set-www-login-fail { | ||
| + | type ipv4_addr | ||
| + | flags interval | ||
| + | elements = { 192.168.178.0/ | ||
| + | } | ||
| + | |||
| + | set addr6-set-www-login-fail { | ||
| + | type ipv6_addr | ||
| + | flags interval | ||
| + | elements = { fdaa: | ||
| + | } | ||
| + | |||
| + | chain f2b-chain { | ||
| + | type filter hook input priority filter - 1; policy accept; | ||
| + | tcp dport { 80, 443 } ip saddr @addr-set-www-login-fail reject with icmp port-unreachable | ||
| + | tcp dport { 80, 443 } ip6 saddr @addr6-set-www-login-fail reject with icmpv6 port-unreachable | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | |||
| ===== Unbanning ===== | ===== Unbanning ===== | ||
| you can manually un-ban your IP address with the fail2ban-client by typing: | you can manually un-ban your IP address with the fail2ban-client by typing: | ||
| - | | + | |
| Or for unbanning all jails at once: | Or for unbanning all jails at once: | ||
| - | fail2ban-client unban --all | + | |
| + | ===== Cleaning ===== | ||
| + | The above unbanning commands will remove the IP's from the nftables firewall, but the rule and table structures will remain in the nfttables firewall. If you want to clean / reset everything: | ||
| + | # fail2ban-client stop www-login-fail | ||
| + | The following command will only clear the nftables structures, but this could lead to errors in jail2bin logs. | ||
| + | # nft clear ruleset | ||
| ===== Optional: Setting Up Mail Notifications ===== | ===== Optional: Setting Up Mail Notifications ===== | ||
| Line 431: | Line 408: | ||
| . . . | . . . | ||
| </ | </ | ||
| - | |||
| ===== NGINX ===== | ===== NGINX ===== | ||
| - | Default | + | We enables the following 2 default |
| - | * **nginx-botsearch.conf**: | + | * **nginx-bad-request.conf**: |
| - | * **nginx-http-auth.conf**: | + | * **nginx-botsearch.conf**: |
| + | The following have been added by ourselves: | ||
| + | * **nginx-x00.conf**: | ||
| + | * **www-login-fail.conf**: | ||
| + | The following default is not used, because we have no basic auth enables in Nginx | ||
| + | * **nginx-http-auth.conf**: | ||
| * **nginx-limit-req.conf**: | * **nginx-limit-req.conf**: | ||
| - | The following additional can be added: | ||
| - | * **nginx-no-script.conf**: | + | ==== / |
| - | * **nginx-x00.conf**: | + | |
| - | * **nginx-proxy.conf**: | + | |
| - | * **nginx-dos.conf**: | + | |
| - | * **nginx-4xx**: | + | |
| - | ==== nginx-noscript.conf ==== | + | |
| - | Add the following jail section to / | + | |
| < | < | ||
| - | [nginx-noscript] | + | # |
| + | # HTTP servers | ||
| + | # | ||
| + | [nginx-botsearch] | ||
| + | enabled = true | ||
| + | port = http, | ||
| + | logpath = / | ||
| + | findtime | ||
| + | maxretry = 3 | ||
| + | banaction = nftables-subnet[type=multiport] | ||
| + | |||
| + | [nginx-bad-request] | ||
| + | enabled = true | ||
| + | port = http, | ||
| + | logpath = / | ||
| + | findtime | ||
| + | maxretry = 3 | ||
| + | banaction = nftables-subnet[type=multiport] | ||
| + | |||
| + | [nginx-x00] | ||
| enabled | enabled | ||
| port = http,https | port = http,https | ||
| - | filter | + | logpath |
| - | logpath | + | findtime |
| - | </ | + | maxretry = 2 |
| - | Add the following | + | banaction = nftables-subnet[type=multiport] |
| - | < | + | |
| - | # | + | [www-login-fail] |
| - | # Noscript filter | + | enabled = true |
| + | port = http,https | ||
| + | logpath = /var/log/nginx/error.www.log | ||
| + | findtime | ||
| + | maxretry = 3 | ||
| + | banaction = nftables-subnet[type=multiport] | ||
| + | |||
| + | # To use more aggressive http-auth modes set filter | ||
| + | # normal (default), aggressive (combines all), auth or fallback | ||
| + | # See "tests/files/logs/nginx-http-auth" | ||
| + | [nginx-http-auth] | ||
| + | # mode = normal | ||
| + | port = http, | ||
| + | logpath = %(nginx_error_log)s | ||
| + | |||
| + | # To use ' | ||
| + | # and define `limit_req` and `limit_req_zone` as described in nginx documentation | ||
| + | # http://nginx.org/ | ||
| + | # or for example see in ' | ||
| + | [nginx-limit-req] | ||
| + | port = http, | ||
| + | logpath = %(nginx_error_log)s | ||
| # | # | ||
| - | # Block IPs trying to execute scripts such as .php, .pl, .exe and other funny scripts. | + | # Web Applications |
| # | # | ||
| - | # Matches e.g. | ||
| - | # 192.168.1.1 - - "GET / | ||
| # | # | ||
| + | [nextcloud] | ||
| + | enabled = true | ||
| + | #port = 80,443 | ||
| + | port = http,https | ||
| + | #protocol = tcp | ||
| + | logpath = / | ||
| + | bantime = 86400 | ||
| + | findtime = 3600 | ||
| + | maxretry = 2 | ||
| + | banaction = nftables-subnet[type=multiport] | ||
| + | </ | ||
| + | ==== / | ||
| + | < | ||
| [Definition] | [Definition] | ||
| + | # The request often doesn' | ||
| + | # This will also match requests that are entirely empty | ||
| + | failregex = ^< | ||
| - | failregex | + | datepattern |
| + | ^[^\[]*\[({DATE}) | ||
| + | {^LN-BEG} | ||
| - | ignoreregex | + | journalmatch |
| </ | </ | ||
| + | ==== / | ||
| + | < | ||
| + | [Definition] | ||
| - | ==== nginx-x00.conf ==== | + | # Blocking repeated 404|444|403|400 |
| - | To block potentially malicious x03\x00 | + | # This will also match requests |
| - | 77.72.83.87 - - _ [28/Dec/2018:14:13:14 +0000] "\x03\x00\x00/ | + | failregex = ^< |
| - | Add the following jail section to / | + | |
| + | datepattern = {^LN-BEG}%%ExY(? | ||
| + | ^[^\[]*\[({DATE}) | ||
| + | {^LN-BEG} | ||
| + | |||
| + | journalmatch = _SYSTEMD_UNIT=nginx.service + _COMM=nginx | ||
| + | |||
| + | </ | ||
| + | |||
| + | ==== / | ||
| < | < | ||
| - | [nginx-x00] | + | INCLUDES] |
| - | enabled | + | # Load regexes for filtering |
| - | port | + | before |
| - | filter | + | |
| - | logpath | + | [Definition] |
| + | failregex | ||
| + | ^ \[error\] \d+#\d+: \*\d+ (\S+ )? | ||
| + | |||
| + | ignoreregex | ||
| + | |||
| + | datepattern | ||
| + | ^[^\[]*\[({DATE}) | ||
| + | {^LN-BEG} | ||
| + | |||
| + | journalmatch = _SYSTEMD_UNIT=nginx.service + _COMM=nginx | ||
| </ | </ | ||
| - | Add the following filter file **/ | + | ==== / |
| < | < | ||
| - | Filename: / | + | [INCLUDES] |
| + | # Load regexes for filtering | ||
| + | before = | ||
| - | [Definition] | + | [Definition] |
| - | failregex = ^{" | + | failregex = ^.+Login\sattempt\suser.+incorrect\spassword.+client:\s< |
| + | ^.+Login\sattempt\sip\[< | ||
| ignoreregex = | ignoreregex = | ||
| - | </ | ||
| - | ==== nginx-proxy.conf ==== | + | datepattern |
| - | Block IPs trying to use server as proxy. | + | |
| - | Add the following jail section to / | + | |
| - | < | + | |
| - | [nginx-proxy] | + | |
| - | enabled = true | + | |
| - | action = iptables-multiport[name=NoProxy, | + | |
| - | filter = nginx-proxy | + | |
| - | logpath = / | + | |
| - | maxretry = 0 | + | |
| - | bantime | + | |
| </ | </ | ||
| - | Add the following filter file **/ | + | ==== / |
| < | < | ||
| - | # Proxy filter / | ||
| - | # | ||
| - | # Block IPs trying to use server as proxy. | ||
| - | # | ||
| - | # Matches e.g. | ||
| - | # 192.168.1.1 - - "GET http:// | ||
| - | # | ||
| [Definition] | [Definition] | ||
| - | failregex = ^< | + | failregex=^.*Login failed: '? |
| + | ^.*\" | ||
| ignoreregex = | ignoreregex = | ||
| + | |||
| </ | </ | ||
| - | ==== nginx-dos.conf | + | |
| - | Block IPs trying to ddos the server. | + | ===== MAIL ===== |
| - | Add the following jail section to /etc/fail2ban/jail.local: | + | ==== /lib/systemd/system/ |
| + | Fail2ban depends on the log files of postfix, dovecot and rspamd. It should only be started after these services. To achieve this add these services into: | ||
| < | < | ||
| - | [nginx-dos] | + | # nano /lib/systemd/system/fail2ban.service |
| - | enabled | + | ------------------------------------------- |
| - | port = http | + | [Unit] |
| - | filter | + | ... |
| - | logpath | + | After=network.target iptables.service firewalld.service ip6tables.service ipset.service nftables.service dovecot.service postfix.service rspamd.service |
| - | findtime = 120 | + | |
| - | maxretry | + | |
| </ | </ | ||
| - | Add the following | + | |
| + | ==== Config ==== | ||
| + | We enables | ||
| + | | ||
| + | * **postfix.conf**: | ||
| + | * **postfix-sasl.conf**: filter for selected Postfix Authentication failures | ||
| + | ==== / | ||
| < | < | ||
| + | [sshd] | ||
| + | |||
| + | # To use more aggressive sshd modes set filter parameter " | ||
| + | # normal (default), ddos, extra or aggressive (combines all). | ||
| + | # See " | ||
| + | enabled = true | ||
| + | #mode = normal | ||
| + | port = ssh | ||
| + | logpath = %(sshd_log)s | ||
| + | #backend = %(sshd_backend)s | ||
| + | backend = systemd | ||
| + | |||
| # | # | ||
| - | # Ddos filter / | + | # Mail servers |
| # | # | ||
| - | # Block IPs trying to ddos the server. | + | [postfix] |
| - | # | + | # To use another modes set filter parameter " |
| - | # | + | enabled = true |
| - | [Definition] | + | mode = more |
| + | port = smtp, | ||
| + | bantime | ||
| + | findtime = 14400 | ||
| + | maxretry = 3 | ||
| + | #logpath = %(postfix_log)s | ||
| + | logpath = / | ||
| + | backend = %(postfix_backend)s | ||
| - | failregex = ^< | + | [postfix-rbl] |
| + | filter | ||
| + | port = smtp, | ||
| + | logpath | ||
| + | backend | ||
| + | maxretry = 1 | ||
| - | ignoreregex | + | [postfix-sasl] |
| - | </code> | + | enabled |
| + | filter | ||
| + | port = smtp, | ||
| + | bantime | ||
| + | findtime = 43200 | ||
| + | maxretry = 2 | ||
| + | banaction = nftables-subnet[type=multiport] | ||
| + | # You might consider monitoring | ||
| + | # running postfix since it would provide the same log lines at the | ||
| + | # " | ||
| + | # | ||
| + | logpath | ||
| + | backend | ||
| - | ==== nginx-4xx ==== | + | [sendmail-auth] |
| - | Get rid of those 404 attempts in my daily logs. | + | port = submission,465,smtp |
| - | Add the following jail section to / | + | logpath = %(syslog_mail)s |
| - | < | + | backend |
| - | [nginx-4xx] | + | |
| - | enabled = true | + | |
| - | port = http,https | + | |
| - | logpath = / | + | |
| - | maxretry | + | |
| - | </ | + | |
| - | Add the following filter file **/ | + | |
| - | < | + | |
| - | [Definition] | + | |
| - | failregex = ^< | + | |
| - | ignoreregex = | + | |
| - | </ | + | |
| + | [sendmail-reject] | ||
| + | # To use more aggressive modes set filter parameter " | ||
| + | # normal (default), extra or aggressive | ||
| + | # See " | ||
| + | #mode = normal | ||
| + | port = smtp, | ||
| + | logpath | ||
| + | backend | ||
| + | |||
| + | |||
| + | # dovecot defaults to logging to the mail syslog facility | ||
| + | # but can be set by syslog_facility in the dovecot configuration. | ||
| + | [dovecot] | ||
| + | enabled | ||
| + | port = pop3, | ||
| + | bantime | ||
| + | findtime = 43200 | ||
| + | maxretry = 2 | ||
| + | #logpath = %(dovecot_log)s | ||
| + | logpath = / | ||
| + | backend = %(dovecot_backend)s | ||
| + | |||
| + | |||
| + | [sieve] | ||
| + | port = smtp, | ||
| + | logpath = %(dovecot_log)s | ||
| + | backend = %(dovecot_backend)s | ||
| + | |||
| + | [mysqld-auth] | ||
| + | port = 3306 | ||
| + | logpath | ||
| + | backend | ||
| + | |||
| + | # Generic filter for PAM. Has to be used with action which bans all | ||
| + | # ports such as iptables-allports, | ||
| + | [pam-generic] | ||
| + | # pam-generic filter can be customized to monitor specific subset of ' | ||
| + | banaction = %(banaction_allports)s | ||
| + | logpath | ||
| + | backend | ||
| + | |||
| + | |||
| + | </ | ||
| ===== Links ===== | ===== Links ===== | ||
linux/apps/fail2ban.1693938758.txt.gz · Last modified: by oscar
