Методы применения fail2ban для защиты ubuntu-сервера от хакеров и спамеров

Должен признаться, что имея уже большой (многолетний) опыт администрирования ubuntu-серверов, я лишь недавно, уступив настойчивым требованиям (рекомендациям) друзей (коллег), решился применить на ряде своих хостов fail2ban. Я очень не люблю модифицировать штатные механизмы функционирования системы, и мысль о том, что некий посторонний продукт будет вмешиваться в работу ядра (через iptables) долгое время приводила меня в ужас.

Но вот настал этот час, и я решил попробовать. В крайнем случае, думал я, сделаю «apt remove» — и верну все взад. Но делать этого не пришлось. Оказалось, что все работает как часы и абсолютно никаких проблем на сервере не возникает. В итоге я остался очень доволен и решил всем рассказать, что именно у меня получилось.

Изначально задача состояла в том, чтобы защитить от хакерской и спамерской активности bind, nginx, postfix и ssh. В последствии в этот список добавился phpBB (чисто случайно и факультативно).

Начал я с того, что некоторое время использовал только штатные фильтры самого fail2ban. И, представьте себе, был вполне доволен. То есть, я не пожалел о том, что задействовал на своих хостах fail2ban — даже в чисто базовой его конфигурации. Собственно говоря, тут тоже сыграла роль моя приверженность использованию исключительно штатных средств. И опять же, как и с внедрением самого fail2ban, мне тут же со всех сторон посыпались советы о применении своих кастомных фильтров, чему я долго сопротивлялся, но в итоге и здесь не выдержал. Что вам сказать? Конечно, это — небо и земля. Впрочем, из дальнейшего изложения вы и сами увидите, что штатные фильтры и рядом не стояли с кастомными — последние работают на порядок эффективнее.

Итак, переходя к конкретному изложению, даю для начала дефолтные настройки, которые работают у меня (идентично на всех хостах) для всех тех модулей (как штатных, так и кастомных), которые будут рассматриваться ниже:

# cat fail2ban.local
[DEFAULT]
dbpurgeage = 5w

# cat default.local
[DEFAULT]
ignoreip = 127.0.0.1/8
port = all
maxretry = 3
findtime = 6h
bantime = 1d

Штатные модули fail2ban

Модуль sshd

Сразу скажу, это — единственный штатный модуль fail2ban (не считая, конечно, модуля recidive), который показал высокую эффективность и который не пришлось заменять кастомным. У меня он работает с такими настройками:

[sshd]
enabled = true
logpath = %(sshd_log)s
backend = %(sshd_backend)s
action  = iptables-allports[name=sshd, blocktype=DROP, protocol=all]
mode    = aggressive

Результат его работы поразителен (в хорошем смысле этого слова):

