RDP 实战与排错 — 抓包、mstsc/xfreerdp 与常见连接故障

Wireshark 抓 RDP、mstsc/xfreerdp/PowerShell 配置命令、连接失败与 CredSSP 报错排查 / 应用层 / TCP 3389

这篇你能学到

  • 怎么用 Wireshark / tcpdump / pktmon 抓到 RDP 流量,以及在密文里还能看出哪些线索(协商结果、失败码、通道列表)。
  • mstscxfreerdp、PowerShell 三套命令的常用参数,从连接、改端口到会话管理。
  • 六类高频故障(连不上、CredSSP 报错、NLA 不支持、证书告警、黑屏、卡顿)的结论先行排查路径,以及 RDP/VNC/SSH/SPICE/X11 的横向对比和面试速查。

1. 抓包观察

1.1 Wireshark 显示过滤式

这组过滤式能干什么:从一堆流量里精准捞出 RDP,并且按层次拆开看——想看谈判过程就用 cotp,想看通道分配就用 t125,想确认加速通道有没有生效就看 udp.port==3389

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
tcp.port == 3389 # 全部 RDP 流量(含 TLS 密文)
rdp # Wireshark RDP 解析器(仅明文阶段可解)
tpkt # TPKT 层(version==0x03 是 RDP 特征)
t125 # MCS 层:Connect-Initial / Channel Join
cotp # X.224/COTP:CR/CC 协商包
cotp.type == 0x0e # Connection Request
cotp.type == 0x0d # Connection Confirm
rdp.rt_cookie # 明文 mstshash 用户名 Cookie
tls.handshake.type == 1 && tcp.port==3389 # RDP 内的 TLS ClientHello
tls.handshake.type == 11 && tcp.port==3389 # 服务端证书(看自签名主体)
udp.port == 3389 # RDP-UDP 加速通道
udp.port == 3391 # RD Gateway UDP over RDP
tcp.port == 3389 && tcp.flags.reset == 1 # 被拒绝/重置的连接

命令行等价抓取:

这组命令能干什么:在没有图形界面的服务器上把 RDP 流量落盘成 pcap 文件,再拿回本地慢慢分析。Windows 那三行尤其实用——不用装 Wireshark,系统自带的 pktmon 就能抓包并转成 pcap。

1
2
3
4
5
6
7
8
9
# Linux/macOS
sudo tcpdump -i any -nn 'tcp port 3389 or udp port 3389' -w rdp.pcap
# 只看握手前 30 个包的关键字段
tshark -r rdp.pcap -Y 'cotp || t125' -V | head -120

# Windows(无需装 Wireshark,用内置 pktmon)
pktmon start --capture --pkt-size 0 -f
pktmon filter add RDP -p 3389
pktmon stop && pktmon etl2pcap PktMon.etl -o rdp.pcap

1.2 典型字段说明(看什么)

观察点字段 / 现象判读
第 1 个数据包cotp Connection Request,Cookie: mstshash=alice客户端已到达服务端;用户名明文可见(安全提示)
CR 中requestedProtocols0x03 = TLS+CredSSP客户端愿意用的安全等级
CC 中selectedProtocol0x02=CredSSP、0x01=TLS、0x00=RC4服务端最终选择;返回 Negotiation Failure(0x03) 说明双方安全策略不匹配
CC 失败码SSL_REQUIRED_BY_SERVER(1) / SSL_NOT_ALLOWED_BY_SERVER(2) / HYBRID_REQUIRED_BY_SERVER(5)直指"服务端强制 NLA / 客户端不支持"类故障
TLS 证书Subject: CN=<主机名>,Issuer 相同自签名证书 → 客户端弹"证书不受信任"
MCS Connect-InitialGCC 客户端核心数据:desktopWidth/HeightcolorDepthclientNamekeyboardLayout确认分辨率/色深协商,排查显示异常
Channel Join逐条 channelId(1003 是 I/O 通道)缺少 cliprdr/rdpdr → 剪贴板/磁盘重定向被策略禁用
稳态流量TPKT 0x03 消失,出现首字节 0x00/0x04 的短包已切到 Fast-Path,属正常
UDP 侧udp.port==3389 有持续双向流量UDP 传输生效;只有 TCP 有流量 → UDP 被防火墙拦,弱网下会卡
无任何响应只有客户端 SYN 重传端口未监听/防火墙丢弃(DROP 而非 REJECT)

