centos7下使用n.grok编译服务端和客户端穿透内网
(发现博客园会屏蔽一些标题中的关键词,比如ngrok、内网穿透,原因不知,所以改了标题才能正常访问,)
有时候想在自己电脑、路由器或者树莓派上搭建一些web、vpn等服务让自己用,但是自己的电脑一般没有外网ip,没法在外部访问这些服务,就像下图,电脑能访问到外网,但是没法从外网访问到电脑。
这时可以用一台有外网ip的服务器利用ngrok在中间做个跳板,如下图,原理是搭有web服务的内网电脑A 与公网服务器C长连接,手机B访问服务器C的指定一个端口,服务器C将收到的手机发来的数据转发给内网电脑A,A做出相对的响应回传给服务器C,C再将收到的数据发给手机A,实现穿透内网。端口转发这些规则都是在服务器C和电脑B上定义好的。
ngrok穿透内网原理搭建比较简单,搭建也比较简单,不需要填很多配置文件。只需要在服务器上运行服务端程序,在内网电脑上运行客户端程序就行了。
需要:一台服务器、一个域名
搭建步骤:
1、环境准备:在服务器上安装git、go语言环境,下载ngrok源码包。
2、用域名生成证书(防止别人用利用你的服务器做跳板)。
3、编译服务端程序。
4、编译客户端程序,并复制到内网电脑上。
5、分别运行服务端和客户端,实现长连接。
6、测试,用手机访问看能不能转发数据。
详细步骤:
(为了容易理解,这里用abcd.cn当做域名,二级域名是ngrok.abcd.cn,指向同一个服务器)
1、环境准备
安装git:yum install git -y
下载go语言包,直接给出下好的了:https://pan.baidu.com/s/1dTzXD-r5kMgIvcD8HZJN1g
解压go语言压缩包,创建环境变量:
tar -zxvf go1.9.2.linux-amd64.tar.gz
vi /etc/profile
添加并保存profile文件:
export GO_HOME=/file/go/go
export PATH=$PATH:$GO_HOME/bin
更新环境变量:source /etc/profile
下载解压github上的ngrok源码:wget https://codeload.github.com/inconshreveable/ngrok/zip/master
给一个下好的ngrok:https://pan.baidu.com/s/1K2PB-Kka0-alLDSBfpotqQ
2、生成证书
执行下列命令:
NGROK_DOMAIN="你的域名" openssl genrsa -out base.key 2048 openssl req -new -x509 -nodes -key base.key -days 10000 -subj "/CN=$NGROK_DOMAIN" -out base.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 base.pem -CAkey base.key -CAcreateserial -days 10000 -out server.crt
执行后文件夹下会生成一些证书文件。
将新生成的证书,替换掉assets/client/tls下的证书
cp
base.pem assets
/client/tls/ngrokroot
.crt -y
3、编译生成服务端程序
make
release-server
会在ngrok/bin/目录下生成ngrokd可执行文件,
运行命令:./bin/ngrokd -tlsKey=server.key -tlsCrt=server.crt -domain="abcd.cn" -httpAddr=":80" -httpsAddr=":443" -tunnelAddr=":4443"
命令中-httpAddr 和-httpsAddr 是手机访问ngrok.abcd.cn的的端口,服务端会将80端口接收到的数据通过4443端口(默认)转发到内网电脑。
出现下列信息是成功运行了。
[22:17:33 CST 2018/08/19] [INFO] (ngrok/log.(*PrefixLogger).Info:83) [registry] [tun] No affinity cache specified [22:17:33 CST 2018/08/19] [INFO] (ngrok/log.Info:112) Listening for public http connections on [::]:80 [22:17:33 CST 2018/08/19] [INFO] (ngrok/log.Info:112) Listening for public https connections on [::]:443 [22:17:33 CST 2018/08/19] [INFO] (ngrok/log.Info:112) Listening for control and proxy connections on [::]:4443 [22:17:33 CST 2018/08/19] [INFO] (ngrok/log.(*PrefixLogger).Info:83) [metrics] Reporting every 30 seconds
4、编译生成客户端程序
这里编译一个window版的客户端:
GOOS=windows GOARCH=amd64 make
release-client
(生成linux客户端直接执行make release-client)
执行完上述命令后会在ngrok/bin/目录下生成windows_amd64文件夹,里面有一个ngrok.exe程序,复制到自己内网电脑上。
比如复制到E:/ngrok文件夹,需在此文件夹里新建ngrok.cfg配置文件,里面写:
server_addr: "abcd.cn:4443" trust_host_root_certs: false
在命令提示符里切换到此文件夹,执行:
ngrok.exe -config=ngrok.cfg -log=ngrok.log -subdomain ngrok 5000
命令中指定配置文件、日志文件,-subdomain后面跟的是二级域名和服务器将数据转发到的本地端口,注意填的是二级域名的前一部分,比如ngrok.abcd.cn就写ngrok。
下图是运行成功的截图:
就会将服务器80接收到的数据转发到内网电脑的5000端口。
5、连接测试
先运行服务端:./bin/ngrokd -tlsKey=server.key -tlsCrt=server.crt -domain="abcd.cn" -httpAddr=":80" -httpsAddr=":443" -tunnelAddr=":4443"
再运行客户端:ngrok.exe -config=ngrok.cfg -log=ngrok.log -subdomain ngrok 5000
6、用手机访问进行测试。
如果是客户端连接不到服务端(就是上面步骤那个图状态不显示online),一般是服务端配置的问题,客户端程序和服务端程序是用证书编译出来的配套使用的。
如果服务端能接收到手机访问的数据但是找不到隧道转发,可能是客户端域名写的有问题(我就是这样的错误)。
手机访问的是二级域名:ngrok.abcd.cn。
自己搭建时别忘了把abcd.cn替换成自己的域名。
ps:域名那里没做其他尝试,不知道填服务器ip可不可行,我在运行客户端写一级域名不行,写二级域名可以,但是看网上教程填的一级域名。。