Монтирование удаленной директории с помощью sshfs. Часть вторая

15.06.2020

Теги: LinuxSSHДиректорияКлиентКлючНастройкаСерверУстановкаФайл

Опция allow_other

Сейчас доступ к директории /home/evgeniy/var-www/ имеет только пользователь evgeniy. Чтобы разрешить другим пользователям работать с файлами в этой директории, нужно использовать опцию allow_other:

$ sshfs -o allow_other developer@123.123.123.123:/var/www/ /home/evgeniy/var-www/
fusermount: option allow_other only allowed if 'user_allow_other' is set in /etc/fuse.conf

По умолчанию это может делать только пользователь root. Чтобы разрешить другим пользователям применять эту опцию, редактируем файл /etc/fuse.conf:

$ sudo nano /etc/fuse.conf
# Set the maximum number of FUSE mounts allowed to non-root users (default is 1000).
#mount_max = 1000

# Allow non-root users to specify the allow_other or allow_root mount options.
user_allow_other

Теперь можем смонтировать уделенную директорию, чтобы с файлами могли работать и другие пользователи:

$ sshfs -o allow_other developer@123.123.123.123:/var/www/ /home/evgeniy/var-www/

Аутентификация по ключу

Давайте создадим пару ключей на клиенте и скопируем публичный ключ на сервер:

$ ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/home/evgeniy/.ssh/id_rsa): 
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in /home/evgeniy/.ssh/id_rsa.
Your public key has been saved in /home/evgeniy/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:aR5/t1LFc40pkZD6WjGgog4om4gbiWbDjP5HTH1+cb8 evgeniy@sshfs-client
The key's randomart image is:
+---[RSA 2048]----+
|          .o .   |
|        . . o    |
|      .. o   . +.|
|    .....oo...o.=|
|.  .o.  S. oo...o|
|O..  o o +o.  .. |
|O@  .   .oo ... .|
|O.o  .  .  ... E |
|.o...        ..  |
+----[SHA256]-----+
$ ssh-copy-id -i ~/.ssh/id_rsa.pub developer@123.123.123.123
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/home/evgeniy/.ssh/id_rsa.pub"
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
developer@123.123.123.123's password: пароль
Number of key(s) added: 1
Now try logging into the machine, with: "ssh developer@123.123.123.123"
and check to make sure that only the key(s) you wanted were added.

Проверяем, что теперь можем подключаться к серверу без ввода пароля:

$ ssh developer@123.123.123.123
Welcome to Ubuntu 18.04.4 LTS (GNU/Linux 4.15.0-106-generic x86_64)
..........
$ exit

И монтируем удаленную директорию уже без ввода пароля:

$ sshfs -o idmap=user,allow_other,reconnect developer@123.123.123.123:/var/www/ /home/evgeniy/var-www/

Монтирование при загрузке

Если есть необходимость автоматически монтировать удаленную директорию при загрузке системы, то есть два пути. Первый — отредактировать файл /etc/fstab и добавить новую запись о монтировании. Второй — создать новый unit-файл для системы инициализации systemd.

1. Редактируем файл /etc/fstab

Монтирование удаленной директории выглядит примерно так:

$ sudo nano /etc/fstab
developer@123.123.123.123:/var/www/  /home/evgeniy/var-www/  fuse.sshfs  allow_other,reconnect,uid=1000  0  0

Но, чтобы это заработало, должна быть настроена аутентификация по ключу на сервере. Мы это уже сделали, но монтирование файловых систем происходит от имени пользователя root. И файл ключа операционная система будет искать в директории /root/.ssh/. А наш ключ рсположен в домашней директории пользователя evgeniy. Поэтому нужно явно указать путь:

$ sudo nano /etc/fstab
developer@123.123.123.123:/var/www/  /home/evgeniy/var-www/  fuse.sshfs  allow_other,reconnect,uid=1000,IdentityFile=/home/evgeniy/.ssh/id_rsa  0  0

Кроме того, нужно один раз подключиться к серверу от имени пользователя root — чтобы был создан файл /root/.ssh/known_hosts:

# ssh -i /home/evgeniy/.ssh/id_rsa developer@123.123.123.123
The authenticity of host '123.123.123.123 (123.123.123.123)' can't be established.
ECDSA key fingerprint is SHA256:4SekW639zeTtdrRugvhGitb54QJroU4p07bkUs83rkA.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '123.123.123.123' (ECDSA) to the list of known hosts.
Welcome to Ubuntu 18.04.4 LTS (GNU/Linux 4.15.0-106-generic x86_64)
# exit

Здесь используется опция монтирования uid=1000 — это значит, что владельцем файлов на клиенте будет пользователь с идентификатором 1000, другими словами — пользователь evgeniy. Неважно, кто создает файл на клиенте — на сервере его владельцем будет пользователь developer, а на клиенте — пользователь evgeniy. По сути, мы получаем тот же эффект, как при использовании опции idmap=user.

Вместо опции uid=1000 мы могли бы использовать опцию idmap=user. В этом случае владельцем файлов на клиенте был бы пользователь root, но выглядит это не очень красиво. Поскольку мы также используем опцию allow_other — c файлами смогут работать и другие пользователи.

Когда мы создаем на клиенте новый файл, на самом деле мы создаем файл на сервере от имени пользователя developer. Основная группа этого пользователя — www-data (см. здесь). Эта группа существует как на сервере, так и на клиенте (хотя на клиенте веб-сервер не установлен). И идентификатор этой группы равен 33 (на клиенте и на сервере установлена ОС Ubuntu). Так что можно не задавать опцию монтирования gid=идентификатор.

2. Создаем новый unit-файл

Здесь опять возможны два варианта — создать файл .service (который просто выполнит команду монтирования), либо файл .mount (который предназначен специально для монтирования файловых систем).

2.1. Создаем service-файл

Итак, создаем новый unit-файл:

# nano /etc/systemd/system/mount-remote-file-system.service
[Unit]
Description=Mount remote file system with sshfs
Requires=network-online.target network.target
After=network-online.service network.target
[Service]
Type=simple
User=evgeniy
ExecStart=/usr/bin/sshfs -f -o allow_other developer@123.123.123.123:/var/www/ /home/evgeniy/var-www/
ExecStopPost=/bin/fusermount -u /home/evgeniy/var-www/
Restart=always
RestartSec=3
[Install]
WantedBy=remote-fs.target
Опция -f для утилиты sshfs говорит о том, что не нужно запускать ее в фоновом режиме (background). При запуске из командной строки утилита sshfs монтирует удаленную файловую систему и возвращает управление оболочке — но продолжает работу в фоновом режиме, обеспечивая доступ к файлам на сервере.

Команда sshfs выполняется от имени пользователя evgeniy, поэтому нам не нужно указывать путь к файлу ключа. Если пользователь не указан, команда будет выполнена от имени пользователя root — в этом случае указываем путь к файлу ключа:

# пользователь не указан, команда будет выполнена от имени пользователя root
Type=simple
ExecStart=/usr/bin/sshfs -f -o allow_other -o IdentityFile=/home/evgeniy/.ssh/id_rsa developer@123.123.123.123:/var/www/ /home/evgeniy/var-www/
ExecStopPost=/bin/fusermount -u /home/evgeniy/var-www/

Если по каким-то причинам нельзя настроить аутентификацию по ключу, можно использовать утилиту sshpass. Опция -f для утилиты sshpass говорит о том, что пароль доступа к серверу сохранен в файле /home/evgeniy/server.pass.

# пользователь не указан, команда будет выполнена от имени пользователя root
Type=simple
ExecStart=/usr/bin/sshpass -f /home/evgeniy/server.pass /usr/bin/sshfs -f -o allow_other developer@123.123.123.123:/var/www/ /home/evgeniy/var-www/
ExecStopPost=/bin/fusermount -u /home/evgeniy/var-www/

Разумеется, утилиту sshpass надо предварительно установить. Если нет желания хранить пароль в отдельном файле, можно просто передать его прямо в команде монтирования:

