saltstack / salt

Software to automate the management and configuration of any infrastructure or application at scale. Get access to the Salt software package repository here:
https://repo.saltproject.io/
Apache License 2.0
14.15k stars 5.48k forks source link

Support New Hash format for ssh key fingerprints #46152

Closed chrisportela closed 5 years ago

chrisportela commented 6 years ago

Description of Issue/Question

Can't add default format of sha256 finger prints because modules:ssh.py:_fingerprint() converts remote fingerprint to a hex digest.

Setup

I'm using salt-call --local to high state an machine I'm going to image.

Here's an example of the expected state

not_github_com_known_host:
  ssh_known_hosts.present:
    - name: not.github.com
    - user: server
    - enc: ssh-rsa
    - fingerprint: p50+tVCEjfjor5kHkKG1M/PxsYIUv52S2bjIKDVQ2Hc
    - fingerprint_hash_type: sha256
    - require:
      - user: user_server
      - pkg: git

Here's the working example

not_github_com_known_host:
  ssh_known_hosts.present:
    - name: not.github.com
    - user: server
    - enc: ssh-rsa
    - fingerprint: a7:9d:3e:b5:50:84:8d:f8:e8:af:99:07:90:a1:b5:33:f3:f1:b1:82:14:bf:9d:92:d9:b8:c8:28:35:50:d8:77
    - fingerprint_hash_type: sha256
    - require:
      - user: user_server
      - pkg: git

Steps to Reproduce Issue

Using ssh-keyscan and ssh-keygen I pulled the fingerprint for my remote git server. I was doing this because for some reason Salt thought I was using a fingerprint different from the server.

I used the sha256 version so I wouldn't need to down grade to md5 and I kept getting the error. I went in to modules > ssh.py > set_known_host to print out what salt believed the fingerprint was vs what I had given it and discovered that my sha256 fingerprint didn't match a hex digest of the remote host's fingerprint which I couldn't get ssh-keygen to give me at all.

I had to just trust that the fingerprint hex digest was correct and using that worked for adding to the known hosts file.

Here is the offending code: https://github.com/saltstack/salt/blob/fd0482b26b09cadc4fd0569184639ed92175fba6/salt/modules/ssh.py#L241-L286

By converting the sha256 fingerprint to a hex-digest it's preventing set_known_host's check from passing because the base64(?) version and hex digest strings aren't equal.

Versions Report

I'm running 2016.11.8 because of incompatibilities we have, but I've linked to the develop branch's version of the issue.

    amazon-ebs: + uname -a
    amazon-ebs: + cat /etc/os-release
    amazon-ebs: + dpkg -l
    amazon-ebs: NAME="Ubuntu"
    amazon-ebs: VERSION="14.04.5 LTS, Trusty Tahr"
    amazon-ebs: ID=ubuntu
    amazon-ebs: ID_LIKE=debian
    amazon-ebs: PRETTY_NAME="Ubuntu 14.04.5 LTS"
    amazon-ebs: VERSION_ID="14.04"
    amazon-ebs: HOME_URL="http://www.ubuntu.com/"
    amazon-ebs: SUPPORT_URL="http://help.ubuntu.com/"
    amazon-ebs: BUG_REPORT_URL="http://bugs.launchpad.net/ubuntu/"
    amazon-ebs: + grep linux-
    amazon-ebs: ii  linux-headers-3.13.0-139         3.13.0-139.188                             all          Header files related to Linux kernel version 3.13.0
    amazon-ebs: + sudo salt-minion --versions-report
    amazon-ebs: ii  linux-headers-3.13.0-139-generic 3.13.0-139.188                             amd64        Linux kernel headers for version 3.13.0 on 64 bit x86 SMP
    amazon-ebs: ii  linux-headers-generic            3.13.0.139.148                             amd64        Generic Linux kernel headers
    amazon-ebs: ii  linux-headers-virtual            3.13.0.139.148                             amd64        Transitional package.
    amazon-ebs: ii  linux-image-3.13.0-139-generic   3.13.0-139.188                             amd64        Linux kernel image for version 3.13.0 on 64 bit x86 SMP
    amazon-ebs: ii  linux-image-virtual              3.13.0.139.148                             amd64        This package will always depend on the latest minimal generic kernel image.
    amazon-ebs: ii  linux-libc-dev:amd64             3.13.0-142.191                             amd64        Linux Kernel Headers for development
    amazon-ebs: ii  linux-virtual                    3.13.0.139.148                             amd64        Minimal Generic Linux kernel and headers
    amazon-ebs: Salt Version:
    amazon-ebs:            Salt: 2016.11.8
    amazon-ebs:
    amazon-ebs: Dependency Versions:
    amazon-ebs:            cffi: Not Installed
    amazon-ebs:        cherrypy: Not Installed
    amazon-ebs:        dateutil: 1.5
    amazon-ebs:       docker-py: Not Installed
    amazon-ebs:           gitdb: Not Installed
    amazon-ebs:       gitpython: Not Installed
    amazon-ebs:           ioflo: Not Installed
    amazon-ebs:          Jinja2: 2.7.2
    amazon-ebs:         libgit2: Not Installed
    amazon-ebs:         libnacl: Not Installed
    amazon-ebs:        M2Crypto: Not Installed
    amazon-ebs:            Mako: 0.9.1
    amazon-ebs:    msgpack-pure: Not Installed
    amazon-ebs:  msgpack-python: 0.4.6
    amazon-ebs:    mysql-python: 1.2.3
    amazon-ebs:       pycparser: Not Installed
    amazon-ebs:        pycrypto: 2.6.1
    amazon-ebs:    pycryptodome: Not Installed
    amazon-ebs:          pygit2: Not Installed
    amazon-ebs:          Python: 2.7.6 (default, Nov 23 2017, 15:49:48)
    amazon-ebs:    python-gnupg: Not Installed
    amazon-ebs:          PyYAML: 3.10
    amazon-ebs:           PyZMQ: 14.0.1
    amazon-ebs:            RAET: Not Installed
    amazon-ebs:           smmap: Not Installed
    amazon-ebs:         timelib: Not Installed
    amazon-ebs:         Tornado: 4.2.1
    amazon-ebs:             ZMQ: 4.0.5
    amazon-ebs:
    amazon-ebs: System Versions:
    amazon-ebs:            dist: Ubuntu 14.04 trusty
    amazon-ebs:         machine: x86_64
    amazon-ebs:         release: 3.13.0-139-generic
    amazon-ebs:          system: Linux
    amazon-ebs:         version: Ubuntu 14.04 trusty
gtmanfred commented 6 years ago

It looks like this function only supports the old format, but it has been changed to be this hash in a newer version ssh.

Apparently this format was changed in OpenSSH > 6.7.

I have marked this as a feature request.

Thanks Daniel

stale[bot] commented 5 years ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

If this issue is closed prematurely, please leave a comment and we will gladly reopen the issue.

AndreyMZ commented 4 years ago

It is still actual. Reopen, please.

Anthony-Bible commented 4 years ago

Looks like this is still an issue in version 3000. As a work around I am able to use the MD5 hash but obviously that isn't ideal

boltronics commented 4 years ago

This is still an issue in 2019.2.4. Here is another request to re-open this issue, please!

This has to be a security issue, because I know that, speaking for myself at least, until now (where I just figured out an acceptable work-around) we were stuck using the older less-secure SSH fingerprints. I'm sure many other people must be in the same boat.

The work-around:

Using GitHub as an example:

According to https://help.github.com/articles/what-are-github-s-ssh-key-fingerprints/ the keys are:

SHA256:nThbg6kXUpJWGl7E1IGOCspRomTxdCARLviKw6E5SY8 (RSA)
SHA256:br9IjFspm1vxR3iA35FWE+4VTyz1hYVLIE2t1/CeyWQ (DSA)

So we need to convert them from base64 to hexadecimal format. Starting with the RSA key:

$ echo -n 'nThbg6kXUpJWGl7E1IGOCspRomTxdCARLviKw6E5SY8' | base64 -d 2>/dev/null | od -A n -t x1
 9d 38 5b 83 a9 17 52 92 56 1a 5e c4 d4 81 8e 0a
 ca 51 a2 64 f1 74 20 11 2e f8 8a c3 a1 39 49 8f

We can reformat this to something Salt can work with by removing the new line and using some sed magic:

$ echo -n 'nThbg6kXUpJWGl7E1IGOCspRomTxdCARLviKw6E5SY8' | base64 -d 2>/dev/null | od -A n -t x1 | xargs echo | sed 's/\ *//g;s/\(..\)/\1:/g;s/:$//'
9d:38:5b:83:a9:17:52:92:56:1a:5e:c4:d4:81:8e:0a:ca:51:a2:64:f1:74:20:11:2e:f8:8a:c3:a1:39:49:8f

We can now do the same for the DSA key:

$ echo -n 'br9IjFspm1vxR3iA35FWE+4VTyz1hYVLIE2t1/CeyWQ' | base64 -d 2>/dev/null | od -A n -t x1 | xargs echo | sed 's/\ *//g;s/\(..\)/\1:/g;s/:$//'
6e:bf:48:8c:5b:29:9b:5b:f1:47:78:80:df:91:56:13:ee:15:4f:2c:f5:85:85:4b:20:4d:ad:d7:f0:9e:c9:64

This beats adding print statements to the set_known_host function in the ssh module and hoping there was no MITM attack... but don't take my word for these answers, you can now do this yourself. It does not negate the need for a proper fix however, as I'm sure most people won't see this issue.

boltronics commented 4 years ago

I came up with a function I can put into an execution module to make things easier until this is fixed (again, please re-open this)!

Tested to work in Python 2.7 and 3.7.

$ python
Python 2.7.16 (default, Oct 10 2019, 22:02:15) 
[GCC 8.3.0] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from codecs import getencoder
>>> from base64 import b64decode
>>> def base64_to_hex(b64_fingerprint):
...     """Returns a converted base64 string to hexadecimal"""
...     def md5_hash_format(fph):
...         """Adds ':' after every two characters of a hex string."""
...         start = 0
...         end = 2
...         output = ''
...         sep = ':'
...         for _ in range(0, int(len(fph) / 2)):
...             if start + 2 == len(fph):
...                 sep = ''
...             output = "{0}{1}{2}".format(output, fph[start:end], sep)
...             start = end
...             end += 2
...         return output
...     fpd = b64decode(b64_fingerprint + '='* (4 - (len(b64_fingerprint) % 4)))
...     # Not in Python 2.7...
...     #return md5_hash_format(fpd.hex())
...     return md5_hash_format(getencoder('hex_codec')(fpd)[0].decode('utf-8'))
... 
>>> base64_to_hex('nThbg6kXUpJWGl7E1IGOCspRomTxdCARLviKw6E5SY8')
'9d:38:5b:83:a9:17:52:92:56:1a:5e:c4:d4:81:8e:0a:ca:51:a2:64:f1:74:20:11:2e:f8:8a:c3:a1:39:49:8f'
>>> base64_to_hex('br9IjFspm1vxR3iA35FWE+4VTyz1hYVLIE2t1/CeyWQ')
'6e:bf:48:8c:5b:29:9b:5b:f1:47:78:80:df:91:56:13:ee:15:4f:2c:f5:85:85:4b:20:4d:ad:d7:f0:9e:c9:64'
>>> 
SamJoan commented 3 years ago

Using the bash one liners I was able to correctly configure the github RSA public key using this configuration:

github.com RSA Key:
    ssh_known_hosts.present:
        - name: github.com
        - user: root
        - enc: ssh-rsa
        - fingerprint: 9d:38:5b:83:a9:17:52:92:56:1a:5e:c4:d4:81:8e:0a:ca:51:a2:64:f1:74:20:11:2e:f8:8a:c3:a1:39:49:8f

I was also running into this issue.

HeinrichFilter commented 1 year ago

After Github had to update their RSA SSH host key the new fingerprint in this format is:

b8:d8:95:ce:d9:2c:0a:c0:e1:71:cd:2e:f5:ef:01:ba:34:17:55:4a:4a:64:80:d3:31:cc:c2:be:3d:ed:0f:6b

I used https://github.com/saltstack/salt/issues/46152#issuecomment-625592695 to generate the fingerprint but I had to run it on a linux machine (macOS produced a shorter result)

nabbi commented 1 year ago

re-open please. 3005.1 impacted

barkingfoodog commented 4 months ago

For bitbucket.org (post 2023 key rotation):

bitbucket.org:
  ssh_known_hosts.present:
    - enc: ssh-rsa
    - fingerprint: e3:a3:92:1c:0d:51:9a:3f:04:f0:44:53:0b:ac:64:35:c9:86:3b:0f:68:17:16:2b:d1:61:7a:cd:65:bc:97:51

Generated using the one-liner from @boltronics on Ubuntu (thanks to @HeinrichFilter for pointing out running on macOS truncates the output).

$ echo -n '46OSHA1Rmj8E8ERTC6xkNcmGOw9oFxYr0WF6zWW8l1E' | base64 -d 2>/dev/null | od -A n -t x1 | xargs echo | sed 's/\ *//g;s/\(..\)/\1:/g;s/:$//'
e3:a3:92:1c:0d:51:9a:3f:04:f0:44:53:0b:ac:64:35:c9:86:3b:0f:68:17:16:2b:d1:61:7a:cd:65:bc:97:51

Feels like this issue shouldn't be closed. Lots of hoops to go through to get this to work, and it's not obvious from the Salt docs. Using Salt 3007.1.