12.1 与系统服务集成

12.1.1 systemd 服务配置

1. 创建 iptables systemd 服务

#!/bin/bash
# create_iptables_service.sh

# 创建 iptables systemd 服务配置
create_iptables_service() {
    local service_file="/etc/systemd/system/iptables.service"
    local rules_file="/etc/iptables/rules.v4"
    local script_file="/usr/local/bin/iptables-restore.sh"
    
    echo "Creating iptables systemd service..."
    
    # 创建规则目录
    mkdir -p /etc/iptables
    
    # 创建恢复脚本
    cat > "$script_file" << 'EOF'
#!/bin/bash
# iptables-restore.sh

RULES_FILE="/etc/iptables/rules.v4"
LOG_FILE="/var/log/iptables-restore.log"

# 日志函数
log_message() {
    echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" | tee -a "$LOG_FILE"
}

# 备份当前规则
backup_current_rules() {
    local backup_file="/etc/iptables/backup_$(date +%Y%m%d_%H%M%S).rules"
    iptables-save > "$backup_file"
    log_message "Current rules backed up to: $backup_file"
}

# 恢复规则
restore_rules() {
    if [ -f "$RULES_FILE" ]; then
        log_message "Restoring iptables rules from: $RULES_FILE"
        
        # 备份当前规则
        backup_current_rules
        
        # 恢复规则
        if iptables-restore < "$RULES_FILE"; then
            log_message "iptables rules restored successfully"
            return 0
        else
            log_message "ERROR: Failed to restore iptables rules"
            return 1
        fi
    else
        log_message "ERROR: Rules file not found: $RULES_FILE"
        return 1
    fi
}

# 保存当前规则
save_rules() {
    log_message "Saving current iptables rules to: $RULES_FILE"
    
    if iptables-save > "$RULES_FILE"; then
        log_message "iptables rules saved successfully"
        return 0
    else
        log_message "ERROR: Failed to save iptables rules"
        return 1
    fi
}

# 验证规则
validate_rules() {
    log_message "Validating iptables rules..."
    
    # 检查规则语法
    if iptables-restore --test < "$RULES_FILE" 2>/dev/null; then
        log_message "Rules validation passed"
        return 0
    else
        log_message "ERROR: Rules validation failed"
        return 1
    fi
}

# 主函数
case "${1:-restore}" in
    "restore")
        restore_rules
        ;;
    "save")
        save_rules
        ;;
    "validate")
        validate_rules
        ;;
    "backup")
        backup_current_rules
        ;;
    *)
        echo "Usage: $0 {restore|save|validate|backup}"
        exit 1
        ;;
esac
EOF

    # 设置脚本权限
    chmod +x "$script_file"
    
    # 创建 systemd 服务文件
    cat > "$service_file" << EOF
[Unit]
Description=iptables firewall service
After=network-pre.target
Wants=network-pre.target
Before=network.target
DefaultDependencies=no

[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=$script_file restore
ExecReload=$script_file restore
ExecStop=/usr/sbin/iptables -F
ExecStop=/usr/sbin/iptables -X
ExecStop=/usr/sbin/iptables -t nat -F
ExecStop=/usr/sbin/iptables -t nat -X
ExecStop=/usr/sbin/iptables -t mangle -F
ExecStop=/usr/sbin/iptables -t mangle -X
ExecStop=/usr/sbin/iptables -P INPUT ACCEPT
ExecStop=/usr/sbin/iptables -P FORWARD ACCEPT
ExecStop=/usr/sbin/iptables -P OUTPUT ACCEPT
TimeoutSec=30

[Install]
WantedBy=multi-user.target
EOF

    # 保存当前规则
    if [ ! -f "$rules_file" ]; then
        echo "Saving current iptables rules..."
        iptables-save > "$rules_file"
    fi
    
    # 重新加载 systemd
    systemctl daemon-reload
    
    echo "iptables systemd service created successfully"
    echo "Service file: $service_file"
    echo "Rules file: $rules_file"
    echo "Script file: $script_file"
    echo
    echo "To enable and start the service:"
    echo "  systemctl enable iptables"
    echo "  systemctl start iptables"
    echo
    echo "To save current rules:"
    echo "  $script_file save"
}

