WebSocket, sıradan bir HTTP isteği değildir. İlk "el sıkışma" (handshake) sonrasında bağlantı açık kalır ve veriler iki yönlü sürekli bir akış halinde gider. Bu nedenle standart HTTP proxy'leri genellikle WS bağlantılarını keser veya hiç işleyemez. Bu makalede, WebSocket trafiğini nasıl doğru bir şekilde proxy'leyeceğimizi inceleyeceğiz: hangi proxy'lerin uygun olduğu, nasıl ayarlandığı ve en sık karşılaşılan hataların neler olduğu.
WebSocket nasıl çalışır ve neden proxy'ler için zordur
Problemi anlamak için mekanizmayı incelemek gerekir. WebSocket bağlantısı, sıradan bir HTTP isteği gibi başlar - istemci Upgrade: websocket ve Connection: Upgrade başlıklarını gönderir. Sunucu 101 Switching Protocols kodu ile yanıt verir - ve bu noktadan itibaren bağlantı HTTP olmaktan çıkar. Sürekli iki yönlü bir kanal haline gelir ve veriler çerçeveler içinde akar.
Sadece istekleri ve yanıtları iletme yeteneğine sahip standart bir HTTP/1.1 proxy, yanıt 101 geldikten sonra bağlantıyla ne yapacağını bilmediği için sorunla karşılaşır. Birçok proxy sunucusu bu noktada bağlantıyı kapatır veya 502 Bad Gateway hatası döner. Diğerleri bağlantıyı tutar, ancak WebSocket çerçevelerini düzgün bir şekilde iletemez, bu da kesintilere veya veri bozulmalarına yol açar.
İşte WebSocket'in proxy'leme açısından normal HTTP'den temel farkları:
| Parametre | HTTP | WebSocket |
|---|---|---|
| Bağlantı türü | İstek → Yanıt → Kapatma | Sürekli, iki yönlü |
| Yaşam süresi | Saniyeler (bir istek) | Dakikalar, saatler, günler |
| Veri başlatıcısı | Sadece istemci | İstemci ve sunucu |
| Handshake sonrası protokol | HTTP | Özel (RFC 6455) |
| Portlar | 80, 443 | 80 (WS), 443 (WSS) |
İşte handshake sonrası protokol değişikliği nedeniyle, birçok basit proxy çözümü WebSocket ile başa çıkamaz. Ya açıkça tünelleme desteği olan bir proxy kullanılmalı ya da içeriği analiz etmeyen daha düşük seviyede çalışan SOCKS5 protokolü uygulanmalıdır.
WebSocket'i destekleyen proxy türleri
Tüm proxy'ler WebSocket için eşit derecede faydalı değildir. Her bir türü inceleyelim:
| Proxy türü | WS desteği | Mekanizma | Zorluk |
|---|---|---|---|
| HTTP proxy | ⚠️ Kısmi | CONNECT tüneli üzerinden | Orta |
| HTTPS proxy | ✅ Evet | CONNECT + TLS | Orta |
| SOCKS4 | ⚠️ Sınırlı | Kimlik doğrulama olmadan TCP tüneli | Düşük |
| SOCKS5 | ✅ Tam | Şeffaf TCP/UDP | Düşük |
| Şeffaf proxy | ❌ Hayır | Sadece HTTP | — |
Sonuç: WebSocket görevleri için en iyi seçim SOCKS5'tir. Bu protokol, taşıma katmanında çalışır ve TCP bağlantısını tünelleştirir, trafik içeriğine girmeden. İçerisinde HTTP, WebSocket, SSH veya başka bir şey olup olmadığı umursamaz. HTTP proxy'leri de WS ile çalışabilir, ancak sadece CONNECT yöntemi üzerinden - burada aşağıda inceleyeceğimiz bazı nüanslar vardır.
CONNECT yöntemi: HTTP proxy'sinin WebSocket'i nasıl tünelleştirdiği
HTTP yöntemi CONNECT, HTTP proxy'sinin hedef sunucuya "kör" bir tünel oluşturmasına olanak tanıyan özel bir mekanizmadır. Proxy, tünel içindeki trafiği analiz etmez, sadece baytları yönlendirir. HTTPS'in HTTP proxy'si üzerinden nasıl çalıştığı ve WebSocket'in nasıl proxy'lenebileceği de bu şekildedir.
Süreç şu şekilde görünür:
- İstemci proxy'ye bir istek gönderir:
CONNECT example.com:443 HTTP/1.1 - Proxy,
example.com:443ile bir TCP bağlantısı kurar - Proxy, istemciye yanıt verir:
200 Connection Established - Bu noktadan itibaren proxy, baytları sadece ileri geri iletir - onları analiz etmeden
- İstemci, tünel üzerinden sunucu ile doğrudan TLS handshake'i gerçekleştirir
- Ardından - TLS üzerinde WebSocket handshake'i yapılır
Ana kısıtlama: CONNECT yöntemi genellikle yalnızca 443 portu için izinlidir. Eğer WebSocket sunucunuz standart olmayan bir portta çalışıyorsa (örneğin, 8080 veya 9000), proxy bağlantıyı reddedebilir. Bu durumda SOCKS5 tercih edilir - port kısıtlaması yoktur.
Ayrıca, bazı kurumsal HTTP proxy'leri (örneğin, standart yapılandırmadaki Squid) belirli portlar için CONNECT yöntemini açıkça engelleyebilir veya kimlik doğrulama isteyebilir. Ticari proxy sağlayıcıları ile çalışıyorsanız, çoğu CONNECT'i kısıtlama olmaksızın destekler.
# CONNECT isteği örneği curl ile (kontrol için)
curl -v -x http://proxy_host:proxy_port \
--proxytunnel \
https://echo.websocket.org
# Eğer proxy CONNECT'i destekliyorsa - göreceksiniz:
# * CONNECT tunnel established, response 200
SOCKS5 ve WebSocket: neden en iyi seçenek
SOCKS5, TCP/UDP bağlantıları düzeyinde bir proxy protokolüdür. HTTP proxy'lerinin aksine, SOCKS5, içindeki uygulama protokolü hakkında hiçbir şey bilmez. Sadece istemci ile hedef sunucu arasında bir tünel oluşturur ve hepsi bu. Bu, WebSocket için birkaç nedenle idealdir:
- Protokol kısıtlaması yok: SOCKS5, WS, WSS, SSH, FTP vb. dahil olmak üzere her türlü TCP trafiğini tünelleştirir.
- Port kısıtlaması yok: yalnızca 443 veya 80 ile değil, her portla çalışır
- Protokol değişiminde kesinti yok: proxy, HTTP'den WebSocket'e geçişi "görmez"
- Kimlik doğrulama desteği: SOCKS5, ticari proxy'ler için kullanışlı olan kullanıcı adı/şifre desteği sunar
- UDP desteği: Uygulamanız WebRTC veya WS ile birlikte UDP kullanıyorsa - SOCKS5 bunu halleder
Modern WebSocket kütüphanelerinin hemen hemen hepsi SOCKS5'i ya doğrudan ya da ek paketler aracılığıyla destekler. Aşağıda Python ve Node.js için belirli örnekleri inceleyeceğiz.
💡 SOCKS5'i ne zaman seçmeli, HTTP CONNECT'i ne zaman?
SOCKS5 kullanın, eğer: standart olmayan bir port varsa, UDP desteğine ihtiyacınız varsa, minimum ayar istiyorsanız.
HTTP CONNECT kullanın, eğer: proxy sağlayıcınız SOCKS5'i desteklemiyorsa veya kurumsal bir proxy üzerinden çalışıyorsanız.
Kod örnekleri: Python'da proxy üzerinden WebSocket
Python için birkaç senaryoyu inceleyelim. Python'daki en popüler WebSocket kütüphaneleri websockets ve websocket-client'dır.
Seçenek 1: websocket-client üzerinden HTTP proxy
import websocket
# HTTP proxy ayarları
proxy_host = "proxy.example.com"
proxy_port = 8080
proxy_user = "username"
proxy_pass = "password"
ws = websocket.WebSocket()
ws.connect(
"wss://echo.websocket.org",
http_proxy_host=proxy_host,
http_proxy_port=proxy_port,
http_proxy_auth=(proxy_user, proxy_pass),
proxy_type="http" # veya "socks5"
)
ws.send("Merhaba, WebSocket!")
result = ws.recv()
print(f"Alındı: {result}")
ws.close()
Seçenek 2: websocket-client üzerinden SOCKS5
import websocket
# SOCKS5 için paket gereklidir: pip install PySocks
ws = websocket.WebSocket()
ws.connect(
"wss://echo.websocket.org",
http_proxy_host="socks5_proxy.example.com",
http_proxy_port=1080,
http_proxy_auth=("username", "password"),
proxy_type="socks5"
)
ws.send("Test mesajı")
print(ws.recv())
ws.close()
Seçenek 3: websockets kütüphanesi (asyncio) üzerinden SOCKS5
websockets (asyncio) kütüphanesi yerleşik proxy desteğine sahip değildir, bu nedenle bir tünel oluşturmak için python-socks kullanıyoruz:
# pip install websockets python-socks[asyncio]
import asyncio
import websockets
from python_socks.async_.asyncio import Proxy
async def connect_via_socks5():
proxy = Proxy.from_url("socks5://username:[email protected]:1080")
# Proxy üzerinden TCP bağlantısı oluştur
sock = await proxy.connect(
dest_host="echo.websocket.org",
dest_port=443
)
# Soketi websockets'e ilet
async with websockets.connect(
"wss://echo.websocket.org",
sock=sock
) as ws:
await ws.send("SOCKS5 üzerinden merhaba!")
response = await ws.recv()
print(f"Cevap: {response}")
asyncio.run(connect_via_socks5())
Seçenek 4: PySocks ile global yamanın yapılması
Python uygulamanızın tüm trafiğini SOCKS5 üzerinden yönlendirmek istiyorsanız, her çağrıyı değiştirmeden socks.setdefaultproxy() kullanın:
# pip install PySocks
import socks
import socket
import websocket
# Socket'i global olarak yamala
socks.set_default_proxy(
socks.SOCKS5,
"proxy.example.com",
1080,
username="user",
password="pass"
)
socket.socket = socks.socksocket
# Artık tüm bağlantılar SOCKS5 üzerinden gidiyor
ws = websocket.WebSocket()
ws.connect("wss://echo.websocket.org")
ws.send("Global SOCKS5 proxy!")
print(ws.recv())
ws.close()
Kod örnekleri: Node.js'de proxy üzerinden WebSocket
Node.js ekosisteminde en popüler WebSocket kütüphanesi ws'dir. HTTP/SOCKS5 üzerinden proxy'leme için https-proxy-agent veya socks-proxy-agent paketi kullanılır.
Seçenek 1: WSS üzerinden HTTP CONNECT proxy
// npm install ws https-proxy-agent
const WebSocket = require('ws');
const { HttpsProxyAgent } = require('https-proxy-agent');
const proxyUrl = 'http://username:[email protected]:8080';
const agent = new HttpsProxyAgent(proxyUrl);
const ws = new WebSocket('wss://echo.websocket.org', { agent });
ws.on('open', () => {
console.log('HTTP proxy üzerinden bağlantı kuruldu');
ws.send('Node.js\'den merhaba!');
});
ws.on('message', (data) => {
console.log(`Alındı: ${data}`);
ws.close();
});
ws.on('error', (err) => {
console.error('Hata:', err.message);
});
Seçenek 2: WSS üzerinden SOCKS5
// npm install ws socks-proxy-agent
const WebSocket = require('ws');
const { SocksProxyAgent } = require('socks-proxy-agent');
const proxyUrl = 'socks5://username:[email protected]:1080';
const agent = new SocksProxyAgent(proxyUrl);
const ws = new WebSocket('wss://echo.websocket.org', { agent });
ws.on('open', () => {
console.log('SOCKS5 üzerinden bağlantı kuruldu');
ws.send(JSON.stringify({ type: 'ping', data: 'test' }));
});
ws.on('message', (data) => {
console.log('Cevap:', data.toString());
});
ws.on('close', (code, reason) => {
console.log(`Kapandı: ${code} - ${reason}`);
});
Seçenek 3: WS (TLS olmadan) HTTP proxy üzerinden manuel olarak
Şifrelenmemiş WS (port 80) için HTTP proxy üzerinden manuel olarak CONNECT isteği göndermek gerekir, çünkü standart ajanlar genellikle yalnızca HTTPS ile çalışır:
const net = require('net');
const WebSocket = require('ws');
function createTunnel(proxyHost, proxyPort, targetHost, targetPort) {
return new Promise((resolve, reject) => {
const socket = net.connect(proxyPort, proxyHost, () => {
const connectReq =
`CONNECT ${targetHost}:${targetPort} HTTP/1.1\r\n` +
`Host: ${targetHost}:${targetPort}\r\n` +
`Proxy-Authorization: Basic ${Buffer.from('user:pass').toString('base64')}\r\n` +
`\r\n`;
socket.write(connectReq);
});
socket.once('data', (data) => {
if (data.toString().includes('200')) {
resolve(socket);
} else {
reject(new Error(`Proxy CONNECT'i reddetti: ${data.toString()}`));
}
});
socket.on('error', reject);
});
}
async function main() {
const socket = await createTunnel(
'proxy.example.com', 8080,
'echo.websocket.org', 80
);
const ws = new WebSocket('ws://echo.websocket.org', { socket });
ws.on('open', () => {
ws.send('Manuel CONNECT tüneli!');
});
ws.on('message', (data) => {
console.log('Alındı:', data.toString());
ws.close();
});
}
main().catch(console.error);
WSS (WebSocket Secure): TLS ile proxy'lemenin özellikleri
WSS, TLS üzerinde WebSocket'tir (HTTP için HTTPS'e benzer). WSS'i SOCKS5 veya HTTP CONNECT üzerinden proxy'lerken önemli bir nokta vardır: TLS şifrelemesi, istemci ile son sunucu arasında kurulur, proxy ile değil. Bu, şu anlama gelir:
- Proxy sunucusu WSS trafiğinin içeriğini görmez - yalnızca hedef IP adresi ve portunu görür
- Sunucu sertifikası doğrudan istemci tarafından kontrol edilir
- Proxy, kendi CA sertifikasını kurmadan verileri "değiştiremez" veya "yakalayamaz"
Bu, güvenlik açısından iyi bir haber. Ancak, ayarlama sırasında pratik zorluklar da vardır:
Proxy üzerinden sertifika doğrulaması
Kurumsal proxy'ler (SSL denetimi yapanlar) kullanırken bazen sertifika doğrulama hatası alabilirsiniz. Bu durumda, proxy sunucusu sunucu sertifikasını kendi sertifikası ile değiştirir. Böyle bir ortamda çalışmak için proxy'nin CA sertifikasını güvenilirler listesine eklemek gerekir:
# Python: kurumsal proxy'nin CA sertifikasını geçiriyoruz
import ssl
import websocket
ssl_context = ssl.create_default_context()
ssl_context.load_verify_locations("/path/to/corporate-ca.crt")
ws = websocket.WebSocket(sslopt={"context": ssl_context})
ws.connect(
"wss://internal.example.com",
http_proxy_host="corp-proxy.company.com",
http_proxy_port=8080,
proxy_type="http"
)
# Test ortamlarında (ÜRETİM için DEĞİL!) kontrolü devre dışı bırakabilirsiniz:
ws_test = websocket.WebSocket(sslopt={"cert_reqs": ssl.CERT_NONE})
ws_test.connect("wss://test.example.com", http_proxy_host="proxy", http_proxy_port=8080)
⚠️ Önemli
TLS sertifika doğrulamasını devre dışı bırakmak (CERT_NONE) yalnızca test ortamında kabul edilebilir. Üretimde bu, MITM (man-in-the-middle) saldırıları için bir zafiyet oluşturur.
SNI (Sunucu Adı Belirtimi) üzerinden proxy
SOCKS5 kullanırken, istemci DNS'i kendisi çözebilir veya bunu proxy'ye devredebilir. socks5h (Hostname çözümlemesi ile SOCKS5) modu, DNS sorgusunun proxy sunucusu tarafında gerçekleştirildiği anlamına gelir. Bu, WSS için önemlidir, çünkü TLS handshake'inde SNI başlığı, ana bilgisayar adıyla eşleşmelidir:
# socks5 — DNS yerel olarak (istemci tarafından) çözülür
# socks5h — DNS proxy sunucusu tarafından çözülür (anonimlik için önerilir)
from python_socks.async_.asyncio import Proxy
# Proxy üzerinden DNS (önerilir):
proxy = Proxy.from_url("socks5h://user:[email protected]:1080")
# Yerel DNS:
proxy = Proxy.from_url("socks5://user:[email protected]:1080")
Yaygın hatalar ve nasıl düzeltileceği
WebSocket'i proxy'lerken en sık karşılaşılan sorunları ve çözümlerini derledik:
Hata 1: 407 Proxy Authentication Required
Proxy kimlik doğrulama gerektiriyor, ancak kimlik bilgilerini göndermediniz veya yanlış gönderdiniz.
# ❌ Yanlış — yetkilendirme yok
ws.connect("wss://example.com", http_proxy_host="proxy.example.com", http_proxy_port=8080)
# ✅ Doğru — kullanıcı adı ve şifre gönderiyoruz
ws.connect(
"wss://example.com",
http_proxy_host="proxy.example.com",
http_proxy_port=8080,
http_proxy_auth=("username", "password")
)
Hata 2: Connection reset by peer / 502 Bad Gateway
Proxy WebSocket veya CONNECT yöntemini desteklemiyor. Çözüm: SOCKS5'e geçin veya sağlayıcınızın WebSocket trafiğini destekleyip desteklemediğini kontrol edin.
Hata 3: Bağlantı 30-60 saniye içinde kesiliyor
Birçok proxy sunucusu "aktif olmayan" TCP bağlantılarını zaman aşımında kapatır. WebSocket bağlantısı, veri alışverişi yoksa aktif görünmeyebilir. Çözüm - ping/pong'u etkinleştirmektir:
# Python — her 20 saniyede bir keepalive ping'i etkinleştir
import websocket
import threading
def run():
ws = websocket.WebSocketApp(
"wss://echo.websocket.org",
on_message=lambda ws, msg: print(msg),
on_error=lambda ws, err: print(f"Hata: {err}"),
on_close=lambda ws, c, m: print("Kapandı")
)
ws.run_forever(
ping_interval=20, # her 20 saniyede bir ping gönder
ping_timeout=10, # pong için en fazla 10 saniye bekle
http_proxy_host="proxy.example.com",
http_proxy_port=8080,
proxy_type="socks5"
)
thread = threading.Thread(target=run)
thread.start()
Hata 4: SSL: CERTIFICATE_VERIFY_FAILED
Genellikle kurumsal proxy kullanırken SSL denetimi ile karşılaşılır. Çözüm: proxy'nin CA sertifikasını güvenilirler listesine ekleyin (yukarıdaki bölüme bakın) veya HTTP proxy yerine SOCKS5 kullanın - SOCKS5 SSL denetimi yapmaz.
Hata 5: Handshake durumu 403 Forbidden
Hedef sunucu bağlantıyı engelliyor. Nedenler: proxy'nin IP'si kara listeye alınmış, gerekli başlıklar (Origin, User-Agent) yok veya sunucu veri merkezlerinden gelen trafiği engelliyor. Çözüm: konut proxy'leri kullanın - gerçek ev kullanıcılarının IP'leri ile daha zor engellenirler.
Hata 6: [Errno 111] Bağlantı reddedildi
Proxy sunucusu erişilemez: yanlış host/port, veya proxy çalışmıyor. Bağlantı bilgilerini kontrol edin ve WebSocket'i test etmeden önce proxy'nin erişilebilirliğini basit bir HTTP isteği ile kontrol edin.
WebSocket görevleri için hangi proxy türünü seçmeli
Proxy türü seçimi belirli bir göreve bağlıdır. İşte pratik bir rehber:
| Görev | Önerilen tür | Neden |
|---|---|---|
| WS üzerinden veri çekme (borsa, finansal veriler) | Veri merkezi proxy'leri | Yüksek hız, düşük gecikme, kararlı bağlantı |
| WebSocket hizmetlerinin engellerini aşma | Konut proxy'leri | Gerçek IP'ler, minimum engellenme riski |
| Mobil uygulamalar ile WS (mobil API'lerle çalışma) | Mobil proxy'ler | Mobil operatörlerin IP'leri - hizmetler tarafından yüksek güvenilirlik |
| WS sunucusunu yük testi | Veri merkezi proxy'leri | Uygun fiyat, hızlı, çok sayıda eşzamanlı bağlantı |
| WS ile coğrafi test | Konut proxy'leri | Geniş ülke ve şehir seçeneği |
WebSocket için önemli proxy parametreleri
WebSocket görevleri için bir proxy sağlayıcısı seçerken aşağıdaki parametrelere dikkat edin:
- SOCKS5 desteği: sağlayıcının yalnızca HTTP değil, SOCKS5 sunduğundan emin olun
- Oturum süresi (session duration): WebSocket için "sticky" oturumlar önemlidir - bir IP uzun süre boyunca. Döngüsel proxy'ler bağlantıyı keser
- Bağlantı zaman aşımı: proxy, uzun ömürlü TCP bağlantılarını (birkaç dakikadan saatlere kadar) desteklemelidir
- Band genişliği: akış WebSocket'i (video, borsa verileri) için yüksek band genişliği önemlidir, sınırlama olmadan
- Gecikme (latency): finansal uygulamalar ve ticaret botları için minimum gecikme kritik öneme sahiptir - hedef hizmete daha yakın sunucularla proxy seçin
💡 WebSocket proxy sağlayıcısının desteğini kontrol etme
WebSocket görevleri için proxy satın almadan önce, ücretsiz bir echo sunucusu üzerinden test edin:
wss://echo.websocket.org veya
wss://ws.postman-echo.com/raw.
Bağlantı kurulursa ve mesajlar geri dönerse - proxy WebSocket ile düzgün çalışıyor demektir.
WebSocket için sticky oturum ayarı
Çoğu konut proxy sağlayıcısı varsayılan olarak IP rotasyonu kullanır. WebSocket için bu kabul edilemez - her IP değişikliği bağlantının kesilmesi anlamına gelir. Sticky session (sabit IP) modunu kullandığınızdan emin olun. Genellikle bu, proxy'nin özel URL formatı aracılığıyla yapılır:
# Sticky session formatı örneği (sağlayıcıya bağlıdır):
# Döngüsel (WebSocket için uygun DEĞİL):
socks5://user:[email protected]:1080
# Sticky session (WebSocket için uygundur):
socks5://user-session-abc123:[email protected]:1080
# Veya ülke ve oturum parametresi ile:
socks5://user-country-us-session-12345:[email protected]:1080
Sonuç
WebSocket, sadece "uzun bağlantılı HTTP" değildir. Bu, proxy'leme sırasında özel bir yaklaşım gerektiren ayrı bir protokoldür. Bu makaleden çıkan ana sonuçlar:
- SOCKS5 - WebSocket için en iyi seçimdir: taşıma katmanında çalışır, protokolü analiz etmez, her portu destekler
- HTTP proxy'leri üzerinden CONNECT de çalışır, ancak port kısıtlamaları ve SSL denetimi ile ilgili olası sorunlar vardır
- Sticky oturumlar zorunludur: döngüsel proxy'ler her IP değişiminde WebSocket bağlantısını keser
- Ping/pong keepalive, proxy'nin zaman aşımında bağlantıyı kesmesini önlemek için gereklidir
- WSS proxy üzerinden güvenlidir: TLS şifrelemesi doğrudan istemci ile sunucu arasında kurulur, proxy içeriği görmez
Eğer bir uygulama geliştiriyorsanız ve WebSocket ile proxy üzerinden çalışıyorsanız - SOCKS5 ve sticky oturumlarla başlayın. Bu, size saatlerce hata ayıklama tasarrufu sağlar. Yüksek hız ve bağlantı kararlılığının önemli olduğu görevler (ticaret botları, veri akışı) için, düşük gecikmeli veri merkezi proxy'leri mükemmel bir seçimdir. Ancak hedef hizmet veri merkezi IP'lerini aktif olarak engelliyorsa - konut proxy'lerini düşünün: gerçek ev kullanıcılarının IP'lerine sahiptirler ve uzun WebSocket oturumlarında bile engellenmeleri çok daha zordur.
```