How to manage my .ssh/known_hosts file
I run an Ubuntu desktop with a bunch of virtual servers in Virtual Box to test stuff out, etc. In the past I have also been connecting to other kinds of remote VPS Linux boxes. Currently my .ssh/known_hosts file has a whole bunch of keys in it, most of which are not being used any more. I want to clean up my .ssh/known_hosts file, but how do I know which key belongs to what host? I.e. how do I know which keys I can safely remove and which ones I should leave alone?
What I found helpful is to sort the file by the fingerprint: cat ~/.ssh/known_hosts | sort -k3 . This is because ssh in many cases (and it is very unclear to me in which situations exactly) makes multiple entries for the same host, and some may have a claertext host name while others will not. When sorted, it will be obvious which host an obscure entry is for, as long as there is also a clear entry for it.
4 Answers 4
To find out which entry is for a known hostname in known_hosts:
To delete a single entry from known_hosts:
Ubuntu by default hashes hostnames the known_hosts file (this is not the default openssh behaviour), to make it difficult for anyone reading the file to know what systems you access.
If you really wanted to clean out the file, simplest option is probably just delete it and check the keys for servers you know as they arise, but really I’d just leave known_hosts alone.
You can stop new hosts entries from being hashed by commenting out the option in /etc/ssh/ssh_config
Cleaning up ~/.ssh/known_hosts also helps when the configuration of the remote host changes and ssh shows a warning. However one should be careful with that and ignore the warnnig only for trusted hosts.
A better option might be to explain how to generate the hash for a specific hostname, allowing him to search for that hash in known_hosts so he can update it.
After above change just add a new entry e.g. by connecting to new server with ssh root@something-new-or-new-dns-alias . This will refresh the original known_hosts file and de-crypt the host names/IPs.
@Cerin, at least by now (2021), the following commands are available: . ssh-keygen -F example.com : shows the known_hosts entry for example.com if it exists, even in hashed form . ssh-keygen -R example.com : removes the known_hosts entry for example.com if it exists, even in hashed form.
If you’ve got a list of all your hosts, you can do something like
ssh-keyscan -t rsa,dsa -f list_of_hosts > ~/.ssh/known_hosts
That will overwrite your .ssh/known_hosts file with a newly generated one based on scanning the hosts.
And also do what theotherreceive suggests; HashKnownHosts is more annoyance than help here.
ssh-keyscan has a very strict formatting rules of the list_of_hosts file. It needs to be be just the addres and no other whitespace then LF after each address. That includes LF after last address. Otherwise you get a lot of trash in the generated file.
I had over 300 stale old entries in my known_hosts file. Not sure that it will work for all systems (or even most systems), but here is my Q&D script. You may have to adjust the matching strings or location.
#!/bin/sh list=`cat ~/.ssh/known_hosts | awk '' |sed -e 's/,/ /g' | sort -u ` listsorted=$(printf "%s\n" $ | sort -u) echo $listsorted #listsorted="10.2.10.1" echo > /tmp/sshstat.txt for host in $listsorted ; do echo $host ssh -oBatchMode=yes -oConnectTimeout=2 root@$ "exit" >/tmp/sshstat.txt 2>&1 ret=$? if [ $ret -ne 0 ]; then echo "Failed: $host" echo sed -i.bak \"/$host/d\" "~/.ssh/known_hosts" | sh else grep "Offending RSA" /tmp/sshstat.txt | sed -e 's/:/ /g' | awk '' | sh fi done #echo $list
Known hosts linux удалить
Вы здесь: Главная страница Админство Удаление хоста с ssh known hosts
Удаление хоста с ssh known hosts
Если Вы работали с сервером по ssh, то наверняка знаете о такой штуке как known hosts. Это та самая штука, которая запоминает отпечатки (fingerprint) всех серверов, которые Вы посещаете и не поволяет сливать пароли и секретные ключи, если отпечаток не совпал. Она просто Вас не пустит дальше, обьясняя это тем, что Вас пытаются обмануть.
Но когда Вы переустанавливаете ОС на сервере и не переносите настройки sshd, то всё будет аналогично. Ну ещё бы, откуда ему знать, что это Вы стали причиной изменения отпечатка.
Тогда нужно стереть запись про этот сервер на клиенте. Проще всего это сделать командой:
Но это удалит данные про все сервера, а нас это не очень то устраивает. Хотя если Вы работаете только с одним сервером, то почему бы и нет. Хотя на практике это крайне редко, даже если Вы думаете иначе.
Нужно ещё добавить, что расположение файла может быть и другим, если в конфиге ssh указано это директивой UserKnownHostsFile.
Если же Вам нужно удалить конкретный хост, то почему бы не открыть файл в текстовом редакторе и не удалить нужную строчку. Ну что, логично и так можно сделать, если у Вас на клиенте не включена опция HashKnownHosts. Если же она включена, то найти нужную строчку будет проблематично.
Но удалить запись всё-таки можно, командой:
Это удалит запись об указанном сервере и можно повторно зайти на него и подтвердить подлинность уже нового отпечатка.
Quickly remove an entry from known_hosts
This is one of the user-friendlier error messages I’ve encountered: What went wrong, possible causes, what to do, pointer to the known_hosts file/line that caused this. When you connect to an existing, well-known server that wasn’t modified, you should check with your friendly admin or hosting provider – in case someone has actually meddled with your server. However, my work on IoT devices involves a lot of SSH’ing to local devices, and frequent teardown/re-flash means they get assigned the same IP address/host name as a previous device – but with a different host key. So each time, OpenSSH will issue its dutiful warning above. I don’t want to disable strict checking completely or on a per-host basis. Removing the offending line by hand each time gets tedious, but luckily OpenSSL’s ssh-keygen can take care of this:
ssh-keygen -R -f "/path/to/.ssh/known_hosts"
Still to much to type on a regular basis. My shell of choice is fish, so I wrapped this in a function rmkh (“remove known host”):
function rmkh -d "removes a given host from ~/.ssh/known_hosts" ssh-keygen -R "$argv" -f "/path/to/.ssh/known_hosts" end
So the next time I get a host verification message, I can just run rmkh
Remove key from known_hosts
I built several virtual machines during the last few weeks. The problem is, the .ssh/known_hosts gives me the Man in the middle warning. This happens because another fingerprint is associated with the virtual machine IP. In the .ssh/known_hosts file, however, I don’t find the record related to the IP, only two bizarre, key-like strings and «ssh-rsa». Does anyone have any ideas about how to remove the old key from known_hosts ?
The «bizarre, key-like strings» you refer to are the hashed hosts/ip addresses. This a security feature which helps stops an intruder from knowing which systems you have access to. If you see this then your ssh_config has HashKnownHosts yes set.
If you feel the file contents are too confusing, you probably have line-wrapping activated. Deactivate it. All lines start with a host name or an IP address.
11 Answers 11
Will modify the file ~/.ssh/known_hosts:6 , removing the 6th line.
In my opinion, using ssh-keygen -R is a better solution for an openssh power user, while your regular Linux admin would do better to keep his/her sed skills fresh by using the above method.
I don’t think it’s a good advice to edit a configuration file manually if you have an official application for that. Taking risks doesn’t make you a pro, finding the quickest and safest option does. It’s like telling people to go ahead and edit /etc/sudoers without visudo . If you want to sharpen your sed skills, go ahead and do that without messing up your system.
«if you have an official application for that» => both ssh-keygen -R and sed -i
A)The deletion of specifically the 6th line, is all very «look no hands». No explanation at all as to what is significant about the 6th line of the file?! B)Also man ssh-keygen mentions ssh-keygen -R hostname you’ve just said ssh-keygen -R with no hostname specified, and you haven’t explained what you mean by that.
When we aren’t using default SSH port, then the hostname for -R should be provided with the following format ‘[
As a rule I agree with other comments that ssh-keygen -R should be used whenever possible. I had issues with that as using the hotsname would delete the new key instead of the old now-offending one. eventually I figured out that I could provide the IP address IP address printed in the ssh error message instead of the hostname, but the sed was next as nothing else was working. Last resort!
There is an ssh-keygen switch ( -R ) for this.
-R hostname
Removes all keys belonging to hostname from a known_hosts file. This option is useful to delete hashed hosts (see the -H option above).
Note: This will change the permissions of the known_hosts file to 0600. If you have a shared known_hosts file for any reason, this could disable the sharing of it.
and the correct one. Also, I had to do [localhost]:port , using the brackets because I used a custom port I guess =/. Like others have said, I would also use the no SSH key-checking approach for my transient/test system development.
This removes all ocurences so the best way. You can add new key with: ssh-keyscan -H my.ssh.server.example.com >> ~/.ssh/known_hosts;
ssh will recreate the file again, but you lose key checking for other hosts!
Or the ssh «man-in-the-middle» message should indicate which line of the known_hosts file has the offending fingerprint. Edit the file, jump to that line and delete it.
Removing the file is a bad advice, it’s like telling someone to buy a new PC because the old one has a broken mouse. Manually editing a file that can be edited by an official application is also a bad idea. The ssh-keygen option was added because of a comment, but with no explanation. I don’t think this answer deserves so many upvotes.
-1 because of the whole «delete the whole known_hosts file» first lines. This is a terrible, terrible, terrible thing to propose, and should be edited out.
You need to run the following command to get rid of this problem. Open the terminal and type the following command:
For all examples below just replace the value after -R :
ssh-keygen -R server-name ssh-keygen -R server.ip.addre.ss ssh-keygen -R 202.54.1.5 ssh-keygen -R server1.example.com
This method has already been suggested in the previous answers. Could you expanded upon what is different in your answer?
@Burgi — this answer gives more detail about the syntax of ssh-keygen -R than any of the other answers so far. It show by example exactly what you can write after -R . So this answer is worthwhile, even though it is not a totally new answer.
@Yitz My comment was made as part of review. At the time (18 months ago) I thought the question needed a little help to make it even better.
All answers are good, but for real SSH pro we have missing information how to remove ssh signature with (non-standard) port number.
- Simple SSH host signature remove command:
and you get warning, and to remove this, you need to use square brackets colon port number:
ssh-keygen -R [example.com]:222
Note, that probably there will be IP record for the same host, so you will need to remove that one also.
Hope this helps for non-standard configuration users.
The warning will tell you the exact line in the known hosts file.
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @ WARNING: POSSIBLE DNS SPOOFING DETECTED! @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ The RSA host key for foo-bar.net has changed, and the key for the corresponding IP address 127.0.0.1 is unchanged. This could either mean that DNS SPOOFING is happening or the IP address for the host and its host key have changed at the same time. Offending key for IP in /home/user/.ssh/known_hosts:6 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
See the /home/user/.ssh/known_hosts:6 part? It specifies the file and line number.