SkillAgentSearch skills...

Bud

**NOT MAINTAINED** Bud - The TLS Terminator

Install / Use

/learn @indutny/Bud
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

Bud

Build Status NPM version

THIS PROJECT IS NOT MAINTAINED ANYMORE

A TLS terminator for superheroes.

What is bud?

Bud is a TLS terminating proxy, a babel fish decoding incoming TLS traffic and sending it in a plain text to your backend servers. Not only does it do this well, bud has a lot of useful features!

Why bud?

  • Asynchronous key/cert loading using the supplied servername extension (SNI)
  • Asynchronous selection of backend to balance (using SNI)
  • Asynchronous OCSP stapling
  • TLS ticket rotation across cluster of workers, or multi-machine cluster (needs separate utility to synchronize them, but the protocol is in-place)
  • Availability: marking backends as dead, reviving them after period of time
  • Multi-frontend mode of operation. Single bud instance might be bound to multiple different ports and interfaces
  • Proxyline support: both HAProxy format at custom BUD JSON format
  • X-Forwarded-For for first HTTP request, and custom frame for SPDY (soon HTTP2 too) connection
  • Multi-context mode of operation, each context is used for different server name. All TLS parameters may be redefined in the context
  • Support for simultaneous ECDSA and RSA certs and keys

Implementation details

Bud is implemented fully in C, with the exception to the tests which are running on [node.js][2]. The networking level is provided by [libuv][3], and the SSL implementation by [OpenSSL][4] 1.0.2h.

Install

Requirements

You must have gcc installed. Chances are that you do, but in case you don't:

# OSX
# Command Line Tools for Xcode: xcode-select --install,
# https://developer.apple.com/downloads, or Xcode

# SmartOS
[sudo] pkgin update
[sudo] pkgin install gcc47

# Ubuntu
[sudo] apt-get update
[sudo] apt-get install build-essential

Easy Install

Bud can easily be installed using npm

[sudo] npm install -g bud

This will install the command line tool bud. Optionally, you can build Bud from source with the steps below.

Build

Preparing:

npm install

Building:

gypkg build

The result will be located at: ./out/Release/bud.

Starting

To start bud - create a configuration file using this template and then:

bud --conf conf.json

Options

Usage: bud [options]

options:
  --version, -v              Print bud version
  --config PATH, -c PATH     Load JSON configuration
  --piped-config, -p         Load piped JSON configuration
  --default-config           Print default JSON config
  --daemon, -d               Daemonize process

Configuration

Bud uses [JSON][0] as the configuration format. Run bud --default-config to get the default configuration options (with comments and description below):

