配置sing-box客户端

·

摘要

这是sing-box翻墙客户端,一般运行在openwrt上。sing-box的配置一般分为以下几个部分:

  • log
  • dns
  • inbounds
  • outbounds
  • route
  • experimental(可选)

一般每一种配置类型使用一个配置文件,但route规则可能比较多,我将route拆分为两个配置文件,路由规则集配置和路由配置。

GeoIP

  • 全称Geographic IP(地理位置 IP)
  • 内容:包含了全球各地的 IP 地址范围段。
  • 作用:让软件知道某个 IP 属于哪个国家或哪个特定的组织(如 Google, Cloudflare)。

GeoSite

  • 全称Geographic Domain Sites(地理位置域名列表)
  • 内容:包含了各大互联网服务的域名列表,通常按类别(如 category-ads)或国家(如 cn)分类。
  • 作用:让软件知道某个域名属于哪个服务。

sing-box新版不支持传统geo数据库,而是使用Sing-box Rule-Set文件,后缀为srs。它的设计目的是为了高性能。相比于普通的 JSON 文本文件,srs 经过了预编译和压缩,加载速度极快,且在匹配成千上万条规则时占用的内存非常低。

另外使用geositegeoip规则有远程规则集和本地规则集两种方式,这里主要介绍使用本地规则集的方式。

构造本地geosite、geoip规则集

下载geosite规则集

直接访问

https://github.com/SagerNet/sing-geosite/tree/rule-set

或者访问

https://github.com/SagerNet/sing-geosite

在分支选择rule-set

下载geoip规则集

方法同geosite,地址如下:

https://github.com/SagerNet/sing-geoip/tree/rule-set

构造本地规则集目录

目前已经得到geosite和geoip两个压缩包。

创建一个文件夹,我这里为rule-set。

将geosite、geoip两个压缩包中的全部srs文件放入rule-set文件夹中。

将rule-set文件夹传入到sing-box工作目录中,这里是:

/usr/share/sing-box/rule-set

log

配置文件路径

/etc/sing-box/conf.d/00_log.json

典型配置文件

{
  "log": {
    "level": "warn",
    "timestamp": true
  }
}

日志等级可以指定以下几种:

  • info
  • warn
  • info

dns

配置文件路径

/etc/sing-box/conf.d/10_dns.json

典型配置文件

{
  "dns": {
    "strategy": "ipv4_only",
    "servers": [
      {
        "tag": "dns-remote",
        "type": "https",
        "server": "1.1.1.1",
        "path": "/dns-query",
        "detour": "proxy-default"
      },
      {
        "tag": "dns-local",
        "type": "udp",
        "server": "192.168.1.2"
      }
    ],
    "rules": [
      {
        "domain_suffix": [
          "lan",
          "home.arpa"
        ],
        "server": "dns-local",
        "disable_cache": true
      },
      {
        "rule_set": [
          "geosite-cn",
          "geosite-geolocation-cn"
        ],
        "server": "dns-local"
      },
      {
        "rule_set": [
          "geosite-geolocation-!cn"
        ],
        "server": "dns-remote",
        "disable_cache": true
      }
    ],
    "final": "dns-remote",
    "independent_cache": true
  }
}

inbounds

配置文件路径

/etc/sing-box/conf.d/20_inbounds.json

典型配置文件

{
  "inbounds": [
    {
      "type": "tun",
      "tag": "tun-in",
      "interface_name": "singtun0",
      "address": [
        "172.19.0.1/30"
      ],
      "auto_route": true,
      "strict_route": true,
      "auto_redirect": false
    },
    {
      "type": "mixed",
      "tag": "mixed-in",
      "listen": "0.0.0.0",
      "listen_port": 7890
    },
    {
      "type": "direct",
      "tag": "dns-in",
      "listen": "127.0.0.1",
      "listen_port": 6053
    }
  ]
}

tun接口

auto_route

自动创建路由,也就是添加系统路由,将流量引入到tun网卡上,如果为false则需要手动添加系统路由到tun网卡才能实现翻墙。该功能只能给流量进行路由,不能修改流量数据包。

strict_route

严格路由,为true时意味着全部流量必须走tun接口,不允许流量走原始网关。可以防止流量绕过代理进而出现DNS泄漏的情况。主要的技术手段就是确保sing-box添加的路由位于最高优先级并对未命中sing-box路由的数据包进行丢弃。与auto_route相同,该功能不能修改流量数据包。

举个例子:在strict_route为false时,因为Linux默认路由的优先级小于本地路由,当openwrt dns指定为本地地址时,dns请求会直接发送到指定dns,而不经过sing-box,进而出现DNS污染。

