frp+nginx实现网络穿透及windows远程桌面连接

前言

之前写过一篇ngrok+nginx实现windows远程桌面连接实现了在公司远程连接家里的电脑,最近发现另一个开源网络穿透frp似乎更优秀,其在git的star达到了61.4k,本篇就是用frp搭建网络穿透。

frp 是什么?


官方的解释为

frp is a fast reverse proxy to help you expose a local server behind a NAT or firewall to the Internet. As of now, it supports TCP and UDP, as well as HTTP and HTTPS protocols, where requests can be forwarded to internal services by domain name.
frp also has a P2P connect mode.

frp 是一种快速反向代理,可帮助您将 NAT 或防火墙后面的本地服务器暴露给 Internet。 目前,它支持 TCP 和 UDP,以及 HTTP 和 HTTPS 协议,可以通过域名将请求转发到内部服务。
frp 还有一个 P2P 连接模式。

简单来说,你个人本地web服务,通过与frp的服务建立隧道连接,然后别人就可以通过访问frp服务来访问你的本地服务了。

frp的git地址: https://github.com/fatedier/frp

frp官方文档: https://gofrp.org/docs/overview/

官方文档罗列了相关概念和操作,要是有能力尽量阅读官方文档。

frp 的下载

frp可以在release页面进行下载,当前的最新版本为0.045,客户端和服务端为同一个,只不过配置和启动命令不同,大家可以根据自己的操作系统进行下载,要是linux不知道下载那个那个文件,可以查看linux cpu 指令集架构 RISC / CISC | arm | amd | X86/i386 | aarch64这篇文章了解cpu对应的指令集架构下载对应的软件包。

frp 服务端

frp 服务端配置


frp的服务端配置文件为frp文件夹下的frps.ini文件,具体完整的配置可以参考frps_full.ini文件.

本人的一个配置为

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 模块名
[common]
# 对frp客户端暴露的端口
bind_port = 7000
# 对外暴露的接口
vhost_http_port = 7099
# 服务端统计仪表盘端口
dashboard_port = 7091
# 仪表盘登录用户名
dashboard_user = admin
# 仪表盘登录密码
dashboard_pwd = admin
# 子域名,这里采用子域名模式
subdomain_host = frp.xxx.com

# 和客户端token链接
authentication_method=token
# 认证链接
token=test_token

frp 服务端启动

标准的启动命令为

1
/frp_path/frps -c /frp_path/frps.ini

frp 的部署

只使用命令,当我们推出linux shell后,服务就暂停了,这不是我们想要的结果,部署有两种方式,使用systemd及后天运行脚本。

systemd
systemd为官方推荐的部署方式,参考官方文档 使用 systemd

后台运行
我们也可以使用linux后台运行命令自己部署

1
nohup /frp_path/frps -c /frp_path/frps.ini &

frp 客户端

frp 客户端配置


frp的客户端配置文件为frp文件夹下的frpc.ini文件,具体完整的配置可以参考frpc_full.ini文件.

本人的一个配置为

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# frpc.ini
# 对应上文服务器配置的模块名
[common]
server_addr = frp.xxx.com
server_port = 7000

# windows 远程桌面端口
[windows]
# 协议需要是tcp
type = tcp
# 本地的远程服务端口,默认为3389,处于安全考虑,建议修改远程默认端口
local_port = 3389
# frp server暴露连接的端口,远程桌面连接时需要输入端口,因此通过端口暴露,这里也建议修改端口
remote_port = 3389
# 和服务端认证链接
token=test_token

# http web 接口服务
[httpweb01]
# 协议
type = http
# 本地服务端口
local_port = 7102
# 子域名,由于我们服务器的域名subdomain_host配置为frp.xxx.com,因此这里暴露的域名为 web1.frp.xxx.com
subdomain = web1
# http basic auth 基础认证的用户名和密码,不然别人只要知道了你的url就可以访问了
http_user = easytrader
http_pwd = easytrader123
# 和服务端认证链接
token=test_token

# web02
[httpweb02]
type = http
local_port = 7103
subdomain = web2
http_user = easytrader
http_pwd = easytrader123
# 和服务端认证链接
token=test_token


frp 客户端启动

标准的启动命令为

1
./frpc -c ./frpc.ini

frp 的部署

linux 下推荐使用 systemd
windows下推荐自己编写.bat文件,然后配置为开机启动项,windows的开机启动配置可以参考win10 开机启动,无需登录

域名配置

登录你的域名管理,配置frp.xxx.com*.frp.xxx.com指向你的frp server地址

nginx 配置

一个简单的nginx配置如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
server {
listen 80;
server_name *.frp.xxx.com;

location / {
proxy_pass http://127.0.0.1:7000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header REMOTE-HOST $remote_addr;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}

本质上就是当后续使用服务的时候,如访问者访问http://web1.frp.xxx.com 时,将请求转交给frp server处理。

frp 的使用情况

登录 http://server ip:7091 进行访问,端口为之前服务端的dashboard_port配置。

服务的使用

远程桌面连接

通过以下地址 frp.xxx.com:3389 进行连接

http接口或页面

如果是页面,直接访问 web1.frp.xxx.com ,输入用户名密码后即可进行访问

如果是程序调用,需要加上 Authorization 的header,具体可以参考文章 JAVA Http Basic auth

自问自答

frp的客户端和服务端通信安全如何保障?

参考身份认证 ,目前 frpc 和 frps 之间支持两种身份验证方式,token 和 oidc,默认为 token。

我暴露的服务如何保障安全

http相关的可以通过设置 BasicAuth 鉴权实现简单的认证。

复杂可以通过安全地暴露内网服务,这样服务只能被部署了visitor frp client的机器访问,缺点是需要部署frp cli。

完结

至此,使用frp搭建的http穿透及远程桌面连接已顺利实现。