跳转至

第17章 审计与日志管理

审计与日志管理是服务器运维的重要组成部分。合理的日志配置既能帮助诊断问题,又能保护用户隐私。

17.1 访问日志配置

17.1.1 为什么需要日志

日志的作用:

1. 故障诊断
   - 连接失败原因
   - 性能问题分析
   - 错误追踪

2. 安全监控
   - 异常访问检测
   - 攻击识别
   - 入侵发现

3. 流量统计
   - 使用量分析
   - 用户行为
   - 资源规划

4. 合规要求
   - 某些场景需要
   - 审计需求

日志的风险:

⚠️ 隐私泄露
- 访问记录
- 用户IP
- 访问时间
- 目标网站

⚠️ 法律风险
- 日志可能被要求提供
- 作为证据使用

⚠️ 存储风险
- 磁盘占用
- 日志泄露

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"
  }
}

仅记录到内存:

{
  "log": {
    "loglevel": "warning",
    "access": "",  // 空字符串 = stdout
    "error": ""
  }
}

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
}

立即执行轮转:

# 测试配置
logrotate -d /etc/logrotate.d/v2ray

# 强制轮转
logrotate -f /etc/logrotate.d/v2ray

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进程监控:

# 安装
apt install nethogs -y

# 运行
nethogs eth0

# 显示每个进程的流量使用
# 适合识别异常流量

17.2.2 流量统计分析

使用X-UI面板:

X-UI内置功能:
✓ 每个用户流量统计
✓ 总流量统计
✓ 流量图表
✓ 到期提醒

访问:
http://your-ip:54321
面板 → 入站列表 → 流量统计

自定义流量统计脚本:

#!/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": "none",  // 完全不记录日志
    "access": "none",
    "error": "none"
  }
}

适度隐私方案:

{
  "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/

本章小结

本章介绍了审计与日志管理的核心内容:

核心要点:

  1. 访问日志配置

    • 选择合适的日志级别
    • 配置日志轮转
    • 隐私保护配置
    • 禁用敏感路径日志
  2. 流量分析工具

    • vnStat流量统计
    • iftop实时监控
    • X-UI面板统计
    • 带宽限制
  3. 异常检测机制

    • 连接异常检测
    • 端口扫描检测
    • 暴力破解防护
    • 自动响应机制
  4. 日志隐私平衡

    • 隐私优先配置
    • 数据匿名化
    • 加密存储
    • 定期清理

日志管理原则:

1. 最小化原则
   只记录必要信息

2. 时效性原则
   定期清理旧日志

3. 安全性原则
   加密敏感日志

4. 隐私性原则
   匿名化用户数据

5. 实用性原则
   保留诊断必需信息

推荐配置:

个人使用:
日志级别:none / error
访问日志:禁用
错误日志:内存或禁用
清理策略:重启清除

小规模共享:
日志级别:error
访问日志:禁用
错误日志:/dev/null
清理策略:每日清理

商业运营:
日志级别:warning
访问日志:匿名化
错误日志:加密存储
清理策略:7天保留

隐私与诊断平衡:

调试期间:
- 日志级别:debug
- 详细记录
- 问题解决后立即清理

正常运行:
- 日志级别:error
- 最小化记录
- 定期清理

高隐私需求:
- 日志级别:none
- 完全禁用
- 接受无法诊断

至此,第五部分"安全与隐私篇"全部完成!


实践任务:

  1. 配置合适的日志级别
  2. 设置日志轮转
  3. 部署异常检测脚本
  4. 实施日志加密
  5. 创建定期清理任务