Jump to Navigation

自建ngrok服务

自建ngrok服务

源代码

ngrok1.7及以下版本有源代码

ngrok2+版本没有源代码,但有bin版本。不知道是否有什么黑科技呢。

本文以有源代码的ngrok-1.7为例,说明自建ngrok服务的过程。

生成ngrok使用的自签加密证书

ngrokd客户端与ngrok客户端tunnel全程使用tls加密传输,所以要在编译前生成加密证书。

简单的生成脚本,

#!/bin/sh

domain="yourdomain.com"

openssl genrsa -out rootCA.key 2048
openssl req -x509 -new -nodes -key rootCA.key -subj "/CN=$domain" -days 5000 -out rootCA.pem
openssl genrsa -out device.key 2048
openssl req -new -key device.key -subj "/CN=$domain" -out device.csr
openssl x509 -req -in device.csr -CA rootCA.pem -CAkey rootCA.key -CAcreateserial -out device.crt -days 5000

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

这里看到,一共有3个证书文件,其中rootCA.pem是自签根证书。

snakeoil.crt是公钥证书文件,snakeoil.key是私钥证书文件。

编译ngrok

ngrok是go语言编写,在此之前保证已经正确安装了golang包。

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

cd ngrok

make release-server release-client

会在./bin/目录生成ngrokd和ngrok可执行程序。

编译过程,可能会遇到code.google.com/p/log4go包下载不了,可以到github.com上git clone,并放在src/目录。

启动默认ngrokd服务端

$ ./bin/ngrokd -domain yourdomain.com

默认情况下,ngrokd会启动三个端口:

  • 80: http协议服务端口
  • 443: https协议服务端口
  • 4443: ngrok的control 和 proxy端口

测试:

$ curl yourdomain.com
Tunnel yourdomain.com not found

由于没有开启客户端,ngrokd无法转发,显示要转发的域名不存在。

启动ngrok客户端,http支持

在配置文件ngrok.cfg中,输入这两行:

server_addr: yourdomain:4443
trust_host_root_certs: false

命令行启动,(控制台cursers程序),

$ bin/ngrok -config ./ngrok.cfg -subdomain test -proto http 80

这句命令含义是,启动一个子域名为test的http协议转发,从服务器端转发到本地80端口。

这里80可以是任意端口,并且也可以带个主机地址的形式,如192.168.1.100:80。

成功启动后,会显示状态,

ngrok                                (Ctrl+C to quit)

Tunnel Status                 online                                                                                        
Version                       1.7/1.7                                                                                       
Forwarding                    http://test.yourdomain.com -> 127.0.0.1:80                                                                                                                       
Web Interface                 127.0.0.1:4040                                                                                
# Conn                        0                                                                                             
Avg Conn Time                 0ms

Status一栏表示与ngrokd连接状态,可能是connecting, online, reconnecting。

如果以上操作没有问题,测试访问 http://test.yourdomain.com,看输出返回是否正常。

使用letsencrypt的证书

这种方式,让ngrok代理的https连接能使用正式的证书,站点更安全。

这里假设已经获取到了letsencrypt证书,在/etc/letsencrypt/live/yourdomain.com/目录会有4个文件:

cert.pem  chain.pem  fullchain.pem  privkey.pem

letsencrypt证书与ngrok证书的对应关系为:

  • snakeoil.crt <- cert.pem (公钥)
  • snakeoil.key <- privkey.pem (私钥)
  • ngrokroot.key <- letsencryptauthorityx1.pem (https://letsencrypt.org/certs/letsencryptauthorityx1.pem)

其中ngrokroot.key是用于签发ngrok证书的根证书,在这也是letsencrypt根证书。

要注意一点, 对于测试的ngrok-1.7版本,ngrokd服务端可以运行时有参数可以指定证书,

而ngrok客户端却没有对应的参数,所以,需要在编译时把letsencrypt的证书放在ngrok源代码中,

编译出使用letsencrypt的证书的ngrokd服务端和ngrok客户端。

有了这个证书之后,再浏览器测试访问https://test.yourdomain.com/,发现显示的证书已经是letsencrypt的签发的了。

其他

对于根域名,ngrok如何设置转发呢?

在配置文件.ngrok中,直接使用全域名,非subdomain的形式即可,如:

rootdomain.net:
    proto:
        http: 80

在命令行下,其实是使用-hostname "rootdomain.net" 参数即可。

在ngrok下使用正式https证书参数:
-tlsKey /path/to/tls.key -tlsCrt /path/to/tls.crt 

如果使用letsencrypt生成的.pem,则使用这两个文件:

./ngrokd -log-level DEBUG -domain fixlan.tk -tlsKey /etc/letsencrypt/live/fixlan.tk/privkey.pem -tlsCrt /etc/letsencrypt/live/fixlan.tk/cert.pem

但需要重新编译ngrok, 这是代码ngrokroot.crt的letsencrypt根证书, https://letsencrypt.org/certs/letsencryptauthorityx1.pem

ngrok的客户端配置,可以多个转发写在同一个配置文件中,

在tunnels:项下面,并列几个不同的subdomain/hostname即可,如

tunnels:
     test1:
         proto:
              http: 81
     test2:
         proto:
              http: 82
     yourdomain.com:
         proto:
              http: 80
     ssh:
         proto:
              tcp: 22
如何设置ngrok web interface地址IP?

第一种方式,当然改源代码一定可行的。

是否可以不使用curses的客户端?

ngrok项目的初衷是为本地搭建临时的对外服务,用途内网服务的展示。

没有发现ngrok客户端选项能够关闭curses显示功能。

可能需要hack一下ngrok客户端源代码,或者把ngrok源代码当作库使用,开发一个相同功能但不使用curses的能够后台运行的客户端程序。

对于没有客户端的子域名,会显示Tunnel fixlan.tk not found。

添加新评论

Plain text

  • 不允许HTML标记。
  • 自动将网址与电子邮件地址转变为链接。
  • 自动断行和分段。
CAPTCHA
This question is for testing whether or not you are a human visitor and to prevent automated spam submissions.
Image CAPTCHA
Enter the characters shown in the image.


Main menu 2

Story | by Dr. Radut