إدارة أنظمة لينكس

SSH بعمق

18 دقيقة الدرس 7 من 28

SSH بعمق

يُعدّ SSH (الصدفة الآمنة) الجهاز العصبي لكل بنية تحتية إنتاجية. تستخدمه للدخول إلى الخوادم، ونقل الملفات، وتنفيذ الأوامر عن بُعد، وإعادة توجيه المنافذ، وتسلسل الوصول عبر خوادم الوسيط. في شركات التقنية الكبرى، تُقنَّن تكوينات SSH وأنماط الـ Bastion ضمن سياسات أمنية رسمية، إذ قد يمتد تأثير الإعدادات الخاطئة ليشمل مراكز بيانات بأكملها. يغطي هذا الدرس الموضوع كما يتعامل معه مهندس SRE كبير: المفاتيح، وتصليب sshd، وملف إعداد العميل، والوكيل، والأنفاق، ونمط Bastion الذي يحمي الأسطول من التعرض المباشر للإنترنت.

المصادقة بالمفاتيح: الأساس

تُحظر المصادقة بكلمة المرور عبر SSH في كل بيئة واعية أمنياً تقريباً. المفاتيح أقوى وتُتيح الأتمتة. يتكون الزوج من مفتاح خاص (يبقى على محطة عملك، لا يُشارك أبداً، ويجب حمايته بعبارة مرور) ومفتاح عام (يُوضع على كل خادم تحتاج الوصول إليه).

# توليد مفتاح Ed25519 (مفضل على RSA للمفاتيح الجديدة — أصغر وأسرع وبنفس الأمان) ssh-keygen -t ed25519 -C "you@company.com" -f ~/.ssh/id_ed25519 # RSA لا يزال مقبولاً عند الحاجة لتوافق واسع (مثل بيئات FIPS القديمة) ssh-keygen -t rsa -b 4096 -C "you@company.com" -f ~/.ssh/id_rsa_work # نسخ مفتاحك العام إلى خادم ssh-copy-id -i ~/.ssh/id_ed25519.pub user@192.168.1.50 # أو الإلحاق يدوياً — مفيد حين لا يتوفر ssh-copy-id cat ~/.ssh/id_ed25519.pub | ssh user@192.168.1.50 \ "mkdir -p ~/.ssh && chmod 700 ~/.ssh && cat >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys"
فكرة أساسية: يجب أن يمتلك ملف authorized_keys على الخادم صلاحية 600 (قراءة وكتابة للمالك فقط) وأن يمتلك مجلد ~/.ssh صلاحية 700. الصلاحيات المتساهلة تجعل sshd يتجاهل الملف بصمت — وهو أحد أكثر أسباب "لماذا لا يعمل مفتاحي؟" شيوعاً في الإنتاج.

تصليب sshd: الخادم الوكيل

يأتي sshd_config الافتراضي بإعدادات معقولة في التوزيعات الحديثة، لكن عدة إعدادات يجب تشديدها قبل تعريض الخادم للإنترنت. حرر /etc/ssh/sshd_config أو الأفضل أنشئ ملفاً في /etc/ssh/sshd_config.d/99-hardening.conf للفصل النظيف عن الإعدادات الافتراضية.

# /etc/ssh/sshd_config.d/99-hardening.conf # تعطيل المصادقة بكلمة المرور — المفاتيح فقط PasswordAuthentication no PermitEmptyPasswords no ChallengeResponseAuthentication no # تعطيل تسجيل الدخول كـ root — استخدم حساباً مخصصاً وارفع الصلاحيات عبر sudo PermitRootLogin no # تقييد الوصول لمجموعات أو مستخدمين محددين AllowGroups ssh-users sudo # استخدام التشفير والخوارزميات القوية فقط (متوافق مع ملف Mozilla الحديث) Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes128-gcm@openssh.com MACs hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com KexAlgorithms curve25519-sha256,curve25519-sha256@libssh.org # تقليل سطح الهجوم X11Forwarding no AllowAgentForwarding no AllowTcpForwarding no PrintMotd no # قطع الاتصال بعد 10 دقائق من الخمول ClientAliveInterval 120 ClientAliveCountMax 5 # الحد من الهجمات التدريجية البطيئة LoginGraceTime 30 MaxAuthTries 3 MaxStartups 10:30:60 # مستوى تسجيل مناسب للتتبع الأمني LogLevel VERBOSE

بعد أي تعديل، اختبر التكوين دائماً قبل إعادة التحميل لتجنب إغلاق نفسك خارج الخادم:

# تحليل التكوين والإبلاغ عن الأخطاء دون إعادة تشغيل sshd -t # تطبيق التغييرات systemctl reload sshd # التحقق من عمل الخادم وامتصاص التغيير systemctl status sshd ss -tlnp | grep :22
خطأ شائع في الإنتاج — إغلاق نفسك خارج الخادم: احتفظ دائماً بجلسة SSH مفتوحة أثناء إعادة تحميل sshd على جهاز بعيد. إعادة التحميل تؤثر فقط على الاتصالات الجديدة؛ جلستك الحالية تنجو. إذا كان التكوين الجديد معطوباً، لا يزال لديك مسار إنقاذ. على الأجهزة الافتراضية السحابية، تأكد من أن وحدة تحكم المورد (AWS Session Manager، GCP Cloud Shell، إلخ) متاحة كبديل قبل تشديد الإعدادات.

