История протокола SSH: от telnet до OpenSSH
Узнайте историю создания SSH после перехвата паролей в 1995 году. В статье приведена хронология развития протокола от небезопасных telnet и rlogin до современных стандартов OpenSSH.
История SSH
История SSH началась с кражи паролей. До 1995 года удаленный вход на Unix-машину осуществлялся через telnet или rlogin, и оба этих протокола передавали пароль по сети в открытом виде. Любой, кто мог перехватить трафик, мог прочитать его, и к началу 1990-х годов это стало массовым явлением.
SSH стал ответом одного разработчика на эту проблему; программа была написана в 1995 году и распространялась бесплатно. С тех пор протокол был полностью переработан один раз, а программа, которую сегодня использует почти каждый, является форком форка. Указанные ниже даты важны, так как каждый этап развития был ответом на конкретный сбой или уязвимость.
Что на самом деле передавали telnet и rlogin
Протокол Telnet описан в RFC 854, опубликованном в мае 1983 года Джоном Постелом и Джойс Рейнольдс. Он описывает терминальную сессию, передаваемую поверх TCP, и не содержит никакого шифрования. Каждый вводимый вами байт, включая пароль, передается в открытом виде, и любое устройство на пути следования трафика может его прочитать.
Протокол rlogin появился в составе Berkeley Unix и был описан позже в RFC 1282 (BSD Rlogin, Б. Кантор, декабрь 1991 года). Он добавил нечто более опасное, чем передача пароля в открытом виде: доверие на основе имени хоста. Сервер можно было настроить так, чтобы он принимал подключения с определенного хоста вообще без пароля. В RFC есть раздел под названием «Поучительная история» (A Cautionary Tale), где сказано: «Обход аутентификации по паролю для доверенных хостов открывает доступ ко ВСЕМ системам с такой конфигурацией, если хотя бы одна из них будет скомпрометирована». Там также отмечается, что доверие основано на именах хостов, поэтому компрометация DNS (системы доменных имен) или подмена адреса сводят эту защиту на нет.
Оба проекта соответствовали сети, в которой они были созданы. Ранний Ethernet был общей средой: каждая машина в сегменте получала каждый кадр и должна была игнорировать кадры, адресованные не ей. Машина, которая переставала их игнорировать (что и означает использование promiscuous mode), видела трафик всех остальных. Если добавить к этому университет, выдающий учетные записи shell тысячам студентов, то одна скомпрометированная учетная запись превращалась в сборщик паролей для всего факультета.
Бюллетень 1994 года, выпущенный без исправлений
3 февраля 1994 года организация CERT опубликовала бюллетень CA-94:01 под названием «Продолжающиеся атаки на мониторинг сети». В нем сообщалось, что злоумышленники получили доступ к учетным данным десятков тысяч систем по всему интернету. Использованный ими инструмент переводил сетевой интерфейс в неразборчивый режим (promiscuous mode) и записывал начало каждого нового сеанса telnet, rlogin и FTP — именно ту часть, которая содержит имя пользователя и пароль.
CERT рекомендовала администраторам сменить пароли для всех учетных записей, доступных по сети. Если сопоставить это с особенностями протоколов, ловушка становится очевидной: новый пароль при первом же использовании передается по тому же каналу в открытом виде. Внутри telnet или rlogin не существовало никакого исправления, так как ни один из этих протоколов не предусматривал механизмов для защиты данных.
Почему атака с перехватом трафика в Хельсинки привела к созданию SSH
В 1995 году сеть Хельсинкского технологического университета подверглась атаке с перехватом паролей, о которой ранее предупреждала организация CERT. Исследователь Тату Илонен написал замену для небезопасных протоколов и в июле 1995 года выпустил её как бесплатное программное обеспечение. Он назвал его Secure Shell.
Успех обеспечили два проектных решения. Сессия шифровалась, поэтому злоумышленник, прослушивающий сегмент сети, не получал полезных данных. Сервер подтверждал свою подлинность с помощью ключа, что позволяло клиенту убедиться в подключении к нужной машине. Это закрыло уязвимость, связанную с доверием к имени хоста в rlogin.
Распространению также способствовало то, что команды соответствовали тем, к которым привыкли пользователи. ssh заменил rsh и rlogin, а scp заменил rcp. Переход требовал лишь изменения привычки, а не рабочего процесса. К концу 1995 года база пользователей достигла примерно 20 000 человек в пятидесяти странах. В декабре того же года Илонен основал компанию SSH Communications Security для разработки и продажи этого программного обеспечения.
От бесплатного релиза к коммерческому продукту
По мере того как SSH становился бизнесом, лицензия на исходный код менялась. Более поздние релизы содержали условия, ограничивающие возможности использования кода другими лицами, и последним релизом, который можно было свободно использовать, стал ssh 1.2.12. В этом нет ничего предосудительного. Это просто означало, что версия SSH, на основе которой мог строить решения остальной мир, перестала развиваться, в то время как разработка продолжалась там, куда этот мир не мог последовать. Лицензии определяют, какой код выживет; это закономерность, о которой стоит прочитать в как лицензирование открытого ПО сформировало современную инфраструктуру.
Почему OpenBSD создала форк OpenSSH в 1999 году
В начале 1999 года Бьёрн Грёнвалл вернулся к последнему свободному релизу и начал исправлять в нём ошибки. Его версия называлась OSSH и поддерживала только протокол SSH 1.3.
Проект OpenBSD взял OSSH за основу и переработал его. Согласно собственным данным проекта, Тео де Раадт, Нильс Провос, Маркус Фридль, Боб Бек, Аарон Кэмпбелл и Даг Сонг выполнили работу по очистке, аудиту и расширению кода. Результатом стал OpenSSH 1.2.2, который был выпущен в составе OpenBSD 2.6 1 декабря 1999 года.
Почему форк, созданный небольшим проектом операционной системы, оказался почти на каждой машине? Из-за того, что требовалось OpenBSD. OpenBSD поставляет проверенную базовую систему, которая должна быть безопасной в конфигурации по умолчанию, поэтому зашифрованный удалённый вход в систему должен был находиться в этой базовой системе под лицензией без каких-либо ограничений. Проверенный код под свободной лицензией — это именно то, что требовалось любому другому поставщику операционных систем. Дэмиен Миллер, Филип Хэндс и другие почти сразу начали работу над портативной веткой, откуда и берется p в версиях вроде 10.5p1. OpenBSD разрабатывает чистую версию, а портативная ветка добавляет связующий код для всех остальных систем. То, как Unix разделился на системы, которые мы используем сегодня — это причина, по которой этот связующий код вообще необходим.
Поддержка второй версии протокола последовала позже. OpenSSH 2.0 был выпущен в составе OpenBSD 2.7 15 июня 2000 года.
Почему SSH-2 — это новый протокол, а не обновление версии
SSH-1 защищал целостность зашифрованного потока с помощью CRC-32 — контрольной суммы, предназначенной для обнаружения ошибок передачи, а не для противодействия злоумышленнику. В 1998 году Ариэль Футорански и Эмилиано Каргиеман из CORE SDI продемонстрировали последствия этого подхода. При использовании режимов шифрования CBC или CFB и проверки CRC-32 злоумышленник, знающий хотя бы 16 байт открытого текста, может внедрить специально сформированный шифротекст, который получатель примет за подлинный. Это позволяет выполнять команды на сервере.
Уязвимость была заложена в самом протоколе, поэтому её нельзя было исправить без нарушения совместимости. Разработчики реализовали детектор — код в файле deattack.c, который пытался распознать атаку в процессе её выполнения. В феврале 2001 года в самом детекторе обнаружили целочисленное переполнение (CVE-2001-0144), что привело к возможности удаленного выполнения кода на серверах и клиентах, где был установлен этот патч. Архитектура, которую невозможно исправить, накапливает патчи, а патчи привносят собственные ошибки.
Протокол SSH-2 был разработан в рабочей группе IETF под названием secsh и опубликован в виде RFC в январе 2006 года: архитектура в RFC 4251, транспортный уровень в RFC 4253, аутентификация пользователей в RFC 4252, уровень соединений в RFC 4254. Разделение на уровни является ключевым моментом, так как каждый уровень теперь можно заменить независимо. Большая часть дальнейшей истории протокола заключается именно в таких заменах.
Следует выделить два изменения. Целостность данных стала обеспечиваться не CRC-32, а HMAC (код аутентификации сообщений на основе хеша) с использованием общего секретного ключа. Теперь злоумышленник, не способный вычислить MAC, не может подделать пакет. Согласование ключей было переведено на алгоритм Diffie-Hellman. В SSH-1 клиент выбирал сессионный ключ и отправлял его, зашифровав открытым ключом RSA сервера, поэтому любой, кто позже получал доступ к закрытым ключам, мог расшифровать записанную сессию. Diffie-Hellman генерирует уникальный секрет для каждой сессии, который никогда не передается по сети. Таким образом, запись трафика сегодня и кража ключа хоста в будущем не дают злоумышленнику никакой информации. Это свойство называется совершенной прямой секретностью (forward secrecy).
SSH-2 не имеет совместимости с SSH-1 на уровне передачи данных. Именно поэтому номер версии изменился целиком, а не на десятичную дробь.
Почему протокол SSH-1 был удален, а не исправлен
Удаление заняло три релиза OpenSSH. В версии 7.0 от 11 августа 2015 года поддержка протокола 1 была отключена по умолчанию на этапе компиляции. В версии 7.4 от 19 декабря 2016 года была удалена серверная часть. В версии 7.6 от 3 октября 2017 года была удалена клиентская часть, включая соответствующие параметры конфигурации и документацию.
Сохранение протокола в качестве опции для устаревшего оборудования могло бы показаться более удобным решением, однако механизм обнаружения CRC-32 объясняет, почему от него отказались. Переполнение было возможно только потому, что код протокола 1 присутствовал в сборке, находясь в пути выполнения, который большинство администраторов считали неактивным в своих системах. Код, который поставляется в составе ПО, может быть задействован. Удаленный код задействовать невозможно.
Почему при первом SSH-подключении появляется предупреждение о ключе хоста
Шифрование гарантирует конфиденциальность трафика, но не подтверждает личность того, кто находится на другом конце соединения. Если злоумышленник перехватывает трафик и отвечает вместо вашего сервера, вы получаете сеанс, который идеально зашифрован, но проходит через атакующего — это называется атакой «человек посередине» (machine-in-the-middle). SSH решает эту проблему с помощью ключа хоста: сервер доказывает, что владеет закрытой частью пары ключей, а клиент сверяет этот ключ с тем, который был записан ранее. Если вас интересуют технические детали самого процесса соединения, см. что происходит при открытии SSH-соединения.
При первом подключении истории нет, поэтому клиенту не с чем сравнивать ключ, и он вынужден спросить вас:
The authenticity of host 'vps.example.com (203.0.113.10)' can't be established.
ED25519 key fingerprint is SHA256:BQ0Qs2jVXhH2lPZ2rM0aQ0mQ8f9pQ0m3nH0oQ1bYqkE.
This key is not known by any other names.
Are you sure you want to continue connecting (yes/no/[fingerprint])?Ответ yes сохраняет этот ключ в ~/.ssh/known_hosts. Каждое последующее соединение сверяется с сохраненным значением, и при несовпадении программа выдает самое заметное предупреждение:
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!Честная интерпретация этого первого запроса заключается в том, что протокол признает свой единственный уязвимый момент. Принцип «доверия при первом использовании» (Trust on first use) означает, что безопасность первого соединения зависит только от безопасности сети, в которой вы находитесь. Этот пробел можно закрыть. Сверьте отпечаток ключа (fingerprint) через консоль вашего провайдера или в логах сборки сервера перед подключением. Опубликуйте его в DNS как запись SSHFP (RFC 4255), что имеет смысл только при наличии DNSSEC. Либо подписывайте ключи хостов собственным центром сертификации (CA), чтобы клиенты доверяли CA, а не каждому ключу в отдельности. На практике большинство пользователей принимают запрос без проверки, и об этом стоит говорить прямо.
Почему открытые ключи вытеснили пароли
Аутентификация по открытому ключу существовала с ранних релизов SSH, но на то, чтобы она стала общепринятой практикой, ушли годы. Механизм является асимметричным: клиент доказывает владение закрытым ключом, подписывая проверочный запрос, при этом закрытый ключ никогда не покидает клиентское устройство. Пароль работает иначе. Несмотря на то что SSH передает его внутри зашифрованного канала, сервер получает сам секрет. В результате скомпрометированный или враждебный сервер получает данные, которые можно использовать против вас в других местах.
Вторая причина — арифметика. Любой сервер с открытым 22 портом на публичном адресе круглосуточно подвергается автоматизированным попыткам входа, а пароль — это строка, которую можно угадать. Ключ невозможно угадать на практике. Настройка PasswordAuthentication no устраняет эту категорию атак целиком, поэтому данный пункт присутствует в каждом чек-листе по усилению безопасности. Генерация и ротация ключей описаны в основах управления SSH-ключами, а настройки на стороне сервера — в усилении безопасности SSH на VPS.
Почему список алгоритмов SSH постоянно меняется
Многоуровневый протокол позволяет выводить алгоритмы из эксплуатации без замены самого протокола. OpenSSH последовательно использует эту возможность, а даты релизов демонстрируют темп изменений.
Алгоритм Ed25519 появился в OpenSSH 6.5 от 30 января 2014 года вместе с шифром chacha20-poly1305 и форматом закрытых ключей, защищенным с помощью bcrypt. Подписи Ed25519 формируют одноразовое число (nonce) для каждой подписи детерминированным способом, поэтому слабый генератор случайных чисел в момент подписи не может привести к утечке закрытого ключа. Именно так в реальных инцидентах были скомпрометированы закрытые ключи DSA и ECDSA.
С DSA ситуация сложилась иначе. В 2015 году OpenSSH 7.0 отключил поддержку хостовых и пользовательских ключей ssh-dss во время выполнения, так как алгоритм ограничен 160-битным закрытым ключом и использованием SHA-1. Версия 9.8 от 1 июля 2024 года отключила DSA на этапе компиляции. Версия 10.0 от 9 апреля 2025 года удалила его, как выразились разработчики проекта, «завершив процесс устаревания, начатый в 2015 году». Десять лет от отключения до удаления.
RSA не исчез, но его старый формат подписи — да. OpenSSH 8.8 от 26 сентября 2021 года перестал принимать подписи RSA, созданные с помощью SHA-1, по умолчанию. В примечаниях к релизу причина указана прямо: SHA-1 криптографически скомпрометирован, а коллизии с выбранным префиксом можно было реализовать менее чем за 50 000 долларов США. Если вы когда-либо сталкивались с sign_and_send_pubkey: no mutual signature supported при подключении к старому серверу, это результат данного изменения. Ваш ключ в порядке. Алгоритм подписи, который запрашивает удаленная сторона, — нет.
Тот же процесс сейчас происходит с обменом ключами, на этот раз с опережением угрозы. Трафик, перехваченный сегодня, может быть сохранен и расшифрован спустя годы тем, кто первым получит доступ к мощному квантовому компьютеру, поэтому протокол обмена ключами должен был измениться до появления такой машины. OpenSSH 9.0 от 8 апреля 2022 года сделал гибридный обмен ключами стандартом: sntrup761x25519-sha512@openssh.com объединяет постквантовый алгоритм с обменом X25519, поэтому результат будет не слабее классической части, даже если новый алгоритм окажется неэффективным. OpenSSH 9.9 от 19 сентября 2024 года добавил mlkem768x25519-sha256, основанный на ML-KEM (module lattice key encapsulation mechanism), стандартизированном NIST в 2024 году. OpenSSH 10.0 сделал его стандартом для обмена ключами, а страница проекта о постквантовой криптографии объясняет причины этого решения. OpenSSH 10.1 от 6 октября 2025 года начал выводить предупреждение, если удаленная сторона не поддерживает этот алгоритм:
** WARNING: connection is not using a post-quantum key exchange algorithm.
** This session may be vulnerable to "store now, decrypt later" attacks.
** The server may need to be upgraded.Это предупреждение включено по умолчанию и управляется опцией WarnWeakCrypto в файле ssh_config. Что это означает на практике и что делать с сервером, который вызывает такое сообщение, описано в разделе постквантовые стандарты обмена ключами SSH.
Что эта история означает для вашего сервера
Команда, которую вы вводите, почти не изменилась с 1995 года. Почти всё, что находится под ней, было заменено: проверка целостности, обмен ключами, алгоритмы подписи, сама кодовая база. Это стало возможным только потому, что каждая замена заканчивалась намеренным удалением старого, а каждое удаление что-то ломало для кого-то.
Поэтому безопасность вашего SSH в основном определяется версией. Настройки по умолчанию содержат решения о том, какие алгоритмы предлагать, какие отклонять и какие предупреждения выводить. Старый сервер продолжает предлагать всё, что было разрешено в его релизе, и будет понижать уровень безопасности при согласовании, чтобы соответствовать старому клиенту. По состоянию на август 2026 года текущим релизом является OpenSSH 10.5, выпущенный 11 августа 2026 года. Разрыв между этой версией и версией на машине, к которой никто не прикасался три года, — это и есть масштаб проблемы. Проверка этого входит в первые десять минут работы на новом VPS.
FAQ
Кто создал SSH и зачем?
Тату Илонен, исследователь из Хельсинкского технологического университета, написал SSH в 1995 году после атаки с перехватом паролей в университетской сети. Инструменты удаленного доступа того времени, telnet и rlogin, передавали пароли по сети в открытом виде, поэтому любой, кто отслеживал общий сегмент сети, мог собрать учетные данные. В июле 1995 года он выпустил программу как бесплатное ПО. К концу того же года у нее было около 20 000 пользователей в пятидесяти странах, а в декабре 1995 года он основал компанию SSH Communications Security.
В чем разница между SSH-1 и SSH-2?
Это разные протоколы, несовместимые на уровне передачи данных. SSH-1 был монолитным протоколом, который использовал CRC-32 для контроля целостности, а клиент отправлял сессионный ключ, зашифрованный RSA-ключами сервера. SSH-2 разделяет задачи на транспортный уровень, уровень аутентификации и уровень соединения (RFC 4251–4254, январь 2006 года), использует HMAC для контроля целостности и генерирует сессионные ключи с помощью алгоритма Диффи-Хеллмана. Благодаря этому записанный трафик остается конфиденциальным, даже если ключ хоста будет скомпрометирован позже. Поддержка SSH-1 была поэтапно удалена из OpenSSH, окончательно исчезнув в версии 7.6 в октябре 2017 года.
Почему OpenSSH заменил оригинальную реализацию SSH?
Разработка оригинального продукта перешла в коммерческую плоскость с ограничивающей лицензией, а последним свободно распространяемым релизом стал ssh 1.2.12. В начале 1999 года Бьёрн Грёнвалл возродил этот релиз под названием OSSH, а команда OpenBSD сделала форк OSSH в OpenSSH, который был включен в состав OpenBSD 2.6 от 1 декабря 1999 года. OpenBSD требовался проверенный код с неограниченной лицензией для базовой системы, и именно эти два свойства позволили всем остальным операционным системам использовать ту же реализацию через переносимую ветку (portable branch).
Почему SSH спрашивает о ключе хоста при первом подключении?
Потому что клиент никогда раньше не видел этот сервер и ему не с чем сравнить ключ. Само по себе шифрование не позволяет отличить честный сервер от машины, находящейся посередине пути (man-in-the-middle), поэтому SSH идентифицирует серверы по ключу и записывает увиденное в ~/.ssh/known_hosts. Первое подключение — это единственный момент, когда нет сохраненного значения для проверки, поэтому клиент запрашивает подтверждение у вас. Сравните отпечаток ключа с тем, который вы получили через консоль провайдера или на самом сервере, и воспринимайте любое последующее сообщение REMOTE HOST IDENTIFICATION HAS CHANGED как реальный инцидент, пока не найдете ему объяснение.
Почему старые SSH-ключи перестают работать после обновления?
Потому что OpenSSH выводит из эксплуатации алгоритмы согласно опубликованному графику. Ключи DSA (ssh-dss) были отключены по умолчанию в OpenSSH 7.0 в 2015 году и полностью удалены в OpenSSH 10.0 от 9 апреля 2025 года. Ключи RSA все еще работают, но подписи, созданные с помощью SHA-1, были отключены по умолчанию в OpenSSH 8.8 в сентябре 2021 года, что проявляется как sign_and_send_pubkey: no mutual signature supported при попытке подключения к старому серверу. Ключ Ed25519, доступный начиная с OpenSSH 6.5 с января 2014 года, позволяет избежать обеих проблем.