Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

sss_ssh_knownhostsproxy ignores the -4/-6 ssh option #5690

Closed
gerases opened this issue Jun 17, 2021 · 8 comments
Closed

sss_ssh_knownhostsproxy ignores the -4/-6 ssh option #5690

gerases opened this issue Jun 17, 2021 · 8 comments

Comments

@gerases
Copy link

gerases commented Jun 17, 2021

Ssh takes an option for whether exclusively IPv4 or IPv6 are to be used. For the IPv4 variant, the option is -4. From the man page:

  -4      Forces ssh to use IPv4 addresses only.

However, when sss_ssh_knownhostsproxy is in the middle with this configuration like so:

  ProxyCommand /usr/bin/sss_ssh_knownhostsproxy -p %p %h

The -4 option is ignored. I'm not sure what other options could be also ignored.

Is this a known issue (non-issue?). Is there a workaround?

@gerases gerases changed the title sss_ssh_knownhostsproxy ignores ssh options sss_ssh_knownhostsproxy ignores the -4/-6 ssh option Jun 21, 2021
@gerases
Copy link
Author

gerases commented Jun 21, 2021

I've looked into the source code. Please confirm my understanding of the C code for sss_ssh_knownhostsproxy is correct (https://github.com/SSSD/sssd/blob/master/src/sss_client/ssh/sss_ssh_knownhostsproxy.c). The slimmed down version of the code is below. Essentially, the sequence of events is this:

  • getaddrinfo is called to collect all possible IPs on the system
  • since ai_hint.ai_family is left as AF_UNSPEC, IPv4 or IPv6 addresses are selected.
  • the proxy then tries to connect using each of the IPs. As soon as a connection is established, no other IPs are tried.

The man page on getaddrinfo says:

ai_family
This field specifies the desired address family for the
returned addresses. Valid values for this field include
AF_INET and AF_INET6. The value AF_UNSPEC indicates that
getaddrinfo() should return socket addresses for any
address family (either IPv4 or IPv6, for example) that can
be used with node and service.

If what I described above is true, then the -4 or -6 option passed to ssh is indeed ignored. It can't possibly be respected given the logic.

      struct addrinfo ai_hint;
      ...
      ai_hint.ai_family = AF_UNSPEC;
      ai_hint.ai_socktype = SOCK_STREAM;
      ai_hint.ai_protocol = IPPROTO_TCP;
      ai_hint.ai_flags = AI_ADDRCONFIG | AI_NUMERICHOST | AI_NUMERICSERV;
      ...
      ret = getaddrinfo(pc_host, strport, &ai_hint, &ai);
      ...
      for (struct addrinfo *ti = ai; ti != NULL; ti = ti->ai_next) {
              int socket_descriptor = -1;
              ret = connect_socket(ti->ai_family, ti->ai_addr, ti->ai_addrlen,
                                   &socket_descriptor);
              if (ret == 0) {
                  ret = proxy_data(socket_descriptor);
                  break;
              }
         }

@gerases
Copy link
Author

gerases commented Jun 21, 2021

@alexey-tikhonov, could you confirm my findings

@sumit-bose
Copy link
Contributor

Hi,

I think your analysis is correct. However I'm not sure if there is an easy fix since I'm not sure if the proxy command knows about the original options from the ssh command line.

Please note that we might want to deprecate sss_ssh_knownhostproxy in future because the main purpose of this program is to handle centrally stored host keys which are made available by SSSD. Since OpenSSH 8.5 the new option KnownHostCommand is available (see #5518) which is a better and more direct solution to make ssh aware of the host keys.

bye,
Sumit

@gerases
Copy link
Author

gerases commented Jun 22, 2021

Thanks @sumit-bose, the new option could indeed be the solution. Barring that, the openssh client would have to introduce a new TOKEN (similar to %h) to indicate the desired protocol. But I agree that's still not as good as the new option.

Somewhat related, it seems sss_ssh_get_ent gets the public key of the host directly from the host even if a directory service is configured. I somehow thought that if for example IPA is configured, the proxy would ask IPA for the destination host's public key. But it doesn't seem to be the case. How would the man-in-the-middle attack be prevented with this approach?

@sumit-bose
Copy link
Contributor

Hi,

sss_ssh_get_ent calls sss_ssh_make_request which will open a socket to the SSSD ssh responder sssd_ssh. The ssh responder will check SSSD's cache for the key or request them via the SSSD backend from the IPA server and finally return the keys to the caller. So the lookup of the keys from IPA is delegated to SSSD which is the trusted component for other types of authentication as well.

HTH

bye,
Sumit

@gerases
Copy link
Author

gerases commented Jun 22, 2021

Hi Sumit,

Yep, that definitely helps. Thanks much for that insight. Implementing that functionality in the script passed to KnownHostsCommand could be interesting but not impossible.

Thanks again,
Sergei

@pbrezina
Copy link
Member

There is bugzilla for that: https://bugzilla.redhat.com/show_bug.cgi?id=1857104 unfortunately there is nothing we can do about it. ProxyCommand option does not have the functionality to pass these arguments to the command. I requested this in OpenSSH a while back, but nothing happened so far.

@gerases gerases closed this as completed Jun 23, 2021
@gerases
Copy link
Author

gerases commented Jun 23, 2021

Thank you @pbrezina, this is great info.

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

No branches or pull requests

3 participants