Vraag Waarom blijven consoles soms voor altijd hangen als de SSH-verbinding wordt verbroken?


Ik heb dit gezien met zoveel consoles (op Linux, Mac, ...) en met veel verschillende machines in veel verschillende netwerken. Ik kan nooit de exacte reden achterhalen, waarom dit gebeurt: het enige wat je hoeft te doen is inloggen op een computer via SSH. Als de verbinding om een ​​of andere reden verbreekt (voor de eenvoud, laten we zeggen dat de netwerkkabel is getrokken), hangt de console soms gewoon voor altijd - op andere momenten gaat het gewoon prima naar de bovenliggende shell.

Het is zo vervelend als dit gebeurt (je verliest bijvoorbeeld de opdrachthistorie.) Is er misschien een geheime toetsenbordsnelkoppeling die een exit kan forceren (Ctrl-C of Ctrl-D werken niet)? En wat is de reden voor deze willekeurige "bug" in alle implementaties?


74
2018-06-22 18:12


oorsprong


Deze thread lijkt gepast om te vermelden Mosh (Mobile Shell) die goed omgaat met verbindingsfouten, waaronder roaming (IP-wijziging) en andere zaken. - Ciprian Tomoiagă


antwoorden:


Er is een "geheime" sneltoets om een ​​exit te forceren: ~) Druk in de bevroren sessie op deze toetsen in de volgende volgorde: invoeren~. De tilde (alleen na een nieuwe regel) wordt herkend als een escape-reeks door de ssh-client en de periode vertelt de client om zijn bedrijf zonder meer te beëindigen.

Het lange hanggedrag bij communicatieproblemen is geen fout, de SSH-sessie hangt in de hoop dat de andere kant terug zal komen. Als het netwerk breekt, kun je soms zelfs dagen later een SSH-sessie terughalen. Natuurlijk kun je het specifiek vertellen om op te geven en te sterven met de bovenstaande reeks. Er zijn ook verschillende dingen die je kunt doen, zoals het instellen van time-outs voor keep-alive in je client, zodat als het een actieve link voor een bepaalde tijd niet heeft, het zichzelf sluit, maar het standaardgedrag is om te blijven zoals zo mogelijk aangesloten!

Bewerk: Een andere nuttige toepassing van deze interrupt-sleutel is om de aandacht van de lokale ssh-client te krijgen en deze op de achtergrond te houden om een ​​minuut terug te keren naar je lokale shell - om iets uit je geschiedenis te halen - en daarna te laten werken op afstand. invoeren~  Ctrl+Z om de ssh-client vervolgens naar de wachtrij op de achtergrondtaak van uw lokale shell te sturen fg zoals normaal om het terug te krijgen.

Bewerk: Wanneer je te maken hebt met geneste SSH-sessies, kun je meerdere tilde-tekens toevoegen om alleen uit te breken van een van de SSH-sessies in de keten, maar de anderen te behouden. Als u bijvoorbeeld in 3 niveaus bent genest (d.w.z. ssh van local-> Machine1-> Machine2-> Machine3), invoeren~. zal je terugbrengen naar je lokale sessie, invoeren~~. zal je achterlaten in Machine1, en invoeren~~~. zal je in Machine2 achterlaten. Dit werkt ook voor andere escape sequences, zoals het tijdelijk naar de achtergrond verplaatsen van de ssh-sessie. Het bovenstaande werkt voor elk niveau van nesten, door gewoon meer tilde's toe te voegen.

Eindelijk, je kunt gebruiken invoeren~? om een ​​helpmenu met beschikbare escape-opdrachten af ​​te drukken.

TL; DR - de ondersteunde escape-opdrachten zijn Ondersteunde escape-sequences:

 ~.   - terminate connection (and any multiplexed sessions)
 ~B   - send a BREAK to the remote system
 ~C   - open a command line
 ~R   - request rekey
 ~V/v - decrease/increase verbosity (LogLevel)
 ~^Z  - suspend ssh
 ~#   - list forwarded connections
 ~&   - background ssh (when waiting for connections to terminate)
 ~?   - this message
 ~~   - send the escape character by typing it twice
(Note that escapes are only recognized immediately after newline.)

121
2018-06-22 18:15