{
  // Number of workers to use, if 0 - only one process will be spawned.
  "workers": 1,

  // Timeout in ms after which workers will be restarted (if they die)
  "restart_timeout": 250,

  // Logging configuration
  "log": {
    // Minimum observable log level, possible values:
    // "debug", "notice", "info" (default), "warning", "fatal"
    "level": "info",

    // syslog facility to use, could be:
    // "auth", "cron", "kern", "lpr", "mail", "news", "syslog"
    // "deamon", "uucp", "local0", ... "local7"
    "facility": "user",

    // if true - logging will be printed to standard output
    "stdio": true,

    // if true - syslog will be used for logging
    "syslog": true
  },

  // Availability of the backend
  "availability": {
    // Maximum number of backend reconnects before giving up
    "max_retries": 5,

    // Time between retries
    "retry_interval": 250,

    // How long backend should not be responding until considered to be dead -- ms
    "death_timeout": 1000,

    // Timeout in ms after which it should be revived
    "revive_interval": 2500
  },

  // Frontend configuration (i.e. TLS/SSL server)
  "frontend": {
    "port": 1443,
    "host": "0.0.0.0",

    // Alternatively you may want to specify multiple address to bind server to
    // "interfaces": [
    //   { "port": 1443, "host": "1.1.1.1" },
    //   { "port": 1444, "host": "2.2.2.2" }
    // ],

    // tcp keepalive value (in seconds)
    "keepalive": 3600,

    // if true - server listed ciphers will be preferenced
    "server_preference": true,

    // Which protocol versions to support:
    // **optional**, default: "ssl23"
    // "ssl23" (implies tls1.*): "tls1", "tls1.1", "tls1.2"
    "security": "ssl23",

    // Path to default TLS certificate
    // NOTE: Could be an array of cert strings
    // e.g. ["-----BEGIN CERTIFICATE-----...", "-----BEGIN CERTIFICATE-----..."]
    "cert": "keys/cert.pem",

    // Path to default TLS private key
    // NOTE: Could be an array of keys as file paths or strings
    "key": "keys/key.pem",

    // **Optional** Passphrase for the private key
    // NOTE: Could be an array of passphrases
    "passphrase": null,

    // **Optional** Cipher suites to use
    // Bud defaults to:
    // "ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA256:ECDHE-RSA-AES256-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA256:DHE-RSA-AES256-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:AES256-GCM-SHA384:AES256-SHA256:AES128-GCM-SHA256:AES128-SHA256:AES128-SHA:DES-CBC3-SHA"
    "ciphers": null,

    // **Optional** ECDH Curve to use, defaults to `prime256v1
    "ecdh": "prime256v1",

    // **Optional** Path to DH parameters file
    // **Recommend** generate a file
    // openssl dhparam -out dh.key 3072
    "dh": null,

    // **Optional** Base64 encoded TLS session ticket key,
    // should decode into 48 raw bytes
    // **Recommend** Generate with:
    // node -pe "require('crypto').randomBytes(48).toString('base64')"
    //
    // **Important note**: it should not be generally set, OpenSSL will generate
    // a random value for it at start, and ticket rotation will change it after
    // some time anyway
    "ticket_key": "yzNUDktR5KmA4wX9g9kDSzEn...true randomness",

    // **Optional** Ticket timeout in seconds, default: 3600
    "ticket_timeout": 3600,

    // **Optional** Interval between rotating ticket keys.
    // NOTE: If you are deploying bud to many boxes - please contact me, I'll
    // explain how ticket may be rotated simulatenously on all of them
    "ticket_rotate": 3600,

    // **Optional** NPN protocols to advertise
    "npn": ["http/1.1", "http/1.0"],

    // NOTE: Better leave this default:

    // **Optional** Renegotiation window in seconds
    "reneg_window": 300,

    // **Optional** Maximum number of renegotiations in a window
    "reneg_limit": 3,

    // **Optional** Maximum size of TLS fragment
    "max_send_fragment": 1400,

    // **Optional** If false - close frontend connection on backend EOF
    "allow_half_open": false,

    // **Optional** If true - the clients will be requested to provide the cert
    "request_cert": true,

    // **Optional**: Either filename or array of PEM certificate chain that
    // should be used for validating client certs
    "ca": "filename"
    // "ca": [ "-----BEGIN CERTIFICATE----\n..." ]
  },

  // Balance tactic
  // **Optional** possible values: "roundrobin", "sni", or "on-fail"
  //
  // * "roundrobin" - on each new connection select next live backend
  // * "sni" - select backend list from either async sni or supplied contexts
  // * "on-fail" - select next backend in list only if the previous one is
  //   dead
  "balance": "roundrobin"

  // Unix-specific option, drop privileges after starting the process
  // **Recommend** Create a user and a group for bud.
  "user": null,
  "group": null,

  // Backend configuration (i.e. address of Cleartext server)
  "backend": [{
    "port": 8000,
    "host": "127.0.0.1",
    "keepalive": 3600,

    // if true - HAProxy compatible proxyline will be sent:
    // "PROXY TCP4 ... ... ... ..."
    // if "json":
    // 'BUD {"family":"TCP4","bud":{"host":"...","port":...},"peer":{...}'
    "proxyline": false,

    // if true:
    // - if NPN is enabled and either `spdy/3.1`, `spdy/3` or `spdy/2` is
    //   negotiated - custom `X_FORWARDED` frame will be sent on connection.
    //   see: https://groups.google.com/forum/#!topic/spdy-dev/XkdtuShtVCEadds
    //
    // - in all other cases `X-Forwarded-For: <address>` will be added right
    //   after the first line in the incoming data.
    //
    // - in order to avoid parsing each request, the `X-Forwarded-For` header
    //   will only be sent on the first client request.

    "x-forward": false,

    // *Optional key*
    // If this property is present - balancing will start from the backend,
    // which `external` value is matching server address.
    // (Useful when listening on multiple interfaces)
    "external": "[1.2.3.4]:443"
  }],

  // SNI context loading
  "sni": {
    "enabled": false,
    "port": 9000,
    "host": "127.0.0.1",

    // %s will be replaced with actual servername
    "url": "/bud/sni/%s"
  },

  // OCSP Stapling response loading
  "stapling": {
    "enabled": false,
    "port": 9000,
    "host": "127.0.0.1",

    // %s will be replaced with actual servername
    "url": "/bud/stapling/%s"
  },

  // Secure contexts (i.e. Server Name Indication support)
  "contexts": [{
    // Servername to match against
    "servername": "blog.indutny.com",

    // **Optional** balance algorithm, could not be `sni`
    "balance": "roundrobin",

    // Path to TLS certificate
    // Could be an array
    "cert": "keys/cert.pem",

    // Path to TLS private key
    // Could be an array
    "key": "keys/key.pem",

    // **Optional** Passphrase for the private key
    // Could be an array
    "passphrase": null,

    // Cipherlist to use (overrides fronten

Related Skills

View on GitHub
GitHub Stars448
CategoryDevelopment
Updated4mo ago
Forks29

Languages

C

Security Score

77/100

Audited on Nov 26, 2025

No findings