2. 常用命令 / 配置

2.1 Windows 客户端(mstsc)

这组命令能干什么:mstsc 是 Windows 自带的远程桌面客户端,命令行参数让你跳过图形界面直接连,并预设分辨率、屏幕数、凭据保存策略等。/restrictedAdmin 尤其值得记住——它让你的密码不会落在远端机器上。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
mstsc # 打开图形界面
mstsc /v:192.168.1.10:3389 # 直连指定主机端口
mstsc /v:srv01 /f # 全屏
mstsc /v:srv01 /w:1920 /h:1080 # 指定分辨率
mstsc /v:srv01 /multimon # 多显示器
mstsc /v:srv01 /admin # 连接到控制台会话(服务器管理用)
mstsc /v:srv01 /restrictedAdmin # 受限管理员模式(不把凭据留在远端)
mstsc /v:srv01 /public # 公共模式,不保存凭据/位图缓存
mstsc C:\rdp\srv01.rdp # 使用 .rdp 配置文件
mstsc /edit C:\rdp\srv01.rdp # 编辑 .rdp 文件

2.2 Windows 服务端配置(PowerShell,管理员)

这组命令能干什么:在被连的那一端把远程桌面打开、放行防火墙、强制启用 NLA,并查看/管理当前有谁登着。排查"连不上"时,前四条基本就是标准体检项。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# 查看/开启远程桌面(0 = 允许)
Get-ItemProperty 'HKLM:\System\CurrentControlSet\Control\Terminal Server' -Name fDenyTSConnections
Set-ItemProperty 'HKLM:\System\CurrentControlSet\Control\Terminal Server' -Name fDenyTSConnections -Value 0

# 放行防火墙(TCP+UDP 3389)
Enable-NetFirewallRule -DisplayGroup "远程桌面"
Enable-NetFirewallRule -DisplayGroup "Remote Desktop"

