Trojan は、HTTPS の Web サイトを守っているのと同じ暗号化技術である TLS の中に隠れるプロキシプロトコルです。デバイスは通常 443 番ポートでサーバと普通の TLS 接続を開き、その中でパスワードと接続したいアドレスを送ります。パスワードが間違っていれば、サーバは普通の Web サイトとしてふるまいます。そのため外から見ると、Trojan プロトコルの通信は日常的な HTTPS のブラウジングと見分けがつきません。
この記事では、Trojan とは何か、どう動くのか、トランスポートと REALITY、長所と短所、trojan:// リンクの読み方を解説します。すぐに設定したい方は iPhone で Trojan を設定する方法 をご覧ください。
Trojan プロトコルとは?
名前とは裏腹に、Trojan はマルウェアとは何の関係もありません。名前はトロイの木馬に由来し、プロキシ通信が無害でありふれたものの中に紛れて運ばれることを表しています。
Trojan は独自の暗号化を発明していません。暗号化は TLS に任せ、その上にごく小さなヘッダー(パスワードのハッシュ、コマンド、接続先アドレス)を加えるだけです。そのためプロトコルはシンプルで、暗号化には銀行やブラウザでも使われている、十分に検証された TLS がそのまま使われます。
設計の狙いは、周囲の通信に溶け込むことです。現在のインターネット通信の大半は 443 番ポートの HTTPS です。Trojan サーバは本物のドメイン名と証明書を持ってそのポートで待ち受け、正規の Trojan クライアント以外からの接続には本物の Web ページを返します。
簡単な歴史
最初の実装である trojan-gfw は C++ で書かれ、2019 年ごろに登場しました。仕様はプロジェクトの プロトコルページ で公開されています。続いて Go で書き直された trojan-go が登場し、WebSocket トランスポートと多重化が追加されました。現在では Xray、sing-box、Mihomo など多くのマルチプロトコル対応サーバ・クライアントに Trojan が組み込まれており、これらのプロジェクトでさらにトランスポートや REALITY への対応が加わりました。
Trojan の仕組み
- TLS ハンドシェイク。 クライアントがサーバ(通常は 443 番ポート)に接続し、
trojan.example.comなどのサーバ名(SNI)を指定して TLS を開始します。サーバはその名前に対応する有効な証明書を提示します。 - Trojan リクエスト。 暗号化された接続の中で、クライアントはパスワードの SHA-224 ハッシュ、コマンド(connect または UDP associate)、接続先(例:
example.org:443)を送ります。 - 照合。 サーバはハッシュを登録ユーザのパスワードと照合します。
- 中継またはフォールバック。 ハッシュが一致すれば、サーバは接続先につないで双方向にデータを中継します。一致しなければ、接続全体をフォールバック用の Web サーバに引き渡すので、アクセスした側には普通の Web サイトが表示されます。
- UDP。 UDP パケットは、同じ TLS 接続の中にフレーム化されて運ばれます。
iPhone ──TLS (SNI trojan.example.com)──▶ Trojan server ──▶ example.org
│
wrong password ──────┴──▶ ordinary website (fallback)
このフォールバックこそが、Trojan と Shadowsocks の違いです。サーバを探査する接続には、接続の切断ではなく普通の Web ページが返ってきます。
トランスポート:TLS のみ、WebSocket、gRPC
素の Trojan は TLS の上で直接動きます。多くのサーバは、Trojan の通信を別のプロトコルの中に入れて運ぶトランスポートも提供しています。
- WebSocket は通常の HTTPS リクエストの中で動きます。CDN やリバースプロキシは WebSocket を扱えるので、サーバを CDN の背後に置いて本当の IP アドレスを隠せます。
- gRPC は HTTP/2 の上で動き、こちらも多くの CDN やリバースプロキシを通過できます。
- HTTP/2 と HTTP Upgrade も、一部のサーバで使われている同様の選択肢です。
トランスポートを使うとオーバーヘッドが増え、パスやサービス名など正しく設定すべき項目も増えます。サーバがそのように構成されている場合にだけ使ってください。
REALITY を使った Trojan
従来の Trojan サーバには、自前のドメインと証明書が必要です。Xray プロジェクトで生まれた REALITY を使えば、それが不要になります。サーバは、無関係な実在の Web サイトの TLS ハンドシェイクを借ります。サーバの公開鍵とショート ID を知っているクライアントはプロキシを利用でき、それ以外の接続は本物の Web サイトにそのまま転送されます。
REALITY は通常 VLESS と組み合わせて使われますが、Trojan サーバでも使えます。詳しくは VLESS + REALITY とは? をご覧ください。
長所と短所
長所
- 443 番ポートの普通の HTTPS に見える。
- 探査に対して、無応答ではなく本物の Web サイトで応答する。
- 独自の暗号ではなく、標準の TLS を使う。
- 実装がシンプルなため、幅広く対応している。
- TCP だけでなく UDP も運べる。
短所
- REALITY を使わない限り、ドメインと有効な証明書が必要。
- クライアントの TLS ハンドシェイクがブラウザのものと異なる場合がある。クライアントにはブラウザのフィンガープリントに合わせるオプションがあるが、あくまで模倣にすぎない。
- Trojan 経由で HTTPS サイトを閲覧するときのように TLS の中で TLS を使うと、パケットサイズやタイミングにパターンが残り得ることが研究者によって示されている。
- パスワードが間違っていてもエラーにならず、フォールバックの Web サイトが表示されるだけなので、ミスに気づきにくい。
- TCP 接続の中を通る UDP はパケットロスの影響を受けやすく、ゲームや通話では体感に影響する。
Trojan・Shadowsocks・VLESS・VMess の比較
| Trojan | Shadowsocks | VLESS | VMess | |
|---|---|---|---|---|
| 暗号化 | TLS | 独自の暗号方式 | TLS または REALITY | 独自(TLS は任意) |
| 見た目 | HTTPS | ランダムなバイト列 | HTTPS | ランダムなバイト列、TLS 使用時は HTTPS |
| 証明書の要否 | 必要、または REALITY | 不要 | 必要、または REALITY | TLS 使用時のみ |
| UDP | 対応 | 対応 | 対応 | 対応 |
| 認証情報 | パスワード | パスワードまたはキー | UUID | UUID |
さらに詳しい比較は、Shadowsocks とは?、VMess と VLESS の違い、プロキシプロトコル比較 をお読みください。
trojan:// リンクの見方
プロバイダは Trojan サーバを trojan:// リンクで共有し、QR コードで提供することもよくあります。
trojan://password@host:port?parameters#name
passwordはサーバのパスワードで、パーセントエンコードされています。hostとportはサーバのアドレスとポートです(省略時は 443)。parametersは TLS とトランスポートの設定です。sniはサーバ名、typeはトランスポート(tcp、ws、grpc)、hostとpathは WebSocket 用、serviceNameは gRPC 用、security=realityとpbk、sidは REALITY 用です。nameはアプリに表示される名前です。
パスワードが secret の場合の例です。
trojan://secret@trojan.example.com:443?sni=trojan.example.com#Basic
trojan://secret@trojan.example.com:443?security=tls&type=ws&host=cdn.example.com&path=%2Fws#WebSocket
trojan://secret@trojan.example.com:443?security=tls&type=grpc&serviceName=TrojanGun#gRPC
trojan://secret@trojan.example.com:443?security=reality&sni=www.example.com&pbk=Z84J2IelR9ch3k8VtlVhhs5ycBUlXA7wHBWcBrjqnAw&sid=0123abcd&fp=chrome#REALITY
Potatso が読み取るパラメータはすべて Trojan リファレンス に記載しています。
iPhone で Trojan を使う
iOS には Trojan の標準サポートがないため、クライアントアプリが必要です。Potatso は iPhone・iPad 向けの無料プロキシクライアントで、trojan:// と trojan-go:// のリンク、QR コード、Clash サブスクリプションを読み込めます。WebSocket、gRPC、HTTP/2、HTTP Upgrade、REALITY にも対応しています。手順は iPhone で Trojan を設定する方法 で詳しく解説しています。
よくある質問
- Trojan プロキシプロトコルはウイルスですか?
- いいえ。Trojan はプロキシプロトコルであり、マルウェアではありません。名前の由来はトロイの木馬で、プロキシ通信をごく普通の HTTPS 接続の中に隠すことからそう呼ばれています。デバイスに害を与えるという意味ではありません。
- Trojan にはドメイン名と証明書が必要ですか?
- 従来の Trojan サーバは本物の TLS 接続を使うため、ドメイン名と有効な TLS 証明書が必要です。REALITY を使う Trojan サーバは、代わりに別の Web サイトの TLS ハンドシェイクを借りるので、自前の証明書は不要です。
- Trojan はどのポートを使いますか?
- 通常は HTTPS の標準ポートである 443 番を使い、接続を普通の Web 通信のように見せます。サーバ側で設定すればどのポートでも使えます。ポートを省略した trojan:// リンクは 443 番を使います。
- Trojan は UDP に対応していますか?
- はい。Trojan は TCP と同じ TLS 接続の中で UDP も運びます。Potatso を含む Clash 互換のクライアントでは、Trojan サーバの UDP はデフォルトでオフになっているため、サーバが UDP を中継する場合はオンにしてください。
- Trojan は Shadowsocks より優れていますか?
- ネットワーク環境によります。Trojan は HTTPS のように見え、探査に対しても本物の Web サイトのように応答します。一方、Shadowsocks はよりシンプルで証明書が不要、オーバーヘッドも小さめです。両方を提供しているプロバイダも多いので、それぞれ試してみるとよいでしょう。