---
description: 'Клетки (jails) улучшают концепцию традиционного окружения chroot несколькими способами'
next: books/handbook/mac
params:
  path: /books/handbook/jails/
part: 'Часть III. Администрирование системы'
prev: books/handbook/security
showBookMenu: 'true'
tags: ["jails", "creating", "managing", "updating"]
title: 'Глава 17. Клетки и контейнеры'
weight: 21
---

[[jails]]
= Клетки и контейнеры
:doctype: book
:toc: macro
:toclevels: 1
:icons: font
:sectnums:
:sectnumlevels: 6
:sectnumoffset: 17
:partnums:
:source-highlighter: rouge
:experimental:
:images-path: books/handbook/jails/

ifdef::env-beastie[]
ifdef::backend-html5[]
:imagesdir: ../../../../images/{images-path}
endif::[]
ifndef::book[]
include::shared/authors.adoc[]
include::shared/mirrors.adoc[]
include::shared/releases.adoc[]
include::shared/attributes/attributes-{{% lang %}}.adoc[]
include::shared/{{% lang %}}/teams.adoc[]
include::shared/{{% lang %}}/mailing-lists.adoc[]
include::shared/{{% lang %}}/urls.adoc[]
toc::[]
endif::[]
ifdef::backend-pdf,backend-epub3[]
include::../../../../../shared/asciidoctor.adoc[]
endif::[]
endif::[]

ifndef::env-beastie[]
toc::[]
include::../../../../../shared/asciidoctor.adoc[]
endif::[]

[[jails-synopsis]]
== Обзор

Поскольку администрирование системы — сложная задача, было разработано множество инструментов, чтобы облегчить жизнь администратору. Эти инструменты часто улучшают способы установки, настройки и обслуживания систем. Один из инструментов, который можно использовать для повышения безопасности системы FreeBSD, — это _клетки (jails)_. Клетки доступны начиная с FreeBSD 4.X и продолжают совершенствоваться в плане полезности, производительности, надёжности и безопасности.

Клетки расширяют концепцию man:chroot[2], которая используется для изменения корневого каталога для набора процессов. Это создаёт безопасное окружение, изолированное от остальной системы. Процессы, созданные в окружении chroot, не могут обращаться к файлам или ресурсам за его пределами. По этой причине компрометация службы, работающей в окружении chroot, не должна позволить злоумышленнику скомпрометировать всю систему.

Однако `chroot` имеет несколько ограничений. Он подходит для простых задач, не требующих большой гибкости или сложных, продвинутых функций. Со временем было найдено множество способов выйти из окружения `chroot`, что делает его не самым идеальным решением для защиты сервисов.

Клетки улучшают концепцию традиционной изолированной среды chroot несколькими способами.

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

Эта глава охватывает:

* Что такое клетка и для каких целей он может использоваться в FreeBSD.
* Типы клеток.
* Различные способы настройки сети для клетки.
* Файл конфигурации клетки.
* Как создать различные типы клетки.
* Как запустить, остановить и перезапустить клетку.
* Основы администрирования клеток, как изнутри, так и снаружи клетки.
* Как обновить различные типы клеток.
* Неполный список различных менеджеров клеток FreeBSD.

[[jail-types]]
== Типы клеток

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

Ниже приведен список различных типов, их характеристики и рекомендации по использованию.

[[thick-jails]]
=== Толстые клетки (Thick Jails)

Толстая клетка (thick jail) — это традиционная форма клетки FreeBSD. В толстой клетке полная копия базовой системы реплицируется внутри окружения клетки. Это означает, что клетка имеет свою собственную отдельную копию базовой системы FreeBSD, включая библиотеки, исполняемые файлы и конфигурационные файлы. Клетку можно рассматривать как почти полноценную автономную установку FreeBSD, но работающую в рамках хостовой системы. Такая изоляция гарантирует, что процессы внутри клетки остаются отделёнными от процессов на хосте и в других клетках.

Преимущества толстых клеток:

* Высокая степень изоляции: процессы внутри клеток изолированы от основной системы и других клеток.
* Независимость: толстые клетки могут иметь версии библиотек, настройки и программное обеспечение, отличные от основной системы или других клеток.
* Безопасность: поскольку клетка содержит собственную базовую систему, уязвимости или проблемы, затрагивающие среду клетки, не оказывают прямого влияния на хост-систему или другие клетки.

Недостатки толстых клеток:

* Ресурсные затраты: поскольку каждая клетка поддерживает свою собственную отдельную базовую систему, толстые клетки потребляют больше ресурсов по сравнению с тонкими клетками.
* Обслуживание: каждая клетка требует собственного обслуживания и обновлений для своих базовых системных компонентов.

[[thin-jails]]
=== Тонкие клетки (Thin Jails)

Тонкая клетка (thin jail) использует базовую систему через снимки OpenZFS или монтирования NullFS из шаблона. Для каждой тонкой клетки дублируется лишь минимальное подмножество базовой системы, что приводит к меньшему потреблению ресурсов по сравнению с толстой клеткой. Однако это также означает, что тонкие клетки обладают меньшей изоляцией и независимостью по сравнению с толстыми. Изменения в общих компонентах могут потенциально затрагивать несколько тонких клеток одновременно.

Вкратце, тонкая клетка в FreeBSD — это тип клетки FreeBSD, который воспроизводит значительную часть, но не всю базовую систему, в изолированной среде.

Преимущества тонких клеток:

* Эффективность использования ресурсов: тонкие клетки более эффективны в использовании ресурсов по сравнению с толстыми клетками. Поскольку они используют общую базовую систему, они занимают меньше места на диске и оперативной памяти. Это позволяет запускать больше клеток на том же оборудовании без чрезмерного потребления ресурсов.
* Быстрое развёртывание: создание и запуск тонких клеток обычно происходит быстрее по сравнению с толстыми клетками. Это может быть особенно полезно при быстром развертывании множества экземпляров.
* Унифицированное обслуживание: поскольку тонкие клетки используют большую часть базовой системы хоста, обновления и обслуживание общих компонентов базовой системы (таких как библиотеки и исполняемые файлы) необходимо выполнять только один раз на хосте. Это упрощает процесс обслуживания по сравнению с поддержкой отдельной базовой системы для каждой толстой клетки.
* Общие ресурсы: тонкие клетки могут проще разделять общие ресурсы, такие как библиотеки и исполняемые файлы, с основной системой. Это может привести к более эффективному использованию кэширования диска и повышению производительности приложений внутри клетки.

Недостатки тонких клеток:

* Уменьшенная изоляция: основной недостаток тонких клеток заключается в том, что они обеспечивают меньшую изоляцию по сравнению с толстыми клетками. Поскольку они используют значительную часть базовой системы шаблона, уязвимости или проблемы, затрагивающие общие компоненты, могут потенциально повлиять на несколько клеток одновременно.
* Проблемы безопасности: уменьшенная изоляция в тонких клетках может представлять угрозу безопасности, так как компрометация одной клетки может с большей вероятностью повлиять на другие клетки или на хост-систему.
* Конфликты зависимостей: если нескольким тонким клеткам требуются разные версии одних и тех же библиотек или программного обеспечения, управление зависимостями может усложниться. В некоторых случаях это может потребовать дополнительных усилий для обеспечения совместимости.
* Проблемы совместимости: приложения в тонкой клетке могут столкнуться с проблемами совместимости, если они рассчитаны на определённое окружение базовой системы, отличающееся от общих компонентов, предоставляемых шаблоном.

[[service-jails]]
=== Сервисные клетки (Service Jails)

Сервисная клетка (service jail) напрямую разделяет всё дерево файловой системы с хостом (корневой путь клетки — [.filename]#/#) и, таким образом, может получать доступ и изменять любые файлы на хосте, а также использует те же учётные записи пользователей, что и хост. По умолчанию у неё нет доступа к сети или другим ресурсам, ограниченным в клетках, но её можно настроить для повторного использования сети хоста и снятия некоторых ограничений клетки. Основное применение сервисных клеток — автоматическое ограничение служб/демонов внутри клетки с минимальной настройкой и без необходимости знания файлов, требуемых такой службой/демоном. Сервисные клетки появились в FreeBSD 15.

Преимущества сервисных клеток:

* Нулевое администрирование: для службы, готовой к использованию в клетке, достаточно одной строки конфигурации в [.filename]#/etc/rc.conf#, для службы, не готовой к использованию в клетке, требуется две строки конфигурации.
* Ресурсоэффективность: сервисные клетки более эффективны в использовании ресурсов, чем тонкие клетки, так как они не требуют дополнительного дискового пространства или сетевых ресурсов.
* Быстрое развёртывание: создание и запуск сервисных клеток обычно выполняется быстрее по сравнению с тонкими клетками, если требуется изолировать только отдельные сервисы/демоны и не нужны параллельные экземпляры одного и того же сервиса/демона.
* Общие ресурсы: сервисные окружения разделяют все ресурсы, такие как библиотеки и исполняемые файлы, с основной системой. Это может привести к более эффективному использованию кэширования диска и повышению производительности приложений внутри окружения.
* Изоляция процессов: сервисные клетки изолируют определённую службу, она не может видеть процессы, которые не являются дочерними по отношению к этой сервисной клетке, даже если они выполняются в рамках той же учётной записи пользователя.

Недостатки сервисных клеток:

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

Большая часть настройки клеток, обсуждаемая ниже, не требуется для сервисных клеток. Чтобы понять, как работают клетки, рекомендуется разобраться в этих возможностях конфигурации. Подробности о том, что необходимо для настройки сервисной клетки, приведены в crossref:jails[service-jails-config, Настройка сервисных клеток].

[[vnet-jails]]
=== Клетки VNET

Клетка FreeBSD VNET — это виртуализированная среда, которая обеспечивает изоляцию и контроль сетевых ресурсов для процессов, выполняющихся внутри неё. Она предоставляет высокий уровень сетевой сегментации и безопасности, создавая отдельный сетевой стек для процессов внутри клетки, что гарантирует изоляцию сетевого трафика внутри клетки от основной системы и других клеток.

По сути, механизм VNET в FreeBSD добавляет возможность настройки сети. Это означает, что клетку VNET можно создать как толстой, так и тонкой.

[[linux-jails]]
=== Клетки Linux

Клетки Linux в FreeBSD — это функция в операционной системе FreeBSD, которая позволяет использовать исполняемые файлы Linux и приложения внутри клетки FreeBSD. Эта функциональность достигается за счёт совместимости, которая позволяет транслировать и выполнять определённые Linux-системные вызовы и библиотеки в ядре FreeBSD. Цель клеток Linux — облегчить выполнение Linux-программ в системе FreeBSD без необходимости в отдельной виртуальной машине или среде Linux.

[[host-configuration]]
== Конфигурация хоста

Прежде чем создавать клетку на хостовой системе, необходимо выполнить определённые настройки и получить некоторую информацию от хостовой системы.

Потребуется настроить утилиту man:jail[8], создать необходимые каталоги для настройки и установки клетки, получить информацию о сети хоста и проверить, использует ли хост файловую систему OpenZFS или UFS.

[TIP]
====
Версия FreeBSD, работающая в клетке, не может быть новее версии, работающей на хосте.
====

[[host-configuration-jail-utility]]
=== Утилита jail

Утилита man:jail[8] управляет клетками.

Чтобы запускать клетки при загрузке системы, выполните следующие команды:

[source, shell]
....
# sysrc jail_enable="YES"
# sysrc jail_parallel_start="YES"
....

[TIP]
====
С `jail_parallel_start` все настроенные клетки будут запущены в фоновом режиме.
====

[[jails-networking]]
=== Сетевое взаимодействие

Сеть для клеток FreeBSD может быть настроена несколькими различными способами:

Режим сетевого взаимодействия хоста (разделение IP)::
В режиме сетевого взаимодействия хоста (host networking) клетка использует тот же сетевой стек, что и основная система. При создании клетки в этом режиме она использует тот же сетевой интерфейс и IP-адрес. Это означает, что клетка не имеет отдельного IP-адреса, и его сетевой трафик ассоциируется с IP-адресом хоста.

Виртуальные сети (VNET)::
Виртуальные сети (VNET) — это функция клеток FreeBSD, предоставляющая более продвинутые и гибкие сетевые решения по сравнению с базовыми режимами, такими как общая сетевая модель (host networking). VNET позволяет создавать изолированные сетевые стеки для каждой клетки, предоставляя им отдельные IP-адреса, таблицы маршрутизации и сетевые интерфейсы. Это обеспечивает более высокий уровень сетевой изоляции и позволяет клеткам функционировать так, как если бы они работали на отдельных виртуальных машинах.

Система netgraph::
man:netgraph[4] — это универсальная инфраструктура ядра для создания пользовательских сетевых конфигураций. Она может использоваться для определения того, как сетевой трафик передаётся между клеткой и основной системой, а также между различными клетками.

[[host-configuration-directories]]
=== Настройка дерева каталогов клетки

Для файлов клеток не назначено какого-то заранее определённого места.

Некоторые администраторы используют [.filename]#/jail#, другие — [.filename]#/usr/jail#, а третьи — [.filename]#/usr/local/jails#. В этой главе будет использоваться [.filename]#/usr/local/jails#.

Помимо каталога [.filename]#/usr/local/jails# будут созданы другие каталоги:

* [.filename]#media# будет содержать сжатые файлы загруженных пользовательских окружений.
* [.filename]#templates# будет содержать шаблоны при использовании тонких клеток.
* [.filename]#containers# будет содержать клетки.

При использовании OpenZFS выполните следующие команды для создания наборов данных для этих каталогов:

[source, shell]
....
# zfs create -o mountpoint=/usr/local/jails zroot/jails
# zfs create zroot/jails/media
# zfs create zroot/jails/templates
# zfs create zroot/jails/containers
....

[TIP]
====
В данном случае для родительского набора данных использовался `zroot`, но могли быть использованы и другие наборы данных.
====

При использовании UFS выполните следующие команды для создания каталогов:

[source, shell]
....
# mkdir /usr/local/jails/
# mkdir /usr/local/jails/media
# mkdir /usr/local/jails/templates
# mkdir /usr/local/jails/containers
....

[[jail-configuration-files]]
=== Файлы конфигурации клетки

Существует два способа настройки клеток.

Первый вариант — добавить запись для каждой клетки в файл [.filename]#/etc/jail.conf#. Другой вариант — создать отдельный файл для каждой клетки в каталоге [.filename]#/etc/jail.conf.d/#.

В случае, если на хостовой системе мало клеток, записи для каждого клетки можно добавить в файл [.filename]#/etc/jail.conf#. Если на хостовой системе много клеток, рекомендуется создать отдельный конфигурационный файл для каждой клетки в каталоге [.filename]#/etc/jail.conf.d/#.

Файлы в [.filename]#/etc/jail.conf.d/# должны иметь расширение `.conf` и должны быть подключены в [.filename]#/etc/jail.conf#:

[.programlisting]
....
.include "/etc/jail.conf.d/*.conf";
....

Типичная запись jail выглядит следующим образом:

[.programlisting]
....
jailname { <.>
  # STARTUP/LOGGING
  exec.start = "/bin/sh /etc/rc"; <.>
  exec.stop = "/bin/sh /etc/rc.shutdown"; <.>
  exec.consolelog = "/var/log/jail_console_${name}.log"; <.>

  # PERMISSIONS
  allow.raw_sockets; <.>
  exec.clean; <.>
  mount.devfs; <.>

  # HOSTNAME/PATH
  host.hostname = "${name}"; <.>
  path = "/usr/local/jails/containers/${name}"; <.>

  # NETWORK
  ip4.addr = 192.168.1.151; <.>
  ip6.addr = ::ffff:c0a8:197 <.>
  interface = em0; <.>
}
....

<.> `jailname` - имя клетки.
<.> `exec.start` - команда(ы), выполняемые в среде клетки при её создании. Типичная команда для выполнения - "/bin/sh /etc/rc".
<.> `exec.stop` - команда(ы), выполняемые в среде клетки перед её удалением. Типичная команда для выполнения — "/bin/sh /etc/rc.shutdown".
<.> `exec.consolelog` - файл для вывода результатов выполнения команды (stdout и stderr).
<.> `allow.raw_sockets` — разрешает создание raw-сокетов внутри клетки. Установка этого параметра позволяет использовать такие утилиты, как man:ping[8] и man:traceroute[8], внутри клетки.
<.> `exec.clean` - выполнение команд в чистом окружении.
<.> `mount.devfs` - подключает файловую систему man:devfs[5] в каталоге [.filename]#/dev# внутри chroot и применяет набор правил из параметра devfs_ruleset, чтобы ограничить видимость устройств внутри клетки.
<.> `host.hostname` - имя хоста для клетки.
<.> `path` - каталог, который будет корневым для клетки. Любые команды, выполняемые внутри клетки, либо с помощью `jail`, либо через man:jexec[8], запускаются из этого каталога.
<.> `ip4.addr` — IPv4-адрес. Существует два варианта настройки IPv4. Первый — указать IP-адрес или список IP-адресов, как показано в примере. Второй — использовать параметр `ip4` со значением `inherit`, чтобы унаследовать IP-адрес хоста.
<.> `ip6.addr` — IPv6-адрес. Существует два варианта настройки для IPv6. Первый — указать IP или список IP, как это сделано в примере. Второй — использовать `ip6` и установить значение `inherit` для наследования IP-адреса хоста.
<.> `interface` - Сетевой интерфейс для добавления IP-адресов клетки. Обычно это интерфейс хоста.

Дополнительную информацию о переменных конфигурации можно найти в man:jail[8] и man:jail.conf[5].

[[classic-jail]]
== Классическая клетка (Толстая клетка)

Эти клетки напоминают настоящую систему FreeBSD. Ими можно управлять почти так же, как обычной системой, и обновлять независимо.

[[creating-classic-jail]]
=== Создание классической клетки

В принципе, для клетки требуется только имя хоста, корневой каталог, IP-адрес и пользовательское пространство.

Пользовательское окружение для клетки можно получить с официальных серверов загрузки FreeBSD.

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

[source, shell, subs=attributes]
....
# fetch https://download.freebsd.org/ftp/releases/amd64/amd64/{rel-latest}-RELEASE/base.txz -o /usr/local/jails/media/{rel-latest}-RELEASE-base.txz
....

После завершения загрузки необходимо извлечь содержимое в каталог клетки.

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

[source, shell, subs=attributes]
....
# mkdir -p /usr/local/jails/containers/classic
# tar -xf /usr/local/jails/media/{rel-latest}-RELEASE-base.txz -C /usr/local/jails/containers/classic --unlink
....

С извлечённой пользовательской средой в каталоге клетки потребуется скопировать файлы часового пояса и DNS-сервера:

[source, shell]
....
# cp /etc/resolv.conf /usr/local/jails/containers/classic/etc/resolv.conf
# cp /etc/localtime /usr/local/jails/containers/classic/etc/localtime
....

Скопировав файлы, следующим шагом будет обновление до последнего уровня исправлений с помощью выполнения следующей команды:

[source, shell]
....
# freebsd-update -b /usr/local/jails/containers/classic/ fetch install
....

Последним шагом является настройка клетки. Необходимо добавить запись в конфигурационный файл [.filename]#/etc/jail.conf# или в [.filename]#jail.conf.d# с параметрами клетки.

Пример может выглядеть следующим образом:

[.programlisting]
....
classic {
  # STARTUP/LOGGING
  exec.start = "/bin/sh /etc/rc";
  exec.stop = "/bin/sh /etc/rc.shutdown";
  exec.consolelog = "/var/log/jail_console_${name}.log";

  # PERMISSIONS
  allow.raw_sockets;
  exec.clean;
  mount.devfs;

  # HOSTNAME/PATH
  host.hostname = "${name}";
  path = "/usr/local/jails/containers/${name}";

  # NETWORK
  ip4.addr = 192.168.1.151;
  interface = em0;
}
....

Выполните следующую команду для запуска клетки:

[source, shell]
....
# service jail start classic
....

Дополнительная информация об управлении клетками приведена в разделе crossref:jails[jail-management,Управление клетками].

[[thin-jail]]
== Тонкие клетки (Thin Jails)

Хотя тонкие клетки используют ту же технологию, что и толстые клетки, процедура их создания отличается. Тонкие клетки можно создавать с использованием снимков OpenZFS или шаблонов и NullFS. Использование снимков OpenZFS и шаблонов с NullFS имеет определённые преимущества перед классическими клетками, например, возможность быстрого создания из снимков или обновления нескольких клеток с помощью NullFS.

[[creating-thin-jail-openzfs-snapshots]]
=== Создание тонкой клетки с использованием снимков OpenZFS

Благодаря хорошей интеграции между FreeBSD и OpenZFS создание новых тонких клеток с использованием снимков OpenZFS очень просто.

Для создания тонкой клетки с использованием снимков OpenZFS первым шагом является создание дерева каталогов клетки, следуя инструкциям в crossref:jails[host-configuration-directories, "Настройка дерева каталогов клетки"].

Далее создайте шаблон. Шаблоны будут использоваться только для создания новых клеток. По этой причине они создаются в режиме "только для чтения", чтобы клетки создавались на неизменяемой основе.

Для создания набора данных для шаблона выполните следующую команду:

[source, shell, subs=attributes]
....
# zfs create -p zroot/jails/templates/{rel-latest}-RELEASE
....

Затем выполните следующую команду для загрузки пользовательской среды:

[source, shell, subs=attributes]
....
# fetch https://download.freebsd.org/ftp/releases/amd64/amd64/{rel-latest}-RELEASE/base.txz -o /usr/local/jails/media/{rel-latest}-RELEASE-base.txz
....

После завершения загрузки необходимо извлечь содержимое в каталог шаблона, выполнив следующую команду:

[source, shell, subs=attributes]
....
# tar -xf /usr/local/jails/media/{rel-latest}-RELEASE-base.txz -C /usr/local/jails/templates/{rel-latest}-RELEASE --unlink
....

Когда пользовательская среда записана в каталог шаблонов, необходимо скопировать файлы часового пояса и DNS-сервера в каталог шаблона, выполнив следующую команду:

[source, shell, subs=attributes]
....
# cp /etc/resolv.conf /usr/local/jails/templates/{rel-latest}-RELEASE/etc/resolv.conf
# cp /etc/localtime /usr/local/jails/templates/{rel-latest}-RELEASE/etc/localtime
....

Следующее, что нужно сделать, — обновиться до последнего уровня исправлений, выполнив следующую команду:

[source, shell, subs=attributes]
....
# freebsd-update -b /usr/local/jails/templates/{rel-latest}-RELEASE/ fetch install
....

После завершения обновления шаблон готов.

Для создания снимка OpenZFS из шаблона выполните следующую команду:

[source, shell, subs=attributes]
....
# zfs snapshot zroot/jails/templates/{rel-latest}-RELEASE@base
....

После создания снимка OpenZFS можно создавать бесконечное количество клеток с помощью функции клонирования OpenZFS.

Для создания тонкой клетки с именем `thinjail` выполните следующую команду:

[source, shell, subs=attributes]
....
# zfs clone zroot/jails/templates/{rel-latest}-RELEASE@base zroot/jails/containers/thinjail
....

Последним шагом является настройка клетки. Необходимо добавить запись в конфигурационный файл [.filename]#/etc/jail.conf# или в [.filename]#jail.conf.d# с параметрами клетки.

Пример может выглядеть следующим образом:

[.programlisting]
....
thinjail {
  # STARTUP/LOGGING
  exec.start = "/bin/sh /etc/rc";
  exec.stop = "/bin/sh /etc/rc.shutdown";
  exec.consolelog = "/var/log/jail_console_${name}.log";

  # PERMISSIONS
  allow.raw_sockets;
  exec.clean;
  mount.devfs;

  # HOSTNAME/PATH
  host.hostname = "${name}";
  path = "/usr/local/jails/containers/${name}";

  # NETWORK
  ip4 = inherit;
  interface = em0;
}
....

Выполните следующую команду для запуска клетки:

[source, shell]
....
# service jail start thinjail
....

Дополнительная информация об управлении клетками приведена в разделе crossref:jails[jail-management,Управление клетками].

[[creating-thin-jail-nullfs]]
=== Создание тонкой клетки с использованием NullFS

Клетка может быть создана с уменьшенным дублированием системных файлов с использованием техники тонкой клетки и NullFS для выборочного совместного использования определённых каталогов из основной системы в клетке.

Первым шагом является создание набора данных для сохранения шаблона, выполните следующую команду, если используется OpenZFS:

[source, shell, subs=attributes]
....
# zfs create -p zroot/jails/templates/{rel-latest}-RELEASE-base
....

Или эту, если используется UFS:

[source, shell, subs=attributes]
....
# mkdir /usr/local/jails/templates/{rel-latest}-RELEASE-base
....

Затем выполните следующую команду для загрузки пользовательской среды:

[source, shell, subs=attributes]
....
# fetch https://download.freebsd.org/ftp/releases/amd64/amd64/{rel-latest}-RELEASE/base.txz -o /usr/local/jails/media/{rel-latest}-RELEASE-base.txz
....

После завершения загрузки необходимо извлечь содержимое в каталог шаблона, выполнив следующую команду:

[source, shell, subs=attributes]
....
# tar -xf /usr/local/jails/media/{rel-latest}-RELEASE-base.txz -C /usr/local/jails/templates/{rel-latest}-RELEASE-base --unlink
....

Когда пользовательская среда записана в каталог шаблонов, необходимо скопировать файлы часового пояса и DNS-сервера в каталог шаблона, выполнив следующую команду:

[source, shell, subs=attributes]
....
# cp /etc/resolv.conf /usr/local/jails/templates/{rel-latest}-RELEASE-base/etc/resolv.conf
# cp /etc/localtime /usr/local/jails/templates/{rel-latest}-RELEASE-base/etc/localtime
....

После перемещения файлов в шаблон следующим шагом будет обновление до последнего уровня исправлений с помощью выполнения следующей команды:

[source, shell, subs=attributes]
....
# freebsd-update -b /usr/local/jails/templates/{rel-latest}-RELEASE-base/ fetch install
....

В дополнение к базовому шаблону также необходимо создать каталог, где будет располагаться `skeleton`. Некоторые каталоги будут скопированы из шаблона в `skeleton`.

Выполните следующую команду, чтобы создать набор данных для `skeleton` в случае использования OpenZFS:

[source, shell, subs=attributes]
....
# zfs create -p zroot/jails/templates/{rel-latest}-RELEASE-skeleton
....

Или эту в случае использования UFS:

[source, shell, subs=attributes]
....
# mkdir /usr/local/jails/templates/{rel-latest}-RELEASE-skeleton
....

Затем создайте `skeleton`-каталоги. `Skeleton`-каталоги будут содержать локальные каталоги для клеток.

Выполните следующие команды для создания каталогов:

[source, shell, subs=attributes]
....
# mkdir -p /usr/local/jails/templates/{rel-latest}-RELEASE-skeleton/home
# mkdir -p /usr/local/jails/templates/{rel-latest}-RELEASE-skeleton/usr
# mv /usr/local/jails/templates/{rel-latest}-RELEASE-base/etc /usr/local/jails/templates/{rel-latest}-RELEASE-skeleton/etc
# mv /usr/local/jails/templates/{rel-latest}-RELEASE-base/usr/local /usr/local/jails/templates/{rel-latest}-RELEASE-skeleton/usr/local
# mv /usr/local/jails/templates/{rel-latest}-RELEASE-base/tmp /usr/local/jails/templates/{rel-latest}-RELEASE-skeleton/tmp
# mv /usr/local/jails/templates/{rel-latest}-RELEASE-base/var /usr/local/jails/templates/{rel-latest}-RELEASE-skeleton/var
# mv /usr/local/jails/templates/{rel-latest}-RELEASE-base/root /usr/local/jails/templates/{rel-latest}-RELEASE-skeleton/root
....

Следующий шаг — создать символьные ссылки на `skeleton`, выполнив следующие команды:

[source, shell, subs=attributes]
....
# cd /usr/local/jails/templates/{rel-latest}-RELEASE-base/
# mkdir skeleton
# ln -s skeleton/etc etc
# ln -s skeleton/home home
# ln -s skeleton/root root
# ln -s ../skeleton/usr/local usr/local
# ln -s skeleton/tmp tmp
# ln -s skeleton/var var
....

Когда `skeleton` готов, необходимо скопировать данные в клетку.

В случае использования OpenZFS, снимки OpenZFS могут быть использованы для простого создания необходимого количества клеток с помощью выполнения следующих команд:

[source, shell, subs=attributes]
....
# zfs snapshot zroot/jails/templates/{rel-latest}-RELEASE-skeleton@base
# zfs clone zroot/jails/templates/{rel-latest}-RELEASE-skeleton@base zroot/jails/containers/thinjail
....

В случае использования UFS можно использовать программу man:cp[1], выполнив следующую команду:

[source, shell, subs=attributes]
....
# cp -R /usr/local/jails/templates/{rel-latest}-RELEASE-skeleton /usr/local/jails/containers/thinjail
....

Затем создайте каталог, в котором будут смонтированы базовый шаблон и skeleton:

[source, shell]
....
# mkdir -p /usr/local/jails/thinjail-nullfs-base
....

Добавьте запись о клетке в [.filename]#/etc/jail.conf# или файл в [.filename]#jail.conf.d# следующим образом:

[.programlisting]
....
thinjail {
  # STARTUP/LOGGING
  exec.start = "/bin/sh /etc/rc";
  exec.stop = "/bin/sh /etc/rc.shutdown";
  exec.consolelog = "/var/log/jail_console_${name}.log";

  # PERMISSIONS
  allow.raw_sockets;
  exec.clean;
  mount.devfs;

  # HOSTNAME/PATH
  host.hostname = "${name}";
  path = "/usr/local/jails/${name}-nullfs-base";

  # NETWORK
  ip4.addr = 192.168.1.153;
  interface = em0;

  # MOUNT
  mount.fstab = "/usr/local/jails/${name}-nullfs-base.fstab";
}
....

Затем создайте файл [.filename]#/usr/local/jails/thinjail-nullfs-base.fstab# следующего содержания:

[.programlisting, subs=attributes]
....
/usr/local/jails/templates/{rel-latest}-RELEASE-base  /usr/local/jails/thinjail-nullfs-base/ nullfs   ro          0 0
/usr/local/jails/containers/thinjail     /usr/local/jails/thinjail-nullfs-base/skeleton nullfs  rw  0 0
....

Выполните следующую команду для запуска клетки:

[source, shell]
....
# service jail start thinjail
....

[[creating-vnet-jail]]
=== Создание клетки VNET

В клетках FreeBSD VNET используется отдельный сетевой стек, включающий интерфейсы, IP-адреса, таблицы маршрутизации и правила межсетевого экрана.

Первым шагом для создания VNET-клетки является создание man:bridge[4] с помощью выполнения следующей команды:

[source, shell]
....
# ifconfig bridge create
....

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

[.programlisting]
....
bridge0
....

Создав `bridge`, необходимо подключить его к интерфейсу `em0` и включить оба, выполнив следующие команды:

[source, shell]
....
# ifconfig bridge0 addm em0 up
# ifconfig em0 up
....

Чтобы сохранить этот параметр после перезагрузки, добавьте следующие строки в [.filename]#/etc/rc.conf#:

[.programlisting]
....
defaultrouter="192.168.1.1"
cloned_interfaces="bridge0"
ifconfig_bridge0="inet 192.168.1.150/24 addm em0 up"
ifconfig_em0="up"
....

Для получения дополнительной информации о мостах см. crossref:advanced-networking[network-bridging, Сетевые мосты].

Следующий шаг — создать клетку, как указано выше.

Можно использовать как процедуру crossref:jails[classic-jail, Классической Клетки (Толстой клетки)], так и процедуру crossref:jails[thin-jail, Тонких Клеток]. Единственное, что изменится — это конфигурация в файле [.filename]#/etc/jail.conf#.

В качестве примера для созданной клетки будет использоваться путь [.filename]#/usr/local/jails/containers/vnet#.

Вот пример конфигурации для VNET-клетки:

[.programlisting]
....
vnet {
  # STARTUP/LOGGING
  exec.consolelog = "/var/log/jail_console_${name}.log";

  # PERMISSIONS
  allow.raw_sockets;
  exec.clean;
  mount.devfs;
  devfs_ruleset = 5;

  # PATH/HOSTNAME
  path = "/usr/local/jails/containers/${name}";
  host.hostname = "${name}";

  # VNET/VIMAGE
  vnet;
  vnet.interface = "${epair}b";

  # NETWORKS/INTERFACES
  $id = "154"; <.>
  $ip = "192.168.1.${id}/24";
  $gateway = "192.168.1.1";
  $bridge = "bridge0"; <.>
  $epair = "epair${id}";

  # ADD TO bridge INTERFACE
  exec.prestart  = "/sbin/ifconfig ${epair} create up";
  exec.prestart += "/sbin/ifconfig ${epair}a up descr jail:${name}";
  exec.prestart += "/sbin/ifconfig ${bridge} addm ${epair}a up";
  exec.start    += "/sbin/ifconfig ${epair}b ${ip} up";
  exec.start    += "/sbin/route add default ${gateway}";
  exec.start	+= "/bin/sh /etc/rc";
  exec.stop	= "/bin/sh /etc/rc.shutdown";
  exec.poststop = "/sbin/ifconfig ${bridge} deletem ${epair}a";
  exec.poststop += "/sbin/ifconfig ${epair}a destroy";
}
....

<.> Представляет IP-адрес клетки, он должен быть *уникальным*.
<.> Относится к ранее созданному мосту.

[[creating-linux-jail]]
=== Создание клетки Linux

FreeBSD может запускать Linux внутри клетки, используя crossref:linuxemu[linuxemu,Linux Binary Compatibility] и man:debootstrap[8]. Клетки не имеют собственного ядра. Они работают на ядре хостовой системы. Поэтому необходимо включить Linux Binary Compatibility в хостовой системе.

Чтобы включить ABI Linux при загрузке, выполните следующую команду:

[source, shell]
....
# sysrc linux_enable="YES"
....

После включения его можно запустить без перезагрузки, выполнив следующую команду:

[source, shell]
....
# service linux start
....

Следующим шагом будет создание клетки, как указано выше, например, в crossref:jails[creating-thin-jail-openzfs-snapshots, Создание тонкой клетки с использованием снимков OpenZFS], но *без* выполнения настройки. Клетки FreeBSD Linux требуют особой конфигурации, которая будет подробно описана ниже.

После создания клетки, как описано выше, выполните следующую команду для выполнения необходимой конфигурации и запуска клетки:

[source, shell]
....
# jail -cm \
    name=ubuntu \
    host.hostname="ubuntu.example.com" \
    path="/usr/local/jails/ubuntu" \
    interface="em0" \
    ip4.addr="192.168.1.150" \
    exec.start="/bin/sh /etc/rc" \
    exec.stop="/bin/sh /etc/rc.shutdown" \
    mount.devfs \
    devfs_ruleset=4 \
    allow.mount \
    allow.mount.devfs \
    allow.mount.fdescfs \
    allow.mount.procfs \
    allow.mount.linprocfs \
    allow.mount.linsysfs \
    allow.mount.tmpfs \
    enforce_statfs=1
....

Для доступа к клетке необходимо установить пакет package:sysutils/debootstrap[].

Выполните следующую команду для доступа к клетке FreeBSD Linux:

[source, shell]
....
# jexec -u root ubuntu
....

Внутри клетки выполните следующие команды для установки пакета package:sysutils/debootstrap[] и подготовки окружения Ubuntu:

[source, shell]
....
# pkg install debootstrap
# debootstrap jammy /compat/ubuntu
....

Когда процесс завершится и на консоли появится сообщение `Base system installed successfully`, необходимо из основной системы остановить клетки, выполнив следующую команду:

[source, shell]
....
# service jail onestop ubuntu
....

Затем добавьте запись в [.filename]#/etc/jail.conf# для Linux-контейнера:

[.programlisting]
....
ubuntu {
  # STARTUP/LOGGING
  exec.start = "/bin/sh /etc/rc";
  exec.stop = "/bin/sh /etc/rc.shutdown";
  exec.consolelog = "/var/log/jail_console_${name}.log";

  # PERMISSIONS
  allow.raw_sockets;
  exec.clean;
  mount.devfs;
  devfs_ruleset = 4;

  # HOSTNAME/PATH
  host.hostname = "${name}";
  path = "/usr/local/jails/containers/${name}";

  # NETWORK
  ip4.addr = 192.168.1.155;
  interface = em0;

  # MOUNT
  mount += "devfs     $path/compat/ubuntu/dev     devfs     rw  0 0";
  mount += "tmpfs     $path/compat/ubuntu/dev/shm tmpfs     rw,size=1g,mode=1777  0 0";
  mount += "fdescfs   $path/compat/ubuntu/dev/fd  fdescfs   rw,linrdlnk 0 0";
  mount += "linprocfs $path/compat/ubuntu/proc    linprocfs rw  0 0";
  mount += "linsysfs  $path/compat/ubuntu/sys     linsysfs  rw  0 0";
  mount += "/tmp      $path/compat/ubuntu/tmp     nullfs    rw  0 0";
  mount += "/home     $path/compat/ubuntu/home    nullfs    rw  0 0";
}
....

Затем клетку можно запустить как обычно с помощью следующей команды:

[source, shell]
....
# service jail start ubuntu
....

Окружение Ubuntu можно запустить с помощью следующей команды:

[source, shell]
....
# jexec ubuntu chroot /compat/ubuntu /bin/bash
....

Дополнительную информацию можно найти в главе crossref:linuxemu[linuxemu,Совместимость с Linux-бинарниками].

[[service-jails-config]]
=== Настройка сервисных клеток

Сервисная клетка полностью настраивается через [.filename]#/etc/rc.conf# или man:sysrc[8]. Базовые системные сервисы готовы для работы в сервисных клетках. Они содержат строку конфигурации, которая включает сеть или снимает другие ограничения клеток. Базовые системные сервисы, которые не имеет смысла запускать внутри клеток, настроены так, чтобы не запускаться как сервисные клетки, даже если они включены в [.filename]#/etc/rc.conf#. Некоторые примеры таких сервисов — это сервисы, которые хотят монтировать или размонтировать что-то в методе start или stop, или только настраивают что-то, например маршрут, межсетевой экран или подобное.

Сторонние службы могут быть или не быть готовы к использованию в сервисных клетках. Чтобы проверить, готова ли служба к работе в сервисной клетке, можно использовать следующую команду:

[source, shell]
....
# grep _svcj_options /path/to/rc.d/servicename
....

Если вывод отсутствует, служба не готова к работе в клетке или не требует дополнительных привилегий, таких как, например, доступ к сети.

Если служба не готова к работе в клетке и требует доступа к сети, её можно подготовить, добавив необходимую конфигурацию в [.filename]#/etc/rc.conf#:

[source, shell]
....
# sysrc servicename_svcj_options=net_basic
....

Для всех возможных `_svcj_options` см. справочную страницу man:rc.conf[5].

Для включения сервисной клетки для указанной службы необходимо остановить службу и установить переменную `servicename_svcj` в значение YES. Чтобы поместить man:syslogd[8] в сервисную клетку, используйте следующую последовательность команд:

[source, shell]
....
# service syslogd stop
# sysrc syslogd_svcj=YES
# service syslogd start
....

Если переменная `servicename_svcj` изменяется, службу необходимо остановить перед внесением изменений. Если она не будет остановлена, rc-фреймворк не определит корректное состояние службы и не сможет выполнить запрошенное действие.

Сервисные клетки управляются только через man:rc.conf[5]/man:sysrc[8] и команду man:service[8]. Утилиты для работы с клетками, такие как man:jls[8], описанные в crossref:jails[jail-management,Управление клетками], могут использоваться для проверки их работы, но команда man:jail[8] не предназначена для управления ими.

[[jail-management]]
== Управление клетками

После создания клетки можно выполнить ряд операций, таких как запуск, перезагрузка или удаление клетки, установка программного обеспечения в неё и т.д. В этом разделе описаны различные действия, которые можно выполнять с клетками с хоста.

[[list-running-jails]]
=== Список работающих клеток

Для вывода списка клеток, запущенных в основной системе, можно использовать команду man:jls[8]:

[source, shell]
....
# jls
....

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

....
   JID  IP Address      Hostname                      Path
     1  192.168.250.70  classic                       /usr/local/jails/containers/classic
....

man:jls[8] поддерживает аргумент `--libxo`, который через библиотеку man:libxo[3] позволяет отображать данные в других форматах, таких как `JSON`, `HTML` и т.д.

Например, выполните следующую команду для получения вывода в формате `JSON`:

[source, shell]
....
# jls --libxo=json
....

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

....
{"__version": "2", "jail-information": {"jail": [{"jid":1,"ipv4":"192.168.250.70","hostname":"classic","path":"/usr/local/jails/containers/classic"}]}}
....

[[start-jail]]
=== Запуск, перезапуск и остановка клетки

man:service[8] используется для запуска, перезагрузки или остановки клетки на хосте.

Например, чтобы запустить клетку, выполните следующую команду:

[source, shell]
....
# service jail start jailname
....

Измените аргумент `start` на `restart` или `stop`, чтобы выполнить другие действия с клеткой.

[[destroy-jail]]
=== Удаление клетки

Удаление клетки, это не просто остановка клетки с помощью man:service[8] и удаление каталога клетки и записи в [.filename]#/etc/jail.conf#.

FreeBSD очень серьезно относится к безопасности системы. По этой причине существуют определённые файлы, которые не может удалить даже пользователь root. Эта функциональность называется Флаги Файлов.

Первым шагом является остановка нужной клетки с помощью выполнения следующей команды:

[source, shell]
....
# service jail stop jailname
....

Второй шаг — удалить эти флаги с помощью man:chflags[1], выполнив следующую команду, где `classic` — имя удаляемой клетки:

[source, shell]
....
# chflags -R 0 /usr/local/jails/containers/classic
....

Третий шаг — удалить каталог, в котором находилась клетка:

[source, shell]
....
# rm -rf /usr/local/jails/containers/classic
....

Наконец, необходимо удалить запись о клетке в [.filename]#/etc/jail.conf# или в [.filename]#jail.conf.d#.

[[handle-packages-jail]]
=== Работа с пакетами в клетке

Утилита man:pkg[8] поддерживает аргумент `-j` для управления пакетами, установленными внутри клетки.

Например, чтобы установить пакет package:www/nginx-lite[] в клетке, можно выполнить следующую команду *с хоста*:

[source, shell]
....
# pkg -j classic install nginx-lite
....

Для получения дополнительной информации о работе с пакетами в FreeBSD см. crossref:ports[ports,"Установка приложений: Пакеты и порты"].

[[access-jail]]
=== Доступ к клетке

Как уже упоминалось выше, оптимальным является управление клетками из основной системы, однако в клетку можно войти с помощью man:jexec[8].

Клетку можно войти, выполнив man:jexec[8] с хоста:

[source, shell]
....
# jexec -u root jailname
....

При входе в клетку будет отображено сообщение, настроенное в man:motd[5].

[[execute-commands-jail]]
=== Выполнение команд в клетке

Для выполнения команды в клетке из основной системы можно использовать man:jexec[8].

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

[source, shell]
....
# jexec -l jailname service nginx stop
....

[[jail-upgrading]]
== Обновление клетки

Обновление клеток FreeBSD гарантирует, что изолированные среды остаются безопасными, актуальными и соответствуют последним функциям и улучшениям, доступным в экосистеме FreeBSD.

[[jails-updating]]
=== Обновление классической клетки или тонкой клетки с использованием снимков OpenZFS

Клетки *должны обновляться с основной* операционной системы. В FreeBSD по умолчанию запрещено использование man:chflags[1] в клетке. Это предотвращает обновление некоторых файлов, поэтому обновление изнутри клетки завершится ошибкой.

Для обновления клетки до последнего патч-релиза версии FreeBSD, под которой он работает, выполните следующие команды на хосте:

[source, shell]
....
# freebsd-update -j classic fetch install
# service jail restart classic
....

Для обновления клетки до новой основной или промежуточной версии сначала обновите хост-систему, как описано в crossref:cutting-edge[freebsdupdate-upgrade,"Выполнение обновлений основной и промежуточной версий"]. После обновления и перезагрузки хоста можно обновить клетку.

[TIP]
====
В случае обновления с одной версии на другую проще создать новую клетку, чем выполнять полное обновление.
====

Например, для обновления с 13.1-RELEASE до 13.2-RELEASE выполните следующие команды на хосте:

[source, shell]
....
# freebsd-update -j classic -r 13.2-RELEASE upgrade
# freebsd-update -j classic install
# service jail restart classic
# freebsd-update -j classic install
# service jail restart classic
....

[NOTE]
====
Необходимо выполнить шаг `install` дважды. Первый раз обновляется ядро, а второй — остальные компоненты.
====

Затем, если это было обновление основной версии, переустановите все установленные пакеты и перезапустите клетку снова. Это необходимо, потому что версия ABI изменяется при обновлении между основными версиями FreeBSD.

С хоста:

[source, shell]
....
# pkg -j jailname upgrade -f
# service jail restart jailname
....

[[upgrading-thin-jail]]
=== Обновление тонкой клетки с использованием NullFS

Поскольку тонкие клетки, использующие NullFS, разделяют большинство системных каталогов, их очень легко обновлять. Достаточно обновить шаблон. Это позволяет обновлять несколько клеток одновременно.

Для обновления шаблона до последнего патч-релиза версии FreeBSD, на которой он работает, выполните следующие команды на хосте:

[source, shell]
....
# freebsd-update -b /usr/local/jails/templates/13.1-RELEASE-base/ fetch install
# service jail restart
....

Для обновления шаблона до новой основной или промежуточной версии сначала обновите основную систему, как описано в crossref:cutting-edge[freebsdupdate-upgrade,"Выполнение обновлений основной и промежуточной версий"]. После обновления и перезагрузки основной системы можно обновить шаблон.

Например, для обновления с 13.1-RELEASE до 13.2-RELEASE выполните следующие команды на хосте:

[source, shell]
....
# freebsd-update -b /usr/local/jails/templates/13.1-RELEASE-base/ -r 13.2-RELEASE upgrade
# freebsd-update -b /usr/local/jails/templates/13.1-RELEASE-base/ install
# service jail restart
# freebsd-update -b /usr/local/jails/templates/13.1-RELEASE-base/ install
# service jail restart
....

[[jail-resource-limits]]
== Ограничения ресурсов клетки

Управление ресурсами основной системы, которые использует клетка — это задача, которую должен учитывать системный администратор.

Используйте man:rctl[8] для управления ресурсами хостовой системы, которые клетка может использовать.

[TIP]
====
Настройка `kern.racct.enable` должна быть включена в файле [.filename]#/boot/loader.conf#.
====

Синтаксис для ограничения ресурсов клетки выглядит следующим образом:

[.programlisting]
....
rctl -a jail:<jailname>:resource:action=amount/percentage
....

Например, чтобы ограничить максимальный объём оперативной памяти, доступной для клетки, выполните следующую команду:

[source, shell]
....
# rctl -a jail:classic:memoryuse:deny=2G
....

Чтобы ограничение сохранялось после перезагрузки системы, необходимо добавить правило в файл [.filename]#/etc/rctl.conf# следующим образом:

[.programlisting]
....
jail:classic:memoryuse:deny=2G/jail
....

Дополнительная информация об ограничениях ресурсов доступна в главе о безопасности в разделе crossref:security[security-resourcelimits,"Ограничения ресурсов"].

[[jail-managers-and-containers]]
== Менеджеры клеток и контейнеры

Как уже объяснялось ранее, каждый тип клетки FreeBSD может быть создан и настроен вручную, но в FreeBSD также существуют сторонние утилиты для упрощения настройки и администрирования.

Ниже приведён неполный список различных менеджеров клеток FreeBSD:

.Менеджеры клеток
[options="header", cols="1,1,1,1"]
|===
| Имя | Лицензия | Пакет | Documentation

| BastilleBSD
| BSD-3
| package:sysutils/bastille[]
| link:https://bastille.readthedocs.io/ru/latest/[Документация]

| pot
| BSD-3
| package:sysutils/pot[]
| link:https://pot.pizzamig.dev/[Документация]

| cbsd
| BSD-2
| package:sysutils/cbsd[]
| link:https://github.com/cbsd/cbsd[Документация]

| AppJail
| BSD-3
| package:sysutils/appjail[], для разработки package:sysutils/appjail-devel[]
| link:https://github.com/DtxdF/AppJail#getting-started[Документация]

| iocage
| BSD-2
| package:sysutils/iocage[]
| link:https://freebsd.github.io/iocage/[Документация]

| ezjail
| link:https://erdgeist.org/beerware.html[Пивная Лицензия]
| package:sysutils/ezjail[]
| link:https://erdgeist.org/arts/software/ezjail/[Документация]

|===
