Статья · ИНСТРУКЦИИ · 15 сент. 2026 · 14 мин чтения

Как сгенерировать SSH-ключ: инструкция для Windows и Linux

Всеволод
Технический писатель · IT, облачные сервисы
Как сгенерировать SSH-ключ: инструкция для Windows и Linux
14 мин чтения

Пароль на сервере перебирают роботы, ключ — нет. Поэтому первое, что делает администратор после создания виртуальной машины, — настраивает вход по SSH-ключу и закрывает парольную аутентификацию. Ниже — полный маршрут: генерация ключей на рабочей машине, перенос публичного ключа на сервер, настройка клиента и диагностика, когда сервер отвечает Permission denied (publickey).

Что понадобится до начала и как устроена пара ключей

Часто пишут, что клиент «шифрует данные приватным ключом, а сервер расшифровывает публичным». Так это не работает: сервер отправляет клиенту вызов — случайные данные, привязанные к сессии, клиент подписывает его приватным ключом, а сервер проверяет подпись публичным. Из подписи невозможно восстановить приватный ключ, поэтому публичную половину пары безопасно размещать хоть на сотне серверов.

Что нужно иметь под рукой:

  • IP-адрес сервера и имя пользователя (root, ubuntu, admin — зависит от образа);
  • рабочий способ попасть на сервер прямо сейчас: пароль по SSH либо консоль в панели провайдера — она спасёт при ошибке в sshd_config;
  • OpenSSH-клиент на вашей машине.

Если сервера под задачу ещё нет, подойдёт облачный сервер Cloud4U — аренда по модели IaaS, где CPU, RAM и диск выделяются под конкретную нагрузку и меняются без переустановки. Для отработки ключевого доступа удобны почасовая тарификация и консоль VMware Cloud Director, через которую вы попадёте на сервер даже при полностью сломанном SSH.

Приватный и публичный ключ: что нельзя никому передавать

Приватный ключ (id_ed25519, без расширения) не покидает вашу машину никогда. Ни в мессенджер, ни в тикет поддержки, ни в git-репозиторий. Если кто-то просит прислать «ваш ключ», он имеет в виду публичный — файл .pub, одну строку вида ssh-ed25519 AAAAC3Nza... user@laptop.

Второе правило: одно устройство — одна пара ключей. Тогда при потере ноутбука вы удаляете одну строку из authorized_keys, а не перегенерируете доступ для всей команды. И генерируйте ключ на той машине, с которой будете подключаться: создавать пару на сервере и скачивать приватную часть себе — плохая практика.

Выбор алгоритма: Ed25519, RSA, ECDSA и аппаратные ключи (ed25519-sk)

По умолчанию берите Ed25519: около 128 бит стойкости, компактность, быстрая подпись и независимость от качества энтропии в момент подписи — в отличие от ECDSA, где слабая энтропия теоретически раскрывает ключ. Поддержка есть в OpenSSH с версии 6.5 (2014). DSA в современных версиях OpenSSH отключён по умолчанию и как алгоритм подписи больше не используется. RSA — только для совместимости со старым оборудованием и системами: устаревшие сетевые устройства, системы с OpenSSH ниже 6.5. Тогда 3072 или 4096 бит, но не 2048.

Отдельная ловушка: с OpenSSH 8.8 (2021) по умолчанию отключена подпись ssh-rsa на базе SHA-1. Симптом — старый RSA-ключ, годами работавший, внезапно перестаёт приниматься после обновления сервера. Сам ключ в порядке, перестал приниматься алгоритм подписи. Временное решение на клиенте:

ssh -o PubkeyAcceptedAlgorithms=+ssh-rsa user@server_ip

Правильное — перевыпустить ключ в Ed25519 или перейти на rsa-sha2-256/rsa-sha2-512: эти варианты подписи поддерживаются с OpenSSH 7.2 и остались без изменений.

Более надёжная альтернатива passphrase — привязка к аппаратному токену (YubiKey и совместимые с FIDO2):

