SSD Nodes Learn 🎉 VPS от $5.50/мес
Руководства Matt ConnorАвтор: Matt Connor

История протоколов передачи файлов: от Kermit до rsync

Узнайте, как эволюционировали протоколы передачи данных от Kermit до rsync. Разбираем, почему FTP уступил место SFTP и SSH в современных сетях и что нового в C-Kermit 11.0.506.

Почему протоколы передачи файлов постоянно менялись

Каждый протокол передачи файлов проектировался с учетом типичных сбоев своего десятилетия. Kermit исходил из того, что линия связи будет искажать байты. XMODEM и ZMODEM предполагали, что соединение медленное и оплачивается поминутно. FTP (file transfer protocol) исходил из того, что промежуточная сеть работает корректно. SSH исходил из того, что сеть враждебна. Это последнее допущение оказалось верным, поэтому сегодня на VPS вы получаете SFTP и rsync поверх SSH и практически ничего больше.

Сейчас есть повод взглянуть на это. Релиз C-Kermit 11.0.506 состоялся 3 августа 2026 года. Это первый стабильный релиз после C-Kermit 9.0.302, вышедшего 20 августа 2011 года, а сам протокол был разработан в мае 1981 года. Сорок пять лет — достаточный срок, чтобы увидеть, как целая категория технологий была создана, стандартизирована, скомпрометирована сетью, в которой работала, а затем поглощена SSH.

Kermit, 1981: разработано для каналов связи, которые поглощают байты

Протокол Kermit был создан в мае 1981 года в вычислительном центре Колумбийского университета Фрэнком да Крузом и Биллом Кэтчингсом. Название было взято в честь лягушонка Кермита. По словам да Круза, на стене висел календарь с персонажами «Маппет-шоу», пока группа пыталась придумать название; никто не ожидал, что проект получит такое распространение.

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

Поэтому при проектировании эти ограничения были приняты буквально. История проекта Kermit перечисляет их:

  • короткие пакеты, так как большинство мейнфреймов не могли принимать длинные потоки входящих данных от терминала;
  • полудуплексный режим с ожиданием подтверждения (stop-and-wait), так как мейнфреймы IBM не поддерживали полнодуплексную связь;
  • кодирование управляющих и 8-битных символов в печатные символы, так как ни те, ни другие не могли пройти через терминальный драйвер мейнфрейма;
  • контрольная сумма для каждого пакета, на которую отвечает получатель, чтобы повреждение пакета приводило к повторной передаче только этого пакета, а не всего файла.

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

Другое необычное свойство Kermit — его охват. Протокол XMODEM перемещал файл между двумя машинами, которые уже «договорились» о том, что такое файл. Kermit был написан как «наименьший общий знаменатель» для систем, которые не имели общих стандартов: с разными наборами символов, разными структурами записей и разными представлениями о том, что завершает строку текста. Именно этот мир описан в долгом пути от мейнфреймов к облачным серверам, и Kermit — это то, как выглядела интероперабельность до того, как сетевой уровень начал решать эти задачи за вас.

Колумбийский университет прекратил спонсирование проекта в 2011 году и выпустил C-Kermit под пересмотренной лицензией BSD (3-clause). Фрэнк да Круз оставался в проекте 44 года, с момента разработки в 1981 году и до 2025 года. Релиз 2026 года поддерживается проектом OpenKermit, в рамках которого Джон Гёрзен занимается модернизацией кодовой базы на C, которая старше большинства людей, читающих этот текст.

XMODEM и ZMODEM: как счета за телефон повлияли на проектирование

Уорд Кристенсен написал MODEM.ASM в 1977 году, и протокол, который он представил, получил название XMODEM. В 1978 году вместе с Рэнди Сьюссом он запустил CBBS, первую публичную доску объявлений (BBS). Кристенсен скончался 11 октября 2024 года.

XMODEM — это один из самых простых протоколов. Данные передаются блоками по 128 байт. Каждый блок содержит однобайтовую контрольную сумму — сумму 128 байт данных по модулю 256. Получатель подтверждает получение каждого блока или запрашивает его повторно. Такая структура обусловлена экономическими причинами. При использовании коммутируемых линий вы платите за время соединения, поэтому ошибка на линии должна приводить к потере одного блока, а не всей передачи целиком.

Слабость протокола кроется в этом же принципе. XMODEM ожидает подтверждения после каждых 128 байт. Чак Форсберг прямо указал на это в спецификации ZMODEM: «Короткая длина блока снижает пропускную способность при работе с системами разделения времени, сетями с коммутацией пакетов и спутниковыми каналами». Именно задержка, а не пропускная способность, губит протоколы с ожиданием подтверждения (stop-and-wait). Каждый цикл обмена данными — это простой линии, за которую вы платите.

