Кратко

  • SSH_MSG_CHANNEL_WINDOW_ADJUST разрешает передать по каналу SSH дополнительные байты, но не подтверждает, что удалённая команда их обработала или завершилась.
  • Ответ на exec, необязательный статус выхода, EOF и двустороннее закрытие относятся к разным этапам и не заменяют устойчивый результат приложения.
  • Для операций с последствиями нужны идемпотентный идентификатор и запрос результата, переживающие сеанс SSH, чтобы обрыв не заставлял повторять действие вслепую.

Четыре состояния под одной зелёной отметкой

Пользователю удалённого запуска нужен один ответ: сработало ли? Протокол отвечает на несколько более узких вопросов. Открылся ли канал? Принял ли сервер запрос exec? Может ли отправитель передать больше данных? Сообщил ли процесс статус выхода? Закрыли ли обе стороны канал?

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

Надёжная модель хранит четыре состояния отдельно: приём запроса, лимит потока канала, завершение процесса и долговечный результат приложения. Первые три наблюдаемы через SSH. Четвёртое определяет удалённая программа.

Что на самом деле даёт окно

Раздел 5.2 RFC 4254 задаёт окно в байтах. Оно ограничивает объём, который другая сторона может послать до ожидания корректировки. SSH_MSG_CHANNEL_WINDOW_ADJUST содержит номер канала получателя и прибавляемое число байтов. Обычные и расширенные данные, включая stderr, расходуют один лимит.

Это договор об управлении потоком. Его поля описывают канал и количество, но не идентификатор команды, состояние приложения, запись на диск или итог. Стандарт не связывает увеличение окна с единственным внутренним событием; устройство буферов и планирование остаются выбором реализации.

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

Приём запуска не равен завершению

У запросов канала есть отдельный ответ. При want reply получатель возвращает успех, отказ или специальное продолжение. exec просит сервер начать выполнение команды, и RFC рекомендует запросить и проверить ответ.

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

Когда библиотека называет этот момент «success», не показывая уровень протокола, имя звучит окончательнее содержания. Операционный журнал должен указывать, что именно подтверждено, и связывать событие с сеансом, каналом и отпечатком команды.

Статус выхода сильнее, но тоже ограничен

RFC 4254 определяет exit-status для момента после завершения удалённой команды. Возвращать его рекомендуется, но не требуется; подтверждение на него не посылается, а клиент может его игнорировать. Ноль «обычно» означает успешное завершение.

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

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

Закрытие канала не устраняет неизвестность

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

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

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

Гарантии безопасности не меняют предмет

RFC 4251 делит SSH на транспорт, аутентификацию пользователя и соединение. RFC 4253 обеспечивает шифрование, аутентификацию сервера и целостность; RFC 4252 аутентифицирует пользователя клиента; протокол соединения мультиплексирует логические каналы.

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

Идентификатор, живущий дольше сеанса

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

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

Начинать следует с точных названий: корректировка окна — лимит байтов, успех запроса — приём, статус выхода — свидетельство процесса, close — конец канала. Завершение бизнеса должен подтвердить сам бизнес-процесс.

Источники