Typical public SSH host key files generated with ssh-keygen have a whitespace as the last character. However, when the SSH hostkey is generated by other means, it is possible that there is no whitespace after the key, and the key is still valid.
The function update_ssh_keys in ipaclient/install/client.py removes the last character of the public ssh key regardless of the actual value of that characters. https://github.com/freeipa/freeipa/blob/master/ipaclient/install/client.py#L1565
update_ssh_keys
If the last character of the key is the last character of the line, this removal action invalidates the key, and the SSHFP record cannot be created later on.
ssh_host_rsa_key.pub is not added to the SSHFP records.
ssh_host_rsa_key.pub is added to the SSHFP records
ipa-client-4.6.4-10.el7.centos.3.x86_64
Instead of removing the last character systematically to remove the whitespace and calling lstrip to remove leading characters, like this:
line = line[:-1].lstrip()
it would be preferable to do :
line = line.strip()
trimming leading and trailing whitespaces in a single operation and avoiding removing characters that are part of the key.
Do you have an example of how to generate the key other than ssh-keygen so we can confirm this works?
In order to provide a simple example, I did a small research and found out my initial assumption about why update_ssh_keys removes the last character of each line was wrong.
The intent of line[:-1] is not to remove a trailing whitespace, but to remove the line return. In my case, there is no whitespace at the end of the ssh key, and no line return either, which is why the removal of the last character is problematic.
line[:-1]
A public SSH host key without a line return is still valid. A call to strip would remove the line return and trailing whitespaces only if they are there.
strip
In my use-case, I initialize the SSH hostkeys with cloud-init. cloud-init creates the public ssh host key without a trailing whitespace or new line at the end.
There is an example in cloud-init documentation - rsa_public: https://cloudinit.readthedocs.io/en/latest/topics/examples.html#configure-instances-ssh-keys
rsa_public
To replicate the production of a public ssh key that would fail to be added by FreeIPA, generate a public ssh host key associated with an existing private key and remove the line return.
ssh-keygen -f /etc/ssh/ssh_host_ed25519_key -y | tr -d '\n' > key.pub
Here is a simplified test case that replicates the logic of update_ssh_keys without going through the whole installation process. It uses the key.pub file generated by the example.
key.pub
from ipapython.ssh import SSHPublicKey with open('key.pub') as f: for line in f: # update_ssh_keys logic line = line[:-1].lstrip() try: pubkey = SSHPublicKey(line) except ValueError as e: print("Error: %s, %s" % (e, line))
If we use strip instead, the key is read correctly.
from ipapython.ssh import SSHPublicKey with open('key.pub') as f: for line in f: # update_ssh_keys logic line = line.strip() try: pubkey = SSHPublicKey(line) except ValueError as e: print("Error: %s, %s" % (e, line))
Metadata Update from @pcech: - Issue tagged with: Falcon
Metadata Update from @rcritten: - Issue assigned to rcritten
Looks good, thanks. I'd be happy to give you credit for the fix but I need a name and/or e-mail address.
Metadata Update from @rcritten: - Issue priority set to: normal - Issue set to the milestone: FreeIPA 4.7.3
Glad I could help.
Félix-Antoine Fortin - felix-antoine.fortin at calculquebec.ca
master:
ipa-4-7:
ipa-4-6:
Metadata Update from @rcritten: - Issue close_status updated to: fixed - Issue status updated to: Closed (was: Open)
Login to comment on this ticket.