# 高级服务配置
create_advanced_service() {
    local service_file="/etc/systemd/system/iptables-advanced.service"
    local config_dir="/etc/iptables"
    local script_file="/usr/local/bin/iptables-manager.sh"
    
    echo "Creating advanced iptables service..."
    
    # 创建配置目录
    mkdir -p "$config_dir"/{rules,scripts,logs}
    
    # 创建高级管理脚本
    cat > "$script_file" << 'EOF'
#!/bin/bash
# iptables-manager.sh - Advanced iptables management script

CONFIG_DIR="/etc/iptables"
RULES_DIR="$CONFIG_DIR/rules"
SCRIPTS_DIR="$CONFIG_DIR/scripts"
LOGS_DIR="$CONFIG_DIR/logs"
LOG_FILE="$LOGS_DIR/iptables-manager.log"
LOCK_FILE="/var/lock/iptables-manager.lock"

# 确保目录存在
mkdir -p "$RULES_DIR" "$SCRIPTS_DIR" "$LOGS_DIR"

# 日志函数
log_message() {
    echo "$(date '+%Y-%m-%d %H:%M:%S') [$$] $1" | tee -a "$LOG_FILE"
}

# 锁定函数
acquire_lock() {
    if [ -f "$LOCK_FILE" ]; then
        local pid=$(cat "$LOCK_FILE")
        if kill -0 "$pid" 2>/dev/null; then
            log_message "ERROR: Another instance is running (PID: $pid)"
            return 1
        else
            log_message "Removing stale lock file"
            rm -f "$LOCK_FILE"
        fi
    fi
    
    echo $$ > "$LOCK_FILE"
    return 0
}

# 释放锁
release_lock() {
    rm -f "$LOCK_FILE"
}

# 清理函数
cleanup() {
    release_lock
    exit $1
}

# 信号处理
trap 'cleanup 1' INT TERM
trap 'cleanup 0' EXIT

# 验证规则文件
validate_rules_file() {
    local rules_file="$1"
    
    if [ ! -f "$rules_file" ]; then
        log_message "ERROR: Rules file not found: $rules_file"
        return 1
    fi
    
    # 语法检查
    if ! iptables-restore --test < "$rules_file" 2>/dev/null; then
        log_message "ERROR: Invalid rules syntax in: $rules_file"
        return 1
    fi
    
    log_message "Rules file validation passed: $rules_file"
    return 0
}

# 备份当前规则
backup_rules() {
    local backup_file="$RULES_DIR/backup_$(date +%Y%m%d_%H%M%S).rules"
    
    log_message "Backing up current rules to: $backup_file"
    
    if iptables-save > "$backup_file"; then
        log_message "Backup completed successfully"
        
        # 保留最近10个备份
        local backup_count=$(ls -1 "$RULES_DIR"/backup_*.rules 2>/dev/null | wc -l)
        if [ $backup_count -gt 10 ]; then
            local old_backups=$((backup_count - 10))
            ls -1t "$RULES_DIR"/backup_*.rules | tail -$old_backups | xargs rm -f
            log_message "Cleaned up $old_backups old backup files"
        fi
        
        return 0
    else
        log_message "ERROR: Backup failed"
        return 1
    fi
}

# 应用规则
apply_rules() {
    local rules_file="$1"
    
    if [ -z "$rules_file" ]; then
        rules_file="$RULES_DIR/rules.v4"
    fi
    
    log_message "Applying rules from: $rules_file"
    
    # 验证规则
    if ! validate_rules_file "$rules_file"; then
        return 1
    fi
    
    # 备份当前规则
    if ! backup_rules; then
        log_message "WARNING: Backup failed, continuing anyway"
    fi
    
    # 应用规则
    if iptables-restore < "$rules_file"; then
        log_message "Rules applied successfully"
        
        # 验证应用结果
        if verify_rules_applied; then
            log_message "Rules verification passed"
            return 0
        else
            log_message "WARNING: Rules verification failed"
            return 1
        fi
    else
        log_message "ERROR: Failed to apply rules"
        return 1
    fi
}

# 验证规则是否正确应用
verify_rules_applied() {
    local current_rules_count=$(iptables-save | grep "^-A" | wc -l)
    
    if [ $current_rules_count -gt 0 ]; then
        log_message "Verification: $current_rules_count rules are active"
        return 0
    else
        log_message "ERROR: No active rules found"
        return 1
    fi
}

# 保存当前规则
save_rules() {
    local rules_file="$RULES_DIR/rules.v4"
    
    log_message "Saving current rules to: $rules_file"
    
    if iptables-save > "$rules_file"; then
        log_message "Rules saved successfully"
        return 0
    else
        log_message "ERROR: Failed to save rules"
        return 1
    fi
}

# 清空所有规则
flush_rules() {
    log_message "Flushing all iptables rules"
    
    # 备份当前规则
    backup_rules
    
    # 清空规则
    iptables -F
    iptables -X
    iptables -t nat -F
    iptables -t nat -X
    iptables -t mangle -F
    iptables -t mangle -X
    iptables -t raw -F
    iptables -t raw -X
    
    # 设置默认策略为 ACCEPT
    iptables -P INPUT ACCEPT
    iptables -P FORWARD ACCEPT
    iptables -P OUTPUT ACCEPT
    
    log_message "All rules flushed, default policies set to ACCEPT"
}

# 运行自定义脚本
run_custom_scripts() {
    local script_type="$1"
    local scripts_path="$SCRIPTS_DIR/$script_type"
    
    if [ -d "$scripts_path" ]; then
        log_message "Running $script_type scripts from: $scripts_path"
        
        for script in "$scripts_path"/*.sh; do
            if [ -f "$script" ] && [ -x "$script" ]; then
                log_message "Executing script: $script"
                if "$script"; then
                    log_message "Script completed successfully: $script"
                else
                    log_message "ERROR: Script failed: $script"
                fi
            fi
        done
    fi
}

# 状态检查
status_check() {
    log_message "Performing iptables status check"
    
    # 规则统计
    local total_rules=$(iptables-save | grep "^-A" | wc -l)
    log_message "Total active rules: $total_rules"
    
    # 默认策略
    for chain in INPUT OUTPUT FORWARD; do
        local policy=$(iptables -L "$chain" -n | head -1 | awk '{print $4}' | tr -d '()')
        log_message "$chain chain policy: $policy"
    done
    
    # 连接跟踪
    if [ -f /proc/net/nf_conntrack ]; then
        local conn_count=$(cat /proc/net/nf_conntrack | wc -l)
        local max_conn=$(cat /proc/sys/net/netfilter/nf_conntrack_max)
        local usage_percent=$((conn_count * 100 / max_conn))
        log_message "Connection tracking: $usage_percent% ($conn_count/$max_conn)"
    fi
    
    log_message "Status check completed"
}

# 主函数
main() {
    if ! acquire_lock; then
        exit 1
    fi
    
    case "${1:-status}" in
        "start"|"restore")
            run_custom_scripts "pre-start"
            apply_rules "$2"
            run_custom_scripts "post-start"
            ;;
        "stop"|"flush")
            run_custom_scripts "pre-stop"
            flush_rules
            run_custom_scripts "post-stop"
            ;;
        "reload"|"restart")
            run_custom_scripts "pre-reload"
            apply_rules "$2"
            run_custom_scripts "post-reload"
            ;;
        "save")
            save_rules
            ;;
        "backup")
            backup_rules
            ;;
        "status")
            status_check
            ;;
        "validate")
            validate_rules_file "${2:-$RULES_DIR/rules.v4}"
            ;;
        *)
            echo "Usage: $0 {start|stop|reload|save|backup|status|validate} [rules_file]"
            exit 1
            ;;
    esac
}

# 执行主函数
main "$@"
EOF

    # 设置脚本权限
    chmod +x "$script_file"
    
    # 创建高级 systemd 服务文件
    cat > "$service_file" << EOF
[Unit]
Description=Advanced iptables firewall service
Documentation=man:iptables(8)
After=network-pre.target
Wants=network-pre.target
Before=network.target
DefaultDependencies=no

[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=$script_file start
ExecReload=$script_file reload
ExecStop=$script_file stop
TimeoutStartSec=60
TimeoutStopSec=30
TimeoutReloadSec=60

# 环境变量
Environment=IPTABLES_CONFIG_DIR=$config_dir

# 安全设置
PrivateTmp=yes
ProtectSystem=strict
ReadWritePaths=$config_dir /var/log
NoNewPrivileges=yes

[Install]
WantedBy=multi-user.target
EOF

    # 创建示例规则文件
    if [ ! -f "$config_dir/rules/rules.v4" ]; then
        cat > "$config_dir/rules/rules.v4" << 'EOF'
# Generated by iptables-manager
*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [0:0]

# 允许回环接口
-A INPUT -i lo -j ACCEPT

# 允许已建立的连接
-A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT

# 允许 SSH
-A INPUT -p tcp --dport 22 -j ACCEPT

# 允许 ICMP
-A INPUT -p icmp -j ACCEPT

COMMIT
EOF
    fi
    
    # 创建示例脚本目录
    mkdir -p "$config_dir/scripts"/{pre-start,post-start,pre-stop,post-stop,pre-reload,post-reload}
    
    # 重新加载 systemd
    systemctl daemon-reload
    
    echo "Advanced iptables service created successfully"
    echo "Service file: $service_file"
    echo "Config directory: $config_dir"
    echo "Manager script: $script_file"
    echo
    echo "To enable and start the service:"
    echo "  systemctl enable iptables-advanced"
    echo "  systemctl start iptables-advanced"
}

# 使用示例
case "${1:-help}" in
    "basic")
        create_iptables_service
        ;;
    "advanced")
        create_advanced_service
        ;;
    "help")
        echo "Usage: $0 <command>"
        echo "Commands:"
        echo "  basic     - Create basic iptables systemd service"
        echo "  advanced  - Create advanced iptables systemd service"
        ;;
    *)
        echo "Unknown command: $1"
        exit 1
        ;;
esac

12.3.2 ELK Stack 集成

1. Logstash 配置

#!/bin/bash
# elk_iptables_config.sh

# 配置 ELK Stack 处理 iptables 日志
configure_logstash() {
    local logstash_conf="/etc/logstash/conf.d/iptables.conf"
    
    echo "Configuring Logstash for iptables logs..."
    
    cat > "$logstash_conf" << 'EOF'
# Logstash configuration for iptables logs

input {
  file {
    path => "/var/log/iptables/*.log"
    start_position => "beginning"
    sincedb_path => "/var/lib/logstash/sincedb_iptables"
    codec => "plain"
    tags => ["iptables"]
  }
  
  syslog {
    port => 5514
    tags => ["iptables", "syslog"]
  }
}

filter {
  if "iptables" in [tags] {
    # 解析 iptables 日志格式
    grok {
      match => {
        "message" => "%{SYSLOGTIMESTAMP:timestamp} %{IPORHOST:host} %{WORD:program}\[%{POSINT:pid}\]: \[%{WORD:log_prefix}\] IN=%{WORD:in_interface}? OUT=%{WORD:out_interface}? MAC=%{COMMONMAC:mac}? SRC=%{IP:src_ip} DST=%{IP:dst_ip} LEN=%{INT:length} TOS=%{BASE16NUM:tos} PREC=%{BASE16NUM:prec} TTL=%{INT:ttl} ID=%{INT:id} (?:DF )?PROTO=%{WORD:protocol}(?: SPT=%{INT:src_port} DPT=%{INT:dst_port})?(?: WINDOW=%{INT:window})?(?: RES=%{BASE16NUM:res})?(?: %{WORD:tcp_flags})*"
      }
    }
    
    # 解析时间戳
    date {
      match => [ "timestamp", "MMM dd HH:mm:ss", "MMM  d HH:mm:ss" ]
    }
    
    # 转换数据类型
    mutate {
      convert => {
        "src_port" => "integer"
        "dst_port" => "integer"
        "length" => "integer"
        "ttl" => "integer"
        "id" => "integer"
        "window" => "integer"
      }
    }
    
    # 添加地理位置信息
    geoip {
      source => "src_ip"
      target => "src_geoip"
    }
    
    geoip {
      source => "dst_ip"
      target => "dst_geoip"
    }
    
    # 分类日志类型
    if [log_prefix] == "IPTABLES-DROP" {
      mutate { add_tag => ["dropped"] }
    } else if [log_prefix] == "IPTABLES-ACCEPT" {
      mutate { add_tag => ["accepted"] }
    } else if [log_prefix] == "IPTABLES-REJECT" {
      mutate { add_tag => ["rejected"] }
    }
    
    # 识别服务
    if [dst_port] {
      if [dst_port] == 22 {
        mutate { add_field => { "service" => "ssh" } }
      } else if [dst_port] == 80 {
        mutate { add_field => { "service" => "http" } }
      } else if [dst_port] == 443 {
        mutate { add_field => { "service" => "https" } }
      } else if [dst_port] == 25 {
        mutate { add_field => { "service" => "smtp" } }
      } else if [dst_port] == 53 {
        mutate { add_field => { "service" => "dns" } }
      } else if [dst_port] == 21 {
        mutate { add_field => { "service" => "ftp" } }
      } else {
        mutate { add_field => { "service" => "unknown" } }
      }
    }
    
    # 检测攻击模式
    if "dropped" in [tags] {
      # 端口扫描检测
      if [dst_port] and [dst_port] > 1024 {
        mutate { add_tag => ["potential_scan"] }
      }
      
      # 暴力破解检测
      if [dst_port] in [22, 21, 23, 3389] {
        mutate { add_tag => ["potential_bruteforce"] }
      }
    }
  }
}

output {
  if "iptables" in [tags] {
    elasticsearch {
      hosts => ["localhost:9200"]
      index => "iptables-%{+YYYY.MM.dd}"
      template_name => "iptables"
      template_pattern => "iptables-*"
      template => "/etc/logstash/templates/iptables-template.json"
    }
    
    # 输出到文件用于调试
    file {
      path => "/var/log/logstash/iptables-processed.log"
      codec => json_lines
    }
  }
}
EOF

    echo "Logstash configuration created: $logstash_conf"
}

# 创建 Elasticsearch 模板
create_elasticsearch_template() {
    local template_file="/etc/logstash/templates/iptables-template.json"
    
    echo "Creating Elasticsearch template..."
    
    mkdir -p "/etc/logstash/templates"
    
    cat > "$template_file" << 'EOF'
{
  "index_patterns": ["iptables-*"],
  "settings": {
    "number_of_shards": 1,
    "number_of_replicas": 0,
    "index.refresh_interval": "5s"
  },
  "mappings": {
    "properties": {
      "@timestamp": {
        "type": "date"
      },
      "src_ip": {
        "type": "ip"
      },
      "dst_ip": {
        "type": "ip"
      },
      "src_port": {
        "type": "integer"
      },
      "dst_port": {
        "type": "integer"
      },
      "protocol": {
        "type": "keyword"
      },
      "log_prefix": {
        "type": "keyword"
      },
      "service": {
        "type": "keyword"
      },
      "in_interface": {
        "type": "keyword"
      },
      "out_interface": {
        "type": "keyword"
      },
      "src_geoip": {
        "properties": {
          "location": {
            "type": "geo_point"
          },
          "country_name": {
            "type": "keyword"
          },
          "city_name": {
            "type": "keyword"
          }
        }
      },
      "dst_geoip": {
        "properties": {
          "location": {
            "type": "geo_point"
          },
          "country_name": {
            "type": "keyword"
          },
          "city_name": {
            "type": "keyword"
          }
        }
      }
    }
  }
}
EOF

    echo "Elasticsearch template created: $template_file"
}

# 创建 Kibana 仪表板配置
create_kibana_dashboard() {
    local dashboard_file="iptables-dashboard.json"
    
    echo "Creating Kibana dashboard configuration..."
    
    cat > "$dashboard_file" << 'EOF'
{
  "version": "7.10.0",
  "objects": [
    {
      "id": "iptables-overview",
      "type": "dashboard",
      "attributes": {
        "title": "iptables Firewall Overview",
        "description": "Overview of iptables firewall activity",
        "panelsJSON": "[]",
        "timeRestore": false,
        "version": 1
      }
    },
    {
      "id": "iptables-dropped-packets",
      "type": "visualization",
      "attributes": {
        "title": "Dropped Packets Over Time",
        "visState": {
          "title": "Dropped Packets Over Time",
          "type": "histogram",
          "params": {
            "grid": {
              "categoryLines": false,
              "style": {
                "color": "#eee"
              }
            },
            "categoryAxes": [
              {
                "id": "CategoryAxis-1",
                "type": "category",
                "position": "bottom",
                "show": true,
                "style": {},
                "scale": {
                  "type": "linear"
                },
                "labels": {
                  "show": true,
                  "truncate": 100
                },
                "title": {}
              }
            ],
            "valueAxes": [
              {
                "id": "ValueAxis-1",
                "name": "LeftAxis-1",
                "type": "value",
                "position": "left",
                "show": true,
                "style": {},
                "scale": {
                  "type": "linear",
                  "mode": "normal"
                },
                "labels": {
                  "show": true,
                  "rotate": 0,
                  "filter": false,
                  "truncate": 100
                },
                "title": {
                  "text": "Count"
                }
              }
            ],
            "seriesParams": [
              {
                "show": "true",
                "type": "histogram",
                "mode": "stacked",
                "data": {
                  "label": "Count",
                  "id": "1"
                },
                "valueAxis": "ValueAxis-1",
                "drawLinesBetweenPoints": true,
                "showCircles": true
              }
            ],
            "addTooltip": true,
            "addLegend": true,
            "legendPosition": "right",
            "times": [],
            "addTimeMarker": false
          },
          "aggs": [
            {
              "id": "1",
              "enabled": true,
              "type": "count",
              "schema": "metric",
              "params": {}
            },
            {
              "id": "2",
              "enabled": true,
              "type": "date_histogram",
              "schema": "segment",
              "params": {
                "field": "@timestamp",
                "interval": "auto",
                "customInterval": "2h",
                "min_doc_count": 1,
                "extended_bounds": {}
              }
            }
          ]
        },
        "uiStateJSON": "{}",
        "kibanaSavedObjectMeta": {
          "searchSourceJSON": {
            "index": "iptables-*",
            "query": {
              "match": {
                "log_prefix": "IPTABLES-DROP"
              }
            },
            "filter": []
          }
        }
      }
    }
  ]
}
EOF

    echo "Kibana dashboard configuration created: $dashboard_file"
    echo "Import this file in Kibana Management -> Saved Objects"
}

# 使用示例
case "${1:-help}" in
    "logstash")
        configure_logstash
        ;;
    "template")
        create_elasticsearch_template
        ;;
    "dashboard")
        create_kibana_dashboard
        ;;
    "all")
        configure_logstash
        create_elasticsearch_template
        create_kibana_dashboard
        ;;
    "help")
        echo "Usage: $0 <command>"
        echo "Commands:"
        echo "  logstash   - Configure Logstash for iptables"
        echo "  template   - Create Elasticsearch template"
        echo "  dashboard  - Create Kibana dashboard"
        echo "  all        - Create all configurations"
        ;;
    *)
        echo "Unknown command: $1"
        exit 1
        ;;
esac

12.4 与自动化工具集成

12.4.1 Ansible 集成

1. Ansible Playbook

# iptables-management.yml
---
- name: iptables Management Playbook
  hosts: all
  become: yes
  vars:
    iptables_rules_dir: "/etc/iptables"
    backup_dir: "/etc/iptables/backups"
    
  tasks:
    - name: Install iptables
      package:
        name: iptables
        state: present
        
    - name: Install iptables-persistent (Debian/Ubuntu)
      package:
        name: iptables-persistent
        state: present
      when: ansible_os_family == "Debian"
      
    - name: Create iptables directories
      file:
        path: "{{ item }}"
        state: directory
        mode: '0755'
      loop:
        - "{{ iptables_rules_dir }}"
        - "{{ backup_dir }}"
        
    - name: Backup current iptables rules
      shell: |
        iptables-save > {{ backup_dir }}/rules-backup-$(date +%Y%m%d-%H%M%S).rules
      changed_when: false
      
    - name: Copy iptables rules template
      template:
        src: iptables.rules.j2
        dest: "{{ iptables_rules_dir }}/rules.v4"
        backup: yes
        mode: '0644'
      notify: reload iptables
      
    - name: Validate iptables rules
      shell: iptables-restore --test < {{ iptables_rules_dir }}/rules.v4
      changed_when: false
      
    - name: Apply iptables rules
      shell: iptables-restore < {{ iptables_rules_dir }}/rules.v4
      notify: save iptables
      
    - name: Configure iptables service
      systemd:
        name: iptables
        enabled: yes
        state: started
      when: ansible_service_mgr == "systemd"
      
  handlers:
    - name: reload iptables
      shell: iptables-restore < {{ iptables_rules_dir }}/rules.v4
      
    - name: save iptables
      shell: |
        if command -v iptables-save >/dev/null 2>&1; then
          iptables-save > {{ iptables_rules_dir }}/rules.v4
        fi

2. Ansible 角色结构

#!/bin/bash
# create_ansible_role.sh

# 创建 Ansible 角色结构
create_ansible_role() {
    local role_name="iptables"
    local role_dir="roles/$role_name"
    
    echo "Creating Ansible role: $role_name"
    
    # 创建角色目录结构
    mkdir -p "$role_dir"/{tasks,handlers,templates,files,vars,defaults,meta}
    
    # 创建 tasks/main.yml
    cat > "$role_dir/tasks/main.yml" << 'EOF'
---
# tasks file for iptables

- name: Include OS-specific variables
  include_vars: "{{ ansible_os_family }}.yml"
  
- name: Install iptables packages
  package:
    name: "{{ iptables_packages }}"
    state: present
    
- name: Create iptables configuration directories
  file:
    path: "{{ item }}"
    state: directory
    mode: '0755'
  loop:
    - "{{ iptables_config_dir }}"
    - "{{ iptables_backup_dir }}"
    - "{{ iptables_scripts_dir }}"
    
- name: Backup current iptables rules
  shell: |
    timestamp=$(date +%Y%m%d-%H%M%S)
    iptables-save > {{ iptables_backup_dir }}/backup-$timestamp.rules
  changed_when: false
  tags: backup
  
- name: Copy iptables management scripts
  template:
    src: "{{ item.src }}"
    dest: "{{ item.dest }}"
    mode: '0755'
  loop:
    - { src: 'iptables-manager.sh.j2', dest: '{{ iptables_scripts_dir }}/iptables-manager.sh' }
    - { src: 'iptables-monitor.sh.j2', dest: '{{ iptables_scripts_dir }}/iptables-monitor.sh' }
  tags: scripts
  
- name: Generate iptables rules
  template:
    src: iptables.rules.j2
    dest: "{{ iptables_config_dir }}/rules.v4"
    backup: yes
    mode: '0644'
  notify:
    - validate iptables rules
    - reload iptables
  tags: rules
  
- name: Configure iptables service
  template:
    src: iptables.service.j2
    dest: /etc/systemd/system/iptables.service
    mode: '0644'
  notify:
    - reload systemd
    - restart iptables
  when: ansible_service_mgr == "systemd"
  tags: service
  
- name: Enable and start iptables service
  systemd:
    name: iptables
    enabled: yes
    state: started
    daemon_reload: yes
  when: ansible_service_mgr == "systemd"
  tags: service
EOF

    # 创建 handlers/main.yml
    cat > "$role_dir/handlers/main.yml" << 'EOF'
---
# handlers file for iptables

- name: validate iptables rules
  shell: iptables-restore --test < {{ iptables_config_dir }}/rules.v4
  
- name: reload iptables
  shell: |
    iptables-restore < {{ iptables_config_dir }}/rules.v4
  
- name: reload systemd
  systemd:
    daemon_reload: yes
    
- name: restart iptables
  systemd:
    name: iptables
    state: restarted
EOF

    # 创建 defaults/main.yml
    cat > "$role_dir/defaults/main.yml" << 'EOF'
---
# defaults file for iptables

# 基本配置
iptables_config_dir: "/etc/iptables"
iptables_backup_dir: "{{ iptables_config_dir }}/backups"
iptables_scripts_dir: "/usr/local/bin"

# 默认策略
iptables_default_input_policy: "DROP"
iptables_default_forward_policy: "DROP"
iptables_default_output_policy: "ACCEPT"

# 基本规则
iptables_allow_loopback: true
iptables_allow_established: true
iptables_allow_icmp: true

# SSH 配置
iptables_ssh_enabled: true
iptables_ssh_port: 22
iptables_ssh_allowed_ips: []

# HTTP/HTTPS 配置
iptables_web_enabled: false
iptables_http_port: 80
iptables_https_port: 443

# 自定义规则
iptables_custom_rules: []

# 日志配置
iptables_logging_enabled: true
iptables_log_prefix: "[IPTABLES]"
iptables_log_level: 4

# 连接跟踪配置
iptables_conntrack_max: 65536
iptables_conntrack_timeout_tcp: 432000
iptables_conntrack_timeout_udp: 30
EOF

    # 创建 vars/Debian.yml
    cat > "$role_dir/vars/Debian.yml" << 'EOF'
---
# Debian/Ubuntu specific variables

iptables_packages:
  - iptables
  - iptables-persistent
  - netfilter-persistent
EOF

    # 创建 vars/RedHat.yml
    cat > "$role_dir/vars/RedHat.yml" << 'EOF'
---
# RedHat/CentOS specific variables

iptables_packages:
  - iptables
  - iptables-services
EOF

    # 创建 templates/iptables.rules.j2
    cat > "$role_dir/templates/iptables.rules.j2" << 'EOF'
# Generated by Ansible - iptables rules
*filter
:INPUT {{ iptables_default_input_policy }} [0:0]
:FORWARD {{ iptables_default_forward_policy }} [0:0]
:OUTPUT {{ iptables_default_output_policy }} [0:0]

{% if iptables_allow_loopback %}
# Allow loopback traffic
-A INPUT -i lo -j ACCEPT
-A OUTPUT -o lo -j ACCEPT
{% endif %}

{% if iptables_allow_established %}
# Allow established and related connections
-A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
{% endif %}

{% if iptables_allow_icmp %}
# Allow ICMP
-A INPUT -p icmp -j ACCEPT
{% endif %}

{% if iptables_ssh_enabled %}
# SSH access
{% if iptables_ssh_allowed_ips %}
{% for ip in iptables_ssh_allowed_ips %}
-A INPUT -p tcp -s {{ ip }} --dport {{ iptables_ssh_port }} -j ACCEPT
{% endfor %}
{% else %}
-A INPUT -p tcp --dport {{ iptables_ssh_port }} -j ACCEPT
{% endif %}
{% endif %}

{% if iptables_web_enabled %}
# Web server access
-A INPUT -p tcp --dport {{ iptables_http_port }} -j ACCEPT
-A INPUT -p tcp --dport {{ iptables_https_port }} -j ACCEPT
{% endif %}

{% for rule in iptables_custom_rules %}
# {{ rule.comment | default('Custom rule') }}
{{ rule.rule }}
{% endfor %}

{% if iptables_logging_enabled %}
# Log dropped packets
-A INPUT -j LOG --log-prefix "{{ iptables_log_prefix }}-DROP " --log-level {{ iptables_log_level }}
{% endif %}

COMMIT
EOF

    # 创建 meta/main.yml
    cat > "$role_dir/meta/main.yml" << 'EOF'
---
galaxy_info:
  author: System Administrator
  description: Ansible role for managing iptables firewall
  company: 
  license: MIT
  min_ansible_version: 2.9
  platforms:
    - name: Ubuntu
      versions:
        - bionic
        - focal
        - jammy
    - name: Debian
      versions:
        - buster
        - bullseye
    - name: EL
      versions:
        - 7
        - 8
        - 9
  galaxy_tags:
    - firewall
    - iptables
    - security
    - networking

dependencies: []
EOF

    echo "Ansible role created successfully: $role_dir"
    echo "Role structure:"
    find "$role_dir" -type f | sort
}

# 使用示例
case "${1:-help}" in
    "create")
        create_ansible_role
        ;;
    "help")
        echo "Usage: $0 <command>"
        echo "Commands:"
        echo "  create  - Create Ansible role for iptables"
        ;;
    *)
        echo "Unknown command: $1"
        exit 1
        ;;
esac

12.4.2 Terraform 集成

1. Terraform 模块

# main.tf
terraform {
  required_version = ">= 0.14"
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 4.0"
    }
  }
}

# 安全组模块
module "iptables_security_group" {
  source = "./modules/security-group"
  
  name_prefix = var.name_prefix
  vpc_id      = var.vpc_id
  
  # SSH 访问
  ssh_enabled    = var.ssh_enabled
  ssh_port       = var.ssh_port
  ssh_cidr_blocks = var.ssh_cidr_blocks
  
  # Web 访问
  web_enabled     = var.web_enabled
  http_port       = var.http_port
  https_port      = var.https_port
  web_cidr_blocks = var.web_cidr_blocks
  
  # 自定义规则
  custom_ingress_rules = var.custom_ingress_rules
  custom_egress_rules  = var.custom_egress_rules
  
  tags = var.tags
}

# EC2 实例配置
resource "aws_instance" "firewall_instance" {
  count = var.instance_count
  
  ami           = var.ami_id
  instance_type = var.instance_type
  key_name      = var.key_name
  
  vpc_security_group_ids = [module.iptables_security_group.security_group_id]
  subnet_id              = var.subnet_id
  
  user_data = templatefile("${path.module}/templates/user_data.sh", {
    iptables_rules = var.iptables_rules
    log_level      = var.log_level
    monitoring_enabled = var.monitoring_enabled
  })
  
  tags = merge(var.tags, {
    Name = "${var.name_prefix}-firewall-${count.index + 1}"
    Role = "firewall"
  })
}

# CloudWatch 日志组
resource "aws_cloudwatch_log_group" "iptables_logs" {
  count = var.monitoring_enabled ? 1 : 0
  
  name              = "/aws/ec2/iptables/${var.name_prefix}"
  retention_in_days = var.log_retention_days
  
  tags = var.tags
}

# CloudWatch 日志流
resource "aws_cloudwatch_log_stream" "iptables_stream" {
  count = var.monitoring_enabled ? var.instance_count : 0
  
  name           = "instance-${count.index + 1}"
  log_group_name = aws_cloudwatch_log_group.iptables_logs[0].name
}

12.5 本章小结

12.5.1 集成要点回顾

本章详细介绍了 iptables 与各种系统和工具的集成方法:

  1. 系统服务集成

    • systemd 服务配置和管理
    • 传统 init 系统配置
    • 开机自启动和服务管理
  2. 监控工具集成

    • Nagios 插件开发和配置
    • Zabbix 监控参数和模板
    • 性能指标收集和告警
  3. 日志系统集成

    • rsyslog 配置和日志分析
    • ELK Stack 集成和可视化
    • 日志轮转和存储管理
  4. 自动化工具集成

    • Ansible 角色和 Playbook
    • Terraform 基础设施即代码
    • 配置管理和部署自动化

12.5.2 最佳实践建议

  1. 服务管理

    • 使用 systemd 管理 iptables 服务
    • 实现规则的自动备份和恢复
    • 配置服务依赖关系
  2. 监控策略

    • 监控规则数量和性能
    • 跟踪连接状态和资源使用
    • 设置合理的告警阈值
  3. 日志管理

    • 结构化日志记录
    • 实时日志分析和告警
    • 长期日志存储和归档
  4. 自动化部署

    • 版本控制配置文件
    • 自动化测试和验证
    • 渐进式部署策略

12.5.3 集成检查清单

  • [ ] 配置 systemd 服务管理
  • [ ] 设置监控和告警
  • [ ] 配置日志收集和分析
  • [ ] 实现自动化部署
  • [ ] 建立备份和恢复机制
  • [ ] 配置性能监控
  • [ ] 设置安全事件响应
  • [ ] 文档化集成流程

12.5.4 下一章预告

下一章我们将进入 iptables 教程的总结部分,回顾整个学习过程,总结最佳实践,并提供进阶学习建议。


练习与思考

理论练习

  1. 集成架构设计

    • 设计一个完整的 iptables 监控架构
    • 规划日志收集和分析流程
    • 制定自动化部署策略
  2. 工具选择分析

    • 比较不同监控工具的优缺点
    • 分析各种日志系统的适用场景
    • 评估自动化工具的集成复杂度

实践练习

  1. 监控系统搭建

    • 配置 Nagios 或 Zabbix 监控 iptables
    • 创建自定义监控脚本
    • 设置告警通知机制
  2. 日志分析系统

    • 搭建 ELK Stack 处理 iptables 日志
    • 创建 Kibana 仪表板
    • 实现实时日志分析
  3. 自动化部署

    • 编写 Ansible Playbook 管理 iptables
    • 使用 Terraform 部署云环境
    • 实现 CI/CD 流水线

思考题

  1. 如何设计一个高可用的 iptables 管理系统?
  2. 在大规模环境中如何优化 iptables 监控性能?
  3. 如何实现 iptables 配置的版本控制和回滚?
  4. 怎样设计 iptables 的灾难恢复方案?
  5. 如何在容器化环境中集成 iptables 管理?

12.1.2 开机自启动配置

1. 传统 init 系统配置

#!/bin/bash
# init_system_config.sh

# 为传统 init 系统配置 iptables
configure_init_system() {
    local init_script="/etc/init.d/iptables"
    local config_file="/etc/sysconfig/iptables"
    
    echo "Configuring iptables for traditional init system..."
    
    # 创建配置目录
    mkdir -p /etc/sysconfig
    
    # 创建 init 脚本
    cat > "$init_script" << 'EOF'
#!/bin/bash
# iptables        iptables firewall
#
# chkconfig: 35 08 92
# description: Starts, stops and saves iptables firewall
#
# config: /etc/sysconfig/iptables
# config: /etc/sysconfig/iptables-config

. /etc/rc.d/init.d/functions

IPTABLES=iptables
IPTABLES_DATA=/etc/sysconfig/$IPTABLES
IPTABLES_CONFIG=/etc/sysconfig/${IPTABLES}-config
VAR_SUBSYS_IPTABLES=/var/lock/subsys/$IPTABLES

# 加载配置
if [ -f "$IPTABLES_CONFIG" ]; then
    . "$IPTABLES_CONFIG"
fi

# 默认配置
IPTABLES_SAVE_ON_STOP=${IPTABLES_SAVE_ON_STOP:-"no"}
IPTABLES_SAVE_ON_RESTART=${IPTABLES_SAVE_ON_RESTART:-"no"}
IPTABLES_SAVE_COUNTER=${IPTABLES_SAVE_COUNTER:-"no"}
IPTABLES_STATUS_NUMERIC=${IPTABLES_STATUS_NUMERIC:-"yes"}
IPTABLES_STATUS_VERBOSE=${IPTABLES_STATUS_VERBOSE:-"no"}
IPTABLES_STATUS_LINENUMBERS=${IPTABLES_STATUS_LINENUMBERS:-"yes"}

# 函数定义
start() {
    [ "$EUID" != "0" ] && exit 4
    [ -x /sbin/$IPTABLES ] || exit 5
    
    # 检查配置文件
    if [ ! -f "$IPTABLES_DATA" ]; then
        echo -n $"${IPTABLES}: No config file found."
        warning
        echo
        return 6
    fi
    
    echo -n $"Starting $IPTABLES: "
    
    # 应用规则
    if /sbin/${IPTABLES}-restore < "$IPTABLES_DATA"; then
        touch $VAR_SUBSYS_IPTABLES
        success
    else
        failure
    fi
    echo
}

stop() {
    [ "$EUID" != "0" ] && exit 4
    
    echo -n $"Stopping $IPTABLES: "
    
    # 保存规则(如果配置了)
    if [ "$IPTABLES_SAVE_ON_STOP" = "yes" ]; then
        save
    fi
    
    # 清空规则
    /sbin/$IPTABLES -F
    /sbin/$IPTABLES -X
    /sbin/$IPTABLES -t nat -F
    /sbin/$IPTABLES -t nat -X
    /sbin/$IPTABLES -t mangle -F
    /sbin/$IPTABLES -t mangle -X
    /sbin/$IPTABLES -P INPUT ACCEPT
    /sbin/$IPTABLES -P FORWARD ACCEPT
    /sbin/$IPTABLES -P OUTPUT ACCEPT
    
    rm -f $VAR_SUBSYS_IPTABLES
    success
    echo
}

restart() {
    # 保存规则(如果配置了)
    if [ "$IPTABLES_SAVE_ON_RESTART" = "yes" ]; then
        save
    fi
    
    stop
    start
}

reload() {
    restart
}

save() {
    [ "$EUID" != "0" ] && exit 4
    
    echo -n $"Saving firewall rules to $IPTABLES_DATA: "
    
    # 备份现有配置
    if [ -f "$IPTABLES_DATA" ]; then
        cp "$IPTABLES_DATA" "${IPTABLES_DATA}.backup.$(date +%Y%m%d_%H%M%S)"
    fi
    
    # 保存规则
    if [ "$IPTABLES_SAVE_COUNTER" = "yes" ]; then
        /sbin/${IPTABLES}-save > "$IPTABLES_DATA"
    else
        /sbin/${IPTABLES}-save | sed '/^:/s/\[[0-9]*:[0-9]*\]/[0:0]/' > "$IPTABLES_DATA"
    fi
    
    if [ $? -eq 0 ]; then
        success
    else
        failure
    fi
    echo
}

status() {
    if [ ! -f $VAR_SUBSYS_IPTABLES ]; then
        echo $"Firewall is stopped."
        return 3
    fi
    
    # 构建状态命令
    local status_cmd="/sbin/$IPTABLES -L"
    
    if [ "$IPTABLES_STATUS_NUMERIC" = "yes" ]; then
        status_cmd="$status_cmd -n"
    fi
    
    if [ "$IPTABLES_STATUS_VERBOSE" = "yes" ]; then
        status_cmd="$status_cmd -v"
    fi
    
    if [ "$IPTABLES_STATUS_LINENUMBERS" = "yes" ]; then
        status_cmd="$status_cmd --line-numbers"
    fi
    
    echo $"Table: filter"
    $status_cmd
    
    echo $"Table: nat"
    /sbin/$IPTABLES -t nat -L -n
    
    echo $"Table: mangle"
    /sbin/$IPTABLES -t mangle -L -n
    
    return 0
}

case "$1" in
    start)
        start
        ;;
    stop)
        stop
        ;;
    restart)
        restart
        ;;
    reload)
        reload
        ;;
    save)
        save
        ;;
    status)
        status
        ;;
    *)
        echo $"Usage: $0 {start|stop|restart|reload|save|status}"
        exit 2
        ;;
esac

exit $?
EOF

    # 设置脚本权限
    chmod +x "$init_script"
    
    # 创建配置文件
    cat > "${config_file}-config" << 'EOF'
# iptables configuration file

# Save current firewall rules on stop.
# Value: yes|no,  default: no
IPTABLES_SAVE_ON_STOP="no"

# Save current firewall rules on restart.
# Value: yes|no,  default: no
IPTABLES_SAVE_ON_RESTART="no"

# Save (and restore) rule and chain counter.
# Value: yes|no,  default: no
IPTABLES_SAVE_COUNTER="no"

# Numeric status output
# Value: yes|no,  default: yes
IPTABLES_STATUS_NUMERIC="yes"

# Verbose status output
# Value: yes|no,  default: no
IPTABLES_STATUS_VERBOSE="no"

# Status output with numbered lines
# Value: yes|no,  default: yes
IPTABLES_STATUS_LINENUMBERS="yes"
EOF

    # 保存当前规则
    if [ ! -f "$config_file" ]; then
        echo "Saving current iptables rules..."
        iptables-save > "$config_file"
    fi
    
    # 配置开机自启动
    if command -v chkconfig >/dev/null 2>&1; then
        chkconfig --add iptables
        chkconfig iptables on
        echo "iptables service added to chkconfig"
    elif command -v update-rc.d >/dev/null 2>&1; then
        update-rc.d iptables defaults
        echo "iptables service added to update-rc.d"
    fi
    
    echo "Traditional init system configuration completed"
    echo "Init script: $init_script"
    echo "Config file: $config_file"
    echo "Config options: ${config_file}-config"
}

# 使用示例
case "${1:-help}" in
    "configure")
        configure_init_system
        ;;
    "help")
        echo "Usage: $0 <command>"
        echo "Commands:"
        echo "  configure  - Configure iptables for traditional init system"
        ;;
    *)
        echo "Unknown command: $1"
        exit 1
        ;;
esac

12.2 与监控工具集成

12.2.1 Nagios 监控集成

1. Nagios 插件开发

#!/bin/bash
# check_iptables.sh - Nagios plugin for iptables monitoring

# Nagios 返回码
OK=0
WARNING=1
CRITICAL=2
UNKNOWN=3

# 默认阈值
WARN_CONN_PERCENT=80
CRIT_CONN_PERCENT=90
WARN_RULES_COUNT=500
CRIT_RULES_COUNT=1000

# 帮助信息
show_help() {
    cat << EOF
Usage: $0 [OPTIONS]

Nagios plugin to monitor iptables firewall status

Options:
  -h, --help              Show this help message
  -t, --type TYPE         Check type: rules|connections|status|performance
  -w, --warning VALUE     Warning threshold
  -c, --critical VALUE    Critical threshold
  -r, --rules-file FILE   Rules file to compare against
  -v, --verbose           Verbose output

Check types:
  rules       - Check rule count and syntax
  connections - Check connection tracking usage
  status      - Check overall firewall status
  performance - Check firewall performance metrics

Examples:
  $0 -t rules -w 500 -c 1000
  $0 -t connections -w 80 -c 90
  $0 -t status
  $0 -t performance
EOF
}

# 解析命令行参数
parse_args() {
    while [[ $# -gt 0 ]]; do
        case $1 in
            -h|--help)
                show_help
                exit $OK
                ;;
            -t|--type)
                CHECK_TYPE="$2"
                shift 2
                ;;
            -w|--warning)
                WARNING_THRESHOLD="$2"
                shift 2
                ;;
            -c|--critical)
                CRITICAL_THRESHOLD="$2"
                shift 2
                ;;
            -r|--rules-file)
                RULES_FILE="$2"
                shift 2
                ;;
            -v|--verbose)
                VERBOSE=1
                shift
                ;;
            *)
                echo "Unknown option: $1"
                exit $UNKNOWN
                ;;
        esac
    done
}

# 检查规则
check_rules() {
    local warn_threshold=${WARNING_THRESHOLD:-$WARN_RULES_COUNT}
    local crit_threshold=${CRITICAL_THRESHOLD:-$CRIT_RULES_COUNT}
    
    # 获取规则数量
    local total_rules=$(iptables-save | grep "^-A" | wc -l)
    
    # 检查规则语法
    local syntax_errors=0
    if [ -n "$RULES_FILE" ] && [ -f "$RULES_FILE" ]; then
        if ! iptables-restore --test < "$RULES_FILE" 2>/dev/null; then
            syntax_errors=1
        fi
    fi
    
    # 性能数据
    local perfdata="rules=$total_rules;$warn_threshold;$crit_threshold;0;"
    
    # 状态判断
    if [ $syntax_errors -gt 0 ]; then
        echo "CRITICAL - Rules syntax error in $RULES_FILE | $perfdata"
        exit $CRITICAL
    elif [ $total_rules -ge $crit_threshold ]; then
        echo "CRITICAL - Too many rules: $total_rules (>= $crit_threshold) | $perfdata"
        exit $CRITICAL
    elif [ $total_rules -ge $warn_threshold ]; then
        echo "WARNING - High rule count: $total_rules (>= $warn_threshold) | $perfdata"
        exit $WARNING
    else
        echo "OK - Rules count: $total_rules | $perfdata"
        exit $OK
    fi
}

# 检查连接跟踪
check_connections() {
    local warn_threshold=${WARNING_THRESHOLD:-$WARN_CONN_PERCENT}
    local crit_threshold=${CRITICAL_THRESHOLD:-$CRIT_CONN_PERCENT}
    
    # 检查连接跟踪是否可用
    if [ ! -f /proc/net/nf_conntrack ]; then
        echo "UNKNOWN - Connection tracking not available"
        exit $UNKNOWN
    fi
    
    # 获取连接统计
    local current_conn=$(cat /proc/net/nf_conntrack | wc -l)
    local max_conn=$(cat /proc/sys/net/netfilter/nf_conntrack_max)
    local usage_percent=$((current_conn * 100 / max_conn))
    
    # 性能数据
    local perfdata="connections=$current_conn;$((max_conn * warn_threshold / 100));$((max_conn * crit_threshold / 100));0;$max_conn usage=${usage_percent}%;$warn_threshold;$crit_threshold;0;100"
    
    # 状态判断
    if [ $usage_percent -ge $crit_threshold ]; then
        echo "CRITICAL - Connection table usage: ${usage_percent}% ($current_conn/$max_conn) | $perfdata"
        exit $CRITICAL
    elif [ $usage_percent -ge $warn_threshold ]; then
        echo "WARNING - Connection table usage: ${usage_percent}% ($current_conn/$max_conn) | $perfdata"
        exit $WARNING
    else
        echo "OK - Connection table usage: ${usage_percent}% ($current_conn/$max_conn) | $perfdata"
        exit $OK
    fi
}

# 检查整体状态
check_status() {
    local issues=0
    local warnings=0
    local status_msg=""
    
    # 检查 iptables 是否运行
    if ! iptables -L >/dev/null 2>&1; then
        echo "CRITICAL - iptables not accessible"
        exit $CRITICAL
    fi
    
    # 检查规则数量
    local total_rules=$(iptables-save | grep "^-A" | wc -l)
    if [ $total_rules -eq 0 ]; then
        issues=$((issues + 1))
        status_msg="${status_msg}No rules loaded; "
    fi
    
    # 检查默认策略
    for chain in INPUT OUTPUT FORWARD; do
        local policy=$(iptables -L "$chain" -n | head -1 | awk '{print $4}' | tr -d '()')
        if [ "$policy" = "ACCEPT" ]; then
            warnings=$((warnings + 1))
            status_msg="${status_msg}$chain policy is ACCEPT; "
        fi
    done
    
    # 检查连接跟踪
    if [ -f /proc/net/nf_conntrack ]; then
        local current_conn=$(cat /proc/net/nf_conntrack | wc -l)
        local max_conn=$(cat /proc/sys/net/netfilter/nf_conntrack_max)
        local usage_percent=$((current_conn * 100 / max_conn))
        
        if [ $usage_percent -ge 90 ]; then
            issues=$((issues + 1))
            status_msg="${status_msg}Connection table near full (${usage_percent}%); "
        elif [ $usage_percent -ge 80 ]; then
            warnings=$((warnings + 1))
            status_msg="${status_msg}High connection usage (${usage_percent}%); "
        fi
    fi
    
    # 性能数据
    local perfdata="rules=$total_rules;;;0; issues=$issues;;;0; warnings=$warnings;;;0;"
    
    # 状态判断
    if [ $issues -gt 0 ]; then
        echo "CRITICAL - $status_msg| $perfdata"
        exit $CRITICAL
    elif [ $warnings -gt 0 ]; then
        echo "WARNING - $status_msg| $perfdata"
        exit $WARNING
    else
        echo "OK - Firewall status normal, $total_rules rules active | $perfdata"
        exit $OK
    fi
}

# 检查性能
check_performance() {
    local start_time=$(date +%s.%N)
    
    # 执行性能测试
    local rule_lookup_time
    local conn_lookup_time
    
    # 测试规则查找时间
    local lookup_start=$(date +%s.%N)
    iptables -L >/dev/null 2>&1
    local lookup_end=$(date +%s.%N)
    rule_lookup_time=$(echo "$lookup_end - $lookup_start" | bc)
    
    # 测试连接跟踪查找时间
    if [ -f /proc/net/nf_conntrack ]; then
        local conn_start=$(date +%s.%N)
        cat /proc/net/nf_conntrack >/dev/null 2>&1
        local conn_end=$(date +%s.%N)
        conn_lookup_time=$(echo "$conn_end - $conn_start" | bc)
    else
        conn_lookup_time=0
    fi
    
    local total_time=$(date +%s.%N)
    total_time=$(echo "$total_time - $start_time" | bc)
    
    # 转换为毫秒
    rule_lookup_ms=$(echo "$rule_lookup_time * 1000" | bc | cut -d. -f1)
    conn_lookup_ms=$(echo "$conn_lookup_time * 1000" | bc | cut -d. -f1)
    total_ms=$(echo "$total_time * 1000" | bc | cut -d. -f1)
    
    # 性能数据
    local perfdata="rule_lookup=${rule_lookup_ms}ms;;;0; conn_lookup=${conn_lookup_ms}ms;;;0; total_time=${total_ms}ms;;;0;"
    
    # 状态判断(基于响应时间)
    if [ $total_ms -gt 5000 ]; then
        echo "CRITICAL - Slow performance: ${total_ms}ms total response time | $perfdata"
        exit $CRITICAL
    elif [ $total_ms -gt 2000 ]; then
        echo "WARNING - Moderate performance: ${total_ms}ms total response time | $perfdata"
        exit $WARNING
    else
        echo "OK - Good performance: ${total_ms}ms total response time | $perfdata"
        exit $OK
    fi
}

# 主函数
main() {
    # 检查是否为 root
    if [ "$EUID" -ne 0 ]; then
        echo "UNKNOWN - This plugin requires root privileges"
        exit $UNKNOWN
    fi
    
    # 检查 iptables 是否安装
    if ! command -v iptables >/dev/null 2>&1; then
        echo "UNKNOWN - iptables not found"
        exit $UNKNOWN
    fi
    
    # 解析参数
    parse_args "$@"
    
    # 执行检查
    case "${CHECK_TYPE:-status}" in
        "rules")
            check_rules
            ;;
        "connections")
            check_connections
            ;;
        "status")
            check_status
            ;;
        "performance")
            check_performance
            ;;
        *)
            echo "UNKNOWN - Invalid check type: $CHECK_TYPE"
            exit $UNKNOWN
            ;;
    esac
}

# 执行主函数
main "$@"

2. Nagios 配置文件

#!/bin/bash
# create_nagios_config.sh

# 创建 Nagios 配置
create_nagios_config() {
    local nagios_dir="/etc/nagios3"
    local plugin_dir="/usr/lib/nagios/plugins"
    
    echo "Creating Nagios configuration for iptables monitoring..."
    
    # 创建命令定义
    cat > "$nagios_dir/conf.d/iptables-commands.cfg" << 'EOF'
# iptables monitoring commands

define command {
    command_name    check_iptables_rules
    command_line    $USER1$/check_iptables.sh -t rules -w $ARG1$ -c $ARG2$
}

define command {
    command_name    check_iptables_connections
    command_line    $USER1$/check_iptables.sh -t connections -w $ARG1$ -c $ARG2$
}

define command {
    command_name    check_iptables_status
    command_line    $USER1$/check_iptables.sh -t status
}

define command {
    command_name    check_iptables_performance
    command_line    $USER1$/check_iptables.sh -t performance
}

define command {
    command_name    check_iptables_rules_file
    command_line    $USER1$/check_iptables.sh -t rules -r $ARG1$ -w $ARG2$ -c $ARG3$
}
EOF

    # 创建服务模板
    cat > "$nagios_dir/conf.d/iptables-services.cfg" << 'EOF'
# iptables service templates

define service {
    name                    iptables-service
    use                     generic-service
    check_interval          5
    retry_interval          1
    max_check_attempts      3
    notification_interval   30
    notification_period     24x7
    notification_options    w,u,c,r
    contact_groups          admins
    register                0
}

# iptables rules monitoring
define service {
    use                     iptables-service
    host_name               localhost
    service_description     iptables Rules Count
    check_command           check_iptables_rules!500!1000
    notes                   Monitor iptables rule count
}

# Connection tracking monitoring
define service {
    use                     iptables-service
    host_name               localhost
    service_description     iptables Connection Tracking
    check_command           check_iptables_connections!80!90
    notes                   Monitor connection tracking table usage
}

# Overall status monitoring
define service {
    use                     iptables-service
    host_name               localhost
    service_description     iptables Status
    check_command           check_iptables_status
    notes                   Monitor overall iptables firewall status
}

# Performance monitoring
define service {
    use                     iptables-service
    host_name               localhost
    service_description     iptables Performance
    check_command           check_iptables_performance
    check_interval          10
    notes                   Monitor iptables performance metrics
}
EOF

    # 创建主机组
    cat > "$nagios_dir/conf.d/iptables-hostgroups.cfg" << 'EOF'
# iptables monitoring host groups

define hostgroup {
    hostgroup_name          firewall-servers
    alias                   Firewall Servers
    members                 localhost
}
EOF

    # 复制插件
    if [ -f "check_iptables.sh" ]; then
        cp check_iptables.sh "$plugin_dir/"
        chmod +x "$plugin_dir/check_iptables.sh"
        echo "Plugin copied to: $plugin_dir/check_iptables.sh"
    fi
    
    echo "Nagios configuration created successfully"
    echo "Configuration files:"
    echo "  Commands: $nagios_dir/conf.d/iptables-commands.cfg"
    echo "  Services: $nagios_dir/conf.d/iptables-services.cfg"
    echo "  Host groups: $nagios_dir/conf.d/iptables-hostgroups.cfg"
    echo
    echo "To apply configuration:"
    echo "  1. Verify configuration: nagios3 -v /etc/nagios3/nagios.cfg"
    echo "  2. Restart Nagios: systemctl restart nagios3"
}

# 使用示例
case "${1:-help}" in
    "create")
        create_nagios_config
        ;;
    "help")
        echo "Usage: $0 <command>"
        echo "Commands:"
        echo "  create  - Create Nagios configuration for iptables"
        ;;
    *)
        echo "Unknown command: $1"
        exit 1
        ;;
esac

12.2.2 Zabbix 监控配置

1. Zabbix 用户参数配置

#!/bin/bash
# zabbix_iptables_config.sh

# 创建 Zabbix iptables 监控配置
create_zabbix_config() {
    local zabbix_conf_dir="/etc/zabbix"
    local scripts_dir="/usr/local/bin/zabbix-scripts"
    
    echo "Creating Zabbix configuration for iptables monitoring..."
    
    # 创建脚本目录
    mkdir -p "$scripts_dir"
    
    # 创建监控脚本
    cat > "$scripts_dir/iptables_monitor.sh" << 'EOF'
#!/bin/bash
# iptables_monitor.sh - Zabbix monitoring script for iptables

# 获取规则数量
get_rules_count() {
    local table="${1:-filter}"
    case "$table" in
        "filter")
            iptables -t filter -L | grep -c "^Chain\|^target"
            ;;
        "nat")
            iptables -t nat -L | grep -c "^Chain\|^target"
            ;;
        "mangle")
            iptables -t mangle -L | grep -c "^Chain\|^target"
            ;;
        "raw")
            iptables -t raw -L | grep -c "^Chain\|^target"
            ;;
        "total")
            iptables-save | grep "^-A" | wc -l
            ;;
        *)
            echo "0"
            ;;
    esac
}

# 获取连接跟踪信息
get_conntrack_info() {
    local metric="$1"
    
    if [ ! -f /proc/net/nf_conntrack ]; then
        echo "0"
        return
    fi
    
    case "$metric" in
        "current")
            cat /proc/net/nf_conntrack | wc -l
            ;;
        "max")
            cat /proc/sys/net/netfilter/nf_conntrack_max
            ;;
        "usage_percent")
            local current=$(cat /proc/net/nf_conntrack | wc -l)
            local max=$(cat /proc/sys/net/netfilter/nf_conntrack_max)
            echo "scale=2; $current * 100 / $max" | bc
            ;;
        "tcp_established")
            grep "tcp.*ESTABLISHED" /proc/net/nf_conntrack | wc -l
            ;;
        "tcp_time_wait")
            grep "tcp.*TIME_WAIT" /proc/net/nf_conntrack | wc -l
            ;;
        "udp_connections")
            grep "udp" /proc/net/nf_conntrack | wc -l
            ;;
        *)
            echo "0"
            ;;
    esac
}

# 获取链统计信息
get_chain_stats() {
    local table="$1"
    local chain="$2"
    local metric="$3"
    
    local stats=$(iptables -t "$table" -L "$chain" -n -v --line-numbers | grep "^Chain" -A 1000 | tail -n +2)
    
    case "$metric" in
        "packets")
            echo "$stats" | awk '{sum += $1} END {print sum+0}'
            ;;
        "bytes")
            echo "$stats" | awk '{sum += $2} END {print sum+0}'
            ;;
        "rules_count")
            echo "$stats" | grep -v "^$" | wc -l
            ;;
        *)
            echo "0"
            ;;
    esac
}

# 获取性能指标
get_performance_metrics() {
    local metric="$1"
    
    case "$metric" in
        "rule_lookup_time")
            local start=$(date +%s.%N)
            iptables -L >/dev/null 2>&1
            local end=$(date +%s.%N)
            echo "scale=3; ($end - $start) * 1000" | bc
            ;;
        "conntrack_lookup_time")
            if [ -f /proc/net/nf_conntrack ]; then
                local start=$(date +%s.%N)
                cat /proc/net/nf_conntrack >/dev/null 2>&1
                local end=$(date +%s.%N)
                echo "scale=3; ($end - $start) * 1000" | bc
            else
                echo "0"
            fi
            ;;
        "memory_usage")
            # 估算 iptables 内存使用
            local rules_count=$(iptables-save | grep "^-A" | wc -l)
            local conn_count=$(cat /proc/net/nf_conntrack 2>/dev/null | wc -l)
            # 粗略估算:每个规则约 100 字节,每个连接约 300 字节
            echo "scale=0; ($rules_count * 100 + $conn_count * 300) / 1024" | bc
            ;;
        *)
            echo "0"
            ;;
    esac
}

# 检查防火墙状态
check_firewall_status() {
    local check="$1"
    
    case "$check" in
        "running")
            if iptables -L >/dev/null 2>&1; then
                echo "1"
            else
                echo "0"
            fi
            ;;
        "rules_loaded")
            local rules_count=$(iptables-save | grep "^-A" | wc -l)
            if [ $rules_count -gt 0 ]; then
                echo "1"
            else
                echo "0"
            fi
            ;;
        "default_policy_secure")
            local secure=1
            for chain in INPUT FORWARD; do
                local policy=$(iptables -L "$chain" -n | head -1 | awk '{print $4}' | tr -d '()')
                if [ "$policy" = "ACCEPT" ]; then
                    secure=0
                    break
                fi
            done
            echo "$secure"
            ;;
        *)
            echo "0"
            ;;
    esac
}

# 主函数
main() {
    local category="$1"
    local subcategory="$2"
    local metric="$3"
    
    case "$category" in
        "rules")
            get_rules_count "$subcategory"
            ;;
        "conntrack")
            get_conntrack_info "$subcategory"
            ;;
        "chain")
            get_chain_stats "$subcategory" "$metric" "$4"
            ;;
        "performance")
            get_performance_metrics "$subcategory"
            ;;
        "status")
            check_firewall_status "$subcategory"
            ;;
        *)
            echo "Usage: $0 {rules|conntrack|chain|performance|status} [subcategory] [metric]"
            exit 1
            ;;
    esac
}

# 执行主函数
main "$@"
EOF

    # 设置脚本权限
    chmod +x "$scripts_dir/iptables_monitor.sh"
    
    # 创建 Zabbix 用户参数配置
    cat > "$zabbix_conf_dir/zabbix_agentd.d/iptables.conf" << EOF
# iptables monitoring user parameters

# Rules monitoring
UserParameter=iptables.rules.total,$scripts_dir/iptables_monitor.sh rules total
UserParameter=iptables.rules.filter,$scripts_dir/iptables_monitor.sh rules filter
UserParameter=iptables.rules.nat,$scripts_dir/iptables_monitor.sh rules nat
UserParameter=iptables.rules.mangle,$scripts_dir/iptables_monitor.sh rules mangle
UserParameter=iptables.rules.raw,$scripts_dir/iptables_monitor.sh rules raw

# Connection tracking monitoring
UserParameter=iptables.conntrack.current,$scripts_dir/iptables_monitor.sh conntrack current
UserParameter=iptables.conntrack.max,$scripts_dir/iptables_monitor.sh conntrack max
UserParameter=iptables.conntrack.usage_percent,$scripts_dir/iptables_monitor.sh conntrack usage_percent
UserParameter=iptables.conntrack.tcp_established,$scripts_dir/iptables_monitor.sh conntrack tcp_established
UserParameter=iptables.conntrack.tcp_time_wait,$scripts_dir/iptables_monitor.sh conntrack tcp_time_wait
UserParameter=iptables.conntrack.udp_connections,$scripts_dir/iptables_monitor.sh conntrack udp_connections

# Chain statistics
UserParameter=iptables.chain.packets[*],$scripts_dir/iptables_monitor.sh chain \$1 \$2 packets
UserParameter=iptables.chain.bytes[*],$scripts_dir/iptables_monitor.sh chain \$1 \$2 bytes
UserParameter=iptables.chain.rules_count[*],$scripts_dir/iptables_monitor.sh chain \$1 \$2 rules_count

# Performance monitoring
UserParameter=iptables.performance.rule_lookup_time,$scripts_dir/iptables_monitor.sh performance rule_lookup_time
UserParameter=iptables.performance.conntrack_lookup_time,$scripts_dir/iptables_monitor.sh performance conntrack_lookup_time
UserParameter=iptables.performance.memory_usage,$scripts_dir/iptables_monitor.sh performance memory_usage

# Status monitoring
UserParameter=iptables.status.running,$scripts_dir/iptables_monitor.sh status running
UserParameter=iptables.status.rules_loaded,$scripts_dir/iptables_monitor.sh status rules_loaded
UserParameter=iptables.status.default_policy_secure,$scripts_dir/iptables_monitor.sh status default_policy_secure

# Discovery rules
UserParameter=iptables.discovery.chains,$scripts_dir/iptables_discovery.sh chains
UserParameter=iptables.discovery.tables,$scripts_dir/iptables_discovery.sh tables
EOF

    # 创建发现脚本
    cat > "$scripts_dir/iptables_discovery.sh" << 'EOF'
#!/bin/bash
# iptables_discovery.sh - Zabbix discovery script for iptables

# 发现链
discover_chains() {
    local tables=("filter" "nat" "mangle" "raw")
    local json_data='{"data":['
    local first=true
    
    for table in "${tables[@]}"; do
        local chains=$(iptables -t "$table" -L | grep "^Chain" | awk '{print $2}')
        
        for chain in $chains; do
            if [ "$first" = true ]; then
                first=false
            else
                json_data="$json_data,"
            fi
            
            json_data="$json_data{\"{#TABLE}\":\"$table\",\"{#CHAIN}\":\"$chain\"}"
        done
    done
    
    json_data="$json_data]}"
    echo "$json_data"
}

# 发现表
discover_tables() {
    local tables=("filter" "nat" "mangle" "raw")
    local json_data='{"data":['
    local first=true
    
    for table in "${tables[@]}"; do
        if [ "$first" = true ]; then
            first=false
        else
            json_data="$json_data,"
        fi
        
        json_data="$json_data{\"{#TABLE}\":\"$table\"}"
    done
    
    json_data="$json_data]}"
    echo "$json_data"
}

# 主函数
case "${1:-help}" in
    "chains")
        discover_chains
        ;;
    "tables")
        discover_tables
        ;;
    "help")
        echo "Usage: $0 {chains|tables}"
        ;;
    *)
        echo "Unknown command: $1"
        exit 1
        ;;
esac
EOF

    # 设置脚本权限
    chmod +x "$scripts_dir/iptables_discovery.sh"
    
    echo "Zabbix configuration created successfully"
    echo "Configuration file: $zabbix_conf_dir/zabbix_agentd.d/iptables.conf"
    echo "Monitor script: $scripts_dir/iptables_monitor.sh"
    echo "Discovery script: $scripts_dir/iptables_discovery.sh"
    echo
    echo "To apply configuration:"
    echo "  1. Restart Zabbix agent: systemctl restart zabbix-agent"
    echo "  2. Import template in Zabbix frontend"
}

# 创建 Zabbix 模板
create_zabbix_template() {
    local template_file="iptables_template.xml"
    
    echo "Creating Zabbix template..."
    
    cat > "$template_file" << 'EOF'
<?xml version="1.0" encoding="UTF-8"?>
<zabbix_export>
    <version>5.0</version>
    <date>2024-01-01T00:00:00Z</date>
    <groups>
        <group>
            <name>Templates/Network devices</name>
        </group>
    </groups>
    <templates>
        <template>
            <template>Template iptables</template>
            <name>Template iptables</name>
            <description>Template for monitoring iptables firewall</description>
            <groups>
                <group>
                    <name>Templates/Network devices</name>
                </group>
            </groups>
            <applications>
                <application>
                    <name>iptables</name>
                </application>
            </applications>
            <items>
                <item>
                    <name>iptables: Total rules count</name>
                    <key>iptables.rules.total</key>
                    <delay>60s</delay>
                    <value_type>3</value_type>
                    <applications>
                        <application>
                            <name>iptables</name>
                        </application>
                    </applications>
                    <triggers>
                        <trigger>
                            <expression>{last()}&gt;1000</expression>
                            <name>iptables: Too many rules ({ITEM.LASTVALUE})</name>
                            <priority>2</priority>
                        </trigger>
                    </triggers>
                </item>
                <item>
                    <name>iptables: Connection tracking usage %</name>
                    <key>iptables.conntrack.usage_percent</key>
                    <delay>30s</delay>
                    <value_type>0</value_type>
                    <units>%</units>
                    <applications>
                        <application>
                            <name>iptables</name>
                        </application>
                    </applications>
                    <triggers>
                        <trigger>
                            <expression>{last()}&gt;90</expression>
                            <name>iptables: Connection tracking table nearly full ({ITEM.LASTVALUE}%)</name>
                            <priority>4</priority>
                        </trigger>
                        <trigger>
                            <expression>{last()}&gt;80</expression>
                            <name>iptables: High connection tracking usage ({ITEM.LASTVALUE}%)</name>
                            <priority>2</priority>
                        </trigger>
                    </triggers>
                </item>
                <item>
                    <name>iptables: Firewall running status</name>
                    <key>iptables.status.running</key>
                    <delay>60s</delay>
                    <value_type>3</value_type>
                    <applications>
                        <application>
                            <name>iptables</name>
                        </application>
                    </applications>
                    <triggers>
                        <trigger>
                            <expression>{last()}=0</expression>
                            <name>iptables: Firewall is not running</name>
                            <priority>4</priority>
                        </trigger>
                    </triggers>
                </item>
            </items>
            <discovery_rules>
                <discovery_rule>
                    <name>iptables chains discovery</name>
                    <key>iptables.discovery.chains</key>
                    <delay>3600s</delay>
                    <item_prototypes>
                        <item_prototype>
                            <name>iptables: {#TABLE} {#CHAIN} packets</name>
                            <key>iptables.chain.packets[{#TABLE},{#CHAIN}]</key>
                            <delay>60s</delay>
                            <value_type>3</value_type>
                            <applications>
                                <application>
                                    <name>iptables</name>
                                </application>
                            </applications>
                        </item_prototype>
                        <item_prototype>
                            <name>iptables: {#TABLE} {#CHAIN} bytes</name>
                            <key>iptables.chain.bytes[{#TABLE},{#CHAIN}]</key>
                            <delay>60s</delay>
                            <value_type>3</value_type>
                            <units>B</units>
                            <applications>
                                <application>
                                    <name>iptables</name>
                                </application>
                            </applications>
                        </item_prototype>
                    </item_prototypes>
                </discovery_rule>
            </discovery_rules>
        </template>
    </templates>
</zabbix_export>
EOF

    echo "Zabbix template created: $template_file"
    echo "Import this template in Zabbix frontend"
}

# 使用示例
case "${1:-help}" in
    "config")
        create_zabbix_config
        ;;
    "template")
        create_zabbix_template
        ;;
    "all")
        create_zabbix_config
        create_zabbix_template
        ;;
    "help")
        echo "Usage: $0 <command>"
        echo "Commands:"
        echo "  config    - Create Zabbix agent configuration"
        echo "  template  - Create Zabbix template"
        echo "  all       - Create both configuration and template"
        ;;
    *)
        echo "Unknown command: $1"
        exit 1
        ;;
esac

12.3 与日志系统集成

12.3.1 rsyslog 集成配置

1. rsyslog 配置

#!/bin/bash
# rsyslog_iptables_config.sh

# 配置 rsyslog 处理 iptables 日志
configure_rsyslog() {
    local rsyslog_conf="/etc/rsyslog.d/10-iptables.conf"
    local log_dir="/var/log/iptables"
    
    echo "Configuring rsyslog for iptables logging..."
    
    # 创建日志目录
    mkdir -p "$log_dir"
    chown syslog:adm "$log_dir"
    chmod 755 "$log_dir"
    
    # 创建 rsyslog 配置
    cat > "$rsyslog_conf" << 'EOF'
# iptables logging configuration

# 定义模板
$template IptablesFormat,"%timegenerated% %HOSTNAME% %syslogtag%%msg%\n"
$template IptablesFile,"/var/log/iptables/%$year%-%$month%-%$day%-iptables.log"
$template IptablesDropFile,"/var/log/iptables/%$year%-%$month%-%$day%-drops.log"
$template IptablesAcceptFile,"/var/log/iptables/%$year%-%$month%-%$day%-accepts.log"
$template IptablesRejectFile,"/var/log/iptables/%$year%-%$month%-%$day%-rejects.log"

# 过滤规则
:msg, contains, "[IPTABLES]" /var/log/iptables/iptables.log;IptablesFormat
:msg, contains, "[IPTABLES-DROP]" /var/log/iptables/drops.log;IptablesFormat
:msg, contains, "[IPTABLES-ACCEPT]" /var/log/iptables/accepts.log;IptablesFormat
:msg, contains, "[IPTABLES-REJECT]" /var/log/iptables/rejects.log;IptablesFormat

# 按日期分割日志
:msg, contains, "[IPTABLES-DROP]" ?IptablesDropFile;IptablesFormat
:msg, contains, "[IPTABLES-ACCEPT]" ?IptablesAcceptFile;IptablesFormat
:msg, contains, "[IPTABLES-REJECT]" ?IptablesRejectFile;IptablesFormat
:msg, contains, "[IPTABLES]" ?IptablesFile;IptablesFormat

# 停止进一步处理
:msg, contains, "[IPTABLES" stop
EOF

    # 创建 logrotate 配置
    cat > "/etc/logrotate.d/iptables" << 'EOF'
/var/log/iptables/*.log {
    daily
    missingok
    rotate 30
    compress
    delaycompress
    notifempty
    create 644 syslog adm
    postrotate
        /usr/lib/rsyslog/rsyslog-rotate
    endscript
}
EOF

    # 重启 rsyslog
    systemctl restart rsyslog
    
    echo "rsyslog configuration completed"
    echo "Configuration file: $rsyslog_conf"
    echo "Log directory: $log_dir"
    echo "Logrotate config: /etc/logrotate.d/iptables"
}

# 创建日志分析脚本
create_log_analyzer() {
    local script_file="/usr/local/bin/iptables_log_analyzer.sh"
    
    echo "Creating iptables log analyzer..."
    
    cat > "$script_file" << 'EOF'
#!/bin/bash
# iptables_log_analyzer.sh - Analyze iptables logs

LOG_DIR="/var/log/iptables"
REPORT_DIR="/var/log/iptables/reports"
DATE=$(date +%Y-%m-%d)

# 创建报告目录
mkdir -p "$REPORT_DIR"

# 分析丢弃的包
analyze_drops() {
    local log_file="$LOG_DIR/${DATE}-drops.log"
    local report_file="$REPORT_DIR/${DATE}-drops-analysis.txt"
    
    if [ ! -f "$log_file" ]; then
        echo "No drops log file found for $DATE"
        return
    fi
    
    echo "Analyzing dropped packets for $DATE..." > "$report_file"
    echo "=========================================" >> "$report_file"
    echo >> "$report_file"
    
    # 统计总丢弃数
    local total_drops=$(grep -c "DPT=" "$log_file")
    echo "Total dropped packets: $total_drops" >> "$report_file"
    echo >> "$report_file"
    
    # 按源 IP 统计
    echo "Top 10 source IPs:" >> "$report_file"
    grep "SRC=" "$log_file" | sed 's/.*SRC=\([0-9.]*\).*/\1/' | sort | uniq -c | sort -nr | head -10 >> "$report_file"
    echo >> "$report_file"
    
    # 按目标端口统计
    echo "Top 10 destination ports:" >> "$report_file"
    grep "DPT=" "$log_file" | sed 's/.*DPT=\([0-9]*\).*/\1/' | sort | uniq -c | sort -nr | head -10 >> "$report_file"
    echo >> "$report_file"
    
    # 按协议统计
    echo "Protocol distribution:" >> "$report_file"
    grep "PROTO=" "$log_file" | sed 's/.*PROTO=\([A-Z]*\).*/\1/' | sort | uniq -c | sort -nr >> "$report_file"
    echo >> "$report_file"
    
    # 时间分布
    echo "Hourly distribution:" >> "$report_file"
    grep "DPT=" "$log_file" | awk '{print $1" "$2}' | cut -d: -f1 | sort | uniq -c >> "$report_file"
    
    echo "Drops analysis completed: $report_file"
}

# 分析接受的包
analyze_accepts() {
    local log_file="$LOG_DIR/${DATE}-accepts.log"
    local report_file="$REPORT_DIR/${DATE}-accepts-analysis.txt"
    
    if [ ! -f "$log_file" ]; then
        echo "No accepts log file found for $DATE"
        return
    fi
    
    echo "Analyzing accepted packets for $DATE..." > "$report_file"
    echo "==========================================" >> "$report_file"
    echo >> "$report_file"
    
    # 统计总接受数
    local total_accepts=$(grep -c "DPT=" "$log_file")
    echo "Total accepted packets: $total_accepts" >> "$report_file"
    echo >> "$report_file"
    
    # 按服务端口统计
    echo "Top 10 services (by destination port):" >> "$report_file"
    grep "DPT=" "$log_file" | sed 's/.*DPT=\([0-9]*\).*/\1/' | sort | uniq -c | sort -nr | head -10 >> "$report_file"
    echo >> "$report_file"
    
    # 按源 IP 统计
    echo "Top 10 client IPs:" >> "$report_file"
    grep "SRC=" "$log_file" | sed 's/.*SRC=\([0-9.]*\).*/\1/' | sort | uniq -c | sort -nr | head -10 >> "$report_file"
    
    echo "Accepts analysis completed: $report_file"
}

# 生成安全报告
generate_security_report() {
    local report_file="$REPORT_DIR/${DATE}-security-report.txt"
    
    echo "Generating security report for $DATE..." > "$report_file"
    echo "======================================" >> "$report_file"
    echo >> "$report_file"
    
    # 检查可疑活动
    echo "Suspicious Activity Analysis:" >> "$report_file"
    echo "-----------------------------" >> "$report_file"
    
    # 端口扫描检测
    local scan_threshold=50
    echo "Potential port scans (>$scan_threshold different ports from same IP):" >> "$report_file"
    
    if [ -f "$LOG_DIR/${DATE}-drops.log" ]; then
        awk '/DPT=/ {
            match($0, /SRC=([0-9.]+)/, src);
            match($0, /DPT=([0-9]+)/, dpt);
            if (src[1] && dpt[1]) {
                ports[src[1]][dpt[1]] = 1;
            }
        }
        END {
            for (ip in ports) {
                count = 0;
                for (port in ports[ip]) count++;
                if (count > '$scan_threshold') {
                    print ip ": " count " different ports";
                }
            }
        }' "$LOG_DIR/${DATE}-drops.log" >> "$report_file"
    fi
    
    echo >> "$report_file"
    
    # 暴力破解检测
    echo "Potential brute force attacks (SSH, FTP, HTTP):" >> "$report_file"
    
    if [ -f "$LOG_DIR/${DATE}-drops.log" ]; then
        for port in 22 21 80 443; do
            echo "Port $port attempts:" >> "$report_file"
            grep "DPT=$port" "$LOG_DIR/${DATE}-drops.log" | \
                sed 's/.*SRC=\([0-9.]*\).*/\1/' | \
                sort | uniq -c | sort -nr | \
                awk '$1 > 10 {print "  " $2 ": " $1 " attempts"}' >> "$report_file"
        done
    fi
    
    echo >> "$report_file"
    
    # 地理位置分析(需要 geoip 数据库)
    if command -v geoiplookup >/dev/null 2>&1; then
        echo "Geographic distribution of attacks:" >> "$report_file"
        
        if [ -f "$LOG_DIR/${DATE}-drops.log" ]; then
            grep "SRC=" "$LOG_DIR/${DATE}-drops.log" | \
                sed 's/.*SRC=\([0-9.]*\).*/\1/' | \
                sort | uniq | \
                while read ip; do
                    country=$(geoiplookup "$ip" | cut -d: -f2 | cut -d, -f1 | xargs)
                    echo "$country"
                done | sort | uniq -c | sort -nr | head -10 >> "$report_file"
        fi
    fi
    
    echo "Security report completed: $report_file"
}

