Tindak Lanjut: Sepertinya serangkaian pemutusan yang cepat bertepatan dengan beberapa bulan menjalankan setiap server mungkin kebetulan dan hanya berfungsi untuk mengungkapkan masalah yang sebenarnya. Alasan kegagalan untuk menyambung kembali hampir pasti karena nilai AliveInterval (jawaban kasperd). Menggunakan opsi ExitOnForwardFailure harus memungkinkan batas waktu terjadi dengan benar sebelum menghubungkan kembali, yang seharusnya memecahkan masalah dalam banyak kasus. Saran MadHatter (skrip kill) mungkin adalah cara terbaik untuk memastikan bahwa terowongan dapat terhubung kembali walaupun semuanya gagal.
Saya memiliki server (A) di belakang firewall yang memulai terowongan terbalik pada beberapa port ke DigitalOcean VPS (B) sehingga saya dapat terhubung ke A melalui alamat IP B. Terowongan telah bekerja secara konsisten selama sekitar 3 bulan, tetapi tiba-tiba gagal empat kali dalam 24 jam terakhir. Hal yang sama terjadi beberapa waktu lalu pada penyedia VPS lain - berbulan-bulan beroperasi dengan sempurna, lalu tiba-tiba mengalami beberapa kegagalan cepat.
Saya memiliki skrip pada mesin A yang secara otomatis menjalankan perintah tunnel ( ssh -R *:X:localhost:X address_of_B
untuk setiap port X) tetapi ketika dijalankan, katanya Warning: remote port forwarding failed for listen port X
.
Masuk ke sshd /var/log/secure
di server menunjukkan kesalahan ini:
bind: Address already in use
error: bind: Address already in use
error: channel_setup_fwd_listener: cannot listen to port: X
Pemecahan membutuhkan reboot VPS. Sampai saat itu, semua upaya untuk menyambung kembali memberikan pesan "penerusan port jarak jauh gagal" dan tidak akan berfungsi. Sekarang ke titik di mana terowongan hanya berlangsung sekitar 4 jam sebelum berhenti.
Tidak ada yang berubah pada VPS, dan ini adalah mesin sekali pakai, pengguna tunggal yang hanya berfungsi sebagai titik akhir terowongan terbalik. Ini menjalankan OpenSSH_5.3p1 pada CentOS 6.5. Tampaknya sshd tidak menutup port pada akhirnya ketika koneksi terputus. Saya bingung menjelaskan mengapa, atau mengapa hal itu tiba-tiba terjadi sekarang setelah berbulan-bulan operasi yang hampir sempurna.
Untuk memperjelas, saya pertama-tama perlu mencari tahu mengapa sshd menolak untuk mendengarkan port setelah terowongan gagal, yang tampaknya disebabkan oleh sshd membiarkan port terbuka dan tidak pernah menutupnya. Itu tampaknya menjadi masalah utama. Saya hanya tidak yakin apa yang menyebabkannya berperilaku seperti ini setelah berbulan-bulan berperilaku seperti yang saya harapkan (yaitu segera menutup port dan memungkinkan skrip untuk menyambung kembali).
sumber
Jawaban:
Saya setuju dengan MadHatter, bahwa kemungkinan port forwarding dari koneksi ssh yang mati. Bahkan jika masalah Anda saat ini ternyata menjadi sesuatu yang lain, Anda dapat berharap untuk mengalami koneksi ssh yang sudah mati cepat atau lambat.
Ada tiga cara koneksi yang mati tersebut dapat terjadi:
Mencari tahu mana dari ketiga di atas yang terjadi tidak terlalu penting, karena ada metode, yang akan membahas ketiganya. Itu adalah penggunaan pesan keepalive.
Anda harus melihat
ClientAliveInterval
kata kuncisshd_config
danServerAliveInterval
interval untukssh_config
atau~/.ssh/config
.Menjalankan
ssh
perintah dalam satu lingkaran dapat bekerja dengan baik. Sebaiknya masukkan juga sleep dalam loop agar Anda tidak membanjiri server ketika koneksi karena suatu alasan gagal.Jika klien terhubung kembali sebelum koneksi berakhir di server, Anda dapat berakhir dalam situasi di mana koneksi ssh baru hidup, tetapi tidak memiliki penerusan port. Untuk menghindari itu, Anda perlu menggunakan
ExitOnForwardFailure
kata kunci di sisi klien.sumber
-o ExitOnForwardFailure yes
itulah yang saya butuhkan. Jadi itu satu hal yang kurang saya perlu mencari tahu. Untuk berpikir, saya akan menulis skrip Python untuk menguraikan pesan peringatan itu. Ini jauh lebih sederhana. : DExitOnForwardFailure
ketika menulis jawaban saya. Saya telah menambahkannya ke jawabannya sekarang.-o ExitOnForwardFailure=yes
(perhatikan tanda sama dengan). Jadi, jika ada yang menemukan ini, jangan salin dan tempel dari komentar saya sebelumnya, itu tidak akan berfungsi. : PAnda dapat menemukan proses yang mengikat port pada server itu dengan
Tampaknya sangat mungkin setengah mati
sshd
, tetapi mengapa membuat asumsi ketika Anda dapat memiliki data? Ini juga merupakan cara yang bagus untuk sebuah skrip untuk menemukan PID untuk mengirim sinyal 9 sebelum mencoba mengangkat terowongan lagi.sumber
Bagi saya ketika sebuah
ssh
terowongan terputus diperlukan beberapa saat untuk koneksi untuk mengatur ulang sehinggassh
proses terus memblokir meninggalkan saya tanpa terowongan aktif dan saya tidak tahu mengapa. Solusi penyelesaiannya adalah denganssh
menggunakan-f
dan untuk menelurkan koneksi baru tanpa menunggu koneksi lama diatur ulang. The-o ExitOnForwardFailure=yes
dapat digunakan untuk limt jumlah proses baru. The-o ServerAliveInterval=60
meningkatkan keandalan koneksi yang sekarang.Anda dapat mengulangi
ssh
perintah itu berulang kali, katakanlah, dalam acron
, atau, dalam satu loop dalam skrip Anda, misalnya, berikut ini, kami menjalankanssh
perintah setiap 3 menit:sumber
-o ExitOnForwardFailure=yes
adalah apa yang saya cari, terima kasih banyak!Dalam pengalaman saya ssh memiliki kebiasaan yang agak menjengkelkan untuk tidak keluar dengan bersih jika 'sesuatu' masih berjalan pada sistem jarak jauh. Misalnya dimulai di latar belakang. Anda dapat mereproduksi ini dengan:
Ssh Anda akan keluar, tetapi tidak akan benar-benar menutup sesi - sampai proses jarak jauh keluar (yang tidak akan, karena itu adalah 'sementara benar' loop). Mungkin hal serupa terjadi - sesi Anda mengalami proses 'macet' yang dihasilkan oleh ssh. Port tetap digunakan, dan karena itu tidak dapat digunakan kembali oleh proses lokal Anda.
sumber
ssh -o ConnectTimeout=10 -o BatchMode=yes -gnN -R *:X:localhost:X root@$TUNSRV 1>>tunnel.log 2>&1 &
sehingga tidak ada yang dieksekusi oleh SSH kecuali terowongan itu sendiri, khususnya karena opsi -N. Apa pun yang disimpan terbuka sedang dilakukan pada server jauh B menggunakan sshd itu sendiri.