Skip to content

Conversation

@DiegoDAF
Copy link

@DiegoDAF DiegoDAF commented Dec 5, 2025

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 user@bastion.example.com -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

When using SSH tunnels, PostgreSQL's .pgpass file was not being used
because the connection was using '127.0.0.1' as the hostname instead
of the original database hostname.

This change preserves the original hostname using PostgreSQL's host/
hostaddr parameters:
- host: original database hostname (used for .pgpass lookup and SSL)
- hostaddr: 127.0.0.1 (actual connection endpoint via SSH tunnel)

Additionally:
- Fix connect_uri() to pass DSN parameter for proper .pgpass handling
- Add SSH tunnel configuration options:
  - ssh_config_file: Use ~/.ssh/config for host settings
  - allow_agent: Enable SSH agent for authentication
  - compression: Disabled for better performance
- Preserve hostaddr parameter when using DSN connections in pgexecute

Benefits:
- .pgpass file now works seamlessly with --ssh-tunnel option
- No need to manually enter passwords when using SSH tunnels
- Maintains security by using standard PostgreSQL authentication
- SSL certificate verification uses correct hostname

Example:
  # .pgpass entry: production.db.example.com:5432:mydb:user:password
  pgcli --ssh-tunnel user@bastion.example.com -h production.db.example.com -d mydb
  # Now automatically uses .pgpass for authentication

Made with ❤️ and 🤖 Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant