
bbs est un routeur pour proxys SOCKS et HTTP. Il expose un service SOCKS5 (ou HTTP CONNECT) 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 compilé avec le support PAC), ou via un fichier JSON.
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 à
false, la route par défaut est utilisée. Si default 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)