温馨提示:
本文所述内容具有依赖性,可能因软硬条件不同而与预期有所差异,故请以实际为准,仅供参考。
现在大部分宽带都不分配固定 IP 了,当在外面想要连接家里的智能管理,或者有项目想要临时给客户演示时,是十分不方便的,内网穿透工具就此诞生,现在比较流行的有 Ngrok 和 Frp,接下来我们将探讨 Ngrok 的部署使用。
一、依赖
Ngrok 是一个 DDNS 服务,因此需要一个公有域名,而要实现外网访问,也就意味着需要一个静态 IP,既然宽带不分配静态 IP,那么我们可以购买便宜的主机来实现,比如:
注意,通过 Ngrok 连接的方式,如果 VPS 是选用国内的,虽然延迟好了,但网络瓶颈也产生了,所以建议带宽要大于 5Mbps。
二、部署
以 CentOS 7.0 x64 为例:
1、安装环境
2020/02/26 更新
Golang 下载地址参见:https://studygolang.com/dl
# 编译环境
# 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++ mercurial
# GO 环境
# wget http://www.golangtc.com/static/go/1.9.2/go1.9.2.linux-amd64.tar.gz
# tar -zxvf go1.9.2.linux-amd64.tar.gz
# mv go /usr/local/
# ln -s /usr/local/go/bin/* /usr/bin/
# 验证一下
# go env
GOARCH="amd64"
GOBIN=""
GOEXE=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOOS="linux"
GOPATH=""
GORACE=""
GOROOT="/usr/lib/golang"
GOTOOLDIR="/usr/lib/golang/pkg/tool/linux_amd64"
CC="gcc"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build672964581=/tmp/go-build"
CXX="g++"
CGO_ENABLED="1"
# 安装高版本 git(>1.8)
# yum remove git*
# wget http://mirrors.ustc.edu.cn/kernel.org/software/scm/git/git-2.9.5.tar.gz
# tar zxf git-2.9.5.tar.gz && cd git-2.9.5
# ./configure --prefix=/usr/local/git
# make && make install
# ln -s /usr/local/git/bin/* /usr/bin/
# 验证一下
# git --version
git version 2.9.5
2、申请证书
Ngrok 通过证书加密,可以自签或者申请,因为自签会有不信任的问题,故建议申请正式证书,申请方法可参考:
需要保存 4 个文件,CA 证书 ca.crt 、ROOT 签发证书 root.crt 、域名证书 domain.com.crt 及私钥 domain.com.key ,此处域名是指要做为管理的域名,避免后续新增或更换需要重新部署,建议申请泛域名证书。
3、编译 Ngrok
① 下载源码
# git clone https://github.com/inconshreveable/ngrok.git
# export GOPATH=~/ngrok
② 替换证书
ca.crt -> ngrok/assets/client/tls/snakeoilca.crt
root.crt -> ngrok/assets/client/tls/ngrokroot.crt
domain.crt -> ngrok/assets/server/tls/snakeoil.crt
domain.key -> ngrok/assets/server/tls/snakeoil.key
注意 root.crt 不要跟 ca.crt 弄反了,否则在 Windows 客户端正常连接,Linux 客户端会出现 remote error: bad certificate
错误。
③ 编译服务端
# cd ngrok/
# make release-server
④ 编译客户端
# Windows 平台 64 位系统
# GOOS=windows GOARCH=amd64 make release-client
- 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
编译完成后,客户端在 ngrok/bin 目录下
4、使用方法
① 域名解析
在域名解析商处记录 domain.com 至主机 IP,即运行 Ngrok 的 VPS,如果申请的证书是单域名证书,则解析单域名,泛域名则设置想要链接的域名。
② 启动服务
服务端程序驻守为 ngrok/bin/ngrokd,可以将其放入 $PATH 中:
# vim ~/.bash_profile
...
PATH=$PATH:$HOME/bin:/root/ngrok/bin
...
# source ~/.bash_profile
也可以直接创建链接:
# ln -s ~/ngrok/bin/* /usr/bin/
启动服务端:
# nohup ngrokd -domain=domain.com -httpAddr=:5442 -httpsAddr=:5443 -tunnelAddr=:4443 > ~/ngrok/ngrok.log &
如果不用默认证书,也可以指定证书启动:
# nohup ngrokd -tlsKey=~/server.key -tlsCrt=~/server.crt -domain=domain.com -httpAddr=:5442 -httpsAddr=:5443 -tunnelAddr=:4443 > ~/ngrok/ngrok.log &
其中,
-domain 为服务域名,
-httpAddr 为 http 服务默认端口地址,访问形式为 xxx.domain.com:5442,
-httpsAddr 为 https 服务默认端口地址,
-tunnelAddr 是服务器用来跟客户端通讯的长连接端口,
不要日志的话删除 > ~/ngrok/ngrok.log
即可。
查看端口监听判断是否启动成功:
# lsof -i :4443
如果有启用防火墙,记得开放端口:
# firewall-cmd --zone=public --add-port=5442/tcp --permanent # firewall-cmd --zone=public --add-port=5443/tcp --permanent # firewall-cmd --zone=public --add-port=4443/tcp --permanent # firewall-cmd --reload
③ 客户端连接
客户端有两种启动方式,一个是命令行直接启动,一个是通过配置文件运行。
I、命令行启动
新建文件 ngrok-config 保存服务器信息:
server_addr: tunel.domain.com:4443
trust_host_root_certs: true
注意,如果在上面证书配置中,如果没有替换 CA 证书,那么 trust_host_root_certs 应设为 false,如果使用的是通配符证书,那么 server_addr 域名随便设,1.domain.com、ngrok.domain.com 都可以。
启动 http 穿透
./ngrok -config=ngrok-config 80
启动 ssh 穿透
./ngrok -config=ngrok-config --proto=tcp 22
要记录日志则添加 -log=log.log
即可
I、配置文件启动
新建文件 ngrok-config 保存服务器及隧道信息
server_addr: tunel.domain.com:4443
trust_host_root_certs: true
tunnels:
web:
proto:
http: 80
subdomain: myapp
auth: "user:secretpassword"
webs:
proto:
https: 443
hostname: myapps.domain.com
crt: example.crt
key: example.key
ssh:
proto:
tcp: 22
remote_port: 5555
如果本地端口或者远程端口不是标准的 80 443 端口,则应该在 hostname 后加上端口号。同样的,可以监听本地局域网内的其他主机,比如说:
ssh: proto: tcp: 192.168.1.3:22 remote_port: 5555
启动命令:
./ngrok -config=ngrok-config start web ssh
ngrok (Ctrl+C to quit)
Tunnel Status online
Version 1.7/1.7
Forwarding http://myapp.domain.com:5442 -> 127.0.0.1:80
Forwarding tcp://tunel.domain.com:5555 -> 127.0.0.1:22
Web Interface 127.0.0.1:4040
# Conn 0
Avg Conn Time 0.00ms
如果屏幕显示如上信息,表示隧道已经打通,我们就可以通过外网域名访问到内网了,记得子域名也要在域名解析商处添加记录,不然域名还是访问不到。另外 Ngrok 也支持在配置中直接指定端口,记得主机要开放该端口。在本地访问 http://127.0.0.1:4040 可以看到请求日志详情。
5、问题排查
① remote error: bad certificate
客户端 ngrok.cfg 中 server_addr 后的值必须严格与服务端 -domain 以及证书中的域名相同,否则 Server 端就会出现此错误:
[04/15/18 18:55:46] [INFO] [tun:15dd7522] New connection from *.*.*.*:*
[04/15/18 18:55:46] [DEBG] [tun:15dd7522] Waiting to read message
[04/15/18 18:55:46] [WARN] [tun:15dd7522] Failed to read message: remote error: bad certificate
[04/15/18 18:55:46] [DEBG] [tun:15dd7522] Closing
也可以将配置文件中的 trust_host_root_certs
设为 false
,另外再确认下 root.crt 有没有跟 ca.crt 弄反了。
② make: bin/go-bindata: Command not found
安装 go 环境时必须将 go/bin 目录添加到 PATH,或者创建链接到系统 bin 目录,比如:
# ln -s /root/go/bin/* /usr/bin/
其他出现 not found 提示也是类似的解决方法,比如
package code.google.com/p/log4go: exec: "hg": executable file not found in $PATH
是说找不到 hg 包,安装一下即可:
# yum install hg -y
③ You may only specify one port to tunnel to on the command line, got 2:
出现这个问题大多是使用了官方给的配置模板,而 ngrok 1.x 旧版本(GitHub 最新版)对此配置支持有问题,开发者对 2.x 已不再开源,故只能调整配置文件(参照上面的配置),或者命令行直接启动使用。
④ Error parsing configuration file *.conf: YAML error: line 5: found character that cannot start any token
主要存在于 Linux 系统下,原因是在写启动配置文件时,按下回车键后编辑器自动格式化了空格,导致 Ngrok 无法识别配置文件,解决方法就是将配置文件的空格删掉,手动重新敲一遍。
参考文章:
1、《GitHub Wiki》
2、《搭建自己的ngrok服务》
3、《How to setup Ngrok with a self-signed SSL cert》
4、《Developer's guide to ngrok》
5、《内网穿透 ngrok 服务器和客户端配置》
6、《ngrok - Documentation》
7、《CentOS7搭建ngrok服务器》
Windows 10Chrome 70.0.3538.25来自 广东 的大神
内网穿透frp要自己搭建折腾过,也用过一些网上的加壳版服务不尽如意,后来一直在用*很方便