ssh
. Это отличный инструмент, но
мне всегда казалась в нём странной одна деталь. Несмотря на то, что
ssh-соединения позволяют передавать файлы с применением
scp
и sftp
, у нас нет возможности
перемещать файлы между локальной и удалённой системой, не запуская
программу на локальном хосте, или не подключаясь к локальной машине
с удалённой.Последнее это настоящая проблема, так как к серверам часто подключаются, находясь в это время за файрволом или за NAT-маршрутизатором, то есть, не имея постоянного IP-адреса. В результате сервер, в любом случае, не сможет подключиться к локальной системе, с которой раньше к нему обращались. Если бы в ssh-сессии можно было бы просто взять локальный или удалённый файл и передать его туда, куда нужно, это было бы очень удобно.
Я, на самом деле, не вполне достиг этой цели, но подобрался к её достижению очень близко. В этом материале я расскажу вам о скрипте, который позволяет монтировать удалённые директории на локальном компьютере. На локальной машине надо будет установить
sshfs
, но на удалённой, на которую вы, возможно, не
можете устанавливать программы, ничего менять не придётся. Если же
потратить на настройку систем некоторое время, и если на клиентском
компьютере имеется работающий ssh-сервер, то можно будет ещё и
монтировать локальные директории на удалённых системах. При этом не
придётся беспокоиться о блокировке IP-адресов или портов.
Фактически, если вы способны подключиться к удалённой машине, это
означает, что вам удастся и то, о чём я хочу рассказать.В результате, если это всё скомбинировать, оказывается, что я очень близок к цели. Я могу работать с командной оболочкой на клиенте или на сервере и имею возможность удобно читать и записывать файлы на обеих сторонах соединения. Для этого нужно лишь всё правильно настроить.
Нет ли тут подвоха?
Возможно, вы решите, что тут кроется какой-то подвох. Ведь речь, фактически, идёт об использовании двух ssh-соединений. Одно применяется для монтирования файловой системы, а другое для входа на компьютер. И это, на самом деле, так и есть. Но если правильно настроить
ssh
, то аутентификацию нужно будет выполнять
лишь один раз, не тратя слишком много времени на организацию двух
подключений.Кроме того, работу значительно облегчает скрипт, о котором я расскажу. Он скрывает от пользователя детали, поэтому процедура подключения выглядит (почти) как обычно, а после этого всё работает как надо.
Пара слов о sshfs
Утилита
sshfs
даёт возможность работать с файловой
системой в пользовательском пространстве (filesystem in userspace,
FUSE). То есть, речь идёт о том, что в пользовательском
пространстве имеется слой, находящийся поверх базовой файловой
системы. В данном случае такой файловой системой является
ssh-сервер, поддерживающий sftp
. Это позволяет
работать с файлами, находящимися на удалённой системе, воспринимая
их так, будто они находятся в реальной файловой системе на
локальном компьютере. Если вы ещё не пробовали sshfs
попробуйте. Работает эта утилита очень хорошо.Предположим, вы вошли на компьютер
myserver
и
выполнили с локальной машины следующую команду:
sshfs myserver:/home/admin ~/mounts/myserver
Это приведёт к тому, что директория удалённого компьютера
/home/admin
будет доступна в локальной системе по пути
~/mounts/myserver
.При использовании
sshfs
можно пользоваться различными
опциями. Например, можно сделать так, чтобы после потери соединения
осуществлялось бы повторное подключение. Подробности о
sshfs
ищите в справке.Так как
sshfs
использует удалённо смонтированную
версию файла, то все изменения, внесённые в файл, сохраняются на
удалённой машине. А после того, как sshfs-соединение закрывают, на
локальной компьютере ничего не остаётся. Сейчас мы это
исправим.Предварительная подготовка
Прежде чем я перейду к описанию скрипта, о котором было упомянуто выше, хочу рассказать о некоторых настройках клиента, которые вы, если хотите, можете доработать под себя. Так, тут я создаю директорию
~/remote
, а в ней создаю поддиректории для
каждого удалённого компьютера. Например это могут быть директории
~/remote/fileserver
и ~/remote/lab
.Скрипт называется
sshmount
. Он принимает те же
аргументы, что и ssh
. Для упрощения работы со скриптом
сведения об удалённом хосте стоит хранить в файле
~/.ssh/config
, что позволит пользоваться простыми и
короткими именами хостов. Например, сведения о компьютере
lab
могут выглядеть так:
Host labHostname lab.wd5gnr-dyn.netPort 444User alwForwardX11 yesForwardX11Trusted yesTCPKeepAlive yesCompression yesControlMaster autoControlPath ~/.ssh/master-%r@%h:%p
На самом деле, острой необходимости в этом нет, но при таком подходе в вашем распоряжении будет приятно выглядящая директория
~/remote/lab
, а не сложная конструкция вида
~/remote/alw@lab.wd5gnr-dyn.net:444
. Во всех этих
параметрах нет ничего таинственного. Единственно, хочу обратить
ваше внимание на то, что ControlMaster
и
ControlPath
позволяют организовать более быструю
работу с соединениями, что, в нашем случае, очень важно.Кроме того, можно организовать автоматическое подключение к удалённой системе с использованием сертификата. Вот материал об этом.
Скрипт
Наш скрипт можно использовать двумя способами. Так, если его вызывают через ссылку к
sshunmount
, то он размонтирует
файловую систему, связанную с указанным удалённым хостом. Если его
вызывают иначе (обычно как sshmount
), то он выполняет
следующие три действия:- Он проверяет, есть ли в директории
~/remote
поддиректория, имя которой совпадает с именем хоста (напримерlab
). Если такой директории нет он выводит сообщение об ошибке и продолжает работу. - Если такая директория существует скрипт просматривает список смонтированных файловых систем на тот случай, если нужная файловая система уже смонтирована. Если это так он продолжает работу.
- Если директория не смонтирована он вызывает
sshfs
и продолжает работу.
Этот скрипт можно найти на GitHub. А вот его код, из которого убраны некоторые комментарии:
#!/bin/bashif [ "$1" == "" ]thenecho Usage: sshmount host [ssh_options] - Mount remote home folder on ~/remote/host and log inecho or: sshunmount host - Remove mount from ~/remote/hostexit 1fi# Если вызван как sshunmount...if [ $(basename "$0") == sshunmount ]thenecho Unmounting... 1>&2fusermount -u "$HOME/remote/$1"exit $?fi# Обычный вызов...if [ -d "$HOME/remote/$1" ] # Существует ли директория?thenif mount | grep "$HOME/remote/$1 " # Файловая система уже смонтирована?thenecho Already mounted 1>&2elsesshfs -o reconnect $1: $HOME/remote/$1 # mountfielseecho No remote directory ~/remote/$1 exists 1>&2fissh $@ # выполнить вход
Этот скрипт даёт мне половину того, что мне нужно. А именно, позволяет удобно работать с удалёнными файлами на локальном компьютере, к которому я подключён. Но сделать так, чтобы с удалённого компьютера можно было бы работать с файлами, расположенными на локальной машине, немного сложнее.
Решаем обратную задачу
Если вы хотите поэкспериментировать с монтированием на сервере папок, находящихся на локальной машине, то нужно будет, чтобы на локальной машине работал бы ssh-сервер. Конечно, если ваш локальный компьютер видим и доступен серверу, то это просто: достаточно запустить на удалённом компьютере
sshfs
и смонтировать
на нём папку с локального компьютера. Но во многих случаях у нас
нет доступа к локальной системе, которая может быть расположена за
файрволами или маршрутизаторами. Особенно это актуально в том
случае, если роль локальной системы выполняет ноутбук, который
может подключаться к сети из разных мест.Но нашу задачу, несмотря на все эти сложности, всё же, можно решить. Её решение состоит из двух частей.
Во-первых надо, при вызове
sshmount
, указать
дополнительный аргумент (файл можно отредактировать в том случае,
если вам нужно будет постоянно выполнять подобную команду):
sshmount MyServer -R 5555:localhost:22
Во-вторых после подключения к хосту нужно выполнить такую команду:
sshfs -p 5555 localhost:/home/me ~/local
Благодаря опции
-R
на удалённой машине создаётся сокет
на порте 5555
(который, естественно, должен быть
свободным) и осуществляется его связь с портом 22
локальной машины. Если исходить из предположения о том, что
ssh-сервер работает на порте 22
, то это позволит
серверу подключиться к локальной машине по тому же соединению. Ему
не нужно знать наш IP-адрес или иметь открытый порт.Команда
sshfs
, которую можно выполнять при запуске
системы, связывает локальную директорию /home/me
с
директорией ~/local
удалённого сервера. Если,
вдобавок, войти в систему локально, то можно будет взглянуть на
переменные окружения, имена которых начинаются с SSH_
,
и узнать подробности о SSH-соединении. Например, это переменные
$SSH_CLIENT
и $SSH_TTY
.Конечно, вам, чтобы вышеприведённые команды заработали бы у вас, нужно будет поменять имена хостов и директорий, а так же адреса портов на те, которые используются в ваших системах. Но после того, как всё будет настроено, все нужные вам файлы будут доступны и на локальной, и на удалённой машинах. Я, кстати, не пытался организовать циклическое монтирование директорий. Если попытаться это сделать может получиться нечто очень странное.
Итоги
Полагаю, нужно с осторожностью выполнять одновременное монтирование удалённых папок на локальной машине и локальных папок на удалённой машине. Например, утилиты, занимающиеся сканированием всей файловой системы, могут в таких конфигурациях запутаться. Кроме того, я всё ещё ищу ответ на вопрос о том, как правильно отключаться от серверной файловой системы при выходе из последней сессии.
Но и сейчас всё это даёт нам хорошие инструменты для организации удобной и надёжной работы с файлами по
ssh
. Надо
отметить, что ещё одним вариантом решения задачи по работе с
файлами удалённых систем может стать
синхронизация папок и использование их для передачи файлов
между компьютерами.Чем вы пользуетесь для работы с файлами удалённых Linux-систем?