1. 正常情况一个内网主机与外网服务器的交互

以访问google为例

假设我们的主机IP是192.168.0.10,路由器LAN IP为192.168.0.1,WAN IP为211.22.145.234(这是一个公网IP),
google 服务器 IP 为74.125.204.101。

1.主机构建HTTP请求数据包,目标IP为74.125.204.101,目标端口是80/443,源IP为192.168.0.10,源端口随机生成,假定为5000
2.主机检查目标IP地址,发现不在一个网段,数据包丢给默认网关192.168.0.1
3.路由器LAN口收到数据包,构建NAT映射,随机生成端口,假定为5500,这样映射就是:5500->192.168.0.10:5000.
  WIN口收到的数据包,如果目标端口是5500,则会转发给192.168.0.10的5000端口
4.路由器修改数据包的源端口为5500,源IP地址为211.22.145.234,使用WAN口将数据包发出去
5.google服务器收到请求,构建响应HTTP数据包,目标IP地址为211.22.145.234,目标端口是5500
6.路由器WAN口收到数据包,目标端口是5500,查询NAT表,发现对应的机器是192.168.0.10:5000,
  所以修改目标IP为192.168.0.10,目标端口为5000,并通过LAN口发送给主机
7.主机收到数据包,完成一次通信

2. 内网穿透实现

测试服务器没有公网IP,想要让外网直接调用内网的服务,就需要用到内网穿透.

和使用路由器与外网交互类似,需要有一个第三方拥有公网IP的服务器进行路由的中转,代替路由器的角色.

由内网服务器主动请求公网服务器,建立一个长连接,这时公网服务器就可以随时随地的向内网服务器发送消息了

当使用浏览器想要访问内网服务时,先将请求发送到公网服务器上,公网服务器再通过之前建立的长连接将请求发送到内网服务器中。

从而实现在外网请求内网服务的需求

3. 公网服务器设置

# 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
# cd frp_0.14.1_linux_amd64/
# sudo vim frps.ini
#
[common]
bind_port = 8989        # frp服务的端口
vhost_http_port = 8889  # frp的http服务的端口

# 启动服务
# ./frps -c frps.ini      # 前台直接启动,测试看日志方便
# nohup ./frps -c ./frps.ini > /dev/null 2>&1 &   # 后台运行

4. 内网客户端设置

# 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
# 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 # 域名

# 启动服务
# ./frpc -c ./frpc.ini    # 前台直接启动,测试看日志方便
# nohup ./frpc -c ./frpc.ini > /dev/null 2>&1 & # 后台运行

5. 测试

配置了ssh,所以可以在远程连接本地服务器

使用下面的命令远程进行连接,成功的话输入密码即可进入系统

ssh 用户名@IP或域名 -p 之前配置的remote_port端口号
例:ssh wenjijie@47.95.199.112 -p 7878

在内网服务器启动一个http服务,这里使用一个7006端口的后端服务

在浏览器使用之前配置的域名和端口进行访问

http://frp.qiuluo.xin:8889/

页面成功显示内网服务返回的内容

现在已经实现了内网映射,但是需要在域名后增加端口号,不符合日常需求

公网服务器上,使用nginx进行映射

# sudo vim /etc/nginx/nginx.conf
# 
server {
    listen 80;
    server_name frp.qiuluo.xin;

    location / {
            proxy_pass http://127.0.0.1:8889/;
    }
}

但是转发后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

6. 例子(frp-0.33.0)

frps.ini

[common]
privilege_mode = true
privilege_token = 20200606
bind_port = 9898
vhost_http_port = 7788
dashboard_port = 7500
# dashboard's username and password are both optional,if not set, default is admin.
dashboard_user = root
dashboard_pwd = root@admin
#subdomain_host = p2pnet.club
#subdomain_host = free.com

frpc.ini

[common]
privilege_token = 2020060611
server_addr = x.x.x.x
server_port = 9898

[ssh]
type = tcp
local_ip = 127.0.0.1
local_port = 22
remote_port = 6000

[http]
#type = tcp
type = http
local_ip = 192.168.9.105
local_port = 60080
remote_port = 7788
custom_domains = www.workerwork.com #修改/etc/hosts文件
http_user = root
http_pwd = baicells
#subdomain = home

[RDP]
privilege_mode = true
type = tcp
local_ip = 127.0.0.1
local_port = 3389
remote_port = 6001