کالبدشکافی TLS Fingerprinting و روشهای دور زدن فایروالهای مدرن (Cloudflare / Akamai)
بررسی عمیق مکانیسمهای شناسایی بات در لایه انتقال و نشست، کالبدشکافی الگوریتمهای JA3/JA4 و فریمهای HTTP/2، همراه با پیادهسازی کلاینت ضدتشخیص در پایتون.
چرا تغییر User-Agent دیگر کافی نیست؟
در معماری فایروالهای وب مدرن (WAF) مانند Cloudflare Turnstile، Akamai Bot Manager و DataDome، تصمیمگیری درباره مسدودسازی یک درخواست بسیار پیش از آنکه هدرهای HTTP رمزگشایی شوند، در لایههای پایینتر شبکه (لایه ۴ و ۵ مدل OSI) انجام میگیرد. زمانی که شما با کتابخانههای استانداردی مثل requests، urllib3 یا httpx در پایتون درخواستی ارسال میکنید، این کتابخانهها از پشته OpenSSL سیستمعامل برای برقراری نشست امن TLS استفاده میکنند.
مرورگرهای واقعی نظیر Google Chrome از پیادهسازی BoringSSL و فایرفاکس از NSS بهره میبرند. تفاوت در ترتیب رمزنگارها (Cipher Suites)، افزونههای TLS و پارامترهای مذاکره باعث میشود که فایروال در همان میلیثانیه اول و پیش از دریافت هدر User-Agent، متوجه عدم تطابق امضای شبکه با مرورگر ادعاشده شود.
کالبدشکافی بسته ClientHello و الگوریتمهای JA3 و JA4+
فرآیند TLS Handshake با ارسال بسته ClientHello به صورت متن آشکار (Unencrypted) از سمت کلاینت آغاز میشود. الگوریتم JA3 که توسط مهندسان Salesforce معرفی شد، ۵ فیلد کلیدی این بسته را استخراج کرده، مقادیر اعشاری آنها را با خط تیره به هم متصل میکند و در نهایت یک هش MD5 از آن میسازد:
- TLSVersion: نسخه پروتکل مورد استفاده در مذاکره اولیه
- Ciphers: لیست کدهای Cipher Suite به ترتیب اولویت کلاینت
- Extensions: لیست افزونههای TLS مانند
server_name(SNI)،application_layer_protocol_negotiation(ALPN) وstatus_request - EllipticCurves (Supported Groups): منحنیهای بیضوی پشتیبانیشده مانند
X25519وsecp256r1 - EllipticCurvePointFormats: فرمت نقاط منحنی بیضوی
گذار از JA3 به JA4+ و چالش TLS Extension Randomization
از نسخه ۱۰۶ کروم، گوگل قابلیت TLS Extension Permutation را فعال کرد که ترتیب افزونهها را در هر اتصال به صورت تصادفی تغییر میدهد تا هش JA3 در هر بار اتصال متفاوت باشد. در پاسخ به این تغییر، فایروالهای نسل جدید به استاندارد JA4+ مهاجرت کردهاند. الگوریتم JA4 افزونهها را پیش از هش کردن به صورت صعودی مرتب (Sort) میکند و علاوه بر آن، مقادیر ALPN و الگوریتمهای امضای دیجیتال (Signature Algorithms) را نیز در محاسبه اثر انگشت دخیل میسازد.
انگشتنگاری لایه HTTP/2 (فریمهای SETTINGS و AKAMAI Hash)
حتی اگر لایه TLS را به طور کامل شبیهسازی کنید، فایروالها بلافاصله ساختار فریمهای اولیه پروتکل HTTP/2 را بررسی میکنند. هر مرورگر هنگام شروع اتصال HTTP/2 یک فریم SETTINGS و یک فریم WINDOW_UPDATE با مقادیر و ترتیب منحصربهفرد ارسال میکند:
- پترن فریم SETTINGS: ترتیب و مقادیر پارامترهایی نظیر
HEADER_TABLE_SIZE،ENABLE_PUSH،MAX_CONCURRENT_STREAMSوINITIAL_WINDOW_SIZEدر کروم، سافاری و کلاینتهای پایتونی کاملاً متفاوت است. - ترتیب Pseudo-Headers: در پروتکل HTTP/2، شبههدرها همیشه پیش از هدرهای عادی ارسال میشوند. کروم از ترتیب دقیق
:method،:authority،:schemeو:pathاستفاده میکند، در حالی که فایرفاکس ترتیب:method،:path،:authorityو:schemeرا به کار میبرد. - فریم PRIORITY و جریان وزندهی: نحوه مدیریت وابستگی استریمها در لایه باینری HTTP/2 یکی از اصلیترین سیگنالهای تشخیص بات در Akamai است.
پیادهسازی کلاینت ضد تشخیص با curl_cffi و چرخش پویای پروفایل
برای دور زدن کامل بررسیهای TLS و HTTP/2 بدون تحمیل سربار سنگین مرورگرهای Headless، بهترین رویکرد در اکوسیستم پایتون استفاده از curl_cffi است. این کتابخانه یک بایندینگ سطح پایین روی curl-impersonate است که به جای OpenSSL، مستقیماً با BoringSSL کامپایل شده و فریمهای HTTP/2 را دقیقاً مطابق با مرورگر هدف بازتولید میکند.
import asyncio
import random
from typing import Dict, Any, Optional
from curl_cffi.requests import AsyncSession, Response
class StealthHttpClient:
"""
Production-grade HTTP/2 & TLS Impersonation Client
Bypasses JA3/JA4 and Akamai HTTP/2 Fingerprinting
"""
BROWSER_PROFILES = [
{
'impersonate': 'chrome124',
'sec_ch_ua': '"Chromium";v="124", "Google Chrome";v="124", "Not-A.Brand";v="99"',
'user_agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36'
},
{
'impersonate': 'safari17_0',
'sec_ch_ua': None,
'user_agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Safari/605.1.15'
}
]
def __init__(self, proxy_url: Optional[str] = None, timeout: int = 20):
self.proxy_url = proxy_url
self.timeout = timeout
def _build_headers(self, profile: Dict[str, Any], extra_headers: Optional[Dict[str, str]] = None) -> Dict[str, str]:
headers = {
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8',
'Accept-Language': 'en-US,en;q=0.9',
'Accept-Encoding': 'gzip, deflate, br, zstd',
'User-Agent': profile['user_agent'],
'Upgrade-Insecure-Requests': '1',
'Sec-Fetch-Dest': 'document',
'Sec-Fetch-Mode': 'navigate',
'Sec-Fetch-Site': 'none',
'Sec-Fetch-User': '?1'
}
if profile['sec_ch_ua']:
headers['sec-ch-ua'] = profile['sec_ch_ua']
headers['sec-ch-ua-mobile'] = '?0'
headers['sec-ch-ua-platform'] = '"macOS"'
if extra_headers:
headers.update(extra_headers)
return headers
async def fetch(self, url: str, headers: Optional[Dict[str, str]] = None, max_retries: int = 3) -> Response:
for attempt in range(1, max_retries + 1):
profile = random.choice(self.BROWSER_PROFILES)
req_headers = self._build_headers(profile, headers)
async with AsyncSession(impersonate=profile['impersonate'], proxies={'https': self.proxy_url} if self.proxy_url else None) as session:
try:
response = await session.get(url, headers=req_headers, timeout=self.timeout)
if response.status_code in (403, 429, 503):
await asyncio.sleep(1.5 ** attempt + random.uniform(0.2, 0.8))
continue
return response
except Exception as exc:
if attempt == max_retries:
raise RuntimeError(f'Failed after {max_retries} attempts: {exc}') from exc
await asyncio.sleep(1.5 ** attempt)
async def main():
client = StealthHttpClient()
resp = await client.fetch('[https://tls.peet.ws/api/all](https://tls.peet.ws/api/all)')
data = resp.json()
print(f"Negotiated TLS JA3 Hash: {data['tls']['ja3_hash']}")
print(f"Akamai HTTP/2 Fingerprint: {data['http2']['akamai_fingerprint_hash']}")
if __name__ == '__main__':
asyncio.run(main())نکته کلیدی مهندسی: بزرگترین خطای معماری در بایپس فایروالها، ایجاد تناقض بین لایهها (Cross-Layer Mismatch) است. اگر پروفایل TLS شما متعلق به chrome124 باشد اما هدر sec-ch-ua یا User-Agent نسخه دیگری را گزارش دهد، یا پراکسی شما بستههای TCP را با TTL لینوکس ارسال کند در حالی که هدرها ادعای سیستمعامل ویندوز را دارند، فایروال بلافاصله درخواست را با امتیاز ریسک بالا مسدود خواهد کرد.