Ngrok想必大家并不是太陌生,类似于国内的花生壳、nat123所提供的服务。可以实现让外网直接访问你搭建在内网的服务(例如网站等)。目前官网的服务端还是可用的,但设置固定二级域名开始收费了。所以使用起来还是有些不是很方便,好消息是它是开源的。那我们就可以自己搭建ngrok服务端。
自建还是有2个硬性要求的:
1、公网服务器(Linux系统)
2、独立域名(解析到你服务器上)
第一步:安装go编译环境(ngrok是go语言开发的)
1、下载go:http://www.golangtc.com/download 下载和你服务器系统对应的版本即可。我的系统是CentOS 64位,我下载的是 go1.6rc2.linux-amd64.tar.gz
2、解压go到 /usr/local/go
3、建链接: ln -s /usr/local/go/bin/* /usr/bin/
第二步:下载ngrok源码
cd /usr/local/src/ git clone https://github.com/inconshreveable/ngrok.git export GOPATH=/usr/local/src/ngrok/ export NGROK_DOMAIN="ngrok.zpblog.cn" cd ngrok
第三步:生成自签名证书
使用ngrok.com官方服务时,我们使用的是官方的SSL证书。自建ngrokd服务,我们需要生成自己的证书,并提供携带该证书的ngrok客户端。
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
第四步:开始编译服务端和客户端
1、服务端
服务端比较容易,先指定一下我的环境变量,然后再make:
GOOS=linux GOARCH=amd64 #如果是32位系统,这里 GOARCH=386
然后make
make release-server
按理讲,应该就可以编译成功了,但是我发现,编译的时候很多依赖包是需要自动下载的,有一个包
log4go 会提示访问不到,修改源码,将该包改为 github 上的地址:
找到 /usr/local/src/ngrok/src/ngrok/log/logger.go ,第五行import中的 log 包,改为: log "github.com/keepeye/log4go"
然后重新 make release-server
编译成功后,应该可以在 /usr/local/src/ngrok/bin 下生成了一个 ngrokd 可执行文件,这就是我们的服务端了,现在启动服务端试试:
bin/ngrokd -domain="$NGROK_DOMAIN" -httpAddr=":8000" -httpsAddr=":4433"
如果没有报错的话,会出现以下输出:
[13:15:43 CST 2016/02/25] [INFO] (ngrok/log.(*PrefixLogger).Info:83) [registry] [tun] No affinity cache specified [13:15:43 CST 2016/02/25] [INFO] (ngrok/log.(*PrefixLogger).Info:83) [metrics] Reporting every 30 seconds [13:15:43 CST 2016/02/25] [INFO] (ngrok/log.Info:112) Listening for public http connections on [::]:8000 [13:15:43 CST 2016/02/25] [INFO] (ngrok/log.Info:112) Listening for public https connections on [::]:4433 [13:15:43 CST 2016/02/25] [INFO] (ngrok/log.Info:112) Listening for control and proxy connections on [::]:4443
现在先 ctrl+c 退出,我们还需要编译客户端呢。
2、客户端
1.1、windows客户端
cd /usr/local/go/src GOOS=windows GOARCH=amd64 ./make.bash cd - GOOS=windows GOARCH=amd64 make release-client #这里的amd64是64位系统,32位改成386 #应该会在 bin/windows_amd64 目录下生成ngrok客户端程序
1.2、树莓派客户端
cd /usr/local/go/src GOOS=linux GOARCH=arm ./make.bash cd - GOOS=linux GOARCH=arm make release-client #应该会在 bin/linux_arm 目录下生成ngrok客户端程序
到这里,编译就完成了,现在让我们把应用跑起来:
按之前的方式启动服务端ngrokd,有以下提示:
Listening for public http connections on [::]:8000
Listening for public https connections on [::]:4433
Listening for control and proxy connections on [::]:4443
记住这两个端口 8000 和 4443 。
现在我们来到自己电脑上,准备启动客户端。在启动之前,我们需要为客户端编写一个配置文件 ngrok.cfg :
server_addr: "ngrok.zpblog.cn:4443" trust_host_root_certs: false
注意,配置文件中用的是4443端口。
然后启动客户端,假设我们要分配一个域名
test.ngrok.zpblog.cn
执行以下命令:
./ngrok -config=./ngrok.cfg -subdomain=test 80
解释一下参数:
-config 就是上面配置文件ngrok.cfg的路径 -subdomain 就是需要分配域名的前缀部分 80 就是本机websever的端口,比如apache监听的端口,一会ngrok会将请求映射到该端口上。
如果没错误,应该会出现以下的输出:
Tunnel Status online Version 1.7/1.7 Forwarding http://test.ngrok.zpblog.cn:8000 -> 127.0.0.1:80 Forwarding https://test.ngrok.zpblog.cn:8000 -> 127.0.0.1:80 Web Interface 127.0.0.1:4040 # Conn 0 Avg Conn Time 0.00ms
现在,访问 test.ngrok.zpblog.cn:8000 ,ngrok服务端就会讲请求转发到我们本地客户端,再由客户端转发给我们的webserver 80端口。所以,我们只需要配置apache或nginx,添加虚拟主机,绑定域名 test.ngrok.zpblog.cn 即可。
事情还没有结束!
你们可以看到现在用来访问的地址后面接了个8000端口:test.ngrok.zpblog.cn:8000
为什么在启动服务端的时候,端口不指定为80呢?
很遗憾,因为这台服务器不是只用来做ngrok服务的,我博客还在上面呢,80端口已经被nginx占用了。
那怎么办?
不得不提nginx是个牛逼的软件,我们可以在nginx中配置一个server,就绑定 *.ngrok.zpblog.cn 域名,然后将所有请求转发到后端 :8000 端口上,这就是反向代理。我发一下自己的nginx配置:
#ngrok.zpblog.cn.conf upstream nodejs { server 127.0.0.1:8000; keepalive 64; } server { listen 80; server_name *.ngrok.zpblog.cn; access_log /home/logs/ngrok.zpblog.cn.log; location / { proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $http_host:8000; proxy_set_header X-Nginx-Proxy true; proxy_set_header Connection ""; proxy_pass http://nodejs; } }
问题处理:
1、……Failed to read valid http request: malformed HTTP request……
解:检查 ngrok.cfg 文件里的端口号是否与 Listening for control and proxy connections on [::]:4443 后的端口号一致。
2、……Failed to read message: remote error: bad certificate……
解1:检查 ngrok.cfg 文件里域名是否与你建立证书时的域名一致。
解2:保证解1正确前提下检查客户端机器系统时间,是否为当前年月日。
参考链接:
http://www.ekan001.com/articles/38
http://tonybai.com/2015/03/14/selfhost-ngrok-service/
http://www.svenbit.com/2014/09/run-ngrok-on-your-own-server/
http://blog.fifsky.com/2015/12/29/ngrok%E8%AF%81%E4%B9%A6%E9%94%99%E8%AF%AF/
相关文章
转:Linux安装rinetd实现TCP/UDP端口转发2021-03-19
windows端口转发(映射)2020-02-20
Windows目标服务器端口监测脚本微信通知2016-08-25
实战 SSH 端口转发2014-09-29
浅谈解决动态IP和80端口被封闭的办法2014-09-27