
bbs is a router for SOCKS and HTTP proxies. It exposes a SOCKS5 (or HTTP CONNECT) service and forwards incoming requests to proxies or chains of proxies based on the request's target. Routing can be configured with a PAC script (if built with PAC support), or through a JSON file.
旧版 bbs 可在此处找到
bbs 是用于 SOCKS 和 HTTP 代理的路由器。它提供 SOCKS5、HTTP CONNECT 或端口转发服务,并根据请求的目标将传入请求转发到代理或代理链。路由可以通过 PAC 脚本(如果构建时启用了 PAC 支持)或 JSON 文件进行配置。
go install github.com/synacktiv/bbs@master
要安装支持 PAC 脚本的 bbs:
go install -tags pac github.com/synacktiv/bbs@master
注意:PAC 依赖未经审计的第三方库。
提供了 bbscli.py Python CLI,以简化 bbs 的配置,避免手动编写 JSON 文件。
它需要 pyparsing 库,该库已由 Debian 打包:
apt install python3-pyparsing
如果您的发行版没有打包该库,可以使用 pip 安装:
pip install pyparsing
配置在单个 JSON 文件中完成,该文件由多个部分组成:
配置文件路径通过参数 -c <path> 提供(默认为 ./bbs.json)。
bbs 在收到 SIGHUP 信号时会重新加载配置文件,使用 kill -HUP <pid> 触发重新加载。
以下是此类配置的示例:
{
"proxies": {
"proxy1": {
"connstring": "socks5://127.0.0.1:1337",
"user": "user",
"pass": "s3cr3t"
},
"proxy2": {
"connstring": "http://127.0.0.1:1338"
}
},
"chains": {
"chain1": {
"proxyDns": true,
"tcpConnectTimeout": 1000,
"tcpReadTimeout": 2000,
"proxies": [
"proxy1",
"proxy2"
]
},
"direct": {
"proxies": []
}
},
"routes": {
"table1": {
"default": "direct",
"blocks": [
{
"comment": "Block1 comment",
"rules": {
"rule": "regexp",
"variable": "host",
"content": "me\\.gandi\\.net"
},
"route": "chain1"
},
{
"comment": "Route non web traffic towards 10.35.0.0/16 through proxy2",
"rules": {
"rule1": {
"rule": "subnet",
"content": "10.35.0.0/16"
},
"op": "AND",
"rule2": {
"rule": "regexp",
"variable": "port",
"content": "^(80|443)$",
"negate": true
}
},
"route": "proxy2"
},
{
"comment": "Drop traffic to 445",
"rules": {
"rule": "regexp",
"variable": "port",
"content": "^445$"
},
"route": "drop"
},
{
"comment": "Route *.corp.local through chain1",
"rules": {
"rule": "regexp",
"variable": "host",
"content": "(?i)^(.*\\.)?corp\\.local$"
},
"route": "chain1",
"disable": true
}
]
},
"table2": {
"default": "drop",
"blocks": [
{
"comment": "Route *.corp.local through chain2",
"rules": {
"rule": "regexp",
"variable": "host",
"content": "(?i)^(.*\\.)?corp\\.local$"
},
"route": "chain2"
}
]
}
},
"servers": [
"socks5://127.0.0.1:1081:table1",
"http://127.0.0.1:1080:table2",
"fwd://127.0.0.1:4445:chain1:10.0.0.1:445"
],
"hosts": {
"host1": "1.1.1.1",
"host2": "10.0.0.1",
"host3": "modified.host3",
"10.1.1.4": "10.1.1.5"
}
}
上游代理必须在 proxies 部分中声明为代理结构的映射。映射键可自由选择,但必须与 chains 定义中使用的键一致。代理结构如下:
connstring 为必填项,格式为 protocol://host:port(protocol 可以是 socks5 或 httpconnect/http)user 和 pass 为可选项对于每个声明的代理,都会创建一个具有相同名称的隐式链(参见下一段)。该链使用默认参数,且仅由单个关联代理组成。如果您想使用非默认参数,则必须显式创建链。
链必须在 chains 部分中声明为链结构的映射。映射键可自由选择,但必须与 routes 定义中使用的键一致,并且不能与 proxies 部分中的映射键相同。
链结构具有类似 proxychains 的参数(参见 https://github.com/rofl0r/proxychains-ng):
proxyDns:布尔值,可选,默认为 truetcpConnectTimeout:整数,可选,默认为 1000(用于连接套接字时,无论是连接到链的第一个代理还是直接连接到目标)tcpReadTimeout:整数,可选,默认为 2000(用于在已连接的套接字上读取代理握手响应时)proxies:字符串列表,可选,默认为空列表chain 的 proxies 键必须包含一个代理名称数组,这些代理名称在 proxies 部分中作为键声明。
如上一段所述,对于在 proxies 部分中声明的每个代理,都会创建一个具有相同名称的隐式链(参见下一段)。该链使用默认参数,且仅由单个关联代理组成。
内置的路由配置模式是通过配置文件完成的。它将地址与链名称关联起来。文件必须包含一个路由表的映射。映射键可自由选择,但必须与 servers 部分中使用的键一致。
每个路由表包含一个代表默认路由的 default 键,以及一个 blocks 键,该键是一个规则块数组。每个规则块包含一个 comment、一组 rules 和一个关联的链名称。规则会被求值:给定一个 host:port 格式的地址,规则结果为 true 或 false。对于给定地址,规则块按其声明顺序求值。可以通过将 disable 字段设置为 true 来禁用规则块。这提供了一种“注释”方式,而 JSON 中无法实现。求值在第一个结果为 true 的规则块处停止,并返回关联的链名称。每个打开的服务器(来自 servers 部分)都与配置中的一个路由表关联。每个服务器上收到的请求根据匹配的路由表进行路由。如果所有规则块都求值为 false,则使用默认路由。如果未定义 default,则默认情况下连接会被丢弃。
Block 字段:
comment(字符串)rules(Rule 或 RuleCombo)route(字符串)disable(布尔值)Rule 字段:
rule(字符串):规则类型,regexp、subnet。variable(字符串):用于正则表达式求值的变量,host、port 或 addr(host:port)。content(字符串):规则的内容,取决于规则类型(见下文)。negate(布尔值)[可选]:是否对规则取反。RuleCombo 字段:
rule1(Rule 或 RuleCombo):左操作数。op(字符串):运算符,AND、And、and、&、&&、OR、Or、or、|、||。rule2(Rule 或 RuleCombo):右操作数。Rule 类型:
regexp:将 variable 中定义的变量(host、port 或 addr=host:port)与 content 中的正则表达式进行匹配。subnet:检查主机是否在 content 定义的子网中。如果主机是域名而非子网地址,则规则返回 false。来自 routes 部分的规则块或 PAC 函数必须返回已声明的链名称,而不是代理名称。如果您想使用单个代理,必须将其包装在链中。drop 名称是特殊的,不需要在此配置中声明。如果 PAC 函数或路由块返回 drop 作为链名称,则该连接会被丢弃。
如果 bbs 在构建时启用了 PAC 支持,并且 -pac 参数指向 PAC 文件,则配置文件中定义的路由将不会被使用。PAC 文件路由不支持多个路由表。每个打开的服务器都将使用同一个 PAC 文件。
bbs 打开的监听器必须在 servers 部分中声明为连接字符串列表,格式为 protocol://bind_addr:bind_port:routing_table 或 protocol://bind_addr:bind_port:chain:dest_addr:dest_port。
routing_table,protocol 可以是 http 或 socks5chain、dest_addr 和 dest_port,protocol 可以是 fwdrouting_table 必须与 routes 部分中定义的表之一匹配chain 必须与 chains 部分中定义的链之一匹配自定义主机解析(类似于 /etc/hosts)可以在 hosts 部分中配置为字符串映射。映射键对应主机名,值对应主机应解析到的 IP 地址。
需要注意的是,映射键也可以是 IP 地址。在这种情况下,作为键的 IP 地址将被替换为作为值的 IP 地址。同样,映射值也可以是主机名,并会替换相应的映射键。
如果定义了自定义主机解析,它们会在连接阶段的开始时进行,即在做出路由决策之后、进行任何本地 DNS 解析之前(如果链配置了 proxyDns=false),并且在将目标地址发送给链中的各个代理之前。
如果 bbs 在构建时启用了 PAC 支持,则可以使用 PAC 脚本而不是 JSON 配置文件来配置路由。但是,这需要使用不受信任的 Go 库。必须通过 -pac 提供 PAC 文件路径。
PAC 脚本必须定义 FindProxyForURL(url, host) 函数。该函数返回的值必须与 JSON 配置中声明的链(而非代理)的名称匹配。