Linux ngrok内网穿透

需求:有台闲置的台式机,09年买的,当时跑win xp,现在跑win7有些吃力,运行Eclipse Web程序力不从心。现在改成CentOS 7 当服务器用。在内网访问很方便。缺点:外网无法使用SSH连接到台式机。还想在台式机部署Web应用,外网可以访问。

关键技术,ngrok

ngrok是一个c/s结构的代理工具,在公网部署server端,在内网(家里或公司)部署client端。server端启动,监听来自client的请求,建立连接。

Linux ngrok内网穿透

需要的工具:

阿里云VPS,别的VPS也行
ngrok
go语言
git
wget
CentOS
第一步,先在阿里云做域名解析

Linux ngrok内网穿透

二级域名,IPV4记录类型,也就是A。

*.tunnel 表示可以生成3级域名。ngrok客户端在不指定子域名时将随机生成一个子域名。

第二步,开放阿里云服务器的端口。

以前不需要开放,现在阿里云提升安全策略,不仅需要在云服务里开放端,还要在安全规则里开放。

Linux ngrok内网穿透

阿里云后台管理真心不方便,很难找到安全规则。需要些耐心。

第三步,安装go语言。

ngrok是go语言写的,因此需要安装go语言。

1
yum install golang
第四步,安装git

为什么要安装git呢?编译ngrok时,需要从github上下载相关依赖。

1
yum install git
第五步,安装wget用于下载ngrok。

1
yum install wget
第六步,下载ngrok

可以使用git下载,也可以使用wget下载。我使用wget下载tar.gz包。

第七步,解压和修改log4go路径

我下载到/opt目录

先切换到/opt目录

1
#cd /opt
再下载

1
wget https://github.com/inconshreveable/ngrok/archive/1.7.1.tar.gz
再解压

1
tar zxvf 1.7.1.tar.gz
ngrok里使用了log4go。log4go之前在code.google.com上,现在log4go改放到github上。因此要修改下

修改/opt/ngrok-1.7.1/src/ngrok/log/logger.go里的code.google.com/p/log4go,使用github.com/alecthomas/log4go代换。

第八步,生成证书。

cd /opt/ngrok-1.7.1 # 指ngrok-1.7.1
openssl genrsa -out rootCA.key 2048
openssl req -x509 -new -nodes -key rootCA.key -subj “/CN=tunnel.yourdomain” -days 5000 -out rootCA.pem
openssl genrsa -out device.key 2048
openssl req -new -key device.key -subj “/CN=tunnel.yourdomain” -out device.csr
openssl x509 -req -in device.csr -CA rootCA.pem -CAkey rootCA.key -CAcreateserial -out device.crt -days 5000
如域名更换了,将tunnel.liyongzhen.com换其它域名即可。

上面的脚本会生成6个证书。

-rw-r–r--. 1 root root 1009 9月 29 06:43 device.crt
-rw-r–r--. 1 root root 907 9月 29 06:43 device.csr
-rw-r–r--. 1 root root 1679 9月 29 06:42 device.key
-rw-r–r--. 1 root root 1675 9月 29 06:42 rootCA.key
-rw-r–r--. 1 root root 1127 9月 29 06:42 rootCA.pem
-rw-r–r--. 1 root root 17 9月 29 06:43 rootCA.srl
复制生成的证书到发行目录

1
2
3
cp rootCA.pem assets/client/tls/ngrokroot.crt
cp device.crt assets/server/tls/snakeoil.crt
cp device.key assets/server/tls/snakeoil.key
第九步,编译客户端程序ngrok和服务端程序ngrokd

1
2
3
cd /opt/ngrok-1.7.1
make release-client
make release-server
生成其它平台的程序,执行下面的脚本。

32位linux客户端:
GOOS=linux GOARCH=386 make release-client
#64位linux客户端:
GOOS=linux GOARCH=amd64 make release-client
32位windows客户端:
GOOS=windows GOARCH=386 make release-client
#64位windows客户端:
GOOS=windows GOARCH=amd64 make release-client
32位mac平台客户端:
GOOS=darwin GOARCH=386 make release-client
64位mac平台客户端:
GOOS=darwin GOARCH=amd64 make release-client
ARM平台linux客户端:
GOOS=linux GOARCH=arm make release-client
有网友说,交叉编译windows客户端,最好安装最新版本Golang,使用yum安装的一直编译不通过。

经测试,在CentOS 1804版本下无任何问题。

第十步,开放端口。

放行端口
#启动防火墙
systemctl start firewalld
systemctl enable firewalld
#放行ngrok需要的4443端口
firewall-cmd --zone=public --add-port=4443/tcp --permanent
#放行80及443端口
firewall-cmd --add-service=http --permanent
firewall-cmd --add-service=https --permanent
#放行自定义端口,例如:TCP 7070及7071端口
firewall-cmd --zone=public --add-port=7070/tcp --permanent
firewall-cmd --zone=public --add-port=7071/tcp --permanent
firewall-cmd --zone=public --add-port=7443/tcp --permanent
重新加载防火墙规则
firewall-cmd --reload
第十一步,启动服务端程序。

先切换到 /opt/ngrok-1.7.1/bin 目录下

给ngrokd添加执行权限。

1
chmod +x ngrokd
执行启动脚本

1
./ngrokd -tlsKey="/opt/ngrok-1.7.1/assets/server/tls/snakeoil.key" -tlsCrt="/opt/ngrok-1.7.1/assets/server/tls/snakeoil.crt" -domain=“tunnel.yourdomain” -httpAddr=":7070" -httpsAddr=":7071" -tunnelAddr=":4443"
上面的脚本在关闭连接后,ngrok也会关闭。改用下面的脚本不会关闭。

1
nohup ./ngrokd -tlsKey="/opt/ngrok-1.7.1/assets/server/tls/snakeoil.key" -tlsCrt="/opt/ngrok-1.7.1/assets/server/tls/snakeoil.crt" -domain=“tunnel.yourdomain” -httpAddr=":7070" -httpsAddr=":7071" -tunnelAddr=":4443"
httpAddr 是访问普通的http使用的端口号,用后面用子域名.tunnel.yourdomain + 这个端口号来访问服务

httpsAddr 是访问的https使用的端口号,同上,只不过是需要https的服务访问才用这个端口(一般用不上)

tunnelAddr 是ngrok通道的端口号,这个端口是Ngrok用来通信的,所以这个端口在服务器上和客户端上设置必须要对应才可以正常的链接,默认端口是4443。这些端口都是云主机上用到的端口。

第十二步,部署客户端程序。

将/opt/ngrok-1.7.1/bin/下的ngrok程序复制到内网(家里或公司)的机器上。

方式有很多种。略

第十三步,建立客户端连接到ngrokd的配置脚本。

在ngrok程序所在的目录(我的内网机子目录/work/server/ngrok),建立一个脚本ngrok.cfg,名称可以随意取,只要是文本文件即可。添加下列内容。

server_addr: tunnel.yourdomain:4443
trust_host_root_certs: false
tunnels:
http:
subdomain: “tomcat”
remote_port:80
proto:
http: “7070”

ssh:
remote_port: 2345
proto:
tcp: “22”
第一行代码,用于连接到ngrokd,端口是第一步开放的端口。域名是第一步添加的域名解析。

第二行代码,不启动TLS认证。

第三行代码起,配置通道。这里配置两个通过。一个7070端口,是tomcat的端口,将tomcat提供的Web服务让外网可以访问。另一个端口是22,映射到外网端口是2345。这样开关两个需求都实现。

第十四步,制作一个启动脚本。

在ngrok程序所在的目录(我的内网机子目录/work/server/ngrok),建立一个脚本start.sh

内容如下:

1
2
path=/work/server/ngrok
nohup $path/ngrok -config $path/ngrok.cfg start http ssh
同时启动http ssh两个通过。

给start.sh添加执行权限。

1
chmod +x /work/server/ngrok/start.sh
将/work/server/ngrok/start.sh添加到/etc/rc.d/rc.local尾部。

#!/bin/bash
THIS FILE IS ADDED FOR COMPATIBILITY PURPOSES

It is highly advisable to create own systemd services or udev rules
to run scripts during boot instead of using this file.

In contrast to previous versions due to parallel execution during boot
this script will NOT be run after all other services.

#Please note that you must run ‘chmod +x /etc/rc.d/rc.local’ to ensure
#that this script will be executed during boot.
touch /var/lock/subsys/local
/work/server/ngrok/start.sh
给/etc/rc.d/rc.local添加执行权限。

1
chmod +x /etc/rc.d/rc.local
到此,所以配置完成,重启内网CentOS,便可以访问。

部署windows客户端