учебники, программирование, основы, введение в,

 

Безопасное сетевое взаимодействие (часть 3)

Протокол SSH
Архитектура протокола SSH
Основные понятия
SSH является протоколом для удаленного безопасного входа и других сетевых сервисов безопасности в недостаточно надежно защищенной сети. Рассмотрим архитектуру протокола SSH, а также основные обозначения, используемые при описании этого протокола. Кроме того, обсудим принципы именования объектов системы, принятые в протоколе SSH, что позволяет реализовывать локальные расширения протокола.
SSH состоит из трех компонентов.

  1. Протокол транспортного уровня (SSH-TRANS) обеспечивает аутентификацию сервера, конфиденциальность и целостность соединения. Также может дополнительно обеспечивать сжатие данных. Протокол транспортного уровня обычно выполняется поверх соединения TCP, но может использоваться и поверх любого другого надежного соединения.
  2. Протокол аутентификации пользователя (SSH-USERAUTH) аутентифицирует клиента для сервера. Он выполняется поверх протокола транспортного уровня.
  3. Протокол соединения (SSH-CONN), мультиплексирует несколько логических каналов в один зашифрованный туннель. Протокол выполняется поверх протокола аутентификации пользователя.

Клиент посылает запрос на сервис всякий раз, когда устанавливается безопасное соединение на транспортном уровне. Второй запрос сервиса посылается после выполнения аутентификации пользователя.
Протокол соединения создает каналы, которые могут использоваться для различных целей. Существуют стандартные методы установки безопасных сессий интерактивного shell и перенаправления («туннелирования») произвольных портов TCP/IP и соединений Х11.
Ключи хоста
Каждый сервер должен иметь ключ хоста. Серверы могут иметь несколько ключей хоста, используемых различными алгоритмами. Несколько серверов могут разделять один ключ хоста. Каждый сервер должен иметь, по крайней мере, один ключ для каждого обязательного алгоритма открытого ключа. В настоящее время требуется поддерживать алгоритм DSS.
С помощью ключа сервера при обмене ключа можно проверить, действительно ли клиент общается с нужным сервером. Для того, чтобы это было возможно, клиент должен предварительно знать об открытом ключе сервера.
Могут использоваться две различные модели:

  1. Клиент имеет локальную базу данных, связывающую каждое имя сервера с соответствующим открытым ключом. Этот метод не требует централизованной административной инфраструктуры и трехсторонней координации. В то же время, такую базу данных тяжело поддерживать при большом количестве клиентов и серверов, с которыми они должны взаимодействовать.
  2. Взаимосвязь имя сервера – ключ проверяется некоторым доверенным сертификационным органом – СА. Клиент знает только ключ корневого CA и может проверить достоверность всех ключей серверов, сертифицированных этими СА.

Второй способ легче с точки зрения поддержки, так как в идеале только единственный ключ корневого СА необходимо хранить у клиента. С другой стороны, каждый хост должен быть соответствующим образом сертифицирован центральным органом перед тем, как можно будет установить безопасное соединение.
В протоколе существует опция, которая позволяет не проверять связывание имя сервера – открытый ключ при первом соединении клиента с сервером. Это обеспечивает возможность взаимодействия без предварительного знания ключа сервера. В этом случае соединение также обеспечивает защиту от пассивного прослушивания; тем не менее, оно уязвимо для активных атак типа встреча посередине. Реализации не должны допускать такие соединения по умолчанию, если они допускают возможность активных атак. Однако, так как инфраструктура открытого ключа еще недостаточно широко распространена, данная опция делает протокол более приемлемым для взаимодействия сторон, обеспечивая более высокий уровень безопасности, чем такие предыдущие решения как telnet или rlogin.
Реализации протокола должны пытаться обеспечивать проверку ключей сервера. Например, можно попробовать принимать ключ сервера без проверки только в первый раз, сохранять ключ в локальной базе данных и сравнивать этот ключ при всех последующих соединениях с данным сервером.
Реализации могут предоставлять дополнительные способы проверки корректности ключей сервера, например, вычислять хэш открытого ключа, который можно легко проверить с помощью телефона или других внешних коммуникационных каналов.
Все реализации должны обеспечить опцию, не позволяющую принимать ключи сервера, которые невозможно проверить.
Предполагается, что простота использования является важным критерием при работе с тем или иным прикладным продуктом, повышающим безопасность сетевого взатмодействия. Таким образом, создавая опцию, позволяющую не проверять ключ сервера, разработчики считали, что это повысит общую безопасность Internet, даже если несколько снизит безопасность протокола в тех конфигурациях, где допускается такая опция.
Возможности дальнейшего развития SSH
Разработчики надеются, что протокол будет развиваться, и некоторые организации захотят использовать собственные методы шифрования, аутентификации или обмена ключей. Централизованная регистрация всех расширений затруднена, особенно для обеспечения экспериментальных или классифицированных методов. С другой стороны, отсутствие централизованной регистрации приводит к конфликтам в методах идентификации, затрудняя интероперабельность.
Для идентификации алгоритмов, методов, форматов и протоколов расширения были выбраны текстовые имена определенного формата. Имена DNS используются для создания локального пространства имен, в котором могут быть определены экспериментальные или классифицированные расширения без риска конфликта с другими реализациями.
Одна из целей разработки состоит в том, чтобы, с одной стороны, максимально упростить базовый протокол, а с другой стороны, иметь возможность поддерживать несколько алгоритмов. Тем не менее, все реализации должны поддерживать минимальный набор алгоритмов для обеспечения интероперабельности. Это не означает, что политика безопасности на всех серверах должна допускать возможность использования всех алгоритмов. Обязательные алгоритмы, которые должны поддерживаться, описаны в соответствующих документах протокола.

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

  1. Должны быть определены наиболее предпочтительные алгоритмы шифрования, целостности и сжатия для каждого направления и каждого порта.
  2. Должны быть определены используемые алгоритмы открытого ключа и метод обмена ключей для аутентификации сервера.
  3. Должны быть определены методы аутентификации, которые использует сервер для каждого пользователя. Может быть определено требование множественной аутентификации для некоторых или для всех пользователей. Методы и алгоритмы аутентификации могут также зависеть от того, с какого адреса пользователь пытается подключиться.
  4. Должны быть определены операции, которые пользователю разрешено выполнять, используя протокол соединения.

