原文链接:麒麟 | Rsyslog + TLS 搭建安全日志服务器全攻略
在企业运维中,集中式日志收集与传输是必不可少的环节。尤其在内外网环境下,日志的安全传输显得尤为重要。今天分享一篇基于 Rsyslog + stunnel + TLS 的日志服务器搭建实践,帮助大家实现日志的安全收集和存储。
整体思路(先懂再做)
Rsyslog 负责产生日志/接收日志、写文件(擅长模板与规则)。
stunnel 负责把原本的 TCP 明文“套”在 TLS 隧道里(兼容老组件)。
双向证书 让服务端只信任“已签发的客户端”,客户端也只信任“自家的 CA/服务端”。
动态目录模板 让不同主机/程序的日志按天分文件存放,便于检索与留存。
一、服务端
1.查看系统信息
清楚发行版与内核版本,便于判断包管理器(如 dnf)与服务名(rsyslog/stunnel)是否一致,避免“照抄命令不生效”。
[root@rsyslogserver ~]# cat /etc/os-release [root@rsyslogserver ~]# uname -a
2.更新系统源
确保后续安装包的版本一致、补丁齐全,降低“老版本 bug”导致的奇怪故障。生产环境建议先在测试/灰度主机验证。
[root@rsyslogserver ~]# dnf update
3.安装软件
rsyslog:负责接收/写入日志。
stunnel:负责 TLS 加密隧道。
openssl:生成 CA/证书/密钥。
policycoreutils-python-utils:提供 semanage 等工具,必要时用于 SELinux 上的端口/路径策略(文中默认未用,但建议预装以备生产环境加固)。
[root@rsyslogserver ~]# dnf -y install rsyslog stunnel openssl policycoreutils-python-utils
4.启动rsyslog
保证 rsyslog 开机即运行,后续 stunnel 解密后的明文日志才能被它接收落盘。
[root@rsyslogserver ~]# systemctl enable --now rsyslog
5.生成CA与服务端证书
自建 CA(ca.crt/ca.key)统一签发内部证书,后续只信任自家CA的证书链。
server.crt/server.key是服务端身份;合并为server.pem便于stunnel使用。
chmod 600 避免私钥泄露。
关键点:-days 设置证书有效期;/CN= 最好写服务端的可解析主机名,便于更严格校验(部分 stunnel 版本结合 verify/checkHost 更稳)。
[root@rsyslogserver ~]# mkdir -p /etc/rsyslog-tls && cd /etc/rsyslog-tls [root@rsyslogserver rsyslog-tls]# openssl req -x509 -newkey rsa:4096 -days 3650 -nodes -keyout ca.key -out ca.crt -subj "/CN=PDSYW-CA" [root@rsyslogserver rsyslog-tls]# openssl req -newkey rsa:4096 -nodes -keyout server.key -out server.csr -subj "/CN=rsyslogserver.pdsyw.cn" [root@rsyslogserver rsyslog-tls]# openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt -days 1825 [root@rsyslogserver rsyslog-tls]# cat server.crt server.key > server.pem [root@rsyslogserver rsyslog-tls]# chmod 600 server.key server.pem
6.在服务端为客户端签证书
每台客户端都有独立证书,服务端 stunnel 在 verify=2 下会校验链路合法性,避免陌生主机接入。可以把 CN 作为设备标识规范命名。
[root@rsyslogserver rsyslog-tls]# openssl req -newkey rsa:2048 -nodes -keyout client.key -out client.csr -subj "/CN=rsyslogclient.pdsyw.cn" [root@rsyslogserver rsyslog-tls]# openssl x509 -req -in client.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out client.crt -days 1825
7.分发客户端签证书
把(client.crt/client.key/ca.crt)安全、规范地放到客户端;提前 mkdir -p,可避免 scp 报 “Not a directory”。
[root@rsyslogserver rsyslog-tls]# ssh root@192.168.80.112 "mkdir -p /etc/rsyslog-tls" [root@rsyslogserver rsyslog-tls]# scp client.crt client.key ca.crt [root@192.168.80.112:/etc/rsyslog-tls/](mailto:root@192.168.80.112:/etc/rsyslog-tls/)
8.服务端rsyslog配置
imtcp:开启 TCP 输入模块(由 stunnel 解密后转发至本地 10514)。
template + DynaFile:按主机/程序/日期自动分目录与文件,检索更清晰。
createDirs/*_Mode:自动建目录并设置安全权限。
ruleset:将接收与落盘动作封装成规则集并绑定到 10514 端口。
这一步决定了日志目录结构与权限,是后续检索与合规审计的基础。
[root@rsyslogserver ~]# mkdir -p /var/spool/rsyslog [root@rsyslogserver ~]# cat >/etc/rsyslog.d/10-receiver-10514.conf <<'EOF' > # ===== rsyslog receiver on 10514 (plain TCP via stunnel) ===== > module(load="imtcp") # 若提示已加载,注释掉也可 > $WorkDirectory /var/spool/rsyslog > > # 动态落盘:/var/log/remote/<源IP>/<程序名>/YYYY-MM-DD.log > template(name="PerHostPerProgram" type="string" > string="/var/log/remote/%hostname%/%programname%/%$year%-%$month%-%$day%.log") > > # 规则集:写入模板文件 > ruleset(name="remote"){ > action(type="omfile" DynaFile="PerHostPerProgram" createDirs="on" > dirCreateMode="0750" fileCreateMode="0640") > } > > # 绑定规则集并监听 10514 > input(type="imtcp" port="10514" ruleset="remote") > EOF
9.语法校验和重启
-N1 只做语法检查,不真正启动,能在变更前发现错误;重启/查看状态确认生效。生产建议配合 systemd 的 Restart=on-failure。
[root@rsyslogserver ~]# rsyslogd -N1 [root@rsyslogserver ~]# systemctl restart rsyslog [root@rsyslogserver ~]# systemctl status rsyslog
10.准备运行用户与目录
创建受限用户运行 stunnel、独立日志与运行目录,减少权限面与入侵面。
[root@rsyslogserver ~]# getent group stunnel >/dev/null || groupadd -r stunnel [root@rsyslogserver ~]# getent passwd stunnel >/dev/null || useradd -r -g stunnel -s /sbin/nologin -M stunnel [root@rsyslogserver ~]# mkdir -p /var/log/stunnel /run/stunnel [root@rsyslogserver ~]# chown -R stunnel:stunnel /var/log/stunnel /run/stunnel
11.服务端stunnel配置
accept 6514:标准 syslog over TLS 端口。
connect 10514:解密后把明文仅发到本机 rsyslog TCP 输入(更安全)。
verify=2:启用双向证书链校验(推荐最低强度)。
setuid/setgid:降权运行。
debug/output:问题排查很关键。
提醒:若要更强校验主机名,结合 stunnel 版本支持配置 checkHost/verify=3。
[root@rsyslogserver ~]# vim /etc/stunnel/stunnel.conf [root@rsyslogserver ~]# cat /etc/stunnel/stunnel.conf ; ===== stunnel server for syslog over TLS ===== ; 建议先不降权,跑通再说;如要降权,取消下面两行注释并确保目录权限 setuid = stunnel setgid = stunnel debug = 4 output = /var/log/stunnel/rsyslog.log cert = /etc/rsyslog-tls/server.pem CAfile = /etc/rsyslog-tls/ca.crt verify = 2 ; verify 取值: ; 0=不校验;1=仅存在;2=验证证书链(常用);3=额外主机名校验(新版本支持 checkHost 时更稳) sslVersion = TLSv1.2 [syslog-tls] accept = 0.0.0.0:6514 connect = 127.0.0.1:10514
12.启用
确保 stunnel 隧道在线,日志才能“加密进/明文出”。
[root@rsyslogserver ~]# systemctl enable --now stunnel [root@rsyslogserver ~]# systemctl status stunnel
13.查看监听端口
[root@rsyslogserver ~]# journalctl -u stunnel -e | tail -n 50 [root@rsyslogserver ~]# ss -lntp | grep -E ':6514|:10514'
14.放行防火墙
若未放行,客户端将超时或拒绝连接。生产环境可加源地址白名单与限速。
[root@rsyslogserver ~]# firewall-cmd --permanent --add-port=6514/tcp [root@rsyslogserver ~]# firewall-cmd --reload
二、客户端
1.查看系统信息
[root@rsyslogclient ~]# cat /etc/os-release [root@rsyslogclient ~]# uname -a
2.更新系统源
[root@rsyslogclient ~]# dnf update
3.安装软件
[root@rsyslogclient ~]# dnf -y install rsyslog stunnel openssl policycoreutils-python-utils
4.启动rsyslog
[root@rsyslogclient ~]# systemctl enable --now rsyslog
5.客户端stunnel配置
client = yes:以客户端角色发起 TLS。
accept 127.0.0.1:10514:本机 rsyslog 仍按“明文 TCP”写到这里。
connect server:6514:由 stunnel 负责加密后送往服务端。
CAfile + verify=2:校验服务端证书链;cert/key 是本机身份供服务端校验(双向认证)。
chmod 600:保护私钥。
好处:无需改业务程序,只要 rsyslog 能往 127.0.0.1:10514 发即可。
[root@rsyslogclient ~]# mkdir -p /etc/rsyslog-tls /var/log/stunnel [root@rsyslogclient ~]# vim /etc/stunnel/stunnel.conf [root@rsyslogclient ~]# cat /etc/stunnel/stunnel.conf ; ===== stunnel client for syslog over TLS ===== debug = 7 output = /var/log/stunnel/rsyslog-client.log CAfile = /etc/rsyslog-tls/ca.crt verify = 2 sslVersion = TLSv1.2 [syslog-tls] client = yes accept = 127.0.0.1:10514 connect = 192.168.80.111:6514 ; >>> 把客户端证书放到服务段里(关键) <<< cert = /etc/rsyslog-tls/client.crt key = /etc/rsyslog-tls/client.key [root@rsyslogclient ~]# chmod 600 /etc/rsyslog-tls/client.key
6.启动stunnel
[root@rsyslogclient ~]# systemctl enable --now stunnel [root@rsyslogclient ~]# systemctl status stunnel
7.查看stunnel日志
[root@rsyslogclient ~]# journalctl -u stunnel -e | tail -n 50
8.查看监听端口
[root@rsyslogclient ~]# ss -lntp | grep 10514
9.客户端rsyslog配置
.:转发所有级别/所有 facility。
@@:TCP(单个 @ 是 UDP),保证可靠传输。
$ActionResumeRetryCount -1:网络抖动时无限重试,降低日志丢失概率。
$LocalHostName:显式指定来源主机名(否则可能是 FQDN 或别名)。
结果:rsyslog → 127.0.0.1:10514(明文)→ stunnel(TLS)→ 服务端。
[root@rsyslogclient ~]# cat >/etc/rsyslog.d/90-forward-to-local.conf <<'EOF' > # ===== forward all logs to local stunnel on 10514 (TCP) ===== > $PreserveFQDN off > $LocalHostName 192.168.80.112 > $ActionResumeRetryCount -1 > *.* @@127.0.0.1:10514 > EOF [root@rsyslogclient ~]# rsyslogd -N1 [root@rsyslogclient ~]# systemctl restart rsyslog [root@rsyslogclient ~]# systemctl status rsyslog
三、全链路检查
1.服务端
确认 stunnel/rsyslog 都在监听且无异常。发生握手/证书问题会在 stunnel 日志里有清晰报错。
[root@rsyslogserver ~]# ss -lntp | grep -E ':6514|:10514' [root@rsyslogserver ~]# journalctl -u stunnel -e | tail -n 50 [root@rsyslogserver ~]# journalctl -u rsyslog -e | tail -n 50
2.客户端
制造一条可定位的测试日志。
[root@rsyslogclient ~]# logger -t TEST "check from $(hostname -f) at $(date)"
3.服务端查看是否按模板落盘
确认已按“主机/程序/日期”写入,并能实时看到 TEST 关键字。若没有落盘,多半是 stunnel/防火墙/证书链/模板权限问题。
[root@rsyslogserver ~]# find /var/log/remote -type f -name "$(date +%F).log" -print [root@rsyslogserver ~]# tail -F /var/log/remote/*/*/$(date +%F).log
四、服务端配置日志轮转
daily + rotate 14 + compress:按日滚动,保留 14 天并压缩。
postrotate HUP:发送 HUP 让 rsyslog 重新打开文件句柄,避免“切了文件却仍写旧文件”的问题。
0640 与 adm 组:限制访问,符合最小权限。
[root@rsyslogserver ~]# cat >/etc/logrotate.d/rsyslog-remote <<'EOF' > /var/log/remote/*/*/*.log { > daily > rotate 14 > compress > delaycompress > missingok > notifempty > create 0640 root adm > sharedscripts > postrotate > systemctl kill -s HUP rsyslog.service >/dev/null 2>&1 || true > endscript > } > EOF
五、生产加固与最佳实践(强烈建议)
更强校验:结合 stunnel 版本使用 verify=3/checkHost=rsyslogserver.pdsyw.cn 等参数,严格校验主机名。
证书生命周期:用到期提醒+灰度更新(先发新证书、双配置平滑切换)。
最小暴露面:服务端 6514 仅对必要网段放行,优先专线/VPN。
SELinux:默认可运行;若自定义端口/目录,务必用 semanage 正确标注类型与端口布尔值。
监控与告警:监控 stunnel/rsyslog 进程、端口、证书到期、落盘量与磁盘水位。
六、常见坑位速查
scp 报 “Not a directory”:先在客户端 mkdir -p /etc/rsyslog-tls 再 scp 到该目录。
verify 失败:检查 client/server 证书是否由同一CA签发,系统时钟是否正确,CN/主机名是否匹配策略。
看不到落盘:服务端 ss -lntp | grep 6514/10514、journalctl -u stunnel/rsyslog;客户端确认 @@127.0.0.1:10514,以及 stunnel 日志是否握手成功。
权限问题:server.key/client.key 均应 600;rsyslog 创建的目录/文件权限由模板里的 *_Mode 控制。
防火墙:忘记放行 6514,或中间有 ACL/安全组拦截。
结语
到这里,你已经完成了一个可生产落地的“Rsyslog + stunnel + TLS”方案:双向证书认证确保只有被信任的客户端才能接入,动态落盘模板让日志结构化存储更清晰,logrotate 保证磁盘可控。后续可以无缝接入 ELK / Loki 做检索与可视化,进一步释放日志的价值。