# 生成统计图表(需要 gnuplot)
generate_charts() {
    if ! command -v gnuplot >/dev/null 2>&1; then
        echo "gnuplot not found, skipping chart generation"
        return
    fi
    
    local chart_dir="$REPORT_DIR/charts"
    mkdir -p "$chart_dir"
    
    # 生成每小时丢弃包数量图表
    if [ -f "$LOG_DIR/${DATE}-drops.log" ]; then
        echo "Generating hourly drops chart..."
        
        # 提取每小时数据
        grep "DPT=" "$LOG_DIR/${DATE}-drops.log" | \
            awk '{print $2}' | cut -d: -f1 | sort | uniq -c > "/tmp/hourly_drops.dat"
        
        # 生成 gnuplot 脚本
        cat > "/tmp/drops_chart.gp" << GNUPLOT_EOF
set terminal png size 800,600
set output "$chart_dir/${DATE}-hourly-drops.png"
set title "Hourly Dropped Packets - $DATE"
set xlabel "Hour"
set ylabel "Packet Count"
set grid
set style data histograms
set style fill solid
plot "/tmp/hourly_drops.dat" using 1:xtic(2) title "Dropped Packets"
GNUPLOT_EOF
        
        gnuplot "/tmp/drops_chart.gp"
        rm -f "/tmp/hourly_drops.dat" "/tmp/drops_chart.gp"
        
        echo "Chart generated: $chart_dir/${DATE}-hourly-drops.png"
    fi
}

