برای اتصال 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

ترمینال را باز کنید و بزنید:

bash
ssh-keygen -t ed25519 -C "you@example.com"

بخش -C فقط یک توضیح است تا بعداً بدانید این کلید مال کیست؛ معمولاً ایمیل یا نام سیستم را می‌نویسند. دستور دو سؤال می‌پرسد:

  1. محل ذخیره: پیش‌فرض ~/.ssh/id_ed25519 است. Enter بزنید، مگر اینکه از قبل کلیدی با همین نام دارید.
  2. passphrase: رمزی که خود کلید خصوصی را قفل می‌کند. اگر لپ‌تاپ‌تان دزدیده شود، همین رمز جلوی استفاده از کلید را می‌گیرد. توصیه می‌کنیم خالی‌اش نگذارید.

نتیجه دو فایل است:

text
~/.ssh/id_ed25519       ← کلید خصوصی؛ به هیچ‌کس ندهید
~/.ssh/id_ed25519.pub   ← کلید عمومی؛ این را روی سرور می‌گذارید

برای اینکه passphrase را در هر اتصال تایپ نکنید، کلید را یک بار به ssh-agent بدهید:

bash
eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_ed25519

در macOS و بیشتر دسکتاپ‌های لینوکس، agent از قبل در حال اجراست و فقط ssh-add کافی است.

ساخت کلید SSH در ویندوز

ویندوز ۱۰ (از نسخه‌ی 1809) و ویندوز ۱۱ کلاینت OpenSSH را به‌صورت داخلی دارند و دیگر نیازی به PuTTY نیست. PowerShell را باز کنید و همان دستور را بزنید:

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 باز کنید:

powershell
Get-Service ssh-agent | Set-Service -StartupType Automatic
Start-Service ssh-agent

سپس در یک PowerShell معمولی کلید را اضافه کنید:

powershell
ssh-add $env:USERPROFILE\.ssh\id_ed25519

کپی کلید عمومی روی سرور

با ssh-copy-id (لینوکس و macOS)

ساده‌ترین راه:

bash
ssh-copy-id -i ~/.ssh/id_ed25519.pub deploy@203.0.113.10

یک بار رمز کاربر را می‌پرسد، کلید را به انتهای ~/.ssh/authorized_keys روی سرور اضافه می‌کند و دسترسی‌ها را هم درست تنظیم می‌کند.

روش دستی (و روش ویندوز)

ویندوز ssh-copy-id ندارد، ولی این یک خط در PowerShell همان کار را می‌کند:

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 بچسبانید. هر کلید دقیقاً یک خط است؛ مراقب باشید ویرایشگر آن را نشکند.

حالا امتحان کنید:

bash
ssh deploy@203.0.113.10

اگر بدون پرسیدن رمز کاربر وارد شدید (یا فقط passphrase کلید را پرسید)، کار درست است. بعد از این مرحله می‌توانید ورود با رمز را روی سرور غیرفعال کنید؛ جزئیاتش در ساعت اول یک سرور تازه آمده است. پیش از بستن نشست فعلی، در یک پنجره‌ی جدید ورود را امتحان کنید تا خودتان را بیرون قفل نکنید.

دسترسی فایل‌ها: 700 و 600

OpenSSH روی دسترسی فایل‌ها سخت‌گیر است. اگر پوشه یا فایل‌ها برای کاربران دیگر قابل‌نوشتن باشند، کلید را نادیده می‌گیرد و دوباره رمز می‌خواهد. روی سرور:

bash
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
chmod go-w ~

و روی سیستم خودتان (لینوکس و macOS):

bash
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) برای هر سرور یک نام مستعار می‌سازد:

~/.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 دیگر نام کاربری و توکن نمی‌خواهند.

  1. محتوای کلید عمومی را کپی کنید:
    • لینوکس: cat ~/.ssh/id_ed25519.pub
    • macOS: pbcopy < ~/.ssh/id_ed25519.pub
    • ویندوز: Get-Content $env:USERPROFILE\.ssh\id_ed25519.pub | Set-Clipboard
  2. در GitHub به Settings → SSH and GPG keys بروید و New SSH key را بزنید.
  3. یک عنوان (مثلاً نام لپ‌تاپ) بنویسید، نوع را Authentication Key بگذارید و کلید را بچسبانید.

حالا اتصال را آزمایش کنید:

bash
ssh -T git@github.com

بار اول باید اثر انگشت GitHub را تأیید کنید؛ آن را با فهرست رسمی در مستندات GitHub مقایسه کنید. پاسخ موفق این شکلی است:

text
Hi username! You've successfully authenticated, but GitHub does not provide shell access.

از این به بعد مخزن‌ها را با آدرس SSH کلون کنید: git clone git@github.com:username/repo.git. اگر مخزنی را قبلاً با HTTPS کلون کرده‌اید، آدرسش را عوض کنید:

bash
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 است که نشان می‌دهد کدام کلیدها امتحان شده‌اند:

bash
ssh -v deploy@203.0.113.10

اگر به سرور دسترسی دیگری دارید، لاگ سمت سرور دلیل دقیق را می‌گوید:

bash
sudo journalctl -u ssh -n 50

REMOTE HOST IDENTIFICATION HAS CHANGED

SSH اثر انگشت هر سرور را بار اول در ~/.ssh/known_hosts ذخیره می‌کند. اگر بعداً تغییر کند، این هشدار بزرگ را می‌بینید. دلیل معمولش بی‌خطر است: سرور را دوباره نصب کرده‌اید یا IP قبلی به سرور جدیدی داده شده. ولی همین هشدار برای تشخیص حمله‌ی مرد میانی ساخته شده، پس پیش از رد شدن مطمئن شوید که تغییر از طرف خودتان بوده. بعد اثر انگشت قدیمی را پاک کنید:

bash
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 بروید. بعد از آن، کار با خود سرور شروع می‌شود؛ دستورات ضروری لینوکس نقطه‌ی خوبی برای قدم بعدی است.