# 🛡️ WiseGate
A high-performance, secure reverse proxy written in Rust with built-in rate limiting and IP filtering capabilities.
## ✨ Features
- **🚀 Ultra-Fast**: ~2MB binary (1 MB after upx)
- **🔒 Secure**: Validates load balancer headers and enforces proxy IP allowlists
- **📊 Rate Limiting**: Per-IP rate limiting with configurable sliding windows
- **🚫 IP Filtering**: Block malicious IPs with environment-based configuration
- **🚫 HTTP Method Filtering**: Block specific HTTP methods (GET, POST, PUT, etc.)
- **🛡️ URL Pattern Blocking**: Block requests containing specific patterns (e.g., `.ext`, `/path/to/block`)
- **🌐 Real IP Extraction**: Correctly extracts client IPs from `x-forwarded-for` and `forwarded` headers
- **⚙️ Zero Dependencies**: Statically compiled binary with no external runtime requirements
## 🎯 Use Cases
- **API Gateway**: Rate limiting and IP filtering for REST APIs
- **DDoS Protection**: Basic protection against IP-based attacks
- **Microservices Security**: Add security layer to existing services without code changes
- **Load Balancer Backend**: Perfect for services behind a load balancers like Clever Cloud's [Sōzu](https://sozu.io)
## 🚀 Quick Start
### Installation
#### Install via Cargo (Recommended)
```bash
cargo install wisegate
```
#### Download Binary
```bash
# Adapt the URL for your platform
wget https://github.com/davlgd/wisegate/releases/latest/download/wisegate-linux-x64
chmod +x wisegate-linux-x64
sudo mv wisegate-linux-x64 /usr/local/bin/wisegate
```
#### Build from Source
```bash
git clone https://github.com/davlgd/wisegate.git
cd wisegate
cargo build --release
sudo cp target/release/wisegate /usr/local/bin/
```
### Basic Usage
```bash
# Optional: Set allowed proxy IPs (enables strict IP validation)
export CC_REVERSE_PROXY_IPS="192.168.1.100,10.0.0.1"
# Start the proxy
wisegate --listen 8080 --forward 9000
```
Your service is now protected! Requests will be forwarded from port 8080 to port 9000 with added security.
## ⚙️ Configuration
All configuration is done via environment variables:
### Proxy Security Configuration
| `CC_REVERSE_PROXY_IPS` | *(Optional)* Comma-separated list of allowed proxy/load balancer IPs. When set, enables strict header validation. | `"192.168.1.1,10.0.0.1"` |
| `TRUSTED_PROXY_IPS_VAR` | *(Optional)* Name of alternative environment variable to use instead of `CC_REVERSE_PROXY_IPS` | `"MY_COMPANY_PROXY_IPS"` |
**Note**: When neither `CC_REVERSE_PROXY_IPS` nor an alternative variable is configured, WiseGate runs in permissive mode where proxy IP validation is disabled. This allows requests without proper reverse proxy headers but maintains other security features.
### Optional Configuration
| `BLOCKED_IPS` | _(none)_ | Comma-separated list of blocked client IPs |
| `BLOCKED_METHODS` | _(none)_ | Comma-separated list of blocked HTTP methods (returns 405) |
| `BLOCKED_PATTERNS` | _(none)_ | Comma-separated list of URL patterns to block (returns 404) |
| `RATE_LIMIT_REQUESTS` | `100` | Maximum requests per time window |
| `RATE_LIMIT_WINDOW_SECS` | `60` | Time window in seconds for rate limiting |
| `PROXY_TIMEOUT_SECS` | `30` | Timeout for upstream requests in seconds |
| `MAX_BODY_SIZE_MB` | `100` | Maximum request body size in MB (0 = unlimited) |
| `ENABLE_STREAMING` | `true` | Enable streaming mode for better memory usage |
### Configuration Examples
#### Strict Mode
```bash
# Proxy IP validation and full security features
export CC_REVERSE_PROXY_IPS="192.168.1.100,10.0.0.1,172.16.0.1"
export BLOCKED_IPS="192.168.1.200,malicious.ip.here"
export BLOCKED_METHODS="PUT,DELETE,PATCH"
export BLOCKED_PATTERNS=".yaml,.php,matomo"
export RATE_LIMIT_REQUESTS=100
export RATE_LIMIT_WINDOW_SECS=60
wisegate --listen 8080 --forward 9000
```
#### Custom Alternative Variable
```bash
# Use custom environment variable name for proxy IPs
export TRUSTED_PROXY_IPS_VAR="MY_PROXY_IPS"
export MY_PROXY_IPS="192.168.1.100,10.0.0.1"
export BLOCKED_METHODS="PUT,DELETE,PATCH"
wisegate --listen 8080 --forward 9000
```
#### Permissive Mode (Basic Security)
```bash
# No proxy IP validation - only method and pattern filtering
export BLOCKED_METHODS="PUT,DELETE,PATCH"
export BLOCKED_PATTERNS=".yaml,.php,matomo"
wisegate --listen 8080 --forward 9000
```
## 🔍 How It Works
### Security Model
WiseGate operates in two modes depending on configuration:
**All modes provide:**
- **HTTP Method Filtering**: Blocks requests using blacklisted HTTP methods (returns 405)
- **URL Pattern Filtering**: Blocks URLs containing configured patterns (returns 404)
#### Permissive Mode (when no proxy IPs are configured)
Additionally provides:
- **Best-Effort IP Extraction**: Attempts to extract client IP from available headers
- **Limited IP Features**: IP filtering and rate limiting are disabled when client IP cannot be determined
- **Conditional Header Injection**: Adds `X-Real-IP` header only when client IP is available
#### Strict Mode (when proxy IPs are configured)
Additionally provides:
- **Header Validation**: Requires both `x-forwarded-for` and `forwarded` headers
- **Proxy Authentication**: Validates the proxy IP (from `by=` field) against allow list
- **Real IP Extraction**: Extracts actual client IP from forwarded headers
- **IP Filtering**: Blocks requests from blacklisted IPs
- **Rate Limiting**: Applies per-IP rate limiting with sliding windows
- **Header Injection**: Adds `X-Real-IP` header for upstream services
### Request Flow
```
Client → Load Balancer → WiseGate → Your Service
↓
✅ Validate headers (strict mode)
✅ Check Trusted Proxy IPs allowlist (strict mode)
✅ Check HTTP methods
✅ Check URL patterns
✅ Extract real client IP (if detected)
✅ Check IP blocklist (if IP is detected)
✅ Apply rate limiting (if IP is detected)
✅ Add X-Real-IP header (if IP is detected)
```
### Example Headers
**Incoming request:**
```http
x-forwarded-for: client.ip, proxy.ip, 203.0.113.1
forwarded: for=203.0.113.1:45678;by=192.168.1.100;proto=https
```
**Forwarded request:**
```http
x-forwarded-for: client.ip, proxy.ip, 203.0.113.1
forwarded: for=203.0.113.1:45678;by=192.168.1.100;proto=https
x-real-ip: 203.0.113.1
```
## ⚡ Performance Features
### Streaming Support
- **Automatic**: Enabled by default for better memory usage
- **Configurable**: Set `ENABLE_STREAMING=false` for legacy buffered mode
- **Memory Efficient**: Handles large files without loading entirely into RAM
### Request Timeouts
- **Configurable**: Set custom timeouts with `PROXY_TIMEOUT_SECS`
- **Default**: 30 seconds timeout for upstream requests
- **Reliability**: Prevents hanging connections
### Body Size Limits
- **Flexible**: Configure maximum request body size
- **Protection**: Prevents memory exhaustion from large uploads
- **Streaming Mode**: More lenient limits when streaming is enabled
## 🤝 Contributing
Contributions are welcome!
- **Issues**: [GitHub Issues](https://github.com/davlgd/wisegate/issues)
- **Discussions**: [GitHub Discussions](https://github.com/davlgd/wisegate/discussions)
### Development Setup
1. Install Rust
2. Clone the repository
3. Make your changes
4. Add tests for new functionality
5. Submit a pull request
### Building
```bash
# Debug build
cargo build
# Optimized release build
cargo build --release
# Cross-compilation for different targets
cargo build --release --target x86_64-unknown-linux-musl
```
### Testing
```bash
# Run tests
cargo test
# Integration testing (Strict Mode)
export CC_REVERSE_PROXY_IPS="127.0.0.1"
./target/release/wisegate --listen 8080 --forward 3000 &
curl -H "x-forwarded-for: 203.0.113.1" \
-H "forwarded: by=127.0.0.1" \
http://localhost:8080/
# Integration testing (Permissive Mode)
unset CC_REVERSE_PROXY_IPS
./target/release/wisegate --listen 8081 --forward 3001 &
curl http://localhost:8081/
```
## 📁 Project Structure
The project follows Rust best practices with a modular architecture for maintainability and clarity:
```
src/
├── main.rs # Entry point and server logic
├── args.rs # Command line argument parsing
├── types.rs # Common types and type aliases
├── env_vars.rs # Environment variable constants
├── config.rs # Configuration management
├── ip_filter.rs # IP validation and filtering logic
├── rate_limiter.rs # Rate limiting implementation
├── request_handler.rs # HTTP request processing
└── server.rs # Server utilities and startup info
```
### Module Responsibilities
- **`main.rs`**: Application entry point, server setup, and connection handling
- **`args.rs`**: CLI argument definitions using Clap
- **`types.rs`**: Shared type definitions (RateLimitConfig, RateLimiter)
- **`env_vars.rs`**: Centralized environment variable names
- **`config.rs`**: Environment variable parsing and configuration loading
- **`ip_filter.rs`**: IP validation, header parsing, and blocking logic
- **`rate_limiter.rs`**: Sliding window rate limiting implementation
- **`request_handler.rs`**: HTTP request/response processing and forwarding
- **`server.rs`**: Startup banner and server utility functions
This modular structure ensures each component has a single responsibility, making the codebase easy to understand, test, and maintain.
## 📝 License
This project is licensed under the Apache License 2.0 - see the [LICENSE](LICENSE) file for details.
## 🏆 Acknowledgments
- Built with [Hyper](https://hyper.rs/) for HTTP handling
- [Tokio](https://tokio.rs/) for async runtime
- [Clap](https://clap.rs/) for CLI parsing
- [Reqwest](https://docs.rs/reqwest/) for HTTP client functionality
- Inspired by the need for a lightweight, simple, secure proxy
---
**Made with ❤️ and ⚡ for the Open Source Community**