背景:
本人所处的校内网络与外网网络经由一道防火墙。导致很多校内服务在外网无法访问(教务处信息,知网信息,校内服务器集群等)。传统的回校方法是借用实验室老师的VPN账户回校,但做开发用占时长,在一定程度影响了老师的回校(不能一号两用)。于是打算另寻他路,研究新的回校方法。在咨询过师兄后,师兄给出使用ngrok实现,在各种baidu了解后,恰巧手头上有一台云服务器,一个域名。于是便有了今天的《搭建ngrok服务器实现内网穿透》
实验环境:
-
公网云服务器一台
-
域名一个
-
云服务器操作系统:Ubuntu16.04LTS
实验概要:
-
在域名提供商给出的接口上设置域名解析(可以是泛解析)
-
安装Golang环境
-
生成私钥以配置私人Ngrokd
-
生成ngrok-server ngrok-client
-
写ngrok-client配置文件
-
在需要进行穿透内网的主机上设置开机启动
实验步骤:
-
在域名提供商给的接口设置解析。(本次实验使用的是企鹅云。设置如图。(偷懒,直接添加了一条泛解析))
-
登录云服务器。(本次实验使用的云服务器操作系统是Ubuntu16.04LTS,故直接使用putty登录)
-
配置环境前准备:(安装gcc git)
sudo apt-get update -y sudo apt-get install gcc sudo apt-get install git
-
配置golang环境
sudo apt-get install golang
-
下载ngrok源码
cd /usr/local/src git clone https://github.com/inconshreveable/ngrok.git
-
生成私钥证书
cd ngrok openssl genrsa -out rootCA.key 2048 openssl req -x509 -new -nodes -key rootCA.key -subj "/CN=你的域名" -days 5000 -out rootCA.pem openssl genrsa -out device.key 2048 openssl req -new -key device.key -subj "/CN=你的域名" -out device.csr openssl x509 -req -in device.csr -CA rootCA.pem -CAkey rootCA.key -CAcreateserial -out device.crt -days 5000
-
将生成的证书替换原ngrok的证书
yes|cp rootCA.pem assets/client/tls/ngrokroot.crt yes|cp device.crt assets/server/tls/snakeoil.crt yes|cp device.key assets/server/tls/snakeoil.key
-
编译生成ngrokd(服务端)
# 交叉编译,客户端同。 # GOOS:linux windows darwin (Mac os) # GOARCH: 386 amd64 arm(树莓派) sudo GOOS=linux GOARCH=386 make release-server
-
在云服务器上开启Ngrokd服务端进行监听:
-
打开您刚刚配置的域名,看看是否出现Tunnel not found的字样。出现则成功完成服务端配置
-
编译生成ngrok客户端
./bin/ngrokd -tlsKey="assets/server/tls/snakeoil.key" -tlsCrt="assets/server/tls/snakeoil.crt" -domain="你的域名" -httpAddr=":80" -httpsAddr=":443" -tunnelAddr=":4443"
# httpAddr httpsAddr分别用来转发http https端口,默认为80 443
# tunnelAddr 是用来监听隧道中客户端请求的端口
# 此处事例的是为树莓派Raspbian操作系统生成的客户端,不同的客户端编译方法不同。参照生成服务端的交叉编译即可。 # 编译成功后,ngrok程序生成在./bin/文件夹中 sudo GOOS=linux GOARCH=arm make release-client
-
配置ngrok客户端文件(ngrok.cfg):
server_addr: "你的域名:4443" trust_host_root_certs: false tunnels: ssh: remote_port: 22000 #远程的端口(占用服务器的端口) proto: tcp: 22 #可以设置内网其他主机端口转发。如"192.168.1.2:80" http: subdomain: mysubdomain #若不设置,会随机分配域名 proto: http: 80 vnc: remote_port: 59000 proto: tcp: 5900 #使用时把#后内容删除
-
配置完成后,使用命令开启反向代理隧道即可
cd NGROK目录(自行改动) ./ngrok -config=ngrok.cfg start http vnc ssh #linux下 ngrok.exe -config=ngrok.cfg start http vnc ssh #Windows下
-
出现如下界面即为成功
-
设置脚本开机自启动(略)
实验中遇到的问题及解决思路(Q&A)
-
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
-
package code.google.com/p/log4go: Get https://code.google.com/p/log4go/source/checkout?repo=: dial tcp 216.58.197.110:443: i/o timeout
-
GOOS="" GOARCH="" go get github.com/jteeuwen/go-bindata/go-bindata # github.com/jteeuwen/go-bindata src/github.com/jteeuwen/go-bindata/toc.go:47: function ends without a return statement make: *** [bin/go-bindata] Error 2
解决方法:前往go安装目录的bin目录下找到go-bindata,将他移动到ngrok/bin下 (没有bin,可新建一个)
解决方法:在 ngrok/src/ngrok/log 目录下找到 logger.go 文件,修改其中第4或5行的:
log "code.google.com/p/log4go”为
log "github.com/keepeye/log4go"