1. 为什么你需要FRP内网穿透?
如果你和我一样,有一台性能不错的台式机放在家里或者实验室,上面装满了各种开发环境、深度学习框架,甚至还有一块宝贵的GPU,那你肯定遇到过和我一样的烦恼:人不在机器旁边,就没办法用它的算力。比如,你正在咖啡馆用笔记本写代码,突然想跑一个模型,但笔记本的CPU慢得像蜗牛,这时候你就会无比想念家里那台“吃灰”的台式机。
传统的远程桌面方案,比如Windows自带的远程桌面或者TeamViewer,用来操作图形界面还行,但对于我们开发者来说,最核心的需求其实是远程访问特定的服务,比如Jupyter Notebook/Lab、SSH终端、或者文件共享。这些服务通常运行在特定的端口上(比如Jupyter的8888端口),而我们的个人电脑通常处于家庭或公司路由器后面,没有独立的公网IP地址,外界根本无法直接访问。
这时候,FRP(Fast Reverse Proxy) 就登场了。你可以把它想象成一个“万能接线员”。你有一台拥有公网IP的云服务器(比如阿里云、腾讯云的轻量应用服务器),它就像公司大楼的前台,谁都能找到。你的本地台式机就是大楼里某个没有对外分机号的工位。FRP的作用,就是在前台(云服务器)那里帮你设置一个转接规则:“喂,如果有人打前台电话7002分机,请帮我转接到内部8888工位”。这样,你在咖啡馆用笔记本访问“前台电话:7002”,就能直接和“内部8888工机位”(也就是你本地的Jupyter服务)通话了。整个过程,你的本地机器完全不需要有公网IP,这就是“内网穿透”的精髓。
我当初就是为了能随时随地用家里台式机的GPU跑深度学习代码,才折腾起了FRP。实测下来,这套方案非常稳定,延迟主要取决于你的云服务器带宽,对于传输代码和模型权重来说完全够用。下面,我就把我从零开始踩过的坑和总结的最佳实践,手把手分享给你。
2. 准备工作:云服务器与FRP工具获取
工欲善其事,必先利其器。在开始配置之前,我们需要准备好两样东西:一台有公网IP的云服务器,以及FRP的软件包。
关于云服务器:这是整个方案的基石,它需要有一个固定的公网IP。市面上阿里云、腾讯云、华为云等都有不错的选择。对于学生朋友,可以重点关注“云工开物”、“校园计划”等活动,经常能免费或以极低价格(比如一年几十块钱)获得一台轻量应用服务器。我当初就是白嫖的阿里云新加坡节点,系统选择Ubuntu 20.04,配置1核1G就完全足够运行FRP服务端了,毕竟它只做流量转发,资源消耗很小。
关于FRP工具:它是一个开源项目,在GitHub上发布。我们不需要编译,直接下载对应系统版本的预编译二进制文件就行。这里有个关键点:服务端(云服务器)和客户端(你的本地电脑)需要下载对应其操作系统的版本。
- 服务端(云服务器,假设是Linux):通常选择 linux_amd64 版本,这是针对64位Linux系统的。
- 客户端(你的本地电脑):如果是Windows,就下载 windows_amd64;如果是Linux(比如Ubuntu),就下载 linux_amd64。
你可以直接到GitHub的Release页面下载,如果网络不畅,也可以在一些国内的镜像站寻找资源。下载后,你会得到一个压缩包,解压后里面文件很多,但我们真正需要关注的只有两个:
- 服务端:frps(可执行程序) 和 frps.ini(配置文件)。
- 客户端:frpc(可执行程序) 和 frpc.ini(配置文件)。
把“s”和“c”记清楚,后面配置就不会搞混了。接下来,我们就先登录到云服务器上,把服务端的环境搭建起来。
3. 云服务器端(FRPS)配置详解
现在,通过SSH连接到你的云服务器。我习惯先创建一个专用用户来运行这些服务,这样更安全,当然你也可以直接用默认用户。
3.1 安装与基础配置
首先,我们下载并解压FRP。以下命令以 v0.50.0 版本为例,你可以去GitHub查看最新版本号进行替换。
# 下载FRP压缩包
wget https://github.com/fatedier/frp/releases/download/v0.50.0/frp_0.50.0_linux_amd64.tar.gz
# 解压
tar zxvf frp_0.50.0_linux_amd64.tar.gz
# 进入解压后的目录
cd frp_0.50.0_linux_amd64
进入目录后,你会看到 frps 和 frps.ini。我们需要编辑 frps.ini 文件来配置服务端。
vim frps.ini
将文件内容修改为如下所示。别担心,我会逐一解释每个参数的作用。
[common]
bind_port = 7000
dashboard_port = 7500
dashboard_user = admin
dashboard_pwd = your_strong_password
token = your_secret_token_here
- [common]: 这是必须的节(section)头。
- bind_port: 这是最重要的端口之一。FRP客户端通过这个端口连接到服务端。默认是7000,你可以改成其他未被占用的端口。
- dashboard_port: FRP提供了一个内置的Web仪表盘,可以查看连接状态和流量统计。我们通过7500端口来访问它。
- dashboard_user 和 dashboard_pwd: 登录上述仪表盘的用户名和密码。务必把 your_strong_password 改成你自己设置的强密码,不要用默认的admin。
- token: 这是另一个关键的安全设置。相当于客户端连接服务端时需要出示的“口令”。客户端配置里必须使用相同的token才能连接成功。请将 your_secret_token_here 替换为一串复杂的随机字符串。
配置保存后,可以先试运行一下:
./frps -c frps.ini
如果看到类似 “frps started successfully” 的日志,说明服务端已经跑起来了。这时,先别急着进行下一步,我们还有一件重要的事要做:开放防火墙端口。
3.2 防火墙与安全组设置
云服务器通常有双重防火墙:操作系统自带的防火墙(如ufw或firewalld)和云服务商控制台的安全组。两者都需要配置,否则流量会被拦在外面。
1. 云服务商安全组(以阿里云/腾讯云为例):
这是最关键的一步。你需要登录到云服务器的管理控制台,找到“安全组”或“防火墙”设置。添加如下几条入方向规则:
| TCP | 7000 | 0.0.0.0/0 | 允许FRP客户端连接 |
| TCP | 7500 | 你自己的IP地址(可选) | 允许访问仪表盘,建议限制IP更安全 |
| TCP | 7001-7003(示例) | 0.0.0.0/0 | 为后续客户端映射的端口,可以先开 |
2. 系统防火墙(如果启用):
如果你在服务器上启用了ufw,需要运行类似命令:
sudo ufw allow 7000/tcp
sudo ufw allow 7500/tcp
sudo ufw reload
完成这些后,你可以在本地浏览器访问 http://你的云服务器IP:7500,用刚才设置的用户名密码登录,就能看到FRP的仪表盘了。如果能看到,说明服务端配置成功!
3.3 配置服务端开机自启动(Systemd)
我们不能总是手动去启动frps。用Systemd来管理服务是最规范、最可靠的方式。这比网上有些教程里修改rc.local的方法要优雅得多。
首先,创建一个Systemd服务配置文件:
sudo vim /etc/systemd/system/frps.service
将以下内容粘贴进去,注意修改 ExecStart 的路径为你实际解压frps的绝对路径。
[Unit]
Description=Frp Server Service
After=network.target
[Service]
Type=simple
User=nobody
Restart=on-failure
RestartSec=5s
ExecStart=/path/to/your/frp/frps -c /path/to/your/frp/frps.ini
[Install]
WantedBy=multi-user.target
这里 User=nobody 是让服务以一个低权限用户运行,增强安全性。然后执行以下命令:
# 重新加载Systemd配置
sudo systemctl daemon-reload
# 启用服务,使其开机自启
sudo systemctl enable frps
# 立即启动服务
sudo systemctl start frps
# 查看服务状态,确认运行正常
sudo systemctl status frps
如果状态显示为 active (running),并且日志没有报错,那么恭喜你,FRP服务端已经配置完毕,并且会随着服务器重启而自动运行。现在,我们可以把目光转向你的本地电脑(客户端)了。
4. 本地客户端(FRPC)配置详解
客户端配置的核心思想是:告诉FRP客户端,本地有哪些服务需要“暴露”出去,以及分别映射到云服务器的哪个端口上。我们以最常见的场景为例:暴露SSH(22端口)、Jupyter Notebook(8888端口)和文件共享(SMB,445端口)。
4.1 Windows客户端配置
在Windows电脑上,下载 windows_amd64 版本的FRP并解压。在解压目录里,找到并编辑 frpc.ini 文件。
[common]
server_addr = 你的云服务器公网IP
server_port = 7000
token = your_secret_token_here
[ssh]
type = tcp
local_ip = 127.0.0.1
local_port = 22
remote_port = 7001
[jupyter]
type = tcp
local_ip = 127.0.0.1
local_port = 8888
remote_port = 7002
[smb]
type = tcp
local_ip = 127.0.0.1
local_port = 445
remote_port = 7003
参数解读:
- server_addr 和 server_port:指向你刚刚配置好的FRP服务端地址和端口(bind_port)。
- token:必须和服务端 frps.ini 里设置的完全一致。
- [ssh], [jupyter], [smb]:这些是自定义的规则名称,你可以随意起名,容易理解就行。
- type:转发协议类型,对于这些服务,tcp 就够了。
- local_ip 和 local_port:本地服务监听的IP和端口。127.0.0.1 表示本机。
- remote_port:这是核心映射端口。它定义了外部通过云服务器的哪个端口来访问内部服务。例如,[jupyter] 规则意味着:访问 云服务器IP:7002 的流量,会被转发到本地电脑的 127.0.0.1:8888。
配置好后,记得回到云服务器控制台的安全组,将 7001, 7002, 7003 这几个 remote_port 在防火墙中开放(TCP协议)。
然后,在Windows的CMD或PowerShell中,进入FRP目录,运行 frpc.exe:
.\\frpc.exe -c .\\frpc.ini
如果连接成功,你会看到客户端日志显示 “login to server success”,并且服务端仪表盘上也会出现在线的客户端连接信息。
设置Windows开机自启动:
为了让 frpc 在Windows开机后自动运行,最方便的方法是使用“任务计划程序”。
4.2 Linux客户端配置
如果你的本地台式机是Linux系统(比如Ubuntu),配置过程与Windows类似,只是文件路径和自启动管理方式不同。
下载 linux_amd64 版本的FRP,解压后编辑 frpc.ini,内容与Windows版本完全相同。然后通过命令行运行:
./frpc -c ./frpc.ini
设置Linux开机自启动(Systemd):
和服务端类似,我们也为客户端创建Systemd服务,这样更专业。
sudo vim /etc/systemd/system/frpc.service
写入以下内容(修改路径):
[Unit]
Description=Frp Client Service
After=network.target
[Service]
Type=simple
User=你的用户名
Restart=on-failure
RestartSec=5s
ExecStart=/path/to/your/frp/frpc -c /path/to/your/frp/frpc.ini
WorkingDirectory=/path/to/your/frp
[Install]
WantedBy=multi-user.target
之后执行 sudo systemctl daemon-reload, sudo systemctl enable frpc, sudo systemctl start frpc 即可。用 systemctl status frpc 检查状态。
5. 配置Jupyter Notebook/Lab支持远程访问
默认情况下,Jupyter只允许本地浏览器访问,这是出于安全考虑。现在我们已经打通了网络隧道,还需要对Jupyter本身进行配置,让它接受远程连接。
5.1 生成配置文件与设置密码
首先,我们需要生成Jupyter的配置文件。在Anaconda Prompt(Windows)或终端(Linux)中执行:
jupyter notebook –generate-config
这条命令会在用户目录下的 .jupyter 文件夹中生成一个配置文件 jupyter_notebook_config.py。记下这个文件的路径。
接下来,为Jupyter设置一个访问密码:
jupyter notebook password
输入你想设置的密码。这个命令会在 .jupyter 目录下生成一个 jupyter_notebook_config.json 文件,里面保存了你密码的哈希值。打开这个json文件,复制 password 字段后面那一长串密文(看起来像乱码),我们稍后会用到。
5.2 修改关键配置参数
现在,用文本编辑器打开之前生成的 jupyter_notebook_config.py 文件。这个文件很长,里面全是注释掉的配置项。我们不需要全部看懂,只需要在文件末尾添加以下几行即可:
c.NotebookApp.ip = '*'
c.NotebookApp.password = u'sha1:刚才复制的密文'
c.NotebookApp.open_browser = False
c.NotebookApp.port = 8888
c.NotebookApp.allow_remote_access = True
- c.NotebookApp.ip = '*':这是最关键的一行,允许任何IP地址的连接。因为现在连接来自FRP转发,源IP不是真正的“本地”。
- c.NotebookApp.password:将 u'sha1:…' 替换为你刚才复制的完整密文字符串。
- c.NotebookApp.open_browser = False:远程启动时不要尝试打开浏览器。
- c.NotebookApp.port = 8888:确保端口与FRP客户端配置中的 local_port 一致。
- c.NotebookApp.allow_remote_access = True:显式允许远程访问。
保存配置文件后,启动Jupyter Notebook:
jupyter notebook
或者,如果你更喜欢功能更强大的JupyterLab:
jupyter lab
5.3 远程访问测试
现在,激动人心的时刻到了。在你的笔记本或任何能上网的设备上,打开浏览器,输入地址:http://你的云服务器IP:7002。
这里的 7002 就是我们在 frpc.ini 中为 [jupyter] 规则设置的 remote_port。如果一切顺利,你应该会看到Jupyter的登录页面,输入之前设置的密码,就能成功进入,并使用本地台式机的全部计算资源了!
关于工作目录的提醒:通过这种方式远程访问Jupyter,你的工作目录是远程台式机上Jupyter启动的目录,而不是你当前所用笔记本上的目录。在Notebook里用 !pwd(Linux)或 !cd(Windows)可以查看当前路径。读写文件都是相对于远程机器的路径,这一点需要适应。
6. 进阶技巧与故障排查
基本的穿透已经实现,但要让这个方案更顺手、更健壮,这里还有一些我踩过坑后总结的进阶技巧。
6.1 在Jupyter中使用不同的Conda虚拟环境
我们经常为不同项目创建独立的Conda环境。如何让这些环境也出现在远程Jupyter的Kernel列表中呢?很简单,只需要在目标虚拟环境中安装一个插件即可。
假设你有一个名为 dl_env 的虚拟环境:
# 激活环境
conda activate dl_env
# 在该环境中安装 ipykernel
conda install ipykernel
# 将这个环境注册为Jupyter的Kernel
python -m ipykernel install –user –name dl_env –display-name "Python (Deep Learning)"
完成后,重启Jupyter,在新建Notebook时,你就可以选择“Python (Deep Learning)”这个Kernel了,所有代码都会在 dl_env 环境中执行。
6.2 使用VSCode连接远程Jupyter服务器
除了浏览器,用VSCode连接远程Jupyter也是一种极佳的体验,尤其是结合其强大的代码提示和版本管理功能。
连接成功后,VSCode底部状态栏会显示远程服务器的信息。这样你就可以在VSCode的舒适环境中,享用远程的强大算力了。同样要注意,文件操作路径是远程服务器路径。
6.3 常见故障与排查思路
-
连接失败,无法访问仪表盘或服务:
- 首要检查:云服务商控制台的安全组规则是否已正确添加并生效。这是新手最容易忽略的一步。
- 其次检查:云服务器和本地客户端的防火墙是否放行了相关端口。
- 确认 frps 和 frpc 的日志是否有错误信息。日志是定位问题的第一手资料。
-
能连接但提示Token错误:
- 确保服务端 frps.ini 和所有客户端 frpc.ini 中的 token 字符串完全一致,包括大小写和任何特殊字符。
-
Jupyter要求输入Token或密码不正确:
- 检查 jupyter_notebook_config.py 中 c.NotebookApp.ip 是否设置为 '*'。
- 确认密码密文是否正确复制,整个 sha1:… 字符串需要完整粘贴。
- 尝试在启动Jupyter时添加 –debug 参数查看更详细的日志。
-
服务不稳定,偶尔断开:
- 在 frpc.ini 的 [common] 节可以添加 tls_enable = true 来启用TLS加密传输,可能更稳定。
- 检查云服务器的带宽是否过小,或被其他应用占满。
- 在客户端和服务端的Systemd服务文件中,我们已设置了 Restart=on-failure,这能保证进程崩溃后自动重启。
配置内网穿透的整个过程,就像是在搭建一座连接个人计算孤岛和外部世界的桥梁。一开始可能会被防火墙、安全组、配置文件这些概念绕晕,但一旦亲手走通整个流程,你会发现它其实逻辑非常清晰。我现在已经习惯了在任何有网络的地方,掏出轻薄本,连接到家中的“工作站”上跑代码、看结果,这种自由的感觉极大地提升了工作效率和幸福感。希望这份详细的指南也能帮你顺利搭建起属于自己的远程开发环境。如果在实际操作中遇到什么问题,多看看日志,耐心排查,你一定能搞定它。
网硕互联帮助中心


评论前必须登录!
注册