پروتکل امنیت لایه انتقال (TLS 1.3) ستون فقرات رمزنگاری ارتباطات در اینترنت امروزی است. در شبکه‌های خصوصی مجازی (VPN)، رله‌های لبه شبکه و تونل‌های کپسوله‌سازی ایمن (نظیر DNS-over-HTTPS و بسته‌های داده چندپخشی محافظت‌شده با TLS)، رمزنگاری لایه انتقال مانع از استراق سمع و تغییر محتوای بسته‌ها می‌شود.

با این حال، کتابخانه‌های مرسوم TLS در فضای کاربری (userspace) مانند OpenSSL، BoringSSL و Rustls، در هنگام فعالیت روی گیت‌وی‌های بسیار پرسرعت با گلوگاه‌های ساختاری جدی مواجه می‌شوند. در پیکربندی‌های سنتی، هر بسته‌ای که از گیت‌وی عبور می‌کند باید بارها میان بافرهای سوکت هسته و حافظه رم برنامه جابه‌جا شده و تعویض‌های مداوم زمینه پردازش (Context Switching) را به پردازنده تحمیل کند.

با ارتقای شبکه‌ها به خطوط 40GbE و 100GbE، این کپی‌کردن‌های پی‌درپی حافظه و اجرای محاسبات رمزنگاری متقارن توسط CPU، حافظه نهان (Cache) را اشباع ساخته و مانع از دستیابی به سرعت کامل کارت‌های شبکه می‌شود.

جهت حذف کامل کپی‌های غیرضروری حافظه و سپردن مستقیم محاسبات رمزنگاری متقارن به تراشه‌های سخت‌افزاری کارت شبکه، هسته لینوکس معماری Kernel TLS (یا kTLS بر پایه CONFIG_TLS) را به همراه قابلیت شتاب‌دهی سخت‌افزاری کارت‌های هوشمند SmartNIC معرفی کرده است.

+--------------------------------------------------------------------------+
|          مقایسه مسیر جریان داده: TLS فضای کاربری در برابر LINUX KTLS     |
+--------------------------------------------------------------------------+
|                                                                          |
|  [ ساختار سنتی رله TLS در فضای کاربری ]                                  |
|                                                                          |
|      ورودی NIC ──> sk_buff ──(کپی اول)──> حافظه برنامه در فضای کاربری    |
|                                                │                         |
|                                    رمزگشایی و رمزگذاری مجدد توسط CPU     |
|                                    (تخلیه مداوم کش‌های L1/L2)            |
|                                                v                         |
|      خروجی NIC <── sk_buff <──(کپی دوم)── حافظه برنامه در فضای کاربری    |
|      (نیاز به ۴ بار کپی رم و ۲ بار تعویض زمینه در هر چرخه انتقال)        |
|                                                                          |
|  ----------------------------------------------------------------------  |
|                                                                          |
|  [ ساختار انتقال بدون کپی LINUX KTLS با تخلیه سخت‌افزاری ]               |
|                                                                          |
|      ورودی کارت شبکه (DMA)                                               |
|           │                                                              |
|           v (بافر صفحات هسته / sk_buff)                                  |
|      +-------------------------------------------------------------+     |
|      |                   پشته شبکه در هسته لینوکس                  |     |
|      |                                                             |     |
|      |   موتور kTLS (CONFIG_TLS) / هدایت با eBPF Sockmap           |     |
|      |   - حذف کامل کپی داده‌ها به فضای کاربری                      |     |
|      |   - ارسال مستقیم در هسته با فراخوانی splice()               |     |
|      +-------------------------------------------------------------+     |
|           │                                                              |
|           v (خروج بدون کپی از طریق DMA)                                  |
|      موتور شتاب‌دهنده رمزنگاری روی کارت شبکه هوشمند (Mellanox / Intel)   |
|           │                                                              |
|           v                                                              |
|      ارسال بسته رمزنگاری‌شده روی فیبر نوری (دستیابی به خط کامل 100GbE)   |
|                                                                          |
+--------------------------------------------------------------------------+

