# SQL_Server暴力破解防护脚本 **Repository Path**: jinshi_admin/SQLBruteForceBlocker ## Basic Information - **Project Name**: SQL_Server暴力破解防护脚本 - **Description**: 基于PowerShell 的 SQL Server 暴力破解防护脚本 - **Primary Language**: PowerShell - **License**: MulanPSL-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 0 - **Created**: 2025-07-28 - **Last Updated**: 2025-07-30 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # SQL Server 暴力破解防护脚本:用户手册与代码解读 ## 一、脚本概述 本脚本用于自动监控 SQL Server 登录失败日志,精准识别暴力破解行为,并借助 Windows 防火墙实现恶意 IP 的自动封禁。脚本具备出色的兼容性,可在各版本 PowerShell 环境中稳定运行,且采用资源优化设计,适合在生产服务器环境中长期部署。 核心功能亮点: * 实时追踪 SQL Server 错误日志中标记为 18456 的登录失败事件 * 依据失败次数阈值自动对恶意 IP 执行封禁操作 * 支持临时封禁(可指定时长)与永久封禁两种模式 * 配备完整的日志记录与持久化机制,确保服务器重启后能无缝恢复监控状态 ## 二、安装与配置 ### 1. 环境要求 * 操作系统:Windows Server 2008 及以上版本 * SQL Server:2008 及以上版本 * 权限要求:需拥有管理员权限(用于操作防火墙和任务计划) * 组件要求:PowerShell(支持 v2 及以上版本) ### 2. 安装步骤 #### 步骤 1:启用 SQL Server 登录日志 1. 打开 SQL Server Management Studio(SSMS),连接至目标服务器 2. 右键点击服务器实例,依次选择 “属性”→“安全性” 3. 在 “登录审核” 选项中勾选 “失败的登录”(建议同时勾选 “成功的登录”,以便后续问题排查) 4. 重启 SQL Server 服务,使配置生效 #### 步骤 2:部署脚本 1. 创建专门的脚本存放目录(例如:`C:\Tools\SQLBruteForceBlocker\`) 2. 将脚本保存为`SQLBruteForceBlocker.ps1` 3. 确保脚本所在目录具备读写权限 #### 步骤 3:配置任务计划程序 1. 按下`Win+R`组合键,输入`taskschd.msc`打开任务计划程序 2. 创建基本任务,命名为 “SQL 自动封禁暴力破解 IP” 3. 触发条件选择 “当计算机启动时” 4. 操作类型选择 “启动程序”,程序 / 脚本设置为`powershell.exe` 5. 添加参数:`-ExecutionPolicy Bypass -File "C:\Tools\SQLBruteForceBlocker\SQLBruteForceBlocker.ps1"` 6. 在任务属性中勾选 “使用最高权限运行” 7. 测试运行该任务,确认脚本能够正常启动 ## 三、参数配置说明 脚本头部的配置参数可根据实际业务需求进行调整: ``` $threshold = 5 # 允许失败的次数阈值,超过此值将被封禁 $logPath = "C:\Program Files\Microsoft SQL Server\MSSQL13.MSSQLSERVER\MSSQL\Log\ERRORLOG" # SQL错误日志路径 $banDuration = 3600 # 封禁时长(秒),0表示永久封禁 $checkInterval = 60 # 检查间隔(秒) $maxProcessLines = 512 # 每次最多处理的新记录行数 $sampleSize = 1024 # 统计错误次数的取样范围(最近的记录数) ``` > 重要提示: > > `$logPath` > > 必须根据 SQL Server 的实际安装路径进行修改,可在 SSMS 中执行 > > `EXEC xp_readerrorlog 0,1,'Log path'` > > 查询具体路径 ## 四、使用与管理 ### 1. 日常监控 * 封禁记录日志位置:`脚本所在目录\SQLBanLogs\ban_records.log` * 时间戳记录文件:`脚本所在目录\SQLBanLogs\last_processed_timestamp.txt` * 运行状态查看:通过任务计划程序的 “历史记录” 可查看脚本的运行状态 ### 2. 手动解除封禁 1. 打开 “高级安全 Windows 防火墙”,进入 “入站规则” 2. 搜索名称包含 “Block SQL BruteForce” 的规则 3. 右键点击相应规则,选择 “禁用” 或 “删除” 即可解除对对应 IP 的封禁 ### 3. 脚本维护 * 定期检查封禁日志,及时清理不再需要的永久封禁规则 * 根据服务器负载情况,合理调整`$checkInterval`、`$maxProcessLines`和`$sampleSize`参数 * 当服务器进行升级或 SQL Server 迁移后,务必重新确认`$logPath`参数的正确性 ## 五、代码解读 ### 1. 整体架构 脚本采用循环监控模式,主要包含以下功能模块: * 初始化模块:负责路径计算、文件夹创建以及时间戳加载 * 日志处理模块:实现日志的读取、过滤与解析操作 * IP 提取与统计模块:从日志中提取 IP 地址并统计其失败登录次数 * 封禁管理模块:处理防火墙规则的创建与定时解封任务 * 异常处理模块:捕获并记录错误信息,保障脚本稳定运行 ### 2. 核心功能解析 #### 路径处理机制 ``` $scriptDir = Split-Path -Parent $MyInvocation.MyCommand.Definition $banLogPath = Join-Path -Path $scriptDir -ChildPath "SQLBanLogs\ban_records.log" $timestampFile = Join-Path -Path $scriptDir -ChildPath "SQLBanLogs\last_processed_timestamp.txt" ``` 采用相对路径设计,使得脚本可部署在任意目录,无需修改路径配置,极大提升了部署的灵活性和标准化程度。 #### 时间戳持久化机制 ``` function Get-LastProcessedTimestamp { param([string]$filePath) if(Test-Path $filePath) { $content = Get-Content $filePath -Raw try { return [DateTime]$content } catch { return $null } } return $null } ``` 通过文件存储上次处理的时间戳,确保服务器重启或脚本意外中断后,不会重复处理历史记录,同时兼容旧版本的 PowerShell。 #### 日志处理与 IP 提取 ``` $allLogLines = Get-Content $logPath -ErrorAction Stop $takeCount = [Math]::Min($sampleSize, $allLogLines.Count) $logContent = $allLogLines | Select-Object -Last $takeCount # 提取错误代码18456的记录 for($i = 0; $i -lt $logContent.Count; $i++) { if($logContent[$i] -match "错误: 18456,严重性: \d+,状态: \d+。") { # 处理两行一组的日志记录 $pair = @() $pair += $logContent[$i] if($i + 1 -lt $logContent.Count) { $pair += $logContent[$i + 1] $i++ } $error18456LinePairs += ,$pair } } ``` 通过限制日志处理数量(`$sampleSize`)优化资源占用,同时专门匹配 SQL Server 登录失败的错误代码 18456,确保识别的准确性。 #### IP 封禁与定时解封 ``` # 创建防火墙规则封禁IP New-NetFirewallRule -DisplayName "Block SQL BruteForce - $ip" ` -Direction Inbound -Action Block -RemoteAddress $ip ` -Protocol Any -Enabled True -Profile Any | Out-Null # 定时解封任务 if($banDuration -gt 0) { $taskName = "Unban SQL IP $ip" $action = New-ScheduledTaskAction -Execute "powershell.exe" ` -Argument "-Command Remove-NetFirewallRule -DisplayName 'Block SQL BruteForce - $ip'" $trigger = New-ScheduledTaskTrigger -Once -At (Get-Date).AddSeconds($banDuration) Register-ScheduledTask -TaskName $taskName -Action $action ` -Trigger $trigger -RunLevel Highest | Out-Null } ``` 通过创建 Windows 防火墙规则实现 IP 封禁,并利用任务计划程序创建定时任务,实现 IP 的自动解封功能。 #### 异常处理机制 ``` try { # 核心处理逻辑 } catch { $errorMsg = "[$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')] 脚本错误: $($_.Exception.Message)" Add-Content -Path $banLogPath -Value $errorMsg Write-Host $errorMsg } ``` 全局异常捕获机制确保脚本在遇到错误时不会直接崩溃,而是会记录错误信息并继续运行,有效提高了脚本的稳定性。 ## 六、常见问题与解决 1. **Q:脚本运行后没有任何反应?** A:检查是否以管理员权限运行脚本;确认 SQL 错误日志路径是否正确;查看`ban_records.log`中的错误信息以定位问题。 2. **Q:存在多次失败登录,但 IP 未被封禁?** A:检查失败次数是否达到`$threshold`阈值;确认日志格式是否包含错误代码 18456;查看防火墙中是否已存在同名规则。 3. **Q:服务器重启后脚本重复封禁 IP?** A:检查`last_processed_timestamp.txt`文件是否存在且格式正确;确认任务计划程序是否能正常启动脚本。 4. **Q:脚本运行时占用资源过高?** A:可减小`$sampleSize`和`$maxProcessLines`的值;适当增大`$checkInterval`检查间隔。 ## 七、版本历史 | 版本 | 主要更新 | | -- | --------------------- | | v1 | 初始版本,基于行数判断新增记录 | | v2 | 改为基于时间戳判断新增记录 | | v3 | 实现时间戳持久化,支持服务器重启 | | v4 | 使用相对路径,优化部署灵活性 | | v5 | 限制日志处理数量,优化资源占用 | | v6 | 修复旧版 PowerShell 兼容性问题 | | v7 | 修复时间戳解析和字符串格式化问题 | 通过上述功能,本脚本为 SQL Server 提供了自动化的暴力破解防护能力,减少了人工干预成本,有效提高了数据库服务器的安全性。