CAPSOLVER
ブログ
n8nにおけるTLSファイントリッピングの解決方法 – CapSolverを使って

n8nにおけるTLSファイアウォールの解決方法 CapSolverを用いて

Logo of CapSolver

Sora Fujimoto

AI Solutions Architect

18-Mar-2026

企業グレードのボット検出保護されたウェブサイトをスクレイピングしようとしたことがある人は、目に見えない壁にぶつかったことがあるでしょう。ヘッダー、クッキー、User-Agentが完璧でも、リクエストがブロックされることがあります。その理由はTLSファイントリプティングであり、HTTPリクエストが送信される前に起こります。

Cloudflare、Akamai、DataDomeなどのボット対策サービスは、生のTLSハンドシェイクを検査して、クライアントが本物のブラウザか自動化ツールかを判断します。Goのnet/http、Pythonのrequests、curl、Node.jsのaxiosなどの標準的なHTTPクライアントは、一意のTLSファイントリプトを持ち、すぐにブロックされます。

このガイドでは、httpcloakを使用して、本物のChrome TLSファイントリプトを偽装する軽量なGoサーバーを構築し、n8nワークフローに接続して、ネットワークレベルで本物のChromeブラウザトラフィックのように見えるHTTPリクエストを作成します。


TLSファイントリプティングとは?

HTTPS経由でクライアントがウェブサイトに接続するたびに、ClientHelloメッセージを送信してTLSハンドシェイクを開始します。このメッセージには次の情報が含まれます:

  • 暗号スイート — クライアントがサポートする暗号化アルゴリズムとその順序
  • TLS拡張 — SNI、ALPN、サポートされるグループ、署名アルゴリズムなどの機能
  • 楕円曲線とポイント形式 — 暗号化パラメータ
  • TLSバージョン — サポートする最大のTLSバージョン

ボット対策サービスはこれらの値を抽出し、JA3またはJA4ファイントリプトと呼ばれるクライアントソフトウェアを一意に識別するファイントリプトを計算します。すべてのブラウザ、HTTPライブラリ、プログラミング言語ランタイムは異なるファイントリプトを生成します。

クライアント JA3ファイントリプト 検出結果
Chrome 145 Chromeの暗号スイート順序に一致するユニークなハッシュ 本物のブラウザ
Firefox 130 異なるハッシュ — Firefoxは異なる暗号優先順位を使用 本物のブラウザ
Go net/http 完全に異なるハッシュ — GoのTLSスタックは明らか ボット/自動化ツール
Python requests もう一つの明確なハッシュ — Pythonのurllib3 TLSは識別可能 ボット/自動化ツール
curl また別のハッシュ — curlのTLSファイントリプトはよく知られている ボット/自動化ツール
Node.js axios Node.jsのTLSファイントリプト — 容易にブロックされる ボット/自動化ツール

重要なポイント:TLSファイントリプティングは、HTTPヘッダーが送信される前にハンドシェイク中に発生します。 ヘッダーの操作では、非ブラウザのTLSファイントリプトを修正することはできません。


標準HTTPクライアントが失敗する理由

ブラウザがHTTPS経由でウェブサイトに接続するとき、サポートされる暗号スイート、拡張機能、設定の詳細を含むTLS ClientHelloを送信します。ボット対策サービスはこのファイントリプト(JA3/JA4ファイントリプトと呼ばれる)を記録し、既知のブラウザプロファイルと比較します。

Goのnet/http、Pythonのrequests、curl、およびほとんどのHTTPライブラリは、一意のTLSファイントリプトを持っています。ヘッダーとクッキーが正しい場合でも、ボット対策システムが非ブラウザのTLSファイントリプトを検出すると、リクエストはブロックされます。

