几乎每一份关于 Suricata 的指南,末尾都是安装 Elasticsearch、Logstash 和 Kibana。对单台 VPS 来说这是个糟糕的建议:这套东西会要走四个 G 的内存和持续的照料,而你想要的只不过是看看过去一天 IDS 抓到了什么。Suricata 没有它们也完全能工作——但它有一个特性,使得人们装上它、一周后又卸掉。

默认设置里的地雷

刚装好时,Suricata 会往 eve.json 里写三十多种事件:不只是 alert,还有每一次 DNS 查询、每一次 TLS 握手、每一笔 HTTP 事务、ARP、DHCP,一条又一条 flow。此外还有每八秒一次的独立 stats.log。而与此同时,Suricata 并不为自己设置日志轮转——那是管理员的活儿,而且没有哪里用大字写着这一点。

来自一台真实服务器的数字:两天 15 GB——其中九个 G 在 eve.json,将近六个在 stats.log。距离磁盘写满还剩大约五天。那台服务器的流量也并不大;在一个繁忙节点上,这就是几个小时的事。

现在就查一下你自己的:

sudo du -sh /var/log/suricata/*

只保留你会读的东西

如果你看的是 alert 而不是在做网络取证,那么从 eve-log 里恰好只需要一种事件。在 /etc/suricata/suricata.yaml 里找到 outputs 块,在 eve-logtypes 中留下 alert,把其余的注释掉。顺手在同一处关掉统计输出:

  - stats:
      enabled: no

改完之后,配置检查是强制的——要在重启服务之前做:

sudo suricata -T -c /etc/suricata/suricata.yaml -v

顺序很重要:如果规则还没加载,这项检查是过不了的。先 suricata-update,再检查配置,然后才启动。

真正管用的轮转

文件 /etc/logrotate.d/suricata

/var/log/suricata/*.log /var/log/suricata/*.json {
    daily
    rotate 7
    maxsize 200M
    missingok
    compress
    delaycompress
    create 0664 suricata suricata
    su suricata suricata
    postrotate
        systemctl kill -s HUP suricata
    endscript
}

这里有两行并不显眼,而两行都很关键。

su suricata suricata——没有它,logrotate 会悄无声息地跳过每一个文件。目录 /var/log/suricata 属于 suricata 组而不是 root,而 logrotate 认为这种安排不安全。邮件里不会有报错,日志里也不会有;你只会一直确信轮转是有的,直到磁盘写满为止。唯一能提前发现的办法是空跑一遍:

sudo logrotate -d /etc/logrotate.d/suricata

create 0664 suricata suricata——新文件的权限。用默认值(0640)时,任何以非 root 用户读日志的面板或脚本,在第一次轮转之后就什么也看不到了。

除了日志还要配置什么

HOME_NET。它描述的是 Suricata 认为哪些是「自己人」。默认值列的是所有私有地址段,而 VPS 有的是公网地址——于是有些规则不触发,或者反着触发。请明确写出你自己的网络。

规则。Emerging Threats Open 规则集由 suricata-update 拉取,它该待在 cron 里每天跑一次。个别吵闹的特征通过标识符在 /etc/suricata/disable.conf 里关掉——别怕用它:这套规则是为企业网络做的,在一台普通 Web 服务器上会有十来条规则不停地、毫无缘由地触发。

模式。默认情况下 Suricata 监听流量的副本并且只发出告警(IDS)。在单台服务器上启用阻断模式(IPS,通过 nfqueue)主要是给自己找风险:一次误报,你就把自己关在门外了。请从观察开始,用一个月看看都抓到了什么。

没有 Kibana 怎么读

简短的 alert 在 /var/log/suricata/fast.log 里——每个事件一行,肉眼可读:

sudo tail -50 /var/log/suricata/fast.log

细节在 eve.json 里,每行一个 JSON 对象。人们通常为之安装 Kibana 的那些事,归结起来就是一条命令:

sudo jq -r 'select(.event_type=="alert") | .alert.signature' \
    /var/log/suricata/eve.json | sort | uniq -c | sort -rn | head -20

这就是出现最频繁的二十条特征。一周下来,这样一份清单会诚实地告诉你服务器上在发生什么,同时也显示出哪些规则该关掉了。

已经有 Fail2ban 了,还要它做什么

两者性质不同。Fail2ban 读的是应用日志,对失败登录做出反应——也就是对已经到达某个服务的东西反应。Suricata 看的是流量本身,看得到那些永远不会出现在任何日志里的东西:端口扫描、与已知特征吻合的漏洞利用尝试、从你机器内部到命令服务器的连接。最后这一项尤其宝贵:向别人的命令服务器发起的外发连接,是服务器上已经有你没启动过的东西在跑的最早信号。

两个都留着没问题,它们不冲突。唯一的问题是,有没有人比一季度一次更频繁地去读它们的输出。同样这些 alert 按类别和来源分开放在一个页面上是什么样子——见下面的演示。