id: e5be3d3aea5447f88b3cb7a8b39e0c12
parent_id: 
item_type: 1
item_id: b81f3b5cd4a84321b12c0d37c3fc5975
item_updated_time: 1764365022745
title_diff: "[{\"diffs\":[[1,\"搭建 ngrok 服务实现内网穿透  JerryQu 的小站\"]],\"start1\":0,\"start2\":0,\"length1\":0,\"length2\":30}]"
body_diff: "[{\"diffs\":[[1,\"<html>\\\r\\\n<head>\\\r\\\n  <title>搭建 ngrok 服务实现内网穿透 | JerryQu 的小站</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/23289775-0bfd-4b15-902e-c55d2d4b1573/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=\\\"9786\\\"></a>\\\r\\\n<h1>搭建 ngrok 服务实现内网穿透 | JerryQu 的小站</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   <p>我们经常会有「把本机开发中的 web 项目给朋友看一下」这种临时需求，为此专门在 VPS 上部署一遍就有点太浪费了。之前我通常是在 ADSL 路由器上配个端口映射让本机服务在外网可以访问，但现在大部分运营商不会轻易让你这么干了。一般小运营商也没有公网 IP，自己的路由器出口还是在局域网内，端口映射这种做法就不管用了。</p> \\\n   <p>之前我就想过能否借助拥有公网 IP 的主机中转来实现这种需求，后来发现已经有这样的软件了：ngrok。而且 ngrok 官网本身还提供了公共服务，只需要注册一个帐号，运行它的客户端，就可以快速把内网映射出去。不过这么好的服务，没多久就被墙了~</p> \\\n   <p>好在 ngrok 是<a href=\\\"https://github.com/inconshreveable/ngrok/\\\" shape=\\\"rect\\\" target=\\\"_blank\\\">开源</a>的，我在 VPS 上搭了一套服务自己用，一劳永逸地解决了内网穿透这个难题，这里记录一下过程。（注意：ngrok.com 提供的服务是基于 ngrok 2.0，github 上目前只有 1.0 的源码，二者功能和命令有一些区别，用的时候别搞混了）</p> \\\n   <h3>编译 ngrok</h3> \\\n   <p>我的 VPS 系统是 Ubuntu 14.04.2 LTS，首先装必要的工具：</p> \\\n   <pre><code>sudo apt-get install build-essential golang mercurial git\\\n</code></pre> \\\n   <p>获取 ngrok 源码：</p> \\\n   <pre><code>git clone https://github.com/inconshreveable/ngrok.git ngrok\\\n ngrok\\\n</code></pre> \\\n   <p>生成并替换源码里默认的证书，注意域名修改为你自己的。（之后编译出来的服务端客户端会基于这个证书来加密通讯，保证了安全性）</p> \\\n   <pre><b>BASH</b><code>NGROK_DOMAIN=&quot;imququ.com&quot;\\\n\\\nopenssl genrsa -out base.key \\\nopenssl req -new -x509 -nodes -key base.key -days 10000 -subj &quot;/CN=$NGROK_DOMAIN&quot; -out base.pem\\\nopenssl genrsa -out server.key \\\nopenssl req -new -key server.key -subj &quot;/CN=$NGROK_DOMAIN&quot; -out server.csr\\\nopenssl x509 -req -in server.csr -CA base.pem -CAkey base.key -CAcreateserial -days 10000 -out server.crt\\\n\\\ncp base.pem assets/client/tls/ngrokroot.crt\\\n</code></pre> \\\n   <p>开始编译：</p> \\\n   <pre><code>sudo make release-server release-client\\\n</code></pre> \\\n   <p>如果一切正常，ngrok/bin 目录下应该有 ngrok、ngrokd 两个可执行文件。</p> \\\n   <p>前面生成的 ngrokd 就是服务端程序了，指定证书、域名和端口启动它（证书就是前面生成的，注意修改域名）：</p> \\\n   <pre><code>sudo ./bin/ngrokd -tlsKey=server.key -tlsCrt=server.crt -domain=&quot;imququ.com&quot; -httpAddr=&quot;:8081&quot; -httpsAddr=&quot;:8082&quot;\\\n</code></pre> \\\n   <p>到这一步，ngrok 服务已经跑起来了，可以通过屏幕上显示的日志查看更多信息。httpAddr、httpsAddr 分别是 ngrok 用来转发 http、https 服务的端口，可以随意指定。ngrokd 还会开一个 4443 端口用来跟客户端通讯（可通过 -tunnelAddr=&quot;:xxx&quot; 指定），如果你配置了 iptables 规则，需要放行这三个端口上的 TCP 协议。</p> \\\n   <p>现在，通过 <a href=\\\"https://imququ.com:8081/\\\" shape=\\\"rect\\\" target=\\\"_blank\\\">https://imququ.com:8081</a> 和 <a href=\\\"https://imququ.com:8082/\\\" shape=\\\"rect\\\" target=\\\"_blank\\\">https://imququ.com:8082</a> 就可以访问到 ngrok 提供的转发服务。为了使用方便，建议把域名泛解析到 VPS 上，这样能方便地使用不同子域转发不同的本地服务。我给 imququ.com 做了泛解析，随便访问一个子域，如：<a href=\\\"http://pub.imququ.com:8081/\\\" shape=\\\"rect\\\" target=\\\"_blank\\\">http://pub.imququ.com:8081</a>，可以看到这样一行提示：</p> \\\n   <pre><code>Tunnel pub.imququ.com: not found\\\n</code></pre> \\\n   <p>这说明万事俱备，只差客户端来连了。</p> \\\n   <p>如果要把 linux 上的服务映射出去，客户端就是前面生成的 ngrok 文件。但我用的是 Mac，需要指定环境变量再编一次：</p> \\\n   <pre><code>sudo GOOS=darwin GOARCH=amd64 make release-server release-client\\\n</code></pre> \\\n   <p>这样在 ngrok/bin 目录下会多出来一个 darwin_amd64 目录，这里的 ngrok 文件就可以拷到 Mac 系统用了。</p> \\\n   <p>写一个简单的配置文件，随意命名如 ngrok.cfg：</p> \\\n   <pre><code>server_addr: imququ.com:\\\ntrust_host_root_certs: false\\\n</code></pre> \\\n   <p>指定子域、要转发的协议和端口，以及配置文件，运行客户端：</p> \\\n   <pre><code>./ngrok -subdomain pub -proto=http -config=ngrok.cfg \\\n</code></pre> \\\n   <p>不出意外可以看到这样的界面，这说明已经成功连上远端服务了：</p> \\\n   <p></p>\\\n   <div>\\\n    <img alt=\\\"ngrok_client\\\" src=\\\"https://imququ.com/static/uploads/2015/04/ngrok_client.png.webp\\\"></img>\\\n   </div>\\\n   <p></p> \\\n   <p>现在再访问 <a href=\\\"http://pub.imququ.com:8081/\\\" shape=\\\"rect\\\" target=\\\"_blank\\\">http://pub.imququ.com:8081</a>，访问到的已经是我本机 80 端口上的服务了。</p> \\\n   <p>上面那张 ngrok 客户端运行界面截图中，有一个 Web Interface 地址，这是 ngrok 提供的监控界面。通过这个界面可以看到远端转发过来的 http 详情，包括完整的 request/response 信息，非常方便。</p> \\\n   <p></p>\\\n   <div>\\\n    <img alt=\\\"ngrok_manager\\\" src=\\\"https://imququ.com/static/uploads/2015/04/ngrok_manager.png.webp\\\"></img>\\\n   </div>\\\n   <p></p> \\\n   <p>实际上，由于 ngrok 可以转发 TCP，所以还有很多玩法，原理都一样，这里就不多写了。</p> \\\n   <p>本文链接：<a href=\\\"https://imququ.com/post/self-hosted-ngrokd.html\\\" shape=\\\"rect\\\" target=\\\"_blank\\\" title=\\\"Permalink to 搭建 ngrok 服务实现内网穿透\\\">https://imququ.com/post/self-hosted-ngrokd.html</a>，<a href=\\\"https://imququ.com/post/self-hosted-ngrokd.html#comments\\\" shape=\\\"rect\\\" target=\\\"_blank\\\">参与评论</a>。</p>\\\n   <p>--<acronym>EOF</acronym>--</p>\\\n   <p>于 2015-04-19 11:17:50 发表于「<a href=\\\"https://imququ.com/category/dev.html\\\" shape=\\\"rect\\\" target=\\\"_blank\\\">WEB 后端</a>」分类下，并被添加「<a href=\\\"https://imququ.com/tag/HTTP.html\\\" shape=\\\"rect\\\" target=\\\"_blank\\\">HTTP</a>、<a href=\\\"https://imququ.com/tag/%E4%BB%A3%E7%90%86.html\\\" shape=\\\"rect\\\" target=\\\"_blank\\\">代理</a>」标签。</p>\\\n   <p>提醒：本文最后更新于 200 天前，文中所描述的信息可能已发生改变，请谨慎使用。</p>\\\n   <p>本站部署于「<a href=\\\"http://www.aliyun.com/product/ecs/\\\" shape=\\\"rect\\\" target=\\\"_blank\\\">阿里云 ECS</a>」。如果你也要购买阿里云服务，可以使用我的九折推荐码 <strong><em>NY1Z0E</em></strong>（限新用户），多谢支持！</p>\\\n  </div>\\\n </div>\\\n</div></span>\\\n</div></body></html>\\u0000\"]],\"start1\":0,\"start2\":0,\"length1\":0,\"length2\":5235}]"
metadata_diff: {"new":{"id":"b81f3b5cd4a84321b12c0d37c3fc5975","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":1764348856899,"user_updated_time":1764345565122,"markup_language":2,"is_shared":0,"share_id":"","conflict_original_id":"","master_key_id":"","user_data":"","deleted_time":1764365022745},"deleted":[]}
encryption_cipher_text: 
encryption_applied: 0
updated_time: 2025-11-28T21:24:52.617Z
created_time: 2025-11-28T21:24:52.617Z
type_: 13