Dacă autentificările SSH sau SFTP au început să eșueze imediat după un upgrade la OpenSSH 10, cauza obișnuită nu este firewall-ul, utilizatorii sau subsistemul SFTP. Problema este schimbul de chei. OpenSSH 10 dezactivează implicit în sshd metodele finite-field Diffie-Hellman vechi, așa că clienții mai vechi încep brusc să eșueze cu erori de tipul Unable to negotiate with x.x.x.x port 22: no matching key exchange method found. Dacă acel client oferă doar metode legacy precum diffie-hellman-group14-sha1 sau diffie-hellman-group1-sha1, transportul SSH nu se finalizează niciodată. Din acest motiv eșuează și SFTP, pentru că SFTP rulează peste SSH. Subsistemul nu este niciodată atins.

Din experiența noastră administrând servere Linux în producție, acesta este exact tipul de incident care apare în timpul refresh-urilor de sistem de operare, migrațiilor de panou și rebuild-urilor de VPS. Totul pare în regulă până când un vechi pachet de contabilitate, un dispozitiv embedded sau un client de transfer fișiere de la un partener nu se mai poate conecta. Atunci afli că „legacy” în SSH înseamnă încă „folosit activ undeva în business-ul tău”. Debian 13 face acest lucru mai frecvent, pentru că livrează OpenSSH 10 în stack-ul implicit. Dacă îți refaci sistemele acum, această clasă de incidente este normală. Nu este ipotetică.

Remedierea este simplă, dar trebuie făcută atent. Reactivezi cel mai mic set posibil de KEX legacy, validezi schimbarea din loguri și îți faci un plan de ieșire. Nu lipi orbește în sshd_config toate algoritmii slabi. Asta este lene, și îți lărgește suprafața de atac fără niciun motiv.

Ce s-a schimbat de fapt în OpenSSH 10

OpenSSH 10 a schimbat valorile implicite ale serverului. Partea importantă este aceasta: sshd nu mai oferă implicit familiile finite-field Diffie-Hellman vechi. Pe un server Debian 13 actualizat, un client legacy care încă depinde de una dintre aceste metode poate eșua înainte să înceapă autentificarea.

  • diffie-hellman-group14-sha1 era deja pe cale de dispariție de ani de zile și nu mai face parte din setul implicit.
  • Metodele diffie-hellman-group-exchange-* sunt și ele eliminate din oferta implicită a serverului în OpenSSH 10.
  • Dacă acel client legacy nu are nicio suprapunere cu noul set implicit de KEX, conexiunea moare în timpul negocierii.
  • SFTP este afectat pentru că folosește același strat de transport SSH.

O greșeală operațională comună este să dai vina pe SFTP în sine. Asta este greșit. Dacă transportul SSH nu poate cădea de acord asupra KEX, nu există sesiune SFTP, nu există problemă de chroot, nu există problemă de internal-sftp și nu există problemă de permisiuni de fișiere pe care să o depanezi. Primul lucru pe care îl verificăm este întotdeauna eșecul de negociere din logurile SSH.

Simptomele exacte pe care le vei vedea

Pe partea de client vei vedea de obicei una dintre acestea:

Unable to negotiate with 203.0.113.10 port 22: no matching key exchange method found.
Their offer: diffie-hellman-group14-sha1

Unable to negotiate with 203.0.113.10 port 22: no matching key exchange method found.
Their offer: diffie-hellman-group1-sha1,diffie-hellman-group14-sha1

Connection closed by remote host

Pe partea de server, de obicei vei găsi dovezile utile într-unul dintre aceste locuri:

  • journalctl -u ssh pe distribuțiile bazate pe systemd
  • /var/log/auth.log pe Debian și Ubuntu dacă rsyslog este activ
  • /var/log/secure pe sistemele bazate pe RHEL
journalctl -u ssh -n 100 --no-pager
grep -i "no matching key exchange method found" /var/log/auth.log
grep -i "Unable to negotiate" /var/log/auth.log

Linia utilă este cea care îți spune ce a oferit clientul. Acea listă îți determină remedierea. Dacă logul arată doar diffie-hellman-group14-sha1, ai o problemă de compatibilitate mai îngustă. Dacă arată group1 și doar schimburi vechi bazate pe SHA1, clientul este mult mai vechi și răspunsul corect poate fi „înlocuiește-l”, nu „slăbește în continuare serverul”.

Nu începe cu un rollback global făcut orbește

Remedierea proastă este să arunci înapoi în sshd_config o listă lungă de algoritmi depășiți și să consideri problema rezolvată. Asta funcționează, dar este genul de scurtătură care rămâne ani de zile. Remedierea corectă începe cu oferta exactă a clientului pe care ai văzut-o în loguri.

  • Dacă acel client oferă diffie-hellman-group14-sha1, începe de acolo.
  • Dacă acel client suportă și ceva mai bun, folosește acel ceva mai bun.
  • Dacă acel client funcționează doar cu diffie-hellman-group1-sha1, tratează asta ca pe o excepție de ultimă instanță.
  • Dacă este vorba de o integrare cu un partener sau un proces intern batch, pune un owner și o dată de retragere pe excepția respectivă.

