CentOS上搭建ngrok服务端(内网穿透)

2016-02-26 浏览:9677
CentOS上搭建ngrok服务端(内网穿透)
评论:(3)复制地址

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/

评论:(3)复制地址
发布:zpblog | 分类:Linux | Tags:ngrok 端口

评论列表:

奇虎分享网

评论于2016-08-17 02:36:18
今天才发现你的博客,连着看了几篇呢 - 回复该评论

游客

评论于2017-10-12 20:24:24
使用frp实现内网穿透https://github.com/fatedier/frp/blob/master/README_zh.md - 回复该评论

小米球

评论于2017-11-15 14:29:18
感谢作者的教程,已经搭建成功,并经过自己的摸索,搞出了https版本,免费分享给有需要的使用,http://ngrok.ciqiuwl.cn 欢迎大家一起交流! - 回复该评论

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。