camo-rs
A high-performance SSL image proxy written in Rust. This is a Rust implementation of Camo, inspired by go-camo.
Camo proxies insecure HTTP images over HTTPS, preventing mixed content warnings on secure pages.
Features
- HMAC-SHA1 URL signing - Compatible with the original Camo
- Dual URL format - Query string (
/<digest>?url=...) and path-based (/<digest>/<encoded_url>) - Dual encoding - Supports both hex and base64 URL encoding
- Content-Type filtering - Whitelist for image types, optional video/audio support
- Size limits - Configurable maximum content length (default 5MB)
- Redirect following - Configurable redirect limit (default 4)
- SSRF protection - Blocks requests to private/internal networks (RFC1918)
- Prometheus metrics - Optional
/metricsendpoint - Structured logging - Built with tracing
Installation
As a library
Add to your Cargo.toml:
[]
= { = "https://github.com/AprilNEA/camo-rs" }
From source
The binary will be at target/release/camo-rs.
Cargo Features
| Feature | Default | Description |
|---|---|---|
client |
Yes | Core URL signing functionality with minimal dependencies |
server |
No | Full proxy server with CLI, metrics, and all dependencies |
# Client only (minimal dependencies: hmac, sha1, hex, base64)
[]
= { = "https://github.com/AprilNEA/camo-rs" }
# Server (includes tokio, axum, reqwest, etc.)
[]
= { = "https://github.com/AprilNEA/camo-rs", = ["server"] }
Library Usage
use ;
// Create a CamoUrl generator with your secret key
let camo = new;
// Sign a URL
let signed = camo.sign;
// Get the full proxy URL
let url = signed.to_url;
// => https://camo.example.com/abc123.../68747470...
// Or just the path
let path = signed.to_path;
// => /abc123.../68747470...
// Use base64 encoding instead of hex
let url = camo.sign
.base64
.to_url;
// Set default encoding
let camo = new.with_encoding;
// Convenience function
let url = sign_url;
// Verify a digest
assert!;
Usage
Start the server
# Using environment variable
CAMO_KEY=your-secret-key
# Using CLI argument
# With custom options
Generate signed URLs
# Generate URL components
# Output:
# Digest: 54cec8e46f18f585268e3972432cd8da7aec6dc1
# Encoded URL: 68747470733a2f2f6578616d706c652e636f6d2f696d6167652e706e67
# Path: /54cec8e46f18f585268e3972432cd8da7aec6dc1/68747470...
# Generate full URL
# Output: https://camo.example.com/54cec8e46f18f585268e3972432cd8da7aec6dc1/68747470...
# Use base64 encoding
URL Formats
The proxy accepts two URL formats:
# Path format
https://camo.example.com/<digest>/<hex-encoded-url>
# Query string format
https://camo.example.com/<digest>?url=<url-encoded-url>
Configuration
| Option | Environment Variable | Default | Description |
|---|---|---|---|
-k, --key |
CAMO_KEY |
(required) | HMAC key for URL signing |
--listen |
CAMO_LISTEN |
0.0.0.0:8080 |
Listen address |
--max-size |
CAMO_LENGTH_LIMIT |
5242880 |
Maximum content length in bytes |
--max-redirects |
CAMO_MAX_REDIRECTS |
4 |
Maximum redirects to follow |
--timeout |
CAMO_SOCKET_TIMEOUT |
10 |
Socket timeout in seconds |
--allow-video |
CAMO_ALLOW_VIDEO |
false |
Allow video content types |
--allow-audio |
CAMO_ALLOW_AUDIO |
false |
Allow audio content types |
--block-private |
CAMO_BLOCK_PRIVATE |
true |
Block private networks (RFC1918) |
--metrics |
CAMO_METRICS |
false |
Enable /metrics endpoint |
--log-level |
CAMO_LOG_LEVEL |
info |
Log level (trace/debug/info/warn/error) |
Integration
Generate URLs in your application
JavaScript/Node.js:
const crypto = require;
const url = ;
Python:
=
=
return f
=
Rust:
use ;
use Sha1;
Endpoints
| Path | Description |
|---|---|
/ |
Health check, returns "OK" |
/health |
Health check, returns "OK" |
/metrics |
Prometheus metrics (if enabled) |
/<digest>/<encoded_url> |
Proxy endpoint (path format) |
/<digest>?url=<url> |
Proxy endpoint (query format) |
Docker
FROM rust:1.83-alpine AS builder
WORKDIR /app
COPY . .
RUN cargo build --release
FROM alpine:latest
COPY --from=builder /app/target/release/camo-rs /usr/local/bin/
EXPOSE 8080
ENTRYPOINT ["camo-rs"]
License
MIT License
Credits
- atmos/camo - Original Camo implementation
- cactus/go-camo - Go implementation reference