不需要 frpc!如何用 frp 的 SSH 隧道网关实现内网穿透:完整实战教程
【免费下载链接】frpA fast reverse proxy to help you expose a local server behind a NAT or firewall to the internet.项目地址: https://gitcode.com/GitHub_Trending/fr/frp
frp 是一款广受欢迎的开源内网穿透工具,而传统方案要求你在内网机器上安装并运行 frpc 客户端。从 v0.53.0 开始,frp 新增了SSH 隧道网关(SSH Tunnel Gateway):frps 服务端内置一个 SSH 服务器,你只需要在本地执行一条标准的ssh -R命令,就能把内网服务暴露到公网——全程无需 frpc。本文带你完整走通配置、打通、验证与安全加固四个环节。
为什么 SSH 隧道网关能替代 frpc?
SSH 协议本身就支持反向端口转发(即-R参数)。frp 的 SSH 隧道网关正是利用了这一点:
- frps 端:开启一个 SSH 监听端口,扮演"SSH 服务器"角色;
- 本地端:用系统自带的
ssh客户端连接它,通过exec请求声明代理参数(类型、端口、域名等); - 流量路径:公网请求打到 frps 分配的端口,frps 经由 SSH 隧道把流量转发回你的本地服务。
也就是说,SSH 反向隧道在这里本质上就是一个"由 ssh 客户端驱动的 frpc"。它的适用场景非常典型:
- 内网是一台无法安装/运行 frpc的机器(无 root、只读系统、临时借用的服务器);
- 只想快速、临时地暴露一个服务,不想写配置文件;
- 资源极度受限的设备,连 frpc 都跑不动。
服务端网关的入口逻辑在 pkg/ssh/gateway.go,SSH 会话与反向转发处理在 pkg/ssh/server.go。
第一步:在 frps 上开启 SSH 隧道网关
编辑frps.toml(完整字段可参考 conf/frps_full_example.toml),最小配置只需一行:
# frps.toml sshTunnelGateway.bindPort = 2200执行./frps -c frps.toml后,frps 会在 2200 端口接受 SSH 连接。💡 此时会在当前工作目录自动生成一个.autogen_ssh_key私钥文件,供内置 SSH 服务器加解密使用,无需额外准备密钥。
完整配置项如下:
| 配置项 | 作用 | 是否必填 |
|---|---|---|
bindPort | frps 的 SSH 服务监听端口 | ✅ 是 |
privateKeyFile | 指定 SSH 服务器使用的私钥文件(可复用本机id_rsa) | 否 |
autoGenPrivateKeyPath | 自动生成的私钥文件存放路径,默认./.autogen_ssh_key | 否 |
authorizedKeysFile | SSH 公钥认证文件,留空则不做 SSH 认证 | 否 |
⚠️安全提醒:最小配置下 SSH 连接无需任何认证。生产环境请务必配置 frps 的token认证,或启用 SSH 公钥认证(见下文"安全加固")。
第二步:一条 SSH 命令打通内网穿透隧道
在本地机器(或需要暴露服务的机器)上执行:
ssh -R :80:127.0.0.1:8080 v0@{frp_address} -p 2200 tcp --proxy_name "test-tcp" --remote_port 9090命令各部分含义:
| 参数 | 说明 |
|---|---|
-R :80:127.0.0.1:8080 | 声明本地127.0.0.1:8080服务需要被转发 |
v0@{frp_address} | 用户名固定为v0,地址为 frps 公网 IP |
-p 2200 | frps 的 SSH 监听端口 |
tcp | 代理类型,支持tcp/http/https/stcp/tcpmux |
--remote_port 9090 | 公网端实际监听的端口 |
--proxy_name | 代理名称,可省略(自动生成随机名) |
执行成功后会看到类似输出,随后保持前台运行即可(Ctrl+C 退出并撤销代理):
frp (via SSH) (Ctrl+C to quit) User: ProxyName: test-tcp Type: tcp RemoteAddress: :9090现在,任何设备访问frps公网IP:9090的流量都会被转发到你本地的 8080 端口——这与以下 frpc 命令完全等效,却少装了一整个客户端:
frpc tcp --proxy_name "test-tcp" --local_ip 127.0.0.1 --local_port 8080 --remote_port 9090进阶:发布 HTTP / HTTPS 服务到自定义域名
如果 frps 配置了vhostHTTPPort,还可以用同一条命令模式发布 HTTP 站点:
ssh -R :80:127.0.0.1:8080 v0@{frp_address} -p 2200 http --proxy_name "test-http" --custom_domain test-http.frps.com之后用curl http://test-http.frps.com即可访问本地 8080 端口的站点,等效于传统的 frpchttp类型代理。https、stcp、tcpmux类型的更多参数,执行对应命令加--help即可查看:
ssh -R :80:127.0.0.1:8080 v0@{frp_address} -p 2200 stcp --help安全加固:token 认证 + SSH 公钥认证
两层认证互相独立、依次生效(先 SSH 认证,后 frps token 认证),建议至少启用其一:
1️⃣ 启用 frps token
在frps.toml中配置auth.token,并在 SSH 命令中带上:
ssh -R :80:127.0.0.1:8080 v0@{frp_address} -p 2200 tcp --remote_port 9090 --token "你的token"2️⃣ 复用本机 authorized_keys 做公钥认证
sshTunnelGateway.bindPort = 2200 sshTunnelGateway.authorizedKeysFile = "/home/user/.ssh/authorized_keys"frp 不支持 SSH 用户名/密码登录,公钥认证复用你现有的密钥即可,无需新建。注意:若更换了 frps 的私钥文件,客户端可能因主机指纹变化而登录失败,删除本地/home/user/.ssh/known_hosts中对应记录即可。
验证与排障
- 查看代理状态:如果 frps 开启了 Web 管理面板(
webServer),登录后可以在 Overview 页面查看当前代理数量与流量概况:
- 代理不生效:确认本地服务端口可访问(如
curl 127.0.0.1:8080),并确认--remote_port未被占用。 - SSH 登录失败:优先检查
known_hosts指纹缓存与authorizedKeysFile配置。 - 需要后台运行:直接
Ctrl+Z+disown,或使用tmux/nohup托管该 ssh 进程。
官方端到端测试覆盖了 tcp、http、https、tcpmux、stcp 全部类型,可作为行为参考:test/e2e/v1/features/ssh_tunnel.go。
常见问题 FAQ
Q:SSH 隧道网关和"用 frp 穿透 SSH 端口"是一回事吗?不是。前者是不使用 frpc、借 SSH 协议反向转发完成基础内网穿透;后者是通过 frpc 把内网的 SSH 服务暴露给公网访问。
Q:一台机器可以建多个隧道吗?可以。每条ssh -R连接就是一个独立代理,多开几个终端即可分别暴露不同端口/域名。
Q:支持 UDP 吗?该模式目前仅覆盖 TCP 类代理(tcp/http/https/stcp/tcpmux)。
总结
| 能力 | 传统 frpc 方案 | SSH 隧道网关方案 |
|---|---|---|
| 内网机安装客户端 | 必须安装 frpc | ❌ 零安装 |
| 编写配置文件 | 需要 | ❌ 一条命令 |
| 代理类型 | 全部 | tcp / http / https / stcp / tcpmux |
| 适用版本 | - | v0.53.0+ |
| 适用场景 | 长期、完整功能 | 临时、快速、免安装 |
当你只需要"快速把内网服务推上公网"时,SSH 隧道网关是最轻量的选择:一行 frps 配置 + 一条 ssh 命令,内网穿透即刻完成。更多字段细节可查阅官方文档 doc/ssh_tunnel_gateway.md,需要完整功能时再切回标准 frpc 方案即可。
【免费下载链接】frpA fast reverse proxy to help you expose a local server behind a NAT or firewall to the internet.项目地址: https://gitcode.com/GitHub_Trending/fr/frp
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考