windows-host-browser について
windows-host-browserは、IliyasのWindows PCで長時間稼働するChromeを操作するスキルで、同じブラウザーセッションを必要とするエージェント向けです。CDPとトンネルで接続し、タブ操作、プロキシ設定、アカウント関連操作のルールを定めています。
主な機能
- 01connect.shによるCDP接続
- 02既存タブの確認と再利用
- 03CDP経由のスクリプト実行とネットワーク監視
- 04Chromeプロファイルごとのプロキシ管理
- 05画面表示操作とアカウント変更の承認規則
活用シーン
- 01ログイン済みブラウザーでのみ見られるページへのアクセス
- 02ヘッドレスブラウザーを阻むチャレンジへの対応
- 03ページスクリプトとネットワークリクエストの調査
- 04指定プロファイルのプロキシ設定と復元
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ iliyasone/ skills --skill windows-host-browserインストール後、Claude Code で/windows-host-browserを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
cdp.pyconnect.shmk-shortcut.ps1詳細
Windows ホストブラウザー
対象は、--remote-debugging-port=<PORT> --user-data-dir="C:\chrome-debug" を指定して起動した、Iliyas の Windows PC 上の長時間稼働している Chrome です。ヘッドレスのサンドボックスではなく、Iliyas も使用する実際のブラウザーで、彼の有効なセッション(Vercel、Google Cloud など)があり、物理画面に表示されています。
以下のすべてを左右するのは、次の2点です。
- 力 — 彼のログインが必要なものには、認証情報を尋ねることなくアクセスできます。また、ページを彼と同じ状態で正確にデバッグできます。開いているタブで JavaScript を実行し、ネットワークトラフィックを監視し、選択したプロキシ経由で接続できます。
- 慎重さ — 彼には、あなたが開くすべてのウィンドウが見え、あなたが変更するすべての設定が共有されます。画面に表示されるものを開くときは彼に伝え、自分が開いたタブは、彼が残すことを望まない限り閉じてください。また、ブラウザー全体に適用される変更(プロキシなど)は、作業後に元に戻してください。認証済み CLI やヘッドレスブラウザーでも同じように取得できるデータについては、そちらを優先してください。
依頼されなくても使用する場合
Iliyas は、作業を中断して彼の指示を待つより、このブラウザーを使うことを望んでいます。より手軽な方法でうまくいかなかった場合は、自分の判断で使用してください。
- Cloudflare のチャレンジや CAPTCHA によってヘッドレスブラウザーが止められる場合。
- ページで彼のログインが必要で、それをカバーする CLI やトークンがない場合。
- 彼のブラウザーまたはセッションでしか起きず、ヘッドレスでは再現できないことがある場合。
依頼されていない場合は、彼のアクティブなタブにフォーカスを残せるよう、Target.createTarget に background: true を指定してブラウザーの WebSocket 経由でページをバックグラウンドタブとして開きます(GET /json/version → webSocketDebuggerUrl。Origin ヘッダーなしで接続します。cdp.py のように)。PUT /json/new は使わないでください。彼が操作する必要がある場合(CAPTCHA など)に限り、Target.activateTarget で前面に表示してください。Chrome のウィンドウが開いていない場合は、それでも新しいウィンドウが表示されます。その旨を伝えてください。タブはデフォルトのプロファイルで開きます。必要なログイン情報が別のプロファイルにある場合は、彼に尋ねてください。自分で開いたタブでは、作業に必要な数ページを、人間と同じくらいの速度で読んだり移動したりできます(「既存のウィンドウを再利用する」で彼の空白タブを引き継いだ場合も、自分のタブとみなし、移動や閉じる操作ができます)。どのページを開いたか、またその理由をチャットで伝えてください。通常、Cloudflare のチャレンジはこのブラウザーでは自然に解消されます。Turnstile のチェックボックスをオンにするのは問題ありません。それ以外の CAPTCHA は、開いているタブで彼に解いてもらってください。
彼のアカウントの状態を変更する操作や料金が発生する操作を行う前には、必ず先に確認してください。フォームの送信、投稿、購入、アカウント設定の変更、確認・承諾・認証・ログアウトを確定するリンクのクリック、OAuth の同意、およびページの JavaScript から送信する GET 以外のリクエストが該当します。また、ブラウザーから Cookie やトークンをコピーする前と、ページに表示された認証情報(API キー、トークン、パスワード、環境変数の値など)を、チャットを含むあらゆる場所に貼り付ける前にも確認してください。その他のプライベートな内容は、課題、PR、他の人とのチャットではなく、彼とのチャットで共有できます。彼のブラウザーを通じたループ処理、ポーリング、一括取得にも、彼の許可が必要です。これらは彼の自宅の IP アドレスとアカウントを使用します。いずれかのプロファイルのプロキシを変更する前にも確認してください。彼からブラウザーを使うよう依頼された場合も、依頼に具体的な操作が明記されていない限り、これらのルールに従ってください。
依頼されずに作業しているときに connect.sh が失敗した場合は、作業を中止して彼に伝えてください。以下の修復操作(Chrome の終了、chromedebug タスクの書き換え、net stop winnat)を行うと、彼のウィンドウや他のエージェントのタブが閉じられるため、彼の許可が必要です。
別のエージェントが同時にブラウザーを使用している場合があります。自分のタブで作業し、他のエージェントのタブは決して閉じたり移動したりしないでください(以下の空白タブに関するルールを参照してください)。
Step 0 — 接続:connect.sh を実行し、固定エンドポイントを使用する
dev-remote ではエンドポイントは固定で、Windows 側で Chrome が使用するポートに関係なく、http://127.0.0.1:18800 です。次のコマンドで必要なものをすべて設定できます。
~/.agents/skills/windows-host-browser/connect.sh
# on success prints: CDP_HTTP=http://127.0.0.1:18800
export CDP_HTTP="http://127.0.0.1:18800"
このスクリプトはべき等で、すでにすべて起動している場合の負荷もわずかです。そうでない場合は、chromedebug のスケジュールされたタスクから現在の Windows 側のポートを再検出します(信頼できる情報源です。ポートは変わるため、「ポートに関する注意」を参照してください。絶対にハードコードしないでください)。プロセスが終了している場合は、タスク経由で Chrome を再起動し(ウィンドウなし。「起動」を参照してください)、2 つの SSH ホップ(dev-remote → wsl → windows)をどちらもローカルポート 18800 に再構築します。
dev-remote の systemd タイマーが 2 分ごとに再実行するため、通常はエンドポイントがすでに動作しています。systemctl status cdp-tunnel.timer で状態を確認でき、ログは journalctl -u cdp-tunnel.service で確認できます。
connect.sh が FAIL を出力する場合は、メッセージに問題が発生したレイヤーが示されます。以下のセクションは手動でのトラブルシューティング手順です。2026-09-01 時点で、Windows 側のポートは9555です(9222、9223、9250、9333、9444 は順に WinNAT にブロックされました)。
手動での手順(connect.sh が自動化する内容)
デバッグポートは Windows ホスト自身のループバック上にしかありません。自宅のマシン(WSL ボックス iliyasone)と dev-remote は、両方とも Iliyas の Tailscale テイルネット上にあり、これが両者を結ぶ安定した経路です。ポートに到達するには 2 ホップのトンネルが必要です。WSL ボックスから Windows のループバックを直接参照できないため、ホストへのトンネルも必要です。まずポートを確認します。
PORT=$(ssh wsl 'ssh windows "schtasks /query /tn chromedebug /xml"' \
| grep -aoE 'remote-debugging-port=[0-9]+' | grep -oE '[0-9]+')
-
WSL ボックス
iliyasone上で:ホストのポートを WSL のループバックに転送します。pgrep -f "ssh .*-L $PORT:127.0.0.1:$PORT windows" >/dev/null \ || ssh -f -N -o ExitOnForwardFailure=yes -o ServerAliveInterval=30 \ -L "$PORT:127.0.0.1:$PORT" windows(
ssh windows "curl 127.0.0.1:$PORT/json/version"でも、トンネルを使わずに一度だけ確認できます。) -
dev-remote上で:ssh wslはテイルネット経由で WSL シェル(100.93.231.101)に接続します。上記の WSL→ホストの転送に、2 つ目の転送を重ねます。pgrep -f "ssh -N .*-L $PORT:127.0.0.1:$PORT wsl" >/dev/null \ || setsid ssh -N -o ExitOnForwardFailure=yes -o ServerAliveInterval=30 \ -L "$PORT:127.0.0.1:$PORT" wsl >/dev/null 2>&1 < /dev/null &
次に確認コマンドを実行します。
curl -s --max-time 4 "http://127.0.0.1:$PORT/json/version" || echo NO_CDP
Chrome のバージョンが表示されたら、ステップ 1 に進みます。NO_CDP の場合に考えられる原因を、対処コストの低い順に示します。トンネルが起動していない(上記の転送を再実行してください)。Chrome が起動しているにもかかわらず、ポートが WinNAT に奪われた(「ポートに関する注意」を参照してください)。自宅の PC または WSL ボックスがオフライン(tailscale status を確認してください。iliyasone がオフラインならマシンの電源が切れているため、こちらから対処できることはありません)。または、デバッグ用 Chrome が起動していない(「起動」を参照してください)。経路を捏造しないでください。
Step 1 — 接続
この注意点はヘルパーだけでなく、すべての WebSocket 接続に当てはまります。Chrome は --remote-allow-origins を指定せずに起動されているため、CDP WebSocket は Origin ヘッダーなしで開いてください。指定すると接続が拒否されます。
以降は $CDP_HTTP に対して通常の CDP を使用します。
GET /json/list— タブとその WebSocket URL を取得します。任意の CDP クライアントで接続し、JS の評価、スクリーンショットの取得、ネットワークイベントの監視を行えます(Network.enableとNetwork.requestWillBeSent/responseReceived)。PUT /json/new?url=…— ページを開きます(Iliyas の画面に表示されるタブです。開く場合はその旨を伝えてください)。GET /json/version→webSocketDebuggerUrl— ブラウザーの WebSocket です。createTargetなどのTarget.*呼び出しに使用します。
既存のウィンドウを再利用する — 増やさない
すべてのウィンドウとタブは Iliyas の画面に表示されており、エージェントには新しいウィンドウを作らないよう依頼しています。何かを開く前に GET /json/list を実行し、次の順序で既存のものを再利用してください。
- 自分で開いた空白のタブ、または Iliyas が空白のままにしているタブがある
(
about:blankまたはchrome://newtab/):ターゲットを新規作成するのではなく、そのタブに移動します(ウェブソケットに接続してPage.navigateを実行)。新しい空白タブは、別のエージェントが開いてこれから移動しようとしている可能性があります。自分のものか判断できない場合は、自分のものではないとしてルール 2 に進んでください。 - 開いているタブが自分のもの、または明らかにアイドル状態である
(Iliyas が現在作業しているものではない):同じウィンドウ内にタブとしてページを開きます。
PUT /json/newを使うと、既存のウィンドウが対象になります。 - 新しいウィンドウは、意図的に必要な場合に限ります。たとえば、既存のウィンドウで Iliyas が別の作業をしている場合や、分離が必要な場合(ウィンドウサイズを変える、別途確認してもらうワークフローなど)です。理由も伝えてください。
片付けるときも同様です。自分が開いたタブは /json/close/<id> で閉じ、自分が開いていないタブは絶対に閉じないでください。
プロキシの制御 — cdp.py(プロファイルごと)
Iliyas からプロキシの変更を依頼されていない限り、どのプロファイルに対しても set または direct を実行する前に、Iliyas に確認してください。自分が承認を得て実行した set を direct で元に戻す場合は、再度確認する必要はありません。すでに設定されていたプロキシは、Iliyas が判断します。
Chrome にはプロキシ設定を管理する Proxy Switcher 拡張機能
(iejkjpdckomcjdhmkemlfdapjodcpgih)が入っています。プロキシはウィンドウごとではなく、Chrome プロファイルごとに設定されます。ブラウザーでは複数のプロファイルを同時に実行でき(別々のウィンドウ、Cookie、拡張機能のコピー)、それぞれ異なるプロキシを使用できます。cdp.py(このファイルと同じ場所にあります)で操作します。デフォルトでは固定エンドポイント http://127.0.0.1:18800 を使用します(先に connect.sh を実行してください)。$CDP_HTTP を設定すると、別の場所で実行する場合に限り、デフォルトのエンドポイントを上書きできます。
python3 cdp.py profiles # list running profiles by their open tabs
python3 cdp.py get -p 2 # proxy setting of profile 2 from that list
python3 cdp.py set 82.38.65.142 41196 http proxyuser 'PASSWORD' -p proton
python3 cdp.py egress -p proton # prove the exit IP/country through it
python3 cdp.py direct -p proton # revert that profile to direct
--profile / -p には、profiles のインデックス、またはそのプロファイルで開いているタブの URL/タイトルの部分文字列を指定します。実行中のプロファイルが 1 つだけなら省略できます。複数ある場合は必須です。誤ったプロファイルにプロキシを設定すると、Iliyas がブラウジングする経路が変わってしまうため、このツールは推測で選びません。
このツールで隠される注意点が 2 つあります。拡張機能は MV3 なので、プロファイルごとのサービスワーカーはスリープし、ターゲット一覧から消えます。また、特定のプロファイルでスリープ中のワーカーは Target.createTarget では起動できません(CDP は実際のプロファイルの browserContextIds を拒否します)。cdp.py は、そのプロファイル自身のページから window.open で一時タブを開き、CDP で拡張機能のポップアップに移動してから、そのタブを閉じることでワーカーを起動します。
set は、そのプロファイルに対して chrome.proxy.settings.set を呼び出します(拡張機能のポップアップが行うのとまったく同じです)。ユーザー名が指定されている場合は、拡張機能のストレージに auth-username/auth-password を書き込み、認証が必要なプロキシでダイアログが表示されないよう、onAuthRequired ハンドラーを再び有効にします。
Iliyas 自身がブラウジングに使うプロファイルでは、作業が終わったら必ず direct を実行してください。プロキシをそのままにすると、本人のブラウジングに影響します。専用のプロキシプロファイルでは、プロキシを設定したままにできます。
新しいプロファイルに拡張機能を追加するには、手動での操作が必要です。そのプロファイルのウィンドウで
https://chromewebstore.google.com/detail/iejkjpdckomcjdhmkemlfdapjodcpgih
を開き、Iliyas に「Add to Chrome」をクリックしてもらいます。インストールの確認画面はネイティブ UI であり、CDP からは操作できません。
プロキシの取得元
reverse-api プロジェクトが proxy テーブル(Postgres、Heroku アプリ pinc000)を管理しています。列は scheme, server, port, username, password, country_code です。認証にユーザー名とパスワードを使う HTTP プロキシで、country_code(ISO-3166 alpha-2)で選択します。認証情報をハードコードせず、テーブルを照会してください。
# on dev-remote, heroku CLI is authed to app pinc000
heroku pg:psql -a pinc000 -c \
"select scheme,server,port,username,password,country_code from proxy where country_code='nl';"
ローテーションはありません。プロキシはアカウントごとに固定されるため、ブラウザーで使用する場合は、希望する国の行をどれでも選んでください。
デバッグ用 Chrome の起動
ステップ 0 で NO_CDP と表示されても ssh wsl が機能する場合は、スケジュールされたタスクで Chrome を起動してください。通常の SSH 経由では起動しないでください。Chrome は画面に表示されないセッション 0 で起動し、ポートをバインドする前に終了してしまいます。
# from the WSL box:
ssh windows 'schtasks /run /tn chromedebug'
# from dev-remote (hop through WSL):
ssh wsl 'ssh windows "schtasks /run /tn chromedebug"'
# then poll: curl -s "$CDP_HTTP/json/version"
タスクは --no-startup-window を指定して Chrome を起動するため、起動しても画面には表示されません。Chrome はバックグラウンドで CDP を起動した状態で動作し、何かがページを開くまでウィンドウは表示されません(その後 PUT /json/new によって、本人の画面にウィンドウが開くことを伝えてください)。これにより、ログオンのたびに 2 分間のタイマーで Chrome が Iliyas の前面に表示されるのを防ぎます。タスクのアクションを書き換える場合は、必ずこのフラグを維持してください。「Agent Chrome」ショートカットは、タスクの起動後にウィンドウ自体を開きます。タスクは LogonType=InteractiveToken で実行されます(全般タブ:「ユーザーがログオンしているときのみ実行する」)。そのため本人に見えるセッションで起動し、パスワードは保存されません。
再起動後、Chrome が数分でまた動作しなくなった場合は、何度も再起動しないでください。「終了時の注意」を参照してください。
Iliyas 自身で開く場合 — デスクトップショートカット
Windows デスクトップにある 「Agent Chrome」 を使うと、このブラウザーを手動で開けます。たとえば、エージェントがそのセッションを使えるよう、サービスにサインインする場合などです。このショートカットは C:\chrome-debug\open-debug-chrome.ps1 を実行します。デバッグ用 Chrome がすでに動作していれば、そのウィンドウで新しいウィンドウを開きます。そうでなければ chromedebug タスクを開始し、デバッグポートから応答があるのを待ってからウィンドウを開きます(タスクのインスタンスがまだ実行中の場合、タスクでは MultipleInstances IgnoreNew が使われているため、通常の schtasks /run は何もせず無視されます。そのためスクリプトは最初に確認します)。本人がどこかにログインする必要がある場合は、代わりにタブを開いてあげるのではなく、このショートカットを使うよう伝えてください。
ショートカットまたは起動スクリプトが見つからない場合は、ホスト上で -EncodedCommand 方式を使って、このファイルと同じ場所にある mk-shortcut.ps1 を実行し、両方を再作成してください。このスクリプトは C:\chrome-debug に .lnk を作成し、デスクトップに移動します。デスクトップフォルダー名がキリル文字(Рабочий стол)のため、WScript.Shell ではデスクトップフォルダーに直接保存できません。
ポートに関する注意 — WinNAT がデバッグポートを奪うことがあります
**症状:**デバッグ用 Chrome は動作していてブラウジングもできますが、$CDP_HTTP/json/version への接続が拒否され、DevTools サーバーも存在しません。--enable-logging --v=1 を指定して起動すると、C:\chrome-debug\chrome_debug.log に bind() ... Only one usage of each socket address ... (0x2740) と表示され、その後に Cannot start http server for devtools と記録されます。
**原因:**Hyper-V/WSL2 の WinNAT/HNS は TCP ポートの範囲を予約します。WSL またはホストの再起動後に、その範囲にデバッグポートが含まれることがあります。netstat ではそのポートが使用中と表示されず、netsh int ipv4 show excludedportrange にも表示されないのに、バインドできなくなります。「昨日は動いたのに今日は動かない」場合は、予約範囲がそのポートに移動したということです。カスタムの user-data-dir、ポリシー、セッション 0 は無関係です。上記のログ行で確認してください。
復旧方法(管理者権限不要、サービスの再起動不要):
-
空いているポートを見つけます。候補のポートでバインドを試し、最初に成功したものを選びます。
foreach ($p in 9223,9250,9333,9555,18222) { try { $l=[System.Net.Sockets.TcpListener]::new([Net.IPAddress]::Loopback,$p) $l.Start(); "OK $p"; $l.Stop() } catch { "FAIL $p" } } -
タスクのポートを変更します。PowerShell の
Set-ScheduledTaskを使い、schtasks /changeは使わないでください。後者は、タスクにパスワードが保存されていないにもかかわらず、Windows のパスワードを誤って要求します。$a = New-ScheduledTaskAction -Execute 'C:\Program Files\Google\Chrome\Application\chrome.exe' ` -Argument '--remote-debugging-port=<PORT> --user-data-dir=C:\chrome-debug --no-startup-window' Set-ScheduledTask -TaskName 'chromedebug' -Action $assh wsl 'ssh windows "..."'経由での引用符の処理は不安定です。回避するには、-EncodedCommand <base64-UTF16LE>で PowerShell を実行してください。 -
古いインスタンスを終了して再起動し、動作を確認します。
Get-CimInstance Win32_Process -Filter "name='chrome.exe'" | ? { $_.CommandLine -like '*chrome-debug*' } | % { Stop-Process $_.ProcessId -Force } schtasks /run /tn chromedebug (Invoke-WebRequest -UseBasicParsing http://127.0.0.1:<PORT>/json/version).Content -
新しい
$PORTを使って、ステップ 0 のトンネルを再実行します。
**恒久的な対策(任意、管理者権限が必要):**WinNAT に取得されないようポートを予約します。net stop winnat; netsh int ipv4 add excludedportrange protocol=tcp startport=<PORT> numberofports=1 store=persistent; net start winnat。winnat を停止すると、一時的に WSL2/Hyper-V の NAT が切断されます。NAT 経由の SSH 接続が一時的に途切れることがあるため、短時間の中断が許容される場合にのみ実行してください。
重大な落とし穴 — バッテリー状態の変化でタスク スケジューラが Chrome を終了する
症状: Port の落とし穴とは逆に、デバッグ用 Chrome の プロセス が起動のたびに数分後に終了します(コマンドラインに chrome-debug を含む chrome.exe が 0 個)。一方、デバッグポートは空いていてバインド可能です。schtasks /run /tn chromedebug を実行すると CDP が復旧しますが、約 2 分以内に再び終了します。
原因: PC がノート PC で、既定の設定で作成されたタスクでは StopIfGoingOnBatteries=true / DisallowStartIfOnBatteries=true になります。充電器を接続していても、Windows の AC/バッテリー状態は数分おきに切り替わることがあります(バッテリーの充電制限機能、コネクターの緩みなど)。状態が切り替わるたびに、タスク スケジューラがタスクの Chrome を終了します。証拠となるのは、タスク スケジューラの操作ログに記録されるイベント 327 です。Task Scheduler stopped instance ... of task "\chromedebug" because the computer is switching to battery power. chromedebug タスクには修正済みの設定が適用されていますが、New-ScheduledTask/Register-ScheduledTask の既定設定を使ってタスクを再作成すると、問題の設定が気付かないうちに再び適用されます。そのため、この症状が再発したら設定を再確認してください。
診断:
-
schtasks /query /tn chromedebug /xml—<Settings>内のStopIfGoingOnBatteries/DisallowStartIfOnBatteriesはfalse、ExecutionTimeLimitはPT0S(無制限)である必要があります。そうでなければ、それが原因です。修正に進んでください。 -
タスク スケジューラの操作ログは既定で無効になっています。有効にして、次に終了する際の記録を確認します。
wevtutil sl Microsoft-Windows-TaskScheduler/Operational /e:true # after a death: Get-WinEvent -LogName 'Microsoft-Windows-TaskScheduler/Operational' -MaxEvents 100 | ? { $_.Message -match 'chromedebug' } | select TimeCreated, Id, Message"switching to battery power" を含むイベント 327 があれば、この落とし穴が原因です。32x の停止イベントがまったくない場合は、Chrome 自体がクラッシュしています。タスクのアクションに
--enable-logging --v=1を追加して再現し、C:\chrome-debug\chrome_debug.logを確認してから、フラグを元に戻してください。 -
バッテリーの状態を確認します。
Get-CimInstance Win32_Battery(結果が返ればノート PC です)と、現在の AC 状態を確認する[System.Windows.Forms.SystemInformation]::PowerStatus(事前にAdd-Type -AssemblyName System.Windows.Formsを実行)を使います。
恒久的な修正 — アクションと InteractiveToken プリンシパルは維持したまま、タスクの設定を置き換えます(Set-ScheduledTask は、渡さなかった部分には手を加えません)。これを .ps1 に保存し、SSH の 2 つのホップをまたいでインラインで引用するのではなく、-EncodedCommand 経由で実行してください。
$s = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries `
-ExecutionTimeLimit ([TimeSpan]::Zero) -MultipleInstances IgnoreNew
Set-ScheduledTask -TaskName 'chromedebug' -Settings $s
# from dev-remote: encode UTF-16LE+base64, run via the double hop
B64=$(iconv -f UTF-8 -t UTF-16LE /tmp/fix.ps1 | base64 -w0)
ssh wsl "ssh windows 'powershell -NoProfile -EncodedCommand $B64'"
(-ExecutionTimeLimit をゼロにすることが重要です。指定しないと New-ScheduledTaskSettingsSet は既定で 72 時間に設定するため、3 日後に Chrome が終了します。)その後、再起動し、CDP が一度応答しただけでなく、状態の切り替わりが起きる時間を過ぎた 4~5 分後もプロセス数がゼロでないことを確認してください。これが本当のテストです。
アクセスの接続方法(および修復方法)
どちらのマシンも、Iliyas の Tailscale テールネット上のノードです。
iliyasone=100.93.231.101— ホーム PC 上の WSL マシンです。Tailscale は Windows ではなく WSL 内で実行されています。Windows ホストには WSL 経由でssh windows(→127.0.0.1:2222、キー~/.ssh/id_win)を使って接続します。Windows のループバックは WSL と共有されていないため、WSL からデバッグポートに接続するには、ステップ 0 のssh -L ... windowsトンネルが必要です。dev-remote=100.105.176.17。その~/.ssh/configにはHost wsl→100.93.231.101が設定されており、root キーは WSL マシンのauthorized_keysにあるため、テールネット経由でssh wslを実行できます。
テールネットのアドレスは自宅の IP アドレスが変わっても変わらないため、Iliyas のネットワークが変わっても再設定は不要です。connect.sh が失敗する場合(または手動確認で NO_CDP と表示される場合)は、次の項目を確認してください。
- 接続先がオフライン(PC がスリープ中/WSL が起動していない):
tailscale statusにiliyasoneがオフラインと表示されます。dev-remote 側からできることはありません。 - Chrome が起動していないが
ssh wslは機能する:「起動」を参照してください。 - ポートが WinNAT に奪われている:「ポートに関する注意点」を参照してください。
- 再起動直後に Chrome がまた終了する:「終了に関する注意点」を参照してください。
- トンネルが起動していない:
connect.shを再実行してください(両方のホップを再構築します)。 - テールネット経路上の MTU ブラックホール(2026-08-15 に確認):
pingは機能するものの、ssh wslがexpecting SSH2_MSG_KEX_ECDH_REPLYで停止する場合、または小さな CDP 呼び出し(/json/version)は機能する一方で、大きな呼び出し(/json/list)が何も返さない場合は、dev-remote とiliyasoneの間で大きなパケットが破棄されています。修正は 2 つあります。すべての wsl への ssh で小さな従来型の KEX を強制します(-o [email protected],curve25519-sha256— デフォルトの耐量子 sntrup761 KEX は大きすぎるパケットを送信します)。また、dev-remote のインターフェース MTU を下げます:ip link set dev tailscale0 mtu 1200(デフォルトの 1280 は実際の経路 MTU を超えています)。MTU の設定は dev-remote の再起動後は維持されませんが、connect.shは高速パス以外の実行時に毎回再適用します。それでも大きな転送が停止する場合は、ip link show tailscale0を確認してください。MTU を修正する前に開いたトンネルは、壊れた MSS のままです。MTU の変更後に再起動してください。
現在、テールネット上にある自宅のノードは 1 台(iliyasone)だけです。Iliyas が後日別のマシンから作業する場合は、別の名前と IP アドレスを持つ独立したノードとして参加させ、そのノードに Host wsl(または Host wsl-<name>)を向けてください。テールネット外の経路を勝手に作らないでください。