+1 voor het kennen van het dodecatouple-secret-proeftijdwachtwoord voor het schieten van sshd in de kop. Ben je erachter gekomen op dezelfde manier als ik deed (fout typeren ~/.somethingorother na het raken van enter)? - voretaq7
@ voretaq7: Nee, ik was niet zo slim, maar toen iemand me een aanwijzing gaf, ging ik "Echt? Dus dat was wat er gebeurde al die keren dat mijn shell gewoon BANG ging, zonder reden toen ik aan het typen was?". Het is geen gebruikelijke volgorde, behalve in de mistypes van degene die u noemt, maar het kan gebeuren. - Caleb
Waarbij "geheim" hij bedoelt "in de man-pagina". - larsks
Hoewel veel mensen dit niet weten, is het echt een geheim in duidelijke weergave. man ssh dekt dit onder de ESCAPE CHARACTERS sectie. ~. (Verbinding verbreken) en ~^Z (achtergrond ssh) zijn erg handig. - Stefan Lasiewski
Natuurlijk staat het in de man-pagina :) Ik gebruikte het woord geheim alleen omdat het OP het deed, en ik gebruikte tong op de wang. Het probleem met deze functie is dat mensen niet weten waar ze moeten zoeken, ze verwachten dat besturingspersonages en dergelijke signalen deel uitmaken van de shell of zo. Zodra je weet waar je moet kijken of zelfs wat je moet vragen, is het er natuurlijk. - Caleb


SSH biedt een mogelijkheid om in leven te blijven. Voeg het volgende toe aan uw lokale ~/.ssh/config (maken als het niet bestaat):

ServerAliveInterval 15
ServerAliveCount 3

Met deze instelling wordt een keep-alive-signaal ingesteld dat elke 15 seconden door de beveiligde tunnel wordt verzonden. Na drie opeenvolgende mislukkingen zal de SSH-client afsluiten.

Merk op dat op sommige systemen het in plaats daarvan moet zijn:

ServerAliveInterval 15
ServerAliveCountMax 3

Afkomstig van dit antwoord op ask.ubuntu: https://askubuntu.com/a/29967/30266


10
2018-01-19 08:44





Het feit dat het hangt is een functie van TCP, niet van SSH. De toepassing kan niet weten dat de TCP-sessie / -verbinding is verbroken tenzij TCP de toepassing informeert via de verbinding dat de verbinding niet langer bestaat. Vanuit het perspectief van elke host bevindt de TCP-sessie zich nog steeds in de status Established en er is niets om te zeggen dat een lange inactieve (geen gegevensstroom) sessie niet geldig is, anders dan een RST of een gebrek aan respons op een TCP-keepalive-pakket (dat is niet universeel geïmplementeerd). Dat lijkt mij geen fout in SSH, ik zou dat gedrag verwachten.


8
2018-06-22 19:49





Als de verbinding op de juiste manier is opgehangen, komt er geen magische toetsaanslag door, omdat de verbinding al is opgehangen voordat u de toets indrukt. U kunt de client vertellen dat deze moet worden beëindigd, maar dit heeft geen invloed op de geschiedenis die bij de server wordt bewaard (of niet).

Hoewel dit de vraag niet echt beantwoordt, kan het helpen de gevolgen van een verbinding te verminderen: als ik op afstand werk (en meestal zelfs als ik dat niet ben), loop ik door screen (met of zonder de byobu wrapper, afhankelijk van de beschikbaarheid), zodat als er een soort verbindingsvertraging is mijn sessie, met al zijn geschiedenis, behouden blijft en beschikbaar is in de staat die ik verliet toen ik opnieuw verbinding maakte.


5
2018-06-22 18:18



Uw suggestie over het scherm is prima, maar het eerste bit is eigenlijk niet van toepassing op het probleem. U hoeft geen sleutels naar de externe kant te krijgen, u hoeft ze alleen maar naar de LOCAL-ssh-client te sturen! De OP wil zijn lokale schaal terug inclusief geschiedenis. SSH neemt het over en reageert niet op normale onderbrekingsreeksen zoals CTRL-C omdat het die doorgeeft. Er is een manier om door te komen en de lokale klant te beëindigen, zie mijn antwoord. Geschiedenis aan de lokale kant wordt meestal toch bewaard als u opnieuw inlogt, afhankelijk van de shell-configuratie. - Caleb
@ Caleb: de vraag vermeldde specifiek het verliezen van geschiedenis, en de opdrachtgeschiedenis wordt op de server opgeslagen. Als u de server wilt vragen om iets anders te doen met de geschiedenis, moet u een bericht naar de server sturen om aan te geven dat het iets anders moet doen met de geschiedenis. Natuurlijk zijn er manieren om bash (en sommige andere shells) te maken om geschiedenislijnen onmiddellijk vast te leggen in plaats van ze in het RAM-geheugen te verzamelen totdat de gebruiker op de juiste manier de shell met exit/logout die het geschiedenisprobleem zou oplossen zonder het te gebruiken screen. - David Spillett