Skip to content

Tern is unable to find host accessible from SSH host #108

Description

@jackHedaya

Hi

Hope all is well!

I'm running the following command:

 tern migrate --conn-string ${CONN_STR} --password ${PASSWORD} --migrations ./db/migrations --ssh-host ${BASTION_PUBLIC_IP} --ssh-user ec2-user

and am getting the following:

Unable to connect to PostgreSQL:
  failed to connect to `host=... user=... database=...`: hostname resolving error (lookup <hostname>: no such host)

I am able to SSH into the host and then perform the DNS lookup successfully.

I suspect tern is performing the DNS lookup locally (where the host is inaccessible) as opposed to on the ssh machine (where the host is accessible).

Activity

  1. jackc commented on Sep 29, 2024

    @jackc
    Owner

    tern doesn't directly do the DNS lookup. It calls https://pkg.go.dev/golang.org/x/crypto/ssh#Client.Dial.

    However, it's possible that the underlying pgx connection is the culprit. It tries to resolve DNS before dialing because one hostname may resolve into multiple IP addresses and we may do some sort of fallback with them. It tries to match psql / libpq behavior. I suspect the same thing would happen if manually tunneling with psql and openssh.

    I'm not totally sure what the proper behavior would be. I guess it would be something like replacing https://pkg.go.dev/github.com/jackc/pgx/v5@v5.7.1/pgconn#Config the LookupFunc in the connection config with something that did the resolution remotely. But I'm not sure how to do a DNS lookup from the remote system.

  2. jackHedaya commented on Sep 29, 2024

    @jackHedaya
    Author

    Hmm I'm also having trouble finding a method of performing the DNS lookup on the remote machine in an OS agnostic manner.

    I did find a solution that works for my case:

    • Establish SSH tunnel with port forward
    ssh -fNM -S /tmp/ternsocket 5432:<host>:5432 ec2-user@bastion
    // Must wait for connection with pg ready
    
    • Run Tern locally
    tern migrate --conn-string <dbuser>@127.0.0.1:5432/<dbname> --password <password> --migrations ./db/migrations
    
    • Close connection
    ssh -S /tmp/ternsocket -O exit ec2-user@bastion
    

    Wondering if this could be generalized.

  3. jackc commented on Sep 30, 2024

    @jackc
    Owner

    I don't know. It would seem that sshd is doing the lookup there. Not sure how to hook into that.

  4. smainz commented on Nov 9, 2024

    @smainz
    Contributor

    Why don't you use an environment var for the IP in your connect string and do the lookup via ssh like this:

    IP_OF_DB_SERVER=$(ssh user@bastion dig +short <hostname_of_db_server> | head -n1)

    This will do an IP lookup on the bastion host and store the result in IP_OF_DB_SERVER on your local workstation.
    Now this can be used to construct the connect string or even easier set --host ${IP_OF_DB_SERVER} --port ...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions