Pages

Wednesday, 1 August 2018

V2Ray的进阶用法-链式代理与透明代理

这个是 TLS 下一步的进化方向:
https://github.com/v2ray/v2ray-core/commit/318a36fe581ac7cab329a3a23624f99e43333d60
V2Ray, 或者准确的说是 Project V, 她在一开始对自己的介绍就是一个模块化的代理工具包平台,而显然,她已经在这条路上越走越远了。刚从 Shadowscoks/R 之类的代理软件过来的用户,看着文档可能会一头雾水:我只是想翻墙就好,不需要这么多乱七八糟的,为什么同样以 json 作为配置文件,V2Ray这些都是啥玩意啊?
如果你对这些是啥玩意并没有兴趣,你可以直接食用我的模板 https://git.io/kiri ,或者使用直接使用一键脚本。如果你又兴趣,你可以仔细看一下官方文档和白话文版文档,我相信你会对仅仅将 V2Ray 当作 ss 替代品感到后悔的。今天就简单地水一下 V2Ray 的两种用法:链式代理和透明代理。

透明代理

透明代理顾名思义,就是一个“一般用户”察觉不到就走了的代理服务器,从实现上是将所有的流量都转发给一台代理,从而做到全局代理的效果(跟 VPN 还是有区别的)。透明代理对于翻墙用户来说一般是部署在软路由上的,当然如果你的 PC 装的是 Linux 的话操作完全一样。下面就针对 Linux 系统来介绍透明代理, Windows 用户也可以通过 Hyper-V 开一个 Linux 虚拟机做软路由,或者借助一些其他的软件。
对 ss 这类软件,这个操作需要借助一些第三方软件才能完成,比如说,redsocks. 在这里,redsocks 的作用是将所有所有 TCP 连接转发到上游的代理服务器,比如 ss 监听在本地的 socks 代理,转发请求这个操作在 Linux 平台上一般是用 iptables 完成的。而我们现在用的是 V2Ray,打开文档,翻到Dokodemo door 这一节, 官方是这样描述的:
Dokodemo door(任意门)是一个传入数据协议,它可以监听一个本地端口,并把所有进入此端口的数据发送至指定服务器的一个端口,从而达到端口映射的效果.
是不是很熟悉?没错,也就是说 V2Ray 自身就可以实现 Redsocks 的功能!我们的透明代理并不需要第三方软件!
一个场景:我已经配置好了服务器和客户端,现在想实现让所有流量都走代理(也就是outbound)——
那就直接参考官网的示例, 具体来说,你可以写出这样的配置文件:

config.json
    {
     "inbound": {...},
     "outbound": {...},
     "inboundDetour": [
         {
             "domainOverride": ["tls","http"],
             "port": 12345,
             "protocol": "dokodemo-door",
             "settings": {
                 "network": "tcp,udp",
                 "followRedirect": true
             },
             "tag":"door"
         },
         ...
     ],
     "outboundDetour": [...],
     "routing": {
        "strategy": "rules",
        "settings": {
          // 添加下面这条规则
          "rules": [{
            "type": "field",
            "inboundTag": ["door"],
            "outboundTag": "你想传出的tag"
          }],
        }
    }
在完事之后,用 iptables 将所有 tcp 流量转发到 door 对应的 12345 端口:
$ iptables -t nat -N V2RAY

$ iptables -t nat -A V2RAY -d 0.0.0.0/8 -j RETURN
$ iptables -t nat -A V2RAY -d 10.0.0.0/8 -j RETURN
$ iptables -t nat -A V2RAY -d 100.64.0.0/10 -j RETURN
$ iptables -t nat -A V2RAY -d 127.0.0.0/8 -j RETURN
$ iptables -t nat -A V2RAY -d 169.254.0.0/16 -j RETURN
$  iptables -t nat -A V2RAY -d 172.16.0.0/12 -j RETURN
$ iptables -t nat -A V2RAY -d 192.168.0.0/16 -j RETURN
$ iptables -t nat -A V2RAY -d 198.18.0.0/15 -j RETURN
$ iptables -t nat -A V2RAY -d 224.0.0.0/4 -j RETURN
$ iptables -t nat -A V2RAY -d 240.0.0.0/4 -j RETURN

$ iptables -t nat -A V2RAY -p tcp -j REDIRECT --to-ports 12345
$ iptables -t nat -A OUTPUT -p tcp -m owner --uid-owner kiri -j V2RAY
$ iptables -t nat -A OUTPUT -p tcp -m owner --uid-owner root -j V2RAY
这样就差不多完了。
另一种场景:我们公司/学校里有一个 http-connect/socks 代理,我想要所有流量都通过代理上网——
这个需求其实有很多其他专门的软件可以解决,比如 redsocks,但是为了显示 V2Ray 的万能,我们来用V2Ray 来完成这件事。
首先,如果是 socks 代理,事情很简单,我们只需要这样写:

config.json
    {
    "inbound":{
         "domainOverride": ["tls","http"],
         "port": 12345,
         "protocol": "dokodemo-door",
         "settings": {
             "network": "tcp",
             "followRedirect": true
         }
     },
     "outbound": {
            "protocol": "socks",
            "settings": {
                "servers": [
                    {
                        "address": "127.0.0.1", //这是上游socks代理的ip
                        "port": 3378    //这是上游socks代理的端口
                    }
                ]
            }
        }
    }
然后,跟上一个情景一样,使用 iptables 将所有流量转发到 12345 端口即可~
不过,如果公司提供的代理类型是 http-connect 的话,问题会有点没那么简单,因为 V2Ray 的传出代理并不支持 http ,而小薇姐姐也说并没有支持的计划(参见 issue#40),于是我们可以借助 eq 的 h2s 来实现啦~
h2s 的作用就是将一个 http 代理转化为一个 socks 代理,然后 V2Ray 的配置就参考上面一样的写就行啦~
不过还有一点要注意的,尽管将 http 代理转换成了 socks代理,但是由于 http 代理是不支持 udp 的,因此我们依然只能将所有 tcp 连接进行转发。

链式代理

要说有什么事情是只用一键脚本的人绝对不知道,而好好看文档的人应该会知道的话,那就是链式代理了。链式代理在 SS/R 中被叫做 “前置代理”,Windows 版和 Android 版的 SS/R 都是有的,而在 V2Ray 中,这个功能更为强大。
为了解释这个概念,官方文档中给出了这么一个例子:当你觉得机场虽然线路可以保证,但是却不能保证安全,而自建的服务器成本太高(包括一个好线路的成本和被墙的风险成本),你可以选择一个折衷的选项——买一个 SS 机场,随便买一台国外服务器(不需要多好的线路),然后把 SS 和 V2Ray 串起来!
听起来有点不可思议?来看一下我画的示意图你差不多就懂了:


这是我们本来直接使用 SS/V2Ray 时的情景,我们对目标网站的请求被包装在一条可靠的隧道中,穿过墙到达代理服务器(或者机场服务器)后,由代理服务器转发到目标网站,非常好懂。


而现在,买下了一家机场的 SS,于是我们在本地到机场之间建立起了一条隧道,在直接把原始请求发给自建服务器之前,我们在里面再加一条通往自建服务器的隧道,最后把原始请求包装在最里面,穿过防火墙、到达机场、送达自建服务器,最后才发到目标网站。这样,我们既利用了机场的好线路,又保障了一定程度的数据安全。
就用 SS 机场做例子,现在怎么做?
直接参考官方文档的做法就行了:

config.json
{
  "inbound": {
    "port": 8080,
    "protocol": "socks",
    "settings": {
      "auth": "noauth",
      "timeout": 0
    },
  },
  "outbound": {
    "protocol": "vmess",
    "settings": { // settings 的根据实际情况修改
      "vnext": [
        {
          "address": "1.2.3.4",
          "port": 8888,
          "users": [
            {
              "alterId": 64,
              "id": "b12614c5-5ca4-4eba-a215-c61d642116ce"
            }
          ]
        }
      ]
    },
    "proxySettings": {
        "tag": "transit"  // 这里的 tag 必须跟作为中转 VPS 的 tag 一致,这里设定的是 "transit"
      }
  },
  "outboundDetour": [
    {
      "protocol": "shadowsocks",
      "settings": {
        "servers": [
          {
            "address": "2.2.2.2",
            "method": "aes-256-cfb",
            "ota": false,
            "password": "password",
            "port": 1024
          }
        ]
      },
      "tag": "transit"
    }
  ]
}
简单的说,就是在你准备发往自建服务器的outbound里加一个字段 proxySettings, 它的值对应的是写给机场的 outbound 的 tag,然后接下来给机场写一个 outbound,协议为 ss,tag 和上面对应就行了。这样就完成了我们的链式代理。
不过!光靠 proxySettings 是有一个大坑的,也就是当我们使用 proxySettings 的时候,streamSettings 就失效了!这会导致我们不能使用ws,tls这些骚操作(虽然实际上并不需要,因为这部分流量已经在国外了)。不过真的我们这样就无计可施了吗?
当然不是,不然怎么说V2Ray是万能的呢。回到上一节,我们有一个可以处理所有tcp,udp请求的 dokodemo-door,它当然也可以用来处理ws了。
重写以上配置文件:

config.json
{
  "inbound": {
    "port": 8080,
    "protocol": "socks",
    "settings": {
      "auth": "noauth",
      "timeout": 0
    },
  },
  "outbound": {
    "protocol": "vmess",
    "settings": {
      "vnext": [{
        "address": "127.0.0.1", // 注意这里
        "port": 50001,          // 注意这里。端口可自定义,与下方任意门的相同即可
        "users": [{
          // 此处与原先的配置相同
          // ...
        }]
      }]
    },
    "streamSettings": {
      "network": "ws",
      "security": "tls",
      "wsSettings": {
        // path 等设置与原先的相同
        // ...
        "headers": {
          "Host": "你的主机名(一般是域名)" // 请务必正确地配置这段,否则 WS 握手会失败
        }
      },
      "tlsSettings": {
        // ...
        "serverName": "你的主机名(一般是域名)", // 请务必正确地配置这段,否则 TLS 握手会失败。一般的,它与上述的 Host 相同
      }
    }
  },

  // 新加入的任意门 inbound,用于内部桥接
  "inboundDetour": [{
    "listen": "127.0.0.1",
    "port": 50001, // 与上面的 VMess 的 port 相同即可
    "protocol": "dokodemo-door",
    "settings": {
      "network": "tcp", 
      "address": "在此填上原本应该填在 VMess 的 address 里的内容", // 注意这里,一般来说就是你的 v2ray 服务端地址
      "port": 443 // 在此填上原本应该填在 VMess 的 port 里的内容。同上
    },
    "tag": "bridge" // tag 是必须要有的,否则无法进行路由
  }],
  "outboundDetour": [
    {
      "protocol": "shadowsocks",
      "settings": {
        "servers": [
          {
            "address": "2.2.2.2",
            "method": "aes-256-cfb",
            "ota": false,
            "password": "password",
            "port": 1024
          }
        ]
      },
      "tag": "transit"
    }
  ]
  ……
  "routing": {
    "strategy": "rules",
    "settings": {
      // 添加下面这条规则
      "rules": [{
        "type": "field",
        "inboundTag": ["bridge"],
        "outboundTag": "transit"
      }],
      // 其余部分不变
      // ...
    }
  }
}
具体的原理就不说了,自己看看配置理解一下吧。
回到上面公司的话题,如果我没有 Linux 环境也没有路由器也不想做软路由,除了透明代理以外我还有什么选择吗?
有的!让我们想一下这个逻辑,我们刚刚是将机场提供给我们的 Shadowsocks 代理做成了链式代理,在 SS 的隧道里面藏进了一个 V2Ray,那么现在公司提供给了我们一个 socks 代理,道理难道不是一样的嘛?
没错,就是一样的。我们只需要将上面配置的 OutboundDetour 中的 shadowsocks 协议改为 socks 协议就可以了。公司提供的是 http 代理的话,就用 h2s 将http代理转换为 socks 代理就可以了。
这些配置我就不给模板了,因为视具体情况而言配置会差别比较大,再说在本文开头我也是建议你们去看一下官方文档来着的~
那我们就下次再见啦~
参考资料:
相关帖子:
https://briteming.blogspot.com/2015/10/v2ray.html 
------------------------------------------------------------
 
v2ray进阶篇:负载均衡实现多线程下载带宽叠加,油管8K视频秒开

经常有人问我v2ray可以实现负载均衡吗?答案是肯定的。v2ray的负载均衡能实现什么功能?第一,自动切换节点,会根据观测记录选择 HTTPS GET 请求完成时间最快的一个出站连接。这个功能和Clash提供的功能很类似。第二,会从出站节点数组中随机选出一个作为最终的出站连接。实现宽带叠加,同时降低节点负载。例如我有两只免费的小笨鸡hax.co.id/woiden.id,不管使用哪一个,速度都不是很好,油管上看1080P都不流畅,更不要提8K秒开了。今天我就带领大家使用v2ray负载均衡实现多线程下载带宽叠加。

一、远程服务器端

v2ray负载均衡对于远程服务器端使用什么协议,没有过多要求,常用的vmess,vless,shadowsocks,trojan均支持。但是我更习惯使用本站提供的V2ray多合一脚本安装VMESS+websocket+TLS+Nginx。
Bash

bash <(curl -sL https://raw.githubusercontent.com/hiifeng/v2ray/main/install_v2ray.sh)

二、客户端配置

1、windows客户端软件使用v2rayN,可以在github上下载目前的最新版本。

https://github.com/2dust/v2rayN/releases/download/5.38/v2rayN-Core.zip

2、配置config.json文件,建议使用Notepad++或UltraEdit等文本编辑器。配置文件内容参考如下:

{
  "policy": {
    "system": {
      "statsOutboundUplink": true,
      "statsOutboundDownlink": true
    }
  },
  "log": {
    "access": "",
    "error": "",
    "loglevel": "warning"
  },
//入站规则
  "inbounds": [
    {
      "tag": "socks",
      "port": 10808,
      "listen": "127.0.0.1",
      "protocol": "socks",
      "sniffing": {
        "enabled": true,
        "destOverride": [
          "http",
          "tls"
        ]
      },
      "settings": {
        "auth": "noauth",
        "udp": true,
        "allowTransparent": false
      }
    },
    {
      "tag": "http",
      "port": 10809,
      "listen": "127.0.0.1",
      "protocol": "http",
      "sniffing": {
        "enabled": true,
        "destOverride": [
          "http",
          "tls"
        ]
      },
      "settings": {
        "auth": "noauth",
        "udp": true,
        "allowTransparent": false
      }
    },
    {
      "tag": "api",
      "port": 53284,
      "listen": "127.0.0.1",
      "protocol": "dokodemo-door",
      "settings": {
        "udp": false,
        "address": "127.0.0.1",
        "allowTransparent": false
      }
    }
  ],
  //出站规则
  "outbounds": [
    {//小鸡woiden.id节点的配置
      "tag": "woiden",                //需要给节点配置tag,名称任意
      "protocol": "vmess",
      "settings": {
        "vnext": [
          {
            "address": "woiden.ifeng.ml",
            "port": 443,
            "users": [
              {
                "id": "948a4c79-ef2a-46f0-a781-810db9efc4a1",
                "alterId": 0,
                "email": "t@t.tt",
                "security": "auto"
              }
            ]
          }
        ]
      },
      "streamSettings": {
        "network": "ws",
        "security": "tls",
        "tlsSettings": {
          "allowInsecure": false,
          "serverName": "woiden.ifeng.ml"
        },
        "wsSettings": {
          "path": "/woiden",
          "headers": {
            "Host": "woiden.ifeng.ml"
          }
        }
      },
      "mux": {
        "enabled": false,
        "concurrency": -1
      }
    },
    {//小鸡hax.co.id节点的配置
      "tag": "hax",                //需要给节点配置tag,名称任意
      "protocol": "vmess",
      "settings": {
        "vnext": [
          {
            "address": "haxid.ifeng.ml",
            "port": 443,
            "users": [
              {
                "id": "5bc4ab2e-63fe-11ed-81ce-0242ac120002",
                "alterId": 0,
                "email": "t@t.tt",
                "security": "auto"
              }
            ]
          }
        ]
      },
      "streamSettings": {
        "network": "ws",
        "security": "tls",
        "tlsSettings": {
          "allowInsecure": false,
          "serverName": "haxid.ifeng.ml"
        },
        "wsSettings": {
          "path": "/haxid",
          "headers": {
            "Host": "haxid.ifeng.ml"
          }
        }
      },
      "mux": {
        "enabled": false,
        "concurrency": -1
      }
    },
    {
      "tag": "direct",
      "protocol": "freedom",
      "settings": {}
    },
    {
      "tag": "block",
      "protocol": "blackhole",
      "settings": {
        "response": {
          "type": "http"
        }
      }
    }
  ],
 //探针,每隔10分钟测试一次数组中节点的连接速度,负载均衡策略对象为leastPing会调用。
  "observatory": {
    "subjectSelector":[
        "woiden",
        "hax"
    ],
    "probeInterval":"10m"
  },
  "stats": {},
  "api": {
    "tag": "api",
    "services": [
      "StatsService"
    ]
  },
  "routing": {
    "domainStrategy": "IPIfNonMatch",
    "balancers": [//负载均衡策略
      {
        "tag": "balancer",
        "selector": [//一个字符串数组,其中每一个字符串将用于和出站协议标识的前缀匹配。
          "woiden",
          "hax"
        ],
        "strategy": {//负载均衡策略对象
          //type可填 random 或 leastPing ;random 会从出站中随机选出一个作为最终的出站连接;
          //leastPing 会根据观测记录选择 HTTPS GET 请求完成时间最快的一个出站连接。
          "type": "random"       
        }
      }
    ],
    "rules": [
      {
        "type": "field",
        "inboundTag": [
          "api"
        ],
        "outboundTag": "api",
        "enabled": true
      },
      {
        "type": "field",
        "outboundTag": "direct",
        "domain": [
          "domain:example-example.com",
          "domain:example-example2.com"
        ],
        "enabled": true
      },
      {
        "type": "field",
        "outboundTag": "block",
        "domain": [
          "geosite:category-ads-all"
        ],
        "enabled": true
      },
      {
        "type": "field",
        "outboundTag": "direct",
        "domain": [
          "geosite:cn"
        ],
        "enabled": true
      },
      {
        "type": "field",
        "outboundTag": "direct",
        "ip": [
          "geoip:private",
          "geoip:cn"
        ],
        "enabled": true
      },
      {//将流量转发给负载均衡策略
        "type": "field",
        "network": "tcp,udp",
        "balancerTag": "balancer"
      }
    ]
  }
}

相关说明:

①以上示例,我在outbounds中放了两个节点。节点数量没有限制,根据自己情况添加即可。

②leastPing需要v2ray v4.38.0以上版本才能支持,建议v2ray使用最新版本。

③183行,type值为random宽带叠加,type值为leastPing自动选择速度最快的节点出站。

④使用v2ray实现的透明代理同样支持宽带叠加,明白原理后,简单修改一下config.json文件即可。

⑤使用v2ray负载均衡宽带叠加,如果‘节点套cdn‘时,可以实现单线复用。

3、v2rayN客户端配置,点击菜单上“服务器”中的“添加自定义服务器”,
然后选择上一步配置好的config.json文件,导入即可。从下面图片中你可以看到,随机与节点hax或woiden建立连接。

参考文献:
https://toutyrater.github.io/app/balance.html
https://guide.v2fly.org/routing/balance2.html
https://www.v2fly.org/config/routing.html#balancerobject
https://www.v2fly.org/config/observatory.html#observatoryobject

No comments:

Post a Comment