După suficiente revizuiri de incidente, modelul este evident. Excepțiile temporare de compatibilitate SSH tind să devină permanente dacă nimeni nu notează de ce există și cine ar trebui să le elimine.

Runbook: reactivează minimul necesar de KEX legacy în sshd_config

Fă mai întâi backup la fișier.

cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak.$(date +%F-%H%M%S)

Apoi adaugă algoritmul cel mai puțin rău care corespunde clientului care eșuează. În majoritatea cazurilor, începi cu diffie-hellman-group14-sha1.

# /etc/ssh/sshd_config
KexAlgorithms +diffie-hellman-group14-sha1

Validează sintaxa înainte de reload.

sshd -t

Dacă sintaxa este curată, dă reload.

systemctl reload ssh

Pe sistemele Debian-based, ssh este de obicei numele corect al unității. Pe unele build-uri poate fi sshd. Nu ghici. Verifică.

systemctl status ssh
systemctl status sshd

Apoi testează din nou de pe clientul care eșua sau reproduce scenariul de pe un client modern forțând aceeași constrângere de KEX.

ssh -oKexAlgorithms=diffie-hellman-group14-sha1 user@server
sftp -oKexAlgorithms=diffie-hellman-group14-sha1 user@server

Dacă funcționează, oprește-te acolo. Nu adăuga mai mult.

Când group14-sha1 nu este suficient

Unii clienți vechi nu oferă nimic dincolo de diffie-hellman-group1-sha1 sau de variante vechi de group-exchange. Aici ai nevoie de judecată.

  • Opțiunea mai bună: înlocuiești sau actualizezi clientul.
  • Stopgap acceptabil: activezi temporar încă o metodă, o documentezi și limitezi expunerea.
  • Idee proastă: arunci înapoi în valorile globale group1, cifruri CBC vechi și MAC-uri vechi fără niciun control.

Dacă chiar trebuie să suporți pentru scurt timp un endpoint foarte vechi, configurația poate arăta așa:

# /etc/ssh/sshd_config
KexAlgorithms +diffie-hellman-group14-sha1,+diffie-hellman-group1-sha1

Asta arată urât. Trateaz-o ca pe un workaround de incident, nu ca pe o alegere de design.

Din experiența noastră, primul lucru care se strică după ce reactivezi KEX vechi nu este întotdeauna KEX în sine. De multe ori este etapa următoare de negociere. Un client care are nevoie de group1 poate avea nevoie și de suport vechi pentru host key sau cipher. Dacă vezi că eroarea se mută de la eșec KEX la nepotrivire de host key sau cipher, acela este semnalul că acel client este prea vechi ca să mai merite acomodare pe un serviciu SSH general-purpose, expus la internet.

Greșeala pe care o fac oamenii cu blocurile Match

Asta contează, pentru că multe articole de blog o spun greșit. Nu poți folosi un bloc normal Match Address în același sshd_config pentru a limita KexAlgorithms la o sursă legacy după IP. Sună elegant, dar nu funcționează așa cum cred mulți.

De ce? Pentru că schimbul de chei are loc înainte de autentificarea utilizatorului și înainte de mare parte din logica post-handshake pentru care este gândit Match. Manualul OpenSSH reflectă exact această realitate. Match acceptă doar un subset de directive, iar KexAlgorithms nu este una dintre ele. Așa că dacă cineva îți spune să repari asta cu:

Match Address 198.51.100.25
    KexAlgorithms +diffie-hellman-group14-sha1

aceea nu este o remediere reală pe partea de server.

Acesta este unul dintre acele detalii care apar doar când testezi efectiv problema în loc să copiezi sfaturi din articole generice despre hardening SSH. Abordarea corectă pentru limitare este alta.

Cum limitezi corect compatibilitatea SSH legacy

Dacă chiar trebuie să limitezi suportul legacy, ai în practică două opțiuni realiste.

  • Rulezi un listener SSH separat pe un IP dedicat sau pe un port nestandard, cu excepția de KEX legacy.
  • Păstrezi excepția pe listener-ul principal doar temporar și restricționezi prin firewall IP-urile sursă până când înlocuiești clientul.

Modelul cu listener separat este mai curat. Exemplu:

# sshd_config principal
Port 22
ListenAddress 0.0.0.0

# instanță legacy pe portul 2222 sau pe IP dedicat
# fișier separat, de exemplu /etc/ssh/sshd_config_legacy
Port 2222
ListenAddress 203.0.113.10
KexAlgorithms +diffie-hellman-group14-sha1
PasswordAuthentication no
PermitRootLogin no
AllowUsers legacy-sftp-user
Subsystem sftp internal-sftp

