Ad tabanlı bir sanal ana bilgisayar SSH ters proxy var mı?


36

Geliştirme ortamımızda HTTP ters proxy'lerine oldukça düşkünüm ve DNS tabanlı sanal ana bilgisayar ters proxy'sini oldukça faydalı buldum. Güvenlik duvarında yalnızca bir bağlantı noktasının (ve standart bağlantı noktasının) açık olması, yönetim için çok daha kolay hale getirir.

SSH bağlantıları yapmak için benzer bir şey bulmak isterdim ama çok fazla şansım olmadı. Standart dışında açık port aralıkları gerektirdiğinden basitçe SSH tünelini kullanmayı tercih etmem. Dışarıda bunu yapabilen bir şey var mı?

HAProxy bunu yapabilir mi?


Amaçlanan uygulama dosya aktarımı mı, yoksa ana bilgisayarlara gerçek SSH erişimi mi?
Kyle Hodgson

Hedefe doğrudan SSH erişimi. Bu ihtiyaç, şirket içinde bir Mercurial sunucu çalıştırma arzusundan kaynaklanıyor ancak sunucumuz güvenlik duvarının arkasında. Şu anda sadece basit bir HTTP sürümü kurmaya çalışıyorum ancak taahhütlerin HTTP yerine SSH kullanmasını istedim. Bu mümkün olsaydı, diğer sunuculara doğrudan SSH erişimi bir bonus olurdu.
ahanson

Bu çok sinir bozucu bir sorundur.
önyargı

Anladığım kadarıyla HAProxy şimdi bunu SNI ile destekliyor. Yine de bunu henüz başaramadım.
Carel

Yanıtlar:


24

Adına dayalı SSH'nin protokolün nasıl çalıştığı göz önüne alındığında mümkün olacağına inanmıyorum.

İşte bazı alternatifler.

  • Yapmanız gereken, 22 numaralı bağlantı noktasını bir ağ geçidi görevi görecek şekilde yanıtlayan ana bilgisayarı ayarlamak. Sonra ssh sunucusunu, anahtara göre istekleri içeriye iletmek üzere yapılandırabilirsiniz. Tuşlarla SSH Gateway örneği

  • İstemcinizi bu ana bilgisayarı proxy olarak kullanacak şekilde ayarlayabilirsiniz. Başka bir deyişle, ağ geçidi ana bilgisayarına ssh olur ve ardından bu ana bilgisayarı iç ana bilgisayarla bağlantı kurmak için kullanır. İstemci yapılandırmasına sahip SSH proxy'si .

  • Ayrıca kenarda basit bir http proxy kurabilirsiniz. Ardından gelen bağlantılara izin vermek için bunu kullanın. HTTP proxy üzerinden SSH .

Açıkçası, yukarıdakilerin hepsinde, doğru şekilde yapılandırıldığından ve ağ geçidini kilitlediğinizden emin olmak oldukça önemlidir.


18

Son 16 aydır bu sorun için bir çözüm arayışı içindeyim. Ancak her baktığımda, bunu ilgili RFC'lerde belirtilen ve büyük uygulamalar tarafından uygulanan SSH protokolüyle yapmak imkansız görünüyor.

Ancak, hafifçe değiştirilmiş bir SSH istemcisi kullanmaya istekliyseniz ve tam olarak tasarlandıklarında amaçlanmayan protokolleri kullanmak istiyorsanız, o zaman bunu başarmak mümkündür. Bu konuda daha fazlası.

Neden mümkün değil

İstemci ana bilgisayar adını SSH protokolünün bir parçası olarak göndermez.

Ana bilgisayar adını bir DNS aramasının bir parçası olarak gönderebilir, ancak bu önbelleğe alınabilir ve istemciden çözümleyicilerden yetkili sunuculara giden yol proxy'yi geçemez ve hatta belirli DNS aramalarını ilişkilendirmenin sağlam bir yolu olmasa bile belirli SSH istemcileri.

SSH protokolü ile de yapabileceğiniz hiçbir şey yok. İstemciden SSH sürümü başlığını bile görmeden bir sunucu seçmeniz gerekir. Proxy'ye bir şey göndermeden önce müşteriye bir afiş göndermelisiniz. Sunuculardan gelen afişler farklı olabilir ve hangisinin kullanılacağını tahmin etme şansınız yoktur.

Bu afiş şifrelenmemiş olarak gönderilse bile, değiştiremezsiniz. Bu afişin her bir kısmı, bağlantı kurulumu sırasında doğrulanacaktır, bu nedenle hattın biraz altında bir bağlantı hatasına neden olmuş olursunuz.

Bana göre, bu bağlantının işe yaraması için müşteri tarafında bir şeylerin değiştirilmesi gerekiyor.

