tcproxy 0.1.1

A TCP proxy for PostgreSQL connections with SSH tunnel support and runtime target switching
Documentation

TCP Proxy for PostgreSQL

A high-performance TCP proxy that forwards PostgreSQL connections to different target databases (including SSH-tunneled connections) based on runtime target selection.

Why Use tcproxy?

This tool solves the common problem of switching between different PostgreSQL environments (local, staging, production) without having to update multiple service configurations. Instead of changing connection strings across your applications, you point them all to the proxy and switch targets at the proxy level.

Quick Start

1. Installation

Option 1: Install from crates.io (Recommended)

cargo install tcproxy

2. Initialize Configuration

# Generate a default configuration file
tcproxy init-config

# Or specify a custom location
tcproxy init-config --output my-config.yaml

3. Configure Your Targets

Edit the generated config.yaml:

proxy:
  listen_port: 5433
  listen_host: "127.0.0.1"
  max_connections: 1000

targets:
  local:
    host: "localhost"
    port: 5432
    
  production:
    host: "prod-db.internal"
    port: 5432
    ssh:
      enabled: true
      host: "bastion.example.com"
      user: "dbuser"
      key_file: "/path/to/your/private-key.pem"
      port: 22
      auto_reconnect: true
      max_reconnect_attempts: 5
      
  staging:
    host: "staging-db.internal"
    port: 5432
    ssh:
      enabled: true
      host: "staging-bastion.example.com"
      user: "dbuser"
      key_file: "/path/to/staging-key.pem"

connection_management:
  health_check_interval_seconds: 30
  health_check_timeout_seconds: 5
  max_consecutive_failures: 3

4. Start the Proxy

# Start with local target
tcproxy start --target local

# Start with production target
tcproxy start --target production

# Override default port
tcproxy start --target local --port 5434

# Override default host
tcproxy start --target local --host 0.0.0.0

5. Connect Your Applications

Update your application connection strings to point to the proxy:

# Instead of connecting directly to different databases:
# postgresql://user:pass@localhost:5432/db          # local
# postgresql://user:pass@prod-db.internal:5432/db   # production

# Connect to the proxy:
postgresql://user:pass@localhost:5433/db

Usage Examples

Basic Commands

# Validate your configuration
tcproxy validate-config

# Show current configuration
tcproxy show-config

# List all available targets
tcproxy list-targets

# Check health of all targets
tcproxy health-check

# Check health of specific target
tcproxy health-check --target production

# Enable debug logging
tcproxy --log-level debug start --target local

# Enable JSON logging for structured logs
tcproxy --json-logs start --target production

Configuration Examples

Simple Local Setup

proxy:
  listen_port: 5433
  listen_host: "127.0.0.1"

targets:
  local:
    host: "localhost"
    port: 5432

Production Setup with SSH Tunnel

proxy:
  listen_port: 5433
  listen_host: "127.0.0.1"
  max_connections: 500

targets:
  production:
    host: "10.0.1.100"  # Internal database IP
    port: 5432
    ssh:
      enabled: true
      host: "bastion.example.com"
      user: "deploy"
      key_file: "/home/deploy/.ssh/production.pem"
      port: 22
      timeout_seconds: 30
      auto_reconnect: true
      reconnect_interval_seconds: 30
      max_reconnect_attempts: 5
      reconnect_backoff_multiplier: 2.0
    connection_pool:
      max_size: 20
      timeout_seconds: 30

connection_management:
  health_check_interval_seconds: 60
  health_check_timeout_seconds: 10
  max_consecutive_failures: 3
  retry_delay_seconds: 5

Multi-Environment Setup

proxy:
  listen_port: 5433
  listen_host: "127.0.0.1"

targets:
  local:
    host: "localhost"
    port: 5432
    
  development:
    host: "dev-db.internal"
    port: 5432
    ssh:
      enabled: true
      host: "dev-bastion.example.com"
      user: "developer"
      key_file: "/path/to/dev-key.pem"
      
  staging:
    host: "staging-db.internal"
    port: 5432
    ssh:
      enabled: true
      host: "staging-bastion.example.com"
      user: "deploy"
      key_file: "/path/to/staging-key.pem"
      
  production:
    host: "prod-db.internal"
    port: 5432
    ssh:
      enabled: true
      host: "prod-bastion.example.com"
      user: "deploy"
      key_file: "/path/to/prod-key.pem"

Configuration Reference

Proxy Section

  • listen_port: Port for the proxy to listen on (default: 5433)
  • listen_host: Host interface to bind to (default: "127.0.0.1")
  • max_connections: Maximum concurrent connections (default: 1000)

Target Section

  • host: Target PostgreSQL host
  • port: Target PostgreSQL port
  • ssh: SSH tunnel configuration (optional)
  • connection_pool: Connection pool settings

SSH Configuration

  • enabled: Enable/disable SSH tunnel
  • host: SSH bastion host
  • user: SSH username
  • key_file: Path to SSH private key
  • port: SSH port (default: 22)
  • timeout_seconds: SSH connection timeout (default: 30)
  • auto_reconnect: Enable automatic reconnection (default: true)
  • reconnect_interval_seconds: Time between reconnection attempts (default: 30)
  • max_reconnect_attempts: Maximum reconnection attempts (default: 5)
  • reconnect_backoff_multiplier: Backoff multiplier for reconnection (default: 2.0)

Connection Management

  • health_check_interval_seconds: Interval between health checks (default: 30)
  • health_check_timeout_seconds: Health check timeout (default: 5)
  • max_consecutive_failures: Max failures before marking target unhealthy (default: 3)
  • retry_delay_seconds: Delay between retry attempts (default: 5)

Logging

tcproxy provides comprehensive structured logging:

# Set log level
tcproxy --log-level debug start --target local

# Enable JSON logging for log aggregation
tcproxy --json-logs start --target production

# Available log levels: trace, debug, info, warn, error

Health Monitoring

Built-in health monitoring helps ensure your targets are available:

# Check all targets
tcproxy health-check

# Check specific target
tcproxy health-check --target production

# Health checks run automatically in the background
# Configure intervals in the connection_management section

Development

Running Tests

# Run unit tests
cargo test

# Run integration tests (requires PostgreSQL)
cargo test --test integration_tests

# Run PostgreSQL-specific tests
cargo test --test postgresql_integration

Building

# Debug build
cargo build

# Release build
cargo build --release

# Run with cargo
cargo run -- start --target local

Command Reference

tcproxy [OPTIONS] [COMMAND]

Commands:
  start            Start the proxy server
  init-config      Generate a default configuration file
  validate-config  Validate configuration file
  show-config      Show current configuration
  list-targets     List available targets
  health-check     Check health status of targets

Options:
  -c, --config <CONFIG>        Configuration file path [default: config.yaml]
  -l, --log-level <LOG_LEVEL>  Log level (trace, debug, info, warn, error) [default: info]
      --json-logs              Enable JSON logging format
  -h, --help                   Print help
  -V, --version                Print version

Start Command Options:
  -t, --target <TARGET>        Target to proxy to (required)
  -p, --port <PORT>           Override listen port
      --host <HOST>           Override listen host

License

MIT License - see LICENSE file for details.

Contributing

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