ObfuscatorClient
ObfuscatorClient پیش از آنکه ترافیک به سمت transport برود، یک تبدیل برگشتپذیر روی payload اعمال میکند. در پیادهسازی فعلی تنها روش پشتیبانیشده XOR است.
این نود باید با یک ObfuscatorServer جفت شود که method، key و گزینههای header یکسانی دارد. این فقط یک لایه سبک برای شکلدهی و مبهمسازی ترافیک است و رمزنگاری به شمار نمیآید. اگر به محرمانگی یا احراز هویت نیاز دارید، از EncryptionClient/EncryptionServer یا TLS استفاده کنید.
ObfuscatorClient با 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:
TunDevice -> ObfuscatorClient -> packet transport
packet transport -> ObfuscatorServer -> RawSocket
وقتی payload یک packet خام IPv4 است و headerها باید برای مسیریابی، تزریق یا خروجی packet خوانا بمانند، از skip: "ipv4" یا skip: "transport" استفاده کنید.
این نود چه میکند؟
- مقدار
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 ندارد.
از آنجا که XOR متقارن است، اجرای دوباره همان تبدیل با همان key، payload اصلی را بازیابی میکند.
نمونه تنظیم
{
"name": "obfuscator-client",
"type": "ObfuscatorClient",
"settings": {
"method": "xor",
"xor_key": 90,
"skip": "transport",
"tls_record_header": true
},
"next": "transport-node"
}
سرور متناظر:
{
"name": "obfuscator-server",
"type": "ObfuscatorServer",
"settings": {
"method": "xor",
"xor_key": 90,
"skip": "transport",
"tls_record_header": true
},
"next": "service-node"
}
فیلدهای اجباری
فیلدهای top-level:
| فیلد | نوع | توضیح |
|---|---|---|
name | string | نامی که کاربر برای نود انتخاب میکند؛ باید در فایل config یکتا باشد. |
type | string | باید دقیقاً "ObfuscatorClient" باشد. |
settings | object | اجباری. باید method و xor_key داشته باشد. |
next | string | در استفاده معمول الزامی است. نود بعدی payloadهای obfuscateشده در جهت upstream را دریافت میکند. |
فیلدهای اجباری داخل settings:
| فیلد | نوع | توضیح |
|---|---|---|
method | string | در پیادهسازی فعلی باید "xor" باشد. |
xor_key | integer | کلید XOR. مقدار در یک بایت ذخیره میشود؛ بنابراین مقادیر خارج از 0..255 به uint8_t تبدیل میشوند. |
تنظیمات اختیاری
| گزینه | نوع | پیشفرض | توضیح |
|---|---|---|---|
skip | string | "none" | مشخص میکند کدام headerهای ابتدایی packet پیش از XOR دستنخورده بمانند. مقدارهای مجاز "none"، "ipv4" و "transport" هستند. |
tls_record_header | boolean | false | یک header پنجبایتی شبیه TLS application-data را به payload سمت transport اضافه میکند یا از آن برمیدارد. |
tls_header | boolean | تنظیم نشده | نام مستعار قدیمی 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 فعال باشد، upstream payload های سمت transport اینطور ارسال میشوند:
17 03 03 + length(2 bytes, big-endian) + obfuscated payload
این bytes یک TLS application-data record header را تقلید میکنند:
| فیلد | مقدار |
|---|---|
| content type | 23 / 0x17 |
| legacy version | 0x0303 |
| length | طول payload obfuscated شده، ۱۶ بیتی big-endian |
در مسیر دریافت downstream، ابتدا header اعتبارسنجی و حذف میشود و سپس XOR اجرا میشود.
این قابلیت TLS نیست: نه handshake دارد، نه certificate، SNI یا ALPN و نه رمزنگاری و احراز هویت. تنها ظاهر یک TLS application-data record پس از handshake را تقلید میکند.
محدودیتهای مهم:
- payloadهای بزرگتر از
65535بایت هنگام wrap شدن کنار گذاشته میشوند - headerهای ناقص هنگام حذف شدن کنار گذاشته میشوند
- recordهایی که طول اعلامشدهشان دقیقاً با طول buffer فعلی payload برابر نیست کنار گذاشته میشوند
- buffer جداگانهای برای reassembly رکوردها وجود ندارد؛ بنابراین هر callback دریافت payload باید دقیقاً یک 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 بایتبهبایت با کلید یکبایتی تنظیمشده است.
نکتههای عملی
ObfuscatorClientوObfuscatorServerبایدmethod،xor_key،skipوtls_record_headerیکسان داشته باشند.- این قابلیت obfuscation است، نه امنیت رمزنگاریشده.
skip: "none"برای byte streamهای معمولی سادهترین حالت است.skip: "transport"برای packetهای خام IPv4 TCP/UDP که IP و transport headerهایشان باید قابل خواندن بمانند مفید است.- اگر headerهای packet خام را obfuscate کنید، ممکن است packet خروجی در مسیر downstream دیگر قابل مسیریابی نباشد؛ حتی اگر واتروال checksumها را برای محاسبه دوباره علامتگذاری کند.