本着玩玩的心态,搭建一个内网穿透的服务。内网穿透:即外网可以直接访问你内网
准备工作
有公网 IP 服务器一台
可以配置域名解析的域名一个。
系统:CentOS (也可为其他,命令稍有不同)
配置域名解析
先把域名给配置了,比如我的域名是yun996.cn,那么建立ngrok.yun996.cn和*.ngrok.yun996.cn解析到 你的 VPS 的 IP 上 (A 记录)。
安装 go 语言环境
ngrok是基于go语言开发的,所以需要先安装go语言开发环境,CentOS可以使用yum安装:
yum install golang
如果没有权限,请使用sudo安装,安装完成之后,执行go version看到类似信息,证明安装成功:
go version go1.7.3 linux/amd64
安装 git 环境
有些 VPS 的系统中自带了 git 环境,有的没有带,如果你的 git 使用不正常,请卸载自带的 git,重装安装。
卸载原有 git (根据需要自选):
yum remove git
更新 yum 源:
yum update
安装 git :
yum install git
安装完后执行git --version,返回类似的信息,证明安装成功:
git version 2.5.0
下载 ngrok 源码:
找一个存放ngrok的文件夹 ,clone 一份源码:
(为了方便演示,本文使用root用户,所以存放在/root/路径下)
cd/root
git clone https://github.com/inconshreveable/ngrok.git
exportGOPATH=/root/ngrok
生成自签名证书
使用ngrok官方服务时,我们使用的是官方的SSL证书。自己建立ngrok服务,需要我们生成自己的证书,并提供携带该证书的ngrok客户端。
证书生成过程需要有自己的一个基础域名,官网随机生成的地址,如:695a358d.ngrok.com,基础域名就是ngrok.com。而在上文中提到的二级域名ngrok.yun996.cn就是用来作为这次要提供的基础域名。如果你的域名是abc.com,那么域名基础域名可以设置为ngrok.abc.com。
以我的基础域名为例(注意替换成自己的域名),生成证书过程如下:
cd/root/ngrokopenssl genrsa-out rootCA.key2048openssl req-x509-new-nodes-key rootCA.key-subj"/CN=ngrok.yun996.cn"-days5000-out rootCA.pemopenssl genrsa-out device.key2048openssl req-new-key device.key-subj"/CN=ngrok.yun996.cn"-out device.csropenssl x509-req-indevice.csr-CA rootCA.pem-CAkey rootCA.key-CAcreateserial-out device.crt-days5000
执行完成以上命令后,在ngrok目录下,会新生成 6 个文件:
device.crt device.csr device.key rootCA.key rootCA.pem rootCA.srl
我们在编译可执行文件之前,需要把生成的证书分别替换到assets/client/tls和assets/server/tls中,这两个目录分别存放着ngrok和ngrokd的默认证书。
cp rootCA.pem assets/client/tls/ngrokroot.crt
cp device.crt assets/server/tls/snakeoil.crt
cp device.key assets/server/tls/snakeoil.key
中间会提示是否覆盖,输入 y 确认即可。这里最好一行一行复制执行,别一起复制执行。
编译 ngrokd 和 ngrok
ngrokd 是服务端的执行文件,进入到 ngrok 目录下,执行如下命令编译:
make release-server
ngrok 是客户端的可执行文件,进入到 ngrok 目录下,执行如下命令编译:
GOOS=xxx GOARCH=xxx make release-client
不同平台使用不同的GOOS和GOARCH,GOOS为编译出来的操作系统 (windows,linux,darwin),GOARCH对应的构架 (386,amd64,arm)编译成你想在哪个客户端使用的配置
例如: GOOS=windows GOARCH=amd64 make release-client
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
然后下载编译后的客户端,通过 ftp 或 scp 等都可以,生成的目录在 ngrok 的 bin 目录下(bin目录是编译成功后才生成的),当前例子的路径为 /root/ngrok/bin/windows_amd64/ngrok.exe
启动 ngrokd 服务器
在 ngrok 的 bin 目录下执行:
./ngrokd -domain="ngrok.yun996.cn" -httpAddr=":8080" -httpsAddr=":8081"
出现想提示,即为启动成功:
[09/14/15 04:47:24] [INFO] [registry] [tun] No affinity cache specified
[09/14/15 04:47:24] [INFO] [metrics] Reporting every 30 seconds
… …
其中,-domain为你的 ngrok 服务域名,-httpAddr为 http 服务端口地址,访问形式为:xxx.ngrok.yun996.cn:8088,也可设置为 80 默认端口,注意端口冲突即可,-httpsAddr为 https 服务,同上。
ngrokd启动后,退出命令行即关闭服务。如果想要在后台运行,则执行:
nohup ./ngrokd -domain="ngrok.yun996.cn" -httpAddr=":8080" -httpsAddr=":8081" &
注意末尾需要有&号,详细搜索nohup了解。关闭服务只需通过:
ps -A # 找到PID,执行关闭
kill xxxid
启动 ngrok 客户端
上面我们编译好了客户端并下载到了本地,演示路径为d:/ngrok/ngrok.exe
在d:/ngrok/目录下,建立 ngrok 配置文件:ngrok.cfg 然后把下面的内容复制进去 (记得修改为自己的子域名)
server_addr: "ngrok.yun996.cn:4443"
trust_host_root_certs: false
server_addr端口默认 4443,还需要服务器开启 4443 端口,使用阿里云或腾讯云的需要去安全组放行 4443 外网端口,不然无法正常使用。
然后使用 cmd 到这个路径下(d:/ngrok/),执行命令启动并转发本地的 4000 端口:
ngrok -subdomain example -config=ngrok.cfg 8080
运行完了以后会有提示域名,根据提示域名访问,我这里这里为 :http://demo.ngrok.yun996.cn:8080,访问这个就等于访问到你的http://127.0.0.1:8080下的内容了。
更详细的 ngrok 配置,请参考官方文档 :https://ngrok.com/docs
踩坑提醒:
1.一定先去ping 一下你的域名,看看能不能ping的通,还有就是你启动客户端的时候,验证是否与服务器端能连接
2. 如果你现在才刚刚有自己的服务器的话,先检查dns 是否配置 ,解析是否正常,还有是否 备案
3.检查4443端口是否开放 ,没有的话 记得开放
4.如果你有出现过
.....
make: bin/go-bindata: Command not found
make: * [client-assets] Error 127
这个错误的情况 是由于 go-bindata被安装到了GOBIN下了,go编译器找不到了。修正方法是将GOBIN/go-bindata拷贝到当前ngrok/bin下。
$ cp /home/ubuntu/.bin/go14/bin/go-bindata ./bin
或者 直接 yum install golang 重新安装go的环境 即可 (简单粗暴,反正我就是这么干的)
5. 如果你有出现过
Tunnel Status reconnecting
Version 1.7/
Web Interface 127.0.0.1:4040
# Conn 0
Avg Conn Time 0.00ms
第一反应先去检查下上面说的 1、2、3这三点是否都没有问题
如果都没有问题了,那你就留言吧。否则你应该就是这样的展示
Tunnel Status online
Version 1.7/1.7
Forwarding http://xxxx:8080 -> 127.0.0.1:8080
Forwarding http://xxxx:8080 -> 127.0.0.1:8080
Web Interface 127.0.0.1:4040
# Conn 0
Avg Conn Time 0.00ms
6. 如果你还出现过这样的情况
[09/13/15 09:55:46] [INFO] [tun:15dd7522] New connection from 54.149.100.42:38252
[09/13/15 09:55:46] [DEBG] [tun:15dd7522] Waiting to read message
[09/13/15 09:55:46] [WARN] [tun:15dd7522] Failed to read message: remote error: bad certificate
[09/13/15 09:55:46] [DEBG] [tun:15dd7522] Closing
那么 你要去看看 你客户端 ngrok.cfg 中server_addr后的值是否与 -domain以及证书中的NGROK_BASE_DOMAIN相同,如果有不同,就改成相同的
除此之外的一些情况,目前还有遇见过。。