Skip to content
/ bbs Public

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.

Notifications You must be signed in to change notification settings

synacktiv/bbs

Repository files navigation

BBS

The old bbs can be found here

Description

bbs is a router for SOCKS and HTTP proxies. It exposes SOCKS5 or HTTP CONNECT services 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.

Install

go install github.com/synacktiv/bbs@master

To install bbs with PAC script support:

go install -tags pac github.com/synacktiv/bbs@master

Note: PAC relies on unaudited third-party libraries.

Configuration

Configuration is performed in one JSON file composed of multiple sections:

  • Proxies: defines all the upstream proxies used by bbs
  • Chains: defines the differents chains of previously defined proxies, and their settings
  • Routes: defines the different routing tables
  • Servers: defines the listeners (SOCKS5 or HTTP) opened by bbs
  • Hosts: defines custom hosts resolution (in a /etc/hosts way)

The configuration file path is provided through argument -c <path> (default to ./bbs.json). bbs reloads configuration files on SIGHUP, use kill -HUP <pid> to reload.

Here is an example of such 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": [
      {
        "comment": "Block1 comment",
        "rules": {
          "rule": "regexp",
          "variable": "host",
          "content": "me\\.gandi\\.net"
        },
        "route": "chain1"
      },
      {
        "comment": "Route web traffic towards 10.35.0.0/16 through chain1",
        "rules": {
          "rule1": {
            "rule": "subnet",
            "content": "10.35.0.0/16"
          },
          "op": "AND",
          "rule2": {
            "rule": "regexp",
            "variable": "port",
            "content": "^(80|443)$"
          }
        },
        "route": "chain1"
      },
      {
        "comment": "Drop traffic to 445",
        "rules": {
          "rule": "regexp",
          "variable": "port",
          "content": "^445$"
        },
        "route": "drop"
      },
      {
        "comment": "Route *.corp.local through chain2",
        "rules": {
          "rule": "regexp",
          "variable": "host",
          "content": "(?i)^(.*\\.)?corp\\.local$"
        },
        "route": "chain1"
      },
      {
        "comment": "Default routing through direct chain",
        "rules": {
          "rule": "true"
        },
        "route": "direct"
      }
    ],
    "table2": [
      {
        "comment": "Default routing through chain1",
        "rules": {
          "rule": "true"
        },
        "route": "chain1"
      }
    ]
  },
  "servers": [
    "socks5://127.0.0.1:1081:table1",
    "http://127.0.0.1:1080:table2"
  ],
  "hosts": {
    "host1": "1.1.1.1",
    "host2": "10.0.0.1"
  }
}

Proxies

Upstream proxies must be declared in the proxies section as a map of proxy structures. Map keys are chosen freely but must match the ones used in chains definition. Proxy structures are like this:

  • connstring is required with format protocol://host:port (protocol can be socks5 or httpconnect/http)
  • user and pass are optional

Chains

Chains must be declared in the chains section as a map of chain structures. Map keys are chosen freely by must match with the ones used in routes definition. Chain structures have proxychains-like parameters (cf. https://github.com/rofl0r/proxychains-ng):

  • proxyDns: boolean, optional, defaults to true
  • tcpConnectTimeout: integer, optional, defaults to 1000
  • tcpReadTimeout: integer, optional, defaults to 2000
  • proxies: string list, optional, defaults to empty list

The proxies key of a chain must contain an array of proxy names declared as keys in the proxies section.

Routes

The built-in configuration mode for routing is through the configuration file. It associates addresses with chain names. The file must contain a map of routing tables. Map keys are chosen freely but must match the ones used in the servers section. Each routing table is an array of rule blocks. Each rule block contains a comment, a set of rules, and an associated chain name. Rules are evaluated: given an address in the host:port format, they can be true or false. For a given address, blocks are evaluated in their declaration order. The evaluation stops at the first block that is true and the associated chain name is returned. Each opened server (from servers section) is associated with one routing table from the configuration. Requests received on each server are routed according to the matching routing table.

Block fields:

  • comment (string)
  • rules (Rule or RuleCombo)
  • route (string)

Rule fields:

  • rule (string): rule type, regexp, subnet or true.
  • variable (string): variable for regexp evaluation, host, port or addr (host:port).
  • content (string): content of the rule, depends on the rule type (see below).
  • negate (bool) [optional]: whether to negate the rule.

RuleCombo fields:

  • rule1 (Rule or RuleCombo): left operand.
  • op (string): operator, AND, And, and, &, &&, OR, Or, or, |, ||.
  • rule2 (Rule or RuleCombo): right operand.

Rule types:

  • regexp: match the variable defined in variable (host, port or addr=host:port) against the regexp in content.
  • subnet: checks if host is in the subnet defined in content. If host is a domain name and not a subnet address, the rule returns false.
  • true: returns true for every address. Useful for default routing at the end of the block array.

The rule blocks from routes section or the PAC function must return declared chain names, not proxy names. If you want to use a single proxy, you must wrap it in a chain. The drop name is special and does not need to be declared in this configuration. If the PAC function or a routing block returns drop as a chain name, then the connection is dropped.

If bbs is built with PAC support and -pac arguments points to a PAC file, routes defined in the configuration file will not be used. PAC file routing does not support multiple routing tables. The same PAC file will be used for every opened server.

Servers

The listeners opened by bbs must be declared in the servers section as a list of connection strings of format protocol://bind_addr:bind_port:routing_table.

  • protocol can be http or socks5
  • routing_table must match one of the tables defined in routes section

Hosts

Custom host resolution (similar to /etc/hosts) can be configured in the hosts section as a map of strings. Map keys correspond to the hostname and the values to the IP address the host should resolve to.

PAC script

If bbs is built with PAC support, routing can be configured with a PAC script instead of a JSON configuration file. However, this requires using an untrusted Go library. The PAC file path must be provided with -pac.

The PAC script must define the FindProxyForURL(url, host) function. The values returned by this function must match the names of the chains (not the proxies) declared in the JSON configuration.

About

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.

Resources

Stars

Watchers

Forks

Packages

No packages published

Languages