SSD Nodes Learn 🎉 VPS від $5.50/міс
Посібники Matt ConnorВід Matt Connor

Протоколи передавання файлів: від Kermit до rsync

Kermit виповнилося 45 років, а C-Kermit 11.0.506 отримав перший стабільний випуск за 15 років. Як FTP, SFTP і rsync змінили передавання файлів.

Чому протоколи передавання файлів постійно змінювалися

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

Зараз є підстава звернутися до цієї теми. C-Kermit 11.0.506 було випущено 3 August 2026. Це перший випуск не в статусі beta після C-Kermit 9.0.302 від 20 August 2011, а реалізований у ньому протокол розробили в May 1981. Сорока п’яти років достатньо, щоб побачити, як ціла категорія виникла, була стандартизована, зламалася через мережу, у якій працювала, а потім увійшла до складу SSH.

Kermit, 1981: створений для лінії, яка поглинає ваші байти

Kermit створили в травні 1981 року у Computer Center Колумбійського університету Frank da Cruz і Bill Catchings. Назву взяли від Kermit the Frog. За словами da Cruz, коли група намагалася придумати назву, на стіні висів календар Muppets, і ніхто не очікував, що цей проєкт набуде такого поширення.

Kermit вирішував не проблему швидкості. Канал між терміналом і мейнфреймом не був потоком для довільних байтів. Це був символьний пристрій із власними обмеженнями. Він міг працювати в режимі 7-bit. Він міг бути напівдуплексним. Він міг поглинати керівні символи або виконувати один із них як команду. Передавання двійкового файлу без змін не працювало.

Тому під час проєктування буквально врахували ці обмеження. Власна історія Kermit Project наводить такі вимоги:

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

Третій пункт є найцікавішим. Kermit передає текстобезпечне кодування вашого файлу, а не сам файл. Керівний байт перетворюється на символ-префікс і друкований символ, а байт із установленим старшим бітом можна закодувати так само для 7-бітового каналу. Будь-який проміжний компонент, який розуміє лише друкований текст, отримує друкований текст. Недолік — розмір: двійковий файл збільшується під час передавання. Для інтерфейсу мейнфрейма, який інакше повністю пошкодив би передавання, це був правильний компроміс.

Інша незвична властивість Kermit — сфера його застосування. XMODEM переміщував файл між двома машинами, які вже однаково розуміли, що таке файл. Kermit створили як спільний знаменник для систем, які не мали узгодженого формату: з різними наборами символів, різними структурами записів і різними правилами визначення кінця текстового рядка. Це світ, описаний у довгому переході від мейнфреймів до cloud servers, а Kermit — приклад того, як виглядала сумісність до того, як мережевий рівень почав забезпечувати її замість вас.

Columbia припинила спонсорування проєкту в 2011 році та випустила C-Kermit за переглянутою 3-clause BSD licence. Frank da Cruz працював над проєктом 44 роки — від проєктування у 1981 році до 2025 року. Реліз 2026 року підтримує OpenKermit project, а John Goerzen займається модернізацією кодової бази C, старшої за більшість людей, які читають цей текст.

XMODEM і ZMODEM: коли вартість телефонного зв’язку визначала дизайн

Ward Christensen написав MODEM.ASM у 1977 році, а протокол, який він запровадив, отримав назву XMODEM. У 1978 році він разом із Randy Suess запустив CBBS — першу публічну bulletin board system. Christensen помер 11 October 2024 року.

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

Слабке місце міститься в тому самому описі. XMODEM очікує підтвердження після кожних 128 байтів. Chuck Forsberg прямо зазначив це у специфікації ZMODEM: «Мала довжина блока знижує пропускну здатність у разі використання систем із розподілом часу, мереж із комутацією пакетів і супутникових каналів». Передавання із зупинкою та очікуванням втрачає ефективність через затримку, а не через пропускну здатність. Кожен цикл передавання й підтвердження залишає лінію бездіяльною, хоча оплата за неї триває.

Потім з’явився YMODEM, а Ward Christensen придумав цю назву в 1985 році. Його внеском була пакетна передача. Перед початком передавання даних відправник повідомляє ім’я та розмір файла. Тому кілька файлів можна передати в межах одного сеансу, а отримувач знає, де закінчується кожен із них.

