Das Symptom
Ein neuer Server, ein frisch eingetragener öffentlicher Schlüssel, und die erste
Verbindung endet mit Received disconnect from …: Too many authentication failures,
bevor überhaupt ein Passwort abgefragt wurde. Gegen den alten Server klappt dieselbe
Anmeldung weiterhin. Der Schlüssel wird daraufhin neu erzeugt, neu hochgeladen, die
Rechte auf .ssh werden zum vierten Mal auf 700 gesetzt, und nichts ändert sich.
Das Verwirrende: Der Server lehnt nicht den richtigen Schlüssel ab. Er kommt gar nicht bis zu ihm.
Die „Layer 8“-Wahrheit
Der Client ist zu hilfsbereit. Läuft ein Agent, bietet ssh dem Server nacheinander
jeden Schlüssel an, den der Agent hält. Für den Server ist jeder abgelehnte Schlüssel ein gescheiterter
Anmeldeversuch, und davon erlaubt er nur eine begrenzte Zahl. Die Handbuchseite zu
sshd_config sagt es knapp: „Specifies the maximum number of authentication attempts
permitted per connection.“ Der Vorgabewert ist 6. Wer acht Schlüssel im Agenten hat und
der passende steht an siebter Stelle, verbraucht die sechs Versuche mit Schlüsseln, die
auf diesem Server nie jemand eingetragen hat. Danach trennt der Server die Verbindung;
zum Passwort kommt es nicht mehr.
Deshalb klappt es gegen den alten Server: Dessen Schlüssel kommt an die Reihe, bevor das Kontingent verbraucht ist; der für den neuen Server nicht. Und deshalb ändert das Neuerzeugen nichts, denn an der Zahl der angebotenen Fremdschlüssel ändert es nichts. Der Server sieht in seinem Protokoll ab dem dritten Fehlschlag jeder Verbindung einen Eintrag, denn laut Handbuchseite gilt: „Once the number of failures reaches half this value, additional failures are logged.“ Ein Administrator, der dort nachsieht, hält den eigenen Kollegen für einen Angreifer mit einem Bündel geratener Schlüssel. Technisch stimmt das sogar.
Die Lösung liegt auf dem Client, nicht auf dem Server. IdentitiesOnly yes in der
ssh_config sorgt laut Handbuchseite dafür, dass ssh nur die konfigurierten
Identitätsdateien verwendet, selbst wenn der Agent, ein PKCS11Provider oder ein
SecurityKeyProvider weitere Identitäten anbietet. Die Seite nennt den Zweck selbst:
„This option is intended for situations where ssh-agent offers many different
identities.“ Zusammen mit IdentityFile im Host-Block bietet der Client dann genau einen
Schlüssel an, und der erste Versuch ist der richtige. Der Agent darf den Schlüssel
weiter entsperrt halten; eingeschränkt wird, was angeboten wird, nicht, woher der
private Teil kommt.
MaxAuthTries auf dem Server hochzusetzen ist die bequeme falsche Antwort. Die
Grenze ist ein Schutz gegen Durchprobieren, und die Protokollschwelle bei der Hälfte
des Werts wandert mit. Wer den Wert anheben muss, kann ihn laut Handbuchseite in
einem Match-Block auf bestimmte Nutzer oder Herkunftsadressen beschränken, statt
ihn allen zu schenken. Aber der Server tat die ganze Zeit, was er sollte. Er hat nur
gezählt.