在Ubuntu服务器的日常运维中,系统日志是排查故障、审计安全事件和监控系统健康度的核心依据。但单机存储日志风险极高,一旦磁盘损坏或服务器被入侵,日志被清理,所有线索都会消失。更严峻的挑战在于,多台服务器分散管理时,逐一登录查看日志效率低下。因此,将日志实时、可靠地转发到中央日志服务器是基础设施安全化的关键一步。仅仅转发还不够,如果日志在公网或内部非信任链路上以明文传输,等于将系统弱点、用户行为和潜在漏洞暴露给嗅探者。解决这个问题的标准方案是结合rsyslog的可靠转发与基于TLS的加密传输,确保日志数据在离开服务器的瞬间就被保护,直到安全抵达集中存储节点。
环境准备与核心组件选型我们选用的技术栈非常明确:Ubuntu 20.04或22.04作为操作系统,rsyslog作为日志守护进程,因为它默认集成在系统中,性能开销极低且原生支持TLS加密。中央日志服务器同样运行Ubuntu和rsyslog,但需要额外安装证书管理工具。客户端与服务器端的rsyslog版本需保持一致或兼容,避免协议协商失败。整个架构中,客户端作为TLS连接的发起方,服务器端作为接收方,证书验证机制确保客户端不会将日志发送到伪造的采集节点。
首先在所有机器上确认rsyslog和必要依赖已安装。通常Ubuntu最小化安装已包含rsyslog,但TLS支持需要额外软件包。在服务器端和客户端分别执行:
sudo apt update sudo apt install rsyslog rsyslog-gnutls gnutls-bin
rsyslog-gnutls提供了基于GnuTLS库的加密网络流模块,这是实现TLS传输的基础。如果系统提示已安装,则检查版本是否支持TLS:
rsyslogd -v | grep -i gnutls
输出中包含gnutls字样即表示支持。接下来需要规划网络拓扑,假设中央日志服务器IP为192.168.10.100,客户端为192.168.10.101,所有通信走TCP 6514端口,这是IANA分配给syslog over TLS的标准端口,避免与明文syslog的514端口混淆。
构建内部CA并签发证书加密传输的基石是证书体系。在生产环境中,建议使用内部CA签发证书,而非自签名证书,因为自签名证书在证书轮换和信任链管理上会带来麻烦。我们将在中央日志服务器上搭建一个轻量级CA,然后为服务器和客户端分别签发证书。
在日志服务器上创建CA目录结构:
mkdir -p /etc/rsyslog-ca/certs mkdir -p /etc/rsyslog-ca/private chmod 700 /etc/rsyslog-ca/private
生成CA私钥和根证书。这里使用椭圆曲线算法secp384r1,兼顾安全性与性能:
certtool --generate-privkey --outfile /etc/rsyslog-ca/private/ca.key --ecc --curve secp384r1
创建CA模板文件/etc/rsyslog-ca/ca_template.cfg,内容如下:
organization = "Internal Logging Infrastructure" country = CN cn = "Logging CA" ca cert_signing_key expiration_days = 3650
自签CA证书:
certtool --generate-self-signed --load-privkey /etc/rsyslog-ca/private/ca.key --template /etc/rsyslog-ca/ca_template.cfg --outfile /etc/rsyslog-ca/certs/ca.pem
现在为日志服务器本身签发服务端证书。生成服务器私钥:
certtool --generate-privkey --outfile /etc/rsyslog-ca/private/server.key --ecc --curve secp384r1
创建服务器证书模板/etc/rsyslog-ca/server_template.cfg:
organization = "Internal Logging Infrastructure" country = CN cn = "192.168.10.100" dns_name = "logserver.internal" ip_address = "192.168.10.100" tls_www_server encryption_key signing_key expiration_days = 365
注意cn字段和ip_address必须与客户端连接时使用的地址匹配,否则TLS握手会因主机名验证失败而中断。签发服务器证书:
certtool --generate-certificate --load-privkey /etc/rsyslog-ca/private/server.key --load-ca-certificate /etc/rsyslog-ca/certs/ca.pem --load-ca-privkey /etc/rsyslog-ca/private/ca.key --template /etc/rsyslog-ca/server_template.cfg --outfile /etc/rsyslog-ca/certs/server.pem
客户端证书签发流程类似。在日志服务器上生成客户端私钥和证书(也可以在各客户端本地生成私钥后发送CSR到CA签发,这里为简化操作统一在CA上生成后安全分发):
certtool --generate-privkey --outfile /etc/rsyslog-ca/private/client101.key --ecc --curve secp384r1
客户端证书模板/etc/rsyslog-ca/client_template.cfg:
organization = "Internal Logging Infrastructure" country = CN cn = "client-101" tls_www_client encryption_key signing_key expiration_days = 365
签发客户端证书:
certtool --generate-certificate --load-privkey /etc/rsyslog-ca/private/client101.key --load-ca-certificate /etc/rsyslog-ca/certs/ca.pem --load-ca-privkey /etc/rsyslog-ca/private/ca.key --template /etc/rsyslog-ca/client_template.cfg --outfile /etc/rsyslog-ca/certs/client101.pem
最后将CA根证书、客户端私钥和客户端证书安全地复制到客户端服务器/etc/rsyslog-ca/对应目录下,权限设置为600,所有者为root。传输过程可使用scp或带外管理通道,绝不能在未加密的信道上传输私钥。
配置中央日志服务器接收加密日志服务器端的rsyslog需要监听6514端口,加载证书并强制要求客户端提供有效证书进行双向TLS认证。双向认证虽然配置稍复杂,但能防止未授权设备向日志服务器投毒或灌入伪造日志。
编辑/etc/rsyslog.conf或创建独立配置文件/etc/rsyslog.d/00-tls-server.conf:
# 加载TCP和TLS模块
module(load="imtcp")
module(load="mmutf8fix")
# 全局TLS配置
global(
DefaultNetstreamDriver="gtls"
DefaultNetstreamDriverCAFile="/etc/rsyslog-ca/certs/ca.pem"
DefaultNetstreamDriverCertFile="/etc/rsyslog-ca/certs/server.pem"
DefaultNetstreamDriverKeyFile="/etc/rsyslog-ca/private/server.key"
)
# 定义TLS监听规则
input(
type="imtcp"
port="6514"
StreamDriver.Name="gtls"
StreamDriver.Mode="1"
StreamDriver.Authmode="x509/name"
StreamDriver.PermittedPeer=["client-101"]
)
关键参数解读:StreamDriver.Mode="1"表示启用TLS;Authmode="x509/name"强制验证客户端证书并检查证书中的cn字段;PermittedPeer列表精确指定了允许连接的客户端证书cn,不在列表中的客户端即使持有CA签发的证书也会被拒绝。这种白名单机制极大增强了安全性。如果客户端数量较多,可使用通配符或改用anon验证模式,但生产环境强烈建议维持严格的白名单。
接下来定义接收到的日志存储位置。在/etc/rsyslog.d/01-remote-log-storage.conf中配置模板:
template(
name="RemoteLogs"
type="string"
string="/var/log/remote/%HOSTNAME%/%$YEAR%-%$MONTH%-%$DAY%.log"
)
if $fromhost-ip != '127.0.0.1' then {
action(
type="omfile"
dynaFile="RemoteLogs"
fileCreateMode="0640"
dirCreateMode="0750"
dirOwner="syslog"
dirGroup="adm"
)
stop
}
这段配置将来自非本机的日志按主机名和日期分层存储,便于后续检索和轮转。重启rsyslog服务使配置生效:
sudo systemctl restart rsyslog sudo systemctl status rsyslog
检查6514端口是否处于监听状态:
ss -tlnp | grep 6514
同时查看/var/log/syslog中是否有rsyslog的TLS相关错误,常见问题包括证书路径错误、私钥权限过大(必须为400或600)或证书链不完整。
客户端配置与可靠转发策略客户端配置的核心是让rsyslog将所有本地日志通过加密通道发送到中央服务器,同时在网络中断时缓存日志到磁盘队列,确保不丢失任何事件。这种可靠转发能力是rsyslog相比简单syslog协议的一大优势。
在客户端创建/etc/rsyslog.d/00-tls-client.conf:
# 加载模块
module(load="imuxsock")
module(load="imklog")
module(load="omfwd")
# 全局TLS配置
global(
DefaultNetstreamDriver="gtls"
DefaultNetstreamDriverCAFile="/etc/rsyslog-ca/certs/ca.pem"
DefaultNetstreamDriverCertFile="/etc/rsyslog-ca/certs/client101.pem"
DefaultNetstreamDriverKeyFile="/etc/rsyslog-ca/private/client101.key"
)
# 定义转发目标并启用磁盘辅助队列
action(
type="omfwd"
target="192.168.10.100"
port="6514"
protocol="tcp"
StreamDriver.Name="gtls"
StreamDriver.Mode="1"
StreamDriver.Authmode="x509/name"
StreamDriver.PermittedPeer=["192.168.10.100"]
queue.filename="fwdToLogServer"
queue.type="LinkedList"
queue.size="50000"
queue.maxDiskSpace="2g"
queue.saveOnShutdown="on"
queue.maxFileSize="100m"
queue.dequeueBatchSize="300"
action.resumeRetryCount="-1"
action.resumeInterval="10"
)
这段配置的深层逻辑在于磁盘辅助队列的设计。当中央日志服务器不可达时,rsyslog会将日志序列化到/var/spool/rsyslog目录下的队列文件中,队列类型LinkedList适合高吞吐场景,内存队列大小50000条,磁盘空间上限2GB。action.resumeRetryCount="-1"表示无限重试,action.resumeInterval="10"表示每10秒尝试重新连接。这种设计确保了在网络分区或服务器维护期间,日志不会因内存缓冲区溢出而丢失。
客户端还需要确保本地日志被正确捕获并转发。默认情况下,/etc/rsyslog.conf中的ruleset会将日志写入本地文件并同时由omfwd模块处理。检查主配置文件,确认包含典型的系统日志输入:
input(type="imuxsock" socket="/dev/log") input(type="imklog")
以及将日志传递到转发动作的规则。如果使用了自定义ruleset,务必在ruleset中调用转发动作或将转发动作绑定到默认ruleset。重启客户端rsyslog后,观察/var/log/syslog中是否出现连接成功的消息,例如“TLS connection established”或类似信息。同时在服务器端检查/var/log/remote/目录下是否开始生成以客户端主机名命名的子目录和日志文件。
验证加密传输与安全加固配置完成后,必须验证日志在网络上确实以加密形式传输。在客户端或中间网络设备上使用tcpdump抓包分析:
sudo tcpdump -i eth0 -nn port 6514 -X -c 20
输出内容应为乱码或不可读的加密数据,而非明文的日志文本。如果能看到syslog格式的明文消息,说明TLS未生效,需立即排查配置。同时使用openssl s_client工具测试TLS握手:
openssl s_client -connect 192.168.10.100:6514 -cert /etc/rsyslog-ca/certs/client101.pem -key /etc/rsyslog-ca/private/client101.key -CAfile /etc/rsyslog-ca/certs/ca.pem
成功握手会显示证书链信息和协议版本,确认协商的加密套件为TLS1.3或至少TLS1.2,禁用任何老旧协议版本。
安全加固方面,务必在rsyslog配置中显式禁用SSL和早期TLS版本。在global块中添加:
global(
DefaultNetstreamDriver="gtls"
DefaultNetstreamDriverCAFile="/etc/rsyslog-ca/certs/ca.pem"
DefaultNetstreamDriverCertFile="/etc/rsyslog-ca/certs/server.pem"
DefaultNetstreamDriverKeyFile="/etc/rsyslog-ca/private/server.key"
GnuTLSPriorityString="NORMAL:-VERS-SSL3.0:-VERS-TLS1.0:-VERS-TLS1.1:+VERS-TLS1.2:+VERS-TLS1.3"
)
GnuTLSPriorityString参数精确控制了允许的协议版本,禁用了所有已知不安全的版本。此外,定期轮换证书,设置合理的证书有效期(服务端和客户端证书不超过一年),并建立证书过期监控告警,防止因证书过期导致日志采集中断。
性能调优与故障排查在高日志量场景下,每秒可能有数千条日志产生。rsyslog的默认配置可能成为瓶颈。针对加密转发场景,可调整以下参数:将omfwd的dequeueBatchSize从默认的16增加到300甚至1000,减少磁盘I/O次数;使用impstats模块监控rsyslog内部队列状态,及时发现队列堆积;在服务器端使用多个工作线程处理入站连接:
input(
type="imtcp"
port="6514"
StreamDriver.Name="gtls"
StreamDriver.Mode="1"
StreamDriver.Authmode="x509/name"
StreamDriver.PermittedPeer=["client-101"]
threads="4"
)
故障排查时,首先确认网络连通性和防火墙规则,6514端口必须在两端放行。其次检查证书有效期:
certtool --certificate-info --infile /etc/rsyslog-ca/certs/server.pem | grep -i "not after"
时间同步也是关键,TLS证书验证依赖准确的时间戳,所有服务器应配置NTP服务,时间偏差超过几分钟就可能导致证书验证失败。最后,rsyslog的调试模式是定位问题的终极手段,可临时在前台运行并输出详细日志:
sudo rsyslogd -dn
调试输出会完整展示TLS握手过程、证书验证细节和队列操作,根据错误信息可快速定位配置错误。
这套方案已经在大量生产环境中验证,能够稳定处理日均数百GB的日志量。通过双向TLS认证、磁盘辅助队列和严格的访问控制,Ubuntu服务器日志远程转发不仅解决了集中管理问题,更构建了一条端到端的可信日志通道,为后续的安全审计、合规检查和实时告警打下了坚实基础。
