用rdp首先肯定是改端口,先躲一波攻击
不要一上来连远程都还没开就改端口,先设置远程,尝试默认3389工作得情况下,再修改,
否则注册表都找不到下面这些值
可以用powershell改
Get-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp' -name "PortNumber"
会返回信息比如
PortNumber : 3389
PSPath : Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp
PSParentPath : Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations
PSChildName : RDP-Tcp
PSDrive : HKLM
PSProvider : Microsoft.PowerShell.Core\Registry
例如需要更改为 9527 则可以用下面的命令,这个复制了到Powershell管理员执行就行。
$portvalue = 9527
Set-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp' -name "PortNumber" -Value $portvalue
New-NetFirewallRule -DisplayName 'RDPPORTLatest-TCP-In' -Profile 'Public' -Direction Inbound -Action Allow -Protocol TCP -LocalPort $portvalue
New-NetFirewallRule -DisplayName 'RDPPORTLatest-UDP-In' -Profile 'Public' -Direction Inbound -Action Allow -Protocol UDP -LocalPort $portvalue
以上是微软的官方代码,有教程更改计算机上的远程桌面的侦听端口
下面还有手动更改的老办法:
1、打开注册表:win+R打开运行对话框,输入“regedit”打开注册表
2、打开注册表路径:[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal Server\Wds\rdpwd\Tds\tcp]
3、这时在右边找到“PortNumber”双击打开
4、设置端口号:选择十进制,看到原端口号为:3389,这时候可以修改后点击确定即可。改成你需要的端口号(但是必须没有被占用的端口号)
5、接着依次打开[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp]
6、点击右边的端口号“PortNumber”同样为3389修改成和上面要改的端口一样,保存后重启电脑
7、通过上面的设置之后,端口号就设置完成了,接下来远程桌面连接的时候需要IP: 端口号的形似如 XXX.XXX.XXX.XXX:port的样式来连接
1:只修改了远程桌面端口还不行,必须修改防火墙远程桌面例外,保证远程桌面入站,打开防火墙,你可能会发现远程桌面是灰色,没有法更改,只能使用注册表
2:修改防火墙远程桌面例外的端口(1)
HKEY_LoCAL_MACHINE\sYsTEM\CurrentControlset\services\sharedAccess\Defaults\FirewallPolicy\FirewallRules,将RemoteDesktop-In-TCP的值中包含3389的数据改成你的端口
3:修改防火墙远程桌面例外的端口(2)
HKEY_LoCAL_MACHINE\sYsTEM\CurrentControlset\services\sharedAccess\Parameters\FirewallPolicy\FirewallRules,将RemoteDesktop-In-TCP的值中包含3389的数据改成你的端口
以下是都设置好了还翻车的一些低级原因:

控制面板改 电源选项,最佳性能或者 卓越,核心在于硬盘不休眠第二步是限制登录IP,这个方法简单,效果显著,比其他任何高级技术都立竿见影,基本用这个的人都是家和单位之间,99.99%的时候都是同城,那其实一个城市的IP段也就很少很少,无论是你手机变来变去,还是家里宽带动态IP,实际也就几段地址而已,这都很好写,就这样就好了,比如

选IP段的办法很简单,你只用时不时看一下你自己的IP,记下来,然后有几个网站(我后面找到贴上来),搜一下就知道这IP的一大段就好了,一个城市对多也就几十段,你单独一种网络撑死不到5段。
有人会说如果经常出差怎么办,出差也很简单,你可以准备一个二奶机,接上远程开关插头开机自启,到了出差的地方,看一眼自己的IP(顺便查到一大段),远程先mstsc二奶机,再用二奶机mstsc你的大奶机,填入你的出差的IP就好了,然后二奶机关机就好了,二奶机是不设IP登录限制的,但是硬件开关在你手上,也很安全。
只要你自己本身没中木马的话,改端口、限制IP就基本已经可以100%的危险了,
但是有的人比如我还是心理没底万一被人爆破了自己不知道那就没什么自信嘛,
这时候你会很自然的想到,每次登录都会给自己发消息(邮件、微信等),这样如果发现不是自己赶紧远程插头断电关机,物理掌控。
操作步骤:
Win + R -- eventvwr.msc -- 应用程序和服务日志 -- Microsoft -- Windows -- TerminalServices- RemoteConnectionManager -- Operational -- 筛选当前日志 -- 1149
可用1149触发计划任务发送提醒邮件或者推送


