1. 什么是内网穿透
内网穿透(Port Forwarding)是一种网络技术,允许你将外部网络中的请求转发到内部网络中的特定计算机或设备。
内网穿透通常需要一种中间代理或服务器,它位于内部网络和外部网络之间,将外部请求路由到内部目标。这可以通过各种工具和服务来实现,包括专用的内网穿透工具、虚拟专用网络(VPN)和云服务。
其中,frp(Fast Remote Port Forwarding)是一款流行的内网穿透工具。
PS:还有操作更简单的工具,更推荐这些:
2. 实现背景
我正在用本地计算机写一些小项目,并买了一个轻量云主机打算用来部署项目,我目前将 nginx 部署在云服务中,我想实现的是,当 nginx 监听到我的请求时,会将我的请求转发给本地计算机从而访问我本地服务,但因为本地计算机处于移动宽带的内网环境,公网 ip 无法连接本地计算机,所以需要做内网穿透处理———建立一个安全的通道,将外部请求通过云服务器中继到我的本地计算机
所以,最后实现的将是:在任意一台计算上通过访问公网ip就能访问我本地计算机的服务
3. 实现步骤
3.1 安装
3.1.1 下载
先在官方发布仓库下载frp对应包,我是想让云服务器内网穿透本地,所以
服务端选 Linux 安装包:frp_0.52.3_linux_amd64.tar.gz
客户端选 Windows 安装包:frp_0.52.3_windows_amd64.zip
3.1.2 安装服务端
将 frp_0.52.3_linux_amd64.tar.gz 文件移动到云服务器中,并使用tar -xzvf frp_0.52.3_linux_amd64.tar.gz
解压
解压之后可以看到有五个文件,我们只需要使用到frps
和frps.toml
这两个文件
注:解压后会发现里面既有 frps 也有 frpc(Windows版本的可执行程序是exe),前者表示 Server(服务端),后者表示 Client(客户端),对应同名配置文件frps.toml和frpc.toml,对于某一端只会用到其中一套程序。
(1) 首先,修改frps.toml
配置文件:
[common]
bind_port = 7000
dashboard_port = 7500
token = 12345678
dashboard_user = admin
dashboard_pwd = admin
vhost_http_port = 8001
各个参数的意思:
bind_port:这是 frp 服务器监听的端口,用于接收来自 frp 客户端的请求。通常,客户端会将其请求转发到该端口。
dashboard_port:这是 frp 控制面板的端口。你可以通过浏览器访问该端口来查看 frp 的实时状态和统计信息。
token:这是访问 frp 控制面板所需的令牌或密码。只有知道正确的令牌或密码的用户才能访问控制面板。
dashboard_user 和 dashboard_pwd:这两个参数是用于控制面板的基本身份验证用户名和密码。如果启用了控制面板身份验证,用户需要提供正确的用户名和密码才能访问控制面板。
vhost_http_port:这是虚拟主机 HTTP 访问的端口。当 frp 客户端配置为将 HTTP 请求转发到某个本地服务时,该服务通常会监听该端口,以接收传入的 HTTP 请求。
(2) 然后,执行nohup ./frps -c frps.toml > frps.log 2>&1 &
,这表示后台启动frps
,并将输出重定向到frps.log
文件中
可以执行cat frps.log
查看执行日志
如何关闭?
执行ps aux | grep frps
找到启动 frps 进程的进程号(PID)
再执行kill PID
终止进程
(3) 最后,访问云服务器公网ip:7500
,输入用户名和密码,就可以进入控制面板了
注意:要先在云主机上添加相关防火墙规则
3.1.3 安装客户端
对于本机计算机,我们直接解压frp_0.52.3_windows_amd64.zip
文件,可以看到如下文件
作为客户端,只需要使用frpc
和frpc.toml
这两个文件
(1) 首先,修改frpc.toml
配置文件:
[common]
server_addr = 你的公网ip
server_port = 7000
token = 12345678
[web]
type = http
local_port = 8080
local_ip = 127.0.0.1
custom_domains = 你的公网ip
参数意义:
server_addr:这是 frp 服务器(云服务器)的地址(即公网ip),客户端会将其用于与服务器建立连接。
server_port:这是 frp 服务器的端口,客户端使用此端口来连接服务器。
token:这是用于授权和身份验证的令牌。客户端必须提供正确的令牌以与服务器通信。
type:这是服务的类型,用于告诉 frp 客户端如何处理请求。在这个示例中,服务类型是 HTTP,表示客户端将处理 HTTP 请求。
local_port:这是客户端本地服务运行的端口。
local_ip:这是客户端本地服务的 IP 地址。通常,你将其设置为 "127.0.0.1",表示本地主机。
custom_domains:这是自定义域名或主机名,将映射到 frp 客户端的本地服务。在这个示例中,客户端将 "公网ip" 映射到本地服务。
这些参数的配置使 frp 客户端能够将传入的 HTTP 请求通过 frp 服务器转发到本地服务(在这种情况下,本地服务在 127.0.0.1:8080 上运行),从而实现反向代理和端口转发。
(2) 然后,进入cmd,执行frpc -c frpc.toml
启动frpc
在控制面板的 Http 这里,我们可以看到 Status 是 online,表示启动成功了
(3) 再然后,我启动一个 web 应用,端口为 8080
(4) 最后,在浏览器输入公网ip:8001
,就可以访问本地计算机的服务了
4. Nginx 配置
这里的配置是 仅使用 nginx 做一个简单校验测试
server {
listen 80;
server_name 公网ip;
# 首页
index index.html;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
location /api/ {
auth_request /auth;
# 鉴权通过后的处理方式
proxy_pass http://公网ip:8001/success;
}
location = /auth {
# 发送子请求到HTTP服务,验证客户端的凭据,返回响应码
internal;
# 设置参数
set $query '';
if ($request_uri ~* "[^\?]+\?(.*)$") {
set $query $1;
}
# 验证成功,返回200 OK
proxy_pass http://公网ip:8001/verify?$query;
# 发送原始请求
proxy_pass_request_body off;
# 清空 Content-Type
proxy_set_header Content-Type "";
}
error_page 404 /404.html;
location = /40x.html {
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
}
}
当用户访问http://公网ip/api/?token=success
时,nginx 监听到 80 端口,会先进入 auth 模块:
- 首先提取参数后,会发送
http://公网ip:8001/verify?token=success
请求进行校验,此时 frp 监听到 8001 端口,会将请求转发到http://127.0.0.1:8080/verify?token=success
,从而访问本地服务 - 当校验通过后,会发送
http://公网ip:8001/success
请求,此时 frp 监听到 8001 端口,会将请求转发到http://127.0.0.1:8080/success
,从而访问本地服务