Хакер - В гостях у чертёнка. FreeBSD глазами линуксоида
nopaywall

Содержание статьи
Первый запуск
Первое отличие от Linux, которое ты заметишь, — FreeBSD загружается в текстовом режиме. И это абсолютно нормально, GUI необходимо устанавливать отдельно.
К примеру, чтобы использовать GNOME 3, нужно проделать следующие шаги. Сперва установить сам GNOME 3 и Xorg:
# pkg install xorg gnome3
Установка GNOMEЗатем отредактировать (с помощью vi!) файл /etc/rc.conf.
dbus_enable="YES" hald_enable="YES" gdm_enable="YES" gnome_enable="YES"
Так ты активируешь средства обмена сообщениями и определения оборудования, а также необходимые GNOME службы и графический менеджер входа в систему.
И только после этого можно перезагрузиться:
# shutdown -r now
Экран входа в системуПосле входа будет стандартный интерфейс GNOME 3 без каких-либо сторонних приложений. После установки Firefox (с чем пришлось повозиться — об этом далее) он появился в приложениях.
Опять же сосредоточимся на различиях. На уровне графического интерфейса их крайне мало. Единственное отличие в интерфейсе — отсутствие кнопок минимизации/максимизации — исправляется парой щелчков мышью в твикере. Аудиофайлы MP3 проигрываются без особых проблем, видео тоже, все устройства определились и заработали.
Включаем кнопки минимизации/максимизации окна в твикереС бытовыми задачами (посерфить в интернете, послушать музыку, посмотреть видео) особых проблем нет, так что не будем задерживаться на этом и перейдем к внутренним различиям.
Под капотом
Внутри FreeBSD значительно отличается от Linux. Конечно же, здесь совсем другое ядро и большая часть рантайма (то есть стандартных библиотек и команд), но отдельно стоит отметить следующие различия:
- загрузчик — хотя сейчас ничто и не мешает использовать Grub 2, но по историческим причинам и из-за лицензирования используется собственный;
- базовый набор команд в большинстве своем совместим с тем, что в Linux, но может сильно отличаться в той части, которая касается управления оборудованием;
- своя система управления пакетами, дополненная системой так называемых портов, которая позволяет автоматически устанавливать софт из исходников;
- мощная модульная система GEOM, позволяющая строить любые мыслимые и немыслимые дисковые конфигурации;
- ZFS из коробки;
- модульный сетевой стек, своего рода аналог GEOM для обработки пакетов;
- несколько брандмауэров, включая мощный и удобный pf из OpenBSD;
- несколько NAT-подсистем.
Сравним некоторые особенности с аналогами в Linux.
Файловые системы
Во FreeBSD есть две основные файловые системы: UFS2 и ZFS. Первая ФС — внучка FFS, вторая — детище Sun.
UFS2 напоминает старые ФС Unix/Linux, такие, например, как ext2: в ней нет журнала (хотя его можно создать с помощью GEOM), но зато есть нечто под названием Soft Updates — механизм, обеспечивающий (почти) беспроблемную работу после аварийного останова. Работает он на основе отслеживания зависимостей метаданных и группирования изменений в них в атомарные записи. Это позволяет избежать неконсистентных состояний ФС, которые в противном случае могли бы помешать запуститься системе, и также позволяет выполнить проверку файловой системы в фоновом режиме.
ZFS — комбинация файловой системы с менеджером томов, портированная во FreeBSD из Solaris. По сравнению с ее ближайшим аналогом в Linux, Btrfs, ZFS более стабильная, имеет работающие аналоги RAID 5/6, поддерживает блочные устройства поверх пула (volumes), в результате чего появляется возможность создавать iSCSI-хранилища, поддерживает кеширование на SSD (что позволяет ощутимо ускорить работу, хотя и увеличивает расход памяти), дедупликацию во время работы.
Минус (по сравнению с традиционными ФС) по большей части один — требует много оперативной памяти с поддержкой ECC.
GEOM и управление дисками
GEOM — фреймворк для работы с блочными устройствами. Представляет собой нечто вроде системы модульной обработки запросов ввода-вывода на пути от диска к ФС и обратно. Один модуль (экземпляр класса в терминологии GEOM) может отвечать за разбивку диска на разделы, другой за шифрование раздела, третий за организацию RAID и так далее.
Все эти модули (экземпляры классов) можно объединять для создания самых разных конфигураций, не ограниченных какими-либо рамками. Например, создать RAID-массив из диска, раздела и зашифрованного раздела, подключенного по сети.
Некоторые из доступных классов:
- geom_ccd — concatenated disk — предназначен для создания массивов дисков. Поддерживается объединение и зеркалирование;
- geom_concat — также предназначен для объединения дисков;
- geom_eli — шифрование. Поддерживает несколько алгоритмов шифрования, два независимых ключа, аппаратное ускорение;
- geom_gate — поддержка хранения по сети. Для его использования необходимо наличие FreeBSD на устройстве, накопитель которого расшаривается;
- geom_journal — поддержка журналирования (только для UFS2);
- geom_mirror — очередная реализация зеркалирования;
- geom_raid — позволяет подключать некоторые реализации «аппаратного» RAID, поддерживаемого во многих материнских платах начального уровня.
Посмотрим, как включить шифрование с помощью geli (требуется чистый или неиспользуемый жесткий диск):
# mkdir /private # geli init ada1 # geli attach ada1 # newfs /dev/ada1.eli # mount /dev/ada1.eli /private ...работа... # umount /private # geli detach ada1
Чтобы устройство подключалось во время загрузки, нужно добавить строку в файл /etc/rc.conf:
geli_devices="ada1"
И изменить /etc/fstab. Пароль будет запрошен при загрузке.
Создание шифрованного контейнера на жестком дискеМодульный сетевой стек Netgraph
Самое ощутимое отличие сетевой подсистемы FreeBSD от таковой в Linux — альтернативный сетевой стек Netgraph. Как и GEOM, Netgraph представляет собой фреймворк, позволяющий строить очень гибкие конфигурации обработки информации, но в этот раз не запросов ввода-вывода, а сетевых пакетов.
В терминологии Netgraph каждый обработчик пакетов называется узлом, принадлежащим определенному типу. У узла есть вход и выход (называемые хуками). Проходя через узлы, пакет может видоизменяться, инкапсулироваться в другой пакет и так далее.
FreeBSD поддерживает десятки различных типов узлов, вот только часть из них:
- ng_ether — предназначен для представления сетевой карты в виде узла;
- ng_iface — предоставляет псевдоинтерфейс для определенного стека протоколов. Используется, например, для создания PPTP VPN с помощью MPD;
- ng_ipfw — используется для интеграции ipfw и Netgraph;
- ng_nat — одна из многочисленных реализаций NAT во FreeBSD;
- ng_netflow — поддержка NetFlow; одно из наиболее распространенных применений Netgraph;
- ng_one2many — реализация дублирования пакетов. Поддерживает три алгоритма передачи: Round Robin (использующийся по умолчанию), «доставка всем» и Failover — пакет отправляется на первый «живой» хук. Также есть статистика;
- ng_pipe — простейший шейпер трафика;
- ng_tag — управление тегами mbuf (теги используются для «навешивания» служебной информации на пакет внутри ядра);
- ng_tee — аналог утилиты tee. Пакеты, проходящие через этот узел (помимо того, что идут, куда шли), могут заворачиваться и на другой.
Пример зеркалирования пакетов с помощью Netgraph (как входящих, так и исходящих):
# kldload ng_ether # ngctl mkpeer em0: tee lower left # ngctl connect em0: em0:lower upper right # ngctl name em0:lower em0_tee # ngctl mkpeer em1: one2many lower one # ngctl connect em1:lower em1: many0 upper # ngctl name em1:lower m2o_mirr # ngctl connect em0_tee: m2o_mirr: left2right many1 # ngctl connect em0_tee: m2o_mirr: right2left many2 # ifconfig em1 up
Полученная конфигурация в виде графаРазберем, что делает каждая команда. Первая загружает модуль ядра, отвечающий за представление сетевой карты в виде узла Netgraph (в моем случае карты назывались em0 и em1 и узлы Netgraph именовались соответственно). У данного типа есть три хука: lower, upper и orphans. На первый поступают исходящие со стороны системы пакеты, на второй, соответственно, попадающие с физического уровня. На третий поступают некорректные пакеты, и в нашем примере он не используется.
Следующая команда создает узел типа tee и одновременно соединяет хук lower узла em0 с хуком left вновь созданного узла, который пока еще никак не именуется.
Остановимся на типе tee подробнее. Узлы данного типа обладают четырьмя хуками: left, right, left2right и right2left. Основная его задача заключается в том, чтобы создавать «разрыв» между двумя хуками, которые обычно соединены в одном узле, и встраиваться в этот «разрыв», позволяя затем перехватывать все, что проходит через препарируемый узел.
Таким образом, третья команда устраняет созданный нами же «разрыв» между двумя хуками, позволяя пакетам идти как обычно. Первый аргумент команды ngctl connect — узел, который подключается. Второй — узел (точнее, относительный или абсолютный путь), к которому подключается первый узел. Третий аргумент — хук первого узла, четвертый — хук второго.
Четвертая команда именует ранее созданный узел.
Пятая создает узел типа one2many (который может действовать и в обратном направлении — то есть many2one), подключая хук one к хуку lower узла интерфейса, на который мы будем зеркалировать.
Шестая команда необходима для корректной работы зеркалирования — без нее система будет дублировать отдельные пакеты.
Седьмая команда подключает many1 к хуку left2right, через который проходят все входящие пакеты, поскольку они идут от хука lower узла em0 (к которому подключен хук left узла типа tee) к хуку upper (к которому, соответственно, подключен хук right).
Восьмая команда делает то же самое с исходящим трафиком, подключая many2 к right2left.
Две команды в совокупности направляют два потока через узел типа one2many на хук one, подсоединенный к узлу em1 посредством хука lower, с которого пакеты и покидают систему.
Последняя команда активирует сетевой интерфейс.
Брандмауэры
Во FreeBSD есть три брандмауэра: ipfw, pf и ipfilter (он не поддерживается и сохранен по историческим причинам). Ipfw — «родной» для FreeBSD брандмауэр, достаточно удобный и функциональный; pf — портированный из OpenBSD, легок в освоении, поддерживает продвинутые возможности, такие как пересборка пакетов, рандомизация номеров последовательности и шейпинг трафика.
Все брандмауэры также поддерживают NAT, плюс есть поддержка в подсистеме Netgraph. Как брандмауэры, так и подсистемы NAT можно комбинировать.
Для примера приведем конфиг pf для веб-сервера (наружу все, внутрь только HTTP(S)):
## Игнорируем loopback-интерфейс set skip on lo ## Блокируем все входящие, разблокируем исходящие block in all pass out all ## Пропускаем внутрь трафик на HTTP-порты pass in quick on em0 proto tcp from any to any port { 80 443 } ## Пропускаем пинги и ICMP Destination unreachable pass in inet proto icmp all icmp-type { echoreq, unreach }
Управление пакетами
Во FreeBSD есть два способа установки сторонних программ: пакеты и порты. Пакеты (как и в Linux) — это уже собранные бинарные версии программ, порты — удобная обертка для сборки из исходников, позволяющая автоматически выкачивать исходники из Сети и собирать из них бинарный пакет.
В абсолютном большинстве случаев обычным пользователям (как и подавляющему большинству администраторов) хватит пакетов. Порты же нужны для большей гибкости — например, для оптимизации ПО под конкретный процессор или для сборки приложения с определенными опциями.
До FreeBSD 9 система управления пакетами была крайне ущербна и не умела отслеживать зависимости. Начиная с версии 10 (2014 год) в качестве системы управления пакетами по умолчанию используется более продвинутая pkgng.
С pkgng, однако, тоже случаются казусы. Например, при установке Firefox на свежеустановленную систему мне «повезло» попасть на его некорректную версию в метаданных. То есть файл пакета был, но его версия (и адрес) отличались от тех, что записаны в метаданных, — в результате при попытке установить данный пакет с помощью pkg install пакетный менеджер попросту не находил указанный URL. В результате пришлось устанавливать все зависимости (благо их было не так уж много), а потом с помощью pkg add устанавливать конкретный пакет по заданному URL.
Если сравнивать с yum или apt-get — ничем особо выдающимся pkgng не отличается. Это просто еще одна система управления пакетами.
DTrace
Еще один порт из Solaris — система динамической трассировки DTrace. Эта технология объединяет в себе функциональность большого количества утилит, предоставляя возможность трассировки библиотечных функций, сисколов, функций ядра и позволяя делать гибкую выборку по тому или иному критерию. DTrace может использоваться разработчиками приложений/ядра для профилирования или системным администратором для анализа и расследования проблем.
В Linux есть аналог DTrace под названием SystemTap. Однако DTrace значительно проще в обращении.
Безопасность
FreeBSD поддерживает несколько подсистем безопасности. Самая простая с точки зрения пользователя — переменная sysctl kern.securelevel. Она позволяет указать так называемый уровень безопасности, а если точнее, уровень вседозволенности:
- 0 — без ограничений;
- 1 — безопасный режим. Нельзя снять флаги immutable и append-only с помощью chflags, запрещена запись в файлы
/dev/io,/dev/mem,/dev/kmem, а также в смонтированные дисковые устройства, запрещена загрузка и выгрузка модулей ядра с помощьюkldloadиkldunload, запрещен вход вkdb(отладчик ядра), запрещен вызов kernel panic через sysctl; - 2 — режим высокой безопасности. В дополнение к ограничениям предыдущего уровня запрещается писать в несмонтированные диски (команда newfs, создающая ФС, работать не будет). Кроме того, запрещено изменение системного времени больше чем на одну секунду;
- 3 — режим сетевой безопасности. В дополнение к перечисленному запрещается изменять правила брандмауэров.
Контейнеры
Еще в 2000 году, задолго до того, как в Linux были реализованы пространства имен и cgroups, необходимые для работы контейнеров (привет, Docker), во FreeBSD уже существовала собственная реализация контейнеров (или, по-другому, песочниц) под названием Jail.
Сегодня Jail поддерживает следующие функции:
- ограничение монтирования заданных ФС и доступа к устройствам (реализуется через devfs.rules);
- возможность присвоения IP-адреса Jail’у (а то и вовсе выделения виртуального сетевого стека);
- возможность запрета chflags на файлы (включено по умолчанию);
- вложенные Jail;
- установка собственного securelevel (не ниже securelevel в текущем Jail);
- ограничение ресурсов с помощью rctl;
- ограничение создания некоторых видов сокетов и IPC.
Jail обеспечивает хороший уровень изоляции и некоторые возможности виртуализации, однако пространства имен в Linux дают большую гибкость. Capsicum (о котором мы поговорим чуть позже) вводит понятие глобальных пространств имен, однако под этим подразумевается всего лишь разделение на подсистемы (PIDs, пути к файлам, идентификаторы ФС, SysV IPC, POSIX IPC и так далее).
TrustedBSD
FreeBSD включает фреймворк TrustedBSD, расширяющий стандартную систему безопасности Unix следующими возможностями:
- ACL — расширенная система прав доступа;
- аудит событий безопасности OpenBSM, формат файла журнала которого соответствует стандарту BSM;
- расширенные атрибуты файловой системы;
- мандатный контроль доступа с различными политиками, такими как LOMAC, BIBA и MLS;
- POSIX.1e Privileges (аналогичные Linux Capabilities), так до конца и не реализованы;
- Capsicum — фреймворк для создания песочниц в приложениях.
Привилегии POSIX.1e и Capsicum
Опишем чуть более подробно привилегии и Capsicum. Привилегии во FreeBSD аналогичны Capabilities в Linux. В файле sys/priv.h определено примерно 250 привилегий. По сравнению с 35 Capabilities в Linux здесь они гораздо более детализированы (вспомним CAP_SYS_ADMIN, по сути выдающую чрезмерно большие привилегии, которые можно было бы разбить на множество более мелких). К сожалению, не существует userland-утилит для управления привилегиями (и по архитектурным соображениям, связанным с реализацией MAC, вряд ли они появятся), и все это богатство используется только на уровне ядра да во время проверки заключенных в Jail процессов.
Capsicum же вводит во FreeBSD понятия Capability (не путать с Linux/POSIX.1e Capabilities) и capability mode, представляющий собой аналог ненастраиваемого seccomp и сильно ограничивающий доступные для программы системные вызовы. Сами же Capabilities базируются на идее «все есть файл» и расширяют файловые дескрипторы, что, по замыслу разработчиков, должно облегчить миграцию программ на новую модель безопасности. На практике, однако, некоторые сущности в системных вызовах *nix не могут быть представлены в виде файловых дескрипторов, так что, с одной стороны, Capsicum действительно облегчает миграцию (и улучшает безопасность), с другой — его применение слегка ограничено системными вызовами, где (хотя бы в теории) можно использовать файловые дескрипторы. К тому же он предназначен пока только для использования во время разработки — уже скомпилированную программу без поддержки Capsicum нельзя запустить в данной песочнице.
В общем-то, глупо было бы считать, что по безопасности какая-то из систем лучше или хуже: FreeBSD идет своим путем, Linux — своим.
Слой совместимости с Linux
FreeBSD поддерживает частичную совместимость с Linux и позволяет запускать некоторые Linux-приложения. Фактически режим совместимости представляет собой реализацию Linux ABI и системных вызовов. Для установки слоя совместимости нужно выполнить следующую команду:
# pkg install linux_base-c6
Затем загрузить модуль, отвечающий за ABI, и смонтировать linprocfs:
# kldload linux # mount -t linprocfs linproc /compat/linux/proc/
Все. Можно использовать некоторые программы, написанные для Linux.
Поддерживается также запуск в Jail-окружении.
Итоги
Если говорить о практическом применении, FreeBSD отлично подходит в качестве системы для NAS/SAN (что подтверждается большим количеством как открытых, так и проприетарных систем хранения на его основе), а также в качестве ОС для работы в сети (в качестве как домашнего, так и промышленного роутера). Как десктоп она мало интересна и не подойдет рядовым пользователям.
FreeBSD идет по отличному от Linux пути. У последней, казалось бы, гораздо больше интересных возможностей — но все они направлены на решение каких-то конкретных частных задач (хотя и не всегда — в качестве примера можно привести ту же реализацию контейнеров в Linux). Возможности FreeBSD же направлены на решение проблемы в целом (GEOM, Netgraph, Capsicum — на момент их разработки аналогов в Linux не было). Скорее всего, связано это с тем, что FreeBSD развивалась в академической среде, а Linux — это просто инструмент.
Читайте ещё больше платных статей бесплатно: https://t.me/nopaywall