.vbs .ps1 .exe 等都可以
以下是一段上古vbs代码,可以新建一个文本,另存为 rdp-sendmail.vbs ,1149事件触发的程序选这个就行
NameSpace ="http://schemas.microsoft.com/cdo/configuration/"Set Email =CreateObject("CDO.Message")
Email.From ="[email protected]"'发件邮件地址
Email.To ="[email protected]"'收件邮件地址
Email.Subject ="Test_"+cstr(now()) '邮件主题
Email.Textbody ="OK! It is only a test."'邮件内容
Email.AddAttachment "D:\My Documents\My Pictures\809041233006998.jpg"'所带附件
With Email.Configuration.Fields
.Item(NameSpace&"sendusing") =2'CDO发送端口号
.Item(NameSpace&"smtpserver") ="smtp.gmail.com"'SMTP服务器
.Item(NameSpace&"smtpserverport") =465'SMTP服务器端口号
.Item(NameSpace&"smtpusessl") =true'SMTP服务器是否使用了SSL
.Item(NameSpace&"smtpauthenticate") =1'认证方式是BASIC
.Item(NameSpace&"sendusername") ="[email protected]"'发件人邮箱账号
.Item(NameSpace&"sendpassword") ="************"'发件人邮箱密码
.Update
End With
Email.Send
不过VBS还是过于老了,可能会有运行权限的问题,现在可以用更先进的powershell,
可以新建一个文本,另存为 rdp-login-push.ps1 ,1149事件触发的程序选这个就行,
# Webhook URL
$url = "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=<your token>"
# 获取最近一次 1149 事件
$latestEvent = Get-WinEvent -LogName "Microsoft-Windows-TerminalServices-RemoteConnectionManager/Operational" | Where-Object { $_.Id -eq 1149 } | Select-Object -First 1
if ($latestEvent) {
# 提取事件属性值
$properties = $latestEvent.Properties | ForEach-Object { $_.Value }
$username = $properties[0]
$ipAddress = $properties[2]
# 默认值处理
$username = if ($username) { $username } else { "Unknown" }
$ipAddress = if ($ipAddress) { $ipAddress } else { "Unknown" }
# 准备推送的消息
$content = "IP: $ipAddress, User: $username"
} else {
# 如果未找到事件
$content = "no recent login events found."
}
# 构造 JSON 请求
$params = @{
msgtype = "text"
text = @{
content = $content
}
} | ConvertTo-Json -Depth 3 -Compress
# 发送 Webhook 请求
Invoke-RestMethod -Uri $url -Method Post -Body $params -ContentType "application/json"
Write-Host "Webhook sent: $content"
但是.ps1还是不够好,可能也会遇到权限问题,不够丝滑无感,
可以用PS2EXE把.ps1生成.exe就好了,
就两行命令就可以,安装就用
Install-Module ps2exe
生成exe就用
Invoke-ps2exe .\source.ps1 .\target.exe
或者
ps2exe .\source.ps1 .\target.exe

这样,每次计算机被远程登录,你都会立马被微信通知

