随着国内运营商的IP不够用的节奏,我们拨号拿到的IP已经不再是类似122.1.33.22
的公网IP了,而是类似10.1.2.33
的内网IP,换句话说,我们没法直接访问到我们自己家里的路由器了!如何解决这个问题呢?目前成本最低的方式就是使用内网穿透技术了。说白了就是端口转发,即我们需要一台类似反向代理的VPS(老高的VPS使用的搬瓦工),把我们的请求转发到内网里,这样就相当于在防火墙内打了个洞,我们的数据能够穿透运营商的限制到达内网设备。
图片来自网络,侵删。
关于内网穿透,老高以前写过用ssh做这件事情,使用ssh的反向隧道管理内网路由器,这次我们使用ngrok开源出来的代码实现。
准备
GO语言
我们的机器需要先安装GOLANG开发环境,系统不限,因为GO语言是跨平台的!安装过程很简单,参考官网的教程即可!
克隆代码
然后我们需要把代码拷贝至本机,使用git
命令即可!
git clone https://github.com/inconshreveable/ngrok.git
cd ngrok
解析域名
因为我们使用了自己的域名(以ngrok.phpgao.com
为例),我们需要做以下解析:
ngrok.phpgao.com -------> A记录到你的VPS IP
*.ngrok.phpgao.com -------> CNAME到ngrok.phpgao.com
生成证书
因为我们使用了自己的域名(以ngrok.phpgao.com
为例),所以我们需要自己签名的证书。
export NGROK_DOMAIN="grok.phpgao.com"
openssl genrsa -out rootCA.key 2048
openssl req -x509 -new -nodes -key rootCA.key -subj "/CN=$NGROK_DOMAIN" -days 36500 -out rootCA.pem
openssl genrsa -out device.key 2048
openssl req -new -key device.key -subj "/CN=$NGROK_DOMAIN" -out device.csr
openssl x509 -req -in device.csr -days 36500 -CA rootCA.pem -CAkey rootCA.key -CAcreateserial -out device.crt
cp rootCA.pem assets/client/tls/ngrokroot.crt
cp device.crt assets/server/tls/snakeoil.crt
cp device.key assets/server/tls/snakeoil.key
编译运行软件
接下来就是愉快的编译时间,需要注意的是,老高在Linux的编译出来的程序默认只能跑在Linux机器上,如果需要编译出能够在其他系统上跑的程序,我们需要一个编译技巧!– 就是在编译命令前修改环境变量,例如这样GOOS=darwin GOARCH=amd64 make release-all
,编译后我们在bin文件夹下能找到编译好的文件,如果是跨平台编译就在bin/darwin_amd64
文件夹里找。
服务端
# 服务端运行在Linux下,我们不需要任何操作
# 发布server版
make release-server
# make release-xxx会把asset文件里面的东西打包成一个可执行文件
# 运行服务端
# 帮助信息
./ngrokd -h
Usage of ./ngrokd:
-domain string
Domain where the tunnels are hosted (default "ngrok.com")
-httpAddr string
Public address for HTTP connections, empty string to disable (default ":80")
-httpsAddr string
Public address listening for HTTPS connections, emptry string to disable (default ":443")
-log string
Write log messages to this file. 'stdout' and 'none' have special meanings (default "stdout")
-log-level string
The level of messages to log. One of: DEBUG, INFO, WARNING, ERROR (default "DEBUG")
-tlsCrt string
Path to a TLS certificate file
-tlsKey string
Path to a TLS key file
-tunnelAddr string
Public address listening for ngrok client (default ":4443")
./ngrokd -domain=$NGROK_DOMAIN
# 可以指定端口
./ngrokd -domain=$NGROK_DOMAIN -httpAddr=":8080" -httpsAddr=":8081"
运行成功后的截图:
客户端
客户端要做的事情就是把本机的端口暴露给VPS,这样VPS就能够转发请求了
# 假设我要在mac上运行客户端,需要在编译命令前加上一些参数
GOOS=darwin GOARCH=amd64 make release-client
# 编译好后scp到本地
scp xxx xxx
# 下面开始本地配置
# 打开配置文件
vim ngrok.cfg
# 添加一下两行
# 第一行是将要绑定的域名+4443端口
server_addr: "ngrok.phpgao.com:4443"
trust_host_root_certs: true
# 帮助信息
./ngrok -h
Examples:
ngrok 80
ngrok -subdomain=example 8080
ngrok -proto=tcp 22
ngrok -hostname="example.com" -httpauth="user:password" 10.0.0.1
# 8080就是我们要转发的端口了
./ngrok -config=./ngrok.cfg 8080
# 指定协议和端口,不指定默认是 http+https
./ngrok -config=./ngrok.cfg -proto=tcp 22
# 指定子域名,不指定就会随机生成
./ngrok -config=./ngrok.cfg -subdomain=test 8080
在浏览器中输入http://127.0.0.1:4040
,就可以看到请求的具体信息了!是不是很神奇!
看到这里是不是还没有成功?不用怕,国内雷锋还是有很多的,不信你看!
又一个国内的 Ngrok 服务器分享 NATAPP Ngrok国内免费服务器——糖果科技 Sunny-Ngrok内网转发
开机启动
vim /etc/rc.local
# 添加以下命令,注意使用绝对路径
# 服务端
nohup /path/to/ngrokd -domain=ngrok.phpgao.com -log="/tmp/ngrok.log" >/dev/null 2>&1 &
# 客户端
nohup ./ngrok -config ngrok.cfg -log stdout -log-level="INFO" -subdomain=test 8080 >/tmp/ngrok.log 2>&1 &
补充
关于配置文件,我们可以使用yml(YAMLAintMarkupLanguage)格式指定更多的信息
tunnels:
webapp:
proto:
http: 8080
auth: "user:pw"
ssh:
proto:
tcp: 22
然后我们可以使用以下命令执行客户端了!
# 运行某些
ngrok -congfig=ngrok.cfg start ssh
ngrok -congfig=ngrok.cfg start ssh webapp
# 运行全部
ngrok -congfig=ngrok.cfg start-all
Reference:
inconshreveable/ngrok Docs Run Ngrok on Your Own Server Using Self-Signed SSL Certificate 自行编译ngrok服务端客户端,替代花生壳,跨平台