„Dodać poprawny klucz hosta do znanych_hostów” / wiele kluczy hosta ssh na nazwę hosta?

147

Próbując ssh do komputera, który kontroluję, otrzymuję znajomy komunikat:

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@    WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!     @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
Someone could be eavesdropping on you right now (man-in-the-middle attack)!
It is also possible that a host key has just been changed.
The fingerprint for the RSA key sent by the remote host is
[...].
Please contact your system administrator.
Add correct host key in /home/sward/.ssh/known_hosts to get rid of this message.
Offending RSA key in /home/sward/.ssh/known_hosts:86
RSA host key for [...] has changed and you have requested strict checking.
Host key verification failed.

Naprawdę zmieniłem klucz. Przeczytałem kilkadziesiąt postów mówiących, że sposobem na rozwiązanie tego problemu jest usunięcie starego klucza z known_hostspliku.

Ale chciałbym, aby ssh zaakceptował zarówno stary klucz, jak i nowy klucz. Język komunikatu o błędzie („ Add correct host key”) sugeruje, że powinien istnieć sposób na dodanie poprawnego klucza hosta bez usuwania starego.

Nie udało mi się dowiedzieć, jak dodać nowy klucz hosta bez usunięcia starego.

Czy to możliwe, czy też komunikat o błędzie jest po prostu bardzo mylący?

Samuel Edwin Ward
źródło
9
To jest klucz hosta, który generuje błąd. Host powinien mieć jeden i tylko jeden klucz. Nie ma to nic wspólnego z kluczami klienta lub użytkownika. Czy masz jeden adres IP, który pływa między różnymi hostami lub coś takiego?
David Schwartz
4
W moim przypadku wiem, że w najbliższej przyszłości będę często przełączać się między dwoma kluczami, jednocześnie bawiąc się niektórymi rzeczami. Wydaje się, że byłoby to również przydatne w jednym adresie IP z sugerowaną sytuacją wielu hostów. Przede wszystkim chcę tylko wiedzieć, czy jest to możliwe dla mojej własnej edukacji poza jakimkolwiek konkretnym praktycznym zastosowaniem.
Samuel Edwin Ward

Odpowiedzi:

