8.1 iptables 日志基础

LOG 目标详解

LOG 目标是 iptables 中用于记录数据包信息的非终止目标,它不会改变数据包的处理流程,只是记录匹配的数据包信息到系统日志中。

LOG 目标的基本语法

# 基本 LOG 语法
iptables -A chain -match_conditions -j LOG [log_options]

# LOG 选项
--log-level level          # 日志级别(0-7)
--log-prefix "prefix"      # 日志前缀(最多29个字符)
--log-tcp-sequence         # 记录 TCP 序列号
--log-tcp-options          # 记录 TCP 选项
--log-ip-options           # 记录 IP 选项
--log-uid                  # 记录发送进程的 UID

日志级别说明

# 日志级别对应关系
0 = emerg     # 系统不可用
1 = alert     # 需要立即处理
2 = crit      # 严重错误
3 = err       # 一般错误
4 = warning   # 警告信息
5 = notice    # 正常但重要的信息
6 = info      # 一般信息
7 = debug     # 调试信息

# 默认级别是 warning (4)

基本日志记录配置

1. 简单日志记录

# 记录所有被拒绝的连接
iptables -A INPUT -j LOG --log-prefix "[INPUT-DENIED]: "
iptables -A INPUT -j DROP

# 记录转发被拒绝的数据包
iptables -A FORWARD -j LOG --log-prefix "[FORWARD-DENIED]: "
iptables -A FORWARD -j DROP

# 记录特定端口的访问
iptables -A INPUT -p tcp --dport 22 -j LOG --log-prefix "[SSH-ACCESS]: "
iptables -A INPUT -p tcp --dport 22 -j ACCEPT

2. 详细日志记录

# 记录 TCP 连接的详细信息
iptables -A INPUT -p tcp --syn -j LOG --log-prefix "[TCP-SYN]: " --log-tcp-sequence --log-tcp-options

# 记录 UDP 流量
iptables -A INPUT -p udp -j LOG --log-prefix "[UDP-TRAFFIC]: " --log-ip-options

# 记录 ICMP 流量
iptables -A INPUT -p icmp -j LOG --log-prefix "[ICMP-TRAFFIC]: " --log-level info

3. 条件日志记录

# 只记录来自特定网段的流量
iptables -A INPUT -s 192.168.1.0/24 -j LOG --log-prefix "[INTERNAL-TRAFFIC]: "

# 记录高频访问(可能的攻击)
iptables -A INPUT -p tcp --dport 80 -m limit --limit 10/min --limit-burst 20 -j LOG --log-prefix "[HTTP-HIGH-FREQ]: "

# 记录端口扫描
iptables -A INPUT -p tcp --tcp-flags SYN,ACK,FIN,RST RST -m limit --limit 1/s -j LOG --log-prefix "[PORT-SCAN]: "

8.2 日志配置和管理

rsyslog 配置

1. 基本 rsyslog 配置

# 编辑 rsyslog 配置文件
vim /etc/rsyslog.conf

# 添加 iptables 日志配置
# 将 kern.warning 级别的日志写入 iptables.log
kern.warning                                            /var/log/iptables.log

# 或者更具体的配置
:msg,contains,"[INPUT-DENIED]"                          /var/log/iptables-input.log
:msg,contains,"[FORWARD-DENIED]"                        /var/log/iptables-forward.log
:msg,contains,"[SSH-ACCESS]"                            /var/log/iptables-ssh.log

# 重启 rsyslog 服务
systemctl restart rsyslog

2. 高级 rsyslog 配置

# 创建专门的 iptables 日志配置文件
vim /etc/rsyslog.d/10-iptables.conf

# 内容如下:
# iptables 日志分类配置
:msg,contains,"[INPUT-DENIED]"          /var/log/iptables/input-denied.log
:msg,contains,"[FORWARD-DENIED]"        /var/log/iptables/forward-denied.log
:msg,contains,"[OUTPUT-DENIED]"         /var/log/iptables/output-denied.log
:msg,contains,"[SSH-ACCESS]"            /var/log/iptables/ssh-access.log
:msg,contains,"[HTTP-ACCESS]"           /var/log/iptables/http-access.log
:msg,contains,"[PORT-SCAN]"             /var/log/iptables/port-scan.log
:msg,contains,"[DDoS-ATTACK]"           /var/log/iptables/ddos-attack.log

