Mengapa konsol terkadang hang selamanya ketika koneksi SSH terputus?

89

Saya telah melihat ini dengan begitu banyak konsol (di Linux, Mac, ...), dan dengan banyak mesin yang berbeda di banyak jaringan berbeda. Saya tidak pernah dapat menunjukkan alasan yang tepat, mengapa ini terjadi: Yang harus Anda lakukan adalah masuk ke mesin melalui SSH. Jika koneksi terputus karena alasan tertentu (untuk kesederhanaan, katakanlah kabel jaringan ditarik), maka kadang-kadang konsol hanya hang selamanya - di waktu lain, itu hanya keluar dengan baik ke shell induk.

Ini sangat menjengkelkan ketika ini terjadi (misalnya Anda kehilangan sejarah perintah.) Apakah mungkin ada pintasan keyboard rahasia yang dapat memaksa keluar (Ctrl-C atau Ctrl-D tidak berfungsi)? Dan apa alasan untuk "bug" acak ini di semua implementasi?

Chris Lercher
sumber
Utas ini tampaknya tepat untuk menyebut Mosh (Mobile Shell) yang menangani dengan baik kegagalan koneksi, termasuk roaming (perubahan IP) dan hal-hal lainnya.
Ciprian Tomoiagă

Jawaban:

138

Ada pintasan keyboard "rahasia" untuk memaksa keluar: ~) Dari sesi yang dibekukan, tekan tombol-tombol ini secara berurutan: Enter~.Tilde (hanya setelah baris baru) dikenali sebagai urutan keluar oleh klien ssh, dan periode memberi tahu klien untuk menghentikan bisnisnya tanpa basa-basi lagi.

Perilaku lama dalam masalah komunikasi bukanlah bug, sesi SSH nongkrong berharap pihak lain akan kembali. Jika jaringan rusak, kadang-kadang bahkan beberapa hari kemudian Anda bisa mendapatkan sesi SSH kembali. Tentu saja Anda dapat secara khusus mengatakannya untuk menyerah dan mati dengan urutan di atas. Ada juga berbagai hal yang dapat Anda lakukan seperti mengatur timeout tetap-hidup di klien Anda sehingga jika itu tidak memiliki tautan aktif untuk jumlah waktu tertentu itu mati sendiri, tetapi perilaku default adalah tetap sebagai terhubung mungkin!

Sunting: Aplikasi lain yang bermanfaat dari kunci interupsi ini adalah untuk mendapatkan perhatian dari klien ssh lokal dan latar belakang untuk kembali ke shell lokal Anda sebentar — katakanlah untuk mendapatkan sesuatu dari sejarah Anda — kemudian tarik untuk tetap bekerja dari jarak jauh. Enter~ Ctrl+ Zuntuk mengirim klien ssh ke antrian pekerjaan latar belakang shell lokal Anda, lalu fgseperti biasa untuk mendapatkannya kembali.

Sunting: Saat berhadapan dengan sesi SSH bersarang, Anda dapat menambahkan beberapa karakter tilde untuk hanya keluar dari salah satu sesi SSH dalam rantai, tetapi mempertahankan yang lainnya. Misalnya, jika Anda bersarang dalam 3 level, (yaitu Anda ssh dari lokal-> Machine1-> Machine2-> Machine3), Enter~.akan membuat Anda kembali ke sesi lokal Anda, Enter~~.akan meninggalkan Anda di Machine1, dan Enter~~~.akan meninggalkan Anda di Machine2 . Ini juga berfungsi untuk urutan pelarian lainnya, seperti memindahkan sesi ssh ke latar belakang sementara. Cara di atas berfungsi untuk semua level sarang, dengan menambahkan lebih banyak tilde.

Terakhir, Anda dapat menggunakan Enter~?untuk mencetak menu bantuan dari perintah escape yang tersedia.

TL; DR - perintah pelarian yang didukung adalah urutan pelarian yang didukung:

 ~.   - 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.)