以下の手順で起こります:

  1. n8nワークフローが保護されたウェブサイトにHTTPリクエストを送信します
  2. TLSハンドシェイクが開始されます — クライアントがClientHelloを送信します
  3. ボット対策サービスはハンドシェイクからJA3/JA4ファイントリプトを記録します
  4. ファイントリプトはGo/Python/Node.jsと一致します — ChromeやFirefoxとは一致しません
  5. リクエストはブロックされ、チャレンジされるか、デコイページが提供されます — ヘッダーが評価される前

これは、User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) ...を設定しても役に立たない理由です。User-AgentはHTTPレベルのヘッダーです。TLSファイントリプティングはより低いレイヤーで動作します。User-AgentがChromeを示してもTLSファイントリプトがGoを示すと、リクエストはすぐにブロックされます。


TLSファイントリプティングを使用する主なサービス

TLSファイントリプティングは企業グレードのボット保護の標準的な手法となっています。次の主要なサービスはTLSファイントリプトをチェックしています:

ボット対策サービス TLSチェック 注意点
Cloudflare Bot Management はい ページ全体の「ブラウザの確認中...」チャレンジ。すべてのリクエストでJA3/JA4をチェック
Akamai Bot Manager はい TLSファイントリプトをボットスコアリングのシグナルの一つとして使用
DataDome はい TLSファイントリプトを行動シグナルとともに分析
多くの他のサービス 一部 TLSファイントリプティングは企業グレードのボット保護で標準化されています

CapSolverは、これらのサービスからのチャレンジを解決するサポートを提供しています。このガイドのTLSサーバーは、最終的なHTTPフェッチが本物のブラウザのように見える任意のキャプチャ解決ワークフローと連携するように設計されています — Cloudflareチャレンジ、Akamai、DataDome、または他のボット対策システムをバイパスする場合でも。


前提条件

要件 注意点
n8nのセルフホスト版 必須 — TLSサーバーはn8nと同じマシンで実行する必要があります。n8n Cloudは適していません。
Go 1.21+ サーバーにインストールする必要があります。go versionで確認してください。
プロセスマネージャー (推奨) systemd、supervisor、Docker、PM2などの任意のプロセスマネージャーで、再起動後にサーバーを実行し続けます

ステップ1 — TLSサーバーを構築する

TLSサーバーは、ポート7878でリクエストを受け付け、httpcloakのChrome-145 TLSプリセットを使用して転送する軽量なGo HTTPサーバーです。

ソースファイルを作成

bash Copy
mkdir -p ~/tls-server && cd ~/tls-server

次の内容でmain.goというファイルを作成してください:

go Copy
package main

import (
	"context"
	"encoding/json"
	"fmt"
	"io"
	"log"
	"net/http"
	"strings"
	"time"

	"github.com/sardanioss/httpcloak/client"
)

type FetchRequest struct {
	URL     string            `json:"url"`
	Method  string            `json:"method"`
	Headers map[string]string `json:"headers"`
	Proxy   string            `json:"proxy"`
	Body    string            `json:"body"`
}

type FetchResponse struct {
	Status  int                 `json:"status"`
	Body    string              `json:"body"`
	Headers map[string][]string `json:"headers"`
}

type ErrorResponse struct {
	Error string `json:"error"`
}

func writeError(w http.ResponseWriter, status int, msg string) {
	w.Header().Set("Content-Type", "application/json")
	w.WriteHeader(status)
	json.NewEncoder(w).Encode(ErrorResponse{Error: msg})
}

