ngrok使用/踩坑分析-http代理

研究了下 ngrok 的使用,坑还是挺多,随后再看看源码吧,看是否能做些修改和定制

疑问1: 是否能支持 ecc 证书,目前用的脚本生成的自签RSA证书

经过测试ngrok客户端+服务器支持 ecc证书。

疑问2: 性能如何?

需要分析源码,完善优化

 

好了,开始吧。

1.   当前git上开源的代码版本,号称是1.0x版本,其实是2.1.7

const (

    Proto = "2"

    Major = "1"

    Minor = "7"

)

下载ngrok源码(ngrok代理服务的server/client都在同一份代码中),git上的最新版本是2.1.7,但是ngrok官方最新代码已经闭源,旧代码 凑合还能用。server和client,自己编译,证书自己搞定吧

git clone https://github.com/inconshreveable/ngrok.git

2.  解压ngrok源码,mv ./ngork  到  /usr/local/ngrok 下

3.  cd  /usr/local/ngrok

我的服务器环境:

[root@localhost ngrok]# cat /etc/redhat-release 
CentOS Linux release 7.5.1804 (Core) 

[root@localhost ngrok]# go version 
go version go1.9.4 linux/amd64


我的客户端运行环境:   windows7 X64 SP1

4.  创建服务器自签名证书

在 /usr/local/ngrok 目录下 
创建 work.sh 脚本,用来创建服务器自签名证书,内容如下:

#!/bin/bash

#生成并替换源码里默认的证书,注意域名要修改为你自己的,这里是一个虚拟的测试域名
NGROK_DOMAIN="dev.mydomain.com"

#测试一下有没有设置成功
echo $NGROK_DOMAIN #输出ngrok.xxx.com表示成功

openssl genrsa -out rootCA.key 2048
openssl req -x509 -new -nodes -key rootCA.key -subj "/CN=$NGROK_DOMAIN" -days 5000 -out rootCA.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 rootCA.pem -CAkey rootCA.key -CAcreateserial -out server.crt -days 5000

rm -rf ./server.csr

创建自签名证书有个重要的点,需要注意  work.sh 内的  NGROK_DOMAIN 可以设置为自己的域名,随后客户端配置文件ngrok.cfg内 server_addr 后面填写的域名也必须是  NGROK_DOMAIN 的值 

5.   证书生成完后,需要拷贝指定证书到指定的位置

下一步也就是第6步,ngrok通过bindata第三方库,将ngrok源码目录下的assets目录(资源文件)打包到可执行文件(ngrokd和ngrok)中 去,assets/client/tls和assets/server/tls下分别存放着用于ngrok和ngrokd的默认证书文件,我们需要将它们替换成我们自己生成的:(因此这一步务必放在编译可执行文件之前)

#拷贝客户端要使用的签发服务器的根证书,也就是根证书
\cp rootCA.pem assets/client/tls/ngrokroot.crt -f
# 拷贝服务器证书到指定目录,替换默认证书
\cp server.crt assets/server/tls/snakeoil.crt  -f
\cp server.key assets/server/tls/snakeoil.key -f

这是使用了 \cp 因为 直接使用cp,依然会提示是否需要覆盖,比较麻烦,使用 \cp 强行覆盖,不提示

6.  编译服务器、客户端

sudo make release-server release-client

这个命令默认编译的是 linux 平台下 服务器、客户端。

linux服务器编译命令: sudo make release-server

我的客户端是win7,客户端需要交叉编译

[root@localhost ngrok]# GOOS=windows GOARCH=amd64 make release-client
生成的服务器可执行程序在            ./bin/ngrokd

生成的win7客户端可执行程序在    ./bin/windows_amd64/ngrok.exe

需要其他平台编译的参考下面:

不同平台使用不同的 GOOS 和 GOARCH,前面的编译选项就是指 go os , go 编译出来的操作系统 (windows,linux,darwin) ;go arch, 对应的构架 (386,amd64,arm)

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
不同平台命令后跟上 make release-client /  make release-server 就行编译指定平台 client / server

编译使用的go包说明:

  • go-bindata 包,该库是一套将任意资源文件转成二进制数据反向生成到Go代码供hash调用的技术,Ngrok的源码利用这一技术将公网证书和密钥,以及站点的HTML生成到go代码中去了,使其变成了一堆byte数组,在程序中hash调用。这么做固然有它的好处,但缺点也显而易见,因为这套技术要提前用一个项目的程序生成另一个项目的Go代码,所以编译起来难免繁琐,于是Ngrok提供了makefile文件以供用户make编译,这就有点尴尬了,本来好好的跨平台Go语言项目,被make和makefile活生生憋成了只能Linux使用的了。
  • build -tags 技术,通过Ngrok项目,我第一次知道Go的这个特性,可以在代码顶端加上// +build !release等标记,注明编译时的模式,比如前面这种表达方式,就是在非release编译模式下才会编译这个文件,然后使用go build -tags 'release'或者go build -tags 'debug'来控制是否编译这个代码文件。这个特性确实灵活,可以在项目中编写不同的编译模式下的代码,缺点呢,就是没有详细文档的情况下,第三方用户并不知道有哪些编译模式,加大了源码本地编译的复杂度,所以这也是原版Ngrok项目使用makefile文件的原因之一。
  • equinox.io 技术,这项技术可以让Go代码在编译和运行期间保持更新,代码作者更新代码后,能够在第三方用户实时更新,具体没有了解,我看原版Ngrok在进行release编译时增加了很多equinox.io令牌密钥,以连接远程仓库,保证代码更新。

