У меня на сервере Ubuntu есть два пользователя и одна общая папка:
Пользователь
writer
, имеющий доступ на запись в/var/shared
. Это приложение регулярно вносит изменения в файлы в этой папке удаленно с помощью ключа SSH.Пользователь
reader
используется несколькими клиентами с ключом SSH, который они могут получить без моего разрешения, поэтому мне нужно ограничить команды, доступные в этой оболочке.
Вопрос:
Мне нужно ограничить команды, доступные пользователю, reader
чтобы он мог использовать только протоколы sftp и rsync (без стандартных команд типа mkdir
, ls
, top
, ...). Только каталог /var/shared
должен быть доступен для чтения и должен быть корневым путем, например, не нужно cd
в него входить, он уже есть /
в sftp или rsync.
Как написать скрипт оболочки, чтобы я мог применить его к usermod -s
пользователю reader
, который будет вести себя таким образом?Я не могу найти никаких образцов. Как мне сделать так, чтобы writer
также оставалось "заключенным" в /var/share
, чтобы пути были такими же?
Примечания:
Я уже пробовал директивы
sshd_config
'sMatch
,ForceCommand internal-sftp
иChrootDirectory
. Это требует,ChrootDirectory
чтобы владел root и был недоступен для записи (755 или меньше), и не поддерживаетrsync
.Я пробовал
rssh
, но это просто не работает для каталогов за пределами домашнего каталога вошедшего в систему пользователя. Поэтому я не мог chroot пользователей в тот же каталог с разными разрешениями.Я пытался использовать
command=".." ssh-rsa....
вauthorized_keys
файле, но не понял, как включить нужное мне поведение, я только проверяюrrsync
скрипт из документации rsync. Этот метод не имеетchroot
нужной мне функции.
Можно ли хотя бы пример для таких оболочек? Возможно ли это сделать скриптами?
Bash и C++ (при необходимости) приветствуются. Вывод ldd /bin/bash
:
linux-vdso.so.1 => (0x00007fff7e9d1000)
libtinfo.so.5 => /lib/x86_64-linux-gnu/libtinfo.so.5 (0x00007f79dfd8b000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f79dfb87000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f79df7bd000)
/lib64/ld-linux-x86-64.so.2 (0x000055bd0767c000)
решение1
Прежде всего, ChrootDirectory
он должен принадлежать пользователю root и не быть доступным для записи другим пользователям. Таким образом, /var/shared
в вашем случае не может быть ChrootDirectory
значением.
Я бы рекомендовал создать каталог, доступный для записи только пользователю root, и сделать /var/shared
содержимое этого каталога доступным либо через монтирование Linux, либо с помощью каких-либо обходных путей с использованием символических ссылок.
Если вам нужно ограничить sftp
или rsync
, вам нужно проверить SSH_ORIGINAL_COMMAND
переменную окружения на сервере с помощью "обертки", принудительно применяемой либо через ForceCommand
, либо через command
в открытом ключе ssh, эта переменная заполняется после аутентификации пользователя и содержит информацию о том, какой тип соединения собираются установить клиенты. Для sftp
него будет иметь sftp-server
внутри, для rsync
него будет иметь rsync
, для просто ssh
сеанса он будет иметь, IIRC, переменная пустая, для ssh date
него будет date
. SSH_ORIGINAL_COMMAND
запускается под аутентифицированным пользователем на сервере!
Это может быть началом вашей обертки:
#!/usr/bin/env bash
set -eu
set -o pipefail
[[ -z "${SSH_ORIGINAL_COMMAND:-}" ]] && exit 1
case "${SSH_ORIGINAL_COMMAND}" in
"/usr/libexec/openssh/sftp-server")
exec /usr/libexec/openssh/sftp-server
;;
"rsync --server"*)
exec ${SSH_ORIGINAL_COMMAND}
;;
*)
exit 1
;;
esac
Как вы можете видеть, ssh -v
дает вам информацию о том, какая команда будет выполнена сервером. Таким образом, вы можете изменить /tmp
на что-то другое в вашей обертке.
$ rsync -a -e "ssh -v" bin localhost:/tmp/ 2>&1 | grep '^debug.*Sending command:'
debug1: Sending command: rsync --server -logDtpre.iLsfxC . /tmp/