func fetchHandler(w http.ResponseWriter, r *http.Request) {
	if r.Method != http.MethodPost {
		writeError(w, http.StatusMethodNotAllowed, "only POST allowed")
		return
	}

	var req FetchRequest
	if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
		writeError(w, http.StatusBadRequest, "invalid JSON: "+err.Error())
		return
	}

	if req.URL == "" {
		writeError(w, http.StatusBadRequest, "url is required")
		return
	}
	if req.Method == "" {
		req.Method = "GET"
	}

	ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second)
	defer cancel()

	c := client.NewClient("chrome-145", client.WithTimeout(60*time.Second))
	defer c.Close()

	if req.Proxy != "" {
		c.SetProxy(req.Proxy)
	}

	headers := make(map[string][]string, len(req.Headers))
	var userAgent string
	for k, v := range req.Headers {
		lower := strings.ToLower(k)
		if lower == "user-agent" {
			userAgent = v
		} else {
			headers[k] = []string{v}
		}
	}

	var bodyReader io.Reader
	if req.Body != "" {
		bodyReader = strings.NewReader(req.Body)
	}

	hcReq := &client.Request{
		Method:    strings.ToUpper(req.Method),
		URL:       req.URL,
		Headers:   headers,
		Body:      bodyReader,
		UserAgent: userAgent,
		FetchMode: client.FetchModeNavigate,
	}

	resp, err := c.Do(ctx, hcReq)
	if err != nil {
		writeError(w, http.StatusBadGateway, "fetch failed: "+err.Error())
		return
	}

	body, err := resp.Text()
	if err != nil {
		writeError(w, http.StatusInternalServerError, "read body failed: "+err.Error())
		return
	}

	w.Header().Set("Content-Type", "application/json")
	json.NewEncoder(w).Encode(FetchResponse{
		Status:  resp.StatusCode,
		Body:    body,
		Headers: resp.Headers,
	})
}

func main() {
	const port = "7878"

	mux := http.NewServeMux()
	mux.HandleFunc("/fetch", fetchHandler)
	mux.HandleFunc("/health", func(w http.ResponseWriter, r *http.Request) {
		w.Header().Set("Content-Type", "application/json")
		fmt.Fprint(w, `{"status":"ok"}`)
	})

	log.Printf("TLS server (httpcloak chrome-145) listening on :%s", port)
	log.Fatal(http.ListenAndServe(":"+port, mux))
}

初期化とビルド

bash Copy
go mod init tls-server
go get github.com/sardanioss/httpcloak/client
go build -o main main.go

サーバーを実行

bash Copy
./main

サーバーはフォアグラウンドで実行されます。バックグラウンドで実行するには、任意のプロセスマネージャー(systemd、supervisor、Dockerなど)を使用するか、screen/tmuxセッションで実行してください。

実行中の確認(別のターミナルで)

bash Copy
curl http://localhost:7878/health

期待される出力: {"status":"ok"}

注意: TLSサーバーは同じマシンにn8nインスタンスを実行する必要があります。n8nワークフローはhttp://localhost:7878/fetchで呼び出します。


ステップ2 — n8nがローカルホストを呼び出せるようにする

デフォルトでは、n8nはローカルホストアドレスへのHTTPリクエストノードをブロックします(SSRF保護)。ワークフローがlocalhost:7878のTLSサーバーにアクセスできるようにするには、これを無効にする必要があります。

N8N_BLOCK_ACCESS_TO_LOCALHOST=falseという環境変数を追加し、n8nインスタンスを再起動してください。実行方法はn8nの実行方法に応じて異なります:

n8nを直接実行する場合:

bash Copy
export N8N_BLOCK_ACCESS_TO_LOCALHOST=false
n8n start

Dockerを使用する場合:

docker runコマンドに-e N8N_BLOCK_ACCESS_TO_LOCALHOST=falseを追加するか、docker-compose.ymlenvironmentセクションに追加してください。


ステップ3 — n8nからTLSサーバーを使用する

TLSサーバーは、任意のHTTPリクエストを受信し、Chrome TLSファイントリプトで転送する単一のエンドポイントを公開しています。

APIリファレンス

エンドポイント: POST http://localhost:7878/fetch

リクエストボディ(JSON):

