SSH uzak bağlantı noktası iletme başarısız oldu


26

Takip: Her sunucuyu birkaç ay çalıştırmakla çakışan hızlı bağlantı kesme dizileri muhtemelen tesadüf eseri gibi görünüyor ve sadece asıl sorunu ortaya çıkarmak için kullanılıyor. Yeniden bağlanamamasının nedeni, kesinlikle AliveInterval değerleri (kasperd'in cevabı). ExitOnForwardFailure seçeneğinin kullanılması, yeniden bağlanmadan önce zaman aşımının uygun şekilde gerçekleşmesine izin vermeli ve bu çoğu durumda sorunu çözmelidir. MadHatter'ın önerisi (kill betiği) muhtemelen her şey başarısız olsa bile tünelin yeniden bağlanabilmesini sağlamak için en iyi yoldur.

Bir güvenlik duvarının arkasında birkaç bağlantı noktasında küçük bir DigitalOcean VPS'ye (B) ters tünel başlatan bir sunucum (A) var, böylece A'nın B'nin IP adresi üzerinden bağlanabiliyorum. Tünel yaklaşık 3 aydır sürekli çalışıyor, ancak son 24 saatte dört kez aniden başarısız oldu. Aynı şey, başka bir VPS sağlayıcısında bir süre önce oldu - aylarca mükemmel çalışma, ardından birden fazla hızlı arıza.

Makine A'da otomatik olarak tünel komutunu çalıştıran bir komut dosyası var ( ssh -R *:X:localhost:X address_of_Bher X bağlantı noktası için), ancak çalıştırıldığında yazıyor Warning: remote port forwarding failed for listen port X.

/var/log/secureSunucudaki sshd'ye girmek şu hataları gösterir:

bind: Address already in use
error: bind: Address already in use
error: channel_setup_fwd_listener: cannot listen to port: X

Çözme VPS'yi yeniden başlatmayı gerektirir. O zamana kadar, yeniden bağlantı kurma girişimleri "uzaktaki bağlantı noktası iletme başarısız oldu" mesajı veriyor ve çalışmaz. Şimdi tünelin durmadan sadece 4 saat önce kaldığı noktaya geldi.

VPS'de hiçbir şey değişmedi ve yalnızca ters tünel bitiş noktası görevi gören tek kullanımlık, tek kullanıcılı bir makine. CentOS 6.5’de OpenSSH_5.3p1’i çalıştırıyor. Görünüşe göre sshd, bağlantı koptuğunda bağlantı noktalarını kapatmıyor gibi görünüyor. Niçin veya neden neredeyse aniden neredeyse mükemmel bir operasyondan sonra gerçekleştiğini açıklamaktan kaçınıyorum.

Açıklığa kavuşturmak için, önce sshd'nin tünel başarısız olduktan sonra portları dinlemeyi reddetmesinin nedenini bulmam gerekiyor, bu sshd'nin portları açık bırakıp asla kapatmamasından kaynaklanıyor gibi görünüyor. Bu asıl sorun gibi görünüyor. Beklediğim gibi davrandıktan sonra aylarca böyle davranmasına neyin neden olacağından emin değilim (yani portları hemen kapatmak ve betiğin yeniden bağlanmasını sağlamak).


Sorun nedir? Bağlantı noktası bağlama hatası nasıl giderilir veya ssh'ın neden öldüğünü veya başka bir şeyi nasıl yeniden bulabilirim?
MadHatter,

Neden sshd'nin VPS'deki portları açmayı reddettiğini bulmam gerekiyor (ciltleme hatası). Bağlantı noktası bağlama hatası, sorunun kökü gibi görünüyor ve bu sorunu çözebiliyorsam her şey çalışmalı.
Justin Mrkva,

2
Her geç ödeme yapan şirket için, bağlantıyı açık tutmak için el ile bir komut dosyası oluşturmak yerine, bunun yerine autossh komutunu kullanın. serverfault.com/questions/598210/…
oligofren

Yanıtlar:


27

MadHatter’la aynı fikirdeyim, feshedilmiş ssh bağlantılarından liman nakliyesi olması muhtemel Şu anki probleminiz başka bir şey olsa bile, ertelenen ssh bağlantılarıyla er ya da geç karşılaşmayı bekleyebilirsiniz.

Bu tür kesilen bağlantıların gerçekleşmesinin üç yolu vardır:

  • Bağlantının diğer ucu tamamen boştayken iki uç noktadan biri yeniden başlatıldı.
  • İki uç noktadan biri bağlantıyı kapattı ancak bağlantı kapatıldığı sırada bağlantıda geçici bir kesinti oldu. Kesinti bağlantı kapatıldıktan sonra birkaç dakika sürdü ve bu nedenle diğer ucu kapalı bağlantıyı hiç öğrenmedi.
  • Bağlantı, ssh bağlantısının her iki uç noktasında da hala işlevseldir, ancak birileri aralarında bir yerde durumsuz bir cihaz koymuştur, bu da boşluğu nedeniyle bağlantıyı zaman aşımına uğratmıştır. Bu durum bilgisi olan cihaz bir NAT veya güvenlik duvarı olacaktır, daha önce bahsettiğiniz güvenlik duvarı ana şüpheli.

Yukarıdaki üçten hangisinin gerçekleştiğini bulmak çok önemli değil, çünkü üçüne de hitap edecek bir yöntem var. Kalıcı mesajların kullanımı budur.

Sen içine bakmak gerekir ClientAliveIntervaliçin anahtar kelime sshd_configve ServerAliveIntervaliçin zaman aralığı ssh_configveya ~/.ssh/config.

sshKomutu bir döngüde çalıştırmak iyi sonuç verebilir. Bir nedenden ötürü bağlantı kesildiğinde sunucuya su akmasına neden olmamanız için döngü içine bir uyku eklemek iyi bir fikirdir.

İstemci bağlantıyı sunucuda sonlandırmadan önce yeniden bağlanırsa, yeni ssh bağlantısının canlı olduğu ancak bağlantı noktası iletmediği bir durumda olabilirsiniz. Bundan kaçınmak için, ExitOnForwardFailureanahtar kelimeyi müşteri tarafında kullanmanız gerekir .


Bunun sorun olabileceğini düşünüyorum. Özellikle, ssh işlemi sona ererse A’daki betiğim yeniden bağlanmaya çalışacaktır (tabii ki uyarı mesajı ssh sürecini öldürmediği için sadece bu olduğunda kilitleniyor, ama bu başka bir gün için bir sorun). Ancak A, B'ye çok hızlı bir şekilde yeniden bağlanmaya çalışırsa, B A'nın yeniden bağlanmasını bekliyor olabilir. Muhtemelen A yeniden bağlanmadan önce B'nin daima zaman aşımına uğradığından emin olmalıyım. MadHatter'ın yeniden bağlantı kurmadan önce sshd işlemlerini öldürme önerisiyle birleştirmesi muhtemel vakaların% 95'ini kapsayacaktır.
Justin Mrkva

1
Uyarı mesajından bahsetmek SSH'yi öldürmemek, beni düşünmeye ve man sayfalarına bakmamı sağladı. Anlaşılan -o ExitOnForwardFailure yestam olarak ihtiyacım olan şeydi. Yani çözmem gereken daha az şey var. Düşünmek için, bu uyarı mesajlarını ayrıştırmak için bir Python betiği yazacaktım. Bu çok daha basit. : D
Justin Mrkva

ExitOnForwardFailureCevabımı yazarken unuttuğum için üzgünüm . Şimdi cevaba ekledim.
kasperd

4
Hiç sorun değil, ve aslında -o ExitOnForwardFailure=yes(eşit işaretine dikkat edin). Bu nedenle, bunun karşısına herhangi biri gelirse, önceki yorumumdan kopyalayıp yapıştırmayın, çalışmaz. : P
Justin Mrkva,

Bu yüzden sunucuyu yaklaşık 10 saattir izliyorum ve iyi çalışıyor gibi görünüyor; Bu noktada, bu cevabın doğru olduğunu (gördüklerime göre yaklaşık% 99 eminim) ve hızlı bağlantı kesmelerinin, birkaç ay sonra ortaya çıkan ağ sorunlarıyla ilgili tesadüf olduğunu kabul ediyorum. Her servise başlamak. Yardımınız için herkese teşekkürler. ;)
Justin Mrkva