148
  1. pobierz klucz rsa swojego serwera, gdzie server_ipjest adres IP twojego serwera, taki jak 192.168.2.1:

    $ ssh-keyscan -t rsa server_ip
    

    Przykładowa odpowiedź:

    # server_ip SSH-2.0-OpenSSH_4.3
    server_ip ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAwH5EXZG...
    
  2. a na kliencie skopiuj całą linię odpowiedzi server_ip ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAwH5EXZG...i dodaj ten klucz na dole ~/.ssh/known_hostspliku:

    server_ip ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAqx9m529...(the offending key, and/or the very bottom of the `known_hosts` file)
    server_ip ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAwH5EXZG... (line you're adding, copied and pasted from above)
    
kwanty
źródło
12
To zadziałało! Jednak używam „HashKnownHosts”, więc wpis wyglądał trochę nie na miejscu. Na szczęście ssh_config (5) wskazał mi ssh-keygen (1), który wyjaśnił, że mogę użyć „ssh-keygen -H” do mieszania niepowiązanych wpisów. Dziękuję Ci!
Samuel Edwin Ward
2
To „działa”, ale nie weryfikujesz klucza, więc jesteś podatny na ataki mitm ...
JasperWallace
3
@JasperWallace, o ile pierwszy etap odbywa się przez bezpieczne połączenie (na przykład przy użyciu localhost) powinno być dość bezpieczne, myślę
ony
3
Czy jest jakiś sposób na zebranie wszystkich typów kluczy z serwera? Czasami nie wiesz, czy są to RSA, DSA, ECDSA, RSA1 ... itd.
Sopalajo de Arrierez
3
@SopalajodeArrierez ta sama strona mówi również, że możesz oddzielać typy przecinkami, więc rób ssh-keyscan -t rsa1,dsa,rsa,ecdsa,ed25519 server_ip- ale jedynym powodem do znalezienia rsa1i dsakluczy jest zidentyfikowanie serwerów, które wymagają aktualizacji / rekonfiguracji
kbolino
94

Usuń wpis ze znanych hostów za pomocą:

ssh-keygen -R *ip_address_or_hostname*

Spowoduje to usunięcie problematycznego adresu IP lub nazwy hosta z pliku znane_hosty i ponowne nawiązanie połączenia.

Ze stron podręcznika:

-R hostname
Usuwa wszystkie klucze należące do nazwy hosta z pliku znane_hosty. Ta opcja jest przydatna do usuwania mieszanych hostów (patrz opcja -H powyżej).

Luis Abarca
źródło
11
„jak dodać nowy klucz hosta bez usuwania starego”.
Samuel Edwin Ward
4
To najlepsze rozwiązanie!
Thomas Decaux,
8
Jak to ma 19 głosów? Odpowiedź na zadane pytanie nie jest bliska…
Molomby,
2
Twoje pytanie pojawia się na drugim miejscu, kiedy wyszukuję w Google „automatyczny klucz hosta aktualizacji git ssh”. Ta odpowiedź była tym, czego szukałem. Otwarcie nowego pytania z dokładnie tym, czego chcę, może zostać zamknięte jako duplikat.
Jason Goemaat
Działa też
nazwa
18

Bardzo prosty sposób to:

cp ~/.ssh/known_hosts ~/.ssh/known_hosts.bak

Następnie edytuj znane_hosty, aby wyczyścić oryginalny klucz, a następnie ssh do hosta, używając:

ssh name@computer

Automatycznie doda nowy klucz; następnie porównaj dwa pliki. Program taki jak meld to dobry sposób na porównanie dwóch plików. Następnie scal pliki, aby znane_hosty zawierały oba klucze

Mój „powód” utrzymywania dwóch kluczy polega na tym, że system docelowy jest uruchamiany wielopunktowo, chociaż śmiem twierdzić, że istnieje sposób synchronizacji kluczy między instalacjami, wydaje się, że dopuszczenie wielu kluczy jest prostsze.

EDYCJA 2015/06

Powinienem dodać, powracając do tego teraz, że zauważam jeszcze prostszy sposób [dopóki wpis jest możliwy do zidentyfikowania, zwykle z nazwy hosta / adresu IP całkiem oprócz komunikatu o błędzie odnoszącego się do jego konkretnej lokalizacji];

  1. Edytuj znane_hosty, aby tymczasowo dodać # na początku „starego” wpisu do znanych_hostów
  2. Połącz [ssh z hostem], zgódź się na monit o dodanie nowego klucza „automatycznie”
  3. Następnie ponownie edytuj znane hosty, aby usunąć #

Istnieje nawet opcja HostKeyAlias ​​jak w

ssh -o HostKeyAlias=mynewaliasforthemachine name@computer

następnie, po tym, jak klient ssh doda nowy klucz pod aliasem, możesz albo edytować znane_hosty, aby zastąpić alias `` prawdziwą '' nazwą hosta / adresem IP, albo połączyć się z tym wcieleniem tego hosta za pomocą opcji aliasu

znak
źródło
Ten „stop”? meldmerge.org
Samuel Edwin Ward
to jest połączenie :) nazwa instalacji apt-get / yum to po prostu połączenie
Mark
Zrobiłem wariant twojej sugestii, który działał dobrze - zamiast cp, mv, następnie ssh, następnie cat ~ / .ssh / known_hosts.bak ~ / .ssh / known_hosts> tmp; mv tmp ~ / .ssh / known_hosts
Peter N Lewis
6

Mam ten sam problem z Raspberry Pi, który uruchamiam z kilkoma różnymi systemami (system deweloperski do kompilacji plików binarnych, projektu, xbmc itp.) I napotkałem ten sam problem. Używają DHCP w sieci lokalnej, a mój router zawsze używał tego samego adresu IP, ponieważ adres MAC był taki sam. Rozwiązałem go, używając różnych nazw domen w pliku hosts:

10.10.10.110 pi-dev
10.10.10.110 pi-xbmc
10.10.10.110 pi-etc

Plik znane_hosty zapisuje odciski palców według nazwy hosta, więc nawet jeśli jest to ten sam adres IP, każda unikalna nazwa hosta otrzymuje inny wpis.

Mam dość dodawania nazw do plików hostów za każdym razem, gdy korzystam z nowego systemu, więc wymyśliłem jeszcze bardziej leniwy sposób, używając początkowych zer na adresach IP, takich jak:

$ ssh [email protected]
$ ssh [email protected]
$ ssh [email protected]

Każda odmiana (niekanonizowanego) adresu IP otrzymuje własny wpis w znanych_hostach.

Mikrofon
źródło
1
Ludzie OpenSSH zrozumieli, że ta luka nie działa już w nowszych wersjach.
Mike
Można użyć CheckHostIP now ~/.ssh/configaby móc nadal korzystać z luki. Możesz nawet zdefiniować tam swoje aliasy, abyś nie musiał się bawić /etc/hostsi definiować CheckHostIP notylko dla tych 3 nazw hostów.
GnP
3

Jeśli zarówno klient, jak i serwer mają OpenSSH 6.8 lub nowszy, możesz użyć tej UpdateHostKeys yesopcji w swoim ssh_configlub ~/.ssh/config. Na przykład:

Host *
    UpdateHostKeys yes

To powoduje, że SSH przechowuje wszystkie klucze hosta, których potrzebuje serwer known_hosts, a gdy serwer zmienia lub usuwa jeden klucz hosta, klucz ten jest również zmieniany lub usuwany w twoim known_hosts.

Mikaela
źródło
To zdecydowanie najbardziej przydatna odpowiedź! Chociaż nie oferuje on jednoznacznie sposobu rozwiązania pierwotnego pytania, jeśli klucz hosta został już zmieniony, wszystkie pozostałe odpowiedzi są niepewne, ponieważ nie weryfikują nowego klucza hosta. Ta opcja umożliwia bezpieczne przechodzenie na nowe klucze hosta.
Jaap Eldering
1

Nie rozumiem, dlaczego chcesz pracować z dwoma kluczami, ale z pewnością możesz dodać więcej niż jeden prawidłowy klucz do ~/.ssh/known_hostspliku, ale musisz to zrobić ręcznie.

Innym rozwiązaniem może być użycie StrictHostKeyChecking=noopcji dla tego konkretnego hosta:

ssh -o StrictHostKeyChecking=no user@host

który możesz umieścić w swoim aliasie ~/.profilelub coś podobnego.

alias hc=ssh -o StrictHostKeyChecking=no user@host
Sven
źródło
StrictHostKeyChecking nie wydaje się w tym przypadku pomagać; najwyraźniej określa tylko zachowanie, gdy hosta nie ma w pliku znane_hosty. Wspomniano tutaj: gossamer-threads.com/lists/openssh/dev/45349#45349
Samuel Edwin Ward
To działa tutaj. Otrzymasz ostrzeżenie, ale logowanie będzie kontynuowane.
Sven
To dziwne. Czy używasz uwierzytelniania za pomocą hasła? Czy korzystasz z OpenSSH?
Samuel Edwin Ward
1

Jeśli używasz tylko ssh w sieci lokalnej, to ...

Prostym rozwiązaniem jest wyczyszczenie starego pliku klucza i zastąpienie go pustym. Umożliwi to ponowne autoryzowanie wszystkich połączeń za pomocą nowych kluczy. Jeśli masz klucze ssh przechowywane dla witryn poza siecią lokalną, musisz upewnić się, że Twoje początkowe połączenie jest bezpieczne, tak jak podczas pierwszego połączenia z tym serwerem.

na przykład

cp known_hosts known_hosts.old
rm known_hosts
nano known_hosts

Następnie naciśnij spację, backspace cntl + x i 'y', aby zapisać nowy bufor (plik). Jest to zła praktyka, ale dobrze, pod warunkiem, że nie regularnie wysyłasz wiadomości poza lokalną sieć (np. Serwer uni lub work)

