Нетипичная причина ошибки code 12 при отправке файлов на VPS через rsync

Задача

Обеспечить загрузку на VPS собираемого локально Docker-образа с помощью gulp-rsync.

Код Gulp таска (TypeScript)

Поскольку на приобретённом VPS недостаточно памяти для Docker-образа, то я решил начать с загрузки одного js-файла. Полагаю, если он будет загружаться нормально, то при наличии достаточной памяти и Docker-образ загрузится без проблем.

import Gulp from "gulp";
import GulpRSync from "gulp-rsync";

Gulp.task(
  "Deploy",
  (): NodeJS.ReadWriteStream => Gulp.src("03-ProductionBuild/BackEndEntryPoint.js").
      pipe(GulpRSync({
        root: "03-ProductionBuild/",
        hostname: "160.251.43.156",
        port: "22",
        username: "non_root_admin",
        destination: "/var/www/myproject.com"
      }))
);

Имя папки с проектом я спрятал под myproject.com, но так как текущий VPS приобретён для учебных целей, то IP-адрес прятать не буду.

Ошибка

После выполнения приведённого выше gulp-таска будет запрошен пароль для учётной записи non_root_admin. После его ввода возникнет ошибка:

gulp-rsync: rsync error: error in rsync protocol data stream (code 12)

Тут сразу возникает вопрос: какова рациональная причина, по которой создатели rsync дают такое "понятное и подробное" объяснение причины ошибки? Если поискать значение code 12, то там будет целая группа разнородных причин. Что же, в рамках долга собственных усилий я обязан отсечь типичные причины.

Отсечение типичных причин

Указан неверный адрес соединения

При вводе правильного пароля для учётной записи "non_root_admin" (как и положено, я создал эту учётную запись с пониженными привилегиями для повседневного пользователя),

введите сюда описание изображения

ошибка будет такая:

Message:
    Error: rsync exited with code 12
    at ChildProcess.<anonymous> (D:\IntelliJ IDEA\InHouseDevelopment\example.com\node_modules\gulp-rsync\rsync.js:121:17)      
    at ChildProcess.emit (node:events:390:28)
    at ChildProcess.emit (node:domain:537:15)
    at maybeClose (node:internal/child_process:1064:16)
    at Process.ChildProcess._handle.onexit (node:internal/child_process:301:5)
    at Process.callbackTrampoline (node:internal/async_hooks:130:17)

Теперь попробую намеренно ввести неправильный пароль. Ошибка станет другой:

[email protected]'s password: [18:36:47] gulp-rsync: Permission denied, please try again. 

Таким образом, как минимум до успешной аутентификации всё идёт хорошо.

Напоследок, выполню обычный вход через SSH:

введите сюда описание изображения

Успешно залогинился.

На VPS не установлен rsync

На VPS у меня новейшая на момент задавания вопроса Ubuntu 20.04. Проверяю версию предустановленной утилиты rsync:

введите сюда описание изображения

Недостаточно памяти

Поначалу оно так и было: для тренировки я купил VPS на 512 мегабайт, но как-то не учёл, Hello-world-приложение на NodeJS порядка 90 килобайт будет весить в Docker-образе около 900 мегабайт. Но потом, как я уже говорил, в рамках этого упражнения я ограничился точкой входа для серверной части BackEndEntryPoint.js.

На данный момент мало что понимаю в табличных данных команды df -h, но этот скриншот послужит доказательством, что по крайней мере на загрузку 90-килобайтового файла памяти должно хватить:

введите сюда описание изображения

Отсутствуют права доступа

Согласно тому, что мне уже подсказали, на VPS должна быть целевая директория "/var/www/myproject.com". Сам я об этом не догадался, ибо думал, что rsync, будучи программой, работающей с копированием файлов и папок сама все создаст.

В общем, я эту директорию создал, причём, чтобы отсечь причину неверных прав - с правами 777. В будущем в целях безопасности нужно будет пересоздать эту директорию с меньшими правами (755?).

sudo mkdir myproject.com -p 777

Вывожу список директорий через ls -al. Созданную директорию подчеркнул красным:

введите сюда описание изображения

