第17章 审计与日志管理¶
审计与日志管理是服务器运维的重要组成部分。合理的日志配置既能帮助诊断问题,又能保护用户隐私。
17.1 访问日志配置¶
17.1.1 为什么需要日志¶
日志的作用:
1. 故障诊断
- 连接失败原因
- 性能问题分析
- 错误追踪
2. 安全监控
- 异常访问检测
- 攻击识别
- 入侵发现
3. 流量统计
- 使用量分析
- 用户行为
- 资源规划
4. 合规要求
- 某些场景需要
- 审计需求
日志的风险:
17.1.2 V2Ray/Xray日志配置¶
基础日志配置:
{
"log": {
"loglevel": "warning",
"access": "/var/log/v2ray/access.log",
"error": "/var/log/v2ray/error.log"
}
}
日志级别说明:
none:
- 不记录任何日志
- 最佳隐私保护
- 无法诊断问题
error:
- 仅记录错误
- 推荐用于生产环境
- 隐私风险低
warning:
- 记录警告和错误
- 适度平衡
- 一般推荐
info:
- 记录详细信息
- 包含连接信息
- 有隐私风险
debug:
- 最详细日志
- 用于调试
- 隐私风险高
- 不要用于生产
隐私保护配置:
{
"log": {
"loglevel": "error",
"access": "none", // 不记录访问日志
"error": "/var/log/v2ray/error.log"
}
}
仅记录到内存:
17.1.3 Nginx访问日志¶
默认日志格式:
http {
log_format main '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent"';
access_log /var/log/nginx/access.log main;
error_log /var/log/nginx/error.log warn;
}
隐私保护日志格式:
# 匿名化IP地址
log_format privacy '$remote_addr_anonymized - [$time_local] '
'$request_method $status $body_bytes_sent';
# 使用map匿名化IP
map $remote_addr $remote_addr_anonymized {
~(?P<ip>\d+\.\d+\.\d+)\.\d+ $ip.0;
~(?P<ip>[^:]+:[^:]+): $ip::;
default 0.0.0.0;
}
# 应用到server
server {
access_log /var/log/nginx/access.log privacy;
}
禁用特定路径日志:
server {
# 代理路径不记录日志
location /v2ray {
access_log off;
error_log /dev/null;
proxy_pass http://127.0.0.1:10000;
}
# 网站内容正常记录
location / {
access_log /var/log/nginx/web.log;
root /var/www/html;
}
}
17.1.4 日志轮转¶
logrotate配置:
# /etc/logrotate.d/v2ray
/var/log/v2ray/*.log {
daily # 每天轮转
rotate 7 # 保留7天
missingok # 文件不存在不报错
notifempty # 空文件不轮转
compress # 压缩旧日志
delaycompress # 延迟压缩
sharedscripts
postrotate
systemctl reload v2ray > /dev/null 2>&1 || true
endscript
}
Nginx日志轮转:
# /etc/logrotate.d/nginx
/var/log/nginx/*.log {
daily
rotate 7
missingok
notifempty
compress
delaycompress
sharedscripts
postrotate
[ -f /var/run/nginx.pid ] && kill -USR1 `cat /var/run/nginx.pid`
endscript
}
立即执行轮转:
17.2 流量分析工具¶
17.2.1 实时流量监控¶
vnStat监控:
# 安装vnStat
apt install vnstat -y
# 初始化接口
vnstat -i eth0 --create
# 启动服务
systemctl enable vnstat
systemctl start vnstat
# 查看统计
vnstat # 总览
vnstat -h # 小时统计
vnstat -d # 日统计
vnstat -m # 月统计
vnstat -l # 实时监控
iftop实时监控:
# 安装
apt install iftop -y
# 运行
iftop -i eth0
# 参数说明
# -n 不解析域名
# -N 不解析端口
# -P 显示端口
# -b 以字节显示
# 推荐用法(匿名)
iftop -i eth0 -n -N
nethogs进程监控:
17.2.2 流量统计分析¶
使用X-UI面板:
自定义流量统计脚本:
#!/bin/bash
# traffic_stats.sh
LOG_FILE="/var/log/v2ray/access.log"
OUTPUT="/tmp/traffic_report.txt"
echo "=== V2Ray流量统计 $(date) ===" > $OUTPUT
echo "" >> $OUTPUT
# 统计总连接数
TOTAL=$(grep "accepted" $LOG_FILE | wc -l)
echo "总连接数: $TOTAL" >> $OUTPUT
# 统计唯一IP数
UNIQUE_IPS=$(grep "accepted" $LOG_FILE | awk '{print $4}' | sort -u | wc -l)
echo "唯一IP数: $UNIQUE_IPS" >> $OUTPUT
# 统计Top 10 IP
echo -e "\nTop 10 IP地址:" >> $OUTPUT
grep "accepted" $LOG_FILE | awk '{print $4}' | sort | uniq -c | sort -rn | head -10 >> $OUTPUT
# 发送报告
mail -s "V2Ray流量报告" admin@example.com < $OUTPUT
17.2.3 带宽限制¶
iptables限速:
# 限制单个IP最大速率为10Mbps
iptables -A FORWARD -s 客户端IP -m limit --limit 10mbit/s -j ACCEPT
iptables -A FORWARD -s 客户端IP -j DROP
# 限制端口总带宽
iptables -A OUTPUT -p tcp --sport 443 -m hashlimit \
--hashlimit-above 100mb/s \
--hashlimit-mode srcip \
--hashlimit-name proxy \
-j DROP
tc流量控制:
#!/bin/bash
# 使用tc(Traffic Control)限速
INTERFACE="eth0"
DOWNLOAD_LIMIT="100mbit"
UPLOAD_LIMIT="100mbit"
# 清除现有规则
tc qdisc del dev $INTERFACE root 2>/dev/null
# 添加根队列
tc qdisc add dev $INTERFACE root handle 1: htb default 10
# 添加类(限制总带宽)
tc class add dev $INTERFACE parent 1: classid 1:1 htb rate $UPLOAD_LIMIT
# 添加默认类
tc class add dev $INTERFACE parent 1:1 classid 1:10 htb rate $UPLOAD_LIMIT
echo "带宽限制已设置: 上传 $UPLOAD_LIMIT"
V2Ray用户限速:
{
"policy": {
"levels": {
"0": {
"handshake": 4,
"connIdle": 300,
"uplinkOnly": 2,
"downlinkOnly": 5,
"statsUserUplink": true,
"statsUserDownlink": true,
"bufferSize": 10240
}
}
}
}
17.3 异常检测机制¶
17.3.1 连接异常检测¶
异常连接模式:
检测脚本:
#!/bin/bash
# detect_abnormal.sh
LOG="/var/log/v2ray/access.log"
ALERT_EMAIL="admin@example.com"
# 检查最近1小时连接数
RECENT_CONN=$(grep "$(date -d '1 hour ago' '+%Y/%m/%d %H')" $LOG | wc -l)
if [ $RECENT_CONN -gt 10000 ]; then
echo "警告:最近1小时连接数异常 ($RECENT_CONN)" | \
mail -s "V2Ray异常检测" $ALERT_EMAIL
fi
# 检查单IP连接数
TOP_IP=$(tail -10000 $LOG | awk '{print $4}' | sort | uniq -c | sort -rn | head -1)
IP_COUNT=$(echo $TOP_IP | awk '{print $1}')
IP_ADDR=$(echo $TOP_IP | awk '{print $2}')
if [ $IP_COUNT -gt 1000 ]; then
echo "警告:IP $IP_ADDR 连接数异常 ($IP_COUNT)" | \
mail -s "V2Ray IP异常" $ALERT_EMAIL
fi
# 检查大流量用户
# 需要配合流量统计
17.3.2 攻击检测¶
端口扫描检测:
#!/bin/bash
# detect_portscan.sh
# 使用iptables recent模块检测端口扫描
# 60秒内连接超过10次视为扫描
iptables -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --set
iptables -A INPUT -p tcp --dport 22 -m state --state NEW -m recent \
--update --seconds 60 --hitcount 10 -j DROP
# 记录扫描IP
iptables -A INPUT -p tcp --dport 22 -m state --state NEW -m recent \
--update --seconds 60 --hitcount 10 -j LOG --log-prefix "Port Scan: "
暴力破解检测(Fail2Ban):
# /etc/fail2ban/filter.d/v2ray.conf
[Definition]
failregex = rejected.*from <HOST>
ignoreregex =
# /etc/fail2ban/jail.local
[v2ray]
enabled = true
port = 443
filter = v2ray
logpath = /var/log/v2ray/error.log
maxretry = 5
findtime = 600
bantime = 3600
17.3.3 自动响应机制¶
IP自动封禁:
#!/bin/bash
# auto_block.sh
LOG="/var/log/v2ray/error.log"
BLOCKED_IPS="/etc/v2ray/blocked_ips.txt"
# 查找最近的错误连接IP
grep "rejected" $LOG | tail -100 | awk '{print $NF}' | sort | uniq -c | sort -rn | \
while read count ip; do
if [ $count -gt 10 ]; then
# 检查是否已封禁
if ! grep -q "$ip" $BLOCKED_IPS; then
echo "封禁IP: $ip (失败次数: $count)"
iptables -A INPUT -s $ip -j DROP
echo "$ip" >> $BLOCKED_IPS
fi
fi
done
流量限制自动降级:
#!/bin/bash
# traffic_limit.sh
# 当总流量超过阈值时自动限速
THRESHOLD_GB=900 # 900GB
CURRENT_GB=$(vnstat --oneline | cut -d';' -f11)
if [ $CURRENT_GB -gt $THRESHOLD_GB ]; then
echo "流量接近限额,启用限速"
# 启用tc限速
tc qdisc add dev eth0 root tbf rate 50mbit burst 32kbit latency 400ms
# 发送通知
echo "流量已达 ${CURRENT_GB}GB,已启用限速" | \
mail -s "流量预警" admin@example.com
fi
17.4 日志隐私平衡¶
17.4.1 隐私优先配置¶
极致隐私方案:
适度隐私方案:
{
"log": {
"loglevel": "error", // 仅记录错误
"access": "none", // 不记录访问
"error": "/dev/null" // 错误也不保存
}
}
内存日志方案:
# 日志写入tmpfs(RAM disk)
# 重启后自动清除
# 创建内存目录
mkdir -p /var/log/v2ray-tmp
mount -t tmpfs -o size=50M tmpfs /var/log/v2ray-tmp
# V2Ray配置
{
"log": {
"loglevel": "warning",
"access": "/var/log/v2ray-tmp/access.log",
"error": "/var/log/v2ray-tmp/error.log"
}
}
# /etc/fstab自动挂载
tmpfs /var/log/v2ray-tmp tmpfs size=50M 0 0
17.4.2 数据匿名化¶
IP地址匿名化:
#!/usr/bin/env python3
# anonymize_log.py
import re
import sys
def anonymize_ip(ip):
"""将IP地址最后一段替换为0"""
if ':' in ip: # IPv6
parts = ip.split(':')
return ':'.join(parts[:-1] + ['0'])
else: # IPv4
parts = ip.split('.')
return '.'.join(parts[:3] + ['0'])
def process_log(input_file, output_file):
"""处理日志文件"""
ip_pattern = re.compile(r'\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}')
with open(input_file, 'r') as fin, open(output_file, 'w') as fout:
for line in fin:
# 替换所有IP地址
line = ip_pattern.sub(lambda m: anonymize_ip(m.group()), line)
fout.write(line)
if __name__ == '__main__':
process_log('/var/log/v2ray/access.log', '/tmp/access_anon.log')
时间戳模糊化:
def anonymize_timestamp(timestamp):
"""将时间戳精确到小时"""
# 2024/01/15 14:23:45 → 2024/01/15 14:00:00
return re.sub(r':\d{2}:\d{2}$', ':00:00', timestamp)
17.4.3 日志加密存储¶
使用加密文件系统:
# 创建加密容器
cryptsetup luksFormat /dev/sdb1
cryptsetup luksOpen /dev/sdb1 encrypted_logs
# 格式化
mkfs.ext4 /dev/mapper/encrypted_logs
# 挂载
mkdir -p /var/log/encrypted
mount /dev/mapper/encrypted_logs /var/log/encrypted
# 日志写入加密分区
{
"log": {
"access": "/var/log/encrypted/access.log",
"error": "/var/log/encrypted/error.log"
}
}
GPG加密日志:
#!/bin/bash
# encrypt_logs.sh
LOG_DIR="/var/log/v2ray"
ENCRYPTED_DIR="/backup/logs"
GPG_KEY="admin@example.com"
# 压缩并加密昨天的日志
DATE=$(date -d yesterday +%Y%m%d)
tar czf - $LOG_DIR/*-$DATE.log | \
gpg --encrypt --recipient $GPG_KEY \
-o $ENCRYPTED_DIR/logs-$DATE.tar.gz.gpg
# 删除原始日志
rm -f $LOG_DIR/*-$DATE.log
# 解密方法
# gpg --decrypt logs-20240115.tar.gz.gpg | tar xzf -
17.4.4 定期清理策略¶
自动清理脚本:
#!/bin/bash
# clean_logs.sh
LOG_DIR="/var/log/v2ray"
RETENTION_DAYS=7
# 删除7天前的日志
find $LOG_DIR -name "*.log" -mtime +$RETENTION_DAYS -delete
# 清空当前日志(保留文件)
truncate -s 0 $LOG_DIR/access.log
truncate -s 0 $LOG_DIR/error.log
echo "$(date): 日志已清理" >> /var/log/clean.log
定时任务:
crontab -e
# 每天凌晨4点清理日志
0 4 * * * /root/scripts/clean_logs.sh
# 每周日加密归档
0 3 * * 0 /root/scripts/encrypt_logs.sh
# 每月1日完全清理
0 5 1 * * rm -rf /var/log/v2ray/* && systemctl restart v2ray
安全删除:
#!/bin/bash
# secure_delete.sh
# 使用shred安全删除日志
shred -vfz -n 3 /var/log/v2ray/access.log
shred -vfz -n 3 /var/log/v2ray/error.log
# 参数说明:
# -v 显示进度
# -f 强制改变权限
# -z 最后用零覆盖
# -n 3 覆盖3次
# 或使用wipe
wipe -rf /var/log/v2ray/
本章小结¶
本章介绍了审计与日志管理的核心内容:
核心要点:
-
访问日志配置:
- 选择合适的日志级别
- 配置日志轮转
- 隐私保护配置
- 禁用敏感路径日志
-
流量分析工具:
- vnStat流量统计
- iftop实时监控
- X-UI面板统计
- 带宽限制
-
异常检测机制:
- 连接异常检测
- 端口扫描检测
- 暴力破解防护
- 自动响应机制
-
日志隐私平衡:
- 隐私优先配置
- 数据匿名化
- 加密存储
- 定期清理
日志管理原则:
推荐配置:
个人使用:
日志级别:none / error
访问日志:禁用
错误日志:内存或禁用
清理策略:重启清除
小规模共享:
日志级别:error
访问日志:禁用
错误日志:/dev/null
清理策略:每日清理
商业运营:
日志级别:warning
访问日志:匿名化
错误日志:加密存储
清理策略:7天保留
隐私与诊断平衡:
调试期间:
- 日志级别:debug
- 详细记录
- 问题解决后立即清理
正常运行:
- 日志级别:error
- 最小化记录
- 定期清理
高隐私需求:
- 日志级别:none
- 完全禁用
- 接受无法诊断
至此,第五部分"安全与隐私篇"全部完成!
实践任务:
- 配置合适的日志级别
- 设置日志轮转
- 部署异常检测脚本
- 实施日志加密
- 创建定期清理任务