he4rt/reqxide

GitHub: he4rt/reqxide

一款基于 PHP 的 TLS/HTTP 指纹识别与浏览器仿真库,解决标准 HTTP 客户端指纹易被反机器人系统识别的问题。

Stars: 35 | Forks: 0

# Reqxide PHP TLS/HTTP 指纹识别库,用于浏览器仿真。 [![测试](https://static.pigsec.cn/wp-content/uploads/repos/2026/04/d321d74d47181619.svg)](https://github.com/he4rt/reqxide/actions) [![最新版本](https://img.shields.io/packagist/v/he4rt/reqxide)](https://packagist.org/packages/he4rt/reqxide) [![许可证](https://img.shields.io/packagist/l/he4rt/reqxide)](https://packagist.org/packages/he4rt/reqxide) Reqxide 为 PHP 带来 TLS 和 HTTP/2 指纹识别功能。它模拟真实浏览器的指纹(Chrome、Firefox、Safari、Edge、OkHttp),使你的 HTTP 请求看起来与真实浏览器流量完全一致。构建在 `curl_impersonate` 之上,提供与 PSR-18 兼容的客户端,并实现透明的浏览器仿真。 移植自 Rust 的 [wreq](https://github.com/nickel-org/wreq)。 ## 为什么? 像 Cloudflare、Akamai 和 DataDome 这样的反机器人系统会通过 TLS 握手和 HTTP/2 帧进行指纹识别,以区分机器人和真实浏览器。标准的 PHP HTTP 客户端(Guzzle、Symfony HttpClient)会产生类似机器的指纹,会被立即拦截。 Reqxide 通过控制以下方面来解决这个问题: - **TLS ClientHello** —— 密码套件、椭圆曲线、签名算法、扩展、ALPN、GREASE、ECH - **HTTP/2 SETTINGS** —— 帧顺序、窗口大小、伪头部顺序、流优先级 - **头部顺序和大小写** —— 浏览器以特定顺序和特定大小写发送头部 结果:你的请求会产生与真实浏览器相同的 JA3/JA4 指纹。 ## 安装 ``` composer require he4rt/reqxide ``` ## 快速开始 ``` use Reqxide\Client; use Reqxide\Emulation\Browser; $client = Client::builder() ->emulation(Browser::Chrome131) ->build(); $response = $client->get('https://example.com')->send(); echo $response->getStatusCode(); // 200 echo (string) $response->getBody(); ``` ## 用法 ### 浏览器仿真 选择一个浏览器配置文件。每个配置文件都捆绑了真实浏览器使用的确切 TLS 配置、HTTP/2 设置、默认头部和头部排序。 ``` use Reqxide\Client; use Reqxide\Emulation\Browser; // Chrome (latest) $client = Client::builder()->emulation(Browser::Chrome131)->build(); // Firefox $client = Client::builder()->emulation(Browser::Firefox136)->build(); // Safari (macOS, iOS, iPad) $client = Client::builder()->emulation(Browser::Safari18)->build(); $client = Client::builder()->emulation(Browser::SafariIOS18)->build(); // Edge (Chromium-based, different sec-ch-ua) $client = Client::builder()->emulation(Browser::Edge131)->build(); // OkHttp (Android HTTP client) $client = Client::builder()->emulation(Browser::OkHttp5)->build(); ``` ### 发起请求 Reqxide 实现了 PSR-18(`ClientInterface`)并提供便捷方法: ``` // Convenience API $response = $client->get('https://api.example.com/users')->send(); $response = $client->post('https://api.example.com/users') ->json(['name' => 'Daniel', 'email' => 'daniel@he4rt.com']) ->send(); // With headers and auth $response = $client->get('https://api.example.com/me') ->bearerToken('your-token') ->header('X-Custom', 'value') ->send(); // Form data $response = $client->post('https://example.com/login') ->form(['username' => 'admin', 'password' => 'secret']) ->send(); // Query parameters $response = $client->get('https://api.example.com/search') ->query(['q' => 'reqxide', 'page' => '1']) ->send(); // PSR-18 standard (drop-in for any PSR-18 consumer) $response = $client->sendRequest($psrRequest); ``` ### 代理支持 支持 HTTP、HTTPS、SOCKS4 和 SOCKS5,并可选认证: ``` use Reqxide\Proxy\Proxy; $client = Client::builder() ->emulation(Browser::Chrome131) ->proxy(Proxy::http('45.38.89.88:6023')) ->build(); // SOCKS5 $client = Client::builder() ->emulation(Browser::Chrome131) ->proxy(Proxy::socks5('127.0.0.1:1080')) ->build(); // With authentication $proxy = new Proxy( scheme: ProxyScheme::Http, host: 'proxy.example.com', port: 8080, username: 'user', password: 'pass', ); ``` ### Cookie 持久化 ``` use Reqxide\Cookie\CookieJar; // Automatic cookie jar $client = Client::builder() ->emulation(Browser::Chrome131) ->cookieStore(true) ->build(); // Shared cookie jar across clients $jar = new CookieJar(); $client = Client::builder() ->emulation(Browser::Chrome131) ->cookieStore($jar) ->build(); // Cookies persist across requests automatically $client->get('https://example.com/login')->form([...])->send(); $client->get('https://example.com/dashboard')->send(); // sends session cookie ``` ### 重定向与重试 ``` use Reqxide\Redirect\RedirectPolicy; use Reqxide\Retry\RetryPolicy; $client = Client::builder() ->emulation(Browser::Chrome131) ->redirect(RedirectPolicy::limited(10)) // follow up to 10 redirects ->retry(RetryPolicy::default()) // retry 5xx, max 2 attempts, 20% budget ->build(); // Disable redirects $client = Client::builder() ->emulation(Browser::Chrome131) ->redirect(RedirectPolicy::none()) ->build(); // Custom retry logic $client = Client::builder() ->emulation(Browser::Chrome131) ->retry(RetryPolicy::custom( classifier: fn($req, $res, $err) => $res?->getStatusCode() === 429, maxRetries: 5, baseDelayMs: 1000, )) ->build(); ``` ### 客户端配置 ``` $client = Client::builder() ->emulation(Browser::Chrome131) ->proxy(Proxy::socks5('127.0.0.1:1080')) ->timeout(30) // seconds ->connectTimeout(10) // seconds ->cookieStore(true) // enable cookie jar ->redirect(RedirectPolicy::limited(10)) // follow redirects ->retry(RetryPolicy::default()) // retry on failure ->verify(false) // disable SSL verification ->defaultHeaders(['X-App' => 'myapp']) // extra headers on every request ->build(); ``` ## 架构 ``` User Code | v +---------------------------------+ | PSR-18 Client (Reqxide\Client) | | sendRequest(RequestInterface) | +---------------------------------+ | v +---------------------------------+ | Middleware Pipeline | | Cookie -> Redirect -> Retry -> | | Compression -> Transport | +---------------------------------+ | +--------+---------+ v v v FFI ext/curl Process (full) (partial) (binary) | | | v v v libcurl-impersonate ``` **三种传输后端:** | 传输方式 | 指纹识别控制 | 依赖 | |-----------|-------------------|----------| | `FfiTransport` | 完整(TLS + HTTP/2 + 头部) | PHP FFI + libcurl-impersonate | | `CurlTransport` | 部分(TLS 密码、曲线、ALPN) | ext-curl | | `ProcessTransport` | 完整(通过二进制文件) | curl-impersonate 二进制文件 | `TransportFactory::create()` 会自动检测最佳可用传输方式。 ## 框架集成 ### Guzzle ``` use Reqxide\Adapter\Guzzle\GuzzleHandlerAdapter; use Reqxide\Emulation\Browser; $handler = new GuzzleHandlerAdapter(Browser::Chrome131); $guzzle = new \GuzzleHttp\Client([ 'handler' => \GuzzleHttp\HandlerStack::create($handler), ]); $response = $guzzle->get('https://example.com'); ``` ### Laravel ``` // In a ServiceProvider use Reqxide\Client; use Reqxide\Emulation\Browser; $this->app->singleton(Client::class, fn () => Client::builder()->emulation(Browser::Chrome131)->build() ); // Usage $client = app(Client::class); $response = $client->get('https://api.example.com/data')->send(); ``` ### Symfony ``` use Reqxide\Adapter\Symfony\SymfonyClientAdapter; use Reqxide\Emulation\Browser; $client = new SymfonyClientAdapter(Browser::Chrome131); $response = $client->request('GET', 'https://example.com', [ 'headers' => ['Accept' => 'application/json'], ]); ``` ## 支持的浏览器 | 浏览器 | 版本 | 关键差异 | |---------|----------|-----------------| | Chrome | 128、129、130、131 | 130+ 支持 X25519MLKEM768(后量子),启用 GREASE | | Firefox | 135、136 | 不支持 GREASE、FFDHE 曲线、Sec-Fetch-* 头部、不同的伪头部顺序 | | Safari | 18(macOS、iPad、iOS) | 不支持 GREASE、无 ECH、最小化头部、不同的 HTTP/2 窗口大小 | | Edge | 131 | 基于 Chromium + Edge 特定的 User-Agent 和 sec-ch-ua | | OkHttp | 4、5 | 仅 HTTP/1.1、无浏览器头部、Android 客户端指纹 | ### 指纹识别精度 每个配置文件控制完整的 TLS/HTTP/2 指纹: ``` Chrome 131: JA3: 9e2da15d3e1b6931c6fbaa3f9ac9cd89 JA4: t13d913h2_f91f431d341e_882d495ac381 HTTP: h2 | Ciphers: 9 Firefox 136: JA3: bdc242f0548bc1fcc45d12edc713b8e1 JA4: t13d1513h2_8daaf6152771_882d495ac381 HTTP: h2 | Ciphers: 15 ``` ## 工作原理 当你选择 `Browser::Chrome131` 时,reqxide 会配置: **TLS 层:** - 密码套件按 Chrome 的确切顺序(9 个密码) - 椭圆曲线:X25519MLKEM768、X25519、P-256、P-384 - 签名算法:8 个算法,按 Chrome 的顺序 - 密钥共享:X25519MLKEM768 + X25519 - 扩展:GREASE、ECH GREASE、排列后的扩展、OCSP 签名、时间戳 **HTTP/2 层:** - SETTINGS 帧:头部表 65536,禁用推送,最大流 1000,窗口 6MB,最大帧 16384,最大头部列表 262144 - 伪头部顺序:`:method`、`:authority`、`:scheme`、`:path` - 连接窗口:15663105 字节 **头部:** - 默认浏览器头部(sec-ch-ua、User-Agent、Accept、Accept-Encoding、Accept-Language) - 头部顺序与 Chrome 发送顺序完全匹配 - 大小写保留(sec-ch-ua,而非 Sec-Ch-Ua) ## 测试 ``` # 完整质量套件 (lint + phpstan + pest + rector) composer test # 单独检查 composer test:lint # Laravel Pint formatting composer test:types # PHPStan level max composer test:unit # Pest with 100% coverage composer test:type-coverage # 100% type coverage composer test:refactor # Rector dry-run # 运行特定测试 ./vendor/bin/pest tests/Unit/Tls/TlsOptionsTest.php ./vendor/bin/pest --filter="Chrome 131" # 集成测试(需要网络) ./vendor/bin/pest --group=integration ``` ## 项目结构 ``` src/ Client.php # PSR-18 ClientInterface ClientBuilder.php # Fluent builder RequestBuilder.php # Per-request builder (get, post, json, form...) Contract/ # Interfaces (Transport, CookieStore, Profile, Redirect, Retry) Emulation/ # Browser enum, Profile, Catalog (Chrome, Firefox, Safari, Edge, OkHttp) Tls/ # TLS options, enums (ciphers, curves, sigalgs, versions) Http2/ # HTTP/2 options (settings, pseudo-headers, priorities) Http1/ # HTTP/1 options (header ordering) Transport/ # CurlTransport, FfiTransport, ProcessTransport, TransportFactory Middleware/ # Pipeline, Cookie, Redirect, Retry, Compression Cookie/ # CookieJar (RFC 6265), Cookie value object Proxy/ # Proxy value object, ProxyScheme enum Redirect/ # RedirectPolicy (limited, none, custom) Retry/ # RetryPolicy, RetryBudget (token bucket) Adapter/ # Guzzle, Laravel, Symfony integrations Exception/ # PSR-18 compliant exception hierarchy ``` ## 致谢 - 移植自 [wreq](https://github.com/nickel-org/wreq)(Rust) - 基于 [curl-impersonate](https://github.com/lwthiker/curl-impersonate) - 由 [He4rt 开发者](https://github.com/he4rt) 构建 ## 许可证 Reqxide 是开源软件,采用 **[MIT 许可证](https://opensource.org/licenses/MIT)** 授权。
标签:BeEF, Browser Profile, Chrome, ClientHello, composer, cURL, Edge, Emulation, ffuf, Firefox, HTTP/2, HTTP指纹, JA3, JA4, OkHttp, OpenVAS, PHP, PSR-18, Radare2, Safari, TLS指纹, TLS握手, 反反爬, 反机器人, 多架构支持, 库, 应急响应, 开源, 浏览器仿真, 爬虫, 网络请求, 网络调试, 自动化, 请求伪装