Total Pageviews

Sunday, 4 March 2018

KONE

Transparent proxy for home/enterprise network。

The project aims to improve the experience of accessing internet in home/enterprise network.
The name "KONE" comes from k1, a chronometer made by Larcum Kendall and played a important role in Captain Cook's voyage.
By now, it supports:
  • linux
  • macosx

Use

Try finding how to use it by reading example.ini!

Web Status

The default web status port is 9200 , just visit http://your_kone_ip:9200/ to check the kone status.

Documents

from https://github.com/xjdrew/kone
(kone: VPN through SOCKS/HTTP proxy.) 
-----------

Kone VPN源码分析

Kone是国人开发的一个VPN(准备确说是VPN转SOCKS/HTTP代理),自带DNS服务,需要结合使用。 通过配置域名规则,只要是需要走代理的域名,DNS都会返回一个VPN内网的IP,随后客户端的数据包会发往这个内网的IP,通过Tun VPN接口得到这些IPv4数据包,并作地址转换转发到监听端口,然后分别对UDP和TCP进行转发处理。TCP会使用代理建立连接(HTTP/SOCKS)。
得益于Go的扩平台特性,Kone可在路由器上使用,结合任意的SOCKS5工具(比如shadowsocks)一起即可.

TCP转发的示意图

本文假设设置了如下配置:
[general]
network = 10.192.0.1/16

[dns]
nameserver = 114.114.114.114
nameserver = 223.5.5.5

[proxy "A"]
url = socks5://192.168.1.1:1080

[pattern "proxy-website-keyword"]
proxy = A
scheme = DOMAIN-KEYWORD
v = google

[rule]
pattern = proxy-website-keyword 
  
匹配域名,如果有域名代理规则匹配,则创建一个DNS会话,
并返回一个假的查询结果Ip给到客户端(从VPN的地址池中分配一个IP,
与VPN的IP处于同一内网)。
同时DNS会话记录了此Ip关联了的域名。
如果发查询的域名没有匹配,
则使用上层DNS服务进行DNS查询,如果返回的结果中CNAME匹配了某个域名代理规则,
或者IP匹配了某个IP代理规则,
则同第上一步,返回假的VPN内网Ip给到客户端.
 
如果2、3匹配到了代理规则并返回客户端假Ip,还会同时开启一个goroutine查询真正的Ip,
这个用处后面会说。
 
如果都没有代理规则匹配,则直接把从上游DNS服务返回的查询结果直接返回给客户端,
这种情况相当于直连,客户端得到DNS结果后的后续的行为都不会经过后面的Nat地址转换/
代理转发的过程。
 
综上,对于代理规则匹配时,返回假内网Ip并创建DNS会话记录了该假Ip、查询的域名、真实Ip、该域名应该走什么代理,这些信息将用于完成后面TCP转发、UDP转发。而当没有代理规则匹配时,数据包会直接发往目标Ip,也没有后面的TCP/UDP转发的需要。

DNS污染?

Kone不能防止DNS污染,除非所使用的NS可以返回正确结果并且不会在返回中途被污染。因为Kone对UDP是没有代理效果的,而DNS又走UDP,所以也不能指望通过路由规则让DNS查询数据包走代理出去。

TCP转发

拦截数据包

通过Tun接口读取数据包,并跟据上层协议分发给相应过滤器。后面的处理UDP与TCP类似,不一样的是UDP还没有实现代理的方式进行转发,都是直接转发.
 

Nat地址转换

对于目标IP为在DNS查询时所返回的内网IP的TCP数据包,统一转发到Kone的TCP转发监听端口。这个转发是通过TCP过滤器在Tun读取到的符合条件的TCP数据包后修改其源和目标地址,并写入回Tun完成的。修改的地址的信息记录为一个Nat会话。
比如上述示意图中客户端查询google.com的ip,得到的是伪造的Tun接口内网IP-10.192.0.11,然后客户端会向这个Ip的443端口发起TCP连接。此时作了如下的地址转换(Nat):
原数据包: 192.168.1.20:N->10.192.0.11:443
转换后:  10.192.0.11:20001-> 10.192.0.1:82
以上这些信息构成了一个Nat会话,记录了数据包原来从哪发到哪,以及转换后的分配的端口20001。N是客户端发起时使用的端口(随机的)不重要。20001是Nat模块分配的(可用范围由配置文件的nat-port-start和nat-port-end指定)。
其中原数据包的源ip/port即192.168.1.20:N唯一标识该会话,地址转换后的源端口20001也唯一标识该会话。

通过代理转发TCP连接

Kone服务端监听TCP转发端口(默认为82端口),发现一个新连接来源自ip 10.192.0.11:20001,通过20001源端口即可查找Nat会话,Nat会话表明该TCP连接原来的目标是10.192.0.11,按此Ip查找到相应的DNS会话,得知此连接的真正目标域名(google.com)以及指定要走什么代理(socks5),从而通过代理转发连接。

Nat地址逆转换

Kone由服务端转发的数据包回来后转发到了的Nat会话转换后的源IP端口即10.192.0.11:20001,那么还要进行Nat地址逆转换。通过20001,可以找到Nat会话的信息,将目标地址转成Nat会话前的源IP和端口,也即客户端192.168.1.20:N。
原数据包: 10.192.0.1:82 -> 10.192.0.11:20001
转换后:  10.192.0.11:443 -> 192.168.1.20:N
Nat逆转换也是在Tun的TCP过滤器中,通过判断来源IP和端口恰好等于Kone的TCP转发监听地址10.192.0.1:82,即可认定这是通过TCP转发模块转发出去的流量返回的数据包,需要进行Nat逆转换.

UDP转发

目前看代码UDP转发并没有走代理(因为当前支持的人理SOCKS/HTTP还未支持UDP吧),只是纯粹的NAT地址转换了。

跟TCP不一样的是,最终转发请求时并没有用原始的域名,而是用原始的域名解释出来的Ip,连接也是直连并不是走代理。

from https://fooltwo.me/post/kone-vpn%E6%BA%90%E7%A0%81%E5%88%86%E6%9E%90/

No comments:

Post a Comment