Skip to content

komAAmok/custls

Β 
Β 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

4,822 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

logo

custls - A minimal-invasive fork of rustls with browser-level TLS fingerprint simulation

Based on rustls - A modern TLS library written in Rust


🎯 What is custls?

custls is a specialized fork of rustls that adds browser-level TLS ClientHello fingerprint simulation capabilities while maintaining all of rustls's security guarantees and performance characteristics.

✨ Key Features

  • 🎭 Browser Fingerprint Simulation - Accurately simulate Chrome, Firefox, Safari, and Edge TLS fingerprints
  • πŸ”„ Smart Randomization - Apply natural variations to avoid static fingerprint detection
  • πŸ’Ύ Fingerprint Caching - Automatically cache successful fingerprints for consistent behavior
  • 🎣 Multi-Phase Hooks - Fine-grained control over ClientHello construction (4 hook phases)
  • ⚑ Minimal Overhead - Only 3.9-5.9% performance impact (well under 10% target)
  • πŸ”’ Security Preserved - Zero unsafe code, all rustls security guarantees maintained
  • πŸ”§ Minimal Invasiveness - <100 lines of modifications to rustls core
  • πŸš€ Easy Integration - Works seamlessly with hyper, reqwest, and other HTTP clients

🎯 Use Cases

  • Web Scraping - Bypass TLS fingerprint-based bot detection (Cloudflare, Akamai, DataDome)
  • API Testing - Test fingerprint detection systems with realistic browser traffic
  • Security Research - Analyze and understand TLS fingerprinting techniques
  • Privacy Tools - Build tools that resist fingerprinting-based tracking

πŸš€ Quick Start

Installation

Add to your Cargo.toml:

[dependencies] rustls = { path = "./custls/rustls" } # Use custls fork hyper = { version = "0.14", features = ["client", "http1", "http2"] } hyper-rustls = "0.24" tokio = { version = "1", features = ["full"] }

Basic Usage

use std::sync::Arc; use rustls::custls::{CustlsConfig, BrowserTemplate, RandomizationLevel, DefaultCustomizer}; // Configure custls to simulate Chrome 130 let custls_config = CustlsConfig::builder() .with_template(BrowserTemplate::Chrome130) .with_randomization_level(RandomizationLevel::Light) .with_cache(true) .build(); let customizer = Arc::new(DefaultCustomizer::new(custls_config)); // Use with your HTTP client (hyper, reqwest, etc.) // See examples/ directory for complete integration examples

With Hyper

use hyper::{Client, Request, Body}; use hyper_rustls::HttpsConnectorBuilder; use rustls::ClientConfig; #[tokio::main] async fn main() -> Result<(), Box<dyn std::error::Error>> { // Configure rustls with custls let mut tls_config = ClientConfig::builder() .with_safe_defaults() .with_native_roots() .with_no_client_auth(); // Build HTTPS connector let https = HttpsConnectorBuilder::new() .with_tls_config(tls_config) .https_only() .enable_http2() .build(); // Create hyper client let client = Client::builder().build::<_, Body>(https); // Make requests with browser-like TLS fingerprints let req = Request::builder() .uri("https://example.com") .header("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36") .body(Body::empty())?; let res = client.request(req).await?; println!("Status: {}", res.status()); Ok(()) }

πŸ“š Documentation

Quick Links

Examples

  • custls_basic_usage.rs - Basic configuration patterns
  • custls_http_client.rs - HTTP client integration patterns
  • hyper_custls_complete.rs - Complete hyper integration
  • custls_custom_hooks.rs - Custom hook implementation
  • custls_custom_template.rs - Custom template creation
  • custls_zero_overhead.rs - Zero-overhead mode

🎨 Browser Templates

custls includes accurate templates for major browsers:

Template Description Use Case
Chrome130 Chrome 130+ (Chromium-based) Most common, best compatibility
Firefox135 Firefox 135+ (Gecko-based) Unique fingerprint, good diversity
Safari17 Safari 17+ (WebKit-based) macOS/iOS scenarios
Edge130 Edge 130+ (Chromium-based) Windows-specific scenarios
Custom User-defined template Advanced customization

🎚️ Randomization Levels

Control the degree of fingerprint variation:

Level Overhead Description Use Case
None ~3.9% Exact template match Maximum performance
Light ~5.1% Small browser-style variations Recommended - Natural behavior
Medium ~4.7% Moderate variations Moderate anti-fingerprinting
High ~4.7% Maximum variation Strong anti-fingerprinting

πŸ“Š Performance

Based on comprehensive benchmarks:

Configuration Latency Overhead
Vanilla rustls 28.5ΞΌs Baseline
custls (None) 29.6ΞΌs +3.9%
custls (Light) 30.0ΞΌs +5.1% βœ…
custls (Medium) 29.8ΞΌs +4.7%
custls (High) 29.8ΞΌs +4.7%

Cache Performance:

  • Cache lookup: <1ns (effectively instant)
  • Hook invocation: <1ns (zero overhead)

βœ… All performance targets met - Well under 10% overhead requirement!

πŸ—οΈ Architecture

custls uses a minimal-invasive architecture:

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ Application Layer β”‚ β”‚ (HTTP clients: hyper, reqwest, etc.) β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ custls Public API β”‚ β”‚ - CustlsConfig β”‚ β”‚ - ClientHelloCustomizer trait β”‚ β”‚ - BrowserTemplate enum β”‚ β”‚ - RandomizationLevel enum β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ custls Core Modules β”‚ β”‚ (All in src/custls/ - isolated) β”‚ β”‚ - hooks.rs - templates.rs β”‚ β”‚ - randomizer.rs - state.rs β”‚ β”‚ - extensions.rs - utils.rs β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ rustls Core (Minimally Modified) β”‚ β”‚ - <100 lines of modifications β”‚ β”‚ - Strategic hook insertion points β”‚ β”‚ - Field exposure for customization β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ 

Modifications to rustls

custls makes minimal, surgical modifications to rustls:

  • Total modifications: <100 lines across 5 files
  • Files modified:
    • src/lib.rs: 1 line (module declaration)
    • src/msgs/client_hello.rs: ~30 lines (field exposure)
    • src/msgs/enums.rs: ~20 lines (extension types)
    • Integration points: minimal hook insertions

All custls logic is isolated in src/custls/ for easy maintenance and upstream rebasing.

πŸ”§ Configuration Options

Basic Configuration

let config = CustlsConfig::builder() .with_template(BrowserTemplate::Chrome130) .with_randomization_level(RandomizationLevel::Light) .with_cache(true) .build();

Advanced Configuration

let config = CustlsConfig::builder() .with_template(BrowserTemplate::Firefox135) .with_randomization_level(RandomizationLevel::Medium) .with_cache(true) .with_max_cache_size(1000) .build();

Custom Hooks

use rustls::custls::ClientHelloCustomizer; #[derive(Debug)] struct MyCustomHooks; impl ClientHelloCustomizer for MyCustomHooks { // Implement custom hook methods for fine-grained control // 4 phases: config, components, structure, wire bytes } let customizer = Arc::new(MyCustomHooks);

πŸ§ͺ Testing

custls includes comprehensive testing:

  • βœ… 230+ unit tests - All core functionality validated
  • βœ… 17 property-based tests - Universal correctness properties verified
  • βœ… Integration tests - Complete handshake flows validated
  • βœ… Browser validation tests - Template fidelity confirmed
  • βœ… Performance benchmarks - Overhead monitoring

Run tests:

# Run all tests cargo test --lib custls # Run benchmarks cargo bench --bench custls_benchmarks # Build examples cargo build --examples

πŸ”’ Security