ZMODEM — відповідь Chuck Forsberg, написана в Omen Technology. Специфікація має редакцію від 14 October 1988 року та зазначає: «ZMODEM було розроблено для public domain за контрактом із Telenet». Telenet керувала публічною мережею передавання даних із комутацією пакетів, і цей контракт позначився на конструкції протоколу. ZMODEM екранує керівні символи мережі, щоб проміжна мережа з комутацією пакетів не обробляла їх. Початок кожного кадру позначається унікальною послідовністю символів, а не визначається за періодом тиші. Тому протокол відновлюється після шуму без очікування завершення тайм-ауту. Він також має явне відновлення передавання, тому перерване передавання продовжується з місця зупинки.

Найважливіше — протокол припиняє постійно очікувати. У власному описі специфікації сказано, що «ZMODEM фактично використовує весь файл як вікно». Відправник безперервно передає дані й зупиняється лише тоді, коли отримувач повідомляє про проблему. Це та сама ідея, яку TCP реалізує через своє вікно, але до неї дійшли з іншого боку — спостерігаючи, як modem простоює.

Чому двоз’єднувальна модель FTP так швидко застаріла

FTP старший за всі ці технології. RFC 114, «A File Transfer Protocol», датовано 16 квітня 1971 року; його автор — A. Bhushan.

Варто знати, що RFC 114 розглядав модель із двома з’єднаннями, але відкинув її. Bhushan зважував варіант «використовувати два повнодуплексні канали: один для керувальної інформації, інший для даних», а потім дійшов висновку: «Ми рекомендуємо використовувати одне повнодуплексне з’єднання для обміну даними та керувальною інформацією». Розділення з’явилося пізніше. У RFC 354 від 8 липня 1972 року зазначено, що «дані та файли передаються лише через з’єднання даних», а команди передаються через окреме Telnet-з’єднання. RFC 959 від жовтня 1985 року, авторами якого є Postel і Reynolds, — це версія, яку досі реалізують усі.

RFC 959 також визначив порти. Стандартний порт даних сервера — «порт поруч із портом керувального з’єднання (тобто L-1)». Якщо керувальне з’єднання використовує порт 21, портом даних є 20.

Проблема полягала в тому, що ця модель не витримала практичного використання. В оригінальному режимі FTP сервер відкриває з’єднання даних назад до клієнта. Клієнт за NAT (перетворенням мережевих адрес) не має адреси, до якої сервер може підключитися. Клієнт за firewall не приймає вхідні з’єднання. Тому з’єднання даних не встановлюється, а передавання зависає одразу після запиту списку або файлу. Рішенням стала команда PASV. RFC 959 визначає її як запит до сервера «прослуховувати порт даних (який не є його стандартним портом даних) і чекати на з’єднання, а не ініціювати його після отримання команди передавання». Сервер повертає адресу та порт для підключення:

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

Ця відповідь означає хост 203.0.113.10 і порт 195, помножений на 256, плюс 80, тобто 50000. Якщо перечитати її, структурна проблема стає очевидною. Кінцева точка другого з’єднання оголошується всередині даних першого з’єднання. NAT-пристрій або firewall не може пропустити це з’єднання, якщо не аналізує керувальний канал і не відкриває порт, указаний у ньому. Linux постачається з connection tracking helper, який робить саме це. Helper працює лише тоді, коли керувальне з’єднання передається у відкритому тексті. Тому шифрування FTP за допомогою TLS (transport layer security) робить middlebox, який забезпечував роботу FTP, нездатним аналізувати цей канал.

Ось головний висновок щодо FTP. Цей протокол зробив мережу учасником протоколу. Протокол, якому потрібно, щоб мережа його розуміла, не може працювати в мережі, яка більше йому не довіряє.

Фінал зафіксований у документації. Firefox вилучив підтримку FTP у версії 90 в липні 2021 року. Chrome вилучив код FTP у Chrome 95 у жовтні 2021 року.

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

4.2BSD, випущена в 1983 році Berkeley за фінансування DARPA, принесла rcp, rsh і rlogin. Ці команди створювалися для кампусу з Unix-машинами в одній мережі, і модель автентифікації це відображає. Хост повідомляв, від імені якого користувача виконується запит. Якщо /etc/hosts.equiv або ~/.rhosts користувача вказував, що цьому хосту довіряють, твердження приймалося, і пароль не запитувався.

Механізм потрібно описати прямо, оскільки саме через нього ці команди більше не використовують. Довіра ґрунтувалася на адресі та твердженні. Обидва передавалися мережею у відкритому вигляді, тому будь-хто на шляху міг їх прочитати, а також підробити. Така модель мала сенс у середовищі, описаному в переході від Unix до Linux, де мережею була одна будівля. Вона втратила сенс одразу, коли мережею став інтернет.

Сильним боком rcp був інтерфейс. Джерело, призначення — готово. Не потрібно відкривати сеанс, узгоджувати режим передавання або встановлювати друге з’єднання. Команда працює як cp, але зі знаком двокрапки в шляху. Цей інтерфейс пережив свій протокол на чотири десятиліття.

SSH охоплює всю категорію

У 1995 році Tatu Ylonen, який тоді працював дослідником у Helsinki University of Technology, написав SSH у відповідь на атаку з перехопленням паролів у мережі університету. У липні 1995 року він випустив його як вільне програмне забезпечення з вихідним кодом. До кінця того року кількість користувачів оцінювали приблизно в 20,000 у 50 країнах, а в грудні 1995 року він заснував SSH Communications Security, щоб продовжити розробку.

У пізніших версіях умови ліцензії стали суворішими, тому розробники OpenBSD відгалузили останній випуск із вільною ліцензією — ssh 1.2.12. Початковий імпорт відбувся 26 September 1999, а OpenSSH 1.2.2 вийшов разом з OpenBSD 2.6 1 December 1999. Це відгалуження є стислим прикладом того, чому умови ліцензій open source важливі на практиці, оскільки реалізація SSH, яку сьогодні використовує майже кожен, походить із версії, ліцензія якої все ще це дозволяла.

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

На його основі з’явилися два інструменти. scp був мережевим протоколом rcp, який працював усередині сеансу SSH, тому він точно успадкував командний рядок rcp. SFTP має іншу архітектуру: це повноцінний протокол передавання файлів зі списками каталогів, атрибутами файлів і довільним доступом, який працює через канал SSH. SFTP ніколи не став RFC. Проєкт IETF draft-ietf-secsh-filexfer досяг версії 13 18 July 2006 року, після чого строк його дії завершився. OpenSSH реалізує версію 3 цього проєкту. Найпоширеніший у світі захищений протокол передавання файлів є нумерованою редакцією покинутого проєкту, і він працює.

Застарілий протокол scp також виведено з експлуатації. OpenSSH 8.8, випущений 26 September 2021 року, попереджав: "у найближчому випуску OpenSSH scp(1) перейде від використання застарілого протоколу scp/rcp до використання SFTP за замовчуванням". OpenSSH 9.0, випущений 8 April 2022 року, реалізував цю зміну: "Цей випуск переводить scp(1) від використання застарілого протоколу scp/rcp до використання протоколу SFTP за замовчуванням".

Причина пояснює одну поширену особливість. Старий протокол scp розгортав шаблони підстановки у віддалених іменах файлів, передаючи їх віддаленій оболонці. Саме тому користувачів привчили брати в подвійні лапки кожен метасимвол у віддаленому шляху. У примітках до версії 8.8 зазначено, що scp через SFTP "більше не потребує цього складного та ненадійного екранування". Отже, на сучасному сервері scp є клієнтом SFTP, який використовує командний рядок rcp. Інтерфейс 1983 року зберігся. Мережевий протокол 1983 року — ні.

rsync, 1996: передавати різницю, а не файл

Andrew Tridgell і Paul Mackerras оголосили про rsync 19 June 1996 в Australian National University разом із технічним звітом TR-CS-96-05 «The rsync algorithm».

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

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

Якщо вставити один байт на початку великого файлу, простий інструмент пошуку різниці має передати весь файл, оскільки зміщуються всі позиції. Рухоме вікно знаходить ті самі блоки за новими позиціями, тому rsync передає один байт і службові дані. Саме тому rsync досі залишається правильним інструментом для каталогу, який потрібно копіювати більше одного разу.

Дві особливості регулярно дивують користувачів, і обидві описані в посібнику. По-перше, rsync не обчислює контрольні суми файлів, щоб вирішити, чи потрібно їх перевіряти. За замовчуванням він «знаходить файли, які потрібно передати, за допомогою алгоритму “швидкої перевірки”, що шукає файли зі зміненим розміром або часом останньої модифікації». Файл, вміст якого змінився, але розмір і часова позначка залишилися такими самими, буде пропущено. --checksum змінює цю поведінку та змушує обидві сторони повністю прочитати кожен файл-кандидат. По-друге, алгоритм пошуку різниці за замовчуванням вимкнено, коли обидва шляхи є локальними, оскільки читання й обчислення контрольних сум для двох копій на одному комп’ютері коштує дорожче, ніж копіювання байтів. Економія виникає лише тоді, коли повільною частиною є канал зв’язку.

