背景:
本人所处的校内网络与外网网络经由一道防火墙。导致很多校内服务在外网无法访问(教务处信息,知网信息,校内服务器集群等)。传统的回校方法是借用实验室老师的VPN账户回校,但做开发用占时长,在一定程度影响了老师的回校(不能一号两用)。于是打算另寻他路,研究新的回校方法。在咨询过师兄后,师兄给出使用ngrok实现,在各种baidu了解后,恰巧手头上有一台云服务器,一个域名。于是便有了今天的《搭建ngrok服务器实现内网穿透》
实验环境:
-
公网云服务器一台
-
域名一个
-
云服务器操作系统:Ubuntu16.04LTS
实验概要:
-
在域名提供商给出的接口上设置域名解析(可以是泛解析)
-
安装Golang环境
-
生成私钥以配置私人Ngrokd
-
生成ngrok-server ngrok-client
-
写ngrok-client配置文件
-
在需要进行穿透内网的主机上设置开机启动
实验步骤:
-
在域名提供商给的接口设置解析。(本次实验使用的是企鹅云。设置如图。(偷懒,直接添加了一条泛解析))
-
登录云服务器。(本次实验使用的云服务器操作系统是Ubuntu16.04LTS,故直接使用putty登录)
-
配置环境前准备:(安装gcc git)
1 2 3 | sudo apt-get update -y sudo apt-get install gcc sudo apt-get install git |
-
配置golang环境
1 | sudo apt-get install golang |
-
下载ngrok源码
1 2 | cd /usr/local/src git clone https: //github .com /inconshreveable/ngrok .git |
-
生成私钥证书
1 2 3 4 5 6 | 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的证书
1 2 3 | 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(服务端)
1 2 3 4 | # 交叉编译,客户端同。 # 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 是用来监听隧道中客户端请求的端口
1 2 3 | # 此处事例的是为树莓派Raspbian操作系统生成的客户端,不同的客户端编译方法不同。参照生成服务端的交叉编译即可。 # 编译成功后,ngrok程序生成在./bin/文件夹中 sudo GOOS=linux GOARCH=arm make release-client |
-
配置ngrok客户端文件(ngrok.cfg):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | 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 #使用时把#后内容删除 |
-
配置完成后,使用命令开启反向代理隧道即可
1 2 3 | cd NGROK目录(自行改动) . /ngrok -config=ngrok.cfg start http vnc ssh #linux下 ngrok.exe -config=ngrok.cfg start http vnc ssh #Windows下 |
-
出现如下界面即为成功
-
设置脚本开机自启动(略)
实验中遇到的问题及解决思路(Q&A)
-
1234567
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
-
1
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
-
1234
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"