id: 784fb8b444b44b47abfd9b4fd7dab820
parent_id: 
item_type: 1
item_id: ea50e7e718014d4ea655de90dc7a0eaa
item_updated_time: 1764365029462
title_diff: "[{\"diffs\":[[1,\"自行编译ngrok服务端客户端，替代花生壳，跨平台_吾爱的博客\"]],\"start1\":0,\"start2\":0,\"length1\":0,\"length2\":31}]"
body_diff: "[{\"diffs\":[[1,\"<html>\\\r\\\n<head>\\\r\\\n  <title>自行编译ngrok服务端客户端，替代花生壳，跨平台_吾爱的博客</title>\\\r\\\n  <basefont face=\\\"微软雅黑\\\" size=\\\"2\\\" />\\\r\\\n  <meta http-equiv=\\\"Content-Type\\\" content=\\\"text/html;charset=utf-8\\\" />\\\r\\\n  <meta name=\\\"exporter-version\\\" content=\\\"YXBJ Windows/608924 (zh-CN, DDL); Windows/10.0.0 (Win64); EDAMVersion=V2;\\\"/>\\\r\\\n  <meta name=\\\"application-data:2525275\\\" content=\\\"6692893/s30/3ab4dbca-53b3-4acb-b204-dca0ef96cf2d/app.yinxiang.com\\\"/>\\\r\\\n  <style>\\\r\\\n\\tbody, td {\\\r\\\n\\t  font-family: 微软雅黑;\\\r\\\n\\t  font-size: 12pt;\\\r\\\n\\t}\\\r\\\n  </style>\\\r\\\n</head>\\\r\\\n<body>\\\r\\\n<a name=\\\"9785\\\"></a>\\\r\\\n<h1>自行编译ngrok服务端客户端，替代花生壳，跨平台_吾爱的博客</h1>\\\r\\\n\\\r\\\n<div>\\\n<span><div>\\\n <div>\\\n  <div>\\\n   <h1>自行编译ngrok服务端客户端，替代花生壳，跨平台</h1>\\\n   <div>\\\n    <div></div>\\\n   </div>\\\n  </div> \\\n  <div>\\\n    阅读:1967 \\\n  </div> \\\n  <blockquote> \\\n   <p>ngrok是一个ddns服务，可以像花生壳一样，为内网机器绑定一个公网域名，方便开发调试远程接口(如微信开发)。</p> \\\n  </blockquote> \\\n  <p>很多人抱怨，微信开发的时候无法在本地实现接口调试，必须将项目放置到一个公网服务器上，有一个正式的域名能否访问，还得是80端口，这样微信那边才能和我们的项目进行通信。</p> \\\n  <p>但是，一般情况下我们的开发环境是在内网，外网无法访问到我们的电脑，而且就算是adsl拨号，电信运营商也不允许使用80端口对外提供服务。</p> \\\n  <p>在这种蛋疼的条件下，机智的程序员们还是有解决办法的：</p> \\\n  <ol><li>用POSTMAN模拟接口访问，局限性很大，比如微信OAUTH授权流程走一个看看?</li><li>本机安装花生壳客户端，为本机绑定一个动态域名，这样只要访问指定的花生壳域名，由花生壳进行反向代理，外面的请求通过花生壳进行转发到本机127.0.0.1，响应包同样通过花生壳进行转发。</li></ol> \\\n  <p>我选择第二种，但是我用不了花生壳，花生壳并没有提供mac os的客户端，所以只能寻找替代方案，答案就是 ngrok。</p> \\\n  <p>ngrok是一款开源的，用go语言开发的动态域名服务，含服务端和客户端，当然，是老外开发的。</p> \\\n  <p>ngrok官网提供了一个官方服务，我们只需要从官网下载客户端即可，很是方便。</p> \\\n  <p>但不幸的是，ngrok官方服务器国内已无法连通，不知道是人家屏蔽了我们，还是我们屏蔽了人家，大家心中有数哈。</p> \\\n  <p>这种境况下，我们大天朝码农还是有办法的，既然人家开源了，那我们自己编译服务端放在自己vps上就是，域名很多人都有吧，不然还搞个毛的web开发。</p> \\\n  <p>天朝已经有位玩家提供了免费的服务，大家到这里查看：http://www.tunnel.mobi/ 。我也用了一段时间，但是昨天突然抽风，给我的开发进度造成了一点损失，所以我决定自己编译一个服务端，接下来进入正题，介绍下我的编译流程。</p> \\\n  <p>编译分两块：</p> \\\n  <ol><li>配套客户端 </li></ol> \\\n  <p>客户端是需要和服务端匹配的，在编译的时候是要指定域名证书的，所以不用担心别人用其他的客户端去连你的服务端。</p> \\\n  <p><strong>编译准备</strong></p> \\\n  <ol><li>一个vps，阿里云或者其他，linux系统即可，这里我推荐debian或ubuntu.</li><li>一个域名，将域名泛解析到你的服务器上。</li><li>为服务器安装git和go</li></ol> \\\n  <p>我就直接在我的博客服务器上编译了，我准备使用 <code>ngrok.ekan001.com</code> 作为动态域名的根，记得泛解析。</p> \\\n  <p>首先我们需要在服务器上安装go环境，我建议下载最新版的go包，直接解压到服务器 <code>/usr/local/go</code> 即可，然后将 <code>/usr/local/go/bin/*</code> 复制到 <code>/usr/bin/</code> 。</p> \\\n  <p>go的下载地址：http://www.golangtc.com/download 下载和你服务器系统对应的版本即可，这里我是linux 64位的，就选择下载 <code>go1.4.2.linux-amd64.tar.gz</code> 即可。</p> \\\n  <p>接着，下载ngrok源码：</p> \\\n  <pre><code> /usr/local/src/\\\ngit clone https://github.com/inconshreveable/ngrok.git\\\nexport GOPATH=/usr/local/src/ngrok/\\\nexport NGROK_DOMAIN=&quot;ngrok.ekan001.com&quot;\\\n ngrok\\\n</code></pre> \\\n  <p><strong>开始编译</strong> </p> \\\n  <ol><li><p>首先为根域名生成证书</p> <pre><code>openssl genrsa -out rootCA.key \\\nopenssl req -x509 - -nodes -key rootCA.key -subj &quot;/CN=$NGROK_DOMAIN&quot; -days  -out rootCA.pem\\\nopenssl genrsa -out device.key \\\nopenssl req - -key device.key -subj &quot;/CN=$NGROK_DOMAIN&quot; -out device.csr\\\nopenssl x509 -req - device.csr -CA rootCA.pem -CAkey rootCA.key -CAcreateserial -out device.crt -days \\\ncp rootCA.pem assets/client/tls/ngrokroot.crt\\\ncp device.crt assets/server/tls/snakeoil.crt \\\ncp device.key assets/server/tls/snakeoil.key\\\n</code></pre></li><li><p>编译服务端</p></li></ol> \\\n  <p>服务端比较容易，先指定一下我的环境变量，然后再make：</p> \\\n  <pre><code>    GOOS=linux GOARCH=amd64\\\n    #如果是32位系统，这里 GOARCH=386\\\n</code></pre> \\\n  <p>然后make</p> \\\n  <pre><code>    make release-server\\\n</code></pre> \\\n  <p>按理讲，应该就可以编译成功了，但是我发现，编译的时候很多依赖包是需要自动下载的，有一个包 <code>4go</code> 是在 code.google 上的，我们天朝服务器是无法访问google的，大家懂，所以我这里是这么处理的：修改源码，将该包改为 github 上的地址:</p> \\\n  <p>找到 <code>/usr/local/src/ngrok/src/ngrok//logger.go</code> ，第五行import中的 log 包，改为： <code> &quot;github.com/keepeye/log4go&quot;</code> 。</p> \\\n  <p>然后重新 <code>make release-server</code> 。</p> \\\n  <p>接下来可能还会遇到一个问题，编译时在 <code>go get gopkg./yaml.v1</code> 步骤时候卡住，这是因为git版本太低，请将服务器git版本升级到1.7.9.5以上。</p> \\\n  <p>编译成功后，应该可以在 <code>/usr/local/src/ngrok/bin</code> 下生成了一个 <code>ngrokd</code> 可执行文件，这就是我们的服务端了，现在启动服务端试试：</p> \\\n  <pre><code>bin/ngrokd -domain=&quot;$NGROK_DOMAIN&quot; -httpAddr=&quot;:8000&quot;\\\n</code></pre> \\\n  <p>如果没有报错的话，会出现以下输出：</p> \\\n  <pre><code>[10:05:48 CST 2015/04/17] [INFO] (ngrok/log.(*PrefixLogger).Info:83) [registry] [tun] No affinity cache specified\\\n[:: CST //] [INFO] (ngrok/.(*PrefixLogger).Info:) [metrics] Reporting every  seconds\\\n[:: CST //] [INFO] (ngrok/.Info:) Listening  public http connections  [::]:\\\n[:: CST //] [INFO] (ngrok/.Info:) Listening  public https connections  [::]:\\\n[:: CST //] [INFO] (ngrok/.Info:) Listening  control  proxy connections  [::]:\\\n</code></pre> \\\n  <p>现在先 <code>ctrl+c</code> 退出，我们还需要编译客户端呢。</p> \\\n  <ol><li>编译客户端</li></ol> \\\n  <p>我的本机系统是 mac osx ，64位，对应的 GOOS 和 GOARCH 是这样的：</p> \\\n  <pre><code>=darwin GOARCH=amd64\\\n</code></pre> \\\n  <p>然后我直接编译：</p> \\\n  <pre><code> release-client\\\n</code></pre> \\\n  <p>编译是成功了，但是我发现编译出来的东西是 <code>bin/ngrok</code> ，它还是linux平台的包，我mac上无法执行。原因是我们没有为go生成交叉编译环境，需要补充下面的一个步骤：</p> \\\n  <p>前文说到，我们的 go 安装在 <code>/usr/local/go</code> ，现在我们执行下面的命令：</p> \\\n  <pre><code> /usr/local/go/src\\\nGOOS=darwin GOARCH=amd64 ./make.bash\\\n</code></pre> \\\n  <p>然后回去ngrok目录，接着编译：</p> \\\n  <pre><code> -\\\nGOOS=darwin GOARCH=amd64 make release-client\\\n</code></pre> \\\n  <p>完了以后可以在 <code>/usr/local/src/ngrok/bin/darwin_amd64/</code> 下发现 <code>ngrok</code> 文件，将它拷贝到我的mac上。</p> \\\n  <p>如果是windows下的客户端，是这样的：</p> \\\n  <pre><code> /usr/local/go/src\\\nGOOS=windows GOARCH=amd64 ./make.bash\\\n -\\\nGOOS=windows GOARCH=amd64 make release-client\\\n#同理，这里的amd64是64位系统，32位改成386\\\n#应该会在 bin/windows_amd64 目录下生成ngrok客户端程序\\\n</code></pre> \\\n  <p>到这里，编译就完成了，现在让我们把应用跑起来：</p> \\\n  <p>按之前的方式启动服务端ngrokd，有以下提示：</p> \\\n  <pre><code>Listening  public  connections  :8000\\\nListening  control  proxy connections  :4443\\\n</code></pre> \\\n  <p>记住这两个端口 8000 和 4443 。</p> \\\n  <p>现在我们来到自己电脑上，准备启动客户端。在启动之前，我们需要为客户端编写一个配置文件 ngrok.cfg ：</p> \\\n  <pre><code>server_addr: &quot;ngrok.ekan001.com:4443&quot;\\\ntrust_host_root_certs: false\\\n</code></pre> \\\n  <p>注意，配置文件中用的是4443端口。</p> \\\n  <p>然后启动客户端，假设我们要分配一个域名 <code>test.ngrok.ekan001.com</code> 执行以下命令：</p> \\\n  <pre><code>./ngrok -config=./ngrok.cfg -subdomain= \\\n</code></pre> \\\n  <p>解释一下参数：</p> \\\n  <pre><code>-config 就是上面配置文件ngrok.cfg的路径\\\n-subdomain 就是需要分配域名的前缀部分\\\n80 就是本机websever的端口，比如apache监听的端口，一会ngrok会将请求映射到该端口上。\\\n</code></pre> \\\n  <p>如果没错误，应该会出现以下的输出：</p> \\\n  <pre><code>Tunnel Status                 online\\\nVersion                       ./.\\\nForwarding                    http://test.ngrok.ekan001.com:8000 -&gt; 127.0.0.1:80\\\nForwarding                    https://test.ngrok.ekan001.com:8000 -&gt; 127.0.0.1:80\\\nWeb Interface                 127.0.0.1:4040\\\n# Conn                        0\\\nAvg Conn Time                 .\\\n</code></pre> \\\n  <p>现在，访问 <code>.ngrok.ekan001:8000</code> ,ngrok服务端就会讲请求转发到我们本地客户端，再由客户端转发给我们的webserver 80端口。所以，我们只需要配置apache或nginx，添加虚拟主机，绑定域名 <code>test.ngrok.ekan001.com</code> 即可。</p> \\\n  <p><strong>事情还没有结束！</strong></p> \\\n  <p>我们前面提到，微信开发中的api地址，是不认80以外的端口的，所以如果我们将 <code>.ngrok.ekan001:8000</code> 作为接口域名，得到的只能是 非法地址 或 配置失败 这个提示。</p> \\\n  <p>为什么在启动服务端的时候，端口不指定为80呢?就像下面：</p> \\\n  <pre><code>bin/ngrokd -domain=&quot;$NGROK_DOMAIN&quot; -httpAddr=&quot;:80&quot;\\\n</code></pre> \\\n  <p>很遗憾，因为这台vps不是只用来做ngrok服务的，我博客还在上面呢，80端口已经被nginx占用了。</p> \\\n  <p>那怎么办？</p> \\\n  <p>不得不提nginx是个牛逼的软件，我们可以在nginx中配置一个server,就绑定 <code>test.ngrok.ekan001.com</code> 域名，然后将所有请求转发到后端 <code>:8000</code> 端口上，这就是反向代理。我发一下自己的nginx配置：</p> \\\n  <pre><code>#ngrok.ekan001.com.conf\\\nupstream nodejs {\\\n    server 127.0.0.1:8000;\\\n    keepalive ;\\\n}\\\n\\\nserver {\\\n    listen ;\\\n    server_name *.ngrok.ekan001.com;\\\n    access_log /home/wwwlogs/ngrok.ekan001.log;\\\n    location / {\\\n        proxy_set_header X-Real-IP $remote_addr;\\\n        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\\\n        proxy_set_header Host  $http_host:;\\\n        proxy_set_header X-Nginx-Proxy ;\\\n        proxy_set_header Connection ;\\\n        proxy_pass      http://nodejs;\\\n\\\n    }\\\n\\\n}\\\n</code></pre> \\\n  <p>生命在于折腾，enjoy it!</p> \\\n  <p>[1] http://www.haiyun.me/archives/1012.html<br clear=\\\"none\\\"/> [2] http://blog.csdn.net/savechina/article/details/5612399<br clear=\\\"none\\\"/> [3] http://www.golangtc.com/download </p> \\\n  <p> 转载请注明出处：<a href=\\\"http://www.ekan001.com/articles/38\\\" shape=\\\"rect\\\" target=\\\"_blank\\\">自行编译ngrok服务端客户端，替代花生壳，跨平台</a> </p> \\\n </div>\\\n</div></span>\\\n</div></body></html>\\u0000\"]],\"start1\":0,\"start2\":0,\"length1\":0,\"length2\":8098}]"
metadata_diff: {"new":{"id":"ea50e7e718014d4ea655de90dc7a0eaa","parent_id":"f67288c3a0be4374b5d532b5dcc3aabc","latitude":"0.00000000","longitude":"0.00000000","altitude":"0.0000","author":"","source_url":"","is_todo":0,"todo_due":0,"todo_completed":0,"source":"joplin-desktop","source_application":"net.cozic.joplin-desktop","application_data":"","order":1764348874728,"user_updated_time":1764345565121,"markup_language":2,"is_shared":0,"share_id":"","conflict_original_id":"","master_key_id":"","user_data":"","deleted_time":1764365029462},"deleted":[]}
encryption_cipher_text: 
encryption_applied: 0
updated_time: 2025-11-28T21:24:57.531Z
created_time: 2025-11-28T21:24:57.531Z
type_: 13