# 强制 NLA(1 = 要求网络级身份验证)
Set-ItemProperty 'HKLM:\System\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp' `
  -Name UserAuthentication -Value 1

# 查看当前监听端口
Get-ItemProperty 'HKLM:\System\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp' -Name PortNumber
netstat -ano | findstr :3389
Get-Service TermService

# 会话管理
query user # 列出会话(等价 quser)
query session # 列出会话状态
logoff 2 # 注销会话 ID 2
tscon 2 /dest:console # 把会话 2 接管到控制台
rwinsta rdp-tcp#5 # 重置指定会话

# 重启服务(会踢掉所有会话,慎用)
Restart-Service TermService -Force

2.3 Linux 客户端 / 服务端

这组命令能干什么:Linux 上用 xfreerdp 连 Windows,参数覆盖了安全模式、证书信任、剪贴板与磁盘重定向、弱网优化、音频;后半段则是反过来——让 Linux 自己变成 RDP 服务端(xrdp),并查看它的日志。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
# FreeRDP 客户端(推荐)
xfreerdp /v:192.168.1.10 /u:alice /d:CORP /p:'密码' /size:1600x900
xfreerdp /v:srv01 /u:alice /cert:ignore # 忽略自签名证书
xfreerdp /v:srv01 /u:alice /sec:nla # 强制 NLA
xfreerdp /v:srv01 /u:alice /sec:tls # 强制 TLS(服务端未开 NLA 时)
xfreerdp /v:srv01 /u:alice +clipboard /drive:home,/home/alice # 剪贴板 + 磁盘重定向
xfreerdp /v:srv01 /u:alice /gfx:AVC444 /network:modem # 弱网优化
xfreerdp /v:srv01 /u:alice /sound:sys:pulse /microphone # 音频双向
xfreerdp /v:srv01 /u:alice /log-level:DEBUG # 排错必用

# Remmina(GUI 客户端)
remmina -c rdp://alice@192.168.1.10

# Linux 做 RDP 服务端
sudo apt install xrdp
sudo systemctl enable --now xrdp
sudo systemctl status xrdp
sudo ss -tlnp | grep 3389
sudo journalctl -u xrdp -f
tail -f /var/log/xrdp-sesman.log

2.4 连通性与安全检测

这组命令能干什么:先确认"端口到底通不通",再用 nmap 脚本探出服务端的 NTLM 信息与加密配置;最后一段是最推荐的安全访问姿势——用 SSH 隧道把 3389 藏起来,不直接暴露在公网。

1
2
3
4
5
6
7
8
9
# 端口探测
nc -zv 192.168.1.10 3389
nmap -p 3389 --script rdp-ntlm-info,rdp-enum-encryption 192.168.1.10
# 检查是否易受 BlueKeep 影响(仅授权环境)
nmap -p 3389 --script rdp-vuln-ms12-020 192.168.1.10

# 通过 SSH 隧道安全访问,避免 3389 暴露公网
ssh -N -L 13389:192.168.1.10:3389 user@jumphost
mstsc /v:127.0.0.1:13389

2.5 修改 RDP 监听端口(降低扫描噪音)

这组命令能干什么:把监听端口从人尽皆知的 3389 换成别的,顺带把新端口的防火墙规则一起加上(TCP 和 UDP 都要加,否则弱网加速失效)。注意这只是降噪,不能替代 NLA、账户锁定等真正的安全措施。

1
2
3
4
5
Set-ItemProperty 'HKLM:\System\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp' `
  -Name PortNumber -Value 13389
New-NetFirewallRule -DisplayName "RDP-13389" -Direction Inbound -Protocol TCP -LocalPort 13389 -Action Allow
New-NetFirewallRule -DisplayName "RDP-13389-UDP" -Direction Inbound -Protocol UDP -LocalPort 13389 -Action Allow
Restart-Service TermService -Force

3. 常见故障与排错

3.1 “远程桌面无法连接到远程计算机”

先记住结论:这是最笼统的报错,九成落在"服务没开 / 防火墙拦了 / 端口被改了 / 你没权限 / 会话满了“这五类里,按下表从网络层往上逐级排除即可。

可能原因排查方法
远程桌面未启用服务端查 fDenyTSConnections 是否为 0;Get-Service TermService 是否 Running
防火墙拦截Test-NetConnection srv01 -Port 3389;客户端只见 SYN 重传即为 DROP
端口被改服务端查 PortNumber 注册表值;netstat -ano | findstr LISTENING
端口被占用Get-Process -Id (Get-NetTCPConnection -LocalPort 3389).OwningProcess
用户无权限用户需属于 Remote Desktop Users 或 Administrators 组
会话数超限工作站版仅 1 个会话;query userlogoff <ID> 释放

3.2 “出现身份验证错误,要求的函数不受支持”(CredSSP 加密 Oracle 修正)

先记住结论这不是你的密码错了,而是两台机器的补丁状态不一致——正确解法是给服务端打补丁,改客户端策略只是应急。

现象:打补丁后的客户端连未打 CVE-2018-0886 补丁的服务端时报错。 原因:CredSSP 加密 Oracle 修正策略默认 Mitigated,拒绝与未修补服务端协商。 正确做法:给服务端打补丁。临时绕过(有安全风险,仅内网应急):

下面这段能干什么:把客户端的 CredSSP 策略临时放宽到"允许连未修补的服务端”,让你先把活干完。修好服务端后一定要改回 0,否则等于长期留了个中间人攻击面。

