HN 日本語サマリー

← 一覧へ戻る
セキュリティ

Show HN: TLSフィンガープリントを制御できるローカルMitMプロキシ

Show HN: A local MitM proxy to control TLS fingerprints (github.com)

9 pointsby ytkoka1 コメント

要約

impersonate-proxyは、YAML設定ファイルからTLSフィンガープリント(JA3/JA4)、HTTP/2フィンガープリント、HTTPヘッダー順序、User-Agent、ソースIPヘッダーを制御できるローカルのMITMプロキシです。Chrome拡張機能も含まれており、プロキシを再起動せずにブラウザツールバーから直接プロキシの切り替えやフィンガープリントプロファイルの変更が可能です。WAFボット検出システムの正規のセキュリティテストを目的としています。

全文翻訳

impersonate-proxy TLSフィンガープリントを制御できるローカルMITMプロキシ 単一のYAML設定ファイルから、TLSフィンガープリント(JA3/JA4)、HTTP/2フィンガープリント、HTTPヘッダー順序、User-Agent、ソースIPヘッダーを制御できるローカルMITMプロキシです。Chrome拡張機能も含まれており、プロキシを再起動せずにブラウザツールバーから直接プロキシの切り替えやフィンガープリントプロファイルの変更が可能です。WAFボット検出システムの正規のセキュリティテストを目的としています。 curl、ブラウザ、またはPlaywrightをプロキシ経由でルーティングして、さまざまなフィンガープリントの組み合わせがどのように分類されるかを観察します。 仕組み curl / browser / Playwright │ HTTP CONNECT (プロキシへ) ▼ ┌─────────────────────────────────────────┐ │ impersonate-proxy │ │ │ │ MITM TLS ◄──────────────► uTLS │ │ (当社のCA証明書) (カスタムJA3/4) │ │ │ │ ヘッダーリライター(UA、順序、追加/削除)│ │ HTTP/2フレーマー(SETTINGS、WINDOW_UPDATE │ 疑似ヘッダー順序) │ └─────────────────────────────────────────┘ │ カスタムTLSクライアントハロー + HTTP/2 ▼ ターゲットサーバー / WAFレイヤー 制御できるもの TLS暗号スイート、拡張機能、その順序(JA3 / JA4) — uTLSプリセットまたは完全にカスタムなcustom_hello仕様を通じて HTTP/1.1 ヘッダー順序、User-Agent、任意のヘッダーの追加/削除、IPスプーフィング(X-Forwarded-For / True-Client-IP) HTTP/2 SETTINGS 値と順序、WINDOW_UPDATE、疑似ヘッダー順序(HTTP/2フィンガープリント) 前提条件 macOSまたはLinux(amd64 / arm64) Go 1.22+ macOS brew install go Linux ディストリビューションパッケージのGoはしばしば古いです。公式バイナリを直接インストールしてください: # ダウンロードして展開します(https://go.dev/dl/ から最新バージョンに1.22.5を置き換えてください) curl -OL https://go.dev/dl/go1.22.5.linux-amd64.tar.gz sudo rm -rf /usr/local/go sudo tar -C /usr/local -xzf go1.22.5.linux-amd64.tar.gz # PATHに追加します(永続化するには、この行を~/.bashrcまたは~/.zshrcに追加してください) export PATH=$PATH:/usr/local/go/bin 確認:go version # go version go1.22.5 linux/amd64 ARM64(Raspberry Pi、AWS Gravitonなど):ダウンロードURLのlinux-amd64をlinux-arm64に置き換えてください。 セットアップ 1. クローンしてビルドする git clone https://github.com/ytkoka/impersonate-proxy.git cd impersonate-proxy make build 2. MITM CA証明書を生成する CAは初回実行時に自動生成されます。ca.crtとca.keyを作成するためにプロキシを一度実行します: make run # 2026/04/22 12:00:00 生成されたCA証明書 → ca.crt # 2026/04/22 12:00:00 127.0.0.1:8080 でリッスン中 preset=chrome Ctrl-C で停止します。 3. CA証明書を信頼する クライアントは、プロキシ生成のリーフ証明書を拒否しないように、当社のMITM CAを信頼する必要があります。 macOS システムキーチェーン(すべてのアプリに影響): make trust-ca # 実行内容:sudo security add-trusted-cert ... Linux システム信頼(すべてのアプリに影響。ca-certificatesパッケージが必要): # Debian / Ubuntu sudo cp ca.crt /usr/local/share/ca-certificates/impersonate-proxy.crt sudo update-ca-certificates # RHEL / Fedora / Amazon Linux sudo cp ca.crt /etc/pki/ca-trust/source/anchors/impersonate-proxy.crt sudo update-ca-trust curl のみ(システム全体での変更なし): curl --cacert ca.crt ... Playwright / Node.js: export NODE_EXTRA_CA_CERTS="$(pwd)/ca.crt" Firefox: Preferences → Privacy & Security → View Certificates → Authorities → Import ca.crt 設定 プロキシを開始する前に config.yaml を編集します。すべてのフィールドにはデフォルト値があります — オーバーライドしたいものだけを指定する必要があります。 listen: "127.0.0.1:8080" mgmt_listen: "127.0.0.1:8081" # Chrome拡張機能が使用する管理API(無効にする場合は空にする) ca_cert: "ca.crt" ca_key: "ca.key" tls: # TLSフィンガープリントプリセット(JA3 / JA4を制御) # オプション:chrome | firefox | safari | edge | ios | random | golang preset: "chrome" http: # User-Agentをオーバーライドします(クライアントのUAを通過させる場合は空のままにします) user_agent: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36" # ソースIPをスプーフィングします:X-Forwarded-ForとTrue-Client-IPの両方をこの値に設定します。 # クライアントが既に設定した値を上書きします(無効にする場合は空のままにします) # client_ip: "1.2.3.4" # この順序でヘッダーを発行します。リストにないヘッダーは後に追加されます。 header_order: - "Host" - "User-Agent" - "Accept" - "Accept-Language" - "Accept-Encoding" - "Connection" # フォワーディング前にヘッダーを削除します add_headers: Accept-Language: "ja,en-US;q=0.9,en;q=0.8" # ヘッダーを削除します remove_headers: [] http2: enabled: true # SETTINGSフレームエントリ — IDと順序の両方がHTTP/2フィンガープリントに影響します。 # RFC 7540 §11.3 ID: # 1=HEADER_TABLE_SIZE 2=ENABLE_PUSH 3=MAX_CONCURRENT_STREAMS # 4=INITIAL_WINDOW_SIZE 5=MAX_FRAME_SIZE 6=MAX_HEADER_LIST_SIZE settings: - { id: 1, val: 65536 } # Chromeのデフォルトが表示されています - { id: 2, val: 0 } - { id: 4, val: 6291456 } - { id: 6, val: 262144 } # コネクションレベルのWINDOW_UPDATEインクリメント window_update: 15663105 # HEADERSフレーム内の疑似ヘッダーの順序 pseudo_header_order: - method - authority - scheme - path 管理API プロキシが起動すると、mgmt_listen(デフォルト127.0.0.1:8081)で軽量HTTP APIも公開します。Chrome拡張機能はこれを使用して、プロキシを再起動せずに実行時に設定を読み取り、更新します。curlで直接呼び出すこともできます: エンドポイント メソッド 説明 /api/config GET 現在の設定をJSONとして返します。現在のcustom_helloも含まれます。 /api/config POST TLSプリセット(完全にカスタムなcustom_helloを含む)、クライアントIP、およびUser-Agentを更新します。 # 現在の設定を読み取る curl http://127.0.0.1:8081/api/config # Firefoxフィンガープリントに切り替え、スプーフィングされたIPを設定する curl -s -X POST http://127.0.0.1:8081/api/config \ -H "Content-Type: application/json" \ -d '{"tls_preset":"firefox","client_ip":"203.0.113.1","user_agent":""}' # 実行時に任意のJA3/JA4フィンガープリントに切り替える — config.yamlのcustom_helloブロックと同じフィールドをJSONで送信します(「カスタムTLSフィンガープリント」を参照) curl -s -X POST http://127.0.0.1:8081/api/config \ -H "Content-Type: application/json" \ -d '{ "tls_preset": "custom", "custom_hello": { "cipher_suites": [2570, 4865, 4866, 4867, 49195, 49199, 49196, 49200, 52393, 52392, 49171, 49172, 156, 157, 47, 53], "curves": ["X25519", "P256", "P384"], "versions": ["1.3", "1.2"], "extensions": [2570, 0, 23, 65281, 10, 11, 35, 16, 5, 18, 13, 51, 45, 43, 27, 21] }, "client_ip": "", "user_agent": "" }' 変更は新しい接続に対して即座に有効になります。 APIを完全に無効にするには、mgmt_listen: "" を設定します。 ブラウザフィンガープリントリファレンス ブラウザ TLSプリセット HTTP/2 SETTINGS WINDOW_UPDATE Chrome chrome 1:65536,2:0,4:6291456,6:262144 15663105 Firefox firefox 1:65536,4:131072,5:16384 12517377 Safari safari 1:4096,3:100,4:2097152,6:16384 10485760 カスタムTLSフィンガープリント(プリセット:「custom」) 組み込みのプリセット(chrome、firefox、safariなど)は、最も一般的なケースをカバーしています。特定のブラウザバージョンやプリセットとは異なるフィンガープリントに一致させる必要がある場合は、preset: "custom" を設定し、custom_helloブロックを提供します。 JA3 / JA4が設定フィールドにマッピングされる方法 フィンガープリントコンポーネント 設定フィールド 注記 TLSバージョン範囲 versions 最小/最大は自動的に導出されます 暗号スイートリスト + 順序 cipher_suites GREASEプレースホルダーとして0x0a0aを使用します。uTLSは接続ごとにランダム化します。 拡張機能タイプID + 順序 extensions 順序はJA3拡張機能コンポーネントを直接制御します。GREASEパターン(0xXAXA)に一致する値は、接続ごとにランダム化されます。 サポートされているグループ(曲線) curves キー共有が送信されるものを制御します。 JA3とJA4は一方向ハッシュです — ハッシュを仕様に戻すことはできません。tls.peet.wsまたはWiresharkを使用してターゲットブラウザの基になるパラメータを見つけ、custom_helloに貼り付けます。 Chrome 131の例 tls: preset: "custom" custom_hello: cipher_suites: # 16進数ID;0x0a0a = GREASEプレースホルダー(接続ごとにランダム化) - 0x0a0a - 0x1301 # TLS_AES_128_GCM_SHA256 - 0x1302 # TLS_AES_256_GCM_SHA384 - 0x1303 # TLS_CHACHA20_POLY1305_SHA256 - 0xc02b # ECDHE-ECDSA-AES128-GCM-SHA256 - 0xc02f # ECDHE-RSA-AES128-GCM-SHA256 - 0xc02c # ECDHE-ECDSA-AES256-GCM-SHA384 - 0xc030 # ECDHE-RSA-AES256-GCM-SHA384 - 0xcca9 # ECDHE-ECDSA-CHACHA20-POLY1305 - 0xcca8 # ECDHE-RSA-CHACHA20-POLY1305 - 0xc013 # ECDHE-RSA-AES128-SHA - 0xc014 # ECDHE-RSA-AES256-SHA - 0x009c # RSA-AES128-GCM-SHA256 - 0x009d curves: - "X25519" - "P256" - "P384" versions: - "1.3" - "1.2" extensions: - 0x0a0a # GREASE - 0 # Server Name - 23 # Session Ticket TLS - 65281 # Extended Master Secret - 10 # Certificate Status Request - 11 # Supported Groups - 35 # Session Ticket - 16 # Application-Layer Protocol Negotiation - 5 # Status Request - 18 # User Transfer - 13 # Signature Algorithms - 51 # Key Share - 45 # Certificate Authorities - 43 # Supported Versions - 27 # New Session Ticket Message - 21 # ALPN