jackc / jackc/pgx

Connecting via SSH fails to resolve host

Open
#1,724 3 comments 0 reactions 0 assignees View on GitHub
bug
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

Open the contributing 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.