cfal/tobaru
 Watch   
 Star   
 Fork   
22 days ago
tobaru

v0.9.4

TLS Passthrough

Connections can now be forwarded to upstream targets without TLS termination. The proxy parses the ClientHello to extract SNI and ALPN, then either terminates or passes through the raw TCP stream based on target configuration. Passthrough targets cannot use HTTP actions or client_tls (validated at config load time). A new example is provided in examples/sni_passthrough.yml.

Wildcard SNI Matching

SNI-based routing now supports wildcard patterns (*.example.com) via a new DomainTrie data structure, replacing the previous HashMap<TlsOption, ...> lookup. The trie supports exact matches, wildcard subdomains, dot-shorthand (.example.com), and catch-all (*). A new example is provided in examples/wildcard_sni.yml.

Host Header Wildcard Routing

HTTP host header matching supports the same wildcard patterns as SNI routing. A Hostnames variant was added for the Host header config, enabling pattern-based virtual hosting. See examples/host_header_routing.yml.

TLS Fingerprint Verification

Both client and server certificate fingerprints (SHA-256) can now be verified:

  • Client fingerprints: The server can require connecting clients to present certificates matching configured SHA-256 fingerprints, optionally combined with CA chain validation.
  • Server fingerprints: Outbound connections can pin upstream server certificates by fingerprint, with optional WebPKI verification.

Client CA Certificate Authentication

Server listeners can require client certificates signed by specified CA certificates via the new client_ca_certs config option. This works alongside or independently of fingerprint-based verification.

Client ALPN and SNI Control

Outbound TLS connections now support explicit ALPN protocol negotiation and SNI hostname configuration. SNI can be set to a specific hostname, disabled entirely (YAML null), or left to default behavior.

TCP Keepalive

Both server-side (client-facing) and target-side (upstream) TCP keepalive can be configured with idle and interval durations. Implemented via socket2 using raw file descriptor manipulation. Failures are logged but do not abort connections.

Hostname Validation

A new hostname_util module provides strict validation for SNI hostnames (per RFC 6066 section 3) and HTTP Host headers. Rejects empty strings, overlength labels, trailing/leading/consecutive dots, non-ASCII bytes in SNI, control characters, and IP address literals in SNI. Pattern normalization strips FQDN trailing dots and validates wildcard placement at deserialization time.

TLS ClientHello Parser

A custom TLS ClientHello parser (tls_parser and tls_reader modules) replaces the previous peek-based TLS detection heuristic. This enables full extraction of SNI and ALPN from the ClientHello before deciding whether to terminate or pass through, and eliminates the polling sleep loop.

Replay Stream Removal

The LazyConfigAcceptor-based flow was replaced with direct ClientHello parsing and manual feeding of buffered bytes into the rustls ServerConnection. For non-TLS fallback, already-read bytes are passed as initial_data through to the HTTP parser via a new LineReader::new_with_data() constructor, so no bytes are lost.

Cooperative Task Scheduling

The bidirectional copy loop now participates in Tokio's cooperative task budgeting (tokio::task::coop), preventing high-throughput streams from starving other tasks on the runtime.

Rustls and Crypto Backend Migration

  • Migrated from ring to aws_lc_rs as the cryptographic backend.
  • Updated to the rustls 0.23 API: CertificateDer<'static>, PrivateKeyDer<'static>, explicit CryptoProvider, danger module verifier traits, simplified key/cert loading.
  • Server config now sets ignore_client_order = true, preferring the server's cipher suite order.
  • Max log level is capped in release builds via Cargo.toml feature flags.

Config and API Changes

  • TlsOption split into purpose-specific AlpnValue and SniValue types, with SniValue performing hostname validation at deserialization time.
  • required_request_headers changed from Option<HashMap<...>> to HashMap<...> (empty map replaces None).
  • NoneOrSome/OneOrSome iterators now require Send/Sync bounds for async task compatibility.
  • Header path fields may now be empty.

Documentation

  • Added CONFIG.md with full configuration reference.
  • Updated README.md with sections on wildcard SNI matching, host header routing, and new TLS features.
  • Added example configs: host_header_routing.yml, sni_passthrough.yml, wildcard_sni.yml.

Minor Improvements

  • Replaced std::io::Error::new(ErrorKind::Other, ...) with std::io::Error::other(...) (Rust 1.74+) throughout the codebase.
  • Replaced line.find(x).is_some() with line.contains(x).
  • Simplified task spawning in main.rs to idiomatic iterator collect.
  • NoneOrSome now derives Default via enum #[default] attribute.
  • Simplified is_unspecified() methods using matches!() macro.
2023-08-23 21:24:50
tobaru

0.9.0

Full Changelog: https://github.com/cfal/tobaru/compare/0.7.1...0.9.0

Breaking changes: The config format has changed. See https://github.com/cfal/tobaru/blob/master/UPGRADING.md for details.

2022-03-14 04:46:15
tobaru

0.7.1

  • Bugfix: Allow common IP masks across TLS configs
2022-03-13 04:32:19
tobaru
2021-06-27 23:55:39
tobaru

0.2.0

  • Fix for copy_bidirectional causing CLOSE_WAIT sockets
  • Defaults to rustls
2021-05-28 21:19:26
tobaru