Затем появился YMODEM, название которому дал Уорд Кристенсен в 1985 году. Его нововведением стала пакетная передача файлов. Отправитель указывает имя и размер файла перед началом передачи данных, поэтому за одну сессию можно передать несколько файлов, и получатель знает, где заканчивается каждый из них.

ZMODEM — это ответ Чака Форсберга, разработанный в компании Omen Technology. Спецификация датирована 14 октября 1988 года, и в ней указано, что «ZMODEM был разработан для общественного достояния в рамках контракта с Telenet». Telenet управляла публичной сетью передачи данных с коммутацией пакетов, и этот контракт отразился на архитектуре протокола. ZMODEM экранирует управляющие символы сети, чтобы промежуточное сетевое оборудование не интерпретировало их как команды. Он отмечает начало каждого кадра уникальной последовательностью символов, а не вычисляет границы кадра по паузам в передаче, что позволяет восстанавливаться после помех без ожидания тайм-аута. Также предусмотрена явная функция докачки: прерванная передача возобновляется с того места, где она остановилась.

Самое важное — он перестает ждать подтверждений. В самой спецификации сказано, что «ZMODEM фактически использует весь файл как окно». Отправитель передает поток данных и останавливается только в том случае, если получатель сообщает о проблеме. Это то же самое решение, которое реализовано в TCP через размер окна, но к нему пришли с другой стороны, наблюдая за простаивающим модемом.

Почему два соединения FTP так плохо устарели

Протокол FTP старше всего остального. RFC 114, «A File Transfer Protocol», датирован 16 апреля 1971 года и написан А. Бхушаном.

Важная деталь: в RFC 114 рассматривалась архитектура с двумя соединениями, но была отвергнута. Бхушан взвесил вариант «использования двух полнодуплексных каналов: одного для управляющей информации, другого для данных» и пришел к выводу: «Мы рекомендуем использовать одно полнодуплексное соединение для обмена как данными, так и управляющей информацией». Разделение произошло позже. В RFC 354 от 8 июля 1972 года указано, что «данные и файлы передаются только через соединение для данных», в то время как команды передаются по отдельному соединению Telnet. RFC 959 от октября 1985 года, авторами которого являются Постел и Рейнольдс, — это версия, которую все используют до сих пор.

RFC 959 также зафиксировал порты. Порт данных сервера по умолчанию — это «порт, соседний с портом управляющего соединения (то есть L-1)», что соответствует порту 20, если управляющее соединение использует порт 21.

Вот часть, которая не прошла проверку временем. В исходном режиме FTP сервер открывает соединение для передачи данных обратно к клиенту. Клиент, находящийся за NAT (network address translation), не имеет адреса, доступного для сервера, а клиент за межсетевым экраном не принимает входящие соединения. В результате соединение для данных не устанавливается, и передача зависает сразу после запроса списка файлов или самого файла. Решением стал режим PASV, который RFC 959 определяет как запрос к серверу «"слушать" на порту данных (отличном от порта по умолчанию) и ожидать подключения, вместо того чтобы инициировать его самостоятельно при получении команды на передачу». Сервер отвечает адресом и портом для подключения:

PASV
227 Entering Passive Mode (203,0,113,10,195,80)

Этот ответ означает хост 203.0.113.10, порт 195 умножить на 256 плюс 80, что составляет 50000. Если прочитать это еще раз, становится видна структурная проблема. Конечная точка второго соединения объявляется внутри полезной нагрузки первого. Устройство NAT или межсетевой экран не может пропустить это соединение, если оно не анализирует управляющий канал и не открывает порт, который видит в нем. В Linux поставляется вспомогательный модуль отслеживания соединений (connection tracking helper), который делает именно это. Этот модуль работает только пока управляющее соединение передается в открытом виде, поэтому использование FTP поверх TLS (transport layer security) делает «слепым» промежуточное устройство, которое делало FTP работоспособным.

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

Финал задокументирован. Firefox удалил поддержку FTP в версии 90 в июле 2021 года. Chrome удалил код FTP в версии 95 в октябре 2021 года.

rcp и r-команды: доверие на основе имени хоста

Версия 4.2BSD, выпущенная в 1983 году Калифорнийским университетом при финансовой поддержке DARPA, представила rcp, rsh и rlogin. Они создавались для университетского кампуса с Unix-машинами в одной сети, и модель аутентификации это отражает. Хост сам заявлял, какой пользователь выполняет вызов. Если /etc/hosts.equiv или файл ~/.rhosts пользователя указывали, что этот хост является доверенным, заявление принималось, и пароль не запрашивался.

