پرش به مطلب اصلی

ObfuscatorServer

ObfuscatorServer همتای سمت سرور ObfuscatorClient است. این دو نود باید از تبدیل برگشت‌پذیر، method، key و گزینه‌های header یکسان استفاده کنند.

در پیاده‌سازی فعلی تنها روش پشتیبانی‌شده XOR است. این نود برای شکل‌دهی و مبهم‌سازی ترافیک به کار می‌رود و یک لایه رمزنگاری نیست.

ObfuscatorServer با packet-tunnel API واتروال ساخته می‌شود و به‌ازای هر line، tunnel state جداگانه‌ای ندارد. بایت‌های payload درجا تغییر می‌کنند؛ مگر در حالت header شبیه TLS که برای فراهم کردن فضای خالی کافی در سمت چپ، ممکن است buffer کپی شود.

جایگاه رایج

مسیر TCP ساده:

client side: TcpListener -> ObfuscatorClient -> TcpConnector
server side: TcpListener -> ObfuscatorServer -> TcpConnector

مسیر UDP:

client side: UdpListener -> ObfuscatorClient -> UdpConnector
server side: UdpListener -> ObfuscatorServer -> UdpConnector

مسیر raw packet:

packet transport -> ObfuscatorServer -> RawSocket

مقدارهای skip و tls_record_header باید با سمت client یکسان باشند.

این نود چه می‌کند؟

  • مقدار settings.method: "xor" الزامی است.
  • وجود settings.xor_key الزامی است.
  • پیش از فرستادن payload در جهت upstream به next، روی بایت‌های آن XOR اعمال می‌کند.
  • در صورت فعال بودن گزینه مربوط، پس از XOR در مسیر upstream یک header پنج‌بایتی شبیه TLS record به ابتدای payload اضافه می‌کند.
  • در مسیر downstream، در صورت فعال بودن گزینه مربوط، پیش از XOR همان header پنج‌بایتی را برمی‌دارد.
  • پیش از فرستادن payload در جهت downstream به نود قبلی، روی بایت‌های آن XOR اعمال می‌کند.
  • می‌تواند header مربوط به IPv4 یا مجموعه headerهای IPv4 و TCP/UDP را بدون obfuscation باقی بگذارد.
  • پس از تغییر بایت‌ها، payloadهای packet-line را برای محاسبه دوباره checksum علامت‌گذاری می‌کند.
  • payloadها را در buffer نگه نمی‌دارد و per-line state ندارد.

پیاده‌سازی سرور قرینه پیاده‌سازی client است. نام‌های client و server فقط نقش آن‌ها در deployment را مشخص می‌کنند؛ خود تبدیل متقارن است.

نمونه تنظیم

{
"name": "obfuscator-server",
"type": "ObfuscatorServer",
"settings": {
"method": "xor",
"xor_key": 90,
"skip": "transport",
"tls_record_header": true
},
"next": "service-node"
}

client متناظر:

{
"name": "obfuscator-client",
"type": "ObfuscatorClient",
"settings": {
"method": "xor",
"xor_key": 90,
"skip": "transport",
"tls_record_header": true
},
"next": "transport-node"
}

فیلدهای اجباری

فیلدهای top-level:

فیلدنوعتوضیح
namestringنامی که کاربر برای نود انتخاب می‌کند؛ باید در فایل config یکتا باشد.
typestringباید دقیقاً "ObfuscatorServer" باشد.
settingsobjectاجباری. باید method و xor_key داشته باشد.
nextstringاجباری در استفاده معمولی. نود بعدی upstream payloadهای transform شده را دریافت می‌کند.

فیلدهای اجباری داخل settings:

فیلدنوعتوضیح
methodstringباید "xor" باشد در پیاده‌سازی فعلی.
xor_keyintegerکلید XOR. مقدار در یک بایت ذخیره می‌شود؛ بنابراین مقادیر خارج از 0..255 به uint8_t تبدیل می‌شوند.

تنظیمات اختیاری

گزینهنوعپیش‌فرضتوضیح
skipstring"none"مشخص می‌کند کدام headerهای ابتدایی packet پیش از XOR دست‌نخورده بمانند. مقدارهای مجاز "none"، "ipv4" و "transport" هستند.
tls_record_headerbooleanfalseیک header پنج‌بایتی شبیه TLS application-data را به payload سمت transport اضافه می‌کند یا از آن برمی‌دارد.
tls_headerbooleanتنظیم نشدهنام مستعار قدیمی tls_record_header است. همچنان پذیرفته می‌شود، اما یک warning در log ثبت می‌شود.

حالت‌های Skip

skip تعیین می‌کند چند بایت ابتدایی payload از XOR مستثنا باشند:

مقداررفتار
"none"کل payload XOR می‌شود.
"ipv4"اگر payload یک packet معتبر IPv4 باشد، header آن دست‌نخورده می‌ماند و بایت‌های بعدی XOR می‌شوند.
"transport"اگر payload یک packet معتبر TCP/UDP روی IPv4 باشد، headerهای IPv4 و TCP/UDP دست‌نخورده می‌مانند. برای سایر protocolهای IPv4 فقط header مربوط به IPv4 دست‌نخورده می‌ماند.

اگر payload بیش از حد کوتاه باشد یا packet معتبر IPv4 نباشد، طول skip برابر 0 در نظر گرفته می‌شود و کل payload XOR خواهد شد.

در حالت skip: "transport"، اگر header مربوط به TCP/UDP ناقص یا نامعتبر باشد، پیاده‌سازی فقط header مربوط به IPv4 را دست‌نخورده باقی می‌گذارد.

Header شبیه TLS

وقتی tls_record_header فعال باشد، payload های سمت transport این‌طور ارسال می‌شوند:

17 03 03 + length(2 bytes, big-endian) + obfuscated payload

این bytes یک TLS application-data record header را تقلید می‌کنند:

فیلدمقدار
content type23 / 0x17
legacy version0x0303
lengthطول payload obfuscated شده، ۱۶ بیتی big-endian

در مسیر دریافت، ابتدا header اعتبارسنجی و حذف می‌شود و سپس XOR اجرا می‌شود.

هشدار

این قابلیت TLS نیست: نه handshake دارد، نه certificate، SNI یا ALPN و نه رمزنگاری و احراز هویت. تنها ظاهر یک TLS application-data record پس از handshake را تقلید می‌کند.

محدودیت‌های مهم:

  • payloadهای بزرگ‌تر از 65535 بایت هنگام wrap شدن کنار گذاشته می‌شوند
  • headerهای ناقص هنگام حذف شدن کنار گذاشته می‌شوند
  • recordهایی که طول اعلام‌شده‌شان دقیقاً با طول buffer فعلی payload برابر نیست کنار گذاشته می‌شوند
  • reassembly buffer record وجود ندارد، پس payload callback های سمت receive باید دقیقاً یک TLS-like record کامل داشته باشند

رفتار جهت‌ها

callback ورودیرفتار
upstream Payloadبر اساس skip XOR را اعمال می‌کند، در صورت فعال بودن گزینه مربوط header شبیه TLS را به ابتدا می‌افزاید، نیاز به محاسبه دوباره checksum در packet-line را علامت می‌زند و payload را به next می‌فرستد.
downstream Payloadدر صورت فعال بودن گزینه مربوط header شبیه TLS را اعتبارسنجی و حذف می‌کند، بر اساس skip XOR را اعمال می‌کند، نیاز به محاسبه دوباره checksum در packet-line را علامت می‌زند و payload را به نود قبلی می‌فرستد.
downstream Initبه نود قبلی فرستاده می‌شود.
سایر lifecycle callbackهااز رفتار پیش‌فرض packet-tunnel استفاده می‌کنند. تغییر payload رفتار اصلی این نود است.

در source فایل‌های معمول callbackهای pass-through نیز وجود دارند، اما مسیر فعلی ساخت نود، علاوه بر رفتارهای پیش‌فرض packet-tunnel، فقط override مربوط به downstream Init و overrideهای payload در دو جهت را نصب می‌کند.

Buffer و Padding

متادیتای نود:

required_padding_left = 5
layer_group = kNodeLayerAnything

این پنج بایت برای header اختیاری شبیه TLS در نظر گرفته شده‌اند. اگر هنگام فعال بودن tls_record_header فضای خالی سمت چپ buffer کافی نباشد، نود payload را در buffer تازه‌ای با padding کافی کپی می‌کند، buffer قبلی را به pool برمی‌گرداند و سپس header را اضافه می‌کند.

وقتی line فعلی worker packet line باشد، نود بعد از transform کردن payload bytes مقدار recalculate_checksum = true را تنظیم می‌کند.

نکته‌های Implementation

XOR helper مسیرهای بهینه دارد:

  • AVX2 وقتی در دسترس باشد
  • aligned 64-bit chunk processing روی buildهای ۶۴ بیتی
  • aligned 32-bit یا byte-wise fallback در غیر این صورت

این مسیرها تنها روی کارایی اثر می‌گذارند؛ رفتار قابل مشاهده همچنان XOR بایت‌به‌بایت با کلید یک‌بایتی تنظیم‌شده است.

نکته‌های عملی

  • ObfuscatorServer و ObfuscatorClient باید method، xor_key، skip و tls_record_header یکسان داشته باشند.
  • این قابلیت obfuscation است، نه امنیت رمزنگاری‌شده.
  • skip: "none" برای byte streamهای معمولی ساده‌ترین حالت است.
  • skip: "transport" برای packetهای خام IPv4 TCP/UDP که IP و transport headerهایشان باید قابل خواندن بمانند مفید است.
  • اگر فقط به رمزنگاری امن نیاز دارید، از EncryptionClient و EncryptionServer استفاده کنید.