illutls is a Go HTTP client designed to simulate real browser TLS fingerprints and HTTP headers.
It combines utls (for TLS ClientHello simulation) with fhttp (for HTTP/2 frame-level fingerprint control) to present a complete, authentic browser identity on every connection.
- TLS Fingerprinting: Precisely controls ClientHello parameters using
utlsto perfectly simulate JA3/JA4 signatures. - HTTP/2 Fingerprinting: Controls HTTP/2 settings, frame order, and pseudo-header order at the lowest level using
fhttp, accurately simulating real browser behavior. - Pre-configured Profiles: Ships with real-world browser profiles covering Chrome, Firefox, Edge, and Safari across Windows, macOS, Linux, Android, and iOS.
- Concurrency Safe:
Clientis entirely safe for concurrent use by multiple goroutines. - Extension Shuffling: Enabled by default to randomize the order of TLS extensions per connection. This simulates real browser extension shuffling to produce variable JA3 hashes while maintaining stable JA4 signatures. Can be disabled via
WithShuffleExtensions(false). - ECH Support: Injects compliant GREASE payloads into the ECH extension (65037) to prevent TLS parsing errors on strict WAFs (e.g., Cloudflare) while preserving fingerprint integrity.
- Proxy Support: Easily route your simulated requests through HTTP/SOCKS5 proxies.
go get github.com/Iruko233/illutlsHere's a simple example of how to make a request imitating Google Chrome on Windows:
package main
import (
"fmt"
"io"
"log"
"github.com/Iruko233/illutls"
_ "github.com/Iruko233/illutls/profiles" // Import built-in profiles
)
func main() {
// Create a new client mimicking Chrome 149 on Windows
client, err := illutls.New(illutls.WithProfile("chrome-149-windows-10"))
if err != nil {
log.Fatalf("Failed to create client: %v", err)
}
defer client.Close()
// Make a GET request
resp, err := client.Get("https://tls.browserleaks.com/json")
if err != nil {
log.Fatalf("Request failed: %v", err)
}
defer resp.Body.Close()
body, err := io.ReadAll(resp.Body)
if err != nil {
log.Fatalf("Failed to read body: %v", err)
}
fmt.Println(string(body))
}illutls includes various pre-built profiles. See the full list of supported profiles here.
You can view all available profiles programmatically:
profiles := illutls.ListProfiles()
for _, p := range profiles {
fmt.Println(p)
}By default, if you don't specify a profile using illutls.WithProfile(), it will default to "chrome-149-windows-10".
You can easily route your traffic through a proxy server using WithProxy:
client, err := illutls.New(
illutls.WithProfile("chrome-149-windows-10"),
illutls.WithProxy("http://user:pass@proxy.example.com:8080"),
)If you need to send a POST request or customize headers, use NewRequest combined with client.Do():
req, err := client.NewRequest("POST", "https://example.com/api", bodyReader)
if err != nil {
log.Fatal(err)
}
// Add your custom headers (the client already pre-populates the browser's default headers)
req.Header.Set("Authorization", "Bearer your_token")
resp, err := client.Do(req)illutls 是一个 Go 语言 HTTP 客户端,旨在模拟真实浏览器的 TLS 指纹和 HTTP 请求头。
它将 utls(用于精确实控 TLS ClientHello)和 fhttp(用于底层 HTTP/2 帧级别的通信控制)结合在一起,在每次连接时都能完美模拟出完整且真实的浏览器特征。
- TLS 指纹控制:使用
utls精确实控 ClientHello 参数,从而完美模拟 JA3/JA4 签名。 - HTTP/2 指纹控制:使用
fhttp在底层控制 HTTP/2 Settings、帧顺序和伪头(Pseudo-header)顺序,精准模拟真实浏览器行为。 - 预置配置(Profiles):内置了覆盖 Windows, macOS, Linux, Android 和 iOS 平台的真实浏览器特征(包含 Chrome, Firefox, Edge, Safari)。
- 并发安全:
Client完全支持多 Goroutine 并发安全调用。 - TLS 扩展随机化 (Extension Shuffling):默认开启,在建立连接时随机打乱 TLS 扩展顺序。此功能可模拟真实浏览器的扩展乱序机制,在生成动态 JA3 指纹的同时保持 JA4 哈希稳定。如有特殊需求,可通过
WithShuffleExtensions(false)关闭。 - ECH 扩展兼容:通过为 ECH 扩展 (65037) 注入符合规范的 GREASE 占位数据,修复了因负载为空导致的部分 WAF(如 Cloudflare)握手解析失败问题,同时确保指纹特征不丢失。
- 代理支持:可以轻松将请求通过 HTTP/SOCKS5 代理进行转发。
go get github.com/Iruko233/illutls下面是一个模拟 Windows 端 Google Chrome 发送请求的简单示例:
package main
import (
"fmt"
"io"
"log"
"github.com/Iruko233/illutls"
_ "github.com/Iruko233/illutls/profiles" // 导入内置的浏览器配置
)
func main() {
// 创建一个模拟 Windows Chrome 149 的客户端
client, err := illutls.New(illutls.WithProfile("chrome-149-windows-10"))
if err != nil {
log.Fatalf("创建客户端失败: %v", err)
}
defer client.Close()
// 发送 GET 请求
resp, err := client.Get("https://tls.browserleaks.com/json")
if err != nil {
log.Fatalf("请求失败: %v", err)
}
defer resp.Body.Close()
body, err := io.ReadAll(resp.Body)
if err != nil {
log.Fatalf("读取响应失败: %v", err)
}
fmt.Println(string(body))
}illutls 包含了多种预构建的配置。点击此处查看所有支持的浏览器配置列表。
你可以通过代码查看所有可用的配置名称:
profiles := illutls.ListProfiles()
for _, p := range profiles {
fmt.Println(p)
}默认情况下,如果你在初始化时不通过 illutls.WithProfile() 指定配置,它将默认使用 "chrome-149-windows-10"。
你可以使用 WithProxy 选项轻松配置代理服务器:
client, err := illutls.New(
illutls.WithProfile("chrome-149-windows-10"),
illutls.WithProxy("http://user:pass@proxy.example.com:8080"),
)如果你需要发送 POST 请求或自定义请求头,请使用 NewRequest 并配合 client.Do() 使用:
req, err := client.NewRequest("POST", "https://example.com/api", bodyReader)
if err != nil {
log.Fatal(err)
}
// 添加你自己的请求头(客户端已经提前填充好了浏览器默认的请求头)
req.Header.Set("Authorization", "Bearer your_token")
resp, err := client.Do(req)MIT License