Перейти к содержанию

Ограничение среды пользователей SSH

Если ваш сервер SSH сконфигурирован по-умолчанию (или без указанных ниже опций), скорее всего любой пользователь, который может подключиться к нему, будет иметь доступ на чтение множества файлов, в том числе системных. Да, это всего лишь доступ на чтение, но далеко не всегда необходимо, чтобы пользователи могли просматривать, например, файл конфигурации того же SSH, список всех пользователей системы и многие другие файлы.

Для ограничения доступа подключающихся пользователей к файлам системы, нужно настроить сервер SSH таким образом, чтобы он предоставлял некую директорию, как корневую для данного пользователя. Особенно это удобно, если пользователи должны иметь различные ограничения.

Все описываемые далее настройки делятся на характерные для всех пользователей и для каждого отдельно.

Настройки для всех пользователей

Создайте директорию, в которой будут позже создаваться "корневые" директории пользователей:

mkdir /users
chown root:root /users
chmod 0755 /users

Настройки для отдельного пользователя

Создайте пользователя (если он не был создан ранее) и укажите его пароль:

useradd -M -s /sbin/nologin USERNAME
passwd PASSWORD

Обратите внимание, что в данном случае для пользователя не будет создана домашняя директория и не будет установлена командная оболочка по-умолчанию. Домашнюю директорию не создаем, т.к. вместо нее будет использоваться псевдо-коневая директория, которую создадим далее. Командная оболочка не нужна только в данном случае. Во второй части статьи я вкратце расскажу, как добавить возможность использования командной оболочки (равно как и других приложений) в ограниченной среде пользователя.

Создайте псевдо-корневую директорию для данного пользователя:

mkdir -p /users/USERNAME

Владельцем этой директории должен быть суперпользователь (для интереса посмотрите, кто является владельцем в корневой директории в полноценной системе):

chown root:root /users/USERNAME

Установите права на псевдо-корневую директорию (сервер SSH требует, чтобы это было значение 755):

chmod 0755 /users/USERNAME

Создайте в псевдо-корневой директории другую директорию, в которой у пользователя должны быть права на запись (альтернатива обычной /home/USERNAME) и установите соответствующие права:

mkdir /users/USERNAME/home
chown USERNAME:USERNAME /users/USERNAME/home
chmod 755 /users/USERNAME/home

Остается только отредактировать файл конфигурации сервера SSH:

mcedit /etc/ssh/sshd_config

Если пользователю необходимо получать доступ к SFTP, замените строку:

Subsystem sftp /usr/lib/openssh/sftp-server

на

Subsystem sftp internal-sftp

Добавьте в файл конфигурации строки, отвечающие за установку для данного пользователя псевдо-корневой директории:

Match User USERNAME
ChrootDirectory /users/USERNAME

Перезапустите сервер SSH:

systemctl restart sshd

Добавление командной оболочки при использовании ограниченной среды

При использовании ограниченной среды, пользователь "видит" в качестве корневой директории указанную вами директорию. Соответственно, если пользователю нужна командная оболочка, то нужны все исполняемые файлы, файлы библиотек и устройств, необходимые для нормальной работы этой оболочки. Рассмотрим простой случай, когда пользователю нужна лишь сама оболочка /bin/sh.

Сначала установим оболочку по-умолчанию для данного пользователя:

usermod --shell /bin/sh USERNAME

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

ldd /bin/sh

Вывод команды будет примерно следующим:

linux-vdso.so.1 (0x00007ffdc2fdc000)
libtinfo.so.6 => /lib/x86_64-linux-gnu/libtinfo.so.6 (0x00007a9b55a60000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007a9b55a5b000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007a9b5589b000)
/lib64/ld-linux-x86-64.so.2 (0x00007a9b55a98000)

Из вывода видно, что файл /bin/sh связан с файлами /lib/x86_64-linux-gnu/libtinfo.so.6, /lib/x86_64-linux-gnu/libdl.so.2, /lib/x86_64-linux-gnu/libc.so.6 и /lib64/ld-linux-x86-64.so.2. Не обращайте внимания на linux-vdso.so.1, т.к. это не настоящий файл, а виртуальный объект, который используется ядром системы для осуществления системных вызовов.

Таким образом, для работы командной оболочки необходимы файлы:

/bin/sh
/lib/x86_64-linux-gnu/libtinfo.so.6
/lib/x86_64-linux-gnu/libdl.so.2
/lib/x86_64-linux-gnu/libc.so.6
/lib64/ld-linux-x86-64.so.2

Скопируйте эти файлы в псевдо-корневую директорию пользователя и установите необходимые права:

mkdir /users/USERNAME/bin
mkdir -p /users/USERNAME/lib/x86_64-linux-gnu
mkdir /users/USERNAME/lib64
cp /bin/sh /users/USERNAME/bin/
cp /lib/x86_64-linux-gnu/libtinfo.so.6 /users/USERNAME/lib/x86_64-linux-gnu/
cp /lib/x86_64-linux-gnu/libdl.so.2 /users/USERNAME/lib/x86_64-linux-gnu/
cp /lib/x86_64-linux-gnu/libc.so.6 /users/USERNAME/lib/x86_64-linux-gnu/
cp /lib64/ld-linux-x86-64.so.2 /users/USERNAME/lib64/
chown -R root:root /users/USERNAME/bin
chown -R root:root /users/USERNAME/lib
chown -R root:root /users/USERNAME/lib64
chmod -R 777 /users/USERNAME/bin
chmod -R 777 /users/USERNAME/lib
chmod -R 777 /users/USERNAME/lib64

Теперь вы можете подключаться к серверу обычным консольным клиентом:

ssh USERNAME@server_address

Обратите внимание, что работать будут только команды, встроенные в саму командную оболочку, например, pwd или time. Но такие команды, как ls или date являются отдельными программами и недоступны данному пользователю. Чтобы сделать доступными их, необходимо также исследовать данные программы на наличие зависимостей и скопировать все соответствующие файлы, как это было показано выше.

Имейте в виду, что для работы некоторых приложений могут быть необходимы файлы устройств или именованных каналов, а не только исполняемые файлы и файлы библиотек. Чтобы добавить эти объекты в ограниченную среду пользователя, нужно создать т.н. "ноды". Рассмотрим добавление некоторых часто используемых нод (null, zero, stdin, stdout, stderr, random, tty):

Создайте директорию dev в псевдо-корневой директории пользователя:

mkdir /users/USERNAME/dev

Перейдите в эту директорию и создайте ноды:

cd /home/test/dev/
mknod -m 666 null c 1 3
mknod -m 666 tty c 5 0
mknod -m 666 zero c 1 5
mknod -m 666 random c 1 8

Более подробная информация о создании нод доступна по команде man mknod. Однако, хочется добавить о том, где можно получить номера типа устройств (или т.н. major node и minor node) - вы можете посмотреть это командой:

stat /dev/null

Вывод команды должен быть примерно следующим:

  Файл: /dev/null
  Размер: 0             Блоков: 0          Блок В/В: 4096   символьный специальный файл
Устройство: 5h/5d       Inode: 5           Ссылки: 1     Тип устройства: 1,3
Доступ: (0666/crw-rw-rw-)  Uid: (    0/    root)   Gid: (    0/    root)
Доступ: 2024-01-08 14:28:32.138178227 +0300
Модифицирован: 2024-01-08 14:28:32.138178227 +0300
Изменён: 2024-01-08 14:28:32.138178227 +0300
 Создан: -

Значение поля Тип устройства - это major node и minor node.