ملف إعداد عميل SSH

كتابة أوامر طويلة مثل ssh -i ~/.ssh/id_ed25519 -p 2222 -J bastion.company.com user@10.0.1.55 عرضة للخطأ ويصعب أتمتتها. ملف ~/.ssh/config يُرمّز كل هذا مرة واحدة ويتيح لك كتابة ssh prod-api-01 فقط.

# ~/.ssh/config # إعدادات عامة تنطبق على جميع المضيفين Host * ServerAliveInterval 60 ServerAliveCountMax 3 AddKeysToAgent yes IdentityFile ~/.ssh/id_ed25519 HashKnownHosts yes StrictHostKeyChecking ask # خادم الوسيط (Bastion) المواجه للإنترنت Host bastion HostName bastion.company.com User deploy Port 22 IdentityFile ~/.ssh/id_ed25519_work ForwardAgent yes # خوادم الإنتاج — يُصل إليها عبر bastion Host prod-* User ec2-user ProxyJump bastion StrictHostKeyChecking yes IdentityFile ~/.ssh/id_ed25519_work # تجاوز لمضيف إنتاج محدد Host prod-api-01 HostName 10.0.1.55 Host prod-db-01 HostName 10.0.2.10 ForwardAgent no

بهذا التكوين، يمر ssh prod-api-01 تلقائياً عبر خادم الوسيط، ويستخدم المفتاح الصحيح، ويُطبّق التحقق من مفتاح المضيف — أمر واحد بدون أي علامات يدوية.

ممارسة احترافية: استخدم HashKnownHosts yes عالمياً. يُخزّن أسماء المضيفين المعروفين كتجزئات SHA-1 بدلاً من النص الصريح، مما يمنع المهاجم الذي يقرأ ~/.ssh/known_hosts من رسم خريطة شبكتك الداخلية.

وكيل SSH: فتح المفاتيح مرة واحدة

المفتاح المحمي بعبارة مرور آمن عند الراحة لكنه مزعج إذا أعدت كتابة عبارة المرور عند كل اتصال. يحتفظ وكيل SSH بالمفاتيح المفككة في الذاكرة طوال فترة جلستك. تفتحه مرة واحدة؛ والوكيل يُوقّع التحديات نيابة عنك.

# تشغيل الوكيل وإضافة مفتاحك eval "$(ssh-agent -s)" ssh-add ~/.ssh/id_ed25519 # يطلب عبارة المرور مرة واحدة ssh-add -l # قائمة المفاتيح المحملة وبصماتها ssh-add -t 3600 ~/.ssh/id_ed25519 # تحميل بانتهاء صلاحية بعد ساعة (أفضل ممارسة) # إزالة مفتاح من الوكيل ssh-add -d ~/.ssh/id_ed25519 # إزالة جميع المفاتيح ssh-add -D

إعادة توجيه الوكيل (ForwardAgent yes أو العلامة -A) تتيح لك SSH من خادم الوسيط إلى الخوادم الداخلية باستخدام المفاتيح من وكيلك المحلي — المفتاح الخاص لا يغادر حاسوبك المحمول قط. هذا هو البديل الآمن لوضع المفاتيح الخاصة على خادم الوسيط.

خطأ شائع — نطاق إعادة توجيه الوكيل: فعّل ForwardAgent فقط على خادم الوسيط (جهاز تثق به وتتحكم فيه). لا تفعّله أبداً لمضيفين عشوائيين: أي شخص يمتلك صلاحية root على جهاز تتصل به بوكيل مُعاد توجيهه يمكنه اختطاف مقبس وكيلك وانتحال هويتك لدى أي خادم آخر يملك مفتاحك صلاحية الوصول إليه.

أنفاق SSH

تتيح أنفاق SSH توجيه حركة TCP بأمان عبر قناة SSH المشفرة. هناك ثلاثة أوضاع:

  • إعادة التوجيه المحلي (-L) — يربط منفذاً على جهازك المحلي ويُوجّه الحركة إلى وجهة بعيدة عبر خادم SSH. الاستخدام الكلاسيكي: الوصول إلى قاعدة بيانات لا تستمع إلا على localhost الخادم البعيد.
  • إعادة التوجيه البعيد (-R) — يربط منفذاً على الخادم البعيد ويُوجّه الحركة الواردة إلى جهازك المحلي. مفيد لتعريض خدمة تطوير محلية مؤقتاً لمضيف بعيد.
  • البروكسي الديناميكي / SOCKS (-D) — يحوّل عميل SSH إلى بروكسي SOCKS5 يُوجّه حركة TCP التعسفية عبر الخادم. يُستخدم للتصفح في الشبكات الداخلية.
