ngrok是一个能够实现不能直接与外网沟通的设备,通过外网服务器的转发实现自我服务器化的软件,也就是不需要通过路由器的端口映射,就能实现内网设备向外网暴露端口的软件。
其实吧,Ngrok网上有不少教程,然而,能用的或者说详细的很少,要不然就是让人看不懂的。这玩意让我头疼了这么久,我觉得我有必要写一个0基础玩家都能搞成功的教程。举例来说,你有一个树莓派,你想操纵它,那你可以在树莓派上连接键盘鼠标,然后用控制台。这样有四个问题
- 你得单独为树莓派买一套键鼠,还得单独为树莓派买一个显示器,这成本太高了,当然土豪随意;
- 我的树莓派只有两个usb接口,如果键鼠把所有接口都占用了,其他的设备比如usb摄像头就没法用了;
- 树莓派的电压、电流很小,我单独为B+买了一个5V/2A的电源,即使这样供电尚且不足,更何况多数人只是用普通的手机充电头了;
- 你每次想操作树莓派的话,都得从椅子上站起来,跑到树莓派那里,然后才能操作,对于我这种懒人频繁操作的人来说,简直太不方便了。
那这四个问题怎么解决呢?前人发明了神器SSH,你只需要在你的电脑上用putty之类的软件通过SSH连接你的树莓派,然后在你的电脑上就可以操作了,是不是很方便?
于是问题又又又又又来了,想用SSH的话,你得在一个局域网下,换句话说,你只能在你家路由器上连着的设备上用。那我想在家也能控制我学校的树莓派怎么搞?其实想想也不难哈,我只需要知道我学校树莓派的IP就行了,跟局域网一样啊,我费这大劲倒腾这个干啥?虽然理论上是这样没错啦,但是现在公网ipv4成了稀缺资源,ipv6又不开放,所以多数用户都是局域网ip(不光是学校里拓扑一层层,包括你家的哟~)。要知道,局域网ip你在公网可是没办法用的,就比方说大家的路由器ip基本都是192.168.1.1,那你在公网登陆这个ip到底是登陆到谁家去了?就是这个道理。
这时候,你就需要内网穿透了。
现在有一种服务叫花生壳,好多只能路由器上都可以安装。那么既然有了花生壳,为啥还要自己捣鼓啊?是这样的,如果把花生壳比作使用别人搭好的ss服务,那么自建Ngrok就是使用自己的ss服务,可见自搭Ngrok的优势不言而喻,流量费用十分经济,速度、稳定性和安全性将远远胜过花生壳。现在花生壳是一种比较流行的穿透内网的方式,不过其稳定性随着使用人数的增多而大打折扣,内网穿透的价格也不便宜,一套花生棒就是动轭上百,而且流量还要单独买,如果遭遇流量攻击套餐基本就泡汤了。
内网穿透的而应用可以很多,比方说你出门旅游,又想看看家里的监控啊什么的都会用到。
Ngrok部署的准备
- 拥有公网IP的VPS或云主机 (我这边用的是Hostdare,大概意见84块不到,当然还有更便宜的)
- 域名 (我用的是狗爹的,5块钱第一年,在我买了之后才发现有免费获取域名的教程,大家可以自己搜一搜qVq)
- 树莓派(我用的初代B+,现在都出道三代B型了qAq)
- Ngrok源代码
- Go语言
编译Ngrok客户端时会使用openssl生成证书来加密通讯,保证了安全性,使用时必须和签署证书时的域名吻合。(这是我上述两个原因中的一个)
编译Ngrok
以下安装过程在CentOS 7平台在进行
安装Go语言环境
安装必要包
yum -y install zlib-devel openssl-devel perl hg cpio expat-devel gettext-devel curl curl-devel perl-ExtUtils-MakeMaker hg wget gcc gcc-c++ build-essential mercurial
由于Go官方地址也可能访问不了,这里使用国内镜像下载源码
wget http://www.golangtc.com/static/go/1.7rc6/go1.7rc6.linux-386.tar.gz
tar -zxvf go1.7.6.linux-386.tar.gz
mv go /usr/local/
ln -s /usr/local/go/bin/* /usr/bin/
安装成功后查看可Go编译环境
go env
升级Git版本
Go编译过程中要求高版本的git,而yum源里面默认只有1.7.1版本。(这里是我两个原因中的一个,我记得我当时是升级过了,但是我昨晚上检查的时候发现并没有升级到2.9.3,于是我昨晚上升级了一下,这是我做的第一个改动。不过据高手,git就是个版本控制工具,不会影响编译结果。)
原版kernel.org国内访问过慢,替换为中科大源
wget https://www.kernel.org/pub/software/scm/git/git-2.9.4.tar.gz 原版kernel.org
wget http://mirrors.ustc.edu.cn/kernel.org/software/scm/git/git-2.9.4.tar.gz
#wget https://coding.net/u/sfantree/p/self_use_OSS/git/raw/master/ngrok/git-2.6.0.tar.gz
#wget https://coding.net/u/sfantree/p/self_use_OSS/git/raw/master/ngrok/git-2.9.4.tar.gz
tar zxvf git-2.9.4.tar.gz
cd git-2.9.4
./configure –prefix=/usr/local/git-2.9.4 make make install
取代yum安装的低版本git
yum remove git*
ln -s /usr/local/git-2.9.4/bin/* /usr/bin/
检查git版本是否为2.9.4
git –version
Ngrok源码配置
声明编译的路径和必要的域名(域名改成你自己的)。(这是我的第二个原因,我之前下载到git文件夹了,可能导致我声明不对,这个可能性大一点。)
git clone https://github.com/inconshreveable/ngrok.git ~/ngrok
export GOPATH=~/ngrok/
export NGROK_DOMAIN=”ngrok.applecaes.xyz”
cd ~/ngrok
生成证书,Ngrok会使用此证书加密通讯
openssl genrsa -out base.key 2048
openssl req -new -x509 -nodes -key base.key -days 10000 -subj “/CN=$NGROK_DOMAIN” -out rootCA.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 rootCA.pem -CAkey base.key -CAcreateserial -days 10000 -out server.crt
将证书文件复制到指定位置
cp rootCA.pem assets/client/tls/ngrokroot.crt -i
cp server.crt assets/server/tls/snakeoil.crt -i
cp server.key assets/server/tls/snakeoil.key -i
编译服务器端与客户端
服务器端为linux-x86-64
export GOOS=linux
export GOARCH=386
make release-server
编译完成过后~/ngrok/bin/ngrokd即为服务端运行文件,树莓派为linux-arm架构,重新声明go env里的变量
export GOOS=linux
export GOARCH=arm
make release-client
编译完成过后~/ngrok/bin/linux_arm/ngrok即为树莓派客户端运行文件,注意:这里测试时只编译了i386的服务器端和arm的客户端,实际上可以通过改变GOOS与GOARCH来获取各个平台的客户端与服务端。不同平台使用不同的GOOS和GOARCH,下面就是对应关系。
Linux平台32位系统:GOOS=linux GOARCH=386
Linux平台64位系统:GOOS=linux GOARCH=amd64
MAC平台32位系统:GOOS=darwin GOARCH=386
MAC平台64位系统:GOOS=darwin GOARCH=amd64
Windows平台32位系统:GOOS=windows GOARCH=386
Windows平台64位系统:GOOS=windows GOARCH=amd64
ARM平台:GOOS=linux GOARCH=arm
其实你也可以选择在本地编译好客户端然后部署在服务器上。
部署Ngrok
绑定域名
在编译配置时的域名ngrok.applecaes.xyz解析到服务器IP,注意:指定A记录时ngrok与*.ngrok都要填上,这样能方便地使用不同子域转发不同的本地服务。
服务器端部署
将编译好的可执行文件移至/usr/bin/下
cp ~/ngrok/bin/ngrokd /usr/bin/
为ngrokd单独开一个screen
yum install -y screen
screen -S ngrokd
运行ngrokd
ngrokd -domain=”ngrok.applecaes.xyz” -httpAddr=”:1111″ -httpsAddr=”:2222″ -tunnelAddr=”:3333″
屏幕会输出一连串日志信息,ttpAddr、httpsAddr 分别是 ngrok 用来转发 http、https 服务的端口,ngrokd 还会开一个 4443 端口用来跟客户端通讯,注意设置防火墙使端口开放。
客户端部署
将服务器中~/ngrok/bin/linux_arm/ngrok文件移至树莓派下。新建配置文件
mkdir ~/ngrok/ && cd ~/ngrok/
touch ~/ngrok/ngrok.cfg
echo “server_addr: ngrok.sfantree.com:3333” >> ~/ngrok/ngrok.cfg
echo “trust_host_root_certs: false” >> ~/ngrok/ngrok.cfg
重新改写客户端配置文件ngrok.cfg
server_addr: ngrok.applecaes.xyz:3333
trust_host_root_certs: false
tunnels:
http:
subdomain: xx
auth: “user:passwd”
proto:
http: 80
ssh:
remote_port: 10001
proto:
tcp: 22
xrdp:
remote_port: 12345
proto:
tcp: 1234
这里我把需要转发的http、ssh和xrdp都写入配置文件,其他tcp服务语法格式和ssh相似,remote_port为远程端口,等下外网连接的时候用的就是这个remote_port,tcp: 22为需要转发的本地端口。
运行客户端
./ngrok-for-arm -config=ngrok.cfg start http ssh
看见Tunnel Status变为online说明成功连接服务器端。
转载需保留链接来源:软件玩家 » Ngrok实现树莓派内网穿透