ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

RDP安全加固:一键脚本修改远程桌面端口与防火墙配置

RDP安全加固:一键脚本修改远程桌面端口与防火墙配置 如果你管过哪怕一台长期开机的 Windows 机器那对 3389 这个端口绝对不会陌生。半年前我给自己一台 Windows Server 2022 例行巡检翻安全日志时发现一个晚上居然有上千条 RDP 登录失败记录全是扫描器在猜口令。把默认端口改掉之后这类暴力探测噪音瞬间下降了两个数量级。以前改端口这事全靠手动折腾改注册表、加防火墙规则、重启服务每一步都得小心翼翼。后来我把整套配置过程封装成一个自带检查逻辑的批处理脚本顺手整理出一套局域网直连 公网地址映射的双链路连接方案放进我自己维护的 WorkBuddy 工具集里。用到现在大半年稳得很。今天就把这套东西完整拆开讲清楚。IT 运维、搞自托管服务、经常在外需要连回家里电脑的折腾党应该都能用上。1. 为什么要改端口默认 3389 就是公网上的活靶子1.1 被扫描器盯上其实是常态接入公网的 Windows 机器几乎每天都在被全网扫描器探测。它们的例行动作很简单扫目标 IP 的 TCP 3389 端口发现端口开着就往里面怼弱口令、试漏洞。我见过最夸张的记录是一台刚装好系统、还没配防火墙的机器3 个小时内日志里出现二十多万条登录尝试。这不是个别现象而是公网环境每天都在发生的事。光靠 Windows 自带的账户锁定策略虽然能缓解一部分暴力破解但问题在于默认端口是公开的扫描器不需要花任何心思就能锁定目标。大量无效登录请求本身就会占用系统资源、刷爆安全日志而且一旦管理员用了弱密码服务器基本等同于裸奔。改端口本质上不是为了设置什么不可逾越的障碍而是把默认的、可预测的入口变成一个需要扫描器额外费劲去探测的参数。全网扫描器大多只扫常见端口清单你把它改成 13390 之后自动化的扫描流量自然会大幅减少。当然针对性攻击不在这个范畴内后面第 4 章我会专门聊在公网场景下还需要做哪些事。1.2 手动配置三步走一步错就当场翻车绝大多数情况下改 RDP 端口需要动三样东西注册表、防火墙、远程桌面服务。注册表路径要记对防火墙要开对端口服务要重启到位三步全对才能连上。问题就出在——这三步里任何一步错了结果往往是改完端口自己连不回去人在办公室机器在机房只能跑现场。我早期手动配置的流程大概是这样的WinR 打开 regedit定位到HKLM\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp把PortNumber从 3389 改成目标端口。打开 Windows Defender 防火墙新建入站规则放行 TCP 对应端口。打开服务管理器重启Remote Desktop Services。这套流程看起来很简单实际执行时坑很多。比如注册表 DWORD 值你到底是输十进制还是十六进制防火墙规则作用域是选域、专用还是公用服务器装的是 Server Core没有图形界面连 regedit 都打不开怎么办批量给几十台机器做同样的配置总不能一台一台去点。所以我才把这三个步骤写成了无脑执行的批处理脚本。脚本自己判断注册表有没有写进去、防火墙规则建没建成、服务状态对不对出问题能直接在控制台看到原因不用再靠肉眼排查。2. 脚本核心模块拆解注册表、防火墙与服务联动2.1 注册表端口写入DWORD 值别搞混RDP 监听端口存在注册表这个位置HKLM\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp键值名是PortNumber数据类型是REG_DWORD默认值为十进制 3389。写入用reg add命令reg add HKLM\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp /v PortNumber /t REG_DWORD /d 13390 /f这里面有两个容易被忽略的地方。第一/t REG_DWORD后面跟的/d参数直接写十进制数值就行比如13390不用换算成十六进制reg add会自动转换。第二/f参数表示强制覆盖不加的话如果键值已存在会交互式询问是否覆盖脚本跑起来就会卡住。除了端口号还需要确认远程桌面功能本身是开启的对应键值是HKLM\SYSTEM\CurrentControlSet\Control\Terminal Server\fDenyTSConnections这个值等于0表示允许远程连接等于1表示拒绝。有些精简版系统装完默认是拒绝状态图形界面的允许远程桌面连接关着光改端口不把这个值改过来端口配得再对也连不上。脚本里我会同时把这里纠偏。2.2 防火墙规则创建先删旧规则再建新规则Windows 自带的防火墙管理命令是netsh advfirewall新增规则写法如下netsh advfirewall firewall delete rule nameWorkBuddy_RDP nul 21 netsh advfirewall firewall add rule nameWorkBuddy_RDP dirin actionallow protocolTCP localport13390 profileany第一行很重要。批量跑脚本的时候如果之前已经创建过同名规则不先删除的话可能产生规则冲突、或者覆盖失败。我习惯用固定的规则名前缀比如WorkBuddy_RDP这样每次执行脚本都会先清理旧规则再建新规则保证状态一致。第二行参数说明dirin入站规则针对外部连进来的流量。actionallow允许通过。protocolTCPRDP 走的是 TCP。localport13390目标端口也就是你刚在注册表里改好的那个端口。profileany同时作用在域、专用、公用三种网络类型上。如果你希望只在专用网络里生效可以改成profileprivate,domain但在现实办公环境里很多时候服务器所在的网络被 Windows 识别为公用保守起见用any最省心。这里多说一句如果机器上装了第三方安全软件它可能会接管防火墙netsh advfirewall添加的规则未必能同步到它的规则引擎里。这种情况我在第 4 章会单独讲。2.3 服务重启与状态检查验证环节不能省注册表改完、防火墙规则建好并不代表配置已经生效。TermService 进程在启动时读取的是默认 3389 端口必须重启服务才能读取新的注册表值。批处理里对应的命令net stop TermService net start TermService需要注意Remote Desktop Services这个服务依赖Remote Desktop Services UserMode Port RedirectorUmRdpService。有些系统版本只重启 TermService 会提示依赖服务未启动稳妥的做法是先看依赖服务状态必要的话一起处理。这里要提醒一件事如果你是通过远程桌面连着这台机器跑脚本重启 TermService 会把当前会话直接断掉。我自己的习惯是要么在服务器本地控制台执行要么提前告诉同事断开重连是正常现象。脚本里也可以加一个提示让操作的人有心理准备。服务启动后还需要验证端口是否真的在监听。命令netstat -ano | findstr :13390能看到 LISTENING 状态就说明服务读取新端口成功了。脚本里可以把这个结果直接打印出来方便操作者当场判断。3. 双链路方案局域网直连与公网 NAT 映射3.1 局域网直连脚本顺手输出内网地址远程桌面连接命令的格式是mstsc /v:IP地址:端口号比如内网机器 IP 是192.168.1.100端口改成13390那连接时就是mstsc /v:192.168.1.100:13390在脚本结束时自动获取并打印本机的 IPv4 地址会方便很多。批处理里可以调用ipconfig抓取也可以用 PowerShell 只读取活动的 IPv4 地址for /f tokens14 %%a in (ipconfig ^| findstr /i IPv4) do echo 局域网 IPv4%%a这种方法在多网卡机器上会输出所有 IPv4 地址正好把内网口、管理口的地址都列出来。用户直接复制一个地址去连就行省得跑 cmd 敲 ipconfig 还要自己找。局域网直连场景下端口是不是常用端口其实无所谓内网环境相对可控重点是延迟低、带宽够。如果办公室里有域环境建议关闭脚本里改端口的操作只做防火墙规则检查避免和域策略冲突。这个我在第 5 章会给出判断逻辑。3.2 公网链路路由器端口转发 非标准端口有公网 IPv4 的情况下想要从外部直接连到内网机器需要在路由器或防火墙上做端口转发也常被称为 NAT 映射。转发规则核心参数是四样协议TCP外部端口自定义一个高位端口比如 13390内部 IP内网那台 Windows 机器的地址比如 192.168.1.100内部端口也就是脚本里设置的 RDP 监听端口通常和外部端口保持一致配置完路由器之后公网侧的连接方式就是mstsc /v:公网IP:13390路由器收到这个端口的入站流量会按照转发规则把它交给内网机器的 13390 端口这样 RDP 连接就能穿透到内网。很多家用路由器管理界面里转发规则或虚拟服务器的位置就能配置。需要特别注意的是如果运营商分配给你的不是静态公网 IP而是动态公网 IP那 IP 每隔一段时间会变。这种情况可以配合 DDNS 服务把动态 IP 绑定到一个固定域名上外网连接直接写mstsc /v:yourdomain.example:13390即可。DDNS 的解决办法在很多路由器里是内置功能填上服务商提供的账号就行不用在 Windows 里额外装东西。3.3 双链路使用技巧内外网用不同的连接入口所谓双链路直连本质就是结合局域网和公网两种场景场景连接目标典型入口办公室 / 家里局域网内网 IP:13390mstsc /v:192.168.1.100:13390出差 / 外网公网 IP 或 DDNS 域名:13390mstsc /v:yourdomain.example:13390在局域网里连接速度快稳定性好在外面用公网域名连接只要有网就能回到机器上。两条链路共用同一个 RDP 监听端口不需要额外配置。公网映射场景下我还建议你做两个加固动作在路由器上限制允许访问的源 IP。很多路由器支持在端口转发规则里限定来源 IP只放行你公司出口 IP 或家里宽带的 IP其余全部拒绝。这样哪怕端口暴露在公网上绝大多数扫描流量也会被挡在路由器外面。在 Windows 里启用 NLA网络级别认证。让客户端在登录窗口弹出之前就先完成一层凭据校验不改协议端口也能减少很多无效连接。这两个动作用不上也行但做了之后远程桌面的安全体验会有明显提升。4. 部署过程中的坑我踩过的那些典型问题4.1 改完端口后连不上先怀疑服务没刷新脚本改完端口、建好防火墙规则看着每一步都正常结果在另一台机器上mstsc /v:IP:13390还是报无法连接。这种场景我遇到太多次了排错顺序非常重要。第一步看端口监听netstat -ano | findstr :13390如果这里什么都没显示说明 TermService 没有读到新端口按经验大概率是服务没重启成功或者重启后又因为某种原因退出了。再去看服务状态sc query TermService如果服务处于STOPPED手动启动一次并观察是否报错。这里容易出现一个怪现象服务启动后用 netstat 看到的是 3389 而不是 13390。原因很可能是服务没有真正重启只是把它停止后又在旧的注册表缓存基础上恢复了。最粗暴但有效的办法是重启整台服务器。第二步检查防火墙规则netsh advfirewall firewall show rule nameWorkBuddy_RDP确认规则存在、方向是 In、动作是 Allow、协议 TCP、端口写的是你新改的端口。注意有没有手滑把端口写错。第三步在服务器本机做回环测试telnet 127.0.0.1 13390本机能通说明服务和防火墙规则没问题问题出在中间网络环境本机都不能通那就是前面几步配置的问题。4.2 第三方安全软件接管防火墙注册表被回滚现在很多 Windows 服务器上装的是第三方安全软件这类软件通常会接管系统防火墙甚至监控注册表关键项的变更。有次我在一台装了三六零安全卫士的机器上跑脚本日志里显示注册表写入成功防火墙规则添加成功但实测端口怎么都不通。最后发现是安全软件把注册表的PortNumber又改回了 3389防火墙规则也被它的主动防御拦掉了。处理办法分两种。一种是在安全软件里把批处理脚本加入白名单再跑一遍另一种是干脆用安全软件自己提供的图形界面或命令行工具来加放行规则。我的经验是跑脚本前先跟安全软件打个招呼先把拦截弹窗那个界面开着脚本每执行一步都看一眼有没有被拦。跑完再验证整条链路的注册表值、防火墙规则、端口监听一次通过才算数。4.3 改端口挡不住所有爆破账户策略要跟上改了端口之后全网扫描器的噪音会明显下降但如果有人针对你的公网 IP 做定向扫描高位端口照样能被发现。因为 TCP 端口一共就 65535 个要扫一个特定 IP 的所有端口在流量不大的情况下几分钟内也能得到结果。所以我一直强调改端口只是第一层过滤真正扛爆破的还是账户策略。建议打开本地安全策略做三件事设置账户锁定阈值为 5 次连续输错 5 次密码账户锁定 15 分钟或者更久。禁用内置 Administrator 账户新建一个普通管理员账户用长密码。启用 NLA网络级别认证不能在 login 阶段直接暴露桌面。我用net accounts命令行来设置锁定策略因为批处理脚本里调用最方便net accounts /lockoutthreshold:5 net accounts /lockoutduration:15 net accounts /lockoutwindow:15在域环境里这套策略会被域控制器下发的组策略覆盖但在工作组环境或独立服务器上命令行设置完立刻生效。4.4 兼容性差异Server Core、Win7、老版本 netsh不同版本 Windows 的网络命令存在细微差异。Windows Server Core 没有图形界面批处理脚本反而更适合它因为它天然就工作在命令行环境。但 Windows 7 和 Server 2008 R2 上跑netsh advfirewall时profileany这个参数是支持的不用担心真正需要注意的反而是如果你在这个环境上把服务所在配置文件指定成private,domain而实际网络被识别为公用网络规则就不会命中。另外如果你之前在这台机器上用过 RDP Wrapper 这类工具来突破多用户并发限制配置 RDP 端口时就要格外小心。RDP Wrapper 的原理是劫持 termsrv.dll它会接管一部分注册表配置。我和它同时改PortNumber时会互相覆盖表现为端口改完过一阵子又变回默认值或者 RDP Wrapper 显示not supported。在同一环境里建议二选一要么用 RDP Wrapper 的完整方案要么用系统自带的 RDP 配置加注册表改端口混用通常没好下场。5. WorkBuddy 完整代码带参数的一键脚本与回滚方案5.1 核心脚本WorkBuddy_RDP_SetPort.bat我把脚本写成支持带参执行默认端口 13390也可以用参数指定其他端口。脚本内容包括权限检查、参数解析、注册表写入、防火墙规则重建、服务重启、结果验证最后打印本机 IPv4 和连接方式。echo off chcp 65001 nul setlocal enabledelayedexpansion :: :: WorkBuddy - RDP Port Firewall Config :: 用法: WorkBuddy_RDP_SetPort.bat [端口号] :: 示例: WorkBuddy_RDP_SetPort.bat 13390 :: :: ---- 1. 管理员权限检查 ---- net session nul 21 if %errorlevel% neq 0 ( echo [错误] 请右键选择以管理员身份运行本脚本。 pause exit /b 1 ) :: ---- 2. 端口参数解析 ---- set RDP_PORT13390 if not %~1 set RDP_PORT%~1 :: 简单校验端口范围 if %RDP_PORT% lss 1024 ( echo [警告] 端口低于1024不建议用于RDP继续执行可能导致意外问题。 choice /c YN /m 是否继续 if errorlevel 2 exit /b 1 ) if %RDP_PORT% gtr 65535 ( echo [错误] 端口号超过65535不合法。 pause exit /b 1 ) echo [信息] 目标RDP端口: %RDP_PORT% :: ---- 3. 注册表写入 ---- reg add HKLM\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp /v PortNumber /t REG_DWORD /d %RDP_PORT% /f nul if errorlevel 1 ( echo [错误] 注册表端口写入失败请检查权限或安全软件拦截。 pause exit /b 1 ) reg add HKLM\SYSTEM\CurrentControlSet\Control\Terminal Server /v fDenyTSConnections /t REG_DWORD /d 0 /f nul :: ---- 4. 防火墙规则重建 ---- netsh advfirewall firewall delete rule nameWorkBuddy_RDP nul 21 netsh advfirewall firewall add rule nameWorkBuddy_RDP dirin actionallow protocolTCP localport%RDP_PORT% profileany nul if errorlevel 1 ( echo [错误] 防火墙规则创建失败。 pause exit /b 1 ) echo [信息] 防火墙规则已放行 TCP %RDP_PORT% :: ---- 5. 重启远程桌面服务 ---- echo [信息] 正在重启 Remote Desktop Services ... net stop TermService nul 21 timeout /t 2 /nobreak nul net start TermService nul 21 :: 等几秒让服务稳定 ping -n 5 127.0.0.1 nul :: ---- 6. 验证端口监听 ---- netstat -ano | findstr :%RDP_PORT% | findstr LISTENING nul if errorlevel 1 ( echo [警告] 端口 %RDP_PORT% 未检测到监听状态。 echo [提示] 请尝试重启本机后再用 netstat 检查。 ) else ( echo [确认] 端口 %RDP_PORT% 已进入监听状态。 ) :: ---- 7. 输出连接信息 ---- echo. echo echo 本机 IPv4 地址: for /f tokens14 %%a in (ipconfig ^| findstr /i IPv4) do ( echo %%a ) echo. echo 局域网连接: mstsc /v:本机IPv4地址:%RDP_PORT% echo 公网连接: mstsc /v:公网IP或域名:%RDP_PORT% echo 需要先在路由器做 TCP %RDP_PORT% 端口转发 echo echo. pause脚本里net stop TermService之后我加了 2 秒等待这样服务停止得干净一点重启后不容易出现端口被 TIME_WAIT 状态占住的奇怪问题。ping -n 5 127.0.0.1纯粹是当作 sleep 用Windows 批处理没有 Unix 那种sleep 3用这个办法最省事。chcp 65001配合脚本内的中文提示时建议将 bat 文件保存为UTF-8 编码否则中文可能显示乱码。如果你懒得改编码直接删掉第一行的chcp 65001 nul把文件存成 ANSIGBK编码中文提示也能正常显示。两种做法都没问题关键是 bat 文件的实际编码要和 CMD 的代码页匹配这一条很多新手容易忽略。5.2 回滚方案WorkBuddy_RDP_Reset.bat改端口这种事配错了要能快速退回默认状态。回滚脚本逻辑很简单把注册表端口重新写回 3389删除自定义防火墙规则重启服务。echo off chcp 65001 nul setlocal enabledelayedexpansion net session nul 21 if %errorlevel% neq 0 ( echo [错误] 请以管理员身份运行。 pause exit /b 1 ) echo [信息] 恢复默认RDP端口 3389 ... reg add HKLM\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp /v PortNumber /t REG_DWORD /d 3389 /f nul reg add HKLM\SYSTEM\CurrentControlSet\Control\Terminal Server /v fDenyTSConnections /t REG_DWORD /d 0 /f nul echo [信息] 删除 WorkBuddy_RDP 防火墙规则 ... netsh advfirewall firewall delete rule nameWorkBuddy_RDP nul 21 echo [信息] 重启远程桌面服务 ... net stop TermService nul 21 timeout /t 2 /nobreak nul net start TermService nul 21 netstat -ano | findstr :3389 | findstr LISTENING nul if errorlevel 1 ( echo [警告] 3389 未处于监听状态建议重启系统。 ) else ( echo [确认] 3389 已恢复监听可以继续使用 mstsc /v:IP:3389 连接。 ) pause回滚脚本同样需要管理员权限运行。如果你改完端口以后一直用的是mstsc /v:IP:13390回滚到 3389 之后客户端连接命令也要改回来不然还是会连不上。因为 RDP 客户端使用mstsc /v:IP不写端口时默认走的就是 3389。5.3 批量部署与日常运维建议WorkBuddy 脚本设计成命令行带参执行天然适合批量部署。比如你有 20 台 Windows 服务器需要统一改成 13390 端口可以使用远程执行方式比如 PsExec 或其他运维工具把脚本推上去跑。但批量场景里有一个和单机不同的坑每台机器上的第三方安全软件环境可能不一样有的放行注册表修改有的会拦截。我的做法是先挑一台环境最接近的测试机执行一遍确认脚本流程没问题再批量铺开。日常运维我还会配合计划任务做定期体检用reg query读取当前PortNumber确认没有被安全软件回滚。用netsh advfirewall firewall show rule nameWorkBuddy_RDP确认规则还在。用netstat -ano | findstr :端口确认 RDP 端口在监听。这三个检查项可以写成一个很小的脚本用计划任务每天跑一次发现异常就写入日志甚至通过邮件或其他告警通道发出来。最后总结一点自己的使用习惯。我始终把跑完脚本必须当场验证作为铁律脚本执行完毕后一定要用另一台机器mstsc连一次能正常进到登录界面才算配置完成。如果连不上优先看netstat端口监听情况和防火墙规则状态不要一上来就怀疑注册表写错了。WorkBuddy 这套脚本我从 Server 2008 R2 一路用到 Windows 11核心逻辑基本没变过真正变来变去的只有各种不同安全软件带来的环境兼容问题。按上面这套方式处理再配上账户锁定策略和 NLA远程桌面的公网直连其实没有那么吓人。
返回列表