Настройка модуля mod_ban.c в ProFTPD
На сервере под управлением FreeBSD 10.1-RELEASE-p13 работает ftp-сервер ProFTPD Version 1.3.5a. Чем больше популярности набирает мой сайт, тем всё больше людей пытается произвести с ним деструктивные действия. В последнее время заметил, что участились попытки подбора паролей к несуществующим пользователям ftp. Все они бесплодны, но чтобы ограничить возможности таких личностей, решил задействовать модуль mod_ban.c, который разработан как раз с целью автоматического запрета доступа к серверу ProFTPD в соответствии с вашими критериями, указанными в конфигурационном файле proftpd.conf . |
Итак, имеем:
# uname -r 10.1-RELEASE-p13 # proftpd -v ProFTPD Version 1.3.5a
Сам порт proftpd-1.3.5a собран со следующими параметрами:
Как вы заметили, теперь нет возможности выбрать самим, какой модуль собрать и подключить. Они все (включая необходимый мне mod_ban.c) собираются автоматически. Убедиться в этом вы можете, изучив файл /usr/ports/ftp/proftpd/Makefile
, секция MODULES+=…
Если у вас данный порт ещё не установлен, делается это следующим образом:
# cd /usr/ports/ftp/proftpd # make config # make install clean # echo 'proftpd_enable="YES"' >> /etc/rc.conf
В операционной системе FreeBSD конфигурационный файл для ProFTPD по-умолчанию расположен по пути /usr/local/etc/proftpd.conf
. Настраивать свой порт я буду как отдельно стоящий сервис ftp, работающий в пассивном режиме на всех сетевых интерфейсах. Доступ к серверу ftp будут иметь анонимный пользователь (только чтение) и локальные пользователи системы (полный, кроме root) в свои настроенные “домашние” каталоги. Для этого в указанный выше файл внесем следующие строки:
# nano -w /usr/local/etc/proftpd.conf ServerName "Some string" ServerType standalone ServerAdmin admin@domain.ru DefaultServer on ServerIdent off PidFile /var/run/proftpd/proftpd.pid ScoreboardFile /var/run/proftpd/proftpd.scoreboard Port 21 PassivePorts 50000 50100 Umask 022 AuthPAM off MaxInstances 50 CommandBufferSize 512 UseReverseDNS off IdentLookups off User nobody Group nogroup
Для включения логирования и анализа работы нашего ftp-сервера, внесем в наш конфигурационный файл следующие строки:
<IfModule mod_log.c> SyslogLevel warn ServerLog /var/log/proftpd/proftpd-server.log SystemLog /var/log/proftpd/proftpd-error.log TransferLog /var/log/proftpd/proftpd-tranfer.log READ,WRITE ExtendedLog /var/log/proftpd/proftpd-extended.log READ,WRITE ExtendedLog /var/log/proftpd/proftpd-paranoid.log ALL AllowLogSymlinks off DebugLevel 5 </IfModule>
Чтобы наши изменения заработали, создадим папку /var/log/proftpd
и соответствующие файлы:
# mkdir /var/log/proftpd # touch /var/log/proftpd/proftpd-server.log # touch /var/log/proftpd/proftpd-error.log # touch /var/log/proftpd/proftpd-tranfer.log # touch /var/log/proftpd/proftpd-extended.log # touch /var/log/proftpd/proftpd-paranoid.log
Для того, чтобы иметь возможность управлять действиями модуля mod_ban.c (и не только) внесем в конфигурационный файл следующие настройки:
<IfModule mod_ctrls.c> ControlsEngine on ControlsACLs all allow user root ControlsMaxClients 2 ControlsLog /var/log/proftpd/proftpd-controls.log ControlsInterval 5 ControlsSocket /var/run/proftpd/proftpd.sock ControlsSocketOwner root wheel ControlsSocketACL allow user root </IfModule>
Которые позволят пользователю root просматривать, добавлять или удалять забаненные хосты непосредственно на сервере FreeBSD. Не забудьте создать файл для логирования действий управления:
# touch /var/log/proftpd/proftpd-controls.log
Так же учтите, что теперь при администрировании сервер ProFTPD с помощью команды ftpdctl
, вы должны указывать обозначенный тут сокет /var/run/proftpd/proftpd.sock
следующим образом: ftpdctl -s /var/run/proftpd/proftpd.sock, так как по умолчанию ProFTPD использует сокет по пути /var/run/proftpd.sock.
Теперь, для непосредственной настройки необходимого нам модуля mod_ban.c в конфигурационный файл ProFTPD по пути /usr/local/etc/proftpd.conf
, необходимо внести следующие строки:
<IfModule mod_ban.c> <Class whitelist> From 192.168.0.0/24 </Class> <IfClass whitelist> BanEngine off </IfClass> <IfClass !whitelist> BanEngine on </IfClass> BanControlsACLs all allow user root BanOnEvent MaxLoginAttempts 3/00:10:00 24:00:00 BanOnEvent ClientConnectRate 5/00:01:00 01:00:00 "Stop connecting frequently" BanTable /var/run/proftpd/proftpd-ban.tab BanLog /var/log/proftpd/proftpd-ban.log BanMessage "Host %a has been banned" </IfModule>
Разберём, что тут настроено. Мы обозначили класс whitelist, для которого указанные ограничения работать не будут (BanEngine off). Я внес в него свою локальную сеть (192.168.0.0/24). Для всех остальных, будут работать ограничения на количество попыток входа (подбор пароля) и ограничение на количество подключений.
Строка BanOnEvent MaxLoginAttempts 3/00:10:00 24:00:00
банит хосты на сутки, с которых пытались более трех раз в течении 10 минут залогиниться (подобрать пароль).
Строка BanOnEvent ClientConnectRate 5/00:01:00 01:00:00
банит хосты на час, с которых пытались подключиться более 5 раз в течении 1 минуты. Им выведется соответствующее сообщение.
Не забудьте создать служебный файл proftpd-ban.tab
(не пугайтесь, если обнаружите, что он всегда остаётся пустым – так и должно быть, но существовать он должен) и файл лога работы модуля mod_ban.c:
# touch /var/run/proftpd/proftpd-ban.tab # touch /var/log/proftpd/proftpd-ban.log
Строка BanControlsACLs all allow user root
позволит пользователю root на FreeBSD управлять забаненными хостами.
Но, чтобы данные настройки заработали корректно, необходимо задать глобально количество MaxLoginAttempts
меньшим, чем мы обозначили в этом разделе. Для этого внесем в конфигурационный файл следующие строки, относящиеся уже к модулю аутентификации mod_auth.c:
<IfModule mod_auth.c>
RootLogin off
AccessDenyMsg "ATTENTION! All connections are loged"
AccessGrantMsg "Now apload/download files"
DefaultRoot ~
TimeoutIdle 300
TimeoutLogin 300
MaxClients 10 "Too many connections"
MaxClientsPerHost 3 "%m client are already connected from your host"
MaxLoginAttempts 1 "Too many of attempts to connected"
</IfModule>
Проверим на присутствие ошибок в нашем конфигурационном файле для ftp-сервера ProFTPD командой proftpd -t
:
# proftpd -t Checking syntax of configuration file Syntax check complete.
А теперь самое интересное! Несмотря на то, что наш конфигурационный файл прошел проверку на валидность, модуль mod_ban.c не подгрузился, следовательно – не работает. Вывод команды proftpd -l
и вовсе не показывает, что данный модуль был скомпилирован по умолчанию:
# proftpd -l Compiled-in modules: mod_core.c mod_xfer.c mod_rlimit.c mod_auth_unix.c mod_auth_file.c mod_auth.c mod_ls.c mod_log.c mod_site.c mod_delay.c mod_facts.c mod_dso.c mod_ident.c mod_auth_pam.c mod_ctrls.c mod_lang.c
И расширенный вывод информации о сборке fpt-сервера командой proftpd -vv
ничего не покажет:
# proftpd -vv ProFTPD Version: 1.3.5a (maint) Scoreboard Version: 01040003 Built: вс июн 14 2015 16:00:38 MSK Loaded modules: mod_lang/1.0 mod_ctrls/0.9.5 mod_auth_pam/1.2 mod_ident/1.0 mod_dso/0.5 mod_facts/0.3 mod_delay/0.7 mod_site.c mod_log.c mod_ls.c mod_auth.c mod_auth_file/1.0 mod_auth_unix.c mod_rlimit/1.0 mod_xfer.c mod_core.c
Также, если вы сейчас попробуете с помощью команды управления ftpdctl
проверить работу модуля, вы обнаружите ошибку:
# ftpdctl -s /var/run/proftpd/proftpd.sock ban info -ve ftpdctl: unsupported action requested
Как оказалось, при конфигурировании ProFTPD, начиная с версии 1.3.4a, модули сделали подгружаемыми динамически и их нужно вручную прописывать в proftpd.conf! Причём необходимо так же учитывать очередность загрузки некоторых модулей. Модули, зависящие от других, должны загружаться позже. Т.е. в нашем случае, чтобы активировать необходимый нам модуль, в конфиге нужно прописать следующую строку:
LoadModule mod_ban.c
Этого оказало мало. В нашем примере, приведенном выше, мы обозначили класс whitelist с помощью директивы <Class>
. После внесение строки, указанной выше, и при последующей проверке валидности конфигурационного файла выскочит ошибка:
# proftpd -t Checking syntax of configuration file 2015-05-21 16:24:54,526 mail.maxblogs.ru proftpd[50386]: fatal: unknown configuration directive '<IfClass>' on line 107 of '/usr/local/etc/proftpd.conf'
Чтобы её исправить, необходимо подгрузить соответствующий этой директиве модуль mod_ifsession.c
, причём он должен быть прописан на загрузку последним, после указания всех модулей. Чтобы всё сделать правильно, необходимо прописать следующее:
<IfModule mod_dso.c> LoadModule mod_ban.c LoadModule mod_ifsession.c </IfModule>
И “красиво” обозначить наш класс, которому можно еще и скорости добавить при обращении к нашему серверу ftp, а остальным уменьшить:
<IfModule mod_ifsession.c> <Class whitelist> From 192.168.0.0/24 </Class> <IfClass whitelist> TransferRate APPE,RETR,STOR 4096 </IfClass> <IfClass !whitelist> TransferRate APPE,RETR,STOR 1024 </IfClass> </IfModule>
Теперь при проверки валидности конфигурационного файла ошибок не будет обнаружено и можете запустить свой сервер ProFTPD командой:
# /usr/local/etc/rc.d/proftpd start
Теперь при запросе на выдачу расширенной информации о нашем ftp-сервере вы увидите, что оба этих модуля подгружены, следовательно, они работают.
# proftpd -vv ProFTPD Version: 1.3.5a (maint) Scoreboard Version: 01040003 Built: вс июн 14 2015 16:00:38 MSK Loaded modules:mod_ifsession/1.3
mod_ban/0.6.2
mod_lang/1.0 mod_ctrls/0.9.5 mod_auth_pam/1.2 mod_ident/1.0 mod_dso/0.5 mod_facts/0.3 mod_delay/0.7 mod_site.c mod_log.c mod_ls.c mod_auth.c mod_auth_file/1.0 mod_auth_unix.c mod_rlimit/1.0 mod_xfer.c mod_core.c
Теперь команда управления сервером ProFTPD ftpdctl
выдаст следующее:
# ftpdctl -s /var/run/proftpd/proftpd.sock ban info -ve ftpdctl: No bans ftpdctl: ftpdctl: No ban events
Вообще, полный список команд управления сервером ftp ProFTPD можно получить так:
# ftpdctl -s /var/run/proftpd/proftpd.sock lsctrl ftpdctl: ban (mod_ban.c) ftpdctl: debug (mod_ctrls_admin.c) ftpdctl: delay (mod_delay.c) ftpdctl: dns (mod_ctrls_admin.c) ftpdctl: down (mod_ctrls_admin.c) ftpdctl: get (mod_ctrls_admin.c) ftpdctl: help (mod_ctrls.c) ftpdctl: insctrl (mod_ctrls.c) ftpdctl: insmod (mod_dso.c) ftpdctl: kick (mod_ctrls_admin.c) ftpdctl: lsctrl (mod_ctrls.c) ftpdctl: lsmod (mod_dso.c) ftpdctl: permit (mod_ban.c) ftpdctl: restart (mod_ctrls_admin.c) ftpdctl: rmctrl (mod_ctrls.c) ftpdctl: rmmod (mod_dso.c) ftpdctl: scoreboard (mod_ctrls_admin.c) ftpdctl: shutdown (mod_ctrls_admin.c) ftpdctl: status (mod_ctrls_admin.c) ftpdctl: trace (mod_ctrls_admin.c) ftpdctl: up (mod_ctrls_admin.c)
Приведу окончательный листинг проделанной настройки ftp-сервера ProFTPD на FreeBSD:
# less /usr/local/etc/proftpd.conf ServerName "Some string" ServerType standalone ServerAdmin admin@domain.ru DefaultServer on ServerIdent off PidFile /var/run/proftpd/proftpd.pid ScoreboardFile /var/run/proftpd/proftpd.scoreboard Port 21 PassivePorts 50000 50100 Umask 022 AuthPAM off MaxInstances 50 CommandBufferSize 512 UseReverseDNS off IdentLookups off User nobody Group nogroup <IfModule mod_dso.c> LoadModule mod_ban.c LoadModule mod_ctrls_admin.c LoadModule mod_ifsession.c </IfModule> <IfModule mod_log.c> SyslogLevel warn ServerLog /var/log/proftpd/proftpd-server.log SystemLog /var/log/proftpd/proftpd-error.log TransferLog /var/log/proftpd/proftpd-tranfer.log READ,WRITE ExtendedLog /var/log/proftpd/proftpd-extended.log READ,WRITE ExtendedLog /var/log/proftpd/proftpd-paranoid.log ALL AllowLogSymlinks off DebugLevel 5 </IfModule> <IfModule mod_ifsession.c> <Class whitelist> From 192.168.0.0/24 </Class> <IfClass whitelist> TransferRate APPE,RETR,STOR 4096 </IfClass> <IfClass !whitelist> TransferRate APPE,RETR,STOR 1024 </IfClass> </IfModule> <IfModule mod_auth.c> RootLogin off AccessDenyMsg "ATTENTION! All connections are loged" AccessGrantMsg "Now apload/download files" DefaultRoot ~ TimeoutIdle 300 TimeoutLogin 300 MaxClients 10 "Too many connections" MaxClientsPerHost 3 "%m client are already connected from your host" MaxLoginAttempts 1 "Too many of attempts to connected" </IfModule> <IfModule mod_ctrls.c> ControlsEngine on ControlsACLs all allow user root ControlsMaxClients 2 ControlsLog /var/log/proftpd/proftpd-controls.log ControlsInterval 5 ControlsSocket /var/run/proftpd/proftpd.sock ControlsSocketOwner root wheel ControlsSocketACL allow user root </IfModule> <IfModule mod_ctrls_admin.c> AdminControlsACLs all allow user root </IfModule> <IfModule mod_ban.c> <IfClass whitelist> BanEngine off </IfClass> <IfClass !whitelist> BanEngine on BanOnEvent MaxLoginAttempts 3/00:10:00 24:00:00 BanOnEvent ClientConnectRate 5/00:01:00 01:00:00 "Stop connecting frequently" </IfClass> BanControlsACLs all allow user root BanTable /var/run/proftpd/proftpd-ban.tab BanLog /var/log/proftpd/proftpd-ban.log BanMessage "Host %a has been banned" </IfModule> <Limit SITE_CHMOD> DenyAll </Limit> <Anonymous ~ftp> User ftp Group nogroup UserAlias anonymous ftp AuthAliasOnly on RequireValidShell off AnonRequirePassword off MaxClients 10 "Sorry, max %m users - try again later" DenyFilter \*.*/ <Limit LOGIN> AllowAll </Limit> <Limit WRITE> DenyAll </Limit> <Limit READ DIRS> IgnoreHidden on </Limit> </Anonymous>
Про создание анонимного пользователя для работы с ftp в приведенной конфигурации вы можете прочитать в этой моей статье: Корректное создание анонимного пользователя FTP.
Кстати, если вы используете файервол, не забудьте открыть соответствующите порты. В моём случае – это PF и мои настройки выглядят следующим образом:
# nano -w /etc/pf.conf ... block all pass in log quick on $ext_if proto tcp from any to $ext_addr port 21 pass in log quick on $ext_if inet proto tcp from any to $ext_if port 50000 >< 50100 ...
где $ext_addr – внешний ip адрес, $ext_if – внешний сетевой интерфейс.
Теперь, после некоторого времени работы нашего ftp-сервера, дадим команду на просмотр существующих банов:
# ftpdctl -s /var/run/proftpd/proftpd.sock ban info -ve ftpdctl: Banned Hosts: ftpdctl: 61.160.223.121 ftpdctl: Reason: MaxLoginAttempts autoban at Fri Jul 03 02:24:20 2015 ftpdctl: Expires: Sat Jul 04 02:24:20 2015 (in 64173 seconds) ftpdctl: <VirtualHost>: Some string (85.31.178.162#21)
Как видим, у нас один хост с ip 61.160.223.121 (кстати, с китайского сегмента сети) оказался забаненным. Проанализируем наши логи.
В логе, куда пишутся управляющие команды и вывод их работы мы увидим следующее:
# less /var/log/proftpd/proftpd-controls.log 2015-07-03 08:34:47,443 mod_ctrls/0.9.5[3188]: accepted connection from root/wheel client 2015-07-03 08:34:47,444 mod_ctrls/0.9.5[3188]: recvd from root/wheel client: 'ban info -ve' 2015-07-03 08:34:47,444 mod_ctrls/0.9.5[3188]: sent to root/wheel client: return value: 0 2015-07-03 08:34:47,444 mod_ctrls/0.9.5[3188]: sent to root/wheel client: 'Banned Hosts:' 2015-07-03 08:34:47,444 mod_ctrls/0.9.5[3188]: sent to root/wheel client: ' 61.160.223.121' 2015-07-03 08:34:47,444 mod_ctrls/0.9.5[3188]: sent to root/wheel client: ' Reason: MaxLoginAttempts autoban at Fri Jul 03 02:24:20 2015' 2015-07-03 08:34:47,444 mod_ctrls/0.9.5[3188]: sent to root/wheel client: ' Expires: Sat Jul 04 02:24:20 2015 (in 64173 seconds)' 2015-07-03 08:34:47,444 mod_ctrls/0.9.5[3188]: sent to root/wheel client: ' <VirtualHost>: Some string (85.31.178.162#21)' 2015-07-03 08:34:47,444 mod_ctrls/0.9.5[3188]: closed connection to root/wheel client
А в нашем “параноидальном” логе работы ProFTPD (куда записываются абсолютно все события ftp-сервера), мы увидим причину, по которой хост с ip 61.160.223.121 был забанен:
# less /var/log/proftpd/proftpd-paranoid.log 61.160.223.121 UNKNOWN - [03/июл/2015:02:24:19 +0300] "USER admin" 331 - 61.160.223.121 UNKNOWN - [03/июл/2015:02:24:19 +0300] "USER admin" 331 - 61.160.223.121 UNKNOWN - [03/июл/2015:02:24:20 +0300] "USER admin" 331 -
С этого ip-адреса пытали три раза войти на наш ftp-сервер с использование имени пользователя admin, которого у меня и нет.
В логе записи ошибок мы обнаружим, что данному хосту доступ был запрещен:
# less /var/log/proftpd/proftpd-error.log | grep 61.160.223.121 2015-07-03 02:24:20,823 mail.maxblogs.ru proftpd[6679] 85.31.178.162 (61.160.223.121[61.160.223.121]): mod_ban.c: error initializing session: Недостаточно привилегий ...
Если у вас возникла необходимость “разбанить” того или иного клиента, нужно дать команду следующего синтаксиса:
ftpdctl permit class|host|user [-s address#port] name1 [name2 ...]
В нашем случае команда примет вид:
# ftpdctl -s /var/run/proftpd/proftpd.sock permit host 61.160.223.121
если вам необходимо вручную дать бан какому-либо клиенту, команда должна иметь следующий синтаксис:
ftpdctl ban class|host|info|user [-s address#port] name1 [name2 ...]
Напоследок, одно небольшое удобство – использование newsyslog для ротации всех файлов лога работы ProFTPD. Внесите в файл по пути /etc/newsyslog.conf
следующую строку:
/var/log/proftpd/*.log 640 7 * @T00 GJC /var/run/proftpd/proftpd.pid
и выполните команду:
# newsyslog
После этого, каждый день в 0.00 каждый файл логов (в отдельности) по пути /var/log/proftpd
вне зависимости от размера заархивируется и переименуется в файл вида proftpd-*.log.0.bz2
и создатся новый лог с прежним именем, о чем будет уведомлен ProFTPD. Файлы старше 7 дней будут затираться.
Вот теперь кажется всё!
________