Опишем механизм прямо, так как именно из-за него эти команды вышли из употребления. Доверие основывалось на адресе и заявлении. И то, и другое передается по сети в открытом виде, поэтому любой участник на пути следования пакетов может их прочитать или подделать. Эта модель была оправдана в условиях, описанных в пути от Unix к Linux, где сеть ограничивалась одним зданием. Она перестала иметь смысл, как только сетью стал интернет.

Что в rcp было реализовано удачно, так это интерфейс. Источник, назначение, готово. Не нужно открывать сессию, согласовывать режим передачи или настраивать второе соединение. Команда работает как cp, где в пути используется двоеточие. Этот интерфейс пережил свой протокол на четыре десятилетия.

SSH поглощает всю категорию

В 1995 году Тату Илонен, на тот момент исследователь Хельсинкского технологического университета, написал SSH в ответ на атаку с перехватом паролей в университетской сети. В июле 1995 года он выпустил его как свободное программное обеспечение с открытым исходным кодом. К концу того же года число пользователей оценивалось примерно в 20 000 человек в 50 странах, а в декабре 1995 года он основал компанию SSH Communications Security для продолжения разработки.

Лицензионные условия ужесточились в последующих версиях, поэтому разработчики OpenBSD создали форк последнего свободно лицензируемого релиза — ssh 1.2.12. Первичный импорт состоялся 26 сентября 1999 года, а OpenSSH 1.2.2 вышел в составе OpenBSD 2.6 1 декабря 1999 года. Этот форк является наглядным примером того, почему условия лицензий open source важны на практике, поскольку реализация SSH, которую сегодня использует почти каждый, происходит от той самой версии, лицензия которой это позволяла.

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

Из этого вышли два инструмента. scp представлял собой протокол rcp, работающий внутри SSH-сессии, поэтому он в точности унаследовал командную строку rcp. SFTP имеет другую архитектуру: это полноценный файловый протокол с листингом директорий, атрибутами файлов и произвольным доступом, передаваемый через SSH-канал. SFTP так и не стал RFC. Черновик IETF, draft-ietf-secsh-filexfer, достиг версии 13 18 июля 2006 года, после чего срок его действия истёк. OpenSSH реализует версию 3 этого черновика. Самый широко используемый протокол безопасной передачи файлов в мире — это пронумерованная ревизия заброшенного черновика, и он работает.

Устаревший протокол scp теперь также выведен из эксплуатации. В OpenSSH 8.8, выпущенном 26 сентября 2021 года, было предупреждение о том, что «в ближайшем релизе OpenSSH утилита scp(1) переключится с использования устаревшего протокола scp/rcp на SFTP по умолчанию». OpenSSH 9.0, выпущенный 8 апреля 2022 года, сделал это: «Этот релиз переключает scp(1) с использования устаревшего протокола scp/rcp на протокол SFTP по умолчанию».

Причина объясняет один технический миф. Старый протокол scp раскрывал маски удаленных имен файлов, передавая их удаленной оболочке, поэтому люди привыкли брать в двойные кавычки каждый метасимвол в удаленном пути. В примечаниях к версии 8.8 сказано, что scp поверх SFTP «больше не требует такого сложного и хрупкого экранирования». Таким образом, на современном сервере scp — это SFTP-клиент, использующий командную строку rcp. Интерфейс 1983 года сохранился. Сетевой протокол 1983 года — нет.

rsync, 1996: передача различий, а не файла

Эндрю Триджелл и Пол Маккеррас анонсировали rsync 19 июня 1996 года в Австралийском национальном университете вместе с техническим отчетом TR-CS-96-05 «Алгоритм rsync».

Все протоколы до него решали задачу перемещения файла без повреждения данных. rsync поставил вопрос иначе: какая часть этого файла уже есть у принимающей стороны? В отчете целевая среда определяется как «двунаправленный канал связи с низкой пропускной способностью и высокой задержкой», а цель — выявление «частей исходного файла, идентичных частям целевого файла», чтобы передавать только несовпадающие фрагменты.

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

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

Два аспекта поведения rsync часто вызывают удивление, и оба описаны в руководстве. Во-первых, rsync не вычисляет контрольные суммы файлов, чтобы решить, нужно ли их проверять. По умолчанию он «находит файлы, требующие передачи, с помощью алгоритма 'quick check', который проверяет изменение размера или времени последнего изменения». Файл, содержимое которого изменилось при сохранении размера и метки времени, будет пропущен. Флаг --checksum меняет это поведение и заставляет обе стороны полностью прочитать каждый файл-кандидат. Во-вторых, дельта-алгоритм по умолчанию отключен, если оба пути локальны, так как чтение и вычисление контрольных сумм двух копий на одном компьютере обходится дороже, чем простое копирование байтов. Экономия ресурсов проявляется только тогда, когда узким местом является сетевой канал.

