В основу FreeBSD Jail вошёл системный вызов chroot, при котором для текущего процесса и всех его потомков, корневой каталог переносится в определённое место на файловой системе. При этом это место для процесса становится корневым каталогом. Таким образом, изолированный процесс может иметь доступ только к низлежащему дереву каталогов.

Однако FreeBSD jail так же имеет поддержку на уровне ядра, что позволяет ограничивать доступ к сети, общей памяти, переменным ядра sysctl и ограничивать видимость процессов вне jail.

Процесс, заключённый в jail может иметь доступ только к определённому IP-адресу операционной системы и использовать определённый hostname. Такой процесс называется «изолированный процесс» или «Jailed-процесс».

Таким образом, создаётся безопасная «клетка», внутри которой можно исполнять даже потенциально опасное программное обеспечение, которое не сможет никак повредить основной системе или другим таким же «клеткам». Впрочем, кое как всё-таки можно изнутри «клетки» повлиять на процессы вне её — FreeBSD Jail не контролирует использование ресурсов (как это делает, например, OpenVZ под Linux).

Настройка

На уровне sysctl системы настраиваются привилегии Jailed-процессов:

Идентификатор sysctl Контролируемая функциональность
security.jail.chflags_allowed Возможность менять системные флаги файлов
security.jail.allow_raw_sockets Возможность создавать низкоуровневые сокеты
security.jail.sysvipc_allowed Возможность использовать System V IPC
security.jail.set_hostname_allowed Возможность задавать собственные hostname внутри Jailed-процессов (обычно hostname задаётся при вызове jail)
security.jail.enforce_statfs Возможность видеть все монтированные файловые системы внутри Jailed-процессов
security.jail.socket_unixiproute_only Ограничение по возможности создания UNIX/IPv4/route сокетов
security.jail.enforce_statfs Возможность видеть JAIL’у все подмонтирование устройства
security.jail.chflags_allowed Возможность использования в JAIL системных флагов (man 1 chflags)
security.jail.list Список запущеных JAIL’ов

Создание “клетки”
Скрипт создания виртуальной среды

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#!/bin/sh

# скрипт создания клеток

case "$2" in
        create)
                # стругаем клетку
                jail_dir="$1"
                mkdir -p ${jail_dir}
                cd /usr/src
                mkdir -p ${jail_dir}
                make world DESTDIR=${jail_dir}
                cd /usr/src/etc
                make distribution DESTDIR=${jail_dir}
                mount_devfs devfs ${jail_dir}/dev

                ;;
        *)
                echo ""
                echo "Usage: `basename $0` { /path/to/jail/directory create }"
                echo ""
                exit 64
                ;;
esac

Создаем тестовую “клетку”

1
./jail_create.sh /usr/local/jails/jail_test create

Корневой каталог jail точно такой как у нашей родительской(реальной) машины, в которой мы становили “клетку”.
Заводим альяс для нашей клетки – у каждой клетки свой IP адрес. А также вешаем syslogd на адрес реальной машины:
Правим /etc/rc.conf к такому виду:

1
2
3
4
ifconfig_nfe0="inet 192.168.0.31  netmask 255.255.255.0 "
ifconfig_nfe0_alias0="inet 192.168.0.100  netmask 255.255.255.0 "
...
syslogd_flags="-b 192.168.0.31"

Настройка Jail
Создаём в клетке пусой файл /etc/fstab

1
/usr/home/lissyara/>touch /usr/local/jails/jail_test/etc/fstab

Создаём в ней файл /usr/local/jails/jail_test/etc/resolv.conf такого содержания:

1
nameserver 192.168.0.1

Файл автозагрузки клетки /usr/local/jails/jail_test/etc/rc.conf

1
2
sshd_enable="YES"
inetd_enable="YES"

Демон sshd будет слушать все, назначенные системе IP адреса.
Если попробовать зайти по ssh на ip-адрес jail-машины, то мы попадем на родную.
Есть два варианта решения:
1) Указывать sshd родной машины какой слушать ip-адрес
2) Сменить порт на родной или jail-машине sshd демона

Мне больше нравиться второй вариант, поетому правим строку в
/usr/local/jails/jail_test/etc/ssh/sshd_config

1
Port 4848

Теперь на родительской машине добавляем в файл автозарузки /etc/rc.conf такие строки

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# запуск клетки
jail_enable="YES"
# список имён jail`ов разделяются пробелами
jail_list="test"
# Разрешаем root'у в клетке изменять её имя хоста
jail_set_hostname_allow="YES"
# специфичные настройки для кажой клетки
# корневая директория клетки `test`
jail_test_rootdir="/usr/local/jails/jail_test"
# имя хоста для клетки `test`
jail_test_hostname="jail-test.lan"
# IP-адрес клетки `test`
jail_test_ip="192.168.0.100"
# Монтировать devfs в клетке `test`
jail_test_devfs_enable="YES"
# монтировать procfs в клетке `test`
jail_test_procfs_enable="YES"
# Флаги для клетки `test`
jail_test_flags="-l -U root"

Входим в клетку и заводим пользователя, root’у даем пароль

1
#jail /usr/local/jails/jail_test/ test 192.168.0.100 /bin/csh

Запускаем клетку

1
2
3
4
# /etc/rc.d/jail start
Configuring jails:.
Starting jails: jail-test.lan.
#

Теперь можем зайти на нашу машину по ssh

1
#ssh 192.168.0.100 -p 4848

дальше настраиваем ОС под свои нужды.

Некоторые замечания о jail:

  • По умолчанию команда ping не работает
    1
    ping: socket: Operation not permitted

    поправить ситуацию можна из родительской машины

    1
    sysctl security.jail.allow_raw_sockets=1

Нравится эта статья? Подпишитесь на RSS-ленту и получите еще больше классной информации!