4

Bu sunucudaki bağlantı noktasını bağlayan işlemi bulabilirsiniz.

sudo netstat -apn|grep -w X

Yarı feshedilmiş gibi görünmek çok muhtemel görünüyor sshd, ancak neden veri alabileceğinize dair varsayımlarda bulunuyorsunuz? Bir betiğin, tüneli tekrar açmadan önce 9'a sinyal gönderecek bir PID bulması da iyi bir yoldur.


Önceki VPS sağlayıcısında bunu kontrol ettiğimi hatırlıyorum ve sshd'nin bu bağlantı noktalarını dinleyen işlem olduğunu onayladım. Bir dahaki sefere olduğunda kontrol edeceğim burada, ancak davranış ve kurulum tamamen aynı olduğundan, farklı olmasını beklemiyorum.
Justin Mrkva

Harika, öyleyse tüneli yeniden açacak olan senaryonuz, yapmadan önce eski tüneli öldürür.
MadHatter,

Söylediğiniz şey buysa, asla aynı anda çalışan birden fazla tünel komut dosyası (A'da) yoktur. Öte yandan, senaryonun uzaktan B'ye bürünerek başıboş işlemleri öldürme emrini vermesini istiyorsan ... bu aslında yarı kötü bir fikir değil. Ancak bir endişe, hata ayıklamaya çalışıyorsam, sürekli olarak tüm SSH bağlantılarını kesmektir. A'daki komut dosyası her zaman bir aksaklık nedeniyle B'yi öldürüyorsa, o zaman sürekli A betiği tarafından B'den kovulmam. : P Bunu yapmadığından emin olmak için test edeceğim. Ama dediğim gibi, yarı kötü bir fikir değil. ;)
Justin Mrkva

Orada olduğunu düşünmemiştim. Uzak sunucuda çalışan bir tünel açmaya çalışan ve bağlama hatası nedeniyle başarısız olan bir komut dosyası olduğunu söylüyorsunuz ve yalnızca ihtiyaç duyduğunuzda (yani mevcut tünel iyi olmadığında) çalıştığını farz ediyorum çünkü başka türlü söylemedin. Tek önerdiğim, yeni tüneli açmaya çalışmadan önce limanı açık tutan belirli süreci öldürmesi.
MadHatter

Ssh çalıştıran script sadece A sunucusunda, B sunucusu ek bir script içermeyen düz bir vanilya sunucusudur. Muhtemelen yapacağım şey, B sunucusuna koymak için bir öldürme komut dosyası yazmak, ardından bir satırda belirli sayıda bağlanmada başarısız olursa, uzaktan A'dan çağırmak. Bu şekilde diğer SSH bağlantılarına müdahale etme olasılığı daha düşüktür. Muhtemelen her seferinde çok hızlı bir şekilde çok fazla çağrılırsa hiçbir şey yapmadan çalıştırılan ve çıkan her zaman kill komut kütüğüne sahip olacağım. Şahsen, sshd'yi öldüren herhangi bir senaryoyu hız sınırlayıcı gibi görünmektedir. : P
Justin Mrkva

3

Bir sshtünel bağlantısı kesildiğinde benim için bağlantının sıfırlanması biraz zaman alıyor, bu yüzden sshsüreç beni aktif tüneller olmadan bırakmayı engelliyor ve nedenini bilmiyorum. Geçici bir çözüm, eski bağlantıların sıfırlanmasını beklemeden ssharka plana koymak -fve yeni bağlantılar oluşturmaktır. -o ExitOnForwardFailure=yesYeni süreç sayısını limt için kullanılabilir. -o ServerAliveInterval=60Mevcut bağlantı güvenilirliğini artırır.

sshKomutu sık sık tekrarlayabilirsiniz , örneğin a cronveya, betiğinizdeki bir döngüde, örneğin aşağıdakilerde sshkomutu her 3 dakikada bir çalıştırıyoruz :

while (1)
do
    ssh -f user@hostname -Rport:host:hostport -N -o ExitOnForwardFailure=yes -o ServerAliveInterval=60
    sleep 180
done

daha sağlam bir çözüm autossh
Marco

-o ExitOnForwardFailure=yesaradığım şeydi, çok teşekkürler!
vadipp

1

Tecrübelerime göre ssh, uzak sistemde hala bir şey çalışıyorsa, temiz çıkmama alışkanlığı bırakıyor. Arka planda başladı. Bunu şununla çoğaltabilirsiniz:

ssh <server>
while true; do  sleep 60; done&
exit

Ssh oturumunuz kapanacak, ancak oturumu kapatmayacak - uzak süreç çıkana kadar (ki, çünkü 'doğru' iken) bir döngü olacak). Benzer bir şey olabilir - oturumunuzun ssh tarafından oluşturulan bir 'sıkışmış' süreci var. Liman kullanımda kalır ve bu nedenle yerel işleminiz tarafından tekrar kullanılamaz.


A makinesinde ssh -o ConnectTimeout=10 -o BatchMode=yes -gnN -R *:X:localhost:X root@$TUNSRV 1>>tunnel.log 2>&1 &yürütülen SSH komutunun tamamı , özellikle -N seçeneğinden dolayı, SSH tarafından tünelin kendisi dışında yürütülen hiçbir şeyin bulunmadığı şeklindedir. Açık tutulan şey, uzaktaki sunucu B'de sshd'nin kendisi kullanılarak yapılıyor.
Justin Mrkva,
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.