Skip to content

r3d91ll/arango-unix-proxy

Repository files navigation

arango-unix-proxy

A high-performance Unix socket reverse proxy for ArangoDB with configurable access control policies.

Overview

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

Architecture

┌─────────────┐     ┌──────────────┐     ┌─────────────────────────────┐
│ Application │────▶│  RO Proxy    │────▶│                             │
│  (Reader)   │     │ (0640 perms) │     │                             │
└─────────────┘     └──────────────┘     │  ArangoDB Unix Socket       │
                                         │  /run/arangodb3/arangodb.sock│
┌─────────────┐     ┌──────────────┐     │                             │
│ Application │────▶│  RW Proxy    │────▶│                             │
│  (Writer)   │     │ (0600 perms) │     │                             │
└─────────────┘     └──────────────┘     └─────────────────────────────┘

Installation

From Source

# 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/rwproxy

Go Install

go install github.com/r3d91ll/arango-unix-proxy/cmd/roproxy@latest
go install github.com/r3d91ll/arango-unix-proxy/cmd/rwproxy@latest

Usage

Read-Only Proxy

The 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/roproxy

Allowed operations:

  • GET, HEAD, OPTIONS - All paths
  • POST to /_api/cursor - Read-only AQL queries only
  • PUT, DELETE to /_api/cursor/* - Cursor management

Blocked AQL keywords: INSERT, UPDATE, UPSERT, REMOVE, REPLACE, TRUNCATE, DROP

Read-Write Proxy

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/rwproxy

Additional allowed operations (beyond read-only):

  • POST to /_api/document, /_api/import, /_api/collection, /_api/index
  • PUT, PATCH, DELETE to /_api/document, /_api/collection, /_api/index

Configuration

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

Systemd Integration

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

Security Considerations

Socket Permissions

  • Read-only socket: 0640 - Group-readable for application users
  • Read-write socket: 0600 - Owner-only in production

Access Control

The proxies implement defense-in-depth:

  1. Method filtering: Only allowed HTTP methods pass through
  2. Path filtering: Only allowed API paths are accessible
  3. AQL inspection: Query bodies are parsed to detect write keywords
  4. Fallback scanning: Raw body scanning for keyword detection

Recommendations

  1. Run each proxy as a dedicated service user
  2. Use Unix groups to control socket access
  3. Place sockets in a dedicated runtime directory
  4. Monitor proxy logs for blocked requests

Using as a Library

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)
}

Performance

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

Development

# Run tests
go test -v ./...

# Run with race detector
go test -race ./...

# Build for multiple platforms
make build-all

# Clean build artifacts
make clean

License

MIT License - see LICENSE for details.

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 2

  •  
  •