Погодин Евгений — ИТ Заметки
🐧Linux Обновлено 28.10.2026

Linux для админа Windows 08. SSH: ключи, безопасная настройка и передача файлов

Note

Материал сверен с официальной документацией (Ubuntu Server, man-страницы и документация проектов; ссылки — в конце статьи). Примеры вывода — иллюстрации: на вашем сервере значения и формат могут отличаться. Перед работой на боевом сервере проверьте команды на тестовой машине.

Для управления Windows-сервером вы открываете RDP. Для Linux-сервера в роли RDP выступает SSH (Secure Shell, «безопасная оболочка»): шифрованный канал, в котором вы получаете консоль сервера, копируете файлы и пробрасываете порты. SSH, открытый в сеть с паролем, становится первой целью перебора. В этой статье вы:

  • подключитесь к lnx1 из Windows встроенным клиентом (первое подключение с проверкой отпечатка описано в статье 02);
  • создадите пару ключей Ed25519, настроите вход без пароля и ssh-agent;
  • закроете парольный вход в безопасном порядке, не потеряв доступ;
  • скопируете файлы через scp, sftp и rsync и откроете внутреннюю веб-панель через туннель -L.
Задача Windows SSH
Удалённая консоль RDP, mstsc, PowerShell Remoting ssh admin-lab@192.168.10.20
Копирование файлов сетевая папка, Copy-Item scp, sftp, rsync
Закрытая часть сертификата закрытый ключ в хранилище файл id_ed25519
Служба на сервере служба RDP служба ssh
Правило брандмауэра порт 3389 порт 22, профиль OpenSSH в ufw

Что нужно знать заранее

Второй сервер для примеров копирования называется lnx2 (192.168.10.21), Windows-клиент — PC1 (192.168.10.101). Адреса учебные: подставляйте адреса своей сети, как сказано в статье про сеть. Имя учётной записи в Windows может быть любым (в примерах admin), а на сервере мы входим как admin-lab, поэтому в командах указываем admin-lab@адрес.

Warning

Ошибка в настройке SSH может закрыть вам единственный путь на сервер. Работайте на тестовой виртуальной машине (ВМ), держите открытой её консоль в гипервизоре и не закрывайте рабочий сеанс, пока не проверите вход во втором.

Как работает SSH

Сервер sshd (демон, то есть фоновая служба) слушает TCP-порт 22. Клиент и сервер договариваются о шифровании, затем проходят две проверки в разные стороны:

  1. Клиент проверяет сервер. У сервера есть собственные ключи хоста (файлы /etc/ssh/ssh_host_*_key). При первом подключении клиент показывает отпечаток открытого ключа сервера и запоминает его в файле known_hosts.
  2. Сервер проверяет пользователя. Вы доказываете, кто вы, паролем либо ключом.

Не путайте ключи хоста (они принадлежат серверу) и ключи пользователя (они принадлежат вам).

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

Клиент в Windows

В Windows 10 и 11 клиент OpenSSH входит в систему как необязательный компонент. В его составе есть ssh, scp, sftp, ssh-keygen, ssh-agent, ssh-add. Проверьте, что он на месте (команды PowerShell выполняются на PC1):

ssh -V

Если команды нет, установите компонент из PowerShell, запущенного от администратора:

Get-WindowsCapability -Online | Where-Object Name -like 'OpenSSH*'
Add-WindowsCapability -Online -Name OpenSSH.Client~~~~0.0.1.0

Можно использовать и PuTTY: это отдельный клиент со своим набором программ (в частности PuTTYgen для ключей), в статье он не разбирается. Встроенный клиент — тот же OpenSSH, поэтому команды, опции и форматы ключей совпадают с Linux.

Первое подключение и смена ключа сервера

