大多数的时间, 我们都不是在家里. 但希望家里的挂在树莓派上的移动硬盘能随时随地的访问到. 办法有很多, 比如动态域名dDNS(著名如某生壳), ssh 反向隧道, ngrok 内网访问等等(等等是因为只知道这些方法了, 还知道其他办法的请留言告诉我).
动态域名的方法有许多弊端, 例如ISP禁止 80 端口访问, 需修改路由器端口映射, 在很多情况下不具备条件, 没有通用性. ssh 反向隧道最简单, 一行命令就行, 但不稳定, ssh 长时间空闲的会自动断开. 所以我选了通用性和稳定性都比较好 ngrok .
使用 ngrok 公共服务器
如果是对速度要求不高, 或者临时用一用, 这种方式最简单快捷, 只要几步就能完成
1 在官网上注册个账号, 打开指引网页 https://dashboard.ngrok.com/get-started
2 下载 ngrok
树莓派下载 Linux(ARM) 的版本
3 执行一行命令, 添加密钥到 ngrok.yml
$ ./ngrok authtoken <密钥>
4 开启端口连接
$ ./ngrok http 80
然后控制台打印出来可以在外网访问的域名, 类似下面
更多使用方法 https://ngrok.com/docs
如果使用国外网友困难, 有国内替代的网站 http://www.ngrok.cc/, 使用方法相似, 就不再细说了.
自建 ngrok 服务器
使用公共服务器虽然便捷, 但毕竟免费的东西总是限制太多, 传输大文件就不用想了. 于是我们要搭建自己的 ngrok 服务器, 前提是有自己服务器和域名.
ngrok 1.0 版本是开源的, 2.0 就不开源了. 1.0 使用 http 通道有内存泄漏的问题, 内存猛涨到把机器卡死为止. 不过用 tcp 通道可避免这个问题. 目前1.0 够用, 内存稳定在 10m 上下.
项目源码地址 https://github.com/tutumcloud/ngrok/blob/master/docs/DEVELOPMENT.md
准备工作
有一个自己可控的域名, 后面需要添加子域名解析,
申请域名stl证书
安装 go 编译器, 项目是用 go 语言编写的
sudo apt-get update
sudo apt-get install golang
编译
下载源码
git clone https://github.com/tutumcloud/ngrok.git
开始编译
# 编译服务端
$ GOOS=linux GOARCH=amd64 make release-server
# 编译客户端, 然后拷贝到客户机使用
$ GOOS=linux GOARCH=arm make release-client
完成后在 bin 目录下生成 ngrokd 和 ngrok, 分别是服务端程序和客户端程序
假如你打算用自签发的 ssl 证书运行服务(不建议), 需要在编译时假如参数, 参考 http://zpblog.cn/linux/run-ngrok-on-your-own-server.html
服务配置
先用 ngrokd --help 看下有哪些参数. 为了方便每次启动不用写那么多参数, 新建文件 bin/startup.sh
#!/bin/bash
PWD=$(dirname $(dirname $(realpath $0)))
$PWD/bin/ngrokd -domain="n.1ai.ltd" -httpAddr=:5000 -httpsAddr=:5443 -tunnelAddr=:4443 -tlsKey="cert/1959640_n.1ai.ltd.key" -tlsCrt="cert/1959640_n.1ai.ltd.pem" -log=log/ngrok.log
启动服务
cd NGROK_HOME
chmod +x bin/startup.sh # 添加可执行权限
setsid bin/startup.sh # setsid 把进程放在后台运行
分配给 ngrok 的是5000 和5443 端口, 为什么不用80和443呢? 因为我们服务器上还有其他的服务 - -!.
客户机配置
把 bin目录下的 ngrok 拷贝到树莓派上, 新建配置文件 ngrok.yml
server_addr: n.1ai.ltd:4443
trust_host_root_certs: true
tunnels:
photo:
remote_port: 5000
proto:
tcp: 127.0.0.1:5000
log: stdout
www:
remote_port: 80
proto:
tcp: 127.0.0.1:80
log: stdout
原理是在服务器上创建 5000, 80 端口与本地连接, 不写 remote_port 将随机分配一个端口
启动客户端
setsid ./ngrok -config=ngrok.yml start photo www
再差一步就能外网访问了. 解析域名到服务器. 例如上面的例子域名是 n.1ai.ltd, 外网访问地址是 n.1ai.ltd:5000 和 n.1ai.ltd
复杂了不少是吧? 是的, 但好处也是多多的, 速度提升了, 能绑固定的域名了, 还能映射多个服务.搭配 nginx 反向代理实现统一用 80 端口访问, 从此摆脱端口号的小尾巴. 太长了不写了, 感兴趣的到公众号留言吧.
下一篇将探讨远程唤醒.
如果您喜欢这篇文章, 请关注我的公众号吧, 和我一起学习每天进步一点点