分类存档: 安全

及时阻止SSH暴力破解入侵者方法

最近,老是发现有很多暴力破解SSH密码的入侵者,虽然服务器密码设置的很复杂,但是对于这类骚扰者,还是及时屏蔽的好。如下有三个工具,原理很简单,就是分析/var/log/secure日志,找出IP,将其屏蔽。

  1. DenyHosts
    DenyHosts是Python语言写的一个程序,它会分析sshd的日志文件(默认是/var/log/secure),当发现重复的攻击时就会记录IP到/etc/hosts.deny文件,启用tcp_wrappers,从而达到自动屏IP的功能。 通过http://denyhosts.sourceforge.net可以下载DenyHosts的程序,可以直接下载rpm包来安装,也可以通过src.rpm包重新编译并安装等,通过这种方式默认是安装在/usr/share/denyhosts目录下。
    我是通过yum直接安装的:yum install denyhosts.noarch, 可以通过修改/etc/denyhosts.conf来更改配置。启动服务:/etc/init.d/denyhosts start

    详细信息,查看源码。

  2. Perl脚本
    #!/usr/bin/perl 
    
    # 及时封锁使用"暴入法" 入侵的使用者(SSH)
    # 技术支援: http://www.vixual.net/ 
    
    #==相关参数== 
    
    #记录ssh 连线的LOG 档,预设: /var/log/secure
    $log_file = "/var/log/secure"; 
    
    #于多久的时间内尝试登入(秒),预设: 1 小时
    $time_range = 1 * 60 * 60; 
    
    #于$time_range 所设定的时间内,尝试登入失败多少次立即封锁IP,预设: 10 次
    $drop_count = 10; 
    
    #寄件通知,预设收件者: root@localhost
    $mail = 'root@localhost'; 
    
    #寄件程式的位置
    $sendmail = "/usr/sbin/sendmail"; 
    
    #==== 
    
    use Time::Local; 
    
    $ip = $ARGV[0];
    $daemon = $ARGV[1];
    $count = 0; 
    
    %month = (
    Jan => 0,
    Feb => 1,
    Mar => 2,
    Apr => 3,
    May => 4,
    Jun => 5,
    Jul => 6,
    Aug => 7,
    Sep => 8,
    Oct => 9,
    Nov => 10,
    Dec => 11
    ); 
    
    $time = time();
    ($second,$minute,$hour,$day,$month,$year) = localtime($time); 
    
    #取得登入失败的 log
    @list = `cat $log_file | grep "sshd.*Failed password.* $ip "`;
    for(my $i = $#list; $i >= 0; $i--){
    #取得 log 的时间
    my($log_month,$log_day,$log_time) = split(/ +/,$list[$i]);
    my($log_hour,$log_minute,$log_second) = split(/:/,$log_time);
    #前一年的记录
    if($log_month > $month){
    $log_year = $year - 1;
    }else{
    $log_year = $year;
    }
    #将时间转为秒数
    $log_time = timelocal($log_second,$log_minute,$log_hour,$log_day,$month{$log_month},$log_year);
    if($time < $log_time + $time_range ){
    $count++;
    }else{
    last;
    }
    } 
    
    if($count > $drop_count){
    #封锁 IP
    `iptables -A INPUT -p tcp -s $ip --dport 22 -j DROP`;
    if($mail){
    #寄件通知
    $hostname = `hostname`;
    $month++;
    $year += 1900;
    chomp($hostname);
    open(MAIL, "| $sendmail -t") || die "Can't open $sendmail !\n";
    print MAIL qq|To: $mail\n|;
    print MAIL qq|Subject: [$hostname]封锁$ip\n|;
    print MAIL qq|Content-Transfer-Encoding: 8bit\n|;
    print MAIL qq|Content-type: text/plain\; charset=Big5\n\n|;
    print MAIL "\n时间: $year-$month-$day $hour:$minute:$second\n----\n使用者\"$ip\" 尝试以SSH 登入伺服器,共失败$ count 次,已于防火墙封锁该IP。\n\n";
    print MAIL @list;
    close(MAIL);
    }
    } 
    
    exit; 
  3. Bash shell
    
    #! /bin/bash
    # 获取前 1 分钟内的 secure 记录,统计 ssh 认证失败的 IP 和其 失败次数
    SCANNER=`grep "\`date \"+ %e %H:%M\" -d \"-1min\"\`" /var/log/secure|awk '/Failed/{print $(NF-3)}'|sort|uniq -c|awk '{print $1"="$2;}'`
    for i in $SCANNER
    do
          # 取认证失败次数
          NUM=`echo $i|awk -F= '{print $1}'`
          # 取其 IP 地址
          IP=`echo $i|awk -F= '{print $2}'`
          # 若其在失败次数超过 5 次且之前没有被阻断过,那么添加一条策略将其阻断,并记录日志
          if [ $NUM -gt 5 ] && [ -z "`iptables -vnL INPUT|grep $IP`" ]
          then
                  iptables -I INPUT -s $IP -j DROP
                  echo "`date` $IP($NUM)" >> /var/log/scanner.log
          fi
    done
    

/var/log/secure 日志不记录问题

上天查看了服务器安全日志,防火墙屏蔽了处理了一些暴力破解ssh密码的ip(其中一个ip地址为北京一家有名的CDN服务提供商),然后删除了所有的/var/log/secure* 日志文件。

今天再来查看日志的时候,发现/var/log/secure竟然没有记录,才想到直接删除日志文件的时候,对应的服务需要重启。运行命令:service syslog  restart ;service sshd restart 后正常。

顺便复习下ssh在syslog中的设置的知识。

  1. /etc/ssh/sshd_config 中的设置:(即:SyslogFacility 设为AUTHPRIV)
    [root@mail ~]# more /etc/ssh/sshd_config
    #Port 22
    # Logging
    # obsoletes QuietMode and FascistLogging
    #SyslogFacility AUTH
    SyslogFacility AUTHPRIV
    #LogLevel INFO
    #就是把sshd的日志定义在authriv.info级别。
  2. 配合/etc/syslog.conf中的设置:
  3. [root@mail ~]# more /etc/syslog.conf
    # Log all kernel messages to the console.
    # Logging much else clutters up the screen.
    #kern.*                                                 /dev/console
    
    # Log anything (except mail) of level info or higher.
    # Don't log private authentication messages!
    *.info;mail.none;authpriv.none;cron.none                /var/log/messages
    
    # The authpriv file has restricted access.
    authpriv.*                                              /var/log/secure
重新启动sshd和syslog