
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.
L'ancienne version de bbs peut être trouvée ici
bbs est un routeur pour les proxys SOCKS et HTTP. Il expose des services SOCKS5, HTTP
CONNECT ou de redirection de ports et transmet les requêtes entrantes à des proxys ou à des chaînes de proxys
en fonction de la cible de la requête. Le routage peut être configuré avec un script PAC (si
le support PAC est inclus à la compilation), ou via un fichier JSON.
go install github.com/synacktiv/bbs@master
Pour installer bbs avec le support des scripts PAC :
go install -tags pac github.com/synacktiv/bbs@master
Note : PAC repose sur des bibliothèques tierces non auditées.
La CLI python bbscli.py est fournie pour faciliter la configuration de bbs et éviter d'écrire des fichiers JSON manuellement.
Elle nécessite la bibliothèque pyparsing, qui est empaquetée par Debian :
apt install python3-pyparsing
Si la bibliothèque n'est pas empaquetée par votre distribution, elle peut être installée avec pip :
pip install pyparsing
La configuration se fait dans un fichier JSON composé de plusieurs sections :
Le chemin du fichier de configuration est fourni via l'argument -c <path> (par défaut ./bbs.json).
bbs recharge les fichiers de configuration sur SIGHUP, utilisez kill -HUP <pid> pour recharger.
Voici un exemple d'une telle configuration :
{
"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"
}
}
Les proxys amont doivent être déclarés dans la section proxies comme une table de structures de proxy.
Les clés de la table sont choisies librement mais doivent correspondre à celles utilisées dans la définition des chaînes.
Les structures de proxy sont les suivantes :
connstring est requis avec le format protocol://host:port (protocol peut être socks5 ou httpconnect/http)user et pass sont optionnelsPour chaque proxy déclaré, une chaîne implicite (voir le paragraphe suivant) est créée avec le même nom. Elle a des paramètres par défaut et est composée du seul proxy associé. Si vous voulez utiliser des paramètres non par défaut, vous devez explicitement créer une chaîne.
Les chaînes doivent être déclarées dans la section chains comme une table de structures de chaîne.
Les clés de la table sont choisies librement mais doivent correspondre à celles utilisées dans la définition des routes, et
doivent être différentes des clés de la table de la section proxies.
Les structures de chaîne ont des paramètres de type proxychains (cf. https://github.com/rofl0r/proxychains-ng) :
proxyDns : booléen, optionnel, défaut à truetcpConnectTimeout : entier, optionnel, défaut à 1000 (utilisé lors de la connexion des sockets, soit au premier proxy
de la chaîne, soit directement à la cible)tcpReadTimeout : entier, optionnel, défaut à 2000 (utilisé lors de la lecture des réponses d'établissement de liaison des proxys sur les sockets connectées)proxies : liste de chaînes, optionnelle, défaut à liste videLa clé proxies d'une chain doit contenir un tableau de noms de proxys déclarés comme clés dans la section proxies.
Comme mentionné dans le paragraphe précédent, pour chaque proxy déclaré dans la section proxies, une chaîne
implicite (voir le paragraphe suivant) est créée avec le même nom. Elle a des paramètres par défaut et est
composée du seul proxy associé.
Le mode de configuration intégré pour le routage se fait via le fichier de configuration. Il associe
des adresses à des noms de chaînes. Le fichier doit contenir une table de tables de routage. Les clés
de la table sont choisies librement mais doivent correspondre à celles utilisées dans la section servers.
Chaque table de routage contient une clé default représentant la route par défaut et une clé blocks
qui est un tableau de blocs de règles. Chaque
bloc de règles contient un comment, un ensemble de rules, et un nom de chaîne
associé. Les règles sont évaluées : étant donné une adresse au format host:port, elles peuvent
être true ou false. Pour une adresse donnée, les blocs sont évalués dans leur
ordre de déclaration. Les blocs peuvent être désactivés en définissant le champ disable à true.
Cela permet une forme de « mise en commentaire », qui n'est pas possible en JSON.
L'évaluation s'arrête au premier bloc qui est true et
le nom de chaîne associé est retourné. Chaque serveur ouvert (de la section servers)
est associé à une table de routage de la configuration. Les requêtes reçues sur
chaque serveur sont routées selon la table de routage correspondante. Si tous les blocs sont évalués à
, la route par défaut est utilisée. Si n'est pas défini, les connexions sont abandonnées par défaut.
Champs d'un bloc :
comment (string)rules (Rule ou RuleCombo)route (string)disable (bool)Champs d'une règle :
rule (string) : type de règle, regexp, subnet.variable (string) : variable pour l'évaluation de l'expression régulière, host, port ou addr (host:port).content (string) : contenu de la règle, dépend du type de règle (voir ci-dessous).negate (bool) [optionnel] : indique si la règle doit être inversée.Champs d'un RuleCombo :
rule1 (Rule ou RuleCombo) : opérande gauche.op (string) : opérateur, AND, And, and, &, &&, OR, Or, or, |, ||.rule2 (Rule ou RuleCombo) : opérande droite.Types de règles :
regexp : fait correspondre la variable définie dans variable (host, port ou addr=host:port) avec l'expression régulière dans content.subnet : vérifie si l'hôte est dans le sous-réseau défini dans content. Si l'hôte est un nom de domaine et non une adresse de sous-réseau, la règle retourne false.Les blocs de règles de la section routes ou la fonction PAC doivent retourner des noms de chaînes
déclarés, et non des noms de proxys. Si vous souhaitez utiliser un seul proxy, vous devez l'envelopper
dans une chaîne. Le nom drop est spécial et n'a pas besoin d'être déclaré dans
cette configuration. Si la fonction PAC ou un bloc de routage retourne drop comme
nom de chaîne, alors la connexion est abandonnée.
Si bbs est compilé avec le support PAC et que l'argument -pac pointe vers un fichier PAC, les routes
définies dans le fichier de configuration ne seront pas utilisées. Le routage par fichier PAC ne prend pas en charge
plusieurs tables de routage. Le même fichier PAC sera utilisé pour chaque serveur ouvert.
Les écouteurs ouverts par bbs doivent être déclarés dans la section servers comme une liste de
chaînes de connexion au format protocol://bind_addr:bind_port:routing_table ou
protocol://bind_addr:bind_port:chain:dest_addr:dest_port.
protocol peut être http ou socks5 si routing_table est fourniprotocol peut être fwd si chain, dest_addr et dest_port sont fournisrouting_table doit correspondre à l'une des tables définies dans la section routeschain doit correspondre à l'une des chaînes définies dans la section chainsUne résolution personnalisée des hôtes (similaire à /etc/hosts) peut être configurée dans la
section hosts comme une table de chaînes. Les clés de la table correspondent au nom d'hôte
et les valeurs à l'adresse IP vers laquelle l'hôte doit être résolu.
Il convient de noter que les clés de la table peuvent également être des adresses IP. Dans ce cas, l'adresse IP de la clé sera remplacée par l'adresse IP de la valeur. De même, les valeurs de la table peuvent être des noms d'hôtes et remplaceront la clé de table correspondante.
Si elles sont définies, les résolutions personnalisées des hôtes ont lieu au début de la phase de connexion, après la décision de routage et avant toute résolution DNS locale (si la chaîne est configurée avec proxyDns=false) et avant l'envoi de l'adresse de destination aux différents proxys de la chaîne.
Si bbs est compilé avec le support PAC, le routage peut être configuré avec un script PAC
au lieu d'un fichier de configuration JSON. Cela nécessite cependant d'utiliser une bibliothèque
Go non fiable. Le chemin du fichier PAC doit être fourni avec -pac.
Le script PAC doit définir la fonction FindProxyForURL(url, host). Les
valeurs retournées par cette fonction doivent correspondre aux noms des chaînes (pas des
proxys) déclarées dans la configuration JSON.
falsedefault