json Copy
{
  "url": "https://example.com",
  "method": "GET",
  "headers": {
    "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/145.0.0.0 Safari/537.36",
    "cookie": "cf_clearance=abc123; session=xyz"
  },
  "proxy": "http://user:pass@host:port",
  "body": ""
}
フィールド タイプ 必須 説明
url 文字列 必須 取得するターゲットURL
method 文字列 不要 HTTPメソッド — デフォルトはGET
headers オブジェクト 不要 送信するHTTPヘッダーのキー値ペア
proxy 文字列 不要 http://user:pass@host:port形式のプロキシURL
body 文字列 不要 リクエストボディ(POST/PUTリクエスト用)

レスポンス(JSON):

json Copy
{
  "status": 200,
  "body": "<html>...</html>",
  "headers": { "content-type": ["text/html"], "..." : ["..."] }
}

n8n HTTPリクエストノードの設定

TLSサーバーをn8nワークフローから呼び出すには、次の設定でHTTPリクエストノードを使用してください:

パラメータ 説明
メソッド POST TLSサーバーに常にPOSTする
URL http://localhost:7878/fetch ローカルTLSサーバーのエンドポイント
コンテンツタイプ Raw JSONを使用しないでください — n8nのJSONモードは誤ってシリアライズされます
Rawコンテンツタイプ application/json TLSサーバーにボディがJSONであることを伝える
ボディ ={{ JSON.stringify({ url: "...", method: "GET", headers: {...}, proxy: "..." }) }} 転送する実際のリクエスト

重要: ボディでcontentType: "json"JSON.stringify()を使用すると、n8nが二重にシリアライズし、{"": ""}ではなくデータを送信します。常にcontentType: "raw"rawContentType: "application/json"を使用してください。

例: 保護されたページを取得する

HTTPリクエストノードのボディ式:

javascript Copy
={{ JSON.stringify({
  url: "https://protected-site.com/data",
  method: "GET",
  headers: {
    "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/145.0.0.0 Safari/537.36",
    "accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
    "accept-language": "en-US,en;q=0.9"
  },
  proxy: "http://user:pass@proxy-host:8080"
}) }}

TLSサーバーはChrome-145 TLSファイントリプトでこのリクエストを転送し、ターゲットは本物のChromeブラウザ接続として認識します。


テストする

コマンドラインからTLSサーバーを直接テストします:

bash Copy
curl -X POST http://localhost:7878/fetch \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://tls-check.example.com",
    "method": "GET",
    "headers": {
      "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/145.0.0.0 Safari/537.36"
    }
  }'

JA3/JA4ファイントリプトチェッカーにサーバーを指定することで、TLSファイントリプトを確認できます — 結果は本物のChromeブラウザと一致するはずです。


このワークフローをインポートする

このワークフローは、TLSサーバーを経由してChrome TLSファイントリプトでリクエストを転送するWebhookエンドポイントを作成します。urlmethodheaders、およびオプションのproxyを含むPOSTを送信してください — ワークフローはlocalhost:7878/fetchに転送し、結果を返します。

Copy
Webhook (POST /tls-fetch) → TLSサーバー経由で取得 → Webhookに応答

以下のJSONをコピーし、メニュー → JSONからインポートでn8nにインポートしてください。

