在网上找了好多教程,大多是在go语言环境配置上面出现问题,导致后面编译不了,弄了好久,找到了一个感觉不错的解决办法,借此记录

先按照正常的步骤来进行安装ngrok

安装 ngrok server

# 拉取 ngrok 
git clone https://github.com/inconshreveable/ngrok.git ngrok
cd ngrok

生成自签名证书
使用 ngrok.com 官方服务时,我使用的是官方的 SSL 证书。自建 ngrokd 服务,我们需要生成自己的证书,并提供携带该证书的 ngrok 客户端。生成并替换源码里默认的证书,注意域名修改为你自己的。(之后编译出来的服务端客户端会基于这个证书来加密通讯,保证了安全性)  证书生成过程需要一个NGROK_DOMAIN。

以 ngrok 官方随机生成的地址 test.ngrok.com 为例,其 NGROK_DOMAIN 就是 ” ngrok.com ”,如果你要提供服务的地址为 ” example.ngrok.xxx.top ”,那NGROK_BASE_DOMAIN就应该是 ” ngrok.xxx.top ”。

NGROK_DOMAIN="ngrok.zmkj6.top"

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

Ngrok 通过 bindata 将 ngrok 源码目录下的 assets 目录(资源文件)打包到可执行文件( ngrokd 和 ngrok )中去
assets/client/tls 和 assets/server/tls 下分别存放着用于 ngrok 和 ngrokd 的默认证书文件
我们需要将它们替换成我们自己生成的

cp base.pem assets/client/tls/ngrokroot.crt
cp server.crt assets/server/tls/snakeoil.crt
cp server.key assets/server/tls/snakeoil.key

编译 server ( 服务端 ) 和 client ( 客户端 )

GO111MODULE=off GOOS=windows GOARCH=386 make release-server
# win服务端

GO111MODULE=off GOOS=windows GOARCH=386 make release-client
# win客户端

GO111MODULE=off GOOS=linux GOARCH=386 make release-server
# linux服务端

GO111MODULE=off GOOS=linux GOARCH=386 make release-client
# linux客户端

在编译客户端的时候需要指明对应的操作系统和构架:

  • Linux 平台 32 位系统:GOOS=linux GOARCH=386
  • Linux 平台 64 位系统:GOOS=linux GOARCH=amd64
  • Windows 平台 32 位系统:GOOS=windows GOARCH=386
  • Windows 平台 64 位系统:GOOS=windows GOARCH=amd64
  • MAC 平台 32 位系统:GOOS=darwin GOARCH=386
  • MAC 平台 64 位系统:GOOS=darwin GOARCH=amd64
  • ARM 平台:GOOS=linux GOARCH=arm

在编译时可能会因为go语言版本较低会产生像下面这样的错误

package context: unrecognized import path "context" (import path does not begin with hostname)
package net/http/httptrace: unrecognized import path "net/http/httptrace" (import path does not begin with hostname)
Makefile:8: recipe for target 'deps' failed
make: *** [deps] Error 1

我就卡在这力很久,因为我使用的 下面这个命令安装的 Go

sudo apt-get install golang
# 这个命令默认安装的是1.6版本的,版本较低

下面我发现这么做是挺好的解决方法,先卸载这个使用下面的命令

卸载之前先

go env
# 查看go安装的位置,一会要将这个 go 安装文件删除
# 找到对应位置,rm 删除对应文件

sudo apt-get remobve go-1.6
# 卸载之前的版本

sudo apt-get autoremove
# 若还有其他版本,都一起卸载

现在要从官网下载最新版本, https://golang.org/dl/  我下载的是linux版本,然后按照官网的安装方式安装,并配置好环境

tar -C /usr/local -xzf go1.12.6.linux-amd64.tar.gz
# 先进入下载文件的目录下,解压文件到 /usr/local

export PATH=$PATH:/usr/local/go/bin
# 配置环境路径

现在再查看 go 版本 go version 已经是最新版了,可以继续编译了,编译完成后会在 bin 目录产生一个服务端文件和一个客户端文件,编译后生成两个文件分别为服务端(ngrokd)和客户端(ngrok)

服务端运行命令

./bin/ngrokd -tlsKey=server.key -tlsCrt=server.crt -domain="ngrok.top" -httpAddr=":801" -httpsAddr=":802"

