يعد بروتوكول أمان طبقة النقل (TLS 1.3) الركيزة التشفيرية الأساسية لكافة الاتصالات الشبكية في العصر الحديث. ففي بنى الشبكات الافتراضية الخاصة (VPN)، ومحطات الترحيل الطرفية، والأنفاق الآمنة المغلفة (مثل بروتوكولات DNS-over-HTTPS وتمرير حزم البيانات المشفرة)، يحمي تشفير النقل البيانات المتدفقة من مخاطر التنصت والتلاعب.

ومع ذلك، تواجه حزم برمجيات TLS التقليدية العاملة في مساحة المستخدم (userspace)، مثل OpenSSL وBoringSSL وRustls، عقبات تقنية حادة عند نشرها على بوابات الشبكة فائقة الكثافة. ففي النمط المعتاد، تخضع كل حزمة تمر عبر البوابة لعمليات نسخ متكررة بين مخازن مقابس النواة وذاكرة البرامج في مساحة المستخدم، مع تبديل متواصل لسياق المعالجة (Context Switching).

ومع توسع متطلبات الشبكات إلى سرعات 40GbE و100GbE، تستنزف عمليات النسخ المتكرر والتشفير المتناظر عبر المعالج المركزي ذاكرة التخزين المؤقت (Cache) وتؤدي لاختناق ناقل الذاكرة، مما يحد من معدل نقل البيانات النهائي.

وللتخلص نهائياً من عمليات النسخ غير الضرورية ونقل عمليات التشفير المتناظر مباشرة إلى عتاد بطاقة الشبكة، وفرت نواة لينكس تقنية Kernel TLS (المعروفة بـ kTLS عبر خيار CONFIG_TLS) بالتكامل مع ميزات التفريغ العتادي على بطاقات SmartNIC الذكية.

+--------------------------------------------------------------------------+
|          مقارنة مسار تدفق البيانات: تشفير المستخدم مقابل LINUX KTLS        |
+--------------------------------------------------------------------------+
|                                                                          |
|  [ نمط الترحيل التقليدي في مساحة المستخدم ]                              |
|                                                                          |
|      دخول البطاقة ──> sk_buff ──(النسخ الأول)──> ذاكرة مساحة المستخدم    |
|                                                      │                   |
|                                           فك التشفير وإعادة التشفير      |
|                                           (استنزاف كاش L1/L2 للمعالج)    |
|                                                      v                   |
|      خروج البطاقة <── sk_buff <──(النسخ الثاني)── ذاكرة مساحة المستخدم   |
|      (يتطلب 4 عمليات نسخ لذاكرة RAM وتبديلين للسياق لكل دورة نقل)        |
|                                                                          |
|  ----------------------------------------------------------------------  |
|                                                                          |
|  [ نمط LINUX KTLS دون نسخ مع التفريغ العتادي المباشر ]                   |
|                                                                          |
|      دخول البطاقة (DMA)                                                  |
|           │                                                              |
|           v (مخزن صفحات النواة / sk_buff)                                |
|      +-------------------------------------------------------------+     |
|      |                     مكدس شبكة نواة لينكس                    |     |
|      |                                                             |     |
|      |   محرك kTLS (CONFIG_TLS) / إعادة توجيه eBPF Sockmap         |     |
|      |   - انعدام تام لأي نسخ نحو مساحة المستخدم                   |     |
|      |   - تمرير مباشر داخل النواة عبر دالة splice()               |     |
|      +-------------------------------------------------------------+     |
|           │                                                              |
|           v (نقل مباشر دون نسخ عبر DMA)                                  |
|      معالج التشفير العتادي المدمج في بطاقة الشبكة (Mellanox / Intel)     |
|           │                                                              |
|           v                                                              |
|      إخراج البيانات المشفرة إلى كابل الألياف (سرعة الخط الكاملة 100GbE)   |
|                                                                          |
+--------------------------------------------------------------------------+

أوجه القصور في المعالجة التقليدية بمساحة المستخدم

تفرض هندسة خوادم الشبكات التقليدية أعباء تشغيلية بالغة عند ترحيل البيانات المشفرة:

  1. استنزاف نداءات النظام: يستدعي التطبيق دالتي read() وSSL_read() بصورة مستمرة، مما يتسبب في انتقال المعالج المتكرر بين النواة ومساحة المستخدم.
  2. النسخ المزدوج للذاكرة: تُنقل الإطارات الواردة من مخازن النواة إلى ذاكرة البرنامج، وعقب المعالجة تعيد دالتا write() وSSL_write() نسخ البيانات نحو مخازن مقابس النواة من جديد.
  3. تشتت كاش المعالج: تستهلك خوارزميات التشفير المتناظر (مثل AES-GCM وChaCha20-Poly1305) سعة ذاكرتي L1 وL2 في المعالج، مما يعيق سرعة التدفق عند تدفق ملايين الحزم في الثانية.

في بيئات الخوادم العاملة بمنافذ 100GbE، يؤدي هذا العائق لحصر إنتاجية نواة المعالج الواحدة عند حدود 18–25 جيجابت/ثانية.

بنية Linux kTLS: الفصل بين المصافحة ومعالجة السجلات