1
2
3
4
5
6
# 客户端临时放宽策略
New-Item 'HKLM:\Software\Microsoft\Windows\CurrentVersion\Policies\System\CredSSP\Parameters' -Force
Set-ItemProperty 'HKLM:\Software\Microsoft\Windows\CurrentVersion\Policies\System\CredSSP\Parameters' `
  -Name AllowEncryptionOracle -Value 2 -Type DWord
gpupdate /force
# 修补服务端后务必改回 0(Force Updated Clients)

3.3 “远程计算机需要网络级别身份验证,而您的计算机不支持”

先记住结论服务端强制要求 NLA,而你的客户端太老不会用——升级客户端是正解,降级服务端安全策略是下策。

  • 客户端过旧(如 XP/老版 FreeRDP)不支持 CredSSP。
  • 排查:抓包看 CC 返回 HYBRID_REQUIRED_BY_SERVER(0x05)
  • 方案:升级客户端;或 xfreerdp /sec:tls;或服务端 UserAuthentication=0降低安全性,不推荐)。

3.4 证书告警:“无法验证此远程计算机的身份”

先记住结论这不是故障,是服务端在用自签名证书——功能完全可用,但你无法确认对面是不是真的那台机器。要消除告警就换成企业 CA 签发的证书。

  • 原因:服务端使用自签名证书。
  • 方案:部署企业 CA 签发证书并绑定:

下面这段能干什么:从本机证书库里按主体名找出证书的指纹,再把这个指纹绑定到 RDP 监听器上,让 RDP 改用受信任的证书而不是自签名证书。

1
2
3
4
# 用指纹绑定证书到 RDP 监听器
$thumb = (Get-ChildItem Cert:\LocalMachine\My | Where-Object Subject -like "*srv01*").Thumbprint
Set-WmiInstance -Class "Win32_TSGeneralSetting" -Namespace root\cimv2\terminalservices `
  -Filter "TerminalName='RDP-tcp'" -Argument @{SSLCertificateSHA1Hash=$thumb}

3.5 连上后黑屏 / 卡在 “正在配置远程会话”

先记住结论网络和认证都没问题了,问题出在"画面这一段"——重点怀疑图形管线(RemoteFX/EGFX/WDDM)、用户配置文件损坏,以及 VPN 场景下的 MTU 分片。

原因排查
显卡驱动或 EGFX 管线异常组策略关闭 “使用高级 RemoteFX 图形”;客户端 .rdpbitmapcachepersistenable:i:0
用户配置文件损坏事件查看器 应用程序和服务日志 → Microsoft → Windows → TerminalServices-LocalSessionManager/Operational
MTU / 分片问题(VPN 场景)降低 MTU 测试:netsh interface ipv4 set subinterface "以太网" mtu=1400 store=persistent
显示驱动 WDDM 冲突组策略:计算机配置 → 管理模板 → Windows 组件 → 远程桌面服务 → 远程会话环境 → 对远程桌面连接使用 WDDM 图形显示驱动程序 设为"已禁用"

3.6 卡顿 / 鼠标拖影 / 视频不流畅

先记住结论头号嫌疑是 UDP 通道没打通——RDP 靠 UDP 承载图形音频来避开 TCP 重传,UDP 被拦就会明显拖影;其次才是画质设置过高和链路丢包。

  1. 确认 UDP 通道是否生效:抓 udp.port==3389 有无双向流量;无则放行 UDP。
  2. 客户端体验设置降级:.rdpconnection type:i:1(低速链路)、关闭桌面背景与字体平滑。
  3. 服务端组策略启用 H.264/AVC 444 图形模式(需 RDP 10+ 客户端)。
  4. 检查丢包与 RTT:ping -tpathping;RDP 对 >2% 丢包非常敏感。
  5. xfreerdp /network:modem|broadband|lan 让 FreeRDP 自动套用预设。