Подключение выполняется командой ssh admin-lab@192.168.10.20. При первом входе клиент показывает отпечаток ключа сервера; как сверить его с настоящим, описано в статье 02: не отвечайте yes не глядя. После ответа ключ сервера записывается в C:\Users\admin\.ssh\known_hosts, и дальше клиент проверяет сервер сам.

Если клиент заявит REMOTE HOST IDENTIFICATION HAS CHANGED, сервер предъявил другой ключ: либо вы переустановили lnx1, либо на этом адресе отвечает чужая машина. Разберитесь, прежде чем удалять старую запись командой ssh-keygen -R 192.168.10.20. Параметр StrictHostKeyChecking по умолчанию равен ask; значение accept-new принимает только новые серверы и не пускает при смене ключа, а no отключает защиту, и использовать его не стоит.

Ключи: создаём, кладём на сервер, входим

Создаём пару

На PC1 в PowerShell:

ssh-keygen -t ed25519 -C "admin@PC1"

Ed25519 — современный тип ключа, его рекомендует и документация Ubuntu (короткие ключи, малая нагрузка). В OpenSSH 9.5 и новее это тип по умолчанию, но в более старых клиентах умолчанием был RSA, поэтому -t ed25519 лучше указывать явно. Для очень старых серверов есть запасной вариант -t rsa -b 4096.

Пример вывода:

Generating public/private ed25519 key pair.
Enter file in which to save the key (C:\Users\admin/.ssh/id_ed25519):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in C:\Users\admin/.ssh/id_ed25519.
Your public key has been saved in C:\Users\admin/.ssh/id_ed25519.pub.
The key fingerprint is:
SHA256:<ОТПЕЧАТОК_КЛЮЧА> admin@PC1

Путь оставьте по умолчанию (Enter). Парольную фразу (passphrase) задайте: она шифрует закрытый ключ, и украденный файл без неё бесполезен. Забытую фразу восстановить нельзя, придётся создать новую пару.

Получились два файла в C:\Users\admin\.ssh\: id_ed25519 (закрытый, он эквивалентен вашему паролю) и id_ed25519.pub (открытый). Закрытый ключ не отправляйте по почте и мессенджерам и не копируйте на серверы.

Кладём открытый ключ на сервер

На Linux для этого есть ssh-copy-id, но в составе OpenSSH для Windows этого скрипта нет. Скопируйте файл через scp (пароль запросят последний раз):

Set-Location $env:USERPROFILE\.ssh
scp .\id_ed25519.pub admin-lab@192.168.10.20:win-key.pub

Затем зайдите на сервер по паролю и выполните на нём (так в authorized_keys добавится ключ и выставятся права):

mkdir -p ~/.ssh
chmod 700 ~/.ssh
cat ~/win-key.pub >> ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keys
rm ~/win-key.pub

Если вы подключаетесь с другого Linux-компьютера, весь этот блок заменяет одна команда ssh-copy-id admin-lab@192.168.10.20.

Файл authorized_keys — это по одному ключу на строку: тип, сам ключ, комментарий:

ssh-ed25519 <ОТКРЫТЫЙ_КЛЮЧ> admin@PC1

Права важны. Каталог ~/.ssh должен быть доступен только вам (700), файл authorized_keys — 600. Если эти файлы, ~/.ssh или домашний каталог доступны на запись другим, сервер откажется использовать ключ, потому что по умолчанию включён StrictModes.

Входим по ключу

С PC1 выполните ssh admin-lab@192.168.10.20. Теперь запрос идёт к вашему закрытому ключу: вводите парольную фразу ключа, а не пароль пользователя admin-lab на сервере. Ключ id_ed25519 из .ssh клиент пробует автоматически, другой файл указывают опцией -i. Если по-прежнему запрашивают пароль сервера, ключ не принят: запустите ssh -v admin-lab@192.168.10.20 и смотрите журнал сервера (sudo journalctl -fu ssh.service).

ssh-agent: фраза один раз

