Pages

Thursday, 23 November 2023

tcp-brutal浅尝


Tcp brutal 文档

参考:https://github.com/apernet/tcp-brutal/blob/master/README.zh.md# 用户指南

前几天 hysteria 的作者发布了 TCP Brutal,TCP Brutal 是 Hysteria 中的同名拥塞控制算法移植到 TCP 的版本。原本是用于 udp 的,现在可以用于 tcp,可以搭配许多 tcp 协议使用了。

brutal 是什么?

Brutal: 这是 Hysteria 自有的拥塞控制算法。与 BBR 不同,Brutal 采用固定速率模型,丢包或 RTT 变化不会降低速度。相反,如果无法达到预定的目标速率,反而会根据计算的丢包率提高发送速率来进行补偿。Brutal 只在你知道(并正确设置了)当前网络的最大速度时才能正常运行。其擅长在拥塞的网络中抢占带宽,因此得名。

Brutal 如果带宽设置低于实际最大值也能正常运行;相当于限速。重要的是不要将其设置得高于实际最大值,否则会因为补偿机制导致连接速度慢、不稳定,且浪费流量。

这也是 Hysteria 为什么这么暴力快速的原因之一

局限性

但是有一个缺点,这个 tcp brutal 是依靠内核的模块进行加速的,一般只有 linux 支持。那有的小伙伴会问,那你搞毛,linux 用户才占比多少。

其实并不是这样,我们看作者的解释:

TCP Brutal 只是 TCP 的拥塞控制算法,并不修改 TCP 协议本身。客户端和服务端可以只有单边安装内核模块。拥塞控制算法控制的是数据的发送,而考虑到代理用户通常下载的数据量远大于上传,只在服务端使用 TCP Brutal 就可以获得大部分的收益。(客户端使用 TCP Brutal 可以获得更好的上传速度,但很多人使用的是 Windows, macOS 或手机,安装内核模块往往不现实。)

意思就是,只要服务端是 linux,由于我们大部分的流量都是下载流量(也就是从服务器返回给我们的数据),只有少部分是上传流量(也就是发送给服务器的流量),而下载流量的速度又基于服务器发给我们的速度,这个发 up 就可以依赖我们的 brutal 了,所以速度还是可以有很大的提升!

虽然我们不能用 brutal 发给我们的服务器,但仅仅只影响上传的流量!

还有一个注意的就是只有支持多路复用的协议才可以用这个,而且需要客户端支持(相当于需要客户端告诉服务端要开启 brutal),目前来说 sing-box 在 tcp brutal 还没放出之前就支持了

安装(懒人版)