ssh-keygen -t ed25519-sk -O resident -C "yubikey-work"

Тип ed25519-sk требует OpenSSH 8.2+ с обеих сторон. На диске остаётся только «заготовка», криптооперация выполняется внутри токена и требует физического касания, так что копировать такой ключ с украденного ноутбука бесполезно. Флаг -O resident сохраняет ключ в памяти токена — его можно извлечь на новой машине через ssh-keygen -K.

Проверка наличия OpenSSH-клиента в Linux, macOS и Windows 10/11

В Linux и macOS клиент установлен по умолчанию, версию смотрим через ssh -V. Если клиента нет: sudo apt install -y openssh-client в Debian/Ubuntu, sudo dnf install -y openssh-clients в AlmaLinux, Rocky Linux и CentOS Stream. В Windows 10 (со сборки 1809) и Windows 11 клиент доступен как встраиваемый компонент системы, но может быть не установлен; проверка и установка в PowerShell от администратора:

Get-WindowsCapability -Online -Name OpenSSH.Client*
Add-WindowsCapability -Online -Name OpenSSH.Client~~~~0.0.1.0

Если в выводе первой команды State: Installed — клиент уже на месте, при State: Not Present выполняем вторую команду. В Windows Server 2025 клиент и сервер OpenSSH установлены по умолчанию, в более ранних выпусках Windows Server, а также в Windows 10 и 11 — нет.

На Astra Linux, РЕД ОС и ALT Linux всё работает штатно — это тот же OpenSSH. Разница в другом: при аттестации ИСПДн или объектов КИИ у регулятора могут быть требования к криптоалгоритмам, и Ed25519 в перечень ГОСТ-средств формально не входит. На практике для административного доступа это закрывается организационными мерами и наложенными СЗИ, но проектную документацию лучше согласовать заранее.

Генерация ключа в Linux и macOS через ssh-keygen

ssh-keygen -t ed25519 -C "zoya@work-laptop"

Комментарий после -C попадёт в конец публичного ключа и останется видимым в authorized_keys — через полгода именно он подскажет, чей это ключ.

Утилита задаст три вопроса. Первый — путь сохранения (/home/zoya/.ssh/id_ed25519): нажмите Enter для основного ключа, для отдельной задачи задайте своё имя. Второй и третий — парольная фраза. Passphrase шифрует приватный ключ на диске: без неё файл, попавший в чужие руки, сразу даёт доступ ко всем серверам. Вводить фразу на каждое подключение не придётся — для этого есть агент ключей. Пустой passphrase разумен только для сервисных ключей автоматизации.

В выводе строка SHA256:... — отпечаток ключа, он пригодится, чтобы сверить, тот ли ключ лежит на сервере. Проверяем результат через ls -l ~/.ssh/: должны быть id_ed25519 (приватный, около 400 байт) и id_ed25519.pub (одна короткая строка — ключи Ed25519 заметно компактнее RSA).

Разбор флагов: -t, -b, -C, -a, -f

  • -t — тип ключа: ed25519, rsa, ecdsa, ed25519-sk. Исторически без флага генерировалась пара RSA, поэтому тип указываем явно.
  • -b — длина в битах. Для Ed25519 бессмысленен, для RSA обязателен: ssh-keygen -t rsa -b 4096.
  • -a — число раундов KDF при шифровании приватного ключа. По умолчанию 16; -a 100 замедляет перебор passphrase.
  • -f — путь к файлу, позволяет обойтись без интерактивного ввода:
ssh-keygen -t ed25519 -a 64 -C "deploy@ci-runner" -f ~/.ssh/id_ed25519_deploy -N ""

Здесь -N "" задаёт пустую фразу — вариант для CI/CD, не для персонального ключа. Флаг -o из старых инструкций указывать не требуется: современные версии ssh-keygen сохраняют приватный ключ в новом формате и без него.

Права доступа на ~/.ssh и владелец файлов

