
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.
O antigo bbs pode ser encontrado aqui
bbs é um roteador para proxies SOCKS e HTTP. Ele expõe serviços SOCKS5, HTTP
CONNECT ou encaminhamento de portas e encaminha as requisições recebidas para proxies ou cadeias de proxies
com base no destino da requisição. O roteamento pode ser configurado com um script PAC (se
compilado com suporte a PAC), ou por meio de um arquivo JSON.
go install github.com/synacktiv/bbs@master
Para instalar o bbs com suporte a script PAC:
go install -tags pac github.com/synacktiv/bbs@master
Nota: o PAC depende de bibliotecas de terceiros não auditadas.
A CLI Python bbscli.py é fornecida para facilitar a configuração do bbs e evitar escrever arquivos JSON manualmente.
Ela requer a biblioteca pyparsing, que é empacotada pelo Debian:
apt install python3-pyparsing
Se a biblioteca não for empacotada pela sua distribuição, ela pode ser instalada usando pip:
pip install pyparsing
A configuração é realizada em um arquivo JSON composto por várias seções:
O caminho do arquivo de configuração é informado pelo argumento -c <path> (padrão ./bbs.json).
O bbs recarrega os arquivos de configuração ao receber SIGHUP; use kill -HUP <pid> para recarregar.
Aqui está um exemplo dessa configuração:
{
"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"
}
}
Os proxies upstream devem ser declarados na seção proxies como um mapa de estruturas
de proxy. As chaves do mapa são escolhidas livremente, mas devem corresponder às usadas na definição
das cadeias. As estruturas de proxy são assim:
connstring é obrigatória com o formato protocol://host:port (protocol pode ser socks5 ou httpconnect/http)user e pass são opcionaisPara cada proxy declarado, uma cadeia implícita (veja o próximo parágrafo) é criada com o mesmo nome. Ela tem parâmetros padrão e é composta pelo único proxy associado. Se você quiser usar parâmetros não padrão, deve criar explicitamente uma cadeia.
As cadeias devem ser declaradas na seção chains como um mapa de estruturas de cadeia.
As chaves do mapa são escolhidas livremente, mas devem corresponder às usadas na definição das rotas, e
devem ser diferentes das chaves do mapa da seção proxies.
As estruturas de cadeia têm parâmetros semelhantes aos do proxychains (cf. https://github.com/rofl0r/proxychains-ng):
proxyDns: booleano, opcional, padrão truetcpConnectTimeout: inteiro, opcional, padrão 1000 (usado ao conectar soquetes, seja ao primeiro proxy
da cadeia ou diretamente ao destino)tcpReadTimeout: inteiro, opcional, padrão 2000 (usado ao ler as respostas de handshake do proxy em soquetes conectados)proxies: lista de strings, opcional, padrão lista vaziaA chave proxies de uma chain deve conter um array de nomes de proxies declarados como chaves na seção proxies.
Como mencionado no parágrafo anterior, para cada proxy declarado na seção proxies, uma cadeia
implícita (veja o próximo parágrafo) é criada com o mesmo nome. Ela tem parâmetros padrão e é
composta pelo único proxy associado.
O modo de configuração embutido para roteamento é por meio do arquivo de configuração. Ele associa
endereços a nomes de cadeias. O arquivo deve conter um mapa de tabelas de roteamento. As chaves do mapa
são escolhidas livremente, mas devem corresponder às usadas na seção servers.
Cada tabela de roteamento contém uma chave default representando a rota padrão e uma chave blocks
que é um array de blocos de regras. Cada
bloco de regras contém um comment, um conjunto de rules e um nome de cadeia
associado. As regras são avaliadas: dado um endereço no formato host:port, elas podem
ser true ou false. Para um determinado endereço, os blocos são avaliados na sua
ordem de declaração. Os blocos podem ser desabilitados definindo o campo disable como true.
Isso permite uma forma de "comentário", o que não é possível em JSON.
A avaliação para no primeiro bloco que for true e
o nome da cadeia associado é retornado. Cada servidor aberto (da seção servers)
é associado a uma tabela de roteamento da configuração. As requisições recebidas em
cada servidor são roteadas de acordo com a tabela de roteamento correspondente. Se todos os blocos forem avaliados como
, a rota padrão é usada. Se não estiver definido, as conexões são descartadas por padrão.
Campos do bloco:
comment (string)rules (Rule ou RuleCombo)route (string)disable (bool)Campos da regra:
rule (string): tipo de regra, regexp, subnet.variable (string): variável para avaliação de regexp, host, port ou addr (host:port).content (string): conteúdo da regra, depende do tipo de regra (veja abaixo).negate (bool) [opcional]: se deve negar a regra.Campos do RuleCombo:
rule1 (Rule ou RuleCombo): operando esquerdo.op (string): operador, AND, And, and, &, &&, OR, Or, or, |, ||.rule2 (Rule ou RuleCombo): operando direito.Tipos de regra:
regexp: corresponde à variável definida em variable (host, port ou addr=host:port) com a regexp em content.subnet: verifica se o host está na sub-rede definida em content. Se o host for um nome de domínio e não um endereço de sub-rede, a regra retorna false.Os blocos de regras da seção routes ou a função PAC devem retornar nomes de cadeias
declarados, não nomes de proxies. Se você quiser usar um único proxy, deve envolvê-lo
em uma cadeia. O nome drop é especial e não precisa ser declarado nesta
configuração. Se a função PAC ou um bloco de roteamento retornar drop como um
nome de cadeia, a conexão é descartada.
Se o bbs for compilado com suporte a PAC e o argumento -pac apontar para um arquivo PAC, as rotas
definidas no arquivo de configuração não serão usadas. O roteamento por arquivo PAC não suporta
múltiplas tabelas de roteamento. O mesmo arquivo PAC será usado para cada servidor aberto.
Os listeners abertos pelo bbs devem ser declarados na seção servers como uma lista de
strings de conexão no formato protocol://bind_addr:bind_port:routing_table ou
protocol://bind_addr:bind_port:chain:dest_addr:dest_port.
protocol pode ser http ou socks5 se a routing_table for fornecidaprotocol pode ser fwd se chain, dest_addr e dest_port forem fornecidosrouting_table deve corresponder a uma das tabelas definidas na seção routeschain deve corresponder a uma das cadeias definidas na seção chainsA resolução de hosts personalizada (semelhante ao /etc/hosts) pode ser configurada na
seção hosts como um mapa de strings. As chaves do mapa correspondem ao hostname
e os valores ao endereço IP para o qual o host deve ser resolvido.
Deve-se notar que as chaves do mapa também podem ser endereços IP. Nesse caso, o endereço IP da chave será substituído pelo endereço IP do valor. Da mesma forma, os valores do mapa podem ser hostnames e substituirão a chave do mapa correspondente.
Se definidas, as resoluções de hosts personalizadas ocorrem no início da fase de conexão, após a decisão de roteamento e antes de qualquer resolução DNS local (se a cadeia estiver configurada com proxyDns=false) e antes de enviar o endereço de destino aos vários proxies da cadeia.
Se o bbs for compilado com suporte a PAC, o roteamento pode ser configurado com um script PAC
em vez de um arquivo de configuração JSON. No entanto, isso requer o uso de uma biblioteca
Go não confiável. O caminho do arquivo PAC deve ser fornecido com -pac.
O script PAC deve definir a função FindProxyForURL(url, host). Os
valores retornados por essa função devem corresponder aos nomes das cadeias (não dos
proxies) declarados na configuração JSON.
falsedefault