Proxy Kullanırken SSL/TLS Sorunlarını Çözme: Tam Rehber
SSL/TLS hataları, proxy sunucuları aracılığıyla çalışırken en sık karşılaşılan sorunlardan biridir. Yanlış yapılandırma, bağlantı arızalarına, veri sızıntılarına ve korumalı kaynakları ayrıştırmanın imkansız hale gelmesine yol açar. Bu rehberde hataların nedenlerini ve somut kod örnekleriyle çözüm yollarını inceleyeceğiz.
SSL/TLS Proxy Aracılığıyla Nasıl Çalışır
Sorunları çözmeden önce, proxy aracılığıyla korumalı bağlantıların çalışma mekanizmasını anlamak önemlidir. HTTPS trafiğini proxy aracılığıyla göndermenin iki temel farklı yaklaşımı vardır ve her birinin kendi özellikleri, avantajları ve potansiyel arıza noktaları vardır.
Şeffaf Tünelleme (CONNECT)
CONNECT yöntemi kullanılırken proxy sunucusu, istemci ve hedef sunucu arasında bir TCP tüneli oluşturur. Proxy trafiğin içeriğini görmez — sadece şifreli baytları her iki yöne iletir. Bu, HTTPS aracılığıyla proxy aracılığıyla çalışmak için en güvenli ve yaygın yöntemdir.
Bağlantı kurma işlemi şu şekilde görünür: istemci, hedef ana bilgisayar ve bağlantı noktasını belirterek proxy'ye bir CONNECT isteği gönderir. Proxy, hedef sunucuyla bir TCP bağlantısı kurar ve istemciye 200 Connection Established yanıtını döndürür. Bundan sonra istemci, kurulan tünel aracılığıyla doğrudan hedef sunucuyla TLS el sıkışması gerçekleştirir.
# CONNECT tüneli şeması
İstemci → Proxy: CONNECT example.com:443 HTTP/1.1
Proxy → Sunucu: [443 portuna TCP bağlantısı]
Proxy → İstemci: HTTP/1.1 200 Connection Established
İstemci ↔ Sunucu: [Tünel aracılığıyla TLS el sıkışması]
İstemci ↔ Sunucu: [Şifreli trafik]
MITM Proxy'si (Kesme)
Bazı proxy'ler (özellikle kurumsal) Man-in-the-Middle tekniğini kullanır: TLS bağlantısını kendi tarafında sonlandırırlar, trafiği şifrelerini çözerler ve ardından hedef sunucuyla yeni bir TLS bağlantısı kurarlar. Bunun için proxy, her etki alanı için proxy'nin kök sertifikası tarafından imzalanan kendi sertifikasını oluşturur.
Bu yaklaşım HTTPS trafiğini incelemeyi ve filtrelemeyi sağlar, ancak proxy'nin kök sertifikasının istemcinin güvenilen depo'suna yüklenmesini gerektirir. Proxy aracılığıyla çalışırken SSL/TLS sorunlarının çoğu tam burada ortaya çıkar.
Yaygın Hatalar ve Nedenleri
Proxy aracılığıyla çalışırken en yaygın SSL/TLS hatalarını inceleyelim. Her hatanın nedenini anlamak, sorunu hızlı bir şekilde çözmenin anahtarıdır.
SSL: CERTIFICATE_VERIFY_FAILED
Bu hata, istemcinin sunucu sertifikasının orijinalliğini doğrulayamadığı anlamına gelir. Birkaç nedeni olabilir: proxy MITM incelemesi kullanıyor ancak kök sertifikası yüklü değil, hedef sunucunun sertifikası süresi dolmuş veya kendi imzalı, ya da sertifika zincirinde ara sertifika eksik.
# Python - tipik hata mesajı
ssl.SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED]
certificate verify failed: unable to get local issuer certificate
# Node.js
Error: unable to verify the first certificate
# cURL
curl: (60) SSL certificate problem: unable to get local issuer certificate
SSL: WRONG_VERSION_NUMBER
Hata, istemci TLS bağlantısı kurmaya çalıştığında ancak beklenmeyen biçimde bir yanıt aldığında oluşur. Çoğunlukla proxy CONNECT yöntemini desteklemediğinde ve HTTPS isteğini normal HTTP olarak işlemeye çalıştığında ortaya çıkar. Ayrıca yanlış bağlantı noktası veya protokol de neden olabilir.
TLSV1_ALERT_PROTOCOL_VERSION
Sunucu, uyumsuz TLS protokolü sürümü nedeniyle bağlantıyı reddeder. Modern sunucular güvenlik nedenleriyle eski TLS 1.0 ve TLS 1.1 sürümlerini devre dışı bırakır. Proxy veya istemci eski sürümleri kullanacak şekilde yapılandırılmışsa, bağlantı reddedilecektir.
SSLV3_ALERT_HANDSHAKE_FAILURE
İstemci ve sunucu şifreleme parametrelerini kabul edemedi. Bu, ortak cipher suite'lerin olmaması, SNI (Server Name Indication) sorunları veya kriptografik kütüphanelerin uyumsuzluğu nedeniyle ortaya çıkabilir.
| Hata | Muhtemel Neden | Çözüm |
|---|---|---|
CERTIFICATE_VERIFY_FAILED |
MITM proxy'si, süresi dolmuş sertifika | Proxy'nin kök sertifikasını yükleyin |
WRONG_VERSION_NUMBER |
HTTP yerine HTTPS, CONNECT desteği yok | Proxy ayarlarını ve protokolü kontrol edin |
PROTOCOL_VERSION |
Eski TLS sürümü | Minimum TLS sürümünü güncelleyin |
HANDSHAKE_FAILURE |
Uyumsuz cipher suite'ler | Şifre listesini yapılandırın |
Sertifika Sorunları
Sertifikalar, proxy aracılığıyla çalışırken sorunların en sık kaynağıdır. Ana senaryoları ve çözüm yollarını inceleyelim.
Proxy Kök Sertifikasının Yüklenmesi
Proxy MITM incelemesi kullanıyorsa, kök sertifikasını güvenilen depoya eklemeniz gerekir. İşlem, işletim sistemi ve kullanılan programlama diline bağlıdır.
# Linux: sertifikayı sistem deposuna ekleme
sudo cp proxy-ca.crt /usr/local/share/ca-certificates/
sudo update-ca-certificates
# macOS: Keychain'e ekleme
sudo security add-trusted-cert -d -r trustRoot \
-k /Library/Keychains/System.keychain proxy-ca.crt
# Windows PowerShell (yönetici olarak)
Import-Certificate -FilePath "proxy-ca.crt" `
-CertStoreLocation Cert:\LocalMachine\Root
Kodda Sertifika Belirtme
Bazen sertifika yolunu doğrudan kodda belirtmek daha uygundur, özellikle konteynerler veya root erişimi olmayan sunucularda çalışırken. Bu, sistem ayarlarının değiştirilmesini önlemeye yardımcı olur.
# Python: özel CA-bundle belirtme
import requests
# Yol 1: sertifika dosyasının yolunu belirtin
response = requests.get(
'https://example.com',
proxies={'https': 'http://proxy:8080'},
verify='/path/to/proxy-ca.crt'
)
# Yol 2: sistem sertifikalarıyla birleştirin
import certifi
import ssl
# Birleştirilmiş sertifika dosyası oluşturun
with open('combined-ca.crt', 'w') as combined:
with open(certifi.where()) as system_certs:
combined.write(system_certs.read())
with open('proxy-ca.crt') as proxy_cert:
combined.write(proxy_cert.read())
response = requests.get(url, verify='combined-ca.crt')
Sertifika Doğrulamasını Devre Dışı Bırakma
Bazı durumlarda (yalnızca test ve hata ayıklama için!) sertifika doğrulamasını devre dışı bırakmak gerekebilir. Bu güvenli değildir ve üretimde kullanılmamalıdır, çünkü bağlantıyı MITM saldırılarına karşı savunmasız hale getirir.
⚠️ Uyarı: Sertifika doğrulamasını devre dışı bırakmak bağlantıyı kesme açısından savunmasız hale getirir. Yalnızca izole bir ortamda hata ayıklama için kullanın, asla üretimde kullanmayın!
# Python - YALNIZCA hata ayıklama için!
import requests
import urllib3
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
response = requests.get(
'https://example.com',
proxies={'https': 'http://proxy:8080'},
verify=False # Güvenli değil!
)
CONNECT Tünellerinin Yapılandırılması
CONNECT tünelinin doğru yapılandırılması, proxy aracılığıyla HTTPS'nin istikrarlı çalışmasının anahtarıdır. Farklı kullanım senaryoları için özellikleri inceleyelim.
CONNECT Desteğini Kontrol Etme
Tüm proxy'ler CONNECT yöntemini desteklemez. HTTP proxy'leri yalnızca HTTP trafiğini proxy'ye almak için yapılandırılabilir. Kullanmadan önce proxy'nin HTTPS tünellemeyi desteklediğinden emin olun.
# netcat/telnet aracılığıyla CONNECT desteğini kontrol etme
echo -e "CONNECT example.com:443 HTTP/1.1\r\nHost: example.com:443\r\n\r\n" | \
nc proxy.example.com 8080
# Başarı durumunda beklenen yanıt:
# HTTP/1.1 200 Connection Established
# Hata durumunda olası yanıtlar:
# HTTP/1.1 403 Forbidden - CONNECT yasak
# HTTP/1.1 405 Method Not Allowed - yöntem desteklenmiyor
CONNECT İsteklerinde Kimlik Doğrulama
Kimlik doğrulama gerektiren proxy kullanırken, kimlik bilgilerini doğru şekilde iletmek önemlidir. Proxy-Authorization başlığı CONNECT isteğinde bulunmalıdır.
# Python: URL aracılığıyla kimlik doğrulama
import requests
proxy_url = 'http://username:password@proxy.example.com:8080'
response = requests.get(
'https://target.com',
proxies={'https': proxy_url}
)
# Python: başlıklar aracılığıyla kimlik doğrulama (karmaşık durumlar için)
import base64
credentials = base64.b64encode(b'username:password').decode('ascii')
session = requests.Session()
session.headers['Proxy-Authorization'] = f'Basic {credentials}'
session.proxies = {'https': 'http://proxy.example.com:8080'}
response = session.get('https://target.com')
SOCKS5 Proxy'si ile Çalışma
SOCKS5 proxy'leri daha düşük bir seviyede çalışır ve HTTPS'nin özel işlenmesini gerektirmez. Basitçe TCP bağlantılarını tünellerler, bu da onları herhangi bir protokolle çalışmak için ideal kılar.
# PySocks ile Python
import requests
proxies = {
'http': 'socks5h://user:pass@proxy:1080',
'https': 'socks5h://user:pass@proxy:1080'
}
# socks5h - proxy aracılığıyla DNS çözümlemesi
# socks5 - yerel DNS çözümlemesi
response = requests.get('https://example.com', proxies=proxies)
Farklı Programlama Dilleri için Çözümler
Her dil ve kütüphane, proxy aracılığıyla SSL/TLS ile çalışmanın kendi özelliklerine sahiptir. En yaygın seçenekleri tam kod örnekleriyle inceleyelim.
Python (requests + urllib3)
import requests
from requests.adapters import HTTPAdapter
from urllib3.util.ssl_ import create_urllib3_context
import ssl
class TLSAdapter(HTTPAdapter):
"""Özelleştirilebilir TLS parametreleriyle adaptör"""
def __init__(self, ssl_context=None, **kwargs):
self.ssl_context = ssl_context
super().__init__(**kwargs)
def init_poolmanager(self, *args, **kwargs):
if self.ssl_context:
kwargs['ssl_context'] = self.ssl_context
return super().init_poolmanager(*args, **kwargs)
# Modern ayarlarla bağlam oluşturma
ctx = create_urllib3_context()
ctx.minimum_version = ssl.TLSVersion.TLSv1_2
ctx.set_ciphers('ECDHE+AESGCM:DHE+AESGCM:ECDHE+CHACHA20')
# Ek sertifika yükleme
ctx.load_verify_locations('proxy-ca.crt')
session = requests.Session()
session.mount('https://', TLSAdapter(ssl_context=ctx))
session.proxies = {
'http': 'http://proxy:8080',
'https': 'http://proxy:8080'
}
response = session.get('https://example.com')
print(response.status_code)
Node.js (axios + https-proxy-agent)
const axios = require('axios');
const { HttpsProxyAgent } = require('https-proxy-agent');
const fs = require('fs');
const https = require('https');
// Ek CA sertifikasını yükleme
const customCA = fs.readFileSync('proxy-ca.crt');
const agent = new HttpsProxyAgent({
host: 'proxy.example.com',
port: 8080,
auth: 'username:password',
ca: customCA,
rejectUnauthorized: true // Üretimde devre dışı bırakmayın!
});
const client = axios.create({
httpsAgent: agent,
proxy: false // Önemli: axios'un yerleşik proxy'sini devre dışı bırakın
});
async function fetchData() {
try {
const response = await client.get('https://example.com');
console.log(response.data);
} catch (error) {
if (error.code === 'UNABLE_TO_VERIFY_LEAF_SIGNATURE') {
console.error('Sertifika sorunu:', error.message);
}
throw error;
}
}
fetchData();
Go (net/http)
package main
import (
"crypto/tls"
"crypto/x509"
"io/ioutil"
"net/http"
"net/url"
"log"
)
func main() {
// Ek sertifikayı yükleme
caCert, err := ioutil.ReadFile("proxy-ca.crt")
if err != nil {
log.Fatal(err)
}
caCertPool := x509.NewCertPool()
caCertPool.AppendCertsFromPEM(caCert)
// TLS yapılandırması
tlsConfig := &tls.Config{
RootCAs: caCertPool,
MinVersion: tls.VersionTLS12,
}
// Proxy yapılandırması
proxyURL, _ := url.Parse("http://user:pass@proxy:8080")
transport := &http.Transport{
Proxy: http.ProxyURL(proxyURL),
TLSClientConfig: tlsConfig,
}
client := &http.Client{Transport: transport}
resp, err := client.Get("https://example.com")
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
log.Printf("Durum: %s", resp.Status)
}
cURL (komut satırı)
# Proxy aracılığıyla temel istek
curl -x http://proxy:8080 https://example.com
# Kimlik doğrulama ile
curl -x http://proxy:8080 -U username:password https://example.com
# CA sertifikasını belirtme
curl -x http://proxy:8080 --cacert proxy-ca.crt https://example.com
# TLS 1.2+ kullanımını zorlama
curl -x http://proxy:8080 --tlsv1.2 https://example.com
# TLS el sıkışmasının hata ayıklaması
curl -x http://proxy:8080 -v --trace-ascii - https://example.com 2>&1 | \
grep -E "(SSL|TLS|certificate)"
MITM İncelemesini Algılama ve Atlatma
Bazı ağlar (kurumsal, genel Wi-Fi) HTTPS trafiğinin şeffaf MITM incelemesini kullanır. Bu, sertifika sabitleme sorunlarına neden olabilir ve belirli sertifikaları bekleyen uygulamaların çalışmasını bozabilir.
MITM Proxy'sini Algılama
import ssl
import socket
def check_certificate_issuer(hostname, port=443):
"""Web sitesinin sertifikasının kimin tarafından verildiğini kontrol eder"""
context = ssl.create_default_context()
with socket.create_connection((hostname, port)) as sock:
with context.wrap_socket(sock, server_hostname=hostname) as ssock:
cert = ssock.getpeercert()
issuer = dict(x[0] for x in cert['issuer'])
subject = dict(x[0] for x in cert['subject'])
print(f"Konu: {subject.get('commonName')}")
print(f"Veren: {issuer.get('commonName')}")
print(f"Kuruluş: {issuer.get('organizationName')}")
# Bilinen kurumsal MITM proxy'leri
mitm_indicators = [
'Zscaler', 'BlueCoat', 'Symantec', 'Fortinet',
'Palo Alto', 'McAfee', 'Cisco', 'Corporate'
]
issuer_str = str(issuer)
for indicator in mitm_indicators:
if indicator.lower() in issuer_str.lower():
print(f"⚠️ MITM proxy algılandı: {indicator}")
return True
return False
# Kontrol
check_certificate_issuer('google.com')
MITM Koşullarında Çalışma
MITM proxy'si algılanırsa, çalışmanın birkaç stratejisi vardır. Proxy'nin kök sertifikasını yükleyebilir (güvenilen kurumsal ağsa), alternatif bağlantı noktaları veya protokoller kullanabilir veya incelemeyi atlatmak için VPN uygulayabilirsiniz.
# MITM proxy sertifikasını yükleme için alma
openssl s_client -connect example.com:443 -proxy proxy:8080 \
-showcerts 2>/dev/null | \
openssl x509 -outform PEM > mitm-cert.pem
# Sertifika bilgisini görüntüleme
openssl x509 -in mitm-cert.pem -text -noout | head -20
Tanılama Araçları
Doğru tanılama, sorunun çözümünün yarısıdır. Proxy aracılığıyla SSL/TLS bağlantılarının hata ayıklanması için araçları ve yöntemleri inceleyelim.
Tanılama için OpenSSL
# Proxy aracılığıyla bağlantıyı kontrol etme
openssl s_client -connect example.com:443 \
-proxy proxy.example.com:8080 \
-servername example.com
# Sertifika zincirini kontrol etme
openssl s_client -connect example.com:443 \
-proxy proxy:8080 \
-showcerts 2>/dev/null | \
grep -E "(Certificate chain|s:|i:)"
# Belirli TLS sürümünü test etme
openssl s_client -connect example.com:443 \
-proxy proxy:8080 \
-tls1_2
# Desteklenen cipher suite'leri kontrol etme
openssl s_client -connect example.com:443 \
-proxy proxy:8080 \
-cipher 'ECDHE-RSA-AES256-GCM-SHA384'
Tanılama için Python Betiği
import ssl
import socket
import requests
from urllib.parse import urlparse
def diagnose_ssl_proxy(target_url, proxy_url):
"""Proxy aracılığıyla SSL'nin kapsamlı tanılaması"""
print(f"🔍 Tanılama: {target_url}")
print(f"📡 Proxy: {proxy_url}\n")
# 1. Proxy'nin erişilebilirliğini kontrol etme
proxy = urlparse(proxy_url)
try:
sock = socket.create_connection(
(proxy.hostname, proxy.port),
timeout=10
)
sock.close()
print("✅ Proxy erişilebilir")
except Exception as e:
print(f"❌ Proxy erişilemez: {e}")
return
# 2. CONNECT yöntemini kontrol etme
try:
response = requests.get(
target_url,
proxies={'https': proxy_url},
timeout=15
)
print(f"✅ HTTPS bağlantısı başarılı: {response.status_code}")
except requests.exceptions.SSLError as e:
print(f"❌ SSL hatası: {e}")
# Tanılama için sertifika doğrulaması olmadan deneme
try:
response = requests.get(
target_url,
proxies={'https': proxy_url},
verify=False,
timeout=15
)
print("⚠️ Sertifika doğrulaması olmadan bağlantı çalışıyor")
print(" Muhtemelen proxy'nin CA sertifikasıyla ilgili sorun")
except Exception as e2:
print(f"❌ Doğrulama olmadan da çalışmıyor: {e2}")
except Exception as e:
print(f"❌ Bağlantı hatası: {e}")
# 3. SSL bilgisi
print(f"\n📋 OpenSSL Sürümü: {ssl.OPENSSL_VERSION}")
print(f"📋 Desteklenen protokoller: {ssl.get_default_verify_paths()}")
# Kullanım
diagnose_ssl_proxy(
'https://httpbin.org/ip',
'http://proxy:8080'
)
Derin Analiz için Wireshark
Karmaşık durumlar için TLS trafiğinde filtre ile Wireshark kullanın. Bu, el sıkışmanın ayrıntılarını görmek ve hatanın tam olarak nerede oluştuğunu belirlemek için izin verir.
# TLS analizi için Wireshark filtreleri
tls.handshake.type == 1 # İstemci Merhaba
tls.handshake.type == 2 # Sunucu Merhaba
tls.handshake.type == 11 # Sertifika
tls.alert_message # TLS uyarıları (hatalar)
# tcpdump ile trafik yakalama
tcpdump -i eth0 -w ssl_debug.pcap \
'port 443 or port 8080' -c 1000
Güvenli Çalışmanın En İyi Uygulamaları
En iyi uygulamaları takip etmek, SSL/TLS sorunlarının çoğunu önlemeye yardımcı olacak ve proxy aracılığıyla çalışırken verilerinizin güvenliğini sağlayacaktır.
TLS Yapılandırması
- Minimum TLS 1.2 kullanın, tercihen TLS 1.3
- Modern cipher suite'leri yapılandırın (ECDHE, AES-GCM, ChaCha20)
- Sertifika doğrulamasını etkinleştirin (üretimde asla devre dışı bırakmayın)
- CA-bundle ve kriptografik kütüphaneleri düzenli olarak güncelleyin
Proxy ile Çalışma
- HTTPS trafiği için CONNECT yöntemini destekleyen proxy'leri tercih edin
- Evrensel tünelleme için SOCKS5 kullanın
- Rezidans proxy'leri ile çalışırken sağlayıcı ağlarının olası özelliklerini göz önünde bulundurun
- Proxy kimlik bilgilerini ortam değişkenlerinde saklayın, kodda değil
Hata İşleme
import requests
from requests.exceptions import SSLError, ProxyError, ConnectionError
import time
def robust_request(url, proxy, max_retries=3):
"""Hatalara karşı dirençli proxy isteği"""
for attempt in range(max_retries):
try:
response = requests.get(
url,
proxies={'https': proxy},
timeout=30
)
return response
except SSLError as e:
print(f"SSL hatası (deneme {attempt + 1}): {e}")
# SSL hataları genellikle yeniden deneme ile düzelmez
if 'CERTIFICATE_VERIFY_FAILED' in str(e):
raise # Yapılandırma düzeltmesi gerekir
except ProxyError as e:
print(f"Proxy hatası (deneme {attempt + 1}): {e}")
time.sleep(2 ** attempt) # Üstel gecikme
except ConnectionError as e:
print(f"Bağlantı hatası (deneme {attempt + 1}): {e}")
time.sleep(2 ** attempt)
raise Exception(f"{max_retries} denemeden sonra istek başarısız")
Sorun Giderme Kontrol Listesi
SSL/TLS hataları oluştuğunda, bu tanılama sırasını izleyin:
- Proxy sunucusunun erişilebilirliğini kontrol edin (ping, telnet)
- CONNECT yönteminin desteklendiğinden emin olun
- Kimlik doğrulama kimlik bilgilerinin doğruluğunu kontrol edin
- openssl s_client aracılığıyla sertifikayı inceleyin
- MITM incelemesinin varlığını kontrol edin
- Gerekli CA sertifikalarını yükleyin
- TLS sürümünü ve cipher suite'leri güncelleyin
💡 İpucu: Proxy aracılığıyla çalışırken SSL/TLS sorunlarının çoğu sertifikalarla ilgilidir. Tanılamaya sertifika zincirini kontrol ederek başlayın ve tüm ara sertifikaların mevcut olduğundan emin olun.
Sonuç
Proxy aracılığıyla çalışırken SSL/TLS sorunları sistematik bir tanılama yaklaşımıyla çözülebilir. Temel noktalar: CONNECT tünelleme ile MITM proxy'si arasındaki farkı anlamak, sertifikaları doğru şekilde yapılandırmak ve modern TLS protokolü sürümlerini kullanmak. Hataların çoğu gerekli CA sertifikalarının olmaması veya kriptografik parametrelerin uyumsuzluğu ile ilgilidir.
Ayrıştırma ve otomasyon gerektiren ve istikrarlı HTTPS çalışması gerektiren görevler için, CONNECT yöntemini tam olarak destekleyen kaliteli proxy'ler kullanılması önerilir — proxycove.com adresinde seçenekler hakkında daha fazla bilgi edinin.