auto_redirect

自动透明代理,用防火墙规则“劫持流量”进入 sing-box,这个选项基本上可以理解成“是否用防火墙强行抓流量”。该功能具备修改数据包的能力,比如将发给8.8.8.8的DNS请求包的目的地址直接改成sing-box的地址。这个功能主要是给透明代理使用的,在tun模式使用会出现“DNS 自我循环”症状(openwrt的UDP端口耗尽,CPU占用率拉满),所以在tun接口中要关闭这个功能。

mixed接口

这里除了创建了tun虚拟网卡,还开启了混合代理(mixed),即同一个端口同时支持socks和HTTP两种代理模式。

有的时候需要用代理模式来测试sing-box翻墙的有效性,同时又不想设置代理密码增加操作,可以让混合代理只绑定“127.0.0.1”,这样只有sing-box本机可以使用这个代理,这种情况一般在VPS端的sing-box上使用较多。

outbounds

配置文件路径

/etc/sing-box/conf.d/30_outbounds.json

典型配置文件

{
  "outbounds": [
    {
      "type": "urltest",
      "tag": "proxy-auto",
      "outbounds": [
        "hk1-outbound"
      ],
      "url": "https://www.gstatic.com/generate_204",
      "interval": "3m",
      "tolerance": 50
    },
    {
      "type": "selector",
      "tag": "proxy-default",
      "outbounds": [
        "hk1-outbound"
      ],
      "default": "hk1-outbound"
    },
    {
      "type": "vless",
      "tag": "hk1-outbound",
      "server": "x.x.x.x",
      "server_port": xxx,
      "uuid": "x-x-x-x-x",
      "flow": "xtls-rprx-vision",
      "tls": {
        "enabled": true,
        "server_name": "www.xxx.com",
        "utls": {
          "enabled": true,
          "fingerprint": "chrome"
        },
        "reality": {
          "enabled": true,
          "public_key": "xxxxxxxxxxxxxxxx",
          "short_id": "xxxxxx"
        }
      }
    },
    {
      "type": "direct",
      "tag": "direct"
    },
    {
      "type": "block",
      "tag": "block-out"
    }
  ]
}

这里面的配置要和VPS上的sing-box服务端对应,服务端具体配置参见:

需要根据sing-box服务器配置填写的字段有以下几个:

  • server
  • server_port
  • server_name
  • public_key
  • short_id(可选)

rule-set

配置文件路径

/etc/sing-box/conf.d/40_route_rule_set.json

典型配置文件

{
  "route": {
    "rule_set": [
      {
        "tag": "geosite-cn",
        "type": "local",
        "format": "binary",
        "path": "rule-set/geosite-cn.srs"
      },
      {
        "tag": "geoip-cn",
        "type": "local",
        "format": "binary",
        "path": "rule-set/geoip-cn.srs"
      },
      {
        "tag": "geosite-geolocation-cn",
        "type": "local",
        "format": "binary",
        "path": "rule-set/geosite-geolocation-cn.srs"
      },
      {
        "tag": "geosite-geolocation-!cn",
        "type": "local",
        "format": "binary",
        "path": "rule-set/geosite-geolocation-!cn.srs"
      }
    ]
  }
}

rule

配置文件路径

/etc/sing-box/conf.d/50_route_rules.json

典型配置文件

{
  "route": {
    "default_domain_resolver": "dns-local",
    "auto_detect_interface": true,
    "final": "proxy-unmatched",
    "rules": [
      {
        "inbound": ["dns-in"],
        "action": "hijack-dns"
      },
      {
        "inbound": ["tun-in"],
        "protocol": "dns",
        "action": "hijack-dns"
      },
      {
        "inbound": "tun-in",
        "action": "sniff",
        "timeout": "1s"
      },
      {
        "inbound": "mixed-in",
        "action": "sniff",
        "timeout": "1s"
      },
      {
        "ip_cidr": [
          "vps1_ip/32",
          "vps2_ip/32"
        ],
        "action": "route",
        "outbound": "direct"
      },
      {
        "ip_is_private": true,
        "outbound": "direct"
      },
      {
        "domain_suffix": [
          "lan",
          "home.arpa"
        ],
        "outbound": "direct"
      },
      {
        "protocol": "udp",
        "port": [443],
        "action": "reject",
        "method": "drop"
      },
      {
        "rule_set": [
          "geosite-cn",
          "geoip-cn",
          "geosite-geolocation-cn"
        ],
        "domain_suffix": [
          "chiphell.com"
        ],
        "outbound": "direct"
      },
      {
        "rule_set": [
          "geosite-geolocation-!cn"
        ],
        "domain_suffix": [
          "iwara.tv"
        ],
        "outbound": "proxy-default"
      }
    ]
  }
}

