安全な通信のための多用途かつ効率的なプロキシ プラットフォーム。
splice(2)
を使用した Linux 上の TCP リレー高速パス。recvmmsg(2)
およびsendmmsg(2)
を使用した Linux 上の UDP リレー高速パス。 リリース パッケージと VCS パッケージは AUR で入手できます。
リリースからダウンロードします。
Go を使用して最新バージョンをビルドしてインストールします。
go install github.com/database64128/shadowsocks-go/cmd/shadowsocks-go@latest
go install github.com/database64128/shadowsocks-go/cmd/shadowsocks-go-domain-set-converter@latest
または、リポジトリのクローンを作成して手動で構築します。
go build -trimpath -ldflags ' -s -w ' ./cmd/shadowsocks-go
go build -trimpath -ldflags ' -s -w ' ./cmd/shadowsocks-go-domain-set-converter
すべての設定例と systemd ユニット ファイルは docs ディレクトリにあります。
clients
フィールドは省略することも、空のままにすることもできます。デフォルトの「直接」クライアントが自動的に追加されます。
運用サーバーでは、 udpRelayBatchSize
8 などの低い値に設定してrecvmmsg(2)
およびsendmmsg(2)
のメリットを享受しながらメモリ使用量を削減することができます。
UDP パケットは、 mtu
から計算される最大パケット サイズまでパディングされる場合があります。サーバーが PPPoE 接続から使用される可能性がある場合は、 mtu
1492 に減らす必要があります。クライアントからサーバーへの PMTU が不明な場合は、 paddingPolicy
NoPadding
に設定することでパディングを完全に無効にすることができます。
ユーザー PSK を持たないサーバー (シングルユーザー モード) の場合、 psk
フィールドは PSK を指定し、 uPSKStorePath
フィールドは省略するか空のままにすることができます。 uPSK ストア ファイルで 1 つ以上のユーザー PSK が指定されている場合、 psk
フィールドはアイデンティティ PSK を指定します。
サーバーを再起動せずにユーザーを追加/更新/削除するには、uPSK ストア ファイルを変更してサーバー プロセスにSIGUSR1
シグナルを送信するか、RESTful API を使用します。 RESTful API からの更新は、uPSK ストア ファイルに自動的に保存されます。
/etc/shadowsocks-go/config.json
{
"servers" : [
{
"name" : " ss-2022 " ,
"listen" : " :20220 " ,
"protocol" : " 2022-blake3-aes-128-gcm " ,
"enableTCP" : true ,
"listenerTFO" : true ,
"enableUDP" : true ,
"mtu" : 1500 ,
"psk" : " qQln3GlVCZi5iJUObJVNCw== " ,
"uPSKStorePath" : " /etc/shadowsocks-go/upsks.json "
}
]
}
/etc/shadowsocks-go/upsks.json
{
"Steve" : " oE/s2z9Q8EWORAB8B3UCxw== " ,
"Alex" : " hWXLOSW/r/LtNKynrA3S8Q== "
}
デフォルトでは、ルーターは設定された DNS サーバーを使用してドメイン名を解決し、IP ルールを照合します。解決された IP アドレスは、IP ルールの照合にのみ使用されます。リクエストは元のドメイン名を使用して行われます。ドメイン名の IP ルール照合を無効にするには、 disableNameResolutionForIPRules
true に設定します。
{
"servers" : [
{
"name" : " socks5 " ,
"listen" : " :1080 " ,
"protocol" : " socks5 " ,
"enableTCP" : true ,
"listenerTFO" : true ,
"enableUDP" : true ,
"mtu" : 1500
},
{
"name" : " http " ,
"listen" : " :8080 " ,
"protocol" : " http " ,
"enableTCP" : true ,
"listenerTFO" : true
}
],
"clients" : [
{
"name" : " ss-2022 " ,
"protocol" : " 2022-blake3-aes-128-gcm " ,
"endpoint" : " [2001:db8:bd63:362c:2071:a0f6:827:ab6a]:20220 " ,
"enableTCP" : true ,
"dialerTFO" : true ,
"enableUDP" : true ,
"mtu" : 1500 ,
"psk" : " oE/s2z9Q8EWORAB8B3UCxw== " ,
"iPSKs" : [
" qQln3GlVCZi5iJUObJVNCw== "
]
},
{
"name" : " direct " ,
"protocol" : " direct " ,
"enableTCP" : true ,
"dialerTFO" : true ,
"enableUDP" : true ,
"mtu" : 1500
}
],
"dns" : [
{
"name" : " cf-v6 " ,
"addrPort" : " [2606:4700:4700::1111]:53 " ,
"tcpClientName" : " ss-2022 " ,
"udpClientName" : " ss-2022 "
},
{
"name" : " system " ,
"type" : " system "
}
],
"router" : {
"defaultTCPClientName" : " ss-2022 " ,
"defaultUDPClientName" : " ss-2022 " ,
"geoLite2CountryDbPath" : " /usr/share/shadowsocks-go/Country.mmdb " ,
"domainSets" : [
{
"name" : " category-ads-all " ,
"type" : " gob " ,
"path" : " /usr/share/shadowsocks-go/ss-go-gob-category-ads-all "
},
{
"name" : " private " ,
"type" : " gob " ,
"path" : " /usr/share/shadowsocks-go/ss-go-gob-private "
},
{
"name" : " cn " ,
"type" : " gob " ,
"path" : " /usr/share/shadowsocks-go/ss-go-gob-cn "
},
{
"name" : " geolocation-!cn@cn " ,
"type" : " gob " ,
"path" : " /usr/share/shadowsocks-go/ss-go-gob-geolocation-!cn@cn "
}
],
"routes" : [
{
"name" : " ads " ,
"client" : " reject " ,
"toDomainSets" : [
" category-ads-all "
]
},
{
"name" : " direct " ,
"client" : " direct " ,
"resolver" : " cf-v6 " ,
"toDomainSets" : [
" private " ,
" cn "
],
"toPrefixes" : [
" 0.0.0.0/8 " ,
" 10.0.0.0/8 " ,
" 100.64.0.0/10 " ,
" 127.0.0.0/8 " ,
" 169.254.0.0/16 " ,
" 172.16.0.0/12 " ,
" 192.0.0.0/24 " ,
" 192.0.2.0/24 " ,
" 192.88.99.0/24 " ,
" 192.168.0.0/16 " ,
" 198.18.0.0/15 " ,
" 198.51.100.0/24 " ,
" 203.0.113.0/24 " ,
" 224.0.0.0/3 " ,
" ::1/128 " ,
" fc00::/7 " ,
" fe80::/10 " ,
" ff00::/8 "
],
"toGeoIPCountries" : [
" CN "
]
},
{
"name" : " cn-verify-ip " ,
"client" : " direct " ,
"resolver" : " system " ,
"toDomainSets" : [
" geolocation-!cn@cn "
],
"toMatchedDomainExpectedGeoIPCountries" : [
" CN "
]
}
]
}
}
docs/config.json を参照してください。
私が見た他の形式はどれもひどいものなので、shadowsocks-go には独自のドメイン セット ファイル形式があります。
心配しないでください。異なる形式間で変換する簡単な変換ツールが用意されています:shadowsocks-go-domain-set-converter
ドメイン セットのテキスト ファイルは、オプションで容量ヒント コメントで始まります。変換ツールは容量のヒントを自動的に生成します。ドメイン一致ルールには次の 4 種類があります。
domain:
ドメインと一致します。suffix:
ドメインとそのサブドメインを照合します。keyword:
ドメインにキーワードが含まれる場合に一致します。regexp:
ドメインが正規表現と一致する場合に一致します。ドメインセットのテキストファイルの例:
# shadowsocks-go domain set capacity hint 1 6 1 1 DSKR
domain:www.example.net
suffix:example.com
suffix:github.com
suffix:cube64128.xyz
suffix:api.ipify.org
suffix:api6.ipify.org
suffix:archlinux.org
keyword:dev
regexp:^adservice.google.([a-z]{2}|com?)(.[a-z]{2})?$
ドメイン セットのテキスト ファイルをロードするとき、shadowsocks-go はすべてのサフィックスをそのまま 1 つのマップにロードします。これにより、起動速度、メモリ使用量、一致速度の最適なバランスが実現されます。パフォーマンスを向上させたい場合は、変換ツールを使用してテキスト ファイルを gob 形式に変換できます。
gob 形式は基本的に同じものですが、すべてがバイナリでシリアル化されており、サフィックスの保存と照合にトライを使用します。変換ツールはサフィックスをロードしてサフィックス トライを構築し、トライとその他のルールを gob ファイルにシリアル化します。とてもきれいですね。
もちろん、私はアルゴリズムの専門家ではないので、プロセス全体にはまだ非効率な部分がたくさんあります。しかし、私にとってはそれで十分です。素晴らしい新しいアイデアがありましたら、ぜひお知らせください。
一般的に使用される一連のドメイン セットは、リリース ブランチのshadowsocks-go-domain-sets で毎週更新されます。 Arch Linux ユーザーは、AUR からshadowsocks-go-domain-sets-git パッケージをインストールできます。
https://github.com/v2fly/domain-list-community をソースとして使用してドメイン セットを生成するには、リポジトリのクローンを作成してジェネレーターを構築し、プレーンテキスト リストを生成します。
./domain-list-community -exportlists ' google,netflix '
shadowsocks-go-domain-set-converter
使用して、プレーンテキストのリストをドメイン セット ファイルに変換します。
shadowsocks-go-domain-set-converter -inDlc google.txt -outGob ss-go-gob-google
shadowsocks-go-domain-set-converter -inDlc netflix.txt -outGob ss-go-gob-netflix
shadowsocks-go は、IP 地理位置情報に MaxMind GeoLite2 Country データベースを使用します。データベースは https://github.com/Dreamacro/maxmind-geoip からダウンロードできます。 Arch Linux ユーザーは、AUR からshadowsocks-go-geolite2-country-git パッケージをインストールできます。
パケット パディング ポリシーは、Shadowsocks 2022 プロトコルに実装されています。パケット パディング ポリシーは、発信パケットにパディングを追加するかどうかを制御します。
パディングを追加するときは MTU が考慮されるため、パディングされたパケットのサイズが MTU を超えることはありません。したがって、MTU を正しく設定することが重要です。
パディング ポリシーは、Shadowsocks 2022 クライアントおよびサーバーごとに個別に構成できます。
PadPlainDNS
: 宛先ポートが 53 の場合はパディングを追加します。(デフォルト)PadAll
: すべてのパケットをパディングします。NoPadding
: パディングなし。拒否ポリシーはすべての TCP サーバーに実装されます。 TCP サーバーの拒否ポリシーは、受け入れられた接続がプロトコルのハンドシェイク プロセスに失敗した場合に呼び出されます。各プロトコルには独自のデフォルトの拒否ポリシーがあります。カスタム拒否ポリシーは、検閲回避サーバーがアクティブな調査を回避するのに役立ちます。
JustClose
: 接続を閉じるだけです。 (クリアテキストプロトコルのデフォルト)ForceReset
: 接続を強制的にリセットします。多くのプロトコルは、無効なデータを受信したときにこのように動作します。 (Shadowsocks 2022 のデフォルト)CloseWriteDrain
: FIN を送信し、EOF まで読み取りを続けます。これは通常、従来の Shadowsocks サーバーがリプレイを処理する方法です。ReplyWithGibberish
: 読み取りを続け、読み取りが返されるたびにランダムなガベージを送信します。これは、リプレイ保護のない従来の Shadowsocks サーバーの動作をエミュレートしますが、リプレイされたペイロードを実際に中継しない点が異なります。Shadowsocks 2022 サーバーは、ハンドシェイクが失敗したときに TCP 接続をフォールバック アドレスに転送するように構成できます。 unsafeFallbackAddress
フィールドをサーバー ブロックに追加して、フォールバック アドレスを指定します。起動時に、この機能を使用するとサーバーが「汚染される」という警告メッセージが表示されます。安全でないフォールバックは、TCP 接続でのみ機能します。
この機能は、脅威モデルにパス外の攻撃者のみが含まれており、ポートを再利用したり、プローブをだましてサーバーが別のものであると認識させたい場合に役立つ可能性があります。パス上の攻撃者 (通常の検閲者など) は、通常のトラフィックがフォールバック トラフィックと一致しないことを簡単に知ることができます。
安全でないストリーム プレフィックス機能を使用すると、Shadowsocks 2022 ストリーム用に事前共有されたクリアテキスト プレフィックスのペアを構成できます。プレフィックスは、単純なファイアウォールを欺くために、要求および応答ストリームの先頭に追加されます。
この機能を使用するには、 unsafeRequestStreamPrefix
とunsafeResponseStreamPrefix
クライアント ブロックとサーバー ブロックの両方に追加し、base64 エンコードでプレフィックスを指定します。クライアントとサーバーは、同じプレフィックスのペアに同意する必要があります。起動時に、この機能を使用するとクライアントとサーバーが「汚染される」ことを知らせる警告メッセージが出力されます。
AGPL-3.0以降