كل ما تعلمته في هذا الفصل — systemd وjournald والتخزين والمراقبة وتحليل الأداء والشبكة وتقوية SSH والمهام المجدولة — يتقاطع هنا. يأخذك هذا المشروع الختامي خطوةً خطوةً في إعداد خادم Ubuntu 24.04 LTS جديد من حالة "تسجيل الدخول كـroot مسموح، كل الإعدادات افتراضية" إلى نظام إنتاجي مُقوَّى وقابل للرصد وقادر على صيانة نفسه. كل خطوة تعكس ما يفعله مهندسو SRE الكبار في اليوم الأول لأي خادم جديد في الشركات الحقيقية.
ما يغطيه هذا المشروع: سنُهيِّئ حساب مسؤول غير جذر مع SSH محكم، ونُقوِّي النواة وسطح الخدمة، ونُعِدّ خدمة تطبيق نموذجية تحت systemd مع حدود موارد، ونُهيِّئ مراقبة الأقراص مع تنبيهات آلية، ونُرسي جمع سجلات مركزياً، ونربط جدول صيانة كامل بـcron — ثم نتحقق من كل طبقة.
المرحلة الأولى: الوصول المبدئي وإعداد المستخدمين
تحصل على مثيل سحابي بصلاحية root فقط. الخطوة الأولى هي إنشاء حساب مسؤول مخصص بصلاحيات sudo، وتقوية SSH، وتعطيل تسجيل دخول root نهائياً.
# على الخادم الجديد بصفة root:
# 1. إنشاء مستخدم عمليات
useradd -m -s /bin/bash -G sudo opsadmin
passwd opsadmin # ضبط عبارة مرور قوية — مطلوبة فقط لأوامر sudo
# 2. قفل كلمة مرور root (sudo هو مسار الرفع الوحيد)
passwd -l root
# 3. نسخ مفتاحك العام إلى الحساب الجديد
mkdir -p /home/opsadmin/.ssh
chmod 700 /home/opsadmin/.ssh
# الصق المفتاح العام من محطة عملك:
# cat ~/.ssh/id_ed25519.pub (نفِّذ هذا على جهازك المحلي أولاً)
echo "ssh-ed25519 AAAA...your-public-key... ops@workstation" \
>> /home/opsadmin/.ssh/authorized_keys
chmod 600 /home/opsadmin/.ssh/authorized_keys
chown -R opsadmin:opsadmin /home/opsadmin/.ssh
المرحلة الثانية: تقوية SSH
عدِّل /etc/ssh/sshd_config بالكتلة التالية. كل سطر هنا موجود في إعدادات الإنتاج في كل شركة تقنية من الدرجة الأولى — ليست بارانويا اختيارية، بل معيار أساسي:
# /etc/ssh/sshd_config — استبدل أو أضف هذه التوجيهات
Port 2222 # منفذ غير افتراضي يقلل ضجيج الماسحات الآلية
Protocol 2 # SSHv1 معطوب؛ أجبر v2 فقط
PermitRootLogin no # لا تسمح بـSSH للجذر مطلقاً
PasswordAuthentication no # المصادقة بالمفتاح فقط؛ كلمات المرور قابلة للاختراق بالقوة
PubkeyAuthentication yes
AuthorizedKeysFile .ssh/authorized_keys
MaxAuthTries 3 # قفل بعد 3 محاولات فاشلة
LoginGraceTime 30 # إنهاء الاتصالات غير المصادق عليها بعد 30 ثانية
ClientAliveInterval 300 # يرسل الخادم keepalive كل 5 دقائق
ClientAliveCountMax 2 # قطع الاتصال بعد 2 keepalive فائت (10 دقائق خمول)
AllowUsers opsadmin # قائمة بيضاء — فقط المستخدمون المسمَّون صراحةً يمكنهم تسجيل الدخول
X11Forwarding no # لا نقل نافذة رسومية على خادم
AllowTcpForwarding no # منع استخدام SSH كبروكسي SOCKS (إلا إن احتجت)
Banner /etc/ssh/ssh_banner # عرض تحذير قانوني قبل المصادقة
# إنشاء لافتة قانونية (تظهر قبل المصادقة — متطلب مسؤولية في كثير من الشركات)
cat > /etc/ssh/ssh_banner <<'EOF'
***********************************************************************
Authorised access only. All connections are monitored and logged.
Disconnect immediately if you are not an authorised user.
***********************************************************************
EOF
# التحقق من الإعداد قبل إعادة التشغيل (خطوة حاسمة — خطأ مطبعي يُغلق عليك الباب)
sshd -t
echo "Exit code: $?" # يجب أن يكون 0
# التطبيق
systemctl restart ssh
# افتح المنفذ الجديد قبل قطع الاتصال (خذل أمان: ابق الجلسة القديمة مفتوحة)
ufw allow 2222/tcp
ufw enable
تحذير إنتاجي — تحقق دائماً قبل إعادة تشغيل sshd: تشغيل sshd -t يُنفِّذ تحليل جاف للإعداد. خطأ مطبعي في sshd_config سيُخرج غير صفري؛ إن شغَّلت systemctl restart ssh بدون هذا الفحص، سيرفض sshd البدء وستُقفَل خارج الخادم — مما يتطلب وصولاً عبر وحدة تحكم الاسترداد أو منفذ التسلسل للمثيل السحابي. هذا أحد أكثر الانقطاعات الذاتية شيوعاً بين المهندسين المبتدئين.
المرحلة الثالثة: تقوية النواة ونظام التشغيل
قوِّ مكدس شبكة النواة وعطِّل الخدمات غير المستخدمة. هذه الإعدادات مأخوذة مباشرةً من معيار CIS Ubuntu 24.04 LTS — المرجع المستخدم في Google وMeta وكل مؤسسة مالية كبرى:
# /etc/sysctl.d/99-hardening.conf
# تحميل بالأمر: sysctl --system (أو إعادة التشغيل)
# --- تقوية الشبكة ---
net.ipv4.ip_forward = 0 # ليس موجه شبكة؛ تعطيل إعادة توجيه الحزم
net.ipv4.conf.all.rp_filter = 1 # تصفية المسار العكسي (منع انتحال IP)
net.ipv4.conf.default.rp_filter = 1
net.ipv4.conf.all.accept_redirects = 0 # تجاهل إعادة توجيه ICMP (ثغرة MITM)
net.ipv4.conf.default.accept_redirects = 0
net.ipv6.conf.all.accept_redirects = 0
net.ipv4.conf.all.accept_source_route = 0 # تجاهل الحزم ذات التوجيه المصدري
net.ipv4.icmp_echo_ignore_broadcasts = 1 # تجاهل ping البث (تضخيم smurf)
net.ipv4.tcp_syncookies = 1 # حماية من فيضان SYN
# --- تقوية النواة ---
kernel.randomize_va_space = 2 # ASLR الكامل (تعشية تخطيط فضاء العناوين)
kernel.dmesg_restrict = 1 # غير الجذر لا يمكنه قراءة حلقة النواة
kernel.sysrq = 0 # تعطيل SysRq (لا حاجة له على خادم بدون شاشة)
fs.protected_hardlinks = 1
fs.protected_symlinks = 1
# تطبيق إعدادات sysctl فوراً (لا حاجة لإعادة تشغيل)
sysctl --system
# تعطيل وإخفاء الخدمات غير المستخدمة (تقليل سطح الهجوم)
for svc in avahi-daemon cups bluetooth ModemManager; do
systemctl disable --now "$svc" 2>/dev/null
systemctl mask "$svc" 2>/dev/null
done
# التحقق من عدم وجود استماع غير متوقع
ss -tulnp | grep -v '127.0.0.1\|::1' # عرض المستمعين غير المحليين فقط
المرحلة الرابعة: نشر خدمة وإدارتها بـsystemd
يجب أن تعمل خدمة الإنتاج تحت مستخدم غير مميز مخصص، مع حدود موارد صارمة، وإعادة تشغيل تلقائية عند الفشل، وإرسال سجلات عبر journald. هذا المثال ينشر واجهة برمجية بسيطة بلغة Python للتحقق من الصحة — النمط ينطبق على أي daemon:
# إنشاء حساب خدمة غير مميز (بدون shell تسجيل دخول، بدون مجلد منزلي)
useradd -r -s /sbin/nologin -d /opt/healthapi healthapi
# تثبيت تطبيق بسيط
mkdir -p /opt/healthapi
cat > /opt/healthapi/server.py <<'EOF'
from http.server import HTTPServer, BaseHTTPRequestHandler
import json, time
class Handler(BaseHTTPRequestHandler):
def log_message(self, fmt, *args):
print(fmt % args, flush=True) # journald يلتقط stdout
def do_GET(self):
if self.path == '/health':
self.send_response(200)
self.send_header('Content-Type','application/json')
self.end_headers()
self.wfile.write(json.dumps({'status':'ok','ts':time.time()}).encode())
else:
self.send_response(404)
self.end_headers()
HTTPServer(('127.0.0.1', 8080), Handler).serve_forever()
EOF
chown -R healthapi:healthapi /opt/healthapi
# /etc/systemd/system/healthapi.service
[Unit]
Description=Health Check API
Documentation=https://wiki.internal/healthapi
After=network.target
[Service]
Type=simple
User=healthapi
Group=healthapi
WorkingDirectory=/opt/healthapi
ExecStart=/usr/bin/python3 /opt/healthapi/server.py
Restart=on-failure
RestartSec=5s
StandardOutput=journal # كل stdout -> journald (قابل للبحث، يُدار تلقائياً)
StandardError=journal
# حدود الموارد (منع عملية مفلتة من إسقاط المضيف)
LimitNOFILE=65536 # الحد الأقصى لمواصفات الملفات المفتوحة
MemoryMax=256M # إيقاف الخدمة إن تجاوزت 256 ميجابايت
CPUQuota=20% # لا تستهلك أكثر من 20% من معالج واحد
# تأمين صندوق الرمل
NoNewPrivileges=yes
PrivateTmp=yes # الخدمة تحصل على /tmp خاص بها
ProtectSystem=strict
ReadWritePaths=/opt/healthapi
[Install]
WantedBy=multi-user.target
# التحميل والتفعيل والتشغيل والتحقق
systemctl daemon-reload
systemctl enable --now healthapi
systemctl status healthapi
# متابعة سجل الخدمة في الوقت الفعلي
journalctl -u healthapi -f
# اختبار نقطة النهاية من المضيف المحلي للتأكد من عملها
curl -s http://127.0.0.1:8080/health
المرحلة الخامسة: مراقبة القرص والتنبيهات الآلية
تتسبب حوادث امتلاء القرص في تلف صامت للبيانات، وأعطال قواعد البيانات، وتعليق التطبيقات — كل ذلك بدون رسالة خطأ واضحة. أعِدّ مراقبة آلية لاصطياد هذا قبل وقوعه:
# /usr/local/bin/disk-alert.sh
#!/usr/bin/env bash
# إرسال تنبيه إلى ملف سجل وjournald إن تجاوز أي نظام ملفات العتبة %
THRESHOLD=80
ALERT_LOG=/var/log/disk-alert.log
df -h --output=target,pcent | tail -n +2 | while read -r mount pct; do
usage="${pct%\%}" # إزالة علامة %
if [[ "$usage" -ge "$THRESHOLD" ]]; then
msg="[DISK ALERT] $(date -Iseconds) ${mount} is at ${pct} (threshold: ${THRESHOLD}%)"
echo "$msg" | tee -a "$ALERT_LOG"
# في الإنتاج: استبدل echo بـcurl لـPagerDuty/Slack webhook أو sendmail
logger -t disk-alert -p user.crit "$msg" # يُرسل أيضاً لـjournald عبر syslog
fi
done
نصيحة احترافية — البنية التحتية كرمز: بمجرد بناء هذا الخادم والتحقق منه يدوياً، التقط كل قرار إعداد في playbooks Ansible أو قالب Terraform + cloud-init. الخادم التالي يجب أن يُعاد إنتاجه بشكل متطابق في أقل من عشر دقائق. في Google وMeta، لا يُهيَّأ أي خادم إنتاجي يدوياً — كل شيء بالتحكم بالإصدارات ومراجعة الكود وتطبيق الأتمتة. الإعداد اليدوي هو دين تقني يتراكم بصمت حتى يُستدعى أحدهم الساعة الثانية صباحاً بسبب خادم "ثلج" يتصرف بشكل مختلف عن كل خادم آخر في الأسطول.
ما بنيته
في هذه المرحلة، لديك خادم متوافق مع الممارسة الإنتاجية في أي شركة من الدرجة الأولى:
الهوية: لا SSH للجذر، مصادقة بالمفتاح فقط، مستخدم غير مميز مخصص، لافتة قانونية.
سطح الشبكة: جدار حماية رفض افتراضي؛ المنفذ 2222 فقط مفتوح؛ النواة محمية ضد هجمات الشبكة الشائعة.
صحة الخدمة: التطبيق يعمل كحساب خدمة أقل امتيازاً تحت systemd، مع حدود للذاكرة والمعالج، وإعادة تشغيل تلقائية، وتسجيل كامل عبر journald.
الصيانة الذاتية: تحديثات أمنية بلا رقابة، تحديثات حزم أسبوعية، تنظيف الملفات المؤقتة، واستعادة الخدمة الآلية — كلها تعمل بجدول منتظم.
الخطوات التالية في منظمة حقيقية: يغطي هذا المشروع الأساس على مستوى نظام التشغيل. في الممارسة العملية ستُضيف: شحن سجلات مركزياً (Loki أو Splunk أو CloudWatch Logs)، كشف اختراق قائم على المضيف (AIDE وFalco)، مراقبة وقت تشغيل خارجية (Prometheus Blackbox Exporter أو خدمة SaaS)، إدارة الأسرار (Vault)، وأتمتة إدارة الإعداد (Ansible أو Chef أو Puppet). تلك المواضيع مغطاة في فصول لاحقة في مسار DevOps هذا.
نستخدم ملفات تعريف الارتباط لتشغيل هذا الموقع وتحليل الزيارات وعرض إعلانات مخصّصة. يمكنك قبول كل ملفات تعريف الارتباط أو رفض غير الأساسية منها.
سياسة الخصوصية