了不起的 Zeek Configuration Framework

写在前面

​ 上半年是忙的要死,下半年都没怎么做“阳间”的事。这会“阳”了,顺带可以整理一些零散的知识点分享给大家。这一偏会比较剪短一些。

背景

​ 知道Zeek的小伙伴应该都熟悉或者知道Suricata吧。Suricata在每次调整规则之后是可以通过reload来直接加载规则的,这样的好处是不用重启Suricata就让规则生效,生效速度很快。不知道大家在Zeek上是怎么做的,我之前都是用zeek deploy的方式确保最新的配置加载。起初,这并不会有什么太大的问题,但是随着Zeek的机器越来越多,操作就会变的异常繁琐。当然,如果你使用了Zeek的集群架构,它也是比较方便的。我今天就来介绍一个让配置加载变的更加便捷的方法,那就是利用Zeek自带的Configuration Framework来实现日常大部分的配置变更与“热”加载。

那么开始吧?

注意支持类型

​ 就像我上面的描述那样,Configuration Framework能做到对日常大部分的配置实现“热”加载。因为它有类型的要求,只有在脚本中包含指定的配置项类型才能实现试试下发与“热”加载。一旦出现类型错误,日志将会被发送至reporter.log文件中,大家注意观察。目前支持的类型在大多数情况下是够用的,下表为详细类型:

Data Type Sample Config File Entry Comments
addr 1.2.3.4 Plain IPv4 or IPv6 address, as in Zeek. No /32 or similar netmasks.
bool T T or 1 for true, F or 0 for false
count 42 Plain, nonnegative integer.
double -42.5 Plain double number.
enum Enum::FOO_A Plain enum string.
int -1 Plain integer.
interval 3600.0 Always in epoch seconds, with optional fraction of seconds. Never includes a time unit.
pattern `/(foo bar)/`
port 42/tcp Port number with protocol, as in Zeek. When the protocol part is missing, Zeek interprets it as /unknown.
set 80/tcp,53/udp The set members, formatted as per their own type, separated by commas. For an empty set, use an empty string: just follow the option name with whitespace.Sets with multiple index types (e.g. set[addr,string]) are currently not supported in config files.
string Don’t bite, Zeek Plain string, no quotation marks. Given quotation marks become part of the string. Everything after the whitespace separator delineating the option name becomes the string. Saces and special characters are fine. Backslash characters (e.g. \n) have no special meaning.
subnet 1.2.3.4/16 Plain subnet, as in Zeek.
time 1608164505.5 Always in epoch seconds, with optional fraction of seconds. Never includes a time unit.
vector 1,2,3,4 The set members, formatted as per their own type, separated by commas. For an empty vector, use an empty string: just follow the option name with whitespace.
示例:record-http_domain

​ 针对需要对HTTP做审计或者监测的小伙伴,可以通过此方法快速的将不需要的记录的域名进行过滤,或者只记录关注的域名。

  • record-http_domain.zeek

    任何需要进行动态调整的参数,都必须在export中通过option去声明。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    module HTTP;
    module HTTPFilterDomain;

    export {
    # domain name
    option local_domain: set[string] = {};
    # record_local_zone
    option record_local_zone: bool = F;
    # Load HTTP config.dat
    redef Config::config_files += { "/usr/local/zeek/share/zeek/site/http-audit/record-http_domain.dat" };
    }

    redef record HTTP::Info += {
    is_local_zone: bool &log &default=F;
    };

    hook HTTP::log_policy(rec: HTTP::Info, id: Log::ID, filter: Log::Filter) &priority = 10
    {
    if ( filter$name != "default" )
    return;

    if ( record_local_zone )
    {
    if ( rec$host ! in local_domain )
    break;
    rec$is_local_zone = T;
    }
    else
    {
    if ( rec$host in local_domain )
    break;
    }
    }
  • record-http_domain.dat

    1
    2
    3
    4
    # string
    HTTPFilterDomain::local_domain ifconfig.io,ipinfo.io
    # bool
    HTTPFilterDomain::record_local_zone F

看一下效果如何

​ 由于我是将HTTP发送到了Kafka里面,好处就是不用关注本身NTA机器的磁盘存储的问题了。这里我通过Kafka的Topic数据给大家看下。

iShot_2022-12-16_16.24.59