为什么要做这件事?
- 家里有一个闲置的树莓派3B+,想把它利用起来,做一个私有云网盘
- 在做微信开发/对接各种支付产品时,使用过免费的内网穿透工具,稳定性欠佳
- 希望能通过SSH远程控制家里的树莓派,执行一些任务
-
于是就想自己解决这个问题.但是树莓派在家里无法被外网直接访问到,要解决这个问题,就要用到内网穿透
也叫NAT穿透
.
工具选择
内网穿透工具有很多,国内最有名的应该就是花生壳了吧,下面我罗列一些比较有名的工具.我并没有一一试用,排名不分先后
- 花生壳
- Ngrok
- frp
- nsloop
- 网云穿
- 一些内网穿透的硬件
- …
我的选择
我就是想把闲置的树莓派利用起来,所以需要买硬件的排除,而且硬件主要是为了服务小白用户,不符合我的预期.
一些连带服务器都免费提供的工具,有各种限制.限制连接的/限制流量的/限制端口的/限制速度的,而且免费版稳定性不太有保障,所以也排除.
我个人有一个阿里云的服务器,可以支撑我独立搭建服务端,因此我最终确定了两个候选产品,也是目前最主流的两个开源内网穿透应用,Ngrok和frp.
https://github.com/inconshreveable/ngrok
https://github.com/fatedier/frp
互联网上好多内网穿透的工具都是基于Ngrok的,可见Ngrok之优秀,github上的star也相当多,有18.1K(2020-02-29),frp在github上声明目前还处于开发阶段,不建议使用在生产环境,但是它的star竟然达到了33.3K(2020-02-29)!
单看官方文档,Ngrok比较容易上手,frp的配置有一箩筐.最终有两点让我选择了frp,一个是frp有官方的中文文档(这可能也是star超级多的原因),还有它提供了一个点对点内网穿透的功能,可以传输大量数据而不经过服务器,虽然这个功能还处于初级开发阶段,但是我准备玩一玩,正好符合我搭建私有云的需求.
部署
自从学会了docker,我就在搭建各种环境的时候就有了洁癖:服务器上的各种软件,必须使用docker来搭建.
去hub.docker.com上搜了一下,有现成的镜像,我选择了snowdreamtech/frps
和snowdreamtech/frpc
.
https://hub.docker.com/r/snowdreamtech/frps
https://hub.docker.com/r/snowdreamtech/frpc
下面两个也很不错,但是由于客户端不支持arm架构,导致客户端在树莓派上无法使用,虽然服务端还是可以用的,但是为了保持统一,我也放弃了服务端.
https://hub.docker.com/r/cloverzrg/frps-docker
https://hub.docker.com/r/cloverzrg/frpc-docker
启动服务端
首先需要配置阿里云的ECS安全组
找到准备搭建frp服务端的ECS->管理->本示例安全组->配置规则->添加安全组规则->将计划使用的端口加入到规则中
如果不确定具体端口,或后期还要增加更多业务,可以打开一个范围内的端口,如10000/11000
配置文件frps.ini
[common] bind_port = 17000 token = myToken vhost_http_port = 10080 vhost_https_port = 10443 dashboard_port = 17500 dashboard_user = admin dashboard_pwd = admin tcp_mux = true max_pool_count = 10启动脚本
docker-compose.yml
version: '3' services: frps: image: snowdreamtech/frps ports: - "17000:17000" - "27500:17500" - "10022:10022" #用于ssh连接 - "10080:10080" #用于开放给外网访问 # 更多端口根据实际需求增加 volumes: - ./frps.ini:/etc/frp/frps.ini
container_name: frps启动服务端
docker-compose -f docker-compose.yml up -d注:加上-d参数直接后台运行,无如下log(可通过
docker logs frps
查看),下面是我去掉-d参数得到的输出,建议首次启动不要加-d参数,观察一下log,确认启动是否成功.root@docker:~/frps-conf# docker-compose -f docker-compose.yml up Starting frps ... done Attaching to frps frps | 2020/02/29 18:57:13 [I] [service.go:152] frps tcp listen on 0.0.0.0:17000 frps | 2020/02/29 18:57:13 [I] [service.go:194] http service listen on 0.0.0.0:10080 frps | 2020/02/29 18:57:13 [I] [service.go:215] https service listen on 0.0.0.0:10443 frps | 2020/02/29 18:57:13 [I] [service.go:251] Dashboard listen on 0.0.0.0:17500 frps | 2020/02/29 18:57:13 [I] [root.go:205] start frps success启动客户端
编辑配置文件
/usr/local/frp/frpc.ini
[common] server_addr = x.x.x.x #服务器ip server_port = 17000 token = myToken [ssh] type = tcp local_ip = 127.0.0.1 local_port = 22 remote_port = 10022 use_encryption = true use_compression = true [pi.mydomain.com] type = http local_port = 80 custom_domains = pi.mydomain.com我配置了一个
ssh
和一个web
通道.编辑docker-compose.yml
version: '3' services: frpc: image: cloverzrg/frpc-docker volumes: - ./frpc.ini:/conf/frpc.ini container_name: frpc network_mode: host #很重要,原因见下面的说明
启动
docker-compose -f docker-compose.yml up -d
首次建议不加-d,先查看一下输出日志
network_mode: host #很重要,为什么这么设置?
容器中的network driver默认为bridge,如果保持默认,使用web服务需要导出端口号,使用sshd服务需要将local_ip设置为宿主机的内网IP,如果把网络模式设置为host,就和主机保持在同一网络
告一段落
-
访问域名
http://pi.mydomain.com:10080
,可以正常访问网页(前提是客户端所在机器启动http服务器,并监听80端口) -
执行命令
ssh -p 10022 [email protected]
可以在任意PC登录树莓派 -
访问IP
http:x.x.x.x:17500
,可以看到仪表盘,里面显示了各个客户端的连接情况
至此,一个简单的frp服务端和frp客户端已经搭建成功.