使用ngrok搭建内网穿透服务

这篇文章记录一下我用服务器搭建ngrok实现外网穿透内网的过程。

为什么需要内网穿透?

先来描述一个场景:最近在服务器上部署了 jenkins,用来自动化构建项目,部署的过程中发现,自动化打包 iOS App 的话,需要调用 Xcode 的服务,而 Xcode 只有在 macOS 才有,所以需要使用本地的 Mac 来作为 jenkins 的 slave 节点。当 jenkins 需要构建 iOS 项目时,把构建命令发送给 slave 节点来构建。这里就需要 jenkins 服务器能够联络到本地的 Mac,而本地 Mac 是没有公网 ip 的,这时候公网服务器就不能和内网 Mac 用 HTTP(s)/TCP 通讯了,而 ngrok 就是用来解决外网服务器和内网设备通讯的。

准备工作

  • 一台具有公网 IP 的 云主机或VPS。
  • 把域名解析到这台公网服务器上。(使用一个二级域名即可,例如: ngrok.domain.com)

搭建 ngrok 编译环境

ngrok 是用 go 语言写的,编译 ngrok 要在服务器上安装 go。

去到 go 的官方下载页面 找到 Linux 版本的下载链接,复制,下载好安装包。

1
$ wget https://dl.google.com/go/go1.10.2.linux-amd64.tar.gz # 当前最新版本go1.10.2

解压go1.10.2.linux-amd64.tar.gz

1
$ tar -zxvf go1.10.2.linux-amd64.tar.gz

移动解压好的 go 目录到 /usr/local/ 目录下。

1
$ mv go /usr/local/

把 go 的命令软链接到 /usr/bin/

1
$ ln -s /usr/local/go/bin/* /usr/bin/

编译 ngrok

克隆 ngrok 仓库到服务器

1
$ git clone https://github.com/inconshreveable/ngrok.git # 这里我把 ngrok 仓库克隆到了当前用户的根目录下(~/) 

设置 go 的 workspace 目录为 ngrok 目录。

1
$ export GOPATH=/home/username/local/ngrok/

进入 ngrok 目录

1
$ cd ngrok

为域名生成证书

1
2
3
4
5
$ openssl genrsa -out rootCA.key 2048
$ openssl req -x509 -new -nodes -key rootCA.key -subj "/CN=你的域名" -days 5000 -out rootCA.pem
$ openssl genrsa -out server.key 2048
$ openssl req -new -key server.key -subj "/CN=你的域名" -out server.csr
$ openssl x509 -req -in server.csr -CA rootCA.pem -CAkey rootCA.key -CAcreateserial -out server.crt -days 5000

把生成的证书拷贝到指定位置

1
2
3
$ cp rootCA.pem assets/client/tls/ngrokroot.crt
$ cp server.crt assets/server/tls/snakeoil.crt
$ cp server.key assets/server/tls/snakeoil.key

把 rootCA.pem 证书下载到本地,双击添加进钥匙串并信任证书。

信任证书

如果使用的是国内大陆的服务器,需要做以下修改(墙外的IP不需要)

1
2
$ nano /usr/local/ngrok/src/ngrok/log/logger.go
log "github.com/keepeye/log4go"

指定编译环境变量

1
2
3
4
5
$ cd /home/username/ngrok/
$ GOOS=linux GOARCH=amd64 # Linux 64bit
$ make release-server # 编译 ngrok 服务端
$ GOOS=darwin GOARCH=amd64 # macOS
$ make release-client # 编译 ngrok Mac客户端

到此,Linux 服务器下的 ngrokd 服务端 和 macOS 下的 ngrok 客户端都编译好了,位于 /ngrok/bin/目录下。

ngrokd 在服务器运行,ngrok 下载到本地 macOS 上运行。

这里放一个编译好的 ngrok macOS 客户端文件 ngrok_macOS_release_client

启动内网穿透服务

服务端启动命令,注意这里要修改防火墙策略开放相应端口(云主机修改安全组策略,一般VPS端口默认开放)。

1
2
$ cd /home/username/ngrok/bin/
$ ./ngrokd -domain="你的域名" -httpAddr=":8081" -httpsAddr=":8082" # 指定 http/https 转发端口

本地 macOS 创建 ngrok.cfg 配置文件

1
2
3
$ nano ngrok.cfg
server_addr: "你的域名:4443"
trust_host_root_certs: true

客户端启动命令

1
2
3
4
# cd 到 ngrok 所在的目录
$ chmod +x ngrok
$ ./ngrok -proto=tcp -config=ngrok.cfg 22 # 使用tcp协议转发本地22端口。
$ ./ngrok -subdomain test -config=ngrok.cfg 80 # 使用http/https协议转发本地80端口

成功

本文为 oxo.red 原创手打笔记。

ngrok 官方教程:https://sunnyos.com/article-show-48.html

参考文章:https://tonybai.com/2015/03/14/selfhost-ngrok-service/

作者

Han

发布于

2018-05-16

更新于

2021-08-20

许可协议

评论