3.7 剪贴板 / 磁盘重定向失效

先记住结论大概率是被组策略禁掉了,通道根本没建起来——抓包看 Channel Join 阶段有没有对应通道,一眼就能分辨是"策略禁用"还是"进程卡死"。

  • 抓包看 Channel Join 阶段是否有 cliprdr / rdpdr;没有说明被组策略禁用。
  • 服务端组策略:远程桌面服务 → 远程桌面会话主机 → 设备和资源重定向,检查"不允许剪贴板重定向"等项。
  • 客户端进程卡死:远端 taskkill /f /im rdpclip.exestart rdpclip.exe 可恢复剪贴板。

3.8 排查思路总览

这张图能干什么:按"卡在哪一步"分叉定位——从最外层的端口连通性,一路走到最内层的图形管线,每一层给出对应的怀疑对象。

1
2
3
4
5
6
7
连不上?
├─ tcping 3389 不通 → 服务未启/防火墙/端口改了/网络不可达
├─ 通但立刻 RST → 服务端拒绝(会话数满、CAL 过期、策略限制)
├─ 有 CC 但 Negotiation Failure → 安全层不匹配(看失败码)
├─ TLS 握手失败 → 证书/协议版本(TLS1.0 被禁用)
├─ CredSSP 报错 → CVE-2018-0886 补丁不一致 / 凭据错误 / 时间不同步致 Kerberos 失败
└─ 连上黑屏/卡顿 → 图形管线、UDP 未放行、MTU、用户配置文件

提示:Kerberos 认证要求客户端与服务端时间偏差 ≤ 5 分钟,时间不同步会表现为莫名其妙的认证失败——这也是 RDP 与 NTP 的隐性关联。

4. 与其他协议对比

维度RDPVNC (RFB)SSHSPICEX11 Forwarding
端口TCP/UDP 3389TCP 5900+NTCP 22TCP 5900+经 SSH 22
规范MS-RDPBCGR(微软开放规范)RFC 6143RFC 4251~4254红帽开放协议X Window System 协议
传输内容绘图订单 + 编码图像 + 设备重定向帧缓冲像素矩形字符流 + 隧道图形/音视频/USB(面向 KVM)图形绘制原语
带宽效率(订单+缓存+H.264)低~中(依赖编码,如 Tight/ZRLE)极高(纯文本)低(往返多,广域网体验差)
加密TLS + CredSSP/NLA(内建)多数实现默认不加密,需隧道内建强加密TLS 可选由 SSH 提供
多用户会话支持(RDS 多会话)通常单一屏幕共享天然多会话单虚机会话多会话
设备重定向剪贴板/磁盘/打印机/音频/USB/智能卡一般仅剪贴板端口转发/SFTP剪贴板/USB/音频有限
跨平台服务端以 Windows 为主(Linux 用 xrdp)全平台全平台Linux/KVMUnix 系
典型用途Windows 图形运维、VDI跨平台屏幕共享、嵌入式服务器命令行运维KVM 虚机控制台转发单个 Linux GUI 程序

选型口诀:管 Windows 用 RDP,管 Linux 命令行用 SSH,跨平台看屏幕用 VNC,只想转发一个 Linux 图形程序用 ssh -X

5. 速查表 / 常见面试题

5.1 端口与标识速查

