chroot
— это, по сути, процесс (и соответствующая команда) для изменения корневой директории для пользователя. Незаменим в ситуации, когда, например, требуется запустить незнакомую программу. А также в тех случаях, когда надо пустить на сервер пользователя, дав ему возможность использовать железо на в полную мощность (т.е. без применения виртуализации), но, при этом, обезопасившись от деструктивных действий такого пользователя (например, ему не следует разрешать бродить по файловой системе, заглядывая пускай и с права на чтение во многие системные файлы).
Недостаток chroot
в том, что для запертого в нём пользователя, требуется собирать какое-то минимальное окружение. Например, копировать в виртуальный корень файл /bin/bash и все связанные файлы для того, чтобы у пользователя появилось приличное окружение. Грубо говоря, в виртуальный корень придётся скопировать часть основной системы. Это приводит к дублированию данных (например, на VPS для этого может не быть лишнего дискового пространства), усложняет обновления (если в настоящий системе обновились какие-то файлы, то их свежие копии вручную придётся копировать в chroot-окружение) и пр.
Мне захотелось как-то избавиться от этих неудобств. Притом пользователей надо было пускать в консоль только для того, чтобы они могли с помощью tar
и mysqldump
делать резервные копии своих сайтов и баз данных.
Нашлось изящное решение — lshell
.
Это пользовательский шел который разрешает залоснившемуся пользователю выполнять строго разрешённые команды. Он есть в стандартных репозиториях Ubuntu 10.10 и установить его можно так:
sudo apt-get install lshell
Теперь создадим пользователя, права которого надо сурово ограничить:
После этого, в для любого пользователя задать новую оболочку командой:
sudo adduser john
Утилита попросит вас задать пароль и указать личные данные пользователя (их можно не вводить и оставить пустыми, тупо нажимая Enter). Для нового пользователя автоматически будет добавлен домашний каталог /home/john
.
А мы установим ему нужную оболочку:
sudo usermod -s /usr/bin/lshell john
Отредактируем файл настрое lshell так, чтобы разрешить нашему новому юзеру выполнять строго определённый набор команд:
sudo nano /etc/lshell.conf
В конец файла добавим:
[john] sftp : 1 # можно соединяться по sftp allowed : ['cd','exit','ls','tar','mysqldump','mysql'] # только эти команды можно выполнять forbidden : [';', '&','`','$(', '${'] # эти управляющие символы запрещены
path : ['/var/www'] # можно кроме домашнего каталога ходить и по указанному пути
Сохраним файл (проще всего нажать F2
для этого).
И испытаем, что же дозволено нашему новичку, зайдя под ним на сервер через ssh:
ssh john@localhost
Если увидим следующее, то значит всё получилось:
You are in a limited shell. Type '?' or 'help' to get the list of allowed commands
john:~$
Набрать действительно help
стоит для того, чтобы узнать, какие команды разрешено исполнять пользователю в этой оболочке. Кроме этого рекомендую набрать lpath
, чтобы проверить, какие пути доступны пользователю. В частности, наш пользователь может перейти в указанную директорию за приделами его домашней: cd /var/www
Всё здорово. Сразу вас предостерегу: не разрешайте пользователю запускать bash
или, например, mc
, добавляя их в перечень разрешенных команд — внутри всякого рода оболочек пропадут ограничения и пользователь сможет бродить по всему диску (т.е. lshell
отслеживает и ограничивает только пути, указываемые в параметрах командной строки). Это нормально, если пользователю надо многое разрешить (тот же bash целиком, например), то следует настраивать chroot
.
Но есть другого рода проблема: если вы попытаетесь зайти от имени john
по протоколу SFTP на сервер от имени юзера, то вас туда пустит (не зря устанавливали в конфиге sftp : 1
), но ограничены вы там никак не будите. То есть тоже сможете облазить всю файловую систему, а мы же так старательно с этим боролись.
OpenSSH позволяет делать chroot и для sftp, но если этой возможностью воспользоваться, то не доступной окажется сама оболочка /usr/bin/lshell
. Поэтому есть немного кривой, но гарантированно работающий метод: надо отдать обработку sftp соединений стороннему демону (а не OpenSSH).
Есть достойный кандидат:
.MySecureShell
Для его установки надо добавить репозитории. В конец файла /etc/apt/sources.list
добавляем:
deb http://mysecureshell.free.fr/repository/index.php/ubuntu testing main
deb-src http://mysecureshell.free.fr/repository/index.php/ubuntu testing main
Потом добавляем ключ этого репозитория:
gpg --keyserver hkp://pool.sks-keyservers.net --recv-keys E328F22B; gpg --export E328F22B | sudo apt-key add -
Обновляем список пакетов и устанавливаем нашего героя:
sudo apt-get update
sudo apt-get install mysecureshell
После установки демон сам запустится. Конфиг его, если что, лежит тут: /etc/ssh/sftp_config
Но там можно ничего не менять (по умолчанию выполняется chroot), зато надо научить OpenSSH при sftp соединении отправлять пользователя к MySecureShell.
Для этого правим /etc/ssh/sshd_config
, находим там примерно такую строку:
Subsystem sftp /usr/lib/openssh/sftp-server
И заменяем её на:
Subsystem sftp /bin/MySecureShell -c sftp-server
Сохраняем файл, перезапускам демона:
service ssh resrart
Готово, можно заходить от имени john по sftp и радоваться тому, как в качестве корня файловой системы пользователю виден его домашний каталог. При этом в /var/www
доступа по sftp не будет. Если вдруг очень хочется его туда пустить и по sftp, то можно предпринять следующее:
mkdir /home/john/www chmod 777 /home/john/www
mount /var/www /home/john/www -o bind
Настоящая директория /var/www
примонтируется как поддиректория в домашний каталог пользователя.
»