David, You can definitely accomplish what you want with iptables. You have the right concept on how to do it, but your rules are not quite right. Try this (and make sure that if you have other rules that these show up first, otherwise other rules you might have in the INPUT chain might be allowing the packets and iptables never gets to these rules): iptables -A INPUT -p tcp -m tcp --dport 22 -m state --state NEW -m recent --set --name SSH iptables -A INPUT -p tcp -m tcp --dport 22 -m state --state NEW -m recent --rcheck --seconds 60 --hitcount 4 --name SSH --rsource -j LOG --log-prefix "SSH_brute_force " iptables -A INPUT -p tcp -m tcp --dport 22 -m state --state NEW -m recent --rcheck --seconds 60 --hitcount 4 --name SSH -j DROP iptables -A INPUT -p tcp -m tcp --dport 22 -m state --state NEW -j ACCEPT Explanation of the above: The first rule in the chain will create the entry for the conneciton attempt in the recent connections table named SSH. Note that all it does is add this entry. It does NOT jump to the ACCEPT target. If it did, the other rules would not be processed...which is what was happening in the example you sent. The second rule generates the log entry if 4 or more connection attempts are made within 60 seconds. Entries in /var/log/messages will have the prefix "SSH_brute_force " as you described in your example. The third rule drops any packets coming from a host that has attempted 4 or more SSH connections within the last 60 seconds. The last rule will allow the connection attempt and does not need to check the recent table because this rule will only be evaluated if the packet has not been dropped yet from the rule above. The approach above only sort of works. When I tested on my system, the ssh client kept retrying the connection for a while and extending the amount of time between connection attempts, so that eventually there were less than 4 packets within 60 seconds and I was able to attempt a login. Increasing the time it takes to 90 seconds did the trick because my ssh client gave up before there were less than 4 attempts within 90 seconds, however, if I change the settings on my ssh client to retry for longer, or even wait longer between retries, then this will circumvent the rules. Another approach would be to build another recent connections table that black lists the attackers (rather then checking for time and number of hits, it just checks for that entry in the table). Here is how that complete rule set would look like: iptables -N SSHATTACKCHAIN iptables -A SSHATTACKCHAIN -m recent --name SSHATTACKER --set iptables -A SSHATTACKCHAIN -j LOG --log-prefix "SSH_brute_force " iptables -A SSHATTACKCHAIN -j DROP iptables -A INPUT -p tcp -m tcp --dport 22 -m state --state NEW -m recent --rcheck --name SSHATTACKER -j LOG --log-prefix "SSH_Blacklisted_Host " iptables -A INPUT -p tcp -m tcp --dport 22 -m state --state NEW -m recent --rcheck --name SSHATTACKER -j DROP iptables -A INPUT -p tcp -m tcp --dport 22 -m state --state NEW -m recent --set --name SSH iptables -A INPUT -p tcp -m tcp --dport 22 -m state --state NEW -m recent --rcheck --seconds 10 --hitcount 4 --name SSH -j SSHATTACKCHAIN iptables -A INPUT -p tcp -m tcp --dport 22 -m state --state NEW -j ACCEPT The above example builds a separate chain to deal with attempts from hosts that attempted 4 or more SSH connections within 60 seconds. The adds the host to a black list table (SSHATTACKER), then log what you want, and finally drops the packet. Note that in this example, the command evaluation actually starts from the 5th iptables command shown above. First we check to see if the host is blacklisted already, and if so, we log the connection attempt with a slight different log prefix (it could be the same if you wanted) and finally we drop the packet. If not on the black list, we continue processing the rules. We log the connection attempt in the recent table SSH, then we check to see if there were 4 or more connection attempts within the last 60 seconds. If there were, then we go through and process the rules in the SSHATTACKCHAIN (commands 2-4 above). Otherwise, if there were less than 4 connection attempts within the last 60 seconds, we accept the packet. Note that the host will be blacklisted for as long as the server is running and iptables has not been flushed. Which means that the host will not be able to ssh to your server period, no matter how much time goes by. This could cause a problem for a host that is coming from a NATed network since all the hosts on that network (the public NAT address) would now be essentially black listed. Might be interesting then to add another rule to remove a host from the blacklist table if there were no connection attempts made within a specific period of time, say 30 minutes (use --remove, rather than --set along with the recent module). Other options would be to not only block ssh, but all network traffic from a blacklisted host, but again there are implications to doing this. If you want additional information or have more questions, please feel free to ask. Wil Wilson Mattos Technology Specialist SUSE® Linux Enterprise 10 Your Linux is ready* www.novell.com/linux
"David C. Benham" <dcb@vcomcon.com> 10/31/2006 12:51 PM >>> If ssh is set to log, the attack will be very obvious. A quick cat /var/log/message | grep "ssh" will make it very clear, although you will need more going forward.
I'm getting killed by attacks that are virtually running all day long now. My QUESTION: why doesn't the following iptables approach work? ACCEPT tcp -- anywhere anywhere tcp dpt:ssh state NEW recent: SET name: SSH side: source LOG tcp -- anywhere anywhere tcp dpt:ssh recent: UPDATE seconds: 60 hit_count: 4 TTL-Match name: SSH side: source LOG level warning prefix `SSH_brute_force ' DROP tcp -- anywhere anywhere tcp dpt:ssh recent: UPDATE seconds: 60 hit_count: 4 TTL-Match name: SSH side: source Sorry for the formatting, it's really just 3 commands and iptables should drop packets from the offending attacker, but it does not. I want an iptables solution to this.
Hi,
You can start by checking the log files. I do not know if this can help but in my particular case I installed python and I run Denyhosts as a deamon , and that authomates the tasks of detecting and preventing attacks. DenyHost checks the log files and if there is an attempt to brute force it place a line is /etc/hosts.deny. So some services running under tcpwrap can be very simply "controlled" in this manner. Also of great importance is to use in the sshd config the directives AllowUsers and DenyUsers. The "usual" targets are the very known system users like wwwrun, tomcat, root and so on. Those should be prevented from a external log in. But of course your solution depends a bit on what is the purpose of that precise brute force monitoring ... and exact service you are monitoring ...
Regards, Pedro Coelho
--- Shashi Kanth Boddula <shashi.boddula@oracle.com> wrote:
Hi All,
I am looking for a good tool to detect brute-force and dictionary attacks on user accounts on a Linux system . The tool should also have the intelligence to differntiate between user mistakes and actual brute-force/dictionary attacks and reduce the false positives. SLES9/SLES10 included security tools are not helping in this case . The seccheck package functionality also not matching with my requirement.
Please , anyone knows any third party security tool or any opensource security tool which solves my problem ?
Thanks & Regards, Shashi Kanth,CISSP
-- Check the headers for your unsubscription address For additional commands, e-mail: suse-security-help@suse.com Security-related bug reports go to security@suse.de, not here
-- Check the headers for your unsubscription address For additional commands, e-mail: suse-security-help@suse.com Security-related bug reports go to security@suse.de, not here
-- Check the headers for your unsubscription address For additional commands, e-mail: suse-security-help@suse.com Security-related bug reports go to security@suse.de, not here