В этой инструкции я хочу пролить свет на то, насколько просто и элегантно возможно устанавливать FreeBSD в серверном окружении — на арендованном железе или в собственном датацентре, вручную или средствами оркестрации вроде Ansible. Шифрование дисков, удобное управление пространством, гипервизор для контейнеров и полных VM, удобный и понятный firewall — это всё и не только это доступно из коробки и занимает мало времени в настройке при правильном подходе.  Начнём с самого простого сценария. У нас стоит железяка или она где-то там стоит, но мы можем на CD-диске или средствами IPMI скормить .iso (или .img). Или даже еще проще — хостер предлагает образ mfsbsd прямо из интерфейса. В любом случае загружаемся с mfsbsd. Бывает, что хостер не дает FreeBSD ни в каком виде, но дает Linux Rescue. Загружаемся в линукс, скачиваем mfsbsd образ диска и накатываем на харды: root@rescue:~# wget https://mfsbsd.vx.sk/files/images/12/amd64/mfsbsd-12.1-RELEASE-amd64.img root@rescue:~# reboot Всё хорошо, когда у нас есть непосредственный доступ к монитору или получение сигнала по сети через IPMI/VNC/web. Но что делать если такой возможности нет и возможно только подключение по сети? Для этого нам нужен образ mfsbsd с уже выставленными настройками сети. Давайте соберем наш индивидуальный образ с настройками сетевого адаптера и демона SSH. Для этого нам нужен какой-то FreeBSD хост для сборки образа. Скачиваем оригинальный .iso root@ns312777:~ # fetch https://download.freebsd.org/ftp/releases/amd64/amd64/ISO-IMAGES/12.0/FreeBSD-12.0-RELEASE-amd64-dvd1.iso Маунтим root@ns312777:~ # mount -t cd9660 /dev/mdconfig -f FreeBSD-12.0-RELEASE-amd64-dvd1.iso/root/cd-rom Качаем mfsbsd root@ns312777:~ # fetch https://github.com/mmatuska/mfsbsd/archive/master.zip root@ns312777:~ # unzip master.zip && cd mfsbsd-master Меняем конфигурационные файлы. Для конфигурации IP достаточно изменить создать conf/rc.conf из conf/rc.conf.sample. Так же следует создать conf/authorized_keys и добавить свой ключ. root@ns312777:~/mfsbsd-master # ls -la conf/ Ну и поехали! root@ns312777:~/mfsbsd-master # make BASE=/root/cd-rom/usr/freebsd-dist Это компактная сборка ОС FreeBSD которая загружается прямо в память, а значит мы можем свободно делать что хотим со всеми доступными носителями. Что-то вроде Linux rescue CD. Вся прелесть этой сборки в том, что она позволяет установить FreeBSD буквально в одну команду. После Linux rescue CD или загрузки с .iso/.img мы попадаем в шелл mfsbsd. root@mfsbsd:~ # cd bin/ Чистим диски или root@mfsbsd:~/bin # ./destroygeom -d /dev/ada0 -d /dev/ada1 затем устанавливаем нашу систему. т.к. на хостах до 3 дисков я предпочитаю ставить систему в зеркале на все диски на небольшой раздел. Благодаря ZFS оставшеесе пространство можно конфигурировать как душе угодно, но об этом позже. Вот она одна единственная команда, которой устанавливается вся система. root@mfsbsd:~/bin # ./zfsinstall -d /dev/ada0 -d /dev/ada1 -d /dev/ada2 -r mirror -p zsys -z 25G для установки системы на трёх дисках в зеркале После установки, файловая система установленной ОС доступна в /mnt/, поэтому мы производим некоторую конфигурацию перед уходом в ребут: Копируем уже добавленный в образ mfsbsd ключ в систему root@mfsbsd:~/bin # mkdir /mnt/root/.ssh && cp /root/.ssh/authorized_keys /mnt/root/.ssh/ Редактируем конфиг SSH (например меняем порт и разрешаем логин рутом) root@mfsbsd:~/bin # ee /mnt/etc/ssh/sshd_config редактируем файл "загрузчика" системы root@mfsbsd:~/bin # ee /mnt/etc/rc.conf Обратите внимание на производителя вашего сетевого адептера, т.к. от этого зависит имя интерфейса. В некоторых случаях можно сделать так: ifconfig_DEFAULT="DHCP" в /etc/rc.conf Выставляем DNS root@mfsbsd:~/bin # ee /mnt/etc/resolv.conf Ну и можно вообще можно сделать так root@mfsbsd:~ # chroot /mnt и добавлять пользователя и вообще делать все из окружения уже свеже-установленной ОС. ну а мы поехали дальше root@mfsbsd:~ # reboot Перед тем как приступить к конфигурации установленной ОС, я хочу отметить еще два способа загрузки в mfsbsd.  Стандартный установщик FreeBSD:  Выбираем Live CD Создаем memory-disk Диск в памяти на необходим для работы с файлами mfsbsd, более того, mfsbsd использует /tmp/ в процессе инсталяции, поэтому там должно быть достаточно свободного места. # fetch https://github.com/mmatuska/mfsbsd/archive/master.zip # unzip master.zip && cd mfsbsd-master/tools ну а дальше уже тоже самое — ./destroygeom и ./zfsinstall Установка из предустановленного образа Linux: Если провайдер сервера дает уже установленный линукс, то мы так же можем "заинсталиться" по-своему, изменив конфигурацию загрузчика GRUB. Для этого на действующей системе нужно добавить grub.cfg следующие строки: Ну и положить соответственно .iso в /boot/boot-isos/ Сам так никогда не делал, поэтому если найдете ошибку или недочет в конфиге — дайте знать. Пожалуй как еще можно извернуться что бы установить FreeBSD я не знаю. Ну вот мы всё установили, загружаемся… Для начала работы нам нужно установить и настроить сеть — в нашем случае главную роль будет выполнять pf, мне нравится это решение за простоту и понятность. Нам нужно настроить файловую систему сервера — мы используем ZFS, потому что это невероятно гибкая и эффективная файловая система. Когда настроена сеть и ФС, мы установим гипервизор. Если нам необходим повышенный уровень безопасности, можно настроить дополнительные утилиты, я опущу их описание в этом туториале. В качестве демонстрации гибкости ZFS я опишу конфигурацию двух серверов, одного с 2-мя дисками и одного с 3-мя дисками. Так же не забываем провести апгрейд системы после установки, порой выходит так, что доступно для установки только что-то древнее. freebsd-update -r 12.1-RELEASE upgrade На момент написания этого руководства 12.1 является последней версией Сервер с двумя дисками Мы его создали в следующей конфигурации: Что всё это значит? У нас железка с двумя дисками, эти два диска оба объемом 3ТБ. Мы на сервере собираемся запустить несколько приложений, часть из них условно критичны, часть "для поиграться", поэтому не жалко утратить данные. Для найболее эффективной конфигурации дискового пространства. Что мы получаем в результате недолгих манипуляций? Пул appdata (зеркало из разделов /dev/ada0p4.eli и /dev/ada1p4.eli) для данных приложения критической важности, пул miscdata ("страйп", т.е. просто последовательно расположены данные на /dev/ada0p5.eli и /dev/ada1p5.eli) для всякой ерунды. Так же есть системный пул и своп, это так же зеркала из разделов обоих дисков. Итого мы имеем для наших приложений 1ТБ зеркалированного пространства и 3.2ТБ для экспериментов.  Как всё это настроить? Несложно. После начальной установки наш диск выглядит как-то так: Добавляем разделы на диски, сначала тот что будем зеркалировать root@:~ # gpart add -t freebsd-zfs -s 1000g /dev/ada0 root@:~ # gpart add -t freebsd-zfs -s 1000g /dev/ada1 а затем всё остальное root@:~ # gpart add -t freebsd-zfs /dev/ada0 root@:~ # gpart add -t freebsd-zfs /dev/ada1 теперь у нас есть разделы /dev/ada0p4, /dev/ada0p5, /dev/ada1p4 и /dev/ada0p5. Т.к. мы не имеем физического доступа к серверу у хостера в ДЦ, целесообразно разделы с нашими данными зашифровать. root@:~ # geli init /dev/ada0p4 root@:~ # geli init /dev/ada0p5 root@:~ # geli init /dev/ada1p4 root@:~ # geli init /dev/ada1p5 вводим пароль шифрования, затем расшифровываем разделы: root@:~ # geli attach /dev/ada0p4 root@:~ # geli attach /dev/ada0p5 root@:~ # geli attach /dev/ada1p4 root@:~ # geli attach /dev/ada1p5 теперь у нас есть разделы /dev/ada0p4.eli, /dev/ada0p5.eli, /dev/ada1p4.eli и /dev/ada0p5.eli, можем построить пулы из этих разделов Можно это заскриптить: root@:~ # zpool create appdata mirror /dev/ada0p4.eli /dev/ada1p4.eli и для данных без зеркалирования root@:~ # zpool create miscdata /dev/ada0p5.eli /dev/ada1p5.eli Ну вот и готов к бою наш сервер. Мы имеем пулы, которые в дальнейшем можем расширать посредством добавления доп. дисков. А еще есть снапшоты, как их применять опишу чуть ниже. Сервер с тремя дисками Тут немного другой конфиг. У нас есть железка с тремя SSD дисками по 450ГБ. Этот сервер будет использоваться в основном для полной виртуализации, поэтому нам нужно как можно больше пространства, но при это возможно продолжать работать после утраты одного из дисков. После начальной установки наши диски выглядят так: root@:~ # gpart show /dev/ada[0-9] Создаем разделы по 420 ГБ (до конца диска не создаем, т.к. при замене диска, его фактический размер может немного отличаться) Шифруем Что за Metadata backup? Это файл, при помощи которого можно сбросить пароль шифрования на тот, что мы ввели. Ну это на случай если потом поменял и забыл. В любом случае стоит иметь ввиду этот нюанс. Аттачим диски и создаем пул и на выходе мы получаем пул с 820 ГБ дискового пространства Собирать ZFS пулы и разных дисков разных конфигураций возможно как угодно. Это своего рода конструктор хранилища, которое можно вечно увеличивать. ZFS создаёт слой абстракции над устройствами, который позволяет достигать крайне удивительных конфигураций.  Установка и настройка гипервизора  FreeBSD предлагает из коробки два решения для "гостевых ОС" — jails и bhyve. Есть cbsd, это враппер для FreeBSD Jails, bhyve и XEN. В данном руководстве я последний затрагивать не буду, т.к. никогда им сам не пользовался. Клетки это клоны системы FreeBSD. Очень удобный инструмент для изоляции процессов. Хост система может хостить клетки любой версии ниже своей. Клетки можно переносить между хостами, снапшотить и откатывать хоть на лету. Стоит использовать клектки когда это возможно, таким образом оптимально использовать ресурс системы, не тратя его на полную виртуализацию.  bhyve в свою очередь это полноценный гипервизор, которым можно поднимать всякие Ubuntu и докеры.  root@:~ # pkg install cbsd Стоит отметить, что на момент написания руководства cbsd тянет всего 11 зависимостей размеров 35 МБ. создаем отдельный раздел на пуле для клеток root@:~ # zfs create miscdata/jails инициализируем cbsd root@:~ # env workdir="/miscdata/jails" /usr/local/cbsd/sudoexec/initenv Запускаем cbsd демона. Запускаем onestart, т.к. мы не добавили cbsd в автозапуск при загрузке системы, т.к. у нас зашифрованы разделы с данными гостевых ОС. root@:~ # service cbsdd onestart При загрузке сервера нужно к нему подключится по SSH (именно поэтому системный раздел не зашифрован, что бы загрузка системы происходила успешно без всяких там VNC/IPMI вводов паролей) и расшфифровать наши дисковые разделы скриптом ./root/attach_disks.sh. При инициализации cbsd мы указали что 192.168.0.0/24 будет подсетью для наших клеток. Ту же подсеть я планирую использовать и для полной виртуализации. Закрутим пару клеток на хосте, но перед этим настроим огненную стену, что бы NAT для клеток работал через хоста. создаем файл правил для фаервола  root@:~ # ee /etc/pf.conf загружаем правила Ну а теперь создаем клетки root@:~ # cbsd jconstruct-tui  Выбираем скачивание с репозитория базы для клеток  и еще пару клеток посредством root@:~ # cbsd jconstruct-tui затем клетки запускаем root@:~ # cbsd jstart webapp и внутри уже делаем что хотим root@:~ # cbsd jlogin webapp Вот так выглядит типичный зоопарк клеток: В webapp клетке у нас слушает nginx, а доступен он извне как раз засчет записи в /etc/pf.conf  Полная виртуализация  Для полной виртуализации нужно подключить доп. модули ядра. Возьмем наш сервер с тремя дисками В /etc/rc.conf включим режим роутера и настроим ИП хоста в подсети клеток и виртуалок Теперь настроим фаервол, похожим образом как с хостом только для клеток. IF_PUBLIC="igb0"
IP_PUBLIC="Y.Y.Y.Y" JAIL_IP_POOL="192.168.0.0/24" icmp_types="echoreq" set limit { states 100000, frags 20000, src-nodes 20000 }
set skip on lo0
scrub in all nat pass on $IF_PUBLIC from $JAIL_IP_POOL to any -> $IP_PUBLIC IP_JAIL="192.168.0.2"
PORT_JAIL="{ 80, 443 }"
rdr pass on $IF_PUBLIC proto tcp from any to $IP_PUBLIC port $PORT_JAIL -> $IP_JAIL Такс, теперь создаем виртуалку root@hyper:~ # cbsd bconstruct-tui  root@hyper:~ # cbsd bstart debian
init_systap: waiting for link: igb0
Looks like /safestore/jails/vm/debian/dsk1.vhd is empty.
May be you want to boot from CD?
[yes(1) or no(0)]
1
Temporary boot device: cd
vm_iso_path: iso-debian-10.1.0-amd64-DVD-1.iso
No such media: /safestore/jails/src/iso/cbsd-iso-debian-10.1.0-amd64-DVD-1.iso in /safestore/jails/src/iso
Shall i download it from: https://ftp.acc.umu.se/debian-cd/current/amd64/iso-dvd/ http://debian-cd.repulsive.eu/10.1.0/amd64/iso-dvd/ https://gensho.ftp.acc.umu.se/debian-cd/current/amd64/iso-dvd/ http://cdimage.debian.org/cdimage/release/10.1.0/amd64/iso-dvd/ http://debian.mirror.cambrium.nl/debian-cd/10.1.0/amd64/iso-dvd/ http://mirror.overthewire.com.au/debian-cd/10.1.0/amd64/iso-dvd/ http://ftp.crifo.org/debian-cd/10.1.0/amd64/iso-dvd/ http://debian.cse.msu.edu/debian-cd/10.1.0/amd64/iso-dvd/?
[yes(1) or no(0)]
1
Download to: /safestore/jails/src/iso/cbsd-iso-debian-10.1.0-amd64-DVD-1.iso
Scanning for fastest mirror…
Mirror source: Bytes per 3sec: Затем нам надо подключится по VNC к порту хоста 5900, я для этого использую проброс портов SSH ssh hyperhost -L 5900:localhost:5900  Устанавливаем систему. IP адрес можно выбрать что-то вроде 192.168.0.100. Добавим в /etc/pf.conf форвардинг SSH И вот мы можем подключится к нашему дебиану. Но перед этим, сделаем одну вещь. root@hyper:~ # zfs snap safestore/jails/debian/dsk1.vhd@fresh Виртулка дебиана сейчас занимает неполный гигабайт. Сделали снапшот свежей системы. Мы ведь хотим управлять нашим виртуальным хозяйством будь то 3, будь то 1300 инстансов. Для универсального управления нашими инстансами мы напишем простые сценарии.  Вот так и получился свой маленький, но удаленький TerraForm  Ну а теперь всё можно красиво управлять Внутри нашего дебиана теперь можем запустит наше приложение или любой произвольный сервис в докере, например почтовый комплекс iRedMail. Ну а зачем нам нужен был снапшот? А что бы мы могли опять что-нибудь развернуть на чистом Debian.  Я опустил другие фишки гипервизора как учет потребления ресурса и клонирование инстансов, может я выделю время под написание еще одной части руководства. User