
远程办公、异地出差、回家后想连回公司电脑处理点急事这类需求我每年都会碰到好几次。最省事的办法当然是让被控电脑直接暴露在公网但大多数家庭宽带和企业内网都在 NAT 后面没有独立公网 IP直接连 3389 根本连不上。这时候就需要一套可靠的内网穿透方案用 frp 在一台有公网 IP 的云主机上做转发入口把内网 Windows 的远程桌面端口映射出去如果追求更低的延迟和更少的公网流量还可以利用 frp 的 xtcp 模式做 UDP 打洞让访问端和被控端尝试点对点直连。这篇内容我就把这两条路线拆开从原理、配置、实测到排错完整走一遍。不管你用的是 Windows 10 还是 Windows 11只要远程桌面能正常开启跟着配下来基本都能用。1. 整体方案设计与核心思路拆解1.1 为什么选择 frp 加 UDP 打洞的组合frp 是我用过的内网穿透工具里比较顺手的一个它开源、配置文件简单支持 TCP、UDP 转发也支持 xtcp 这种点对点打洞模式。对于 Windows 远程桌面来说默认走 TCP 3389但 Windows 也会尝试 UDP 3389 来提升图形传输效率。如果只做 TCP 映射所有流量都要经过公网服务器延迟取决于服务器和你家宽带的距离而且公网服务器的带宽会直接成为瓶颈。UDP 打洞的价值就在于它让访问端和被控端在建立连接后尽可能直连数据不再绕行公网服务器延迟更低服务器压力也更小。当然UDP 打洞不是万能的。它依赖双方 NAT 设备的类型如果一方是 Symmetric NAT打洞成功率会明显下降这时候 frp 会自动回退到通过公网服务器转发或者需要你改用 TCP 映射兜底。所以我的建议是先配好 TCP 映射保证随时能连上再叠加 xtcp 打洞作为优化项。这样即使打洞失败远程桌面也不会断。1.2 公网服务器、内网主机、访问端的角色分工整个方案里有三个角色。第一个是公网服务器它运行 frps负责监听公网端口、验证客户端身份、在 TCP 映射模式下转发流量在 UDP 打洞模式下充当信令交换点。第二个是被控的内网 Windows 主机它运行 frpc把本地的 3389 端口注册到 frps 上。第三个是访问端可以是一台运行 frpc 的电脑也可以直接通过远程桌面客户端连接公网服务器的映射端口。如果你只用 TCP 映射访问端不需要安装 frp直接打开 Windows 自带的“远程桌面连接”输入公网 IP 和映射端口就能连。如果你想用 xtcp 打洞访问端也需要运行 frpc并配置成 visitor 角色它会在本地监听一个端口然后你再用远程桌面连接这个本地端口。这样做的好处是访问端和被控端之间的数据可以走 P2P公网服务器只负责牵线。1.3 方案拓扑与数据流向先看 TCP 映射模式的数据流向访问端发起远程桌面连接目标地址是公网服务器的 13389 端口frps 收到连接后根据端口找到对应的 frpc 会话把流量转发给内网主机的 frpcfrpc 再把流量转给本地的 127.0.0.1:3389也就是 Windows 的远程桌面服务。整个过程中公网服务器扮演的是端口转发入口的角色所有数据都经过它。再看 UDP 打洞模式被控端 frpc 先向 frps 注册一个 xtcp 类型的服务访问端 frpc 也向 frps 注册一个 visitor 角色。frps 会把双方的公网地址和端口信息互相交换然后访问端和被控端同时向对方发送 UDP 包尝试在各自的 NAT 设备上建立映射。一旦打洞成功双方就会建立一条直接的 UDP 通道远程桌面的流量不再经过公网服务器。如果打洞失败frp 会尝试通过 frps 中转保证连接仍然可用。这个过程中NAT 类型是关键。Full Cone NAT 最容易打洞Restricted Cone 和 Port Restricted Cone 也大概率能成功Symmetric NAT 则很难。你可以用一些 STUN 检测工具查看自己的 NAT 类型但不用太纠结因为 frp 会自动回退。实测下来国内大部分家庭宽带是 Port Restricted Cone 或 Symmetric NAT打洞成功率大概一半一半所以 TCP 映射兜底非常必要。2. 公网服务端与内网客户端的准备与部署2.1 公网服务器选型与系统初始化公网服务器不需要太高配置1 核 1G 的云主机就够用系统用 Debian 12 或 Ubuntu 22.04 都行。关键是要有公网 IP并且你能在安全组里开放需要的端口。我一般会开放这几个端口7000/TCP 给 frps 的绑定端口7001/UDP 给 xtcp 的信令和打洞辅助13389/TCP 给远程桌面映射入口。如果你还想用 dashboard 看状态可以再开 7500/TCP但强烈建议只对特定 IP 开放或者干脆不开。系统初始化方面先更新软件包安装 curl、wget、vim 这些基础工具。然后创建一个专门的目录比如/opt/frp把 frp 的服务端和客户端解压进去。下载 frp 可以去它的 GitHub Releases 页面选择对应架构的压缩包。国内服务器下载 GitHub 可能比较慢可以先用本地电脑下载再上传或者使用一些镜像加速这里不展开。安全组配置有一个常见坑很多人只开了 TCP 7000忘了开 UDP 7001结果 xtcp 一直打洞失败。所以你在配置安全组时最好把 TCP 和 UDP 都按需放行。另外公网服务器的防火墙比如 ufw 或 firewalld也要同步放行否则安全组开了也没用。2.2 frps 服务端安装与配置详解frps 的配置文件我习惯用 ini 格式虽然新版本也支持 toml但 ini 更直观。下面是一个基础配置[common] bind_port 7000 bind_udp_port 7001 token 你的复杂令牌 dashboard_port 7500 dashboard_user admin dashboard_pwd 你的强密码 log_file /opt/frp/frps.log log_level info log_max_days 7bind_port是 frps 监听的 TCP 端口客户端通过它注册。bind_udp_port是 UDP 端口xtcp 打洞时用来交换信息。token是客户端和服务端的共享密钥必须设置得复杂一些否则任何人只要知道你的公网 IP 和端口就能把内网服务暴露出去。dashboard是监控面板能看到连接数、流量、客户端状态方便排查问题。配置好后可以用./frps -c frps.ini前台启动测试。确认没问题后建议配置 systemd 服务让它开机自启和崩溃重启。创建一个/etc/systemd/system/frps.service文件内容大概是这样[Unit] Descriptionfrp server Afternetwork.target [Service] Typesimple ExecStart/opt/frp/frps -c /opt/frp/frps.ini Restarton-failure RestartSec5s [Install] WantedBymulti-user.target然后执行systemctl daemon-reload、systemctl enable frps、systemctl start frps。这样 frps 就会在后台运行日志会写到你指定的文件里。注意不要把 dashboard 暴露在公网而不设密码也不要使用默认的 admin/admin这是非常低级的错误。2.3 frpc 客户端安装与基础映射配置在内网 Windows 主机上下载 frp 的 Windows 版本解压到比如C:\frp目录。然后创建frpc.ini[common] server_addr 你的公网IP server_port 7000 token 你的复杂令牌 tls_enable true [rdp_tcp] type tcp local_ip 127.0.0.1 local_port 3389 remote_port 13389 use_encryption true use_compression true [rdp_udp] type udp local_ip 127.0.0.1 local_port 3389 remote_port 13389 use_encryption true use_compression true这里定义了两个转发规则一个 TCP一个 UDP都把本地 3389 映射到公网服务器的 13389 端口。因为 TCP 和 UDP 是不同协议所以可以使用相同的 remote_port。tls_enable开启 TLS 加密use_encryption和use_compression让流量加密并压缩对远程桌面这种图形流量有一定帮助。启动 frpc 可以用命令行frpc.exe -c frpc.ini。如果要开机自启可以用 Windows 任务计划程序设置触发器为“计算机启动时”操作指向frpc.exe参数填-c C:\frp\frpc.ini。也可以用 nssm 把它注册成 Windows 服务。我个人更喜欢任务计划程序因为配置简单不容易出权限问题。启动后去 frps 的 dashboard 看看客户端是否在线对应的转发规则是否显示为绿色。如果显示离线先检查 token 是否一致再检查公网服务器的防火墙和 frpc 的日志。2.4 Windows 远程桌面开启与防火墙放行被控 Windows 主机需要开启远程桌面。在 Windows 10/11 专业版上进入“设置 - 系统 - 远程桌面”把“启用远程桌面”打开。系统会提示你确认并显示当前电脑的名称。注意Windows 家庭版不支持作为远程桌面服务端如果你用的是家庭版需要先升级到专业版或者改用其他远程控制方式。开启后确保你的账户有密码。远程桌面不允许空密码账户登录。然后检查防火墙Windows 防火墙默认会放行远程桌面但如果你装了第三方安全软件可能会拦截 3389。可以在“高级安全 Windows Defender 防火墙”里查看入站规则确保“远程桌面 - 用户模式 (TCP-In)”是启用的。如果你修改过远程桌面端口记得在规则里同步修改。还有一个细节网络级别身份验证NLA。默认情况下远程桌面会要求 NLA这能提升安全性但有些旧客户端可能连不上。如果你遇到连接问题可以暂时在“系统属性 - 远程”里取消勾选“仅允许运行使用网络级别身份验证的远程桌面的计算机连接”但我不建议长期关闭因为它能防止未授权连接消耗资源。3. TCP 映射与 UDP 打洞的实操配置3.1 先用 TCP 映射快速打通远程桌面3389TCP 映射是最基础也最可靠的一步。配置好 frpc 后在访问端的“远程桌面连接”里输入公网IP:13389点击连接。如果一切正常你会看到 Windows 的登录界面。第一次连接时可能会提示证书不受信任选择“是”继续即可。如果连不上按这个顺序排查第一在公网服务器上执行netstat -tlnp | grep 13389看 frps 是否在监听这个端口。第二检查云服务器安全组是否开放了 13389/TCP。第三在访问端用telnet 公网IP 13389测试端口连通性如果 telnet 不通说明网络层有问题。第四查看 frpc 日志如果提示connect to server error说明 frpc 没连上 frps如果提示port already used说明 remote_port 被占用了。另外远程桌面的连接速度取决于公网服务器的带宽和延迟。如果你用的是按流量计费的云主机长时间挂远程桌面可能会消耗不少流量。这也是为什么我建议在 TCP 映射稳定后再尝试 UDP 打洞因为打洞成功后流量就不再走公网服务器了。3.2 配置 frp xtcp 实现 UDP 打洞的点对点连接xtcp 需要被控端和访问端都运行 frpc。先在被控端的frpc.ini里增加一个 xtcp 规则[rdp_xtcp] type xtcp role server sk 你的打洞密钥 local_ip 127.0.0.1 local_port 3389然后在访问端的frpc.ini里增加 visitor 规则[rdp_xtcp_visitor] type xtcp role visitor server_name rdp_xtcp sk 你的打洞密钥 bind_addr 127.0.0.1 bind_port 13389注意server_name必须和被控端的段名一致sk也必须一致。访问端启动 frpc 后它会在本地监听 127.0.0.1:13389。你再用远程桌面连接127.0.0.1:13389frpc 就会尝试通过 frps 交换地址然后打洞直连被控端的 3389。如果打洞成功你在 frpc 日志里会看到类似nat hole punching success的提示。这时候远程桌面的延迟会明显降低公网服务器的流量也会大幅减少。如果打洞失败frpc 会回退到通过 frps 转发你仍然能连上只是延迟和流量会回到 TCP 映射的水平。打洞成功率受 NAT 类型影响很大。你可以用一些 STUN 检测工具查看自己的 NAT 类型但更简单的办法是直接试。如果一直失败可以尝试更换网络环境比如从公司网络换到家庭宽带或者用手机热点测试。有些企业防火墙会直接阻断 UDP这种情况就只能用 TCP 映射。3.3 安全加固加密、压缩、权限验证、访问控制内网穿透把内网服务暴露到公网安全是重中之重。首先token 一定要复杂最好包含大小写字母、数字和特殊符号长度不少于 20 位。其次开启 TLS在 frpc 和 frps 的 common 段都加上tls_enable true。这样客户端和服务端之间的通信会加密防止被中间人窃听。对于转发规则可以加上use_encryption true和use_compression true。加密能保护远程桌面的登录凭证和画面数据压缩能减少带宽占用。frps 还可以配置allow_ports限制客户端只能映射特定端口比如allow_ports 13389防止别人用你的 frps 映射其他敏感服务。公网服务器的防火墙也要做限制。如果你知道访问端的固定 IP可以在安全组里只允许那个 IP 访问 13389。如果访问端 IP 不固定至少要把 dashboard 端口关掉或加密码。远程桌面本身也要启用强密码和账户锁定策略避免被暴力破解。我还会在 Windows 上启用“网络级别身份验证”并在 frps 日志里定期检查异常连接。3.4 实测效果与延迟对比我在一台国内云主机、家庭 500M 宽带、公司 200M 宽带的组合下做过测试。TCP 映射模式下远程桌面的平均延迟在 35ms 到 60ms 之间具体取决于云主机的位置。UDP 打洞成功后延迟降到 15ms 到 25ms几乎和局域网远程桌面差不多。流量方面TCP 映射时所有画面和操作都经过公网服务器一小时大概消耗 300MB 到 800MB打洞成功后公网服务器只承担信令交换流量几乎为零。下面这个表格是我整理的关键对比对比项TCP 映射UDP 打洞xtcp访问端是否需要 frpc不需要需要延迟较高取决于服务器较低接近直连公网服务器带宽消耗高低打洞成功率100%约 50% 到 80%配置复杂度简单中等适用场景兜底、应急长期高频使用从实测来看如果你的主要需求是偶尔连一下TCP 映射足够了。如果你每天都要远程办公几个小时UDP 打洞带来的体验提升非常明显值得花时间配置。4. 常见问题与排查技巧实录4.1 连接被拒绝或超时的排查路径远程桌面连不上最常见的原因是端口没通。先在访问端用telnet 公网IP 13389测试。如果 telnet 直接提示连接失败说明公网服务器的安全组或防火墙没放行。如果 telnet 能通但远程桌面报错说明 frps 到 frpc 的链路有问题。进入公网服务器执行ss -tlnp | grep 13389看 frps 是否监听。再看 frps 日志如果提示login to server failed说明 token 不对。如果提示client offline说明内网主机的 frpc 没连上。在内网主机上检查 frpc 进程是否在运行日志里有没有报错。常见错误包括connect to server error网络不通或端口不对、dial tcp 127.0.0.1:3389: connect: connection refusedWindows 远程桌面没开启或端口被改。还有一个容易被忽略的点Windows 防火墙可能只允许本地子网连接。在“高级安全 Windows Defender 防火墙”里检查“远程桌面 - 用户模式 (TCP-In)”规则的“远程 IP 地址”是否限制为本地子网。如果是改成“任何 IP 地址”即可。4.2 UDP 打洞失败的典型原因与解决UDP 打洞失败时先看 frpc 日志。如果提示nat hole punching failed通常有这几个原因第一frps 没有开放bind_udp_port或者安全组没放行 UDP 7001。第二一方或双方是 Symmetric NAT导致打洞无法建立。第三sk或server_name不一致导致信令交换失败。第四企业防火墙阻断了 UDP 出站。解决办法确认 frps 配置了bind_udp_port 7001并且安全组开放了 7001/UDP。检查被控端和访问端的sk、server_name是否完全一致。如果 NAT 类型太严格可以尝试用手机热点测试或者改用 TCP 映射兜底。frp 还支持 stcp 类型它通过 frps 转发但需要访问端也运行 frpc安全性比普通 TCP 映射更高可以作为打洞失败时的备选方案。另外有些路由器会开启“SIP ALG”或“UDP 过滤”这些功能会干扰打洞。可以登录路由器后台暂时关闭这些选项再测试。如果打洞成功但远程桌面经常断开可能是 UDP 超时时间太短可以在 frpc 里调整udp_packet_size或heartbeat_interval让连接保持活跃。4.3 远程桌面常见错误代码与处理0x204 是远程桌面比较常见的错误通常和凭证或安全层有关。可以尝试在远程桌面连接里点击“显示选项 - 高级 - 服务器身份验证”选择“连接且不警告我”。或者在“体验”里把连接速度设为“局域网”让安全层协商更宽松。如果还是不行检查被控端是否启用了 NLA尝试暂时关闭 NLA 再连。“某些设置由你的组织来管理”这个提示通常是组策略或注册表残留导致的。可以在被控端运行gpedit.msc进入“计算机配置 - 管理模板 - Windows 组件 - 远程桌面服务 - 远程桌面会话主机 - 连接”检查是否有策略限制。如果没有组策略编辑器可以检查注册表HKLM\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services把多余的键值删掉。如果你用的是 Windows Server可能会遇到“远程桌面授权模式尚未配置”的提示。这是正常的授权提醒不是故障。普通 Windows 专业版不会有这个问题也不需要额外配置授权服务器。只要在合法授权的范围内使用按系统提示配置即可。4.4 日常维护与监控建议frp 运行久了日志会越来越大。可以在 frps 和 frpc 的配置里设置log_max_days让日志自动轮转。我一般设置 7 天既能保留排错所需的信息又不会占满磁盘。dashboard 是个好用的工具可以定期看看在线客户端、流量曲线和连接数。如果发现陌生客户端立即更换 token 并检查防火墙。版本更新也很重要。frp 社区活跃新版本会修复安全漏洞和打洞逻辑。每隔几个月可以去 GitHub 看看有没有新版本升级前先备份配置文件。升级时注意查看 release notes有些配置项可能改名或废弃。最后远程桌面的账户安全不能忽视。给远程登录的账户设置强密码启用账户锁定策略比如连续 5 次失败锁定 15 分钟。如果条件允许可以给远程桌面配置双因素认证或者通过公网服务器的安全组限制访问来源 IP。我自己还会在 frps 里设置allow_ports 13389防止有人拿我的服务器做其他转发。我个人在实际操作中的体会是内网穿透这件事先把 TCP 映射跑通再折腾 UDP 打洞心里会踏实很多。打洞成功是惊喜失败也不影响使用。另外公网服务器的带宽不用买太大1M 到 3M 就够应急真正高频使用还是靠打洞直连。最后再分享一个小技巧如果你有多台内网 Windows 主机可以给每台设置不同的 remote_port比如 13389、13390、13391然后在 frps 的 dashboard 里起个备注名管理起来会清晰很多。