Нетипичная причина ошибки 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.





