Debian服务器上应用日志的留存,很多运维人员一开始只关注“能存下来”,但真正出问题的时候才发现,要么日志被轮转提前删了,要么关键字段被截断,要么应用自己把日志写到不可控的目录。日志安全留存的核心不是开一个rsyslog就完事,而是要把应用日志的写入路径、轮转策略、权限隔离、防篡改和审计追溯串成一条线。下面直接说具体做法。

先确认应用日志到底写到了哪里

Debian环境下,不同应用写日志的习惯差别很大。Nginx、Apache默认走/var/log下的独立目录,PHP-FPM慢日志和错误日志可能在/var/log/php*或者池配置里指定的路径,Java应用经常用log4j2或logback输出到自定义目录,Node.js和Python服务则可能直接打到systemd journal或者容器标准输出。你首先要做的是把所有应用的日志路径、格式、轮转方式摸清楚。不要假设它们都遵守系统默认规则。很多安全事件追溯失败,就是因为应用把日志写到了/tmp或者随代码发布目录,重启或发布时被清空。

建议在Debian上统一日志目录规范,例如/var/log/app/<应用名>/,每个应用一个子目录。这样后续做权限和备份策略会简单很多。对于已经在跑的应用,不要直接改路径,先确认配置文件里日志路径的定义位置,再逐步迁移。

用logrotate做基础轮转但不要只依赖默认配置

Debian自带的logrotate默认每周轮转一次、保留4周,这对安全审计来说往往不够。应用日志如果涉及登录、支付、权限变更、接口调用,建议至少保留6个月,有合规要求的保留1年以上。直接在/etc/logrotate.d/下为应用单独建配置文件,不要修改系统全局配置。

