Anti-DDoS Proxy ve CDN hızlandırma gibi FullNAT senaryolarında, yönlendirme düğümü trafiği arka uç sunucusuna iletmeden önce istemcinin kaynak IP adresini ve bağlantı noktasını kendi bilgileriyle değiştirir. Alibaba Cloud Linux 3 için bir çekirdek modülü olan vtoa, TCP üstbilgisine gömülü TCP Seçenek Adresi (TOA) verilerinden orijinal istemci IP adresini ve bağlantı noktasını kurtarır. Uygulamanız, ağ altyapısında herhangi bir değişiklik yapmadan, önerilen getsockopt veya getpeername yöntemlerinden birini kullanarak bu bilgilere erişebilir.
Hem IPv4 hem de IPv6 desteklenir.
Çalışma prensibi
Bir istemci isteği yönlendirme düğümüne (örneğin, bir Anti-DDoS düğümüne) ulaşır.
Yönlendirme düğümü FullNAT uygulayarak istemcinin kaynak IP adresini ve bağlantı noktasını kendi bilgileriyle değiştirir ve orijinal adresi bir TCP Seçeneği alanına (TOA) gömer.
Arka uç sunucusu bağlantıyı alır.
vtoaçekirdek seviyesinde TCP üstbilgisinden TOA verilerini ayıklar.Uygulamanız, orijinal istemci adresini almak için
getsockopt(önerilen) veyagetpeernamesistem çağrısını kullanır.
Kullanım senaryoları
-
Anti-DDoS Proxy: İstemci istekleri Anti-DDoS yönlendirme düğümünde FullNAT işlemine tabi tutulur. Anti-DDoS, gerçek istemci IP adresini ve bağlantı noktasını TCP Seçeneğine gömer. Arka uç kaynak sunucusu, gerçek istemci IP adresini kurtarmak için
vtoakullanır. CDN hızlandırma: CDN hızlandırma düğümleri istekleri kaynak sunucuya iletir. Kaynak sunucu, gerçek istemci adresini kurtarmak için
vtoakullanır.
Desteklenen sistemler
vtoa kullanımı için 5.10.134-15 veya daha sonraki bir çekirdek sürümüne sahip Alibaba Cloud Linux 3 gereklidir.
Çekirdek sürümünü kontrol etmek için uname -r komutunu çalıştırın.
vtoa, getpeername sistem çağrısının döndürdüğü değeri değiştirir. Yüklemeden önce aşağıdaki durumların kabul edilebilir olduğunu doğrulayın:
Cilium gibi eBPF aracılığıyla
getpeernameişlevini değiştiren ağ bileşenlerivtoaile çakışabilir ve anormal davranışlara neden olabilir.getpeernameişlevine bağımlı uygulamalar etkilenebilir.
Bu sorunlardan kaçınmak için, getpeername dönüş değerini değiştirmeden orijinal istemci adresini alan getsockopt yöntemini kullanın.
vtoa yükleme
vtoa paketini yum ile yükleyin:
sudo yum install vtoa -y
Yüklemeden sonra vtoa hemen başlar ve önyükleme sırasında otomatik olarak başlatılmak üzere yapılandırılır. Genellikle ek bir yapılandırmaya gerek yoktur.
Kaldırmak için:
sudo yum remove vtoa -y
Kaldırma işleminden sonra vtoa devre dışı bırakılır.
vtoa hizmetini yönetme
vtoa yüklendikten sonra otomatik olarak çalışsa da, systemctl kullanarak hizmeti kontrol edebilirsiniz:
| Eylem | Komut |
|---|---|
| Başlat | sudo systemctl start vtoa |
| Durdur | sudo systemctl stop vtoa |
| Önyüklemede otomatik başlatmayı etkinleştir | sudo systemctl enable vtoa |
| Önyüklemede otomatik başlatmayı devre dışı bırak | sudo systemctl disable vtoa |
| Durumu kontrol et | systemctl status vtoa |
Gerçek istemci adresini alma
vtoa çalıştıktan sonra, orijinal istemci adresini almak için aşağıdaki sistem çağrılarından birini kullanın. caddr.sa_family alanı IPv4 için AF_INET, IPv6 için AF_INET6 değerini alır.
getsockopt kullanımı (önerilen)
Bu yöntem 5.10.134-17 veya daha sonraki bir çekirdek sürümü gerektirir. Doğrulamak için uname -r komutunu çalıştırın.
vtoa, optname değeri 1348 olan bir soket seçeneği kaydeder. Orijinal istemci adresini doğrudan almak için getsockopt işlevini IPPROTO_IP ve bu optname parametresiyle çağırın. Bu yöntem getpeername tarafından döndürülen değeri değiştirmez; bu nedenle eBPF tabanlı ağ araçlarının bulunduğu ortamlarda güvenlidir.
struct sockaddr caddr;
int optlen = sizeof(caddr);
int optname = 1348;
getsockopt(fd, IPPROTO_IP, optname, &caddr, &optlen);
// caddr.sa_family can be AF_INET or AF_INET6, which correspond to IPv4 and IPv6 addresses.
getpeername kullanımı
Bu yöntem 5.10.134-15 veya daha sonraki çekirdek sürümlerinde desteklenir. Gelecekte kullanımdan kaldırılabilir. Mümkün olduğunda getsockopt kullanın.
vtoa etkinleştirildiğinde, getpeername FullNAT adresi yerine orijinal istemci adresini döndürür. Her zamanki gibi getpeername çağrısı yapmak dışında uygulama kodunda değişiklik yapılmasına gerek yoktur.
struct sockaddr caddr;
int caddr_len = sizeof(caddr);
getpeername(fd, &caddr, &caddr_len);
// caddr.sa_family can be AF_INET or AF_INET6, which correspond to IPv4 and IPv6 addresses.
// accept() can also be used to get the client address in a similar way.
Neden getsockopt tercih edilir: getpeername, soket üzerindeki tüm çağrılar için eş adresini global olarak geçersiz kılar. Bu durum, belirli eBPF tabanlı araçlar gibi NAT adresini bekleyen bileşenlerin bozulmasına neden olabilir ve gelecekteki bir çekirdek sürümünde kullanımdan kaldırılabilir. getsockopt, getpeername dönüş değerini değiştirmeden orijinal istemci adresini alır; bu da karma ortamlarda daha güvenli hale getirir.
SSS
vtoa hangi TCP seçenek formatlarını destekler?
vtoa, TCP Seçeneklerinde taşınan adres bilgilerini ayrıştırır. Format eşleşmezse vtoa seçeneği sessizce yoksayar. Bu durum uygulamayı etkilemez ve vtoa'nın devre dışı olmasıyla eşdeğerdir.
İki format desteklenir:
TOA (IPv4) — opcode 254
opsize = 8'dir. Hem ip hem de port ağ bayt düzenindedir.
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| opcode | opsize | port |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| ip |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
TOA_V6 (IPv6) — opcode 253
opsize = 20'dir. Hem ip hem de port ağ bayt düzenindedir.
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| opcode | opsize | port |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| |
+ +
| |
+ ip +
| |
+ +
| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Konteyner ortamlarında vtoa nasıl kullanılır?
vtoa konteyner düzeyinde yalıtımı desteklemez. vtoa paketini bir konteynerin içine değil, ana bilgisayara (host) yükleyin. Ana bilgisayara yüklendiğinde, o düğümdeki tüm konteynerler için etkili olur (örneğin, containerd çalışma zamanı kullanan ACK ile).
vtoa yüklü ancak hala FullNAT adresini alıyorum — nasıl sorun gideririm?
Aşağıdakileri sırayla kontrol edin:
Çekirdek sürümü:
uname -rkomutunu çalıştırın ve sürümün5.10.134-15veya üzeri (getsockoptkullanıyorsanız5.10.134-17veya üzeri) olduğunu doğrulayın.Hizmet durumu:
systemctl status vtoakomutunu çalıştırın ve hizmetin aktif (çalışıyor) olduğunu doğrulayın.TOA formatı: Yukarı akış yönlendirme düğümünüzün (Anti-DDoS, CDN veya özel FullNAT) opcode
254(IPv4) veya253(IPv6) ile bir TOA eklediğini doğrulayın. Opcode veya format eşleşmezsevtoaseçeneği sessizce yoksayar.eBPF çakışmaları: Ana bilgisayarda Cilium veya başka bir eBPF tabanlı bileşen çalışıyorsa,
getpeernameişlevini de kancalayıp kancalamadığını kontrol edin. Çakışan kancalar beklenmeyen sonuçlar üretebilir. Böyle bir durumda,getpeernamedönüş değerini değiştirmeyengetsockoptyöntemine geçiş yapın.