✦ Oplossingen · Server- en developerfouten

REMOTE HOST IDENTIFICATION HAS CHANGED: Host key verification failed

SSH meldt ‘REMOTE HOST IDENTIFICATION HAS CHANGED!’ en ‘Host key verification failed’? Lees wanneer het onschuldig is, wanneer niet, en hoe je het oplost.

Zo ziet de foutmelding eruit

  • @ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @
  • IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
  • Host key verification failed.
  • Offending ED25519 key in /home/user/.ssh/known_hosts:12
  • The authenticity of host 'server.voorbeeld.nl (203.0.113.10)' can't be established.
  • fatal: Could not read from remote repository.

Waarom gebeurt dit?

Elke SSH-server heeft een eigen sleutel, de host key. De eerste keer dat je verbinding maakt, vraagt SSH of je die server vertrouwt en bewaart hij de vingerafdruk (fingerprint) van die sleutel in ~/.ssh/known_hosts. Bij elke volgende verbinding vergelijkt SSH de sleutel met wat het heeft bewaard. Is die anders, dan stopt SSH met de grote waarschuwing REMOTE HOST IDENTIFICATION HAS CHANGED! en weigert het met Host key verification failed.

Die controle beschermt je tegen een ‘man-in-the-middle’-aanval: iemand die zich tussen jou en de server plaatst en zich voordoet als die server, om je wachtwoord of je verkeer te onderscheppen. Daarom is de melding zo nadrukkelijk. Meestal is er echter een onschuldige reden: de server is opnieuw geïnstalleerd, verhuisd naar een andere machine, het IP-adres is aan een andere server gegeven, of de beheerder heeft de sleutels bewust vervangen.

Host key verification failed komt ook zonder de grote waarschuwing voor, bijvoorbeeld in een script, cronjob of buildstraat. Dan is de server nog helemaal niet bekend in known_hosts en kan SSH je niet vragen of je hem vertrouwt, omdat er niemand is om ‘yes’ te typen. Of het bestand known_hosts is niet leesbaar voor de gebruiker waaronder het script draait.

Zo herken je dit probleem

  • Je ziet een kader van @-tekens met ‘REMOTE HOST IDENTIFICATION HAS CHANGED’ en een regel ‘Offending … key in …known_hosts:nummer’.
  • Het gaat om de sleutel van de server. Gaat het om jóúw sleutel, dan zie je ‘Permission denied (publickey)’: zie Permission denied (publickey).
  • In een script, cronjob of deploy zie je alleen ‘Host key verification failed.’: dan is de server meestal nog niet bekend voor die gebruiker. Zie ook cronjob draait niet.
  • Werkt dezelfde verbinding vanaf een andere computer of een ander netwerk zonder waarschuwing, wees dan extra voorzichtig: dan kan het netwerk waarop je zit het verkeer omleiden.

Zo los je het op, stap voor stap

Menunamen kunnen per versie of toestel iets anders heten. Loop de stappen op volgorde af en stop zodra het werkt.

  1. Stop en zoek uit waarom de sleutel veranderde

    Typ geen wachtwoord en ga niet verder. Vraag je af of er iets aan de server is gebeurd: opnieuw geïnstalleerd, verhuisd, een nieuw IP-adres, een andere server achter dezelfde naam. Vraag het de beheerder of je hostingpartij als je het niet zelf weet. Is er geen verklaring, behandel het dan als een mogelijk probleem.

  2. Vergelijk de vingerafdruk via een ander kanaal

    SSH toont in de waarschuwing de vingerafdruk van de nieuwe sleutel, bijvoorbeeld SHA256:…. Vergelijk die met een vingerafdruk die je via een ánder kanaal krijgt: de beheerder die hem op de server zelf opvraagt, het beheerpaneel of de console van je server, of bij GitHub en GitLab de officiële documentatie met hun vingerafdrukken. Komen ze overeen, dan is de wijziging echt.

    # op de server zelf (via console of bestaande sessie):
    ssh-keygen -lf /etc/ssh/ssh_host_ed25519_key.pub
  3. Verwijder de oude sleutel uit known_hosts

    Is de nieuwe sleutel bevestigd, verwijder dan de oude regel. ssh-keygen -R haalt alle bewaarde sleutels voor die naam weg en maakt een reservekopie (known_hosts.old). Doe het voor de hostnaam én voor het IP-adres als je beide gebruikt, en vermeld een afwijkende poort tussen blokhaken.

    ssh-keygen -R server.voorbeeld.nl
    ssh-keygen -R 203.0.113.10
    ssh-keygen -R "[server.voorbeeld.nl]:2222"
  4. Maak opnieuw verbinding en accepteer de nieuwe sleutel

    Maak opnieuw verbinding. SSH vraagt dan ‘Are you sure you want to continue connecting (yes/no/[fingerprint])?’ en toont de vingerafdruk. Controleer die nog één keer tegen wat je in stap 2 kreeg en typ pas dan yes. Je kunt ook de vingerafdruk zelf plakken; SSH vergelijkt hem dan voor je.

    ssh gebruiker@server.voorbeeld.nl
    
    # voor Git-hosting:
    ssh -T git@github.com
  5. Script of cronjob: zet de sleutel vooraf klaar

    Een script kan geen vraag beantwoorden. Voeg de sleutel daarom eenmalig en gecontroleerd toe aan known_hosts van de gebruiker waaronder het script draait (dat is vaak een andere gebruiker dan jij, bijvoorbeeld www-data of root). Met ssh-keyscan haal je de sleutel op; vergelijk de vingerafdruk met ssh-keygen -lf voordat je hem toevoegt. Met ssh-keygen -F kijk je of een host al bekend is.

    ssh-keyscan -t ed25519 server.voorbeeld.nl > /tmp/hostkey
    ssh-keygen -lf /tmp/hostkey
    cat /tmp/hostkey >> ~/.ssh/known_hosts
    ssh-keygen -F server.voorbeeld.nl
  6. Controleer de rechten van known_hosts

    Draait het script onder een andere gebruiker, kijk dan of die gebruiker een eigen ~/.ssh/known_hosts heeft en die kan lezen. Een bestand dat van root is in de map van een andere gebruiker, geeft ook ‘Host key verification failed’.

    ls -l ~/.ssh/known_hosts
    sudo -u www-data ssh -T git@github.com
  7. Beheerder: kondig sleutelwijzigingen aan

    Installeer je een server opnieuw, bewaar dan de oude host keys (/etc/ssh/ssh_host_*) en zet ze terug, of laat gebruikers vooraf weten dat de sleutel verandert en wat de nieuwe vingerafdruk is. Zo leer je niemand om de waarschuwing blind weg te klikken.

