SSH-ключи: один раз настроил — забыл о паролях навсегда
Если ты до сих пор подключаешься к серверу вводя пароль каждый раз — эта статья изменит твою жизнь. Немного, но приятно.
SSH-ключи — это одна из тех вещей, которые кажутся сложными пока не разберёшься. А потом думаешь: «почему я не сделал это раньше?». Настраивается один раз за десять минут, работает годами, и заодно делает твой сервер значительно безопаснее.
Давай разберём всё по-человечески — без академических определений и лишней воды.
Сначала — зачем это вообще нужно
Обычная схема подключения по SSH с паролем выглядит так:
ssh user@192.168.1.100
# вводишь пароль
# подключился
Казалось бы — что не так? Работает же. Проблем несколько.
Пароли брутфорсят. Любой сервер с открытым 22-м портом получает тысячи попыток подбора пароля в сутки. Это не преувеличение — это реальность. Зайди в /var/log/auth.log на своём сервере и посмотри сколько там строчек Failed password for root. Гарантирую — удивишься.
Пароли можно забыть, подсмотреть, утечь. Ключ — это файл на твоей машине. Его не подберут перебором.
Пароли неудобны при автоматизации. Скрипты, CI/CD, rsync между серверами — всё это требует авторизации. С паролем это головная боль. С ключами — просто работает.
Ключи можно отозвать точечно. Если дал доступ к серверу коллеге — удаляешь его ключ и всё. Не меняешь пароль для всех.
Как это работает — объясняю без магии
SSH-ключи работают по принципу асимметричной криптографии. Звучит страшно, на практике просто:
Генерируешь пару ключей — публичный и приватный. Они математически связаны.
- Приватный ключ — хранится только у тебя на машине. Никому не передаётся. Никогда.
- Публичный ключ — кладётся на сервер. Его можно показывать кому угодно, в этом нет ничего страшного.
Когда ты подключаешься — сервер видит публичный ключ, твоя машина доказывает что у неё есть соответствующий приватный ключ (не передавая его!), и соединение устанавливается. Без ввода пароля.
Аналогия из жизни: публичный ключ — это замок, который ты вешаешь на сервере. Приватный ключ — это ключ от замка, который только у тебя. Замок можно показывать всем — без ключа его всё равно не открыть.
Генерируем ключи — делаем один раз
Открываем терминал на своей машине (не на сервере!).
bash
ssh-keygen -t ed25519 -C "my-work-laptop"
```
Что тут происходит:
- `-t ed25519` — алгоритм шифрования. Ed25519 — современный и надёжный, используй его. Старый RSA тоже работает, но ed25519 лучше.
- `-C "my-work-laptop"` — комментарий. Просто метка, чтобы потом понимать, какой ключ от какой машины.
Команда спросит несколько вещей:
```
Enter file in which to save the key (/home/user/.ssh/id_ed25519):
```
Просто жмёшь Enter — сохранится в стандартное место. Можно указать другой путь, если хочешь несколько ключей для разных серверов.
```
Enter passphrase (empty for no passphrase):
```
Здесь — на твоё усмотрение. Passphrase — это пароль на сам ключ. Если кто-то украдёт файл ключа — без passphrase он сразу сможет его использовать. С passphrase — нет.
Для рабочих серверов — рекомендую поставить passphrase. Для домашних экспериментов — можно оставить пустым, просто жмёшь Enter дважды.
После генерации в папке `~/.ssh/` появятся два файла:
```
~/.ssh/id_ed25519 # приватный ключ — никому не показываем
~/.ssh/id_ed25519.pub # публичный ключ — кладём на сервера
Посмотреть публичный ключ:
bash
cat ~/.ssh/id_ed25519.pub
```
Увидишь что-то вроде:
```
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBkDv... my-work-laptop
Вот эту строку целиком — нужно будет положить на сервер.
Копируем ключ на сервер — три способа
Способ 1 — автоматический (самый простой)
bash
ssh-copy-id user@192.168.1.100
Команда сама скопирует публичный ключ на сервер в нужное место. Один раз спросит пароль (в последний раз!) — и всё.
Если ключ не дефолтный:
bash
ssh-copy-id -i ~/.ssh/id_ed25519.pub user@192.168.1.100
Способ 2 — вручную через pipe
Если ssh-copy-id нет (бывает на некоторых системах):
bash
cat ~/.ssh/id_ed25519.pub | ssh user@192.168.1.100 "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys"
Выглядит страшно, но делает простую вещь: берёт содержимое публичного ключа и дописывает его в файл ~/.ssh/authorized_keys на сервере.
Способ 3 — руками
Заходишь на сервер с паролем, открываешь файл:
bash
nano ~/.ssh/authorized_keys
Вставляешь строку с публичным ключом, сохраняешь. Всё.
Файл authorized_keys — это просто список публичных ключей, которым разрешено подключаться. По одному на строку. Хочешь дать доступ ещё кому-то — добавляешь его ключ новой строкой.
Проверяем что всё работает
bash
ssh user@192.168.1.100
Если настроено правильно — подключится без запроса пароля. Вот и всё.
Если не работает — проверяем права на файлы. Это частая проблема:
bash
# На сервере
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
SSH очень параноидален по поводу прав доступа. Если на папке .ssh или файле authorized_keys права слишком открытые — он откажется их использовать. 700 для папки, 600 для файла — запомни эти цифры.
Отключаем вход по паролю — делаем сервер реально безопасным
Это важный шаг, который многие пропускают. Ключи настроили — хорошо. Но если вход по паролю остался включён — брутфорс никуда не делся.
Сначала убедись, что вход по ключу работает. Не закрывай текущую SSH-сессию — открой новый терминал и подключись. Если работает — продолжаем.
На сервере открываем конфиг SSH:
bash
sudo nano /etc/ssh/sshd_config
```
Находим и меняем (или добавляем) строки:
```
PasswordAuthentication no
PubkeyAuthentication yes
AuthorizedKeysFile .ssh/authorized_keys
```
И ещё одна важная строка — отключаем вход под root:
```
PermitRootLogin no
Зачем? Потому что все брутфорс-боты в первую очередь пробуют именно root. Убрал root-логин — сразу отсёк большую часть атак.
Перезапускаем SSH:
bash
sudo systemctl restart sshd
И ещё раз проверяем подключение из нового терминала — убеждаемся что всё работает.
Несколько ключей для разных серверов
Со временем серверов становится больше. Удобно иметь разные ключи — например, один для рабочих серверов, другой для личных проектов.
Генерируем ключ с кастомным именем:
bash
ssh-keygen -t ed25519 -f ~/.ssh/id_work -C "work-servers"
ssh-keygen -t ed25519 -f ~/.ssh/id_personal -C "personal-vps"
Чтобы не указывать ключ каждый раз вручную — создаём файл конфигурации SSH:
bash
nano ~/.ssh/config
```
И прописываем:
```
Host work-server
HostName 203.0.113.10
User deploy
IdentityFile ~/.ssh/id_work
Host my-vps
HostName 198.51.100.5
User ivan
IdentityFile ~/.ssh/id_personal
Port 2222
Теперь вместо:
bash
ssh -i ~/.ssh/id_personal -p 2222 ivan@198.51.100.5
Просто пишешь:
bash
ssh my-vps
И всё. SSH сам знает какой ключ использовать, какой порт, какого пользователя. Это реально удобно когда серверов несколько.
SSH-агент — вводим passphrase один раз за сессию
Если поставил passphrase на ключ — каждое подключение будет просить его вводить. Неудобно. Для этого есть ssh-agent.
Агент хранит разблокированный ключ в памяти в течение текущей сессии. Вводишь passphrase один раз при загрузке системы — и до перезагрузки больше не вводишь.
bash
# Запустить агента
eval "$(ssh-agent -s)"
# Добавить ключ (спросит passphrase один раз)
ssh-add ~/.ssh/id_ed25519
На macOS это работает ещё удобнее — passphrase можно сохранить в Keychain и вводить вообще только при первом использовании после перезагрузки системы:
bash
ssh-add --apple-use-keychain ~/.ssh/id_ed25519
Полезные мелочи, которые экономят нервы
Скопировать публичный ключ в буфер обмена:
bash
# macOS
cat ~/.ssh/id_ed25519.pub | pbcopy
# Linux с xclip
cat ~/.ssh/id_ed25519.pub | xclip -selection clipboard
Удобно когда нужно вставить ключ в веб-интерфейс (GitHub, GitLab, панель хостинга).
Проверить какие ключи добавлены в агент:
bash
ssh-add -l
Подключиться с отладочным выводом — если что-то не работает:
bash
ssh -vvv user@server
Флаг -vvv выводит подробный лог подключения. Сразу видно на каком шаге проблема — ключ не найден, не та директория, проблема с правами и т.д.
Прокинуть SSH-агент на удалённый сервер:
bash
ssh -A user@server
Флаг -A — agent forwarding. Подключился к серверу A, с него нужно подключиться к серверу B — и ключи с твоей машины будут доступны. Не нужно копировать ключи на промежуточные серверы.
Осторожно: не используй -A на серверах, которым не доверяешь полностью. Администратор такого сервера теоретически может воспользоваться твоим агентом.
Типичные ошибки и как их решать
«Permission denied (publickey)»
Первым делом проверяешь права:
bash
ls -la ~/.ssh/
Должно быть:
- ~/.ssh — drwx------ (700)
- ~/.ssh/authorized_keys — -rw------- (600)
- ~/.ssh/id_ed25519 — -rw------- (600)
Если что-то не так:
bash
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
chmod 600 ~/.ssh/id_ed25519
Убеждаешься что ключ вообще скопирован:
bash
cat ~/.ssh/authorized_keys
Должна быть строка с твоим публичным ключом.
Проверяешь что SSH вообще разрешает ключи — в /etc/ssh/sshd_config строка PubkeyAuthentication yes должна быть раскомментирована.
«Warning: Unprotected private key file»
SSH ругается на права приватного ключа. Решается одной командой:
bash
chmod 600 ~/.ssh/id_ed25519
Хост изменился — «WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED»
Бывает когда переустанавливаешь сервер — меняются его ключи, а у тебя в known_hosts старые. Страшное сообщение, но решается просто:
bash
ssh-keygen -R hostname_or_ip
Удаляет старую запись из known_hosts. При следующем подключении SSH попросит подтвердить новый отпечаток сервера.
Бонус — SSH-ключи для GitHub и GitLab
Тот же механизм работает и для git-репозиториев. Больше не нужно вводить логин/пароль при каждом push.
Берёшь содержимое публичного ключа:
bash
cat ~/.ssh/id_ed25519.pub
Идёшь в GitHub → Settings → SSH and GPG keys → New SSH key. Вставляешь, сохраняешь.
Проверяешь:
bash
ssh -T git@github.com
# Hi username! You've successfully authenticated...
И меняешь remote репозитория на SSH-адрес если ещё не:
bash
git remote set-url origin git@github.com:username/repo.git
Всё — push и pull без паролей навсегда.
Итог — что сделать прямо сейчас
Если дочитал до сюда — значит понял концепцию. Теперь конкретный план действий:
- Генерируй ключ: ssh-keygen -t ed25519 -C "my-machine"
- Копируй на сервер: ssh-copy-id user@your-server
- Проверь что работает — подключись без пароля
- Отключи вход по паролю в sshd_config
- Настрой ~/.ssh/config если серверов несколько
- Добавь ключ в GitHub/GitLab
Десять минут работы — и ты забываешь о паролях при работе с серверами. А сервер при этом становится значительно защищённее.
Если есть вопросы или что-то пошло не так — пиши в комментарии, разберём.