Лучший способ передачи файлов по локальной сети между двумя компьютерами Linux
Я хочу передавать файлы (музыкальную папку) между двумя компьютерами Linux. После поиска лучшего способа сделать это, я увидел, что есть много способов сделать это. Я знаю, что об этом спрашивали много, везде и всегда. Основная проблема заключается в том, что в последнее время нет четкого консенсуса по поводу одного из лучших способов сделать эту задачу в 2011 году для начинающих пользователей Linux (даже в зависимости от некоторых параметров).
Поэтому, в духе сайтов Stack Exchange, я хочу, чтобы это было связано не с моей конкретной ситуацией, а скорее с руководством для других, а также о том, как передавать файлы между двумя компьютерами Linux по локальной сети. Я думаю, что вики была бы полезна для многих.
Вот что я нашел до сих пор:
- SSH
- SSHFS
- УПП
- SFTP
- NFS
- самба
- податель
Что самое простое? Самый гибкий? Простейшее? Лучшее решение? Каковы плюсы и минусы каждого? Есть ли другие (лучшие) варианты? Каковы параметры при выборе лучшего метода (решение может зависеть от количества файлов, размера файла, простоты и гибкости, ...)?
11 ответов
В среде Linux, как для безопасности, так и для простоты использования, лучше использовать ssh. SSH, SSHFS, SCP и SFTP, как вы перечислите, - это просто разные сервисы, построенные поверх протокола SSH. SCP очень прост в использовании, он работает так же, как CP, но вы можете указать имена пользователей и компьютеров в пути. Таким образом, мы могли бы сделать CP как cp ~/music/ ~/newmusic/
, но мы могли бы так же легко сделать scp ~/music/ user@host:~/newmusic
отправить его на компьютер с именем host. Вот и все - нам не нужно ничего настраивать. Вам будет предложено ввести пароль учетной записи на другом компьютере, если у вас нет сертификата или какой-либо другой настройки аутентификации (разумеется, scp делится этими настройками с ssh).
SFTP - это инструмент, который позволяет легко выполнять множество операций в удаленной файловой системе - он работает так же, как FTP, но работает через SSH, поэтому он защищен и требует только SSH-сервера. man sftp
расскажет вам все о том, как его использовать. Я не использую SFTP просто для перемещения папки между двумя компьютерами, это более полезно, когда вам нужно выполнить много операций, например, если вы переставляете файлы на другом компьютере.
SSHFS просто расширяет SFTP до файловой системы: он позволяет вам подключить виртуальный хост к вашей файловой системе, поэтому работа с сетью происходит абсолютно прозрачно. SSHFS предназначена для полупостоянных установок, а не просто для однократной передачи файлов. Для настройки требуется больше усилий, о чем вы можете прочитать на сайте проекта.
Если вам нужно работать в среде со смешанными ОС, Samba станет вашим лучшим выбором. Windows и OS X поддерживают Samba полностью автоматически, также как и Linux, хотя иногда это сложно использовать.
Мой личный фаворит для случаев, когда безопасность не имеет значения, netcat + tar:
Чтобы отправить каталог, перейдите в каталог, содержимое которого вы хотите отправить на компьютер, выполняющий отправку, и выполните:
tar -cz . | nc -q 10 -l -p 45454
На компьютере, получающем содержимое, перейдите туда, где вы хотите, чтобы содержимое отображалось, и выполните:
nc -w 10 $REMOTE_HOST 45454 | tar -xz
замещать $REMOTE_HOST
с ip / hostname компьютера, выполняющего отправку. Вы также можете использовать другой порт вместо 45454
,
На самом деле происходит то, что "принимающий" компьютер подключается к передающему компьютеру через порт 45454 и получает содержимое каталога tar'd и gzip'd и передает его непосредственно в tar (и gzip), чтобы извлечь его в текущий каталог.
Быстрый пример (использование localhost в качестве удаленного хоста)
Компьютер 1
caspar@jumpy:~/nctest/a/mydir$ ls
file_a.txt file_b.log
caspar@jumpy:~/nctest/a/mydir$ tar -cz . | nc -q 10 -l -p 45454
Компьютер 2
caspar@jumpy:~/nctest/b$ ls
caspar@jumpy:~/nctest/b$ nc -w 10 localhost 45454 | tar -xz
caspar@jumpy:~/nctest/b$ ls
file_a.txt file_b.log
Для одноразовых ходов рекомендуется scp.
Но если вы обнаружите, что этот каталог может работать, и вам нужно много раз перемещать его, чтобы обновлять другую позицию, тогда вы можете использовать rsync (с ssh).
Поскольку у rsync много аргументов, я обычно помещаю его в небольшую оболочку, чтобы я понял это правильно (каждый раз). Идея состоит в том, чтобы отправлять только то, что изменилось с момента последнего запуска.
#!/bin/bash
user="nisse"
host="192.168.0.33"
echo "Sync: /home/media/music/"
rsync --archive --delete -v --progress -e "ssh -l $user " /home/media/music/ $host:/home/media/music/
Это переместит каталог с именем "/home/media/music/" с локального компьютера на компьютер с именем 192.168.0.33, используя пользователя "nisse". И удалите все, что не существует на локальном компьютере.
Я бы порекомендовал вам попробовать альтернативы, вместо того, чтобы идти прямо с SSH для перемещения файлов в вашей локальной сети, поскольку накладные расходы - IMMENSE. Я бы пошел с решением Каспара, если это по какой-то причине не будет работать для вас:
У источника:
$ python3 -m http.server {PICK_YOUR_PORT}
По назначению:
$ wget -r {ip / hostname}:{port}/{File / Directory}
Это будет не только легче, чем при использовании SSH, но и намного быстрее со скоростями в диапазоне 45~65 МБ на стандартной CAT6 UTP.
Если вы действительно хотите выжать максимум из соединения, попробуйте заменить wget
с lftp
и используя pget -n20
а также mirror -r
команды.
The fastest is probably netcat
(as caspar described).
I like the combination of tar
& ssh
, which is secure and still fast:
On the source
tar -cf - . | ( ssh user@target && cd /target/path && tar -xf - )
Doing that as root, it preserves file permissions. Или использовать -p
on both sides. Также -S
might be considered if you have sparse files.
It's possible to reduce the encryption overhead of ssh
если вы используете arcfour
as cipher which works with openSSH:
tar -cpSf - . | ( ssh -c arcfour user@targethost && cd /target/path && tar -xpSf - )
To update the remote path, rsync
is perfect:
rsync -av --sparse --delete -e "ssh -c arcfour" . root@targethost:/target/path
If it absolutely has to be done over the LAN, I'd use rsync
, так как он поймет, где остановился, если его прервут. В нем также есть несколько других приемов для минимизации объема передаваемых данных, хотя я сомневаюсь, что многие / любые из них будут иметь отношение к случаю копирования музыкальной библиотеки в нетронутую папку. Если безопасность является проблемой, просто установите RSYNC_RSH=ssh
сначала и данные будут туннелироваться через ssh.
Однако, если бы я на самом деле делал это, я бы вообще не использовал LAN. Я копировал файлы на жесткий диск USB, а затем выключал его. По моему опыту, это может быть на несколько порядков быстрее, чем при работе по локальной сети, несмотря на необходимость дважды копировать файлы - USB 2.0 рассчитан на 480 Мбит / с, что быстрее, чем что-либо, кроме гигабитного Ethernet, плюс он менее чувствителен к условиям что ухудшит производительность локальной сети. Он также полностью независим от ОС, при условии, что вы используете файловую систему, которую могут обрабатывать все задействованные машины, - я бы порекомендовал VFAT/FAT32, поскольку это в значительной степени универсально.
Было упомянуто много отличных ответов, я подумал, что добавлю еще одну альтернативу, rclone, и она является личным фаворитом из-за ее поддержки многих поставщиков облачных хранилищ и поддержки Windows.
На хост-машине:
rclone serve sftp . --addr 0.0.0.0:2222
Это запустит SFTP-сервер, который будет прослушивать порт 2222 на всех адресах. По умолчанию он будет использовать файл авторизованных ключей текущего пользователя (~/.ssh/authorized_keys
)
В клиентской системе:
Вы можете использовать любую программу с графическим интерфейсом или интерфейсом командной строки с поддержкой SFTP. К сожалению, похоже, что он не поддерживает SCP. Но вы можете подключиться к SFTP-серверу в терминале аналогично
sftp -P 2222 dave@10.75.0.200
Команда rclone serve также поддерживает дополнительные протоколы, включая Webdav, DLNA, FTP, HTTP(s), если вы ограничены определенным протоколом.
Если вам нужно синхронизировать две папки, вы можете использовать встроенную команду синхронизации. Однако вам нужно настроить rclone, используя
rclone config
и добавьте удаленный сервер FTP/SFTP.
Пример:
rclone sync /home/dave/projects localSftpServer:projects
Я использую Unison, который является отличным синхронизатором файлов по многим различным протоколам. Вы можете настроить его для использования scp
, rcp
, ftp
или даже локально в файловой системе между двумя папками. Я использую его для синхронизации своей музыкальной библиотеки, поскольку она может передавать несколько файлов одновременно по сети и действительно настраивается в своей конфигурации. Я храню свою музыкальную коллекцию в резервном копировании и синхронизирую более 2-3 компьютеров. Он будет копировать только измененные файлы и делает это, сохраняя индекс на обоих концах передачи, чтобы иметь возможность определить, когда клиент изменил файл или когда файл сервера изменился.
Ваш пробег может варьироваться, но это, безусловно, намного лучше, чем scp
всю свою музыкальную коллекцию каждый раз, когда вы добавляете новую песню:)
Я бы предложил rsync, поскольку он будет копировать файлы постепенно. Вы можете настроить его на копирование только измененных или новых файлов только после первоначального обновления. Вы можете использовать ssh в качестве транспортного уровня, если хотите.
Подход Caspar с netcat великолепен своей простотой, но могут возникнуть ситуации, когда вы не хотите отправлять незашифрованные файлы по сети.
Чтобы действительно сделать это правильно, вам, вероятно, следует использовать зрелое решение, такое какscp
, SFTP, samba или магическая червоточина (действительно крутая, но на момент написания, к сожалению, не очень подходит для отправки огромных папок).
Но учитывая, что вы находитесь в такой ситуации:
- вы не хотите настраивать учетную запись пользователя для другой стороны или не знаете, как ее настроить, чтобы другой человек не мог выполнять команды оболочки на вашем компьютере (поэтому SCP/SFTP не учитывается)
- затраты на настройку FTPS/samba также слишком велики для одноразовой передачи
- твои папки слишком велики для магической червоточины
- и вы не ожидаете серьезных нападающих
Следующее решение может быть интересным:
С использованиемgpg -c
для шифрования
Режим вытягивания:
serve (host): tar -cz . | gpg -c --cipher-algo AES256 | ncat -lp 8000
fetch (client): ncat HOST 8000 --recv-only | gpg -d | tar -xz
(здесь, используя nmapncat
выполнение. Остальные см. ниже..)
Нажмите режим:
Если к получателю подключиться проще, чем к отправителю, вы можете легко поменять их роли, изменив команды netcat в конвейере:
send (client): tar -cz . | gpg -c --cipher-algo AES256 | ncat HOST 8000
recv (host): ncat -lp 8000 --recv-only | gpg -d | tar -xz
Команда хоста всегда должна выполняться первой.
Пароль через командную строку:
Если вы хотите, пароль можно указать на обоих концах, используя
-
gpg [...] --batch --passphrase-fd 3 3<<<'PASSWORD'
, или -
gpg [...] --batch --passphrase-file <(cat <<<'PASSWORD')
или просто -
gpg [...] --batch --passphrase PASSWORD
. Однако этой формы следует избегать, особенно в многопользовательских системах.
Осторожность:
Насколько я понимаю, GPG аутентифицирует зашифрованный текст по паролю, но это происходит очень поздно, так чтоtar
Процесс извлечения может быть уже невозможно откатить, и файлы в вашем локальном каталоге могут быть перезаписаны, если какая-то часть зашифрованного текста была заменена или неправильно передана. По этой причине, прежде чем делать это, всегда переходите в новый пустой каталог .
Обратите внимание, что я не эксперт по GPG/криптографии и не могу обещать, что это не очень опасно и в других отношениях.
Вещи, которые вы также можете попробовать
Netcat OpenBSD
Я думаю, что это работает, но никаких гарантий:
Режим вытягивания:
serve (host): ENCRYPT | nc -lNp 8000
fetch (client): nc -d HOST 8000 | DECRYPT
Нажмите режим:
send (client): ENCRYPT | nc -N HOST 8000
receive (host): nc -ldp 8000 | DECRYPT
GNU неткат
Теоретически это может сработать:
Режим вытягивания:
serve (host): ENCRYPT | nc -clp 8000
fetch (client): nc HOST 8000 | DECRYPT
Нажмите режим:
send (client): ENCRYPT | nc -c HOST 8000
receive (host): nc -lp 8000 | DECRYPT
Однако в моих испытаниях это часто терпело неудачу из-за закрытия соединения до того, как все байты были отправлены/получены.
Это можно смягчить, не указывая-c
вариант (в этом случае вам придется закрыть соединение вручную, используя Ctrl+C, когда вы считаете, что все готово), или путем создания некоторой задержки на стороне отправителя:
(ENCRYPT; sleep 10s) | nc -clp 8000
Различные реализации netcat на клиенте/сервере
Должно сработать.
Зашифруйте поток, используяopenssl enc
Подавать файлы:
tar -cz . | openssl enc -e -aes-256-ctr -pbkdf2 | ncat -lp 8000
Получить файлы:
ncat HOST 8000 --recv-only | openssl enc -d -aes-256-ctr -pbkdf2 | tar -xz
openssl
попросит у вас пароль. Альтернативно, вы можете указать пароль, используя-k PASSWORD
параметр командной строки на обоих концах или в многопользовательских системах, используя-pass file:<(cat<<<PASSWORD)
.
Помните, что это не обеспечивает аутентифицированное шифрование, а это означает, что нет никакой гарантии, что поток не будет изменен. Итак, кто-то может действительно испортить вашу файловую систему, если изменит несколько байтов. Тем не менее, вы получаете базовые проверки избыточности в архиве gzip, включенном с помощью-z
вариант, это вас не защитит надежно. Вероятно, это подойдет для защиты любовного письма от ваших друзей, но не используйте его, если в сети есть кто-то еще более гнусный!
К сожалению, opensslenc
не поддерживает режимы шифрования с аутентификацией.
С использованиемzip
для шифрования
Сервер:
tar -cz . | zip -e -Ppassword | ncat -lp 8000
Клиент:
ncat HOST 8000 --recv-only | funzip -password | tar -xz
Вроде работает, но выдает следующую ошибку:
funzip error: invalid compressed data--length error
(не из-за сетевых ошибок, я получаю ту же ошибку при вызовеfunzip
в локальной трубе, напримерecho text | zip | funzip
.)
Сначала я следовал процессу ssh для входа без пароля http://www.tecmint.com/ssh-passwordless-login-using-ssh-keygen-in-5-easy-steps/
Для скриптов и текстовых файлов у меня просто отлично работает следующее
Для передачи данных с локального хоста на удаленный хост.cat localfile | ssh <user>@<ip> "cat > <path>/<remotefile>"
Для передачи данных с удаленного хоста на локальный хост.ssh <user>@<ip> "cat > <path>/<remotefile>" | cat > localfile
Это работает для меня, чтобы передавать файлы во встроенных системах, в которых нет встроенного ssh-клиента или scp.
Нет scp - только ssh.