Releases: davlgd/wisegate
Releases · davlgd/wisegate
Release list
v0.12.0
Security
- X-Real-IP spoofing: Strip any client-supplied
X-Real-IPheader before processing so the upstream only ever sees the value wisegate computed. - Authorization leakage: When wisegate has performed authentication, the
Authorizationheader is now stripped before forwarding. Opt back in withCC_FORWARD_AUTH_HEADER=true(orAuthenticationProvider::forward_authorization_header()in the library) when the upstream genuinely needs the credentials. - IPv6 rate-limit bypass: Extracted IPs are canonicalised (RFC 5952), so
2001:0db8::1and2001:db8::1now key the same rate-limit bucket. Blocked/allowed IP lists are also matched on canonical form, so non-canonical IPv6 spellings in config still apply.
Added
wisegate_core::DefaultConfig: ready-to-use struct implementing every configuration trait with the same defaults as the CLI, so library users can drop wisegate-core in without trait boilerplate.- Startup warnings: warn when
CC_REVERSE_PROXY_IPScontains the bind sentinel0.0.0.0, and when wisegate listens on0.0.0.0with no auth and no IP blocklist (a common open-proxy misconfiguration). - Full env-var reference in
--help: every recognised variable is now listed, grouped by purpose (proxy security / filtering / rate limiting / authentication / proxy behaviour). CC_FORWARD_AUTH_HEADERenv var to opt into upstream Authorization forwarding.
Changed
- Library example: README and
wisegate-corecrate docs now showcase theDefaultConfigpath instead of the 5-trait implementation snippet. ConnectionTracker::track(): returnsimpl Dropinstead of the concreteConnectionGuard; binary callers only ever depended on the drop side anyway.- Doc:
request_handler::handle_requestrustdoc now spells out the Tokio runtime requirement, the permissive-mode header-trust caveat, and that strict mode requires bothX-Forwarded-ForandForwardedheaders (theby=field is what gets matched against the proxy allowlist).
Refactored
ip_filter: deduplicated the canonical-IP equality path into a privateips_matchhelper and dropped the deadis_valid_ip_formatwrapper.
Full Changelog: v0.11.0...v0.12.0
v0.11.0
Added
- Sliding window log algorithm: True sliding window rate limiting replacing the fixed window approach
Fixed
- Content-Length pre-check: Check body size before buffering to prevent memory exhaustion
- Hop-by-hop header filtering: Filter on request path per RFC 7230
- URL pattern bypass: Case-insensitive URL pattern blocking to prevent bypass
- Bearer token prefix: Case-insensitive
Bearerprefix per RFC 6750 - WWW-Authenticate header: Sanitize realm value to prevent header injection
- Credential masking: Mask auth credentials and tokens in verbose log output
Performance
- Zero-copy body forwarding: Pass
Bytesdirectly to reqwest body instead ofto_vec() - Hop-by-hop comparison: Case-insensitive comparison without allocation
- Method/pattern filtering: Reduce allocations in method and URL pattern filtering
- url_decode: Byte-based iteration avoiding String allocation per hex pair
- Blocked patterns: Pre-normalize to lowercase at config load time
- forward_host: Use
Arc<str>to avoid per-connectionString::clone
Refactored
- RateLimiter: Unified state into single
Mutex, encapsulated internals, moved cleanup state per-instance - Client IP: Replace sentinel string with
Option<String> - ConnectionGuard: RAII guard with saturating decrement
- Config caching: Replace
once_cell::Lazywithstd::sync::LazyLock - ConfigProvider: Use trait consistently instead of standalone getters
- Header constants: Use constants instead of magic strings in IP filter and request handler
- Test infrastructure: Merge
AuthTestEnvironmentintoTestEnvironmentwith builder pattern - Error types: Remove unused error variants
- Defaults: Remove redundant constant aliases, use defaults module directly
- Method matching: Simplify HTTP method matching in request forwarding
- Rate limiter locking: Eliminate nested locking in cleanup path
- Dead code cleanup: Remove unused
Resulttype alias, builder methods, and consolidate redundant tests - Clippy warnings: Fix
collapsible_if,expect_fun_call, andmanual_containsin integration tests
Documentation
- Fix request flow order in README to match implementation
- Fix library examples, document
TRUSTED_PROXY_IPS_VARwhitelist - Remove unsupported CIDR notation from proxy IPs example
Full Changelog: v0.10.0...v0.11.0
v0.10.0
What's Changed
Added
- Authentication integration tests: 9 new tests covering Basic Auth, Bearer Token, and combined authentication scenarios
- defaults module: Centralized default configuration values in
wisegate-core/src/defaults.rs(DRY principle)
Changed
- request_handler: Now uses
WiseGateErrorfor consistent error handling throughout the pipeline - test_utils: Uses centralized defaults module for configuration values
Full Changelog: v0.9.0...v0.10.0
v0.9.0
Added
- HTTP Basic Authentication (RFC 7617): Protect your endpoints with username/password
- Support for multiple password formats: plain text, bcrypt, APR1 MD5, SHA1
- Constant-time comparison to prevent timing attacks
- Multiple users via
CC_HTTP_BASIC_AUTH_Nenvironment variables - Configurable realm via
CC_HTTP_BASIC_AUTH_REALM
- Bearer Token Authentication (RFC 6750): API key authentication
- Simple token-based authentication via
CC_BEARER_TOKEN - Constant-time comparison to prevent timing attacks
- Can be used alone or combined with Basic Auth (either method accepted)
- Simple token-based authentication via
- auth module: New
wisegate-core/src/auth/module with:Credentialsstruct for credential storagehash::verify()for multi-format password verificationhash::constant_time_eq()for secure comparisoncheck_basic_auth()for request authenticationcheck_bearer_token()for bearer token verification
- AuthenticationProvider trait: Configuration trait for authentication settings
bearer_token()method for bearer token accessis_basic_auth_enabled()andis_bearer_auth_enabled()helpers
- New environment variables:
CC_HTTP_BASIC_AUTH,CC_HTTP_BASIC_AUTH_N,CC_HTTP_BASIC_AUTH_REALM,CC_BEARER_TOKEN - New error types:
AuthenticationRequired,InvalidCredentials - New headers:
AUTHORIZATION,WWW_AUTHENTICATEconstants - 51 new tests: Comprehensive coverage for auth module
Changed
- Request pipeline now includes authentication check after method blocking, before rate limiting
ConfigProvidertrait now requiresAuthenticationProviderimplementation- Startup info displays authentication status (Basic Auth and Bearer Token)
Full Changelog: v0.8.0...v0.9.0
v0.8.0
What's Changed
Added
- wisegate-core crate: Extracted reusable library for embedding in other projects
- ConfigProvider trait: Dependency injection for configuration, enabling library reuse
- EnvVarConfig: Default implementation reading from environment variables
- WiseGateError: Custom error type with HTTP status mapping and user-friendly messages
- HTTP header constants: Centralized in
headers.rswithis_hop_by_hop()helper - ConnectionTracker: Track active connections for graceful shutdown
- ConnectionLimiter: Semaphore-based connection limiting with permit management
- Shared TestConfig: Centralized test configuration in
test_utils.rsmodule - Comprehensive unit tests: 220 tests covering all modules
Refactored
- Workspace structure: Split into
wisegate(CLI) andwisegate-core(library) - ip_filter: Accepts
ConfigProviderinstead of global config - rate_limiter: Accepts
ConfigProviderinstead of global config - request_handler: Accepts
ConfigProviderand HTTP client, uses centralizedheaders::is_hop_by_hop() - main.rs: Uses
ConnectionTrackerandConnectionLimiterfor cleaner connection management
Removed
- test-local.py: Removed redundant Python test script (replaced by Rust integration tests)
- Duplicated TestConfig: Consolidated into shared
test_utils.rsmodule - Duplicated is_hop_by_hop: Now uses centralized function from
headers.rs
Full Changelog: v0.7.2...v0.8.0
v0.7.2
Added
- ConfigProvider trait: Dependency injection for configuration, enabling library reuse
- EnvVarConfig: Default implementation reading from environment variables
Refactored
- ip_filter: Accepts
ConfigProviderinstead of global config - rate_limiter: Accepts
ConfigProviderinstead of global config - request_handler: Accepts
ConfigProviderinstead of global config - main: Uses
EnvVarConfigfor dependency injection
Full Changelog: v0.7.1...v0.7.2
v0.7.1
Refactored
- NewType RateLimiter: Replaced type alias with proper struct for better encapsulation
- RateLimitEntry struct: Named fields instead of tuple for clearer code
- StartupConfig: Decoupled
server.rsfrom CLIArgsstruct - IP validation:
validate()now returns parsedIpAddrto avoid double parsing
Full Changelog: v0.7.0...v0.7.1
v0.7.0
What's Changed
Added
- Structured logging:
tracingwith JSON support (--json-logs) - Graceful shutdown: SIGINT/SIGTERM handling with 30s connection drain
- Connection limiting:
MAX_CONNECTIONSenv var with semaphore-based limiting - HTTP connection pooling: Reusable client with 32 connections per host
- Configuration caching:
once_cell::Lazyfor zero-overhead config access - Library structure: Extracted
lib.rsfor better testability and reuse - Complete rustdoc: All public functions documented with examples
Enhanced
- Performance:
opt-level = 3(2x faster than"z", +0.8MB) - Dependencies: Updated to latest versions (tokio 1.49, reqwest 0.13, clap 4.5.54)
- Documentation: Simplified README
Full Changelog: v0.6.1...v0.7.0
v0.6.1
v0.6.0
✨ New Features
- CLI Short Flags:
-l,-f,-v,-qfor better UX - Quiet Mode:
--quietfor production deployments (minimal output) - Verbose Mode:
--verboseshows full config + environment variables - Enhanced Help: Comprehensive CLI help with environment variable docs
🔧 Enhanced Functionality
- Better Error Handling: Replaced panics with graceful error handling
- Improved Validation: Configuration validation with fallback to defaults
- Security Enhancements: Better hop-by-hop header filtering
🧹 Code Quality
- Simplified Architecture: Removed experimental streaming modes
- Better Organization: Centralized defaults and cleaner separation
- Type Safety: Enhanced validation and error propagation
Full Changelog: v0.5.0...v0.6.0