hijack-dns的工作过程

配置文件中有一段是

{
  "inbound": ["dns-in"],
  "action": "hijack-dns"
}

这个dns劫持具体劫持的是什么?

有些APP会硬编码DNS,即不使用操作系统指定的DNS服务器(这里认为是sing-box所在openwrt),比如硬编码8.8.8.8。这些DNS查询流量到了openwrt上,如果不劫持则会直接转发给8.8.8.8,这样就很容易被GFW污染导致翻墙失败。这个劫持的意义就是可以将所有DNS流量都劫持过来,使用sing-box配置的DNS规则进行查询,从而抵抗GFW的DNS污染。

sniff的工作过程

{
  "inbound": "tun-in",
  "action": "sniff",
  "timeout": "1s"
}

通过偷看数据包握手阶段的特定字段(如 TLS 的 SNI 或 HTTP 的 Host),在不解密的情况下识别出该连接要访问的真实域名,从而实现基于域名的精确路由。

嗅探过程:

  1. 截获请求:一个 App 没发 DNS 请求,直接向某个 IP 发起 TLS 连接(加密连接)。
  2. 偷看握手sing-box拦住这个连接,盯着它发出的第一个“打招呼”的数据包(Client Hello),从中读取出明文传输的 SNI (Server Name Indication)
  3. 重新路由sing-box瞬间明白“哦,这个IP其实是google.com”,然后查表发现google.com需要走代理,于是就把这个连接转给了你的远端节点。

experimental

配置文件路径

/etc/sing-box/conf.d/60_experimental.json

远程srs规则集

srs规则集url可以从上面提到过的github页面获取到。

{
  "tag": "geosite-cn",
  "type": "remote",
  "format": "binary",
  "url": "https://raw.githubusercontent.com/SagerNet/sing-geosite/rule-set/geosite-cn.srs",
  "download_detour": "proxy-default"
}

设置dnsmasq上游DNS

目前sing-box已经是一个合格的socks、http代理服务器了,但目前还不能将openwrt作为翻墙旁路由。因为openwrt的DNS服务默认由dnsmasq提供,目前dnsmasq收到DNS查询请求时还无法转发给sing-box,所以要配置dnsmasq的上游DNS为sing-box。

==========================================================================
【 场景 A:未配置转发(默认状态)】
流量直接从 dnsmasq 发往公共 DNS,缺乏策略控制。

用户设备 (PC/手机)
|
| (DNS 请求: 53 端口)
v
[ OpenWrt: dnsmasq ]
|
| (根据 /etc/resolv.conf 转发)
v
[ 运营商 DNS / 公共 DNS (如 114.114.114.114) ]
|
| (返回解析结果)
v
[ 成功解析 ]

==========================================================================
【 场景 B:配置转发给 sing-box(推荐状态)】
流量经由 sing-box 过滤和分流,实现防污染、去广告或规则分流。

用户设备 (PC/手机)
|
| (DNS 请求: 53 端口)
v
[ OpenWrt: dnsmasq ]
|
| ( server=127.0.0.1#6053 ) <-- 核心配置生效处
v
[ OpenWrt: sing-box (监听 6053) ]
|
|--------------------------------------------|
| (分流策略) |
v v
[ 国内 DNS (阿里/腾讯) ] [ 远程 DNS (P DNS/TLS) ]
| |
|-------------------( 返回结果 )--------------|
v
[ 成功解析 (更安全、精准) ]

==========================================================================

在 OpenWrt 中,修改UCI配置文件是最推荐的方式,这里就采用这种方式。dnsmasq 的配置主要存储在 /etc/config/dhcp 文件中。假定sing-box的dns端口是6053,该端口可在inbounds配置中指定。

1. 打开配置文件nano /etc/config/dhcp

2. 找到 config dnsmasq 这一段,添加或修改以下选项:

  • 找到 option resolvfile,将其改为一个不存在的文件或添加 option noresolv '1'(防止读取运营商 DNS)。
  • 添加 list server '127.0.0.1#6053'

修改后的样子应该是这样的:

config dnsmasq
    option domainneeded '1'
    option boguspriv '1'
    option noresolv '1'  # 不使用本地解析文件
    list server '127.0.0.1#6053'  # 转发到 6053
    option localservice '1'

3. 保存并重启服务/etc/init.d/dnsmasq restart

发表回复

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