Akamai Bot Manager е едно от най-често срещаните анти-ботови решения на пазара.Той се използва от много високопоставени уебсайтове, вариращи от сайтове за електронна търговия до туристически сайтове, и в зависимост от конфигурацията му може да бъде трудно да се заобиколи. Въз основа на моя опит, типичният модел, с който се сблъсквам, когато сайт активира защита на Akamai Bot Manager, е, че скреперът (обикновено един Scrapy в моята купчина) виси и изтича от първата заявка. Но какво е Akamai Bot Manager и как мога да видя дали сайтът го използва? Преглед на Akamai Bot Manager Откриването на ботове на Akamai, подобно на всеки друг съвременен софтуер за защита от ботове, работи на няколко нива. е един от първите: Akamai анализира TLS ръкостискане и данни за връзка (JA3 TLS пръстови отпечатъци, шифровани пакети, версия на TLS и т.н.), за да види дали те съответстват на истински браузър или известен инструмент за автоматизация. всеки браузър (Chrome, Firefox, Safari и т.н.) има характерен TLS пръстови отпечатъци, и ако вашият клиент TLS Client Hello не съответства на всеки обикновен браузър, Akamai знае нещо е рисковано. Network fingerprinting Той също така проверява - Реалните браузъри почти винаги използват HTTP/2+ тези дни и изпращат HTTP заглавия в определен ред и формат.Ако клиентът все още използва HTTP/1.1 или има заглавия в ред, различен от браузъра, това е червено знаме. Огледалото на истинския браузър е от решаващо значение. HTTP/2 usage and header order and their order Друг слой е Akamai проверява дали клиентският IP адрес е от жилищна мрежа, мобилна мрежа или център за данни. Жилищните и мобилните IP адреси (видът на реалните потребители) имат високи резултати по отношение на доверието, докато известните IP диапазони на центъра за данни са автоматично подозрителни. - винаги да изглежда, че идват от различни реални потребителски места, а не от облачна сървърна ферма. IP reputation and analysis residential proxies накрая, Датчикът на JavaScript на уеб страницата събира множество точки от данни за околната среда и взаимодействията на клиента (като например времето, движенията на мишката или тяхното отсъствие, необичайни свойства в обекта на браузъра и т.н.). моделите на AI на Akamai събират тези данни, за да присвоят вероятност за бот на всяка сесия.Този аспект е най-трудният за заобикаляне и често изисква стартиране на браузър без глава или възпроизвеждане на логиката на сензора. (Това е извън нашия обхват тук - нашият фокус ще бъде да преминем проверките на нивото на мрежата, което е най-често срещаният случай за уебсайтове за електронна търговия, според моя опит.) АКАМАЙ заетост Поведенчески анализ using client-side scripts and AI models АКАМАЙ заетост Поведенчески анализ Поведенчески анализ Използване на скриптове от страна на клиента и AI модели Но как можем да открием, че сайтът използва Akamai Bot Manager? Освен от Ако забележите, че и бисквитки, използвани на уебсайт, това е най-ясният знак, че той използва Akamai, за да се защити. Обичайното разширение на браузъра Wappalyzer АБК бмс - бмс Обичайното разширение на браузъра Wappalyzer АБК АБК бмс - бмс бмс - бмс Като се имат предвид тези защити, много потребители на Scrapy са се обърнали към изтегляне манипулатор да заобиколят Akamai. Този плъгин интегрира библиотека, за да се преструват на реални браузърни мрежови подписи. scrapy-impersonate curl_cffi На практика Scrapy Impersonate прави исканията на вашия Scrapy spider "изглеждат" като Chrome или Firefox: той предлага TLS пръстови отпечатъци (JA3), които съответстват на тези браузъри, използва HTTP/2, и дори регулира заглавията на ниско ниво HTTP/2 рамки, за да имитира моделите на браузъра. Ограничения на Scrapy Impersonate Докато Scrapy Impersonate е мощен инструмент, той идва с определени ограничения: Scrapy Impersonate is designed as a Scrapy download handler, which means it only works within Scrapy’s asynchronous framework. If your project doesn’t use Scrapy or you want to switch to a different framework (like a simple script with / or an asyncio pipeline), you can’t directly carry over its capabilities. Migrating away from Scrapy often means a of your HTTP logic, and you’d lose the built-in TLS spoofing unless you implement a new solution from scratch. Locked into Scrapy: requests httpx complete rewrite Using Scrapy Impersonate alongside proxy rotation can be tricky. Under the hood, it replaces Scrapy’s default downloader with one based on , which doesn’t seamlessly integrate with Scrapy’s proxy middleware. Early adopters discovered that HTTPS proxy support was broken because the proxy handling code was bypassed. Although fixes and workarounds (like disabling Scrapy’s built-in proxy handling and configuring directly) exist, it’s harder to rotate proxies or handle proxy authentication with this setup. Robust error handling for proxy failures (e.g., detecting a dead proxy and retrying) is not as straightforward as with Scrapy’s standard downloader, because errors bubble up from the layer and may not trigger Scrapy’s usual retry logic. Proxy Rotation Challenges: curl_cffi curl_cffi curl Scrapy Impersonate currently supports a finite list of browser fingerprints (Chrome, Edge, Safari, etc., up to certain versions). This list can lag behind the latest browser releases. You might be stuck impersonating an older browser version, which could be a problem if a target site specifically requires the nuances of a newer TLS handshake (some advanced WAFs actually check minor details that change between Chrome versions). Maintenance and Flexibility: Perhaps most importantly, even with proper TLS and HTTP/2 impersonation, . For websites that have implemented a higher level of protection, checking also the browser fingerprint, any browserless configuration, including Scrapy Impersonate, isn’t sufficient for Akamai or similar top-tier bot defenses. You might get past the TLS handshake, but fail on other signals (like the absence of the expected sensor data or subtle discrepancies in headers/cookies). In other words, it’s a piece of the puzzle, not a complete solution. Not a Silver Bullet: Akamai Bot Manager can still detect and block you Решението, което ще видим днес, помага за решаването на първите две точки: ще се свържем заедно , за оптимален TLS пръстов отпечатък и ротационен жилищен прокси, за да ротираме нашите IP адреси и да имаме по-високи оценки за репутация. 3 Прокси 3 Прокси Разбиране на TLS пръстови отпечатъци и JA3 Преди да се потопите в решението, е важно да разберете какво точно лъжем. Този пръстов отпечатък е комбинация от версията на протокола TLS и набор от опции, които клиентът казва, че поддържа – помислете за него като за „диалекта“ на клиента да говори TLS. Ключовите компоненти включват: TLS fingerprint e.g. TLS 1.2 vs TLS 1.3. Modern browsers will offer 1.3 (while still allowing 1.2 for compatibility). Older clients or some libraries might only do 1.2. Supported TLS Version: the list of cryptographic algorithms the client can use, in preferred order. Browsers tend to have long lists including ciphers like AES-GCM, ChaCha20, etc., plus some GREASE (randomized) values to prevent fingerprinting. Cipher Suites: extra features in TLS, like Server Name Indication (SNI), supported groups (elliptic curves), ALPN (which is used for HTTP/2 negotiation), etc. Both the presence of certain extensions and their order matter. Extensions: Концепцията за е стандартизиран начин за записване на тези детайли за TLS Client Hello. JA3, кръстен на инициалите на създателите си, съставя низ от пръстови отпечатъци, като съединява горните полета в определен ред: JA3 fingerprinting JA3_string = TLSVersion,CipherSuiteIDs,ExtensionIDs,EllipticCurveIDs,EllipticCurveFormatIDs Всеки списък (цифри, разширения и т.н.) е придружен от и секциите на Например, браузърът на Chrome може да генерира серия JA3 като: - , 771,4866-4867-4865-....-47-255,0-11-10-16-23-...-21,29-23-30-25-24,0-1-2 Това представлява TLS 1.2 (771 е 0x0303), специфичен набор от шифровани пакети, разширения, поддържани криви и формати на криви (номерата са стандартизирани идентификатори). Инструментите за сигурност често записват или сравняват хаша MD5 (тъй като е по-лесно да се справят с него, отколкото с дълга серия от числа). MD5 hashed Защо това е важно за ботовата детекция? Chrome версия X на Windows ще Представете същия JA3 пръстови отпечатъци до списъка за подреждане. Firefox ще има свой собствен отделен JA3. browser TLS stacks are fairly uniform винаги Библиотеката с искания на Python (която използва OpenSSL под капака) има JA3, който е напълно различен от всеки основен браузър, така че е лесно откриваем. Anti-bot услуги като Akamai поддържат бази данни от JA3 хаши: ако вашият JA3 не е в списъка "известни добри" (обикновени браузъри) или ако е в известен списък за автоматизация, ще получите знамена. Накратко, за да преминете проверките за пръстови отпечатъци на Akamai TLS, . we need our client’s JA3 to match a popular browser Това обикновено означава имитиране на най-новия Chrome или Firefox пръстови отпечатъци (тъй като те са най-честите легитимни потребители в мрежата). Не е достатъчно просто да промените последователността User-Agent – трябва да промените ръкохватката на ниско ниво TLS. Scrapy Impersonate прави това вътрешно чрез (което само по себе си използва специална конструкция от къдрици и TLS библиотеки, за да имитира браузъри). curl_cffi TLS Impersonation Proxy + Резидентна прокси верига Нашето решение е да за да направим нашия скрепер практически неразличим от истинския потребител на браузъра: chain two proxies JA3Proxy is an open-source tool that acts as an HTTP(S) proxy that replays traffic with a chosen TLS fingerprint. In other words, you run JA3Proxy locally, configure it to imitate a specific browser’s TLS handshake, and then direct your scraper traffic through it. JA3Proxy will terminate your TLS connection and initiate a new TLS handshake to the target site using the impersonated fingerprint. From the target site’s perspective, it looks like, say, a Chrome browser connecting. The beauty of this approach is that – you can use Python , , cURL, or anything, by simply pointing it at JA3Proxy. You are no longer locked into Scrapy or any particular library to get browser-like TLS; the proxy takes care of it. JA3Proxy for TLS Impersonation: it’s client-agnostic requests httpx Under the hood, JA3Proxy uses (an advanced TLS library in Go) to customize the Client Hello. It supports a variety of client profiles (Chrome, Firefox, Safari, etc., across different versions). You can, for example, configure it to mimic the latest browsers available in the library. For our needs, we’d choose the latest available Chrome fingerprint, Chrome 133. As for Scrapy-Impersonate, the integration of the latest browsers in the library can take some time, but until this gets regularly updated, it’s not an issue. uTLS One thing to note: JA3Proxy focuses on TLS fingerprints (the JA3 part). It doesn’t inherently modify HTTP headers (other than those that relate to TLS, like ALPN for HTTP/2) or handle higher-level browser behaviors. It gets us past the network fingerprinting, which is the hardest to change, but we must still ensure our HTTP headers and usage patterns are correct. Luckily, we can manually set headers in our HTTP client to mimic a browser (User-Agent, etc.), and HTTP/2 can be achieved as long as the TLS negotiation allows it (Chrome’s Client Hello will advertise ALPN support for h2, so if the site supports it, JA3Proxy will negotiate HTTP/2). The second part of the chain is an upstream . This will take care of the IP reputation and distribution. Residential Proxy for IP Rotation: residential proxy The combined effect is powerful: to Akamai, your scraper now looks like Chrome 133 running on a residential IP. The TLS handshake matches Chrome’s JA3, the HTTP/2 and headers can be adjusted to match Chrome, and the source IP is a regular household. This addresses the major fingerprinting vectors at the network level. It doesn’t solve Akamai’s JavaScript-based challenges by itself, but this should be enough to bypass most of the websites you’ll encounter. Инсталиране на JA3Proxy Нека да настроим JA3Proxy и да го свържем с жилищен прокси. Инсталиране на JA3Proxy JA3Proxy е написан в Go. Имате две лесни опции: компилиране от източник или използване на контейнер Docker. За да създадете от източник, ще трябва Go инсталиран. git clone https://github.com/LyleMi/ja3proxy.git cd ja3proxy make Това трябва да доведе до може да се изпълнява в папката. (Алтернативно, можете да ръчно, тъй като проектът е Go-базиран.) ja3proxy go build Ако предпочитате Docker, има предварително изградено изображение в GitHub Container Registry. docker pull ghcr.io/lylemi/ja3proxy:latest ще изтеглите последното изображение. След това можете да го изпълните с (Ние ще покажем командата за изпълнение в един миг.) Docker е удобен, защото пакетира всичко, без да се нуждае от локална среда Go. docker run В моя личен опит инсталацията беше малко кошмар. Не можах да направя изображението на Docker да работи, тъй като последователно получавах грешки, когато се опитвах да се свържа с него, тъй като не беше разпознат никакъв браузър. Тогава реших да изградя ръчно на моя Mac и се натъкнах на същите грешки. Въпреки това, след часове дебютиране, открих, че трябва да актуализирам някои зависимости, особено uTLS; имаше конфликти в версиите на библиотеките и всичко това причиняваше проблеми. Получаване или създаване на TLS сертификати JA3Proxy може да действа като HTTPS прокси, което означава, че прехваща TLS и представя свой собствен сертификат на вашия клиент. По подразбиране той търси и Ако не предоставите сертификат, може да го изпълните в просто текст (като обикновен HTTP прокси) и просто да пренебрегнете проверката на сертификата във вашия клиент (не се препоръчва за производство, но е приемливо за тестване). cert.pem key.pem Най-добрата практика е да генерирате самоподписан корен сертификат и ключ и да конфигурирате вашия скрепер, за да се доверите на този сертификат, така че да можете да прехващате трафика без предупреждения за сигурност. openssl req -x509 -newkey rsa:2048 -sha256 -days 365 -nodes -keyout key.pem -out cert.pem -subj "/CN=JA3Proxy" Това създава а / (За производствена употреба може дори да използвате законен вътрешен CA, ако имате тази настройка, но за повечето цели за изтриване, самоподписан е добре, стига вашият клиент да знае как да му се довери.) cert.pem key.pem Стартиране на JA3Proxy с пръстов отпечатък на Chrome Ако използвате двоичен, изпълнете команда като: ./ja3proxy -port 8080 -client Chrome -version 131 -cert cert.pem -key key.pem -upstream YOURPROXYIP:PORT Нека разчупим тази команда: - порт 8080 му казва да слуша на порт 8080 (можете да изберете друг порт, ако е необходимо). -client Chrome -version 131 избира профила за пръстови отпечатъци. В този пример той използва вградения профил за Chrome 131. Можете да ги замените с профила, съответстващ на браузъра/версията, която искате – например, ако Chrome 130 се поддържа в най-новата версия, може да използвате -client Chrome -version 130. (Можете да намерите списъка с наличните пръстови отпечатъци, като проверите документацията на JA3Proxy или библиотеката uTLS, която използва. -cert и -key посочете файловете с TLS сертификати, които генерирахме в стъпка 2. -upstream 123.45.67.89:1080 е адресът на проксито на upstream. Това трябва да бъде заменено с вашия жилищен прокси краен пункт. Важно: JA3Proxy очаква това да бъде SOCKS5 прокси адрес__github.com__. Ако вашият доставчик ви даде нещо като proxy.provider.com:8000 с потребителско име/парола, можете да опитате формата на потребителско име:password@proxy.provider.com:8000. (JA3Proxy ще анализира струната и трябва да се справя с автентичността за SOCKS5 ако е дадена във формуляра user:pass@host:port. Ако това не работи, може да конфигурирате вашия жилищен прокси, за да бъде разрешен IP или да използвате функция IP whitelist, за да избе Ако използвате Docker, еквивалентът ще бъде: docker run -p 8080:8080 \ -v $(pwd)/cert.pem:/app/cert.pem -v $(pwd)/key.pem:/app/key.pem \ ghcr.io/lylemi/ja3proxy:latest \ -client Chrome -version 133 -cert /app/cert.pem -key /app/key.pem \ -upstream YOURPROXYIP:PORT Ние монтираме cert и ключ в контейнера и излагаме порт 8080. Настройка на командата, за да включите действителните си прокси удостоверения / хост. (или какъвто и да е хост / порт, който сте посочили). localhost:8080 Реален случай на използване - MrPorter.com MrPorter.com е моден уебсайт за електронна търговия, който, заедно с много други в индустрията, се защитава с Akamai Bot Manager. Използвайки проста Python заявка, както е посочено в файла По време на прегледа се натъкнах на грешка, както се очакваше. simple_request.py import requests URL = "https://www.mrporter.com/en-gb/mens/product/loewe/clothing/casual-shorts/plus-paula-s-ibiza-wide-leg-printed-cotton-blend-terry-jacquard-shorts/46376663162864673" headers = { "accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8", "accept-language": "en-US,en;q=0.5", "priority": "u=0, i", "sec-ch-ua": "\"Brave\";v=\"135\", \"Not-A.Brand\";v=\"8\", \"Chromium\";v=\"135\"", "sec-ch-ua-mobile": "?0", "sec-ch-ua-platform": "\"macOS\"", "sec-fetch-dest": "document", "sec-fetch-mode": "navigate", "sec-fetch-site": "none", "sec-fetch-user": "?1", "sec-gpc": "1", "service-worker-navigation-preload": "true", "upgrade-insecure-requests": "1", "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/135.0.0.0 Safari/537.36" } def main(): try: response = requests.get(URL, headers=headers, timeout=10) response.raise_for_status() print(response.text) except requests.RequestException as e: print(f"Error fetching the page: {e}") if __name__ == "__main__": main() Резултатът : Error fetching the page: HTTPSConnectionPool(host='www.mrporter.com', port=443): Read timed out. (read timeout=10) Чрез използване , Въпреки това, не можах да намеря база данни, която показва, че Python исканията обикновено използват този пръстов отпечатък. със сигурност, това е различно от пръстовия отпечатък, който имам с Brave Browser, със същите заглавия и User Agent. Scrapfly TLS пръстови отпечатъци Можем да видим резултатите Scrapfly TLS пръстови отпечатъци Можем да видим резултатите Редът на Cipher Suites е различен и следователно пръстовият отпечатък също ще бъде различен. Сега нека стартираме докера JA3Proxy, без да прикачваме жилищен прокси, и да видим какво се случва. docker run -p 8080:8080 \ -v $(pwd)/cert.pem:/app/cert.pem -v $(pwd)/key.pem:/app/key.pem \ ghcr.io/lylemi/ja3proxy:latest \ -client Chrome -version 131 -cert /app/cert.pem -key /app/key.pem Получихме посланието HTTP Proxy Server listen at :8080, with tls fingerprint 131 Chrome Така че можем да използваме localhost:8080 като прокси в нашия Python заявка скрипт. Друга причина за грешките в инсталацията ми беше, че се опитах да използвам Python Requests, за да се свържа с JA3Proxy. След като копаех известно време, открих, че проблемът е, че библиотеката за заявки не поддържа HTTP/2, докато JA3Proxy го прави при използване на модерна версия на Chrome. За моите тестове трябва да използвам HTTPX, както е показано в файла . request_with_proxies.py В този случай, ако отново се обадя на Scrapfly TLS API, първата част от низа JA3 (редбата Cipher) . е идентичен с този на моя браузър е идентичен с този на моя браузър Като последен тест, ако използваме този скрипт, за да поискаме страницата MrPorter, можем да го изтеглим без никакви проблеми. Създаване на резидентен прокси Сега, когато сме решили измамата на пръстовия отпечатък на TLS, просто трябва да завъртим IP адреса, който целевият уебсайт ще види. JA3Proxy има опция, която ни помага в това, наречено нагоре. След като стартирате командата JA3Proxy, ./ja3proxy -addr 127.0.0.1 -client Chrome -version 131 -cert cert.pem -key key.pem -upstream socks5h://USER:PASS@PROVIDER:PORT -debug Ние можем да тунелираме нашите искания, като използваме предпочитания от нас прокси доставчик. Моля, имайте предвид, че трябва да се свържете чрез SOCKS5, така че се уверете, че вашият доставчик поддържа тази функция. Чрез проверка на IP след това мога да видя, че моите жилищни ротационни IP-та са на място и мога да продължа да изтеглям страниците на MRPorter без проблем. pierluigivinciguerra@Mac 85.AKAMAI-JA3PROXY % python3.10 request_with_proxies.py 200 {"ip":"5.49.222.37"} pierluigivinciguerra@Mac 85.AKAMAI-JA3PROXY % python3.10 request_with_proxies.py 200 {"ip":"197.244.237.29"} pierluigivinciguerra@Mac 85.AKAMAI-JA3PROXY % python3.10 request_with_proxies.py 200 {"ip":"41.193.144.67"} pierluigivinciguerra@Mac 85.AKAMAI-JA3PROXY % python3.10 request_with_proxies.py 200 {"ip":"102.217.240.216"} pierluigivinciguerra@Mac 85.AKAMAI-JA3PROXY % python3.10 request_with_proxies.py Заключения В този пост видяхме как да заобиколим Akamai Bot Manager на уебсайта на MrPorter. нивото на защита на уебсайта е средно, така че няма сложно предизвикателство за отпечатък на браузъра, но, според моя опит, това е най-честият случай на употреба, когато се сблъскваме с Akamai по пътя ни. Избирам да следвам подхода JA3Proxy, за да го заобиколя, така че това решение да може да се използва в различни рамки.Ако използвате Scrapy, винаги можете да разчитате на Scrapy Impersonate, въпреки ограниченията му, или можете да опитате да зададете шифрите в правилния ред ръчно. Статията е част от поредицата "Лабораторията" на Пиерлуиджи Винчигуера. Проверете страницата му Substack за повече знания за уеб сканиране. Статията е част от поредицата "Лабораторията" на Пиерлуиджи Винчигуера. Проверете страницата му Substack за повече знания за уеб сканиране. „Лаборатория“