# 使用 frp 将 Windows 本地端口稳定映射到 Ubuntu 公网服务器

在开发、远程访问或部署测试服务时,经常会遇到一个需求:本地 Windows 电脑上有一个服务端口,希望外网设备可以通过公网 IP 访问它。

本文记录一套长期稳定的方案:使用 frp 将 Windows 本地端口 27703 映射到 Ubuntu 公网服务器的 27703 端口。

最终效果如下:

外部设备访问:公网服务器IP:27703

Ubuntu 公网服务器 frps

Windows 客户端 frpc

Windows 本地服务:127.0.0.1:27703

# 一、方案说明

frp 分为两个组件:

frps:运行在公网服务器上,负责接收外部连接
frpc:运行在内网 Windows 客户端上,负责把本地服务暴露到公网服务器

本文环境如下:

公网服务器:Ubuntu
客户端:Windows
本地服务端口:27703
公网映射端口:27703
frp 控制端口:7000

其中:

7000:frpc 连接 frps 使用
27703:外部用户真正访问的业务端口

# 二、确认 Windows 本地端口

在 Windows PowerShell 中执行:

netstat -ano | findstr :27703

理想情况下应看到类似:

TCP    127.0.0.1:27703    0.0.0.0:0    LISTENING    xxxx

或者:

TCP    0.0.0.0:27703      0.0.0.0:0    LISTENING    xxxx

其中 LISTENING 表示该端口正在监听,可以作为 frp 的 localPort

如果只看到:

ESTABLISHED

则说明它只是已有连接,不一定是本地服务监听端口。这种情况下需要继续确认真正监听的端口。

可以根据 PID 查询进程:

tasklist | findstr PID数字

或者:

Get-Process -Id PID数字

# 三、Ubuntu 服务器安装 frps

SSH 登录 Ubuntu 公网服务器:

ssh root@你的公网服务器IP

以下以 frp v0.69.1 为例。若后续有新版本,可以到官方 Release 页面下载对应版本:

https://github.com/fatedier/frp/releases

先确认服务器架构:

uname -m

如果输出是 x86_64,使用 linux_amd64 包:

VERSION=0.69.1
cd /tmp

wget -O frp.tar.gz https://github.com/fatedier/frp/releases/download/v${VERSION}/frp_${VERSION}_linux_amd64.tar.gz
tar -xzf frp.tar.gz

mkdir -p /opt/frp /etc/frp
cp frp_${VERSION}_linux_amd64/frps /opt/frp/frps
chmod +x /opt/frp/frps

如果输出是 aarch64,使用 linux_arm64 包:

VERSION=0.69.1
cd /tmp

wget -O frp.tar.gz https://github.com/fatedier/frp/releases/download/v${VERSION}/frp_${VERSION}_linux_arm64.tar.gz
tar -xzf frp.tar.gz

mkdir -p /opt/frp /etc/frp
cp frp_${VERSION}_linux_arm64/frps /opt/frp/frps
chmod +x /opt/frp/frps

检查 frps 是否可执行:

/opt/frp/frps -v

如果能输出版本号,说明二进制文件正常。

# 四、配置 Ubuntu 服务器 frps

生成一个随机 token:

openssl rand -hex 32

编辑 frps 配置:

nano /etc/frp/frps.toml

写入:

bindPort = 7000

auth.method = "token"
auth.token = "这里换成你的随机token"

allowPorts = [
  { single = 27703 }
]

transport.tls.force = true

配置说明:

bindPort = 7000:frpc 连接 frps 的端口
auth.token:客户端和服务端必须一致
allowPorts:只允许映射 27703,避免随意开放公网端口
transport.tls.force:强制使用 TLS 传输

# 五、创建 frps systemd 服务

创建服务文件:

nano /etc/systemd/system/frps.service

写入:

[Unit]
Description=frp server
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
ExecStart=/opt/frp/frps -c /etc/frp/frps.toml
Restart=always
RestartSec=5
LimitNOFILE=1048576

[Install]
WantedBy=multi-user.target

启动并设置开机自启:

systemctl daemon-reload
systemctl enable --now frps
systemctl status frps --no-pager