Apoi îl combini cu reguli de firewall care permit doar IP-ul partenerului sau intervalul IP al acelui birou să ajungă la listener-ul legacy.

Dacă nu poți justifica acel efort suplimentar de curățenie, fii sincer cu tine. Ceea ce faci nu este o excepție chirurgicală. Este o slăbire globală a serviciului SSH.

Validează din loguri, nu din presupuneri

După ce faci schimbarea, testează din ambele părți și urmărește logurile live.

journalctl -u ssh -f

ssh -vvv user@server
sftp -vvv user@server

Ce vrei să confirmi:

  • Eroarea anterioară de KEX dispare.
  • Sesiunea ajunge acum la autentificare.
  • Subsistemul SFTP pornește corect dacă use case-ul este transferul de fișiere.
  • Nicio nouă eroare de host key sau cipher mismatch nu o înlocuiește pe cea veche de KEX.

Ar trebui să inspectezi și configurația efectivă a serverului, nu doar fișierul pe care l-ai editat.

sshd -T | grep -i kexalgorithms

Comanda aceea economisește timp. Pe sisteme aglomerate, cu include files, automatizări și unelte de panou, ceea ce crezi că este activ și ceea ce folosește de fapt sshd nu sunt întotdeauna același lucru.

Ce se strică de obicei după prima remediere

  • Ai dat reload la unitatea greșită. Debian folosește adesea ssh, nu sshd.
  • Ai înlocuit lista implicită de KEX în loc să o extinzi. Folosește + dacă nu vrei în mod deliberat să suprascrii totul.
  • Ai activat prea mulți algoritmi slabi. Asta rezolvă tichetul și creează o problemă de securitate pe termen lung.
  • Ai reparat KEX, dar ai ignorat următorul eșec. Clienții vechi eșuează adesea imediat după KEX la negocierea host key sau cipher.
  • Ai presupus că Match poate limita KEX. Nu poate în modul normal, single-daemon, în care oamenii îl descriu.

Un insight operațional foarte real aici: cea mai periculoasă versiune a acestui incident nu este outage-ul. Este workaround-ul tăcut care rămâne în loc după ce outage-ul s-a terminat. Șase luni mai târziu nimeni nu-și mai amintește de ce este activ group1, iar nimeni nu mai știe ce proces de business depinde încă de el.

Când trebuie să te oprești din a mai petici problema

Dacă endpoint-ul care eșuează este un appliance de zece ani, un client desktop SFTP abandonat sau o aplicație pe care nimeni nu o mai poate actualiza, atunci nu mai rezolvi o problemă SSH. Gestionezi datorie tehnică. În acel punct, opțiunile oneste sunt:

  • să înlocuiești clientul
  • să îl segmentezi în spatele unui listener legacy dedicat
  • să muți workflow-ul pe un traseu de transfer administrat și controlat
  • să elimini dependența

Pentru echipele care nu vor să își piardă săptămâna depanând breakage-uri SSH după upgrade, serviciul ServerSpan de Administrare Linux este construit exact pentru această clasă de probleme de producție. Dacă problema de fond este mai mare decât un singur daemon SSH și deja refaci sau actualizezi infrastructura, o implementare curată pe un nou server virtual este adesea calea mai rapidă decât să pui excepție peste excepție pe un nod îmbătrânit.

Pentru context conex, vezi Debian 13 Trixie este disponibil acum pe serverele virtuale ENGINYRING și Cum să detectezi intruși în serverul tău VPS: ghid complet de securitate.

Un checklist scurt de recovery

  1. Citește logurile SSH și capturează lista exactă de KEX oferită de client.
  2. Adaugă doar metoda legacy minimă necesară, începând cu diffie-hellman-group14-sha1.
  3. Validează cu sshd -t.
  4. Dă reload la unitatea corectă a serviciului SSH.
  5. Confirmă configurația efectivă cu sshd -T | grep kexalgorithms.
  6. Testează din nou cu ssh -vvv sau sftp -vvv.
  7. Dacă acel client are nevoie în continuare de group1 sau de și mai multe concesii legacy, mută-l pe un listener dedicat sau înlocuiește-l.
  8. Documentează excepția și setează o dată de eliminare.

Dacă gestionezi incidentul în felul acesta, repari outage-ul fără să transformi un singur client SFTP vechi într-un downgrade permanent la nivelul întregului server.

Sursă și Atribuire

Aceast articol se bazează pe date originale ale serverspan.com. Pentru metodologia completă și pentru a asigura integritatea datelor, articolul original trebuie citat. Sursa canonică este disponibilă la: OpenSSH 10 întrerupe conexiunile SSH/SFTP vechi: cum repari eroarea „no matching key exchange method found”.