گلوگاه‌های اساسی در پردازش فضای کاربری

در سرویس‌های سنتی شبکه، هدایت ترافیک رمزگذاری‌شده بار سنگینی به منابع سرور وارد می‌کند:

۱. تعداد بالای فراخوانی‌های سیستمی: برنامه‌ها با تکرار مداوم دستورهای read() یا SSL_read() مدام بین حالت کاربر و حالت هسته جابه‌جا می‌شوند. ۲. کپی دوطرفه در حافظه RAM: داده‌های دریافتی از کارت شبکه ابتدا به فضای پویا (Heap) برنامه منتقل می‌شوند. پس از بررسی، توابع write() مجدداً بسته‌ها را در بافرهای ارسالی هسته کپی می‌کنند. ۳. تخلیه مداوم حافظه نهان پردازنده: پردازش سنگین الگوریتم‌های متقارن (AES-GCM یا ChaCha20-Poly1305) داده‌های کش L1 و L2 را پاک کرده و پاسخ‌دهی به میلیون‌ها بسته بر ثانیه را کند می‌سازد.

در سرورهایی با کارت‌های 100GbE، این محدودیت فیزیکی سرعت یک هسته پردازنده را به حدود ۱۸ الی ۲۵ گیگابیت بر ثانیه محدود نگه می‌دارد.

معماری Linux kTLS: جداسازی دست‌تکانی و انتقال رکوردها

فناوری Kernel TLS با تقسیم وظایف این چالش را مرتفع می‌سازد:

  • لایه کنترل در فضای کاربری: وظایف پیچیده دارای وضعیت متغیر—شامل اعتبارسنجی زنجیره گواهی‌های X.509، مذاکره پروتکل‌های ALPN و تبادل کلیدهای نامتقارن (ECDHE یا الگوریتم‌های پساکوانتوم)—همچنان در کتابخانه‌های فضای کاربری (مانند OpenSSL) باقی می‌ماند.
  • لایه داده در هسته: به محض اتمام دست‌تکانی و محاسبه کلیدهای متقارن نشست، برنامه این کلیدها را از طریق دستور setsockopt() به لایه سوکت هسته تحویل می‌دهد.

از آن مرحله به بعد، هسته لینوکس قالب‌بندی رکوردهای TLS، افزایش شماره‌های توالی و عملیات رمزگذاری/رمزگشایی را مستقیماً در حین تبادل داده (tcp_sendmsg و tcp_recvmsg) مدیریت می‌کند.

+--------------------------------------------------------------------------+
|                  مراحل راه‌اندازی پروتکل KTLS در هسته لینوکس             |
+--------------------------------------------------------------------------+
|                                                                          |
|    ۱. برقراری اتصال اولیه در لایه TCP                                    |
|                                                                          |
|    ۲. اجرای کامل دست‌تکانی TLS 1.3 در فضای کاربری (OpenSSL)              |
|       - توافق روی الگوریتم: TLS_AES_256_GCM_SHA384                       |
|       - استخراج کلیدهای متقارن و مقادیر IV                               |
|                                                                          |
|    ۳. فعال‌سازی ULP پروتکل kTLS روی سوکت:                                |
|       setsockopt(fd, SOL_TCP, TCP_ULP, "tls", sizeof("tls"));            |
|                                                                          |
|    ۴. انتقال پارامترهای رمزنگاری به هسته:                                |
|       setsockopt(fd, SOL_TLS, TLS_TX, &crypto_info, sizeof(info));       |
|       setsockopt(fd, SOL_TLS, TLS_RX, &crypto_info, sizeof(info));       |
|                                                                          |
|    ۵. تبادل مستقیم داده‌ها در هسته:                                      |
|       هسته بسته‌بندی، رمزنگاری و بررسی اصالت را خودکار انجام می‌دهد      |
|       برنامه‌ها به سادگی از splice() و MSG_ZEROCOPY بهره می‌برند         |
|                                                                          |
+--------------------------------------------------------------------------+