# пользователь не указан, команда будет выполнена от имени пользователя root
Type=simple
ExecStart=/usr/bin/sshfs -o allow_other -o ssh_command="sshpass -p 'qwerty' ssh" developer@123.123.123.123:/var/www/ /home/evgeniy/var-www/
ExecStopPost=/bin/fusermount -u /home/evgeniy/var-www/

Сообщаем системе про новый unit-файл:

# systemctl daemon-reload

Добавляем новую службу в автозагрузку:

# systemctl enable mount-remote-file-system.service

Теперь удаленная файловая система будет монтироваться автоматически во время загрузки системы. Кроме того, смонтировать и размонтировать удаленную файловую систему можно с помощью команд:

$ sudo systemctl start mount-remote-file-system.service
$ sudo systemctl stop mount-remote-file-system.service

2.2. Создаем mount-файл

Мне пришлось изменить имя директории для монтирования удаленной файловой системы с /home/evgeniy/var-www/ на /home/evgeniy/server/, потому что имя unit-файла должно состоять из имен директорий, показывающих путь к точке монтирования, то есть вот так home-evgeniy-server.mount.

# nano /etc/systemd/system/home-evgeniy-server.mount
[Unit]
Description=Mount remote file system with sshfs
Requires=network-online.target network.target
After=network-online.service network.target
[Mount]
What=developer@123.123.123.123:/var/www/
Where=/home/evgeniy/server/
Options=allow_other,uid=1000,IdentityFile=/home/evgeniy/.ssh/id_rsa
Type=fuse.sshfs
[Install]
WantedBy=remote-fs.target

Если по каким-то причинам нельзя настроить аутентификацию по ключу, можно использовать пароль:

Where=/home/evgeniy/server/
Options=allow_other,uid=1000,ssh_command=sshpass -f /home/evgeniy/server.pass ssh
Type=fuse.sshfs
Where=/home/evgeniy/server/
Options=allow_other,uid=1000,ssh_command=sshpass -p qwerty ssh
Type=fuse.sshfs

Сообщаем системе про новый unit-файл:

# systemctl daemon-reload

Добавляем новую службу в автозагрузку:

# systemctl enable home-evgeniy-server.mount

Теперь удаленная файловая система будет монтироваться автоматически во время загрузки системы. Кроме того, смонтировать и размонтировать удаленную файловую систему можно с помощью команд:

$ sudo systemctl start home-evgeniy-server.mount
$ sudo systemctl stop home-evgeniy-server.mount

Посмотреть текущее состояние можно с помощью команды:

$ sudo systemctl status home-evgeniy-server.mount
● home-evgeniy-server.mount - Mount remote file system with sshfs
   Loaded: loaded (/etc/systemd/system/home-evgeniy-server.mount; enabled; vendor preset: enabled)
   Active: active (mounted) since Mon 2020-06-15 16:39:26 MSK; 2min 50s ago
    Where: /home/evgeniy/server
     What: developer@123.123.123.123:/var/www/
  Process: 646 ExecMount=/bin/mount developer@123.123.123.123:/var/www/ /home/evgeniy/server -t fuse.sshfs -o allow_other,uid=1000,IdentityFile=/home/evgeniy/.ssh/id_rsa (code=exited, status=0/SUC
    Tasks: 6 (limit: 2328)
   CGroup: /system.slice/home-evgeniy-server.mount
           ├─659 ssh -x -a -oClearAllForwardings=yes -oIdentityFile=/home/evgeniy/.ssh/id_rsa -2 developer@123.123.123.123 -s sftp
           └─798 sshfs developer@123.123.123.123:/var/www/ /home/evgeniy/server -o rw,allow_other,uid=1000,IdentityFile=/home/evgeniy/.ssh/id_rsa,dev,suid

июн 15 16:39:25 sshfs-client systemd[1]: Mounting Mount remote file system with sshfs...
июн 15 16:39:26 sshfs-client systemd[1]: Mounted Mount remote file system with sshfs.

Дополнительно

Поиск: Linux • SSH • Директория • Клиент • Ключ • Настройка • Сервер • Установка • Файл • SSHFS

Каталог оборудования
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Производители
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Функциональные группы
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.