在 CentOS 搭建 ngrok server,进行内网穿透

在日常开发环境中,可能会碰到需要内网穿透的一些需求,如微信小程序的开发,为了便于开发调试,需要将内网机器对外暴露,较便捷的方式有(难易度由上往下依次繁琐):

  • 使用 ngrok 等类似客户端,通过别人架设的服务器进行内网穿透,较为灵活,可自建服务器。
  • 注册一个花生壳,使用其推出的内网穿透服务,有的时候会抽风,且 ssl 域名存在不够用的情况需增购。
  • 在外网架一个 nginx,通过在路由器设置 NAT 后,转发到内网机器上,灵活度较高,但需拥有路口路由器配置权限。

本文主要讲解如何使用 ngrok 自建一个内网穿透服务器,通过本文,你可以掌握:

  1. 在 centos 等其他 linux 衍生版本上搭建一个 ngrok server。

  2. 通过 openssl 生成证书。

  3. 在 windows,linux,arm 系统上使用生成 ngrok 客户端进行内网穿透。

1. 准备工作

一些说明:

  • 本问编写时,系统环境为 CenntOS 7.6,win10 1903。

  • 包管理工具使用的是 yum ,源默认情况下使用的是 阿里镜像。

  • 需要 golang 环境:go1.11.5 linux/amd64。

  • git 客户端(可选)。

  • SSL 证书:使用 openssl 生成。

  • 使用 go 编译服务端和客户端用执行文件。

1.1 域名解析

  • 增加泛子域名和普通子域名解析

1.2 配置环境

  1. ngrok 基于golang,若没有 golang 环境的需进行安装。

1
sudo yum install -y golang
  1. 将 ngrok.git 克隆一份下来,也可以直接下载后直接拷贝至服务器,按需即可。如果没有安装 git 客户端或者版本太低需升级,可通过如下命令进行安装/更新。

  • 查看版本信息:

  • 更新/安装 git

1
2
3
4
yum remove git
yum install epel-release
yum install https://centos7.iuscommunity.org/ius-release.rpm
yum install git2u
  • 本博文发布时,镜像中的 git 版本为 2.16.5

  • 克隆 ngrok 库到本地

1
2
cd /etc
git clone https://github.com/inconshreveable/ngrok

1.3 SSL 证书

1
2
3
4
5
6
7
8
9
10
11
12
13
#1.指定 ngrok 所用域名:这里以域名 bangwogaoding.com 为例
export NGROK_DOMAIN="ngrok.bangwogaoding.com";
#2.直接使用自带 ssl 证书生成工具:
#2.1 key 文件
openssl genrsa -out bangwogaodingCA.key 2048
#2.2 pem 文件
openssl req -x509 -new -nodes -key bangwogaodingCA.key -subj "/CN=$NGROK_DOMAIN" -days 3650 -out bangwogaodingCA.pem
#2.3 客户端 key
openssl genrsa -out ngrokClientCA.key 2048
#2.3 客户端 csr 文件
openssl req -new -key ngrokClientCA.key -subj "/CN=$NGROK_DOMAIN" -out ngrokClientCA.csr
#2.5 创建私钥
openssl x509 -req -in ngrokClientCA.csr -CA bangwogaodingCA.pem -CAkey bangwogaodingCA.key -CAcreateserial -out ngrokClientCA.crt -days 3650
  • 上面生成的 bangwogaodingCA.pem,ngrokClientCA.crt,ngrokClientCA.key 复制到
    assets/client/tls 和 assets/server/tls,这两个目录分别存放着ngrok和ngrokd的默认证书。具体如下:

1
2
3
cp bangwogaodingCA.pem assets/client/tls/ngrokroot.crt
cp ngrokClientCA.crt assets/server/tls/snakeoil.crt
cp ngrokClientCA.key assets/server/tls/snakeoil.key

1.4 编译 ngrokd 和 ngrok 可执行文件

ngrokd 是服务端的执行文件

ngrok 是客户端的执行文件

1
2
3
4
#编译服务端,生成的文件在 ./bin 文件夹对应的目录中,如:ngrokd
GOOS="linux" GOARCH="amd64" make release-server
#编译客户端,生成的文件在 ./bin 文件夹对应的目录中,如 windows_amd64
GOOS="windows" GOARCH="amd64" make release-client

GOOS 和 GOARCH 说明:

  • 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

启动 ngrokd 服务器

1
2
cd /etc/ngrok/bin
./ngrokd -domain="ngrok.bangwogaoding.com" -httpAddr=":80" -httpsAddr=":443"

启动 ngrok 客户端

  • 生成的客户端位于生成目录下的 /bin 文件夹内,如:

  • 可使用 ftp 工具将其拷贝至需要内网穿透的电脑中,这里以 windows 系统为例:

  1. 复制 ngrokd.exe 到本地文件夹

  2. 增加配置文件 config.d

1
2
3
#config.d 内容,请自行使用一开始解析的子域名
server_addr: "ngrok.bangwogaoding.com:4443"
trust_host_root_certs: false
  1. 启动客户端

1
2
3
4
# config.d 为上面增加的配置文件,也可不使用配置文件,直接显式指定。
# demo:subdomain,即设定的泛子域名
# 5002 端口,表示的是本机需要对外穿透出去的端口
ngrok.exe -config=config.d -subdomain=demo -log=log.txt 5002
  1. 关于第三点,也可以使用批处理文件方便调整和修改。

1
2
3
# run.bat
@echo off
ngrok.exe -config=config.d -subdomain=demo -log=log.txt 5002

效果

  1. 内网需要穿透的站点如下:

  1. 启动客户端

  1. 外网访问效果

注意事项

  1. 防火墙启用的状态下,确保服务器的端口都打开,如 4443 是必须的,其他的,如 80,443端口根据你自己需要打开。

1
2
# 查看目前已经打开的端口
firewall-cmd --list-ports
  1. 如果使用的是 云资源,如阿里云,华为,腾讯,AWS等,请确保相关安全组已经允许通过 443,80,4443 等端口。

参考

https://www.svenbit.com/2014/09/run-ngrok-on-your-own-server/

https://tonybai.com/2015/03/14/selfhost-ngrok-service/

https://github.com/inconshreveable/ngrok/blob/master/docs/SELFHOSTING.md