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

nixos/ssh: hash ssh_known_hosts file #93542

Closed
wants to merge 1 commit into from

Conversation

erictapen
Copy link
Member

@erictapen erictapen commented Jul 20, 2020

Motivation for this change

This would harden the handling of SSH keys in NixOS a bit, without compromising usability imho.

Consider this use case: A NixOS machine is defined with

{
  programs.ssh.knownHosts = {
    "myremote" = {
      hostNames = [ "10.0.0.2" "example.com" ];
      publicKey = "ssh-rsa ... root@example.com";
    };
  };
}

and then is deployed in a way, that the *.nix files don't end up on the remote host (e.g. by using NixOps or by building locally, copying the closure with nix copy and then activating on the remote side).

Now let's say an attacker gains access to that machine. Without this pull request they can easily see how to access root@example.com and derive from the existence of the known_hosts entry, that they might have access to that host. With this PR they only see hashed hosts, which would require them to figure out the remote URL by themselfes. That would make hopping from machine to machine and therefore compromising the whole network considerably harder.

See also ssh-keygen(1):

-H Hash a known_hosts file. This replaces all hostnames and
addresses with hashed representations within the specified
file; the original content is moved to a file with a .old
suffix. These hashes may be used normally by ssh and sshd,
but they do not reveal identifying information should the
file's contents be disclosed. This option will not modify
existing hashed hostnames and is therefore safe to use on
files that mix hashed and non-hashed names.

At the same time I don't know of any good use cases to look at /etc/ssh/ssh_known_hosts and derive any legible information from that file. So no usability tradeoffs in sight for me. If there should the need arise, one could change this behaviour by introducing an option lke hashKnownHosts ? true.

Things done
  • Hash knownHosts
  • Wrote an release notes entry.

Also I tested this commit for the past three months on my setup.

I didn't write a NixOS test, as programs.ssh.knownHosts isn't tested yet.

  • Tested using sandboxing (nix.useSandbox on NixOS, or option sandbox in nix.conf on non-NixOS linux)
  • Built on platform(s)
    • NixOS
    • macOS
    • other Linux distributions
  • Tested via one or more NixOS test(s) if existing and applicable for the change (look inside nixos/tests)
  • Tested compilation of all pkgs that depend on this change using nix-shell -p nixpkgs-review --run "nixpkgs-review wip"
  • Tested execution of all binary files (usually in ./result/bin/)
  • Determined the impact on package closure size (by running nix path-info -S before and after)
  • Ensured that relevant documentation is up to date
  • Fits CONTRIBUTING.md.

Pinging @aszlig @edolstra as they maintain the openssh test.
Pinging @Izorkin @alyssais @philandstuff @edef1c as the recently contributed to nixos/modules/programs/ssh.nix.

From ssh-keygen(1):

> -H     Hash a known_hosts file.  This replaces all hostnames and
>        addresses with hashed representations within the specified
>        file;  the original content is moved to a file with a .old
>        suffix.  These hashes may be used normally by ssh and sshd,
>        but they do not reveal identifying information should the
>        file's contents be disclosed.  This option will not modify
>        existing hashed hostnames and is therefore safe to use on
>        files that mix hashed and non-hashed names.
@erictapen
Copy link
Member Author

Pinging @aszlig @edolstra as they maintain the openssh test.
Pinging @Izorkin @alyssais @philandstuff @edef1c as they recently contributed to nixos/modules/programs/ssh.nix.

@philandstuff
Copy link
Contributor

+0 from me - I'm neither in favour nor against this change. It seems like an incredibly small benefit, but also an incredibly small cost.

There is code out there to brute force hashed known hosts - John the Ripper (a password cracking tool) has a mode for cracking hashed known_hosts, and known hosts are in some ways an easier problem than passwords as they are not designed to be high entropy. Particularly private IPs (RFC 1918) can be enumarated, so hashing these provides little protection. Hostnames require a bit more thought, but you can easily feed a dictionary into it, and people are not going to be designing hostnames to be hard to guess.

However I agree there is not a lot of cost to hashing the known hosts file, I can't really think of a useful use of keeping it plaintext in the specific case that it was generated as part of a nixos configuration (whereas I can think of uses for manually-managed known_hosts files, which doesn't apply here). Hence, to repeat myself, I'm +0 on this.

@edef1c
Copy link
Member

edef1c commented Jul 22, 2020

I personally don't have much for or against. I'd turn this off on my dev machine, and don't rely on TOFU host-to-host SSH for production use, since I use host certificates signed by an SSH CA, which effectively hashes the host information.

It's worth taking into account that the tab-completion for SSH hosts also relies on known_hosts, and some people may depend on that.

Do we have any feelings re: turning HashKnownHosts on in the global ssh_config? Do we want to make any of this configurable? We could have a single HashKnownHosts toggle that turns both of these on, default-enabled.

@erictapen
Copy link
Member Author

erictapen commented Jul 24, 2020

Thanks for your comments. I agree with your points, especially the one about bruteforceability of hashed known_hosts. I didn't really think about it, but of course, host names usually have not enough entropy to be meaningfully secured by a hash function. Maybe this is really the wrong place to harden, as it would provide a false sense of security. I'll close this PR.

@erictapen erictapen closed this Jul 24, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants