Upstream proxy, başka bir proxy sunucusunun istemci isteklerini ilettiği proxy sunucusudur; böylece ilk proxy'nin upstream proxy'ye karşı istemci gibi davrandığı bir zincir oluşur.
Upstream Proxy Nedir?
Bir istemci bir proxy sunucusuna istek gönderdiğinde, o proxy sunucusu istenen kaynağı genellikle doğrudan internetteki köken sunucudan alır. Ancak birçok mimari tasarımda ilk proxy sunucusu kökene doğrudan bağlanmaz. Bunun yerine isteği, upstream proxy olarak bilinen başka bir proxy sunucusuna iletir. Bu ikinci proxy de isteği ya kendi önbelleğinden karşılayarak, ya bir başka upstream proxy'ye ileterek ya da köken sunucudan alarak işler.
Upstream proxy kullanmanın başlıca amaçları şunlardır:
- Katmanlı güvenlik: ek bir güvenlik ve erişim denetimi katmanı eklemek.
- Özelleşmiş işlevler: içerik filtreleme, antivirüs taraması veya gelişmiş önbellekleme gibi belirli görevleri özel bir proxy'ye devretmek.
- Ağ bölümlendirme: farklı ağ bölümlerini birbirine bağlamak veya dış ağlara denetimli erişim sağlamak.
- Anonimlik ve gizlilik: birden çok sıçrama üzerinden kaynak istemcinin IP adresini gizlemek.
- Kısıtlamaları aşmak: coğrafi engelleri veya ağ kısıtlamalarını aşmak için trafiği farklı coğrafi konumlar ya da ağlar üzerinden yönlendirmek.
- Yük dengeleme: istekleri birden çok upstream proxy veya köken sunucu arasında dağıtmak.
Upstream proxy'li bir isteğin akışı şöyledir: Client -> Proxy A -> Upstream Proxy B -> Origin Server. Bu senaryoda Proxy A, upstream olarak Proxy B'yi kullanacak şekilde yapılandırılmıştır.
Kademeli (Cascading) Proxy'ler
Proxy zincirleme (proxy chaining) olarak da bilinen kademeli proxy'ler, birden çok proxy sunucusunun sırayla dizildiği ve her proxy'nin istekleri zincirdeki bir sonrakine ilettiği, son proxy'nin ise köken sunucuya bağlandığı mimariyi ifade eder. Bu, istemci istekleri için çok sıçramalı bir yol oluşturur.
Kademeli Proxy'lerin Avantajları
- Güçlendirilmiş güvenlik: her proxy kendi güvenlik politikalarını, kimlik doğrulamasını ve erişim denetimlerini uygulayabilir.
- Modüler mimari: farklı proxy'ler farklı işlevlerde uzmanlaşabilir (örneğin biri önbellekleme, diğeri WAF, bir başkası çıkış denetimi için).
- Karmaşık yönlendirme: ayrıntılı yönlendirme mantığına olanak tanır; belirli trafik türlerini farklı zincirler veya coğrafi konumlar üzerinden yönlendirir.
- Artan anonimlik: sıçrama sayısı arttıkça asıl istemciyi izlemek zorlaşır.
- Yedekli atlatma: zincirdeki bir proxy arızalanır veya engellenirse alternatif yollar sunar.
Kademeli Proxy'lerin Dezavantajları
- Artan gecikme: her ek proxy sıçraması işlem gecikmesi ve ağ gecikmesi getirir.
- Karmaşıklık: yapılandırma ve yönetim, özellikle hata ayıklama ve sorun giderme açısından daha karmaşık hale gelir.
- Tek hata noktaları: yedeklilik düşünülmediyse zincirdeki herhangi bir proxy'nin arızalanması hizmeti kesintiye uğratabilir.
- Hata ayıklama zorlukları: bir isteğin izlediği yolu takip etmek ve sorunları belirlemek birden çok sunucu üzerinde zor olabilir.
- Başlık yönetimi:
X-Forwarded-ForveViagibi başlıkların doğru işlenmesi, loglama ve köken sunucunun durumu görebilmesi açısından kritiktir.
Upstream Proxy Yapılandırması
Yaygın proxy sunucuları için, bir proxy'nin istekleri upstream'e nasıl ileteceğini gösteren yapılandırma örnekleri.
Nginx (Upstream için Reverse Proxy Olarak)
Nginx genellikle reverse proxy olarak çalışır. Bir Nginx örneğini istekleri bir upstream proxy'ye iletecek şekilde yapılandırmak için, upstream proxy'nin adresini bir location bloğu içindeki proxy_pass direktifinde tanımlarsınız.
# Nginx yapılandırması (örn. proxy.example.com)
# Bu Nginx örneği Proxy A olarak çalışır ve Upstream Proxy B'ye iletir.
http {
upstream upstream_proxy_b {
# Upstream proxy'nizin adresi (Proxy B)
server 192.168.1.100:3128; # Örnek: Proxy B'nin IP'si ve portu
# İsteğe bağlı: Proxy B'nin birden çok örneği varsa yük dengeleme/failover için birden çok sunucu ekleyin
# server 192.168.1.101:3128;
}
server {
listen 80;
server_name proxy.example.com;
location / {
# İstekleri tanımlı upstream_proxy_b'ye geçir
proxy_pass http://upstream_proxy_b;
# Proxy zincirleri için önerilen başlıklar
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Via "1.1 $hostname"; # Mevcut proxy'yi Via başlığına ekle
}
}
}
Squid (Upstream için Forward Proxy Olarak)
Squid yaygın olarak forward proxy şeklinde kullanılır. Squid'i bir upstream proxy kullanacak şekilde yapılandırmak için cache_peer direktifini kullanırsınız.
# Squid yapılandırması (örn. proxy-a.conf)
# Bu Squid örneği Proxy A olarak çalışır ve Upstream Proxy B'ye iletir.
# Upstream proxy'yi tanımla (Proxy B)
# Sözdizimi: cache_peer hostname type http_port icp_port [options]
# type: parent veya sibling (upstream için parent daha yaygındır)
# http_port: upstream proxy'nin HTTP portu
# icp_port: ICP portu (kullanılmıyorsa veya bilinmiyorsa genelde 0)
cache_peer 192.168.1.100 parent 3128 0 no-query default_parent
# Birden çok upstream proxy örneği (Proxy B ve Proxy C)
# cache_peer 192.168.1.101 parent 3128 0 no-query round-robin
# cache_peer 192.168.1.102 parent 3128 0 no-query
# İstemcilerin bu proxy'yi kullanmasına izin veren erişim denetimi
acl localnet src 192.168.0.0/24 # Örnek: istemci ağınız
http_access allow localnet
http_access deny all
# Squid'in istemci istekleri için dinlediği portu belirt
http_port 3129 # Proxy A 3129 portunu dinler
# İsteğe bağlı: Via başlığı ekle
via off # Squid varsayılan olarak Via başlıkları ekler; 'off', Squid'in kendi 'Via' başlığını eklemeyeceği anlamına gelir,
# ancak mevcut olanları iletir. Kendi başlığını *eklemesini* garantilemek için bu satırı kaldırın veya 'on' yapın.
# Kademeli kurulumlarda genellikle 'via on' ya da varsayılan davranış tercih edilir.
Bu Squid yapılandırmasında proxy-a, 3129 portunu dinler ve default_parent seçeneği nedeniyle tüm istekleri 192.168.1.100:3128 adresine (Proxy B) iletir.
Kademeli Proxy Yapılandırması
Kademeli proxy'leri kurmak için zincirdeki her proxy'yi bir sonrakini gösterecek şekilde yapılandırırsınız.
Senaryo: Client -> Proxy A -> Proxy B -> Internet
Bu senaryoda zincirde iki proxy bulunur.
Proxy A Yapılandırması (Ön Uç Proxy)
Proxy A, istemciler için ilk temas noktasıdır ve istekleri Proxy B'ye iletir.
Proxy A olarak Nginx:
(Yukarıdaki "Upstream Proxy Yapılandırması" bölümündeki Nginx örneğine bakın. upstream_proxy_b bloğu ve proxy_pass http://upstream_proxy_b; direktifi Nginx'i istekleri Proxy B'ye gönderecek şekilde yapılandırır.)
Proxy A olarak Squid:
(Yukarıdaki "Upstream Proxy Yapılandırması" bölümündeki Squid örneğine bakın. cache_peer 192.168.1.100 parent 3128 0 no-query default_parent direktifi Squid'i istekleri Proxy B'ye gönderecek şekilde yapılandırır.)
Proxy B Yapılandırması (Ara/Upstream Proxy)
Proxy B, istekleri Proxy A'dan alır ve ardından internete (veya zincir daha uzunsa bir başka upstream proxy'ye) iletir.
Proxy B olarak Nginx:
Proxy B de bir Nginx örneğiyse, genellikle köken sunucuya ileten standart bir reverse proxy olarak yapılandırılır. Yalnızca bir çıkış noktası ya da başka bir proxy olarak çalışıyorsa, yapılandırması Proxy A'nınkine benzer olur; ancak proxy_pass hedefi bir sonraki proxy veya gerçek köken olur.
# Proxy B için Nginx yapılandırması (192.168.1.100)
# Bu Nginx örneği Proxy A'dan istek alır ve internete iletir.
http {
server {
listen 3128; # Proxy B, Proxy A'dan gelen istekler için 3128 portunu dinler
server_name proxy-b.example.com; # Ya da yalnızca IP üzerinde dinleyin
location / {
# Burada Proxy B, istemcinin özgün isteğine göre doğrudan kökene iletebilir
# Ya da zincir devam ediyorsa *başka* bir upstream'e iletebilir.
# Basitlik için, özgün isteğe göre internete ilettiğini varsayıyoruz.
# Nginx'in forward proxy olarak kullanımı daha karmaşıktır ve genellikle dinamik çözümleme gerektirir.
# Daha yaygın senaryo, Nginx'in bilinen bir köken kümesi için reverse proxy olarak
# ya da tek bir "sonraki sıçrama" proxy'si için çalışmasıdır.
# Örnek: Proxy B belirli ve bilinen bir kökene iletiyorsa
# proxy_pass http://www.example.com;
# Proxy B'nin rastgele alan adları için genel bir forward proxy gibi çalışması gerekiyorsa (Nginx'te daha az yaygın)
# Bu, dinamik çözümleme gerektirir ve genellikle Squid gibi özel forward proxy'lerle ele alınır.
# Nginx'in genel bir forward proxy olarak çalışması için çoğu zaman özel Lua betikleri veya modüller gerekir.
# Daha basit bir Nginx Proxy B yalnızca *başka* bir sabit upstream'e geçiş yapabilir.
# Gerçek bir "internet" çıkışı için genellikle Squid tercih edilir.
# Proxy B sadece çıkış noktasıysa ve nihai kökeni bilmiyorsa (Squid gibi)
# Nginx'in *genel amaçlı* forward proxy yetenekleri tam da burada sınırlıdır.
# Proxy B bir Nginx ise, büyük olasılıkla belirli servisler için reverse proxy'dir
# ya da sonraki sıçramanın da sabit olduğu tanımlı bir zincirde bir sonraki sıçramadır.
# Kademeli kurulum açısından, Nginx Proxy B ise genellikle *bilinen* bir sonraki sıçramaya
# veya bilinen bir kökene geçiş yapacak şekilde yapılandırılır.
# "Genel internet" çıkışı için Squid daha uygundur.
# Proxy B'nin bilinen bir *nihai* upstream'e ilettiğini varsayalım; örneğin anonimleştirici bir proxy
# ya da belirli bir çıkış ağ geçidi.
proxy_pass http://final_egress_proxy:8080; # Örnek: nihai bir çıkış proxy'sine iletme
# Ya da kökenden önceki son sıçramaysa ve Nginx dinamik upstream çözümlemesi için yapılandırıldıysa:
# proxy_pass $scheme://$host$request_uri; # Dinamik forward proxy için özel kurulum gerektirir
# Basitlik için, Proxy B'nin genel internet erişimi sağlayan bir Squid proxy olduğunu varsayalım.
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Via "1.1 $hostname";
}
}
}
Proxy B olarak Squid:
Proxy B, istekleri Proxy A'dan alır ve ya doğrudan internetten getirecek ya da bir başka upstream'e iletecek şekilde yapılandırılır. İnternetten önceki son proxy ise, başka bir proxy'yi gösteren cache_peer direktifine ihtiyacı yoktur (belirli alan adları veya failover için gerekmediği sürece).
# Proxy B için Squid yapılandırması (192.168.1.100)
# Bu Squid örneği Proxy A'dan istek alır ve internetten getirir.
# Proxy B, Proxy A'dan gelen istekler için 3128 portunu dinler
http_port 3128
# İsteğe bağlı: Proxy B'nin de kendi upstream'i varsa (örneğin bir ISP proxy'si veya başka bir özel proxy)
# cache_peer upstream.isp.com parent 8080 0 no-query default_parent
# Proxy A'nın (ve diğer yetkili istemcilerin) bağlanmasına izin veren erişim denetimi
acl proxy_a_network src 192.168.1.0/24 # Örnek: Proxy A'nın bulunduğu ağ
http_access allow proxy_a_network
http_access deny all
# Proxy B için önbellekleme, loglama vb. ayarları gerektiği gibi yapılandırın
Gelişmiş Kademelendirme: Koşullu Upstream'ler
Daha karmaşık yönlendirmeler için, belirli alan adlarına veya yollara yönelik istekleri farklı upstream proxy'lere göndermek isteyebilirsiniz.
Nginx'te koşullu upstream'ler:
http {
# Genel trafik için upstream grubu
upstream general_upstream {
server 192.168.1.100:3128; # Proxy B
}
# Belirli hassas trafik için upstream grubu
upstream secure_upstream {
server 192.168.2.200:4444; # Güvenli Proxy C
}
server {
listen 80;
server_name proxy.example.com;
location /secure/ {
# /secure/ isteklerine Güvenli Proxy C bakar
proxy_pass http://secure_upstream;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location / {
# Diğer tüm istekler Proxy B'ye gider
proxy_pass http://general_upstream;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
}
Squid'de koşullu upstream'ler:
# Birden çok cache_peer tanımla
cache_peer 192.168.1.100 parent 3128 0 no-query name=general_proxy
cache_peer 192.168.2.200 parent 4444 0 no-query name=secure_proxy
# Belirli trafiği tanımlayan ACL'ler
acl secure_domains dstdomain .secure.example.com
acl secure_urls url_regex ^https://secure\.
# İstekleri ACL'lere göre yönlendir
cache_peer_access secure_proxy allow secure_domains
cache_peer_access secure_proxy allow secure_urls
cache_peer_access general_proxy allow all
# Açık bir peer erişim kuralıyla eşleşmeyen trafiğin doğrudan ya da default_parent'a gitmesini sağlayın
# default_parent tanımlı değilse, istekler 'never_direct'/'always_direct' ayarına göre başarısız olabilir veya doğrudan gidebilir
# Genellikle bir default_parent ya da her şeyi yakalayan son bir 'cache_peer_access' bulundurmak daha iyidir.
Kademeli Proxy'lerde Dikkat Edilmesi Gerekenler
Gecikme ve Performans
Zincirdeki her proxy, işlem süresi ve ağ gecikmesi ekler. Sıçrama sayısını en aza indirmek, yüksek performanslı proxy'ler ve ağ bağlantıları kullanmak kritiktir. Darboğazları belirlemek için uçtan uca gecikmeyi izleyin.
Güvenlik ve Kimlik Doğrulama
- Proxy'ler arası kimlik doğrulama: ara proxy'lere yetkisiz erişimi önlemek için proxy'ler arasında kimlik doğrulama uygulayın (örneğin IP beyaz listesi, paylaşılan gizli anahtarlar, istemci sertifikaları).
- SSL/TLS sonlandırma: SSL/TLS sonlandırmanın nerede yapılacağına karar verin. Proxy'ler trafiği şifre çözüyorsa, sertifika yönetiminin doğru olduğundan ve sonraki sıçramalar için yeniden şifrelemenin yapıldığından emin olun.
- Erişim denetimi: yalnızca yetkili upstream/downstream proxy'lerden veya istemcilerden gelen trafiğe izin vermek için her proxy'de sıkı erişim denetim listeleri (ACL) yapılandırın.
Hata Ayıklama ve Sorun Giderme
İstekleri birden çok proxy boyunca izlemek karmaşık olabilir.
* X-Forwarded-For başlığı: bu başlık, özgün istemci IP adresini ve zincirdeki sonraki proxy IP'lerini takip eder. Her sıçramada doğru şekilde eklendiğinden emin olun (Nginx'te $proxy_add_x_forwarded_for).
* Via başlığı: Via başlığı, isteğin geçtiği ara proxy'leri gösterir. Her proxy kendi tanımlayıcısını bu başlığa eklemelidir.
* Loglama: merkezi loglama ve korelasyon kimlikleri, istekleri proxy zincirinin tamamı boyunca izlemek için şarttır.
Yük Dengeleme ve Failover
Yüksek erişilebilirlik sağlamak ve trafiği dağıtmak için upstream proxy'ler arasında yük dengelemeyi yapılandırın.
* Nginx: upstream bloğunu birden çok server direktifiyle ve least_conn, round_robin, backup, down gibi seçeneklerle kullanın.
nginx
upstream proxy_b_cluster {
server 192.168.1.100:3128 weight=5; # Birincil Proxy B
server 192.168.1.101:3128 backup; # Yedek Proxy B
server 192.168.1.102:3128; # Bir diğer birincil Proxy B
least_conn; # En az bağlantı yöntemini kullan
}
# Ardından proxy_pass http://proxy_b_cluster;
* Squid: round-robin, weighted-round-robin, failover ve no-query gibi seçeneklerle birden çok cache_peer direktifi kullanın.
squid
cache_peer 192.168.1.100 parent 3128 0 no-query weight=10
cache_peer 192.168.1.101 parent 3128 0 no-query weight=5
cache_peer 192.168.1.102 parent 3128 0 no-query round-robin
Başlık Yönetimi
HTTP başlıklarının dikkatli yönetimi kritiktir. X-Forwarded-For ve Via dışında, upstream proxy'lerde kimlik doğrulaması için Proxy-Authorization başlığını değerlendirin ve ilgili diğer başlıkların politikaya uygun şekilde iletildiğinden veya kaldırıldığından emin olun.
Karşılaştırma: Tek Upstream ile Kademeli Upstream'ler
| Özellik / Yön | Tek upstream proxy | Kademeli upstream proxy'ler |
|---|---|---|
| Karmaşıklık | Düşük; daha basit yapılandırma ve yönetim. | Yüksek; birden çok sunucuda karmaşık yapılandırma, yönetim ve hata ayıklama. |
| Gecikme | Minimum ek yük; bir ek ağ sıçraması. | Daha fazla ek yük; proxy başına birden çok ağ sıçraması ve işlem gecikmesi. |
| Esneklik | Tek bir proxy'nin yetenekleriyle sınırlı. | Yüksek; her aşamada özelleşmiş işlevlere ve karmaşık yönlendirmeye olanak tanır. |
| Güvenlik katmanları | Tek katmanlı güvenlik ve erişim denetimi. | Çok katmanlı güvenlik; her proxy farklı politikalar uygulayabilir. |
| Anonimlik | Kökene karşı temel düzeyde anonimlik sağlar. | Güçlendirilmiş anonimlik; birden çok sıçrama nedeniyle asıl istemciyi izlemek zordur. |
| Hata ayıklama | Görece basit. | Zorlu; başlıkların (X-Forwarded-For, Via) ve logların dikkatli yönetimini gerektirir. |
| Arıza etkisi | Tek upstream'in arızası tüm trafiği durdurur. | Failover yapılandırılmadıysa zincirdeki herhangi bir proxy'nin arızası hizmeti kesebilir. |
| Kullanım alanları | Temel içerik filtreleme, önbellekleme, basit erişim denetimi. | Gelişmiş güvenlik, uyumluluk, coğrafi yönlendirme, özelleşmiş servisler, yüksek anonimlik ihtiyaçları. |