# 主函数
main() {
    local action="${1:-all}"
    
    case "$action" in
        "drops")
            analyze_drops
            ;;
        "accepts")
            analyze_accepts
            ;;
        "security")
            generate_security_report
            ;;
        "charts")
            generate_charts
            ;;
        "all")
            analyze_drops
            analyze_accepts
            generate_security_report
            generate_charts
            ;;
        "help")
            echo "Usage: $0 {drops|accepts|security|charts|all} [date]"
            echo "  drops    - Analyze dropped packets"
            echo "  accepts  - Analyze accepted packets"
            echo "  security - Generate security report"
            echo "  charts   - Generate charts (requires gnuplot)"
            echo "  all      - Run all analyses"
            ;;
        *)
            echo "Unknown action: $action"
            exit 1
            ;;
    esac
}

# 如果提供了日期参数,使用它
if [ -n "$2" ]; then
    DATE="$2"
fi

# 执行主函数
main "$@"
EOF

    # 设置脚本权限
    chmod +x "$script_file"
    
    echo "Log analyzer created: $script_file"
}

# 使用示例
case "${1:-help}" in
    "configure")
        configure_rsyslog
        ;;
    "analyzer")
        create_log_analyzer
        ;;
    "all")
        configure_rsyslog
        create_log_analyzer
        ;;
    "help")
        echo "Usage: $0 <command>"
        echo "Commands:"
        echo "  configure  - Configure rsyslog for iptables"
        echo "  analyzer   - Create log analyzer script"
        echo "  all        - Configure rsyslog and create analyzer"
        ;;
    *)
        echo "Unknown command: $1"
        exit 1
        ;;
esac