Let op: Zet StrictHostKeyChecking niet uit en verwijs UserKnownHostsFile niet naar /dev/null om de melding kwijt te raken. Dan schakel je precies de bescherming uit die je tegen een onderschepte verbinding moet waarschuwen, ook voor alle volgende keren.

Onschuldig of een aanval?

Je kunt aan de melding zelf niet zien of er iets kwaadaardigs gebeurt. Het verschil zit in de verklaring die je ervoor hebt.

  • Waarschijnlijk onschuldig: de server is aantoonbaar opnieuw geïnstalleerd of verhuisd, de beheerder heeft het aangekondigd, of de vingerafdruk komt overeen met wat de beheerder of de officiële documentatie opgeeft.
  • Verdacht: niemand weet van een wijziging, het gebeurt alleen op een bepaald netwerk (hotel, openbare wifi), of de vingerafdruk komt niet overeen met wat de beheerder op de server zelf ziet.

Bij twijfel: log niet in, gebruik geen wachtwoord en neem contact op met de beheerder via een ander kanaal.

Wanneer schakel je hulp in?

  • Je weet niet waarom de sleutel van je server veranderd is en niemand kan het verklaren.
  • Een uitrolscript of cronjob faalt op ‘Host key verification failed’ en je weet niet onder welke gebruiker het draait.
  • Je hebt de server opnieuw laten installeren en wilt de oude host keys terugzetten of veilig vervangen.
  • Je vermoedt dat iemand je verbinding onderschept en wilt nagaan of er al ingelogd is.

Lukt het niet? Wij helpen

Kom je er met deze stappen niet uit, of wil je het liever niet zelf doen? We kijken online mee of komen langs. Hulp op afstand kost €20 per uur; komen we langs, dan is de prijs op aanvraag. Je weet vooraf waar je aan toe bent.

Aanvraag

Hulp aanvragen

Schrijf kort wat er misgaat en wat je al hebt geprobeerd. Kies of we bellen, online meekijken of langskomen.

Veelgestelde vragen

Vragen over dit probleem

Is ‘REMOTE HOST IDENTIFICATION HAS CHANGED’ altijd een hack?

Nee, meestal is de server opnieuw geïnstalleerd of verhuisd. Maar je kunt het pas weten als je de nieuwe vingerafdruk via een ander kanaal hebt gecontroleerd.

Hoe verwijder ik de oude sleutel?

Met ssh-keygen -R hostnaam. Dat haalt de oude regels voor die host uit known_hosts en maakt een reservekopie.

Mag ik StrictHostKeyChecking uitzetten?

Liever niet. Daarmee accepteer je voortaan elke sleutel, ook die van een aanvaller. Zet in scripts de juiste sleutel vooraf in known_hosts.

Waarom faalt mijn cronjob wel en werkt het in de terminal?

De cronjob draait vaak onder een andere gebruiker, met een eigen known_hosts waarin de server nog niet staat. Voeg de sleutel voor die gebruiker toe.