搭建ngrok服务实现内网穿透
日期: 2019-05-09
环境说明:
编译环境:
名称:CentOS7
系统:CentOS7 1810 64位
GO版本:1.11 和 1.13 均测试编译通过,1.18不行
公网主机:
名称:cloud7
系统:CentOS7 minimal 1804 64位
本地主机:
名称:yl_deep_local
系统:Ubuntu 18.04 64位
本次需要做内网穿透,实现再其他地方能连接本地主机yl_deep_local。注意文中的 tunnel.MYDOMAIN.COM 请替换为自己实际用的域名。
1 编译程序
1.0 准备工作
编译环境的主机最好配置国内的yum源,还需要配置epel源。配置epel后能方便的使用yum安装go语言编译环境。
1.1 下载源码包
git clone https://github.com/inconshreveable/ngrok.git
可以使用git下载,也可以直接下载zip包(我这里直接下载zip包,解压并上传到系统中)
我将源码放置于/opt/src/ngrok-src
,如下图
1.2 生成证书
注意替换为自己的域名
mkdir ~/tmp
cd ~/tmp
export NGROK_DOMAIN="tunnel.MYDOMAIN.COM"
openssl genrsa -out rootCA.key 2048
openssl req -x509 -new -nodes -key rootCA.key -subj "/CN=$NGROK_DOMAIN" -days 5000 -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 rootCA.key -CAcreateserial -out server.crt -days 5000
完成后生成如下证书(位于~/tmp
目录):
替换证书
cd /opt/src/ngrok-src
cp ~/tmp/rootCA.pem assets/client/tls/ngrokroot.crt
cp ~/tmp/server.crt assets/server/tls/snakeoil.crt
cp ~/tmp/server.key assets/server/tls/snakeoil.key
1.3 安装go语言编译环境
(需配置epel源)
yum install golang
使用root账号运行,安装了如下包
1.4 编译程序
客户端版本说明
- 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
cd /opt/src/ngrok-src
export GOPATH=$(pwd) # 设置go目标目录
GOOS=windows GOARCH=amd64 make release-client # 编译windows 64客户端
GOOS=windows GOARCH=amd64 make release-server # 编译windows 64服务端
GOOS=linux GOARCH=amd64 make release-client # 编译linux 64客户端
GOOS=linux GOARCH=amd64 make release-server # 编译linux 64服务端
GOOS=darwin GOARCH=amd64 make release-client # 编译MAC 64客户端
GOOS=darwin GOARCH=amd64 make release-server # 编译MAC 64服务端
完成编译后bin目录下有以下文件(各平台都编译了,以后备用)
2 配置服务端
2.1 配置域名解析到公网主机ip
这样 *.tunnel.MYDOMAIN.COM 和 tunnel.MYDOMAIN.COM 都解析到了公网主机 cloud7
2.2 配置服务端并启动服务
将ngrokd(linux amd64版)上传到公网主机的/opt/ngrok/目录下,然后添加执行权限
chmod +x /opt/ngrok/ngrokd # 后来由于方便起见放到 /usr/bin 目录下
后来由于方便起见放到 /usr/bin
目录下,以便可以使用命令直接运行
ngrokd -domain=tunnel.MYDOMAIN.COM -httpAddr=:5442 -httpsAddr=:5443 -tunnelAddr=:4443
效果如下图:
看情况,后台启动添加 nohup,日志重定向到日志文件或/dev/null
2.3 开启防火墙端口
我这里只用4443
firewall-cmd --zone=public --add-port=4443/tcp --permanent
firewall-cmd --reload
3 配置客户端
3.1 配置客户端
将ngrok(linux amd64版)上传到本地主机的/opt/ngrok/目录下,然后添加执行权限
chmod +x /opt/ngrok/ngrok
新建配置文件(这里使用配置文件的方式启动ngrok,另一种方式是直接命令中指定相关配置选项)
cd /opt/ngrok/
vi /opt/ngrok/ngrok-config
内容如下
server_addr: "tunnel.MYDOMAIN.COM:4443"
trust_host_root_certs: false
tunnels:
web:
proto:
http: 80
subdomain: web
webs:
proto:
https: 443
hostname: webs.tunnel.MYDOMAIN.COM
ssh:
proto:
tcp: 10022
remote_port: 10022
这里配置了3条转发,这里测试用10022作为ssh端口,默认端口为22。
3.2 启动客户端
前面配置了3条,这里只启动ssh
./ngrok -config=ngrok-config start ssh
效果如下
如果需同时启动其他规则,命令start后添加其他规则名称即可,如启动web和webs
./ngrok -config=ngrok-config start web webs
如果想一次启动所有,可以使用命令
./ngrok -config=ngrok-config start-all
3.3 效果测试
xshell的ssh配置,主机中填写域名
使用xshell连接
连接成功,试了几个小时,没有掉线情况。之前使用ssh转发,经常掉,现在终于解决问题了。
4 配置为服务自启动
将程序配置为服务项,开机启动
4.1 配置服务端
服务端为CentOS7
vi /usr/lib/systemd/system/ngrokd.service
内容如下,注意Exec命令中不要有双引号,会导致失败(找了好久问题)
[Unit]
Description=ngrokd
After=network.target
[Service]
TimeoutStartSec=30
ExecStart=/usr/bin/ngrokd -domain=tunnel.MYDOMAIN.COM -httpAddr=:5442 -httpsAddr=:5443 -tunnelAddr=:4443 -log-level=INFO
ExecStop=/bin/kill -SIGINT $MAINPID
ExecReload=/bin/kill -SIGHUP $MAINPID
Restart=on-failure
#NotifyAccess=main
#WatchdogSec=30
[Install]
WantedBy=multi-user.target
启动设置及相关命令
systemctl daemon-reload # 载入配置服务
systemctl enable ngrokd # 设置开机启动
systemctl start ngrokd # 开启ngrok
systemctl status ngrokd # 查看状态
systemctl stop ngrokd # 停止
4.2 配置客户端
客户端为Ubuntu 18.04
vim /lib/systemd/system/ngrok-ssh.service
内容如下
[Unit]
Description=ngrok-ssh.service
[Service]
#Type=forking
#PIDFile=/run/test.pid
#EnvironmentFile=/etc/systemd/test.conf
ExecStart=/usr/bin/nohup /usr/bin/ngrok -log=stdout -log-level=INFO -config=/opt/ngrok/ngrok-config start ssh
ExecReload=/bin/kill -SIGHUP $MAINPID
ExecStop=/bin/kill -SIGINT $MAINPID
Restart=on-failure
#NotifyAccess=main
#WatchdogSec=30
[Install]
WantedBy=multi-user.target
相关命令
systemctl daemon-reload # 载入配置服务
systemctl enable ngrok-ssh # 设置开机启动
systemctl start ngrok-ssh # 启动服务
systemctl status ngrok-ssh # 查看状态
systemctl stop ngrok-ssh # 停止服务
5 后续补充
2022-10-19重新编译,有几个坑:
- go 新版不行,后使用ubuntu 20.04(go 1.13)成功编译;
- 依赖
uniseg
最高支持uniseg-0.2.0
版本的,试出来的; - 由于网络问题可能无法下载依赖的,可以通过手动下载,然后放置到
src
下对应的目录,如提示go get -tags 'release' -d -v ngrok/... github.com/nsf/termbox-go (download)
时,可以到github下载源代码,然后放到src/github.com/nsf/termbox-go
即可,如图: