• suricata学习笔记1--初步认识


    1、前言
      最近工作需要对网站的关键字进行检测,找出敏感词。这个过程需要对报文进行收集、解码、检测和记录日志。当前只是简单实现功能,根据关键字进行简单的匹配,而没有进行关键字的语义分析。导致的结果就是JAVA可以匹配AV这个敏感关键字。报文检测这方面,开源项目已经做得非常好了,我所了解的有snort、suircata、bro,这三个都是非常优秀的IDS(入侵检测系统)。由于对bro没有深入了解,我们对比了snort和suricata,结合suricata的多线程和模块化,全面兼容snort规则,我们选用了suricata进行关键字检测。
      刚开始接触suricata的时候,压根不知道这个单词怎么发音,于是乎赶紧再词典上查一下。suircata是一款支持IDS、IPS和NSM的系统。关于suircata的详细介绍可以参考官网:https://suricata-ids.org/
    备注:
      IDS:英文“Intrusion Detection Systems”的缩写,中文意思是“入侵检测系统”。依照一定的安全策略,通过软、硬件,对网络、系统的运行状况进行监视,尽可能发现各种攻击企图、攻击行为或者攻击结果,以保证网络系统资源的机密性、完整性和可用性。
      IPS是英文“Intrusion Prevention System”的缩写,中文意思是入侵防御系统。随着网络攻击技术的不断提高和网络安全漏洞的不断发现,传统防火墙技术加传统IDS的技术,已经无法应对一些安全威胁。在这种情况下,IPS技术应运而生,IPS技术可以深度感知并检测流经的数据流量,对恶意报文进行丢弃以阻断攻击,对滥用报文进行限流以保护网络带宽资源。
      NSM:英文“network security monitoring”的缩写,中文意思是“网络安全监控”。
    2、总体架构
      报文检测系统通常四大部分,报文获取、报文解码、报文检测、日志记录;suricata不同的功能安装模块划分,一个模块的输出是另一个模块的输入,suricata通过线程将模块串联起来。

      接下来以IDS为例来说明suircata的线程与模块之间是如何连接起来的。
      首先注册runmods,运行方式指定suricata获取报文的方式,例如libpcap、netmap、af-packet等,代码如下图所示:

     

      然后再根据设置suricata的工作模式,找到对应获取报文的处理模块。suircata默认是通过af-packet mmap获取报文,然后调用获取报文模块当然入口函数,
    入口函数中函数添加了解码模块、流处理模块(检测报文)、日志处理模块。通过slot链条安装注册顺序串联起来。每一个线程都包含一个slot的链表,每个结点都悬挂着不同的模块,程序执行的时候会遍历slot链表,按照加入链表的熟悉执行模块。

    创建线程,并将模块添加到slot链表过程代码如下所示:

     1 /* create the threads */
     2 for (thread = 0; thread < threads_count; thread++) {
     3         char tname[TM_THREAD_NAME_MAX];
     4         ThreadVars *tv = NULL;
     5         TmModule *tm_module = NULL;
     6         const char *visual_devname = LiveGetShortName(live_dev);
     7 
     8         if (single_mode) {
     9             snprintf(tname, sizeof(tname), "%s#01-%s", thread_name, visual_devname);
    10         } else {
    11             snprintf(tname, sizeof(tname), "%s#%02d-%s", thread_name,
    12                      thread+1, visual_devname);
    13         }
    14         tv = TmThreadCreatePacketHandler(tname,
    15                 "packetpool", "packetpool",
    16                 "packetpool", "packetpool",
    17                 "pktacqloop");
    18         if (tv == NULL) {
    19             SCLogError(SC_ERR_THREAD_CREATE, "TmThreadsCreate failed");
    20             exit(EXIT_FAILURE);
    21         }
    22 
    23         //添加收包模块
    24         tm_module = TmModuleGetByName(recv_mod_name);
    25         if (tm_module == NULL) {
    26             SCLogError(SC_ERR_INVALID_VALUE, "TmModuleGetByName failed for %s", recv_mod_name);
    27             exit(EXIT_FAILURE);
    28         }
    29         TmSlotSetFuncAppend(tv, tm_module, aconf);
    30         //添加解包模块
    31         tm_module = TmModuleGetByName(decode_mod_name);
    32         if (tm_module == NULL) {
    33             SCLogError(SC_ERR_INVALID_VALUE, "TmModuleGetByName %s failed", decode_mod_name);
    34             exit(EXIT_FAILURE);
    35         }
    36         TmSlotSetFuncAppend(tv, tm_module, NULL);
    37         //添加流处理模块,用于检测报文
    38         tm_module = TmModuleGetByName("FlowWorker");
    39         if (tm_module == NULL) {
    40             SCLogError(SC_ERR_RUNMODE, "TmModuleGetByName for FlowWorker failed");
    41             exit(EXIT_FAILURE);
    42         }
    43         TmSlotSetFuncAppend(tv, tm_module, NULL);
    44        //添加阻断模块
    45         tm_module = TmModuleGetByName("RespondReject");
    46         if (tm_module == NULL) {
    47             SCLogError(SC_ERR_RUNMODE, "TmModuleGetByName RespondReject failed");
    48             exit(EXIT_FAILURE);
    49         }
    50         TmSlotSetFuncAppend(tv, tm_module, NULL);
    51         //添加日志处理模块
    52         SetupOutputs(tv);
    53 
    54         TmThreadSetCPU(tv, WORKER_CPU_SET);
    55 
    56         if (TmThreadSpawn(tv) != TM_ECODE_OK) {
    57             SCLogError(SC_ERR_THREAD_SPAWN, "TmThreadSpawn failed");
    58             exit(EXIT_FAILURE);
    59         }
    60 }
    61         

    在AF-PACKET工作模式下提供三种工作方式:

    关于工作方式可以参考:http://blog.csdn.net/firedb/article/details/7581853。
    目前我只用过worker工作模式,整个流程通过一个线程来处理。

    3、总结

      这是目前对suricata的一个整体的认识,接下来认真研究每个模块之间是如何交互。需要深入学习suricata是如何收集报文,如何将收集的报文传递给解码模块,解码模块做哪些工作,输出是什么。

    suricata各模块功能:
      Receive:从NFQUEUE中接收数据包,并将封装在Packet结构中,然后放入下一个缓冲区。
      Decode:对数据包进行解码,主要是对数据包头部信息进行分析并保存在Packet结构中。
      StreamTCP:对数据包进行TCP流重组。
      Detect:检测数据包是否包含入侵行为。
      Verdict:对检测后的数据包进行判定,并将判定结果告诉内核(通过ipq_set_verdict函数),方便内核对数据包进行接收、丢弃等处理。
      RespondReject:通过libnet对那些要执行Reject操作的数据包进行相应的回应。

  • 相关阅读:
    边工作边刷题:70天一遍leetcode: day 52
    边工作边刷题:70天一遍leetcode: day 53-1
    边工作边刷题:70天一遍leetcode: day 53
    边工作边刷题:70天一遍leetcode: day 54
    边工作边刷题:70天一遍leetcode: day 55
    JavaScript 组件化开发之路(一)
    Promise
    HTML5 API 之 history
    时隔一年,window.scroll
    sublimeLinter-jshint 配置
  • 原文地址:https://www.cnblogs.com/Anker/p/5989842.html
Copyright © 2020-2023  润新知