Що насправді використовують на VPS і чому

Коротко: SFTP — для кількох файлів, rsync через SSH — для каталогу, який ви копіюватимете повторно.

Обидва протоколи працюють через SSH, тому успадковують перевірку ключа хоста та шифрування без додаткового налаштування. Це п’ятдесят років роботи, стиснені в стандартній конфігурації. Розробники Kermit мали припускати, що лінія зв’язку пошкоджуватиме дані, тому вбудували в протокол контрольні суми та повторне передавання. Тепер це робить TCP. Christensen і Forsberg мали припускати, що кожен байт коштує грошей, тому реалізували відновлення передавання та потокову передачу. Тепер це робить алгоритм дельта-синхронізації rsync, причому ефективніше. Автори FTP припускали наявність мережі взаємодіючих хостів. І лише це припущення виявилося хибним так, що його не могла виправити жодна кількість доопрацювань протоколу.

Яку користь досі дають контрольні суми

Слово «контрольна сума» виконувало в цій історії три різні функції, і їх не можна взаємозамінювати.

Контрольні суми для кожного пакета в Kermit і XMODEM виявляли пошкодження під час передавання мережею. Сьогодні це забезпечують контрольна сума TCP та виправлення помилок на канальному рівні, тому жоден сучасний інструмент передавання не змушує вас про це думати.

Блокові контрольні суми в rsync не відповідають на запитання «чи правильні ці дані». Вони відповідають на запитання «чи є у вас уже цей блок». Надійна контрольна сума в цьому разі є ключем пошуку, а не твердженням про походження файлу.

Третя функція досі залишається на вашій відповідальності. Опублікована контрольна сума для файлу випуску відповідає на запитання, на яке TLS відповісти не може. TLS підтверджує, що ви з’єдналися з правильним сервером. Він не підтверджує, що на цьому сервері розміщено правильний файл, і не захищає файл, завантажений із дзеркала. Саме тому контрольні суми та підписи файлів випуску досі варті цих тридцяти секунд, а сформувати таку звичку легко: перевіряйте контрольну суму кожного завантаженого файлу, який встановлюєте.

Усе інше в цій історії було вирішено нижчим рівнем. Ця проблема залишилася, тому що вона ніколи не була мережевою.

FAQ

Чи безпечно й далі використовувати FTP на VPS?

Ні. Звичайний FTP передає облікові дані та вміст файлів у відкритому вигляді, тому будь-хто на шляху передавання може прочитати і те, і інше. Він також залежить від брандмауера, який аналізує канал керування. Це стає неможливим, щойно канал керування шифрується за допомогою TLS. Браузери вже відмовилися від його підтримки: Firefox вилучив підтримку FTP у версії 90 у липні 2021 року, а Chrome вилучив відповідний код у версії 95 у жовтні 2021 року. Використовуйте SFTP через SSH. Для нього потрібен один порт і не потрібен міжмережевий посередник із підтримкою конкретного протоколу.

Навіщо FTP взагалі потрібен пасивний режим?

Тому що в початковому режимі FTP сервер відкриває з’єднання для передавання даних назад до клієнта. RFC 959 визначає стандартний порт даних сервера як «порт, сусідній із портом з’єднання керування (тобто L-1)», тобто порт 20, якщо для керування використовується порт 21. Клієнт за NAT (трансляцією мережевих адрес) не має адреси, до якої сервер може підключитися. Тому це з’єднання не встановлюється, і передавання зависає. PASV змінює напрямок: сервер починає прослуховувати порт і повертає адресу та порт у відповіді 227 Entering Passive Mode, щоб клієнт міг підключитися до них.

Чи використовує scp власний протокол?

Ні, починаючи з OpenSSH 9.0, випущеного 8 квітня 2022 року. У цій версії «scp(1) переходить від застарілого протоколу scp/rcp до протоколу SFTP за замовчуванням». OpenSSH 8.8 оголосив про цю зміну у вересні 2021 року. Видима відмінність стосується екранування. Старий протокол розгортав віддалені шаблони підстановки, передаючи їх віддаленій оболонці. Протокол на основі SFTP цього не робить. Тому шляхи, які залежали від такого розгортання оболонкою, тепер обробляються інакше.

Коли rsync кращий за scp для VPS?

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

Чому Kermit кодував файли як текст для друку, а не передавав необроблені байти?

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

#history#kermit#ftp#rsync#sftp#ssh