تتجاوز تقنية Kernel TLS هذه المعضلة من خلال فصل مهام الاتصال بوضوح:

  • مستوى التحكم في مساحة المستخدم: تتولى مكتبات البرمجيات (مثل OpenSSL) المهام المعقدة ذات الحالات المتغيرة—كالتحقق من شهادات X.509 والتفاوض على بروتوكولات ALPN وتبادل المفاتيح غير المتناظرة (ECDHE أو خوارزميات ما بعد الحوسبة الكمومية).
  • مستوى البيانات في النواة: فور اكتمال المصافحة وتوليد مفاتيح الجلسة المتناظرة، يمرر التطبيق هذه المفاتيح إلى طبقة مقابس النواة عبر نداء setsockopt().

من تلك اللحظة فصاعداً، تتكفل نواة لينكس بتأطير سجلات TLS وإدارة أرقام التسلسل وإجراء عمليات التشفير والتحقق أثناء معالجة المقابس المباشرة (tcp_sendmsg وtcp_recvmsg).

+--------------------------------------------------------------------------+
|                  مراحل تشغيل تقنية KTLS داخل نواة لينكس                  |
+--------------------------------------------------------------------------+
|                                                                          |
|    1. إتمام مصافحة TCP القياسية                                          |
|                                                                          |
|    2. إنجاز مصافحة TLS 1.3 في مساحة المستخدم (OpenSSL / BoringSSL)       |
|       - التفاوض على خوارزمية: TLS_AES_256_GCM_SHA384                     |
|       - استخراج مفاتيح التشفير المتناظرة ومتجهات التهيئة (IV)            |
|                                                                          |
|    3. تفعيل بروتوكول kTLS عبر نداء النظام:                               |
|       setsockopt(fd, SOL_TCP, TCP_ULP, "tls", sizeof("tls"));            |
|                                                                          |
|    4. تزويد النواة ببيانات التشفير:                                      |
|       setsockopt(fd, SOL_TLS, TLS_TX, &crypto_info, sizeof(info));       |
|       setsockopt(fd, SOL_TLS, TLS_RX, &crypto_info, sizeof(info));       |
|                                                                          |
|    5. المعالجة المباشرة في النواة:                                       |
|       النواة تتولى التغليف والتشفير والتحقق من سلامة البيانات تلقائياً   |
|       البرامج تستفيد من دوال splice() وsendfile() و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

+--------------------------------------------------------------------------+
|                  مقارنة مستويات تشغيل تقنية KTLS                         |
+--------------------------------------------------------------------------+
| وضع التشغيل         | وحدة المعالجة         | عبء المعالج | سرعة 100GbE  |
+---------------------+-----------------------+-------------+--------------+
| برمجيات مساحة المستخ| المعالج العام للبرنامج| 100% مرتفع  | يتعذر بلوغها |
| تقنية kTLS برمجياً  | كود النواة المحسن     | 35-50%      | يمكن بلوغها  |
| تفريغ kTLS العتادي  | شريحة بطاقة SmartNIC  | أقل من 2%   | خط النقل كامل|
+--------------------------------------------------------------------------+

عند تفعيل التفريغ العتادي:

  1. تربط النواة بيانات السياق المشفر بهيكل sk_buff دون إجهاد المعالج بتشفير الحزم.
  2. تقرأ وحدة DMA في بطاقة الشبكة البيانات الصريحة مباشرة من ذاكرة الخادم.
  3. تتولى دوائر 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 والتفريغ العتادي فوائد عملية ملموسة:

  1. كفاءة استيعاب الاستعلامات: تتعامل العقد الطرفية المشغلة لخدمات DoH وDoT مع مئات الآلاف من الاستعلامات المتزامنة بزمن استجابة يقل عن ميلي ثانية واحدة.
  2. خفض استهلاك الطاقة والحرارة: يؤدي تحويل معالجة AES-GCM للبطاقات إلى تخفيض استهلاك المعالجات بنسبة 80%، مما يمنع انخفاض تردد المعالجات جراء الحرارة.
  3. تعزيز حماية الذاكرة: نظراً لتدفق البيانات حصرياً داخل النواة، لا تبقى أي بيانات للمستخدمين داخل ذاكرة التطبيقات، مما يقي من مخاطر تسريب البيانات عبر هجمات تفريغ الذاكرة.

إرشادات التشغيل والتطبيق

عند نشر هذه المنظومة في بيئات العمل الحية:

  • إصدار النواة: ينصح باستخدام نواة Linux 5.15 LTS أو أحدث، ونواة 6.1+ لبطاقات SmartNIC.
  • صلاحيات المقابس: التحقق من منح البرامج صلاحية إعداد مقابس ULP أو تزويدها بإذن CAP_NET_ADMIN.
  • اختيار التشفير: تفضيل خوارزميات TLS_AES_128_GCM_SHA256 وTLS_AES_256_GCM_SHA384 لضمان التوافق مع شرائح التسريع العتادي.

يشكل دمج Linux kTLS وتقنيات النقل دون نسخ والتفريغ العتادي معياراً هندسياً متميزاً يجمع بين قوة الحماية والسرعة القصوى في بوابات VPN المتطورة.