Найти в Дзене
Ivan-Yurievich

SSH-ключи: один раз настроил — забыл о паролях навсегда

Если ты до сих пор подключаешься к серверу вводя пароль каждый раз — эта статья изменит твою жизнь. Немного, но приятно. SSH-ключи — это одна из тех вещей, которые кажутся сложными пока не разберёшься. А потом думаешь: «почему я не сделал это раньше?». Настраивается один раз за десять минут, работает годами, и заодно делает твой сервер значительно безопаснее. Давай разберём всё по-человечески — без академических определений и лишней воды. Обычная схема подключения по SSH с паролем выглядит так: ssh user@192.168.1.100
# вводишь пароль
# подключился Казалось бы — что не так? Работает же. Проблем несколько. Пароли брутфорсят. Любой сервер с открытым 22-м портом получает тысячи попыток подбора пароля в сутки. Это не преувеличение — это реальность. Зайди в /var/log/auth.log на своём сервере и посмотри сколько там строчек Failed password for root. Гарантирую — удивишься. Пароли можно забыть, подсмотреть, утечь. Ключ — это файл на твоей машине. Его не подберут перебором. Пароли неудобны при а
Оглавление

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 без паролей навсегда.

Итог — что сделать прямо сейчас

Если дочитал до сюда — значит понял концепцию. Теперь конкретный план действий:

  1. Генерируй ключ: ssh-keygen -t ed25519 -C "my-machine"
  2. Копируй на сервер: ssh-copy-id user@your-server
  3. Проверь что работает — подключись без пароля
  4. Отключи вход по паролю в sshd_config
  5. Настрой ~/.ssh/config если серверов несколько
  6. Добавь ключ в GitHub/GitLab

Десять минут работы — и ты забываешь о паролях при работе с серверами. А сервер при этом становится значительно защищённее.

Если есть вопросы или что-то пошло не так — пиши в комментарии, разберём.