Skip to content

Ngrok实现内网穿透

ngrok是一种反向代理服务,能够实现内网穿透。首先介绍其官网实现,再自建ngrok服务器

官网实现

ngrok官网已经搭建好了服务器,同时提供了客户端以及详细的教程

注册好后登录到个人主页,下载客户端进行配置

  1. 下载客户端
  2. 解压压缩包
  3. 运行客户端程序添加账户的authtoken到配置文件ngrok.yml
  4. 启动客户端

配置文件ngrok.yml默认放置在~/.ngrok2目录下

ngrok可使用不同协议进行通信,当前实现ssh连接,执行如下命令:

$ ./ngrok tcp 22

配置成功后在官网个人主页的状态栏中会列出连接的信息

这样就可以在本地打开命令行窗口连接到内网

$ ssh -p 12544 内网服务器用户名@0.tcp.ngrok.io
The authenticity of host '[0.tcp.ngrok.io]:12544 ([3.17.202.129]:12544)' can't be established.
ECDSA key fingerprint is SHA256:YXdgs3OJN0yxuNLLU.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '[0.tcp.ngrok.io]:12544,[3.17.202.129]:12544' (ECDSA) to the list of known hosts.
Welcome to Ubuntu 16.04.4 LTS (GNU/Linux 4.4.0-130-generic x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/advantage

544 packages can be updated.
393 updates are security updates.

Last login: Thu Jul 11 11:00:36 2019 from 127.0.0.1
$ 

自建ngrok服务器

使用官网服务器进行内网穿透很方便,不过其延迟比较大,估计是因为服务器都搭建在国外,作者inconshreveable开源了其ngrok实现,所以可以自建服务器进行配置

共分为6

  1. SSL证书配置
  2. DNS修改
  3. 客户端和服务器软件编译
  4. 服务器软件运行
  5. 客户端配置
  6. 客户端运行

SSL证书配置

ngrok通过SSL证书进行安全通信,有两种方式创建SSL证书,一是购买公共SSL证书,另一种是自建SSL证书,我在阿里云上购买了免费的SSL证书

证书申请成功后下载解压后得到两个文件:***.key***.pem

如果不是使用https隧道(比如http隧道、ssh隧道等),在证书上绑定指定域名即可,比如ngrok.xxx.com;否则添加一个通配符(wildcard)域名,比如*.xxx.com

DNS修改

自建服务器需要申请一个域名,同时在DNS解析设置上新增一条A记录,将指定域名和服务器IP进行绑定

客户端和服务器软件编译

环境配置

当前使用腾讯云服务器,首先配置运行环境(编译器+go环境)

$ sudo apt-get install mercurial git gcc g++

参考Go Getting Started进行安装

# 下载已编译压缩包
$ wget https://dl.google.com/go/go1.12.1.linux-amd64.tar.gz
# 解压到指定路径
$ sudo tar -C /usr/local -xzf go1.12.1.linux-amd64.tar.gz
# 设置全局变量
$ export PATH=$PATH:/usr/local/go/bin
# 测试
$ go version
go version go1.12.1 linux/amd64

设置环境变量GOOS/GOARCH为指定服务器和客户端平台,比如

$ export GOOS=linux
$ export GOARCH=amd64

ngrok编译

下载ngrok源码

$ git clone https://github.com/inconshreveable/ngrok.git

编译服务器和客户端软件

# 两个平台都一样的话同时编译
$ make release-all
# 或者分开编译,注意GOOS/GOARCH设置
$ make release-server
$ make release-client

生成的文件在bin目录下,ngrok是客户端应用,ngrokd是服务器应用

服务器软件运行

运行如下命令:

$ ./ngrokd -tlsKey=a.key -tlsCrt=a.pem -domain="ngrok.example.com" -httpAddr=":6060" -httpsAddr=":6061" -tunnelAddr=":6062"
  • tlsKeytlsCrt表示SSL证书地址
  • domain表示之前配置的域名
  • ngrok服务器会监听HTTPS/HTTPSs/TCP端口,默认是80/443/4443,修改为其他端口号

注意:腾讯云服务器上需要在安全组设置中开放上述端口号

客户端配置

下载编译好的ngrok到内网电脑上,创建配置文件ngrok.cfg:

$ cat ngrok.cfg 
server_addr: ngrok.xxx.xxx:6062
trust_host_root_certs: true
tunnels:
  ssh:
    remote_port: 12345
    proto:
      tcp: 22

配置文件指定了远程服务器地址和端口号,并指定了远程映射的端口号12345以及使用的协议和本地端口号22,表明将远程端口号12345和本地端口号22进行绑定

参数trust_host_root_certs用于SSL证书配置,如果使用了公共证书,设置为true;如果使用了私有证书,设置为false

注意:同样需要在安全组中开放端口12345

客户端运行

运行如下命令:

$ ./ngrok -config ngrok.cfg -log ngrok.log start ssh

参数config指定配置文件,参数log指定日志文件

运行成功后就可以打开命令行窗口登录

$ ssh -p 12345 zj@ngrok.xxx.xxx  # zj是内网的用户名
Welcome to Ubuntu 16.04.4 LTS (GNU/Linux 4.4.0-130-generic x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/advantage

544 packages can be updated.
393 updates are security updates.

Last login: Thu Jul 11 12:25:19 2019 from 127.0.0.1
$ 

系统服务设置

外网服务器系统服务配置

在云服务器上新建ngrokd.service,目录是/etc/systemd/system/

$ cat ngrokd.service 
[Unit]
Description=ngrok

[Service]
ExecStart=/bin/bash /opt/ngrokd/ngrokd.sh

[Install]
WantedBy=multi-user.target

赋予可执行权限777

$ sudo chmod 777 ngrokd.service

其作用是执行/opt/ngrokd/ngrokd.sh脚本,脚本实现如下:

$ cat ngrokd.sh 
#!/bin/bash

cd /opt/ngrokd

./ngrokd -tlsKey=a.key -tlsCrt=a.pem -domain="ngrok.zhujian.com" -httpAddr=":6060" -httpsAddr=":6061" -tunnelAddr=":6062"

同样授予脚本可执行权限

内网服务器系统服务配置

同样在内网电脑上编写脚本ngrok.sh

#!/bin/bash

cd /opt/ngrok

./ngrok -config ngrok.cfg -log ngrok.log start ssh

/etc/systemc/system目录下编写服务ngrok.service

[Unit]
Description=ngrok

[Service]
ExecStart=/bin/bash /opt/ngrok/ngrok.sh

[Install]
WantedBy=multi-user.target

注意:基于脚本和服务程序可执行权限

启动服务

使用命令systemctl分别启动系统服务ngrokd.servicengrok.service

$ sudo systemctl start ngrok.service

相关阅读