Mailing List Archive

"ssh-keygen -R hostname" errors out with non-existent known_hosts
I've just run into what I consider a bug: If ~/.ssh/known_hosts does
not exist, and the account owner runs the command or their script
includes the command "ssh-keygen -R {hostname}", it reports an error
rather than reporting "oh, yes, the file was empty and therefore your
attempt to delete the hostname was unnecessary".

If I want to delete a hostkey entry, and there is none to be found,
shouldn't that be considered a successful operation?
_______________________________________________
openssh-unix-dev mailing list
openssh-unix-dev@mindrot.org
https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev
Re: "ssh-keygen -R hostname" errors out with non-existent known_hosts [ In reply to ]
On Tue, 23 Mar 2021, Nico Kadel-Garcia wrote:

> I've just run into what I consider a bug: If ~/.ssh/known_hosts does
> not exist, and the account owner runs the command or their script
> includes the command "ssh-keygen -R {hostname}", it reports an error
> rather than reporting "oh, yes, the file was empty and therefore your
> attempt to delete the hostname was unnecessary".
>
> If I want to delete a hostkey entry, and there is none to be found,
> shouldn't that be considered a successful operation?

I think the condition of known_hosts being absent is worth communicating.
Maybe a different exit value for that case?


diff --git a/ssh-keygen.c b/ssh-keygen.c
index a442dc8e..3f603163 100644
--- a/ssh-keygen.c
+++ b/ssh-keygen.c
@@ -1305,8 +1305,14 @@ do_known_hosts(struct passwd *pw, const char *name, int find_host,
free(cp);
have_identity = 1;
}
- if (stat(identity_file, &sb) != 0)
- fatal("Cannot stat %s: %s", identity_file, strerror(errno));
+ if (stat(identity_file, &sb) != 0) {
+ if (errno != ENOENT) {
+ fatal("Cannot stat %s: %s", identity_file,
+ strerror(errno));
+ }
+ logit("Hosts file %s does not exist", identity_file);
+ cleanup_exit(1);
+ }

memset(&ctx, 0, sizeof(ctx));
ctx.out = stdout;
_______________________________________________
openssh-unix-dev mailing list
openssh-unix-dev@mindrot.org
https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev
Re: "ssh-keygen -R hostname" errors out with non-existent known_hosts [ In reply to ]
On Tue, Mar 23, 2021 at 7:01 PM Damien Miller <djm@mindrot.org> wrote:
>
> On Tue, 23 Mar 2021, Nico Kadel-Garcia wrote:
>
> > I've just run into what I consider a bug: If ~/.ssh/known_hosts does
> > not exist, and the account owner runs the command or their script
> > includes the command "ssh-keygen -R {hostname}", it reports an error
> > rather than reporting "oh, yes, the file was empty and therefore your
> > attempt to delete the hostname was unnecessary".
> >
> > If I want to delete a hostkey entry, and there is none to be found,
> > shouldn't that be considered a successful operation?
>
> I think the condition of known_hosts being absent is worth communicating.
> Maybe a different exit value for that case?

Exit 0, please. An absent known_hosts file doesn't contain the entry
the "ssh-keygen -R hostname" entry is expected to remove, and the
result should be considered a success for the command.

> diff --git a/ssh-keygen.c b/ssh-keygen.c
> index a442dc8e..3f603163 100644
> --- a/ssh-keygen.c
> +++ b/ssh-keygen.c
> @@ -1305,8 +1305,14 @@ do_known_hosts(struct passwd *pw, const char *name, int find_host,
> free(cp);
> have_identity = 1;
> }
> - if (stat(identity_file, &sb) != 0)
> - fatal("Cannot stat %s: %s", identity_file, strerror(errno));
> + if (stat(identity_file, &sb) != 0) {
> + if (errno != ENOENT) {
> + fatal("Cannot stat %s: %s", identity_file,
> + strerror(errno));
> + }
> + logit("Hosts file %s does not exist", identity_file);
> + cleanup_exit(1);
> + }
>
> memset(&ctx, 0, sizeof(ctx));
> ctx.out = stdout;
_______________________________________________
openssh-unix-dev mailing list
openssh-unix-dev@mindrot.org
https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev
Re: "ssh-keygen -R hostname" errors out with non-existent known_hosts [ In reply to ]
On Tue, 23 Mar 2021, Nico Kadel-Garcia wrote:

