使用Ngrok实现内网穿透服务
# 使用Ngrok实现内网穿透服务
tags: 网络 Linux ngrok
ngrok是什么?
ngrok是一个能够实现不能直接与外网沟通的设备,通过外网服务器的转发实现自我服务器化的软件,也就是不需要通过路由器的端口映射,就能实现内网设备向外网暴露端口的软件。
实现ngrok服务需要什么?
需要一个能够提供服务的外网服务器,并运行ngrok服务端,它将默认监听4443端口,当内网的机器运行ngrok客户端并连接上服务器时,将通过4443端口进行转发设置,并按设定将指定的端口的数据动作与服务器进行转发。协议上它支持http,https,tcp协议
如何搭建自己的ngrok服务器
最新版ngrok目前仅由官方提供技术支持和服务器,开源的ngrok代码只支持到1.7版本,只有自己编译的ngrok才能在自己的服务器上提供内网穿透服务。ngrok使用GO语言编写,可以自己配置实现交叉编译,全平台通用
一. 软件的编译
以下动作发生在debian 8.2 x86平台
1. 编译安装GO
建议安装1.4版本平台,由于软件开发时间问题,新版本的GO可能会出现编译问题
下载GO1.4
# pwd
# ~/Software
# apt-get install gcc cmake
# wget http://www.golangtc.com/static/go/1.4/go1.4.linux-386.tar.gz
# tar xvf http://www.golangtc.com/static/go/1.4/go1.4.linux-386.tar.gz
配置编译环境
# export GOROOT=$HOME/software/go
# export PATH=$PATH:$GOROOT/bin
编译&检查
# cd go/src/
# ./all.bash
编译完成后~/go/bin中的go就是我们的二进制go程序
2. 编译安装ngrok
下载ngrok
# cd ~/software
# git clone https://github.com/inconshreveable/ngrok.git ngrok
# cd ngrok
配置ssl证书信息
# NGROK_DOMAIN="moonwalker.me"
注意域名换成你自己的
# openssl genrsa -out base.key 2048
# openssl req -new -x509 -nodes -key base.key -days 10000 -subj "/CN=$NGROK_DOMAIN" -out base.pem
# openssl genrsa -out server.key 2048
# openssl req -new -key server.key -subj "/CN=$NGROK_DOMAIN" -out server.csr
# openssl x509 -req -in server.csr -CA base.pem -CAkey base.key -CAcreateserial -days 10000 -out server.crt
将生成的证书文件拷贝到指定位置,替代默认证书
# cp base.pem assets/client/tls/ngrokroot.crt
# cp server.crt assets/server/tls/snakeoil.crt
# cp server.key assets/server/tls/snakeoil.key
编译生成服务端和客户端
# make release-server release-client
编译出的程序会放在ngrok/bin/下,ngrok为客户端程序,ngrokd为服务器程序。注意这个服务端和客户端只适合你用于编译的机器的所属平台上运行,例如使用x86构架的主机编译无法在arm构架上运行,需要后面的交叉编译
3. 启动Ngrok服务
# ./ngrokd -domain="ngrok.moonwaker.me" -httpAddr=":8080" -httpsAddr=":8081" -tunnelAddr=":4443"
使用netstat -tunlp
可以看到服务器已经做好端口监听,并且已经将两个协议的转发端口做了监听,当然三个参数的端口都是默认好的,这里写出来是为了方便修改。
4. 运行客户端
如果是同样平台的机器可以直接将ngrok复制走运行,如果是想在树莓派等arm平台上要配置交叉编译再编译一次
配置编译平台
# cd ~/software/go/src
# GOOS=linux
# GOARCH=arm
# ./make.bash
通过上面的命令配置好go编译器的交叉编译选项,然后重新编译
# cd ~/software/ngrok/src
# make release-server release-client
写一个配置文件ngrok.cfg,基础的配置如下
server_addr: ngrok.moonwalker.me:4443
trust_host_root_certs: false
这里已经可以通过命令
# ./ngrok -subdomain ngrok -proto=http -config=ngrok.cfg 80
直接将80端口转发到服务器端的8081端口,并且协议走的是http
当然也可以对其它端口进行tcp转发,比如转发22端口
# ./ngrok -proto=tcp -config ngrok.cfg 22
ngrok会随意选择一个端口对本机的22端口进行转发
如果想一次性转发多个端口或者想指定远程的对应端口,需要完善ngrok.cfg
server_addr: ngrok.moonwalker.me:4443
trust_host_root_certs: false
tunnels:
ssh:
remote_port: 1122
proto:
tcp: 22
ss:
emote_port: 8388
proto:
tcp: 8388
ftp:
remote_port: 20
proto:
tcp: 20
ftp2:
remote_port: 21
proto:
tcp: 21
http:
subdomain: www
proto:
http: 80
https: 192.168.1.4:443
特别需要注意的是配置文件为YAML语法,所有缩进都要使用空格,不能够使用tab
而且可以看出不但可以转发本机的端口,亦可以转发其它内网设备
启动特定的转发tunnel
# ./ngrok -config ngrok.cfg start ssh ss
当然也可以将所有配置全部转发
# ./ngrok -config ngrok.cfg start-all