/var/log/app/myapp/*.log {
    daily
    rotate 180
    compress
    delaycompress
    missingok
    notifempty
    create 640 myapp adm
    sharedscripts
    postrotate
        systemctl reload myapp > /dev/null 2>&1 || true
    endscript
}

这里有几个关键点:daily配合rotate 180可以保留半年,compress节省空间,delaycompress让前一天日志还能被直接读取,create 640 myapp adm确保新日志文件权限不会变成默认的644。postrotate里的reload很重要,很多应用如果不重新打开文件句柄,轮转后会继续写旧文件,导致日志丢失。

应用日志的写入权限要收紧

Debian上很多应用以独立系统用户运行,例如www-data跑Nginx和PHP,Java应用可能用专门的app用户。日志目录的属主和权限要严格控制。不要让应用以root写日志,也不要让日志目录对其他用户可读。常见错误是把日志目录设成755,文件设成644,这样服务器上任何一个普通用户都能读取日志,里面可能有会话token、用户手机号、内部接口地址等敏感信息。

正确做法是:日志目录属主为应用运行用户,属组为专门的日志组,例如adm或新建一个logread组。目录权限750,文件权限640。需要读日志的运维人员加入logread组,而不是直接给sudo。这样即使应用本身被攻破,攻击者也只能写自己的日志,无法读取其他应用的日志,也无法修改历史日志文件。

防止应用自身篡改或删除日志

应用运行用户对日志目录有写权限,意味着一旦应用被入侵,攻击者可以清空日志。要缓解这个问题,Debian上可以用文件系统属性配合日志集中转发。chattr +a可以让文件只能追加不能删除或覆盖,但应用轮转时会受影响,所以一般只对归档后的日志做这个操作。更实用的方案是让应用日志同时输出到本地文件和远程日志服务器。rsyslog可以读取本地文件并转发,但要注意应用日志格式多样,直接转发原始文件比解析后转发更可靠。

# /etc/rsyslog.d/30-app-forward.conf
module(load="imfile" PollingInterval="10")

input(type="imfile"
      File="/var/log/app/myapp/app.log"
      Tag="myapp-app"
      Severity="info"
      Facility="local0")

*.* @@remote-log-server:514

这里用imfile模块监控应用日志文件,通过TCP转发到远程日志服务器。远程服务器上再做集中存储和备份。这样即使本地日志被删除,远程还有一份。要注意的是,imfile对日志轮转敏感,logrotate的postrotate里需要给rsyslog发HUP信号,或者使用copytruncate方式轮转。不过copytruncate会截断文件,极端情况下可能丢几行日志,对安全审计来说不如create加reload可靠。

时间同步是日志留存的前提

Debian服务器如果时间不准,日志留存再多也没有意义。安全事件追溯时,不同服务器日志时间对不上,根本无法还原攻击路径。务必配置chrony或systemd-timesyncd,强制与内部NTP服务器同步。在/etc/chrony/chrony.conf里配置多个时间源,并开启步进调整。同时检查应用日志时间格式,统一使用ISO 8601带时区格式,避免只输出时分秒没有日期,或者日期格式混乱。

日志内容本身要满足审计要求

留存日志不只是存文件,日志内容必须能回答“谁在什么时间从哪个IP做了什么操作,结果如何”。很多应用默认日志级别是INFO,但关键操作没有记录,或者记录了但字段不全。对于Web应用,至少要在访问日志里记录客户端真实IP、请求方法、URI、状态码、响应时间、User-Agent、Referer。对于业务日志,要记录用户ID、操作类型、操作对象、操作结果。如果应用日志做不到,可以在Nginx层补充访问日志,在应用层增加审计日志输出。

Debian上Nginx的日志格式可以自定义,建议在/etc/nginx/nginx.conf里定义完整的log_format,包含请求耗时和上游响应时间。这样排障和安全分析都能用。

log_format security '$remote_addr - $remote_user [$time_local] '
                    '"$request" $status $body_bytes_sent '
                    '"$http_referer" "$http_user_agent" '
                    'rt=$request_time uct="$upstream_connect_time" '
                    'uht="$upstream_header_time" urt="$upstream_response_time"';

然后在server块里用access_log /var/log/nginx/site_access.log security; 这样每条日志都有完整的访问上下文。

日志留存要配合备份和归档策略

轮转只是把日志从活跃文件变成压缩归档,但归档文件仍然在本地磁盘上。如果磁盘故障或者服务器被入侵,本地归档也可能丢失。Debian服务器应该定期把归档日志同步到独立的备份存储,可以用rsync、scp或者对象存储工具。对于安全日志,建议每天同步一次,保留多个版本。同步时用校验和验证完整性,避免传输过程中损坏。

一个简单的做法是用cron每天凌晨执行rsync,把/var/log/app/下的归档文件同步到备份服务器。注意同步时排除正在写入的活跃日志文件,只同步已经轮转压缩的.gz文件。这样不会因为文件正在写入导致同步不完整。

#!/bin/bash
# /etc/cron.daily/app-log-backup
rsync -av --checksum --include='*.gz' --exclude='*' \
  /var/log/app/ backup-server:/backup/logs/$(hostname)/

如果日志量很大,可以考虑按应用和日期分目录存储,方便后续按时间范围检索和恢复。

监控日志留存状态

日志留存策略配置好之后,还要监控它是否真的在按预期工作。常见的故障包括:logrotate配置错误导致日志没有轮转,磁盘写满导致应用停止写日志,远程转发中断导致本地日志堆积,应用升级后日志路径变化导致imfile监控失效。Debian上可以用简单的脚本检查关键日志文件的大小和修改时间,如果超过阈值就告警。也可以监控磁盘使用率,给/var/log单独分区,避免日志写满影响系统运行。

建议给/var/log单独挂载分区,并设置合理的容量。如果应用日志量特别大,可以考虑把/var/log/app单独挂载到更大的磁盘。磁盘使用率达到80%就告警,90%就强制清理最老的归档日志,同时通知运维排查。

最后强调几个容易忽略的点

第一,应用日志里不要记录明文密码、身份证号、银行卡号、完整手机号等敏感信息。如果业务需要,做脱敏后再写日志。第二,日志文件本身要防篡改,除了远程转发,还可以定期对归档日志计算哈希值并保存到只读位置。第三,Debian系统日志和应用日志要分开管理,不要混在同一个文件里。第四,容器化应用如果跑在Debian宿主机上,容器日志要映射到宿主机目录并纳入同样的留存策略,不要只存在容器可写层里。第五,定期做日志恢复演练,确认备份的日志真的能解压、能检索、能用于分析,而不是等到出事才发现备份文件损坏。

日志安全留存不是一次性配置,而是需要持续维护的工程。把路径、权限、轮转、转发、备份、监控这六个环节都做实,Debian服务器上的应用日志才能真正在安全事件发生时发挥作用。