Geçici çözümlerin çoğu SSH trafiğini farklı bir protokolün içine yerleştiriyor. Biri ayrıca, SSH protokolüne kendisinin de eklendiğini hayal edebilir, bunun içinde müşteri tarafından gönderilen sürüm başlığı ana bilgisayar adını içerir. Afişin bir kısmı şu anda serbest biçimli bir kimlik alanı olarak belirtildiğinden ve istemciler genellikle sürüm afişini kendi göndermeden önce sunucudan beklemelerine rağmen, protokol istemcinin kendi afişini göndermesine izin verir ilk. Ssh istemcisinin bazı son sürümleri (örneğin, Ubuntu 14.04'teki sürüm) sunucu başlığını beklemeden başlığını gönderir.

Sunucunun ana bilgisayar adını bu başlığa dahil etmek için adımlar atmış olan herhangi bir müşteri bilmiyorum. Böyle bir özellik eklemek için OpenSSH posta listesine bir düzeltme eki gönderdim . Ancak, ana bilgisayar adını SSH trafiğini izleyen hiç kimseye açıklamama arzusuna dayanarak reddedildi. Gizli bir ana bilgisayar adı, ad tabanlı bir proxy'nin çalışmasıyla temel olarak uyuşmadığından, yakında SSH protokolü için resmi bir SNI uzantısı görmeyi beklemeyin.

Gerçek bir çözüm

Benim için en iyi olan çözüm aslında IPv6'yı kullanmaktı.

IPv6 ile her sunucuya atanmış ayrı bir IP adresine sahip olabilirim, böylece ağ geçidi paketi hangi sunucuya göndereceğini bulmak için hedef IP adresini kullanabilir. SSH istemcileri, bazen IPv6 adresini almanın tek yolunun Teredo'yu kullanacağı ağlarda çalışıyor olabilir. Teredo'nun güvenilmez olduğu bilinmektedir, ancak yalnızca bağlantının yerel IPv6 ucu bir genel Teredo rölesi kullanıyorsa. Biri proxy'yi yöneteceğiniz ağ geçidine bir Teredo rölesi yerleştirebilir. Miredo, beş dakikadan daha kısa bir sürede röle olarak kurulabilir ve yapılandırılabilir.

Bir geçici çözüm

Bir atlama ana bilgisayarı / bastion ana bilgisayarı kullanabilirsiniz. Bu yaklaşım, tek tek sunucuların SSH bağlantı noktalarını doğrudan halka açık internete maruz bırakmak istemediğiniz durumlar için tasarlanmıştır. SSH için ihtiyaç duyduğunuz harici IP adreslerinin sayısını azaltma konusunda ek bir faydası var, bu yüzden bu senaryoda kullanılabilir. Güvenlik nedeniyle başka bir koruma katmanı eklemeye yönelik bir çözüm olması, ek güvenlik gerekmediğinde kullanmanıza engel olmaz.

ssh -o ProxyCommand='ssh -W %h:%p user1@bastion' user2@target

Gerçek çözüm (IPv6) erişiminizin dışındaysa, çalışmasını sağlamak için kesmek için kirli

Tarif etmek üzere olduğum hack, yalnızca kesinlikle en son çare olarak kullanılmalı. Bu hack'i kullanmayı düşünmeden önce, SSH üzerinden harici olarak erişilebilir olmasını istediğiniz her sunucu için bir IPv6 adresi almanızı şiddetle tavsiye ederim. IPv6'yı SSH sunucularınıza erişmek için birincil yönteminiz olarak kullanın ve yalnızca IPv6'yı dağıtma üzerinde herhangi bir etkisinin olmadığı IPv4 içeren bir ağdan bir SSH istemcisi çalıştırmanız gerektiğinde kullanın.

Buradaki fikir, müşteri ve sunucu arasındaki trafiğin, kusursuz bir şekilde geçerli SSH trafiği olması gerektiğidir. Ancak proxy'nin yalnızca ana bilgisayar adını tanımlamak için paket akışını yeterince anlaması gerekir. SSH, bir ana bilgisayar adı göndermenin bir yolunu tanımlamadığından, bunun yerine, böyle bir olasılık sağlayan diğer protokolleri göz önüne alabilirsiniz.

Hem HTTP hem de HTTPS, sunucunun herhangi bir veri göndermeden önce istemciye bir ana bilgisayar adı göndermesine izin verir. Şimdi soru, SSH trafiği olarak ve HTTP ve HTTPS olarak aynı anda geçerli olan bir bayt akışı oluşturmanın mümkün olup olmadığıdır. HTTP'ler hemen hemen başlangıçsızdır, ancak HTTP mümkündür (HTTP'nin yeterince liberal tanımları için).

SSH-2.0-OpenSSH_6.6.1 / HTTP/1.1
$: 
Host: example.com

Bu size SSH veya HTTP gibi görünüyor mu? SSH'dir ve tamamen RFC uyumludur (bazı ikili karakterlerin SF görüntülemesi tarafından biraz karıştırılması dışında).

SSH sürüm dizgisi, yukarıdaki değere sahip olan bir yorum alanı içerir / HTTP/1.1. Newline SSH'den sonra bazı ikili paket verileri vardır. İlk paket, MSG_SSH_IGNOREmüşteri tarafından gönderilen ve sunucu tarafından yok sayılan bir mesajdır. İhmal edilecek yük:

: 
Host: example.com

Bir HTTP proxy'si kabul ettiği şekilde yeterince liberalse, aynı bayt dizisi denilen bir HTTP yöntemi SSH-2.0-OpenSSH_6.6.1olarak yorumlanır ve yoksayma iletisinin başındaki ikili veriler bir HTTP başlık adı olarak yorumlanır.

Proxy, ne HTTP yöntemini ne de ilk başlığını anlardı. Ancak Host, arka ucu bulmak için gereken tek şey olan başlığı anlayabilir .

Bunun çalışması için proxy'nin, yalnızca arka ucu bulmak için yeterli HTTP'yi anlaması gerektiği prensibiyle tasarlanması gerekirdi ve arka uç bulunduktan sonra, proxy basitçe ham bayt akışını geçecek ve gerçek sonlandırmayı terk edecek arka uç tarafından yapılacak HTTP bağlantısının

HTTP proxy'si hakkında çok fazla varsayımda bulunmak için biraz uzatma gibi gelebilir. Ancak, SSH'yi desteklemek amacıyla geliştirilen yeni bir yazılım yüklemeye istekliyseniz, HTTP proxy gereksinimleri çok kötü gelmiyor.

Kendi durumumda, bu yöntemi kodda, konfigürasyonda veya başka türlü bir değişiklik yapmadan önceden kurulmuş bir proxy üzerinde çalışmak için buldum. Ve bu sadece HTTP ile yazılmış ve SSH'sız akılda tutulan bir proxy içindi.

Müşteri ve vekil kavramının ispatı . (Proxy'nin benim tarafımdan işletilen bir hizmet olduğunu reddetme. Bu kullanımı destekleyen başka bir proxy onaylandıktan sonra bağlantıyı değiştirmekten çekinmeyin.)

Bu kesimin uyarıları

  • Kullanmayın. IPv6 olan gerçek çözümü kullanmak daha iyidir.
  • Proxy HTTP trafiğini anlamaya çalışırsa, kesinlikle kesilecektir.
  • Değiştirilmiş bir SSH istemcisine güvenmek hoş değildir.

the gateway can use the destination IP address to find out which server to send the packet toIPv6 çözümünde ne demek istediğinizi ayrıntılandırabilir misiniz ?
Jacob Ford

@JacobFord Bu cümleyi anlamak için anahtar proxy değil , ağ geçidi kelimesini kullanmamdır . IPv6 ile her ana bilgisayara bir tane atamak için yeterli IP adresi alırsınız ve hala yedek adresleri vardır. Proxy'nin arkasına koyacağınız tüm makinelerin kendi IP adresleri olacaktı; Artık bir proxy'ye ihtiyacınız yok, istemciler trafiklerini istenen ana bilgisayarın IP adresine gönderir ve trafiği doğrudan oraya yönlendirebilirsiniz.
kasperd

Geçici çözüm bölümü için, ssh için nispeten yeni bir komut anahtarı vardır -J, bu nedenle kullanabilirsiniz: ssh -J user1 @ front user2 @ target
PMN

3

Bunun mümkün olacağını düşündüğüm bir şey değil, en azından tarif ettiğiniz şekilde, yanlış olduğumu ispat etmeyi sevsem de. Müşterinin bağlanmak istediği ana bilgisayar adını gönderdiği görünmüyor (en azından açık şekilde). SSH bağlantısının ilk adımı şifreleme kurmak gibi görünüyor.

Ayrıca, ana bilgisayar anahtar doğrulamasıyla ilgili sorunlarınız olur. SSH istemcileri, bir IP adresini ve ana bilgisayar adını temel alarak anahtarları doğrular. Farklı anahtarlara sahip, ancak bağlandığınız IP ile birden çok ana bilgisayar adınız olur.

Olası bir çözüm, müşterilerin bu makineye girebileceği, normal (veya istenirse kısıtlanmış) bir kabuk alabileceği ve daha sonra oradan dahili konaklara ssh yapabileceği bir 'temel' ana bilgisayara sahip olmak olacaktır.


Temel kavram, güncel olarak kurduğumuz şeydir ancak sürüm kontrolüm için sorunlu (fazladan çaba sarf etmeden).
ahanson

Ssh'nin fqdn'yi göndermemesi ve DNS'yi istemci tarafında işlemesi çok can sıkıcı bir durum. Sanırım çoğu TCP / IP uygulama seviyesi protokolü oluşturulduğunda insanlar genel IP kullanımı ve NAT konusunda endişelenmediler. Ciddi olduğundan, gereken iptables (yani çekirdek filtreler) ile FQDN tabanlı NAT yapabilecektir.
önyargı

Ana bilgisayar anahtarı ters proxy'nin anahtarı olabilir. Bu, bir iç ağ ve ana bilgisayar üzerinde kontrol sahibi olduğunuz için arka uç güvenliğine güveniyorsanız, bu bir avantajdır.
rox0r

@bias Üst düzey protokol ana bilgisayar adını göndermiş olsa bile, ana bilgisayar adına göre NAT yapamazsınız. Yapılmamasının nedeni, arka uç seçiminin SYN paketi alındığında yapılması gerektiği, ancak ana bilgisayar adının yalnızca SYN işlendikten ve bir SYN-ACK döndürüldükten sonra gönderilmesi gerektiğidir. Bununla birlikte, http ve https gibi hostname gönderen protokoller için çok ince bir uygulama katmanı proxy kullanabilirsiniz.
kasperd

3

Blokta yeni bir çocuk var. SSH piper, bağlantınızı, önceden tanımlanmış kullanıcı adlarına göre, iç ana bilgisayarlara eşlenmesi gereken şekilde yönlendirir. Ters proxy bağlamındaki en iyi çözüm budur.

Github üzerinde SSh piper

İlk testlerim onaylandı, SSH ve SFTP'nin ikisi de işe yarıyor.


Bu etkili bir MITM saldırısı. MITM saldırılarına karşı korunan her kurulumun kırılmasını bekliyorum.
kasperd

1
Aslında ev sahibi parti hem ev sahibi hem de ortadaki adamdır, bu nedenle sadece ikisi söz konusudur.
Király István

@ KirályIstván bu harika bir proje ve diğer cevapların% 100 doğru olmadığını kanıtlıyor. Github.com/gliderlabs/sshfront ve bazı bash / python'u temel alan benzer bir araç yarattım (kaynak açamıyorum ama bu ilginç değil - bash ssh istemcisini çalıştırıyor ve python auth handler olarak kullanılıyor). Ancak şimdiki çözümle ilgili bir sorunum var. Sftp'yi desteklemez (scp çalışır). Alt sistemi çalıştırmaya çalışıyor debug1: Sending subsystem: sftp. Görünüşe göre gömlek önü alt sistemleri desteklemiyor. SSH Piper'da Hem'i destekliyor musunuz?
Maciek Sawicki

1
@ MaciekSawicki Ben yazar değilim. Sadece projemde kullanıyorum. .)
Király István

2

Proxy moduna sahip olan Honeytrap'in (düşük etkileşimli bal küpü) bunu başarması için değiştirilemeyeceğini merak ediyorum.

Bu honeypot herhangi bir protokolü başka bir bilgisayara iletebilir. Ad tabanlı bir vhost sistemi eklemek (Apache tarafından uygulandığı gibi), herhangi bir protokol no için mükemmel bir ters proxy yapabilir?

Bunu başarabilecek becerilerim yok ama belki harika bir proje olabilir.


Mükemmel fikir!
önyargı

1
Apache'deki vhost özelliği, sunucudan herhangi bir veri gönderilmeden önce ana bilgisayar adını gönderen istemciye dayanır. SSH protokolü böyle bir ana bilgisayar adı içermiyor, bu yüzden böyle bir özelliği nasıl uygulamaya başlayacağınızı bile bilmiyorum. Ancak fikirlerinizi detaylandırabilirseniz, bir kavram kanıtı uygulamaktan veya size neden işe yaramayacağını söylemekten memnuniyet duyarım.
kasperd

1

Bir güvenlik duvarının arkasına erişmek istediğiniz bağlantı noktası / ana bilgisayar sayısı arttıkça, VPN'lerin rahatlığı artar.

Yine de VPN'leri sevmiyorum.


1

ssh nasıl çalıştığından dolayı bunun mümkün olmadığını düşünüyorum. Https'ye benzer şekilde, farklı ana bilgisayarlar için farklı (harici) IP'lere sahip olmanız gerekir, çünkü ağ geçidi nereye bağlanmak istediğinizi bilmez, çünkü ssh içindeki her şey gömülüdür.

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.