Caleb
sumber
11
+1 untuk mengetahui kata sandi dodecatouple-secret-probation untuk memotret sshd di kepala. Apakah Anda mengetahuinya dengan cara yang sama seperti yang saya lakukan (salah ketik ~/.somethingorothersetelah menekan enter)?
voretaq7
2
@ voretaq7: Tidak, saya tidak sepintar itu, tetapi ketika seseorang tahu saya, saya berkata, "Benarkah? Jadi, itulah yang terjadi sepanjang waktu, kulit saya hanya BANG! Tanpa alasan saat saya mengetik?" . Itu bukan urutan umum kecuali dalam salah ketik yang Anda sebutkan, tetapi itu bisa terjadi.
Caleb
14
Dimana "rahasia" maksudnya "di halaman manual".
larsks
4
Sementara banyak orang tidak tahu tentang ini, itu benar-benar rahasia di depan mata. man sshmembahas hal ini di bawah ESCAPE CHARACTERSbagian ini. ~.(Putus) dan ~^Z(latar belakang ssh) sangat praktis.
Stefan Lasiewski
9
Tentu saja ada di halaman manual :) Saya hanya menggunakan kata rahasia karena OP melakukannya, dan saya menggunakan lidah di pipi. Masalah dengan fitur ini adalah bahwa orang tidak tahu di mana mencarinya, mereka mengharapkan karakter kontrol dan sinyal tersebut menjadi bagian dari shell atau semacamnya. Begitu Anda tahu ke mana harus mencari atau bahkan apa yang harus ditanyakan, tentu saja ada di sana.
Caleb
12

SSH menawarkan fasilitas tetap hidup. Tambahkan berikut ini ke lokal Anda ~/.ssh/config(buat jika tidak ada):

ServerAliveInterval 15
ServerAliveCount 3

Pengaturan ini akan menghasilkan sinyal tetap hidup yang dikirim setiap 15 detik melalui terowongan aman. Setelah tiga kegagalan berturut-turut, klien SSH akan keluar.

Perhatikan bahwa pada beberapa sistem (termasuk macOS 10.14) sebagai gantinya harus:

ServerAliveInterval 15
ServerAliveCountMax 3

Diambil dari jawaban ini di ask.ubuntu: https://askubuntu.com/a/29967/30266

krlmlr
sumber
9

Fakta bahwa itu hang adalah fungsi dari TCP, bukan SSH. Aplikasi tidak memiliki cara untuk mengetahui bahwa sesi / koneksi TCP telah terputus kecuali TCP menginformasikan aplikasi menggunakan koneksi bahwa koneksi sudah tidak ada lagi. Dari perspektif masing-masing host, sesi TCP masih dalam kondisi mapan dan tidak ada yang mengatakan bahwa sesi lama (tidak ada data mengalir) tidak valid selain RST atau kurangnya respons terhadap paket TCP keepalive (yang tidak diterapkan secara universal). Bagi saya itu bukan bug di SSH, saya mengharapkan perilaku itu.

joeqwerty
sumber
5

Jika koneksi digantung dengan benar, semua keystroke ajaib tidak akan bisa lewat karena koneksi sudah digantung sebelum Anda mengeluarkan tombol yang ditekan. Anda dapat memberi tahu klien untuk mengakhiri tetapi ini tidak akan memengaruhi riwayat disimpan (atau tidak) di ujung server.

Meskipun ini tidak benar-benar menjawab pertanyaan, ini dapat membantu mengurangi efek hang koneksi: ketika saya bekerja dari jarak jauh (dan bahkan biasanya ketika saya tidak) saya menjalankan screen(dengan atau tanpa byobubungkus tergantung pada ketersediaannya) sehingga jika ada koneksi apa pun menjatuhkan sesi saya, dengan semua riwayatnya, dipertahankan dan tersedia dalam keadaan saya meninggalkannya ketika saya menghubungkan kembali.

David Spillett
sumber
6
Saran Anda tentang layar baik-baik saja, tetapi bit pertama sebenarnya tidak berlaku untuk masalah ini. Anda tidak perlu memasukkan kunci ke sisi jarak jauh, Anda hanya perlu membawanya ke klien ssh LOCAL! OP menginginkan cangkang lokalnya kembali termasuk sejarah. SSH mengambil alih dan tidak menanggapi urutan istirahat normal seperti CTRL-C karena meneruskannya. Ada cara untuk melewati dan mengakhiri klien lokal, lihat jawaban saya. Sejarah di ujung lokal biasanya disimpan jika Anda login lagi, tergantung pada konfigurasi shell.
Caleb
2
@ Caleb: pertanyaan yang secara khusus disebutkan kehilangan riwayat, dan riwayat perintah disimpan sisi server. Untuk memberi tahu server untuk melakukan sesuatu yang berbeda dengan riwayat, Anda perlu mengirim pesan ke server untuk mengatakannya agar melakukan sesuatu yang berbeda dengan riwayat. Tentu saja ada cara membuat bash (dan beberapa cangkang lainnya) segera merekam jalur histori daripada mengumpulkannya dalam RAM sampai pengguna benar-benar ada cangkang dengan exit/ logoutyang akan memecahkan masalah sejarah tanpa menggunakan screen.
David Spillett