iptables -A INPUT -p ICMP --icmp-type 8 -j LOG --log-prefix "Ping detected: "
iptables -A INPUT -p ICMP --icmp-type 8 -j ACCEPT
Теперь по событию, подпадающее под это правило, будет писаться сообщение в
/var/log/messages
и
/var/log/syslog
:
kernel: [122972.300408] Ping detected: IN=eth0 OUT= MAC=00:64:d9:36:7b:d7:00:24:2d:a6:e2:43:08:91 SRC=xxx.xxx.xxx.xxx DST=xxx.xxx.xxx.xxx LEN=60 TOS=0x00 PREC=0x00 TTL=124 ID=23020 PROTO=ICMP TYPE=8 CODE=0 ID=33602 SEQ=2462
Когда попаданий в правила много, то невозможно проанализировать системные сообщения, т.к. логи iptables’а наводняют весь файл логов.
Настройка
Для избежания вышеописанного необходимо изменить критерий в префиксе сообщения, например, так:
iptables -A INPUT -p ICMP --icmp-type 8 -j LOG --log-prefix "Iptables: Ping detected: "
iptables -A INPUT -p ICMP --icmp-type 8 -j ACCEPT
И создать файл
/etc/rsyslog.d/iptables.conf
со следующим содержанием:
echo ':msg, contains, "Iptables: " -/var/log/iptables.log' > /etc/rsyslog.d/iptables.conf
echo '& ~' >> /etc/rsyslog.d/iptables.conf
Параметры:
& ~
— говорит о том, что дальнейшую обработку записи производить не следует, поэтому она не попадет в другие файлы логов.
"Iptables: "
— тот самый log-prefix — критерий по которому rsyslog принимает решение перенаправить лог в нужный файл. Префикс можно было и не менять, а оставить как есть —
Ping detected
, но если правило не одно, то удобнее иметь общий префикс для всех правил, который и был сделан.
/var/log/iptables.log
— сам файл лога.
Перезапустить демон rsyslog:
/etc/init.d/rsyslog restart
Теперь сообщение в логе
/var/log/iptables.log
выглядит так:
kernel: [122972.300408] Iptables: Ping detected: IN=eth0 OUT= MAC=00:64:d9:36:7b:d7:00:24:2d:a6:e2:43:08:91 SRC=xxx.xxx.xxx.xxx DST=xxx.xxx.xxx.xxx LEN=60 TOS=0x00 PREC=0x00 TTL=124 ID=23020 PROTO=ICMP TYPE=8 CODE=0 ID=33602 SEQ=2462
Наконец Iptables пишет в свой личный лог не
засирая трогая системные.
Можно пойти дальше, создав правила для разных событий и каждое событие направить в свой лог, например:
iptables -A INPUT -m state --state INVALID -j LOG --log-prefix "Iptables: Invalid packet: "
iptables -A INPUT -m limit --limit 3/minute --limit-burst 3 -j LOG --log-prefix "Iptables: INPUT packet died: "
iptables -A FORWARD -m limit --limit 3/minute --limit-burst 3 -j LOG --log-prefix "Iptables: FORWARD packet died: "
Создать правила для ведения логирования каждого файла:
echo ':msg, contains, "Iptables: Invalid packet" -/var/log/iptables_invalid.log' > /etc/rsyslog.d/iptables_invalid.conf
echo '& ~' >> /etc/rsyslog.d/iptables_invalid.conf
echo ':msg, contains, "Iptables: INPUT" -/var/log/iptables_input.log' > /etc/rsyslog.d/iptables_input.conf
echo '& ~' >> /etc/rsyslog.d/iptables_input.conf
echo ':msg, contains, "Iptables: FORWARD" -/var/log/iptables_forward.log' > /etc/rsyslog.d/iptables_forward.conf
echo '& ~' >> /etc/rsyslog.d/iptables_forward.conf
Перезапустить rsyslog:
/etc/init.d/rsyslog restart
При такой конфигурации лог Iptables разделен на три части и каждая пишется в свой файл.
Ротация логов Iptables
Настроить ротацию логов iptables можно создав файл
/etc/logrotate.d/iptables
со следующим содержимым. Для одного общего лога:
/var/log/iptables.log {
daily
rotate 30
compress
missingok
notifempty
sharedscripts
}
или для раздельных:
/var/log/iptables_invalid.log {
daily
rotate 30
compress
missingok
notifempty
}
/var/log/iptables_input.log {
daily
rotate 30
compress
missingok
notifempty
}
/var/log/iptables_forward.log {
daily
rotate 30
compress
missingok
notifempty
}
Где
daily
— ротировать ежедневно
rotate 30
— сохранять 30 последних ротированных файлов
compress
— сжимать
missingok
— отсутствие файла не является ошибкой
notifempty
— не обрабатывать пустые файлы
Убедиться в правильности ротации можно принудительно запустив ее:
logrotate -f /etc/logrotate.conf
Работоспособность тестировалась на Debian 7 и Debian 8. Также должно работать на всех дистрибутивах, использующих Iptables и rsyslog.
==================
Ну, во всём этом пропущено основное: iptables пишут в dmesg, откуда оно копируется в syslog. Очевидным решением было бы не городить хитрые костыли (что само по себе полезно, но должно быть сильно мотивировано), а просто разделить логи от ядра и приложений. Сам по себе dmesg в syslog не попадает, его туда специально копируют. ValdikSS 1 июня 2015 в 23:01 # Эх, Debian Jessie так полностью на journalctl и не переключился, bootlogs замаскирован. А если бы не был замаскирован, задача бы решалась буквально одной командой без дополнительных настроек: journalctl -k | grep "IN=.*OUT=.*" pfactum 1 июня 2015 в 10:32 # Так а чем вам NFLOG+ulogd2 не угодил? mureevms 1 июня 2015 в 11:53 # Не вижу особого смысла ради логирования нескольких правил использовать дополнительную сущность в виде ulogd2. Подправить rsyslog гораздо проще, как мне кажется.