# 停止进一步处理这些消息
:msg,contains,"[INPUT-DENIED]"          stop
:msg,contains,"[FORWARD-DENIED]"        stop
:msg,contains,"[OUTPUT-DENIED]"         stop
:msg,contains,"[SSH-ACCESS]"            stop
:msg,contains,"[HTTP-ACCESS]"           stop
:msg,contains,"[PORT-SCAN]"             stop
:msg,contains,"[DDoS-ATTACK]"           stop

# 创建日志目录
mkdir -p /var/log/iptables

# 重启 rsyslog
systemctl restart rsyslog

3. 日志轮转配置

# 创建 logrotate 配置文件
vim /etc/logrotate.d/iptables

# 内容如下:
/var/log/iptables/*.log {
    daily
    missingok
    rotate 30
    compress
    delaycompress
    notifempty
    create 0644 root root
    postrotate
        /bin/systemctl reload rsyslog > /dev/null 2>&1 || true
    endrotate
}

/var/log/iptables.log {
    daily
    missingok
    rotate 30
    compress
    delaycompress
    notifempty
    create 0644 root root
    postrotate
        /bin/systemctl reload rsyslog > /dev/null 2>&1 || true
    endrotate
}

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

日志性能优化

1. 限制日志频率

# 使用 limit 模块限制日志频率
iptables -A INPUT -m limit --limit 5/min --limit-burst 10 -j LOG --log-prefix "[INPUT-DENIED]: "
iptables -A INPUT -j DROP

# 使用 hashlimit 模块按源 IP 限制
iptables -A INPUT -m hashlimit --hashlimit-above 10/min --hashlimit-burst 20 --hashlimit-mode srcip --hashlimit-name ddos -j LOG --log-prefix "[DDoS-ATTACK]: "
iptables -A INPUT -m hashlimit --hashlimit-above 10/min --hashlimit-burst 20 --hashlimit-mode srcip --hashlimit-name ddos -j DROP

# 使用 recent 模块记录重复攻击
iptables -A INPUT -m recent --name attackers --rcheck --seconds 60 --hitcount 10 -j LOG --log-prefix "[REPEAT-ATTACK]: "
iptables -A INPUT -m recent --name attackers --rcheck --seconds 60 --hitcount 10 -j DROP
iptables -A INPUT -m recent --name attackers --set

2. 选择性日志记录

# 只记录外网访问
iptables -A INPUT -i eth0 -j LOG --log-prefix "[EXTERNAL-ACCESS]: "

# 只记录特定端口
iptables -A INPUT -p tcp -m multiport --dports 22,80,443 -j LOG --log-prefix "[IMPORTANT-PORTS]: "

# 只记录新连接
iptables -A INPUT -m state --state NEW -j LOG --log-prefix "[NEW-CONNECTION]: "

# 不记录内网流量
iptables -A INPUT ! -s 192.168.0.0/16 -j LOG --log-prefix "[NON-INTERNAL]: "

8.3 ULOG 和 NFLOG

ULOG 目标(已废弃)

ULOG 是较老的用户空间日志记录机制,现在已被 NFLOG 替代。

# ULOG 示例(不推荐使用)
iptables -A INPUT -j ULOG --ulog-nlgroup 1 --ulog-prefix "INPUT: "

NFLOG 目标

NFLOG 是现代的用户空间日志记录机制,提供更好的性能和功能。

1. NFLOG 基本配置

# 基本 NFLOG 语法
iptables -A INPUT -j NFLOG --nflog-group group_id --nflog-prefix "prefix"

# 示例配置
iptables -A INPUT -p tcp --dport 22 -j NFLOG --nflog-group 1 --nflog-prefix "SSH: "
iptables -A INPUT -p tcp --dport 80 -j NFLOG --nflog-group 2 --nflog-prefix "HTTP: "
iptables -A INPUT -p tcp --dport 443 -j NFLOG --nflog-group 3 --nflog-prefix "HTTPS: "

# NFLOG 选项
--nflog-group group_id     # 指定 netlink 组 ID(0-65535)
--nflog-prefix "prefix"    # 日志前缀
--nflog-range size         # 复制到用户空间的数据包大小
--nflog-threshold count    # 批量发送的数据包数量

2. 使用 ulogd2 处理 NFLOG

# 安装 ulogd2
apt-get install ulogd2  # Ubuntu/Debian
yum install ulogd       # CentOS/RHEL

# 配置 ulogd2
vim /etc/ulogd.conf

# 基本配置示例
[global]
loglevel=5
rmem=131071
bufsize=150000

# NFLOG 输入插件
plugin="/usr/lib/x86_64-linux-gnu/ulogd/ulogd_inppkt_NFLOG.so"
plugin="/usr/lib/x86_64-linux-gnu/ulogd/ulogd_raw2packet_BASE.so"
plugin="/usr/lib/x86_64-linux-gnu/ulogd/ulogd_inpflow_NFCT.so"
plugin="/usr/lib/x86_64-linux-gnu/ulogd/ulogd_filter_IFINDEX.so"
plugin="/usr/lib/x86_64-linux-gnu/ulogd/ulogd_filter_IP2STR.so"
plugin="/usr/lib/x86_64-linux-gnu/ulogd/ulogd_filter_PRINTPKT.so"
plugin="/usr/lib/x86_64-linux-gnu/ulogd/ulogd_output_LOGEMU.so"
plugin="/usr/lib/x86_64-linux-gnu/ulogd/ulogd_output_SYSLOG.so"
plugin="/usr/lib/x86_64-linux-gnu/ulogd/ulogd_output_MYSQL.so"
plugin="/usr/lib/x86_64-linux-gnu/ulogd/ulogd_output_PGSQL.so"
plugin="/usr/lib/x86_64-linux-gnu/ulogd/ulogd_output_SQLITE3.so"

# 堆栈配置
stack=log1:NFLOG,base1:BASE,ifi1:IFINDEX,ip2str1:IP2STR,print1:PRINTPKT,emu1:LOGEMU
stack=log2:NFLOG,base1:BASE,ifi1:IFINDEX,ip2str1:IP2STR,print1:PRINTPKT,sys1:SYSLOG

# NFLOG 输入配置
[log1]
group=1

[log2]
group=2

# 输出配置
[emu1]
file="/var/log/ulogd/ulogd.log"
sync=1

[sys1]
facility=LOG_LOCAL0
level=LOG_INFO

# 启动 ulogd2
systemctl enable ulogd2
systemctl start ulogd2

8.4 实时监控和分析

实时日志监控

1. 使用 tail 实时查看日志

# 实时查看 iptables 日志
tail -f /var/log/iptables.log

# 实时查看特定类型的日志
tail -f /var/log/iptables.log | grep "SSH-ACCESS"

# 多文件同时监控
tail -f /var/log/iptables/*.log

# 彩色输出
tail -f /var/log/iptables.log | grep --color=always "DENIED\|ACCEPT\|DROP"

2. 使用 journalctl 查看日志

# 查看 iptables 相关的系统日志
journalctl -f | grep iptables

# 查看内核日志
journalctl -f -k | grep "\[INPUT-DENIED\]\|\[FORWARD-DENIED\]"

# 查看特定时间段的日志
journalctl --since "2024-01-01 00:00:00" --until "2024-01-01 23:59:59" | grep iptables

# 查看特定服务的日志
journalctl -u iptables -f

3. 自定义监控脚本

#!/bin/bash
# iptables 实时监控脚本

LOG_FILE="/var/log/iptables.log"
ALERT_EMAIL="admin@example.com"
THRESHOLD=100

# 监控函数
monitor_attacks() {
    local count=$(tail -n 1000 $LOG_FILE | grep "$(date '+%b %d %H:%M')" | grep "DENIED" | wc -l)
    
    if [ $count -gt $THRESHOLD ]; then
        echo "ALERT: High number of denied connections: $count" | mail -s "iptables Alert" $ALERT_EMAIL
        
        # 自动封禁攻击 IP
        tail -n 1000 $LOG_FILE | grep "$(date '+%b %d %H:%M')" | grep "DENIED" | \
        grep -oE 'SRC=[0-9.]+' | cut -d= -f2 | sort | uniq -c | sort -nr | head -10 | \
        while read count ip; do
            if [ $count -gt 10 ]; then
                iptables -I INPUT -s $ip -j DROP
                echo "Blocked IP: $ip (count: $count)"
            fi
        done
    fi
}

# 分析端口扫描
analyze_port_scan() {
    local scan_ips=$(tail -n 1000 $LOG_FILE | grep "PORT-SCAN" | \
                    grep -oE 'SRC=[0-9.]+' | cut -d= -f2 | sort | uniq -c | sort -nr)
    
    if [ -n "$scan_ips" ]; then
        echo "Port scan detected from:"
        echo "$scan_ips"
        
        # 自动封禁扫描 IP
        echo "$scan_ips" | while read count ip; do
            if [ $count -gt 5 ]; then
                iptables -I INPUT -s $ip -j DROP
                echo "Blocked scanning IP: $ip"
            fi
        done
    fi
}

# 主循环
while true; do
    monitor_attacks
    analyze_port_scan
    sleep 60
done

日志分析工具

1. 基本统计分析

#!/bin/bash
# iptables 日志分析脚本

LOG_FILE="/var/log/iptables.log"

echo "=== iptables 日志分析报告 ==="
echo "分析时间: $(date)"
echo "日志文件: $LOG_FILE"
echo

# 总体统计
echo "=== 总体统计 ==="
echo "总日志条数: $(wc -l < $LOG_FILE)"
echo "今日日志条数: $(grep "$(date '+%b %d')" $LOG_FILE | wc -l)"
echo "最近1小时日志条数: $(grep "$(date '+%b %d %H:')" $LOG_FILE | wc -l)"
echo

# 按类型统计
echo "=== 按类型统计 ==="
echo "INPUT 拒绝: $(grep "INPUT-DENIED" $LOG_FILE | wc -l)"
echo "FORWARD 拒绝: $(grep "FORWARD-DENIED" $LOG_FILE | wc -l)"
echo "SSH 访问: $(grep "SSH-ACCESS" $LOG_FILE | wc -l)"
echo "HTTP 访问: $(grep "HTTP-ACCESS" $LOG_FILE | wc -l)"
echo "端口扫描: $(grep "PORT-SCAN" $LOG_FILE | wc -l)"
echo

# 按源 IP 统计
echo "=== 前10个源 IP ==="
grep -oE 'SRC=[0-9.]+' $LOG_FILE | cut -d= -f2 | sort | uniq -c | sort -nr | head -10
echo

# 按目标端口统计
echo "=== 前10个目标端口 ==="
grep -oE 'DPT=[0-9]+' $LOG_FILE | cut -d= -f2 | sort | uniq -c | sort -nr | head -10
echo

# 按协议统计
echo "=== 按协议统计 ==="
grep -oE 'PROTO=[A-Z]+' $LOG_FILE | cut -d= -f2 | sort | uniq -c | sort -nr
echo

# 按时间统计
echo "=== 按小时统计(今日) ==="
for hour in {00..23}; do
    count=$(grep "$(date '+%b %d') $hour:" $LOG_FILE | wc -l)
    printf "%s:00 - %4d 条\n" $hour $count
done
echo

# 可疑活动检测
echo "=== 可疑活动检测 ==="
echo "高频访问 IP (>100次):"
grep -oE 'SRC=[0-9.]+' $LOG_FILE | cut -d= -f2 | sort | uniq -c | sort -nr | awk '$1 > 100 {print $2 " (" $1 " 次)"}'
echo

echo "端口扫描活动:"
grep "PORT-SCAN" $LOG_FILE | grep -oE 'SRC=[0-9.]+' | cut -d= -f2 | sort | uniq -c | sort -nr | head -5
echo

echo "DDoS 攻击迹象:"
grep "DDoS-ATTACK" $LOG_FILE | grep -oE 'SRC=[0-9.]+' | cut -d= -f2 | sort | uniq -c | sort -nr | head -5

2. 高级分析脚本

#!/bin/bash
# 高级 iptables 日志分析

LOG_FILE="/var/log/iptables.log"
OUTPUT_DIR="/var/log/iptables-analysis"
DATE=$(date '+%Y%m%d')

mkdir -p $OUTPUT_DIR

# 生成 IP 地理位置信息
generate_geo_report() {
    echo "=== IP 地理位置分析 ===" > $OUTPUT_DIR/geo-report-$DATE.txt
    
    grep -oE 'SRC=[0-9.]+' $LOG_FILE | cut -d= -f2 | sort | uniq -c | sort -nr | head -20 | \
    while read count ip; do
        # 使用 geoiplookup 或 API 查询地理位置
        location=$(geoiplookup $ip 2>/dev/null | cut -d: -f2 | tr -d ' ')
        echo "$ip ($count 次) - $location" >> $OUTPUT_DIR/geo-report-$DATE.txt
    done
}

# 生成攻击模式分析
generate_attack_pattern() {
    echo "=== 攻击模式分析 ===" > $OUTPUT_DIR/attack-pattern-$DATE.txt
    
    # 分析攻击时间模式
    echo "按小时攻击分布:" >> $OUTPUT_DIR/attack-pattern-$DATE.txt
    for hour in {00..23}; do
        count=$(grep "$(date '+%b %d') $hour:" $LOG_FILE | grep "DENIED" | wc -l)
        printf "%s:00 - %4d 次攻击\n" $hour $count >> $OUTPUT_DIR/attack-pattern-$DATE.txt
    done
    
    echo "" >> $OUTPUT_DIR/attack-pattern-$DATE.txt
    
    # 分析攻击端口模式
    echo "攻击端口分布:" >> $OUTPUT_DIR/attack-pattern-$DATE.txt
    grep "DENIED" $LOG_FILE | grep -oE 'DPT=[0-9]+' | cut -d= -f2 | sort | uniq -c | sort -nr | head -20 >> $OUTPUT_DIR/attack-pattern-$DATE.txt
    
    echo "" >> $OUTPUT_DIR/attack-pattern-$DATE.txt
    
    # 分析攻击协议模式
    echo "攻击协议分布:" >> $OUTPUT_DIR/attack-pattern-$DATE.txt
    grep "DENIED" $LOG_FILE | grep -oE 'PROTO=[A-Z]+' | cut -d= -f2 | sort | uniq -c | sort -nr >> $OUTPUT_DIR/attack-pattern-$DATE.txt
}

# 生成威胁情报报告
generate_threat_intel() {
    echo "=== 威胁情报分析 ===" > $OUTPUT_DIR/threat-intel-$DATE.txt
    
    # 提取攻击 IP
    grep "DENIED" $LOG_FILE | grep -oE 'SRC=[0-9.]+' | cut -d= -f2 | sort | uniq > $OUTPUT_DIR/attack-ips-$DATE.txt
    
    # 检查是否在已知恶意 IP 列表中
    if [ -f "/etc/iptables/malicious-ips.txt" ]; then
        echo "已知恶意 IP 匹配:" >> $OUTPUT_DIR/threat-intel-$DATE.txt
        comm -12 <(sort $OUTPUT_DIR/attack-ips-$DATE.txt) <(sort /etc/iptables/malicious-ips.txt) >> $OUTPUT_DIR/threat-intel-$DATE.txt
    fi
    
    # 生成建议封禁的 IP 列表
    echo "" >> $OUTPUT_DIR/threat-intel-$DATE.txt
    echo "建议封禁的 IP (攻击次数 > 50):" >> $OUTPUT_DIR/threat-intel-$DATE.txt
    grep "DENIED" $LOG_FILE | grep -oE 'SRC=[0-9.]+' | cut -d= -f2 | sort | uniq -c | sort -nr | awk '$1 > 50 {print $2}' >> $OUTPUT_DIR/threat-intel-$DATE.txt
}

# 生成性能分析报告
generate_performance_report() {
    echo "=== 性能分析报告 ===" > $OUTPUT_DIR/performance-$DATE.txt
    
    # 规则匹配统计
    echo "规则匹配统计:" >> $OUTPUT_DIR/performance-$DATE.txt
    iptables -L -n -v | grep -E "Chain|pkts" >> $OUTPUT_DIR/performance-$DATE.txt
    
    echo "" >> $OUTPUT_DIR/performance-$DATE.txt
    
    # NAT 表统计
    echo "NAT 表统计:" >> $OUTPUT_DIR/performance-$DATE.txt
    iptables -t nat -L -n -v | grep -E "Chain|pkts" >> $OUTPUT_DIR/performance-$DATE.txt
    
    echo "" >> $OUTPUT_DIR/performance-$DATE.txt
    
    # 连接跟踪统计
    echo "连接跟踪统计:" >> $OUTPUT_DIR/performance-$DATE.txt
    if [ -f "/proc/net/stat/nf_conntrack" ]; then
        cat /proc/net/stat/nf_conntrack >> $OUTPUT_DIR/performance-$DATE.txt
    fi
    
    echo "" >> $OUTPUT_DIR/performance-$DATE.txt
    echo "当前连接数: $(cat /proc/net/nf_conntrack | wc -l)" >> $OUTPUT_DIR/performance-$DATE.txt
    echo "最大连接数: $(cat /proc/sys/net/netfilter/nf_conntrack_max)" >> $OUTPUT_DIR/performance-$DATE.txt
}

# 执行所有分析
echo "开始生成 iptables 分析报告..."
generate_geo_report
generate_attack_pattern
generate_threat_intel
generate_performance_report

echo "分析报告已生成到 $OUTPUT_DIR"
echo "报告文件:"
ls -la $OUTPUT_DIR/*-$DATE.txt

8.5 监控工具集成

与 Nagios 集成

1. Nagios 插件脚本

#!/bin/bash
# check_iptables_log.sh - Nagios 插件

LOG_FILE="/var/log/iptables.log"
WARNING_THRESHOLD=100
CRITICAL_THRESHOLD=500
TIME_WINDOW=5  # 分钟

# 获取最近 N 分钟的攻击次数
attack_count=$(grep "$(date -d "$TIME_WINDOW minutes ago" '+%b %d %H:%M')" $LOG_FILE | grep "DENIED" | wc -l)

# 检查阈值
if [ $attack_count -ge $CRITICAL_THRESHOLD ]; then
    echo "CRITICAL - $attack_count attacks in last $TIME_WINDOW minutes"
    exit 2
elif [ $attack_count -ge $WARNING_THRESHOLD ]; then
    echo "WARNING - $attack_count attacks in last $TIME_WINDOW minutes"
    exit 1
else
    echo "OK - $attack_count attacks in last $TIME_WINDOW minutes"
    exit 0
fi

2. Nagios 配置

# 在 Nagios 配置中添加
# /etc/nagios/objects/commands.cfg
define command {
    command_name    check_iptables_attacks
    command_line    /usr/local/nagios/libexec/check_iptables_log.sh
}

# /etc/nagios/objects/services.cfg
define service {
    use                     generic-service
    host_name               firewall-server
    service_description     iptables Attacks
    check_command           check_iptables_attacks
    check_interval          5
    retry_interval          1
    max_check_attempts      3
}

与 Zabbix 集成

1. Zabbix 用户参数

# 在 zabbix_agentd.conf 中添加
UserParameter=iptables.attacks[*],grep "$1" /var/log/iptables.log | grep "DENIED" | wc -l
UserParameter=iptables.connections,cat /proc/net/nf_conntrack | wc -l
UserParameter=iptables.rules.count,iptables -L | grep -c "^Chain"
UserParameter=iptables.dropped.packets,iptables -L -n -v | awk '/DROP/ {sum += $1} END {print sum+0}'

2. Zabbix 监控脚本

#!/bin/bash
# zabbix_iptables_discovery.sh

# 发现 iptables 链
echo '{"data":['
iptables -L | grep "^Chain" | awk '{print $2}' | while read chain; do
    echo '{"#{#CHAIN}":"'$chain'"},'
done | sed 's/,$/'
echo ']}'

与 Prometheus 集成

1. iptables_exporter

#!/usr/bin/env python3
# iptables_exporter.py

import subprocess
import time
import re
from prometheus_client import start_http_server, Gauge, Counter

# 定义指标
iptables_rules_total = Gauge('iptables_rules_total', 'Total number of iptables rules')
iptables_packets_total = Counter('iptables_packets_total', 'Total packets processed', ['chain', 'target'])
iptables_bytes_total = Counter('iptables_bytes_total', 'Total bytes processed', ['chain', 'target'])
iptables_connections_current = Gauge('iptables_connections_current', 'Current number of tracked connections')

def collect_iptables_metrics():
    # 收集规则统计
    try:
        output = subprocess.check_output(['iptables', '-L', '-n', '-v'], universal_newlines=True)
        
        # 解析输出
        for line in output.split('\n'):
            if re.match(r'^\s*\d+', line):
                parts = line.split()
                if len(parts) >= 3:
                    packets = int(parts[0])
                    bytes_count = int(parts[1])
                    target = parts[2]
                    
                    # 更新指标(这里简化处理)
                    iptables_packets_total.labels(chain='INPUT', target=target)._value._value = packets
                    iptables_bytes_total.labels(chain='INPUT', target=target)._value._value = bytes_count
        
        # 收集连接跟踪信息
        with open('/proc/net/nf_conntrack', 'r') as f:
            connections = len(f.readlines())
            iptables_connections_current.set(connections)
            
    except Exception as e:
        print(f"Error collecting metrics: {e}")

def main():
    # 启动 HTTP 服务器
    start_http_server(8000)
    
    while True:
        collect_iptables_metrics()
        time.sleep(30)

if __name__ == '__main__':
    main()

2. Prometheus 配置

# prometheus.yml
scrape_configs:
  - job_name: 'iptables'
    static_configs:
      - targets: ['localhost:8000']
    scrape_interval: 30s

3. Grafana 仪表板

{
  "dashboard": {
    "title": "iptables Monitoring",
    "panels": [
      {
        "title": "Packet Rate",
        "type": "graph",
        "targets": [
          {
            "expr": "rate(iptables_packets_total[5m])",
            "legendFormat": "{{chain}} - {{target}}"
          }
        ]
      },
      {
        "title": "Current Connections",
        "type": "singlestat",
        "targets": [
          {
            "expr": "iptables_connections_current"
          }
        ]
      }
    ]
  }
}

8.6 安全事件响应

自动响应脚本

1. 攻击检测和自动封禁

#!/bin/bash
# auto_block.sh - 自动攻击检测和封禁

LOG_FILE="/var/log/iptables.log"
BLOCK_LIST="/etc/iptables/blocked_ips.txt"
WHITE_LIST="/etc/iptables/whitelist.txt"
THRESHOLD=20
TIME_WINDOW=5  # 分钟

# 创建必要的文件
touch $BLOCK_LIST $WHITE_LIST

# 检测攻击函数
detect_attacks() {
    local current_time=$(date '+%b %d %H:%M')
    local window_start=$(date -d "$TIME_WINDOW minutes ago" '+%b %d %H:%M')
    
    # 分析最近时间窗口内的攻击
    grep "$current_time\|$window_start" $LOG_FILE | grep "DENIED" | \
    grep -oE 'SRC=[0-9.]+' | cut -d= -f2 | sort | uniq -c | sort -nr | \
    while read count ip; do
        # 检查是否在白名单中
        if grep -q "^$ip$" $WHITE_LIST; then
            continue
        fi
        
        # 检查是否已经被封禁
        if grep -q "^$ip$" $BLOCK_LIST; then
            continue
        fi
        
        # 如果攻击次数超过阈值,则封禁
        if [ $count -ge $THRESHOLD ]; then
            echo "$(date): Blocking IP $ip (attack count: $count)" | tee -a /var/log/auto_block.log
            
            # 添加 iptables 规则
            iptables -I INPUT -s $ip -j DROP
            
            # 记录到封禁列表
            echo "$ip" >> $BLOCK_LIST
            
            # 发送告警邮件
            echo "IP $ip has been automatically blocked due to $count attacks in $TIME_WINDOW minutes." | \
            mail -s "Auto Block Alert" admin@example.com
        fi
    done
}

# 清理过期封禁
cleanup_blocks() {
    local temp_file=$(mktemp)
    
    # 检查每个被封禁的 IP
    while read ip; do
        # 检查最近24小时是否还有攻击
        local recent_attacks=$(grep "$(date '+%b %d')" $LOG_FILE | grep "DENIED" | grep "SRC=$ip" | wc -l)
        
        if [ $recent_attacks -eq 0 ]; then
            echo "$(date): Unblocking IP $ip (no recent attacks)" | tee -a /var/log/auto_block.log
            
            # 删除 iptables 规则
            iptables -D INPUT -s $ip -j DROP 2>/dev/null
        else
            echo "$ip" >> $temp_file
        fi
    done < $BLOCK_LIST
    
    mv $temp_file $BLOCK_LIST
}

# 主循环
while true; do
    detect_attacks
    
    # 每小时清理一次过期封禁
    if [ $(date '+%M') -eq 0 ]; then
        cleanup_blocks
    fi
    
    sleep 60
done

2. DDoS 检测和缓解

#!/bin/bash
# ddos_protection.sh - DDoS 检测和缓解

LOG_FILE="/var/log/iptables.log"
DDOS_THRESHOLD=1000  # 每分钟连接数
SYN_FLOOD_THRESHOLD=100  # SYN 包阈值

# DDoS 检测函数
detect_ddos() {
    local current_minute=$(date '+%b %d %H:%M')
    
    # 检测连接洪水
    local connection_count=$(grep "$current_minute" $LOG_FILE | grep "NEW" | wc -l)
    
    if [ $connection_count -gt $DDOS_THRESHOLD ]; then
        echo "$(date): DDoS attack detected - $connection_count connections per minute"
        
        # 启用 DDoS 防护规则
        enable_ddos_protection
        
        # 发送告警
        echo "DDoS attack detected with $connection_count connections per minute" | \
        mail -s "DDoS Alert" admin@example.com
    fi
    
    # 检测 SYN 洪水攻击
    local syn_count=$(grep "$current_minute" $LOG_FILE | grep "SYN" | wc -l)
    
    if [ $syn_count -gt $SYN_FLOOD_THRESHOLD ]; then
        echo "$(date): SYN flood attack detected - $syn_count SYN packets per minute"
        
        # 启用 SYN flood 防护
        enable_syn_flood_protection
    fi
}

# 启用 DDoS 防护
enable_ddos_protection() {
    echo "Enabling DDoS protection..."
    
    # 限制新连接速率
    iptables -I INPUT -p tcp --syn -m limit --limit 1/s --limit-burst 3 -j ACCEPT
    iptables -I INPUT -p tcp --syn -j DROP
    
    # 限制 ICMP
    iptables -I INPUT -p icmp -m limit --limit 1/s --limit-burst 1 -j ACCEPT
    iptables -I INPUT -p icmp -j DROP
    
    # 限制每个 IP 的连接数
    iptables -I INPUT -p tcp --syn -m connlimit --connlimit-above 10 -j DROP
    
    echo "DDoS protection enabled"
}

# 启用 SYN flood 防护
enable_syn_flood_protection() {
    echo "Enabling SYN flood protection..."
    
    # 启用 SYN cookies
    echo 1 > /proc/sys/net/ipv4/tcp_syncookies
    
    # 调整 SYN 队列大小
    echo 2048 > /proc/sys/net/ipv4/tcp_max_syn_backlog
    
    # 减少 SYN-ACK 重试次数
    echo 3 > /proc/sys/net/ipv4/tcp_synack_retries
    
    echo "SYN flood protection enabled"
}

# 禁用 DDoS 防护
disable_ddos_protection() {
    echo "Disabling DDoS protection..."
    
    # 删除临时规则
    iptables -D INPUT -p tcp --syn -m limit --limit 1/s --limit-burst 3 -j ACCEPT 2>/dev/null
    iptables -D INPUT -p tcp --syn -j DROP 2>/dev/null
    iptables -D INPUT -p icmp -m limit --limit 1/s --limit-burst 1 -j ACCEPT 2>/dev/null
    iptables -D INPUT -p icmp -j DROP 2>/dev/null
    iptables -D INPUT -p tcp --syn -m connlimit --connlimit-above 10 -j DROP 2>/dev/null
    
    echo "DDoS protection disabled"
}

# 主循环
while true; do
    detect_ddos
    sleep 60
done

事件通知系统

1. 邮件通知脚本

#!/bin/bash
# notify_security_event.sh

EMAIL="admin@example.com"
SMS_API="https://api.sms-service.com/send"
SLACK_WEBHOOK="https://hooks.slack.com/services/YOUR/SLACK/WEBHOOK"

# 发送邮件通知
send_email() {
    local subject="$1"
    local message="$2"
    
    echo "$message" | mail -s "$subject" $EMAIL
}

# 发送 SMS 通知
send_sms() {
    local message="$1"
    
    curl -X POST $SMS_API \
        -d "to=+1234567890" \
        -d "message=$message"
}

# 发送 Slack 通知
send_slack() {
    local message="$1"
    
    curl -X POST -H 'Content-type: application/json' \
        --data "{\"text\":\"$message\"}" \
        $SLACK_WEBHOOK
}

# 综合通知函数
notify_security_event() {
    local event_type="$1"
    local details="$2"
    local severity="$3"
    
    local subject="Security Alert: $event_type"
    local message="Security Event Detected\n\nType: $event_type\nSeverity: $severity\nTime: $(date)\nDetails: $details"
    
    # 根据严重程度选择通知方式
    case $severity in
        "CRITICAL")
            send_email "$subject" "$message"
            send_sms "CRITICAL: $event_type detected"
            send_slack "🚨 CRITICAL: $event_type detected at $(date)"
            ;;
        "HIGH")
            send_email "$subject" "$message"
            send_slack "⚠️ HIGH: $event_type detected at $(date)"
            ;;
        "MEDIUM")
            send_email "$subject" "$message"
            ;;
        "LOW")
            send_slack "ℹ️ LOW: $event_type detected at $(date)"
            ;;
    esac
}

# 示例使用
# notify_security_event "Port Scan" "Multiple port scan attempts from 192.168.1.100" "HIGH"

本章小结

本章详细介绍了 iptables 的日志记录和监控功能:

  1. 日志基础:LOG 和 NFLOG 目标的使用方法
  2. 日志配置:rsyslog 配置、日志轮转和性能优化
  3. 实时监控:日志监控工具和自定义脚本
  4. 日志分析:统计分析和威胁情报生成
  5. 监控集成:与 Nagios、Zabbix、Prometheus 的集成
  6. 安全响应:自动攻击检测、DDoS 防护和事件通知

本章练习

  1. 基础练习

    • 配置基本的日志记录规则
    • 设置 rsyslog 日志分类
    • 编写简单的日志分析脚本
  2. 进阶练习

    • 配置 NFLOG 和 ulogd2
    • 实现实时攻击检测
    • 集成监控系统
  3. 实战练习

    • 搭建完整的日志监控系统
    • 实现自动安全响应
    • 配置多渠道告警通知
  4. 分析练习

    • 分析真实的攻击日志
    • 生成安全分析报告
    • 优化日志记录性能

下一章我们将学习 iptables 的性能优化技巧。