Shadowsocks は暗号化されたプロキシプロトコルです。デバイスは各接続を、自分とサーバだけが知っているキーで暗号化して Shadowsocks サーバに送り、サーバが代わりに Web サイトへの接続を開きます。軽量で TCP と UDP の両方を運べ、見分けのつくハンドシェイクを持たないため、通信経路上ではランダムなバイト列のように見えます。
この記事では、Shadowsocks とは何か、どう動くのか、どの暗号方式を使うべきか、プラグインの役割、ss:// リンクの読み方、そして VPN との違いを解説します。すでにサーバをお持ちなら、iPhone で Shadowsocks を設定する方法 に進んでください。
Shadowsocks とは?
Shadowsocks は 2 つの要素でできています。デバイス上のクライアントと、自分またはプロバイダが運用するサーバです。両者は同じ暗号方式とパスワード(最新の暗号方式ではキー)を共有します。アプリが接続を開くたびに、クライアントがそれを暗号化してサーバに送ります。サーバはそれを復号して本来の接続先につなぎ、双方向にデータを中継します。
このプロトコルはオープンで、shadowsocks.org で公開されている一連の「SIP」仕様にまとめられています。そのため実装が非常に多く、Rust、C、Go によるサーバがあり、sing-box、Xray、Mihomo など多くのマルチプロトコルツールにも組み込まれています。ほぼすべてのプロキシプロバイダが Shadowsocks サーバを提供できます。
簡単な歴史
- 2012 年:clowwindy として知られる開発者が、小さな Python プロジェクトとして Shadowsocks を公開しました。検閲のあるネットワークで、フル機能の VPN よりシンプルで軽いものを必要とする人々のために設計されました。
- 2015 年:原作者がプロジェクトから手を引き、GitHub からコードを削除しました。コミュニティは shadowsocks-libev、のちに shadowsocks-rust などのフォークで開発を続けました。
- 2017 年:AEAD 暗号方式(SIP004)が、元のストリーム暗号に代わって推奨されるようになり、旧設計の完全性の問題が解消されました。
- 2022 年:Shadowsocks 2022 エディション(SIP022)で、固定長のキーとリプレイ攻撃への対策が追加されました。
Shadowsocks の仕組み
iPhone のアプリが Shadowsocks サーバ経由でページを読み込むときの流れは次のとおりです。
- クライアントアプリが接続を取り込みます。iOS では VPN 構成を使ってこれを行います。
- クライアントは、接続先(例:
example.org:443)と最初のデータを共有キーで暗号化し、サーバのアドレスとポートに送ります。 - サーバがそれを復号します。パスワードや暗号方式が間違っていて復号できなければ、サーバは接続を切るだけです。
- サーバが
example.org:443に接続し、双方向にデータを中継します。こちらに返すデータはすべて暗号化されます。 - 音声通話などの UDP パケットは 1 つずつ暗号化され、同じサーバのポートに送られます。
iPhone ──(encrypted Shadowsocks)──▶ ss.example.com:8388 ──(normal connection)──▶ example.org
あいさつのやり取りも証明書の交換もありません。最初のバイト列はランダムなソルトで、その後に暗号文が続きます。そのため Shadowsocks は接続の開始が速い反面、パスワードが間違っていてもエラーメッセージは出ず、接続がタイムアウトするだけです。
Shadowsocks の暗号方式:2022、AEAD、ストリーム
暗号方式は、通信をどう暗号化するかを決めます。Shadowsocks の暗号方式には 3 つの系統があります。
| 系統 | 例 | おすすめ度 |
|---|---|---|
| 2022(SIP022) | 2022-blake3-aes-128-gcm、2022-blake3-aes-256-gcm、2022-blake3-chacha20-poly1305 |
サーバが対応していれば最良の選択 |
| AEAD(SIP004) | aes-256-gcm、aes-128-gcm、chacha20-ietf-poly1305 |
十分に安全で、対応も非常に広い |
| ストリーム | aes-256-cfb、chacha20-ietf、rc4-md5 |
旧式。サーバがこれしか提供していない場合のみ使用 |
AEAD 暗号方式はデータのまとまりごとに認証を行うため、途中で改ざんされたデータはサーバが拒否します。古いストリーム暗号は暗号化しかしないので、データを書き換えられてもどちらの側も気づけず、こうした暗号を使うサーバは探査(プロービング)されやすくなります。
2022 暗号方式はさらに一歩進んでいます。パスワードの代わりにランダムなキーを使うため、弱いパスワードの問題がありません。タイムスタンプとリプレイ対策が加わり、記録した接続をそのまま再送することもできません。さらに、複数のユーザがそれぞれのキーで 1 つのポートを共有することもできます(SIP023)。2022 のキーは固定長の Base64 で、次のコマンドで生成できます。
openssl rand -base64 16
これは 2022-blake3-aes-128-gcm 用の 16 バイトです。それ以外の 2022 暗号方式には 32 バイトが必要です。Potatso が対応する暗号方式の一覧は Shadowsocks リファレンス にあります。
Shadowsocks のプラグイン
プラグイン(SIP003)は、Shadowsocks の接続を別のレイヤーで包み、別の通信のように見せかけます。
- simple-obfs は、接続を普通の HTTP や TLS セッションの開始部分のように見せます。
- v2ray-plugin と gost-plugin は、WebSocket(必要に応じて TLS 付き)で通信を運びます。これにより CDN や Web サーバを経由できます。
- ShadowTLS、Restls、JLS は、カバーとなる Web サイトと本物の TLS ハンドシェイクを行ってから、Shadowsocks に引き継ぎます。
プラグインにはコストもあります。どれもオーバーヘッドが増え、ほとんどは TCP しか運べないため、UDP はプラグインを通らないか、使えなくなります。Cloak や kcptun のように別プログラムとして動くプラグインもあり、iOS アプリではクライアントと並べて動かすことができません。
ss:// リンクの見方
プロバイダは通常、サーバを ss:// リンク(SIP002)で共有し、QR コードで表示することもよくあります。
ss://YWVzLTI1Ni1nY206c2VjcmV0@ss.example.com:8388#Tokyo
YWVzLTI1Ni1nY206c2VjcmV0はaes-256-gcm:secretを Base64 にしたもので、暗号方式とパスワードを表します。ss.example.com:8388はサーバのアドレスとポートです。#Tokyoはアプリに表示される名前です。
2022 のサーバでは、暗号方式とキーをそのまま(パーセントエンコードして)記述し、プラグインは plugin パラメータに入れます。
ss://2022-blake3-aes-128-gcm:MTIzNDU2Nzg5MDEyMzQ1Ng%3D%3D@ss.example.com:8388#2022
ss://YWVzLTI1Ni1nY206c2VjcmV0@ss.example.com:443/?plugin=simple-obfs%3Bobfs%3Dtls%3Bobfs-host%3Dcdn.example.com#Obfs
多数のサーバを持つプロバイダは、代わりにすべてのサーバをまとめたサブスクリプション URL を提供するのが一般的です。詳しくは プロキシのサブスクリプションとは? をご覧ください。
Shadowsocks と VPN の違い
Shadowsocks は VPN と呼ばれることがよくありますが、WireGuard、OpenVPN、IPsec とは仕組みが異なります。
| Shadowsocks | 従来の VPN | |
|---|---|---|
| 運ぶもの | 個々の TCP 接続と UDP パケット | 仮想ネットワークを通るすべての IP パケット |
| ハンドシェイク | 目に見えるものはなく、ランダムなバイト列に見える | 識別可能なハンドシェイクがある |
| ルーティング | クライアントがルールでサイトごとに選べる | 通常はすべての通信、または IP 範囲で指定 |
| iPhone での利用 | クライアントアプリが必要 | IKEv2 は iOS に内蔵、その他はアプリが必要 |
| サーバから見えるもの | 接続先のサイト | 接続先のサイト |
iPhone では両者の境界があいまいになります。Shadowsocks クライアントは通信を取り込むために iOS の VPN 構成を使うので、VPN アイコンが表示されます。しかし、スマートフォンから出ていくのは VPN プロトコルではなく Shadowsocks の通信です。
どちらも匿名化ツールではありません。サーバの運営者には接続先が見えるため、信頼できるプロバイダを選ぶか、自分でサーバを運用してください。
長所と短所
長所
- シンプルかつ軽量で、オーバーヘッドがごくわずか。
- UDP を運べるので、通話、ゲーム、QUIC が使える。
- ほぼすべてのクライアント、サーバ、プロバイダが対応している。
- 最新の 2022 暗号方式と AEAD 暗号方式はよく設計されている。
短所
- 完全にランダムに見える通信は、それ自体がシグナルになり得る。このパターンが検出可能であることは研究者によって示されており、TLS ベースのプロトコルが普及した理由になっている。
- プラグインなしでは TLS による偽装ができず、プラグインを使うとほとんどの場合 UDP が使えなくなる。
- 古いサーバでは、いまだに脆弱なストリーム暗号が使われていることがある。
- 設定が間違っていても何も表示されずに失敗するため、問題の原因を突き止めにくい。
他のプロトコルとの比較
| プロトコル | 見た目 | UDP | 証明書の要否 |
|---|---|---|---|
| Shadowsocks | ランダムなバイト列 | 対応 | 不要 |
| Trojan | HTTPS | 対応(TLS 内) | 必要、または REALITY |
| VLESS + REALITY | 借用したサイトへの HTTPS | 対応 | 不要 |
| Hysteria 2 | HTTP/3(QUIC) | 対応 | 通常は必要 |
より詳しくは プロキシプロトコル比較 をお読みください。
iPhone で Shadowsocks を使う
iOS は単体では Shadowsocks を扱えないため、クライアントアプリが必要です。Potatso は iPhone・iPad 向けの無料プロキシクライアントで、ss:// リンク、QR コード、サブスクリプションの読み込みに対応し、2022 暗号方式と AEAD 暗号方式をサポートし、よく使われるプラグインも内蔵しています。手順は iPhone で Shadowsocks を設定する方法 で詳しく解説しています。
よくある質問
- Shadowsocks は VPN ですか?
- いいえ。Shadowsocks は暗号化されたプロキシプロトコルで、アプリの接続を 1 本ずつサーバ経由で中継します。一方、VPN はネットワークのパケットをすべてトンネルします。iPhone ではクライアントアプリが通信を取り込むために VPN 構成を使いますが、サーバに送られるのは Shadowsocks の通信です。
- Shadowsocks は安全ですか?
- 2022 暗号方式または AEAD 暗号方式を使えば、デバイスとサーバ間の通信は暗号化され、改ざんからも保護されます。ただし、どのサイトに接続しているかはサーバから見えるため、信頼できるサーバだけを使い、rc4-md5 のような古いストリーム暗号は避けてください。
- Shadowsocks の暗号方式はどれが最適ですか?
- サーバが対応していれば、2022-blake3-aes-128-gcm などの 2022 暗号方式を使ってください。対応していなければ aes-256-gcm か chacha20-ietf-poly1305 がおすすめです。クライアントでは、サーバに設定されている暗号方式とまったく同じものを選ぶ必要があります。
- Shadowsocks は UDP に対応していますか?
- はい。Shadowsocks は TCP だけでなく UDP も中継できるので、音声通話、ゲーム、QUIC も通せます。ただし、ほとんどのプラグインは TCP しか運べないため、プラグインを使うサーバでは、UDP はプラグインを通らずに中継されるか、まったく中継されないのが一般的です。
- Shadowsocks は検出されますか?
- 目に見えるハンドシェイクがないため、多くの VPN プロトコルよりは特徴をつかまれにくいものの、検出できないわけではありません。完全にランダムに見える通信はそれ自体が目立つことがあり、プラグインや Trojan のような TLS ベースのプロトコルが生まれたのはそのためです。