7.   下载客户端 执行程序到客户端执行环境

sz     ./bin/windows_amd64/ngrok.exe

注: sz  命令需要安装  yum install -y lrzsz

此处有个坑,如果只下载 客户端执行文件是不行的。还需要把第5个步骤中的

assets/client/tls/ngrokroot.crt  一并下载并覆盖到客户端执行环境下,提示,最好是把 assets 这个目录打包压缩,下载到客户端解压,给client使用。

客户端需要ngrok.exe ngrok.cfg 以及 assets 目录,直接把服务器端    覆盖过证书的这个目录 assets 也下载到客户端环境,执行程序同一级目录即可。

下面是客户端目录主要文件列表:

  ---  ngrok.exe

  ---  ngrok.cfg

  ---  assets

  ---   ---  client

  ---    ---    ---  tls 

  ---    ---    ---   ---   ngrokroot.crt

8.   执行 服务端

[root@localhost ngrok]# ./bin/ngrokd -tlsKey=./server.key -tlsCrt=./server.crt -domain="dev.mydomain.com" -httpAddr=":80" -httpsAddr=":443" -tunnelAddr=":4443"
[15:09:40 CST 2018/10/26] [INFO] (ngrok/log.(*PrefixLogger).Info:83) [registry] [tun] No affinity cache specified
[15:09:40 CST 2018/10/26] [INFO] (ngrok/log.(*PrefixLogger).Info:83) [metrics] Reporting every 30 seconds
[15:09:40 CST 2018/10/26] [INFO] (ngrok/log.Info:112) Listening for public http connections on [::]:80
[15:09:40 CST 2018/10/26] [INFO] (ngrok/log.Info:112) Listening for public https connections on [::]:443
[15:09:40 CST 2018/10/26] [INFO] (ngrok/log.Info:112) Listening for control and proxy connections on [::]:4443

服务端参数解析:

a.  可以看到 侦听 80  443 4443

b.  ngrok客户端连接的是客户端配置文件:ngrok.cfg 内配置的端口 4443 

     server_addr: "dev.mydomain.com:4443"

c.  -domain为你的服务域名,-httpAddr为http服务端口地址,访问形式为xxx.dev.mydomain.com:4443,也可设置为80默认端口,-httpsAddr为https服务,同上。

ngrokd还会开一个端口用来跟客户端通讯(可通过-tunnelAddr=":xxx" 指定),如果你配置了 iptables 规则,需要放行这个通讯端口(4443)上的 TCP 协议。

firewall-cmd --zone=public --add-port=4443/tcp --permanent
firewall-cmd --reload

9.   启动客户端

此处客户端配置文件是个大坑,按照网上大量分享的配置

server_addr:"dev.mydomain.com:4443"

trust_host_root_certs:false

类似这种配置完全不行,各种问题,原因是网上大家分享的是最新版本ngrok的配置。

而我们编译的是开源版本  2.1.7 版本,是较旧版本,需要配置按照yaml方式设置

server_addr: "dev.mydomain.com:4443"
trust_host_root_certs: false
tunnels:
  abc:
    proto:
      http: 8081
    subdomain: ngrok

这配置也是个坑。。里面不许用tab,只能用空格, 不然客户端就启动失败。

10.   连接成功

客户端 cmd 命令行

C:\ngrok>.\ngrok.exe -config=ngrok.cfg -log=out.log -subdomain=abc 8081

这个子域名 subdomain=abc 作用是,最终生成的映射域名是  abc.dev.mydomain.com 

客户端启动一个http服务,端口8081。此客户端是需要被映射到ngrok上,提供给别人访问的服务。

如果跟ngrok连接success,ngrok客户端会输出下图内容:

隧道状态绿色字体: online 即为成功。

此时,浏览器输入 http://abc.dev.mydomain.com/  可以测试验证,

如果想实现其他局域网内终端访问该内网http服务, 则需要,其他网络内的终端,把本机dns 设置下,

C:\windows\System32\drivers\etc\hosts

文件内需要新增dns解析记录 10.8.0.1  abc.dev.mydomain.com

10.8.0.1 即为 ngrok server 服务器IP地址。

11.  ngrok启动后,内部会提供一个http服务,浏览器内输入http://localhost:4040/http/in

就可以查看,当前状态

12.   还有个大坑!

 证书重新生成后,居然客户端/服务器可执行程序,需要重新编译。

否则会输出  

Failed to read message: remote error: bad certificate

 

先写这么多,回头继续。

 

 

 

 

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值