资讯动态

ASP老系统IP白名单硬隔离实现与VBScript网段校验

发布时间:2026/9/16 4:21:13 来源:尧图企业网站定制
简介这是一套基于经典ASP技术开发的公安行业网站管理系统实战案例面向Web开发初学者及政务系统维护人员聚焦IP白名单访问控制这一典型安全需求帮助理解传统IISASP架构下的权限管控实现逻辑。资源包共1195个文件主体为298个ASP核心业务脚本含manage_web.asp、zhiban.asp等管理模块、467个GIF/JPG/PNG图形资源、69个JS交互脚本与51个HTML前端页面辅以CSS样式、PSD设计源稿及INI配置文件完整呈现了从登录鉴权、值班管理到内容发布的功能链路压缩包体积25.05MB。已有79人学习下载可直接部署调试深入掌握Request.ServerVariables(REMOTE_ADDR)获取客户端IP、服务端条件跳转、ASP内置对象Session/Server/Response协同使用等关键技能并通过nzcms系列ASP文件结构理解国产化CMS早期演进路径。1. 这不是普通ASP网站而是一套带IP白名单硬隔离的公安内网管理前端宁志公安局网站管理系统 IP限制签收版 v2022.4.30.zip 看似是常规ASP站点压缩包实则在架构层就做了强边界控制——它不依赖IIS权限配置或防火墙策略而是把IP校验逻辑直接嵌入到每个核心页面manage_web.asp、zhiban.asp、list.asp的顶部执行流中。这意味着即使攻击者绕过登录页、伪造Session、甚至拿到管理员Cookie只要IP不在白名单内连index.asp的HTML骨架都吐不出来。这种“请求即拦截”的设计比单纯在登录环节做IP判断更彻底。它面向的是公安系统内部网络环境IP段固定如10.128.0.0/16、终端可控、无公网暴露面因此不追求OAuth或JWT等现代鉴权模型而是用最轻量、最确定的Request.ServerVariables(REMOTE_ADDR)做第一道闸机。如果你正在维护一个局域网内的政务类ASP老系统且需要快速落地可审计的访问控制这个版本的实现思路比重写整套后端更务实。2. IP限制机制的三层嵌套实现与VBScript硬编码逻辑解析2.1 白名单存储结构从data.asax到内存缓存的加载链路该系统未使用数据库存储IP白名单而是将规则固化在data.asax文件中——这是ASP时代典型的配置即代码实践。打开data.asax可见如下结构!-- data.asax -- % 公安局内网白名单IPv4 Dim g_IPList g_IPList Array( _ 10.128.1.5, _ 10.128.1.12, _ 10.128.2.33, _ 10.128.2.201, _ 10.128.3.0/24, _ 支持CIDR网段 10.128.4.0/24 _ ) %提示data.asax在ASP中属于Application级全局文件IIS启动时自动加载一次所有会话共享g_IPList数组。这种设计避免了每次请求都读取文件或查库但修改后需重启IIS或等待Application超时回收。关键点在于10.128.3.0/24这类CIDR写法——系统并未调用第三方组件而是用纯VBScript实现网段匹配。其核心函数位于nzcms_dna.asp中 nzcms_dna.asp 中的 IPInSubnet 函数 Function IPInSubnet(ip, subnet) Dim ipParts, netParts, maskBits, i If InStr(subnet, /) 0 Then IPInSubnet (ip subnet) : Exit Function End If ipParts Split(ip, .) netParts Split(Split(subnet, /)(0), .) maskBits CInt(Split(subnet, /)(1)) 将IP和网段转为32位整数 Dim ipNum, netNum ipNum CLng(ipParts(0)) * 2^24 CLng(ipParts(1)) * 2^16 CLng(ipParts(2)) * 2^8 CLng(ipParts(3)) netNum CLng(netParts(0)) * 2^24 CLng(netParts(1)) * 2^16 CLng(netParts(2)) * 2^8 CLng(netParts(3)) 计算子网掩码 Dim mask mask (2^maskBits - 1) * 2^(32 - maskBits) IPInSubnet ((ipNum And mask) (netNum And mask)) End Function这段代码逻辑清晰先将IP和网段地址转为32位整数再通过位运算And比对是否落在同一子网。它规避了正则表达式或字符串分割的性能损耗在IIS 5.1环境下毫秒级完成判断。注意maskBits必须是整数若传入/25以外的值如/33会导致2^33溢出此时函数返回False——这反而是安全兜底行为。2.2 全局拦截入口nzcms_2.asp中的强制校验链所有业务页面manage_web.asp,zhiban.asp等顶部均包含!--#include filenzcms_2.asp--而nzcms_2.asp的核心逻辑是 nzcms_2.asp Dim clientIP, isAllowed, i clientIP Request.ServerVariables(REMOTE_ADDR) 处理代理转发场景X-Forwarded-For If Request.ServerVariables(HTTP_X_FORWARDED_FOR) Then clientIP Split(Request.ServerVariables(HTTP_X_FORWARDED_FOR), ,)(0) End If isAllowed False For i 0 To UBound(g_IPList) If InStr(g_IPList(i), /) 0 Then If IPInSubnet(clientIP, g_IPList(i)) Then isAllowed True : Exit For End If Else If clientIP g_IPList(i) Then isAllowed True : Exit For End If End If Next If Not isAllowed Then Response.Status 403 Forbidden Response.Write h1访问被拒绝/h1p您的IP地址 clientIP 不在授权列表中。/p Response.End End If注意HTTP_X_FORWARDED_FOR的处理仅取第一个IP防止客户端伪造长链。Response.End是关键——它立即终止响应流后续ASP代码包括数据库连接、HTML渲染完全不执行。这比跳转到错误页更安全杜绝了任何信息泄露可能。2.3 动态IP适配zhiban.asp中的值班员临时放行机制zhiban.asp作为值班管理页面实现了特殊放行逻辑当值班员使用工号密码登录后其当前IP会被临时加入Application(tempIPList)集合有效期2小时。该机制在zhiban.asp中体现为 zhiban.asp 登录成功后追加 If loginSuccess Then Dim tempIPs If IsEmpty(Application(tempIPList)) Then tempIPs Array(clientIP) Else tempIPs Application(tempIPList) ReDim Preserve tempIPs(UBound(tempIPs) 1) tempIPs(UBound(tempIPs)) clientIP End If Application.Lock Application(tempIPList) tempIPs Application(tempIPExpire) DateAdd(h, 2, Now()) Application.UnLock End If而nzcms_2.asp的校验逻辑随后扩展为 在原有 isAllowed 判断前插入 If Not IsEmpty(Application(tempIPList)) Then If Application(tempIPExpire) Now() Then For i 0 To UBound(Application(tempIPList)) If clientIP Application(tempIPList)(i) Then isAllowed True : Exit For End If Next Else Application.Lock Application(tempIPList) Empty Application(tempIPExpire) Empty Application.UnLock End If End If这种“静态白名单动态临时授权”双轨制既保障了日常访问的确定性又满足了值班场景的灵活性。Application对象的锁机制Lock/UnLock确保了多用户并发写入的安全性。3. 关键页面功能拆解与% %嵌入式开发模式实战3.1manage_web.asp基于ADO的SQL Server数据操作模板manage_web.asp是后台管理主入口其数据库操作严格遵循ASP经典模式Connection→Recordset→Close。以用户列表查询为例!-- manage_web.asp 片段 -- % Dim conn, rs, sql Set conn Server.CreateObject(ADODB.Connection) conn.Open ProviderSQLOLEDB;Data Source10.128.1.10;Initial Catalognzcms_db;User IDsa;PasswordAdmin2022; sql SELECT id, username, dept, last_login FROM users WHERE status1 ORDER BY last_login DESC Set rs Server.CreateObject(ADODB.Recordset) rs.Open sql, conn, 1, 3 adOpenKeyset, adLockOptimistic If Not rs.EOF Then % table border1 trthID/thth用户名/thth部门/thth最后登录/th/tr % Do While Not rs.EOF % tr td% rs(id) %/td td% Server.HTMLEncode(rs(username)) %/td td% rs(dept) %/td td% FormatDateTime(rs(last_login), 2) %/td /tr % rs.MoveNext Loop % /table % Else Response.Write p暂无活跃用户/p End If rs.Close Set rs Nothing conn.Close Set conn Nothing %提示Server.HTMLEncode()是必备防护防止XSSFormatDateTime(rs(last_login), 2)中参数2对应vbLongDate输出如2022年4月30日符合国内政务系统日期习惯。连接字符串明文写死在代码中虽不符合现代安全规范但在内网隔离环境中属常见做法。3.2list.asp分页与%短标记的高效渲染list.asp负责案件列表展示采用客户端分页因数据量小但%短标记的使用极大提升了HTML生成效率!-- list.asp -- % Dim pageSize, pageNum, totalRecords, totalPages pageSize 15 pageNum CInt(Request.QueryString(page)) If pageNum 1 Then pageNum 1 获取总记录数单次查询 Set rs Server.CreateObject(ADODB.Recordset) rs.Open SELECT COUNT(*) FROM cases WHERE status IN (1,2), conn, 1, 1 totalRecords rs(0) rs.Close totalPages Int((totalRecords - 1) / pageSize) 1 If pageNum totalPages Then pageNum totalPages 获取当前页数据 sql SELECT TOP pageSize * FROM cases WHERE id NOT IN _ (SELECT TOP ((pageNum-1)*pageSize) id FROM cases ORDER BY create_time DESC) _ ORDER BY create_time DESC rs.Open sql, conn, 1, 1 % div classcase-list % Do While Not rs.EOF % div classcase-item h3% Server.HTMLEncode(rs(title)) %/h3 pstrong编号/strong% rs(case_no) % | strong状态/strong% IIf(rs(status)1,待处理,已归档) % | strong时间/strong% FormatDateTime(rs(create_time), 2) %/p /div % rs.MoveNext : Loop % /div !-- 分页导航 -- div classpagination % For i 1 To totalPages % a href?page% i % class% IIf(ipageNum,active,) %% i %/a % Next % /div%是% Response.Write的简写减少字符输入提升可读性。IIf()函数用于三元表达式IIf(rs(status)1,待处理,已归档)比写完整If...Else更紧凑。分页SQL采用NOT IN子查询虽在大数据量下有性能瓶颈但对公安系统日均百条案件的场景足够高效。3.3nzcms_bq.aspBBS模块中的防注入参数化查询实践nzcms_bq.asp是内部论坛模块其发帖功能展示了ASP时代较先进的防注入手段——参数化查询通过Command对象 nzcms_bq.asp 发帖处理 If Request.Form(action) post Then Dim cmd Set cmd Server.CreateObject(ADODB.Command) cmd.ActiveConnection conn cmd.CommandText INSERT INTO posts (title, content, author_id, create_time) VALUES (?, ?, ?, GETDATE()) cmd.Parameters.Append cmd.CreateParameter(title, 200, 1, 255, Request.Form(title)) cmd.Parameters.Append cmd.CreateParameter(content, 201, 1, 10000, Request.Form(content)) cmd.Parameters.Append cmd.CreateParameter(author_id, 3, 1, , Session(user_id)) cmd.Execute Response.Redirect nzcms_bq.asp?msgsuccess End If注意cmd.Parameters.Append显式声明参数类型200adVarChar,201adLongVarChar,3adInteger和长度彻底阻断SQL注入。GETDATE()由SQL Server执行避免客户端时间篡改。这种写法在ASP项目中并不普遍说明该系统开发者具备较强的安全意识。4. 部署调试与IIS 6.0兼容性关键配置4.1 IIS 6.0虚拟目录设置与脚本映射验证该系统针对Windows Server 2003 IIS 6.0环境优化部署时需确认以下三项配置项正确值错误表现验证命令主目录执行权限“脚本和可执行文件”403.14错误目录浏览被禁cacls C:\Inetpub\wwwroot\nzcms /T /E /G IIS_WPG:RASP脚本映射.asp→C:\WINDOWS\system32\inetsrv\asp.dll404.2错误MIME类型未注册cscript adsutil.vbs get w3svc/1/root/ScriptMaps默认文档index.asp必须在首位显示IIS默认欢迎页而非系统首页cscript adsutil.vbs get w3svc/1/root/DefaultDoc提示adsutil.vbs位于C:\Inetpub\AdminScripts\是IIS 6.0原生管理工具。执行get w3svc/1/root/ScriptMaps后检查输出中是否存在.asp映射行且路径指向asp.dll。若缺失需手动添加cscript adsutil.vbs set w3svc/1/root/ScriptMaps .asp,C:\WINDOWS\system32\inetsrv\asp.dll,5,GET,HEAD,POST,TRACE。4.2 常见报错定位与On Error Resume Next的双刃剑用法系统大量使用On Error Resume Next见nzcms_sql.asax这是ASP时代处理COM组件异常的惯用手法但会掩盖真实错误。调试时需临时注释 nzcms_sql.asax 原始片段 On Error Resume Next Set conn Server.CreateObject(ADODB.Connection) conn.Open connStr If Err.Number 0 Then Response.Write 数据库连接失败 Err.Description Response.End End If On Error GoTo 0 恢复错误中断关键调试步骤在global.asa中启用Application(debug) True修改nzcms_2.asp在IP校验失败时追加日志If Not isAllowed Then Dim fso, logFile Set fso Server.CreateObject(Scripting.FileSystemObject) Set logFile fso.OpenTextFile(C:\Inetpub\wwwroot\nzcms\logs\access.log, 8, True) logFile.WriteLine Now() | BLOCKED | clientIP | Request.ServerVariables(URL) logFile.Close Response.Status 403 Forbidden Response.Write h1访问被拒绝/h1... Response.End End If检查IIS日志%SystemDrive%\inetpub\logs\LogFiles\W3SVC1\比对cs-uri-stem与sc-status字段确认是403还是500错误。4.3asp:gridview列中的数据怎么换行问题的本地化解决方案虽然该系统未使用.NET的GridView但list.asp中表格单元格内容过长时同样面临换行需求。标准做法是在CSS中设置style .case-item h3 { word-break: break-all; white-space: pre-line; } /style但ASP环境常需服务端预处理。nzcms_dna.asp提供WrapText函数Function WrapText(text, maxLength) Dim result, i, lenText result lenText Len(text) For i 1 To lenText If i Mod maxLength 1 And i 1 Then result result br result result Mid(text, i, 1) Next WrapText result End Function在list.asp中调用td% WrapText(Server.HTMLEncode(rs(title)), 20) %/td此函数按字符数强制换行比CSS更可控适用于IE6等老旧浏览器——这正是公安内网环境的真实约束。5. 安全加固与IP限制策略的演进式优化技巧5.1 从硬编码白名单到XML配置的平滑迁移data.asax的硬编码方式不利于运维。可创建ip_whitelist.xml?xml version1.0 encodingGB2312? whitelist ip10.128.1.5/ip ip10.128.1.12/ip subnet10.128.3.0/24/subnet subnet10.128.4.0/24/subnet /whitelist并在nzcms_dna.asp中添加加载函数Function LoadIPListFromXML() Dim xmlDoc, ipNodes, subnetNodes, i, list Set xmlDoc Server.CreateObject(Microsoft.XMLDOM) xmlDoc.Async False xmlDoc.Load Server.MapPath(ip_whitelist.xml) Set ipNodes xmlDoc.SelectNodes(//ip) Set subnetNodes xmlDoc.SelectNodes(//subnet) ReDim list(ipNodes.Length subnetNodes.Length - 1) For i 0 To ipNodes.Length - 1 list(i) ipNodes(i).Text Next For i 0 To subnetNodes.Length - 1 list(ipNodes.Length i) subnetNodes(i).Text Next LoadIPListFromXML list End Function然后在data.asax中替换为% Dim g_IPList g_IPList LoadIPListFromXML() %提示Microsoft.XMLDOM在IIS 6.0默认可用无需额外安装。GB2312编码确保中文注释正常读取。此改造零侵入现有逻辑仅替换数据源。5.2 日志审计增强记录IP校验全过程在nzcms_2.asp的校验逻辑末尾添加审计日志 校验完成后追加 Dim auditLog auditLog Now() | clientIP | isAllowed | Request.ServerVariables(HTTP_USER_AGENT) | Request.ServerVariables(URL) vbCrLf Dim fso, logFile Set fso Server.CreateObject(Scripting.FileSystemObject) Set logFile fso.OpenTextFile(Server.MapPath(logs\ip_audit.log), 8, True) logFile.Write auditLog logFile.Close生成的日志格式为2022-04-30 14:22:18|10.128.2.33|True|Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1)|/nzcms/manage_web.asp 2022-04-30 14:23:05|192.168.1.100|False|curl/7.58.0|/nzcms/index.asp配合Windows自带的findstr命令可快速分析findstr False C:\Inetpub\wwwroot\nzcms\logs\ip_audit.log | findstr 192.168精准定位非法扫描源。5.3 应急熔断nzcms_sql.asax中的数据库连接池保护nzcms_sql.asax定义了连接池超时与重试机制 nzcms_sql.asax Const MAX_CONN_ATTEMPTS 3 Const CONN_TIMEOUT 15 秒 Function GetDBConnection() Dim conn, attempts, startTime Set conn Server.CreateObject(ADODB.Connection) attempts 0 Do While attempts MAX_CONN_ATTEMPTS On Error Resume Next conn.Open connStr, , , 64 adConnectUnspecified If Err.Number 0 Then GetDBConnection conn Exit Function End If attempts attempts 1 If attempts MAX_CONN_ATTEMPTS Then WScript.Sleep 1000 等待1秒后重试 End If Loop 三次失败后返回空连接业务层需处理 Set GetDBConnection Nothing End Function64标志位adConnectUnspecified启用连接池WScript.Sleep避免雪崩式重连。当数据库短暂不可用时系统降级为只读IP校验仍生效保障核心访问控制不中断。本文还有配套的精品资源点击获取

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价