# fail2ban-client status sshd
Status for the jail: sshd
|- Filter
| |- Currently failed: 12
| |- Total failed: 2881
| `- File list: /var/log/auth.log
`- Actions
|- Currently banned: 226
|- Total banned: 877
`- Banned IP list: 78.187.21.105 54.38.52.18 156.251.179.157 103.172.20.218 87.106.44.172 165.154.1.18 103.144.2.208 8.243.50.114 210.79.191.199 157.7.113.83 113.193.234.210 175.100.24.139 14.29.198.63 220.119.37.141 103.76.120.204 122.118.198.152 106.13.69.159 187.210.77.100 116.99.172.236 116.99.169.79 27.79.47.236 27.79.1.111 92.118.39.72 159.223.37.230 201.245.201.162 49.49.239.64 121.125.70.58 85.24.209.239 165.154.6.116 103.186.0.182 23.91.97.213 120.62.8.17 23.227.147.163 106.58.166.77 156.227.236.72 61.72.55.130 62.14.96.56 172.190.142.151 157.66.26.151 222.107.156.227 105.27.148.94 187.107.88.97 177.229.197.38 51.75.194.10 165.227.152.183 87.106.4.124 85.121.120.129 185.196.8.6 217.154.35.203 217.154.167.36 206.189.112.134 185.196.10.164 185.196.10.227 64.188.83.244 34.91.0.68 212.11.64.156 83.168.90.177 34.78.29.97 69.5.189.81 185.196.10.197 20.26.135.100 152.228.130.131 40.81.244.142 91.107.150.117 207.154.254.44 185.196.10.248 203.192.232.180 143.110.241.64 54.38.157.20 217.154.192.185 134.209.108.115 52.237.80.79 66.154.124.165 91.134.240.52 194.164.195.247 161.35.173.173 35.200.237.19 185.196.10.253 91.107.151.241 128.199.124.133 64.188.83.153 20.244.18.126 172.173.117.246 194.190.153.226 103.49.239.212 176.191.43.176 31.57.187.56 34.58.124.191 203.209.181.4 172.191.157.64 188.166.218.64 37.49.227.76 151.60.149.93 23.227.173.100 154.222.24.142 185.113.139.51 89.126.209.84 146.190.79.63 103.182.132.154 186.96.151.198 178.128.92.222 52.187.9.8 34.175.118.185 155.4.245.222 195.158.4.216 143.198.161.12 87.106.146.223 167.172.206.192 196.28.242.198 137.184.228.138 154.236.187.90 93.71.118.99 185.237.95.203 159.223.8.62 87.106.69.120 81.193.216.17 189.147.255.203 135.237.122.43 103.147.159.91 68.183.236.1 165.232.163.9 185.227.111.126 185.158.23.150 52.172.177.191 103.250.11.207 27.50.25.190 41.111.162.34 148.113.204.225 209.46.120.16 157.20.207.165 52.224.109.126 131.161.249.165 103.249.84.18 50.6.193.137 203.145.34.78 157.230.129.46 103.88.76.27 4.211.84.189 134.112.56.47 172.200.228.35 45.120.120.69 74.88.7.20 122.168.194.41 166.1.60.230 86.54.42.185 14.63.196.175 20.123.146.95 196.188.63.22 4.210.186.201 196.188.63.205 68.183.203.22 137.184.203.236 4.210.91.174 176.53.96.208 94.180.238.116 103.176.78.213 163.7.4.33 14.103.112.35 103.48.84.178 119.12.169.207 111.68.98.152 154.90.59.75 158.178.137.15 92.27.101.99 119.203.251.187 101.91.114.235 213.209.159.158 14.34.157.138 154.90.54.142 14.103.107.221 130.162.132.75 2.57.121.112 103.13.207.182 154.117.199.56 14.29.198.130 165.154.147.69 107.175.77.100 14.103.112.106 213.209.159.159 209.141.41.212 117.221.161.3 72.17.34.38 123.58.213.127 170.238.160.191 92.118.39.56 45.249.246.120 42.51.49.239 37.143.61.84 2.57.122.210 117.216.143.31 80.94.92.182 80.94.95.115 103.76.120.202 131.161.219.137 103.13.207.34 82.153.157.222 212.33.235.243 69.6.220.104 45.78.198.158 103.86.198.162 171.231.188.206 27.79.5.10 177.53.215.134 83.97.24.41 103.189.235.33 13.81.183.28 157.97.107.143 185.152.92.63 36.64.68.99 103.27.60.83 103.67.78.217 158.69.194.34 219.153.100.188 103.23.198.86 103.49.238.236 199.231.163.19 49.231.192.36 20.49.0.100 88.142.46.185 161.248.189.72 91.217.139.150 221.213.129.46 212.11.64.229 119.205.179.217 116.230.142.197 125.138.175.113

Это, я считаю, прекрасный результат, не нуждающийся ни в какой кастомизации. Именно в таком виде у меня это и работает — одинаково на всех хостах. В работу fail2ban с sshd я решил не вмешиваться. Ведь все знают главный принцип системного администрирования — не трогай технику, и она не подведет.

Модуль bind

Штатный модуль bind (использует фильтр named-refused) предназначен для защиты сервера имен от несанкционированной передаче зон методом AXFR. Никаких других задач он выполнять не способен, в то время как основная хакерская активность (по моим наблюдениям) направлена на попытки заставить ваш сервер имен выполнить несанкционированную рекурсию. Работает этот модуль у меня с такими настройками:

[bind]
enabled = true
filter = named-refused
logpath = /var/log/named/security.log
action = iptables-allports[name=bind, blocktype=DROP, protocol=all]

Результаты его работы впечатляют (на этот раз — в плохом смысле этого слова):

# fail2ban-client status bind
Status for the jail: bind
|- Filter
| |- Currently failed: 0
| |- Total failed: 0
| `- File list: /var/log/named/security.log
`- Actions
|- Currently banned: 0
|- Total banned: 0
`- Banned IP list:

Справедливости ради, надо сказать, что поначалу здесь изредка появлялись некие (слабо) отличные от нуля показатели, но, видимо, со временем эти клиенты улетели в recidive и теперь ими тут уже и не пахнет.

Совершенно ясно, что этот модуль нуждается в кастомизации, которая и была мною выполнена и будет описана ниже в надлежащем месте этой публикации.

Модуль nginx-botsearch

Этот модуль предназначен для борьбы для блокирования хакерской активности среди клиентов www-сервера nginx. Он работает как с access.log (лог доступа), так и с error.log (лог ошибок). Запускаю я его с такими параметрами:

[nginx-botsearch]
enabled = true
filter = nginx-botsearch
logpath = /var/log/nginx/access.log
          /var/log/nginx/error.log
action = iptables-allports[name=nginx-botsearch, blocktype=DROP, protocol=all]

Следует отметить, что этот штатный фильтр показывает намного большую эффективность чем предыдущий (хотя и сильно отстает от моих кастомных модулей, о которых речь впереди):

# fail2ban-client status nginx-botsearch
Status for the jail: nginx-botsearch
|- Filter
| |- Currently failed: 0
| |- Total failed: 56
| `- File list: /var/log/nginx/access.log /var/log/nginx/error.log
`- Actions
|- Currently banned: 4
|- Total banned: 19
`- Banned IP list: 45.156.128.106 45.156.128.109 64.181.211.198 94.26.106.17

Почтовые фильтры fail2ban

К штатным почтовым (для сервера postfix, которым я везде пользуюсь) фильтрам fail2ban относятся: postfix, postfix-sasl и dovecot. Работают они у меня с такими настройками:

[postfix]
enabled = true
filter = postfix
logpath = /var/log/mail.log
action = iptables-allports[name=postfix, blocktype=DROP, protocol=all]

[postfix-sasl]
enabled = true
filter = postfix[mode=auth]
logpath = /var/log/mail.log
action = iptables-allports[name=postfix-sasl, blocktype=DROP, protocol=all]

[dovecot]
enabled = true
filter = dovecot[mode=aggressive]
logpath = /var/log/mail.log
action = iptables-allports[name=dovecot, blocktype=DROP, protocol=all]

Эффективность их работы, конечно не нулевая, но явно не удовлетворяет наших ожиданий (ниже будет показано, что мои кастомные фильтры блокируют спамеров и хакеров намного лучше):

# fail2ban-client status postfix
Status for the jail: postfix
|- Filter
| |- Currently failed: 22
| |- Total failed: 39
| `- File list: /var/log/mail.log
`- Actions
|- Currently banned: 0
|- Total banned: 0
`- Banned IP list:

# fail2ban-client status postfix-sasl
Status for the jail: postfix-sasl
|- Filter
| |- Currently failed: 4
| |- Total failed: 17
| `- File list: /var/log/mail.log
`- Actions
|- Currently banned: 0
|- Total banned: 3
`- Banned IP list:

# fail2ban-client status dovecot
Status for the jail: dovecot
|- Filter
| |- Currently failed: 28
| |- Total failed: 300
| `- File list: /var/log/mail.log
`- Actions
|- Currently banned: 3
|- Total banned: 25
`- Banned IP list: 3.131.220.121 64.227.10.52 65.49.1.152

Модуль recidive

Этот прекрасно работающий штатный модуль fail2ban (и потому, как уже было выше упомянуто, не нуждающийся ни в какой кастомизации) предназначен для организации особо длительного бана для тех ip-адресов, которые систематически занимаются хакерской и спамерской деятельностью. Работает он у меня с такими параметрами:

[recidive]
enabled = true
logpath = /var/log/fail2ban.log
filter = recidive
findtime = 1w
bantime = 4w
action = iptables-allports[name=recidive, blocktype=DROP, protocol=all]

И работает весьма успешно:

# fail2ban-client status recidive
Status for the jail: recidive
|- Filter
| |- Currently failed: 1232
| |- Total failed: 1666
| `- File list: /var/log/fail2ban.log
`- Actions
|- Currently banned: 90
|- Total banned: 177
`- Banned IP list: 103.103.245.61 103.179.27.94 134.209.43.171 139.59.71.161 14.103.115.80 152.32.200.117 162.158.87.106 165.154.128.17 172.70.250.179 18.97.26.108 20.220.15.47 27.111.32.174 3.143.162.210 40.69.66.178 45.144.212.136 45.144.212.169 45.149.173.219 45.149.173.233 45.204.209.224 52.138.22.173 77.83.39.180 80.94.95.116 80.94.95.216 92.118.39.92 4.223.76.100 74.82.47.3 2.57.122.238 52.178.176.146 185.93.89.64 3.129.187.38 121.229.27.155 172.70.248.157 20.234.20.103 18.218.118.203 77.83.39.71 40.69.27.251 64.62.156.172 77.90.185.65 103.211.219.58 34.158.79.105 185.177.72.22 185.177.72.13 34.193.92.251 13.79.87.25 85.113.41.196 20.220.232.101 3.132.26.232 4.204.200.32 20.151.11.236 78.128.112.74 172.71.15.44 92.118.39.95 52.169.148.186 20.151.2.242 45.148.10.121 81.29.142.100 40.113.19.56 216.73.216.84 2.57.121.25 74.125.208.227 103.98.176.164 185.177.72.52 185.177.72.49 92.118.39.72 20.220.232.240 20.216.146.160 203.192.232.180 185.196.10.253 176.53.96.208 2.57.121.112 172.190.142.176 3.134.216.108 3.131.220.121 64.181.211.198 213.209.159.159 80.94.92.182 131.161.219.137 85.203.23.37 85.203.23.27 85.203.23.25 85.203.23.24 91.92.243.228 74.125.208.229 46.151.182.6 74.243.251.125 103.49.238.236 199.231.163.19 89.248.168.239 74.125.208.228 18.116.101.220

При этом отмечу, что этот модуль вылавливает «рецедивистов» и среди штатных, и среди кастомных модулей — не делая между ними никакого различия. То есть, он работает в интересах всей системы защиты в целом.

Модули Extra Systems для fail2ban

Ввиду глубокой неудовлетворенности тем состоянием дел, которое имело место на начальном этапе эксплуатации системы fail2ban с использованием одних лишь штатных модулей этого продукта, мною был разработан ряд собственных (кастомных) фильтров, которые продемонстрировали на практике куда более высокую эффективность отлова спамеров и хакеров на моих хостах.

Модуль es-bind-errors

Этот модуль предназначен для нейтрализации как тех хакеров, которые пытаются делать незаконные AXFR зон на сервере bind, так и тех, которые пытаются незаконно вызвать там рекурсию — как правило, с целью DDOS атаки на определенные серверы имен. Следует отметить, что хакерская активность второго вида идет намного активнее первой. Именно поэтому эффективность данного кастомного модуля существенно превышает эффективность штатного (который интересуется одними лишь AXFR). Работа модуля es-bind-errors на моих серверах идет с такими параметрами:

[es-bind-errors]
enabled = true
filter = es-bind-errors
logpath = /var/log/named/security.log
action = iptables-allports[name=es-bind-errors, blocktype=DROP, protocol=all]

и такими результатами:

Status for the jail: es-bind-errors
|- Filter
| |- Currently failed: 8
| |- Total failed: 252
| `- File list: /var/log/named/security.log
`- Actions
|- Currently banned: 2
|- Total banned: 15
`- Banned IP list: 176.65.139.36 86.41.74.151

Текст фильтра имеет такой вид:

# cat es-bind-errors.conf
[Definition]
failregex = ^.* query-errors: info: client @0x\S+ <HOST>#\d+ \(.*\): query failed \(REFUSED\)
            ^.* security: error: client @0x\S+ <HOST>#\d+ \(.*\): zone transfer '.*' denied
ignoreregex =

Модули от Extra Systems для работы fail2ban с nginx

Для работы с логами nginx мною было разработано два фильтра — es-nginx-access (анализирует лог доступа) и es-nginx-errors (анализирует лог ошибок). Они имеют такой текст:

# cat es-nginx-access.conf
[Definition]
failregex = ^<HOST> - - \[.*\] ".*" 400\s
            ^<HOST> - - \[.*\] "GET /.*\.php HTTP/.*" 404
            ^<HOST> - - \[.*\] "POST /wp-login.php HTTP/\d\.\d" (200|301)\s
            ^<HOST> - - \[.*\] "(GET|POST) /\.(?!well-known/acme-challenge/).*" 404
            ^<HOST> - - \[.*\] "GET /\$\(pwd\)/\..*" 404
            ^<HOST> - - \[.*\] "(GET|POST) /.*(\.\.\/\.\.\/\.\.\/|cgi-bin|eval-stdin).*" 404
            ^<HOST> - - \[.*\] "GET /\?(p|m|author)=\d+ HTTP/\d\.\d" 404\s
            ^<HOST> - - \[.*\] "POST //?xmlrpc\.php HTTP/\d\.\d" 200\s
            ^<HOST> - - \[.*\] "GET /(dns-query|query|resolve)\?(dns|name)=.*" 404\s
ignoreregex =

# cat es-nginx-errors.conf
[Definition]
failregex = ^.* open\(\) ".*\/wp-includes\/wlwmanifest\.xml" failed \(2: No such file or directory\), client: <HOST>
            ^.* directory index of ".*" is forbidden, client: <HOST>
            ^.* ".*\/index\.(php|htm).*" is not found \(2: No such file or directory\), client: <HOST>
            ^.* open\(\) ".*(\.env|\.git|\.auto\.tfvars).*" failed \(2: No such file or directory\), client: <HOST>
            ^.* open\(\) ".*\.php" failed \(2: No such file or directory\), client: <HOST>
            ^.*\[crit\] \d+#\d+: \*\d+ SSL_do_handshake\(\) failed \(SSL: error:0A00006C:SSL routines::bad key share\) while SSL handshaking, client: <HOST>, server: .*$
ignoreregex =

Эксплуатация этих модулей в моей системе производится с такими параметрами:

[es-nginx-access]
enabled = true
filter = es-nginx-access
logpath = /var/log/nginx/access.log
action = iptables-allports[name=es-nginx-access, blocktype=DROP, protocol=all]

[es-nginx-errors]
enabled = true
filter = es-nginx-errors
logpath = /var/log/nginx/error.log
action = iptables-allports[name=es-nginx-errors, blocktype=DROP, protocol=all]

и обеспечивает такие (можно прямо сказать — выдающиеся) результаты:

Status for the jail: es-nginx-access
|- Filter
| |- Currently failed: 74
| |- Total failed: 3126
| `- File list: /var/log/nginx/access.log
`- Actions
|- Currently banned: 84
|- Total banned: 340
`- Banned IP list: 185.177.72.52 185.177.72.49 220.181.108.166 5.101.64.6 165.232.120.118 85.203.23.114 85.203.23.151 85.203.23.146 85.203.23.148 85.203.23.116 85.203.23.135 85.203.23.115 85.203.23.137 85.203.23.142 85.203.23.141 85.203.23.127 85.203.23.121 85.203.23.129 85.203.23.159 85.203.23.155 85.203.23.128 85.203.23.158 85.203.23.119 85.203.23.161 20.220.232.240 200.9.155.87 147.185.132.38 162.158.95.127 162.158.95.128 181.176.14.90 172.71.26.130 172.70.90.140 172.70.91.183 20.216.146.160 216.180.246.179 35.216.144.195 52.169.119.118 185.91.69.5 172.190.142.176 167.94.146.55 64.181.211.198 199.195.248.31 20.223.198.174 20.215.218.57 85.203.23.26 85.203.23.37 85.203.23.27 85.203.23.25 85.203.23.24 85.203.23.32 85.203.23.23 51.107.72.110 74.125.208.229 68.221.64.113 200.129.167.17 85.203.23.75 85.203.23.61 85.203.23.67 85.203.23.89 85.203.23.56 85.203.23.99 85.203.23.87 85.203.23.98 14.229.82.79 172.70.251.204 172.70.251.203 104.23.225.169 104.23.225.32 104.23.225.74 104.23.225.109 80.82.77.202 51.120.72.165 172.213.208.27 168.63.71.67 51.120.82.8 74.243.251.125 20.215.185.19 74.7.242.141 20.203.162.101 74.7.227.40 217.154.69.208 89.248.168.239 74.125.208.228 18.116.101.220

Status for the jail: es-nginx-errors
|- Filter
| |- Currently failed: 22
| |- Total failed: 1952
| `- File list: /var/log/nginx/error.log
`- Actions
|- Currently banned: 51
|- Total banned: 306
`- Banned IP list: 185.177.72.52 185.177.72.49 162.158.95.127 162.158.95.128 172.71.26.109 172.70.91.196 172.70.91.183 172.70.90.140 172.71.26.130 172.70.91.63 172.70.90.203 172.71.26.43 45.156.128.108 65.49.1.162 172.190.142.176 64.181.211.198 20.223.198.174 20.215.218.57 85.203.23.26 85.203.23.37 85.203.23.27 85.203.23.25 85.203.23.33 85.203.23.24 85.203.23.32 85.203.23.34 85.203.23.35 85.203.23.23 85.203.23.47 85.203.23.80 172.70.251.204 172.70.251.203 104.23.225.159 104.23.225.169 104.23.225.30 104.23.225.72 104.23.225.148 104.23.225.32 104.23.225.74 104.23.225.109 104.23.225.29 104.23.225.71 51.120.72.165 172.213.208.27 157.245.151.235 74.243.251.125 20.215.185.19 20.203.162.101 89.248.168.239 45.149.173.217 149.102.225.179

Почтовый фильтр es-postfix

Этот фильтр объединяет в себе все возможности штатных фильтров fail2ban для работы с postfix, sasl и dovecot, но работает гораздо эффективнее:

Status for the jail: es-postfix
|- Filter
| |- Currently failed: 35
| |- Total failed: 745
| `- File list: /var/log/mail.log
`- Actions
|- Currently banned: 15
|- Total banned: 108
`- Banned IP list: 185.169.4.161 51.159.234.118 66.132.172.186 35.203.210.145 35.203.211.53 178.16.54.141 3.134.216.108 3.131.220.121 157.230.178.76 159.223.184.214 91.92.243.228 137.184.209.168 65.49.1.152 46.151.182.6 3.18.101.236

Он имеет такой код:

# cat es-postfix.conf
[Definition]
failregex = ^.*postfix/smtpd\[\d+\]: disconnect from unknown\[<HOST>\]\s
            ^.*dovecot: (?:imap|pop3)-login: Disconnected: Connection closed \(no auth attempts in \d+ secs\): user=<>, rip=<HOST>, lip=.*$
            ^.*dovecot: (?:imap|pop3)-login: Disconnected: Connection closed: read\(size=\d+\) failed: Connection reset by peer \(no auth attempts in \d+ secs\): user=<>, rip=<HOST>, lip=.*$
            ^.*postfix/(?:submission/)?smtpd\[\d+\]: disconnect from \S+\[<HOST>\] commands=0/0$
            ^.*postfix/smtpd\[\d+\]: NOQUEUE: reject: RCPT from unknown\[<HOST>\]: 450 4.7.1 Client host rejected: cannot find your reverse hostname.*$
            ^.*dovecot: imap-login: Disconnected: Connection closed: SSL_accept\(\) failed:.*rip=<HOST>, lip=.*$
            ^.*postfix/smtpd\[\d+\]: warning: hostname \S+ does not resolve to address <HOST>: Name or service not known$
            ^.*postfix/smtpd\[\d+\]: NOQUEUE: reject: RCPT from unknown\[<HOST>\]: 450 4.7.25 Client host rejected: cannot find your hostname.*$
            ^.*postfix/smtpd\[\d+\]: warning: \S+\[<HOST>\]: SASL LOGIN authentication failed: authentication failure$
            ^.*postfix/smtpd\[\d+\]: NOQUEUE: reject: RCPT from \S+\[<HOST>\]: 554 5.7.1 Service unavailable; Client host \[\S+\] blocked using .*$
            ^.*postfix/(?:submission/)?smtpd\[\d+\]: warning: non-SMTP command from \S+\[<HOST>\]: .*$
            ^.*postfix/submission/smtpd\[\d+\]: disconnect from \S+\[<HOST>\] ehlo=0/1 commands=0/1$
ignoreregex =

и эксплуатируется со следующими параметрами:

[es-postfix]
enabled = true
filter = es-postfix
logpath = /var/log/mail.log
action = iptables-allports[name=es-postfix, blocktype=DROP, protocol=all]

Модуль для phpBB

Этот модуль предназначен для защиты от спам-ботов тех форумов, которые работают на платформе phpBB. Для его эксплуатации в качестве метода защиты на самом форуме мы (в процедуре регистрации новых юзеров) применяем кастомные вопросы, на которые не может правильно ответить робот. Комбинация этих двух методов (кастомные вопросы вместо капчи на форуме и фильтр phpBB для fail2ban) полностью очистила наш форум от какой бы то ни было спам-активности.

Этот модуль имеет такой код:

# cat es-phpBB.conf
[Definition]
failregex = ^<HOST> - - \[.*\] "POST /ucp.php\?mode=register HTTP/\d\.\d" 200\s
ignoreregex =

эксплуатируется с такими параметрами

[es-phpBB]
enabled = true
filter = es-phpBB
logpath = /var/log/nginx/access.log
action = iptables-allports[name=es-phpBB, blocktype=DROP, protocol=all]

и обеспечивает такую эффективность

Status for the jail: es-phpBB
|- Filter
| |- Currently failed: 0
| |- Total failed: 54
| `- File list: /var/log/nginx/access.log
`- Actions
|- Currently banned: 3
|- Total banned: 11
`- Banned IP list: 103.112.171.50 93.178.119.137 77.222.108.109

В заключение скажу два слова о том, как строились эти мои кастомные фильтры. После того, как я запустил в работу fail2ban со штатными настройками (описано в разделе «Штатные модули fail2ban»), я каждый день наблюдал как в тех или иных логах (smtp, http, dns) продолжается хакерская активность того или иного рода. И вот наблюдая за этой активностью, я и строил регулярные выражения, которые ее описывали. Как видно выше, этих выражений много — и это потому, что существует много видов хакерской активности. И каждая из строк в моих фильтрах блокирует ту или иную хакерскую или спамерскую активность.

Таким образом, последовательно блокируя один за другим все наблюдаемые сегодня на практике методы атаки, я добился того, что из моих логов практически исчезли любые следы деятельности хакеров. Пара такого рода обращений — и в бан на сутки (причем, по методу DROP, для всех портов и для всех протоколов). А для тех, кто плохо понимает — существует recidive, время нахождения в котором составляет у меня четыре недели. При таком подходе к делу, нагрузка на мои серверы (с момента внедрения данной системы) упала во много раз. Теперь они заняты исключительно обслуживанием легальных клиентов и совершенно не отвлекаются (как это было раньше) на хакеров и спамеров.

В целом, у меня сложилось прекрасное впечатление от fail2ban. Благодаря использованию этой системы защиты на своих серверах я избавился от постоянных забот, от необходимости систематически в ручном режиме заниматься тем, что сейчас без моего участия прекрасно делает эта автоматика в режиме 24 часа / 7 дней в неделю / 365 дней в году. Я получил прекрасную возможность тратить свое время на нечто более приятное и полезное. Система fail2ban — (заявляю об этом со всей ответственностью) источник счастья для любого системного администратора, обслуживающего большое число хостов на базе ubuntu server. Таков мой окончательный вывод.