正常情况下应看到:

active (running)

确认 7000 端口已经监听:

ss -lntp | grep 7000

正常应看到类似:

LISTEN 0 4096 *:7000 *:* users:(("frps",pid=xxxx,fd=xx))

# 六、放行服务器端口

如果服务器启用了 ufw

ufw allow 7000/tcp
ufw allow 27703/tcp
ufw reload
ufw status

同时还需要到云服务器控制台的安全组中放行:

入方向 TCP 7000
入方向 TCP 27703
来源 0.0.0.0/0

注意:

7000 是 frp 控制连接端口
27703 是公网业务访问端口

两个端口都要放行。

# 七、Windows 安装 frpc

在 Windows 管理员 PowerShell 中执行:

$version = "0.69.1"

New-Item -ItemType Directory -Force C:\frp | Out-Null

Invoke-WebRequest `
  -Uri "https://github.com/fatedier/frp/releases/download/v$version/frp_${version}_windows_amd64.zip" `
  -OutFile "$env:TEMP\frp.zip"

Expand-Archive "$env:TEMP\frp.zip" -DestinationPath "$env:TEMP\frp" -Force

Copy-Item "$env:TEMP\frp\frp_${version}_windows_amd64\frpc.exe" C:\frp\frpc.exe -Force

确认安装成功:

C:\frp\frpc.exe -v

# 八、配置 Windows frpc

编辑配置文件:

notepad C:\frp\frpc.toml

写入:

serverAddr = "你的公网服务器IP"
serverPort = 7000
loginFailExit = false

auth.method = "token"
auth.token = "这里换成和服务器一样的随机token"

transport.tls.enable = true

[[proxies]]
name = "tcp-27703"
type = "tcp"
localIP = "127.0.0.1"
localPort = 27703
remotePort = 27703

说明:

serverAddr:Ubuntu 公网服务器 IP
serverPort:frps 的 bindPort,也就是 7000
localPort:Windows 本地服务端口
remotePort:公网服务器暴露端口
loginFailExit = false:连接失败后继续重试,适合长期运行

如果本地服务实际监听的是某个特定网卡地址,比如:

10.126.126.1:27703

可以将:

localIP = "127.0.0.1"

改成:

localIP = "10.126.126.1"

# 九、Windows 手动测试 frpc

在 Windows PowerShell 中执行:

C:\frp\frpc.exe -c C:\frp\frpc.toml

如果连接成功,通常会看到类似:

login to server success
proxy added: [tcp-27703]
start proxy success

此时不要关闭窗口,使用外部设备访问:

公网服务器IP:27703

如果该服务是 HTTP 服务,可以用浏览器访问:

http://公网服务器IP:27703

如果不是 HTTP 服务,则使用对应客户端连接。

# 十、Windows 设置开机自启

确认手动运行成功后,可以使用任务计划程序设置开机自启。

管理员 PowerShell 执行:

$Action = New-ScheduledTaskAction `
  -Execute "C:\frp\frpc.exe" `
  -Argument "-c C:\frp\frpc.toml"

$Trigger = New-ScheduledTaskTrigger -AtStartup

$Settings = New-ScheduledTaskSettingsSet `
  -AllowStartIfOnBatteries `
  -DontStopIfGoingOnBatteries `
  -RestartCount 999 `
  -RestartInterval (New-TimeSpan -Minutes 1)

Register-ScheduledTask `
  -TaskName "frpc" `
  -Action $Action `
  -Trigger $Trigger `
  -Settings $Settings `
  -RunLevel Highest `
  -User "SYSTEM"

立即启动:

Start-ScheduledTask -TaskName "frpc"

查看状态:

Get-ScheduledTask -TaskName "frpc"

修改配置后重启任务:

Stop-ScheduledTask -TaskName "frpc"
Start-ScheduledTask -TaskName "frpc"

# 十一、公网连通性测试

Windows 测试公网端口:

Test-NetConnection 你的公网服务器IP -Port 27703

成功时会看到:

TcpTestSucceeded : True

Ubuntu 或其他 Linux 设备测试:

nc -vz 你的公网服务器IP 27703

如果没有安装 nc

sudo apt update
sudo apt install -y netcat-openbsd

也可以测试 frp 控制端口:

nc -vz 你的公网服务器IP 7000

如果业务是 HTTP 服务,可以使用:

curl http://你的公网服务器IP:27703

如果不是 HTTP 服务,curl 不一定能看出有效结果,优先使用 nc -vz 判断 TCP 端口是否连通。

# 十二、常见问题排查

# 1. Windows 提示 actively refused

错误类似:

dial tcp 公网IP:7000: connectex: No connection could be made because the target machine actively refused it

这通常表示服务器的 7000 端口没有监听。

在 Ubuntu 上检查:

systemctl status frps --no-pager
ss -lntp | grep 7000

如果本机测试也失败:

curl 127.0.0.1:7000

并提示:

Couldn't connect to server

说明 frps 没有成功运行。

# 2. frps 状态是 203/EXEC

如果看到:

status=203/EXEC

说明 systemd 无法执行 /opt/frp/frps。常见原因:

文件不存在
没有执行权限
下载了错误架构的 frps

检查:

ls -l /opt/frp/frps
file /opt/frp/frps
uname -m

修复后执行:

chmod +x /opt/frp/frps
/opt/frp/frps -v
systemctl restart frps

# 3. token 错误

如果日志提示认证失败,检查服务端和客户端:

auth.token

两边必须完全一致。

# 4. 端口不允许

如果提示远程端口不允许,检查服务器配置:

allowPorts = [
  { single = 27703 }
]

修改后重启:

systemctl restart frps

# 5. frpc 成功但公网访问失败

依次检查:

ss -lntp | grep 27703
ufw status

并确认云服务器安全组放行:

TCP 27703

还要确认 Windows 本地服务仍在监听:

netstat -ano | findstr :27703

# 十三、延迟会不会很高

frp 本身的转发开销通常不大,真正影响延迟的是网络路径。

frp 转发后的链路是:

外部设备
  → Ubuntu 公网服务器
  → Windows 客户端
  → Windows 本地服务

总延迟大致等于:

外部设备到公网服务器的延迟
+
公网服务器到 Windows 客户端的延迟
+
frp 自身少量处理开销

frp 自身通常只是几毫秒级别,主要瓶颈一般是:

服务器地域
跨运营商链路
Windows 客户端上行带宽
本地网络稳定性

建议公网服务器尽量选择靠近 Windows 客户端的地域。如果是实时交互、远程桌面、游戏类服务,对延迟更敏感;如果只是普通 Web、API 或 TCP 服务,frp 通常足够使用。

可以用以下命令测试延迟:

Windows 测服务器:

ping 你的公网服务器IP

Ubuntu 或 Linux 设备测服务器:

ping 你的公网服务器IP

测试端口连接耗时:

time nc -vz 你的公网服务器IP 27703

# 十四、总结

使用 frp 可以比较稳定地把 Windows 本地服务映射到 Ubuntu 公网服务器上。完整流程包括:

1. 确认 Windows 本地服务端口正在 LISTENING
2. Ubuntu 安装并配置 frps
3. 使用 systemd 保持 frps 长期运行
4. 放行服务器防火墙和云安全组端口
5. Windows 安装并配置 frpc
6. 测试连通后设置 Windows 开机自启
7. 通过日志、ss、netstat、nc 等工具排查问题

对于本文的场景,最终核心配置是:

服务器 /etc/frp/frps.toml

bindPort = 7000

auth.method = "token"
auth.token = "你的token"

allowPorts = [
  { single = 27703 }
]

transport.tls.force = true

Windows C:\frp\frpc.toml

serverAddr = "你的公网服务器IP"
serverPort = 7000
loginFailExit = false

auth.method = "token"
auth.token = "你的token"

transport.tls.enable = true

[[proxies]]
name = "tcp-27703"
type = "tcp"
localIP = "127.0.0.1"
localPort = 27703
remotePort = 27703

配置成功后,外部设备即可通过:

公网服务器IP:27703

访问 Windows 本地的:

127.0.0.1:27703