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

TlsServer

TlsServer لایه TLS سمت server در WaterWall است و از OpenSSL استفاده می‌کند. TLS record‌های رمزنگاری‌شده را از node قبلی می‌گیرد، یک handshake واقعی در سمت server انجام می‌دهد و application data رمزگشایی‌شده را به node بعدی می‌فرستد. داده cleartext برگشتی نیز دوباره رمزنگاری می‌شود و به‌شکل TLS record به node قبلی برمی‌گردد.

رفتار این node شبیه یک TLS terminator عمومی مانند nginx stream است، نه nginx http. خود node HTTP، HTTP/2، Trojan، VLESS یا هر application protocol دیگری را که بعد از TLS قرار دارد تجزیه نمی‌کند.

جایگاه رایج​

chain سمت server برای HTTP:

TcpListener -> TlsServer -> HttpServer

chain همراه با proxy protocol:

TcpListener -> TlsServer -> TrojanServer -> TcpUdpConnector
TcpListener -> TlsServer -> VlessServer -> TcpUdpConnector

TLS termination عمومی قبل از routing:

TcpListener -> TlsServer -> Router

node بعدی application data را به‌شکل cleartext دریافت می‌کند، نه TLS record.

نمونه ساده​

[
{
"name": "tls-server",
"type": "TlsServer",
"settings": {
"cert-file": "/etc/waterwall/fullchain.pem",
"key-file": "/etc/waterwall/privkey.pem",
"min-version": "TLSv1.2",
"max-version": "TLSv1.3",
"select-alpns": ["http/1.1"],
"session-cache": "none",
"session-tickets": true,
"verbose": false
},
"next": "http-server"
},
{
"name": "http-server",
"type": "HttpServer",
"settings": {},
"next": "service"
}
]

نمونه fallback​

{
"name": "tls-server",
"type": "TlsServer",
"settings": {
"cert-file": "/etc/waterwall/fullchain.pem",
"key-file": "/etc/waterwall/privkey.pem",
"fallback-node-name": "nginx-fallback",
"fallback-intentional-delay-ms": 7,
"fallback-intentional-delay-jitter-ms": 1,
"select-alpns": ["http/1.1"]
},
"next": "protected-protocol"
}

fallback فقط تا پیش از قطعی شدن مسیر TLS قابل انتخاب است. کاربردش رسیدگی به probe‌های plaintext یا malformed روی یک پورت عمومی TLS است، نه مسیریابی application پس از authentication.

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

فیلدهای top-level:

fieldtypeتوضیح
namestringنام دلخواه node؛ باید داخل config یکتا باشد.
typestringباید دقیقاً "TlsServer" باشد.
settingsobjectتنظیمات TLS server؛ نباید خالی باشد.
nextstringnode‌ای که پس از موفقیت TLS داده cleartext را دریافت می‌کند؛ در استفاده معمول لازم است.

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

fieldtypeتوضیح
cert-filestringمسیر فایل PEM certificate سرور.
key-filestringمسیر فایل PEM private key سرور.

هر دو فایل باید برای OpenSSL context معتبر باشند.

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

fielddefaultتوضیح
sniتنظیم نشدهفقط client‌هایی را می‌پذیرد که SNI آن‌ها دقیقاً برابر این مقدار باشد.
select-alpns["http/1.1"]فهرست انتخاب ALPN به‌ترتیب ترجیح server.
alpnsتنظیم نشدهنام قدیمی تنظیم ALPN؛ بهتر است از select-alpns استفاده کنید.
min-version"TLSv1.2"حداقل TLS version.
max-version"TLSv1.3"حداکثر TLS version.
ciphers"HIGH:!aNULL:!MD5"OpenSSL cipher string برای TLS 1.2 و قدیمی‌تر.
prefer-server-ciphersfalseserver cipher preference را فعال می‌کند.
session-timeout300عمر TLS session به ثانیه.
handshake-timeout-ms60000مهلت قطعی برای کامل شدن TLS handshake؛ مقدار 0 آن را غیرفعال می‌کند.
session-cache"none"حالت session cache.
session-cache-size20480اندازه cache داخلی OpenSSL.
session-ticketstrueTLS session ticket‌ها را فعال می‌کند.
fallback-node-nameتنظیم نشدهbranch جایگزین برای ورودی‌ای که پیش از قطعی شدن مسیر TLS، آشکارا غیر TLS است. نام‌های fallback-node و fallback هم پذیرفته می‌شوند.
fallback-intentional-delay-ms7تأخیر عمدی برای payload‌های upstream در fallback؛ در delay غیرصفر jitter اعمال می‌شود. در 0، fallback مقداردهی‌شده که FIFO قدیمی یا drain زمان‌بندی‌شده ندارد حتی هنگام Pause، payload را inline می‌گیرد؛ بایت‌های نگه‌داشته‌شده بدون انتظار برای Resume و به‌ترتیب FIFO تخلیه می‌شوند.
fallback-intentional-delay-jitter-ms1jitter تصادفی برای زمان‌بندی payload‌های fallback؛ اگر delay صفر باشد نادیده گرفته می‌شود.
tls13-record-shapingتنظیم نشدهتنظیم آزمایشی padding و delay سمت فرستنده برای TLS 1.3.
verbosefalseجزئیات بیشتری از lifecycle مربوط به TLS را log می‌کند.

نمی‌توانید sni و fallback را هم‌زمان تنظیم کنید؛ وگرنه ممکن بود یک ClientHello معتبر با SNI متفاوت به‌عنوان plaintext به fallback برسد و رفتار سرور را قابل fingerprint کند.

شکل‌دهی آزمایشی TLS 1.3 record​

تنظیم tls13-record-shaping به‌صورت اختیاری نخستین application record‌های TLS 1.3 را که همین node می‌فرستد pad می‌کند و به تأخیر می‌اندازد. اگر این تنظیم وجود نداشته باشد، قابلیت غیرفعال است. این قابلیت هرگز ciphertext دریافتی، handshake record‌ها، alert‌ها، application record‌های خالی، بایت‌های fallback یا record‌های TLS 1.2 را تغییر نمی‌دهد. اگر باید هر دو جهت ارسال شکل داده شوند، TlsServer محلی و TlsClient راه دور را جداگانه تنظیم کنید.

فرم سفارشی:

"tls13-record-shaping": {
"scope": {"first-application-records": 8},
"outcomes": [
{
"probability": 50,
"padding-bytes": [100, 200],
"delay": {"probability": 75, "ms": [10, 20]}
},
{"probability": 10, "padding-bytes": [400, 600]}
]
}

padding-bytes و delay.ms یک integer یا بازه integer شامل دو سر [minimum, maximum] می‌پذیرند. تعداد outcome‌ها باید بین ۱ تا ۱۶ باشد؛ first-application-records بین ۱ تا ۱۰۲۴، padding بین ۱ تا ۴۰۹۶ byte و delay بین ۰ تا ۱۰۰۰ millisecond است. probability‌های outcome به‌صورت تجمعی و mutually exclusive تفسیر می‌شوند و مجموع آن‌ها نباید از ۱۰۰ بیشتر باشد. هر بار حداکثر یک outcome انتخاب می‌شود و درصد استفاده‌نشده record را بدون تغییر می‌گذارد. probability مربوط به delay فقط پس از انتخاب همان outcome بررسی می‌شود. key ناشناخته و مقدار غیرinteger یا خارج از محدوده باعث خطای startup می‌شود. هر record واجد شرایط یک جایگاه از scope مصرف می‌کند، حتی اگر هیچ outcome‌ای انتخاب نشود.

در حال حاضر فقط فرم سفارشی شامل scope و outcomes پذیرفته می‌شود. تا زمانی که اندازه‌گیری‌های representative برای capture، overhead، موفقیت connection و classifier انتشار یک preset versionشده را توجیه نکنند، key به نام profile رد می‌شود.

