Closed yuqingm7 closed 1 year ago
First, just to confirm, did you want to be using host-based auth here? That's a relatively rarely used feature compared to username/password or public key based auth.
The problem seems to occur when it is trying to determine a client hostname to use. I'm not sure why the sockaddr wouldn't have been set by the time auth begins. That should be set by the asyncio code when the connection is made. Is there anything unusual about how you are opening the TCP connection? Are you letting asyncssh.connect()
do this, or are you trying to do something with a jump host or proxy command?
If needed, you can specify the client host explicitly using the client_host
argument when you connect. You'll need this to be set to something that the remote system would recognize and trust. If you do that, it shouldn't need to get the client_host from the sockname. You just need to make sure the client host is something the remote system recognizes and trusts.
I just noticed you said "via proxy" above. Could you say a bit more about what kind of proxy you are using? I suspect that's the problem -- if the sockname information isn't being filled in, you'd see the problem you reported here.
Hi @ronf!
Thank you for your quick response!
did you want to be using host-based auth here? That's a relatively rarely used feature compared to username/password or public key based auth.
This is a good question! Yeah, publickey based and pwd based auth are heavily used. HostbasedAuthentication
is configured on server side in sshd_config
. We could probably enforce password based authentication in the future for this machine, but still I'd love to understand why this error happens.
Could you say a bit more about what kind of proxy you are using?
The proxy itself is an internal tool provided by other folks. I don't really have a deep understanding other than it supports HTTP/HTTPs/SOCKS proxy. The code snippet is
options = asyncssh.SSHClientConnectionOptions(
client_factory=lambda: _SSHClient(self),
username=username,
password=self.pw if self.pw else None,
client_keys=[(privkey, cert)] if not self.pw else None,
known_hosts=None,
x509_trusted_certs=None,
proxy_command=proxy_command,
)
self.conn = await asyncio.wait_for(
asyncssh.connect(
host=self.hostip if self.hostip else self.host,
port=self.port,
options=options,
),
timeout=conn_timeout,
)
If I use ssh -o "ProxyCommand=<proxy_cmd>" hostname
, it prompts for password. I can log into the machine with the password. So I'm a bit curious if it makes sense in asyncssh to at least catch the exceptions raised in host-based authN part and try other preferred authN methods. Thanks a lot!
Yeah - I should probably automatically disable host-based auth when the connection doesn't have 'sockname' available, such as in the case where proxy_command is used and AsyncSSH can only see a pipe to the proxy process rather than a TCP socket it can query the address of, unless client_host
is set manually by the caller. I'll look into this.
As a workaround for now, you should be able to explicitly set host_based_auth=False
in your asyncssh.connect()
call or when creating theSSHClientConnectionOptions
. You should only need this if you were on a system where client host keys were available.
Thanks for the report!
I have a potential fix for this in commit 1469ac9 in the "develop" branch, if you'd like to give it a try.
Hi @ronf, thank you so much for your quick fix. Yeah, we're planning to go with host_based_auth=False
or preferred_auth="keyboard-interactive"
for now. Thanks!
Happy to help!
The fix mentioned here is now available in AsyncSSH 2.13.2.
Hi experts!
I'm using asyncssh to connect to remote hosts via proxy, which gives me the
Connection failure: getnameinfo() argument 1 must be a tuple
.Dug a little, the failure comes from host_based_auth piece. The stacktrace is
Dug a bit deeper, this is caused by the fact that
self.get_extra_info('sockname')
returnsNone
.Wondering if anyone could help me debug this issue. Thanks a lot!