Что такое SSH и как работает протокол
Узнайте принципы работы SSH для удаленного управления сервером. Разбираем клиент-серверную модель, использование порта 22, проверку ключей хоста и аутентификацию по ключу.
Что такое SSH?
SSH (secure shell) — это протокол для удаленного входа в систему и выполнения команд через зашифрованное соединение. Вводимые вами данные передаются на удаленную машину, а результат их выполнения возвращается обратно; при этом никто в сети не может перехватить или прочитать этот трафик. Арендованный Linux-сервер не имеет физического монитора или клавиатуры, поэтому SSH является основным способом взаимодействия с такой машиной.
Название SSH относится к двум понятиям. SSH — это сам протокол, описанный в RFC 4251 — RFC 4254. OpenSSH — это программная реализация протокола, которую использует практически каждый Linux-сервер и ноутбук. Когда говорят «подключиться по SSH к серверу», имеют в виду, что клиентская программа ssh на локальной машине устанавливает связь с серверной программой sshd на удаленной стороне.
Проблема, которую призван был решить SSH
Удаленный вход в систему появился задолго до SSH. Telnet открывал обычное TCP-соединение на порт 23 и передавал каждый байт в неизменном виде. Шифрование отсутствовало, что касалось и паролей. Любой, кто имел доступ к трафику, мог его прочитать: человек в той же офисной сети или оператор любого маршрутизатора на пути следования пакетов. Семейство протоколов rlogin имело те же уязвимости и доверяло клиентской машине по имени, что фактически означало доверие любому устройству, которое представлялось этим именем в сети.
Тату Илонен написал первый SSH в 1995 году в Хельсинкском технологическом университете после того, как в университетской сети была проведена атака с перехватом паролей. Разработка сохранила полезную часть telnet — поток байтов между терминалом и удаленной оболочкой — и добавила две вещи, которые telnet не обеспечивал: шифрование потока и подтверждение того, что сервер на другом конце является именно тем, к которому вы хотели подключиться.
Вторую часть легко упустить из виду, хотя она составляет половину сути SSH. Одно лишь шифрование вас не спасет. Промежуточный узел может принять ваше соединение, зашифровать его, прочитать всё, что вы отправляете, и перенаправить данные на реальный сервер. SSH предотвращает это, присваивая каждому серверу постоянный идентификатор, называемый host key, и проверяя его при каждом соединении.
Принцип работы модели клиент-сервер
Существует две программы. На сервере постоянно работает sshd, ожидая входящих соединений. На вашем компьютере их инициирует ssh. Это отдельные программы с собственными файлами конфигурации, и их путаница — самая частая причина, по которой правки не вступают в силу.
- Сервер считывает
/etc/ssh/sshd_config. Здесь отключается вход по паролю и задаётся порт для прослушивания. - Клиент считывает
/etc/ssh/ssh_configдля системных настроек по умолчанию, а затем~/.ssh/configдля ваших персональных настроек конкретных хостов.
В Debian и Ubuntu юнит службы называется ssh. В RHEL, Rocky и Fedora он называется sshd. В последних версиях Ubuntu служба устанавливается с активацией через сокет, поэтому systemctl status ssh может сообщать inactive (dead), даже если машина полностью доступна. Это происходит потому, что прослушивание порта выполняет ssh.socket, который запускает службу по требованию.
Клиентом не обязательно должен быть OpenSSH. PuTTY в Windows, Termius на телефоне и встроенные средства удалённого доступа в редакторах кода используют один и тот же протокол для связи с sshd. В Windows 10 и 11 также включён клиент OpenSSH, поэтому ssh you@server работает в PowerShell без необходимости установки дополнительного ПО.
Почему SSH использует порт 22?
Порт — это число, которое указывает ядру, какой ожидающей подключения программе принадлежит входящее соединение, и порты в Linux работают одинаково для любого сервиса. SSH использует порт 22, потому что IANA закрепила его за ним в 1995 году. Илонен запросил свободный номер рядом с протоколами, которые SSH должен был заменить: 21 был занят FTP, 23 — telnet, а 22 оставался свободным.
Поскольку 22 является портом по умолчанию, все системы ориентируются на него. Ваш удаленный репозиторий Git, скрипт резервного копирования и панель управления провайдера сначала пытаются подключиться именно к 22 порту. То же самое делает каждый автоматизированный сканер в интернете. Новый сервер с включенным входом по паролю начинает собирать записи, подобные этой, в /var/log/auth.log через несколько минут после загрузки:
Failed password for invalid user admin from 203.0.113.55 port 43122 ssh2Этот трафик постоянен, и он не направлен на вас лично. Перенос sshd на порт 2222 убирает большинство таких записей, так как сканеры прочесывают весь интернет по 22 порту, а не изучают ваш сервер. Это не делает машину более устойчивой к взлому для того, кто действительно решит её атаковать. Рассматривайте смену порта исключительно как способ снижения уровня шума.
Вы можете увидеть ответ сервера еще до входа в систему:
nc 203.0.113.10 22В Ubuntu 24.04 эта команда выведет что-то похожее на SSH-2.0-OpenSSH_9.6p1 Ubuntu-3ubuntu13. Баннер передается в открытом виде, до начала шифрования, так как обеим сторонам он необходим для согласования версии протокола. Нажмите Ctrl+C, чтобы закрыть соединение.
Что происходит в сети при подключении
Ниже приведена последовательность действий, которую выполняет ssh you@server до того, как вы увидите приглашение командной строки.
- Клиент преобразует имя хоста в IP-адрес, затем открывает TCP-соединение с портом 22.
- Обе стороны отправляют свои версии баннеров в открытом виде.
- Обе стороны обмениваются списками поддерживаемых алгоритмов: обмена ключами, шифрования, аутентификации сообщений и сжатия. Это всё ещё открытый текст. Выбирается наиболее сильный вариант, поддерживаемый обеими сторонами.
- Выполняется обмен ключами. Современный OpenSSH предпочитает
curve25519-sha256. Оба участника получают общий секретный ключ, при этом сам ключ не передаётся по сети. Таким образом, злоумышленник, записавший весь сеанс, не сможет вычислить этот ключ впоследствии. - Сервер подписывает результат обмена своим закрытым ключом хоста. Клиент проверяет подпись с помощью открытого ключа хоста, хранящегося в локальных файлах. Этот этап предотвращает подмену сервера промежуточным узлом.
- Включается шифрование.
chacha20-poly1305@openssh.comявляется алгоритмом шифрования по умолчанию в текущих версиях OpenSSH. - Только теперь клиент приступает к вашей аутентификации с помощью пароля или ключа. Имя пользователя и пароль передаются внутри зашифрованного канала.
- Клиент открывает канал и запрашивает оболочку (shell).
Этот порядок действий — главное отличие от telnet. Аутентификация происходит после того, как канал зашифрован и сервер подтвердил свою подлинность, поэтому пароль никогда не передаётся по сети в открытом виде.
Наблюдатель в сети всё же может получить некоторую информацию. Он видит ваш IP-адрес, IP-адрес сервера, порт 22, оба баннера версий в открытом виде, а также время передачи и примерный размер каждого пакета. Он не видит ваше имя пользователя, пароль, вводимые команды или их вывод. Поиск имени хоста на этапе 1 не является частью SSH и обычно не является конфиденциальным, поэтому DNS-запрос, преобразующий имя вашего сервера может выдать, к какому именно узлу вы подключаетесь, даже если сам сеанс остаётся защищённым.
Хост-ключ и запрос отпечатка при первом подключении
Когда openssh-server устанавливается, он генерирует пары хост-ключей для машины и записывает их в /etc/ssh/, например, в ssh_host_ed25519_key и ssh_host_ed25519_key.pub. Закрытая часть никогда не покидает сервер. Открытая часть — это идентификатор сервера, и именно с ней сверяется подпись на шаге 5.
При первом подключении к новому серверу клиенту не с чем сравнивать ключ, поэтому он задает вопрос:
The authenticity of host '203.0.113.10 (203.0.113.10)' can't be established.
ED25519 key fingerprint is SHA256:E9nVQ5Sm2oQ3nGm5Zf1tOaU7Xh0k2p8bWc4dLrTvYxA.
This key is not known by any other names.
Are you sure you want to continue connecting (yes/no/[fingerprint])?Отпечаток — это SHA256-хеш открытого ключа хоста, представленный в формате base64, поэтому он достаточно короток для визуальной проверки. Ввод yes записывает этот ключ в ~/.ssh/known_hosts на вашей локальной машине. При каждом последующем подключении к тому же адресу клиент сравнивает ключ, предложенный сервером, с сохраненным. Если они совпадают, ничего не выводится, и вы сразу переходите к командной строке.
Эта модель называется «доверие при первом использовании» (trust on first use), и важно понимать, в чем заключается её уязвимость. Первое подключение — это единственный момент, когда вы не защищены, так как принимаете ключ, который видите впервые. Чтобы устранить этот риск, получите отпечаток другим способом и сравните его. Большинство провайдеров выводят его в логах загрузки в веб-консоли, также его можно вывести на самом сервере:
ssh-keygen -lf /etc/ssh/ssh_host_ed25519_key.pubЭта команда выведет ту же строку SHA256:, что была показана в запросе. Вариант [fingerprint] в запросе существует именно для этого: вставьте ожидаемый отпечаток, и клиент продолжит работу только в том случае, если он совпадает с тем, что предоставил сервер.
В Debian и Ubuntu known_hosts по умолчанию хешируется, поэтому файл содержит строки, начинающиеся с |1|, а не читаемые имена хостов. Выполните ssh-keygen -F 203.0.113.10, чтобы найти запись для конкретного хоста.
Почему SSH сообщает об изменении ключа хоста?
Рано или поздно вы столкнетесь с этим блоком текста:
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!Он заканчивается на Host key verification failed., и клиент отказывается устанавливать соединение. Также выводится Password authentication is disabled to avoid man-in-the-middle attacks., поскольку ввод пароля на неизвестной машине — это именно та угроза, для предотвращения которой и существует данная проверка.
Сообщение выглядит как экстренное предупреждение, но в большинстве случаев это не так. Обычные причины:
- Вы пересобрали или переустановили сервер, поэтому
sshdсгенерировал новые ключи хоста при первой загрузке. Это самая распространенная причина. - Вы удалили один VPS и создали другой, а провайдер назначил новой машине старый IP-адрес.
- Вы подключаетесь через форвард или балансировщик нагрузки, который теперь направляет трафик на другой backend-сервер.
- Кто-то действительно перехватывает соединение.
Прежде чем что-либо удалять, определите причину. Если вы переустановили машину десять минут назад, причина очевидна. Если с вашей стороны ничего не менялось, остановитесь и проведите расследование, так как это предупреждение означает, что проверка работает как положено. Как только вы убедитесь в безопасности, удалите устаревшую запись и подключитесь снова:
ssh-keygen -R 203.0.113.10При следующем подключении снова появится запрос отпечатка ключа, что даст вам возможность сравнить его с данными из консоли провайдера.
Аутентификация по паролю против аутентификации по ключу
Аутентификация по паролю передает ваш пароль внутри уже зашифрованного канала, а sshd проверяет его по базе данных учетных записей, обычно через PAM (pluggable authentication modules). Она не требует предварительной подготовки, поэтому провайдер может предоставить вам новый сервер, имеющий только пароль root.
Слабость заключается не в шифровании. Проблема в том, что пароль — это короткий секрет, который вы отправляете на сервер при каждом входе, а порт 22 круглосуточно перебирают боты, которые никогда не устают.
Аутентификация по открытому ключу работает иначе. Вы создаете пару ключей на своем компьютере. Открытая часть помещается в ~/.ssh/authorized_keys внутри вашей учетной записи на сервере. Закрытая часть остается на вашем ноутбуке и никогда не передается. Для входа клиент подписывает фрагмент данных, включающий идентификатор сессии из обмена ключами, а сервер проверяет эту подпись с помощью открытого ключа, который у него уже есть. Поскольку подписанные данные привязаны только к этой конкретной сессии, перехваченная подпись бесполезна для любых других целей.
Следите за направлением передачи, так как его часто путают, что приводит к проблемам: открытый ключ отправляется на сервер, закрытый ключ остается у вас. Если закрытый ключ был скопирован на сервер, доверять ему больше нельзя.
У входа по ключу есть свои сценарии сбоев. sshd игнорирует ключи, если права доступа к файлам слишком слабые, о чем сообщает в логе сервера:
Authentication refused: bad ownership or modes for directory /home/ubuntu/.sshКлиент всегда сообщает вам только Permission denied (publickey) — это одно и то же сообщение для десятка разных причин, поэтому правильное чтение ошибки publickey стоит изучить до того, как вы потеряете доступ. Практическая работа по созданию ключей, их защите парольной фразой и загрузке в агент описана в управлении SSH-ключами, а отключение входа по паролю без риска остаться за бортом — в укреплении безопасности SSH на VPS.
SFTP, scp и проброс портов используют одно и то же соединение
Эта концепция позволяет понять, как устроена остальная часть мира SSH. Аутентификация открывает зашифрованное соединение, которое может одновременно передавать несколько независимых каналов. Оболочка (shell) — это лишь один из видов таких каналов.
- Удалённая оболочка.
ssh you@serverоткрывает сессионный канал и запрашивает интерактивную оболочку. - Одиночная команда.
ssh you@server uptimeоткрывает канал, выполняет одну команду, выводит результат и завершает работу. - SFTP. Клиент запрашивает у
sshdзапуск подсистемыsftp, и передача файлов происходит внутри того же соединения. SFTP — это протокол передачи файлов, работающий поверх SSH, и он не имеет ничего общего с FTP. Протокол, представляющий собой FTP с добавленным шифрованием, называется FTPS, и он никак с этим не связан. - scp. Копирует файлы, используя те же учётные данные. Начиная с OpenSSH 9.0, выпущенного в 2022 году,
scpпо умолчанию использует протокол SFTP. - Проброс портов.
ssh -L 8080:localhost:80 you@serverпревращает порт 8080 на вашем ноутбуке в «дверь» к порту 80 на сервере, при этом трафик передаётся внутри зашифрованного соединения.-Rвыполняет проброс в обратном направлении, а-D 1080превращает сессию в SOCKS-прокси. - Git. Удалённый репозиторий, такой как
git@github.com:user/repo.git, представляет собой SSH-логин, на удалённой стороне которого вместо оболочки запускается обработчик команд. - rsync и Ansible также являются SSH-клиентами. Они открывают канал, выполняют задачу и считывают вывод обратно.
Каждый пункт из этого списка использует один и тот же порт, одну и ту же проверку ключа хоста и одни и те же учётные данные. Именно поэтому настройка аутентификации по ключам окупается мгновенно: каждый из этих инструментов наследует её. По этой же причине файл ~/.ssh/config, который сокращает время входа в систему, становится тем самым файлом, который упрощает масштабирование при управлении несколькими серверами Linux с одного ноутбука.
Чего не делает SSH
- Он не обеспечивает безопасность вашего сервера. SSH защищает путь к двери. Сама дверь никуда не делась, и злоумышленники будут продолжать дергать за ручку. Блокировка повторяющихся попыток входа с помощью fail2ban помогает справиться с объемом таких запросов, а аутентификация только по ключам устраняет сам объект их перебора.
- Он не защищает вас от вашей собственной машины. Любой, у кого есть доступ к вашему ноутбуку, получает доступ к вашему закрытому ключу и загруженному агенту.
- Он не скрывает факт использования SSH. Номер порта и баннер с версией в открытом виде выдают его.
- Он не охватывает события, происходящие до установления соединения. Поиск имени хоста и ваше решение о том, какому адресу доверять, происходят раньше.
Дальнейшие шаги
Если у вас сейчас открыта консоль управления новым сервером, придерживайтесь проверенного порядка действий. Войдите в систему, создайте обычного пользователя, установите свой ключ, а затем закройте уязвимые пути доступа. Статья Первые десять минут на новом VPS описывает этот процесс от начала до конца, а что такое VPS на самом деле поможет разобраться в устройстве машины, если эти термины для вас новы. После этого изучите материалы по работе с ключами и укреплению безопасности — именно в такой последовательности.
FAQ
Что означает аббревиатура SSH?
SSH расшифровывается как secure shell. Это протокол для входа на удаленный компьютер и выполнения команд через зашифрованное соединение, описанный в RFC 4251 — RFC 4254. OpenSSH — это реализация, которую используют практически все: клиент ssh на вашем компьютере и сервер sshd на удаленном. Он заменил telnet, который передавал все данные, включая пароли, по сети в открытом виде.
Почему SSH использует порт 22?
IANA назначила порт 22 для SSH в 1995 году, рядом с FTP на 21 и telnet на 23 — протоколами, которые он должен был заменить. Ничто не обязывает использовать именно этот номер: Port в /etc/ssh/sshd_config меняет его на сервере, а ssh -p позволяет выбрать другой на стороне клиента. Поскольку 22 является портом по умолчанию, автоматизированные сканеры постоянно обращаются к нему, поэтому /var/log/auth.log на новом сервере быстро заполняется строками Failed password for invalid user. Смена порта снижает этот фоновый шум, но не обеспечивает реальной защиты.
Что делать, если SSH предупреждает об изменении ключа хоста?
Прежде чем что-либо удалять, найдите причину. Обычно она безобидна: сервер был переустановлен, поэтому sshd сгенерировал новые ключи хоста, либо старый IP-адрес был назначен новой машине. Если вы знаете, что машина была переустановлена, выполните ssh-keygen -R <host>, чтобы удалить сохраненный ключ, переподключитесь и сравните показанный вам отпечаток с тем, который отображается в консоли вашего провайдера. Если с вашей стороны изменений не было, не подключайтесь и не вводите пароль. OpenSSH уже блокирует аутентификацию по паролю в этом состоянии именно по этой причине.
Отличаются ли SFTP и scp от SSH?
Они работают поверх SSH. После аутентификации SSH-соединение может поддерживать несколько каналов, и командная оболочка — лишь один из них. SFTP — это протокол передачи файлов, который использует подсистему sftp в sshd через то же самое соединение, а scp использует протокол SFTP в качестве основы начиная с OpenSSH 9.0. Проброс портов и Git через SSH также являются каналами внутри одного соединения. Все они используют один и тот же порт, одну и ту же проверку ключа хоста и одну и ту же процедуру входа. Заметьте, что SFTP — это не FTP с добавленным шифрованием; последний называется FTPS и является отдельным протоколом.
Действительно ли аутентификация по ключу лучше, чем по паролю?
Да, для любого сервера, доступного из Интернета. Пароль — это короткий секрет, который вы передаете серверу при каждом входе, а порт 22 постоянно перебирается автоматизированными клиентами. При использовании пары ключей закрытая часть никогда не покидает ваш компьютер: клиент подписывает данные, привязанные к текущей сессии, а сервер проверяет эту подпись с помощью открытого ключа в ~/.ssh/authorized_keys. Записанную подпись невозможно использовать повторно для входа на другой сервер. Защищайте закрытый ключ парольной фразой, так как файл ключа без нее является готовым инструментом для входа для любого, кто его скопирует.