padding از بایت‌های صفر استاندارد TLS 1.3 در TLSInnerPlaintext استفاده می‌کند و به‌اندازه انتخاب‌شده به ciphertext می‌افزاید، البته تا ظرفیت قانونی باقی‌مانده در TLS record. Delay پس از رمزنگاری اعمال می‌شود و latency انتخاب‌شده را اضافه می‌کند. ترتیب record‌ها روی wire با رابطه release_at = max(now + delay, previous_release_at) حفظ می‌شود. ciphertext صف‌شده برای هر line حداکثر ۸ MiB است؛ در ۶ MiB یک Pause محلی برای producer و در ۳ MiB یک Resume محلی ارسال می‌شود. Pause و Resume دریافتی، حتی اگر تکراری باشند، شفاف عبور می‌کنند. خروجی ciphertext در زمان مقرر و با ترتیب FIFO بدون انتظار برای Resume تخلیه می‌شود؛ Pause تایمر تخلیه را لغو نمی‌کند. پس از آنکه close_notify همتا سمت cleartext را پایان داد، TlsServer هیچ payload، Pause یا Resume‌ای به آن سمت نمی‌فرستد؛ application بایت‌هایی که بعداً دریافت شوند یا پیش‌تر توسط یک callback بیرونی رمزگشایی شده باشند دور ریخته می‌شوند. اگر سمت cleartext پایان یابد، ciphertext پذیرفته‌شده server و یک close_notify بدون padding پیش از downstream Finish تخلیه می‌شوند. پایان سمت wire خروجی صف‌شده را لغو و دور می‌ریزد و فقط به سمت cleartext منتقل می‌شود. اگر ساخت timer شکست بخورد، record‌ها فوراً و به‌ترتیب تخلیه می‌شوند.

پس از مصرف کامل scope تنظیم‌شده برای application record‌ها، ابتدا صف فعلی shaping به‌طور کامل تخلیه می‌شود تا هیچ TLS record بعدی از ciphertext تأخیردار سبقت نگیرد. تا زمانی که این مانع ترتیب‌دهی فعال است، درخواست توقف محلی shaping حتی پایین‌تر از low watermark باقی می‌ماند؛ Resume عبوری همچنان مشورتی است. وقتی صف خالی باشد و write-BIO در یک مرز کامل قرار داشته باشد، timer و صف shaping مربوط به line آزاد می‌شوند؛ خروجی‌های بعدی TLS بدون parse کردن record یا نگه‌داری metadata شکل‌دهی، حتی هنگام Pause مستقیم forward می‌شوند. بنابراین محدودیت ۸ MiB و watermark‌های ۶/۳ MiB فقط پنجره محدود و فعال shaping را مقید می‌کنند. رمزنگاری و رمزگشایی TLS ادامه دارد؛ پایان shaping به معنی bypass دائمی tunnel نیست.

record shaping می‌تواند اندازه و زمان‌بندی record‌های ابتدایی را کمتر قابل پیش‌بینی کند، اما نمی‌تواند یک round trip داخلی handshake را حذف کند، burst را کوچک‌تر کند یا همه ویژگی‌های جهت و زمان‌بندی را پنهان کند. وقتی multiplexing برای deployment مناسب است، آن را همراه MuxClient/MuxServer استفاده کنید.

TLS Version‌ها​

مقادیر قابل قبول:

TLSv1
TLSv1.1
TLSv1.2
TLSv1.3
TLS1.0
TLS1.1
TLS1.2
TLS1.3
1.0
1.1
1.2
1.3

min-version نباید از max-version بزرگ‌تر باشد.

ALPN Selection​

TlsServer از ALPN فقط برای انتخاب protocol استفاده می‌کند، نه برای کنترل دسترسی.

ترتیب اعضای array همان ترتیب ترجیح server است:

"select-alpns": ["h2", "http/1.1"]

اگر client هر دو مقدار را ارائه کند، h2 انتخاب می‌شود. اگر ALPN ارسال‌شده با هیچ گزینه‌ای مشترک نباشد، handshake بدون ALPN توافق‌شده ادامه پیدا می‌کند. وقتی client اصلاً ALPN نفرستد، callback انتخاب در OpenSSL اجرا نمی‌شود و handshake باز هم بدون ALPN ادامه می‌یابد.

mode‌های select-alpns:

Configurationرفتار
نوشته نشدهمقدار پیش‌فرض ["http/1.1"] به کار می‌رود.
[]انتخاب ALPN کاملاً غیرفعال می‌شود.
array غیرخالینخستین مقدار تنظیم‌شده‌ای انتخاب می‌شود که client نیز آن را ارائه کرده باشد.

alpns قدیمی است، اما همچنان خوانده می‌شود. هر عضو می‌تواند یک string یا objectی با فیلد value باشد. alpns و select-alpns را هم‌زمان با مقدار غیرخالی تنظیم نکنید.

ALPN، protocol انتخاب‌شده را به tunnel‌های بعدی اعلام نمی‌کند. اگر h2 را ارائه می‌کنید، chain بعد از TlsServer باید واقعاً بتواند رفتاری قابل‌قبول برای HTTP/2 نشان دهد؛ در غیر این صورت deployment راحت‌تر fingerprint می‌شود.

session Cache​

مقادیر پشتیبانی‌شده برای session-cache:

valueرفتار
"none"حالت server cache در OpenSSL، با lookup و store داخلی غیرفعال؛ مقدار پیش‌فرض.
"off"session cache را غیرفعال می‌کند.
"builtin"cache داخلی server در OpenSSL را با session-cache-size فعال می‌کند.
"builtin:SIZE"cache داخلی را فعال می‌کند و اندازه را همان‌جا می‌گیرد؛ برای مثال "builtin:4096".

حالت shared در پیاده‌سازی فعلی پشتیبانی نمی‌شود.

رفتار در runtime​

TlsServer مقداردهی اولیه line را فقط از طریق upstream Init می‌پذیرد. فراخوانی downstream Init در هر حالتی، از جمله هنگام تخلیه نهایی fallback، استفاده نادرست و fatal از callback است؛ node خطا را ثبت و فرایند را خاتمه می‌دهد. payload پاسخ در جهت downstream همچنان روی line‌هایی که از upstream مقداردهی اولیه شده‌اند پشتیبانی می‌شود.

در upstream Init، TlsServer:

  1. state مربوط به OpenSSL را برای line می‌سازد
  2. memory BIO‌ها را می‌سازد
  3. SSL object را در server mode قرار می‌دهد
  4. مگر با handshake-timeout-ms: 0، deadline مربوط به handshake را فعال می‌کند
  5. اگر fallback تنظیم نشده باشد، branch محافظت‌شده next را بلافاصله راه می‌اندازد
  6. در صورت وجود fallback، منتظر بایت‌های اولیه می‌ماند تا مسیر TLS یا fallback را انتخاب کند

بایت‌های رمزنگاری‌شده upstream از node قبلی وارد OpenSSL می‌شوند. پس از پایان TLS handshake، application data رمزگشایی‌شده به next می‌رود.

داده cleartext برگشتی از next تا کامل شدن TLS handshake در صف می‌ماند. سپس با SSL_write() رمزنگاری می‌شود و به‌شکل TLS record در جهت downstream فرستاده می‌شود.

مفهوم Establishment​

در WaterWall، Est یعنی transport زیرین برقرار شده است؛ نه اینکه TLS handshake هم پایان یافته باشد.

TlsServer downstream Est را فقط یک بار می‌فرستد و ممکن است این اتفاق پیش از پایان TLS handshake رخ دهد. آماده بودن TLS در state داخلی و پس از پایان handshake در OpenSSL مشخص می‌شود.

رفتار fallback​

fallback فقط تا پیش از قطعی شدن مسیر TLS قابل انتخاب است.

