Главная
Главная Руководства FreeBSD › FreeBSD - jail



Автор:

Статья опубликована: 2015-06-24 12:21:47
Последние правки: 2018-05-05 23:20:45

Немного про jail на FreeBSD. Установка, настройка, создание клетки, оптимизация.

  • Исходные данные
    # uname -sr
    FreeBSD 10.1-RELEASE-p13
    

  • Что такое и для чего

    О FreeBSD jail очень доступно написано в википедии, желающие могут почитать. Для ленивцев приведу цитату:

    FreeBSD Jail (англ. jail — «тюрьма») — механизм виртуализации в системе FreeBSD, позволяющий создавать внутри одной операционной системы FreeBSD несколько независимо работающих FreeBSD на том же ядре операционной системы, но совершенно независимо настраиваемых с независимым набором установленных приложений.

    Но главный плюс такой виртуализации заключается в том, что программы в клетке работают также шустро как если бы выполнялись на хостовой системе.

    Для чего это нужно? Да для чего угодно. Например, можно поднять два сервера, основной и для разработчиков. А мне jail понадобился из-за того, что не получилось подружить на одном физическом сервере домру и билайн. Настройка подключения к Билайн на FreeBSD - это вообще для мазохистов, но очень уж манящий тариф они предложили и я не смог отказаться.

    ВАЖНО! После запуска клетки вылезли две проблемы:
    • Внезапно на хост-системе перестал работать DLNA-сервер Serviio. Изучение логов показало, что он затыкался на попытке привязаться на ip, который был отдан клетке. Настроек для задания конкретного ip для serviio я не нашел (возможно, они есть в управлялке, посмотрю и напишу в статье о serviio).
    • Оказалось, что для клетки нельзя задать сетевой интерфейс, чтобы он получал ip через dhcp. Static only. Причем задавать на хост-системе.

    Так что в моем случае придется использовать VirtualBox. Поэтому статья закончится на настройке и запуске клетки. Как обустраивать клетку внутри, настройки брандмауера и прочее - ищите в Гугле. Единственное, о чем напишу дополнительно - как сделать так, чтобы в клетке работал ping.


  • Настройка

    Считаем, что:
    - сетевой интерфейс: rl0
    - наш основной ip: 192.168.100.1
    - клетки называются jail1 и jail2
    - ip клеток: 192.168.200.1 и 192.168.200.2

    /etc/rc.conf (добавить или поменять)
    ifconfig_rl0_alias0="inet 192.168.200.1 netmask 255.255.255.0"
    ifconfig_rl0_alias1="inet 192.168.200.2 netmask 255.255.255.0"
    
    jail_enable="YES"
    jail_list="jail1 jail2"
    
    syslogd_flags="-s -b 192.168.100.1"
    
    - _aliasX - прописываем статические ip для клеток (иначе никак)
    - jail_list - тут перечисляем активные клетки
    - syslogd_flags - говорим демону слушать только на своем ip

    /etc/ssh/sshd_config
    ListenAddress 192.168.100.1
    
    - sshd должен висеть только на своем ip.

    Далее, /etc/jail.conf - файл с настройками наших клеток.
    exec.start = "bin/sh /etc/rc";
    exec.stop = "/bin/sh /etc/rc.shutdown";
    exec.clean;
    mount.devfs;
    allow.mount;
    path = "/jails/$name";
    interface = "rl0";
    
    jail1 {
     host.hostname = "jail1.localnet";
     ip4.addr = "192.168.200.1";
     ip6.addr = "";
     mount.fstab = "/etc/fstab.jail1";
    }
    jail2 {
     host.hostname = "jail2.localnet";
     ip4.addr = "192.168.200.2";
     ip6.addr = "";
     mount.fstab = "/etc/fstab.jail2";
    }
    
    /etc/fstab.jail1
    # Device                Mountpoint                      FStype  Options Dump    Pass#
    
    /jails/base             /jails/jail1/.base            nullfs  ro      0       0
    /usr/ports              /jails/jail1/usr/ports      nullfs  rw      0       0
    

  • Создание клеток
    # cd /usr/src
    # make buildworld
    
    Операции ниже показаны для jail1, но их нужно выполнить для каждой клетки.
    # mkdir -p /jails/jail1
    # cd /usr/src
    # make installworld DESTDIR=/jails/jail1
    # make distribution DESTDIR=/jails/jail1
    # mount -t devfs devfs /jails/jail1/dev
    
    Для экономии места а также для удобства обновления, во всех клетках будем использовать общие системные файлы. Как это выглядит?
    - создаем директорию с общими файлами, /jails/base и в неё копируем директории и файлы из хост-системы. Для этого используем скрипт:
    #!/bin/sh
    
    DEST="/jails/base"
    
    mkdir -p $DEST
    
    # root
    LIST="bin lib libexec sbin"
    for DIR in $LIST
    do
        echo /$DIR
        cp -R /$DIR $DEST/
    done
    
    # /etc
    LIST="defaults devd gss mtree periodic rc.d unbound"
    mkdir $DEST/etc
    for DIR in $LIST
    do
        echo /etc/$DIR
        cp -R /etc/$DIR $DEST/etc/
    done
    
    # /usr
    LIST="bin games include lib lib32 libdata libexec sbin share"
    # src"
    mkdir $DEST/usr
    for DIR in $LIST
    do
        echo /usr/$DIR
        cp -R /usr/$DIR $DEST/usr/
    done
    
    chmod u+s $DEST/usr/bin/su
    
    - команда chmod в последней строчке скрипта не дает команде su при запуске из клетки завершаться с ошибкой su: not running setuid
    - директория /jails/base при старте клетки монтируется в неё как /.base (см выше содержимое файла /etc/fstab.jail1)
    - заменяем директории в клетке на ссылки из .base. Этот скрипт должен располагаться в директории /jails где находятся клетки. В качестве параметра ему нужно передать название директории клетки. Скрипт также создает внутри новой клетки директории /.base и /usr/ports
    #!/bin/sh
    
    JAILS="/jails"
    JAIL=$1
    
    mkdir -p $JAILS/$JAIL/.base
    mkdir -p $JAILS/$JAIL/usr/ports
    
    # root
    LIST="bin lib libexec sbin"
    for DIR in $LIST
    do
        chflags -R noschg $JAILS/$JAIL/$DIR
        rm -r $JAILS/$JAIL/$DIR
        ln -s .base/$DIR $JAILS/$JAIL/$DIR
    done
    
    # /etc
    mkdir -p $JAILS/$JAIL/etc
    LIST="defaults devd gss mtree periodic rc.d unbound"
    for DIR in $LIST
    do
        chflags -R noschg $JAILS/$JAIL/etc/$DIR
        rm -r $JAILS/$JAIL/etc/$DIR
        ln -s ../.base/etc/$DIR $JAILS/$JAIL/etc/$DIR
    done
    
    # /usr
    mkdir -p $JAILS/$JAIL/usr
    LIST="bin games include lib lib32 libdata libexec sbin share"
    for DIR in $LIST
    do
        chflags -R noschg $JAILS/$JAIL/usr/$DIR
        rm -r $JAILS/$JAIL/usr/$DIR
        ln -s ../.base/usr/$DIR $JAILS/$JAIL/usr/$DIR
    done
    

  • Настройка клетки - очень кратко, только чтобы клетка запустилась. Делать это нужно в хост-системе, но для каждой клетки. Просто идёте в директорию клетки и там меняете. Все пути ниже даны относительно корня клетки. Настройки показаны для jail1.

    - чтобы не было ругани при запуске, создаем пустой файл /etc/fstab

    /etc/rc.conf (если файла нет, то создаем). В него пишем:
    syslogd_flags="-s -b 192.168.200.1"
    

  • Управление

    Запускаем
    # /etc/rc.d/jail start
    
    Смотрим список работающих клеток
    # jls
    
    Останавливаем jail1
    /etc/rc.d/jail stop jail1
    
    Заходим в клетку jail1 из консоли на хост-системе
    # jexec jail1 /bin/sh
    
    О чем не забыть:
    - задать пароль рута в клетке (так как считается что это отдельная ОС и после создания клетки у root пароль пустой)


  • Если в клетке не работает ping - рассказываю, как и обещал.

    За это отвечает переменная sysctl security.jail.allow_raw_sockets. Ранее она была глобальной и оказывала воздействие на все клетки как новые так и существующие. Но так было только до FreeBSD версии 7.x.

    Начиная с FreeBSD 8.x этот и ещё несколько параметров, является локальными для каждой клетки. Список этих параметров можно найти на странице руководства jail(8).

    Управлять этими параметрами можно в момент запуска клетки, например:
    jail -c host.hostname=foo.local ip4.addr=192.168.200.1 allow.raw_sockets=1 allow.sysvipc=1 path=/jails/jail1 command=/bin/sh
    
    Либо же задав в описании клетки в /etc/jail.conf хост-системы:
    jail1 {
     allow.raw_sockets = 1;
    }
    
    Также, эти параметры можно изменять по ходу работы клетки. Например, если jid нужной клетки равен 42:
    jail -m jid=42 allow.raw_sockets=1
    
    Глобальные переменные sysctl security.jail.foo выполняют теперь роль значений по умолчанию, которые копируются в параметры новых клеток, если не указано иное. Поэтому на существующие клетки их изменение больше не влияет, даже после перезапуска клеток.