Penolakan
Jika koneksi SSH Anda tidak bertahan dari pemadaman jaringan singkat, maka ada sesuatu yang terjadi yang tidak memungkinkan ssh
dan TCP melakukan hal normal mereka.
Lihat di bawah untuk detailnya. Bagaimanapun:
Solusi Tanpa-Dependensi Tercepat dan Terkotor
Buat skrip shell seperti ini:
#!/bin/sh -
# Tune these numbers depending on how aggressively
# you want your SSH session to get reconnected.
timeout_options='-o ServerAliveInterval=4 -o ServerAliveCountMax=2'
# 255 is the status OpenSSH uses to signal SSH errors, which
# means we want to connect. All other exit statuses suggest
# an intentional exit.
status=255
# Keep opening the SSH connection and immediately dropping into
# `screen` until an intentional exit happens.
while [ "$status" = 255 ]
do
ssh $timeout_options -t "$@" screen -dR
status=$?
# You can add a `sleep` command here or a counter or whatever
# you might need as far as rate/retry limiting.
done
exit "$status"
Ini hanya akan menjalankan loop bodoh-sederhana yang terus berusaha terhubung ssh
dan dilampirkan screen
. Lewati host atau apa pun yang biasanya Anda berikan pada ssh
permohonan Anda sebagai argumen baris perintah.
Sambungan ulang hanya didasarkan pada apakah SSH melaporkan kesalahan dengan koneksi, yang berarti ia tidak memiliki kecerdasan untuk mendeteksi kesalahan non-SSH seperti "Anda benar-benar tidak mengaktifkan WiFI" atau apa pun, tetapi itu mungkin tidak masalah untuk kamu.
Saya berasumsi Anda memiliki ssh-agent
atau kunci SSH tanpa-frasa sandi yang akan memungkinkan koneksi kembali berfungsi tanpa masukan tambahan dari Anda.
Akan ada kondisi perlombaan kecil di mana jika Anda menekan ^C
pada fraksi yang tepat yang tidak dapat dilihat manusia sedetik pun selama penyambungan kembali, Anda bisa berakhir dengan membunuh skrip alih-alih meneruskannya ^C
ke terminal klien, jadi jika Anda mencurigai koneksi hang jangan tumbuk ^C
terlalu bersemangat.
Solusi Perangkat Lunak Tambahan Sederhana
Anda dapat mencoba program autossh , yang seharusnya tersedia di repositori paket Ubuntu Anda.
Jika Anda perlu membangun dari sumber atau mengauditnya, ini adalah program C tunggal yang mengkompilasi tanpa pustaka tambahan sebagai dependensi, tampaknya memiliki lebih banyak intelijen tentang memeriksa keaktifan koneksi daripada retasan saya di atas, dan juga dikirimkan dengan rscreen
perintah skrip yang mudah yang otomatis -terhadap screen
.
Detail
Bagaimana ssh
biasanya pulih
Hanya untuk memverifikasi, karena saya tidak suka mengatakan sesuatu tanpa memeriksa diri saya sendiri, saya melakukan sedikit tes sebelum menjawab:
Saya menggunakan WiFi dengan perangkat Linux, membuat koneksi SSH ke perangkat lain di LAN saya, memverifikasi bahwa saya memiliki ssh
koneksi yang berfungsi ke ujung lainnya (dapat menjalankan perintah, dll), kemudian pada klien memutus WiFi (menyebabkan antarmuka untuk tidak dikonfigurasikan: tidak ada lagi alamat IP), mengetikkan lebih banyak karakter ke dalam sesi ssh (tentu saja tidak ada respons), dan kemudian terhubung kembali ke WiFi saya - koneksi ulang sebenarnya gagal setidaknya sekali karena sinyal buruk dan faktor lainnya , kemudian akhirnya terhubung kembali: Saya menunggu sekitar lima detik hingga ssh
sesi pulih, tidak ada yang terjadi sehingga saya menekan satu tombol lagi, dan ssh
sesi segera menjadi hidup kembali, dengan semua kunci yang saya ketik selama pemutusan muncul di baris perintah.
Lihat, ssh
hanya menulis / membaca ke soket jaringan TCP sampai OS mengatakan ada sesuatu yang salah, dan TCP sebenarnya sangat toleran terhadap penurunan koneksi yang berkepanjangan.
Ditinggalkan ke perangkatnya sendiri dengan pengaturan kernel default, TCP stack di Linux dengan senang hati akan mentolerir koneksi yang benar-benar diam selama beberapa menit sebelum menyatakan koneksi mati dan melaporkan kesalahan ke ssh
- pada saat akhirnya menyerah kita berbicara di stadion baseball itu. dari ~ 30 menit, atau setidaknya cukup lama untuk bertahan lebih lama dari cegukan koneksi yang berlangsung satu detik atau satu menit.
Di bawah penutup, Linux TCP stack secara bertahap mencoba kembali pesan dengan penundaan yang lebih lama, yang berarti bahwa pada saat koneksi Anda kembali, Anda mungkin melihat jeda tambahan sebelum ssh
sesi Anda tampaknya "hidup" lagi.
Mengapa ini terkadang rusak
Seringkali ada sesuatu yang secara aktif menyebabkan koneksi ditutup setelah beberapa periode tidak aktif secara signifikan lebih pendek daripada jumlah yang akan ditoleransi oleh TCP stack, dan kemudian gagal melaporkan status koneksi tersebut ke ssh
klien Anda .
Calon yang mungkin termasuk:
Firewall atau NAT'ing router, yang harus menggunakan memori untuk mengingat setiap koneksi TCP langsung - sebagai optimasi dan beberapa mitigasi terhadap serangan DOS, mereka kadang-kadang hanya akan melupakan koneksi Anda, dan kemudian secara diam-diam mengabaikan paket konsekuen untuk itu, karena paket di tengah koneksi ketika Anda tidak ingat koneksi yang ada terlihat tidak valid.
Firewall / router berperilaku lebih baik akan menyuntikkan paket TCP RST, yang biasanya bermanifestasi sebagai connection reset by peer
pesan kesalahan, tetapi paket reset adalah api-dan-lupa, jadi jika koneksi ke klien Anda masih mengalami masalah pada saat itu dan menjatuhkan Reset paket juga, klien Anda akan berpikir koneksi masih hidup.
Server itu sendiri mungkin memiliki kebijakan firewall untuk secara diam-diam menjatuhkan paket yang tidak terduga, yang akan memutus upaya koneksi kembali klien setiap kali server menganggap koneksi ditutup tetapi klien tidak: klien Anda terus berusaha melanjutkan koneksi, tetapi server hanya mengabaikannya karena tidak ada koneksi langsung ke mana paket-paket ini berada dalam keadaan firewall server.
Karena Anda menjalankan Linux, hati-hati periksa server Anda iptables
/ ip6tables
(atau nft
jika Anda menggunakan hal-hal baru) untuk apa yang Anda izinkan vs menjatuhkan. Sangat umum untuk memperbolehkan paket baru / mapan / terkait pada port TCP SSH, tetapi bukan yang "tidak valid" - jika Anda secara diam-diam menghapus semua yang tidak diizinkan, pengaturan umum ini dapat menyebabkan pembekuan semacam ini setelah masalah koneksi singkat .
Server SSH Anda sendiri mungkin dikonfigurasikan untuk menutup koneksi setelah beberapa saat tidak aktif, menggunakan salah satu opsi OpenSSH untuk paket kenang-kenangan klien TCP atau SSH. Dengan sendirinya ini tidak akan menyebabkan hang tidak terbatas, tetapi dapat menempatkan Anda di salah satu negara yang dijelaskan di atas.
Mungkin saja Anda tidak memberikan cukup waktu untuk "melepas" sendiri setelah Anda masuk ke keadaan di mana ssh
sesi Anda ditutup.
<Enter>
dan ketik~.
untuk memberi tahu sisi Anda untuk menjatuhkan koneksi, dan Anda cukup mengulangi perintah ssh terakhir untuk menyambung kembali (misalnya dengan panah atas atau!!
).