在虚拟机服务器上使用 frp 内网穿透,核心思路是找一台有公网 IP 的服务器做中转,把虚拟机的流量“借道”转发出去,整个过程分为服务端部署、客户端配置和自启动验证三步。
为什么虚拟机场景偏爱用 frp 内网穿透方案
不少朋友问虚拟机服务器怎么用 frp 内网穿透,其实本质和物理机没区别,虚拟机多了一层虚拟网卡,在配置时需要注意端口绑定和防火墙放行位置,抛开原理,你更需要关心的是它到底能解决什么问题。
虚拟机的典型困境
虚拟机跑在一台宿主机上,网络通常有两种模式:NAT 模式下虚拟机只能单向访问外网,外部根本摸不到它;桥接模式下虽然有独立 IP,但校园网、公司局域网或家庭宽带往往不给你公网 IPv4,这时候想从外面 SSH 进虚拟机、访问里面的 Web 服务,frp 内网穿透就成了最轻量、最可控的选择。
对比同类穿透工具
业内专家指出,frp 在开源穿透工具中属于“性能与配置的平衡点”,和 ngrok 相比,frp 自建服务端不依赖第三方平台,数据路径完全由自己掌控;和 WireGuard 或 ZeroTier 组建虚拟局域网相比,frp 只转发指定端口,不需要把两台机器完整打通,暴露面更小,也更容易排查问题。
行业共识认为,对于已经在用虚拟机做开发、测试或小型生产环境的用户,frp 内网穿透配置教程掌握后,能规避一大部分“没有公网 IP”带来的沟通成本,下面直接进入实操环节,带你走一遍完整流程。
frp 内网穿透工作原理与前置准备
通信链路是怎么建立的
frp 采用经典 C/S 架构,服务端运行在有公网 IP 的云服务器上(比如酷番云、简米云轻量应用服务器),监听一个端口等待连接,虚拟机内部运行 frp 客户端,主动向服务端发起长连接,当外部用户访问云服务器的某个端口时,服务端把流量通过这条已经建立的长连接隧道转发给虚拟机里的客户端,客户端再把流量交给虚拟机本地的服务进程。
整个过程中你只需记住一句话: “客户端永远主动连服务端” ,这就意味着虚拟机不需要公网 IP,只需要能访问互联网,隧道就能建立。
需要准备哪些东西
开始动手前,清点一下手里的资源:
- 一台公网服务器:操作系统推荐 Debian 11/12 或 Ubuntu 22.04,国内云服务器商轻量机型即可,带宽选 3M 以上,否则转发流量时会卡。
- 虚拟机服务器:无论 VMware、VirtualBox 还是 Proxmox VE 里的 LXC 容器,只要系统是 Linux(本文以 Ubuntu 22.04 为例)就能用,Windows Server 虚拟机的配置逻辑一样,只是命令换成 PowerShell。
- 一个域名(强烈建议):虽然直接用 IP 也能穿透,但 frp 配置里用域名可以方便后续做 HTTPS 证书,还能避免云服务器 IP 被屏蔽后频繁修改配置的尴尬。
- 防火墙放行权限:云服务器安全组以及宿主机防火墙,你都得有权限操作,不然端口不通,配置写得再漂亮也没用。
服务端部署步骤:云服务器上的 frps 安装
下载并安装 frps
先去 GitHub 的 frp 发布页面,找到 linux_amd64 的压缩包,如果云服务器在国内,强烈建议用镜像站加速下载,否则容易超时,下载时注意认准 frps 前缀的文件,这是服务端:
# 进入 /opt 目录操作 cd /opt # 下载 0.61.1 版本(具体版本号以 GitHub 发布页为准) wget https://github.com/fatedier/frp/releases/download/v0.61.1/frp_0.61.1_linux_amd64.tar.gz # 解压并重命名目录,方便打理 tar -zxvf frp_0.61.1_linux_amd64.tar.gz mv frp_0.61.1_linux_amd64 frps cd frps
编写服务端配置文件
编辑 frps.toml 文件(新版 frp 使用 TOML 格式,老版是 ini 格式,注意区分),内容如下:
bindPort = 7000 # 配置一个 token,客户端连接时需要使用这个密钥 auth.method = "token" auth.token = "换成你自己的随机字符串,至少16位" # 开启面板,方便查看连接状态 webServer.addr = "0.0.0.0" webServer.port = 7500 webServer.user = "admin" webServer.password = "面板管理密码" # 日志配置,排查故障时非常有用 log.to = "/var/log/frps.log" log.level = "info" log.maxDays = 7
用 systemd 管理 frps 进程,这是 Linux 上最优雅的守护进程方式,创建一个服务文件:
vim /etc/systemd/system/frps.service
[Unit] Description=frp server service After=network.target [Service] Type=simple ExecStart=/opt/frps/frps -c /opt/frps/frps.toml Restart=on-failure RestartSec=5s [Install] WantedBy=multi-user.target
最后启动并设置开机自启:
systemctl daemon-reload systemctl enable frps systemctl start frps systemctl status frps
此时云服务器的 7000 端口(bindPort)和 7500 端口(面板端口)需要在安全组中放行,如果你还想用 frp 转发 HTTP 流量,记得把后续要用到的高位端口也一并规划好。
虚拟机客户端部署:让 frpc 主动连接你的云服务器
下载并编写客户端配置
找到之前下载的压缩包里的 frpc 文件,拷进虚拟机,同样写一个 frpc.toml:
serverAddr = "你的云服务器公网IP或域名" serverPort = 7000 auth.method = "token" auth.token = "和上面服务端一模一样的token" # 配置 SSH 穿透,把虚拟机的 22 端口映射到云服务器的 6000 端口 [[proxies]] name = "ssh" type = "tcp" localIP = "127.0.0.1" localPort = 22 remotePort = 6000 # 配置 Web 服务穿透,把虚拟机的 80 端口映射到云服务器的 8080 端口 [[proxies]] name = "web" type = "http" localIP = "127.0.0.1" localPort = 80 customDomains = ["vm.example.com"]
注意这里有个关键细节:type 为 tcp 时用 remotePort 指定云服务器上对外开放的端口;type 为 http 时用 customDomains 指定访问域名,两种模式按需选择,也可以混用,如果你的虚拟机跑的是 Web 服务且没有域名,把 type 改成 tcp 映射一个远程端口也是一样的效果。
设置 frpc 开机自启
和 frps 一样,创建 systemd 服务:
vim /etc/systemd/system/frpc.service
[Unit] Description=frp client service After=network.target [Service] Type=simple ExecStart=/opt/frpc/frpc -c /opt/frpc/frpc.toml Restart=always RestartSec=5s [Install] WantedBy=multi-user.target
启动并验证:
systemctl daemon-reload systemctl enable frpc systemctl start frpc
验证隧道是否通了
在你的本机电脑上执行:
ssh -p 6000 用户名@云服务器公网IP
能成功登录虚拟机,说明 SSH 隧道已经通了,打开浏览器访问 http://vm.example.com:8080(或 http://云服务器IP:8080),看到虚拟机里的网页就说明 Web 穿透也成功了。
多端口与多虚拟机映射:如何优雅地扩展
什么场景需要多端口?开发环境要同时 SSH、访问数据库、看 Elasticsearch 监控页面,每一路都是一条 proxy,管理思路分两种:
单客户端多 proxy
直接在 frpc.toml 里继续追加 [[proxies]] 段落即可,每增加一段,就多一扇窗户,例如追加 MySQL 映射:
[[proxies]] name = "mysql" type = "tcp" localIP = "127.0.0.1" localPort = 3306 remotePort = 3306
云服务器安全组里放行 3306 端口,外部工具就能直连虚拟机里的 MySQL 了。
多台虚拟机共用一个 frpc 进程
如果宿主机上有多个虚拟机,建议在每台虚拟机里单独装 frpc,而不是在宿主机里统一转发,原因很简单:虚拟化网络 NAT 模式下,宿主机访问虚拟机内的端口需要额外做端口映射,多了中间层,排查链路时会很痛苦,每台虚拟机独立跑 frpc,配置互相隔离,一台挂了不影响另一台。
端口冲突处理
公网服务器上不同 proxy 的 remotePort 不能重复,否则后启动的 proxy 会报端口占用错误,规划时可以按业务划分端口段,6000-6099 给 SSH,7000-7099 给 Web,8000-8099 给数据库,多台虚拟机之间用不同段位区分,看一眼端口就知道是哪台机器、什么服务。
排查常见故障:连接不上和访问慢怎么办
客户端显示连接服务端失败
先看云服务器安全组是否放行了 bindPort,其次登录云服务器执行:
netstat -tlnp | grep frps
确认 frps 进程在监听,然后看虚拟机的 frpc 日志:
journalctl -u frpc -e
日志里会明确提示是 timeout 还是 auth 失败。timeout 基本就是防火墙拦截,auth 失败就是 token 不一致,前者查安全组和 iptables,后者回去校对两边的 auth.token 值。
连接建立成功但访问不通
这种属于“隧道通,但门没开”,SSH 通了但连不上,先确认虚拟机里的 sshd 服务是否在监听 22 端口:
ss -tlnp | grep :22
接着从云服务器上反过来测试本机端口,确认转发链路是否完整,如果隧道协议是 http,记得检查虚拟机 Web 服务是否绑定了 0.0.1 还是 0.0.0,后者才能被 frpc 正常访问到。
转发速度特别慢
frp 的转发速率理论上取决于云服务器带宽和两端网络质量,多数情况下,速度慢的根源在于云服务器的入网带宽被占满,可以用 iftop 或 nload 查看实时流量,确认是否有其他进程在“偷跑”带宽。
安全加固与性能调优要点
日常使用中的安全守则
- token 务必足够随机:不要用 admin123 这类弱密码,建议用
openssl rand -hex 16生成一串。 - 面板不要暴露在公网:frps 的 webServer 端口只允许云服务器的内网访问,或者干脆用防火墙把 7500 端口限制为只允许你自己的 IP 访问。
- 旧版本及时升级:frp 项目更新活跃,如果穿透的是生产环境,建议跟随官方发布节奏,及时升级到稳定版本,避免老旧版本已知漏洞被利用。
- 最小化暴露原则:只需要映射 SSH 就绝对不要顺手把数据库端口也开出去,每多一个映射端口,就多一分被扫描的风险。
提升转发性能的几个细节
- 在
frpc.toml的[[proxies]]中添加transport.bandwidthLimit= 你想要的上限,用来限制单条连接的带宽,防止某一条代理把服务器出口带宽吃干抹净。 - 新版 frp 支持 TLS 加密,在服务端和客户端的
transport.tls结构中启用enable = true,能提高抗嗅探能力,但会略微增加 CPU 开销,低配虚拟机上体验更明显。 - 如果要穿透 UDP 流量(比如游戏服务器),把 proxy 的 type 改为
udp即可,其余逻辑一致。
常见问题速查表
| 现象 | 可能原因 | 解决方向 |
|---|---|---|
| frpc 反复重启 | token 不匹配或服务端没启动 | 查 journalctl -u frpc -e 日志 |
| SSH 连不上但显示 connected | 虚拟机 sshd 未监听 22 或防火墙拦截 | 检查本地 ss -tlnp 与 iptables |
| HTTP 访问显示 404 | customDomains 域名没解析到公网服务器 | 在 DNS 服务商处添加 A 记录指向云服务器 IP |
| 传输速度很慢 | 云服务器带宽不足或中转链路拥堵 | 查看云服务器监控图,评估升级带宽 |
| 重启后 frp 服务消失 | systemd 服务未 enable | systemctl enable frpc frps 后重启验证 |
frp 内网穿透与虚拟机配合的常见疑问
虚拟机里的 Windows 系统也能用 frp 吗?
能,Windows 版 frp 在 GitHub Release 页面同样有编译好的可执行文件,下载 frp_x.x.x_windows_amd64.zip,解压后用记事本编辑 frpc.toml 并保存为 UTF-8 编码,在命令行里进入 frpc 所在目录,执行 frpc.exe -c frpc.toml 即可,如果希望开机自动运行,可以在 Windows 计划任务中创建一个“开机触发”的任务,或者直接使用内置的 NSSM 工具把 frpc 注册为系统服务,需要留意的是,Windows Defender 防火墙首次运行时一定要允许 frpc.exe 的专用网络访问权限,否则连接会被拦下。
frp 内网穿透安全吗,会不会被外部扫描攻击?
frp 本身只是做了流量中转,安全层级取决于你的配置,不使用 token 时任何客户端只要能连到服务端就能随意建立映射,非常危险,开启 token 认证后,配合 webServer 面板定期查看连接日志和活跃隧道列表,能有效察觉异常连接,行业常态是公网环境会持续受到各类扫描,所以千万不要把虚拟机的敏感端口(如 3389 远程桌面、5432 数据库默认端口)原样映射到公网,修改 remotePort 到高位端口,可以降低大量自动化工具的探测命中率。
家里虚拟机做 frp 穿透,域名需要备案吗?
这取决于你使用的云服务器在哪个地区,国内主流云厂商(简米云、酷番云等)的服务器默认要求域名解析到该服务器时完成 ICP 备案,否则 HTTP/HTTPS 访问会被拦截,穿透 TCP 类型的 SSH 或数据库服务通常不受备案影响,但绑定 customDomains 的 HTTP 流量会严格检查,想省去备案流程,直接把云服务器选在香港或海外节点,延迟会高一些,但胜在省事,就家庭虚拟机场景而言,使用 IP 加高位端口的 TCP 穿透访问题不大,需要 Web 服务且有备案条件就尽快备案,整体链路会更顺畅。
首发原创文章,作者:王坚,如若转载,请注明出处:https://idctop.com/article/782611.html


