在CentOS服务器运维中,rsyslog是系统默认的日志守护进程,负责收集内核、应用程序、安全认证等各类日志。但如果不做过滤和集中转发,你会面临两个核心问题:一是日志量太大,本地磁盘被撑满;二是分散在各台机器上的日志无法统一审计,出了安全事件根本查不过来。解决方案就是通过rsyslog的过滤规则(filter)把有用的日志挑出来,再通过转发模块(如omfwd、omrelp)统一推送到日志中心服务器(比如ELK、Graylog或自建的rsyslog收集器)。下面我把完整的配置流程、过滤语法、转发方式、安全加固全部讲透。

一、rsyslog基础架构先搞清楚

rsyslog的工作原理是"输入模块→规则过滤→动作执行"。输入模块(如imuxsock、imjournal)从系统各处收集日志,规则部分根据facility(日志来源类别)和severity(严重级别)进行匹配,匹配成功后执行动作(action),动作可以是写本地文件、转发到远程、丢弃等。CentOS 7/8默认安装rsyslog,配置文件主路径是/etc/rsyslog.conf,额外的规则文件放在/etc/rsyslog.d/目录下,建议新建独立文件如/etc/rsyslog.d/security-forward.conf,方便管理。

二、安全日志过滤:只留你需要的

安全相关的日志主要来自authpriv(认证和授权)和auth(旧版认证)这两个facility。你需要过滤的典型场景包括:SSH登录成功/失败、sudo提权操作、用户切换、防火墙变更、SELinux拒绝事件等。rsyslog的过滤语法非常直观,用property-based filter即可:

# 过滤所有authpriv设施的日志(包括info及以上级别)
:authpriv.*  /var/log/secure

# 只过滤警告及以上级别的认证日志,减少噪音
:authpriv.warning  /var/log/auth-warning.log

# 过滤包含特定关键字的日志,比如SSH失败登录
:msg, contains, "Failed password" /var/log/ssh-failures.log

# 过滤sudo相关操作
:msg, contains, "sudo:" /var/log/sudo-actions.log

# 过滤SELinux拒绝事件
:msg, contains, "AVC" /var/log/selinux-denials.log

这里有个关键点:多条规则按顺序匹配,一旦某条规则命中且带有"~"(丢弃)或明确的动作,后续规则就不再处理。所以规则顺序很重要,把最具体的过滤放前面,通用的放后面。如果你想把某类日志只转发不存本地,就在动作部分写转发地址而不是本地文件路径。

三、日志转发到日志中心的三种方式

转发是这篇文章的核心。rsyslog支持多种转发协议,根据你的日志中心架构选择合适的方式:

1. UDP转发(omfwd模块,最简单但不可靠)

# 通过UDP转发所有authpriv日志到日志中心
:authpriv.*  @192.168.1.100:514

UDP速度快、配置简单,但日志可能丢失,适合对完整性要求不高的场景。注意@符号表示UDP,如果用@@则表示TCP。

2. TCP转发(omfwd模块,推荐生产使用)

# 通过TCP转发,确保日志不丢失
:authpriv.*  @@192.168.1.100:514

TCP有确认机制,日志中心收到后会回ACK,发送端才继续发下一条。生产环境强烈建议用TCP,尤其是安全日志,丢一条都可能漏掉入侵痕迹。

3. RELP转发(omrelp模块,带可靠性和TLS加密)

# 使用RELP协议转发,支持TLS加密
module(load="omrelp")

:authpriv.*  action(type="omrelp" target="192.168.1.100" port="2514"
    tls="on" tls.certfile="/etc/pki/tls/certs/client-cert.pem"
    tls.keyfile="/etc/pki/tls/private/client-key.pem"
    tls.caCert="/etc/pki/tls/certs/ca-cert.pem")

RELP是rsyslog自有的可靠传输协议,比TCP更进一步,支持批量发送和TLS加密。如果你的日志中心是Graylog,它原生支持RELP输入。TLS加密能防止日志在传输过程中被窃听或篡改,这对安全日志来说是刚需。

四、完整配置文件示例

下面给出一个生产级的完整配置文件/etc/rsyslog.d/security-forward.conf,你可以直接参考修改:

# /etc/rsyslog.d/security-forward.conf
# CentOS安全日志过滤与转发配置

# 加载必要模块
module(load="imuxsock")
module(load="imjournal" StateFile="imjournal.state")
module(load="omfwd")

# 全局转发模板,统一格式方便日志中心解析
template(name="SecureForwardFormat" type="string"
    string="%TIMESTAMP% %HOSTNAME% %syslogtag%%msg%\n")

# 规则1:SSH登录失败日志,单独记录并转发
:msg, contains, "Failed password" -/var/log/ssh-failed.log
:msg, contains, "Failed password" @@192.168.1.100:514;SecureForwardFormat

