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 与各种系统和工具的集成方法:
系统服务集成
- systemd 服务配置和管理
- 传统 init 系统配置
- 开机自启动和服务管理
监控工具集成
- Nagios 插件开发和配置
- Zabbix 监控参数和模板
- 性能指标收集和告警
日志系统集成
- rsyslog 配置和日志分析
- ELK Stack 集成和可视化
- 日志轮转和存储管理
自动化工具集成
- Ansible 角色和 Playbook
- Terraform 基础设施即代码
- 配置管理和部署自动化
12.5.2 最佳实践建议
服务管理
- 使用 systemd 管理 iptables 服务
- 实现规则的自动备份和恢复
- 配置服务依赖关系
监控策略
- 监控规则数量和性能
- 跟踪连接状态和资源使用
- 设置合理的告警阈值
日志管理
- 结构化日志记录
- 实时日志分析和告警
- 长期日志存储和归档
自动化部署
- 版本控制配置文件
- 自动化测试和验证
- 渐进式部署策略
12.5.3 集成检查清单
- [ ] 配置 systemd 服务管理
- [ ] 设置监控和告警
- [ ] 配置日志收集和分析
- [ ] 实现自动化部署
- [ ] 建立备份和恢复机制
- [ ] 配置性能监控
- [ ] 设置安全事件响应
- [ ] 文档化集成流程
12.5.4 下一章预告
下一章我们将进入 iptables 教程的总结部分,回顾整个学习过程,总结最佳实践,并提供进阶学习建议。
练习与思考
理论练习
集成架构设计
- 设计一个完整的 iptables 监控架构
- 规划日志收集和分析流程
- 制定自动化部署策略
工具选择分析
- 比较不同监控工具的优缺点
- 分析各种日志系统的适用场景
- 评估自动化工具的集成复杂度
实践练习
监控系统搭建
- 配置 Nagios 或 Zabbix 监控 iptables
- 创建自定义监控脚本
- 设置告警通知机制
日志分析系统
- 搭建 ELK Stack 处理 iptables 日志
- 创建 Kibana 仪表板
- 实现实时日志分析
自动化部署
- 编写 Ansible Playbook 管理 iptables
- 使用 Terraform 部署云环境
- 实现 CI/CD 流水线
思考题
- 如何设计一个高可用的 iptables 管理系统?
- 在大规模环境中如何优化 iptables 监控性能?
- 如何实现 iptables 配置的版本控制和回滚?
- 怎样设计 iptables 的灾难恢复方案?
- 如何在容器化环境中集成 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()}>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()}>90</expression>
<name>iptables: Connection tracking table nearly full ({ITEM.LASTVALUE}%)</name>
<priority>4</priority>
</trigger>
<trigger>
<expression>{last()}>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