Даже при таких высоких правах ошибка code 12 всё равно не исчезает.

Блокирование запроса файрволлом

Что интересно, файрволл подозревают редко (не видел его в перечислениях частых причин). А ведь изначальные настройки файрволла в Ubuntu 20.04-

Output
Status: active

To                         Action      From
--                         ------      ----
OpenSSH                    ALLOW       Anywhere
OpenSSH (v6)               ALLOW       Anywhere (v6)

Вроде как это не означает, что соединение по rsync разрешено. На это же косвенно и указывает эта статья, где написано, как это соединение разрешить для конкретного IP-адреса.

sudo ufw allow from 203.0.113.103 to any port 873
                         ↑
Это не мой IP-адрес, но для примера сойдёт

Теперь статус файрволла имеет вид

введите сюда описание изображения

К сожалению, и это не изменило ситуацию.

Более подробный вывод rsync в опциями

Если в рамках эксперимента просто попытаться отправить файл через rsync, то в выводе не будет ничего нового:

PS D:\IntelliJ IDEA\InHouseDevelopment\myproject.com> rsync -a "03-ProductionBuild/BackEndEntryPoint.js" [email protected]:/var/www/myproject.com
[email protected]'s password: 
rsync: connection unexpectedly closed (0 bytes received so far) [Receiver]
rsync error: error in rsync protocol data stream (code 12) at io.c(235) [Receiver=3.1.3]
rsync: connection unexpectedly closed (0 bytes received so far) [sender]
rsync error: error in rsync protocol data stream (code 12) at io.c(228) [sender=3.2.3

Когда меня попросили выполнить ту же команду с опцией -vvv, то вывод был такой (впрочем, то же не отличающийся информативностью):

[email protected]'s password: 
rsync: connection unexpectedly closed (0 bytes received so far) [Receiver]
rsync error: error in rsync protocol data stream (code 12) at io.c(235) [Receiver=3.1.3]
[Receiver] _exit_cleanup(code=12, file=io.c, line=235): about to call exit(12)
rsync: connection unexpectedly closed (0 bytes received so far) [sender]
rsync error: error in rsync protocol data stream (code 12) at io.c(228) [sender=3.2.3]
[sender] _exit_cleanup(code=12, file=io.c, line=228): about to call exit(12)

Вывод команды "sudo ifconfig -a" на VPS

docker0: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500
        inet 172.17.0.1  netmask 255.255.0.0  broadcast 172.17.255.255
        ether 02:42:25:6e:af:f5  txqueuelen 0  (Ethernet)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 160.251.43.156  netmask 255.255.254.0  broadcast 160.251.43.255
        inet6 fe80::2:a0ff:fefb:2b9c  prefixlen 64  scopeid 0x20<link>
        ether 02:02:a0:fb:2b:9c  txqueuelen 1000  (Ethernet)
        RX packets 26904  bytes 2536794 (2.5 MB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 708  bytes 96146 (96.1 KB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 68  bytes 5564 (5.5 KB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 68  bytes 5564 (5.5 KB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

Информация о локально установленном RSync

Честно говоря, не помню как поставил его на свой Windows 10, но скорее всего через Chocolatey. Вывод rsync -V такой:

rsync  version 3.2.3  protocol version 31
Copyright (C) 1996-2020 by Andrew Tridgell, Wayne Davison, and others.
Web site: https://rsync.samba.org/
Capabilities:
    64-bit files, 64-bit inums, 64-bit timestamps, 64-bit long ints,
    socketpairs, hardlinks, no hardlink-specials, symlinks, IPv6, atimes,
    batchfiles, inplace, append, no ACLs, xattrs, optional protect-args,
    iconv, symtimes, prealloc, stop-at, no crtimes
Optimizations:
    no SIMD, asm, openssl-crypto
Checksum list:
    xxh64 (xxhash) md5 md4 none
Compress list:
    zstd lz4 zlibx zlib none

rsync comes with ABSOLUTELY NO WARRANTY.  This is free software, and you
are welcome to redistribute it under certain conditions.  See the GNU
General Public Licence for details.

Ответы (0 шт):