Чтобы не вводить фразу при каждом подключении, закрытый ключ хранит ssh-agent. В Windows это служба, по умолчанию она отключена. Включают её один раз в PowerShell от администратора:

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

Ключ добавляют в обычном окне PowerShell под своей учётной записью (если повышенное окно открыто под другой, $env:USERPROFILE укажет на чужой профиль):

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

ssh-add -l показывает отпечатки загруженных ключей. Пробрасывать агента на серверы (ssh -A) без необходимости не стоит: промежуточный сервер получит доступ к вашему агенту. Для «прыжка» через промежуточный сервер надёжнее опция -J, она описана ниже.

Права на закрытый ключ в Windows

OpenSSH проверяет права на закрытый ключ и на файл config. Требование проекта Win32-OpenSSH: ключ принадлежит вам, у других пользователей доступа к нему нет. Ключ, созданный ssh-keygen на этой машине, получает правильные права сам. Если вы скопировали ключ с другого компьютера, клиент может ответить WARNING: UNPROTECTED PRIVATE KEY FILE!.

Приёмы icacls (/inheritance:r убирает унаследованные права, /remove убирает лишнюю учётную запись, /grant выдаёт права) показаны в документации Microsoft на примере других файлов. Для ключа применим тот же приём:

$key = "$env:USERPROFILE\.ssh\id_ed25519"
icacls.exe $key /inheritance:r
icacls.exe $key /grant:r "${env:USERDOMAIN}\${env:USERNAME}:(R)"
icacls.exe $key

Последняя команда показывает итог: в списке должны остаться вы (допустимы также SYSTEM и Administrators). Если владелец файла не вы (ключ скопирован из-под администратора), проверьте его командой Get-Acl $key | Select-Object Owner; смена владельца потребует прав администратора.

Файл ~/.ssh/config

Чтобы не вводить адрес и имя пользователя, заведите файл C:\Users\admin\.ssh\config (на Linux — ~/.ssh/config):

Host lnx1
    HostName 192.168.10.20
    User admin-lab
    IdentityFile ~/.ssh/id_ed25519
    IdentitiesOnly yes

Host lnx2
    HostName 192.168.10.21
    User admin-lab
    ProxyJump lnx1

Теперь достаточно ssh lnx1, а ssh lnx2 пройдёт через lnx1 (ProxyJump равносилен опции -J). Открытый ключ с PC1 должен лежать и в ~/.ssh/authorized_keys на lnx2: lnx1 лишь передаёт соединение дальше. Для каждого параметра берётся первое найденное значение, поэтому частные блоки Host пишут выше общих, а общие настройки — в блок Host * в конце файла. Файл не должен быть доступен на запись другим пользователям.

Настройка сервера: sshd_config

Где лежат настройки и кто побеждает

