Skip to content

A modern forward proxy with blocklist management for your home network. Named after the squid relative, this is a spiritual successor to traditional Squid proxy setups.

Notifications You must be signed in to change notification settings

josephmc5/calamari

Repository files navigation

Calamari 🦑

A modern forward proxy with blocklist management for your home network. Named after the squid relative, this is a spiritual successor to traditional Squid proxy setups.

Features

  • Forward HTTP/HTTPS Proxy: Domain-based blocking without TLS inspection
  • Public Blocklist Support: Integrates with popular blocklists (OISD, Steven Black, etc.)
  • In-Memory Domain Cache: O(1) blocked domain lookups with zero database overhead on the hot path
  • Modern Web UI: No-build-step SPA using Preact and HTM (ES modules from CDN)
  • Client Management: Track and label devices by IP address with request statistics
  • Client Groups: Organize clients into logical groups
  • Manual Blocking: Add custom domain blocks with optional reasons
  • Traffic Logging: Track all requests with filtering by status, domain, IP, and date range
  • Domain Discovery: Track domains that have never been seen on the network before
  • Real-time Activity: Server-Sent Events (SSE) stream for live request monitoring
  • Statistics: View proxy usage stats, block rates, weekly trends, and top blocked domains
  • Auto-Updates: Automatically fetch and update blocklists on a schedule
  • Event-Driven Architecture: Async event bus for decoupled request processing
  • SQLite Database: Lightweight storage behind a repository interface

Comparison to existing tools

Most open-source proxies focus on either raw forwarding, content filtering, or developer-oriented inspection. Calamari sits in a different niche: a modern forward proxy designed for home networks that combines blocklist management, high-performance in-memory decision making, and built-in reporting to turn raw traffic into meaningful insight. The comparison below shows how Calamari relates to several well-known proxy projects and highlights where its emphasis on usability and analytics sets it apart.

Project Forward Proxy Blocklist Support HTTPS Support Reporting & Analytics Web UI Caching Notes
Calamari ✅ Domain-based HTTP/HTTPS ✅ Public + custom ✅ No TLS MITM ✅ Rich reporting (site visits, stats) ✅ Multi-page SPA ❌ No caching Modern UX + reporting focus
Squid ⚠️ ACLs/filtering via config/plugins ✅ (SSL/TLS) ⚠️ Logs only (no built-in analytics) ✅ Advanced caching Classic proxy with ACLs; reporting relies on log tools (Wikipedia)
Privoxy ⚠️ Filtering rules (ads/tracking) ⚠️ HTTPS inspection w/ config ⚠️ Browser config/status page only Focus on privacy/filtering, not analytics (Wikipedia)
mitmproxy ⚠️ via scripts/addons ⚠️ HTTPS MITM/interception ⚠️ Session view in UI ✅ Web/console UI Developer/analysis tool, not home proxy (mitmproxy)
dumbproxy ⚠️ Scriptable filters (JS) ✅ (via scripting) ⚠️ DNS cache Lightweight forward proxy w/ some filtering (Reddit)

Technology Stack

Backend

  • Go 1.22+: Main language with clean architecture pattern
  • chi v5: Lightweight, fast HTTP router
  • SQLite + sqlx: Embedded database with repository pattern
  • go-playground/validator v10: Request validation
  • Server-Sent Events (SSE): Real-time activity streaming

Frontend

  • Preact 10: React-like components (3kb gzipped)
  • HTM: JSX alternative using template literals
  • ES Modules: Direct browser imports from esm.sh CDN
  • No Build Step: Zero bundling, zero transpiling—just open and edit
  • Vanilla CSS: Custom styles, no framework

The frontend architecture is unique: all dependencies are loaded as ES modules directly from CDN, and HTM provides JSX-like syntax without any compilation. This means you can edit the UI by simply modifying /web/static/app.js and refreshing the browser—no npm scripts, no webpack, no build pipeline.

⚠️ Some Mobile Apps May Not Work Through Calamari

