Sudoku
Sudoku یک پراکسی رمزشده روی TCP است که بایتهایش را به شکل سرنخهای جدولهای کوچک سودوکو پنهان
میکند. میتوانید خروجی را طوری تنظیم کنید که شبیه متن ساده باشد یا تصادفیبودنی کم و ثابت داشته باشد،
بهجای اینکه شبیه نویز تصادفی باشد. این همان inbound و outbound با "type": "sudoku" است. TCP را
حمل میکند و UDP را هم درون همان اتصال TCP. این پروتکل Sudoku از
saba-futai/sudoku است که mihomo هم از آن پشتیبانی میکند و از
sing-box-extended به اینجا منتقل شده است.
چرا از آن استفاده کنیم
- شبکه ترافیکی را که کاملاً تصادفی به نظر میرسد مسدود میکند، مثل Shadowsocks یا VMess ساده.
- میخواهید ترافیک شبیه متن ساده باشد (
prefer_ascii) یا از همان بایت اول شبیه HTTP باشد. - تونل HTTP یا WebSocket میخواهید که پشت CDN کار کند (
stream،poll،ws).
هزینهاش سرعت است: هر بایتی که آپلود میکنید دستکم چهار بایت روی شبکه میشود.
چطور از فیلترینگ عبور میکند
برخی فیلترها اتصالهایی را که بایتهایشان کاملاً تصادفی است مسدود میکنند، چون پروتکلهای عادی ساختاری از خود نشان میدهند. Sudoku هیچوقت بایتهای رمزشدهاش را مستقیم نمیفرستد. بهجایش سرنخهای سودوکو میفرستد و شما انتخاب میکنید که این سرنخها چه شکلی باشند:
prefer_entropy(پیشفرض): بایتهای روی شبکه از الگوی بیتی ثابتی پیروی میکنند، پس ترافیک از دادهٔ رمزشده کمتر تصادفی است.prefer_ascii: همهٔ بایتهای روی شبکه نویسههای چاپیاند، پس ترافیک شبیه متن است.custom_table: خودتان تعیین میکنید کدام بیتهای هر بایت سرنخ را حمل کنند، پس الگو با دیگر سرورهای Sudoku فرق دارد.
ماسک HTTP یا یک درخواست HTTP به ابتدای اتصال اضافه میکند (legacy)، یا کل اتصال را به شکل
درخواستهای واقعی HTTP یا WebSocket اجرا میکند که CDN میتواند آنها را عبور دهد (stream، poll،
ws، auto).
محدودیتها:
- فیلتر میتواند الگوی بایتی یک حالت را یاد بگیرد و مسدودش کند. جدولها و ماسک HTTP این کار را سختتر میکنند، نه ناممکن.
- ماسک
legacyفقط یک درخواست HTTP جعلی است که پس از آن دادهٔ غیر HTTP میآید. از CDN، یا از فیلتری که بعد از درخواست اول را هم میخواند، عبور نمیکند. - بدون ماسک HTTP و TLS، دستدادن TLS در کار نیست، پس فیلتری که فقط TLS را اجازه میدهد آن را مسدود میکند.
- وقتی IP سرور مسدود است کمکی نمیکند، مگر اینکه آن را پشت CDN بگذارید.
چطور کار میکند
- هر مقدار بایت جدول سودوکوی ۴×۴ مخصوص خودش را دارد که با کلید از میان ۲۸۸ جدول ممکن انتخاب میشود. فرستنده چهار سرنخ میفرستد، هر کدام جایگاه یک خانه و مقدارش، که فقط با همان جدول جور درمیآیند. گیرنده جدول را پیدا میکند و بایت را برمیگرداند. هر بایت مجموعههای سرنخ ممکن زیادی دارد و فرستنده یکی را تصادفی و با ترتیب تصادفی انتخاب میکند.
- هر سرنخ یک بایت روی شبکه است، پس ترافیک آپلود چهار برابر میشود. بایتهای پرکنندهٔ تصادفی هم
لابهلای آن قرار میگیرند (
padding_minتاpadding_max). - ترافیک دانلود بهطور پیشفرض همین کدگذاری را دارد. با
enable_pure_downlink: falseاز شکل فشردهای استفاده میکند که حدود یک و یکسوم برابر داده است و سریعتر است. - درون این کدگذاری، داده با
aead_methodرمز میشود. دستدادن با X25519 کلیدهای تازهٔ نشست میسازد و تکرار (replay) را رد میکند. - ساعت کلاینت و سرور باید کمتر از ۶۰ ثانیه با هم فاصله داشته باشد، وگرنه دستدادن شکست میخورد.
- با
multiplex: "on"چند اتصال یک نشست Sudoku را با هم به اشتراک میگذارند.
پیکربندی
به برچسب ساخت with_sudoku نیاز دارد. بدون آن، کانفیگ دارای "type": "sudoku" با خطای «Sudoku is
not included in this build, rebuild with -tags with_sudoku» متوقف میشود.
سرور:
{
"type": "sudoku",
"tag": "sudoku-in",
"listen": "::",
"listen_port": 8443,
"key": "a long random password",
"table_type": "prefer_ascii"
}
کلاینت:
{
"type": "sudoku",
"tag": "sudoku-out",
"server": "example.com",
"server_port": 8443,
"key": "a long random password",
"table_type": "prefer_ascii"
}
فیلدهای مشترک دو طرف
اینها باید در کلاینت و سرور یکسان باشند.
| فیلد | نوع | پیشفرض | معنی |
|---|---|---|---|
key |
رشته | الزامی | کلید مشترک. یا هر گذرواژهای، یا یک جفتکلید (پایینتر را ببینید). |
aead_method |
رشته | chacha20-poly1305 |
رمزنگاری داده: chacha20-poly1305، aes-128-gcm یا none. |
table_type |
رشته | prefer_entropy |
شکل بایتها روی شبکه: prefer_entropy، prefer_ascii، up_ascii_down_entropy یا up_entropy_down_ascii. «up» از کلاینت به سرور است و «down» از سرور به کلاینت. |
custom_table |
رشته | "" |
هشت حرف که تعیین میکند هر بیت از هر بایت چه چیزی را حمل کند: دقیقاً دو x، دو p و چهار v، مثلاً xpxvvpvv. فقط در جهت entropy به کار میرود. |
custom_tables |
آرایهٔ رشته | [] |
چند الگوی custom_table. کلاینت برای هر اتصال یکی را برمیدارد و سرور تشخیص میدهد کدام بوده. اگر تنظیم شود جای custom_table را میگیرد. |
padding_min |
عدد | 10 |
کمترین سهم پرکننده به درصد، از 0 تا 100. |
padding_max |
عدد | 30 |
بیشترین سهم پرکننده به درصد، از 0 تا 100. دستکم برابر padding_min. |
enable_pure_downlink |
بولی | true |
true ترافیک دانلود را مثل آپلود کدگذاری میکند. false از شکل فشرده استفاده میکند که دادهٔ کمتری مصرف میکند. |
اگر فقط یکی از padding_min و padding_max را تنظیم کنید و با پیشفرض دیگری ناسازگار باشد، دیگری
خودش را با آن هماهنگ میکند.
وقتی custom_table یا custom_tables با جهت آپلود entropy تنظیم شده باشد، سرور کلاینتهایی را هم
که جدول پیشفرض دارند میپذیرد، تا کلاینتها بتوانند یکییکی عوض شوند.
فیلدهای سرور (inbound)
فیلدهای معمول گوشدادن (listen، listen_port و…) و علاوه بر آن:
| فیلد | نوع | پیشفرض | معنی |
|---|---|---|---|
handshake_timeout |
عدد | 5 |
چند ثانیه منتظر دستدادن کلاینت بماند. حالتهای تونل HTTP دستکم 15 ثانیه صبر میکنند. |
disable_http_mask |
بولی | false |
true ماسک HTTP را خاموش میکند. |
http_mask_mode |
رشته | legacy |
legacy، stream، poll، ws یا auto. auto کلاینتهای stream، poll و ws را میپذیرد. |
path_root |
رشته | "" |
بخش اولی که پیش از همهٔ مسیرهای ماسک HTTP میآید؛ مثلاً aabbcc مسیر /aabbcc/session را میسازد. فقط حرف، رقم، _ و -. |
inbound خودش TLS ندارد. برای HTTPS یک CDN یا reverse proxy که TLS را باز میکند جلویش بگذارید.
fallback یک host:port است. اتصالی که Sudoku نیست، مثل مرورگر یا کاوشگر، همراه با آنچه تا آن لحظه
فرستاده به آن داده میشود، تا سرور شبیه سایتی باشد که آنجاست. وقتی ماسک HTTP خاموش است
(disable_http_mask) کار میکند؛ اتصالی که پیش از شکست بیش از ۶۴ کیلوبایت بفرستد بهجای آن بسته میشود.
فیلدهای کلاینت (outbound)
فیلدهای معمول سرور و اتصال (server، server_port، detour و…) و علاوه بر آن:
| فیلد | نوع | پیشفرض | معنی |
|---|---|---|---|
multiplex |
رشته | off |
off، auto یا on. on چند اتصال را روی یک نشست Sudoku اجرا میکند. auto فقط اتصالهای HTTP را در حالتهای ماسک stream، poll و auto دوباره به کار میبرد. |
http_mask |
شیء | ماسک روشن، legacy |
ماسک HTTP. بدون این شیء، ماسک در حالت legacy روشن است. |
http_mask.enabled |
بولی | false |
ماسک را روشن میکند. وقتی http_mask را اضافه کردید باید این را true بگذارید، وگرنه ماسک خاموش است. |
http_mask.mode |
رشته | legacy |
legacy، stream، poll، ws یا auto. auto اول stream و بعد poll را امتحان میکند. |
http_mask.host |
رشته | "" |
سرآیند Host و نام سرور TLS برای stream، poll، ws و auto. خالی یعنی server. |
http_mask.path_root |
رشته | "" |
همان path_root سرور. |
http_mask.multiplex |
رشته | "" |
اگر تنظیم شود جای multiplex را میگیرد. |
http_mask.tls |
شیء | ندارد | یک بلوک TLS معمولی outbound. فقط در stream، poll، ws و auto به کار میرود. |
ماسک HTTP در دو طرف
کلاینت بهطور پیشفرض ماسک را روشن میکند و ماسک سرور از disable_http_mask پیروی میکند که آن هم
بهطور پیشفرض روشن است. دو طرف را یکسان نگه دارید:
- کلاینت بدون
http_maskو سرور بدونdisable_http_mask: هر دو از ماسکlegacyاستفاده میکنند. - برای خاموش کردنش، در سرور
"disable_http_mask": trueبگذارید و به کلاینت"http_mask": { "enabled": false }بدهید. - برای حالت تونل، در هر دو طرف همان حالت را بگذارید (یا در سرور
auto)، و همانpath_rootرا.
سرور legacy کلاینتهای بدون ماسک را هم میپذیرد. سروری که ماسکش خاموش است کلاینتهای ماسکدار را
نمیپذیرد. سرور در حالت stream، poll، ws یا auto کلاینتهای legacy را نمیپذیرد.
کلیدها
key یکی از اینهاست:
- گذرواژه: همان متن در هر دو طرف.
- جفتکلید: سرور کلید عمومی را میگیرد (۶۴ نویسهٔ hex) و کلاینت یک کلید خصوصی (۶۴ یا ۱۲۸ نویسهٔ hex). کلاینت میتواند خود کلید عمومی را هم به کار ببرد. چند کلید خصوصی متفاوت میتوانند به یک کلید عمومی تعلق داشته باشند، پس هر کاربر میتواند کلید خودش را داشته باشد.
این نسخه دستوری برای ساختن جفتکلید ندارد.
خطاها
مقدار نادرست table_type، custom_table، aead_method، پرکننده، حالت، multiplex یا path_root، یا
key خالی، در هر دو طرف جلوی بارگذاری کانفیگ را میگیرد.
سازگاری
فقط میان دو نمونهٔ sing-box هیدیفای آزموده شده است: بدون ماسک، با ماسک HTTP و با prefer_ascii. با
Sudoku اصلی یا mihomo آزموده نشده است.