| 
 | 
 
之前已经使用ubuntu和shadowsocks配合ipset实现了科学上网,详见这里https://yylib.com/bbs/forum.php?mod=viewthread&tid=1&extra=,为啥要继续折腾呢,出于以下几个目的: 
1:SS有的时候确实会被干掉,特别是在节假日的时候,自己的私人VPS小流量也不行,只有换端口号才能解决。因此听说新一代协议V2ray的抗干扰更好,更加稳定,所以换一下试试。在研究V2ray的过程中,看到了一个分支Xray,见这里https://xtls.github.io/,他的教程相对更加完善(但都是针对单臂路由或者旁路由的,作为主路由是不行的,所以我会针对性的做改动),就决定用Xray试试 
2:以前使用SS时,UDP打游戏是无法很好解决的,一些外服游戏的直连很不稳定,并且switch的NAT TYPE也很差,据说V2RAY/Xray的tproxy模式可以很好解决这个问题,实现UDP的透明代理 
3:从DNS开始解决分流,外网的直接DNS就解析到外网,以前通过pdnsd转发53请求到dnsmasq来实现,现在XRAY可以通过内置的DNS解析服务统一实现。 
 
 
 
 
 
 
下面是详细步骤记录(部分重复的不再详细写,见之前的帖子https://yylib.com/bbs/forum.php?mod=viewthread&tid=1&extra=): 
1:安装ubuntu-server 20.04 
后来发现,由于17.04以上,开始使用netplan替代原有ifconfig系统,非常不习惯,netplan的配置文件搞了几次总是搞不定,最终换回16.04 
由于16.04不兼容intel cpu最近几年的新的集成显卡,启动后会黑屏。需要更新linux内核,把ubuntu的linux内核更新至4.20版本可以解决问题。怎么更新自行搜索吧,网上很多教程。 
 
2:root和ssh 
设置root用户密码,允许SSH连接。 
我后续还是都用root来执行,包括安装xray的root选项,以及使用root来执行自动化脚本 
 
3:DHCP和内网 
先用一个网卡接入网络,IP设置为192.168.1.1,配置dnsmaq,开启DHCP服务。 
DHCP给内网其它机器的网段为192.168.1.X,即192.168.1.0/24。 
后面配置文件中一般用192.168.0.0/16来覆盖包含这个网段并预留更大的网段。 
 
4: 拨号pppoe 
apt-get install pppoeconf 
然后使用一个脚本,定期监控pppoe 
 
5:VPS服务器 安装 服务端xray 
这个会相对复杂,主要是配置服务器的https加密证书,以便让流量伪装成HTTPS服务的流量。但是V2RAY和XRAY的433跳转仅为nginx测试,在apache2出问题,所以暂时还无法解决良好的回落跳转问题,也就是万一有工作人员人工检查你这个网址,还是会发现https不正常。 
服务器安装请参考这个详细教程:https://xtls.github.io/document/level-0 
这个教程详细讲了如何配置HTTPS证书。 
 
我稍微做了改动,把其中的用户换为root(安装脚本加 -u root参数),www服务换为apache2 
我的server端config.json: 
// REFERENCE: 
// https://github.com/XTLS/Xray-examples 
// https://xtls.github.io/config/ 
// 常用的 config 文件,不论服务器端还是客户端,都有 5 个部分。外加小小白解读: 
// ┌─ 1*log 日志设置 - 日志写什么,写哪里(出错时有据可查) 
// ├─ 2_dns DNS-设置 - DNS 怎么查(防 DNS 污染、防偷窥、避免国内外站匹配到国外服务器等) 
// ├─ 3_routing 分流设置 - 流量怎么分类处理(是否过滤广告、是否国内外分流) 
// ├─ 4_inbounds 入站设置 - 什么流量可以流入 Xray 
// └─ 5_outbounds 出站设置 - 流出 Xray 的流量往哪里去 
{ 
  // 1\_日志设置 
  "log": { 
    "loglevel": "warning", // 内容从少到多: "none", "error", "warning", "info", "debug" 
    "access": "/root/xray_log/access.log", // 访问记录 
    "error": "/root/xray_log/error.log" // 错误记录 
  }, 
  //dns已经在客户端设置了,这里不需要多此一举了 
  // 2_DNS 设置 
  //"dns": { 
  //  "servers": [ 
  //    "https+local://1.1.1.1/dns-query", // 首选 1.1.1.1 的 DoH 查询,牺牲速度但可防止 ISP 偷窥 
  //    "localhost" 
  //  ] 
  //}, 
  // 3*分流设置 
  "routing": { 
    "domainStrategy": "AsIs", 
    "rules": [ 
      // 3.1 防止服务器本地流转问题:如内网被攻击或滥用、错误的本地回环等 
      { 
        "type": "field", 
        "ip": [ 
          "geoip:private" // 分流条件:geoip 文件内,名为"private"的规则(本地) 
        ], 
        "outboundTag": "block" // 分流策略:交给出站"block"处理(黑洞屏蔽) 
      } 
      // 3.2 屏蔽广告 
      //{ 
      //  "type": "field", 
      //  "domain": [ 
      //    "geosite:category-ads-all" // 分流条件:geosite 文件内,名为"category-ads-all"的规则(各种广告域名) 
      //  ], 
      //  "outboundTag": "block" // 分流策略:交给出站"block"处理(黑洞屏蔽) 
      //} 
    ] 
  }, 
  // 4*入站设置 
  // 4.1 这里只写了一个最简单的 vless+xtls 的入站,因为这是 Xray 最强大的模式。如有其他需要,请根据模版自行添加。 
  "inbounds": [ 
    { 
      "port": 444, 
      "protocol": "vless", 
      "settings": { 
        "clients": [ 
          { 
            "id": "d59b91a5-****-4fa9-****-1c3b68d4f31e", // 填写你的 UUID 
            "flow": "xtls-rprx-direct", 
            "level": 0, 
            "email": "ddr@softbank-VPS" 
          } 
        ], 
        "decryption": "none", 
        //fallback的逻辑太傻,占用443端口,爷不理解 
        "fallbacks": [ 
          { 
           "dest": 443 // 默认回落到防探测的代理 
          } 
        ] 
      }, 
      "streamSettings": { 
        "network": "tcp", 
        "security": "xtls", 
        "xtlsSettings": { 
          "allowInsecure": false, // 正常使用应确保关闭 
          "minVersion": "1.2", // TLS 最低版本设置 
          "alpn": ["http/1.1"], 
          "certificates": [ 
            { 
              "certificateFile": "/root/xray_cert/xray.crt", 
              "keyFile": "/root/xray_cert/xray.key" 
            } 
          ] 
        } 
      } 
    } 
  ], 
  // 5*出站设置 
  "outbounds": [ 
    // 5.1 第一个出站是默认规则,freedom 就是对外直连(vps 已经是外网,所以直连) 
    { 
      "tag": "direct", 
      "protocol": "freedom" 
    }, 
    // 5.2 屏蔽规则,blackhole 协议就是把流量导入到黑洞里(屏蔽) 
    { 
      "tag": "block", 
      "protocol": "blackhole" 
    } 
  ] 
}  
6:软路由安装xray客户端 
XRAY其实不区分客户端和服务端,安装都是一样的,只是配置文件的差别。 
在软路由上安装xray会比较麻烦,因为这时你还无法科学上网,但是github大概率是没法直接访问的,所以: 
 
先修改/etc/hosts 
13.114.40.48           www.github.com 
13.230.158.120          api.github.com 
52.192.72.89            github.com 
52.68.31.213            codeload.github.com 
185.199.108.133         raw.github.com 
185.199.110.153         documentcloud.github.com  
#安装为root权限 
wget https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geoip.dat  
wget  https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geosite.dat  
mv ./*.dat /usr/local/share/xray/  bash -c "$(curl -L https://github.com/XTLS/Xray-install/raw/main/install-release.sh)" @ install -u root  
这样就安装完成,下面是配置,分两部分一部分是iptables的规则,一部分是客户端的config.json 
配置的思路和教程可以看这个: 
 
https://guide.v2fly.org/app/tproxy.html 
 
https://xtls.github.io/document/level-2/tproxy.html#%E5%BC%80%E5%A7%8B%E4%B9%8B%E5%89%8D 
 
这个教程的大概思路就是,把所有发往外网的包,先通过iptables在prerouting的mangle环节打上mark 1标签,有mark 1标签的包,会经过单独添加的route表100的路由指向,用tproxy模式(注意不是redirect,redirect无法很好实现udp的透明代理)发到软路由上的XRAY本地服务端口,本地xray对每个包进行判断,看是走直连直接把包发给外网,还是代理到你的VPS服务端,不管哪种都会把包打mark 2。 
为了实现软路由本机也能科学上网,还专门对output的mangle环节也做了一些设置,让本机各种程序的包再次进入上面的mark 1循环。 
 
这教程针对的是单臂路由/旁路由,使用起来是没问题的,如果你的软路由是主路由,直接使用会有包的死循环,无法使用,原因是: 
 
linux的netfilter逻辑: 
 
 
 
 
 
 
(1):单臂路由(比如单臂路由自身有一块网卡,ip为192.168.1.2;家里上网网关有两块网卡,lan为192.168.1.1,wan为外网IP)走到xray截胡包,改为direct或者proxy再发包时,经由output发出时,因为本身只有一块网卡,需要把这个包output直接发给网关的网卡192.168.1.1,再被WAN网卡转发出去外网,是没有任何问题的。 
如果你的主路由(有两块网卡,lan为192.168.1.1接收内网各个机器发来的包,转发给外网IP的wan网卡实现上网)这么干,就会存在问题,在output的时候,这个包又被发给了本机(的wan网卡),这时会再次进入iptables在prerouting的mangle环节,被打上mark 1,形成死循环。所以要在主路由的iptables里面加一行配置避免这种情况。 
(2):单臂路由的XRAY判断完毕,用output发包时,因为只有一块网卡,因此这个包的Source地址是192.168.1.2,经由网关DNAT发给外网,外网回包后,网关自动SNAT,再把包发回单臂路由,这时这个回包的dest是192.168.1.2,是内网IP,是不会进入网上教程的prerouting的mangle环节的,没问题。 
但是如果是主路由,XRAY判断完毕,用output发包时,因为多块网卡,会直接用那个外网网卡的IP作为source地址来发包,外网包回包时,dest是你主路由的外网IP,这时就会再次进入网上教程的prerouting的mangle环节,形成死循环,造成你无法收到回包。因此也需要修改iptables规则避免这种现象。 
 
我把我设置的iptables规则写成一个sh脚本,设置为crontab reboot时执行一次,完整的sh脚本如下: 
#!/bin/bash 
export PATH=$PATH:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games 
 
 
#for soft router nat 
#允许在不同interface转发包forward命令 
echo 1 > /proc/sys/net/ipv4/ip_forward 
 
#清空iptables 
iptables -F # 若是没有加上 -t 指定 table,预设是使用 -t filter 
iptables -P INPUT ACCEPT # 没加上 -t 指定 table,预设使用 -t filter 
iptables -P FORWARD ACCEPT 
 
#开启NAT模式,这样就可以实现软路由的基本功能让内网所有机器可以上网 
iptables -t nat -A POSTROUTING -o ppp0 -j MASQUERADE 
#这条命令执行后,会在conntrack里生成一个记录,以便收到回包时自动DNAT 
 
#not allow other people use my proxy 
iptables -A INPUT ! -d 192.168.1.0/24 -p tcp --dport 981 -j DROP 
iptables -A INPUT ! -d 192.168.1.0/24 -p tcp --dport 980 -j DROP 
iptables -A INPUT ! -d 192.168.1.0/24 -p tcp --dport 988 -j DROP 
 
#for xunlei 端口转发 
iptables -t nat -A PREROUTING ! -d 192.168.1.0/24 -p tcp --dport 10001 -j DNAT --to-destination 192.168.1.100:10001 
iptables -t nat -A PREROUTING ! -d 192.168.1.0/24 -p udp --dport 10002 -j DNAT --to-destination 192.168.1.100:10002 
iptables -t nat -A PREROUTING ! -d 192.168.1.0/24 -p tcp --dport 16003 -j DNAT --to-destination 192.168.1.100:16003 
 
#for xray 
#添加路由表 100。#这个表啥意思,是说你进入这个表的流量,都去LO网口?那样的话是直接froward到LO重新发包,引起prerouting,还是进入input chain? 猜测是进入input #local这个type,这是一个路由类型,凡这个类型的路由项,一旦有流量被匹配,所有的流量统统送到本地进行处理 
ip route add local default dev lo table 100  # 为路由表 100 设定规则,凡是打了mark1的,都走路由表100 
ip rule add fwmark 1 table 100  #新建一个XRAY规则集合 
iptables -t mangle -N XRAY  
#以下是针对本地局域网和广播的包,就跳出XRAY的chain的执行栈,继续向后执行了 
#针对VPS的IP的,是否要加入到这个规则里面,避免再次跳转形成循环,如果VPS是个域名动态IP怎么办? 因为被打了mark2,所以直接送出了,也不会再进入prerouting 
#但是在XRAY内部,怎么区分我是访问VPS的网站,还是访问VPS的代理?因为自己的域名和IP很可能都不在geo的CN表里,这样所有访问自己VPS网站的流量也都会被代理,看起来问题不大。不过最好设置一条单独域名和IP规则,避免被代理。 
#如果是内网客户端访问本机的外网IP,怎么处理??应该要设置一条规则直接return 
iptables -t mangle -A XRAY -m mark --mark 2 -j RETURN #已经被处理过的包不再进入 
iptables -t mangle -A XRAY ! -s 192.168.1.0/24 -j RETURN #不是本地发出的包不应该代理 
iptables -t mangle -A XRAY -d 10.0.0.0/8 -j RETURN #预留内网网段 
iptables -t mangle -A XRAY -d 100.64.0.0/10 -j RETURN #运营商NAT保留地址段 
iptables -t mangle -A XRAY -d 127.0.0.0/8 -j RETURN #本机地址网段 
iptables -t mangle -A XRAY -d 169.254.0.0/16 -j RETURN #本地对等网络地址段 
iptables -t mangle -A XRAY -d 172.16.0.0/12 -j RETURN #预留内网网段 
iptables -t mangle -A XRAY -d 192.0.0.0/24 -j RETURN #预留内网网段,注意这里是24,也就是不覆盖192.168 
iptables -t mangle -A XRAY -d 224.0.0.0/4 -j RETURN #预留的组播地址 
iptables -t mangle -A XRAY -d 240.0.0.0/4 -j RETURN #E类地址保留作研究之用 
iptables -t mangle -A XRAY -d 255.255.255.255/32 -j RETURN #广播地址 
#以下是劫持全部的局域网53端口的DNS查询,这样局域网的机器设置什么DNS都无所谓了 
iptables -t mangle -A XRAY -d 192.168.0.0/16 -p tcp ! --dport 53 -j RETURN 
iptables -t mangle -A XRAY -d 192.168.0.0/16 -p udp ! --dport 53 -j RETURN 
#以下两句是最重要的,对进入XRAY CHAIN的剩余全部流量,不满足上面任何一条的,都用TPROXY的模式,转发到xray service的监听端口去,xray处理完,走outbound出来,应该就直接走output了。output会触发下面的XRAY_SELF,但是因为mark 2,所以可以被放行 
iptables -t mangle -A XRAY -p tcp -j TPROXY --on-port 988 --tproxy-mark 1 
iptables -t mangle -A XRAY -p udp -j TPROXY --on-port 988 --tproxy-mark 1 
#转发 TCP 时,REDIRECT 后包的目的地址已经变了,理论上来说,原目的地址已经丢了,透明代理是拿不到原目的地址的。那为什么透明代理能正确转发包呢? 
#实际上 netfilter 框架(iptables 也是基于这个框架暴露的勾子开发的)有 SO_ORIGINAL_DST 选项可以支持拿到原目的地址,netfilter 会将包的原目的地址放在 socket 的 SO_ORIGINAL_DST 属性里。 
#那么为什么 TCP 可以通过 SO_ORIGINAL_DST 拿到原目的地址,UDP 却不行? 
#原因跟 netfilter 的实现有关,SO_ORIGINAL_DST 是在 socket 上实现的,当 TCP 建立连接后,从对端的 socket 上就能拿到这个连接的原目的地址,实现成本很低。 
#而 UDP 不是面向连接的,无法从 socket 里去拿原目的地址 
#TProxy 可以不改变包的头,将包重定向到本地 socket,所以UDP的透明代理转发不能用原来SS-redir的 REDIRECT 
#进行完此处理动作后,将 会继续比对其它规则,因此可以继续执行NAT表的动作?? 
iptables -t mangle -A PREROUTING -j XRAY 
#为何还要搞个 --tproxy-mark 0x01/0x01 的选项呢 
#从数据包流向知道,PREROUTING 之后可能走 INPUT,也可能走 FORWARD,那到底走哪条,是由路由表决定的,因此,得有一条路由指示该包就是给本机的。 
#系统中初始就有两张路由表,一张 local (ID 255),一张 main (ID 254),可通过 ip route show table tableID 查看。这两张表都是按目的地址来路由的,如果照这两张表去走,这个包妥妥地就走 FORWARD 转发流程了,因为包的目的地址不是本机。 
#于是,就需要配置路由表,不能按目的地址来路由,所以配置按 mark 来路由: 
#通过添加100的路由表,来修改UDP包的路由选择 
#那些没有加chaina名称的iptables规则什么时候执行? XRAY,XRAY_SELF就是链名,相当于prerouting.   
#那这个自定义链,什么时候触发呢? 就是在prerouting -j 到XRAY的时候 
 
#iptables -t mangle -N XRAY_SELF 
#iptables -t mangle -A XRAY_SELF -d 10.0.0.0/8 -j RETURN 
#iptables -t mangle -A XRAY_SELF -d 100.64.0.0/10 -j RETURN 
#iptables -t mangle -A XRAY_SELF -d 127.0.0.0/8 -j RETURN 
#iptables -t mangle -A XRAY_SELF -d 169.254.0.0/16 -j RETURN 
#iptables -t mangle -A XRAY_SELF -d 172.16.0.0/12 -j RETURN 
#iptables -t mangle -A XRAY_SELF -d 192.0.0.0/24 -j RETURN 
#iptables -t mangle -A XRAY_SELF -d 224.0.0.0/4 -j RETURN 
#iptables -t mangle -A XRAY_SELF -d 240.0.0.0/4 -j RETURN 
#iptables -t mangle -A XRAY_SELF -d 255.255.255.255/32 -j RETURN 
#iptables -t mangle -A XRAY_SELF -d 192.168.0.0/16 -p tcp ! --dport 53 -j RETURN 
#iptables -t mangle -A XRAY_SELF -d 192.168.0.0/16 -p udp ! --dport 53 -j RETURN 
#iptables -t mangle -A XRAY_SELF -m mark --mark 2 -j RETURN #mark2的是已经被X-RAY处理过一次的,就直接放行好了,不需要再继续prerouting 
#iptables -t mangle -A XRAY_SELF -p tcp -j MARK --set-mark 1 #这些是由本机新发起的包,需要打mark1重新去prerouting 
#iptables -t mangle -A XRAY_SELF -p udp -j MARK --set-mark 1 #这些是由本机新发起的包,需要打mark1重新去prerouting 
#本机发起的网络包,是不走prerouting的,直接走output 
#TProxy 只能在 PREROUTING 链上设置,不能在 OUTPUT 上设置 
#这种情况,只能让包出去,再回来,回来的时候再通过 TProxy 规则重定向到透明代理。 
#那怎么让它从本网口出去又马上回到本网口来呢?还是走路由,在 OUTPUT 链给包打上 1 的mark,出去的时候就会查路由表,一查发现是给到 lo 口的,于是又回来了。 
#iptables -t mangle -A OUTPUT -j XRAY_SELF  
这里的修改如下: 
增加: 
iptables -t mangle -A XRAY -m mark --mark 2 -j RETURN #已经被处理过的包不再进入 
iptables -t mangle -A XRAY ! -s 192.168.1.0/24 -j RETURN #不是本地发出的包不应该代理 
这两行规则,可以使得主路由实现全局透明代理 
并且为了避免隐患,把本机科学上网的XRAY_SELF全部删除了 
 
软路由的XRAY客户端config.json配置如下: 
//没有看到对BT流量的不代理处理,估计是漏了,已经在route自己添加了一条 
{ 
  "log": { 
    "loglevel": "warning", 
    "error": "/var/log/xray/error.log", 
    "access": "/var/log/xray/access.log", 
    "dnslog": true 
  }, 
  "inbounds": [ 
    //socks代理 
    { 
      "tag": "s-in", 
      "port": 980, 
      "protocol": "socks", 
      "sniffing": { 
        "enabled": true, 
        "destOverride": ["http", "tls"] 
      }, 
      "settings": { 
        "auth": "noauth", 
        "udp": true 
      } 
    }, 
    //http代理 
    { 
      "tag": "h-in", 
      "port": 981, 
      "protocol": "http", 
      "sniffing": { 
        "enabled": true, 
        "destOverride": ["http", "tls"] 
      }, 
      "settings": { 
        "auth": "noauth", 
        "udp": false 
      } 
    }, 
    //透明代理,代理所有流量。通过iptables把全部流量都转发到此端口 
    { 
      "tag": "ipt-in", //对进入的流量打标签ipt-in 
      "port": 988, 
      "protocol": "dokodemo-door",  //这个模式叫任意门,Dokodemo door(任意门)可以监听一个本地端口,并把所有进入此端口的数据发送至指定服务器的一个端口,从而达到端口映射的效果. 
                                    //dokodemo-door 是用来接收透明代理的入站协议,followRedirect 项须为 true 以及 sockopt.tproxy 项须为 tproxy,建议开启 snifing,否则路由无法匹配域名; 
      "settings": { 
        "network": "tcp,udp", 
        "followRedirect": true //当值为 true 时,dokodemo-door 会识别出由 iptables 转发而来的数据,并转发到相应的目标地址 
      }, 
      "sniffing": { 
        "enabled": true, 
        "destOverride": ["http", "tls"] //当流量为指定类型时,按其中包括的目标地址重置当前连接的目标。  意思是伪装为HTTP类型的TLS加密的流量? 
      },        // 流量探测主要作用于在透明代理等用途. 比如一个典型流程如下: 
 
                // 如有一个设备上网,去访问 abc.com,首先设备通过 DNS 查询得到 abc.com 的 IP 是 1.2.3.4,然后设备会向 1.2.3.4 去发起连接. 
                // 如果不设置嗅探,Xray 收到的连接请求是 1.2.3.4,并不能用于域名规则的路由分流. 
                // 当设置了 sniffing 中的 enable 为 true,Xray 处理此连接的流量时,会从流量的数据中,嗅探出域名,即 abc.com 
                // Xray 会把 1.2.3.4 重置为 abc.com.路由就可以根据域名去进行路由的域名规则的分流 
                // 因为变成了一个向 abc.com 请求的连接, 就可以做更多的事情, 除了路由域名规则分流, 还能重新做 DNS 解析等其他工作. 
 
                // 当设置了 sniffing 中的 enable 为 true, 还能嗅探出 bittorrent 类型的流量, 然后可以在路由中配置"protocol"项来设置规则处理 BT 流量, 比如服务端用来拦截 BT 流量, 或客户端固定转发 BT 流量到某个 VPS 去等. 
 
      "streamSettings": { //StreamSettingsObject 对应入站或出站中的 streamSettings 项。每一个入站或出站都可以分别配置不同的传输配置,都可以设置 streamSettings 来进行一些传输的配置。 
        "sockopt": { 
          "tproxy": "tproxy"  //是否开启透明代理(仅适用于 Linux)"tproxy":使用 TProxy 模式的透明代理。支持所有基于 IPv4/6 的 TCP 和 UDP 连接。 
        } 
      } 
    } 
  ], 
  "outbounds": [ 
    { //隐藏的路由规则:当入站流量不符合任何条件时,转发给第一个出站  
      "tag": "direct", 
      "protocol": "freedom", 
      "settings": { 
        "domainStrategy": "UseIPv4" 
      }, 
      "streamSettings": { 
        "sockopt": { 
          "mark": 2 
        } 
      } 
    }, 
    { //翻墙出站 
      "tag": "proxy", 
      "protocol": "vless", 
      "settings": { 
        "vnext": [ 
          { 
            "address": "yourvps.com",   //这里会引起问题,这个域名解析不走下面的dns-out,然后似乎因为53被劫持,又被劫持了回来,劫持回来后跑到server的CN规则去了,并且造成223.5.5.5的返回为空失败,非常奇怪。解决办法是在软路由的/etc/hosts文件里直接解析 
            "port": 444, 
            "users": [ 
              { 
                "id": "d59b91a5-****-4fa9-****-1c3b68d4f31e", 
                "flow": "xtls-rprx-direct", 
                "encryption": "none" 
              } 
            ] 
          } 
        ] 
      }, 
      "streamSettings": { 
        "network": "tcp", 
        "security": "xtls", 
        "sockopt": { 
          "mark": 2 
        } 
      } 
    }, 
    { 
      "tag": "block", 
      "protocol": "blackhole", 
      "settings": { 
        "response": { 
          "type": "http" 
        } 
      } 
    }, 
    { //被劫持的53端口流量走这里,进入protocol": "dns",意思是用DNS那部分配置来解析? 
      "tag": "dns-out", 
      "protocol": "dns", 
      "settings": { 
        "address": "8.8.8.8"  //这里的DNS是为了修改原始DNS请求里的服务求地址,那应该不改是最好的? 
      }, 
      "proxySettings": { 
        "tag": "proxy" 
      }, 
      "streamSettings": { 
        "sockopt": { 
          "mark": 2 
        } 
      } 
    } 
  ], 
  "dns": { 
    "queryStrategy": "UseIPv4", 
    "disableFallback": true, 
    "disableFallbackIfMatch": true, 
    "hosts": { //这个解析本是为了拦截到DNS去再玩一次浪费时间,但是没有生效,看起来是个严重的程序BUG。 修改/etc/hosts有用处,可以避免VPS的多次解析 
      "yourvps.com": "137.***.***.122" 
    }, 
    //若命中的 DNS 服务器查询失败或 expectIPs 不匹配,则使用下一个命中的 DNS 服务器进行查询;否则返回解析得到的 IP。  
    //但是即使成功,似乎也会继续去查下一个,把写的全部走完,不知道是为啥。 
    //另外,还存在第一个返回的比第二个慢的问题 
    //以及存在IPv4返回但是V6没返回,导致报解析失败的问题 
    "servers": [  
      { 
        "address": "223.5.5.5", //阿里DNS 
        "domains": [ 
          "geosite:cn", 
          "geosite:apple-cn", 
          "geosite:google-cn" 
        ], 
        "expectIPs": ["geoip:cn"], 
        "skipFallback": true 
      }, 
      { 
        "address": "8.8.8.8", 
        "domains": [ 
          "geosite:geolocation-!cn", 
          "geosite:speedtest" 
        ], 
        "skipFallback": true 
      }, 
      "localhost" 
    ] 
  }, 
  "routing": { //隐藏的路由规则:当入站流量不符合任何条件时,转发给第一个outbound出站。  
    //"IPIfNonMatch":当域名没有匹配任何规则时,将域名解析成 IP(A 记录或 AAAA 记录)再次进行匹配; 
    //当一个域名有多个 A 记录时,会尝试匹配所有的 A 记录,直到其中一个与某个规则匹配为止; 
    //解析后的 IP 仅在路由选择时起作用,转发的数据包中依然使用原始域名;   
    //"domainStrategy": "IPIfNonMatch",  
    "domainStrategy": "AsIs",  
    "rules": [ 
      { 
        "type": "field", 
        "inboundTag": ["s-in"], 
        "outboundTag": "proxy" 
      }, 
      { 
        "type": "field", 
        "inboundTag": ["h-in"], 
        "outboundTag": "proxy" 
      }, 
      { 
        "type": "field", 
        "outboundTag": "direct", 
        "protocol": ["bittorrent"] 
      }, 
      { 
        "type": "field", 
        "domain": ["geosite:category-ads-all"], 
        "outboundTag": "block" 
      }, 
      { //yourvps.com 的不需要代理 
        "type": "field", 
        "ip": "137.***.***.122", 
        "outboundTag": "direct" 
      }, 
      { //给DNS用的,这google和CloudFlare两个DNS直接去proxy  其实没啥必要啊,因为这俩IP肯定会命中geo的设置被自动分流到proxy,那这么干的原因是为了避免反向DNS解析? 
        "type": "field", 
        "ip": ["8.8.8.8", "1.1.1.1"], 
        "outboundTag": "proxy" 
      }, 
      { 
        "type": "field", 
        "outboundTag": "direct", 
        "ip": [ 
          "223.5.5.5/32", 
          "119.29.29.29/32", 
          "180.76.76.76/32", 
          "114.114.114.114/32" 
        ] 
      }, 
      { //劫持全部的53端口流量,发给DNS-OUT。  所以TCP的53也被劫持了? 
        "type": "field", 
        "inboundTag": ["ipt-in"], 
        "port": 53, 
        //"network": "udp", 
        "outboundTag": "dns-out"  //53端口的去DNS-out这个outbound,然后又被导入到内置的DNS服务去了 
      },      
      { 
        "type": "field", 
        "outboundTag": "direct", 
        "domain": [ 
          "geosite:apple-cn", 
          "geosite:google-cn" 
        ] 
      },      
      { 
        "type": "field", 
        "domain": ["geosite:geolocation-!cn"], //非中国的域名,走proxy。 
        "outboundTag": "proxy" 
      }, 
      { 
        "type": "field", 
        "outboundTag": "direct", 
        "ip": [ 
          "geoip:cn", 
          "geoip:private" 
        ] 
      }, 
      { 
        "type": "field", 
        "ip": ["geoip:telegram"], 
        "outboundTag": "proxy" 
      }       
    ] 
  } 
}  
经过这样设置后,主路由就可以科学的上网了。 
我是用的一个赛扬双核 G3900,在百兆带宽跑满时(阿里云+BT+youtube网络视频),由于所有的包都先给xray,再进行分流,XRAY的cpu占用率大概是每个核20%-35%。所以不知道以后如果升级到千兆,这个性能是否可以满足。但是目前也没想到什么在xray之前就能分流的高效的办法,总要有个程序来查表干这件事,就看谁的查表算法写的好了。除了查表算法,也许用缓存来减少查表规模也是个可行的思路。 
 
 
 
 
 |   
 
 
 
 |