# إعادة التوجيه المحلي: الوصول إلى MySQL البعيد (منفذ 3306) كمنفذ محلي 3307 ssh -L 3307:127.0.0.1:3306 user@db-host -N # عبر خادم وسيط: إعادة التوجيه إلى مضيف يصل إليه الوسيط لكنك لا تستطيع ssh -L 3307:db.internal:3306 user@bastion -N # إعادة التوجيه البعيد: عرض المنفذ المحلي 8080 على منفذ الخادم 9090 ssh -R 9090:127.0.0.1:8080 user@server -N # بروكسي SOCKS5 ديناميكي على المنفذ المحلي 1080 ssh -D 1080 user@server -N -f

نمط Bastion

يُعدّ خادم الوسيط (Bastion) (المعروف أيضاً بخادم القفز) نقطة الدخول الوحيدة المعتمدة لوصول SSH إلى شبكة خاصة. لا تمتلك بقية الخوادم عناوين IP عامة وتقبل اتصالات SSH فقط من IP الخادم الداخلي. هذا يُقلّص سطح الهجوم بشكل جذري: جهاز واحد فقط مواجه للإنترنت، محكم وخاضع للمراقبة والتدقيق.

SSH Bastion Pattern Internet Engineer Laptop (key) DMZ / Public Subnet Bastion Host Public IP · port 22 Private Subnet (No Public IP) App Servers prod-api-01/02 Database prod-db-01 Monitoring Grafana / Prometheus Security Group Allow :22 from bastion only SSH :22 ProxyJump SSH المباشر محجوب بواسطة Security Group
نمط Bastion — يصل المهندسون إلى الخوادم الخاصة عبر خادم الوسيط فقط؛ مجموعات الأمان تحجب SSH المباشر من الإنترنت.

تُنفّذ بيئات السحابة الحديثة هذا النمط إما باستخدام خادم Bastion تقليدي أو بدائل مُدارة:

  • AWS Systems Manager Session Manager — لا خادم وسيط على الإطلاق؛ وكيل على كل نسخة؛ وصول عبر سياسة IAM، مُدقّق بالكامل في CloudTrail.
  • GCP Identity-Aware Proxy (IAP) tunneling — نموذج مشابه؛ لا يتطلب منفذ SSH عاماً.
  • Tailscale / Cloudflare Access — شبكة تراكب أو بروكسي zero-trust؛ لا يتطلب VPN.

SSH القائم على الشهادات: ما وراء المفاتيح المُصرَّح بها

على نطاق واسع، تُصبح إدارة authorized_keys عبر مئات الخوادم كابوساً: مفتاح موظف مغادر يجب حذفه من كل جهاز بشكل فردي. تستخدم المنظمات الكبيرة بدلاً من ذلك شهادات SSH — بيانات اعتماد موقّعة قصيرة الصلاحية تصدرها هيئة مصادقة (CA) داخلية. المفتاح العام لـ CA يُوضع على كل خادم مرة واحدة؛ أي شهادة موقّعة من تلك الـ CA تُقبل طوال فترة صلاحيتها (غالباً 8-24 ساعة). عند مغادرة موظف، توقف ببساطة عن إصدار الشهادات — الجلسات الحالية تنتهي صلاحيتها بشكل طبيعي.

ممارسة شركات التقنية الكبرى: رائدت شركات مثل Google وNetflix نموذج SSH القائم على الشهادات على نطاق واسع (نشرت Netflix مشروع BLESS مفتوح المصدر — CA SSH مبني على Lambda). يمتلك HashiCorp Vault محرك أسرار SSH مدمج يُصدر شهادات موقّعة عند الطلب بعد المصادقة عبر LDAP أو OIDC — المعيار الذهبي للحلول المُستضافة ذاتياً. حتى لو لم تُطبّق الشهادات اليوم، افهم النموذج لأنك ستصادفه في أي بنية تحتية ناضجة بما يكفي.

أوضاع الفشل الشائعة

  • أخطاء صلاحيات authorized_keys — يرفض sshd استخدام الملف إذا كان قابلاً للكتابة للجميع أو كان مجلد المنزل قابلاً للكتابة للمجموعة. الحل: chmod 700 ~/.ssh; chmod 600 ~/.ssh/authorized_keys.
  • حجب SELinux/AppArmor لـ sshd — على RHEL/CentOS، إذا نقلت SSH إلى منفذ غير قياسي يجب تشغيل semanage port -a -t ssh_port_t -p tcp 2222 وإلا سيحجب SELinux المنفذ الجديد حتى بعد تحديث sshd_config.
  • عدم تطابق مفتاح المضيف المعروف — بعد إعادة بناء خادم بنفس الـ IP، يتغير مفتاح المضيف. يرفض SSH الاتصال بتحذير مثير للقلق. الحل: ssh-keygen -R <hostname-or-ip>. في الأتمتة، استخدم StrictHostKeyChecking accept-new للاتصال الأول من إدارة التكوين، ثم اقفله على yes.
  • صلاحية مقبس إعادة توجيه الوكيل — إذا كان SSH_AUTH_SOCK غير مضبوط أو اختفى ملف المقبس، يفشل التوجيه بصمت. تحقق عبر ssh-add -l على المضيف البعيد.