bash <(curl -fsSL https://github.com/vveg26/sing-box-reality-hysteria2/raw/main/tcp-brutal-reality.sh)

安装(折腾版)

安装模块

安装脚本(内核高于 5.8 uname -r 可查看内核版本):

bash <(curl -fsSL https://tcp.hy2.sh/)

安装 sing-box

安装正式版

bash -c "$(curl -L https://sing-box.vercel.app)" @ install

安装预发布版

bash -c "$(curl -L https://sing-box.vercel.app)" @ install --beta

编译安装最新版

bash -c "$(curl -L https://sing-box.vercel.app)" @ install --go

卸载

bash -c "$(curl -L https://sing-box.vercel.app)" @ remove
项目
程序 /usr/local/bin/sing-box
配置 /usr/local/etc/sing-box/config.json
geoip /usr/local/share/sing-box/geoip.db
geosite /usr/local/share/sing-box/geosite.db
热载 systemctl reload sing-box
重启 systemctl restart sing-box
状态 systemctl status sing-box
查看日志 journalctl -u sing-box -o cat -e
实时日志 journalctl -u sing-box -o cat -f

修改配置文件

nano /usr/local/etc/sing-box/config.json

{
"inbounds": [
{
"type": "vless",
"listen": "::",
"listen_port": 443,//端口号
"users": [
{
"uuid": "0000-00000-0000-0000000",//sing-box generate uuid
"flow": ""//流控为空,因为开启了mux所以也可以减轻tls in tls特征
}
],
"tls": {
"enabled": true,
"server_name": "",
"reality": {
"enabled": true,
"handshake": {
"server": "csgo.com",//偷取证书的域名,tls1.3,h2
"server_port": 443
},
"private_key": "xxxxxxxxxx",//sing-box generate reality-keypair
"short_id": [
"7af0217d76ca919a"//sing-box generate rand --hex 8
]
}
},
"multiplex": {
"enabled": true,
"padding": true, // false / true
"brutal": {
"enabled": true,
"up_mbps": 100, // 客户端的下行速率
"down_mbps": 1000
}
}
}
],
"outbounds": [
{
"type": "direct"
}
]
}

systemctl restart sing-box

客户端配置文件

{
"log": {
"level": "debug",
"timestamp": true
},
"dns": {
"servers": [
{
"tag": "proxyDns",
"address": "8.8.8.8",
"detour": "proxy"
},
{
"tag": "localDns",
"address": "https://223.5.5.5/dns-query",
"detour": "direct"
},
{
"tag": "block",
"address": "rcode://success"
},
{
"tag": "remote",
"address": "fakeip"
}
],
"rules": [
{
"domain": [
"ghproxy.com",
"cdn.jsdelivr.net",
"testingcf.jsdelivr.net"
],
"server": "localDns"
},
{
"geosite": "category-ads-all",
"server": "block"
},
{
"outbound": "any",
"server": "localDns",
"disable_cache": true
},
{
"geosite": "cn",
"server": "localDns"
},
{
"clash_mode": "direct",
"server": "localDns"
},
{
"clash_mode": "global",
"server": "proxyDns"
},
{
"geosite": "geolocation-!cn",
"server": "proxyDns"
},
{
"query_type": [
"A",
"AAAA"
],
"server": "remote"
}
],
"fakeip": {
"enabled": true,
"inet4_range": "198.18.0.0/15",
"inet6_range": "fc00::/18"
},
"independent_cache": true,
"strategy": "ipv4_only"
},
"inbounds": [
{
"type": "tun",
"inet4_address": "172.19.0.1/30",
"mtu": 9000,
"auto_route": true,
"strict_route": true,
"sniff": true,
"endpoint_independent_nat": false,
"stack": "system",
"platform": {
"http_proxy": {
"enabled": true,
"server": "127.0.0.1",
"server_port": 2080
}
}
},
{
"type": "mixed",
"listen": "127.0.0.1",
"listen_port": 2080,
"sniff": true,
"users": []
}
],
"outbounds": [
{
"tag": "proxy",
"type": "selector",
"outbounds": [
"auto",
"direct",
"sing-box-reality-brutal"
]
},
{
"type": "vless",
"tag": "sing-box-reality-brutal",
"uuid": "00000-0000-0000-000000",//uuid
"packet_encoding": "xudp",
"server": "107.108.11.12",//vps ip
"server_port": 443, //对应端口
"flow": "",
"tls": {
"enabled": true,
"server_name": "csgo.com",//偷证书
"utls": {
"enabled": true,
"fingerprint": "chrome"
},
"reality": {
"enabled": true,
"public_key": "xxxxxxxxxxxxxx",
"short_id": "xxxxxxxx"
}
},
"multiplex": {
"enabled": true,
"protocol": "h2mux",
"max_connections": 1,
"min_streams": 4,
"padding": true,
"brutal": {
"enabled": true,
"up_mbps": 50, //上行速度,windows,macos不会生效所以可随便写
"down_mbps": 100 //下行速度,对应服务器的下行速度,当然可自行修改
}
}
},
{
"tag": "direct",
"type": "direct"
},
{
"tag": "block",
"type": "block"
},
{
"tag": "dns-out",
"type": "dns"
},
{
"tag": "auto",
"type": "urltest",
"outbounds": [
"sing-box-reality-brutal"
],
"url": "http://www.gstatic.com/generate_204",
"interval": "1m",
"tolerance": 50
}
],
"route": {
"auto_detect_interface": true,
"final": "proxy",
"geoip": {
"download_url": "https://testingcf.jsdelivr.net/gh/MetaCubeX/meta-rules-dat@release/geoip.db",
"download_detour": "direct"
},
"geosite": {
"download_url": "https://testingcf.jsdelivr.net/gh/MetaCubeX/meta-rules-dat@release/geosite.db",
"download_detour": "direct"
},
"rules": [
{
"protocol": "dns",
"outbound": "dns-out"
},
{
"network": "udp",
"port": 443,
"outbound": "block"
},
{
"geosite": "category-ads-all",
"outbound": "block"
},
{
"clash_mode": "direct",
"outbound": "direct"
},
{
"clash_mode": "global",
"outbound": "proxy"
},
{
"domain": [
"clash.razord.top",
"yacd.metacubex.one",
"yacd.haishan.me",
"d.metacubex.one"
],
"outbound": "direct"
},
{
"geosite": "geolocation-!cn",
"outbound": "proxy"
},
{
"geoip": [
"private",
"cn"
],
"outbound": "direct"
},
{
"geosite": "cn",
"outbound": "direct"
}
]
},
"experimental": {
"clash_api": {
"external_controller": "127.0.0.1:9090",
"external_ui_download_url": "",
"external_ui_download_detour": "",
"external_ui": "ui",
"secret": "",
"default_mode": "rule",
"store_selected": true,
"cache_file": "",
"cache_id": ""
}
}
}
------------------------------------------

TCP Brutal是Hysteria中的同名拥塞控制算法移植到TCP的版本,sing-box率先做了支持。

更多详细的介绍请移步项目页面查看:

https://github.com/apernet/tcp-brutal/blob/master/README.zh.md
https://sing-box.sagernet.org/configuration/shared/tcp-brutal/

前提条件:需要Linux内核版本5.8或更高,Debian11-12默认内核都是满足的。这里我用Debian11测试。

首先编译Brutal的Linux内核模块,这里我选择直接打包成deb,这样弄一次后,其他的机器就可以直接用deb安装了,方便不少。

安装依赖:

apt -y update apt -y install build-essential linux-headers-$(uname -r) dkms dh-make git

获取项目代码、创建dkms压缩包:

git clone https://github.com/apernet/tcp-brutal.git 

cd tcp-brutal 

make dkms-tarball

看一下dkms.conf文件的内容:

cat dkms.conf

类似:

PACKAGE_NAME="tcp-brutal" 

PACKAGE_VERSION="1.0.0.r7.g845241d"  

...

根据查看到的PACKAGE_NAME和PACKAGE_VERSION创建相应的目录:

mkdir -p /usr/src/tcp-brutal-1.0.0.r7.g845241d

把压缩包文件解压到相应的目录

tar xzvf dkms.tar.gz --strip-components=2 -C /usr/src/tcp-brutal-1.0.0.r7.g845241d

将包纳入dkms管理、构建deb包、安装deb包:

cd /usr/src/tcp-brutal-1.0.0.r7.g845241d 

dkms add -m tcp-brutal -v 1.0.0.r7.g845241d 

dkms mkdeb 

dpkg -i tcp-brutal-dkms_1.0.0.r7.g845241d_amd64.deb

查看状态,如有类似回显,说明一切正常:

root@imlala:~# dkms status 

tcp-brutal, 1.0.0.r7.g845241d, 5.10.0-26-amd64, x86_64: installed

[备注1]

如果不构建deb包,可以在本机执行如下命令直接安装brutal内核模块:

dkms install -m tcp-brutal -v 1.0.0.r7.g845241d

[备注2]

如果构建了deb包,后续在其他机器上安装brutal内核模块的话就很方便了。先把deb包传到对应的机器:

scp tcp-brutal-dkms_1.0.0.r7.g845241d_amd64.deb root@1.2.3.4:/opt

然后执行如下命令即可:

cd /opt 

dpkg -i tcp-brutal-dkms_1.0.0.r7.g845241d_amd64.deb 

apt install -

dkms status

现在我们还需要加载brutal模块:

modprobe brutal

检查模块是否加载成功,如有类似如下回显,说明正常:

root@imlala:~# lsmod | grep brutal 

brutal 20480 0

将brutal模块设置为开机自动加载:

echo "brutal" > /etc/modules-load.d/brutal.conf

至此brutal内核模块的配置就完成了。

现在我们要编译安装sing-box的beta版本,先安装依赖:

apt -y install curl build-essential libssl-dev zlib1g-dev gcc-mingw-w64

安装go:

curl -L https://go.dev/dl/go1.21.4.linux-amd64.tar.gz -o go1.21.4.linux-amd64.tar.gz 

tar -C /usr/local -xzf go1.21.4.linux-amd64.tar.gz 

echo 'export PATH=$PATH:/usr/local/go/bin' > /etc/profile.d/golang.sh 

source /etc/profile.d/golang.sh

编译的时候可以自己添加参数来支持更多的功能:

https://sing-box.sagernet.org/installation/build-from-source/#build-tags

这里我需要用到reality和utls所以就加了这两个。

编译linux平台的二进制文件:

go install -v -tags with_reality_server with_utls github.com/sagernet/sing-box/cmd/sing-box@v1.7.0-beta.2

编译windows平台的二进制文件:

env GOOS=windows GOARCH=amd64 CGO_ENABLED=0 CC=x86_64-w64-mingw32-gcc

go install -v -tags with_reality_server with_utls github.com/sagernet/sing-box/cmd/sing-box@v1.7.0-beta.2

复制编译好的文件:

cp $(go env GOPATH)/bin/sing-box /usr/local/bin/

新建sing-box需要用到的目录:

mkdir -p /usr/local/etc/sing-box

新建systemd服务:

systemctl edit --full --force sing-box.service

写入如下配置:

[Unit]
Description=sing-box service
Documentation=https://sing-box.sagernet.org
After=network.target nss-lookup.target

[Service]
CapabilityBoundingSet=CAP_NET_ADMIN CAP_NET_BIND_SERVICE
AmbientCapabilities=CAP_NET_ADMIN CAP_NET_BIND_SERVICE
ExecStart=/usr/local/bin/sing-box run -c /usr/local/etc/sing-box/config.json
Restart=on-failure
RestartPreventExitStatus=23
LimitNOFILE=infinity

[Install]
WantedBy=multi-user.target

新建sing-box的配置文件:

nano /usr/local/etc/sing-box/config.json

这里我配置一个vless-reality节点:

{
  "log": {
    "level": "info"
  },
  "inbounds": [
    {
      "type": "vless",
      "tag": "vless-in",
      "listen": "0.0.0.0",
      "listen_port": 443,
      "users": [
        {
          "name": "imlala",
          "uuid": "219c8c62-430a-439a-a6f6-d8f6a2a225a2",
          "flow": ""
        }
      ],
      "tls": {
        "enabled": true,
        "server_name": "go.dev",
        "reality": {
          "enabled": true,
          "handshake": {
            "server": "go.dev",
            "server_port": 443
          },
          "private_key": "mPVhErJjoa-hx7K8TAzVR_hiKM3UYuuTQEoECcSqNFE",
          "short_id": [
            "9534dcf8c8d0c43f"
          ]
        }
      },
      "multiplex": {
        "enabled": true,
        "padding": true,
        "brutal": {
          "enabled": true,
          "up_mbps": 300,
          "down_mbps": 300
        }
      }
    }
  ],
  "outbounds": [
    {
      "type": "direct",
      "tag": "direct"
    }
  ]
}

[备注1]

请注意这套配置不支持xtls-rprx-vision,所以flow需要留空。

[备注2]

sing-box generate uuid // 生成uuid 

sing-box generate reality-keypair // 生成private_key、public_key 

sing-box generate rand 8 --hex // 生成short_id

启动sing-box并设置开机自启:

systemctl enable --now sing-box

客户端配置,这里我给出一个自己目前在用的,tun模式:

{
  "log": {
    "level": "info",
    "timestamp": true
  },
  "dns": {
    "servers": [
      {
        "tag": "cloudflare",
        "address": "https://1.1.1.1/dns-query"
      },
      {
        "tag": "dnspod",
        "address": "https://1.12.12.12/dns-query",
        "detour": "direct"
      },
      {
        "tag": "block",
        "address": "rcode://success"
      }
    ],
    "rules": [
      {
        "geosite": "category-ads-all",
        "server": "block",
        "disable_cache": true
      },
      {
          "outbound": "any",
          "server": "dnspod"
      },
      {
        "geosite": "cn",
        "server": "dnspod"
      }
    ],
    "strategy": "ipv4_only"
  },
  "inbounds": [
    {
      "type": "tun",
      "tag": "tun-in",
      "interface_name": "tun0",
      "inet4_address": "172.28.0.1/30",
      "auto_route": true,
      "strict_route": true,
      "stack": "system",
      "sniff": true
    }
  ],
  "outbounds": [
    {
      "type": "vless",
      "tag": "vless-out",
      "server": "1.2.3.4",
      "server_port": 443,
      "uuid": "219c8c62-430a-439a-a6f6-d8f6a2a225a2",
      "flow": "",
      "tls": {
        "enabled": true,
        "server_name": "go.dev",
        "utls": {
          "enabled": true,
          "fingerprint": "chrome"
         },
        "reality": {
          "enabled": true,
          "public_key": "2Gga7qZ8dA8agbF2lAnojBC_Nr90mxys_yMaJarty3A",
          "short_id": "9534dcf8c8d0c43f"
        }
      },
      "packet_encoding": "xudp",
      "multiplex": {
          "enabled": true,
          "protocol": "h2mux",
        "max_streams": 10,
          "padding": true,
          "brutal":{
            "enabled": true,
            "up_mbps": 30,
            "down_mbps": 1000
          }
      }
    },
    {
      "type": "direct",
      "tag": "direct"
    },
    {
      "type": "block",
      "tag": "block"
    },
    {
      "type": "dns",
      "tag": "dns"
    }
  ],
  "route": {
    "geoip": {
      "download_url": "https://github.com/SagerNet/sing-geoip/releases/latest/download/geoip.db",
      "download_detour": "vless-out"
    },
    "geosite": {
      "download_url": "https://github.com/SagerNet/sing-geosite/releases/latest/download/geosite.db",
      "download_detour": "vless-out"
    },
    "rules": [
      {
        "protocol": "dns",
        "outbound": "dns"
      },
      {
        "geosite": "cn",
        "geoip": [
          "cn",
          "private"
        ],
        "outbound": "direct"
      },
      {
        "geosite": "category-ads-all",
        "outbound": "block"
      }
    ],
    "auto_detect_interface": true
  }
}

[备注1]

tun模式注意windows防火墙拦截,自己手动允许一下:

这样一波操作下来,可以说基本上只要不涉及到grpc和http2的协议现在都可以用上brutal了,这就很牛逼了。。。
 


No comments:

Post a Comment