使用ngrok进行内网穿透 2020-04-18 前进路上 暂无评论 2240 次阅读 本文发布于2020-04-18, 文章内容或资源可能已经失效,仅供参考,谢谢。 平常我们搭建一个网站通常是在一个远程服务器上,域名解析,在服务器上搭建网站,然后就可以访问了,过程很简单。但是如果我们在自己电脑上搭建一个网站并且想让公网可以访问的话,由于我们的电脑没有固定的公网ip地址,就要多进行一些操作了。 这篇文章记录一下如何使用ngrok进行内网穿透,以在公网中访问我们在内网电脑上的资源。 > Ngrok 就是一种实现内网穿透的开源软件。Ngrok 借用在公网的服务端和局域网内部的服务端构建了一个代理通道。当有服务请求时,会先将请求达到公网服务端,再由公网服务端转发给内网服务端,以达到内网暴露公网的目的。 > 目录 > [TOC] ## 流程 你需要准备一台有公网IP的服务器,在服务器上运行ngrok服务端,在内网电脑上运行ngrok客户端。当有请求访问内网电脑的资源时,由于解析的设置,此请求会被送到ngrok服务端,公网服务端会与内网的客户端进行连接以将内网的资源暴露给公网。 ## 准备 使用ngrok进行内网穿透你需要准备: - 一个域名(本文假设为ngrok.zkk.me) - 一个有公网ip的服务器(本文为CentOS 7.6系统) - 一个内网电脑(本文为windows 10系统) ## 域名解析 你需要将域名ngrok.zkk.me添加A类解析至服务器,由于内网电脑上不同网站是用域名ngrok.zkk.me的不同子域名来区分的,所以还需要将泛域名\*.ngrok.zkk.me添加A类解析至服务器。解析情况如下表 | Type | Host | Value | | :------------: | :------------: | :------------: | | A Record | ngrok | XXX.XXX.XXX.XXX | | A Record | \*.ngrok | XXX.XXX.XXX.XXX | ## 申请SSL证书 由于有些同学会需要用到以https的形式访问内网网站,所以我们需要申请SSL证书。这里以在https://freessl.cn 申请证书为例 1. 首先在https://freessl.cn 注册账户 2. 注册并登陆后来到首页,在申请证书的框内填写泛域名`*.ngrok.zkk.me`,品牌选择`Let's Encrypt V2`,然后点击“创建免费的SSL证书” [![申请证书](https://api.wuwz.net/distribute/web/zkkme/img/002c/002c-1.png "申请证书")](https://api.wuwz.net/distribute/web/zkkme/img/002c/002c-1.png "申请证书") 3. 然后来到创建SSL证书的设置页面,上面输入你的邮箱,在这里你可以进行一些设置。这里CSR生成我们选择“浏览器生成”,然后点击创建,点击创建后浏览器会下载一个zip压缩包,里面是证书的私钥`private.key`。 [![创建SSL证书](https://api.wuwz.net/distribute/web/zkkme/img/002c/002c-2.png "创建SSL证书")](https://api.wuwz.net/distribute/web/zkkme/img/002c/002c-2.png "创建SSL证书") 4. 然后来到域名验证页面。只要按照要求对域名进行了TXT解析,然后两个都检测通过的话基本上就可以验证成功。 [![域名验证](https://api.wuwz.net/distribute/web/zkkme/img/002c/002c-3.png "域名验证")](https://api.wuwz.net/distribute/web/zkkme/img/002c/002c-3.png "域名验证") 5. 验证成功会得到证书内容如下 [![下载证书文件](https://api.wuwz.net/distribute/web/zkkme/img/002c/002c-4.png "下载证书文件")](https://api.wuwz.net/distribute/web/zkkme/img/002c/002c-4.png "下载证书文件") 点击下载文件会下载一个zip压缩包,里面是申请到的SSL证书和私钥,这个私钥与刚才下载的那个文件相同。保存好这两个文件,后面需要用到 [![SSL证书](https://api.wuwz.net/distribute/web/zkkme/img/002c/002c-5.png "SSL证书")](https://api.wuwz.net/distribute/web/zkkme/img/002c/002c-5.png "SSL证书") ## 编译ngrok服务端 我是在CentOS 7.6系统上安装的ngrok服务端。 ngrok服务端需要Golang语言环境,先安装必要工具 ```shell yum -y install build-essential golang mercurial git ``` - 下载ngrok源码 找一个你喜欢的地方进行ngrok服务端的安装,我用的是`/home` 进入到准备安装ngrok的目录,下载ngrok源码包 ```shell cd /home git clone https://github.com/inconshreveable/ngrok.git ``` 下载完源码包后需要用我们刚刚申请的证书和密钥来替换自带的证书和私钥 - 删除证书 删除自带的证书和密钥 ```shell cd ngrok rm -f assets/server/tls/snakeoil.crt rm -f assets/server/tls/snakeoil.key rm -f assets/client/tls/ngrokroot.crt ``` - 上传证书 上传我们申请的证书和密钥,将`full_chain.pem`和`private.key`上传到`ngrok/assets/server/tls/`目录下,并重命名为`snakeoil.crt`和`snakeoil.key`,如图 [![server证书替换](https://api.wuwz.net/distribute/web/zkkme/img/002c/002c-6.png "server证书替换")](https://api.wuwz.net/distribute/web/zkkme/img/002c/002c-6.png "server证书替换") 将`full_chain.pem`上传到`ngrok/assets/client/tls/`目录下,并重命名为`ngrokroot.crt`,如图 [![ngrokroot.crt上传](https://api.wuwz.net/distribute/web/zkkme/img/002c/002c-7.png "ngrokroot.crt上传")](https://api.wuwz.net/distribute/web/zkkme/img/002c/002c-7.png "ngrokroot.crt上传") - 编译服务端 来到ngrok根目录下,执行编译服务端指令 ```shell cd /home/ngrok make release-server ``` 编译结果如下表示编译成功(此步骤等待时间可能比较长) ```shell 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) 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 //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) 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 //gopkg.in/inconshreveable/go-update.v0/check?go-get=1 get "gopkg.in/inconshreveable/go-update.v0/check": verifying non-authoritative meta tag get "gopkg.in/yaml.v1": found meta tag get.metaImport{Prefix:"gopkg.in/yaml.v1", VCS:"git", RepoRoot:"https://gopkg.in/yaml.v1"} at //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 ``` 编译出的服务端程序的路径为`bin/ngrokd`,我们先尝试运行一下,这里我们尝试使用8888端口来进行http访问,9999端口进行https访问,请确保你所要使用的端口没有被占用 ```shell ./bin/ngrokd -domain="ngrok.zkk.me" -httpAddr=":8888" -httpsAddr=":9999" ``` 输出内容如下表示运行成功 ```shell [00:29:01 CST 2020/04/18] [INFO] (ngrok/log.(*PrefixLogger).Info:83) [registry] [tun] No affinity cache specified [00:29:01 CST 2020/04/18] [INFO] (ngrok/log.Info:112) Listening for public http connections on [::]:8888 [00:29:01 CST 2020/04/18] [INFO] (ngrok/log.Info:112) Listening for public https connections on [::]:9999 [00:29:01 CST 2020/04/18] [INFO] (ngrok/log.Info:112) Listening for control and proxy connections on [::]:4443 [00:29:01 CST 2020/04/18] [INFO] (ngrok/log.(*PrefixLogger).Info:83) [metrics] Reporting every 30 seconds ``` ## 编译并配置ngrok客户端 ### 编译 由于ngrok客户端可能运行于不同平台,所以我们需要针对不同平台执行不同的编译指令。 ```shell # 32位linux客户端 GOOS=linux GOARCH=386 make release-client # 64位linux客户端 GOOS=linux GOARCH=amd64 make release-client # 32位windows客户端 GOOS=windows GOARCH=386 make release-client # 64位windows客户端 GOOS=windows GOARCH=amd64 make release-client # 32位mac平台客户端 GOOS=darwin GOARCH=386 make release-client # 64位mac平台客户端 GOOS=darwin GOARCH=amd64 make release-client # ARM平台linux客户端 GOOS=linux GOARCH=arm make release-client ``` 我使用的是64位windows,所以使用如下指令编译客户端 ```shell GOOS=windows GOARCH=amd64 make release-client ``` 编译输出内容如下 ```shell 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/... go install -tags 'release' ngrok/main/ngrok ``` 编译成功之后,在`bin/windows_amd64`目录下会有一个`ngrok.exe`文件,这就是运行在内网电脑上的客户端 ### 配置 把编译好的`ngrok.exe`下载到内网的电脑上,放到一个你喜欢的位置 在与`ngrok.exe`同级目录下新建一个文件,名为`ngrok.cfg`,并写入以下内容 ```shell server_addr: "ngrok.zkk.me:4443" trust_host_root_certs: false tunnels: http: proto: http: 80 subdomain: "test" https: proto: https: 80 subdomain: "test" ``` 解释一下,这段配置的意思是说在本地新建两个隧道,子域名为`test.ngrok.zkk.me`,当通过`http`形式访问`test.ngrok.zkk.me`时,会转到本地80端口,当通过`https`形式访问时,也转到本地80端口。这里说一下,本地网站Nginx不要配置ssl使用的端口,也就是不区分http和https,只配置http访问的一个端口就可以。如果你本地使用ssl配置的端口的话,浏览器以`https`形式访问时会出现400错误,错误内容是"The plain HTTP request was sent to HTTPS port"。因为无论是http还是https,本地ngrok客户端都会以http形式转发。 ## 运行并测试 > 首先内网电脑上应该先建立一个网站,关于如何在windows系统上使用Nginx和PHP建立网站,请看这一篇笔记:[Windows配置Nginx + PHP](https://zkk.me/0x002b.html "Windows配置Nginx + PHP")。 - 运行服务端 ```shell ./bin/ngrokd -domain="ngrok.zkk.me" -httpAddr=":8888" -httpsAddr=":9999" ``` - 运行客户端 在CMD中切换到`ngrok.exe`所在目录,执行以下命令 ```shell ngrok -config=ngrok.cfg start-all ``` 执行后如果看到如下结果说明非常成功 [![部署成功](https://api.wuwz.net/distribute/web/zkkme/img/002c/002c-8.png "部署成功")](https://api.wuwz.net/distribute/web/zkkme/img/002c/002c-8.png "部署成功") 上面输出的内容意思是:当在浏览器访问http://test.ngrok.zkk.me:8888 时会以http形式转到本地80端口,当在浏览器访问https://test.ngrok.zkk.me:9999 时也会以http形式转到本地80端口。这也是之前我为什么说如果你在ngrok.cfg中的本地使用的端口配置了ssl就会出现400错误。 接着浏览器使用上述地址访问一下,进行验证 [![验证](https://api.wuwz.net/distribute/web/zkkme/img/002c/002c-9.png "验证")](https://api.wuwz.net/distribute/web/zkkme/img/002c/002c-9.png "验证") 成功访问,大功告成! 如果你感觉带着端口访问很不舒服,那你可以看一下这篇文章 [Nginx反代理ngrok,实现80和443端口访问](https://zkk.me/0x002d.html "Nginx反代理ngrok,实现80和443端口访问") > REFERENCE - 在服务器上搭建自己的ngrok服务 -- ruananqing - ngrok、https流量穿透内网配置 -- 蓝猫大哥的博客 - Ngrok实现内网穿透 - ngrok配置ssl证书实现https内网穿透 -- vXZH - Ngrok 服务搭建完全手册 -- Pylixm的技术博客 标签: 内网穿透 如果您对此页面有任何问题或建议,请在本站留言,或联系邮箱me[at]zkk.me本网站部分内容转载自其他网站,如有侵权,请联系博主