NAT Traversal Nasıl Çalışır (2020)
(tailscale.com)- NAT Traversal, NAT ve güvenlik duvarlarının arkasındaki cihazların UDP paketlerini doğrudan değiş tokuş etmesini sağlayarak Tailscale’in WireGuard tünellerini merkezi bir hub olmadan bağlayabilmesinin temelini oluşturan teknolojidir
- Temel önkoşul, protokolün UDP tabanlı olması ve NAT keşfi için kullanılan paketlerle gerçek iletişim paketlerinin aynı ağ soketinden gönderilip alınabilmesidir
- Durum bilgisi tutan güvenlik duvarları yalnızca önce dışarı çıkan UDP paketiyle eşleşen yanıtları kabul ettiğinden, eşler birbirlerinin
ip:portbilgisini bilip neredeyse aynı anda paket gönderirse güvenlik duvarı durumunu açabilir - NAT kaynak IP ve portu değiştirdiği için STUN, port eşleme, NAT64 işleme, doğum günü paradoksuna dayalı port keşfi ve röle gibi tamamlayıcı tekniklere ihtiyaç duyulur
- ICE olası aday yolları aynı anda deneyip en iyi yolu seçer; Tailscale ise DERP rölesi üzerinden hemen bağlantı kurar ve daha iyi bir doğrudan yol bulunduğunda şeffaf biçimde ona geçer
NAT Traversal için temel koşullar
- Amaç, iki cihaz arasında çift yönlü bir UDP paket akışı oluşturmak ve bunun üzerinde WireGuard, QUIC, WebRTC gibi protokollerin çalışmasını sağlamaktır
- Doğrudan uygulamak için iki koşul önemlidir
- Protokol UDP tabanlı olmalıdır
- TCP ile de mümkündür, ancak karmaşıklık artar ve uygulama biçimine bağlı olarak çekirdek değişiklikleri gerekebilir
- Akış odaklı bir bağlantı gerekiyorsa UDP üzerinde çalışan QUIC düşünülebilir
- Programın paket gönderip aldığı ağ soketini doğrudan kontrol etmesi gerekir
- NAT Traversal, asıl protokolün dışında ek paketler göndermek zorunda olduğundan mevcut ağ kütüphanelerine basitçe eklemek zordur
- NAT Traversal mantığının ve asıl protokolün aynı soketi paylaşıp paralel çalıştığı bir yapı yararlıdır
- Protokol UDP tabanlı olmalıdır
- Doğrudan soket erişimi zorsa yerel bir proxy konabilir
- Asıl protokol proxy ile iletişim kurar
- Proxy, NAT Traversal’dan ve eşe paket rölelemekten sorumludur
Durum bilgisi tutan güvenlik duvarlarını aşmak
- Durum bilgisi tutan güvenlik duvarları, geçmişte gördükleri paketleri hatırlayarak yeni paketlere izin verilip verilmeyeceğine karar verir
- Windows Defender firewall, Ubuntu
ufw, BSDpf, macOSpf, AWS Security Groups gibi biçimleri vardır - Yaygın yapılandırma, tüm outbound bağlantılara izin verip tüm inbound bağlantıları engellemektir
- Windows Defender firewall, Ubuntu
- UDP’de kural basittir
- Güvenlik duvarı
2.2.2.2:1234adresinden5.5.5.5:5678adresine çıkan bir UDP paketi gördüyse, ters yönde5.5.5.5:5678adresinden2.2.2.2:1234adresine gelen pakete izin verir - Daha gevşek bazı güvenlik duvarları, bir kez iletişim kurmuş yerel porta herhangi bir yerden gelen trafiğe izin verebilir; ancak bu giderek daha nadir görülür
- Güvenlik duvarı
- Sunucu ve istemci yapısında, güvenlik duvarı arkasındaki cihaz bağlantıyı önce başlatabildiği için sorun küçüktür
- VPN’de bu, güvenlik duvarı olmayan bir hub ile güvenlik duvarı arkasındaki spoke’ların bağlandığı hub-and-spoke yapısına dönüşür
- İki istemcinin doğrudan iletişim kurması gerektiğinde iki taraftaki güvenlik duvarlarının birbirini engellediği bir durum oluşur
- İki tarafın da yanıt alabilmek için önce dışarı paket göndermesi gerekir, ancak karşı taraf da aynı koşuldadır
- Kullanıcının port açmayı elle ayarlaması zahmetlidir ve Tailscale gibi mesh ağlarda ölçeklenebilirliği düşüktür
- Havaalanı veya kafe yönlendiricileri gibi kullanıcının kontrol edemediği çok sayıda güvenlik duvarı da vardır
- Çözümün özü, UDP güvenlik duvarı kurallarının gerçek bir yanıt ilişkisini doğrulamayarak yalnızca IP ve port kombinasyonuna bakmasıdır
- İki eş de karşı tarafın
ip:portbilgisini önceden bilip aynı anda UDP paketi gönderirse, ilk birkaç paket engellense bile güvenlik duvarı durumu açılır - Sonrasında karşı tarafın gönderdiği paketler yanıt gibi görünerek geçer
- İki eş de karşı tarafın
- Bu yöntem için bir yan kanal gerekir
- İki uç noktanın neredeyse aynı anda iletişim kurmayı denemesi gerekir
- Birkaç saniyelik gecikme olabilir; yalnızca birkaç bin bayt taşıyabilen bir iletişim yolu yeterlidir
- WebRTC bir sinyalleşme kanalı gerektirir; Tailscale ise coordination server ve DERP sunucularını yan kanal olarak kullanır
- Güvenlik duvarı durumu kalıcı değildir
- UDP oturumu zaman aşımı için yaygın değer 30 saniyedir
- Bağlantıyı korumak için düzenli aralıklarla paket göndermek ya da gerektiğinde out-of-band yöntemle bağlantıyı yeniden başlatmak gerekir
- Durum bilgisi tutan güvenlik duvarları birkaç katman olsa bile outbound trafiğe izin veriyorlarsa eşzamanlı gönderim yöntemiyle aşılabilirler
NAT’ın sorunu nasıl zorlaştırdığı
- NAT (Network Address Translator), durum bilgisi tutan bir güvenlik duvarı gibi çalışırken paketin IP adresini veya portunu da değiştirir
- NAT Traversal’da sorun yaratan şey çoğunlukla Source NAT (SNAT)’tır
- SNAT, birden fazla cihazın daha az sayıda IP adresini, çoğu zaman tek bir genel IPv4 adresini paylaşmasını sağlar
- DNAT da vardır, ancak burada ele alınan NAT Traversal sorunuyla ilişkisi daha sınırlıdır
- Örneğin bir dizüstü bilgisayar
192.168.0.20:1234adresinden internetteki7.7.7.7:5678sunucusuna UDP paketi gönderdiğinde, ev yönlendiricisi genel IP üzerinde boş bir port olan2.2.2.2:4242değerini seçer- Yönlendirici,
192.168.0.20:1234ile2.2.2.2:4242adreslerinin aynı olduğunu belirten bir NAT mapping oluşturur - Daha sonra çıkan paketler
2.2.2.2:4242adresinden gelmiş gibi değiştirilir - Gelen yanıtlar yeniden
192.168.0.20:1234adresine çevrilir
- Yönlendirici,
- Kurumsal ağlarda da aynı ilke geçerlidir
- Fark, NAT katmanının yüksek erişilebilirlik veya kapasite nedeniyle birden çok cihazdan oluşabilmesi ve birden fazla genel IP’ye sahip olabilmesidir
STUN ve NAT eşlemelerini keşfetmek
- NAT arkasındaki eş, karşı tarafın görebileceği kendi genel
ip:portbilgisini bilemez; NAT eşlemesi de genellikle internete çıkan trafik oluştuğunda yaratılır - STUN, NAT arkasındaki istemcinin internette nasıl göründüğünü öğrenmesini sağlayan protokoldür
- İstemci STUN sunucusuna “uç noktam sana nasıl görünüyor?” diye sorar
- STUN sunucusu, UDP paketinin geldiği genel
ip:portbilgisini yanıtlar
- STUN’ın bildirdiği genel
ip:porteşle paylaşıldığında, güvenlik duvarını aşmak için kullanılan eşzamanlı gönderim tekniği uygulanabilir - NAT Traversal mantığı ile gerçek iletişim protokolünün aynı soketi kullanması gerekmesinin nedeni de budur
- Her soket için NAT cihazında farklı bir eşleme oluşur
- Gerçek iletişimde kullanılacak soket dışında başka bir soketle STUN yapılırsa işe yaramaz bir
ip:portelde edilir
- STUN tek başına tüm NAT’ları çözemez
- Çoğu ev yönlendiricisinde çalışabilir
- Bazı kurumsal NAT ağ geçitlerinde başarısız olabilir
- STUN ile görünen
2.2.2.2:4242bilgisinin tüm internette aynı anlama geldiği varsayımı her zaman doğru değildir
Kolay NAT ve zor NAT
- NAT cihazları hedefe göre farklı eşlemeler oluşturabilir ya da hedeften bağımsız olarak aynı eşlemeyi koruyabilir
- RFC 4787, eşlemenin hedeften bağımsız olarak korunduğu kolay biçimi Endpoint-Independent Mapping (EIM) olarak adlandırır
- Eşlemenin hedefe göre değiştiği zor biçim Endpoint-Dependent Mapping (EDM)’dir
- Yalnızca hedef IP’ye göre değişebilir veya hedef IP ve port birlikte ölçüt alınabilir
- NAT Traversal açısından ikisi de iyi değildir
- Eski terimler olan Full Cone, Restricted Cone, Port-Restricted Cone, Symmetric NAT, NAT eşleme davranışı ile güvenlik duvarı davranışını birlikte ifade eder
- Pratik uygulamalarda “Symmetric ve diğerleri” ya da EIM ve EDM ayrımı daha önemlidir
- Eşzamanlı gönderim tekniği, çeşitli güvenlik duvarı türlerinden geçebilir
- Gerçek ortamlarda IP ve porta bağımlı güvenlik duvarları ezici çoğunluktadır
- Ancak yolun herhangi bir yerinde tek bir hard NAT bile varsa, yalnızca STUN ve eşzamanlı gönderimle sorun yaşanır
Doğrudan Bağlantı Başarısız Olduğunda Röle
- Doğrudan bağlantı, tüm teknikler kullanılsa bile başarısız olabilir
- NAT zorsa veya UC Berkeley guest Wi-Fi gibi DNS dışındaki outbound UDP’yi engelleyen ağlarda NAT teknikleriyle çözülemez
- Bu durumda iki taraf da erişebildiği bir röle üzerinden paket alışverişi yapabilir
- Doğrudan bağlantı kadar iyi değildir, ancak röle yol üzerinde yeterince yakınsa ve bant genişliği yeterliyse bağlantı kalitesindeki düşüş büyük olmayabilir
- Gecikme artsa veya bant genişliği azalsa bile hiç bağlantı olmamasından iyidir
- Geleneksel röle protokolü TURN’dür
- İstemci TURN sunucusunda kimlik doğrulaması yapar
- TURN sunucusu röle için bir
ip:portayırır - Eşler bu
ip:portüzerinden iletişim kurar
- Tailscale, TURN yerine DERP(Detoured Encrypted Routing Protocol) geliştirdi
- DERP, HTTP üzerinde çalışır
- Katı outbound kuralları olan ağlarda kullanışlıdır
- Hedefin açık anahtarına göre şifrelenmiş yükü röleler
- DERP iki rol üstlenir
- NAT Traversal başarısız olduğunda veri rölesi
- NAT Traversal’a yardımcı olan yan kanal
- STUN, eşzamanlı gönderim ve röleye kadar uygulandığında %90’dan fazlasında doğrudan bağlantının mümkün olduğu, rölenin ise her zaman bir tür bağlantılılığı garanti edebileceği tahmin edilir
Hard NAT İçin Ek Teknik
- Hard NAT’ta kolay taraftaki eş, zor taraftaki NAT’ın hangi portu açtığını bilmez
- STUN ile IP’nin genelde doğru olduğu varsayılabilir
- Bilinmeyen şey porttur ve olası değer sayısı 65.535’tir
- Tüm portları basitçe taramak, 100 paket/saniye hızında en kötü durumda yaklaşık 10 dakika sürer ve port taraması gibi görünür
- Doğum günü paradoksu kullanılarak arama maliyeti azaltılabilir
- Hard NAT tarafı 256 soketle 256 port açar, kolay NAT tarafı ise rastgele hedef portları dener
- 256 portun açık olduğu varsayılırsa başarı olasılığı şöyledir
- 174 rastgele deneme: %50
- 256 rastgele deneme: %64
- 1024 rastgele deneme: %98
- 2048 rastgele deneme: %99,9
- 100 port/saniye hızında yarısı 2 saniye içinde geçer; yaklaşık 20 saniyede ise tüm alanın %4’ünden azı denenmiş olsa da başarıya neredeyse kesin olarak ulaşılır
- İki taraf da hard NAT ise çok daha zordur
- Artık
{source port, destination port}çiftinin eşleşmesi gerekir - Aynı koşullarda 20 saniye sonra başarı olasılığı %0,01’dir
- %99,9 başarı olasılığı için iki tarafın da ayrı ayrı 170.000 probe göndermesi gerekir; 100 paket/saniye hızında bu 28 dakika sürer
- Artık
- Bu yöntem ev-ofis, ev-bulut, bazı ofis-bulut veya bulut-bulut senaryolarında bağlantılılığı iyileştirebilir
- Ev yönlendiricileri kolay NAT olma eğilimindedir; hard NAT ise ofis yönlendiricileri veya bulut NAT gateway’leri olma eğilimindedir
Port Eşleme Protokolleri
- NAT’a doğrudan “bu WAN portunu şu LAN
ip:portadresine ilet” diye istekte bulunan protokoller vardır - Başlıca üç tanesi şunlardır
- UPnP IGD: 1990’ların sonunda çıkan bir protokoldür; XML, SOAP ve UDP üzerinde multicast HTTP gibi teknolojiler kullanır, uygulaması ve güvenliği zordur
- NAT-PMP: Apple’ın geliştirdiği NAT Port Mapping Protocol’dür; yalnızca port yönlendirme yapar ve basittir
- PCP: NAT-PMP v2’nin Port Control Protocol’e evrilmiş hâlidir
- Yerel varsayılan gateway’de UPnP IGD, NAT-PMP ve PCP denenip yanıt alınırsa herkese açık port eşlemesi istenebilir
- Başarılı olursa STUN’da olduğu gibi herkese açık
ip:portöğrenilmekle kalmaz, NAT’ın ilgili port için daha hoşgörülü davranması da sağlanabilir - Nereden gelirse gelsin, eşlenmiş porta ulaşan her paket iç cihaza iletilir
- Başarılı olursa STUN’da olduğu gibi herkese açık
- Bu protokollere güvenilemez
- Cihazda uygulanmamış olabilirler
- Varsayılan olarak kapalı olabilirler
- Politika gereği devre dışı bırakılmış olabilirler
- UPnP’nin geçmişteki güvenlik açıkları nedeniyle politika gereği kapatıldığı durumlar vardır
- Bazı cihazlar tek bir “UPnP” onay kutusuyla UPnP, NAT-PMP ve PCP’yi birlikte kapatabilir
- Kullanılabiliyorlarsa veri yolundaki bir NAT fiilen ortadan kalkar ve bağlantı kolaylaşır
Double NAT ve CGNAT
- Bir cihazın önünde iki NAT katmanının bulunduğu double NAT durumunda en dıştaki, yani internetten hemen önceki NAT’ın davranışı en önemlisidir
- Birden fazla katmanlı durum bilgili güvenlik duvarlarında olduğu gibi ek NAT katmanları genellikle görünmezdir
- Mevcut teknikler NAT katmanı sayısından bağımsız olarak çalışabilir
- Double NAT’ın ciddi biçimde bozduğu şey port eşleme protokolleridir
- Port eşleme, istemciye en yakın NAT katmanında etkili olur
- Ancak uzak eşin geçmesi gereken yer en dıştaki NAT’tır
- Sonuçta elde edilen
ip:port, ara ağın adresidir ve uzak eş buna ulaşamaz
- Double NAT, açık NAT Traversal yapmayan çoğu sıradan uygulama için görünmezdir
- Ancak birçok oyunda çok oyunculu deneyimi kötüleştirebilir ve IPv6’yı ortadan kaldırarak NAT’sız bağlantı seçeneklerini azaltabilir
- CGNAT(Carrier-Grade NAT), ISP’nin IPv4 adres kıtlığını çözmek için bir kez daha SNAT uyguladığı yapıdır
- Ev yönlendiricisi cihazları ara bir IP’ye SNAT eder
- ISP ağı içindeki ikinci NAT katmanı, ara IP’leri daha az sayıda herkese açık IP’ye eşler
- CGNAT’ta kullanıcı ISP’nin NAT’ını sıfırlayamaz
- Geçmişte ileri seviye kullanıcılar ev yönlendiricisindeki port yönlendirmeyle sorunu aşabiliyordu, ancak CGNAT’ta bu yöntem engellenir
- CGNAT da temelde double NAT olduğundan mevcut tekniklerin çoğu çalışmaya devam eder
- Port eşleme protokolleri istisnai olarak sınırlıdır
Hairpinning Sorunu
- Aynı CGNAT’ın arkasında olup farklı ev NAT’larının arkasında bulunan iki eş özel bir sorunla karşılaşır
- STUN sunucusu internet dışından görülen herkese açık
ip:portbilgisini verir - Ancak iki eşin gerçekte ihtiyaç duyduğu şey, CGNAT içindeki ara ağda geçerli olan
ip:portbilgisidir
- STUN sunucusu internet dışından görülen herkese açık
- Ev NAT’larından en az biri port eşleme protokolünü destekliyorsa bağlantı kolaylaşabilir
- Double NAT nedeniyle port eşleme protokolünün ara ağdaki
ip:portbilgisini vermesi bu kez yardımcı olur
- Double NAT nedeniyle port eşleme protokolünün ara ağdaki
- Port eşleme kullanılamıyorsa hairpinning gerekir
- Örneğin peer A, STUN ile elde ettiği peer B’nin
2.2.2.2:5678adresine paket gönderir - CGNAT’ın bu paketi dış internete göndermek yerine içeride peer B’nin NAT eşlemesine geri döndürmesi gerekir
- Örneğin peer A, STUN ile elde ettiği peer B’nin
- Birçok NAT hairpinning’i desteklemez
- İç ağdan iç olmayan bir IP’ye giden paketlerin her zaman internete çıktığını varsayan cihazlar vardır
- Bu varsayım yönlendirme silikonuna gömülü olabilir ve yeni donanım olmadan düzeltilemeyebilir
- CGNAT devreye girdiğinde hairpinning bağlantılılık açısından önemli hâle gelir
- Hairpinning ve port eşleme ikisi de başarısız olursa röle kullanmak gerekir
IPv6 ve NAT64
- Yalnızca IPv6 olan bir dünyada NAT sorunu çok daha basit hale gelir
- Tüm cihazlar NAT olmadan erişilebilir adreslere sahip olabilir
- Ancak durum bilgili güvenlik duvarları yine de kalacağından güvenlik duvarını aşma ve yan kanallar yine de gerekir
- Giden UDP’yi engelleyen ağlar için HTTP gibi protokoller kullanan fallback relay’ler de hâlâ yararlıdır
- Yalnızca IPv6 henüz yeterli değil
- Dünya büyük ölçüde IPv4 kullanıyor ve yaklaşık %33 IPv6 düzeyinde
- IPv6 dağıtımı eşit olmadığından, eş kombinasyonuna göre %100 IPv6 da olabilir, %0 IPv6 da
- Hedef koşulsuz bağlantıysa IPv4+NAT işlemeye devam etmek gerekir
- IPv6 ve IPv4’ün birlikte var olması NAT64 adlı ek bir durum oluşturur
- NAT44, IPv4’ü başka bir IPv4’e çevirir
- NAT64, içerideki IPv6’yı dışarıdaki IPv4’e çevirir
- DNS64 ile birlikte kullanıldığında, uç cihaza IPv6-only ağ gibi görünürken IPv4 internete erişim sağlar
- Yalnızca DNS adları kullanan uygulamaların NAT64’ün pek farkında olması gerekmez
- Ancak NAT Traversal belirli IP ve portlarla doğrudan uğraştığı için ayrı işlem gerekir
- Cihaz CLAT(Customer-side translator) destekliyorsa, işletim sistemi doğrudan IPv4 bağlantısı varmış gibi göstererek NAT64’ü arka planda işler
- CLAT mobil cihazlarda yaygındır
- Masaüstü, dizüstü ve sunucularda nadirdir
- CLAT yoksa NAT64+DNS64’ü doğrudan algılamak gerekir
ipv4only.arpa.için DNS isteği gönderilir- Bu ad yalnızca bilinen sabit IPv4 adreslerine çözümlenir
- IPv6 adresi dönerse bunu DNS64 dönüştürmüş demektir; böylece NAT64 prefix’i öğrenilebilir
- Bundan sonra bir IPv4 adresiyle iletişim kurmak için
{NAT64 prefix + IPv4 address}biçiminde IPv6 paketi göndermek yeterlidir- NAT64 üzerinden STUN çalıştırıp public
ip:portbulunduğunda, tekrar sıradan NAT Traversal problemine dönülür
- NAT64 üzerinden STUN çalıştırıp public
ICE ile aday yolları birleştirme
- Tüm teknikler arasında hangisinin kullanılacağını baştan kesin biçimde sınıflandırma yaklaşımı iyi ölçeklenmez
- Çünkü ağ mühendisleri ve NAT cihazı uygulayıcıları çok çeşitli davranışlar üretir
- ICE(Interactive Connectivity Establishment)’in özü, mümkün olan her şeyi aynı anda denemek ve çalışanlar arasından en iyi yolu seçen bir algoritma olmasıdır
- İletişim başlarken yerel soket için aday endpoint listesini toplar
- IPv6
ip:ports - IPv4 LAN
ip:ports - STUN ile keşfedilen IPv4 WAN
ip:ports - NAT64 translator üzerinden keşfedilen IPv4 WAN
ip:ports - Port mapping protokolüyle tahsis edilen IPv4 WAN
ip:port - Statik yapılandırılmış port forwarding gibi operatör tarafından sağlanan endpoint’ler
- IPv6
- Ardından yan kanal üzerinden aday listeleri değiş tokuş edilir ve karşı tarafın verdiği tüm endpoint’lere probe paketleri gönderilir
- Probe paketleri güvenlik duvarını ve NAT’ı açmaya yarayan paketler olarak iş görür
- Aynı zamanda ping/pong biçiminde durum kontrolü görevi de görür
- Belirli bir süre sonra çalıştığı doğrulanan aday yollar arasından, sezgisel olarak en iyi yol seçilir
- ICE genellikle LAN > WAN > WAN+NAT gibi önceden belirlenmiş puanlar kullanır
- Tailscale v0.100.0’dan itibaren sabit kodlanmış tercih sırası yerine gidiş-dönüş gecikmesini kullanır
- Tailscale bağlantıyı katı bir probe aşaması ve iletişim aşaması olarak ayırmaz
- Tüm bağlantılar DERP önceden seçilmiş halde başlar
- Kullanıcı fallback yol üzerinden bağlantıyı hemen kullanabilir
- Yol keşfi paralel çalışır; birkaç saniye sonra daha iyi bir yol bulunursa şeffaf biçimde yükseltilir
Çalışma sırasında yolun korunması ve güvenlik
- Asimetrik yollara dikkat etmek gerekir
- ICE, iki eşin de aynı ağ yolunu seçip çift yönlü paket akışının sürmesini sağlamaya çalışır
- Aynı düzeyde bir prosedür uygulamasanız bile kullanılan tüm yollarda çift yönlü trafik olmalıdır
- Periyodik ping/pong probe’ları bile bunu korumaya yetebilir
- O anda seçili yol başarısız olabilir
- NAT bakımı nedeniyle durumun kaybolması buna örnektir
- Olası tüm yolları sürekli probe ederek warm fallback tutulabilir
- Ancak downgrade nadir olduğundan, son çare relay’e düşüp yol keşfini yeniden başlatmak daha verimli olabilir
- Üst protokolün kendi güvenliğini sağladığı varsayımı önemlidir
- QUIC TLS sertifikaları kullanır
- WireGuard kendi public key’lerini kullanır
- Yol dinamik olarak değiştirildiğinde IP tabanlı güvenlik anlamsız hale gelir
- En azından end-to-end kimlik doğrulama gerekir
- Üst katmanda end-to-end güvenlik varsa ping/pong probe’ları spoof edilebilir olsa bile, en kötü durumda saldırgan trafiğin kendi üzerinden geçmesini sağlamaya çalışabilir
- Yine de yol keşif paketlerinin de doğrulanıp şifrelenmesi daha iyidir
Sağlam NAT Traversal bileşenleri
- Sağlam NAT Traversal için şu öğeler gerekir
- UDP tabanlı olarak genişletilecek bir protokol
- Program içinden doğrudan erişilebilen bir soket
- Eşle iletişim kurmak için bir yan kanal
- Birkaç STUN sunucusu
- İsteğe bağlı ama güçlü biçimde önerilen bir fallback relay ağı
- Uygulama adımları şöyledir
- Doğrudan bağlı arayüzlerde soketin tüm
ip:portsdeğerleri listelenir - STUN sunucularına sorgu gönderilerek WAN
ip:portsve NAT zorluk derecesi bulunur - Port mapping protokolüyle ek WAN
ip:portsbulunur - NAT64 varsa algılanır ve o yol üzerinden de WAN
ip:portbulunur - Yan kanal üzerinden tüm
ip:portsve şifreleme anahtarları eşle değiş tokuş edilir - Hızlı bağlantı kurulumu için önce fallback relay üzerinden iletişim kurulabilir
- Karşı tarafın tüm
ip:portsdeğerleri probe edilir; gerekirse hard NAT’ı aşmak için doğum günü paradoksu tabanlı arama yapılır - Mevcut yoldan daha iyi bir bağlantı yolu bulunursa şeffaf biçimde yükseltilir
- Etkin yol durursa, bağlantıyı korumak için gerektiğinde downgrade edilir
- Tüm iletişim end-to-end şifrelenmeli ve doğrulanmalıdır
- Doğrudan bağlı arayüzlerde soketin tüm
1 yorum
Hacker News yorumları
Harika bir yazı. Genelde TCP tabanlı hole punching’in UDP’den daha zor olduğu için yapılmaması gerektiğine dair örtük bir kabul var; oysa pratikte, zaten karmaşık olan UDP akışına kıyasla ek karmaşıklık çok büyük görünmüyor
Yazıda da TCP NAT geçişinin mümkün olduğu, ancak karmaşıklık eklediği ve derine inildiğinde çekirdek değişiklikleri gerektirebileceği kabul ediliyor. Yine de ham UDP paketiyle bağlantıyı başlatma kısmını TCP SYN paketi ve eşzamanlı açma (simultaneous open) desteğiyle değiştirmenin yeterli olacağını düşünüyorum
Özellikle UC Berkeley misafir Wi‑Fi’ı gibi DNS dışındaki tüm UDP çıkışlarını engelleyen ağlar olduğunu düşününce, TCP hole punching’i yalnızca “UDP’den daha zor” diye geçiştirmek üzücü. Neredeyse benzer şekilde uygulanabilir ve ek karmaşıklığının da sınırlı olduğunu düşünüyorum
https://ttcplinux.sourceforge.net/documents/one/tcpstate/tcp...
Bu yüzden TCP’de eşzamanlı açma yapmanın ek karmaşıklığı oldukça küçüktür. Asıl zor kısım, açık eşlemeyi iletmek ve “eşzamanlı” delme/açmayı koordine etmektir; bu da genelde UDP’de de gerekir
TCP’deki ek bir karmaşıklık, sahte TCP SYN paketleri üretmek yerine gerçek bir
connect()çağrısı yapmak gerekmesidir. Çünkü bazı güvenlik duvarları sıra numarasına bakarAncak TCP hole punching, UDP paketlerine kıyasla SYN flood’a çok daha fazla benzeyebilir; bu yüzden bazı ağlarda başarı oranı düşebilir. Pratikte ise henüz çok fazla filtrelemeyle karşılaşmadım
TCP hole punching oldukça ilginç. Birden fazla NTP ölçümüyle sistem saatinin NTP’ye göre ne kadar saptığını, yani “saat ofsetini” hesaplıyor; başlatıcı da NTP zamanına göre gelecekteki bir buluşma zamanı belirliyor. Beklenenden daha doğru ve aynı arayüzdeki soketler arasında TCP hole punching de çalışıyor
Bu tuhaf yerel tabanlı punching modunu desteklememin nedeni, ana makine içi punching bu verimlilikle başarılı oluyorsa LAN ve internette de yeterince hızlı olma ihtimalinin yüksek olmasıydı. Kod Python’da ve ilk deneme oldukça sarsıcıydı. TCP hole punching zamanlamaya duyarlı olduğundan, Python’da eski usul doğrudan soket yönetimi, threading ve C soket deneyimine dayanarak yapılmış derme çatma bir event loop kullanınca başarısız oldu
O kodu çalıştırmak için Python sürecinin önceliğini yükseltmek, böylece başka süreçlerin punching denemeleri arasında gecikme yaratmasını engellemek gerekiyordu. Verimsiz bir implementasyonda zamanlamaya bu kadar duyarlı. Mevcut implementasyon, her biri kendi event loop’una sahip bir süreç havuzu kullanıyor; zamana yayılmış bir iş listesi oluşturuyor ve her iş aynı soketi yeniden kullanarak bağlantıyı açıyor. Başlıca işletim sistemlerinde test ettikten sonra Python’da en iyi yaklaşımın bu olduğuna karar verdim
TCP ve UDP hole punching’in zorluklarının benzer olduğu görüşüne katılıyorum. İkisinde de en zor kısım NAT öngörüsü aşaması. Henüz simetrik NAT aşma kodunu kullanmadım, ama bunu entegre etmenin ya da yeni bir eklenti olarak yapmanın yolu görünmeye başladı
Yönlendiricinin durum tablosu çok küçüktür ve bazı punching teknikleri oldukça agresiftir. Örneğin simetrik NAT’ı aşmaya çalışan algoritmalar gibi yüzlerce TCP bağlantısı açılırsa, yönlendirici hizmet reddi durumuna sokulabilir
UDP’de durum yönetimi optimizasyonları sayesinde, punching yüzünden tüm yönlendiricinin kilitlenme olasılığı daha düşük olabilir. Ancak bu bir tahmin
Etkisi şaşırtıcı derecede iyi, ama bunu prodüksiyon kurumsal ağına koyalım denince nedense içim rahat etmiyor
Geleneksel NAT ve güvenlik duvarını aşmayı, bunun yerine yalnızca tek bir yazılım ACL’ine dayanmayı öneriyor gibi hissettirdiği için riskli görünüyor. Örneğin AWS test ortamında unutulmuş bir VM’de Tailscale varsa ve saldırgan oraya erişirse, iç kurumsal ağdaki dizüstü bilgisayara kadar çekirdekten geçip yalnızca kullanıcı alanındaki Tailscale ACL kodunun izin/verme engelleme kararını verdiği bir yol oluşuyor gibi görünüyor
Yetkisiz biri o noktaya kadar girse bunu fark edip edemeyeceğimizi bilmiyorum
NAT’ı ve onunla ilişkili durum izlemeli filtrelerin çoğunu delmek çok kolaydır. Gerçek kurumsal prodüksiyon ortamlarında, satılık ürün olarak böyle şeyler uyguladım; bu sihir değil, sahadaki uzmanların iyi bildiği bir teknik
Gerçek paket filtreleme, yani güvenlik duvarı istiyorsanız NAT’tan ayrı bir güvenlik duvarı örneği yerleştirip uygun kurallar koymanız gerekir. Yine de bu da çoğunlukla trafik miktarını azaltmaya yarar; güvenlik duvarının kendisinin gerçek güvenlik getirisi artık küçüktür. Çünkü saldırıların çoğu HTTP/HTTPS, POP/IMAP gibi üst katmanlardan gelir
Aslında işin çoğunu durum izlemeli güvenlik duvarı yaparken krediyi NAT alıyor. Tailscale güvenlik duvarını ortadan kaldırmıyor; doğru ACL tabanlı, çok daha kapsamlı bir yapılandırma sağlıyor
Ancak Tailscale’in ACL araçlarının ciddi ölçüde geliştirilebileceğini kabul ediyorum
Bunun etkisiyle Windows ağ yığını da epey değişti ve daha karmaşık hale geldi. WireGuard Linux’a girdikten sonra herkesin bir yerlerde bir VPS’e bağlanan en az bir VPN’i var. Bilmediğimizi bilmediğimiz şeyler yüzünden, gerçek durum sandığımızdan daha kötü olabilir
Güvenlik duvarı farklı bir kavramdır. Yine de bağlantılılık ve güvenliği birlikte konuşacak olursak, internet güvenliğinin hep hedef porta göre paketleri engelleme yöntemine dayanmış olması üzücü ve rahatsız edici
Doğru olan yerine kolay olanı yapıp buna “profesyonel çözüm” denmesi de işin gerçeği
Yine de içerideki bir şeyin önce dışarıyla konuşması gerektiğinden, gerçek bir güvenlik duvarı hem giden hem gelen bağlantıları izin listesiyle yönetmelidir
Başka bir deyişle sınır güvenliğine güveniyorsanız, birilerinin eninde sonunda kendi kurumlarındaki “fosforlu yeleğin” ne olduğunu bulması sadece zaman meselesidir
Uygulama katmanında zaten şifreleme yapan cihazlar için, bağlantı şifrelemesi olmayan Tailscale benzeri bir alternatif olsa iyi olurdu. İnternetin neredeyse tamamı böyle çalıştığı gibi, her zaman alt katmana kadar şifrelemek gerekmez
Düşük güçlü cihazlarda, örneğin Tailscale benzeri bir tünel çalıştıran IoT cihazlarında hesaplama maliyeti özellikle büyüktür
GRE tünelleri var ve gerçekten çok kullanılıyor, ancak UDP hole punching’i ele almadıkları için hub-spoke yapısı gerekir. GRE, yani
ip fouile eşler arası mesh oluşturulamazKimlik doğrulama için kriptografik bir el sıkışmadan sonra UDP hole punching ve şifrelenmemiş GRE tüneli sağlayan bir kütüphane var mı merak ediyorum
Daha genel amaçlı bağlantılılığa yönelik bir şey istiyorsanız libp2p aradığınıza yakın olabilir
https://datatracker.ietf.org/doc/html/rfc8445
https://github.com/pion/webrtc
https://github.com/algesten/str0m
https://libp2p.io
Python ile yazdım. Ancak çoğu ağ kodunun aksine varsayılan arayüzün kullanılacağını varsaymaz. İstediğiniz herhangi bir arayüzde servis çalıştırabilmenizi sağlayarak daha çeşitli ve kullanışlı şeyler yapılmasını istedim
Çoğunlukla standart kütüphane modüllerine dayanır. C uzantılarını sevmiyorum; çapraz platform paketlerini sık sık bozuyorlar
Eşlerin karşı tarafın kullandığı
ip:portu önceden bilmesi gerektiğini ve bunu senkronize etmek için bir koordinasyon sunucusu kurulduğunu görünce, SIP keşke adının hakkını verseydi diye düşünüyorumSIP, Session Initiation Protocol demek; yani VPN gibi keyfi oturumları da başlatabilmesi gereken bir ada sahip, ama pratikte o kadar karmaşık bir keşmekeş ki katlanmaya değeri azalmış durumda. Aslen P2P RTP akışları kurmak için iletişim amaçlı bir yan kanal olarak tasarlanmış diye düşünüyorum
HTTP gibi ama durumlu, çift yönlü, federe ve UDP üzerinde de çalışıyor
baresip’in sadece SIP yapabilmek için uygulamak zorunda kaldığı miktara bakınca TLS over UDP’ye kadar uzanan devasa bir şey. Üstelik şişirilmiş de değil; o özelliklere gerçekten ihtiyaç var
2020 tarihli bir yazı. Önceki tartışmalar şöyleydi:
2022: https://news.ycombinator.com/item?id=30707711
2020: https://news.ycombinator.com/item?id=24241105
https://news.ycombinator.com/item?id=30707711
https://news.ycombinator.com/item?id=24241105
How NAT traversal works (2020) - https://news.ycombinator.com/item?id=36969018 - Ağustos 2023, 106 yorum
How NAT traversal works (2020) - https://news.ycombinator.com/item?id=30707711 - Mart 2022, 37 yorum
How NAT Traversal Works - https://news.ycombinator.com/item?id=24241105 - Ağustos 2020, 28 yorum
Bu arada bağlantıların tıklanabilir olmamasının nedeni, iki veya daha fazla boşlukla girintilenen satırların kod olarak biçimlendirilmesiymiş: https://news.ycombinator.com/formatdoc
İnsanlara NAT traversal'ı açıklarken gönderdiğim yazı tam olarak buydu.
P2P uygulamalar geliştirirken bu yönteme sürekli dayanmak zorunda kalabiliriz. IPv6 yeterli ivmeyi kazanamadı; çünkü NAT ve SNI yönlendirmesi çoğu insan için sorunların çoğunu çözüyor.
ISP'ler açısından da bu durumun değişmesini sağlayacak pek bir teşvik yok.
Tüm internette NAT traversal konusunu ele alan en ayrıntılı yazılardan biri olduğunu düşünüyorum. Yine de delta davranışı hakkında bilgi eksik.
Karmaşık bir şey değil; bazı NAT'ların ardışık dış portlar atarken gözlemlenebilir bir desene sahip olduğu anlamına geliyor. En yaygın desen kaynak portu korumaktır; önceki eşlemeden 1 artırma gibi desenler de olabilir.
Teorik olarak çok iyi bir yazı, ama bir yazılım mühendisinin pratikte bundan ne kadar yararlanabileceğini merak ediyorum. Çok şey açıklıyor, ancak bir algoritma yazmaya yetecek kadar ayrıntılı olmayabilir. Örneğin sadece bu yazıya bakarak NAT türünü test eden bir algoritma yazılabilir mi ya da kendi hole punching kodu ayarlanabilir mi, emin değilim.
Şahsen bu kadar uzun bir yazıdan daha yararlı olan basit tablolar içeren makaleler de gördüm. Yine de iyi bir başlangıç noktası olabilir.
Yazının son bölümü özellikle önemli. Mobil sistemlerde kullanılan simetrik NAT'ı aşma olasılığı var. Güncel NAT traversal araştırmaları da benzer teknikler kullanıyor ve neredeyse %100'e yakın başarı oranı iddia ediyor.
Geçmişi hatırlatan ilginç bir yazı. 2010'da bu yöntemi kullanan unutkan P2P mesh ağı oluşturmuştum.
O dönemde insanlar güvenliği bizim düşündüğümüz kadar önemsemiyordu; bugün de hâlâ yeterince önemsemiyorlar. Cihaz sayısı arttı, değerleri de yükseldi, ama hâlâ epey güvensizler.
Donanımsal güven kökü, kimlik doğrulama/yetkilendirme için güvenli bir güven zinciri ve asgari geçici yetkilere sahip gerçekten güvenli uç noktalar hâlâ zor; ev ağlarında, kurumsal ağlarda ve büyük üretim veri merkezi ağlarında ağ çevresi güvenlik tiyatrosu devam ediyor.
Bunların güvenlik ihlallerinin başlıca kök nedeni gibi görünmemesinin tek nedeni, hâlâ ortalıkta daha kolay saldırı yollarının bolca bulunması.
Biraz konu dışı ama birkaç hafta önce bu alan hakkında hiçbir şey bilmezken biraz okuma yaptım.
Edindiğim izlenim, IPv6'nın tüm bunları ortadan kaldırdığı ve NAT traversal'ı da artık gereksiz kıldığı yönünde. Öyleyse IPv6 neden daha yaygın kullanılmıyor; ayrıca ev ağı ve Tailscale VPN'de başlamak için ne yapmak gerekir, merak ediyorum.
İş tarafında da teşvik eksik.
IPv6 yerine böyle bir şeyin ortaya çıkmış olması bile yeterince iyi hack'lerin gücünü çok iyi gösteriyor.