1. 选择安全可靠的日志库
优先使用成熟、社区支持良好的日志库(如Winston、Bunyan、Pino),这些库提供丰富的安全特性(如日志级别控制、格式化输出、传输加密)。例如,Winston支持多传输方式(文件、控制台、数据库),可通过配置限制日志输出目标;Bunyan以JSON格式输出日志,便于后续结构化分析;Pino则以高性能著称,适合大型应用。
2. 严格控制日志文件访问权限
遵循“最小权限原则”,为日志文件和目录设置严格的权限:
/var/log/[appname]
),避免与应用程序文件混放;nodeapp
)和组(如nodeapp
),运行Node.js应用;750
(所有者可读写执行,组可读执行,其他用户无权限),日志文件权限为640
(所有者可读写,组可读,其他用户无权限)。sudo groupadd nodeapp
sudo useradd -g nodeapp nodeapp -s /bin/false
sudo mkdir -p /var/log/my-node-app
sudo chown nodeapp:nodeapp /var/log/my-node-app
sudo chmod 750 /var/log/my-node-app
若使用PM2管理应用,需通过--uid
和--gid
参数指定运行用户/组:pm2 start app.js --uid nodeapp --gid nodeapp
。
3. 敏感信息过滤与脱敏
避免在日志中记录敏感数据(如密码、API密钥、个人身份信息(PII)),可通过以下方式实现:
redactyl.js
)移除敏感字段。例如,Winston可通过自定义格式化函数替换密码:const winston = require('winston');
const logger = winston.createLogger({
format: winston.format.combine(
winston.format.timestamp(),
winston.format.json(),
winston.format((info) => {
if (info.message && info.message.includes('password')) {
info.message = info.message.replace(/password=\w+/g, 'password=******');
}
return info;
})()
),
transports: [new winston.transports.File({ filename: 'logs/app.log' })]
});
redactyl.js
支持正则表达式、嵌套对象处理,可自动识别并脱敏敏感属性(如apiKey
、phone
)。4. 实施日志轮转与归档策略
防止日志文件过大占用磁盘空间,同时控制敏感信息的存储时间:
logrotate
工具自动轮转日志(按日期或大小),设置保留期限(如14天)和压缩(如gzip)。例如,创建/etc/logrotate.d/my-node-app
配置文件:/var/log/my-node-app/*.log {
daily
missingok
rotate 14
compress
delaycompress
notifempty
create 640 nodeapp nodeapp
sharedscripts
postrotate
[ ! -f /var/run/my-node-app.pid ] || kill -USR1 `cat /var/run/my-node-app.pid`
endscript
}
5. 集中式日志管理与监控
将日志发送到集中式日志管理系统(如ELK Stack、Graylog、Datadog),实现统一存储、分析和实时监控:
6. 强化系统与应用层安全配置
npm audit
检查依赖库漏洞);ufw
)限制对日志文件的访问(仅允许可信IP),使用SSH密钥认证代替密码认证;sudo aa-status
,并根据需要调整配置文件。7. 日志传输安全
若日志需要通过网络传输(如发送到远程日志服务器),使用加密协议(如TLS/SSL)保护数据传输过程: