diff --git a/content/blog/_index.fa.md b/content/blog/_index.fa.md new file mode 100644 index 0000000..7f52dfe --- /dev/null +++ b/content/blog/_index.fa.md @@ -0,0 +1,11 @@ +--- +title: Blog, but in Farsi +toc: true +--- + +
+{{< hextra/hero-badge link="index.xml" >}} + RSS Feed + {{< icon name="rss" attributes="height=14" >}} +{{< /hextra/hero-badge >}} +
diff --git a/content/blog/transports.fa.md b/content/blog/transports.fa.md new file mode 100644 index 0000000..a65cb7f --- /dev/null +++ b/content/blog/transports.fa.md @@ -0,0 +1,135 @@ +--- +title: معرفی ترنسپورت های v2ray +date: 2024-08-01 +--- + +## پیش‌زمینه +**یادداشت**: برای جزئیات تاریخی از بهترین سطح اطلاعاتم استفاده کردم. اما در موردشون مطمئن نیستم. + +برنامه v2ray در ابتدا با vmess-tcp شروع شد. به مرور زمان، vmess (توسط فایروال) تشخیص داده شد و v2ray فانکشنالیتی‌هایی برای تبدیل سوکت TCP به زیرساختی در لایه‌ای پایین تر اضافه کرد. + +* یکی از این لایه‌ها، ترنسپورت‌ها هستن، هدف اصلی این داکیومنت. + +* بسته به فرک v2rayای که استفاده میکنید، mux هم می‌تواند یکی دیگر از این لایه‌ها باشد. + +* تی‌ال‌اس(TLS) لایه واقعی نیست. تنظیمات TLS به دست کد ترنسپورت میرسه و ترنسپورت میتونه هر کاری بخواد با اون بکنه. اگرچه اکثر ترنسپورت ها به شکل مشابه از `tlsSettings` استفاده میکنن. + +به هرحال برگردیم سراغ ترنسپورت‌ها. + +در v2ray ترنسپورت *هرچیزی* هست که توانایی درست کردن زیرساخت ارتباط دو طرفه بین سرور و کلاینت رو داشته باشه. سوکت های TCP دقیقا همین کار رو میکنن، ولی لازم نیست حتما TCP باشند، یا حتی بر پایه TCP باشند. فقط کافیه بایت ها رو به ترتیب از کلاینت به سرور(و برعکسش) بدون از دست دادنش منتقل کنه. + +زمانی که این ارتباط وجود داشته باشه، Vmess, VLESS و تروجان (یا هر پروتکلی) با استفاده از اون ترنسپورت میتونن متصل بشن. ولی برای ساده شدن کار، در این مقاله پروتکل ها نادیده گرفته شده و فقط چند خط متن منتقل میکنیم. + + +## پیش‌نیاز ها +شما به یک ترمینال لینوکس نیاز خواهید داشت. هر چیزی که اینجا نوشتم در اوبونتو ۲۴ انجام شده ولی تفاوتی ندارد. می‌تونید از WSL یا VirtualBox روی ویندوز استفاده کنید یا با ssh دستورات رو روی یک سرور یا vps اجرا کنید. + +## اولین ترنسپورت +میخوایم با چند تا دستور لینوکس ببینیم که یک ترنسپورت چه کار هایی می‌تونه انجام بده. اول از یک چیز ساده شروع میکنیم. + +یک ترمینال باز کنید و دستور زیر رو وارد کنید: +``` +nc -l localhost 6003 # سرور +``` +و در یک ترمینال دیگه: +``` +nc localhost 6003 # کلاینت +``` + +اگر دستور nc رو ندارید می‌تونید با `sudo apt install netcat` نصبش کنید. + +در داخل یکی از ترمینال ها متن بنویسید، می‌بینید که داخل اون یکی ظاهر میشه و دو طرفست. + +این دستور معادل ترنسپورت TCP در v2ray هست. برای تست اینکه یه پورت TCP باز هست یا نه میتونید هاست و پورت رو عوض کنید. + +## وبسوکت + +وبسوکت یک پروتکل مبتنی بر HTTP هست که عملا همون کار سوکت TCP رو انجام میده. تفاوت اصلیش اینه: + +۱. وبسوکت اول هر کانکشن یه هندشیک بزرگ http اضافه میکنه. این کار برای کوکی، آتنتیکیشن، داشتن چند سرویس وبسوکت پشت path های مختلف و برای وادار کردن وبسایت ها که فقط بتونند به منشا خودشون کانکشن باز کنند مفیده. + اگر نیت ساخت ترنسپورت باشه بعضی از این قابلیت ها بخصوص مسیریابی بر اساس path، نسبتا مفیدند، ولی [در مجموع] هندشیک اول اتصال، لیتنسی اضافه میکنه. + +۲. وبسوکت بایت منتقل نمیکنه، "پیام" منتقل میکنه. در tcp برای جابجا کردن hello world، کافیه "hello world" منتقل بشه. در حالی که در وبسوکت باید 'hello world' منتقل بشه. برای کاربرد ترنسپورت، این طراحی فقط اضافه بار(اورهد) ایجاد میکنه و خاصیتی نداره. + +دلیل این که با این قضیه کنار اومدیم اینه که بعضی cdn ها میتونن وبسوکت رو همینطور که هست فروارد کنن. + +همونطور که `nc` عملا یه ترنسپورت TCP هست، ابزار هایی مثل [websocat](https://github.com/vi/websocat/) هم عملا ترنسپورت websocket هستن. با استفاده از توضیحات README بایست وبسوکت رو نصب کنید. + +این ابزار رو برای تست اینکه وبسوکت روی مسیر خاصی اجرا شده هم می‌تونید بکار ببرید: + +``` +curl https://example.com # example.com سرویس اچ‌تی‌تی‌پی درستی هست +websocat wss://example.com # ولی وبسوکت نیست. پس این دستور با خطا تموم میشه +``` + +اگر `websocat` روی سرور v2rayاتون اجرا نمیشه ولی `curl` می‌تونه بازش کنه، احتمالا به این معنیه که path رو جایی اشتباه تنظیم کردید. + +برای این که یه سرور وبسوکت لوکال مثل مثال قبلی `nc` بالا بیارید، باید این کار رو کنید: + +``` +websocat -s 6003 # سرور +websocat ws://localhost:6003 # کلاینت +``` + +این دفعه هم می‌تونید ببینید که هر خطی تو یک ترمینال بفرستید تو دیگری مشاهده میشه. + +از جایی که وبسوکت بر پایه HTTP/1.1 هست و HTTP/1.1 بر پایه tcp، میتونیم `websocat` رو بفرستیم روی `nc` تا خروجی هندشیک اولیه رو مشاهده کنیم: + +``` +nc -l localhost 6003 # سرور +websocat ws://localhost:6003 # کلاینت +``` + +وقتی دستور دوم رو اجرا میکنید، تو ترمینالی که دستور اول رو اجرا کردید می‌تونید خروجی مشابه خروجی زیر رو مشاهده کنید: +``` +GET / HTTP/1.1 +Host: localhost:6003 +Connection: Upgrade +Upgrade: websocket +Sec-WebSocket-Version: 13 +Sec-WebSocket-Key: 2t6m3Hm+P4RlFwVIiNPQTw== + +``` + +این بخشی از اضافه‌بار(اورهد) وبسوکته. اینجا کلاینت منتظر پاسخه. چطوره پاسخ هم با هم مشاهده کنیم؟ + +هر دو پروسه رو با `Ctrl-c` متوقف کنید و با `websocat -s 6003` یک سرور جدید راه بندازید. + +متن بالا رو بردارید و با nc مستقیما بفرستید: + +``` +echo 'GET / HTTP/1.1 +Host: localhost:6003 +Connection: Upgrade +Upgrade: websocket +Sec-WebSocket-Version: 13 +Sec-WebSocket-Key: MOIjFT7/cVsCCr95mkpCtg== +' | unix2dos | nc localhost 6003 | cat -v +``` + +۱. دستور `echo` فقط متنی که جلوش هست رو مینویسه. +۲. دستور `unix2dos` آخر خط ها رو از \n به \r\n تبدیل می‌کنه، چون در HTTP/1.1 دومی برای آخر خط استفاده میشه. +۳. دستور NC دیتا رو به سرور می‌فرسته و پاسخ سرور رو نمایش میده. +۴. دستور `cat -v` کاری می‌کنه کارکتر های اسپشل(در واقع بایت هایی که کارکتر نیستن) نمایش داده بشن. [در اینجا ^M] + +شما خروجی‌ای شبیه خروجی زیر مشاهده می‌کنید: + +``` +HTTP/1.1 101 Switching Protocols^M +Sec-WebSocket-Accept: HKN6nOSb0JT0jWhszYuKJPUPpHg=^M +Connection: Upgrade^M +Upgrade: websocket^M +``` + +از اینجا به بعد می‌تونید از سمت سرور به کلاینت دیتا بفرستید. در ترمینالی که سرور `websocat` رو اجرا کردید کلمهٔ `hello` رو بنویسید و خروجی زیر رو مشاهده می‌کنید: + +``` +M-^A^Fhello +``` + +کارکتر های اضافه‌ای که اول پیام قرار گرفته، فریمینگ(چهارچوب‌بندی) وبسوکت است. + +اینجا نمی‌تونید از سمت کلاینت به سرور پیامی بفرستید. چرا که پروتکل وبسوکت انتظار داره دیتا در همین فریمینگی که مشاهده کردید از کلاینت ارسال بشه. + +## وبسوکت 0-RTT +(خلاص شدن از شر اضافه‌بار[و لیتنسی] هندشیک) diff --git a/content/blog/transports.md b/content/blog/transports.md index 92a0614..2442a42 100644 --- a/content/blog/transports.md +++ b/content/blog/transports.md @@ -5,7 +5,7 @@ aliases: - /transports.html --- -Translations: [Russian](https://marzban.dev/blog/about_transport/) +Translations: [Russian](https://marzban.dev/blog/about_transport/), [Farsi](../../fa/blog/transports/) ## Background diff --git a/custom.css b/custom.css new file mode 100644 index 0000000..2b0bf25 --- /dev/null +++ b/custom.css @@ -0,0 +1,5 @@ +/* https://github.com/rust-lang/mdBook/issues/2316#issuecomment-1967370177 */ +#content > main:nth-child(1) > * { + text-align: start; + unicode-bidi: plaintext; +} diff --git a/hugo.yaml b/hugo.yaml index c1803f2..6a975d1 100644 --- a/hugo.yaml +++ b/hugo.yaml @@ -19,6 +19,17 @@ outputs: term: - html +defaultContentLanguage: en +languages: + en: + languageName: English + weight: 1 + fa: + languageName: فارسی + languageCode: fa + languageDirection: rtl + weight: 2 + markup: # allow raw html goldmark: @@ -36,6 +47,11 @@ menu: weight: 1 params: type: blog + - name: Farsi Blog + pageRef: /fa/blog + weight: 2 + params: + type: blog - name: GitHub weight: 3 url: "https://github.com/mmmray"