Some modern mobile apps (e.g., Instagram, Facebook, TikTok, YouTube) may not function correctly when routed through Calamari. This is not a bug in Calamari but a limitation of how many mobile apps are designed to communicate over the network. These apps often rely on certificate pinning, HTTP/2/HTTP/3 (QUIC over UDP), and assumptions about making direct TLS connections to their servers. A traditional forward proxy—even without TLS interception—alters the connection path in ways these apps are not built to tolerate.

Browsers and standard desktop clients are designed to work behind proxies, but many mobile apps explicitly expect a direct internet connection and may fail, hang, or behave unpredictably when a proxy is present. This is a well-known limitation of forward proxies in modern networks and one reason consumer filtering tools often rely on DNS-level blocking instead of HTTP/HTTPS proxying.

Quick Start

Using Docker (Recommended)

git clone https://github.com/josephmc5/calamari.git
cd calamari

docker compose up -d
docker compose logs -f

Building from Source

go mod tidy
make build
./calamari -data ./data

Or run directly:

make run

The proxy will be available at:

  • Proxy Server: http://localhost:8080
  • Web UI: http://localhost:3000

Configuration

Configure your devices to use the proxy:

Browser (Firefox Example)

  1. Settings → Network Settings → Manual proxy configuration
  2. HTTP Proxy: localhost Port: 8080
  3. HTTPS Proxy: localhost Port: 8080
  4. No proxy for: localhost, 127.0.0.1

Test Browser

Launch an isolated Chrome instance pre-configured with the proxy:

make test-browser

# Custom port
make test-browser PORT=9090

Or run the scripts directly: scripts/test-browser.bat (Windows) or scripts/test-browser.sh (Linux/Mac).

System-wide (Linux)

export http_proxy=http://localhost:8080
export https_proxy=http://localhost:8080

System-wide (Windows)

netsh winhttp set proxy localhost:8080

Web UI

Access the web interface at http://localhost:3000. The UI is a modern single-page app built with Preact and HTM, requiring no build step—all components are loaded as ES modules directly from CDN.

Dashboard (#/)

  • Overview stats: total requests, blocked count, block rate, blocklist entries
  • Weekly trend chart (allowed vs blocked)
  • Top blocked domains
  • New domains widget (recently discovered domains with stats)
  • Real-time activity feed (Server-Sent Events)

Network Menu

Monitor and analyze network activity:

Clients (#/clients)

  • View all devices that have made requests through the proxy
  • Track each client by IP address with optional labels
  • See request counts, blocked counts, and first/last seen timestamps
  • Filter and search by IP or label
  • Edit client labels for easier identification

Requests (#/requests)

  • Full request log table with filters (all, blocked only, allowed only)
  • Filter by domain, IP address, and date range
  • Adjustable result limit (50–500)
  • Top 20 blocked domains
  • Pagination support for large datasets

Domains (#/domains)

  • Track domains that have never been seen on the network before
  • Stats: total discovered, discovered today, discovered this week, blocked at discovery
  • Filter by domain, device IP, date range, and blocked status
  • Useful for detecting malware, new apps, unusual telemetry, or investigating unknown domains

Settings Menu

Configuration and management pages:

Blocklists (#/blocklists)

  • Add/remove/enable/disable blocklist sources
  • Trigger manual updates
  • Add/remove manual domain blocks with optional reasons
  • Configure blocklist update frequency

Client Groups (#/client-groups)

  • Create logical groups to organize clients
  • Assign clients to groups for easier management
  • Track group statistics

Log Management (#/log-management)

  • Configure log retention period
  • Set cleanup frequency and schedule
  • Trigger manual log cleanup

Default Blocklists

Calamari seeds two popular blocklists on first run:

  • OISD Big: Comprehensive blocklist covering ads, trackers, and malware
  • Steven Black: Unified hosts file with adware and malware domains

Supported Blocklist Formats

  • Hosts file format (0.0.0.0 domain.com or 127.0.0.1 domain.com)
  • Domain lists (one domain per line)
  • AdBlock format (||domain.com^)

Command Line Options

calamari [options]

Options:
  -data string
        Path to data directory (default "./data")
  -proxy-port string
        Proxy server port (default "8080")
  -web-port string
        Web UI port (default "3000")

Architecture

Request Flow

Client Request
  → Proxy Server (port 8080)
    → DomainChecker.IsBlocked()     ← in-memory map lookup, O(1)
    → EventBus.Publish(RequestLog)  ← non-blocking publish to event bus
    → Forward or block

Event Bus (buffered channel, async workers)
  → LogSink                         ← write to database
  → StatsSink                       ← update daily statistics
  → BroadcastSink                   ← send to SSE subscribers (real-time UI)
  → DiscoverySink                   ← record new domains

Event-Driven Architecture

The proxy handler is decoupled from downstream processing via an internal event bus. This ensures the hot path (domain lookup and forwarding) remains fast while request logging, statistics updates, and real-time broadcasting happen asynchronously in background workers.

Benefits:

  • Handler only does proxying + single Publish() call (non-blocking)
  • Easy to add new event sinks without touching proxy code
  • Graceful shutdown drains pending events
  • Configurable buffer size and worker count

Cache Lifecycle

The in-memory domain set is rebuilt from the database whenever blocklists or manual blocks change (add, remove, toggle, update). This keeps lookups fast while ensuring the cache stays consistent.

Data Persistence

All data is stored in the ./data directory:

  • calamari.db: SQLite database with all proxy data

This directory is mounted as a volume in Docker to persist data across container restarts.

Development

Makefile Targets

# Build and run
make build          # Build binary
make run            # Run from source
make tidy           # go mod tidy
make dev            # Run with live reload (requires air)

# Testing
make test           # Run all Go tests
make test-unit      # Run Go unit tests only (fast, -short flag)
make test-verbose   # Run Go tests with verbose output
make test-coverage  # Generate coverage report (coverage.html)
make test-race      # Run Go tests with race detector

make test-ui        # Run JavaScript unit tests (Vitest)
make test-ui-watch  # Run Vitest in watch mode
make test-ui-coverage # Generate JS test coverage report

make test-e2e       # Run end-to-end tests (Playwright)
make test-e2e-ui    # Run Playwright in interactive UI mode
make test-e2e-headed # Run Playwright with visible browser
make test-e2e-smoke # Run smoke tests only

make test-all       # Run both Go and JS unit tests

# Docker
make docker-build   # Build Docker image
make docker-up      # Start container
make docker-down    # Stop container
make docker-logs    # Tail container logs

# Utilities
make test-browser   # Launch isolated Chrome with proxy configured

Testing

Calamari uses a comprehensive testing strategy:

Go Backend Tests:

  • Handler tests use httptest
  • Repository tests use in-memory SQLite (:memory:)
  • Run with make test or make test-unit for fast feedback

JavaScript Unit Tests (Vitest):

  • Test pure functions, component calculations, and state logic
  • Fast, watch-mode friendly
  • Requires Node.js 18+ (brew install node, then npm install)

End-to-End Tests (Playwright):

  • Full-stack integration testing
  • Tests pages, API integration, SSE, and multi-page workflows
  • Runs in Chromium, Firefox, and WebKit
  • Auto-starts test server
  • Requires: npx playwright install

Running Tests:

# Go tests
make test                    # All Go tests
make test-coverage           # With coverage report

# JS unit tests
make test-ui                 # Run once
make test-ui-watch           # Watch mode for development

# E2E tests
make test-e2e                # All browsers
make test-e2e-ui             # Interactive mode (recommended for debugging)
make test-e2e-headed         # See browser while running

# Everything
make test-all                # Go + JS unit tests

Building for Production

CGO_ENABLED=1 go build -ldflags="-s -w" -o calamari ./cmd/calamari

License

MIT License - See LICENSE file for details

Contributing

Contributions welcome! Please open an issue or PR.

About

A modern forward proxy with blocklist management for your home network. Named after the squid relative, this is a spiritual successor to traditional Squid proxy setups.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published