Shell脚本如何自动化配置防火墙规则

wen 实用脚本 2

本文目录导读:

Shell脚本如何自动化配置防火墙规则

  1. 使用iptables的自动化脚本
  2. 使用firewalld的自动化脚本
  3. 通用防火墙管理脚本
  4. 配置文件示例
  5. 使用建议

我来详细介绍Shell脚本自动化配置防火墙规则的方法,主要包括iptables和firewalld两种主流方案。

使用iptables的自动化脚本

基础防火墙配置脚本

#!/bin/bash
# firewall_config.sh - 自动化配置iptables防火墙规则
# 设置颜色输出
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
NC='\033[0m' # No Color
# 日志函数
log_info() {
    echo -e "${GREEN}[INFO]${NC} $1"
}
log_warn() {
    echo -e "${YELLOW}[WARN]${NC} $1"
}
log_error() {
    echo -e "${RED}[ERROR]${NC} $1"
}
# 检查是否root用户
check_root() {
    if [[ $EUID -ne 0 ]]; then
        log_error "此脚本需要root权限运行"
        exit 1
    fi
}
# 备份当前规则
backup_rules() {
    local backup_file="/etc/iptables/rules.backup.$(date +%Y%m%d_%H%M%S)"
    mkdir -p /etc/iptables
    iptables-save > "$backup_file"
    log_info "规则已备份到: $backup_file"
}
# 清空现有规则
flush_rules() {
    log_warn "正在清空现有iptables规则..."
    iptables -F
    iptables -X
    iptables -Z
    iptables -t nat -F
    iptables -t nat -X
    iptables -t mangle -F
    iptables -t mangle -X
}
# 设置默认策略
set_default_policy() {
    local default_policy=${1:-DROP}
    log_info "设置默认策略为: $default_policy"
    iptables -P INPUT $default_policy
    iptables -P FORWARD $default_policy
    iptables -P OUTPUT ACCEPT
}
# 配置基本规则
configure_basic_rules() {
    log_info "配置基本防火墙规则..."
    # 允许本地回环接口
    iptables -A INPUT -i lo -j ACCEPT
    iptables -A OUTPUT -o lo -j ACCEPT
    # 允许已建立的连接
    iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
    # 允许SSH连接(默认端口22)
    iptables -A INPUT -p tcp --dport 22 -j ACCEPT
    # 允许ICMP(ping)
    iptables -A INPUT -p icmp -j ACCEPT
    # 防止DoS攻击
    iptables -A INPUT -p tcp --dport 80 -m limit --limit 25/minute --limit-burst 100 -j ACCEPT
}
# 配置Web服务规则
configure_web_rules() {
    log_info "配置Web服务规则..."
    # HTTP
    iptables -A INPUT -p tcp --dport 80 -j ACCEPT
    # HTTPS
    iptables -A INPUT -p tcp --dport 443 -j ACCEPT
}
# 配置动态端口规则(从配置文件读取)
configure_dynamic_ports() {
    local config_file="/etc/firewall/ports.conf"
    if [[ -f "$config_file" ]]; then
        log_info "从配置文件读取端口规则: $config_file"
        while IFS=':' read -r protocol port description; do
            [[ -z "$protocol" || "$protocol" =~ ^# ]] && continue
            iptables -A INPUT -p "$protocol" --dport "$port" -j ACCEPT
            log_info "  允许 $protocol 端口 $port ($description)"
        done < "$config_file"
    else
        log_warn "端口配置文件不存在: $config_file"
    fi
}
# 配置高级安全规则
configure_advanced_rules() {
    log_info "配置高级安全规则..."
    # 限制SSH暴力破解
    iptables -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --set
    iptables -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --update --seconds 60 --hitcount 4 -j DROP
    # 阻止空数据包
    iptables -A INPUT -p tcp --tcp-flags ALL NONE -j DROP
    # 阻止SYN Flood攻击
    iptables -A INPUT -p tcp ! --syn -m state --state NEW -j DROP
    # 阻止XMAS扫描
    iptables -A INPUT -p tcp --tcp-flags ALL ALL -j DROP
}
# 保存规则
save_rules() {
    log_info "保存防火墙规则..."
    # 检查iptables-persistent是否安装
    if command -v netfilter-persistent &> /dev/null; then
        netfilter-persistent save
        netfilter-persistent reload
    elif command -v iptables-save &> /dev/null; then
        iptables-save > /etc/iptables/rules.v4
        ip6tables-save > /etc/iptables/rules.v6
    else
        log_warn "未找到持久化工具,规则可能在重启后丢失"
    fi
    log_info "规则保存完成"
}
# 主函数
main() {
    check_root
    echo "========================================="
    echo "    iptables防火墙自动化配置脚本"
    echo "========================================="
    # 交互式配置
    read -p "是否备份当前规则? [Y/n]: " backup
    if [[ "$backup" != "n" && "$backup" != "N" ]]; then
        backup_rules
    fi
    read -p "是否清空现有规则? [Y/n]: " flush
    if [[ "$flush" != "n" && "$flush" != "N" ]]; then
        flush_rules
    fi
    read -p "默认策略 (DROP/ACCEPT) [DROP]: " policy
    policy=${policy:-DROP}
    set_default_policy "$policy"
    configure_basic_rules
    read -p "是否配置Web服务规则? [y/N]: " web
    if [[ "$web" == "y" || "$web" == "Y" ]]; then
        configure_web_rules
    fi
    read -p "是否配置动态端口规则? [y/N]: " dynamic
    if [[ "$dynamic" == "y" || "$dynamic" == "Y" ]]; then
        configure_dynamic_ports
    fi
    read -p "是否配置高级安全规则? [y/N]: " advanced
    if [[ "$advanced" == "y" || "$advanced" == "Y" ]]; then
        configure_advanced_rules
    fi
    save_rules
    # 显示配置摘要
    echo ""
    echo "========================================="
    echo "    规则配置摘要"
    echo "========================================="
    iptables -L -n -v | head -30
    log_info "防火墙配置完成!"
}
# 执行主函数
main "$@"

端口配置文件示例 (/etc/firewall/ports.conf)

# 格式: 协议:端口:描述
tcp:3306:MySQL数据库
tcp:5432:PostgreSQL数据库
tcp:6379:Redis缓存
tcp:8080:Tomcat应用
udp:1194:OpenVPN
tcp:8443:备用HTTPS

使用firewalld的自动化脚本

#!/bin/bash
# firewalld_config.sh - 自动化配置firewalld规则
# 检查firewalld状态
check_firewalld() {
    if ! systemctl is-active firewalld &> /dev/null; then
        echo "firewalld未运行,正在启动..."
        systemctl start firewalld
        systemctl enable firewalld
    fi
}
# 基础配置
configure_basic() {
    # 设置默认区域
    firewall-cmd --set-default-zone=public
    # 允许SSH
    firewall-cmd --permanent --add-service=ssh
    # 允许DHCP
    firewall-cmd --permanent --add-service=dhcpv6-client
    # 允许ICMP
    firewall-cmd --permanent --add-protocol=icmp
}
# 配置服务
configure_services() {
    local services=("http" "https" "mysql" "postgresql")
    for service in "${services[@]}"; do
        if firewall-cmd --query-service="$service" &> /dev/null; then
            firewall-cmd --permanent --add-service="$service"
            echo "已添加服务: $service"
        fi
    done
}
# 配置端口
configure_ports() {
    local ports_file="/etc/firewalld/custom_ports.txt"
    if [[ -f "$ports_file" ]]; then
        while IFS=':' read -r port protocol; do
            firewall-cmd --permanent --add-port="${port}/${protocol}"
            echo "已添加端口: ${port}/${protocol}"
        done < "$ports_file"
    fi
}
# 配置区域
configure_zones() {
    # 创建自定义区域
    firewall-cmd --permanent --new-zone=web_server
    firewall-cmd --permanent --zone=web_server --add-service=http
    firewall-cmd --permanent --zone=web_server --add-service=https
    firewall-cmd --permanent --new-zone=db_server
    firewall-cmd --permanent --zone=db_server --add-port=3306/tcp
    # 设置接口到区域
    firewall-cmd --permanent --zone=web_server --change-interface=eth0
}
# 配置富规则
configure_rich_rules() {
    # 限制SSH访问来源
    firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.1.0/24" service name="ssh" accept'
    # 拒绝特定IP
    firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="10.0.0.5" drop'
    # 限制连接数
    firewall-cmd --permanent --add-rich-rule='rule service name="http" limit value="100/m" accept'
}
# 重载配置
reload_config() {
    firewall-cmd --reload
    echo "防火墙配置已重载"
}
# 显示状态
show_status() {
    echo "=== 区域信息 ==="
    firewall-cmd --get-active-zones
    echo -e "\n=== 服务列表 ==="
    firewall-cmd --list-services
    echo -e "\n=== 端口列表 ==="
    firewall-cmd --list-ports
    echo -e "\n=== 富规则 ==="
    firewall-cmd --list-rich-rules
}
# 主函数
main() {
    check_firewalld
    echo "开始配置firewalld..."
    configure_basic
    configure_services
    configure_ports
    configure_zones
    configure_rich_rules
    reload_config
    show_status
    echo "firewalld配置完成!"
}
main

通用防火墙管理脚本

#!/bin/bash
# firewall_manager.sh - 通用防火墙管理工具
# 检测防火墙类型
detect_firewall() {
    if command -v firewall-cmd &> /dev/null; then
        echo "firewalld"
    elif command -v ufw &> /dev/null; then
        echo "ufw"
    elif command -v iptables &> /dev/null; then
        echo "iptables"
    else
        echo "unknown"
    fi
}
# 通用添加端口函数
add_port() {
    local port=$1
    local protocol=${2:-tcp}
    local firewall_type=$(detect_firewall)
    case $firewall_type in
        firewalld)
            firewall-cmd --permanent --add-port=${port}/${protocol}
            firewall-cmd --reload
            ;;
        ufw)
            ufw allow ${port}/${protocol}
            ;;
        iptables)
            iptables -A INPUT -p $protocol --dport $port -j ACCEPT
            iptables-save > /etc/iptables/rules.v4
            ;;
        *)
            echo "不支持的防火墙类型"
            return 1
            ;;
    esac
    echo "已添加端口: ${port}/${protocol}"
}
# 通用删除端口函数
remove_port() {
    local port=$1
    local protocol=${2:-tcp}
    local firewall_type=$(detect_firewall)
    case $firewall_type in
        firewalld)
            firewall-cmd --permanent --remove-port=${port}/${protocol}
            firewall-cmd --reload
            ;;
        ufw)
            ufw deny ${port}/${protocol}
            ;;
        iptables)
            iptables -D INPUT -p $protocol --dport $port -j ACCEPT
            iptables-save > /etc/iptables/rules.v4
            ;;
        *)
            echo "不支持的防火墙类型"
            return 1
            ;;
    esac
    echo "已删除端口: ${port}/${protocol}"
}
# 批量配置端口
batch_config_ports() {
    local config_file=$1
    if [[ ! -f "$config_file" ]]; then
        echo "配置文件不存在: $config_file"
        return 1
    fi
    echo "从配置文件批量配置端口: $config_file"
    while IFS=':' read -r action port protocol; do
        [[ -z "$action" || "$action" =~ ^# ]] && continue
        case $action in
            allow)
                add_port $port $protocol
                ;;
            deny)
                remove_port $port $protocol
                ;;
            *)
                echo "未知操作: $action"
                ;;
        esac
    done < "$config_file"
}
# 主菜单
show_menu() {
    clear
    echo "========================================="
    echo "    通用防火墙管理工具"
    echo "    当前防火墙: $(detect_firewall)"
    echo "========================================="
    echo "1. 添加端口"
    echo "2. 删除端口"
    echo "3. 批量配置端口"
    echo "4. 显示当前规则"
    echo "5. 备份规则"
    echo "6. 恢复规则"
    echo "7. 退出"
    echo "========================================="
    read -p "请选择操作: " choice
    case $choice in
        1)
            read -p "端口: " port
            read -p "协议(tcp/udp): " protocol
            add_port $port $protocol
            ;;
        2)
            read -p "端口: " port
            read -p "协议(tcp/udp): " protocol
            remove_port $port $protocol
            ;;
        3)
            read -p "配置文件路径: " config_file
            batch_config_ports $config_file
            ;;
        4)
            case $(detect_firewall) in
                firewalld)
                    firewall-cmd --list-all
                    ;;
                ufw)
                    ufw status verbose
                    ;;
                iptables)
                    iptables -L -n -v
                    ;;
            esac
            ;;
        5)
            backup_dir="/etc/firewall_backup"
            mkdir -p $backup_dir
            case $(detect_firewall) in
                firewalld)
                    cp /etc/firewalld/zones/* $backup_dir/
                    ;;
                iptables)
                    iptables-save > $backup_dir/rules.backup.$(date +%Y%m%d)
                    ;;
            esac
            echo "规则已备份到: $backup_dir"
            ;;
        6)
            read -p "备份文件路径: " backup_file
            case $(detect_firewall) in
                iptables)
                    iptables-restore < $backup_file
                    echo "规则已恢复"
                    ;;
                *)
                    echo "当前防火墙不支持此功能"
                    ;;
            esac
            ;;
        7)
            exit 0
            ;;
        *)
            echo "无效选择"
            ;;
    esac
    read -p "按回车键继续..."
    show_menu
}
# 启动管理工具
show_menu

配置文件示例

批量配置端口文件 (/etc/firewall/port_config.txt)

# 格式: 动作:端口:协议
# 动作: allow 或 deny
allow:80:tcp
allow:443:tcp
allow:8080:tcp
allow:3306:tcp
allow:5432:tcp
deny:23:tcp
deny:3389:tcp

使用建议

  1. 自动化部署:结合Ansible或Puppet进行大规模部署
  2. 日志记录:添加日志审计功能
  3. 监控告警:集成到监控系统
  4. 版本控制:将配置文件纳入Git管理
  5. 定期更新:设置cron任务定期检查和更新规则

这些脚本提供了完整的防火墙自动化管理方案,可以根据实际需求进行定制和扩展。

抱歉,评论功能暂时关闭!