Note: The primary documentation for Dito will be migrated to an mdBook format. Please be patient 🙂
<img src="https://img.shields.io/badge/status-active-green.svg" alt="Status">
<img src="https://img.shields.io/badge/release-0.7.0-green.svg" alt="Release">
<img src="https://img.shields.io/badge/license-Apache2-blue.svg" alt="License">
<img src="https://img.shields.io/badge/language-Go-blue.svg" alt="Language">
<img src="https://github.com/andrearaponi/dito/raw/0.7.5/dito.png" alt="Dito Logo">
Dito is an advanced, highly extensible reverse proxy server written in Go. It features a robust plugin-based architecture, custom certificate handling for backend connections, dynamic configuration reloading, and more. Plugins can manage their own dependencies and provide custom middleware functionality.
dito/
├── cmd/ # Entry points (main application & plugin-signer)
├── app/ # Core application logic
├── config/ # Configuration loader & hot-reload
├── handlers/ # Request routing & proxy handlers
├── middlewares/ # Built-in middlewares (plugins can add more)
├── plugin/ # Plugin loading, signing, and verification
├── plugins/ # Example and community plugins
├── transport/ # HTTP transport customization
├── websockets/ # WebSocket support
├── writer/ # Custom response writers
├── logging/ # Logging utilities
└── metrics/ # Prometheus metrics collection
Ensure you have Go (>= 1.21) and make installed.
# Clone repo
git clone https://github.com/andrearaponi/dito.git && cd dito
# One-command setup & start
make quick-start
This will: 1. Build all binaries (Dito & plugin-signer) 2. Generate Ed25519 keys 3. Build & sign plugins 4. Update config with correct paths & hashes 5. Start the Dito server
# 1. Clone repo
git clone https://github.com/andrearaponi/dito.git && cd dito
# 2. Setup (build, keys, plugins, config)
make setup
# 3. Start server
make run
| Category | Command | Description |
|---|---|---|
| 🚀 Quick | quick-start |
Clean, setup everything and start (recommended) |
setup |
Full setup (build, keys, plugins, config) | |
run |
Start the Dito server | |
| 🔨 Build | build |
Build Dito binary only |
build-plugins |
Build all plugins | |
build-plugin-signer |
Build plugin-signer tool | |
| 🔑 Security | generate-keys |
Generate Ed25519 key pair |
sign-plugins |
Sign all plugins | |
update-config |
Update config paths & key hashes | |
| 🔍 Debug | debug-config |
Debug configuration issues |
help |
Show all commands | |
| 🧹 Cleanup | clean |
Remove all build artifacts |
clean-plugins |
Clean plugin binaries only | |
| 🧪 Development | test |
Run tests |
vet |
Run go vet | |
fmt |
Format code |
Build Dito:
bash
go build -o bin/dito ./cmd/dito/main.go
(Note: Ensure the path to main.go is correct, e.g., ./cmd/dito/main.go if main.go is in cmd/dito/)
Build plugin-signer:
bash
cd cmd/plugin-signer && go build -o ../../bin/plugin-signer . && cd ../..
Generate keys:
bash
./bin/plugin-signer generate-keys
(This will create keys in the current directory, presumably bin/ if run from there, or the project root. Move them to bin/ if needed or specify paths)
Build plugins:
bash
find plugins -mindepth 1 -maxdepth 1 -type d -exec sh -c 'cd "$1" && go build -buildmode=plugin -o "$(basename "$1").so"' sh {} \;
Sign plugins:
bash
find plugins -name "*.so" -exec ./bin/plugin-signer sign {} \;
(Ensure plugin-signer can find the private keys; you might need to specify -privateKey path/to/key)
Update config.yaml (ensure public_key_path & public_key_hash are correct).
Run Dito:
bash
./bin/dito
Start with default config:
make run
Or directly:
./bin/dito -f /path/to/custom-config.yaml -enable-profiler
cmd/config.yaml (or the correct path to your template)bin/config.yaml (auto-updated by make setup or make quick-start)Key fields:
port: '8081'
hot_reload: true
metrics:
enabled: true
path: "/metrics"
logging:
enabled: true
verbose: false
level: "info"
plugins:
directory: "./plugins" # Relative to where Dito is run, or absolute path
public_key_path: "./ed25519_public.key" # Relative to where Dito is run, or absolute path
public_key_hash: "<SHA256_HASH>" # The SHA256 hash of the public key
transport:
http:
idle_conn_timeout: 90s
max_idle_conns: 1000
max_idle_conns_per_host: 200
max_conns_per_host: 0
tls_handshake_timeout: 2s
response_header_timeout: 2s
expect_continue_timeout: 500ms
disable_compression: false
dial_timeout: 2s
keep_alive: 30s
force_http2: true
locations:
- path: "^/test-ws$"
target_url: "wss://echo.websocket.org"
enable_websocket: true
replace_path: true
- path: "^/dito$"
target_url: "https://httpbin.org/get"
replace_path: true
transport:
http:
disable_compression: true
additional_headers:
X-Custom: "true"
excluded_headers:
- Cookie
middlewares:
- hello-plugin # Plugin name as defined in its directory
Dito provides flexible response body size limits that can be configured both globally and per location to prevent memory issues and control resource usage.
Set default limits for all locations in the main configuration:
# Global response limits configuration
response_limits:
max_response_body_size: 100000 # 100KB default limit for all locations
Override global limits for specific locations with custom settings:
locations:
- path: "^/api/small"
target_url: "https://api.example.com"
max_response_body_size: 1024 # 1KB limit for this specific endpoint
disable_response_buffering: false # Enable response buffering (default)
- path: "^/api/large"
target_url: "https://api.example.com"
max_response_body_size: 52428800 # 50MB limit for large responses
disable_response_buffering: true # Disable buffering for streaming
413 Request Entity Too Large status code when limits are exceededContent-Length header before processing to fail fastWhen a response exceeds the configured limit, Dito returns a standardized JSON error:
{
"error": {
"code": 413,
"message": "Response body size exceeds limit",
"details": {
"limit_bytes": 90,
"path": "/api/endpoint"
}
}
}
The disable_response_buffering option controls how responses are handled:
false (default): Responses are buffered in memory before sending to clientEnables proper error handling when limits are exceeded
true: Responses are streamed directly to client
Dito uses Go plugins (.so files). Each plugin must:
1. Be in its own subdirectory under plugins/.
2. Contain:
* <plugin-name>.so
* <plugin-name>.so.sig (signature file)
* config.yaml (plugin-specific config, optional but common)
Steps (if done manually):
1. Generate key pair:
bash
./bin/plugin-signer generate-keys -privateKey ed25519_private.key -publicKey ed25519_public.key
(Save these keys securely, e.g., in bin/ or a dedicated directory)
Compute public key hash:
bash
shasum -a 256 ed25519_public.key | awk '{print $1}'
(Ensure the path to ed25519_public.key is correct)
Update Dito's config.yaml with public_key_path (e.g., ./bin/ed25519_public.key) and the computed public_key_hash.
Sign plugin:
bash
./bin/plugin-signer sign -plugin path/to/plugin.so -privateKey path/to/ed25519_private.key
(This will create a .sig file next to the plugin's .so file)
public key integrity validation failed: Regenerate hash and update config. Ensure the hash exactly matches the specified public key file.failed to read public key: Check public key file path in config.yaml & file permissions.plugin signature verification failed: Re-sign with correct private key. Ensure public key in config.yaml matches the private key used for signing.This allows for fine-grained control over how Dito connects to backend services, including:
Dito supports WebSocket proxying, allowing you to seamlessly forward WebSocket connections to your backend servers. This can be configured per location, enabling WebSocket support on specific routes.
To enable WebSocket support, add enable_websocket: true to the location configuration. Here’s an example:
# List of location configurations for proxying requests.
locations:
- path: "^/test-ws$" # Regex pattern to match the request path.
target_url: "wss://echo.websocket.org" # The target URL to which the request will be proxied.
enable_websocket: true # Enable WebSocket support for this location.
replace_path: true # Replace the matched path with the target URL.
Future versions of Dito will include more advanced WebSocket features, such as:
These features aim to provide full control, security, and reliability for WebSocket connections in Dito, enhancing the overall communication experience.
Dito supports mTLS (mutual TLS) for secure connections to backends. You can specify:
cert_file: The