Connecting via SSH fails to resolve host
- Dominant language
- Go
- Stars
- 14.3k
- Forks
- 1.1k
- Avg merge
- 6d 9h
- Merged PRs (30d)
- 11
Description
**Describe the bug**
When connecting to redshift with the pgx driver, if we use a ssh tunnel, but specify the hostname of the connection as a private DNS name (resolvable on ssh tunnel host, but not resolvable on the wider internet), the connection attempts will fail with
`lookup ****.*****.private (host) on 10.47.240.10:53: (ssh host + port) no such host`. This is not the case if we use the standard dbSql library to connect.
**To Reproduce**
Steps to reproduce the behavior:
create a route 53 hosted zone (e.g. name.private), for some vpc-123abc, and add a host record pointing to a redshift IP, e.g. redshift.name.private → 54.151.2.2
spin up an ec2 host in the above vpc, validate you can resolve redshift.name.private.
Use these credentials to connect to redshift over pgx via connectionConfig like this
```
type tunnel struct {
config *pgsshConfig
client *ssh.Client
}
func() connectionFunction() {
sshPort := uint16(22)
if config.SSHTunnel.Port != 0 {
sshPort = config.SSHTunnel.Port
}
tunnelHost := fmt.Sprintf("%s:%s", config.SSHTunnel.Host, fmt.Sprint(sshPort))
tunnelConfig := ssh.ClientConfig{
User: utils.SSHTunnelUser(),
Auth: getAuthMethods(),
HostKeyCallback: knownhosts.CertChecker.HostKeyFallback,
Timeout: time.Duration(config.MaxTimeoutSecs * int64(time.Second)),
}
tunnel := tunnel{config: &pgsshConfig{tunnelHost, tunnelConfig, mkPgxConnStr(config, tz)}}
pgxCfg, err := pgxpool.ParseConfig(mkPgxConnStr(config, tz))
if err != nil {
return nil, err
}
sshcon, err := ssh.Dial("tcp", tunnel.config.tunnelHost, &tunnel.config.tunnelConfig)
if err != nil {
return nil, err
}
pgxCfg.ConnConfig.DialFunc = func(ctx context.Context, network, addr string) (net.Conn, error) {
conn, err := sshcon.Dial(network, addr)
return conn, err
}
pool, err := pgxpool.ConnectConfig(ctx, pgxCfg)
if err != nil {
// This is where we see the error
}
...
}
```
**Expected behavior**
The connection should work without throwing any errors
**Actual behavior**
No such host error
**Version**
- Go: -> `go version go1.20.5 darwin/amd64`
- PostgreSQL: `NA
- pgx: `github.com/jackc/pgx/v4 v4.18.1`
**Additional context**
From looking at the `lookupHost` code in lookup_unix.go, it looks like the issue is that pgx tries to resolve the hostname of the server well before it tries to dial ssh which wont work if a caller would only be able to resolve the IP on the ssh host.
Related: https://github.com/jackc/pgx/issues/1661
Thank you!
Contributor guide
Research direction
Start with lookup_unix.go and the related issue #1661, then trace how pgx resolves the server hostname before invoking the configured DialFunc. Reproduce the supplied private-DNS SSH-tunnel case and verify that the connection succeeds when the hostname is resolvable only from the SSH host.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- go, postgresql
- Domain
- database, networking
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100