classifier، بایت‌های ابتدایی upstream را بررسی می‌کند:

  • بایت‌هایی که آشکارا TLS نیستند به fallback می‌روند
  • بایت‌هایی که شبیه TLS handshake شروع می‌شوند، مانند 16 03، در مسیر TLS می‌مانند
  • با تولید ServerHello توسط OpenSSL، مسیر line روی branch محافظت‌شده TLS قطعی می‌شود

با شروع fallback، TlsServer منابع TLS مربوط به line را آزاد و branch جایگزین را مقداردهی اولیه می‌کند. در عملیات عادی و delay غیرصفر، بایت‌های ذخیره‌شده و batch‌های upstream بعدی با delay و jitter تنظیم‌شده فرستاده می‌شوند. در delay صفر، fallback مقداردهی‌شده که FIFO قدیمی یا drain زمان‌بندی‌شده ندارد حتی هنگام Pause، payload را inline می‌گیرد. بایت‌های نگه‌داشته‌شده بدون انتظار برای Resume و با ترتیب FIFO تخلیه می‌شوند؛ ورودی جدید از آن‌ها سبقت نمی‌گیرد. از آن به بعد payload‌ها بدون رمزنگاری یا رمزگشایی TLS از fallback عبور می‌کنند.

handshake‌هایی که ظاهر TLS دارند اما malformed، بیش‌ازحد بزرگ، ناقص یا کند هستند در همان مسیر TLS بسته می‌شوند؛ پس از تشخیص اولیه دیگر به fallback فرستاده نخواهند شد.

تأخیر fallback فقط روی payload‌های upstream در عملیات عادی اعمال می‌شود و FIFO آن تا 1 MiB برای هر line محدود است. پاسخ‌های downstream عمداً به تأخیر نمی‌افتند. اگر upstream Finish برسد، بایت‌های صف‌شده حتی هنگام Pause به‌صورت همگام و به‌ترتیب FIFO پیش از Finish fallback تخلیه می‌شوند. اگر Init هنوز روی stack باشد، batch دور ریخته می‌شود. delay باقی‌مانده پس از Finish زنده نگه داشته نمی‌شود. این node برای انتخاب branch خارج از مسیر عادی next فعال می‌ماند و bypass نمی‌شود.

پیش از Init branch منتخب، آخرین Pause دریافتی فقط برای بازپخش پس از Init نگه داشته می‌شود و Resume آن را لغو می‌کند. پس از Init همه Pause و Resumeها به branch منتخب می‌رسند و خروجی منتظر آن‌ها نمی‌ماند.

برای camouflage روی یک پورت عمومی، بهتر است fallback یک سرویس واقعی TLS، معمولاً nginx، با certificate، SNI، ALPN، cipher، ticket و نسخه protocol مشابه TlsServer باشد. قرار دادن HTTP ساده پشت یک پورت عمومی TLS معمولاً خیلی راحت‌تر fingerprint می‌شود.

مسیریابی بر اساس SNI با fallback واقعی TLS​

وب‌سرور Nginx دو ورودی غیرمنتظره عمومی روی HTTPS listener را از یکدیگر متمایز می‌کند:

  1. درخواست Plaintext HTTP روی پورت HTTPS: Nginx یک درخواست عادی روی پورت HTTPS را در داخل با وضعیت 497 دسته‌بندی می‌کند. اگر error_page سفارشی نشده باشد، پاسخ پیش‌فرض معمولاً همان صفحه HTML قابل‌شناسایی با وضعیت بیرونی 400 است. گزینه fallback-node-name در TlsServer این حالت را با هدایت بایت‌های غیر TLS پیش از تعهد به TLS به سمت node fallback مدیریت می‌کند. بخش پردازش خطاهای SSL در مستندات Nginx را ببینید.
  2. پیام TLS ClientHello با SNI ناشناخته یا متفاوت: اتصال ابتدا در context سرور پیش‌فرض Nginx ساخته می‌شود و اگر SNI منطبق پیدا نشود، handshake معمولاً با certificate و تنظیمات همان context کامل می‌شود. سرور پیش‌فرض می‌تواند با تنظیم صریح ssl_reject_handshake on این handshake‌ها را رد کند. بخش انتخاب virtual server در Nginx را ببینید.