クリックしてワークフローJSONを展開
json Copy
{
  "name": "TLS Fetch — Chrome Fingerprint Proxy",
  "nodes": [
    {
      "parameters": {
        "content": "## TLS Fetch — Chrome Fingerprint Proxy\n\n**誰向け:** 認証されたブラウザのTLSファイントリプトを持つHTTPリクエストが必要な開発者。\n\n**何をするのか:** HTTPリクエストをGo TLSサーバー(httpcloak)を経由して転送し、ボット検出を回避します。これはChromeのTLSファイントリプトを模倣します。\n\n**動作方法:**\n1. WebhookがターゲットURLとリクエストの詳細を受け取ります\n2. リクエストはローカルTLSサーバーに転送され、Chromeのファイントリプトで送信されます\n3. 結果は呼び出し元に返されます\n\n**セットアップ:**\n1. ポート7878でTLSサーバー(httpcloak)が実行されていることを確認してください\n2. ワークフローを有効にします\n3. 要求の詳細を含むWebhookURLにPOSTしてください",
        "height": 494,
        "width": 460,
        "color": 1
      },
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        -720,
        -300
      ],
      "id": "sticky-blog-main-1773678228122-1",
      "name": "Sticky Note"
    },
    {
      "parameters": {
        "httpMethod": "POST",
        "path": "tls-fetch",
        "responseMode": "responseNode",
        "options": {}
      },
      "type": "n8n-nodes-base.webhook",
      "typeVersion": 2.1,
      "position": [
        -200,
        0
      ],
      "id": "tls00001-0001-0001-0001-000000000001",
      "name": "Receive Solver Request",
      "webhookId": "tls00001-aaaa-bbbb-cccc-000000000001"
    },
    {
      "parameters": {
        "method": "POST",
        "url": "http://localhost:7878/fetch",
        "sendBody": true,

"contentType": "raw",
"rawContentType": "application/json",
"body": "={{ JSON.stringify(json.body) }}", "options": { "timeout": 60000 } }, "type": "n8n-nodes-base.httpRequest", "typeVersion": 4.3, "position": [ 100, 0 ], "id": "tls00001-0001-0001-0001-000000000002", "name": "TLSサーバー経由で取得" }, { "parameters": { "respondWith": "json", "responseBody": "={{ JSON.stringify(json) }}",
"options": {}
},
"type": "n8n-nodes-base.respondToWebhook",
"typeVersion": 1.5,
"position": [
400,
0
],
"id": "tls00001-0001-0001-0001-000000000003",
"name": "Webhookに応答"
}
],
"connections": {
"Receive Solver Request": {
"main": [
[
{
"node": "TLSサーバー経由で取得",
"type": "main",
"index": 0
}
]
]
},
"TLSサーバー経由で取得": {
"main": [
[
{
"node": "Webhookに応答",
"type": "main",
"index": 0
}
]
]
}
},
"active": false,
"settings": {
"executionOrder": "v1"
}
}
``


結論

n8nのHTTPリクエストをネットワークレベルで本格的なChromeブラウザのトラフィックのように見せかけるTLSファイバープリントスプーフィングサーバーを設定しました。これは、TLSファイバープリントをチェックするアンチボットサービスによって保護されているウェブサイトのスクレイピングに不可欠です。

このTLSサーバーは以下の回避に役立ちます:

  • Cloudflare Bot Management — 全画面チャレンジでTLSファイバープリントをチェック
  • Akamai Bot Manager — 企業向けのボット検出にTLS分析を使用
  • DataDome — 行動 + TLSファイバープリント分析
  • PerimeterX / HUMAN — デバイス + TLSファイバープリント検出
  • CapSolverがサポートする他の多くのアンチボットサービス

httpcloakライブラリのChrome-145プリセットは、JA3/JA4ファイバープリントスプーフィング、HTTP/2 SETTINGSフレーム、ALPNネゴシエーション、ヘッダー順序を処理し、TLS層で本物のChromeブラウザと区別がつかないリクエストを生成します。


TLSスプーフィングと同時にCAPTCHAを解決したいですか? CapSolver をチェックしてください — これはn8nと直接統合されている公式ノードで、Cloudflareチャレンジ、Turnstile、reCAPTCHAなど多くの種類をサポートしています。初回チャージで8%のボーナスが得られるバーコード n8n を使ってください!

CapSolverボーナスコードバナー

よくある質問

TLSファイバープリントとは何ですか?

TLSファイバープリントは、サーバーがTLS ClientHelloメッセージの特徴(暗号スイート、拡張機能、その順序など)を分析して、どのソフトウェアが接続しているかを特定する技術です。各HTTPクライアント(Chrome、Firefox、curl、Go、Pythonなど)には独自のファイバープリントパターンがあります。

