利用frp实现内网穿透

最近在学校内部搭建了一个Web服务环境,想通过公网来访问,所以研究了一下内网穿透,网上有很多方法来实现内网穿透,大多数都是收费的,像ngrokfrp这样的可以自己搭建,所以本着学习的想法,打算自己搭建一个,使用frp工具来实现。

原理

一般来说,学习的话就得把原理弄清楚,不然做出来能用以后碰到类似的也就记得不太深,所以这里就要唠叨一下内网穿透的原理了,当然也是从网上大神的文章学习来的。

公网主机先监听一个端口(8888端口为例),监听这个端口是用于向外部提供一个HTTP服务。同时其他任意一个端口(这里我们假设为7777),监听这个端口是用于让内网服务器主动连接进来打通一个隧道。接着内网再主动向公网主机的7777发起一个请求,这样内网就成功与公网主机建立了一个连接通道。然后当有任何客户端主动连接公网的8888端口时,公网接收到连接请求之后马上把这连接请求通过先前建立好的隧道转发到内网主机,内网主机接收到来自隧道的数据包后再主动连接内网主机自身的80端口(也可以为自己定义web服务端口),连接成功之后将数据包原封不动地转发数据包给80端口,待HTTP服务器程序处理完这个数据包,生成了响应报文之后再原路转发回去,最终到达公网的8888端口,然后返回给最开始请求公网服务器8888端口的客户端。

前期准备

  • 公网服务器一个(我使用的是阿里云服务器CentOS7)
  • 内网服务器一个(我的是Linux系统)
  • 阅读frp官方文档
  • frp各版本下载链接
  • 在内网服务器上放一个测试页面(非必须)
  • 父域名和公网IP绑定

服务器端配置(公网ip的服务器上)

GitHub上下载代码

mkdir /usr/frp
cd /usr/frp
wget https://github.com/fatedier/frp/releases/download/v0.22.0/frp_0.22.0_linux_amd64.tar.gz
tar -zxvf frp_0.22.0_linux_amd64.tar.gz 

修改配置文件

服务端要使用的文件是frps.inifrps这两个文件,进入刚刚解压之后的目录

cat frps.ini
[common]
bind_port = 7000

关于frps.ini的完整配置文件参考同级目录下的frps_full.ini或者官方文档frps_full.ini

修改配置文件内容:

vi frps.ini
[common]
bind_port = 7000
# 填写 frp 服务端密码
token = 12345678
#访问客户端web服务自定义的端口号
vhost_http_port = 8888
vhost_https_port = 443
#dashboard_addr和dashboard_port查看FRPS的仪表盘
dashboard_addr = 0.0.0.0
dashboard_port = 7500
#为基本身份验证面板用户和passwd保护,如果没有设置,包括默认值为admin
dashboard_user = admin
dashboard_pwd = admin

启动frps

前端启动

# 使用 -c 参数指定配置文件,使用Ctrl+C终止程序
./frps -c frps.ini

说明启动成功了,但是直接使用这里的命令行来运行是不行的,因为在关掉ssh窗口后程序frps就会停止运行,因此要使用nohup [command] &这种操作来使其在后台运行.

后台启动

nohup /usr/frp/frp_0.22.0_linux_amd64/frps -c /usr/frp/frp_0.22.0_linux_amd64/frps.ini &

停止

pkill frps

客服端配置(内网IP的服务器上)

下载对应操作系统的压缩包,然后解压,进入解压后的目录,这里直接写怎么配置,其他的就不细说了。

主要用到的文件是frpc.inifrpc,关于frpc.ini的完整配置文件参考同级目录下的frpc_full.ini或者官方文档frps_full.ini

首先查看配置文件默认的配置内容,cat frpc.ini

[common]
server_addr = 127.0.0.1   
server_port = 7000              

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

在默认的客户端配置文件当中,配置了一个TCP映射,不过我们需要搭建Web服务,因此还需要添加一个HTTP映射,并修改对应的服务端IP地址。

修改配置文件内容:

[common]
#公网服务器ip
server_addr = 39.106.201.219 
#与服务端bind_port一致   
server_port = 7000              
token = 12345678

[ssh]
#连接协议
type = tcp 
#内网服务器Ip       
local_ip = 10.203.87.22 
#ssh默认端口号
local_port = 22
#自定义的访问内部ssh端口号      
remote_port = 6000   

[web]
#访问协议
type = http
#内网服务器Ip         
local_ip = 10.203.87.22 
#内网web服务的端口号
local_port = 80 
#所绑定的公网服务器域名,一级、二级域名都可以   
custom_domains = zyddn.club 

启动客户端./frpc -c frpc.ini

后台启动命令和对应的停止命令与服务端的frp一样

测试

测试失败,出现错误

浏览器访问zyddn.club:8888,结果是The page you visit not found

服务端提示: [W] [newhttp.go:209] http: proxy error: no such domain

客户端提示:connect: connection refused

解决方法

查看apache有没有启动,这回比较智障,居然忽略了查看服务状态。

再次访问:

zyddn.club:8888

测试结果,回显正常

另一种配置方法,其实大致差不多

服务端:

[common]
bind_port = 5000
# 填写 frp 服务端密码
token = 12345678
#访问客户端web服务自定义的端口号
vhost_http_port = 8888
vhost_https_port = 3344
#dashboard_addr和dashboard_port查看FRPS的仪表盘
dashboard_addr = 0.0.0.0
dashboard_port = 4000
#为基本身份验证面板用户和passwd保护,如果没有设置,包括默认值为admin
dashboard_user = admin
dashboard_pwd = admin
# 此设置需要配合客户端设置,仅在穿透到内网中的 http 或 https 时有用(可选)
# 假设此项设置为 example.com,客户端配置 http 时将 subdomain 设置为 test,
# 则你将 test.example.com 解析到服务端后,可以使用此域名来访问客户端对应的 http
subdomain_host = zyddn.club

客户端:

[common]
server_addr = 39.106.201.219
server_port = 5000
token = 12345678

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

[web]
type = http
local_ip = 10.203.87.22
local_port = 80
subdomain = test

访问:

test.zyddn.club:8888

测试结果,回显正常

总结

关于apache没开启那件事我觉得需要解释一下,因为我之前测试内网穿透的时候是开了的,完全没有想到是apache的问题啊,天地良心,话说,这此的内网穿透实践的确学到新的东西了,感觉人生又充满了活力,这是一条不正经的总结。

-------------本文结束感谢您的阅读-------------

本文标题:利用frp实现内网穿透

文章作者:Peithon

发布时间:2018年12月11日 - 06:12

最后更新:2018年12月11日 - 07:12

原始链接:https://peithon.github.io/2018/12/11/frp-test/

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。