تنظیم TlsServer.sni مدل رد صریح handshake (ssl_reject_handshake on) را پیاده می‌کند، نه مسیریابی default vhost در Nginx. از آنجا که TlsServer.sni نمی‌تواند با fallback-node-name ترکیب شود، برای سناریوهایی که نیازمند استتار کامل Nginx هستند (که در آن SNI ناشناخته، عدم ارسال SNI و درخواست‌های plaintext همگی به یک Nginx HTTPS listener واقعی برسند)، باید SniffRouter پیش از TlsServer قرار گیرد:

TcpListener :443 -> SniffRouter
|-- route (expected SNI) -> TlsServer -> protected backend
`-- default (unmatched) -> TcpConnector -> real nginx HTTPS listener

الگوی config مینیمال:

{
"name": "sniff-router",
"type": "SniffRouter",
"settings": {
"routes": [
{
"domain": "vpn.example.com",
"detection": "tls",
"next": "protected-tls-server"
}
]
},
"next": "nginx-fallback-connector"
}

در این معماری:

  • node SniffRouter پیش از پایان TLS، مقدار SNI در ClientHello آشکار را بررسی و دسته‌بندی می‌کند.
  • پیام‌های ClientHello منطبق به TlsServer هدایت می‌شوند (که نباید fallback-node-name داشته باشد). استفاده از فیلتر sni در TlsServer اختیاری و به عنوان بررسی redundant fail-closed است، نه مکانیزم اصلی مسیریابی.
  • پیام‌های ClientHello با SNI آشکار نامنطبق، پیام‌های فاقد SNI آشکار و ترافیک plaintext به شاخه پیش‌فرض next در SniffRouter و به Nginx واقعی بدون رمزگشایی هدایت می‌شوند.
  • ECH مقدار SNI درونی را پنهان می‌کند، اما ClientHello بیرونی آن ممکن است همچنان نام سرور آشکاری داشته باشد. SniffRouter بر اساس همان مقدار بیرونی مسیریابی می‌کند: نام بیرونی منطبق به شاخه محافظت‌شده می‌رود و نام بیرونی نامنطبق یا غایب به شاخه پیش‌فرض می‌رود. این node نمی‌تواند بر اساس نام درونی رمزنگاری‌شده مسیریابی کند.
  • پیام‌های کامل ClientHello پیش از اعمال حد آستانه buffer ارزیابی می‌شوند. ورودی‌های ناقصی که کمتر از سقف ۸۱۹۲ بایت هستند در حالت انتظار می‌مانند و مشمول idle timeout در listener اولیه (مانند TcpListener) خواهند بود.
  • برای مشاهده config کامل، فایل tests/examples/vless_tls_sni_camouflage_server.json را بررسی کنید.

محدودیت‌ها و مرزهای شناسایی:

  • مقدار SNI تنها متادیتای مسیریابی است، نه احراز هویت: هر کلاینتی که SNI مورد انتظار را بداند به TlsServer محافظت‌شده می‌رسد. احراز هویت باید در لایه‌های درونی پروتکل (مانند VLESS یا Trojan) انجام گیرد.
  • رفتار پروتکل درونی همچنان قابل مشاهده است: بایت‌های پاسخ رد یا fallback، شیوه بسته‌شدن اتصال و timing پس از رسیدن probe به SNI محافظت‌شده همچنان می‌توانند پروتکل درونی یا deployment را آشکار کنند.
  • سلامت و پاسخ‌دهی fallback: در صورت در دسترس نبودن سرور Nginx پشتیبان یا تفاوت در رفتارهای certificate/ALPN/cipher/session، سرویس قابل شناسایی خواهد بود.
  • تایمینگ و timeout‌ها: buffering در SniffRouter و اتصال مجدد تأخیر اندکی ایجاد می‌کنند. زمان‌های timeout در TcpListener را با سرور پوششی هماهنگ کنید. WaterWall ادعای یکسان‌بودن کامل تایمینگ یا تطابق بایت‌به‌بایت اثر انگشت TLS را ندارد.

handshake timeout​

handshake-timeout-ms مهلتی قطعی است که با مقداردهی line آغاز می‌شود و دریافت بایت‌های جدید آن را تمدید نمی‌کند. این زمان از timeout‌های listener، مانند initial-idle-timeout-ms و active-idle-timeout-ms در TcpListener، مستقل است.

فقط زمانی handshake-timeout-ms را 0 بگذارید که عمداً هیچ deadline قطعی برای TLS handshake نمی‌خواهید.

رفتار Finish​

برای بستن تمیز جهت downstream، اگر TLS handshake کامل شده باشد TlsServer ابتدا alert مربوط به TLS close_notify را می‌فرستد و flush می‌کند. سپس state محلی TLS را از بین می‌برد و WaterWall Finish را در جهت downstream ادامه می‌دهد.

اگر peer یک TLS shutdown تمیز بفرستد، TlsServer آن را Finish در جهت upstream و به سمت node بعدی در نظر می‌گیرد.

خطاهای fatal در OpenSSL باعث پاک شدن state محلی و بسته شدن جهت‌های لازم می‌شوند. در fallback mode، branch جایگزین نیز پیش از بسته شدن سمت قبلی بسته می‌شود؛ delay باقی‌مانده برای Finish نگه داشته نمی‌شود.

padding​

TlsServer مستقیماً چیزی به ابتدای payload‌های WaterWall اضافه نمی‌کند، بنابراین مقدار زیر را اعلام می‌کند:

required_padding_left = 0

ساخت TLS record‌ها از طریق memory BIO‌های OpenSSL انجام می‌شود.

نکته‌های Nginx Matching​

مقادیر پیش‌فرض برای شباهت به رفتار عادی TLS server در nginx stream انتخاب شده‌اند. تغییر گزینه‌های زیر ممکن است همچنان TLS معتبری بسازد، اما خروجی دیگر شبیه آن baseline نخواهد بود:

  • ciphers
  • min-version یا max-version
  • prefer-server-ciphers
  • session-cache
  • session-tickets
  • ALPN selection
  • sni
  • fallback target و fallback timing

اگر هدفتان شباهت در سطح wire به nginx پیش‌فرض است، این مقدارها را تغییر ندهید مگر اینکه اندازه‌گیری مشخصی دلیل آن را نشان داده باشد.

اشتباه‌های رایج​

  • انتظار نداشته باشید TlsServer خودش HTTP را تجزیه کند؛ برای این کار HttpServer را بعد از آن قرار دهید.
  • sni را با fallback ترکیب نکنید.
  • از ALPN برای authentication یا رد کردن اتصال استفاده نکنید؛ نبودن ALPN مشترک، handshake را بدون ALPN توافق‌شده ادامه می‌دهد.
  • h2 را اعلام نکنید مگر اینکه هر دو مسیر محافظت‌شده و fallback بتوانند پاسخی قابل‌قبول برای HTTP/2 بدهند.
  • از shared برای session cache استفاده نکنید؛ پیاده‌سازی نشده است.

متادیتای node​

متادیتای برگرفته از کد منبع:

این node با kNodeFlagBlocksSplice استفاده از splice را برای کل chain صریحاً غیرفعال می‌کند. این پرچم حتی در صورت وجود هم‌زمان kNodeFlagSupportsSplice اولویت دارد.

ویژگیمقدار
node flagskNodeFlagBlocksSplice
can_have_prevtrue
can_have_nexttrue
layer_groupkNodeLayer4
layer_group_prev_nodekNodeLayer4
layer_group_next_nodekNodeLayer4
required_padding_left0 بایت