تحديثات نواة لينكس الأمنية: متى تعيد التشغيل ومتى يكفي الترقيع الحي

تحديث النواة لا يحميك حتى تعيد التشغيل، لأن النواة القديمة تبقى عاملة في الذاكرة. الترقيع الحي يسد الثغرات العاجلة بلا توقف، لكن نافذة إعادة تشغيل كل 30 يوماً مع فحص بعدها تبقى ضرورية.
تثبيت تحديث النواة عبر apt upgrade أو dnf update لا يغلق الثغرة فوراً. الحزمة الجديدة تُنسخ إلى مجلد /boot، بينما النواة القديمة المصابة تبقى هي العاملة في الذاكرة حتى تعيد تشغيل السيرفر. لهذا قد ترى سيرفراً "محدّثاً" بالكامل حسب مدير الحزم، وهو في الحقيقة يعمل بنواة عمرها 200 يوم. الحل له طريقان: إعادة التشغيل، وهي الطريقة الوحيدة التي تضمن تشغيل النواة الجديدة بكامل إصلاحاتها، والترقيع الحي (live patching) عبر أدوات مثل kpatch وCanonical Livepatch وKernelCare، التي تستبدل الدوال المصابة داخل النواة العاملة دون إيقاف. الترقيع الحي ممتاز لسد الثغرات الحرجة بين نوافذ الصيانة، لكنه لا يغطي كل الإصلاحات، ولا يحدّث المكتبات مثل glibc وOpenSSL، ولا يغني عن إعادة التشغيل نهائياً. القاعدة العملية التي نوصي بها: ترقيع حي للثغرات العاجلة، ونافذة إعادة تشغيل ثابتة كل 30 يوماً تقريباً مدتها دقائق، مع فحص بعدها يتأكد أن النواة العاملة هي الأحدث وأن كل خدمة عادت تعمل. في هذا المقال الأوامر الدقيقة لكل خطوة، وحدود كل أداة، وما يحدث للخدمات التي لا تقلع وحدها.
لماذا تبقى ثغرة النواة مفتوحة بعد التحديث
النواة هي البرنامج الوحيد الذي لا يمكن إعادة تشغيله كعملية عادية، فهي التي تدير كل العمليات الأخرى. عندما يقلع السيرفر تُحمَّل صورة النواة من القرص إلى الذاكرة مرة واحدة، وبعدها لا تعود النواة إلى ملفاتها على القرص أبداً. مدير الحزم يضع الإصدار الجديد بجانب القديم ويحدّث إعدادات GRUB ليختار الجديد في الإقلاع القادم، وهنا تنتهي مهمته.
قارن بين ما يقوله مدير الحزم وما يعمل فعلاً:
# النواة العاملة الآن
uname -r
# أنوية مثبتة على أوبونتو وديبيان
ls /boot/vmlinuz-*
# أنوية مثبتة على AlmaLinux وRocky
rpm -q kernel --last | head -3
إذا كان ناتج uname -r أقدم من أحدث نواة في القائمة، فكل ثغرة أُصلحت بين الإصدارين ما زالت قابلة للاستغلال على سيرفرك الآن. على أوبونتو يكفي فحص وجود الملف /var/run/reboot-required، وعلى توزيعات عائلة RHEL يعطيك الأمر needs-restarting -r من حزمة dnf-utils جواباً مباشراً بنعم أو لا.
هذا ليس خطراً نظرياً. ثغرة Dirty COW المعروفة برقم CVE-2016-5195 بقيت في النواة نحو 9 سنوات قبل اكتشافها، وثغرة Dirty Pipe برقم CVE-2022-0847 سمحت لأي مستخدم عادي بالكتابة فوق ملفات للقراءة فقط والوصول إلى صلاحيات root. في الحالتين كان التحديث متاحاً خلال أيام، لكن السيرفرات التي ثبتته ولم تُعِد التشغيل بقيت مكشوفة.
الترقيع الحي: كيف يعمل وما حدوده
فكرة الترقيع الحي أن تُحمَّل وحدة نواة صغيرة تحتوي النسخة المصححة من الدالة المصابة، ثم يُعاد توجيه كل استدعاءات الدالة القديمة إلى الجديدة أثناء تشغيل النظام. العملية تستغرق أجزاء من الثانية، والخدمات لا تشعر بشيء.
| الأداة | التوزيعات | النموذج | أمر فحص الحالة |
|---|---|---|---|
| kpatch | RHEL وما يتوافق معها | ضمن اشتراك التوزيعة | kpatch list |
| Canonical Livepatch | أوبونتو LTS | عبر Ubuntu Pro، مجاني لعدد محدود من الأجهزة للاستخدام الشخصي | canonical-livepatch status |
| KernelCare | معظم التوزيعات الشائعة | اشتراك تجاري لكل سيرفر | kcarectl --info |
| Ksplice | Oracle Linux | ضمن دعم Oracle | uptrack-show |
الحدود هي ما يجب أن تفهمه قبل الاعتماد على أي منها:
- ليس كل إصلاح قابلاً للترقيع. الإصلاح الذي يغيّر بنية بيانات داخلية في النواة، أو يعدّل كوداً يعمل في كل لحظة مثل جدولة المعالج، يصعب أو يستحيل تطبيقه حياً. مزودو هذه الأدوات يختارون الثغرات الخطيرة فقط ويتركون الباقي لإعادة التشغيل.
- الترقيع يغطي النواة وحدها. مكتبات مثل glibc وOpenSSL تعمل داخل كل عملية، وتحديثها لا يصل للعمليات الجارية حتى تعيد تشغيلها. أداة
needrestartعلى أوبونتو، أوneeds-restartingعلى عائلة RHEL، تعرض لك العمليات التي ما زالت تستخدم مكتبة قديمة محذوفة. - الدعم محدود بعمر النواة. كل أداة تدعم مجموعة أنوية محددة لفترة زمنية، فإذا بقيت على نواة قديمة جداً تتوقف الترقيعات عن الوصول دون أن تلاحظ.
- الترقيعات تتراكم. بعد أشهر من الترقيع الحي يصبح الفرق بين ما يعمل وبين الحزمة المثبتة كبيراً، وأي إقلاع غير مخطط سيأخذك فجأة إلى نواة لم تُختبر مع تطبيقك.
نافذة إعادة تشغيل كل 30 يوماً بأقل أثر
إعادة تشغيل خادم سحابي على KVM تستغرق عادة من 30 إلى 90 ثانية حتى تعود الخدمات للعمل. هذا رقم صغير إذا اخترت له التوقيت الصحيح وجهّزت له الخطوات. اقتراحنا لمعظم أنظمة الشركات في السعودية: فجر يوم السبت بين الساعة 4:00 و5:00 بتوقيت الرياض، حيث تكون الحركة في أدنى مستوياتها لأغلب الأنظمة الداخلية.
- قبل النافذة بـ48 ساعة: أبلغ المستخدمين برسالة واحدة واضحة بموعد التوقف ومدته المتوقعة، دقيقتان على الأكثر.
- قبل النافذة مباشرة: خذ نسخة احتياطية أو snapshot، وسجّل ناتج
uname -rوقائمة الخدمات العاملة في ملف للمقارنة لاحقاً. - التحديث: نفّذ تحديث الحزم كاملاً، وليس النواة وحدها، حتى تستفيد من إعادة التشغيل في تحديث كل المكتبات.
- إعادة التشغيل: أمر
systemctl reboot، وراقب عودة السيرفر عبر ping من جهاز آخر. - الفحص بعد الإقلاع: التفاصيل في القسم التالي، ولا تغلق النافذة قبل إنهائها.
لحفظ قائمة الخدمات قبل التشغيل ومقارنتها بعده:
systemctl list-units --type=service --state=running --no-legend | awk '{print $1}' | sort > /root/services-before.txt
# بعد الإقلاع
systemctl list-units --type=service --state=running --no-legend | awk '{print $1}' | sort > /root/services-after.txt
diff /root/services-before.txt /root/services-after.txt
أي سطر يظهر في الفرق يبدأ بعلامة < هو خدمة كانت تعمل قبل التشغيل ولم تعد بعده، وهذه أول ما تتعامل معه.
التحقق بعد التحديث: ثلاث دقائق تمنع مفاجآت الأسبوع
بعد الإقلاع نفّذ هذه الأوامر بالترتيب:
uname -r
systemctl --failed
journalctl -b -p err --no-pager | tail -30
df -h
ss -tlnp
الأمر الأول يؤكد أن النواة العاملة هي الأحدث المثبتة. الثاني يعرض أي خدمة فشلت في الإقلاع، والمطلوب أن يكون الناتج صفر خدمات. الثالث يعرض أخطاء هذا الإقلاع تحديداً، مثل قرص لم يُركّب أو وحدة نواة لم تُحمّل. الرابع يتأكد أن كل الأقراص والأقسام مركّبة بسعتها الصحيحة. الخامس يعرض المنافذ المفتوحة، فإن كان تطبيقك يستمع على المنفذ 443 أو 3306 ولم يظهر في القائمة فالخدمة متوقفة حتى لو لم تظهر كفاشلة.
الخدمات التي لا تقلع وحدها
أكثر مشكلة نراها بعد إعادة التشغيل ليست النواة، وإنما خدمة شغّلها أحدهم يدوياً قبل أشهر ولم يفعّلها للإقلاع التلقائي. السيرفر يعمل، والموقع لا يفتح. أشهر الأسباب:
- خدمة غير مفعّلة: تحقق بالأمر
systemctl is-enabled nginx، وإذا كان الناتج disabled ففعّلها بـsystemctl enable --now nginx. - عملية مشغّلة داخل screen أو tmux: عامل طوابير أو سكربت Node.js شغّله مطور في جلسة طرفية. الحل نقله إلى وحدة systemd بملف service خاص به مع
Restart=always. - حاويات Docker بلا سياسة إعادة تشغيل: الحاوية التي أُنشئت دون
--restart unless-stoppedلن تعود بعد الإقلاع. افحص بالأمرdocker inspect -f '{{.HostConfig.RestartPolicy.Name}}' اسم_الحاوية. - قسم في fstab لم يُركّب: إذا كان القرص الإضافي غير متاح لحظة الإقلاع قد يتوقف الإقلاع كاملاً. خيار
nofailفي سطر fstab يمنع ذلك، مع فحصdf -hبعدها. - ترتيب الاعتماديات: تطبيق يقلع قبل قاعدة البيانات فيفشل اتصاله ويتوقف. أضف
After=mysql.serviceوRequires=mysql.serviceفي ملف وحدة التطبيق.
أفضل اختبار هو أول إعادة تشغيل مخطط لها، فهي تكشف كل هذه المشاكل في وقت هادئ تختاره أنت، بدل أن تكشفها انقطاعة كهرباء أو تعطل عتاد في منتصف يوم عمل.
القرار العملي
إذا كان نظامك يحتمل دقيقتين من التوقف كل 30 يوماً، وهذا حال أغلب أنظمة الشركات الداخلية، فإعادة التشغيل المجدولة تكفيك وحدها مع متابعة النشرات الأمنية لتوزيعتك. أضف الترقيع الحي عندما يكون النظام حساساً للتوقف، أو عندما تظهر ثغرة حرجة بين نافذتين ولا تريد انتظار الموعد، وفي كل الحالات اجعل فحص uname -r وsystemctl --failed جزءاً ثابتاً من كل صيانة.
على الخادم السحابي من كلاود تملك نواتك بالكامل وتعيد التشغيل متى شئت من لوحة التحكم أو من الطرفية، والسيرفرات في الرياض بزمن استجابة نحو 8ms، وإن أردت ألا تدير النواة إطلاقاً، فـالاستضافة السحابية المُدارة تبدأ بـ2,900 ريال سنوياً ونتولى نحن تحديث السيرفر وصيانته. المقارنة الكاملة في صفحة الأسعار.


