文章发布地址:https://blog.qiuluo.xin/2019/06/07/frp%E5%86%85%E7%BD%91%E7%A9%BF%E9%80%8F/
1 背景
1.1 正常情况一个内网主机与外网服务器的交互
以访问google为例。
假设我们的主机IP是192.168.0.0,路由器LAN IP为192.168.0.1,WAN IP为211.22.145.234(这是一个公网IP),google 服务器 IP 为74.125.204.101。
- 主机构建HTTP请求数据包,目标IP为74.125.204.101,目标端口是80/443,源IP为192.168.0.0,源端口随机生成,假定为5000
- 主机检查目标IP地址,发现不在一个网段,数据包丢给默认网关192.168.0.1
- 路由器LAN口收到数据包,构建NAT映射,随机生成端口,假定为5500,这样映射就是:5500->192.168.0.0:5000.WIN口收到的数据包,如果目标端口是5500,则会转发给192.168.0.0的5000端口。
- 路由器修改数据包的源端口为5500,源IP地址为211.22.145.234,使用WAN口将数据包发出去
- google服务器收到请求,构建响应HTTP数据包,目标IP地址为211.22.145.234,目标端口是5500
- 路由器WAN口收到数据包,目标端口是5500,查询NAT表,发现对应的机器是192.168.0.0:5000,所以修改目标IP为192.168.0.0,目标端口为5000,并通过LAN口发送给主机
- 主机收到数据包,完成一次通信
1.2 内网穿透实现
测试服务器没有公网IP,想要让外网直接调用内网的服务,就需要用到内网穿透。
和使用路由器与外网交互类似,需要有一个第三方拥有公网IP的服务器进行路由的中转,代替路由器的角色。
由内网服务器主动请求公网服务器,建立一个长连接,这时公网服务器就可以随时随地的向内网服务器发送消息了。
当使用浏览器想要访问内网服务时,先将请求发送到公网服务器上,公网服务器再通过之前建立的长连接将请求发送到内网服务器中。从而实现在外网请求内网服务的需求。
2 服务搭建
2.1 公网服务搭建
2.1.1 下载工具
通过下面的链接下载frp上传到服务器。
https://github.com/fatedier/frp/releases/download/v0.14.1/frp_0.14.1_linux_amd64.tar.gz
或直接使用wget下载
wget https://github.com/fatedier/frp/releases/download/v0.14.1/frp_0.14.1_linux_amd64.tar.gz
解压
sudo tar zxf frp_0.14.1_linux_amd64.tar.gz
2.1.2 修改配置
cd frp_0.14.1_linux_amd64/
sudo vim frps.ini
内容如下:
[common]
bind_port = 8989 # frp服务的端口
vhost_http_port = 8889 # frp的http服务的端口
2.1.3 启动服务
两种启动方式使用一种即可
./frps -c frps.ini # 前台直接启动,测试看日志方便
nohup ./frps -c ./frps.ini > /dev/null 2>&1 & # 后台运行
2.2 内网服务搭建
2.2.1 下载工具
与公网服务器下载同样的文件,通过下面的链接下载frp上传到服务器。
https://github.com/fatedier/frp/releases/download/v0.14.1/frp_0.14.1_linux_amd64.tar.gz
或直接使用wget下载
wget https://github.com/fatedier/frp/releases/download/v0.14.1/frp_0.14.1_linux_amd64.tar.gz
解压
sudo tar zxf frp_0.14.1_linux_amd64.tar.gz
2.2.2 修改配置
cd frp_0.14.1_linux_amd64/
sudo vim frpc.ini
内容如下:
[common]
server_addr = 47.95.199.112 # 公网服务器IP
server_port = 8989 # 公网服务器的bind_port
[ssh]
type = tcp # 协议格式
local_ip = 127.0.0.1
local_port = 22 # 本地ssh服务端口
remote_port = 7878 # 远程连接时使用的端口
[web]
type = http # 协议格式
local_ip = 127.0.0.1
local_port = 7006 # 本地服务端口
custom_domains = frp.qiuluo.xin # 域名
2.1.3 启动服务
两种启动方式使用一种即可
./frpc -c ./frpc.ini # 前台直接启动,测试看日志方便
nohup ./frpc -c ./frpc.ini > /dev/null 2>&1 & # 后台运行
3 测试
3.1 ssh
配置了ssh,所以可以在远程连接本地服务器
使用下面的命令远程进行连接,成功的话输入密码即可进入系统。
ssh 用户名@IP或域名 -p 之前配置的remote_port端口号
例:ssh [email protected] -p 7878
3.2 http
在内网服务器启动一个http服务,这里使用一个7006端口的后端服务。
在浏览器使用之前配置的域名和端口进行访问
http://frp.qiuluo.xin:8889/
页面成功显示内网服务返回的内容。
4 nginx映射
现在已经实现了内网映射,但是需要在域名后增加端口号,不符合日常需求。
4.1 公网服务器上,使用nginx进行映射。
sudo vim /etc/nginx/nginx.conf
增加如下server
server {
listen 80;
server_name frp.qiuluo.xin;
location / {
proxy_pass http://127.0.0.1:8889/;
}
}
4.2 修改内网服务器配置
但是转发后frp收到的域名不再是frp.qiuluo.xin
,所以需要在内网frp配置文件custom_domains
后增加127.0.0.1
修改后的配置文件
[common]
server_addr = 47.95.199.112
server_port = 8989
[ssh]
type = tcp
local_ip = 127.0.0.1
local_port = 22
remote_port = 7878
[web]
type = http
local_ip = 127.0.0.1
local_port = 7006
custom_domains = frp.qiuluo.xin,127.0.0.1
5 完成
重启frp客户端服务。
重新使用浏览器去掉端口后访问,发现可以拿到内网服务的内容,frp内网穿透搭建完成。
以后在内网每新增一个服务(使用一个新的端口),都需要修改frp配置进行公网服务器和内网服务器的端口映射。
6 参考
https://blog.csdn.net/lishanleilixin/article/details/78384848
https://www.jianshu.com/p/b60795a3c9fc
https://www.imooc.com/article/72503