# 规则2:SSH登录成功日志
:msg, contains, "Accepted" -/var/log/ssh-accepted.log
:msg, contains, "Accepted" @@192.168.1.100:514;SecureForwardFormat

# 规则3:sudo操作日志
:msg, contains, "sudo:" -/var/log/sudo.log
:msg, contains, "sudo:" @@192.168.1.100:514;SecureForwardFormat

# 规则4:所有authpriv警告及以上,统一转发
:authpriv.warning  @@192.168.1.100:514;SecureForwardFormat

# 规则5:SELinux拒绝事件
:msg, contains, "AVC" -/var/log/selinux-audit.log
:msg, contains, "AVC" @@192.168.1.100:514;SecureForwardFormat

# 规则6:防火墙规则变更(iptables/firewalld)
:msg, contains, "IN=" -/var/log/firewall-changes.log
:msg, contains, "IN=" @@192.168.1.100:514;SecureForwardFormat

注意"-"符号表示不写本地文件只做转发,如果你既想本地留存又想转发,去掉"-"同时写两个动作即可。分号后面跟的是自定义模板,确保日志格式统一。

五、日志中心接收端配置要点

转发端配好了,接收端也得跟上。如果你用的是rsyslog做日志中心,需要在/etc/rsyslog.conf中开启监听:

# 日志中心服务器配置
module(load="imtcp"
    MaxSessions="500"
    StreamDriver.Name="gtls"
    StreamDriver.Mode="1"
    StreamDriver.AuthMode="anon")

input(type="imtcp" port="514")

# 或者用RELP输入
module(load="imrelp")
input(type="imrelp" port="2514" tls="on"
    tls.certfile="/etc/pki/tls/certs/server-cert.pem"
    tls.keyfile="/etc/pki/tls/private/server-key.pem"
    tls.caCert="/etc/pki/tls/certs/ca-cert.pem")

如果用ELK(Elasticsearch + Logstash + Kibana),Logstash的input配置用tcp或relp插件即可接收。Graylog则在Inputs里添加Syslog TCP或RELP输入,绑定对应端口。

六、安全加固:别让日志转发本身成为攻击面

很多人配完转发就不管了,这是大忌。日志转发通道如果不加固,攻击者可以伪造日志注入、中间人窃听、甚至利用rsyslog漏洞提权。必须做以下几点:

第一,防火墙限制。只允许日志中心服务器的IP访问本机514端口:

firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.1.100" port protocol="tcp" port="514" accept'
firewall-cmd --reload

第二,启用TLS加密。前面RELP转发已经展示了TLS配置,TCP转发也可以通过gtls驱动实现加密传输,千万别用明文。

第三,限制rsyslog运行权限。确保rsyslog以非root用户运行,配置文件权限设为640,所属组为syslog:

chown root:syslog /etc/rsyslog.d/security-forward.conf
chmod 640 /etc/rsyslog.d/security-forward.conf

第四,定期审计转发日志。在日志中心设置告警规则,如果某台服务器突然停止发送日志,可能是被入侵后rsyslog被停掉了,这种沉默本身就是信号。

七、性能优化和常见坑

大批量服务器转发日志时,性能瓶颈通常出在两个地方:一是发送端rsyslog的队列,二是接收端的写入速度。rsyslog默认使用内存队列,高并发时建议改为磁盘队列保证不丢日志:

# 在全局配置中设置队列
global(
    workDirectory="/var/spool/rsyslog"
    maxMessageSize="64k"
)

# 针对转发动作使用磁盘辅助队列
action(type="omfwd" target="192.168.1.100" port="514" protocol="tcp"
    queue.type="LinkedList"
    queue.filename="fwd_queue"
    queue.maxDiskSpace="1g"
    queue.saveOnShutdown="on"
    queue.size="50000")

另一个常见坑是时间戳不一致。转发的日志如果时间戳是本地时间,到了日志中心和其他服务器的日志混在一起就乱了。建议在模板中使用ISO 8601格式或者统一转成UTC:

template(name="ISO8601Format" type="string"
    string="%timestamp:::date-rfc3339% %HOSTNAME% %syslogtag%%msg%\n")

还有一点容易忽略:rsyslog配置改完后必须重启服务才生效,而且要用systemctl reload而不是restart,避免中断正在写入的日志:

systemctl restart rsyslog
# 或者热重载
systemctl reload rsyslog

八、总结与实操建议

CentOS安全日志的过滤与转发,本质上就是"精准筛选+可靠传输+安全加固"三步走。过滤阶段用property filter和msg contains组合,把SSH、sudo、SELinux、防火墙等关键事件单独拎出来;转发阶段生产环境务必用TCP或RELP+TLS,别图省事用UDP;加固阶段防火墙白名单、文件权限、TLS证书一个都不能少。建议先在一台测试机上跑通全流程,验证日志中心能正常接收和解析,再批量推广到所有服务器。日志是安全运维的基石,这套体系搭好了,后续做入侵检测、合规审计、故障排查都有底气。