SSL-bump daemon
Transparently intercept HTTPS traffic for access control, content inspection, or caching. Certificates are pre-computed or generated on-the-fly.
The SSL-bump daemon sslbd
allows to transparently intercept in especially HTTPS traffic for
various purposes, e.g. access control, content inspection, or caching. Additionally, an explicit
mode is available for local installations, see below for details and deployment scenarios.
In a nutshell, for incoming connections, sslbd
typically performs the following steps:
- Determine some hostname, usually by parsing the incoming SSL client helo for an SNI. Alternatively, SOCKS4 or HTTP CONNECT information gets used, if the client is configured to ask us directly.
- Using this hostname, process configured ACLs (or ask an upstream HTTP service) for access control. Upon negative result, the client will be alerted if possible and the connection will be closed immediately.
- Additional ACLs will be processed in order to determine the SSL operation:
- Nothing: A new connection to the original destination will be established and payload will be forwarded untouched.
- Splicing (disabled per default): Perform independent handshakes with the client and the original destination. By this means, decrypted traffic can be dumped to disk e.g. for debugging purposes.
- Forward to a parent HTTP proxy: Perform client handshake and forward decrypted HTTP requests to an HTTP proxy e.g. for caching or inspection purposes.
- If required by the chosen mode, a matching certificate is used or generated on-the-fly.
- If the first step did succeed, hostname-based access control will be catched up on by trying to parse the certificate as returned by the upstream destination.
By this means, this implementation also focuses on high performance by using an event-driven loop, async-io, and async DNS and IPC.
Certificates
Per default, sslbd
will generate self-signed certificates on-the-fly. This will however cause
at least warnings in almost any recent browser or command-line tool. In especially when HSTS
and/or certificate pinning is in place, this mode is not an option.
Because of this, there are several possibilities for certificate management:
- Per-hostname self-signed certificate: As mentioned before, this is a built-in feature with
no more steps necessary. If you are ok with ignoring warnings and you intend to use
sslbd
only for a small set of domains that do not impose additional countermeasures such as HSTS, this is the easiest solution. - Root CA: Certificates are also generated as needed, but using the given CA for signing instead.
Please note that the CA can have
nameConstraints
to reduce the security impact. - Per-hostname: A certificate wallet is also supported, which removes the need for generating any certificate at runtime.
Basic Usage
There are 3 main daemons involved (apart from AC or parent proxies):
Installation
./configure
will try to detect the presence of header files for optional features and enable
or disable them accordingly. Despite its name, it is a custom script that will generate
conf/config.in
.
conf/config.inc
contains static configuration and global limits that you might want to take
a look at.
make
will locally build all needed binaries. Apart from common build environment dependencies,
there should be no other mandatory requirements, except for OpenSSL’s libssl-dev
, of course.
Traffic Redirection
Direct connections to the listening port are supported for both HTTP (CONNECT) and SOCKS4. Transparently intercepted connections are also supported, this however needs care with firewall rules in order to prevent loops. The following rule will intercept all non-marked HTTPS traffic:
sudo iptables -t nat -A OUTPUT -p tcp --dport 443 -m tos ! --tos 0x20 -j DNAT --to-destination 127.0.0.1:4444
This assumes sslbd
is configured to use TOS 32 for outgoing connections.
Please note that this might conflict with a local parent proxy, if not configured to also use TOS marking.
Configuration Reference
The configuration possibilities are as follows:
- Main
sslbd
configuration file - Certificate daemon
certd
configuration file - Certificate daemon coordinator
certdd
arguments - Compile-time macros
sslbd
The main sslbd
takes as single argument a configuration file, with the following supported keys:
loglevel
- One of
io
,debug
,info
,notice
, orerror
port
- The main port to listen on.
connect_tos
- IP TOS value to mark upstream connections with, 0 for disabled.
parent
- Connect to a parent proxy instead of the original destination.
error_cache
- Size of the source/destination connect error cache.
dns_server
- DNS resolver to use.
dns_cache
- DNS cache entries.
http_err_doc
- Path to the HTTP + HTML document to use as errorpage.
dump_dir
- Where to stream traffic to disk.
pid_file
- Pid file to write at startup.
stats_file
- Statistics file, will be updated in-place periodically.
jail
- Chroot directory.
certd_sock
- UDS IPC socket path to a certificate daemon. Repeat this directive with unique paths to configure and loadbalance multiple helper processes.
wallet_dir
- Directory holding pre-generated certificates to be used. Named after the CN, private key and certificate are expected im PEM format (
~
-separated). ssl_cache
- SSL cache entries.
sni_cache
- Cache for the SNI. Recommended as for session resumptions, no SNI might be transmitted.
dh_params
- DH parameter file.
bump_acl
- Rules to define the main operation, processed in order. For example,
bump_acl 127.0.0.1/32 0.0.0.0/0:443 *.example.com bump
will enablebump
mode tor the given SNI globbing pattern and IP addresses. ac_acl
- Rules for denying access, processed in order. For example,
ac_acl 0.0.0.0/0 0.0.0.0/0:443 www.example.com false
does not allow a certain domain. ac_upstream
- Parent proxy for access control. HTTP response status determines whether a connection is allowed (504) or not (403).
ac_cache
- Access control rule cache size.
certd
The certd
daemon for generating certificates takes a config-file and a UDS-filename as argument.
The config file supports:
loglevel
- One of
io
,debug
,info
,notice
, orerror
cert_cache
- Number of cerfificates to be cached in memory.
ca
- Root CA to use for signing certificates.
pid_file
- Pid file to write at startup.
certdd
The certdd
daemon merely spawns multiple certd
instances.
It takes the desired number of children as first argument.
Further arguments are passed along, with the last argument (socket filename) appended by .<instance>
.
config.inc
This file controls or enables/disables several features at compile-time.
MAX_CLIENTS (512)
- Number of parallel connections, used for estimating global file descriptor limit
MAX_ACCEPTS (10)
- How many accept calls at once for the listening socket
POLL_EVENTS_MAX (512)
- Handle that much events at max per poll loop
POLL_INTERVAL (1)
- Sleep in ms after each event-loop for collecting more events and less spinning under low load (acc. to
POLL_INTERVAL_MAX
andPOLL_EVENTS_MAX
) POLL_INTERVAL_MAX (1000)
- Don’t sleep
POLL_INTERVAL
ms if there are more file descriptors than this MAX_IOS (3)
- Max low-level read/write operations per call (can have multiple calls overall)
BUF_SIZE (4096)
- Continuous buffer size, used in main buffer chain and at other various places
BUF_MAX (8)
- Max number of buffers per chain
MAX_AIO (2*BUF_SIZE)
- Max number of pending bytes per fd, more considered an error, 0 disables aio completely
MAX_IDLE (70)
- Connection timeout in s during i/o state (browsers might use 60)
MAX_SHORT_IDLE (3)
- Short timeout in s during processing state for various operations, such as SNI peeking, cert generation, acl lookups, …
SNI_PEEK_PORT (443)
- If not zero, don’t try to peek for a SNI for other ports
REQUIRE_ORIGINAL_DST (0)
- Are direct connections allowed? This will require some proxy protocol to be used or DNS resolution for determining the original destination.
ORIGINAL_DST
- For testing purposes, assume this destination as the intercepted original destination.
ORIGINAL_DST_PORT
- For testing purposes, assume replace the intercepted original port with this one.
TRANSPARENT (0)
- Spoof the client’s source IP address for upstream connections?
MAX_POOL_SPARE (10000)
- In bytes, 0 disables pooling.
SLAB_POOL_MIN (64)
- Smallest slab
SLAB_POOL_NUM (8)
- Number of slots (with each doubled size, so 8192 @ 64)
WILDCARD_CERTS (1)
- Create wildcard-certificates by stripping the first subdomain (not for 1st and 2nd level)?
MAX_SNI_LEN (255)
- Limit for hostnames/CNs
PARSE_CLIENT_HELO (0)
- Use custom client handshake parsing for getting the SNI? Otherwise, use OpenSSL w/ more overhead but this might detect handshake errors more early.
AC_CACHE_TTL (300)
- AC cache expiration in s, 0 for disabled expiration.
SPLICE (0)
- Splicing decrypted content to disk using aio enabled?
Documentation
Apart from this document, most part of the code uses doxygen-style comments. Use make docs
to locally generate the corresponding HTML documentation.