Настройки демона лежат в /etc/ssh/sshd_config и в каталоге /etc/ssh/sshd_config.d/. В Ubuntu первой строкой основного файла стоит Include /etc/ssh/sshd_config.d/*.conf, то есть дополнительные файлы подключаются в начале. Для большинства директив действует первое найденное значение, поэтому значение из sshd_config.d/ перекрывает значение из основного файла. Файлы подключаются в лексическом порядке: из двух конфликтующих файлов побеждает тот, чьё имя идёт раньше. Поэтому свой файл называйте так, чтобы он шёл первым, например 10-keys-only.conf.

Какие значения реально действуют, покажет sudo sshd -T: он выводит итоговую конфигурацию с учётом всех файлов. Загляните и в сам каталог (ls /etc/ssh/sshd_config.d/): там могут лежать чужие файлы, и если имя одного из них идёт раньше вашего, победит он.

Значения по умолчанию (man sshd_config и пакет Ubuntu):

Директива По умолчанию в sshd В Ubuntu
PasswordAuthentication yes не меняется: пароль разрешён
PubkeyAuthentication yes не меняется
PermitRootLogin prohibit-password не меняется
KbdInteractiveAuthentication yes пакет ставит no
UsePAM no пакет ставит yes
Port 22 не меняется

Обратите внимание на PermitRootLogin: значение prohibit-password запрещает root только пароль, а вход по ключу остаётся возможным. Мы закроем и его, работать будем под admin-lab с sudo.

Строка UsePAM yes важна: PAM (Pluggable Authentication Modules, подключаемые модули аутентификации) при ней обслуживает и клавиатурно-интерактивный вход (KbdInteractiveAuthentication), который, как отмечает man, обычно играет ту же роль, что и пароль. Чтобы пароль не «просочился» через второй путь, мы отключим оба параметра. В Ubuntu 26.04 LTS (OpenSSH 10.x) эти директивы и порядок обработки файлов те же, что в 24.04 LTS.

Отключаем вход по паролю: безопасный порядок

Если закрыть пароль до проверки ключа, вы закроете себе единственный вход. Порядок такой:

  1. Откройте консоль ВМ в гипервизоре: это запасной вход без сети.
  2. Оставьте текущий сеанс открытым. Назовём его сеансом A.
  3. Настройте ключ, как описано выше. Во втором окне (сеанс B) проверьте, что вход идёт по ключу, а пароль сервера не запрашивается (lnx1 — псевдоним из config; без него укажите admin-lab@192.168.10.20):
ssh -o PreferredAuthentications=publickey lnx1
  1. В сеансе A создайте файл настроек:
sudo nano /etc/ssh/sshd_config.d/10-keys-only.conf
PasswordAuthentication no
KbdInteractiveAuthentication no
PermitRootLogin no
  1. Проверьте синтаксис и итоговые значения, пока ничего не применено:
sudo sshd -t
sudo sshd -T | grep -iE 'passwordauth|kbdinter|rootlogin'

Если sshd -t молчит, синтаксис верен. Команда sshd -T выводит итог в нижнем регистре. Пример вывода (порядок строк может отличаться):

permitrootlogin no
passwordauthentication no
kbdinteractiveauthentication no

Warning

Не закрывайте сеанс A, пока не проверите новый вход во втором окне (сеанс C вы откроете в шаге 7): если что-то пошло не так, сеанс A позволит вернуть настройки.

  1. Примените настройки командой sudo systemctl reload ssh. Юнит сам выполняет перед этим sshd -t, и при ошибке в файле работающий демон остаётся на старой конфигурации. Команда restart тоже подходит, но при ошибке в файле демон не поднимется. Служба в Ubuntu называется ssh (юнит ssh.service): привычное по другим дистрибутивам имя sshd в Ubuntu 24.04 по умолчанию не работает (Unit sshd.service could not be found).
  2. Не закрывая сеанс A, откройте сеанс C и убедитесь, что вход по ключу работает. Затем проверьте, что пароль больше не принимается:
ssh -o PubkeyAuthentication=no lnx1

Ожидается отказ в доступе без запроса пароля (обычно Permission denied (publickey); точный текст зависит от версии клиента).

  1. Только теперь сеанс A можно закрыть. Для отката удалите файл 10-keys-only.conf и снова выполните sudo systemctl reload ssh; если открытых сеансов нет, это делают через консоль ВМ.

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

Кого пускать: AllowUsers и AllowGroups

По умолчанию пускают всех пользователей. Директива AllowUsers оставляет доступ только перечисленным, а AllowGroups разрешает вход членам указанных групп. Образец для файла 10-keys-only.conf:

AllowUsers admin-lab

Ошибка в имени заблокирует всех, поэтому проверяйте вход по схеме выше. В AllowUsers можно указать и источник: admin-lab@192.168.10.0/24 пустит пользователя только из офисной сети. Прочие ограничения по сети надёжнее добавлять в ufw, как в статье про сеть: sudo ufw limit OpenSSH или правило с адресом источника.

Смена порта — не защита

Перенос SSH на нестандартный порт сокращает шум в журналах, но не защищает: сканер находит любой открытый порт. Менять его нужно осознанно. В Ubuntu демон запускается по требованию через сокет ssh.socket, поэтому одной правки Port недостаточно: README пакета описывает правку sshd_config или файла в sshd_config.d, а затем systemctl daemon-reload и systemctl restart ssh.socket. Заранее откройте новый порт в ufw и держите открытый второй сеанс.

fail2ban и второй фактор

fail2ban читает журналы и временно блокирует адреса с повторными неудачными входами. Это помощник, а не замена ключей. Установка: sudo apt install fail2ban. Файлы *.conf пакета не правят, свои значения кладут в /etc/fail2ban/jail.local. Jail (набор правил для одной службы) sshd пакет в Ubuntu включает сам; проверить: sudo fail2ban-client status. Пример своих значений:

[sshd]
enabled = true
maxretry = 5
findtime = 10m
bantime = 1h
ignoreip = 127.0.0.1/8 192.168.10.0/24

После sudo systemctl restart fail2ban смотрите состояние командой sudo fail2ban-client status sshd. Обязательно внесите свою подсеть в ignoreip, иначе забаните сами себя после нескольких опечаток.

В OpenSSH из Ubuntu 26.04 есть и встроенная защита PerSourcePenalties, она включена по умолчанию: адрес, с которого были неудачные попытки входа, на время получает отказ в соединении. В 24.04 (OpenSSH 9.6) её нет. Это дополняет ключи и fail2ban, но не заменяет их.

Поверх ключей можно включить второй фактор: TOTP/HOTP (одноразовые коды) или U2F/FIDO (аппаратные устройства). Руководства есть в документации Ubuntu Server.

Передача файлов: scp, sftp, rsync

scp

scp копирует по SSH с теми же ключами. Начиная с OpenSSH 9.0 он передаёт данные протоколом SFTP; старый протокол включается опцией -O. Примеры из PowerShell на PC1:

scp .\report.pdf lnx1:
scp lnx1:/home/admin-lab/report.pdf .
scp -r .\site lnx1:/home/admin-lab/

Путь после двоеточия, если он относительный, считается от домашнего каталога; пустой путь (lnx1:) — это и есть домашний каталог. Порт указывают опцией -P (заглавная буква: строчная -p сохраняет время и права), -r копирует каталоги. Локальные пути лучше писать с .\: имя с двоеточием scp может принять за имя узла.

sftp

sftp — интерактивный режим, как FTP, но по SSH. Запустите sftp lnx1; внутри доступны ls, cd (удалённый каталог), lls и lcd (локальный), get (скачать), put (загрузить), mkdir, bye (выход).

rsync

rsync копирует только изменившееся и подходит для регулярной синхронизации между серверами (аналог robocopy). Ему нужна установка на обеих сторонах; в наборе OpenSSH для Windows его нет, поэтому типичный сценарий — копирование между Linux-серверами. Сначала пробный запуск с опцией -n (--dry-run), затем настоящий:

rsync -avzn --mkpath ~/site/ admin-lab@192.168.10.21:backup/site/
rsync -avz --mkpath ~/site/ admin-lab@192.168.10.21:backup/site/

Опции: -a (архивный режим: рекурсивно, с правами, временем и владельцами), -v (подробный вывод), -z (сжатие), --mkpath (создать недостающие каталоги пути назначения: без неё rsync создаёт только последний каталог, и каталог backup на lnx2 должен уже существовать). Обратите внимание на слэш в конце источника: site/ копирует содержимое каталога, site без слэша создаст внутри назначения каталог site. Опция --delete удаляет в приёмнике файлы, которых нет в источнике: опасная, всегда сначала прогоняйте её с -n.

Команда выполняется на lnx1, поэтому lnx1 должен сам входить на lnx2. Создайте на lnx1 отдельную пару ключей (ssh-keygen -t ed25519) и добавьте её открытую часть в ~/.ssh/authorized_keys пользователя на lnx2. Свой личный ключ с PC1 на сервер не копируйте и пересылку агента (-A) ради этого не включайте.

Туннель -L и прыжки через сервер

Допустим, на lnx2 есть веб-панель на порту 80, закрытая от офиса, а lnx1 до неё доступен. Откройте туннель на PC1:

ssh -N -L 8080:192.168.10.21:80 lnx1

Порт 8080 на вашем PC1 теперь ведёт к 192.168.10.21:80, как его видит lnx1. Откройте в браузере http://localhost:8080. Опция -N означает «не запускать команду»: окно с командой оставьте открытым, а чтобы закрыть туннель, нажмите Ctrl+C. По умолчанию порт слушает только локальный адрес PC1, из сети он недоступен. Туннель удобен, чтобы не открывать панель в ufw всем подряд. Если на сервере запрещены пробросы (AllowTcpForwarding no, по умолчанию они разрешены), соединения через туннель будут отклоняться.

Подключение к lnx2 через lnx1 одной командой: ssh -J admin-lab@192.168.10.20 admin-lab@192.168.10.21. Это то же, что ProxyJump в файле config.

Типичные ошибки и недоразумения

  • Отключили пароль до проверки ключа. Вход закрыт, выручает только консоль ВМ: удалите файл из sshd_config.d и примените настройки. Следуйте порядку из раздела выше.
  • Настройка «не действует». Значение из sshd_config.d/ перекрывает основной файл, а среди файлов побеждает первый по имени. Смотрите итог через sudo sshd -T.
  • Permission denied (publickey). Проверьте пользователя в команде, права на ~/.ssh (700), authorized_keys (600) и домашний каталог, а также цельность строки ключа в файле. Подробности — в ssh -v и в sudo journalctl -fu ssh.service.
  • WARNING: UNPROTECTED PRIVATE KEY FILE!. Закрытый ключ доступен другим. В Linux ssh просто игнорирует такой файл, в Windows поправьте права через icacls.
  • Connection refused или timed out. Первое обычно означает, что демон не слушает порт (sudo ss -tulpn), второе — что пакеты отбрасывает фильтр (ufw или сеть).
  • Unit sshd.service could not be found. На Ubuntu 24.04 служба называется ssh: sudo systemctl reload ssh.
  • Ключ без парольной фразы или копия личного закрытого ключа на сервере. Кто получит файл, тот получит ваши права. Для личного ключа фраза нужна всегда. Для автоматических задач (резервное копирование) заводят отдельный ключ на сервере-источнике и ограничивают его в authorized_keys на приёмнике (опции restrict, command=).

Проверьте себя

  1. Какой из двух файлов ключа нужно положить на сервер, а какой нельзя передавать никому? На сервер кладут открытый (id_ed25519.pub) в ~/.ssh/authorized_keys; закрытый (id_ed25519) остаётся только у вас.
  2. Почему нельзя ставить PasswordAuthentication no до проверки входа по ключу, и что нужно держать открытым? Если ключ не работает, парольного входа уже не будет и сервер станет недоступен по SSH; нужны открытый рабочий сеанс (или консоль ВМ) и проверка входа по ключу во втором сеансе.
  3. В sshd_config указано PasswordAuthentication yes, а в sshd_config.d/10-keys-only.conf — no. Какое значение действует? no: файлы из sshd_config.d подключаются в начале основного файла, а для большинства директив действует первое найденное значение.
  4. Что делает команда sshd -t и чем она отличается от sshd -T? -t проверяет синтаксис конфигурации и ключи, -T выводит итоговую (эффективную) конфигурацию, включая проверку из -t.
  5. Для чего опция -n в rsync и что делает --delete? -n (--dry-run) — пробный запуск без изменений; --delete удаляет в приёмнике файлы, которых нет в источнике.

Что дальше

Источники

Ещё по теме «Linux»