到此,就已经绝对安全了,毕竟被爆破就消息提醒后硬件断电最大,什么技术也不如硬件断电权限高。
剩下的就是一些非必要的操作
你一定很想知道哪里的IP、在什么时间、用什么用户名在爆破你,
那可以用powershell写一段运行,比如就叫RDPloginlog.ps1
# 定义输出文件路径
$outputFile = ".\RDPLogs.csv"
# 初始化 CSV 文件并写入表头
"Status,Time,IPAddress,Username" | Out-File -FilePath $outputFile -Encoding UTF8
# 获取所有安全日志中的事件
$allEvents = Get-WinEvent -LogName "Security"
foreach ($event in $allEvents) {
$eventId = $event.Id
$time = $event.TimeCreated
# 筛选 RDP 相关的事件 ID(4624 成功登录,4625 登录失败)
if ($eventId -eq 4624 -or $eventId -eq 4625) {
# 提取事件 XML
$eventXml = [xml]$event.ToXml()
# 提取登录类型(LogonType)
$logonType = $eventXml.Event.EventData.Data | Where-Object { $_.Name -eq "LogonType" } | Select-Object -ExpandProperty '#text'
# 提取 IP 地址
$ipAddress = "Unknown"
$ipElement = $eventXml.Event.EventData.Data | Where-Object { $_.Name -eq "IpAddress" }
if ($ipElement) {
$ipAddress = $ipElement.'#text'
}
# 提取用户名
$username = "Unknown"
$userElement = $eventXml.Event.EventData.Data | Where-Object { $_.Name -eq "TargetUserName" }
if ($userElement) {
$username = $userElement.'#text'
}
# 筛选远程桌面登录类型(LogonType = 10)
if ($eventId -eq 4624 -and $logonType -eq "10") {
$status = "Success"
"$status,$time,$ipAddress," | Out-File -FilePath $outputFile -Append -Encoding UTF8
} elseif ($eventId -eq 4625) {
$status = "Failure"
"$status,$time,$ipAddress,$username" | Out-File -FilePath $outputFile -Append -Encoding UTF8
}
}
}
Write-Host "RDP 日志已导出至 $outputFile"
或者反过来,你也可以查成功登录的(不过好像没必要,推送里面已经都看得到了),
Param(
[array]$ServersToQuery = (hostname),
[datetime]$StartTime = "January 1, 1970"
)
foreach ($Server in $ServersToQuery) {
$LogFilter = @{
LogName = 'Microsoft-Windows-TerminalServices-LocalSessionManager/Operational'
ID = 21, 23, 24, 25
StartTime = $StartTime
}
$AllEntries = Get-WinEvent -FilterHashtable $LogFilter -ComputerName $Server
$AllEntries | Foreach {
$entry = [xml]$_.ToXml()
[array]$Output += New-Object PSObject -Property @{
TimeCreated = $_.TimeCreated
User = $entry.Event.UserData.EventXML.User
IPAddress = $entry.Event.UserData.EventXML.Address
EventID = $entry.Event.System.EventID
ServerName = $Server
}
}
}
$FilteredOutput += $Output | Select TimeCreated, User, ServerName, IPAddress, @{Name='Action';Expression={
if ($_.EventID -eq '21'){"logon"}
if ($_.EventID -eq '22'){"Shell start"}
if ($_.EventID -eq '23'){"logoff"}
if ($_.EventID -eq '24'){"disconnected"}
if ($_.EventID -eq '25'){"reconnection"}
}
}
$Date = (Get-Date -Format s) -replace ":", "."
$FilePath = "D:\$Date`_RDP_Report.csv"
$FilteredOutput | Sort TimeCreated | Export-Csv $FilePath -NoTypeInformation
Write-host "Writing File: $FilePath" -ForegroundColor Cyan
Write-host "Done!" -ForegroundColor Cyan
#End
还有一点可能有人需要,就是在非自己电脑上rdp自己主机之后删除rdp记录(都什么年代了你还没一个手机或者电脑用,要去公用电脑RDP自己服务器吗?不建议,极其危险,现在公共使用还有没有毒的机吗?)
Win + R -- regedit -- HKEY_CURRENT_USER > SOFTWARE > Microsoft > Terminal Server Client > Default
展开“Default”并右键单击连接记录选择“删除”;在左侧窗格中,找到并展开Servers键,其中包含从该机器建立的所有远程桌面连接的详细信息,选择要删除的用户,然后右键单击“UsernameHint”将其删除。然后在主路径中找到RDP文件,这是一个隐藏文件,默认情况下不会显示。可以打开命令提示符,输入删除命令“del/ah%homepath%\documents\default.rdp”删除。
或者用cmd/bat
reg delete “HKEY_CURRENT_USER\Software\Microsoft\Terminal Server Client\Default” /va /f
reg delete “HKEY_CURRENT_USER\Software\Microsoft\Terminal Server Client\Servers” /f
reg add “HKEY_CURRENT_USER\Software\Microsoft\Terminal Server Client\Servers”
del /ah %homepath%\documents\default.rdp
以下是非常小众的一般人不需要看的扩展技术
如果你只有一个入站端口,但是有N个内网的RDP需要远程连接,就可以找个机子做RD网关,然后就可以跳转到所有机器。
这个是windows server的功能,
可以先装一个Windows Server 2019 Datacenter (Desktop Experience)
ed2k://|file|cn_windows_server_2019_updated_july_2020_x64_dvd_2c9b67da.iso|5675251712|19AE348F0D321785007D95B7D2FAF320|/
装完之后,可以先打补丁更新系统,
win+r -- sconfig 然后
1.打开“服务器管理器” → 添加角色和功能,直接一直下一步到“服务器角色”界面,勾选“远程桌面服务”的“远程桌面网关”,然后继续下一步到底,其中会自动关联安装IIS(web)模块。
2.服务器管理器 → 工具 → IIS 管理器(一般是第一个)→展开左边 Sites → 右键点 Default Web Site→“编辑绑定”,把HTTPS的默认443可以改成你自己的可以入站的端口,然后powershell执行
iisreset
3.服务器管理器 → 工具 → Remote Desktop Services → RD Gateway Manager
(1)Connection Authorization Policy(CAP)(连接授权策略)
控制谁可以通过网关
新建策略:
名称:AllowGroupAccess
允许用户组:比如添加 Administrators 或你自己的域账户组
认证方式:默认使用密码,也可勾选智能卡
(2)Resource Authorization Policy(RAP)(资源授权策略)
控制他们能连谁
新建策略:
名称:AllowToLAN
用户组:同上
资源组:可以写成 *(允许连接所有主机),或指定 IP/domain
协议:允许 RDP
(3)配置证书(必须做)
回到左侧树 → 右键你的服务器名 → 属性
切换到“SSL 证书”标签页
有两个选项:
使用你已有的合法证书(推荐)
没有的话点击“创建自签名证书”
勾选“允许使用此证书”
(4)改端口(将 443 改为xxxxx)
因为你没有 443 端口,做如下操作:
打开 IIS 管理器(服务器管理器 → 工具 → IIS)
展开左侧树,找到 “默认网站”
右键 → 绑定 → 选择 HTTPS → 编辑
把端口从 443 改成 xxxxx
然后再打开“RD Gateway Manager”:
在主界面右键服务器名 → 属性 → SSL标签页 → 也改成 xxxxx
4.接下来就可以在远程的电脑上用mstsc了,可以在“高级”里面设置RD网关,填入IP和端口号就可以了,然后登录的时候IP和端口直接填第二部的内网的就可以,到时候需要输两次密码,第一次是RD网关的,RD网关验证这里注意不要直接使用用户名,肯定错,要用 计算机名\用户名 或者 .\用户名 ,这样就对了。
此外,你一般的证书肯定不是RD网关要到哪种,就是下面一个问题
Let’s Encrypt域名证书格式不是pfx或者p12该怎么办
Linux / WSL / Git Bash / Cygwin 环境下有 OpenSSL,运行这个命令即可:
openssl pkcs12 -export -out cert.pfx -inkey privkey.pem -in fullchain.pem -certfile fullchain.pem
参数说明:
-inkey privkey.pem 是你的私钥
-in fullchain.pem 是服务器证书
-certfile fullchain.pem 是证书链(有时是 chain.pem)
它会让你输入一个密码(这个密码你必须记住!RD Gateway 导入时要用)
证书是其他格式,可以用
openssl pkcs12 -export -out domain.pfx -inkey domain.key -in domain.crt -certfile ca_bundle.crt
如果你没有 ca_bundle.crt,也可以临时省略 -certfile:
openssl pkcs12 -export -out domain.pfx -inkey domain.key -in domain.crt
不过最后要说是,RD网关了解了解就好了,跳一次太慢了,不够丝滑,不建议尝试。