pgcli icon indicating copy to clipboard operation
pgcli copied to clipboard

Enable .pgpass support for SSH tunnel connections

Open DiegoDAF opened this issue 4 weeks ago • 0 comments

Summary

This PR enables PostgreSQL's .pgpass file to work seamlessly with SSH tunnel connections. Previously, when using --ssh-tunnel, the .pgpass file was not consulted because pgcli was connecting to 127.0.0.1 instead of the original database hostname.

Problem

When using SSH tunnels, the connection flow was:

  1. User specifies: --ssh-tunnel user@bastion --host production.db.com
  2. SSH tunnel created: 127.0.0.1:random_portproduction.db.com:5432
  3. pgcli connects to: 127.0.0.1:random_port
  4. .pgpass lookup fails (looking for 127.0.0.1 instead of production.db.com)

Solution

Use PostgreSQL's host/hostaddr parameter separation:

  • host: Original database hostname (for .pgpass lookup and SSL verification)
  • hostaddr: Actual connection endpoint 127.0.0.1 (SSH tunnel local port)

Changes

Core Functionality

  • Modified connect() to preserve original host and use hostaddr for tunnel
  • Updated connect_uri() to pass DSN parameter for proper .pgpass handling
  • Modified pgexecute.py to preserve hostaddr when using DSN connections

SSH Tunnel Enhancements

  • Added ssh_config_file: Use ~/.ssh/config for host settings
  • Added allow_agent: Enable SSH agent for authentication
  • Set compression: False: Better performance for database connections

Benefits

.pgpass file now works with SSH tunnels ✅ No manual password entry needed ✅ Standard PostgreSQL authentication flow ✅ SSL certificate verification uses correct hostname ✅ Maintains all existing functionality

Example Usage

# Setup .pgpass file
echo "production.db.example.com:5432:mydb:dbuser:secret_password" >> ~/.pgpass
chmod 600 ~/.pgpass

# Connect via SSH tunnel - password read from .pgpass automatically!
pgcli --ssh-tunnel [email protected] -h production.db.example.com -d mydb -U dbuser

Technical Details

PostgreSQL supports both host and hostaddr parameters:

  • When both are specified, host is used for authentication (.pgpass, Kerberos, SSL CN)
  • hostaddr is used for the actual TCP connection
  • This is perfect for SSH tunnels where we need different values for each

Compatibility

  • Fully backward compatible
  • No changes to non-SSH tunnel connections
  • Existing SSH tunnel connections continue to work
  • New functionality is transparent to users

Made with ❤️ and 🤖 Claude Code

DiegoDAF avatar Dec 05 '25 19:12 DiegoDAF