مفاتيح SSH: إعداد الدخول إلى الخادم دون كلمة مرور
يتلخص إعداد مفاتيح SSH في ثلاث خطوات: إنشاء زوج المفاتيح بالأمر ssh-keygen -t ed25519، ونسخ المفتاح العام إلى الخادم بالأمر ssh-copy-id user@host، ثم التحقق من الدخول. بعد ذلك يُعطَّل الدخول بكلمة المرور عبر PasswordAuthentication no في /etc/ssh/sshd_config، وتُعرَّف الاتصالات المتكررة في ~/.ssh/config.
مفتاح SSH زوج من الملفات: المفتاح الخاص يبقى لديك، والمفتاح العام يوضع على الخادم. عند الاتصال يتحقق الخادم من أنك تملك المفتاح الخاص المقابل لأحد المفاتيح العامة المصرّح بها، فيسمح لك بالدخول دون كلمة مرور. وهذا أكثر راحة وأماناً بكثير من كلمة المرور، لأن تخمين المفتاح بالتجربة المتكررة يكاد يكون مستحيلاً. فيما يلي إعداد مفاتيح SSH من إنشائها حتى تعطيل الدخول بكلمة المرور، مع شرح الأخطاء التي يتعثر فيها الناس عادةً.
كيف تعمل المصادقة بالمفتاح
المفاتيح غير متماثلة. المفتاح العام (id_ed25519.pub) يمكن أن تعرضه على أي شخص، فمنه لا يمكن استخراج المفتاح الخاص. أما المفتاح الخاص (id_ed25519) فلا يغادر جهازك ولا يُرسل عبر الشبكة أبداً.
عند الدخول يخبر العميل الخادم بالمفتاح الذي يريد استخدامه. يبحث الخادم عن المفتاح العام في الملف ~/.ssh/authorized_keys الخاص بالمستخدم، فإذا وجده طلب من العميل توقيع بيانات الجلسة بالمفتاح الخاص. ويتحقق الخادم من التوقيع بالمفتاح العام، فإذا كان صحيحاً سُمح بالدخول. ولا تُرسل كلمة المرور في أي مرحلة من هذه العملية.
الخطوة الأولى: إنشاء المفتاح بـ ssh-keygen
على جهازك (لينكس أو macOS أو Windows 10/11 الذي يحتوي على OpenSSH) نفّذ:
ssh-keygen -t ed25519 -C "alena@laptop"
يحدد الخيار -t الخوارزمية، ويضع الخيار -C تعليقاً يُضاف إلى نهاية المفتاح العام ويساعد لاحقاً على معرفة صاحب المفتاح. وخوارزمية Ed25519 هي الخيار الحديث الموصى به: مفاتيحها قصيرة وسريعة وآمنة. وإذا كان الخادم قديماً ولا يدعمها، فاستخدم RSA بطول 3072 بت على الأقل: ssh-keygen -t rsa -b 4096.
Generating public/private ed25519 key pair.
Enter file in which to save the key (/home/alena/.ssh/id_ed25519):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/alena/.ssh/id_ed25519
Your public key has been saved in /home/alena/.ssh/id_ed25519.pub
The key fingerprint is:
SHA256:Xq3v0m6c1y2pVv8m3N0uYv9yQm0e6dFv5gH2rZt1aBc alena@laptop
هل تحتاج إلى عبارة مرور
تُشفّر عبارة المرور (passphrase) المفتاح الخاص على القرص. فإذا سُرق الحاسوب المحمول أو تسرّب الملف، لا يكون المفتاح بلا عبارة مرور مفيداً لأحد. يُنصح بتعيين عبارة مرور للمفاتيح الشخصية، ولتجنب إدخالها في كل اتصال استخدم ssh-agent، فهو يحتفظ بالمفتاح المفكوك التشفير في الذاكرة حتى نهاية الجلسة.
eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_ed25519
ssh-add -l # قائمة المفاتيح المحمّلة
المفاتيح بلا عبارة مرور تُستخدم للأتمتة، كالـ CI أو سكريبت النسخ الاحتياطي. ومن الأفضل تقييد هذه المفاتيح على الخادم (انظر أدناه).
الخطوة الثانية: نسخ المفتاح العام إلى الخادم بـ ssh-copy-id
أبسط طريقة هي ssh-copy-id. فهو يتصل بكلمة المرور مرة واحدة، ثم يضيف المفتاح العام إلى ~/.ssh/authorized_keys على الخادم، ويضبط الصلاحيات الصحيحة.
ssh-copy-id -i ~/.ssh/id_ed25519.pub deploy@203.0.113.10
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/home/alena/.ssh/id_ed25519.pub"
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
deploy@203.0.113.10's password:
Number of key(s) added: 1
Now try logging into the machine, with: "ssh 'deploy@203.0.113.10'"
and check to make sure that only the key(s) you wanted were added.
إذا كان الخادم يستمع على منفذ غير قياسي فأضف -p 2222.
إذا لم يكن ssh-copy-id متاحاً
لا توجد أداة ssh-copy-id في Windows. يمكن نقل المفتاح يدوياً بأمر واحد:
cat ~/.ssh/id_ed25519.pub | ssh deploy@203.0.113.10 "mkdir -p ~/.ssh && chmod 700 ~/.ssh && cat >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys"
ويحدد مزودو السحابة المفتاح العام عادةً عند إنشاء الخادم، فيُضاف إلى authorized_keys عبر cloud-init.
الخطوة الثالثة: التحقق من الدخول
ssh deploy@203.0.113.10
إذا لم يُطلب منك كلمة المرور (أو طُلبت عبارة مرور المفتاح فقط)، فكل شيء يعمل. وعند أول اتصال بخادم جديد يعرض SSH بصمة مفتاح الخادم ويسألك إن كنت تثق به. وبعد الإجابة بـ yes تُحفظ البصمة في ~/.ssh/known_hosts، ويحذّرك SSH لاحقاً إذا تغير مفتاح الخادم.
لمعرفة المفاتيح التي يجربها العميل، ولماذا يرفضها الخادم، شغّل الاتصال بالوضع المفصّل:
ssh -v deploy@203.0.113.10
ملف ~/.ssh/config: أسماء قصيرة للخوادم
عندما تكثر الخوادم، يصبح كتابة المستخدم وعنوان IP والمنفذ ومسار المفتاح في كل مرة أمراً مزعجاً. كل ذلك يُكتب في ~/.ssh/config:
Host prod
HostName 203.0.113.10
User deploy
Port 2222
IdentityFile ~/.ssh/id_ed25519
IdentitiesOnly yes
Host bastion
HostName bastion.example.com
User alena
Host db-internal
HostName 10.0.0.15
User admin
ProxyJump bastion
Host *
ServerAliveInterval 60
AddKeysToAgent yes
بعد ذلك يكفي الأمر ssh prod، وتفهم scp وrsync وGit هذه الأسماء أيضاً: rsync -av ./site/ prod:/var/www/.
IdentitiesOnly yes: استخدام المفتاح المحدد فقط. وبدون هذا السطر يجرب العميل كل المفاتيح في الـ agent، فقد يقطع الخادم الاتصال بسبب كثرة المحاولات قبل أن يصل إلى المفتاح الصحيح.ProxyJump: الاتصال بخادم داخلي عبر خادم وسيط (bastion) بأمر واحد.ServerAliveInterval: إرسال نبضة كل 60 ثانية حتى لا ينقطع الاتصال عند الخمول.
يجب أن تكون صلاحيات الملف 600، وإلا فقد يرفض SSH قراءته: chmod 600 ~/.ssh/config.
تمرير الـ agent: متى يُستخدم وما خطره
قد تحتاج أحياناً إلى الاتصال من الخادم بخادم آخر، مثلاً لتنفيذ git pull من مستودع خاص. لا يجوز نسخ المفتاح الخاص إلى الخادم. بدلاً من ذلك يمكن استخدام ssh -A أو ForwardAgent yes، فيستطيع الخادم استخدام الـ agent المحلي خلال الجلسة. لكن أي شخص يملك صلاحية root على ذلك الخادم يستطيع أيضاً استخدام الـ agent طالما أنت متصل. لذلك فعّل التمرير للخوادم الموثوقة فقط، واستخدم ProxyJump للمرور عبر وسيط، فهو لا يكشف الـ agent.
الخطوة الرابعة: تعطيل الدخول بكلمة المرور
ما دامت كلمة المرور مسموحة، يبقى الخادم هدفاً للتخمين المتكرر. وبعد أن تتأكد من الدخول بالمفتاح، عطّل كلمات المرور. والمهم: لا تُغلق الجلسة الحالية قبل أن تتحقق من الدخول في نافذة جديدة، وإلا قد تفقد الوصول إلى الخادم.
افتح /etc/ssh/sshd_config (أو أنشئ ملفاً في /etc/ssh/sshd_config.d/ إذا كان الملف الرئيسي يحمّل الملفات الأخرى عبر التوجيه Include)، واضبط:
PasswordAuthentication no
KbdInteractiveAuthentication no
PubkeyAuthentication yes
PermitRootLogin no
يمنع PermitRootLogin no الدخول مباشرة بحساب root: يدخل المديرون بحساباتهم الشخصية ثم يرفعون الصلاحيات عبر sudo. وإذا كان لا بد من دخول root، فاستخدم PermitRootLogin prohibit-password، أي الدخول بالمفتاح فقط.
تحقّق من صحة الصياغة ثم أعد تحميل الخدمة:
sudo sshd -t
sudo systemctl reload ssh # في Debian/Ubuntu؛ وفي أنظمة RHEL استخدم sshd
يبقى الأمر sshd -t صامتاً إذا كانت الإعدادات صحيحة. ثم في نافذة جديدة تأكد من أن الدخول بالمفتاح يعمل، وأن الخادم يرفض الدخول بكلمة المرور:
$ ssh -o PubkeyAuthentication=no deploy@203.0.113.10
deploy@203.0.113.10: Permission denied (publickey).
حماية إضافية
تعطيل كلمات المرور هو الإجراء الأهم. ويُضاف عادةً تقييد المنفذ 22 بجدار الحماية (ufw allow from 198.51.100.0/24 to any port 22)، وتثبيت fail2ban الذي يحظر عنوان IP بعد سلسلة من المحاولات الفاشلة. ويعرض الأمر sudo fail2ban-client status sshd حالة الحماية.
ويمكن تقييد المفتاح المخصص للأتمتة داخل authorized_keys باستخدام خيارات قبل المفتاح. فمثلاً، تسمح الصيغة from="198.51.100.7",no-port-forwarding,no-pty ssh-ed25519 AAAA... backup بالدخول من عنوان واحد فقط، ودون واجهة تفاعلية.
الأخطاء الشائعة وحلولها
Permission denied (publickey)
هذا أكثر الأخطاء شيوعاً. وأسبابه، من الأكثر شيوعاً إلى الأقل:
- صلاحيات خاطئة على الخادم.يتجاهل sshd الملف
authorized_keysإذا كان المجلد أو الملف قابلاً للكتابة من مستخدمين آخرين. الحل:chmod 700 ~/.sshوchmod 600 ~/.ssh/authorized_keys، ويجب ألا يكون المجلد الشخصي قابلاً للكتابة من المجموعة أو الآخرين. - مالك خاطئ.إذا أنشأت الملفات باستخدام
sudo، فستكون ملكيتها لـ root. الحل:sudo chown -R deploy:deploy /home/deploy/.ssh. - المفتاح أُضيف إلى مستخدم آخر.نسخت المفتاح لحساب
rootبينما تدخل بحسابdeploy، أو العكس. - العميل يعرض مفتاحاً غير الصحيح.انظر إلى مخرجات
ssh -v: السطورOffering public keyتُظهر المفاتيح التي تُجرَّب. حدد المفتاح الصحيح بالخيار-iأو بـIdentityFile. - المفتاح تالف بسبب النسخ.يجب أن يكون المفتاح العام سطراً واحداً. وأي سطر جديد يُدخل عند اللصق من الحافظة يفسد المفتاح.
يعرض السجل على الخادم سبب الرفض: sudo journalctl -u ssh -n 30 (وفي RHEL استخدم -u sshd). وقد تجد أسطراً مثل Authentication refused: bad ownership or modes for directory /home/deploy/.ssh.
UNPROTECTED PRIVATE KEY FILE
يرفض العميل استخدام المفتاح الخاص إذا كان يستطيع قراءته مستخدمون آخرون. الحل: chmod 600 ~/.ssh/id_ed25519.
REMOTE HOST IDENTIFICATION HAS CHANGED
مفتاح الخادم لا يطابق المفتاح المحفوظ في known_hosts. يحدث هذا بعد إعادة تثبيت الخادم أو تغيير عنوانه، لكن الشكل نفسه يظهر في هجوم «الرجل في المنتصف». تأكد من أن الخادم أُعيد إنشاؤه فعلاً، ثم احذف السجل القديم: ssh-keygen -R 203.0.113.10.
Too many authentication failures
عرض الـ agent على الخادم مفاتيح كثيرة، فأغلقه الخادم بسبب الحد MaxAuthTries. الحل هو IdentitiesOnly yes مع IdentityFile صريح في ~/.ssh/config.
الخلاصة
إعداد مفاتيح SSH يستغرق خمس دقائق: ssh-keygen -t ed25519، ثم ssh-copy-id، ثم التحقق من الدخول، وبعد ذلك PasswordAuthentication no وإعادة تحميل sshd مع إبقاء الجلسة الثانية مفتوحة. ويغنيك ملف ~/.ssh/config عن الأوامر الطويلة، وتحل صلاحيات 700 و600 معظم أخطاء «Permission denied». ويُشرح SSH وrsync وحماية الخادم بجدار الحماية وfail2ban عملياً في دورة لينكس.
الأسئلة الشائعة
هل يمكن استخدام مفتاح SSH واحد لجميع الخوادم؟
تقنياً نعم، وكثيرون يفعلون ذلك. لكن لمجالات الاستخدام المختلفة (العمل، والمشاريع الشخصية، وCI) يُفضَّل إنشاء مفاتيح منفصلة، فتسريب مفتاح واحد لا يفتح الوصول إلى كل شيء.
أين تُحفظ مفاتيح SSH في Windows؟
يحفظها OpenSSH المدمج في المجلد C:\Users\اسم_المستخدم\.ssh\، وفيه id_ed25519 وid_ed25519.pub وknown_hosts وconfig. وينشئها الأمر ssh-keygen نفسه في PowerShell.
كيف أغيّر عبارة المرور لمفتاح موجود؟
نفّذ الأمر ssh-keygen -p -f ~/.ssh/id_ed25519، فيطلب العبارة القديمة ثم الجديدة. المفتاح نفسه لا يتغير، ولا حاجة لنقله إلى الخوادم.
كيف أسحب صلاحية الدخول عبر مفتاح؟
احذف سطر المفتاح العام من ملف ~/.ssh/authorized_keys على الخادم. وتعين التعليقات في نهاية المفتاح على العثور على السطر الصحيح.
إذا بقي لديّ المفتاح الخاص فقط، كيف أحصل على المفتاح العام؟
الأمر ssh-keygen -y -f ~/.ssh/id_ed25519 يحسب المفتاح العام من المفتاح الخاص ويعرضه.
يُشرح هذا الموضوع بالتفصيل مع التطبيق العملي في دورة «Linux: с нуля до уверенного администрирования».
- Удалённый доступ и сетевые хранилища: SSH, rsync, NFS и SMB
- Firewall и защита сервера: ufw, nftables, fail2ban и GPG