なぜUser-AgentヘッダーをChromeに設定できないのですか?

User-AgentヘッダーはHTTPレベルの属性です。TLSファイバープリントはより低いレベルで発生します。HTTPヘッダーが送信される前にTLSハンドシェイク中に発生します。アンチボットサービスは両方のレイヤーを比較します。User-AgentがChromeでもTLSファイバープリントがGo/Pythonであれば、リクエストはボットとしてマークされます。

httpcloakとは何ですか?

httpcloak は、本物のブラウザのTLSプロファイルをスプーフィングするGoライブラリです。JA3/JA4ファイバープリントの一致、HTTP/2 SETTINGSフレーム、ALPNネゴシエーション、ヘッダー順序を処理します。chrome-145プリセットにより、実際のChrome 145ブラウザと区別がつかなくなります。

他のChromeバージョンのプリセットを使用できますか?

はい。httpcloakは複数のブラウザプリセットをサポートしています。利用可能なプリセットについてはhttpcloakドキュメントを参照してください。プリセットを変更するには、main.go内のclient.NewClient("chrome-145", ...)を目的のブラウザプロファイルに変更してください。

n8n Cloudで動作しますか?

難しいです。TLSサーバーはn8nと同じマシン上で実行する必要があるローカルのGoバイナリです。ワークフローがhttp://localhost:7878/fetchを呼び出す必要があります。n8n Cloudではローカルサービスをワークフローと併せて実行することはできません。自己ホストされたn8nインスタンスが必要です。

TLSサーバーを別のマシンで実行できますか?

はい、ただしn8nのHTTPリクエストノードのURLをhttp://localhost:7878/fetchからhttp://your-server-ip:7878/fetchに更新し、ポート7878がアクセス可能であることを確認してください。また、n8nのSSRF保護を無効にするか、サーバーのIPをホワイトリストに追加する必要があります。

新しいバージョンがリリースされたときにChromeプリセットを更新するには?

httpcloak依存関係を更新します: go get -u github.com/sardanioss/httpcloak/clientmain.go内のプリセット文字列を新しいバージョンに変更し、go build -o main main.goで再ビルドし、サーバーを再起動します。

このTLSサーバーは並列リクエストをサポートしていますか?

はい。GoのHTTPサーバーは並列リクエストをネイティブに処理します。各リクエストは独自のhttpcloakクライアントインスタンスを作成し、独自のTLS接続を維持します。高負荷のワークロードの場合、各接続が独自のTLS状態を保持するため、メモリ使用量を監視してください。

パフォーマンスオーバーヘッドはどのくらいですか?

TLSサーバーは最小限の遅延を追加します。通常、ローカルプロキシのホップで10〜50ミリ秒です。実際のHTTPS接続にかかる時間の大部分は、ターゲットにかかる時間です。ChromeのTLSハンドシェイクはGoのデフォルトよりやや重いですが、実際には無視できるほどです。

サーバー再起動後にTLSサーバーを実行し続けるには?

systemd、supervisor、Dockerなど、任意のプロセスマネージャーを使用してTLSサーバーをサービスとして登録し、起動時に実行するように設定してください。簡単な設定には、screentmuxセッション内で実行することもできます。

コンプライアンス免責事項: このブログで提供される情報は、情報提供のみを目的としています。CapSolverは、すべての適用される法律および規制の遵守に努めています。CapSolverネットワークの不法、詐欺、または悪用の目的での使用は厳格に禁止され、調査されます。私たちのキャプチャ解決ソリューションは、公共データのクローリング中にキャプチャの問題を解決する際に100%のコンプライアンスを確保しながら、ユーザーエクスペリエンスを向上させます。私たちは、サービスの責任ある使用を奨励します。詳細については、サービス利用規約およびプライバシーポリシーをご覧ください。

もっと見る