A high-performance Unix socket reverse proxy for ArangoDB with configurable access control policies.
This project provides two proxy servers that sit between your application and ArangoDB's Unix socket, enabling:
- Read-only access control: Block all write operations at the proxy level
- Read-write access control: Allow document CRUD while blocking administrative operations
- HTTP/2 support: Full HTTP/2 over Unix sockets for improved performance
- AQL query inspection: Parse and validate AQL queries to block write operations
- Zero network overhead: Unix socket to Unix socket communication
┌─────────────┐ ┌──────────────┐ ┌─────────────────────────────┐
│ Application │────▶│ RO Proxy │────▶│ │
│ (Reader) │ │ (0640 perms) │ │ │
└─────────────┘ └──────────────┘ │ ArangoDB Unix Socket │
│ /run/arangodb3/arangodb.sock│
┌─────────────┐ ┌──────────────┐ │ │
│ Application │────▶│ RW Proxy │────▶│ │
│ (Writer) │ │ (0600 perms) │ │ │
└─────────────┘ └──────────────┘ └─────────────────────────────┘
# Clone the repository
git clone https://github.com/r3d91ll/arango-unix-proxy.git
cd arango-unix-proxy
# Build both proxies
make build
# Or build individually
go build -o bin/roproxy ./cmd/roproxy
go build -o bin/rwproxy ./cmd/rwproxygo install github.com/r3d91ll/arango-unix-proxy/cmd/roproxy@latest
go install github.com/r3d91ll/arango-unix-proxy/cmd/rwproxy@latestThe read-only proxy blocks all write operations:
# Using defaults
./bin/roproxy
# Custom socket paths
LISTEN_SOCKET=/tmp/arango-ro.sock \
UPSTREAM_SOCKET=/run/arangodb3/arangodb.sock \
./bin/roproxyAllowed operations:
GET,HEAD,OPTIONS- All pathsPOSTto/_api/cursor- Read-only AQL queries onlyPUT,DELETEto/_api/cursor/*- Cursor management
Blocked AQL keywords: INSERT, UPDATE, UPSERT, REMOVE, REPLACE, TRUNCATE, DROP
The read-write proxy allows document operations:
# Using defaults
./bin/rwproxy
# Custom socket paths
LISTEN_SOCKET=/tmp/arango-rw.sock \
UPSTREAM_SOCKET=/run/arangodb3/arangodb.sock \
./bin/rwproxyAdditional allowed operations (beyond read-only):
POSTto/_api/document,/_api/import,/_api/collection,/_api/indexPUT,PATCH,DELETEto/_api/document,/_api/collection,/_api/index
All configuration is done via environment variables:
| Variable | Default | Description |
|---|---|---|
LISTEN_SOCKET |
/run/arango-proxy/readonly.sock (RO) or /run/arango-proxy/readwrite.sock (RW) |
Path for the proxy socket |
UPSTREAM_SOCKET |
/run/arangodb3/arangodb.sock |
Path to ArangoDB's Unix socket |
PROXY_CLIENT_TIMEOUT_SECONDS |
120 |
HTTP client timeout (0 to disable) |
PROXY_DIAL_TIMEOUT_SECONDS |
10 |
Socket connection timeout |
Example service files are provided in the examples/systemd/ directory:
# Install service files
sudo cp examples/systemd/*.service /etc/systemd/system/
sudo systemctl daemon-reload
# Enable and start
sudo systemctl enable --now arango-roproxy
sudo systemctl enable --now arango-rwproxy- Read-only socket:
0640- Group-readable for application users - Read-write socket:
0600- Owner-only in production
The proxies implement defense-in-depth:
- Method filtering: Only allowed HTTP methods pass through
- Path filtering: Only allowed API paths are accessible
- AQL inspection: Query bodies are parsed to detect write keywords
- Fallback scanning: Raw body scanning for keyword detection
- Run each proxy as a dedicated service user
- Use Unix groups to control socket access
- Place sockets in a dedicated runtime directory
- Monitor proxy logs for blocked requests
You can embed the proxy in your own Go application:
package main
import (
"log"
"net/http"
proxy "github.com/r3d91ll/arango-unix-proxy"
)
func main() {
// Create a custom allow function
customAllow := func(r *http.Request, peek proxy.BodyPeeker) error {
// Your custom logic here
return proxy.AllowReadOnly(r, peek)
}
// Create the proxy
p := proxy.NewUnixReverseProxy(
"/run/arangodb3/arangodb.sock",
customAllow,
)
// Use it as an http.Handler
http.Handle("/", p)
}The proxy adds minimal overhead:
- Latency: < 0.2ms p50 overhead
- Throughput: Limited only by ArangoDB and system resources
- Memory: ~10MB per proxy instance
- HTTP/2: Multiplexed connections reduce overhead
# Run tests
go test -v ./...
# Run with race detector
go test -race ./...
# Build for multiple platforms
make build-all
# Clean build artifacts
make cleanMIT License - see LICENSE for details.
Contributions are welcome! Please feel free to submit a Pull Request.