
在工作和生活中经常会遇到这样的窘境:自己想要访问的设备没有公网IP。这时可以通过内网穿透(Internet penetration)的方法,来通过公网IP的服务器间接访问原设备,从而将设备的服务展示在公网之上。这其中用到了代理的思想,相关的工具十分多样,并能扩展不同的应用情景。
标题:代理与内网穿透:工具及应用
frp内网穿透
frp是一个可用于内网穿透的高性能的反向代理应用,支持 tcp, udp, http, https 协议,可以以具有公网IP的设备(下文简称服务器)为中介,与内网设备(下文简称原客户端)构建信道,实现内网穿透,这里以ssh应用为例,在x86_64架构的ubuntu_linux上实验,其他情景类推
在github上下载合适系统架构的frp程序release包,包内主要关注两部分,frps打头的文件用于服务器(s:server),frpc打头的用于客户端
服务器需要开放两个端口,一个用于和客户端通信的bind_port/server_port(下文以7000为例);一个用于公网上的用户访问的remote_port(下文以6000为例),并将数据转发给客户端
以阿里云为例,开放端口需要在控制台的防火墙中进行配置,否则无法使用
在服务器上解压包,修改
frps.ini配置文件:[common] bind_port = 7000 #与客户端绑定的进行通信的端口然后在服务器启动服务:
# 前台启动 ./frps -c ./frps.ini # 后台启动(正常使用后推荐后台启动) nohup ./frps -c ./frps.ini &在客户端解压包,修改
frpc.ini配置文件:[common] server_addr = 127.127.127.127 # 公网服务器ip,这里是个假设 server_port = 7000 # 与服务器bind_port一致 #公网通过ssh访问内部服务器 [ssh] type = tcp # 连接协议 local_ip = 127.0.0.1 # 客户端在内网的ip(127.0.0.1也行) local_port = 22 # 客户端ssh默认端口号 remote_port = 6000 # 自定义的用于公网用户访问的ssh中介端口号然后在客户端启动frp连接服务器的服务:
# 前台启动 ./frpc -c ./frpc.ini # 后台启动(正常使用后推荐后台启动) nohup ./frpc -c ./frpc.ini &最后公网用户就可以访问客户端了,注意:
- 端口号是供公网用户访问而非客户端服务器通信的端口
- 用户名是客户端的用户名
- ip是服务器的ip
ssh -p 6000 blablawang@127.127.127.127
注:如果自己没有服务器,或者想要更加简单的实现frp方式的内网穿透,则可以使用sakura frp服务,它的实现原理也基于frp(甚至在安装客户端并登录之后能在目录下找到frpc.ini配置文件),相当于为用户提供了frp服务端。在官网上可以创建隧道(相当于按照上述步骤配置新的网络应用),创建时用户不必再关注bind_port/server_port,只需指定协议类型、remote_port、local_port、auth_pass等即可
ssh代理
通过设置ssh的正反向代理,就能实现端口转发(forwarding port)的效果。该方法用途很多,也能够实现内网穿透的功能,但在该情景下一般表现不如frp。
反向代理
反向代理(reverse proxy):是指以代理服务器来接受公网上的连接请求,然后将请求转发给内部网络上的服务器,并将从服务器上得到的结果返回给公网上请求连接的客户端,此时代理服务器对外就表现为一个反向代理服务器。其实是”代理服务器”代理了”目标服务器”,去和”客户端”进行交互,代理隐藏了服务器,常用于服务器负载均衡、提供安全保障、内网穿透等情景。
这里以ssh应用场景为例,设备A要通过具有公网IP的代理服务器B来访问没有公网IP的设备C
开启代理服务器B的ssh转发功能,找到配置文件
/etc/ssh/sshd_config,加入如下命令GatewayPorts yes这里的配置参数在man文档ssh_config(5)中介绍为:“Specifies whether remote hosts are allowed to connect to local forwarded ports. ”
然后重启ssh
service ssh restart在代理服务器B中开放用于A访问的端口,流程参考上一节,这里假定为6000
在设备C中运行以下指令开启反向代理:
ssh -CNfR b_port:127.0.0.1:c_port b_user@b_ip参数
C表示压缩数据,在快速网络下建议不用参数
N表示不执行远程指令,端口转发时很有用参数
f表示反向代理指令在设备C的后台执行参数
R表示反向代理,要求代理服务器B的对应端口收到的数据转发到设备C来b_port填写2中代理服务器B设置的remote_port,假定为6000c_port表示设备C的local_port,ssh服务默认为22b_user表示代理服务器B的用户名,一般用rootb_ip即代理服务器B的公网IP127.0.0.1表示设备C 的本地IP
开启后,反向代理进程就会转入设备C的后台执行,代理服务器B也会完成转发工作,从而完成内网穿透,ssh连接方法和上一节相同
正向代理
正向代理(forward proxy):是一个位于客户端和目标服务器之间的服务器(代理服务器),为了从目标服务器取得内容,客户端向代理服务器发送一个请求并指定目标,然后代理服务器向目标服务器转交请求并将获得的内容返回给客户端。实际上是”代理服务器”代理了”客户端”,去和”目标服务器”进行交互,代理隐藏了客户端,并常用于访问国外学习网站、提高客户端访问速度等情景。
和反向代理的相同之处在于代理服务器的设置;不同之处在于,参数R变为L,一般需要知道内网设备C的IP,而且由客户端执行指令,因此往往不适用于内网穿透情景。
参考上文的简写,常见指令如下:
ssh -CNfL a_port:c_ip:c_port b_user@b_ip
设备A通过该指令,可以通过访问自己的特定端口,借助代理服务器B,来访问IP已知的设备C上的特定端口提供的服务
ssh -CNfL a_port:b_ip:b_port b_user@b_ip
设备A通过该指令,可以通过访问自己的特定端口,来访问设备B的一个不对外提供服务的端口。特别的,第一处b_ip:b_port是相对于后面的b_ip而言的,因此可以写作127.0.0.1
其他应用
泰拉瑞亚联机
背景:泰拉瑞亚是款2D开放世界创造游戏,并可通过C/S架构进行多人游戏,而多人服务器由玩家的电脑搭建,在大陆境内通过steam好友方式加入服务器网络并不理想,因此考虑采用指定IP方式加入,此时就需要内网穿透来把自己设备的泰拉瑞亚服务发布到公网上
方法:
- 使用frp方式内网穿透时,只需要将上文的local_port指定为泰拉瑞亚的默认多人服务器端口(7777),然后让玩家输入server_addr和remote_port即可
- 使用ssh方式时,据说速度慢而且运营商网络对ssh有管控,容易断线,因此不推荐