SSH Tunneling Guide
SSH Tunneling Guide
Section titled “SSH Tunneling Guide”DBCrust provides powerful SSH tunneling capabilities that make connecting to databases behind firewalls and in secure environments seamless. This guide covers everything from basic setup to advanced configurations.
🔒 Why SSH Tunneling?
Section titled “🔒 Why SSH Tunneling?”SSH tunneling allows you to securely connect to databases that are:
- Behind corporate firewalls
- In private networks or VPCs
- Requiring jump host access
- In production environments with restricted access
Benefits:
- ✅ Secure: All traffic encrypted through SSH
- ✅ Automatic: Set up once, works transparently
- ✅ Pattern-based: Configure rules that apply automatically
- ✅ Multiple protocols: Works with all database types
🚀 Quick Start
Section titled “🚀 Quick Start”Manual SSH Tunnel
Section titled “Manual SSH Tunnel”For one-time connections, use the --ssh-tunnel flag:
# Basic SSH tunneldbcrust postgres://user:pass@internal-db.company.com/myapp \ --ssh-tunnel jumphost.company.com
# With SSH user and portdbcrust postgres://user:pass@internal-db.company.com/myapp \ --ssh-tunnel admin@jumphost.company.com:2222
# With SSH keydbcrust postgres://user:pass@internal-db.company.com/myapp \ --ssh-tunnel admin@jumphost.company.com \ --ssh-key ~/.ssh/production_keyAutomatic Pattern Matching
Section titled “Automatic Pattern Matching”Configure automatic tunnels in your config file for seamless connections:
[ssh_tunnel_patterns]# Pattern → SSH target"^db\\.internal\\..*\\.com$" = "jumphost.example.com"".*\\.private\\.net" = "admin@jumphost.example.com:2222""prod-.*\\.company\\.com" = "bastion.company.com:22"".*\\.rds\\.amazonaws\\.com$" = "ec2-bastion.company.com"Now connections automatically use tunnels:
# This automatically routes through jumphost.example.comdbcrust postgres://user:pass@db.internal.mycompany.com/prod
# This automatically routes through admin@jumphost.example.com:2222dbcrust mysql://user:pass@mysql.private.net/analytics🛠️ Configuration Options
Section titled “🛠️ Configuration Options”SSH Tunnel Patterns
Section titled “SSH Tunnel Patterns”Patterns use regular expressions to match database hostnames:
[ssh_tunnel_patterns]# Exact match"production-db.company.com" = "bastion.company.com"
# Wildcard patterns"^.*\\.internal\\.company\\.com$" = "jumphost.company.com"
# Multiple environments"dev-.*\\.company\\.com" = "dev-bastion.company.com""staging-.*\\.company\\.com" = "staging-bastion.company.com""prod-.*\\.company\\.com" = "prod-bastion.company.com"
# Cloud providers".*\\.rds\\.amazonaws\\.com$" = "ec2-bastion.us-west-2.amazonaws.com"".*\\.postgres\\.database\\.azure\\.com$" = "vm-bastion.westus2.cloudapp.azure.com"SSH Configuration
Section titled “SSH Configuration”DBCrust respects your SSH configuration (~/.ssh/config):
Host jumphost HostName jumphost.company.com User admin Port 2222 IdentityFile ~/.ssh/company_key ServerAliveInterval 60 ServerAliveCountMax 3
Host prod-bastion HostName bastion.prod.company.com User dbadmin IdentityFile ~/.ssh/prod_key ProxyJump jumphostThen use SSH config names in patterns:
[ssh_tunnel_patterns]"^prod-.*\\.company\\.com$" = "prod-bastion""^staging-.*\\.company\\.com$" = "jumphost"🎯 Real-World Examples
Section titled “🎯 Real-World Examples”Enterprise AWS Setup
Section titled “Enterprise AWS Setup”[ssh_tunnel_patterns]# Production RDS instances"^prod-.*\\.rds\\.amazonaws\\.com$" = "prod-bastion""^staging-.*\\.rds\\.amazonaws\\.com$" = "staging-bastion"
# Private subnet databases"^.*\\.vpc-internal\\.company\\.com$" = "vpc-bastion"Host prod-bastion HostName bastion.prod.company.com User ec2-user IdentityFile ~/.ssh/prod-access.pem
Host staging-bastion HostName bastion.staging.company.com User ec2-user IdentityFile ~/.ssh/staging-access.pemUsage:
# Automatically tunnels through prod-bastiondbcrust postgres://app_user@prod-main.rds.amazonaws.com/myapp
# Automatically tunnels through staging-bastiondbcrust postgres://app_user@staging-replica.rds.amazonaws.com/myappMulti-Hop SSH Connections
Section titled “Multi-Hop SSH Connections”For environments requiring multiple jumps:
Host jump1 HostName first-jump.company.com User admin IdentityFile ~/.ssh/company_key
Host jump2 HostName second-jump.internal User admin IdentityFile ~/.ssh/internal_key ProxyJump jump1
Host database-host HostName db.deep-internal.company.com User dbuser ProxyJump jump2[ssh_tunnel_patterns]"^db\\.deep-internal\\.company\\.com$" = "database-host"Django Production Setup
Section titled “Django Production Setup”Perfect for Django teams accessing production databases:
[ssh_tunnel_patterns]# Django production databases"^django-prod\\..*" = "prod-bastion""^django-staging\\..*" = "staging-bastion"
# Analytics databases"^analytics\\..*" = "data-bastion"Django management commands work seamlessly:
# These automatically tunnel through appropriate bastionspython manage.py dbcrust --database defaultpython manage.py dbcrust --database analytics🔧 Advanced Features
Section titled “🔧 Advanced Features”Port Forwarding Configuration
Section titled “Port Forwarding Configuration”DBCrust automatically manages local ports, but you can configure the range:
[ssh_tunnel]local_port_range_start = 5000local_port_range_end = 5999bind_address = "127.0.0.1" # DefaultConnection Pooling with Tunnels
Section titled “Connection Pooling with Tunnels”When using connection pooling, tunnels are shared efficiently:
[performance]enable_connection_pooling = truepool_max_connections = 5
[ssh_tunnel]reuse_connections = true # Default: trueconnection_timeout = 30 # secondsTunnel Health Monitoring
Section titled “Tunnel Health Monitoring”DBCrust monitors tunnel health and automatically reconnects:
[ssh_tunnel]health_check_interval = 30 # secondsmax_reconnect_attempts = 3reconnect_delay = 5 # seconds🚨 Troubleshooting
Section titled “🚨 Troubleshooting”Common Issues
Section titled “Common Issues”Connection Refused
Section titled “Connection Refused”# Test SSH connection manuallyssh -v jumphost.company.com
# Test with specific user/portssh -v admin@jumphost.company.com -p 2222
# Test key authenticationssh -v -i ~/.ssh/company_key admin@jumphost.company.comPermission Denied
Section titled “Permission Denied”# Check SSH key permissionschmod 600 ~/.ssh/your_key
# Check SSH config permissionschmod 644 ~/.ssh/config
# Verify key is loaded in SSH agentssh-add ~/.ssh/your_keyTimeout Issues
Section titled “Timeout Issues”# Increase timeouts in config[ssh_tunnel]connection_timeout = 60health_check_interval = 60
[performance]connection_timeout = 60Pattern Matching Problems
Section titled “Pattern Matching Problems”Test your regex patterns:
# Enable debug logging to see pattern matchingdbcrust --debug postgres://db.internal.company.com/testDebug output shows:
DEBUG: Testing SSH pattern '^db\.internal\..*\.com$' against 'db.internal.company.com'DEBUG: Pattern matched! Using SSH tunnel: jumphost.company.comDEBUG: Creating SSH tunnel: db.internal.company.com:5432 -> jumphost.company.com -> localhost:5001Debug Mode
Section titled “Debug Mode”Enable detailed SSH debugging:
# Full debug outputdbcrust --debug postgres://internal-db/myapp --ssh-tunnel jumphost.com
# SSH-specific debuggingexport DBCRUST_SSH_DEBUG=1dbcrust postgres://internal-db/myapp --ssh-tunnel jumphost.comLogging
Section titled “Logging”SSH tunnel operations are logged:
[logging]level = "debug"file_output = truefile_path = "~/.config/dbcrust/dbcrust.log"Log output includes:
2024-01-15 14:30:00 DEBUG [ssh_tunnel] Creating tunnel: db.company.com:5432 -> bastion.company.com -> localhost:50012024-01-15 14:30:01 DEBUG [ssh_tunnel] Tunnel established successfully2024-01-15 14:30:01 DEBUG [ssh_tunnel] Health check passed🛡️ Security Best Practices
Section titled “🛡️ Security Best Practices”SSH Key Management
Section titled “SSH Key Management”# Generate dedicated keys for database accessssh-keygen -t ed25519 -C "dbcrust-access" -f ~/.ssh/dbcrust_key
# Use different keys for different environmentsssh-keygen -t ed25519 -C "prod-db-access" -f ~/.ssh/prod_db_keyssh-keygen -t ed25519 -C "staging-db-access" -f ~/.ssh/staging_db_keyPrinciple of Least Privilege
Section titled “Principle of Least Privilege”Configure jump hosts with minimal permissions:
- SSH access only (no shell access)
- Specific port forwarding rules
- Time-limited access tokens
Audit Logging
Section titled “Audit Logging”Enable comprehensive logging for compliance:
[logging]level = "info" # Log all tunnel creation/destructionfile_output = truefile_path = "/var/log/dbcrust/dbcrust.log"
[ssh_tunnel]log_connections = true # Log each tunnel establishmentlog_disconnections = true # Log tunnel closures🔗 Integration Examples
Section titled “🔗 Integration Examples”CI/CD Pipelines
Section titled “CI/CD Pipelines”# GitHub Actions example- name: Setup SSH tunnel for database tests run: | # Configure SSH key mkdir -p ~/.ssh echo "${{ secrets.SSH_PRIVATE_KEY }}" > ~/.ssh/ci_key chmod 600 ~/.ssh/ci_key
# Add SSH config cat >> ~/.ssh/config << EOF Host ci-bastion HostName bastion.ci.company.com User ci-user IdentityFile ~/.ssh/ci_key ServerAliveInterval 60 EOF
# Run tests through tunnel dbcrust postgres://test@prod-replica.company.com/testdb \ --ssh-tunnel ci-bastion \ --query "SELECT version()"Docker Compose
Section titled “Docker Compose”version: '3.8'services: app: build: . volumes: - ~/.ssh:/root/.ssh:ro - ~/.config/dbcrust:/root/.config/dbcrust:ro environment: - DATABASE_URL=postgres://user@prod-db.company.com/app # DBCrust automatically uses SSH tunnel based on patternsTeam Configurations
Section titled “Team Configurations”Share SSH tunnel patterns across your team:
# Store in version controlgit add .dbcrust/ssh-patterns.toml
# Team members can importcp .dbcrust/ssh-patterns.toml ~/.config/dbcrust/📚 See Also
Section titled “📚 See Also”- Configuration Reference - Complete configuration options
- Security Guide - Security best practices
- Vault Integration - Dynamic credentials with Vault
- URL Schemes - All supported connection methods