Размеры пакета и заголовка
Минимальный размер пакета SSH равен 28 байтам. Возрастание минимального размера по сравнению с заголовками TCP/IP незначительно для больших пакетов, но очень существенно для небольших, коими являются сессии telnet. Минимальный размер заголовка TCP/IP равен 32 байтам. Таким образом, реально заголовок пакета возрастает с 33 до 61 байта.
Общая доля данных типа telnet в Internet незначительна, поэтому общая нагрузка на трафик небольшая.
Только в одном случае возрастающий размер пакета имеет важное значение – при соединении по медленному модему. Протокол РРР сжимает заголовки TCP/IP, подчеркивая возрастание размера пакета.
Некоторые проблемы могут быть связаны с максимальным размером пакета. Для минимизации задержки на изменение экрана не должно быть больших пакетов в интерактивных сессиях. О максимальном размере пакета договариваются отдельно для каждого канала.
Локализация и поддержка различных наборов символов
В большинстве случаев протоколы SSH непосредственно не выводят текст на терминал пользователя. Тем не менее, существует несколько случаев, в которых данные должны быть выведены на терминал. В этом случае набор символов должен быть указан явно. В большинстве случаев используется кодировка ISO 10646 UTF-8. При этом определяется поле для тега языка.
Существует большая проблема с набором символов для интерактивных сессий. Простого решения не существует, так как различные приложения могут показывать данные в различных форматах. Клиентом также могут применяться различные типы эмуляции терминалов, и используемый набор символов зависит от эмуляции терминала. Таким образом, для непосредственного описания используемого набора символов для данных терминальной сессии единственного места не существует. Тем не менее, стандарный тип эмуляции терминала «vt100» передается клиенту и неявно определяет набор символов и кодировку. Приложения обычно используют тип терминала для определения набора символов, или набор символов определяется с использованием внешних параметров. Эмуляция терминала может также допускать конфигурирование набора символов по умолчанию. В любом случае набор символов для терминальной сессии первоначально локально определяется клиентом.
Внутренние имена, используемые для идентификации алгоритмов и протоколов, обычно никогда не показываются пользователям и должны быть в US-ASCII.
Хотя имя пользователя и клиент, и сервер определяют внутренне, оно должно быть показано в логах, отчетах и т.п. Имена должны иметь кодировку ISO 10646 UTF-8, но в некоторых случаях могут требоваться другие кодировки.
В целях локализации протокол старается минимизировать число передаваемых текстовых сообщений. Когда они присутствуют, такие сообщения обычно относятся к ошибкам, отладочной информации или некоторым внешним конфигурационным данным. Для данных, которые должны быть показаны, следует предусмотреть возможность вызывать локализованное сообщение вместо переданного сервером.
Способ именования объектов протокола
Протокол SSH ссылается на конкретные алгоритмы хэширования, шифрования, целостности, сжатия и обмена ключа по именам. Существуют некоторые стандартные алгоритмы, которые должны поддерживать все реализации. Существуют также алгоритмы, которые определены в протоколе, но являются дополнительными. Более того, ожидается, что некоторые организации захотят использовать собственные алгоритмы.
Для имен алгоритмов существует два формата:

  1. Имена, которые не содержат символ «@», зарезервированны для обозначений IANA. Примерами являются '3des-cbc', 'sha-1', 'hmac-sha1'. Имена данного формата не должны использоваться без регистрации в IANA. Зарегистрированные имена не должны содержать символов «@» или «.».
  2. Можно определить дополнительные алгоритмы, используя имена в формате name@domainname. Часть, следующая за символом @, должна представлять собой полностью определенное доменное Internet-имя лица или организации, определяющих его. Каждый домен управляет своим локальным пространством имен.

Протокол транспортного уровня

Введение

Транспортный уровень является протоколом нижнего уровня в семействе протоколов SSH. Он обеспечивает шифрование и целостность данных, а также аутентификацию сервера.
Аутентификация пользователя данным протоколом не выполняется. Для этого определен специальный протокол, который расположен выше данного протокола.
Протокол используется для ведения переговоров о способе обмена ключа, алгоритме открытого ключа, алгоритме симметричного шифрования, алгоритме аутентификации сервера и хэш-алгоритме. Считается, что в большинстве окружений будут необходимы только две взаимные передачи для полного обмена ключей, аутентификации сервера, запроса сервиса и принятия уведомления о запросе сервиса. В худшем случае будет три взаимные передачи.

Установление соединения

SSH работает поверх любого 8-битного надежного транспорта. Транспорт, расположенный ниже, должен защищать от ошибок передачи, чтобы при возникновении ошибки SSH-соединение прерывалось. Как обычно, соединение инициирует клиент.

Обмен версией протокола

Когда соединение уровня ТСР установлено, обе стороны должны послать информационную строку в форме SSH-protoversion-softwareversion comments.
Рассмотрим версию протокола 2.0.
Обмен ключей начинается непосредственно после посылки данного сообщения. Все пакеты, следующие за строкой идентификации, будут использовать так называемый протокол бинарных пакетов.

Совместимость со старыми версиями SSH

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

Старый клиент, новый сервер

Реализации сервера могут поддерживать конфигурационный флаг совместимости, который устанавливает совместимость со старыми версиями. Когда флаг установлен, сервер должен идентифицировать свой протокол версии как 1.99. Клиенты, использующие протокол 2.0, должны идентифицировать его как 2.0.
В режиме совместимости сервер не должен посылать любые данные после своей строки идентификации до тех пор, пока не получит строку идентификации от клиента. После этого сервер может определить, использует ли клиент старый протокол, и в этом случае сам должен использовать старый протокол.
Когда нет необходимости в совместимости со старыми клиентами, сервер может послать свои инициализационные данные обмена ключа непосредственно после строки идентификации.

Новый клиент, старый сервер

Новый клиент может немедленно послать дополнительные данные после своей строки идентификации, т.е. перед получением идентификации сервера. Поэтому старый протокол может уже быть искажен, когда клиент узнает, что сервер старый. В этом случае клиент должен закрыть соединение с сервером и установить соединение, используя старый протокол.

Протокол бинарного пакета

Требование кратности общей длины 8 байтам или размеру блока шифратора, в зависимости от того, что больше, должно выполняться, даже если используется потоковый шифратор. Поле длины пакета также зашифровано.

Максимальная длина пакета

Все реализации должны иметь возможность обрабатывать пакеты с длиной некомпрессированного содержимого 32768 байт или меньше и общий размер пакета 35000 байт или меньше (включая длину, длину добавления, содержимое, добавление и МАС). Реализации должны поддерживать более длинные пакеты, если это необходимо, например, если требуется послать очень большую цепочку сертификатов. Такие пакеты могут быть посланы, если строка версии указывает, что другой участник может обработать их. Тем не менее, реализации должны проверять, приемлема ли длина пакета для принимающей стороны, во избежание отказа в обслуживании или атаки с переполнением буфера.

Компрессия

Если договариваются о компрессии, то поле содержимого и только оно будет сжато с использованием выбранного алгоритма. Поле длины и МАС будут вычислены, исходя из сжатого содержимого.
Компрессия должна быть независимой для каждого направления, и реализации должны позволять независимо изменять алгоритм для каждого направления.
В настоящий момент требуется, чтобы реализации поддерживали нулевую компрессию и метод компрессии zlib.

Шифрование

Об алгоритме шифрования и ключе договариваются во время обмена ключа. Когда шифрование присутствует, длина пакета, длина добавления, содержимое и поля добавления каждого пакета должны шифроваться данным алгоритмом.
Зашифрованные данные во всех пакетах, посылаемые в одном направлении, должны рассматриваться как единый поток данных. Все алгоритмы шифрования должны использовать длину ключа не менее 128 битов.
Алгоритмы шифрования для каждого направления должны выполняться независимо друг от друга, и реализации должны позволять независимое изменение алгоритма для каждого направления (если локальная политика позволяет использование нескольких алгоритмов).


Таблица 22.1. Структура бинарного пакета

Рacket_length

Длина пакета (в байтах), не включая поля МАС и packet_length.

Рadding_length