custls maintains all rustls security guarantees:

  • βœ… Zero unsafe code in custls module
  • βœ… RFC 8446 downgrade protection implemented
  • βœ… Certificate validation fully preserved
  • βœ… Constant-time operations maintained
  • βœ… Session security properly handled

🀝 Integration with HTTP Clients

custls works seamlessly with popular Rust HTTP clients:

Hyper

let https = HttpsConnectorBuilder::new() .with_tls_config(tls_config) .https_only() .enable_http2() .build(); let client = Client::builder().build::<_, Body>(https);

Reqwest

let client = Client::builder() .use_preconfigured_tls(tls_config) .build()?;

See Integration Guide for complete examples.

πŸ“‹ Best Practices

βœ… DO

  1. Match HTTP headers to TLS fingerprint

    // TLS: Chrome 130 β†’ HTTP headers: Chrome 130 .header("User-Agent", "Mozilla/5.0 ... Chrome/130.0.0.0 ...")
  2. Enable caching for consistency

    .with_cache(true) // Maintain consistent fingerprints per target
  3. Use Light randomization

    .with_randomization_level(RandomizationLevel::Light) // Natural variation
  4. Reuse clients

    let client = create_client(config); for url in urls { client.get(url).await?; }

❌ DON'T

  1. Don't mix fingerprints and headers - TLS Chrome + HTTP Firefox = detected
  2. Don't over-randomize - High level may produce unnatural fingerprints
  3. Don't frequently switch templates - Appears as abnormal behavior
  4. Don't ignore errors - Connection failures may indicate detection

πŸ› οΈ Troubleshooting

Connection Rejected

Cause: Fingerprint detected as abnormal

Solution:

// Try different template .with_template(BrowserTemplate::Firefox135) // Adjust randomization .with_randomization_level(RandomizationLevel::Medium) // Clear cache .with_cache(false)

Performance Degradation

Cause: High randomization or cache disabled

Solution:

// Lower randomization .with_randomization_level(RandomizationLevel::Light) // Enable cache .with_cache(true)

πŸ“ˆ Roadmap

  • Core browser templates (Chrome, Firefox, Safari, Edge)
  • Multi-phase hook system
  • Fingerprint caching
  • Comprehensive testing
  • Performance optimization
  • ECH (Encrypted Client Hello) support
  • Post-quantum cryptography hooks
  • QUIC ClientHello customization
  • Additional browser templates

🀝 Contributing

Contributions are welcome! Please see CONTRIBUTING.md for guidelines.

πŸ“„ License

custls is distributed under the same licenses as rustls:

  • Apache License version 2.0 (LICENSE-APACHE)
  • MIT license (LICENSE-MIT)
  • ISC license (LICENSE-ISC)

You may use this software under the terms of any of these licenses, at your option.

πŸ™ Acknowledgments

custls is built on top of rustls, an excellent TLS library created and maintained by:

  • Joe Birr-Pixton (@ctz, Project Founder)
  • Dirkjan Ochtman (@djc, Co-maintainer)
  • Daniel McCarney (@cpu, Co-maintainer)
  • Josh Aas (@bdaehlie, Project Management)

Special thanks to the rustls team for creating such a solid foundation.

πŸ“ž Support

⚠️ Disclaimer

custls is designed for legitimate use cases such as web scraping, testing, and security research. Users are responsible for ensuring their use complies with applicable laws and terms of service.


custls - Browser-level TLS fingerprint simulation for Rust

Built with ❀️ on top of rustls

About

Custls is a fork of rustls, designed to enhance TLS client fingerprinting resistance while preserving the original library's strong security guarantees, minimal configuration needs, and memory-safe Rust implementation.

Resources

License

Unknown and 3 other licenses found

Licenses found

Unknown
LICENSE
Apache-2.0
LICENSE-APACHE
ISC
LICENSE-ISC
MIT
LICENSE-MIT

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages

  • Rust 98.6%
  • Other 1.4%