نحوه پیاده‌سازی kTLS در برنامه‌های کاربردی

نمونه فعال‌سازی kTLS بر روی یک سوکت فعال از طریق OpenSSL 3.0+:

#include <sys/socket.h>
#include <netinet/tcp.h>
#include <linux/tls.h>
#include <openssl/ssl.h>

int enable_ktls_session(SSL *ssl, int socket_fd) {
    /* مرحله ۱: فعال‌سازی قابلیت kTLS */
    SSL_set_options(ssl, SSL_OP_ENABLE_KTLS);

    /* مرحله ۲: اتمام دست‌تکانی TLS 1.3 */
    if (SSL_accept(ssl) <= 0) {
        return -1;
    }

    /* مرحله ۳: اطمینان از عملکرد kTLS در هسته */
    if (BIO_get_ktls_send(SSL_get_wbio(ssl))) {
        /* هسته لینوکس رمزگذاری داده‌های خروجی را بر عهده گرفته است */
    }
    if (BIO_get_ktls_recv(SSL_get_rbio(ssl))) {
        /* هسته لینوکس رمزگشایی داده‌های ورودی را مدیریت می‌نماید */
    }

    return 0;
}

انتقال بدون کپی با توابع splice() و sendfile()

بزرگ‌ترین دستاورد فنی kTLS امکان استفاده از توابع Zero-Copy برای بسته‌های رمزنگاری‌شده است.

در مدل‌های پیشین، امکان استفاده از دستور splice() وجود نداشت زیرا داده‌ها پیش از ارسال به رمزگشایی در حافظه برنامه نیاز داشتند. با kTLS داده‌ها می‌توانند مستقیماً میان دو سوکت جابه‌جا شوند:

/* انتقال داده‌ها میان دو سوکت بدون ورود به فضای کاربری */
int pipefd[2];
pipe(pipefd);

while (1) {
    /* انتقال داده‌های رمزگشایی‌شده به پایپ درون هسته */
    ssize_t bytes = splice(inbound_fd, NULL, pipefd[1], NULL, 65536, SPLICE_F_MOVE);
    if (bytes <= 0) break;

    /* هدایت داده‌ها به سوکت خروجی kTLS با رمزنگاری لحظه‌ای */
    splice(pipefd[0], NULL, outbound_fd, NULL, bytes, SPLICE_F_MOVE);
}

تخلیه محاسبات به کارت‌های هوشمند SmartNIC

علاوه بر پیاده‌سازی بهینه‌شده نرم‌افزاری در هسته، کارت‌های شبکه رده سازمانی (نظیر NVIDIA Mellanox ConnectX-6 Dx و Intel Ethernet 800) از حالت پیشرفته تخلیه سخت‌افزاری kTLS (Device Offload) پشتیبانی می‌کنند.

مقایسه سطوح عملکردی kTLS

+--------------------------------------------------------------------------+
|                  مقایسه حالت‌های مختلف کاری فناوری KTLS                  |
+--------------------------------------------------------------------------+
| حالت کاری           | بخش پردازنده‌کننده    | بار پردازنده | سرعت 100GbE |
+---------------------+-----------------------+--------------+-------------+
| نرم‌افزار فضای کاربر | پردازنده مرکزی (برنامه)| ۱۰۰٪ (سنگین) | غیرقابل دست |
| نرم‌افزار kTLS هسته  | کد بهینه هسته لینوکس  | ۳۵-۵۰٪       | قابل دستیابی|
| تخلیه به سخت‌افزار  | تراشه کارت SmartNIC   | کمتر از ۲٪   | اشباع خط کامل|
+--------------------------------------------------------------------------+