Длина дополнения (в байтах).

Payload

Полезное содержимое пакета. Если договариваются о сжатии, это поле сжимается. Первоначально компрессия не устанавливается

Padding

Добавление произвольной длины такое, что общая длина (packet_length || padding_length || payload || padding) кратна размеру блока шифрования или 8 байтам, в зависимости от того, что больше. Должно быть, по крайней мере, четыре байта добавления. Добавление должно состоять из случайных байтов. Максимальная длина добавления равна 255 байтов

МАС

Аутентификационный код сообщения. Если договариваются об аутентификации сообщения, это поле содержит байты МАС. Первоначально алгоритм МАС должен быть "none"

Целостность данных

Целостность данных обеспечивается включением в каждый пакет аутентификационного кода сообщения (МАС), который вычисляется для ключа, последовательного номера пакета и содержимого пакета.
Об алгоритме аутентификации сообщения и ключе договариваются во время обмена ключа. Первоначально МАС не используется и его длина должна быть равна нулю. После обмена ключа выбранный МАС вычисляется перед шифрованием для следующего пакета данных:

mac = MAC (key, sequence_numbеr || 
           unencrypted_packet)

где unencrypted_packet есть весь пакет без МАС (поля длины, содержимого и присоединения) и sequence_number есть полный последовательный номер пакета, представленный как uint32. Последовательный номер первого пакета равен нулю и возрастает для каждого пакета (независимо от того, используется шифрование и МАС или нет). Он никогда не обнуляется, даже если о ключах или алгоритмах договариваются заново. Он возвращается в ноль после 232 пакетов. Сам последовательный номер пакета не включается в пакет, посылаемый по сети.
Алгоритмы МАС для каждого направления должны выбираться независимо, и реализации должны позволять независимо изменять алгоритм для обоих направлений.
Байты МАС, полученные из алгоритма МАС, должны передаваться без шифрования как последняя часть пакета. Число байтов МАС зависит от выбранного алгоритма.

Методы обмена ключа

Метод обмена ключа определяет создание одноразовых ключей сессии для шифрования и вычисления МАС и определяет также метод аутентификации сервера.
В настоящей версии определен только один метод обмена ключей: diffie-hellman-groupl-shal.
Будем рассматривать именно этот метод.

Алгоритмы открытого ключа

Данный протокол разработан таким образом, чтобы он мог выполняться с любым форматом открытого ключа и любым алгоритмом, используемым для подписи и/или шифрования.
Существует несколько аспектов, которые определяют тип открытого ключа:

  1. Формат ключа: как ключ шифрует и как представлены сертификаты. Некоторые ключи в данном протоколе могут содержать не только собственно ключ, но и сертификаты.
  2. Алгоритмы подписи и/или шифрования. Некоторые типы ключей не имеют возможности одновременно поддерживать и подпись, и шифрование. Использование ключа может также определяться ограничениями политики, например, требованием наличия сертификатов. В данном случае для различных альтернативных политик должны быть определены различные типы ключа.
  3. Представление подписи и/или зашифрованных данных. Должно быть специфицированно добавление, упорядочивание байтов, форматы данных и, быть может, дополнительные характеристики.
Обмен ключа

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

Переговоры об алгоритме

Обмен ключа начинается каждой стороной с посылки следующего пакета:

SSH_MSG_KEXINIT
cookie (random bytes)
kex_algorithms
server_host_key_algoritms
encryption_algorithms_client_to_server
encryption_algorithms_server_to_client
mac_algorithms_client_to_server
mac_algorithms_ server _to_client
compression_algorithms_client_to_server
compression_algorithms_ server _to_client
languages_client_to_server
languages_ server _to_client
first_kex_packet_follows

Таблица 22.2. Параметры переговоров

Cookie

Должно быть случайным числом, созданным отправителем. Цель создания этого cookie следующая: сделать так, чтобы ни одна из сторон не могла полностью определить ключи и идентификатор сессии

Kex_algorithms

Алгоритмы обмена ключей, которые были определены выше. Первым алгоритмом должен быть самый предпочтительный. Если обе строны сделают один и тот же выбор, то этот алгоритм и должен использоваться. В противном случае следующий алгоритм должен применяться для выбора метода обмена ключа: повторять по каждому kex алгоритму клиента. Выбрать первый алгоритм, который удовлетворяет следующиим условиям:

  • сервер также поддерживает данный алгоритм;
  • если алгоритм требует шифрования ключом сервера, существует алгоритм шифрования у серверной части server_host_key_algorithms, который также поддерживается клиентом;
  • если алгоритм требует подписи ключом сервера, существует алгоритм подписи у серверной части server_host_key_algoritms, который также поддерживается клиентом;
  • если нет алгоритма, который удовлетворяет всем этим условиям, соединение прерывается.

Server_host_key_algoritms

Список алгоритмов, поддерживающих ключ сервера. Списки алгоритмов сервера, для которых он имеет ключи; списки алгоритмов клиента, которые он желает принимать. У сервера может быть несколько ключей, возможно, для разных алгоритмов.
Выбирается алгоритм ключа сервера, который может использоваться для подписи и является первым алгоритмом в списке клиента. Если такого алгоритма нет, стороны должны разорвать соединение

Encryption_algorithms

Список возможных алгоритмов симметричного шифрования в порядке предпочтения. Выбранный алгоритм шифрования для каждого направления должен быть первым алгоритмом в списке клиента, и также находиться в списке алгоритмов сервера. Если такого алгоритма нет, то стороны должны разорвать соединение.
"none" должно быть явно указано в списке, если это принимается

Mac_algorithms

Список возможных МАС-алгоритмов в порядке предпочтения. Выбранный алгоритм МАС должен быть первым в списке клиента, а также существовать в списке сервера. Если такого алгоритма нет, стороны должны разорвать соединение.
"none" должно быть явно указано в списке, если это принимаемо.

Compression_algorithms

Список возможных алгоритмов сжатия в порядке предпочтения. Выбранный алгоритм сжатия должен быть первым алгоритмом в списке клиента и должен также существовать в списке сервера. Если такого алгоритма нет, стороны должны разорвать соединение.
"none" должно быть явно указано в списке, если это принимается

Languages

Список тегов языков в порядке предпочтения в соответствии с RFC-1766. Оба участника могут игнорировать этот список. Если нет предпочтений по языку, список должен быть пустым

First_kex_packet_follows

Признак того, что следующим пакетом будет обмен ключа. Если пакет с обменом ключа будет послан, значение должно быть true. Если нет, то значение должно быть false.

Каждый поддерживаемый алгоритм должен быть в списке в соответствии с предпочтениями. Каждая строка должна содержать название, по крайней мере, одного алгоритма.
После получения SSH_MSG_KEXINIT пакета от другой стороны, каждый участник будет знать, правильно ли были сделаны предположения. Если каким-либо из участников были сделаны неправильные предположения, а последнее поле было true, то следующий пакет должен молча игнорироваться, и обе стороны должны затем выполнить повторный KEXINIT. Если предположения правильные, обмен ключа должен быть продолжен с использованием выбранного метода.
После обмена пакетом KEXINIT выполняется алгоритм обмена ключа. Он может включать обмен несколькими пакетами, как определено в конкретном методе обмена ключа.

Выход из обмена ключа

Обмен ключа создает два значения: разделяемый секрет K и хэш обмена Н. Ключи для шифрования и вычисления МАС получаются из этих значений. Хэш обмена Н из первого сообщения обмена ключа также используется как идентификатор сессии. Эти данные используются при аутентификации: они подписаны закрытым ключом сервера. После вычисления идентификатор сессии остается прежним, даже если ключи впоследствии изменяются.
Каждый метод обмена ключа должен определить хэш-функцию, которая используется для этого обмена ключа. Будем обозначать этот алгоритм HASH.
Ключи шифрования должны вычисляться как HASH некоторого известного значения и общего секрета K следующим образом:

  1. Инициализационный вектор при шифровании в направлении от клиента к серверу:

HASH (K || "A" || session_id) ("A" означает единственный символ ASCII A).

  1. Инициализационный вектор при шифровании в направлении от сервера к клиенту:

HASH (K || "B" || session_id)

  1. Ключ шифрования в направлении от клиента к серверу:

HASH (K || "C" "" || sessin_id)

  1. Ключ шифрования в направлении от сервера к клиенту:

HASH (K || "D" || session_id)

  1. Ключ целостности в направлении от клиента к серверу:

HASH (K || "E" || session_id)

  1. Ключ целостности в направлении от сервера к клиенту:

HASH (K || "F" || session_id)
Общий секрет должен быть извлечен из первых 128 битов полученного хэш-значения, если требуется 128 битный ключ. При использовании других алгоритмов из хэш-значения берут столько байтов, сколько требуется для этого алгоритма. Если длина ключа больше, чем длина результата HASH, ключ расширяется итерационным вычислением HASH. Этот процесс повторяется до тех пор, пока не получится результат достаточной длины.

K1 = HASH (K || X || session_id)
    (например, в первом случае Х есть "A")
K2 = HASH (K || K1) K3 = HASH (K || K1 || K2) и т.д.
Принятие ключей в использование

Обмен ключа заканчивается сообщением SSH_MSG_NEWKEYS, которое посылает каждая сторона. Это сообщение посылается с использованием старых ключей и алгоритмов. Все сообщения, посылаемые после этого сообщения, уже должны использовать новые ключи и алгоритмы.
Реализации не должны принимать любые другие сообщения после обмена ключа до тех пор, пока не получат сообщение SSH_MSG_NEWKEYS.

SSH_MSG_NEWKEYS
Обмен ключа Диффи-Хеллмана

Обмен ключа Диффи-Хеллмана обеспечивает разделяемый секрет, который не может быть определен оппонентом. При обмене ключа используется подпись, создаваемая закрытым ключом сервера для аутентификации сервера и защиты от атак «man-in-the-middle».
Будем использовать следующие обозначения:


- клиент;

S - сервер;

р - простое число;

g - генератор для подгруппы GF (p);

V_S - строка версии S;

V_C - строка версии С;

K_S - открытый ключ сервера S;

I_C - сообщение KEXINIT C;

I_S - сообщение KEXINIT S, которыми участники обменялись перед данными сообщениями.

  1. С создает случайное число х и вычисляет e = gx mod p. C посылает e к S.
SSH_MSG_KEXDH_INIT
e
  1. S создает случайное число у и вычисляет f = gy mod p. S получает e и вычисляет K = еу mod p, H = hash (V_C || V_S || I_C || I_S || K_S || e || f || K) и подпись s для Н своим закрытым ключом сервера. S посылает {K_S || f || s} к С. Операция подписывания может включать вторую операцию хэширования.
SSH_MSG_KEXDH_REPLY
открытый ключ сервера и сертификаты (K_S)
f s
  1. С проверяет, действительно ли K_S является ключом сервера S, используя сертификаты или локальную БД. С также может принимать ключ без проверки, однако это делает протокол небезопасным против активных атак (но это может быть сделано из практических соображений во многих окружениях). Затем С вычисляет K = fx mod p, H = hash (V_C || V_S || I_C || K_S || e || f || K) и проверяет подпись s для Н.

Хэш Н вычисляется от конкатенации следующих значений:


V_C – строка версии клиента (CR и NL исключаются)

V_C – строка версии сервера (CR и NL исключаются)

I_C – содержимое сообщения SSH_MSG_KEXINIT клиента

I_S – содержимое сообщения SSH_MSG_KEXINIT сервера

K_S – ключ хоста

e – значение, посылаемое клиентом

f – значение, посылаемое сервером

K – разделяемый секрет

Эти значения называются хэшем обмена и используются для аутентификации сервера.
Алгоритм подписи применяется к значению Н. Большинство алгоритмов подписи включают хэширование. Например, ssh-dss определяет использование SHA. В этом случае данные, во-первых, хэшируются HASH, в результате чего вычисляется Н, и затем Н хэшируется с использованием SHA как часть операции подписывания.

Повторный обмен ключа

Повторный обмен ключа начинается посылкой SSH_MSG_KEXINIT пакета, когда не полностью выполнен обмен ключа. При получении данного сообщения участник должен ответить собственным сообщением SSH_MSG_KEXINIT за исключением того случая, когда полученный SSH_MSG_KEXINIT уже является повтором. Оба участника могут начать повторный обмен, но роли не должны меняться, т.е. сервер остается сервером, клиент остается клиентом.

Запрос сервиса

После выполнения обмена ключа клиент запрашивает один из следующих сервисов: ssh-userauth, ssh-connection.
Сервер должен ответить сообщением:

SSH_MSG_SERVICE_REQUEST
service name

Если сервер поддерживает сервис и разрешает клиенту использовать его, он должен ответить следующим сообщением:

SSH_MSG_SERVICE_ACCEPT
service name
Дополнительные сообщения

Каждый из участников может послать любое из следующих сообщений в любое время.

Сообщение разрыва соединения
SSH_MSG_DISCONNECT
reason code
description
language tag

Это сообщение вызовет немедленный разрыв соединения. Отправитель не должен посылать или получать какие-либо данные после этого сообщения, и получатель не должен принимать какие-либо данные после получения этого сообщения.

Обсуждение проблем безопасности

Данный протокол создает безопасный зашифрованный канал в небезопасной сети. Он выполняет аутентификацию сервера, обмен ключа, шифрование и обеспечение целостности передаваемых данных. Он также создает уникальный идентификатор сессии, который может использоваться протоколами более высокого уровня.
Данный протокол может использоваться без существования надежной взаимосвязи между ключом сервера и именем сервера. Такое использование небезопасно, но может быть необходимо в недостаточно защищенных критических окружениях, и тем не менее обеспечивает защиту от пассивных атак. Однако реализации протокола, выполняющиеся на верхнем уровне данного протокола, должны помнить о такой возможности.
Данный протокол разработан для использования поверх надежного транспорта. Протокол не дает возможности избежать атак типа отказ в обслуживании.

Протокол аутентификации пользователя

Обзор протокола аутентификации

Протокол аутентификации пользователя выполняется поверх протокола SSH транспортного уровня. Данный протокол предполагает, что лежащий ниже протокол обеспечивает целостность и конфиденциальность.
Имя сервиса для данного протокола – ssh-userauth.
Идентификатор сессии данный протокол получает из протокола транспортного уровня. Протоколу аутентификации пользователя необходима конфиденциальность, которая обеспечивается протоколом транспортного уровня.
Аутентификацией клиента управляет сервер, посылая клиенту сообщение, что аутентификация может продолжаться. Клиент может выбирать в любом порядке один из перечисленных сервером методов. Это, с одной стороны, дает серверу возможность более комплексного управления аутентификационным процессом, а, с другой стороны, дает клиенту гибкость в использовании методов, которые он поддерживает или которые больше всего подходят для пользователя, если сервер предоставляет возможность аутентификации несколькими методами.
Аутентификационные методы идентифицируются по имени. Метод none зарезервирован, но не должен быть в списке поддерживаемых. Тем не менее, этот метод может быть послан клиентом. Сервер должен всегда отвергать этот запрос, если не допускает отсутствия аутентификации; только в данном случае сервер должен принимать его. Основная цель посылки такого запроса клиентом состоит в том, чтобы получить от сервера список поддерживаемых методов аутентификации.
Сервер должен определить таймаут для аутентификации и разрывать соединение, если аутентификация не проведена за указанное время. Дополнительно должно быть установлено ограничение на число неудачных попыток аутентификации, которые клиент может предпринять в течение одной сессии. Если порог превышен, сервер должен разорвать соединение.

Запросы на аутентификацию

Все запросы на аутентификацию должны использовать строго фиксированный формат сообщений. Определены только первые несколько полей; оставшиеся поля зависят от метода аутентификации.

SSH_MSG_USERAUTH_REQUEST
имя пользователя (UTF-8 кодировка)
имя сервиса (в US-ASCII)
имя метода (в US-ASCII)
остаток пакета определяется методом аутентификации

Имя пользователя и сервис повторяются при каждой новой попытке аутентификации и могут изменяться. Сервер должен проверять это в каждом сообщении и полностью проверять любое добавленное аутентификационное состояние, если были сделаны подобные изменения.
Имя сервиса определяет сервис, который будет запущен после завершения процесса аутентификации. Может быть определено несколько различных сервисов. Если запрашиваемый сервис недоступен, сервер может разорвать соединение немедленно или в любое более позднее время. Рекомендуется посылать соответствующее сообщение о разрыве соединения. В любом случае, если сервис не существует, аутентификация не может считаться удачной.
Если пользователь, который запрашивает аутентификацию, не существует, сервер может либо разорвать соединение, либо послать поддельный список приемлемых аутентификаций, но никогда не может считать аутентификацию удачно завершившейся. Это дает возможность серверу избегать обнаружения информации о том, какие имена пользователей существуют.
Аутентификационный запрос может привести к дальнейшему обмену сообщениями. Все такие сообщения зависят от используемого метода аутентификации, и клиент может в любое время продолжить обмен, послав новое сообщение SSH_MSG_USERAUTH_REQUEST. В этом случае сервер должен сбросить всю информацию о предыдущей попытке аутентификации и продолжить процесс аутентификации заново.

Ответы на запросы аутентификации

Если сервер отклонил запрос на аутентификацию, он должен ответить следующим сообщением:

SSH_MSG_USERAUTH_FAILURE
аутентификации, которые могут быть продолжены
частичный успех

«Аутентификации, которые могут быть продолжены» – это разделенный запятыми список имен методов аутентификации, с использованием которых можно продолжать аутентификационный диалог.
Считается, что серверы должны включать только те методы, которые реально используются. Однако нигде не запрещено включать методы, которые не могут быть задействовать для аутентификации пользователя.
Уже успешно завершенные аутентификации не должны включаться в список, если они по какой-либо причине не должны выполняться снова.
«Частичный успех» должен быть true, если запрос на аутентификацию, на который дается данный ответ, был успешным. Он должен быть false, если запрос не был успешно обработан.
Когда сервер принимает аутентификацию, он должен ответить:

SSH_MSG_USERAUTH_SUCCESS

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

Запрос на аутентификацию «none»

Клиент может запросить список сервисов, которые могут выполняться после использования метода аутентификации none.
Если аутентификация не является необходимой для пользователя, сервер должен вернуть SSH_MSG_USERAUTH_SUCCESS. В противном случае сервер должен вернуть SSH_MSG_USERAUTH_FAILURE и может возвратить список методов аутентификации, с использованием которых можно продолжить аутентификацию.
Но данный метод в списке поддерживаемых сервером методов не должен стоять по умолчанию.

Завершение аутентификации пользователя

Аутентификация завершается, когда сервер отвечает сообщением SSH_MSG_USERAUTH_SUCCESS. Все относящиеся к аутентификации сообщения, полученные после посылки данного сообщения, должны молча игнорироваться.
После посылки SSH_MSG_USERAUTH_SUCCESS сервер запускает запрошенный сервис.

Баннерные сообщения

В некоторых случаях может допускаться посылка предупреждающего (warning) сообщения перед аутентификацией. Многие системы UNIX могут показывать текст из /etc/issue или использовать tcp wrappers или аналогичные программы для показа баннеров перед попыткой входа пользователя.
Сервер SSH может послать сообщение SSH_MSG_USERAUTH_BANNER в любое время перед успешным завершением аутентификации. Данное сообщение содержит текст, который будет показан пользователю. Формат сообщения следующий:

SSH_MSG_USERAUTH_BANNER
сообщение 
language tag

По умолчанию клиент должен показать это сообщение на экране пользователя. Однако, так как сообщение, вероятно, будет посылаться при каждой попытке входа и поскольку некоторым клиентским ПО придется открывать отдельное окно для этого напоминания, клиентское ПО может разрешать пользователю полностью запрещать показ баннеров сервера.
Если строка сообщения показывается, управляющие символы должны фильтроваться во избежание атак посылки управляющих терминальных символов.
Метод аутентификации с использованием открытого ключа: publickey
Единственным обязательным методом аутентификации является аутентификация с использованием открытого ключа. Все реализации должны поддерживать этот метод. Однако не все пользователи имеют открытые ключи, и большинство локальных политик, вероятно, не будут требовать в ближайшем будущем обязательной аутентификации с использованием открытого ключа.
При использовании данного метода посылается подпись, созданная закрытым ключом пользователя. Сервер должен убедиться, что открытый ключ данного пользователя является действительным, и проверить, что подпись правильна. Если оба этих условия выполняются, запрос аутентификации должен считаться выполненным; в противном случае он должен быть отвергнут. Заметим, что сервер может потребовать дополнительные аутентификации после успешного завершения данной аутентификации.
Закрытые ключи на хосте клиента часто хранятся в зашифрованном виде, и пользователь должен ввести парольную фразу перед созданием подписи. Операция подписывания означает достаточно большую вычислительную нагрузку. Чтобы избежать лишних вычислений и взаимодействия с пользователем, применяется следующее сообщение для запроса, может ли приниматься аутентификация с использованием ключа.
SSH_MSG_USERAUTH_REQUEST
имя пользователя
сервис
"publickey"
FALSE
имя алгоритма открытого ключа
public key blob
Алгоритмы открытого ключа определены в спецификации транспортного уровня. Public key blob может содержать сертификаты.
Любой алгоритм открытого ключа из данного списка может использоваться для аутентификации. Подобный список не является обязательным при переговорах об обмене ключа, но он влияет на то, для каких алгоритмов сервер имеет открытый ключ. Если сервер не поддерживает некоторый алгоритм, он должен просто отвергнуть запрос.
Сервер должен ответить на данное сообщение либо SSH_MSG_USERAUTH_FAILURE, либо
SSH_MSG_USERAUTH_PK_OK
имя алгоритма открытого ключа из запроса
public key blob из запроса
Для того чтобы реально пройти аутентификацию, клиент должен затем послать подпись, созданную с использованием своего закрытого ключа. Клиент может послать подпись непосредственно, без начальной проверки, принимаем ли ключ. Подпись посылается в следующем пакете:
SSH_MSG_USERAUTH_REQUEST
имя пользователя
сервис
"publickey"
TRUE
имя алгоритма открытого ключа
открытый ключ, используемый для аутентификации
подпись
Подпись осуществляется для данных в следующем порядке:

  • Идентификатор сессии;
  • Содержимое пакета без подписи.

Когда сервер получает данное сообщение, он должен убедиться, что предложенный ключ принимается для аутентификации, и после этого проверить корректность подписи.
Если обе проверки проходят, то данный метод считается успешным. Сервер может потребовать дополнительной аутентификации. Сервер должен ответить сообщением SSH_MSG_USERAUTH_SUCCESS, если больше никаких аутентификаций не требуется, или сообщением SSH_MSG_USERAUTH_FAILURE, если проверки не прошли или необходимы дополнительные аутентификации.
Метод аутентификации с использованием пароля: password
При аутентификации с использованием пароля посылаются следующие пакеты. Сервер может потребовать от пользователя изменить пароль. Все реализации должны поддерживать аутентификацию паролем.
SSH_MSG_USERAUTH_REQUEST
имя пользователя
сервис
"password"
FALSE
незашифрованый пароль
Для пароля применяется кодировка ISO-10646 UTF-8. Сервер сам решает, как интерпретировать пароль и как проверять его законность в базе данных паролей. Однако если пользователь вводит пароль в некоторой другой кодировке, клиентское ПО должно перед пересылкой преобразовать пароль в кодировку ISO-10646 UTF-8; сервер должен преобразовать пароль в кодировку, используемую в данной системе для хранения паролей.
Пароль передается в пакете в незашифрованном виде, но весь пакет шифруется на транспортном уровне, тем самым пароль защищен от просматривания и модификации. И сервер, и клиент должны проверять, обеспечивает ли нижний транспортный уровень конфиденциальность, т.е. используется ли шифрование. Если конфиденциальность не обеспечивается (none шифратор), аутентификация паролем должна быть запрещена. Если нет конфиденциальности или МАС, то изменение пароля должно быть запрещено.
Обычно сервер отвечает на данное сообщение сообщением об успехе или неудачном выполнении аутентификации. Однако сервер может ответить и сообщением SSH_MSG_USERAUTH_PASSWD_CHANGEREQ.
SSH_MSG_USERAUTH_PASSWD_CHANGEREQ
приглашение (ISO-10646 UTF-8)
тег языка
В этом случае клиентское ПО должно запросить у пользователя новый пароль и послать новый запрос с использованием следующего сообщения. Клиент также может послать это сообщение вместо обычного запроса аутентификации паролем без соответствующего требования со стороны сервера.
SSH_MSG_USERAUTH_REQUEST
имя пользователя
сервис
"password"
TRUE
незашифрованный старый пароль (ISO-10646 UTF-8)
незашифрованный новый пароль (ISO-10646 UTF-8)
Сервер должен ответить на это сообщение сообщениями SSH_MSG_USERAUTH_SUCCESS, SSH_MSG_USERAUTH_FAILURE, или другим сообщением SSH_MSG_USERAUTH_PASSWD_CHAGEREQ. Эти ответы имеют следующий смысл:
SSH_MSG_USERAUTH_SUCCESS
Пароль изменен и аутентификация успешно
выполнена.
SSH_MSG_USERAUTH_FAILURE с частичным успехом
Пароль изменен, но необходимы дополнительные
аутентификации.
SSH_MSG_USERAUTH_FAILURE без частичного успеха
Пароль не изменен. Это означает, что либо изменение пароля не поддерживается, либо старый пароль – неправильный. Заметим, что если сервер уже послал SSH_MSG_USERAUTH_PASSWD_CHANGEREQ, то известно, что он поддерживает изменение пароля.
SSH_MSG_USERAUTH_CHANGEREQ
Пароль не изменен, потому что новый пароль не принимается, например, слишком прост для разгадывания.
Метод аутентификации на основе адреса хоста: hostbased
Некоторые серверы могут разрешить аутентификацию на основе адреса хоста, с которого вошел пользователь, или на основании имени пользователя на удаленном хосте. Хотя такая форма аутентификации не должна быть приемлемой для серверов, требующих высокой степени безопасности, это может оказаться очень удобно во многих окружениях. Данная форма аутентификации не является обязательной.
Клиент запрашивает данную форму аутентификации, посылая сообщение, аналогично UNIX способам аутентификации rhosts и hosts.equiv. Отличие от этих способов аутентификации состоит в том, что идентификация хоста клиента выполняется более строго.
Данный метод выполняется следующим образом: клиент посылает подпись, созданную закрытым ключом хоста клиента, которую сервер проверяет с помощью открытого ключа хоста клиента.
SSH_MSG_USERAUTH_REQUEST
имя пользователя
сервис
"hostbased"
алгоритм открытого ключа для ключа хоста
открытый ключ хоста и сертификаты для
клиента хоста
имя хоста клиента (FQDN; US-ASCII)
имя пользователя клиента на удаленном хосте
подпись
Имена алгоритмов открытого ключа определены в спецификации транспортного уровня. «Открытый ключ хоста клиента» может включать сертификаты.
Подпись закрытым ключом хоста клиента выполняется для следующих данных:

  • Идентификатор сессии;
  • Пакет, содержащий информацию, без подписи.

Сервер должен убедиться, что ключ хоста клиента принадлежит клиенту хоста, указанному в сообщении, что данному пользователю на данном хосте разрешен вход, и что подпись является действительной. Сервер может игнорировать имя пользователя клиента, если он хочет провести аутентификацию только хоста клиента.
Рекомендуется предусмотреть возможность выполнения сервером дополнительных проверок того, что сетевой адрес, полученный из внешней, неизвестной сети, соответствует данному имени хоста клиента.
Обсуждение проблем безопасности
Цель данного протокола состоит в выполнении аутентификации пользователя клиента. Предполагается, что эта аутентификация выполняется поверх безопасного транспортного уровня протокола, который уже аутентифицировал сервер, установил зашифрованный канал и определил уникальный идентификатор данной сессии. Транспортный уровень должен обеспечивать безопасность для аутентификации пароля и других методов, которые имеют доступ к секретным данным.
Сервер после повторных неуспешных аутентификаций может перейти в состояние sleep, это затруднит подбор пароля.
Если транспортный уровень не обеспечивает шифрование, методы аутентификации, которые имеют доступ к секретным данным, должны быть недоступны. Если защита с помощью МАС не обеспечивается, запросы на изменение данных аутентификации (например, изменение пароля) должны быть недоступны, для того, чтобы избежать атак, связанных с модификацией текста.
Разрешается использовать несколько аутентификационных методов с различными характеристиками безопасности. Локальная политика сервера определяет, какие методы (или комбинации методов) будут применяться для конкретного пользователя. Результирующая аутентификация не сильнее, чем допустимая самая слабая комбинация методов.
Протокол соединения
Рассмотрим протокол соединения SSH. Он обеспечивает интерактивные входные сессии, удаленное выполнение команд, перенаправление ТСР/IP-соединений и перенаправление Х11-соединений. Все эти каналы мультиплексируются в единственный зашифрованный туннель. Протокол соединения SSH разработан для выполнения выше транспортного уровня SSH и протоколов аутентификации пользователя. Данный сервис называется ssh-connection.
Общие запросы
Существует несколько типов запросов, которые воздействуют на удаленный конец «глобально», независимо от канала. Примером является запрос на начало ТСР/IP, перенаправляемого на определенный порт. Все подобные запросы используют следующий формат.
SSH_MSG_GLOBAL_REQUEST
имя запроса (ограничено US-ASCII)
ждать ответа
. . .   данные, специфичные для запроса
Получатель будет отвечать на данное сообщение SSH_MSG_REQUEST_SUCCESS, SSH_MSG_REQUEST_FAILURE или некоторым специфичным для запроса сообщением, если «ждать ответа» есть TRUE.
SSH_MSG_REQUEST_SUCCESS
Если получатель не распознает или не поддерживает запрос, он просто отвечает:
SSH_MSG_REQUEST_FAILURE

Механизм канала

Все терминальные сессии, перенаправляемые соединения и т.п. являютс я каналами. Каждая из сторон может открыть канал. Несколько каналов мультиплексируются в единственное соединение.
Каналы идентифицируются номерами на каждом конце. Номера канала на разных концах могут различаться. Запросы на открытие канала содержат номер канала отправителя. Любые другие относящиеся к каналу сообщения содержат номер канала получателя.
Каналы являются потокоуправляемыми. Никакие данные не могут быть посланы по каналу до тех пор, пока полученное сообщение не укажет, что пространство окна доступно. Пространство окна определяет количество данных, которое можно передать по каналу в данный момент времени.

Открытие канала

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

SSH_MSG_CHANNEL_OPEN
тип канала (ограничение US-ASCII)
канал отправителя
начальный размер окна
максимальный размер пакета
. . .   данные, специфичные для типа канала

Тип канала представляет собой имя, определенное в архитектуре протокола. «Канал отправителя» является локальным идентификатором канала, используемым отправителем данного сообщения. «Начальный размер окна» определяет, сколько байтов данных канала может быть послано отправителем данного сообщения без регулирования размера окна. «Максимальный размер пакета» определяет максимальный размер индивидуального пакета данных, который может быть послан отправителем. Например, можно использовать небольшие пакеты для интерактивных соединений для уменьшения времени ответа по медленным каналам.
Затем удаленная сторона решает, может ли она открыть канал, и отвечает следующим сообщением

SSH_MSG_CHANNEL_OPEN_CONFIGURATION
канал получателя 
канал отправителя
начальный размер окна
максимальный размер пакета
. . . данные, специфичные для типа канала

Где «канал получателя» есть номер канала, указанный в первоначальном запросе открытия, и «канал отправителя» есть номер канала на другом конце, или

SSH_MSG_CHANNEL_OPEN_FAILURE
канал отправителя 
код причины
дополнительная текстовая информация 
    (ISO-10646 UTF-8)
тег языка

Если получатель SSH_MSG_CHANNEL_OPEN сообщения не поддерживает указанный тип канала, он отвечает SSH_MSG_OPEN_FAILURE.

Передача данных

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

            
SSH_MSG_CHANNEL_WINDOW_ADJUST
канал получателя 
байты для добавления

После получения этого сообщения получатель может послать на указанное число байтов больше, чем было разрешено посылать раньше. Размер окна при этом возрастает.
Данные передаются в сообщении следующего типа:

SSH_MSG_CHANNEL_DATA
канал получателя
данные

Максимально допустимое количество данных определяется текущим размером окна. Размер окна уменьшается на количество переданных данных. Оба участника могут игнорировать все данные, посланные после того, как разрешенное окно стало пустым.
Дополнительно некоторые каналы могут передавать несколько типов данных. Примером могут служить stderr данные из интерактивных сессий. Такие данные могут быть переданы в SSH_MSG_CHANNEL_EXTENDED сообщениях, где отдельное целое определяет тип данных. Допустимые типы и их интерпретация зависит от типа канала.

SSH_MSG_CHANNEL_EXTENDED_DATA
канал получателя
код типа данных
данные
Закрытие канала

Когда участник не собирается больше передавать данные по каналу, он должен послать:

SSH_MSG_CHANNEL_EOF
канал получателя

На данное сообщение явного ответа быть не должно, однако приложение может послать EOF на другой конец канала. Заметим, что канал после такого сообщения остается открытым , и данные могут быть посланы в другом направлении. Данное сообщение не использует пространство окна и может быть послано даже в том случае, если доступного пространства нет.
Когда один из участников хочет закрыть канал, он посылает SSH_MSG_CHANNEL_CLOSE. При получении данного сообщения участник должен послать обратно SSH_MSG_CHANNEL_CLOSE, если данное сообщение еще не было послано. Канал считается закрытым для участника, когда он и получил, и отправил SSH_MSG_CHANNEL_CLOSE, после чего участник может переиспользовать номер канала. Он может послать SSH_MSG_CHANNEL_CLOSE без отправления или получения SSH_MSG_CHANNEL_EOF.

SSH_MSG_CHANNEL_CLOSE
канал получателя

Данное сообщение не потребляет пространство окна и может быть послано даже в том случае, если доступного пространства нет.
Рекомендуется, чтобы любые данные, посланные до этого сообщения, были по возможности доставлены реальному получателю.

Запросы, специфичные для канала

Многие типы канала имеют расширения, специфичные для этого конкретного типа канала. Примером является запрос pty для интерактивной сессии.
Все запросы, специфичные для канала, имеют следующий формат.

SSH_MSG_CHANNEL_REQUEST
канал получателя
тип запроса (ограничено US-ASCII)
ждать ответа
. . .   данные, специфичные для типа

Если ждать ответа есть FALSE, то никакого ответа на запрос послано не будет. В противном случае получатель отвечает либо SSH_MSG_CHANNEL_SUCCESS, либо SSH_MSG_CHANNEL_FAILURE, либо сообщениями, специфичными для запроса. Если запрос не распознан или не поддерживается каналом, возвращается SSH_MSG_CHANNEL_FAILURE.
Данное сообщение не потребляет пространство окна и может быть послано даже в том случае, если доступного пространства окна нет. Типы запросов определяются локально для каждого типа канала.
Допускается, что клиент посылает дальнейшие сообщения без ожидания ответа на запрос.

SSH_MSG_CHANNEL_SUCCESS
канал получателя 
SSH_MSG_CHANNEL_FAILURE
канал получателя

Эти сообщения не потребляют пространства окна и могут быть посланы даже в том случае, если доступного пространства нет.

Интерактивные сессии

Сессией является удаленное выполнение программы. Программа может быть shell, приложением, командой системы или некоторой встроенной подсистемой. Она может иметь или не иметь tty, и может включать или не включать перенаправление Х11. Одновременно могут быть активны несколько сессий.

Открытие сессии

Сессия начинается с посылки следующего сообщения:

SSH_MSG_CHANNEL_OPEN
"session"
канал отправителя
начальный размер окна
максимальный размер пакета

Реализации клиента должны отвергать любые запросы открытия канала сессии, затрудняя атаки на клиента со стороны неизвестного сервера.

Запрос псевдо-терминала

Псевдо-терминал может быть открыт для сессии после посылки следующего сообщения:

SSH_MSG_CHANNEL_REQUEST
канал получателя 
"pty-req"
ждать ответа
значение переменной окружения TERM (т.е. vt100)
ширина терминала, символы (т.е. 80)
высота терминала, строки (т.е. 24)
ширина терминала, пикселы (т.е. 480)
высота терминала, пикселы (т.е. 640)
режимы кодировки терминала

Нулевая величина параметров должна игнорироваться. Значения символ/ строка перекрывает величины пикселов, если они не равны нулю.
Запросы на открытие pty клиент должен игнорировать.

Передача переменных окружения

Переменные окружения могут быть переданы в shell или команду, которые начинают выполняться. Обычно каждая ситема имеет предконфигурационные установки допустимых переменных. Так как неуправляемая установка переменных окружения может быть очень опасна, рекомендуется, чтобы реализации позволяли устанавливать только те переменые, чьи имена явно указаны в конфигурации.

SSH_MSG_CHANNEL_REQUEST
"env"
ждать ответа
имя переменной
значение переменной
Начало выполнения shell или команды

После того, как сессия установлена, на удаленном конце начинает выполняться программа. Программа может быть shell, прикладной программой или подсистемой.

SSH_MSG_CHANNEL_REQUEST
канал получателя
"shell"
ждать ответа

Данное сообщение запрашивает shell, определенный по умолчанию, который стартует на другом конце.

SSH_MSG_CHANNEL_REQUEST
канал получателя 
"exec"
ждать ответа
команда

Данное сообщение требует, чтобы сервер начал выполнение данной команды. Строка команды может содержать путь.

SSH_MSG_CHANNEL_REQUEST
канал получателя
"subsystem"
ждать ответа
имя подсистемы

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

Передача данных сессии

Передача данных сессии выполняется с использованием пакетов SSH_MSG_CHANNEL_DATA и SSH_MSG_CHANNEL_EXTENDED_DATA и механизма окна. Тип расширенных данных SSH_MSG_CHANNEL_DATA_STDERR определен для stderr-данных.

Сообщение об изменении размеров окна терминала

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

SSH_MSG_CHANNEL_REQUEST
канал получателя 
"window-change"
FALSE
ширина терминала, столбцы
высота терминала, строки
ширина терминала, пикселы
высота терминала, пикселы

На данное сообщение никакого ответа не требуется.

Управление локальным потоком

Во многих системах существует возможность определить, использует ли псевдо-терминал управление потоком ^S ^Q. (^S – останавливает вывод на экран; ^Q – перезапускает вывод на экран). Когда управление потоком разрешено, часто требуется поддерживать управление потоком на стороне клиента для быстрых ответов на запросы пользователя. Первоначально за управление потоком отвечает сервер.
Данное сообщение используется сервером для информирования клиента о том, может или не может он выполнять управление потоком, т.е. обработку ^S ^Q). Если client can do равно TRUE, клиенту разрешается выполнять управление потоком, с использованием ^S ^Q. Клиент может игнорировать это сообщение.

SSH_MSG_CHANNEL_REQUEST
канал получателя 
"xon-xoff"
FALSE
client can do

На это сообщение не посылается ответа.

Сигналы

Сигналы могут быть доставлены удаленному процессу или сервису с помощью следующего сообщения. Некоторые системы могут не поддерживать сигналы, в этом случае они должны игнорировать данное сообщение.

SSH_MSG_CHANNEL_REQUEST
канал получателя 
"signal"
FALSE
номер сигнала
Возвращаемый статус выхода

Когда команда, выполняемая на другом конце, завершается, может быть послано следующее сообщение для возврата статуса выхода команды. Возвращение статуса рекомендуется. На данное сообщение никакого подтверждения не посылается. После этого сообщения канал должен быть закрыт с SSH_MSG_CHANNEL_CLOSE.
Клиент может игнорировать данное сообщение.

SSH_MSG_CHANNEL_CLOSE
канал получателя 
"exit-status"
FALSE
статус выхода

Выполнение удаленной команды можно также прервать с помощью сигнала. Это можно сделать с помощью следующего сообщения. Нулевой статус выхода обычно означает, что команда выполнена успешно.

SSH_MSG_CHANNEL_REQUEST
канал получателя 
"exit-signal"
FALSE
номер сигнала
core dumped
сообщение об ошибке (ISO-10646 UTF-8)
тег языка

«Сообщение об ошибке» содержит дополнительное объяснение ошибки. Это сообщение может состоять из нескольких строк. Клиентское ПО может показать данное сообщение пользователю.

Перенаправление порта TCP/IP
Запрос перенаправления порта

Участнику нет необходимости посылать явный запрос перенаправления своего конца на другой порт. Однако, если он хочет иметь соединение с портом на другой стороне, перенаправленное на локальную сторону, он должен сделать явный запрос с помощью следующего сообщения:

SSH_MSG_GLOBAL_REQUEST
"tcpip-forward"
ждать ответа
адрес для связывания
номер порта для связывания

«Адрес для связывания» и «порт для связывания» определяют IP-адрес и порт, к которому будет привязан сокет. Можно фильтровать соединения на основе информации, полученной в запросе открытия.
Перенаправление на привилегированные порты следует разрешать только в том случае, если пользователь аутентифицирован как привилегированный.
Реализации клиента должны отвергать эти сообщения; обычно они посылаются только клиентом серверу.
Порт перенаправления может быть отменен следующим сообщением. Запросы открытия канала могут быть получены до получения ответа на данное сообщение.

SSH_MSG_GLOBAL_REQUEST
"cancel-tcpip-forward"
ждать ответа
адрес для связывания
номер порта для связывания

Реализации клиента должны отвергать данное сообщение; обычно оно посылается только клиентом.

Обсуждение проблем безопасности

Данный протокол выполняется на верхнем уровне SSH. Предполагается, что аутентификация пользователя и защита против атак сетевого уровня обеспечивается протоколами нижнего уровня.
Данный протокол может использоваться для выполнения команд на удаленных машинах. Протокол также позволяет серверу выполнять команды на машине клиента. Реализации могут не допускать этого для предотвращения атак со стороны машины сервера на машину клиента.
Порты перенаправления могут потенциально допускать проникновение сквозь внешние границы безопасности, такие как firewalls.
Так как данный протокол обычно выполняется внутри зашифрованного туннеля, firewalls не имеют возможности просматривать трафик.

 

 
На главную | Содержание | < Назад....Вперёд >
С вопросами и предложениями можно обращаться по nicivas@bk.ru. 2013 г.Яндекс.Метрика