How can I configure /etc/syslog.conf
file in order to save log information about iptables
in a specific file.
I want to save these information separately, so I can extract what I want easily and rapidly.
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. It only takes a minute to sign up.
Sign up to join this communityTake a look in the man page for iptables
. It shows a target called LOG
which can do what you want.
Set the logging level for LOG
to 4.
# DROP everything and Log it
iptables -A INPUT -j LOG --log-level 4
iptables -A INPUT -j DROP
Configure syslog.conf
to write these messages to a separate file.
# /etc/syslog.conf
kern.warning /var/log/iptables.log
Restart syslogd.
Debian/Ubuntu
$ sudo /etc/init.d/sysklogd restart
Fedora/CentOS/RHEL
$ sudo /etc/init.d/syslog restart
NOTE: This method of logging is called fixed priorities. They are either numbers or names (1,2,3,4,..) or (DEBUG, WARN, INFO, etc.).
If by chance you're using rsyslog
, you can create a property based filter like so:
# /etc/rsyslog.conf
:msg, contains, "NETFILTER" /var/log/iptables.log
:msg, contains, "NETFILTER" ~
Then add thils switch to your iptables rules that you want to log:
–log-prefix NETFILTER
As an alternative you could also log the messages using this type of property filter:
:msg, startswith, "iptables: " -/var/log/iptables.log
& ~
:msg, regex, "^\[ *[0-9]*\.[0-9]*\] iptables: " -/var/log/iptables.log
& ~
NOTE: This 2nd method doesn't require any changes to iptables
.
/var/log/iptables
and also in /var/log/messages
. I want only one copy from this data in iptables.log
This assumes your firewall already makes logs, as any sane firewall should. For some examples, it requires an identifiable message, such as "NETFILTER" in slm's example.
make a file in rsyslog.d
vim /etc/rsyslog.d/10-firewall.conf
This works in CentOS 7. I don't know how to verify that it came from the firewall other than looking for IN and OUT... CentOS is weird. Don't use this unless the next version doesn't work.
# into separate file and stop their further processing
if ($msg contains 'IN=' and $msg contains 'OUT=') \
then {
-/var/log/firewall
& ~
}
This works in CentOS 7 and checks for the message content too (replace "Shorewall" with whatever you have in your -j LOG rule's message):
# into separate file and stop their further processing
if ($msg contains 'Shorewall') and \
($msg contains 'IN=' and $msg contains 'OUT=') \
then {
-/var/log/firewall
& ~
}
This works in others (Ubuntu, Debian, openSUSE). And this is the best way to do it. No searching for strings in the message:
# into separate file and stop their further processing
if ($syslogfacility-text == 'kern') and \\
($msg contains 'IN=' and $msg contains 'OUT=') \\
then -/var/log/firewall
& ~
And here is what a default openSUSE machine has (which I think every distro should have and is missing) (difference seems to be only "stop" instead of "& ~"; not all systems support both syntaxes):
if ($syslogfacility-text == 'kern') and \
($msg contains 'IN=' and $msg contains 'OUT=') \
then {
-/var/log/firewall
stop
}
And for all of the above, don't forget a logrotate.d file too:
vim /etc/logrotate.d/firewall
containing:
/var/log/firewall {
rotate 7
size 500k
postrotate
# before using this, run the command yourself to make sure
# it is right... the daemon name may vary
/usr/bin/killall -HUP rsyslogd
endscript
}