
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
Для установки bbs с поддержкой PAC-скриптов:
go install -tags pac github.com/synacktiv/bbs@master
Примечание: PAC опирается на непроверенные сторонние библиотеки.
Python-CLI bbscli.py предоставляется для упрощения настройки 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 в виде карты структур
прокси. Ключи карты выбираются свободно, но должны совпадать с ключами, используемыми
в определении цепочек. Структуры прокси выглядят так:
connstring обязателен и имеет формат protocol://host:port (protocol может быть socks5 или httpconnect/http)user и pass необязательныДля каждого объявленного прокси создаётся неявная цепочка (см. следующий раздел) с тем же именем. Она имеет параметры по умолчанию и состоит из одного соответствующего прокси. Если вы хотите использовать нестандартные параметры, необходимо явно создать цепочку.
Цепочки должны быть объявлены в разделе chains в виде карты структур цепочек.
Ключи карты выбираются свободно, но должны совпадать с ключами, используемыми в определении маршрутов, и
должны отличаться от ключей карты раздела proxies.
Структуры цепочек имеют параметры, аналогичные proxychains (см. https://github.com/rofl0r/proxychains-ng):
proxyDns: логическое значение, необязательно, по умолчанию truetcpConnectTimeout: целое число, необязательно, по умолчанию 1000 (используется при подключении сокетов — либо к первому прокси
цепочки, либо напрямую к цели)tcpReadTimeout: целое число, необязательно, по умолчанию 2000 (используется при чтении ответов на рукопожатие прокси на подключённых сокетах)proxies: список строк, необязательно, по умолчанию пустой списокКлюч proxies в chain должен содержать массив имён прокси, объявленных как ключи в разделе proxies.
Как упоминалось в предыдущем разделе, для каждого прокси, объявленного в разделе proxies, создаётся неявная
цепочка (см. следующий раздел) с тем же именем. Она имеет параметры по умолчанию и
состоит из одного соответствующего прокси.
Встроенный режим настройки маршрутизации осуществляется через файл конфигурации. Он связывает
адреса с именами цепочек. Файл должен содержать карту таблиц маршрутизации. Ключи карты
выбираются свободно, но должны совпадать с ключами, используемыми в разделе servers.
Каждая таблица маршрутизации содержит ключ default, представляющий маршрут по умолчанию, и ключ blocks,
который представляет собой массив блоков правил. Каждый
блок правил содержит comment, набор rules и связанное имя цепочки.
Правила вычисляются: для адреса в формате host:port они могут
быть true или false. Для заданного адреса блоки вычисляются в порядке их
объявления. Блоки могут быть отключены установкой поля disable в true.
Это позволяет своеобразно «комментировать», что невозможно в JSON.
Вычисление останавливается на первом блоке, который вернул true, и
возвращается связанное имя цепочки. Каждый открытый сервер (из раздела servers)
связан с одной таблицей маршрутизации из конфигурации. Запросы, полученные на
каждом сервере, маршрутизируются в соответствии с соответствующей таблицей маршрутизации. Если все блоки вернули
, используется маршрут по умолчанию. Если не определён, соединения разрываются по умолчанию.
Поля блока:
comment (строка)rules (Rule или RuleCombo)route (строка)disable (логическое значение)Поля правила:
rule (строка): тип правила, regexp, subnet.variable (строка): переменная для вычисления regexp: host, port или addr (host:port).content (строка): содержимое правила, зависит от типа правила (см. ниже).negate (логическое значение) [необязательно]: инвертировать ли правило.Поля RuleCombo:
rule1 (Rule или RuleCombo): левый операнд.op (строка): оператор: AND, And, and, &, &&, OR, Or, or, |, ||.rule2 (Rule или RuleCombo): правый операнд.Типы правил:
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.
protocol может быть http или socks5, если указана routing_tableprotocol может быть fwd, если указаны chain, dest_addr и dest_portrouting_table должна соответствовать одной из таблиц, определённых в разделе routeschain должна соответствовать одной из цепочек, определённых в разделе chainsПользовательское разрешение имён хостов (аналогично /etc/hosts) может быть настроено в
разделе hosts в виде карты строк. Ключи карты соответствуют имени хоста,
а значения — IP-адресу, на который должен разрешаться хост.
Следует отметить, что ключи карты также могут быть IP-адресами. В этом случае IP-адрес ключа будет заменён IP-адресом значения. Аналогично, значения карты могут быть именами хостов и заменят соответствующий ключ карты.
Если задано, пользовательское разрешение имён хостов выполняется в начале фазы установления соединения: после принятия решения о маршрутизации и до любого локального разрешения DNS (если цепочка настроена с proxyDns=false), а также до отправки адреса назначения различным прокси цепочки.
Если bbs собран с поддержкой PAC, маршрутизация может быть настроена с помощью PAC-скрипта
вместо JSON-файла конфигурации. Однако для этого требуется использовать непроверенную
библиотеку Go. Путь к PAC-файлу должен быть указан с помощью -pac.
PAC-скрипт должен определять функцию FindProxyForURL(url, host). Возвращаемые
этой функцией значения должны соответствовать именам цепочек (не прокси),
объявленных в JSON-конфигурации.
falsedefault