Как то раз появилась следующая задача: создать локального пользователя в ОС Linux, с ограниченным доступом к папкам и файлам, включая не только редактирование, но и просмотр, а также возможность использовать только разрешенные утилиты. Предусматривается только локальный доступ, сетевого доступа нет.Что бы не изобретать велосипед, первым делом начал копать интернет, в результате чего были найдены следующие варианты:
- ограничения доступа через сетевые службы ssh, sftp (не подошло)
- разграничение прав доступа самой операционной системой linux (не подошло, хотелось бы универсальное решение)
- использование chroot (не подошло)
- использование сторонних утилит, например SELinux (не подошло, усложняет систему).
В результате поиска, был найден встроенный механизм ограничения возможностей пользователя внутри оболочки bash, он называется Restricted Shell или rbash.
В нем реализованы следующие ограничения:
- нет возможности смены каталога командой cd
- нельзя сбрасывать или изменять значения переменных SHELL, PATH, ENV, BASH_ENV
- запрещено указывать команды содержащие / (косую черту)
- запрещено импортировать функции из основной оболочки
- запрещено перенаправлять вывод с использованием операторов >, <, |, <>, >&, &>, >>
- запрещено использовать команду exec для подмены команды и пр.
Есть минус, это безопасность, поэтому необходимо в обязательном порядке добавить alias на команды в файл поведения оболочки .bashrc (информация будет далее).
Конечно rbash из коробки, всех задач не решает, поэтому на примере рассмотрим создание пользователя и настройка его окружения для полного решения нашей задачи.
Далее все операции выполняются от суперпользователя (root).
1. Создаем ограниченную оболочку
echo '/bin/bash -r' > /bin/zbash chmod +x /bin/zbash
2. Создаем пользователя
adduser --home /home/zuser --shell /bin/zbash zuser
3. Изменяем права директории
chown root.zuser /home/zuser chmod 750 /home/zuser
4. Переходим в директорию и очищаем ее
cd ~zuser ls -a rm .bash* rm .profile ls -a
5. Настраиваем оболочку и права
echo "PATH=:/home/zuser/bin" > .bashrc echo "alias help='echo access is limited'" >> .bashrc # alias на команду help echo "bind 'set disable-completion on'" >> .bashrc # Отключает автодополнение на tab mkdir -p bin chmod 750 bin chown -R root.zuser /home/zuser chmod 640 .bash*
Файл .bashrc определяет поведение командной оболочки, в данный файл можно добавить alias для команд или дополнительные опции.
Для обеспечения безопасности выполните следующие команды:
echo "alias echo=':'" >> .bashrc echo "alias cat=':'" >> .bashrc echo "alias bash=':'" >> .bashrc echo "alias sh=':'" >> .bashrc echo "alias ln=':'" >> .bashrc echo "alias set=':'" >> .bashrc echo "alias uset=':'" >> .bashrc echo "alias export=':'" >> .bashrc echo "alias typeset=':'" >> .bashrc echo "alias declare=':'" >> .bashrc echo "alias alias=':'" >> .bashrc echo "alias unalias=':'" >> .bashrc
Данный список можно продолжать…
6. Проверяем работу
root@host: su zuser zuser@host: help access is limited zuser@host: pwd /home/zuser zuser@host: ls /tmp/ bash: ls: команда не найдена zuser@host: /bin/ls bash: /bin/ls: ограниченный режим в команде нельзя использовать косую черту {/} zuser@host: echo $PATH :/home/zuser/bin zuser@host: PATH=/bin/ bash: PATH: переменная только для чтения zuser@host: exit
7. Добавляем допустимые команды
ln -s /bin/ping /home/zuser/bin/ping
Важно, пути в команде ln необходимо указывать полностью.
8. Для ограничения опций команды можно использовать обертки
mkdir /var/scripts echo "/usr/sbin/useradd -D" > /var/scripts/user-info chmod +x /var/scripts/user-info ln -s /var/scripts/user-info /home/zuser/bin/user-info
9. Для работы с файлами и папками можно также создать обертку
с черным списком (разрешить все, кроме):
— создаем файл
nano /var/scripts/ls
— содержимое файла
blacklist="\? ../ /etc /bin /boot /var" for var in $blacklist do if [[ $* == *$var* ]]; then echo 'Access is denied:' $* exit fi done /bin/ls $*
blacklist — переменная содержащая черный список директорий или файлов (через пробел)
— добавляем команду для пользователя zuser
chmod +x /var/scripts/ls ln -s /var/scripts/ls /home/zuser/bin/ls
Данный скрипт разрешает выполнять команду ls с любыми ключами для каталогов и файлов не совпадающих с черным списком
с белым списком (запретить все, кроме):
— создаем файл
nano /var/scripts/cat
— содержимое файла
whitelist="./ /tmp/" # белый список for var in $whitelist do if [[ $* == *$var* ]]; then /bin/cat $* # запуск утилиты cat с заданными параметрами exit fi done echo 'Access is denied:' $*
whitelist — переменная содержащая белый список директорий или файлов (через пробел)
— добавляем команду для пользователя zuser
chmod +x /var/scripts/cat ln -s /var/scripts/cat /home/zuser/bin/cat
Данный скрипт разрешает выполнять команду cat с ука��анными файлами в белом списке
Готово, в итоге получили следующий результат:
- мы создали пользователя zuser с оболочкой rbash
- отключили возможность использования автодополнения в консоли
- zuser может запускать утилиты только из директории /home/zuser/bin
- добавили пользователю zuser команду ping
- добавили пользователю zuser собственную команду user-info
- пользователю zuser ограничили через обертку выполнение команд ls и cat
Данный способ к сожалению не гарантирует 100% безопасность, и при определенных знаниях и квалификации пользователь может покинуть данную оболочку. Спасибо Jouretz arheops YaDr они в комментариях привели примеры обхода ограничений оболочки.
В данном решение существуют следующие уязвимости (Shell Escape), которые необходимо обязательно учитывать:
| PATH | Возможность изменить переменную PATH |
| Копирование файлов по scp | Возможность загрузить свой скрипт |
| При подключении по ssh можно изменить оболочку |
|
| При подключении по ssh можно изменить файл конфигурации оболочки |
|
| При подключении по ssh можно использовать ShellShock |
|
| Через утилиты vi, vim |
|
| Через утилиты vi, vim |
|
| Через утилиты man, more, less |
|
| Через утилиту find |
|
| Через утилиту awk |
|
| Через утилиту nmap |
|
| Через утилиту nmap |
|
| Через perl |
|
| Через python |
|
| Через ruby |
|
| Через LD_PRELOAD | Создаем файл evil.c:
Компилируем:
Передаем полученный файл evil.so на машину с закрытой консолью и выполняем:
В качестве аргумента любая доступная команда |
В связи с наличием достаточно большого количества уязвимостей, данный способ можно использовать только для локального пользователя на не критических системах, для доступа по сети через ssh лучше использовать chroot или другие утилиты ограничения возможностей пользователей.
Надеюсь данная информация будет полезной.