W bezpiecznej sieci lokalnej jest to bezpieczne, ponieważ po prostu nie można dostać się do człowieka w środku ataku.

Zawsze lepiej jest używać kodu, który rozumiesz!

Aaron
źródło
4
Wyczyszczenie całego known_hostspliku za każdym razem spowoduje zanegowanie większości zabezpieczeń zapewnianych w inny sposób przez ssh.
kasperd
Rzeczywiście, argumentowałbym, że w bezpiecznej sieci wewnętrznej bezpieczniej jest zrozumieć swój kod i obejść zabezpieczenia, niż bezmyślnie kopiować kod. W sieci zewnętrznej sytuacja wyglądałaby inaczej.
Aaron
-1

Tak wiele odpowiedzi, ale tak wiele, które rezygnują z ochrony, całkowicie wyłączając ścisłe sprawdzanie hosta lub niszcząc niepowiązane informacje o hostie lub zmuszając użytkownika do interaktywnego akceptowania kluczy, być może w późniejszym czasie, gdy jest to nieoczekiwane.

Oto prosta technika, która pozwala ci pozostawić ścisłe sprawdzanie hosta, ale zaktualizuj klucz w kontrolowany sposób, gdy spodziewasz się zmiany:

  • Usuń stary klucz i zaktualizuj jednym poleceniem

    ssh-keygen -R server.example.com && \
        ssh -o StrictHostKeyChecking=no server.example.com echo SSH host key updated.
    
  • Powtórz z adresami IP lub innymi nazwami hostów, jeśli ich używasz.

Zaletą tego podejścia jest to, że ponownie uruchamia serwer dokładnie raz. Większość wersji ssh-keygen wydaje się nie zwracać błędu, jeśli serwer, który próbujesz usunąć, nie istnieje w znanym pliku hosts, jeśli jest to dla ciebie problem, użyj dwóch poleceń po kolei.

Podejście to sprawdza również łączność i wysyła ładną wiadomość do dzienników w komendzie ssh (która loguje się, aktualizuje klucz hosta i wysyła zaktualizowany klucz hosta SSH , a następnie natychmiast kończy działanie.

Jeśli twoja wersja ssh-keygen zwraca niezerowy kod wyjścia, a wolisz sobie z tym poradzić bez błędu, niezależnie od wcześniejszego połączenia, po prostu użyj dwóch poleceń w kolejności, ignorując wszelkie błędy polecenia ssh-keygen.

Jeśli użyjesz tej techniki, nigdy nie musisz zmieniać komendy ssh ani wyłączać sprawdzania hosta, z wyjątkiem tej jednej komendy ssh. Możesz być pewien, że przyszłe sesje ssh będą działać bez konfliktu lub konieczności jawnego przyjęcia nowego klucza, o ile powyższe polecenie ssh działało bezbłędnie.

markgo2k
źródło
-3

Miałem ten sam problem.

Wszystko, co zrobiłem, to sudo nano /home/user/.ssh/ host_allowusunąłem klucz.

Kiedy wróciłem do serwera, dodałem nowy klucz.

David
źródło
2
Przydałoby się więcej informacji na temat tego, dlaczego tak się dzieje.
Drew Khoury
-4

Użyj polecenia sed, aby usunąć linię obrażającą

OUTPUT: as show in above example
Offending key in /home/user/.ssh/known_hosts:86

Usuń wiersz 86, jak wspomniano w znanych hostach.

CODE: 
sed -i '86d' /home/user/.ssh/known_hosts

Następnym razem podczas uzyskiwania dostępu za pomocą ssh, system automatycznie doda nowy klucz.

nowsze wersje ssh

posługiwać się:

ssh-keygen -R <hostname|ip address>

Spowoduje to usunięcie wpisu nazwy hosta i wykonanie kopii zapasowej starej .known_hostjakoknown_hosts.old

Viikram Simha
źródło
4
„Chciałbym, aby ssh zaakceptował zarówno stary klucz, jak i nowy klucz.” Twoja odpowiedź tego nie robi.
Samuel Edwin Ward