Change Request: Don't modify known_hosts file when host_key_checking=False

In a “Development or Test” context (e.g. using Vagrant to spin up temporary machines), it is usually not desired to store the host key in ~/.ssh/known_hosts file, as the related host:port is frequently reused by other machines. In this kind of simple context, we also assume that ssh-keyscan tool is not used.

At the moment, it is possible to configure Ansible to not modify the known host file the following way:

  • paramiko connection: ANSIBLE_PARAMIKO_RECORD_HOST_KEYS=false

  • ssh connection: ANSIBLE_SSH_ARGS=‘-o UserKnownHostsFile=/dev/null’
    (Note that there is no ANSIBLE_SSH_RECORD_HOST, equivalent to ANSIBLE_PARAMIKO_RECORD_HOST)

This change request idea comes from the Vagrant context, where by default Ansible is configured so that the known host keys are not considered (via ANSIBLE_HOST_KEY_CHECKING=False). But we’d also want that the known host file is not modified by Ansible.
Of course, we can easily implement this behavior with the parameters listed above, but I think that having an “ssh-connection-agnostic” way to configure Ansible would be more comprehensive and could be useful in any other contexts that uses temporary “unsafe machines” that share the same host:port addresses.

Therefore I see three possible approaches to resolve this issue:

  • Change the behavior of “ANSIBLE_HOST_KEY_CHECKING=False”, so that the known_hosts file is not modified in this case.

  • Introduce a new option (e.g. ANSIBLE_RECORD_HOST_KEYS, set to true by default), impacting both (ssh and parmiko) connection modes (This would deprecate ANSIBLE_PARAMIKO_RECORD_HOST by the way)

  • Introduce a new option (e.g. ANSIBLE_USER_KNOWN_HOSTS_FILE), to optionally specify the host file to use by both (ssh and parmiko) connection modes.

I prefer the first approach (change behavior of “ANSIBLE_HOST_KEY_CHECKING=False”) for the following reasons:

  • A host key that we don’t check - or even trust - should actually not be stored as known host.

  • For openssh connection, it corresponds to usual “-o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no” combination.

  • These ‘unnecessary’ entries in the known hosts file will never be automatically replaced when the host key changes, leading to keep outdated information. Having a key mismatch when using ANSIBLE_HOST_KEY_CHECKING=False can lead to confusing situations, like the SSH forwarding problem documented in https://gist.github.com/glenjamin/7f1d4335e7a9760b75e5.

  • The backward compatibility on Ansible safe default (ANSIBLE_HOST_KEY_CHECKING=True) is maintained, and only the “non-standard” mode is impacted.

So, I’d like to know if more people are interested in this change request and if you would you accept a patch for that?
If yes, which approach do you prefer? For the first approach, I already created d90436ea65a82aab1f746c503d8a0b68a5e315a8, as a possible base for a pull request.

Many thanks in advance for your reviews!

Gilles

Related References:

Not really interested in changing behavior too much just for your development use case when it’s just as easy to turn checking off.

In interest in my reading comprehension of the above novel, can you give me a two sentence summary?

BTW, all that you post above is settable in ansible.cfg, the environment variables are just there for legacy reasons.

Thank you Michael for quick feedback and sorry if my verbose post was not clear. I am again word flooding below for completeness, but I hope it will be easier to navigate this time :wink:

Not really interested in changing behavior too much just for your development use case when it’s just as easy to turn checking off.

There is no doubt that I can deal with the current configuration options, but I felt that Ansible could really gain to be easier to configure in that situation, hence the creation of this post.

In interest in my reading comprehension of the above novel, can you give me a two sentence summary?

When [defaults].host_key_checking is disabled, Ansible still adds new hosts into the user known_hosts file, which is not desirable (for the reasons explained in the original post). In this case (host key checking turned off), I propose to completely skip the user known_hosts file (alternative solutions are also presented in the original post).

BTW, all that you post above is settable in ansible.cfg, the environment variables are just there for legacy reasons.

Sure! But this note “alarmed” me a little bit by the way… Do you mean that the environmental configuration alternative won’t be maintained in the future? These equivalent environment variables are a great way to combine settings with an existing ansible.cfg file, so please keep them!

Please let me close the second chapter of this awful novel with two examples that illustrate the “before” and “after” idea.

At the moment, following settings are necessary for my use case:

[defaults]

host_key_checking = False

[paramiko_connection]

record_host_keys = False

[ssh_connection]

ssh_args = -o UserKnownHostsFile=/dev/null

By changing host_key_checking=False behavior (as illustrated in d90436ea65a82aab1f746c503d8a0b68a5e315a8), following would then be equivalent:

[defaults]

host_key_checking = False

Thanks again in advance for your feedbacks!

Best,
Gilles

The environment variable options will not go away (ever). I believe the point Michael was trying to make was that since you can create local ansible.cfg files in the working directory (which can override those set globally in /etc/ansible/ansible.cfg) it is easy enough to make this work without having to specify the env variables with every run.

What you are proposing is to drastically change the meaning of the host_key_checking option, which we do not want to do. At the very least, we would have to create a second option (ie. save_host_keys = False) to implement the behavior you want, but since (as you’ve illustrated above) you can already accomplish the same thing with only 2 other lines of configuration we do not feel that this is necessary.

At best, this warrants a minor tweak to the Vagrant guide (http://docs.ansible.com/guide_vagrant.html), to specifically mention setting these options would be recommended. We’d be glad to take a documentation pull request along those lines.

Thanks!

The environment variable options will not go away (ever).

OK I am relieved on this point, thanks for the precision :slight_smile:

What you are proposing is to drastically change the meaning of the host_key_checking option, which we do not want to do.

This was indeed the most radical variant and I understand that you don’t want to change the meaning of host_key_checking=False.

At the very least, we would have to create a second option (ie. save_host_keys = False) to implement the behavior you want,

I also proposed this second variant in my initial post, which provides the following advantages:

  • create a “configuration contract” for possible ssh connection alternatives that might come in the future
  • remove this discrepancy between paramiko and ssh settings
  • do not force to rely on the “multipurpose” ssh_args option

but since (as you’ve illustrated above) you can already accomplish the same thing with only 2 other lines of configuration we do not feel that this is necessary.

The idea was not to spare a configuration line but to provide optimal maintenance and usage capabilities on a long term perspective.
That said, I agree that this is minor stuff and your arguments to reject this proposition are totally fair.

At best, this warrants a minor tweak to the Vagrant guide (http://docs.ansible.com/guide_vagrant.html), to specifically mention setting these options would be recommended. We’d be glad to take a documentation pull request along those lines.

Based on this discussion, upcoming Vagrant 1.7+ will very probably set these settings by default (see vagrant#3900), so that Vagrant users won’t have to care about this. I also keep in mind to provide relevant updates to the Vagrant guide.

James and Michael: Thank you a lot for taking time to answer to these questions.

Best regards,
Gilles