Application: ISC-DHCPd, Syslog и Logrotate.
Задача: наладить сбор сообщений о событиях обслуживания сервером клиентских DHCP-запросов в отдельном журнальном файле.
Используемый в Linux и BSD сервер автоматизации выдачи сетевых настроек "ISC DHCPd" (далее DHCPd) старенький и местами странно отсталый. Американский "Internet Systems Consortium" выпустил его первую стабильную версию в конце 1997 года, прошли десятилетия, в 2017 году мы уже пользуемся четвёртой версий, а средств управления без перезапуска этим сервисом нет, как отсутствует и поддержка возможности направить сообщения о событиях в произвольный файл. За двадцать лет важнейший и привычный всем функционал так и не добавили - но альтернативы нет, и мы продолжаем жить с тем, что неудобно, но работает.
По умолчанию весь поток сообщений о взаимодействии с клиентами DHCPd отправляет в подсистему журналирования "syslog" несущей операционной системы. Казалось бы, пусть себе шлёт их, куда захочет. В общем, пусть бы оно и так, но для сети в пару десятков тысяч пользователей поток сообщений льётся так обильно, что полностью забивает собой всё остальное - можно считать, что об остальных системных событиях вы уже не узнаете.
Определение параметров журналирования в DHCPd.
Единственное, что можно сделать в конфигурационном файле, так это указать "метку", по которой в дальнейшем можно будет вылавливать интересующие нас сообщения в общей массе:
# vi /etc/dhcp/dhcpd.conf
....
# Use this to send dhcp log messages to a different log file (you also
# have to hack syslog.conf to complete the redirection).
log-facility local7;
....
# Use this to send dhcp log messages to a different log file (you also
# have to hack syslog.conf to complete the redirection).
log-facility local7;
....
Не обязательно использовать метку "local7", но она фигурирует в примере от разработчиков, и не конфликтует с метками других распространённых сервисов - так что проще оставить "по умолчанию".
Как я упоминал выше, применение параметров без полного перезапуска DHCPd не поддерживается, так что особо важно предварительно проверить, не допущено ли ошибок в конфигурации такового:
# /usr/sbin/dhcpd -f -t -q
# /etc/init.d/isc-dhcp-server restart
# /etc/init.d/isc-dhcp-server restart
На данный момент три приложения системы журналирования в Linux актуальны и используются: "Syslog", "RSyslog" и "Syslog-NG" - рассмотрим способы обработки сообщений DHCPd в каждой из них.
Сбор событий DHCPd в отдельном файле посредством "Syslog".
Старая и простая подсистема, в которой всё с интересующей нас меткой просто отправляется в файл, после чего обработка пакета данных завершается:
# vi /etc/syslog.conf
....
loca7.* /var/log/dhcpd.log
....
loca7.* /var/log/dhcpd.log
....
# /etc/init.d/syslog reload
Сбор событий DHCPd в отдельном файле посредством "RSyslog".
В этой, пришедшем на замену "Syslog"-у, подсистеме журналирования, по умолчанию обработка пакета данных продолжается даже после совпадения с критерием фильтрации - явно останавливаем процесс операндом "& ~":
# vi /etc/rsyslog.d/dhcpd.conf
local7.* /var/log/dhcpd.log
& ~
& ~
# /etc/init.d/rsyslog reload
Сбор событий DHCPd в отдельном файле посредством "Syslog-NG".
В наиболее современном "Syslog-NG" управление потоками гибче, но существенно сложнее - приходится не только вылавливать нужное, но и отсекать это же там, где оно помешает:
# vi /etc/syslog-ng/syslog-ng.conf
....
# Указываем целевой файл журнала
destination d_dhcpd { file("/var/log/dhcpd.log"); };
# Описываем критерии фильтрации (можно по "метке", но эффективнее по наименованию испускающего событие приложению)
// filter f_dhcpd { facility(local7); };
filter f_dhcpd { program('^dhcpd$'); };
# Добавляем в некоторые имеющиеся фильтры указания исключать из них уже захваченное фильтром "f_dhcpd":
filter f_debug { .... and not filter(f_dhcpd); };
filter f_error { .... and not filter(f_dhcpd); };
filter f_messages { .... and not filter(f_dhcpd); };
filter f_syslog { .... and not filter(f_dhcpd); };
# Формируем цепочку обработчиков, которая обслуживает поток сообщений DHCPd
log { source(s_src); filter(f_dhcpd); destination(d_dhcpd); };
....
# Указываем целевой файл журнала
destination d_dhcpd { file("/var/log/dhcpd.log"); };
# Описываем критерии фильтрации (можно по "метке", но эффективнее по наименованию испускающего событие приложению)
// filter f_dhcpd { facility(local7); };
filter f_dhcpd { program('^dhcpd$'); };
# Добавляем в некоторые имеющиеся фильтры указания исключать из них уже захваченное фильтром "f_dhcpd":
filter f_debug { .... and not filter(f_dhcpd); };
filter f_error { .... and not filter(f_dhcpd); };
filter f_messages { .... and not filter(f_dhcpd); };
filter f_syslog { .... and not filter(f_dhcpd); };
# Формируем цепочку обработчиков, которая обслуживает поток сообщений DHCPd
log { source(s_src); filter(f_dhcpd); destination(d_dhcpd); };
....
# /etc/init.d/syslog-ng reload
Настройка ротации файлов журнала.
Конечно же, если поддержка вывода журнала событий в DHCPd отсутствует, то усечения и ротация такового тоже не предусмотрена. Исправим это:
# vi /etc/logrotate.d/dhcpd
/var/log/dhcpd.log {
weekly
rotate 7
size 100M
missingok
notifempty
compress
delaycompress
copytruncate
su root root
}
weekly
rotate 7
size 100M
missingok
notifempty
compress
delaycompress
copytruncate
su root root
}
Проверяем корректность настройки ротации:
# logrotate -d /etc/logrotate.d/dhcpd
Усечение и ротация файлов журнала событий DHCPd практически необходима - в сети с десятком тысяч пользователей таковой разрастается до сотни мегабайт за один день. Неоднократно видел серверы, где DHCPd насыпал два гигабайта в журнал и рост файла прекращался из-за ограничений файловой системы.