Самая частая причина «ключ настроил, а не пускает» — права. Демон sshd при включённом StrictModes (по умолчанию) отказывается читать ключи из каталога, доступного на запись кому-то кроме владельца; клиент так же откажется использовать приватный ключ, который видят посторонние.

chmod 700 ~/.ssh
chmod 600 ~/.ssh/id_ed25519 ~/.ssh/config
chmod 644 ~/.ssh/id_ed25519.pub

То же на сервере после установки ключа: chmod 700 ~/.ssh, chmod 600 ~/.ssh/authorized_keys, chown -R $USER:$USER ~/.ssh.

Отдельно про домашний каталог. Если на /home/zoya стоят права 775 или 777, либо владелец каталога — не тот пользователь, sshd откажет в доступе, даже когда внутри .ssh всё идеально:

chmod 750 /home/zoya
chown zoya:zoya /home/zoya

Сценарий типичен после восстановления из резервной копии или массового chmod -R по домашним каталогам.

Passphrase и ssh-agent: удобство без потери безопасности

Расшифрованный ключ держит в памяти агент:

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

В GNOME и KDE агент уже запущен системой, достаточно одного ssh-add. macOS умеет хранить фразу в Keychain: ssh-add --apple-use-keychain ~/.ssh/id_ed25519, а чтобы не повторять это после перезагрузки, в ~/.ssh/config добавляют блок Host * с UseKeychain yes и AddKeysToAgent yes. В Windows роль агента играет служба ssh-agent, по умолчанию отключённая (PowerShell от администратора):

Set-Service -Name ssh-agent -StartupType Automatic
Start-Service ssh-agent
ssh-add $env:USERPROFILE\.ssh\id_ed25519

Посмотреть загруженные ключи — ssh-add -l. Ответ The agent has no identities означает, что ключ не добавлен, а Could not open a connection to your authentication agent — что агент вообще не запущен в этой сессии.

Генерация ключа в Windows: встроенный OpenSSH и PuTTYgen

Для Windows есть два маршрута с разными форматами файлов, смешивать их не стоит: встроенный OpenSSH — для PowerShell, WSL и скриптов, PuTTYgen — для графического PuTTY и WinSCP.

Генерация в PowerShell и исправление прав на приватный ключ через icacls

Синтаксис OpenSSH одинаков везде: ssh-keygen -t ed25519 -C "zoya@win-work". Ключи будут созданы в C:\Users\<имя>\.ssh\. Скопировать публичный в буфер: Get-Content $env:USERPROFILE\.ssh\id_ed25519.pub | Set-Clipboard.

Типичная для Windows проблема: файлы наследуют разрешения каталога, и на приватный ключ оказываются права у групп Пользователи, Прошедшие проверку или SYSTEM. Клиент отвечает Permissions for '...' are too open. This private key will be ignored. chmod в Windows нет, исправляем через icacls:

icacls $env:USERPROFILE\.ssh\id_ed25519 /inheritance:r
icacls $env:USERPROFILE\.ssh\id_ed25519 /grant:r "$($env:USERNAME):(R)"
icacls $env:USERPROFILE\.ssh\id_ed25519 /remove "Authenticated Users" "BUILTIN\Users" "SYSTEM"

Отдельный случай — Windows как сервер. На Windows Server с OpenSSH Server для пользователей из группы администраторов действует не C:\Users\<имя>\.ssh\authorized_keys, а общий C:\ProgramData\ssh\administrators_authorized_keys; ключ в домашнем каталоге просто проигнорируют. На файл нужны жёсткие права:

icacls C:\ProgramData\ssh\administrators_authorized_keys /inheritance:r /grant "Administrators:F" /grant "SYSTEM:F"

PuTTYgen: генерация, сохранение .ppk и конвертация в формат OpenSSH

PuTTYgen входит в стандартный установщик PuTTY. Порядок действий:

  1. В блоке Parameters выберите тип ключа EdDSA и оставьте Ed25519 (255 bits). Именно EdDSA, а не «SSH-2 RSA 2048»; если сервер устаревший — RSA с 4096 бит.
  2. Нажмите Generate и подвигайте мышью в пустой области окна — PuTTYgen собирает энтропию из движений курсора.
  3. Заполните Key comment и Key passphrase.
  4. Save private key — сохраните .ppk, например C:\Users\zoya\.ssh\work.ppk.

Ловушка, на которой спотыкается почти каждый: файл, сохранённый кнопкой Save public key, сервер не примет. Это формат RFC 4716 — многострочный, с заголовками ---- BEGIN SSH2 PUBLIC KEY ----, а в authorized_keys нужен однострочный формат OpenSSH. Брать нужно текст из верхнего поля окна — «Public key for pasting into OpenSSH authorized_keys file». Если окно уже закрыто, откройте .ppk кнопкой Load, введите passphrase — поле заполнится заново.

Конвертация нужна постоянно: ключ сделан в PuTTYgen, а подключаться надо из WSL или Ansible. Через интерфейс: .ppk → OpenSSH — Load → меню Conversions → Export OpenSSH key; OpenSSH → .ppk — Load → фильтр All Files → выбрать id_ed25519 → Save private key. Через командную строку с пакетом putty-tools:

puttygen work.ppk -O private-openssh -o ~/.ssh/id_ed25519
puttygen work.ppk -O public-openssh -o ~/.ssh/id_ed25519.pub
puttygen ~/.ssh/id_ed25519 -o work.ppk

После конвертации приватного ключа в Linux сразу выставьте chmod 600. Потеряли .pub, но приватный ключ цел? Публичную часть можно восстановить, обратное невозможно:

ssh-keygen -y -f ~/.ssh/id_ed25519 > ~/.ssh/id_ed25519.pub

Добавление публичного ключа на сервер

Публичный ключ должен оказаться в ~/.ssh/authorized_keys того пользователя, под которым вы входите. Одна строка — один ключ.

Автоматическая и ручная установка ключа в authorized_keys

Способ первый — ssh-copy-id, если парольный вход пока разрешён:

ssh-copy-id -i ~/.ssh/id_ed25519.pub user@server_ip

Утилита создаст ~/.ssh с правами 700, допишет ключ и выставит 600. Указывайте .pub явно: без -i утилита может отправить все ключи из агента. Нестандартный порт — флагом -p 2222.

Способ второй — вручную одной командой, когда ssh-copy-id недоступен (в Windows его нет):

cat ~/.ssh/id_ed25519.pub | ssh user@server_ip "mkdir -p ~/.ssh && chmod 700 ~/.ssh && cat >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys"

Из PowerShell то же самое с Get-Content вместо cat. Обратите внимание на >>, а не >: одиночная стрелка затрёт все ключи, которые уже лежали в файле.

Способ третий — через панель провайдера. При создании ВМ почти везде есть поле для публичного ключа: сервер поднимается уже с настроенным ключевым доступом.

Сверить, тот ли ключ лежит на сервере, можно по отпечатку:

ssh-keygen -lf ~/.ssh/id_ed25519.pub
ssh user@server_ip "ssh-keygen -lf ~/.ssh/authorized_keys"

Строки SHA256:... должны совпасть. Из PuTTY подключение настраивается так: Connection → SSH → Auth → Credentials, поле Private key file for authentication — путь к .ppk; в Connection → Data в Auto-login username — имя пользователя.

Ограничение прав ключа: from, command, no-port-forwarding

Строка в authorized_keys может начинаться с опций — и это превращает ключ из универсального доступа в узкий пропуск. Ключ для системы резервного копирования, которому разрешено только снимать дамп и только с конкретной подсети:

from="10.20.0.0/24",command="/usr/local/bin/backup-dump.sh",no-port-forwarding,no-agent-forwarding,no-pty ssh-ed25519 AAAAC3Nza... backup@nas
  • from="..." — принимать ключ только с этих адресов или подсетей;
  • command="..." — при входе выполняется строго эта команда, что бы клиент ни просил; запрошенная им попадёт в SSH_ORIGINAL_COMMAND;
  • no-port-forwarding, no-agent-forwarding, no-X11-forwarding — запрет туннелей, проброса агента и графики;
  • no-pty — не выдавать терминал.

Есть краткая форма restrict, которая включает все запреты разом, а нужное возвращается точечно: restrict,pty,from="192.0.2.5" ssh-ed25519 AAAA.... Для деплой-ключей в CI/CD это минимальная разумная мера. Раз в квартал полезно смотреть, чьи ключи лежат на серверах:

sudo awk '/^ssh-|^ecdsa-|^sk-/ {print FILENAME": "$NF}' /home/*/.ssh/authorized_keys /root/.ssh/authorized_keys 2>/dev/null

Когда машин больше пары десятков, россыпь ключей заменяют SSH-сертификатами: центр сертификации подписывает ключ пользователя на ограниченный срок, сервера доверяют подписи через TrustedUserCAKeys, а отзыв доступа сводится к тому, что сертификат не продлевают.

Настройка входа без пароля и отключение парольной аутентификации

Конфиг ~/.ssh/config: алиасы, IdentityFile, ProxyJump

Когда серверов больше одного, набирать ssh -i ~/.ssh/id_ed25519_deploy -p 2222 deploy@203.0.113.10 надоедает на третий раз. Создайте ~/.ssh/config:

Host prod-web
    HostName 203.0.113.10
    User deploy
    Port 2222
    IdentityFile ~/.ssh/id_ed25519_deploy
    IdentitiesOnly yes

Host db-internal
    HostName 10.0.5.20
    User admin
    IdentityFile ~/.ssh/id_ed25519
    IdentitiesOnly yes
    ProxyJump prod-web

Host *
    ServerAliveInterval 60
    AddKeysToAgent yes

Теперь подключение — просто ssh prod-web, а ssh db-internal автоматически пройдёт через бастион, не требуя копировать на него приватный ключ.

Ключевая опция здесь — IdentitiesOnly yes, и её пропускают почти всегда. Без неё клиент предлагает серверу все ключи из агента подряд; если их больше пяти-шести, сервер разрывает соединение с Too many authentication failures ещё до того, как дойдёт очередь до нужного. ServerAliveInterval 60 спасает от обрыва простаивающих сессий на промежуточном NAT. Права на конфиг — chmod 600.

Правка sshd_config без риска потерять доступ к серверу

Перед правкой убедитесь, что вход по ключу уже работает прямо сейчас, оставьте открытой вторую SSH-сессию и проверьте, что консоль в панели провайдера открывается.

Вместо редактирования основного файла лучше положить отдельный файл в каталог подключаемых конфигураций — так обновление пакета не затрёт изменения. Директива Include /etc/ssh/sshd_config.d/*.conf есть в актуальных выпусках Ubuntu, Debian, AlmaLinux и Rocky Linux; проверить её наличие можно командой grep -i include /etc/ssh/sshd_config:

sudo tee /etc/ssh/sshd_config.d/99-keys-only.conf > /dev/null <<'EOF'
PubkeyAuthentication yes
PasswordAuthentication no
KbdInteractiveAuthentication no
PermitRootLogin prohibit-password
EOF

KbdInteractiveAuthentication no закрывает интерактивный ввод пароля, через который на некоторых сборках пароль просачивается в обход PasswordAuthentication no. Если Include в системе нет, добавьте те же строки в /etc/ssh/sshd_config, сделав копию файла, и проверьте, что параметры не заданы повторно ниже: sshd применяет первое встреченное значение.

Проверяем синтаксис командой sudo sshd -t — отсутствие вывода означает, что ошибок нет. Полезнее посмотреть итоговую конфигурацию с учётом всех включённых файлов:

sudo sshd -T | grep -Ei "passwordauthentication|pubkeyauthentication|permitrootlogin|kbdinteractive"

Применяем через sudo systemctl reload sshd — reload перечитывает конфигурацию, не обрывая сессии. На Debian и Ubuntu служба может называться ssh. Если в системе включена сокет-активация sshd (проверяется через systemctl is-enabled ssh.socket), то при изменении порта одного reload не хватит — нужен sudo systemctl restart ssh.socket.

Из третьего окна, не закрывая страховочную сессию, проверяем, что ключевой вход работает, а парольный закрыт:

ssh prod-web
ssh -o PreferredAuthentications=password -o PubkeyAuthentication=no user@server_ip

Первая команда должна пустить без вопросов, вторая — ответить Permission denied (publickey).

Проверка и решение проблем

Основной инструмент диагностики — подробный режим клиента ssh -v user@server_ip. В выводе ищите строки Offering public key, Server accepts key и Authenticated to ... using "publickey".

Клиент вообще не предлагает ключ. Строки Offering public key нет — клиент не нашёл файл или не считает его подходящим. Проверьте путь в IdentityFile, права на приватный ключ (600) и то, что агент держит ключ (ssh-add -l). Укажите ключ явно: ssh -i ~/.ssh/id_ed25519 -o IdentitiesOnly=yes user@server_ip.

Ключ предложен, но сервер его отверг — после Offering public key сразу идёт Permission denied (publickey). Проблема на сервере: заходите через консоль провайдера и смотрите sudo journalctl -u ssh -n 50 --no-pager, на системах с rsyslog — /var/log/auth.log (Debian, Ubuntu) или /var/log/secure (AlmaLinux, Rocky Linux). Расшифровка частых записей:

  • Authentication refused: bad ownership or modes for directory /home/zoya — сработал StrictModes. Исправляется chmod 750 и chown на домашний каталог.
  • no such identity или пустой authorized_keys — ключ установлен не туда: частый случай, когда ключ ставили пользователю root, а подключаются как ubuntu.
  • key_read: uudecode failed — строка ключа повреждена переносом или лишним пробелом.
  • userauth_pubkey: key type ssh-rsa not in PubkeyAcceptedAlgorithms — тот самый случай с отключённой подписью SHA-1 у старых RSA-ключей.

Too many authentication failures. Клиент перебрал все ключи из агента и исчерпал лимит попыток сервера (MaxAuthTries, по умолчанию 6). Исправляется IdentitiesOnly yes в конфиге.

Windows: Permissions for '...' are too open. Разбирали в разделе про icacls. В WSL та же ошибка возникает, если ключ лежит на диске Windows (/mnt/c/Users/...): файловая система DrvFs не хранит права Unix. Скопируйте ключ внутрь WSL и выставьте chmod 600.

Изменился отпечаток сервера. Появляется WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!, подключение блокируется. Причин две: сервер переустановили — или кто-то встал посередине соединения. Сначала убедитесь, что верно первое, сверив отпечаток через консоль провайдера, и только потом удаляйте старую запись командой ssh-keygen -R server_ip.

Passphrase забыта. Восстановить нельзя, но если ключ добавлен в агент, его можно сменить в текущей сессии: ssh-keygen -p -f ~/.ssh/id_ed25519.

Приватный ключ утрачен или скомпрометирован. Сгенерируйте новую пару на чистой машине; зайдите на серверы через страховочный доступ; удалите строку старого ключа из authorized_keys на каждом сервере и добавьте новый; пройдите по внешним сервисам, куда загружали публичную часть; просмотрите журналы на предмет входов с посторонних адресов.

Класть приватный ключ в облачное хранилище, в репозиторий или на общий диск нельзя — это ровно тот путь, которым ключи и утекают. Если копия нужна, храните её в менеджере паролей или на зашифрованном носителе. Правильнее не создавать резервную копию ключа вообще, а иметь на серверах второй ключ доступа — с другой машины или с аппаратного токена.

Вверх!