در حالت تخلیه سخت‌افزاری: ۱. هسته لینوکس بدون دستکاری داده‌ها، برچسب‌های متنی رمزنگاری را به ساختار sk_buff ضمیمه می‌کند. ۲. کنترلر DMA کارت شبکه داده‌های خام را مستقیماً از حافظه رم می‌خواند. ۳. مدارهای اختصاصی AES روی کارت شبکه داده‌ها را در حین تبدیل به سیگنال‌های نوری با سرعت خط رمزگذاری می‌نمایند.

دستورهای فعال‌سازی تخلیه سخت‌افزاری:

# بررسی پشتیبانی سخت‌افزاری کارت شبکه
ethtool -k eth0 | grep tls-hw

# روشن کردن شتاب‌دهنده سخت‌افزاری در ارسال و دریافت
ethtool -K eth0 tls-hw-tx-offload on
ethtool -K eth0 tls-hw-rx-offload on

یکپارچگی با eBPF Sockmap برای هدایت ترافیک در هسته

برای دستیابی به حداکثر سرعت، فناوری kTLS با نگاشت‌های eBPF sockmap (BPF_MAP_TYPE_SOCKMAP) ادغام می‌شود.

برنامه eBPF هدرهای داده را به محض رمزگشایی در صف سوکت بررسی کرده و با دستور bpf_msg_redirect_map() بسته را مستقیماً به سمت سوکت تونل خروجی هدایت می‌کند، بدون آنکه نیازی به بیدارکردن پردازش‌های فضای کاربری باشد:

کارت ورودی ──> رمزگشایی kTLS ──> فیلتر eBPF ──> رمزگذاری kTLS ──> کارت خروجی
               [ اجرای صددرصدی در هسته بدون تعویض زمینه ]

کاربرد در معماری RiceGuard و زیرساخت VPNRice

در گیت‌وی‌های شبکه توزیع‌شده VPNRice، فناوری kTLS و شتاب‌دهی سخت‌افزاری مزایای عملیاتی چشمگیری به همراه دارد:

۱. پاسخ‌دهی به حجم عظیم درخواست‌ها: گره‌های لبه شبکه که ترافیک DoH و DoT را پردازش می‌کنند، صدها هزار پرس‌وجوی هم‌روند را با تاخیری کمتر از یک میلی‌ثانیه مدیریت می‌نمایند. ۲. کاهش مصرف برق و حرارت سرورها: انتقال محاسبات AES-GCM به کارت‌های شبکه بار پردازنده اصلی را تا ۸۰ درصد کاهش داده و مانع از داغ‌شدن پردازنده‌ها در رک‌های متراکم می‌شود. ۳. امنیت داده‌های در حال تبادل: به دلیل هدایت مستقیم بسته‌ها میان صف‌های هسته، داده‌های کاربران هرگز در بافرهای فضای کاربری باقی نمی‌ماند و در برابر آسیب‌پذیری‌های تخلیه حافظه محافظت می‌شود.

الزامات نگهداری و استقرار در تولید

هنگام پیاده‌سازی این معماری رعایت موارد زیر توصیه می‌شود:

  • نسخه هسته: به‌کارگیری لینوکس نسخه 5.15 LTS یا بالاتر، و نسخه 6.1+ برای تخلیه سخت‌افزاری SmartNIC.
  • مجوزهای پردازش: اعطای اختیارات مربوط به پیکربندی سوکت‌های ULP یا واگذاری دسترسی CAP_NET_ADMIN.
  • انتخاب الگوریتم‌ها: اولویت‌دادن به TLS_AES_128_GCM_SHA256 و TLS_AES_256_GCM_SHA384 جهت هماهنگی با مدارهای شتاب‌دهنده سخت‌افزاری.

ترکیب فناوری‌های Linux kTLS، ارسال بدون کپی و شتاب‌دهنده‌های SmartNIC معیاری پیشرفته در صنعت شبکه خلق کرده و کارایی و امنیت را در گیت‌وی‌های مدرن VPN ارتقا می‌بخشد.