Bölüm 43:Adres Çevirisi
Ağlar'a “Sen”i Katmak yazısının parçası: adres çubuğuna yazdığın tek bir isteğin peşinden bakırla fiberin fiziğine kadar inen uzun bir teknik yolculuk.
Tüm bölümler
- Giriş
- Adres Çubuğundan İsteğe
- Paket Anahtarlamalı Yol
- İsimden Adrese
- Önbellek, Tazelik ve Güven
- Port Numarası ve Soket
- Bağlantısız Taşıma: UDP
- Üç Adımlı El Sıkışma
- Simetrik Şifreleme
- Açık Anahtarlı Kriptografi
- TLS El Sıkışması
- Sertifika Zinciri
- HTTP Mesajının Anatomisi
- Durum, Çerez ve Oturum
- HTTP/2'den HTTP/3'e
- İçerik Dağıtım Ağları
- Diğer Uygulama Protokolleri
- Katmanlı Mimari
- Kapsülleme ve Başlıklar
- Paket Yakalama ve Çözümleme
- Ağ Arayüz Kartı
- Fiziksel Adresleme
- Hata Sezme ve CRC
- Adres Çözümleme: ARP
- Anahtarlama ve Ortam Erişimi
- Ağ Topolojileri
- Sanal Yerel Ağlar
- Kablosuz Erişim: 802.11
- Radyo Kanalı ve Kapasite
- Kablosuz Ağ Güvenliği
- Hücresel Ağlar
- Spektrum ve Kuşaklar
- Hareketlilik ve Aktarma
- Adres Kiralama: DHCP
- Adresin Anatomisi
- Adres Tükenmesi ve IPv6
- Yönlendirici Mimarisi
- Kuyruk Yönetimi
- Cihaz Yapılandırma
- Yönlendirme Protokolleri
- Kontrol Düzlemi ve SDN
- Ağ İzleme ve Yönetimi
- Alanlar Arası Yönlendirme
- Adres Çevirisi
- Ara Kutular
- Tünelleme ve IPsec
- Güvenlik Duvarları
- Operatör ve Metro Ağları
- Bitten Sinyale
- Çoklama Teknikleri
- İletim Ortamları
- Kablo Sonlandırma
- Fiber Optik İletim
- Bakır Erişim Ağı: DSL
- Pasif Optik Ağlar
- Kablo Erişim Ağları
- Denizaltı Kabloları
- Veri Merkezi Ağları
- Kapsülleme Çözme
- Güvenilir Aktarım
- Tıkanıklık Denetimi
- Trafik Çözümleme
- Gecikme Bütçesi
- Son Söz
Paket dışarı çıktı ve yolunu buldu. Ama üstündeki adres artık seninki değil.
Sınırdaki geçit kaynak alanını silip yerine kendi adresini yazdı. O adres değiştiği için cevap da geçide dönecek. Peki geçit dönen cevabı senin makinene nasıl ulaştırıyor?
Aynı adres neden milyonlarca ağda birden var?
Kendi makinenin adresine bakarsan büyük ihtimalle 192.168 ile başlıyor. Aynı adres şu anda başka ağlarda da duruyor, hem de milyonlarcasında. Bu bir kaza değil. Üç blok yerel ağlara ayrıldı ve bu üç blok internette yönlendirilmiyor.
| Blok | Uçlar | Adres sayısı |
|---|---|---|
10.0.0.0/8 | 10.0.0.0 – 10.255.255.255 | 16.777.216 |
172.16.0.0/12 | 172.16.0.0 – 172.31.255.255 | 1.048.576 |
192.168.0.0/16 | 192.168.0.0 – 192.168.255.255 | 65.536 |
Üçünün toplamı 17.891.328 adres eder. Hangisinin seçileceğine ağın boyu karar veriyor; kurumsal ağların çoğu en büyük bloktan çalışıyor.
Böyle bir adresi hedef gösteren paket omurgada yol bulamıyor. Otonom sistemlerin birbirine hangi önekleri ilan ettiğini gördün; özel bloklar o ilanların hiçbirinde geçmiyor. Taşıyıcı yönlendirici onu düşürüyor. Bu yüzden özel adresleme tek başına bir çözüm değil; ikinci parça çeviridir.
Geçit paketin üstünde neyi değiştiriyor?
Ev kutusunun dört işini sayarken varsayılan geçidin dışarı çıkan paketleri neden çevirdiğini açmadan bırakmıştım. Cevabın adı NAT (Network Address Translation, Ağ Adres Çevirisi).
Geçidin iki arayüzü iki ayrı dünyaya ait. İçeri bakan yüz özel bloktan bir adres taşıyor, dışarı bakan yüz genel bloktan. Çeviri tam bu iki yüzün arasında oluyor.
İşin kendisi tek cümleye sığıyor: geçit, giden paketin kaynak adresini ve kaynak portunu siliyor, yerine kendi dış adresini ve kendi seçtiği yeni bir portu yazıyor. Seçeneksiz bir IPv4 başlığı 20 bayt tutuyor. Silinen kaynak adres onun içinde 4 baytlık bir pencere; kaynak portu taşıma başlığında 2 baytlık bir alan.
Değiştirdiği çifti bir çeviri tablosuna yazmasa dönüş paketini kime vereceğini bilemezdi. Tablonun iki sütunu var: WAN tarafı ve LAN tarafı. Bir satır tam olarak bir akışın kimliği.
| Protokol | WAN tarafı | LAN tarafı |
|---|---|---|
| TCP | 198.51.100.83:60117 | 192.168.42.137:52310 |
| TCP | 198.51.100.83:60118 | 192.168.42.104:52310 |
| UDP | 198.51.100.83:60119 | 192.168.42.137:51820 |
Gelen yönde işlem simetrik olarak yürüyor. Uzaktaki sunucu cevabı 198.51.100.83:60117 hedefine gönderiyor. Geçit tabloya bakıyor, hedef alanını 192.168.42.137:52310 yapıyor ve paketi içeri veriyor. O sunucu senin özel adresini hiç görmedi.
Dört alanı yan yana koyunca hangi ikisinin oynadığı tek bakışta çıkıyor:
| yön ve nokta | kaynak IP | kaynak port | hedef IP | hedef port |
|---|---|---|---|---|
| giden · geçitten önce | 192.168.42.137 | 52310 | 203.0.113.9 | 443 |
| giden · geçitten sonra | 198.51.100.83 | 60117 | 203.0.113.9 | 443 |
| dönen · geçitten önce | 203.0.113.9 | 443 | 198.51.100.83 | 60117 |
| dönen · geçitten sonra | 203.0.113.9 | 443 | 192.168.42.137 | 52310 |
Dört alanın geçitten önce ve sonra nasıl göründüğünü izleyelim:
192.168.42.137 milyonlarca ağda birden var.- Giden paket geçide varıyor. Kaynak alanında evindeki özel adres, hedef alanında uzaktaki sunucu. Bu paket olduğu gibi internete çıkarsa cevabı dönecek bir yer yok:
192.168.42.137milyonlarca ağda birden var. - Geçit yalnızca kaynak çiftini değiştiriyor. Kaynak adresin yerine kendi genel adresini, kaynak portun yerine kendi seçtiği yeni bir numarayı yazıyor. Hedef çiftine hiç dokunmuyor — iki kartta da aynı duruyor.
- Değişikliği bir satıra yazıyor. Bu satır olmadan dönüş paketini kime vereceğini bilemezdi. Satırı yazan şey içeriden çıkan bu ilk paket; dışarıdan gelen ve tabloda karşılığı olmayan bir istek hiçbir yere gidemiyor.
- Dönen paket aynı satırı ters okuyor. Cevap
198.51.100.83:60117hedefine geliyor. Geçit satırı bulup hedef çiftini LAN tarafına çeviriyor. Giden yönde kaynak, dönen yönde hedef değişiyor; tek satır iki yönü birden tarif ediyor.
Kalın yazılan alanlar geçidin dokunduğu yerler. Giden yönde kaynak çifti, dönen yönde hedef çifti değişiyor; öteki iki alana hiç dokunulmuyor. Bu simetri tesadüf değil, tablonun kendisi: bir satır iki yönü birden tarif ediyor.
Aynı tabloya iki uçtan bakınca ilginç bir şey oluyor. Senin makinen bağlantıyı 192.168.42.137:52310 ↔ 203.0.113.9:443 diye biliyor; sunucu ise 203.0.113.9:443 ↔ 198.51.100.83:60117 diye. İki uç aynı bağlantıya farklı adlar veriyor ve ikisi de haklı. Ortadaki kutu bir çevirmen gibi çalışıyor, ve iki taraf da çevirmenin varlığından habersiz.
Alanlara dokunmanın bir bedeli var: geçit hem IP başlığının checksum’ı hem de taşıma katmanının sağlamasını yeniden hesaplamak zorunda. Satırlar protokolü de taşıyor, çünkü ICMP’nin portu yok; orada eşleme kimlik alanı üzerinden kuruluyor.
Bir yana: Cisco terminolojisinde aynı makinenin iki adı var. İçerideki özel adres iç yerel adres, geçidin dışarıya bakan yüzündeki genel adres ise iç global adres diye geçiyor. Hangi taraftan bakıldığına göre ad değişiyor.
Bir bağlantının kimliğini soket four-tuple’ı taşıyordu: kaynak adres, kaynak portu, hedef adres, hedef portu. NAT bunun ilk iki bileşenini yolun ortasında değiştiriyor. İki uç aynı bağlantıya bakıp farklı four-tuple’lar görüyor.
Bu düzenlemenin iki kazancı var. Sağlayıcıdan abone başına tek adres almak yetiyor, cihaz başına bir adres değil. İkincisi, iç adres planı dışarıdan bağımsız kalıyor: sağlayıcı değişse de içerideki adresler olduğu gibi duruyor.
Tek adresin arkasına kaç bağlantı sığıyor?
Dışarı çıkan bütün datagramların kaynak adresi aynı; ayıran şey kaynak portları. Çeviriyi mümkün kılan da bu. Sınır buradan geliyor: port alanı 16 bit, sıfır kullanılmadığı için geriye 65.535 numara kalıyor. Pratikte tek bir dış adresin arkasında yaklaşık 60.000 eşzamanlı bağlantı taşınıyor. Darboğaz adres değil, port havuzu.
Beşinci bölümün apartmanı burada bir kat yukarı taşınıyor. Sokak adresi geçidin dış adresine, daire numarası geçidin attığı dış porta, dairede oturan da içerideki makineye karşılık geliyor. Benzetme şurada bitiyor: apartmanda daire numaralarını kimse yeniden dağıtmaz, geçitte ise numarayı her akış için geçidin kendisi seçiyor.
Numarayı geçidin seçmesi bir sorunu kendiliğinden eliyor. Yukarıdaki tablonun ilk iki satırında iki ayrı cihaz aynı kaynak portu seçmiş, ama çakışma yok.
| Tür | Eşleme |
|---|---|
| Statik NAT | Bir iç adres hep aynı dış adrese; kalıcı satır |
| Dinamik NAT | Havuzdan geçici eşleme; iş bitince bırakılıyor |
| Port çevirisi | Çok sayıda iç adres tek dış adrese; ayrım portta |
Ev ve mobil ağlarda gördüğün çeviri neredeyse her zaman üçüncüsü, yani port çevirisi (PAT, öteki adıyla NAPT). RFC 3022’nin tanımladığı temel NAT’ta bir özel adres bir dış adrese bağlanıyor; porta dokunmadan çoğa bir eşleme kurulamıyor. Ölçek sınırı da buradan çıkıyor: çok geniş özel ağlarda tek bir port havuzu ve tek bir tablo darboğaza dönüşüyor.
Tabloya satırı kim yazıyor?
Satırı yazan şey içeriden çıkan ilk pakettir. Dışarıdan gelen ve tabloda karşılığı olmayan bir istek hiçbir yere gidemiyor. Geçit onu kime vereceğini bilmiyor. NAT arkasındaki bir sunucuya dışarıdan bağlanma problemi tam olarak budur. Uygulama tasarımcısı bunu hesaba katmak zorunda, özellikle iki ucun doğrudan buluşmaya çalıştığı eşler arası uygulamalarda.
Tablodaki satırlar ölümlü oluyor. Kullanılmayan eşleme zaman aşımıyla siliniyor ve RFC 4787 bu süreye alt sınır koyuyor: bir UDP eşleme zamanlayıcısı iki dakikadan önce dolamıyor, önerilen varsayılan ise beş dakika ve üstü. Eşlemenin silinmemesi için uygulamanın daha kısa aralıklarla canlı tutma paketi göndermesi gerekiyor. Uzun süre sessiz kalan bir bağlantının koptuğunu gördüysen sebebi bu. Linux tabanlı bir geçitte tablonun kendisine conntrack -L ile bakabilirsin; çıktıdaki her satır bir eşlemedir.
Tabloya satır yazmanın elle yapılan bir yolu da var. Port yönlendirme, dış adresin belirli bir portuna gelen paketi sabit bir iç adrese ve porta gönderen kalıcı bir satır kuruyor. Ev kamerası böyle açılıyor.
Bütün geçitler aynı satırı aynı şekilde yazmıyor
Şimdiye kadar “bir satır açılıyor” dedim. Gerçekte o satırın ne kadar açık olduğu geçitten geçide değişiyor ve bu fark, NAT’ın arkasında çalışan uygulamaların kaderini belirliyor.
İki ayrı soru var. Birincisi eşleme: aynı iç çiftten farklı hedeflere giden paketler aynı dış portu mu kullanıyor? İkincisi süzme: açılan dış porta kim paket gönderebiliyor?
| davranış | aynı dış port | içeri kimi kabul ediyor |
|---|---|---|
| tam koni | her hedefe aynı | herkes |
| adres kısıtlı koni | her hedefe aynı | yalnızca daha önce paket yolladığın IP |
| port kısıtlı koni | her hedefe aynı | yalnızca daha önce paket yolladığın IP ve port |
| simetrik | her hedefe ayrı | yalnızca o hedef |
İlk üçünde eşleme uç-bağımsız: dışarıdan bakan port, hedef kim olursa olsun aynı kalıyor. RFC 4787’nin ilk şartı da bu ve sebebi birazdan görülecek. Dördüncüsünde ise her yeni hedef yeni bir dış port doğuruyor; dışarıdan bakan biri senin portunu tahmin edemiyor.
Simetrik NAT bir güvenlik kazancı gibi duruyor ama asıl etkisi başka: iki ucun doğrudan buluşmasını imkânsıza yakın kılıyor.
İki NAT arkasındaki iki makine birbirini nasıl buluyor?
Görüntülü görüşme, çevrimiçi oyun ve dosya paylaşımı aynı problemi çözmek zorunda: iki tarafın da tablosu boş, ikisi de yalnızca içeriden çıkan paketle satır açabiliyor, ve kimse ilk paketi alamıyor. Kilitli bir kapının iki yanında iki kişi.
Çözüm üç parçalı ve üçünün de adı var.
STUN en basiti. İnternette duran bir sunucuya paket yolluyorsun, o da “seni 198.51.100.83:60117 olarak görüyorum” diye cevap veriyor. Kendi dış adresini ve portunu böyle öğreniyorsun — kendi geçidin sana söylemiyor, dışarıdaki bir tanık söylüyor.
Delik açma (hole punching) asıl numara. İki taraf da öğrendiği dış çifti bir aracı sunucu üzerinden karşıya bildiriyor, sonra ikisi birden karşının dış çiftine paket yolluyor. Her paket kendi geçidinde bir satır açıyor. İlk paketler karşı tarafın geçidinde henüz satır olmadığı için düşüyor; ama satırlar açıldıktan sonra ikinci tur geçiyor. İki kapı da içeriden açılmış oluyor.
Numaranın çalışması için eşlemenin uç-bağımsız olması şart: aracıya bildirdiğin portun, karşı tarafa giderken de aynı kalması gerekiyor. Simetrik NAT tam burada işi bozuyor — bildirdiğin port yalnızca aracıyla konuşurken geçerli.
TURN ise pes etmenin adı. Delik açılamıyorsa trafik ortadaki bir röle sunucusundan geçiriliyor. Çalışıyor, ama artık uçtan uca değil: gecikme artıyor ve bant genişliğini biri ödüyor.
Üçünü sırayla deneyip en iyisini seçen çerçevenin adı ICE. Tarayıcındaki görüntülü görüşme başlarken saniyenin bir kısmını tam olarak buna harcıyor: adayları topluyor, sırayla sınıyor, çalışan ilk yolu seçiyor. Eşler arası dağıtımın niçin bu kadar uğraştırdığını söylemiştim; sebebi tam olarak bu üç harfli merdiven.
Adres yükün içine yazılmışsa ne oluyor?
Buraya kadar geçit yalnızca başlıklara dokundu. Bazı protokoller bu varsayımı bozuyor: adresi yükün içine yazıyorlar.
Klasik örnek FTP. İstemci veri bağlantısı için sunucuya kendi adresini ve portunu bir komut satırıyla bildiriyor — ve o satır, IP başlığında değil, TCP yükünün içinde yazılı bir metin. Geçit başlıkları çevirip yükü olduğu gibi geçirirse, sunucu içerideki özel adrese bağlanmaya çalışıyor ve hiçbir yere varamıyor.
Çare, geçidin yükü de okuyup içindeki adresi düzeltmesi. Bunu yapan parçanın adı uygulama katmanı geçidi (ALG) ve tanımı gereği yedinci katmana çıkan bir üçüncü katman cihazı. Katmanlamanın üçüncü faturası bilgi saklamaktı; ALG o faturanın en çıplak kalemidir.
Bedeli de ağır. ALG protokolü bilmek zorunda, yani her yeni protokol için yeni kod gerekiyor. Yük şifreliyse hiçbir şey yapamıyor. Ve yanlış çalıştığında ortaya, hiçbir ucun açıklayamadığı arızalar çıkıyor: SIP telefonlarının tek yönlü ses sorunu çoğu zaman kutudaki bir ALG’nin eseridir. Modern protokoller bu yüzden adresi yükün içine hiç yazmıyor; STUN ile dış adresini öğrenip onu yazmayı tercih ediyorlar.
Bir yan etki daha var ve adı saç tokası (hairpinning). İçerideki bir sunucuyu, dış adresini yazarak yine içeriden çağırdığında paket geçide çıkıp aynı arayüzden geri dönmek zorunda. Kutuların bir kısmı bunu yapmıyor: aynı sunucu dışarıdan erişilebilirken içeriden erişilemiyor. Ev ağında “telefon şebekeden çalışıyor, Wi-Fi’da çalışmıyor” şikâyetinin en sık sebebi budur.
DerinleşmeNAT bir güvenlik önlemi mi, yoksa öyle sanılan bir yan etki mi?
İçerideki cihazların dışarıdan doğrudan adreslenememesi çeviriye sık sık bir güvenlik avantajı diye yazılır. Ama bu tasarlanmış bir politika değil, tablonun boş olmasının yan etkisi. Politika yazılan ve uygulanan bir kuraldır; buradaki koruma yalnızca satır bulunmamasıdır. Tabloya satır yazan her mekanizma o korumayı delip geçer: elle açılan bir port yönlendirme, içeriden kurulan her bağlantı, kutunun kendiliğinden eşleme açan özellikleri. Gerçek politika kutunun kural tablosunda durur; sınırdaki listede ilk eşleşen satırın kazandığını birazdan göreceğiz. Oradaki ret yazılmış bir karardır, buradaki kapalılık ise yalnızca bir boşluktur.
İkinci itiraz daha derin. Bir ağ katmanı cihazı taşıma katmanının port alanına dokunuyor; yönlendiricinin üçüncü katmanın üstüne çıkmaması beklenirdi. End-to-end argument’a ödetilen bedel de bu. Bağlantının kimliğine artık yalnızca uçlar karar vermiyor.
Dört cevaptan yaygınlaşanlar erteleyenler oldu. Kökten çözen IPv6 yayıldığı ölçüde her cihaz yeniden dışarıdan adreslenebilir hâle geliyor ve çeviriden gelen erişilemezlik kendiliğinden kayboluyor. İçeriyi kapalı tutan bir şey kalıyorsa o çeviri değil, yazılmış bir kuraldır.
Çeviri ikinci kez yapılırsa ne oluyor?
Bu iş yalnızca evlerde olmuyor. Kurum ağları ve 4G/5G hücresel ağlar aynı mekanizmayı yoğun kullanıyor. Telefonunun mobil veriyle aldığı adres de çevrilmiş bir adres.
Operatör aboneye genel adres vermeyi de bırakabiliyor. Bu düzenlemenin adı CGNAT (Carrier-Grade NAT), yani operatör düzeyi çeviri. RFC 6598 bunun için 100.64.0.0/10 bloğunu paylaşımlı adres alanı olarak ayırdı. Blokta 4.194.304 adres var ve bir operatör bununla dört milyondan fazla aboneyi genel adres harcamadan numaralayabiliyor. Blok klasik özel adres alanından ayrı tutuldu. Sebebi çakışma: abonenin evinde zaten özel adres kullanılıyor ve aynı blok iki katmanı birbirine karıştırırdı. Bu trafik sağlayıcı sınırlarının ötesine de iletilmiyor.
Sonuç iki kat çeviri. Ev geçidi 192.168.42.137:52310 çiftini 100.64.19.7:60117 yapıyor, operatörün cihazı da onu 198.51.100.83:41022 yapıyor. Paketin kaynağı hedefe varana kadar iki kez değişiyor. İki ayrı tabloda iki satır duruyor. Bedeli de belli: port yönlendirme çalışmıyor, kayıt tutmak zorlaşıyor ve bir abonenin yaptığı, dış dünyada aynı adresi paylaşan öteki abonelere yansıyor.
Bütün bunları kendi makinende yan yana koyabilirsin:
ip addr show # Windows'ta: ipconfig
curl -s https://api.ipify.orgBirincisi içerideki özel adresi basıyor, ikincisi dışarıdan görünen adresi. İki farklı adres, tek makine.
Özet
Peki, ne öğrendik?
- Özel adresleme tek başına yetmiyor: üç blok yalnızca yerel ağda anlamlı, dışarı çıkışı ancak çeviri ile birlikte mümkün oluyor.
- Çeviri iki alana dokunuyor: geçit kaynak adresi ile kaynak portu değiştiriyor ve dönüş yolunu tek bir tablo satırında saklıyor.
- Sınırı koyan şey port havuzu: 16 bitlik alan tek dış adresin arkasına yaklaşık 60.000 eşzamanlı bağlantı sığdırıyor.
- Tabloyu içeriden çıkan paket yazıyor: karşılığı olmayan istek içeri giremiyor, kalıcı satırı ise port yönlendirme elle açıyor.
- Her geçit satırı aynı genişlikte açmıyor: koni davranışlarında dış port her hedefe aynı kalır, simetrik NAT’ta ise hedef başına değişir ve delik açma çalışmaz.
- İki uç birbirini üç adımda buluyor:
STUNdış adresi öğretir, delik açma iki kapıyı içeriden açar,TURNbaşarısızlıkta trafiği röleye alır — sırayıICEyürütür.- Operatör aynı işi ikinci kez yapabiliyor: CGNAT abonenin adresini de paylaştırıyor ve kaynak adres yolda iki kez değişiyor.
Geçit paketin üstündeki iki alanı senden habersiz değiştirdi ve bunu yaparken sıradan bir yönlendiricinin işini aştı. Adres çevrildi; peki yol üstünde paketimize dokunan başka kim var?
44. bölüme devam et: Ara Kutular