CentOS系统里rsyslog服务如果没加固,很容易被日志洪水攻击打垮——攻击者疯狂发送海量伪造日志,瞬间塞满你的磁盘、吃光CPU内存,导致系统崩溃或者关键日志丢失。最直接的加固办法,就是在rsyslog配置里设置速率限制、过滤非法消息、用TCP代替UDP传输,并且把日志存到远程安全服务器上。

一、日志洪水攻击到底怎么搞垮你的系统?

攻击原理很简单:利用rsyslog默认配置的宽松处理方式。比如默认用UDP 514端口,攻击者就能伪造大量源IP,每秒发送成千上万条垃圾日志。rsyslog会老老实实接收每条消息,进行解析、分类、写入磁盘。瞬间后果有三:第一,磁盘I/O被日志写入占满,系统卡死;第二,/var/log分区被塞爆,新日志无法记录;第三,rsyslog进程CPU占用率飙到100%,连带影响其他服务。更隐蔽的是,攻击者可能故意发送格式错误的消息,触发rsyslog解析漏洞,直接获取服务器权限。

二、紧急加固:立即启用速率限制模块

CentOS 7/8自带的rsyslog 8.x版本已经内置imjournal和imuxsock模块的速率限制功能。打开/etc/rsyslog.conf文件,找到以下两行配置:

$ModLoad imjournal
$ModLoad imuxsock

在它们下面添加参数:

$IMJournalRatelimitInterval 600  # 每10分钟为一个统计周期
$IMJournalRatelimitBurst 10000   # 周期内最多接收10000条日志
$SystemLogRateLimitInterval 60   # 系统日志限流周期60秒
$SystemLogRateLimitBurst 5000    # 60秒内最多5000条系统日志

关键参数解释:RatelimitInterval定义时间窗口长度(单位秒),Burst是窗口内允许的最大日志条数。超过限制的日志会被直接丢弃,并在/var/log/messages里记录一条警告。建议生产环境先设宽松值(比如每秒允许1000条),观察正常业务流量后再调整。

三、过滤非法来源和垃圾消息

光限速不够,还得过滤。在/etc/rsyslog.conf的RULES部分前添加过滤规则:

# 拒绝非内网IP的日志源
$AllowedSender UDP, 192.168.1.0/24, 10.0.0.0/8
$AllowedSender TCP, 192.168.1.0/24

# 丢弃内容异常的日志(比如超长或含特殊字符)
if $msg contains 'attack_pattern' or $msg length > 8192 then {
    stop
}

# 屏蔽频繁重复的消息(防洪水)
$RepeatedMsgReduction on

注意:AllowedSender只对rsyslog充当日志服务器时有效。如果系统只发不收,需要改用InputTCPServer或InputUDPServer模块的"permit"参数。过滤规则建议放在文件顶部,避免无效日志消耗后续处理资源。

四、强制使用TCP+TLS加密传输

UDP协议无连接、不验证,是洪水攻击最爱。务必改用TCP并启用TLS。先生成证书:

openssl genrsa -out /etc/rsyslog.key 2048
openssl req -new -key /etc/rsyslog.key -out /etc/rsyslog.csr
openssl x509 -req -days 3650 -in /etc/rsyslog.csr -signkey /etc/rsyslog.key -out /etc/rsyslog.crt

然后在配置里启用TCP和TLS:

# 加载TCP和TLS模块
$ModLoad imtcp
$ModLoad gtls

# TLS配置
$DefaultNetstreamDriver gtls
$DefaultNetstreamDriverCAFile /etc/rsyslog.crt
$DefaultNetstreamDriverCertFile /etc/rsyslog.crt
$DefaultNetstreamDriverKeyFile /etc/rsyslog.key

# 开启TCP监听(默认514端口)
$InputTCPServerStreamDriverMode 1
$InputTCPServerStreamDriverAuthMode anon
$InputTCPServerRun 514

客户端配置也要同步改:用"@@server_ip:514"格式指向服务器,并加载同样的TLS证书。TCP+TLS会增加约15%的CPU开销,但能防止日志窃听和伪造。

五、日志本地存储的防护策略

就算攻击没堵住,也要防止本地系统被冲垮。关键三招:第一,给/var/log单独分区,设置磁盘配额。编辑/etc/fstab,给对应分区添加"usrquota,grpquota"选项,然后用edquota限制rsyslog用户组容量。第二,启用日志轮转压缩,编辑/etc/logrotate.d/syslog,改成每天轮转、保留7天、立即压缩:

/var/log/messages
{
    daily
    rotate 7
    compress
    delaycompress
    postrotate
        /bin/kill -HUP `cat /var/run/rsyslogd.pid 2> /dev/null` 2> /dev/null || true
    endscript
}

第三,设置inotify监控,如果日志文件增长异常就触发告警。安装inotify-tools后写监控脚本:

#!/bin/bash
inotifywait -m /var/log -e modify |
while read path action file; do
    if [[ "$file" =~ "messages" ]]; then
        size=$(stat -c%s "$path$file")
        if [ $size -gt 10000000 ]; then  # 单文件超过10MB告警
            echo "警报: $file 异常增长" | mail -s "日志洪水警告" admin@example.com
        fi
    fi
done

六、搭建远程日志堡垒机

终极方案:把日志实时转发到独立的远程服务器。准备一台专用于日志收集的CentOS服务器(称它为log-server),配置为只接收不发送。在log-server上启用高强度限制:

# 限制每个客户端连接速率
$InputTCPServerStreamDriverMode 1
$InputTCPServerStreamDriverAuthMode x509/name
$InputTCPServerStreamDriverPermittedPeer *.yourdomain.com
$InputTCPServerRun 10514

# 每个IP每秒最多100条日志
$template RemoteLogs,"/var/log/remote/%FROMHOST%/%PROGRAMNAME%.log"
:fromhost-ip, !isequal, "127.0.0.1" ?RemoteLogs
& ~
$InputTCPServerRateLimitBurst 100
$InputTCPServerRateLimitInterval 1

客户端配置指向log-server:

*.* @@log-server.yourdomain.com:10514

注意:远程服务器要关闭所有不必要的端口,用防火墙白名单只允许客户端IP访问514/10514端口。日志文件按客户端IP和应用分类存储,方便溯源。

七、监控和应急响应清单

加固后必须建立监控:第一,用rsyslog统计模块生成每小时报表,在配置里添加:

$ModLoad impstats
$ModLoad immark
$MarkMessagePeriod 3600  # 每小时打标记
template(name="stats" type="string" string="%msg%\n")
ruleset(name="statistics") {
    action(type="omfile" file="/var/log/rsyslog-stats.log" template="stats")
}

第二,配置Zabbix或Prometheus监控rsyslog队列长度、丢弃消息数、TCP连接数。第三,准备应急脚本,当磁盘使用超90%时自动清理旧日志并告警。最后记住,所有配置修改后都要用命令"rsyslogd -N1"测试语法,然后用"systemctl restart rsyslog"重启服务。定期审计/var/log/secure和rsyslog-stats.log,看是否有异常连接尝试。

总结来说,CentOS上防日志洪水不是单一措施能解决的。必须组合拳:速率限制筑第一道堤坝,TCP+TLS加固传输通道,远程日志实现异地容灾,再加上实时监控和应急脚本。这套方案能让你的日志系统扛住每秒数万条的洪水攻击,同时保证关键审计日志不丢失。注意,每次系统更新或rsyslog升级后,要重新测试配置,防止安全策略被覆盖。