💾 Archived View for pub.phreedom.club › ~taxuswc › sshfs_federation.gmi captured on 2024-05-10 at 11:31:15. Gemini links have been rewritten to link to archived content

View Raw

More Information

⬅️ Previous capture (2023-12-28)

-=-=-=-=-=-=-

прототип "федерации" c помощью sshfs и дурной головы

пример

Предположим, у вас есть K (для общности) VPS-ок, и необходимо расшарить некое подмножество каталогов каждой VPS со всеми остальными. Ну, и конечно дурная голова, которая смогла придумать такую проблему. В качестве решения можно завести пользователей с жёстко ограниченными правами и дальше монтировать каталоги через sshfs. Для ограничения полномочий удобнее всего использовать т.н. sftp chroot jail.

ссылка на арчевики, где достаточно подробно

Ниже я изображу своё решение, ваше может отличаться в зависимости от конечных нужд.

Каталоги для монтирования

Пусть VPS-ки имеют hostname'ы host_1,...,host_K. На host_j, данные с которой мы собираемся монтировать на host_i, заводим каталоги для входящей и исходящей "корреспонденции" и публичных ключей (ниже написано почему так):

# mkdir /srv/repub # re[mote] pub[lic]
# mkdir -p /srv/repub/nodes/host_i/{in,out}
# mkdir -p /srv/repub/keys

Аналогично на host_i:

# mkdir -p /srv/repub/nodes/host_j/{in,out}
# mkdir -p /srv/repub/keys

Группы и пользователи

# groupadd repub # re[mote] pub[lic]
# useradd -g repub -s $(command -v nologin) -d /srv/repub/nodes/host_1/out host_1
# ...

То есть, заводим набор пользователей для каждого хоста с домашним каталогом, совпадающим с каталогом для "исходящей корреспонденции" — туда мы будем монтировать каталоги, которые нужно расшарить с этим хостом и запрещаем им запускать интерактивную оболочку по умолчанию.

Настройка sshd

Убедитесь, что поддержка sftp в /etc/ssh/sshd_config включена:

# override default of no subsystems
Subsystem       sftp    /usr/lib/openssh/sftp-server

Добавим теперь правила доступа для этих пользователей. Удобнее вынести настройки в отдельный файл: /etc/ssh/sshd_config.d/repub.conf. Он автоматически подгружается в основной конфиг директивой Include, которая обычно находится где-то в начале /etc/ssh/sshd_config. НО, там она у меня не заработала, а заработала только после перетаскивания в самый конец файла:

Match all
Include /etc/ssh/sshd_config.d/repub.conf
# end of /etc/ssh/sshd_config

В /etc/ssh/sshd_config.d/repub.conf запишем что-то такое:

Match Group repub
  AllowUsers *
  ChrootDirectory %h
  ForceCommand internal-sftp
  AllowTcpForwarding no
  X11Forwarding no
  PasswordAuthentication no

То есть, мы разрешаем логиниться всем пользователям группы repub (это нужно на случай, если AllowUsers было где-то в основном sshd_config) по ключу и запускать sftp (и только его). Корневой директорией для них будет их домашняя директория (т.е. ничего сверх того, что мы смонтируем в /srv/repub/nodes/host_i/out они не увидят), пробрасывать порты и графику — не дозволяется.

Поскольку в домашние директории мы планируем что-то монтировать, удобнее хранить публичные ключи каждого пользователя-хоста отдельно в /srv/repub/keys/host_i. Об этом полезно намекнуть sshd, включив все эти файлы (по шаблону) в поле AuthorizedKeysFile:

AuthorizedKeysFile      /srv/repub/keys/%u .ssh/authorized_keys

Закрыть глаза, systemctl restart sshd / kill -HUP $(pidof sshd) / что у вас там и надеяться на лучшее.

Если вы смогли залогинится обратно, продолжим.

Создание ключей для авторизации

На host_i, с которой мы собираемся монтировать каталог на host_j, генерируем новый ключ для авторизации:

# ssh-keygen -t ed25519 -f /srv/repub/keys/self

Теперь публичный ключ (/srv/repub/keys/self.pub) нужно добавить в файл с ключами на host_j.

# chown root:root /srv/repub/keys
# chmod u=rwx,g=rx,o=rx /srv/repub/keys
# (umask u=rw,g=r,o=r && printf "%s\n" '<public-key-string>' >> /srv/repub/keys/host_i) 

Монтирование

На host_j: cмонтируем (только на чтение) каталог, который нужно расшарить c host_i

# mount -r --bind /path/to/directory /srv/repub/nodes/host_i/out/directory

На host_i: примонтируем (только на чтение) всё, что расшарено.

# sshfs host_i@host_j:/ /srv/repub/nodes/host_j/in -o allow_other,ro,IdentityFile=/srv/repub/keys/self
# ln -s /srv/repub/nodes/host_j/in/directory /path/where/we/want/it

Гусь готов, товарищи!

По вкусу можно довесить в опции sshfs uid=..,gid=.. чему нужно (например, если монтируется каталог пользователя, который есть на обоих хостах).

Отладка

По умолчанию, при (почти) любой ошибке соединения sshfs выдаёт реплику в духе "connection reset by peer" и завершается с ошибкой. Чтобы сделать его поразговорчивее, добавьте в опции (список через запятую после -o ) debug,sshfs_debug,loglevel=debug

Потенциальные причины ошибки соединения:

--

~taxuswc *2023-04-03 #ssh #unix