Firewalling with syslog-ng, a working prototype
Hi list, For a week or so, I'm gathering the building blocks for a sort of low-tech intrusion detection/prevention system. My "itch": having a system that acts "real time" on the log messages that various daemons produce; having it low profile; easy to get it to act (i.e. no scripts that call scripts that call other scripts). For example, if sshd says "invalid user", I'd like the firewall to act on this, with as little steps in between as possible. Luckily, syslog-ng is able to find patterns all by itself, so I'm able to "skip the middle man", i.e. I can use syslog-ng directly on the firewalling rules. And what is better: I'm not even using the program() call! I'm currently running such a system in pre-production and I'm delighted. It's really easy to build. It works like a charm. Here's how: 0) Install syslog-ng. 1) To get started, get the sshd pattern from the Balabit git web frontend: http://git.balabit.hu/?p=bazsi/syslog-ng-patterndb.git;a=blob;f=access/sshd.... and put it in /etc/syslog-ng/patterndb.d/, run pdbtool merge -D . -p /var/lib/syslog-ng/patterndb.xml 2) Setup your syslog-ng.conf file. Add, in the appropriate sections: # a destination; we have a dual destination here, a file to see the # blocked hosts, and an iptables-destination in /proc to block them. destination d_syslogblock { file("/proc/net/xt_recent/syslogblock" template("+${usracct.device}\n")); file("/var/log/syslogblock"); }; # a parser for the pattern-DB we made in step 1 parser pattern_db { db_parser( file("/var/lib/syslog-ng/patterndb.xml")); }; # a filter to filter the parser results filter f_syslogblock { tags("secevt") and match("REJECT" value("secevt.verdict")); }; # and finally, the log itself: log { source(s_src); parser(pattern_db); filter(f_syslogblock); destination(d_syslogblock); }; 3) Now set up your firewalling. A minimalistic firewall would look like: ip6tables -N block ip6tables -A INPUT -i lo -j ACCEPT ip6tables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT ip6tables -A INPUT -m state --state INVALID -j DROP ip6tables -A INPUT -m recent --rcheck --name block \ --seconds 3600 -j DROP # see note (1) below ip6tables -A INPUT -m recent --rcheck --name syslogblock \ --seconds 900 --hitcount 15 -j block ip6tables -A block -m recent --rcheck --name block --set 4) Repeat step 3, but with "iptables" instead of "ip6tables". (I used ip6tables on purpose, because it's time you get ready for IPv6 if you aren't). Ready. Not too hard, isn't it? It works as follows. syslog-ng will put the IP-address of any wrong password or username into the /proc/net/xt_recent/syslogblock file, with a "+" in front of the address. This is the iptables way of telling the "recent" module it should add a certain address. Now the IPtables rules tell, that if someone is seen in this "syslogblock" list more that 15 times within 15 minutes, then (s)he will be added to the "block" list. And if someone is in the "block" list, (s)he will be blocked for an hour. Note (1): if you replace the "--rcheck" here with an "--update" statement, the block will last even longer: "--rcheck" says: were you blocked less than an hour ago? Then we can't let you in. While "--update" says: were you blocked less than an hour ago, but you're here *again*? We'll block you for *another* hour, starting now. So the latter means that you actually need to be quiet for 60 minutes to be able to log in again. There is only one caveat in this whole setup: if you (or syslog-ng) inadvertedly send garbage to the /proc/net/xt_recent/syslogblock file, then this file will be closed. Syslog-ng will reopen it after the "reopen" timeout, so your message will probably come through; but should something change in the working of syslog-ng, like should syslog-ng try to *re-send* such a broken message, then this will, effectively, block the rest of the blocking messages. (I don't think this will happen, because "fprintf" is not a reliable transport, so to say, but you'll never know). I'll be implementing this solution for a couple of other servers in the next weeks or so, and I'll report if there is more to say about it. Oh, BTW: I think that these two lines: ip6tables -A INPUT -m recent --rcheck --name syslogblock --seconds 900 --hitcount 15 -j block ip6tables -A block -m recent --rcheck --name block --set can be concatenated so that you don't need a separate "block" chain anymore, as follows: ip6tables -A INPUT -m recent --rcheck --name syslogblock --seconds 900 --hitcount 15 -m recent --rcheck --name block --set But I'm not sure, I'll have to check. Best regards, Valentijn -- http://www.openoffice.nl/ Open Office - Linux Office Solutions Valentijn Sessink v.sessink#openoffice.nl +31(0)20-4214059
On Sun, 2011-02-20 at 23:06 +0100, Valentijn Sessink wrote:
Hi list,
For a week or so, I'm gathering the building blocks for a sort of low-tech intrusion detection/prevention system.
[snip]
I'm currently running such a system in pre-production and I'm delighted. It's really easy to build. It works like a charm. Here's how:
[snip] I'll be implementing this on my own servers too. Been toying with the idea ever since you posted about it first, but now with the step-by-step howto, there're no more obstacles. Very sweet solution, I'm loving it! -- \o/
Hi, Op 20-02-11 23:16, Gergely Nagy schreef:
I'll be implementing this on my own servers too. Been toying with the idea ever since you posted about it first, but now with the step-by-step howto, there're no more obstacles.
Cool. Please let me know your findings. V.
Simple and effective--I like it. If we had any ssh ports open to the world, I'd definitely try it. On Sunday, February 20, 2011, Valentijn Sessink <valentyn@blub.net> wrote:
Hi,
Op 20-02-11 23:16, Gergely Nagy schreef:
I'll be implementing this on my own servers too. Been toying with the idea ever since you posted about it first, but now with the step-by-step howto, there're no more obstacles.
Cool. Please let me know your findings.
V. ______________________________________________________________________________ Member info: https://lists.balabit.hu/mailman/listinfo/syslog-ng Documentation: http://www.balabit.com/support/documentation/?product=syslog-ng FAQ: http://www.campin.net/syslog-ng/faq.html
Op 21-02-11 00:13, Martin Holste schreef:
Simple and effective--I like it. If we had any ssh ports open to the world, I'd definitely try it.
Sshd was a nice starting point because the pattern file existed already. But I'll be adding more services to this, dovecot-auth to begin with. V.
Op 20-02-11 23:16, Gergely Nagy schreef:
I'll be implementing this on my own servers too. Been toying with the idea ever since you posted about it first, but now with the step-by-step howto, there're no more obstacles.
Cool. Please let me know your findings.
It's running on 4 now, so far, working like a charm, blocking what should be blocked, and so on. There's another server I want to switch to this solution from sshguard, but the kernel there is ancient (it's a Xen guest, and I can't upgrade for reasons beyond my control), and it doesn't have /proc/net/xt_recent, only /proc/net/ipt_recent. I haven't tried whether that works the same or not, as I'd have to go through a lot of pain to gain access to the box if anything goes wrong. Nevertheless, this particular system will be switched over aswell, sooner or later. -- |8]
Op 21-02-11 18:20, Gergely Nagy schreef:
for reasons beyond my control), and it doesn't have /proc/net/xt_recent, only /proc/net/ipt_recent.
I haven't tried whether that works the same or not, as I'd have to go through a lot of pain to gain access to the box if anything goes wrong.
ipt_recent is the older name of the current xt_recent thing. In fact, my preliminary tests with -m recent were conducted on an older box with ipt_recent. I think they are almost the same; but ipt_recent doesn't have a "+" in front of the IP-addresses. Change your template accordingly and you're set. V.
On Mon, 2011-02-21 at 19:22 +0100, Valentijn Sessink wrote:
Op 21-02-11 18:20, Gergely Nagy schreef:
for reasons beyond my control), and it doesn't have /proc/net/xt_recent, only /proc/net/ipt_recent.
I haven't tried whether that works the same or not, as I'd have to go through a lot of pain to gain access to the box if anything goes wrong.
ipt_recent is the older name of the current xt_recent thing. In fact, my preliminary tests with -m recent were conducted on an older box with ipt_recent. I think they are almost the same; but ipt_recent doesn't have a "+" in front of the IP-addresses. Change your template accordingly and you're set.
Enabled this on the Xen VM too, so far, so good! Only my home router is left now (but that's only a matter of getting ipt_recent onto the firmware). Thanks again! -- |8]
I spotted an error: Op 20-02-11 23:06, Valentijn Sessink schreef:
ip6tables -A block -m recent --rcheck --name block --set
That should be: ip6tables -A block -m recent --name block --set V.
Op 20-02-11 23:06, Valentijn Sessink schreef:
can be concatenated so that you don't need a separate "block" chain anymore, as follows: ip6tables -A INPUT -m recent --rcheck --name syslogblock --seconds 900 --hitcount 15 -m recent --rcheck --name block --set But I'm not sure, I'll have to check.
I checked, the iptables devs say that iptables does short circuit evaluation, so the above should work nicely. Best regards, Valentijn
Valentijn Sessink <valentyn@blub.net> wrote:
[snipped 'the good stuff']
4) Repeat step 3, but with "iptables" instead of "ip6tables". (I used ip6tables on purpose, because it's time you get ready for IPv6 if you aren't).
Be careful as you are possibly opening yourself up to a DoS; for the v6 case. Most attackers will be able to move through their local /64 which might cause problems when using recent directly, might be worth combining it with hashlimit too. Otherwise, 'neato'. Cheers -- Alexander Clouter .sigmonster says: share, n.: To give in, endure humiliation.
Op 21-02-11 12:50, Alexander Clouter schreef:
Be careful as you are possibly opening yourself up to a DoS; for the v6 case. Most attackers will be able to move through their local /64 which might cause problems when using recent directly, might be worth combining it with hashlimit too.
Thanks for the useful addition. Yes, we did realise that you can get IPv6/48 netblocks for free, meaning a million billion billion IP addresses, meaning you could use a new source address for every single attempt and still have some left for all the square centimeters of your part of the earth. Fortunately, the xt_recent module is quite limiting in itself: the "ip_list_tot" is 100, meaning there won't be more than 100 IP addresses in the list. And please note, that IPv4 and IPv6 are mixed here, so it's 100 addresses total. All in all, this method won't work when IPv6 attacks become more widely used and more sophisticated (using a new IP address for every connection); it would just slowly flush the list. However, I haven't seen such a connection for now, so at the moment, you would be safe by looking at the "block" log file once in a while. (With a script or so ;-) Best regards, Valentijn
Hi, It's such a great idea, that I posted on my blog about it. Thanks for both the idea and the implementation. And of course your possible pattern additions are more than welcome. On Sun, 2011-02-20 at 23:06 +0100, Valentijn Sessink wrote:
Hi list,
For a week or so, I'm gathering the building blocks for a sort of low-tech intrusion detection/prevention system.
My "itch": having a system that acts "real time" on the log messages that various daemons produce; having it low profile; easy to get it to act (i.e. no scripts that call scripts that call other scripts). For example, if sshd says "invalid user", I'd like the firewall to act on this, with as little steps in between as possible. Luckily, syslog-ng is able to find patterns all by itself, so I'm able to "skip the middle man", i.e. I can use syslog-ng directly on the firewalling rules. And what is better: I'm not even using the program() call!
I'm currently running such a system in pre-production and I'm delighted. It's really easy to build. It works like a charm. Here's how:
-- Bazsi
Balazs Scheidler schreef:
It's such a great idea, that I posted on my blog about it. Thanks for both the idea and the implementation.
Thank you for the praise. You might want to link to my personal blog, in addition to the mailing list message: http://valentijn.sessink.nl/?p=322 documents the setup. Best regards, Valentijn -- http://www.openoffice.nl/ Open Office - Linux Office Solutions Valentijn Sessink v.sessink@openoffice.nl +31(0)20-4214059
On Wed, 2011-02-23 at 18:27 +0100, Valentijn Sessink wrote:
Balazs Scheidler schreef:
It's such a great idea, that I posted on my blog about it. Thanks for both the idea and the implementation.
Thank you for the praise. You might want to link to my personal blog, in addition to the mailing list message: http://valentijn.sessink.nl/?p=322 documents the setup.
Updated the post to include this link too. -- Bazsi
participants (5)
-
Alexander Clouter
-
Balazs Scheidler
-
Gergely Nagy
-
Martin Holste
-
Valentijn Sessink