Home Archives Categories Tags Docs

搭建私有 Ngrok 内网穿透服务

发布时间: 更新时间: 总字数:1538 阅读时间:4m 作者: 分享

Ngrok 是一个反向代理,可以将本地的web或tcp服务通过公共端口和外部建立一个安全通道,这样就可以通过外网直接访问本地对应的服务,在进行微信公众号等测试开发的时候非常有用

域名解析

将需要外网访问的域名解析到所部署的服务器上,为了支持多级域名需要进行泛解析。比如ngrok的域名使用 ngrok.example.com 的话,需要将 ngrok.example.com*.ngrok.example.com 域名的A记录解析到所部署的服务器IP上,这样客户端就可以使用如 jet.ngrok.example.com 这样的域名进行访问了。

编译安装ngrok

安装GO环境

参考:https://xiexianbin.cn/go/2017/01/02/go-install

安装后版本:

[root@xiexianbin_cn src]# go version
go version go1.11.4 linux/amd64

下载 Ngrok

ngrok项目的官方地址是:https://github.com/inconshreveable/ngrok
获取源码:

cd /usr/local/src
git clone https://github.com/tutumcloud/ngrok.git

域名证书

域名证书可以到 SSL 证书提供商获取,也可以自己生成签名证书,步骤如下:

需要将NGROK_DOMAIN替换为自己的域名

cd $GOPATH/src/github.com/inconshreveable/ngrok
NGROK_DOMAIN="p.80.xyz"
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 device.key 2048
openssl req -new -key device.key -subj "/CN=$NGROK_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

编译并启动服务端

ngrokd 为服务端的执行文件,ngrok为客户端的执行文件,我们先来编译ngrok的服务端程序,在ngrok目录下面执行下面的命令:

make release-server
[root@xiexianbin_cn ngrok]# make release-server
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/...
bin/go-bindata -nomemcopy -pkg=assets -tags=release \
	-debug=false \
	-o=src/ngrok/server/assets/assets_release.go \
	assets/server/...
go get -tags 'release' -d -v ngrok/...
github.com/inconshreveable/mousetrap (download)
github.com/rcrowley/go-metrics (download)
Fetching https://gopkg.in/inconshreveable/go-update.v0?go-get=1
Parsing meta tags from https://gopkg.in/inconshreveable/go-update.v0?go-get=1 (status code 200)
get "gopkg.in/inconshreveable/go-update.v0": found meta tag get.metaImport{Prefix:"gopkg.in/inconshreveable/go-update.v0", VCS:"git", RepoRoot:"https://gopkg.in/inconshreveable/go-update.v0"} at https://gopkg.in/inconshreveable/go-update.v0?go-get=1
gopkg.in/inconshreveable/go-update.v0 (download)
github.com/kardianos/osext (download)
github.com/kr/binarydist (download)
Fetching https://gopkg.in/inconshreveable/go-update.v0/check?go-get=1
Parsing meta tags from https://gopkg.in/inconshreveable/go-update.v0/check?go-get=1 (status code 200)
get "gopkg.in/inconshreveable/go-update.v0/check": found meta tag get.metaImport{Prefix:"gopkg.in/inconshreveable/go-update.v0", VCS:"git", RepoRoot:"https://gopkg.in/inconshreveable/go-update.v0"} at https://gopkg.in/inconshreveable/go-update.v0/check?go-get=1
get "gopkg.in/inconshreveable/go-update.v0/check": verifying non-authoritative meta tag
Fetching https://gopkg.in/inconshreveable/go-update.v0?go-get=1
Parsing meta tags from https://gopkg.in/inconshreveable/go-update.v0?go-get=1 (status code 200)
Fetching https://gopkg.in/yaml.v1?go-get=1
Parsing meta tags from https://gopkg.in/yaml.v1?go-get=1 (status code 200)
get "gopkg.in/yaml.v1": found meta tag get.metaImport{Prefix:"gopkg.in/yaml.v1", VCS:"git", RepoRoot:"https://gopkg.in/yaml.v1"} at https://gopkg.in/yaml.v1?go-get=1
gopkg.in/yaml.v1 (download)
github.com/inconshreveable/go-vhost (download)
github.com/alecthomas/log4go (download)
github.com/nsf/termbox-go (download)
github.com/mattn/go-runewidth (download)
github.com/gorilla/websocket (download)
go install -tags 'release' ngrok/main/ngrokd
[root@xiexianbin_cn ngrok]#

首次编译时间有一些长。编译成功之后会在项目目录的bin目录下面生成一个 ngrokd 的文件,使用下面的命令启动服务:

bin/ngrokd -domain="ngrok.example.com" -httpAddr=":8080" -httpsAddr=":8443" -tunnelAddr=":4443"

参数说明:

  • domain 表示服务的域名
  • httpAddr 表示HTTP的端口
  • httpsAddr 表示HTTPS的端口
  • tunnelAddr 用来设置通道的端口,在客户端和服务端建立连接的端口,需要在防火墙中开放次端口(默认为4443)

可以将命令加入到 `/etc/rc.local 中使其开机启动,命令如下:

/usr/local/src/ngrok/bin/ngrokd -domain="ngrok.80.xyz" -httpAddr=":8080" -httpsAddr=":8443" -tunnelAddr=":4443" > /dev/null 2>&1 &

其中 `/usr/local/ngrokngrok的安装目录,最后不显示运行的日志,并且在后台运行。

客户端

编译客户端

首先进入项目的根目录,使用下面的命令编译专用的客户端文件:

GOOS=windows GOARCH=amd64 make release-client
GOOS=darwin GOARCH=amd64 make release-client
GOOS=linux GOARCH=amd64 make release-client

其中GOOS用乱设置操作系统,GOARCH用来设置对应的架构(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

上面的命令表示编译windows下使用的32位的客户端程序,编译好的文件在bin`目录下对应平台的目录下面。

启动客户端

接下来就可以使用客户端了,首先创建一个ngrok的配置文件ngrok.cfg

server_addr: "ngrok.example.com:4000"
trust_host_root_certs: false

域名后面的端口是设置的通道端口。

接下来使用下面的命令运行客户端:

./ngrok -subdomain jet -config=ngrok.cfg 8080

其中jet是自定义的域名前缀,ngrok.cfg是上面的配置文件,8080是映射的本地到外网的端口,这样就可以使用 http://jet.ngrok.example.com:8088 访问本地8080的端口了。

另外,还可以使用 -proto 来指定协议的类型(默认是http协议),支持httptcp等多种协议:

./ngrok -subdomain jet -config=ngrok.cfg -proto=tcp 8080

使用Nginx反向代理到80端口

上面通过子域名访问的时候不是默认的80端口,可以使用Nginx进行反向代理,配置信息如下:

upstream tdt_99tone_ngrok_server {
    server 127.0.0.1:8088 weight=1 max_fails=3 fail_timeout=30s;
    keepalive 64;
}

server {
    listen 80;
    server_name *.ngrok.example.com ngrok.example.com;
    charset utf-8;

    location / {
        proxy_next_upstream http_502 http_504 error timeout invalid_header;
            proxy_set_header Host  $host:8088;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_pass http://tdt_99tone_ngrok_server;
            proxy_redirect off;
    }

    access_log off;
    log_not_found off;
}

上面例子中的8088ngrok设置的httpAddr参数设置的端口,有两处。这样就可以直接使用域名的80端口访问了。

完毕。

相关文章
最近更新
最新评论
加载中...