# 其中 httpAddr=":1080" 是内网的 http 穿透出来,外网对应的端口   
# 同样 httpsAddr=":10443" 是内网的 https 穿透出来,外网对应的端口
# 二者都可以自定义

将 bin 下的 ngrok 文件下载到客户端上

参数 -domain 表示服务器域名,请改成你自己的域名;-httpAddr 表示默认监听的HTTP端口,-httpsAddr表示默认监听的HTTPS端口,因为我用不到所以都设置成空字符串”“来关闭监听,如果需要打开的话记得格式是 :12345(冒号+端口号)这样的;-tunnelAddr 表示服务器监听客户端连接的隧道端口号,格式和前面一样;-log 表示日志文件位置;还有个 -log-level 用来控制日志记录的事件级别,选项有DEBUG、INFO、WARNING、ERROR。

如果编译的是不带release的版本,还可以通过-tlsCrt-tlsKey选项来指定证书文件的位置。

出现类似以下内容,则说明我们的服务器端ngrokd正常运行了:

[16:41:56 CST 2017/04/20] [INFO] (ngrok/log.(*PrefixLogger).Info:83) [registry] [tun] No affinity cache specified
[16:41:56 CST 2017/04/20] [INFO] (ngrok/log.(*PrefixLogger).Info:83) [metrics] Reporting every 30 seconds
[16:41:57 CST 2017/04/20] [INFO] (ngrok/log.Info:112) Listening for public http connections on [::]:80
[16:41:57 CST 2017/04/20] [INFO] (ngrok/log.Info:112) Listening for public https connections on [::]:443
[16:41:57 CST 2017/04/20] [INFO] (ngrok/log.Info:112) Listening for control and proxy connections on [::]:4443
[16:41:57 CST 2017/04/20] [INFO] (ngrok/log.(*PrefixLogger).Info:83) [tun:627acc92] New connection from 42.53.196.242:9386
[16:41:57 CST 2017/04/20] [DEBG] (ngrok/log.(*PrefixLogger).Debug:79) [tun:627acc92] Waiting to read message
[16:41:57 CST 2017/04/20] [DEBG] (ngrok/log.(*PrefixLogger).Debug:79) [tun:627acc92] Reading message with length: 159

客户端绑定多种方式

建立配置文件,在ngrok同路径下建立配置文件 ngrok.conf :

server_addr: "ngrok.zmkj6.top:4443"
trust_host_root_certs: false
tunnels:
  ssh:
    remote_port: 6666
    proto:
      tcp: 22

server_addr 端口默认4443,可通过 ngrokd 服务端启动修改端口。在tunnels里配置隧道信息,具体可见「翻译」ngrok 1.X 配置文档。注意httphttps隧道可设置subdomainauth,而tcp里只能设置remote_port

还可以 转发其他IP的端口 ,方法就是在 proto 下的tcp(或http、https)后的端口号写成IP地址:端口号的格式(中间是英文冒号)。如:tcp: 192.168.11.1:80

如果想一次性转发多个端口或者想指定远程的对应端口,需要完善 ngrok.conf

server_addr: "ngrok.zmkj6.top:4443"
trust_host_root_certs: false
tunnels:
 ssh:
  subdomain: ssh
  remote_port: 6666
  proto:
   tcp: 22
 ss:
  subdomain: ss
  emote_port: 5555
  proto:
   tcp: 5555
 ftp:
  subdomain: ftp
  remote_port: 1021
  proto:
   tcp: 21
 http:
  subdomain: www
  proto:
   http: 80
   https: 443

// subdomin 后面对应的是二级域名

现在运行客户端:

./ngrok -config=ngrok.conf start ssh

# 或者
# ./ngrok -subdomain test -proto=tcp -config=ngrok.conf 3000

不仅可以穿透本机的ip即127.0.0.1,还可以穿透局域网下的其他ip例子

server_addr: ngrok.zmkj6.top:4443
trust_host_root_certs: false
tunnels:
 ssh:
  subdomain: ssh
  remote_port: 1022
  proto:
   tcp: 192.168.123.1:22  //不只填写端口号,还跟着要穿透的那个ip

连接成功后,显示连接成功,就是没流量进出,很可能是因为 客户机端口没开

可以安装个screen来后台守护进程

sudo apt-get install screen
# 安装

screen -S name
# 创建一个名字是name的后台

screen -r name
#打开后台

下一篇文章我们一起看看神奇的 screen 吧!