最小权限原则:仅授予Node.js应用运行所需的最低权限,避免过度开放(如禁止使用777权限);用户隔离:使用专用用户(如nodeapp)运行应用,避免以root身份运行;目录结构规范:建议将日志存放在/var/log/[appname]/目录下,便于集中管理。
# 创建用户组
sudo groupadd nodeapp
# 创建专用用户(无登录权限,shell设为/bin/false)
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
在Node.js应用中,通过fs.createWriteStream明确指定日志文件的权限(0o640表示所有者可读写,组可读,其他用户无权限):
const fs = require('fs');
const logStream = fs.createWriteStream('/var/log/my-node-app/app.log', {
flags: 'a', // 追加模式
mode: 0o640 // 关键权限设置
});
若用PM2管理应用,启动时需指定专用用户/组,并修复PM2自身目录权限:
# 启动应用时绑定用户/组
pm2 start app.js --uid nodeapp --gid nodeapp
# 设置PM2日志目录权限(确保PM2能写入)
sudo chown -R nodeapp:nodeapp /home/nodeapp/.pm2
使用logrotate工具自动分割、压缩旧日志,配置文件存放在/etc/logrotate.d/下(以my-node-app为例):
# 创建logrotate配置文件
sudo vim /etc/logrotate.d/my-node-app
配置内容如下(每日轮转、保留14天、压缩旧日志、通知应用重新打开文件):
/var/log/my-node-app/*.log {
daily # 每日轮转
missingok # 忽略缺失文件
rotate 14 # 保留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
}
若应用无法写入日志目录,可使用setfacl添加ACL权限(无需修改原有权限结构):
sudo setfacl -R -m u:nodeapp:rwx /var/log/my-node-app # 授予用户读写执行权限
若系统启用SELinux,需调整日志目录的上下文(以httpd_log_t为例):
# 添加SELinux上下文规则
sudo semanage fcontext -a -t httpd_log_t "/var/log/my-node-app(/.*)?"
# 应用上下文到现有目录
sudo restorecon -Rv /var/log/my-node-app
600);winston(支持多传输、格式化)、pino(高性能)或bunyan(结构化JSON),提升日志管理能力;auditd等工具监控日志文件的访问与修改,及时发现异常操作。