一种SSH暴力攻击的应对方案

今天突然发现公司服务器遭到非常密集的SSH暴力攻击,开始的时候使用手动的方式将攻击方的IP地址添加防火墙过滤规则中。但是有发现攻击者IP地址不断发生变动。如果这样下去,就是有100个手来不及添加过滤规则。因此不才在这种压力之下,灵机暗动,计上心来。
何不整一个能够自动检查攻击的IP地址,并将攻击者丢入18层地狱,让其百千万劫不得出离。

基本的原理是:
1  定时启动lastb 读取最新的20行攻击记录
2  统计记录中频次超过5次的IP地址,
3  将高频次攻击的IP地址添加到防火墙过滤规则中

/**
* @brief 发现公司服务器收到SSH频繁攻击,因此编制这个程序作为后台监测软件。
*    检查ssh登录失败次数,并且获取对应的IP地址,然后根据情况将对应的IP地址
*    通过防火墙禁止。
* @note 这个程序运行在Linux下。通过iptables操作防火墙
* @author 宋炜
* @date 2017-8-2
* @version 1.0
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string>
#include <vector>
#include <regex>
#include <map>

typedef std::vector< std::string > ArrayString;
struct stBadRecordItem
{
    std::string   ip;
    int           count;

    stBadRecordItem(){
        ip.clear();
        count = 0;
    }
    stBadRecordItem(const stBadRecordItem& b )
    {
        ip = b.ip;
        count = b.count;
    }

    stBadRecordItem& operator=( const stBadRecordItem& b )
    {
        ip = b.ip;
        count = b.count;

        return *this;
    }
};

typedef std::map< std::string , struct stBadRecordItem > Record;

int main()
{
    ArrayString    a_str;
    FILE *fail_log_host;
    char *line = NULL;
    size_t line_size = 0;

    Record record;
    do{
        /*从ssh操作失败记录中读取20行数据*/
        line = (char*)malloc(300);
        if( line == NULL ) return -1;

        fail_log_host = popen("lastd -n 20" , "r");
        for( int i = 0; i < 20; i ++ ){
            getline( &line , &line_size , fail_log_host );
            std::string str( line );
            a_str.push_back( str );
        }
        free( line );
        pclose( fail_log_host );

        //记录IP
        std::regex reg("\\d{1,3}(\\.\\d{1,3}){3}");

        for( int i = 0; i < a_str.size(); i ++ ){
            std::smatch m;
            if( std::regex_search( a_str[ i ] , m , reg ) ){
                if( record.find( m[ 0 ] ) != record.end() ){
                    //如果IP已经在map中则,增加出现次数
                    record[ m[ 0 ] ].count ++;
                }
                else{
                    //如果IP没有记录则,登记到map中
                    stBadRecordItem item;
                    item.ip = m[ 0 ];
                    item.count = 1;
                    record.insert( std::pair< std::string , struct stBadRecordItem >( item.ip , item ) );
                }
            }
        }
        //检查IP地址登录的次数
        for( Record::iterator it=record.begin(); it != record.end(); it ++ ){
            if( it->second.count >= 5 ){//将IP地址添加到防火墙过滤黑名单中
                std::string str = "iptables -I INPUT -s " + it->second.ip;
                str += " -j DROP";
                std::cout << str << std::endl;

                system(str.c_str() );
            }
        }
        a_str.erase( a_str.begin() , a_str.end() );
        record.erase( record.begin() , record.end());
        sleep(120);//等候2分钟重新检查
    }while( 1 );
    return 0;
}

转载于:https://my.oschina.net/u/3071588/blog/1542019

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值