内网穿透的一点经验

概述


很久之前我就有想法自己做一个内网穿透,但是当时因为没有什么大的动力,对内网穿透的认识还停留在“花生壳,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。

既然决定编译安装了,剩下的事情就变简单了。

简单说一下安装过程:

  1. 安装golang git
    sudo yum install golang git # for centos..
    sudo apt install golang git # for debian..
  2. git clone
    git clone https://github.com/mamboer/ngrok.git
  3. 创建证书并替换,替换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
    
  4.  编译
    make release-server release-client

    这里需要说一下,如果客户端与服务端架构相同(比如都是linux,amd64),可以一次编译出来,然后过去使用。如果架构不同,则需要交叉编译,或者把所有的文件发过去在客户端/服务端重新编译。

  5. 启动服务端
    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大法好!

如果之后有尝试新的工具,会在本文内作出补充。

 

CC BY-NC-SA 4.0 本作品使用基于以下许可授权:Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.

One thought on “内网穿透的一点经验

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注