目录
概述
很久之前我就有想法自己做一个内网穿透,但是当时因为没有什么大的动力,对内网穿透的认识还停留在“花生壳,nat123”这种必须要寄人篱下的存在。当然,自己心里也有数,这个是肯定能自己实现的,只是没有仔细研究。
因为一些原因,前一段时间打算自己搞内网穿透了,此文来记录半个月多来的经历。
目前使用的内网穿透工具有两个:
- ngrok (start on Mar. 19, 2018)
- frp (start on Mar. 29, 2018)
工具篇
ngrok
先上结论:不推荐。
简单介绍一下ngrok。ngrok 是一个反向代理,通过在公共的端点和本地运行的 Web 服务器之间建立一个安全的通道。支持TCP协议,不支持UDP协议。ngrok有两个大版本,1.*开源在github,用golang编写。2.*闭源。
ngrok的安装过程可谓曲折。
当时在网上看到的教程大多都是编译安装,然而我是一个比较愁编译的人,坚持能不编译就不编译。所以打算偷懒用apt安装。
客户端安装上client,服务端安装上server,启动!
但是事实证明,apt安装似乎不是一个好选择。启动后出现了client无法连接到server的情况,错误信息是说证书错误。可能是因为编译的过程使用的是ngrok自己域名的证书,所以在使用自己域名的时候可能会出现问题。我感觉这个问题是可以解决的,但是当时(半个月前)找了很久的解决方法都没有解决。最后还是决定编译安装。
apt安装的版本是1.6,编译安装的版本是1.7。
既然决定编译安装了,剩下的事情就变简单了。
简单说一下安装过程:
- 安装golang git
sudo yum install golang git # for centos.. sudo apt install golang git # for debian..
- git clone
git clone https://github.com/mamboer/ngrok.git
- 创建证书并替换,替换example.domain 为你的域名。
cd ngrok openssl genrsa -out rootCA.key 2048 openssl req -x509 -new -nodes -key rootCA.key -subj "/CN=example.domain" -days 5000 -out rootCA.pem openssl genrsa -out device.key 2048 openssl req -new -key device.key -subj "/CN=example.domain" -out device.csr openssl x509 -req -in device.csr -CA rootCA.pem -CAkey rootCA.key -CAcreateserial -out device.crt -days 5000 cp rootCA.pem assets/client/tls/ngrokroot.crt cp device.crt assets/server/tls/snakeoil.crt cp device.key assets/server/tls/snakeoil.key
- 编译
make release-server release-client
这里需要说一下,如果客户端与服务端架构相同(比如都是linux,amd64),可以一次编译出来,然后过去使用。如果架构不同,则需要交叉编译,或者把所有的文件发过去在客户端/服务端重新编译。
- 启动服务端
ngrokd -domain="example.domain" -httpAddr=":8088" -httpsAddr=":8089"
客户端创建配置文件 ngrok.cfg (名字随意):
server_addr: "example.domain:4443" trust_host_root_certs: false
然后启动:
ngrok -subdomain demo -config=ngrok.cfg 8080
此时,本机的8080端口会转发至demo.example.domain
安装过程谈不上简单,功能谈不上高级,运行不能说稳定(断线重连疑似有bug无法实现,一直处于 reconnect 状态),还仅支持TCP,ngrok不是很令人满意。
速度方面,实测不如frp。
ngrok自带http控制面板,默认端口4040,可以看到日志什么的,功能比较简单。
frp
frp同样开源, 同样用golang编写(很奇怪主流的几个内网穿透全部是用golang编写的,gitee上的一个chuantou记得也是golang)。frp支持UDP协议,似乎比ngrok开发要晚一点(未确认)。
因为frp的验证方式是用的密码,所以安装过程就简单不少,不需要配置证书。开发者还直接做好了编译好的二进制文件,可以直接下载使用:https://github.com/fatedier/frp/releases (开心)
配置过程省略,此处可以有百度,frp的配置十分简单省心,功能也令人满意。
frp也自带了控制面板,可以显示配置信息、流量统计等。功能与ngrok一样,也比较简单(说简陋也可以)。
实际方案
我的需求是,转发内网的一个网站和一个sql server数据库。
网站的话非常简单,先在内网的跳板机(也就是客户端)用NGINX做一次反向代理,转发网站的80端口到本地的某个高位端口,然后用ngrok/frp 穿透到公网服务器(服务端)的某个高位端口,然后再在服务端上做一次NGINX反向代理。
sqlserver的话,起初的想法是用iptables端口转发,但是没有成功,最后还是用NGINX来做的。过程与网站类似。sql server是用的TCP1433端口和UDP1434端口,但是只转发1433的话也是可以用的。
如果用frp转发sqlserver的话,不能直接在frp的配置文件里直接转发目标服务器的端口,实测如果这样做的话,sql连接会在某一特定的步骤终止连接,原因未知。用NGINX转发到本地后再穿透则不存在这个问题。
结语
因为frp可以满足需求稳定运行,所以暂时就常识了这两种内网穿透工具,在这里要先喊一句:NGINX大法好!
如果之后有尝试新的工具,会在本文内作出补充。
本作品使用基于以下许可授权:Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.
frp直联sql server没有问题,是不是端口号没有写“,”而写成”:”了?