> On Tue, Mar 23, 2021 at 7:01 PM Damien Miller <djm@mindrot.org> wrote:
> >
> > On Tue, 23 Mar 2021, Nico Kadel-Garcia wrote:
> >
> > > I've just run into what I consider a bug: If ~/.ssh/known_hosts does
> > > not exist, and the account owner runs the command or their script
> > > includes the command "ssh-keygen -R {hostname}", it reports an error
> > > rather than reporting "oh, yes, the file was empty and therefore your
> > > attempt to delete the hostname was unnecessary".
> > >
> > > If I want to delete a hostkey entry, and there is none to be found,
> > > shouldn't that be considered a successful operation?
> >
> > I think the condition of known_hosts being absent is worth communicating.
> > Maybe a different exit value for that case?
>
> Exit 0, please. An absent known_hosts file doesn't contain the entry
> the "ssh-keygen -R hostname" entry is expected to remove, and the
> result should be considered a success for the command.

I certainly don't agree.

"grep foo /nonexistent" or "sed -i s/foo/bar /nonexistent" don't return
status 0 either for exactly the same reason.

-d
_______________________________________________
openssh-unix-dev mailing list
openssh-unix-dev@mindrot.org
https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev
Re: "ssh-keygen -R hostname" errors out with non-existent known_hosts [ In reply to ]
On Wed, 24 Mar 2021, Damien Miller wrote:

> > Exit 0, please. An absent known_hosts file doesn't contain the entry
> > the "ssh-keygen -R hostname" entry is expected to remove, and the
> > result should be considered a success for the command.

Agreed.

> "grep foo /nonexistent" or "sed -i s/foo/bar /nonexistent" don't return
> status 0 either for exactly the same reason.

This is more of a ,g/entry/d than a /entry/d in ed(1) parlance.

It’s a convenience command to remove an entry from the list of
known hosts, whether it exists or not or the file doesn’t even
exist; it should only fail when the job can’t be done (e.g. the
file is write-protected).

Think of it as 'rm -f known_hosts/entry' which won’t fail if
known_hosts/ doesn’t exist.

