У меня есть машина А.
С него я могу подключиться по SSH к машине B.
Машина B может подключиться по FTP к машине C.
Я хочу загрузить файлы с C на A.
У меня нет прямого доступа из A в C.
Порт 20 и 21
✓ ✓ Управление FTP ✓ Управление FTP -
â â SSH â âвввввввввввва ***
â A ââââââºâ B â â C - с файлами â
- º Я хочу
✓ Данные FTP ✓
Случайные порты ââ
Я знаю, что на этом сайте есть миллион вопросов о SFTP.
Насколько я могу судить, это не то же самое, что SFTP.
С SFTP кажется, что SSH-сервер должен быть тем же сервером, на котором есть файлы для загрузки, что здесь не проблема.
Это правильно? Или есть способ сделать это с помощью простой команды SFTP и некоторых дополнительных аргументов?
Есть ли простые способы сделать это?
Файлы большие, а диск и память на B крошечные, поэтому, если возможно, я хотел бы передавать данные напрямую. (По сравнению с двухэтапной FTP-загрузкой на диск B.)
В общем, SSH может туннелировать что угодно. Но очевидно, что FTP использует больше, чем просто порты 20 и 21. Он использует целую кучу случайных и непредсказуемых портов, новых для каждой файловой операции. Возможный диапазон таких FTP-портов настолько велик, что с одним клиентом, который я попробовал, я не смог просто перенаправить весь диапазон с помощью SSH.
(Обратите внимание, что я пытаюсь пассивный FTP, где все сетевые подключения инициируются с клиента на сервер. В отличие от активный FTP, где C инициирует обратное соединение с B, что невозможно из-за NAT между ними.)
Я попытался написать скрипт на python, взламывая вместе Стандартная библиотека FTP и сторонний Библиотека туннелей SSH. Это довольно запутанное и дерганое решение, в результате которого я открываю новый порт для каждого нового файла, но никогда его не закрываю. Также недавнее обновление одной библиотеки нарушило некоторые зависимости, поэтому теперь скрипт не работает с последней версией этих библиотек. У меня возникает соблазн переписать решение с учетом лежащего в его основе Парамико библиотека. Но я боюсь, что это глубокая кроличья нора. Этот материал действительно неудобен. (Дайте мне знать, если вам нужно увидеть мою попытку. Я пытаюсь опустить ее, чтобы избежать проблема X/Y.)
Есть ли более простой способ сделать это туннелирование?
Я бы предпочел решение с Python, но на данный момент я достаточно отчаялся, чтобы использовать любой инструмент.