项目
标准端口TCP 3389 + UDP 3389(IANA 服务名 ms-wbt-server
RD GatewayTCP 443(RPC over HTTPS)+ UDP 3391
RD Web AccessTCP 443
RD 授权(License)TCP 135 + 动态 RPC
RD Connection BrokerTCP 5504 / 3389
抓包特征字节TPKT 首字节 0x03
明文用户名位置X.224 CR 的 Cookie: mstshash=
服务名(Windows)TermService(远程桌面服务)、UmRdpService(重定向)
关键日志TerminalServices-LocalSessionManager/OperationalTerminalServices-RemoteConnectionManager/Operational、安全日志 4624(登录类型 10 = RemoteInteractive)

5.2 高频面试题

Q1:RDP 为什么要在 TCP 之上再叠 X.224 和 MCS? A:RDP 源自 ITU-T T.120 多点会议协议族,T.125 MCS 提供的"多通道复用 + 多点通信"能力被直接复用来实现虚拟通道;X.224 Class 0 + TPKT(RFC 1006)则是把面向 OSI 的传输原语搬到 TCP 上的适配层。历史包袱,但也带来天然的多通道能力。

Q2:RDP 和 VNC 最本质的区别? A:RDP 是语义级远程化——服务端理解 GDI 绘图语义,发送的是"画什么";VNC 是像素级同步——发送的是"屏幕哪块变成了什么样"。因此 RDP 在文字/窗口场景带宽低得多,且能重定向设备;VNC 胜在协议简单、跨平台、可共享物理屏幕。

Q3:什么是 NLA,为什么强烈建议开启? A:Network Level Authentication,基于 CredSSP,在建立 RDP 会话之前先在 TLS 内完成身份认证。好处:① 未认证请求不消耗服务端会话/图形资源,抗 DoS;② 大幅缩小攻击面(BlueKeep CVE-2019-0708 等预认证漏洞在开启 NLA 后无法被匿名利用);③ 支持单点登录。

Q4:RDP 的 UDP 通道是干什么用的?关掉会怎样? A:MS-RDPEUDP,用于承载对时延敏感、对丢包容忍的图形与音频数据(Lossy 模式),避免 TCP 重传导致的画面停顿。关掉后连接仍然可用(回退到纯 TCP),但弱网/高时延下会明显卡顿、鼠标拖影。

Q5:抓 RDP 包时能看到什么明文? A:TCP 握手后的 X.224 Connection Request 里有明文 Cookie: mstshash=<用户名>,以及协商的安全协议标志;TLS 握手中可见服务端证书主体(通常是主机名)。此后全部加密。所以从抓包可枚举登录用户名,这也是不要把 3389 直接暴露公网的理由之一。

Q6:为什么公网暴露 3389 很危险?应该怎么做? A:3389 是被扫描最频繁的端口之一,长期面临口令爆破与勒索软件投递(BlueKeep、DejaBlue 等预认证 RCE 曾大规模利用)。正确做法:置于 VPN / RD Gateway(443) / 零信任网关之后;强制 NLA + MFA;账户锁定策略;改非标端口降噪;只允许白名单源 IP;及时打补丁。

Q7:Fast-Path 和 Slow-Path 有什么区别? A:Slow-Path 完整携带 TPKT+X.224+MCS+安全头,用于连接建立与控制类 PDU;Fast-Path 把这些头压缩成最少 2 字节(首字节即动作与标志),用于稳态的输入事件和图形更新,显著降低小包开销与时延。

Q8:远程桌面登录在 Windows 安全日志里是什么登录类型? A:类型 10(RemoteInteractive);若通过 RD Gateway 或某些代理场景可能表现为类型 3(Network)后再提权。审计爆破时应重点关注 4625 中 LogonType=10 的失败事件。

Q9:RDP 会话断开与注销的区别? A:断开(Disconnect)只切断网络连接,服务端会话与进程仍在运行,可重连恢复现场;注销(Logoff)终止会话与所有进程。运维中"服务器登录数满"多因大量断开会话未回收,可用组策略设置"已断开会话的时间限制"自动清理。

Q10:Linux 上如何提供 RDP 服务?与 xrdp 的关系? A:xrdp 实现了 RDP 服务端协议栈,后端通过 xorgxrdp 或 VNC(Xvnc)驱动会话。它支持 TLS 与部分虚拟通道(剪贴板、磁盘),但不支持完整的 Windows 图形订单集,性能与兼容性弱于原生 Windows RDP。