bye,
//mirabilos
--
«MyISAM tables -will- get corrupted eventually. This is a fact of life. »
“mysql is about as much database as ms access” – “MSSQL at least descends
from a database” “it's a rebranded SyBase” “MySQL however was born from a
flatfile and went downhill from there” – “at least jetDB doesn’t claim to
be a database” (#nosec) ??? Please let MySQL and MariaDB finally die!
_______________________________________________
openssh-unix-dev mailing list
openssh-unix-dev@mindrot.org
https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev
Re: "ssh-keygen -R hostname" errors out with non-existent known_hosts [ In reply to ]
I'm inclined to agree with Damien. It doesn't totally make sense to exit 0. The command hasn't successfully completed in the case in which it can't find the known_host file.

It may be a success according to your semantics in this instance, but what about in cases where the known_host file *should* have been found, but wasn't?

On Wed, 24 Mar 2021 02:20:19 +0100 (CET)
Thorsten Glaser <t.glaser@tarent.de> wrote:

> On Wed, 24 Mar 2021, Damien Miller wrote:
>
> > > Exit 0, please. An absent known_hosts file doesn't contain the entry
> > > the "ssh-keygen -R hostname" entry is expected to remove, and the
> > > result should be considered a success for the command.
>
> Agreed.
>
> > "grep foo /nonexistent" or "sed -i s/foo/bar /nonexistent" don't return
> > status 0 either for exactly the same reason.
>
> This is more of a ,g/entry/d than a /entry/d in ed(1) parlance.
>
> It’s a convenience command to remove an entry from the list of
> known hosts, whether it exists or not or the file doesn’t even
> exist; it should only fail when the job can’t be done (e.g. the
> file is write-protected).
>
> Think of it as 'rm -f known_hosts/entry' which won’t fail if
> known_hosts/ doesn’t exist.
>
> bye,
> //mirabilos
> --
> «MyISAM tables -will- get corrupted eventually. This is a fact of life. »
> “mysql is about as much database as ms access” – “MSSQL at least descends
> from a database” “it's a rebranded SyBase” “MySQL however was born from a
> flatfile and went downhill from there” – “at least jetDB doesn’t claim to
> be a database” (#nosec) ??? Please let MySQL and MariaDB finally die!
> _______________________________________________
> openssh-unix-dev mailing list
> openssh-unix-dev@mindrot.org
> https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev


--
Noah Zalev <noah@zalev.ca>
_______________________________________________
openssh-unix-dev mailing list
openssh-unix-dev@mindrot.org
https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev
Re: "ssh-keygen -R hostname" errors out with non-existent known_hosts [ In reply to ]
On Tue, 23 Mar 2021, Noah Zalev wrote:

> It may be a success according to your semantics in this instance, but
> what about in cases where the known_host file *should* have been
> found, but wasn't?

What do you care?

Its job is to ensure the next ssh to that host will not have an old
host key in the way. If there’s no known_hosts file, that’s done.

If you really need to test whether that file exists… test(1) exists.

Don’t complicate things.

bye,
//mirabilos
--
«MyISAM tables -will- get corrupted eventually. This is a fact of life. »
“mysql is about as much database as ms access” – “MSSQL at least descends
from a database” “it's a rebranded SyBase” “MySQL however was born from a
flatfile and went downhill from there” – “at least jetDB doesn’t claim to
be a database” (#nosec) ??? Please let MySQL and MariaDB finally die!
_______________________________________________
openssh-unix-dev mailing list
openssh-unix-dev@mindrot.org
https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev
Re: "ssh-keygen -R hostname" errors out with non-existent known_hosts [ In reply to ]
> Its job is to ensure the next ssh to that host will not have an old
> host key in the way. If there’s no known_hosts file, that’s done.

one could make the same argument about umount; it's job is to make
sure a particular device isn't mounted

$ umount: /mnt/this-disk-does-not-exist: no mount point specified.
umount: /mnt/this-disk-does-not-exist: no mount point specified.
$ echo $?
32

> If you really need to test whether that file exists… test(1) exists.

and similarly someone could test(1) that ~/.ssh/known_hosts exists
before calling ssh-keygen -R (which honestly seems like the easiest
solution to the original problem)

anyway, this is definitely in the realm of bikeshedding.
_______________________________________________
openssh-unix-dev mailing list
openssh-unix-dev@mindrot.org
https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev
Re: "ssh-keygen -R hostname" errors out with non-existent known_hosts [ In reply to ]
On Wed, 24 Mar 2021, Thorsten Glaser wrote:

> On Tue, 23 Mar 2021, Noah Zalev wrote:
>
> > It may be a success according to your semantics in this instance, but
> > what about in cases where the known_host file *should* have been
> > found, but wasn't?
>
> What do you care?

Because known_hosts not existing is an abnormal condition for a tool
that is asked to modify known_hosts.
_______________________________________________
openssh-unix-dev mailing list
openssh-unix-dev@mindrot.org
https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev
Re: "ssh-keygen -R hostname" errors out with non-existent known_hosts [ In reply to ]
On Tue, Mar 23, 2021 at 11:53 PM Damien Miller <djm@mindrot.org> wrote:
>
> On Wed, 24 Mar 2021, Thorsten Glaser wrote:
>
> > On Tue, 23 Mar 2021, Noah Zalev wrote:
> >
> > > It may be a success according to your semantics in this instance, but
> > > what about in cases where the known_host file *should* have been
> > > found, but wasn't?
> >
> > What do you care?
>
> Because known_hosts not existing is an abnormal condition for a tool
> that is asked to modify known_hosts.

It's frequent in setups that don't generate known_hosts at all, due to
IP and hostkey drift and poor local DNS which is startlingly common in
small networks and dynamically generated clusters. It's also common in
brand new docker environments or newly built host images, unless
someone defines a procedure to build a .ssh/known_hosts file as part
of creating the image. It also happens when people do "user -r" for a
system account, and forget to use the "-m" option to create a home
directory. Those accounts are going to have issues *generating* a
known_hosts account, but I think it makes more sense to have that fail
at a step that is supposed to create or update such an entry, not one
that is supposed to delete entries.

The one time I could see it as useful to error out is when the
account's home directory is expected to exist, via a filesystem or NFS
mount , and is enitrely unavailable. That.... gets a bit peculiar, and
I'd prefer not to try to outsmart everyone else's potential conditions
and make people fail in what is not that rare a circumstance.
_______________________________________________
openssh-unix-dev mailing list
openssh-unix-dev@mindrot.org
https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev
Re: "ssh-keygen -R hostname" errors out with non-existent known_hosts [ In reply to ]
On 24/03/2021 02:42, Peter Moody wrote:
>> Its job is to ensure the next ssh to that host will not have an old
>> host key in the way. If there’s no known_hosts file, that’s done.
> one could make the same argument about umount; it's job is to make
> sure a particular device isn't mounted
>
> $ umount: /mnt/this-disk-does-not-exist: no mount point specified.
> umount: /mnt/this-disk-does-not-exist: no mount point specified.
> $ echo $?
> 32
>
Or even just "rm":

$ rm nonexistent
rm: cannot remove 'nonexistent': No such file or directory
$ echo $?
1

But in this case, there is a flag to get the other behaviour.

$ rm -f nonexistent
$ echo $?
0

If the requirement is "to ensure the next ssh to that host will not have
an old host key in the way", and you are doing this on every connection
to that host, then you could simply ignore the known_hosts file entirely:

host *.foo.bar
  StrictHostKeyChecking no
  UserKnownHostsFile /dev/null
  LogLevel ERROR

I do this for test VMs which are being frequently deleted and recreated.

_______________________________________________
openssh-unix-dev mailing list
openssh-unix-dev@mindrot.org
https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev
Re: "ssh-keygen -R hostname" errors out with non-existent known_hosts [ In reply to ]
On Wed, 24 Mar 2021, Nico Kadel-Garcia wrote:

> > Because known_hosts not existing is an abnormal condition for a tool
> > that is asked to modify known_hosts.
>
> It's frequent in setups that don't generate known_hosts at all, due to
> IP and hostkey drift and poor local DNS which is startlingly common in
> small networks and dynamically generated clusters. It's also common in
> brand new docker environments or newly built host images, unless
> someone defines a procedure to build a .ssh/known_hosts file as part
> of creating the image. It also happens when people do "user -r" for a
> system account, and forget to use the "-m" option to create a home
> directory. Those accounts are going to have issues *generating* a
> known_hosts account, but I think it makes more sense to have that fail
> at a step that is supposed to create or update such an entry, not one
> that is supposed to delete entries.

Sure, but you're talking about known_hosts not existing being a common
situation but I never disputed this.

What's abnormal is running a tool to modify known_hosts when no such file
exists.

-d
_______________________________________________
openssh-unix-dev mailing list
openssh-unix-dev@mindrot.org
https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev
Re: "ssh-keygen -R hostname" errors out with non-existent known_hosts [ In reply to ]
On 23.03.21 06:42, Nico Kadel-Garcia wrote:
> If I want to delete a hostkey entry, and there is none to be found,
> shouldn't that be considered a successful operation?

I can think of (easily more than) two scenarios where someone would want
to run such a command in the first place:

-- An admin performing cleanups on users' known_hosts file after a
server changed keypairs or got decommissioned, where not finding the old
pubkeys in some of the user configs would be expected and ignored

-- A user who has had strict hostkey checking block his login and tries
to fix the problem, where the command *failing* to (semi-)fix the
problem is something he definitely wants to know about

You can't have one and the same command do *both*.

If anything, the reaction of "ssh-keygen -R ..." to a missing
known_hosts file should be consistent with the outcome of it not finding
a matching key therein to delete (which is to output an error message
but still do an exit(0), apparently).

Regards,
--
Jochen Bern
Systemingenieur

Binect GmbH
Re: "ssh-keygen -R hostname" errors out with non-existent known_hosts [ In reply to ]
On Wed, Mar 24, 2021 at 5:45 AM Jochen Bern <Jochen.Bern@binect.de> wrote:
>
> On 23.03.21 06:42, Nico Kadel-Garcia wrote:
> > If I want to delete a hostkey entry, and there is none to be found,
> > shouldn't that be considered a successful operation?
>
> I can think of (easily more than) two scenarios where someone would want
> to run such a command in the first place:
>
> -- An admin performing cleanups on users' known_hosts file after a
> server changed keypairs or got decommissioned, where not finding the old
> pubkeys in some of the user configs would be expected and ignored
>
> -- A user who has had strict hostkey checking block his login and tries
> to fix the problem, where the command *failing* to (semi-)fix the
> problem is something he definitely wants to know about
>
> You can't have one and the same command do *both*.
>
> If anything, the reaction of "ssh-keygen -R ..." to a missing
> known_hosts file should be consistent with the outcome of it not finding
> a matching key therein to delete (which is to output an error message
> but still do an exit(0), apparently).

This is why I'm suggesting should be the default.
_______________________________________________
openssh-unix-dev mailing list
openssh-unix-dev@mindrot.org
https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev
Re: "ssh-keygen -R hostname" errors out with non-existent known_hosts [ In reply to ]
> On Mar 25, 2021, at 20:49, Nico Kadel-Garcia <nkadel@gmail.com> wrote:
>
> ?On Wed, Mar 24, 2021 at 5:45 AM Jochen Bern <Jochen.Bern@binect.de> wrote:
>>
>>> On 23.03.21 06:42, Nico Kadel-Garcia wrote:
>>> If I want to delete a hostkey entry, and there is none to be found,
>>> shouldn't that be considered a successful operation?
>>
>> I can think of (easily more than) two scenarios where someone would want
>> to run such a command in the first place:
>>
>> -- An admin performing cleanups on users' known_hosts file after a
>> server changed keypairs or got decommissioned, where not finding the old
>> pubkeys in some of the user configs would be expected and ignored
>>
>> -- A user who has had strict hostkey checking block his login and tries
>> to fix the problem, where the command *failing* to (semi-)fix the
>> problem is something he definitely wants to know about
>>
>> You can't have one and the same command do *both*.
>>
>> If anything, the reaction of "ssh-keygen -R ..." to a missing
>> known_hosts file should be consistent with the outcome of it not finding
>> a matching key therein to delete (which is to output an error message
>> but still do an exit(0), apparently).
>
> This is why I'm suggesting should be the default.

What's wrong with:

ssh-keygen -R hostname || true

?
_______________________________________________
openssh-unix-dev mailing list
openssh-unix-dev@mindrot.org
https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev
Re: "ssh-keygen -R hostname" errors out with non-existent known_hosts [ In reply to ]
On Fri, Mar 26, 2021 at 2:42 AM Jim Knoble <jmknoble@pobox.com> wrote:
>
>
> > On Mar 25, 2021, at 20:49, Nico Kadel-Garcia <nkadel@gmail.com> wrote:
> >
> > ?On Wed, Mar 24, 2021 at 5:45 AM Jochen Bern <Jochen.Bern@binect.de> wrote:
> >>
> >>> On 23.03.21 06:42, Nico Kadel-Garcia wrote:
> >>> If I want to delete a hostkey entry, and there is none to be found,
> >>> shouldn't that be considered a successful operation?
> >>
> >> I can think of (easily more than) two scenarios where someone would want
> >> to run such a command in the first place:
> >>
> >> -- An admin performing cleanups on users' known_hosts file after a
> >> server changed keypairs or got decommissioned, where not finding the old
> >> pubkeys in some of the user configs would be expected and ignored
> >>
> >> -- A user who has had strict hostkey checking block his login and tries
> >> to fix the problem, where the command *failing* to (semi-)fix the
> >> problem is something he definitely wants to know about
> >>
> >> You can't have one and the same command do *both*.
> >>
> >> If anything, the reaction of "ssh-keygen -R ..." to a missing
> >> known_hosts file should be consistent with the outcome of it not finding
> >> a matching key therein to delete (which is to output an error message
> >> but still do an exit(0), apparently).
> >
> > This is why I'm suggesting should be the default.
>
> What's wrong with:
>
> ssh-keygen -R hostname || true
>
> ?

Well, for one thing it's sloppy and ignores very real error
conditions, such as ~/.ssh/known_hosts or whatever is the designated
known_hosts file being write protected, but containing the hostname.,
and the remove command failing. One *might* use something like this.

[ ! -s ~/.ssh/known_hosts ] || ssh-keygen -R hostname

But why make me write a shell wrapper and try to outsmart
functionality that can be and, I think should be, embedded in the
ssh-keygen as reporting success. "The hostname key is not in
~/.ssh/known_hosts, yay!!!"
_______________________________________________
openssh-unix-dev mailing list
openssh-unix-dev@mindrot.org
https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev