自搭Ngrok实现树莓派内网穿透


作者:lingyun 来源:凌云物网智科实验室 时间:2017-08-09

安装go环境

根据自己主机平台下载对应的go安装包。 golang官网 国内镜像

#wget https://golangtc.com/static/go/1.8.3/go1.8.3.linux-amd64.tar.gz
wget https://storage.googleapis.com/golang/go1.8.3.linux-amd64.tar.gz
tar zxvf go1.8.3.linux-amd64.tar.gz
sudo mv go /usr/local/

配置go环境变量

cat > /etc/profile.d/go.sh << EOF
#!/bin/bash
export GOROOT=/usr/local/go
export GOBIN=\$GOROOT/bin
export PATH=\$PATH:\$GOBIN
#(option) export GOPATH=\$HOME/go
EOF
# 生效
source /etc/profile
# 查看版本
go version

添加域名解析

需要设置ngrok服务的域名和子域名都要添加解析,例如设置后面的tun.sfantree.com,那么tun*.tun的解析均需要添加A记录

838.png

配置

下载ngrok源代码

#不包含依赖包
#git clone https://github.com/inconshreveable/ngrok.git ngrok
#包含依赖包
wget https://coding.net/u/sfantree/p/self_use_OSS/git/raw/master/source/ngrok.tar.gz
tar zxvf ngrok.tar.gz 
cd ngrok

这里说明一下自定义密钥的原因,文档中说明ngrok only makes TLS-encrypted connections,客户端的合法连接依靠证书体系来确定,可以认为服务端和客户端的二进制文件是一一对应的,不过服务端在运行时可以指定证书(server.crt)和私钥(server.key),如果不指定将会使用编译时的证书和私钥(位于assets/server),而rootCA.pem(根证书)编译进客户端

mkdir ssl
export NGROK_DOMAIN="tun.sfantree.com"
openssl genrsa -out ssl/base.key 2048
openssl req -new -x509 -nodes -key ssl/base.key -days 10000 -subj "/CN=$NGROK_DOMAIN" -out ssl/rootCA.pem
openssl genrsa -out ssl/server.key 2048
openssl req -new -key ssl/server.key -subj "/CN=$NGROK_DOMAIN" -out ssl/server.csr
openssl x509 -req -in ssl/server.csr -CA ssl/rootCA.pem -CAkey ssl/base.key -CAcreateserial -days 10000 -out ssl/server.crt

/bin/cp ssl/rootCA.pem assets/client/tls/ngrokroot.crt 
/bin/cp ssl/server.crt assets/server/tls/snakeoil.crt 
/bin/cp ssl/server.key assets/server/tls/snakeoil.key

类比HTTPS证书

这和HTTPS证书原理是一样的,无非就是自己充当一个合法的证书颁发机构,base.key就是CA公司的老本,涉及商业机密的密钥是不会向外界公开的,rootCA.pem是CA公司利用刚才的base.key生成的根证书

CA公司与操作系统和浏览器之间早有一场愉快的PY交易,让根证书预装在用户的设备上,美其名曰合法的根证书,没预装的根证书统统都是非法的,因此如果你自签根证书默认情况是被chrome标记为不安全的,当然如果PY交易不愉快,例如沃森,StartSSL还有未来的赛门铁克,都会被浏览器踢出合法的根证书列表。

由于自签发证书对用户访问不友好,最后你会和CA公司发生PY交易,CA机构验证NGROK_DOMAIN的所有者之后,会依据base.key给你生成server.csrserver.crt,由于CA公司之前已经买通了浏览器,因此你的网站证书在浏览器检验下是合法的

编译

直接make release-server可能会报错

$ make release-server GOOS=linux GOARCH=386

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复制一份。

$ make release-server GOOS=linux GOARCH=386

bin/go-bindata -nomemcopy -pkg=assets -tags=release \
        -debug=false \
        -o=src/ngrok/client/assets/assets_release.go \
        assets/client/...
bin/go-bindata -nomemcopy -pkg=assets -tags=release \
        -debug=false \
        -o=src/ngrok/server/assets/assets_release.go \
        assets/server/...
go get -tags 'release' -d -v ngrok/...
go install -tags 'release' ngrok/main/ngrokd
go install: cannot install cross-compiled binaries when GOBIN is set
make: *** [server] Error 1

无法交叉编译,需要去掉$GOBIN的变量声明,解决方法如下

export GOPATH=`pwd`
mkdir bin
cp $GOBIN/go-bindata bin
unset GOBIN

编译服务端ngrokd

go支持交叉编译的平台非常多,详见 GO中文文档

#64位linux server
make release-server GOOS=linux GOARCH=amd64
#32位linux server
make release-server GOOS=linux GOARCH=386

编译客户端

#linux
make release-client GOOS=linux GOARCH=amd64
#OS X
make release-client GOOS=darwin GOARCH=amd64
#win
make release-client GOOS=windows GOARCH=386
#armv6l
make release-client GOOS=linux GOARCH=arm

编译的可执行文件都在bin/$GOOS_$GOARCH,根据相应的平台下载对应的客户端

这里我们只需要x64的linux server和树莓派对应的arm

配置服务

Linux x64的服务端位于bin/ngrokd,因为HTTP服务也是建立在TCP上,所以我一律设置为TCP转发,方便统一管理,另外映射HTTP/HTTPS服务也不要直接占用80/443端口,建议前置一个nginx监听80/443反向代理到ngrok实现端口复用。

#调试到标准输出
#bin/ngrokd -domain "tun.sfantree.com"  -httpAddr ""  -httpsAddr ""  -tunnelAddr ":4443"
#不输出日志 后台运行
bin/ngrokd -tlsKey=ssl/server.key -tlsCrt=ssl/server.crt -domain "tun.sfantree.com" -log "/dev/null" -httpAddr"" -httpsAddr"" -tunnelAddr "4443"&

配置客户端

bin/linux_arm/ngrok下载到树莓派,在树莓派创建配置文件

cat > ngrok.conf <<EOF
#必须是 域名:隧道端口 的格式
server_addr: "tun.sfantree.com:4443"
#自行编译无需验证ngrok官网证书
trust_host_root_certs: false
tunnels:
    ssh:
        remote_port: 10086
        proto:
            tcp: 22
    http:
        remote_port: 10087
        proto:
            tcp: 80
EOF

启动客户端,start后面参数是需要启动的服务

pi@raspberrypi $./ngrok -config=ngrok.conf start ssh http

ngrok                                                                                         (Ctrl+C to quit)

Tunnel Status                 online                                                                          
Version                       1.7/1.7                                                                         
Forwarding                    tcp://tun.sfantree.com:10087 -> 127.0.0.1:22                                    
Forwarding                    tcp://tun.sfantree.com:10088 -> 127.0.0.1:80                                    
Web Interface                 127.0.0.1:4040                                                                  
# Conn                        0                                                                               
Avg Conn Time                 0.00ms
在线咨询
微信号
13554373241
联系方式
135-5437-3241
邮箱
guowenxue@aliyun.com
返回顶部