۸. SSH و مدیریت راه دور¶
SSH درِ اصلی هر سرور است؛ هم مهمترین ابزار شما و هم اولین هدف مهاجم. دو قانون: هرگز خودتان را بیرون نکنید (نشست فعلی را تا تأیید اتصال جدید باز نگه دارید) و هر تغییر را اول اعتبارسنجی کنید (sshd -t).
راهنمای سریع¶
| فرمان | کاربرد | ریسک |
|---|---|---|
ssh -v / ssh -G HOST |
عیبیابی اتصال / تنظیمات مؤثر کلاینت | بدون تغییر |
sudo sshd -t / sudo sshd -T |
اعتبارسنجی / تنظیمات مؤثر سرور | بدون تغییر |
ssh-keygen -lf |
اثرانگشت کلید | بدون تغییر |
scp / rsync / sftp |
انتقال فایل | تغییر |
ssh-copy-id / ssh-keygen -R |
نصب کلید / حذف host key قدیمی | تغییر |
ویرایش sshd_config + reload |
سختگیری | مخرب (قفل شدن از سرور) |
rsync --delete |
همگامسازی با حذف | مخرب |
اتصال و کپی فایل¶
ssh admin@SERVER_IP
ssh -p 2222 admin@SERVER_IP
ssh admin@SERVER_IP 'uptime; df -h /' # اجرای یک فرمان
ssh -t admin@SERVER_IP 'sudo systemctl status nginx' # -t: برای فرمانهای تعاملی (sudo)
scp ./file.txt admin@SERVER_IP:/tmp/
scp admin@SERVER_IP:/var/log/syslog ./syslog.remote
rsync -avh --progress ./project/ admin@SERVER_IP:/opt/project/
rsync -avhn ./project/ admin@SERVER_IP:/opt/project/ # -n: فقط نشان بده، انجام نده
sftp admin@SERVER_IP
در rsync، اسلش انتهای مسیر مبدأ مهم است: source/ محتویات را کپی میکند؛ source خود پوشه را هم در مقصد ایجاد میکند. همیشه اول با -n تست کنید. scp در نسخههای جدید OpenSSH از پروتکل SFTP استفاده میکند و برای کارهای جدی rsync/sftp ترجیح دارد.
کلید SSH¶
ssh-keygen -t ed25519 -C "admin@workstation"
ssh-copy-id admin@SERVER_IP
ssh -i ~/.ssh/id_ed25519 admin@SERVER_IP
ssh-add ~/.ssh/id_ed25519
ssh-add -l
ssh-keygen -lf ~/.ssh/id_ed25519.pub # اثرانگشت (برای مقایسه)
کلید خصوصی را منتشر نکنید و برای آن passphrase در نظر بگیرید. مجوزهای رایج: ~/.ssh برابر 700 و کلید خصوصی برابر 600. برای هر شخص/دستگاه کلید جدا بسازید تا بتوان یکی را ابطال کرد.
محدودکردن کلید در authorized_keys¶
هر خط ~/.ssh/authorized_keys میتواند گزینه داشته باشد (پیش از نوع کلید):
# فقط از این شبکه، بدون tunnel/pty، و فقط یک فرمان (مثلاً حساب بکاپ)
from="192.0.2.0/24",no-port-forwarding,no-agent-forwarding,no-X11-forwarding,command="/usr/local/bin/backup-receive" ssh-ed25519 AAAA... backup@host
فایل ~/.ssh/config (کلاینت)¶
# ~/.ssh/config (مجوز 600)
Host bastion
HostName 192.0.2.5
User admin
IdentityFile ~/.ssh/id_ed25519
IdentitiesOnly yes
Host app-*
User admin
ProxyJump bastion # عبور از bastion بدون agent forwarding
ServerAliveInterval 30
ServerAliveCountMax 3
Host app-prod1
HostName 198.51.100.11
ssh app-prod1 # از طریق bastion
ssh -J admin@192.0.2.5 admin@198.51.100.11 # یکباره، بدون config
ssh -G app-prod1 | grep -Ei '^(hostname|user|proxyjump|identityfile) '
از ForwardAgent yes (ssh -A) روی میزبانهای غیرقابلاعتماد بپرهیزید: root آن سرور میتواند از agent شما سوءاستفاده کند. ProxyJump راه امنتر است.
تنظیمات و عیبیابی¶
ssh -v admin@SERVER_IP
ssh -vvv admin@SERVER_IP
sudo sshd -t
sudo sshd -T | grep -Ei 'permitrootlogin|passwordauthentication|pubkeyauthentication|allowusers|port'
sudo systemctl status ssh
sudo journalctl -u ssh --since '-30 min'
در برخی توزیعها نام سرویس sshd است (RHEL) و در بعضی ssh (Debian/Ubuntu؛ alias sshd هم معمولاً هست). sshd -T مقدار مؤثر نهایی را نشان میدهد؛ تنها منبع قابلاعتماد برای اینکه «چه چیزی واقعاً فعال است».
رویهٔ ایمن تغییر sshd (بدون قفل شدن)¶
- نشست فعلی را باز نگه دارید و یک نشست دوم (یا کنسول) آماده داشته باشید.
- نسخهٔ پشتیبان:
sudo cp -a /etc/ssh/sshd_config /etc/ssh/sshd_config.bak.$(date +%F) - اعمال تغییر، سپس
sudo sshd -t(نباید خروجی بدهد). sudo sshd -T | grep ...برای تأیید مقدار مؤثر.sudo systemctl reload ssh(نه restart؛ reload اتصالهای موجود را نمیکشد).- از نشست جدید وارد شوید و تأیید کنید؛ فقط بعد از آن نشست قدیمی را ببندید.
- شبکهای که ممکن است بعد از تغییر دسترسی نداشته باشد (فایروال): یک «برگرداننده» زماندار:
echo 'cp /etc/ssh/sshd_config.bak.DATE /etc/ssh/sshd_config && systemctl reload ssh' | sudo at now + 10 minutesو بعد از تأییدatrm.
پیکربندی امنتر¶
فایل معمولاً /etc/ssh/sshd_config یا فایلهای زیر /etc/ssh/sshd_config.d/ است.
# /etc/ssh/sshd_config.d/10-hardening.conf (نمونه)
PermitRootLogin no
PasswordAuthentication no
KbdInteractiveAuthentication no
PubkeyAuthentication yes
PermitEmptyPasswords no
AllowUsers admin1 admin2
MaxAuthTries 3
LoginGraceTime 30
X11Forwarding no
AllowAgentForwarding no
ClientAliveInterval 300
ClientAliveCountMax 2
ترتیب فایلهای sshd_config.d: اولین مقدار برنده است
در OpenSSH برای هر گزینه اولین مقدار خواندهشده معتبر است و فایلهای .d به ترتیب حروفالفبا خوانده میشوند. فایلهای cloud-init (مثل 50-cloud-init.conf با PasswordAuthentication yes) ممکن است تنظیم شما را بیاثر کنند. نام فایل خود را با عدد کوچک بگذارید (10-…) و حتماً با sshd -T مقدار مؤثر را ببینید، نه فقط فایل را.
- ورود مستقیم root را در صورت امکان غیرفعال کنید.
- احراز هویت کلیدی را ترجیح دهید، اما قبل از غیرفعالکردن گذرواژه، ورود کلیدی را از یک نشست جداگانه آزمایش کنید.
- دسترسی کاربران را با
AllowUsersیاAllowGroupsمحدود کنید. - تغییر پورت بهتنهایی جایگزین کنترل دسترسی و بهروزرسانی نیست (فقط نویز لاگ را کم میکند).
- محدودکردن منبع با فایروال (
ufw allow from 192.0.2.0/24 to any port 22) از هر تنظیم sshd مؤثرتر است. - ضد brute-force:
fail2banیاsshguard(امنیت).
تونل SSH¶
# تونل محلی: پورت محلی 15432 به پورت 5432 سرور مقصد
ssh -N -L 15432:127.0.0.1:5432 admin@SERVER_IP
# تونل معکوس: پورت 9000 روی سرور به سرویس محلی شما
ssh -N -R 9000:127.0.0.1:3000 admin@SERVER_IP
# SOCKS proxy پویا
ssh -N -D 1080 admin@SERVER_IP
# پسزمینه
ssh -f -N -L 15432:127.0.0.1:5432 admin@SERVER_IP
تونل را فقط برای سرویسهایی ایجاد کنید که مجاز به دسترسی به آنها هستید؛ فراموش نکنید که تونل ممکن است کنترلهای شبکهای را دور بزند. تونلهای پسزمینه را ببینید و ببندید: ps aux | grep 'ssh -f'.
هشدار تغییر کلید میزبان¶
این پیام یا یعنی سرور بازسازی/تعویض شده (بیخطر)، یا حملهٔ man-in-the-middle. قبل از هر کاری اثرانگشت را از راه امن دیگر (کنسول) با ssh-keygen -lf /etc/ssh/ssh_host_ed25519_key.pub مقایسه کنید؛ فقط بعد از اطمینان:
StrictHostKeyChecking no را بهصورت عمومی تنظیم نکنید.
خطاهای رایج¶
| نشانه | علت احتمالی | روش بررسی |
|---|---|---|
Permission denied (publickey) |
کلید نصب نیست/مجوزها اشتباه/کاربر ممنوع | ssh -v ؛ سرور: journalctl -u ssh |
Authentication refused: bad ownership or modes |
مجوز ~، ~/.ssh یا authorized_keys زیادی باز است |
chmod go-w ~ ; chmod 700 ~/.ssh ; chmod 600 ~/.ssh/authorized_keys |
Too many authentication failures |
agent کلیدهای زیادی میفرستد | ssh -o IdentitiesOnly=yes -i KEY |
Connection refused |
sshd اجرا نیست / پورت اشتباه | systemctl status ssh ، ss -lntp \| grep sshd |
Connection timed out |
فایروال/مسیر/IP اشتباه | nc -vz IP 22 ، traceroute |
| بعد از reload دسترسی نیست | سینتکس/AllowUsers/فایروال | کنسول؛ sshd -t ؛ برگرداندن بکاپ |
| تنظیم PasswordAuthentication اثر ندارد | فایل .d با اولویت بالاتر |
sshd -T \| grep passwordauth |
| نشست بعد از چند دقیقه میمیرد | NAT/فایروال idle timeout | ServerAliveInterval 30 ؛ tmux |
نکات امنیتی و عملیاتی¶
- کلید خصوصی بدون passphrase روی لپتاپ = دسترسی به همهٔ سرورها اگر لپتاپ برود. از
ssh-agent+ passphrase یا کلید سختافزاری استفاده کنید. - کلید کارمند خارجشده را از همهٔ
authorized_keysها حذف کنید (فهرستبرداری: ممیزی حسابها). - لاگ ورودها را مرکزی کنید؛
Accepted publickeyاز IP/ساعت غیرعادی را هشدار دهید. - ساعت و مجوز فایلها را در
~/.sshدورهای بازبینی کنید.
خلاصهٔ اجرایی¶
- تغییر sshd:
sshd -t←sshd -T← reload ← نشست جدید ← فقط بعد نشست قدیمی را ببند. - مقدار مؤثر را با
sshd -Tبخوانید (ترتیب.dمهم است). ProxyJumpبهجای agent forwarding؛ کلید با passphrase.- هشدار تغییر host key را جدی بگیرید.