ngrok1.0是开源的,ngrok官网目前是2.0版本,https://ngrok.com/ 二者功能和命令有一些区别,用的时候别搞混了,这里讲的是ngrok1.7版本
操作如下:
首先安装必要工具:golang mercurial git .
获取ngrok源码:
git clone https://github.com/inconshreveable/ngrok.git cd ngrok
生成并替换源码里默认的证书,注意域名修改为你自己的。(之后编译出来的服务端客户端会基于这个证书来加密通讯,保证了安全性)
NGROK_DOMAIN="rasp.pw" openssl genrsa -out base.key 2048 openssl req -new -x509 -nodes -key base.key -days 10000 -subj "/CN=$NGROK_DOMAIN" -out base.pem openssl genrsa -out server.key 2048 openssl req -new -key server.key -subj "/CN=$NGROK_DOMAIN" -out server.csr openssl x509 -req -in server.csr -CA base.pem -CAkey base.key -CAcreateserial -days 10000 -out server.crt cp base.pem assets/client/tls/ngrokroot.crt
get error:
GOOS="" GOARCH="" go get github.com/jteeuwen/go-bindata/go-bindata
bin/go-bindata -nomemcopy -pkg=assets -tags=release \
-debug=false \
-o=src/ngrok/client/assets/assets_release.go \
assets/client/…
make: bin/go-bindata: Command not found
make: *** [client-assets] Error 127
go-bindata被安装到了$GOBIN下了,go编译器找不到了。修正方法是将$GOBIN/go-bindata拷贝到当前ngrok/bin下。
开始编译
sudo make release-server release-client
如果go版本是1.4,可能会遇到如下错误(日期:2016-05-30):
go install -tags 'release' ngrok/main/ngrok # github.com/gorilla/websocket src/github.com/gorilla/websocket/conn.go:647: c.br.Discard undefined (type *bufio.Reader has no field or method Discard) make: *** [client] Error 2
如果出现些错误,请更新go到1.5.3版本,(https://github.com/gorilla/websocket/issues/137)
如果一切正常,ngrok/bin 目录下应该有 ngrok、ngrokd 两个可执行文件
不同的客户端,需要指定环境变量再编译一次
raspberry pi
sudo GOOS=linux GOARCH=arm make release-client
ngrok/bin目录下会多出来一个linux_arm目录,这里的ngrok就可以在raspberry上运行了
windows x64
sudo GOOS=windows GOARCH=amd64 make release-server release-client
这样在 ngrok/bin 目录下会多出来一个 windows_amd64 目录,这里的ngrok.exe就可以在64位的windows上运行了。
MAC同理
sudo GOOS=darwin GOARCH=amd64 make release-server release-client
服务端:
前面生成的 ngrokd 就是服务端程序了,指定证书、域名和端口启动它(证书就是前面生成的,注意修改域名)
sudo ./bin/ngrokd -tlsKey=server.key -tlsCrt=server.crt -domain="rasp.pw" -httpAddr=":8081" -httpsAddr=":8082"
到这一步,ngrok 服务已经跑起来了,可以通过屏幕上显示的日志查看更多信息。httpAddr、httpsAddr 分别是 ngrok 用来转发 http、https 服务的端口,可以随意指定。ngrokd 还会开一个 4443 端口用来跟客户端通讯(可通过 -tunnelAddr=":xxx" 指定),如果你配置了 iptables 规则,需要放行这三个端口上的 TCP 协议
现在,通过 https://rasp.pw:8081 和 https://rasp.pw:8082 就可以访问到 ngrok 提供的转发服务。为了使用方便,建议把域名泛解析到 VPS 上,这样能方便地使用不同子域转发不同的本地服务。我给 rasp.pw 做了泛解析,随便访问一个子域,如:http://pi.rasp.pw:8081,可以看到这样一行提示:
Tunnel pub.rasp.pw:8081 not found
这说明万事俱备,只差客户端来连了。
客户端:
写一个简单的配置文件,随意命名如 ngrok.cfg:
server_addr: rasp.pw:4443 trust_host_root_certs: false
注意因为客户端自带SSL证书,所以这里是false。
指定子域、要转发的协议和端口,以及配置文件,运行客户端:
./ngrok -subdomain pi -proto=http -config=ngrok.cfg 80
不出意外可以看到这样的界面,这说明已经成功连上远端服务了:
TCP端口转发
强大的功能,可以转发任意端口,例如22(SSH+sftp+scp),可以远程访问树莓派并传输文件。以及其他你需要功能。
ngrok -proto=tcp -config=ngrok.cfg 22
TCP端口转发不支持subdomain,需要手动设置协议参数为tcp。
多端口转发,如果每转发一个端口就要运行一个ngrok程序太麻烦了,还好程序提供了配置文件可以同时转发多个端口,修改之前的ngrok.cfg文件
server_addr: rasp.pw:4443 trust_host_root_certs: false tunnels: http: proto: http: 80 subdomain: pi https: proto: https: 443 subdomain: web ssh: remote_port: 5000 proto: tcp: 22
加粗斜体可以修改。其中remote_port
是你想要请求的远端端口号,如果不指定,每次可能会变。另外英文冒号后面有空格,tunnels中不能使用TAB制表符,只能使用空格。格式可以参考ngrok官方配置文档 以及有关博客。
启动方式为:
./ngrok -config=ngrok.cfg start http https ssh
Raspberry 后台启动方式:
setsid ./ngrok -config=ngrok.cfg -log=log start http https ssh
(update: 2016-07-08)
关于路由R6300v2的内网穿透(梅林6.6.1)
参考:http://koolshare.cn/thread-6007-1-1.html
路由刷的 梅林6.6.1 使用arm版本可以运行,但无法后台,并且时间不长,ngrok挂掉,不知道为什么 ,后来在koolshare网站中找到'小宝'修改的ngrok ,
按上面链接教程配置好服务端, 客户端路径:/jffs/ngrok 运行如下命令
./tunnel -c default.json -p /tmp/tun.pid
其中default.json和原版本ngrok.cfg配置相似,但也不同之处,
虽然可以正常运行,但是运行时间也不长,不知道什么原因被Kill掉,此问题在koolshare论坛中也有反馈,目前解决方法是自己手动添加守护脚本,
和tunnel同一目录添加一个tun.sh(此文件名不能和PRO_NAME重名,否则计算NUM值有误)文件,内容如下
#!/bin/sh LOGTIME=$(date "+%Y-%m-%d %H:%M:%S") PRO_NAME=tunnel NUM=$(ps | grep $PRO_NAME | grep -v grep |wc -l) if [ "${NUM}" -lt "1" ];then echo $LOGTIME $PRO_NAME is stop, restart.... >> /tmp/1.log /jffs/ngrok/tunnel -c /jffs/ngrok/default.json -p /tmp/tun.pid else echo $LOGTIME $PRO_NAME is running! >> /tmp/1.log fi
把此脚本添加到crontab中每3分钟(根据自己需求调整)执行一次, 可以直接crontab -e进行添加
*/3 * * * * /bin/sh /jffs/ngrok/tun.sh
可是路由重启后,crontab命令丢失,需要添加定时控制脚本到文件/jffs/scriipts/services-start,如果没有则自行新建。下一步设置权限755.
#!/bin/sh cru a tunnel "*/3 * * * * /bin/sh /jffs/ngrok/tun.sh"
路由重启后自动添加定时任务, 这样就可以保证在路由上内网穿透了.
问题:
在ngrok目录下执行如下命令,编译ngrokd:
$ make release-server
不过在我的AWS上,出现如下错误:
GOOS="" GOARCH="" go get github.com/jteeuwen/go-bindata/go-bindata
bin/go-bindata -nomemcopy -pkg=assets -tags=release \
-debug=false \
-o=src/ngrok/client/assets/assets_release.go \
assets/client/…
make: bin/go-bindata: Command not found
make: *** [client-assets] Error 127
go-bindata被安装到了$GOBIN下了,go编译器找不到了。修正方法是将$GOBIN/go-bindata拷贝到当前ngrok/bin下。
$ cp /home/ubuntu/.bin/go14/bin/go-bindata ./bin
再次执行make release-server。
如果你的go环境很混乱就重新安装一个是用软连接接起来:
sudo ln -s /usr/local/go/bin/go /usr/bin/go