برای اتصال SSH به سرور کافی است در ترمینال (یا PowerShell در ویندوز ۱۰ و ۱۱) بنویسید ssh user@IP؛ مثلاً ssh root@203.0.113.10. بار اول اثر انگشت سرور را تأیید میکنید، رمز را وارد میکنید و وارد خط فرمان سرور میشوید. ولی ورود با رمز هم ناامنتر است و هم آزاردهنده؛ روش درست ورود با کلید SSH است.
ساخت کلید SSH در ویندوز، لینوکس و macOS با یک دستور انجام میشود: ssh-keygen -t ed25519. این دستور دو فایل میسازد: کلید خصوصی که روی سیستم خودتان میماند و کلید عمومی (با پسوند .pub) که روی سرور یا GitHub قرار میدهید. در ادامه همهی مراحل را قدمبهقدم میرویم: ساخت کلید، کپیکردنش روی سرور، کوتاهکردن دستور اتصال با فایل config، اضافهکردن کلید به GitHub و رفع خطاهای رایج.
کلید SSH چطور کار میکند؟
کلید SSH یک جفت کلید رمزنگاری است. کلید عمومی مثل قفل است: میتوانید آن را روی هر تعداد سرور نصب کنید و افشا شدنش خطری ندارد. کلید خصوصی مثل کلیدِ آن قفل است و هرگز نباید از سیستم شما خارج شود. هنگام اتصال، سرور چالشی میفرستد که فقط صاحب کلید خصوصی میتواند به آن جواب بدهد، و رمزی هم روی شبکه جابهجا نمیشود.
امروز الگوریتم پیشنهادی ed25519 است: کلیدهایش کوتاه، سریع و امناند و همهی نسخههای جدید OpenSSH و GitHub از آن پشتیبانی میکنند. RSA فقط وقتی لازم است که با سیستم خیلی قدیمی سروکار دارید؛ آن هم با حداقل ۴۰۹۶ بیت.
ساخت کلید SSH در لینوکس و macOS
ترمینال را باز کنید و بزنید:
ssh-keygen -t ed25519 -C "you@example.com"
بخش -C فقط یک توضیح است تا بعداً بدانید این کلید مال کیست؛ معمولاً ایمیل یا نام سیستم را مینویسند. دستور دو سؤال میپرسد:
- محل ذخیره: پیشفرض
~/.ssh/id_ed25519است. Enter بزنید، مگر اینکه از قبل کلیدی با همین نام دارید. - passphrase: رمزی که خود کلید خصوصی را قفل میکند. اگر لپتاپتان دزدیده شود، همین رمز جلوی استفاده از کلید را میگیرد. توصیه میکنیم خالیاش نگذارید.
نتیجه دو فایل است:
~/.ssh/id_ed25519 ← کلید خصوصی؛ به هیچکس ندهید
~/.ssh/id_ed25519.pub ← کلید عمومی؛ این را روی سرور میگذارید
برای اینکه passphrase را در هر اتصال تایپ نکنید، کلید را یک بار به ssh-agent بدهید:
eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_ed25519
در macOS و بیشتر دسکتاپهای لینوکس، agent از قبل در حال اجراست و فقط ssh-add کافی است.
ساخت کلید SSH در ویندوز
ویندوز ۱۰ (از نسخهی 1809) و ویندوز ۱۱ کلاینت OpenSSH را بهصورت داخلی دارند و دیگر نیازی به PuTTY نیست. PowerShell را باز کنید و همان دستور را بزنید:
ssh-keygen -t ed25519 -C "you@example.com"
فایلها در C:\Users\<نامکاربری>\.ssh\ ساخته میشوند. اگر پیام «ssh-keygen is not recognized» گرفتید، از Settings → System → Optional features قابلیت «OpenSSH Client» را نصب کنید.
برای استفاده از ssh-agent در ویندوز، سرویسش بهطور پیشفرض غیرفعال است. یک بار PowerShell را با دسترسی Administrator باز کنید:
Get-Service ssh-agent | Set-Service -StartupType Automatic
Start-Service ssh-agent
سپس در یک PowerShell معمولی کلید را اضافه کنید:
ssh-add $env:USERPROFILE\.ssh\id_ed25519
کپی کلید عمومی روی سرور
با ssh-copy-id (لینوکس و macOS)
سادهترین راه:
ssh-copy-id -i ~/.ssh/id_ed25519.pub deploy@203.0.113.10
یک بار رمز کاربر را میپرسد، کلید را به انتهای ~/.ssh/authorized_keys روی سرور اضافه میکند و دسترسیها را هم درست تنظیم میکند.
روش دستی (و روش ویندوز)
ویندوز ssh-copy-id ندارد، ولی این یک خط در PowerShell همان کار را میکند:
type $env:USERPROFILE\.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"
اگر به سرور دسترسی دیگری دارید (مثلاً کنسول وب سرویسدهنده)، میتوانید محتوای فایل .pub را کپی کنید و روی سرور در یک خط جدید از ~/.ssh/authorized_keys بچسبانید. هر کلید دقیقاً یک خط است؛ مراقب باشید ویرایشگر آن را نشکند.
حالا امتحان کنید:
ssh deploy@203.0.113.10
اگر بدون پرسیدن رمز کاربر وارد شدید (یا فقط passphrase کلید را پرسید)، کار درست است. بعد از این مرحله میتوانید ورود با رمز را روی سرور غیرفعال کنید؛ جزئیاتش در ساعت اول یک سرور تازه آمده است. پیش از بستن نشست فعلی، در یک پنجرهی جدید ورود را امتحان کنید تا خودتان را بیرون قفل نکنید.
دسترسی فایلها: 700 و 600
OpenSSH روی دسترسی فایلها سختگیر است. اگر پوشه یا فایلها برای کاربران دیگر قابلنوشتن باشند، کلید را نادیده میگیرد و دوباره رمز میخواهد. روی سرور:
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
chmod go-w ~
و روی سیستم خودتان (لینوکس و macOS):
chmod 700 ~/.ssh
chmod 600 ~/.ssh/id_ed25519 ~/.ssh/config
chmod 644 ~/.ssh/id_ed25519.pub
اگر هنگام اتصال پیام UNPROTECTED PRIVATE KEY FILE دیدید، دقیقاً همین دسترسی کلید خصوصی مشکل دارد.
کوتاهکردن دستور اتصال با ~/.ssh/config
وقتی چند سرور با کاربر، پورت و کلید متفاوت دارید، بهخاطر سپردن همهشان سخت است. فایل ~/.ssh/config (در ویندوز C:\Users\<نامکاربری>\.ssh\config) برای هر سرور یک نام مستعار میسازد:
Host app
HostName 203.0.113.10
User deploy
Port 22
IdentityFile ~/.ssh/id_ed25519
IdentitiesOnly yes
Host staging
HostName 198.51.100.20
User deploy
IdentityFile ~/.ssh/id_ed25519_staging
IdentitiesOnly yes
Host *
ServerAliveInterval 60
از این به بعد به جای دستور طولانی فقط مینویسید ssh app. همین نام در scp و rsync هم کار میکند: scp backup.sql app:/tmp/. گزینهی IdentitiesOnly yes باعث میشود SSH فقط همان کلید مشخصشده را امتحان کند، نه همهی کلیدهای داخل agent را؛ این کار جلوی خطای «Too many authentication failures» را میگیرد. ServerAliveInterval هم مانع قطعشدن نشستهای بیکار میشود.
اضافهکردن کلید SSH به GitHub
با کلید SSH، git push و git pull دیگر نام کاربری و توکن نمیخواهند.
- محتوای کلید عمومی را کپی کنید:
- لینوکس:
cat ~/.ssh/id_ed25519.pub - macOS:
pbcopy < ~/.ssh/id_ed25519.pub - ویندوز:
Get-Content $env:USERPROFILE\.ssh\id_ed25519.pub | Set-Clipboard
- لینوکس:
- در GitHub به Settings → SSH and GPG keys بروید و New SSH key را بزنید.
- یک عنوان (مثلاً نام لپتاپ) بنویسید، نوع را Authentication Key بگذارید و کلید را بچسبانید.
حالا اتصال را آزمایش کنید:
ssh -T git@github.com
بار اول باید اثر انگشت GitHub را تأیید کنید؛ آن را با فهرست رسمی در مستندات GitHub مقایسه کنید. پاسخ موفق این شکلی است:
Hi username! You've successfully authenticated, but GitHub does not provide shell access.
از این به بعد مخزنها را با آدرس SSH کلون کنید: git clone git@github.com:username/repo.git. اگر مخزنی را قبلاً با HTTPS کلون کردهاید، آدرسش را عوض کنید:
git remote set-url origin git@github.com:username/repo.git
برای سروری که فقط باید یک مخزن را pull کند، به جای کلید شخصیتان از Deploy key در تنظیمات همان مخزن استفاده کنید تا دسترسی سرور به همان یک مخزن محدود بماند. دستورهای روزمرهی گیت را هم در دستورات ضروری Git آوردهایم.
خطاهای رایج و راهحل
Permission denied (publickey)
یعنی سرور هیچکدام از کلیدهایی را که فرستادید قبول نکرد. به ترتیب بررسی کنید:
- آیا با کاربر درست وصل میشوید؟ کلید در
authorized_keysهمان کاربر است، نه root؟ - آیا کلید عمومی کامل و در یک خط کپی شده؟
- دسترسیهای 700 و 600 روی سرور درست است؟
- اگر چند کلید دارید، با
-iیاIdentityFileکلید درست را مشخص کردهاید؟
بهترین ابزار عیبیابی حالت verbose است که نشان میدهد کدام کلیدها امتحان شدهاند:
ssh -v deploy@203.0.113.10
اگر به سرور دسترسی دیگری دارید، لاگ سمت سرور دلیل دقیق را میگوید:
sudo journalctl -u ssh -n 50
REMOTE HOST IDENTIFICATION HAS CHANGED
SSH اثر انگشت هر سرور را بار اول در ~/.ssh/known_hosts ذخیره میکند. اگر بعداً تغییر کند، این هشدار بزرگ را میبینید. دلیل معمولش بیخطر است: سرور را دوباره نصب کردهاید یا IP قبلی به سرور جدیدی داده شده. ولی همین هشدار برای تشخیص حملهی مرد میانی ساخته شده، پس پیش از رد شدن مطمئن شوید که تغییر از طرف خودتان بوده. بعد اثر انگشت قدیمی را پاک کنید:
ssh-keygen -R 203.0.113.10
و دوباره وصل شوید تا اثر انگشت جدید ثبت شود.
Connection refused یا Connection timed out
این دو ربطی به کلید ندارند. refused یعنی سرور در دسترس است ولی روی آن پورت سرویس SSH گوش نمیدهد (سرویس خاموش است یا پورت عوض شده). timed out یعنی بستهها اصلاً به سرور نمیرسند؛ IP، دیوار آتش سرور (ufw) یا فایروال سرویسدهنده را بررسی کنید.
جمعبندی
اتصال SSH با یک دستور ssh user@host شروع میشود، ولی کار حرفهای با کلید انجام میشود: یک بار با ssh-keygen -t ed25519 کلید بسازید، یک passphrase رویش بگذارید، کلید عمومی را با ssh-copy-id یا روش دستی روی سرور و در GitHub قرار دهید، و برای هر سرور در ~/.ssh/config یک نام کوتاه تعریف کنید. دسترسیهای 700 و 600 را فراموش نکنید و در هر خطا اول سراغ ssh -v بروید. بعد از آن، کار با خود سرور شروع میشود؛ دستورات ضروری لینوکس نقطهی خوبی برای قدم بعدی است.