Что на самом деле используется на VPS и почему

Коротко: SFTP для нескольких файлов, rsync поверх SSH для директории, которую вы будете копировать повторно.

Оба инструмента работают через SSH, поэтому они наследуют проверку ключей хоста и шифрование без дополнительной настройки. Это пятьдесят лет разработок, сжатых в стандартную конфигурацию. Разработчики Kermit были вынуждены исходить из того, что линия связи будет повреждать данные, поэтому они встроили контрольные суммы и повторную передачу в протокол. Сейчас это делает TCP. Кристенсен и Форсберг исходили из того, что каждый байт стоит денег, поэтому они реализовали докачку и потоковую передачу. Сейчас дельта-алгоритм rsync делает это лучше. Авторы FTP предполагали наличие сети из сотрудничающих узлов, и это единственное из тех предположений, которое оказалось ложным настолько, что никакая доработка протокола не смогла бы это исправить.

Что дают контрольные суммы сегодня

Термин «контрольная сумма» (checksum) исторически выполнял три разные функции, и они не взаимозаменяемы.

Попакетные контрольные суммы в протоколах Kermit и XMODEM обнаруживали повреждения данных при передаче по линии связи. Сегодня эту задачу решают контрольная сумма TCP и механизмы коррекции ошибок на канальном уровне, поэтому современные инструменты передачи данных не требуют от вас участия в этом процессе.

Блочные контрольные суммы в rsync не отвечают на вопрос «верны ли эти данные». Они отвечают на вопрос «есть ли у вас уже этот блок». В данном контексте надежная контрольная сумма — это ключ поиска, а не подтверждение происхождения файла.

Третья функция — единственная, которая по-прежнему остается вашей зоной ответственности. Опубликованная контрольная сумма для файла релиза отвечает на вопрос, на который TLS ответить не может. TLS гарантирует, что вы установили соединение с нужным сервером. Он не гарантирует, что на этом сервере лежал именно тот файл, который был нужен, и он никак не защищает файл, полученный с зеркала. Именно поэтому контрольные суммы и цифровые подписи релизов по-прежнему стоят потраченных на них 30 секунд, а эту привычку легко выработать: проверяйте контрольную сумму каждого скачиваемого файла перед установкой.

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

FAQ

Безопасно ли до сих пор использовать FTP на VPS?

Нет. Обычный FTP передает учетные данные и содержимое файлов в открытом виде, поэтому любой участник сети на пути следования трафика может их перехватить. Кроме того, работа FTP зависит от межсетевого экрана, который должен анализировать управляющий канал, что становится невозможным при шифровании этого канала с помощью TLS. Браузеры уже отказались от поддержки FTP: Firefox удалил её в версии 90 в июле 2021 года, а Chrome — в версии 95 в октябре 2021 года. Используйте SFTP поверх SSH: для него требуется только один порт, и он не нуждается в промежуточных устройствах, понимающих протокол.

Зачем FTP вообще нужен пассивный режим?

Потому что в исходном режиме FTP сервер сам инициирует соединение для передачи данных в сторону клиента. Согласно RFC 959, портом данных по умолчанию для сервера является «порт, соседний с портом управляющего соединения (то есть L-1)», поэтому при использовании порта 21 для управления используется порт 20. Клиент, находящийся за NAT (network address translation), не имеет адреса, доступного для сервера, поэтому соединение не устанавливается, и передача зависает. Режим PASV меняет направление: сервер начинает слушать порт и отвечает клиенту адресом и портом в сообщении 227 Entering Passive Mode, к которому клиент подключается самостоятельно.

Использует ли scp до сих пор собственный протокол?

Нет, начиная с OpenSSH 9.0, выпущенного 8 апреля 2022 года, который «переключает scp(1) с использования устаревшего протокола scp/rcp на протокол SFTP по умолчанию». Об этом изменении было объявлено в OpenSSH 8.8 в сентябре 2021 года. Заметное отличие заключается в обработке кавычек. Старый протокол раскрывал удаленные маски (wildcards), передавая их удаленной оболочке, а протокол на базе SFTP этого не делает. Поэтому пути, которые зависели от раскрытия оболочкой, теперь ведут себя иначе.

В каких случаях rsync лучше, чем scp для VPS?

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

Почему Kermit кодировал файлы как печатный текст, а не передавал «сырые» байты?

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