Предисловие


Примерно 9 лет назад, когда в моем городе появились первые безлимитные тарифы (что-то вроде 128 кбит/сек за 500 руб.), я принял решение держать в квартире собственный «сервер» для решения различных задач. Одной из первых идей было поднятие зеркала для проекта FreeBSD.org. Проработало оно где-то 2 года. Далее в этом уже не было смысла, ввиду расширения каналов и других причин.

Помимо этого, сервер принимал на себя в разные периоды времени и другие задачи:

  • Хранение резервный копий данных, документов и дистрибутивов;
  • Закачка торрентов;
  • Раздача торрентов по DLNA и SMB на различные устройства;
  • VPN-клиент к провайдеру (был даже период, когда сервер держал два PPTP соединения через MPD – для работы локального трафика и медленного безлимита);
  • VPN-сервер и подключение до офисного шлюза (канал до работы);
  • Asterisk сервер для IP-телефонии (в дальнейшем в доме появились всякие SPA-3112, радио-трубки и т.д.);
  • FTP-служба для получения данных с IP-камеры, для сброса бекапов с Mikrotik-ов скриптами;
  • И т.д. и т.п.

Общая мысль – в руках был конструктор с кучей разноцветных деталей и большое желание прикрутить еще что-нибудь эдакое. В общем то обычная ситуация для большинства системных администраторов, знающих и любящих *nix-системы.

Операционная система


В качестве операционной системы первые 4-5 лет у меня была FreeBSD. В определенный момент, когда я сменил работу и стал усиленно погружаться в технологии Microsoft – мне стало абсолютно некогда заниматься своим домашним сервером. Еще помню, что мне здорово надоело тратить время на portupgrade. Может и другие причины были, точно не помню. Но итогом был переезд на Debian (полдня) и сервер оказался надолго заброшен (использовал, но не модифицировал – лишь изредка обновлял).

И вот совсем недавно, в январские праздники, состоялся очередной возврат к истокам – сервер был вновь переустановлен – уже на FreeBSD 11. И причина тому – мое знакомство и восхищение проектом CBSD.

Причины полюбить проект CBSD


Для этого нужно вспомнить причины, по которым я ушел с FreeBSD лет 5 назад – отсутствие свободного времени, устаревшая система установки бинарных пакетов (pkg_*), неудобное управление Jails. Сложно точно сказать почему я перешел с FreeBSD на Linux тогда. Но в чем я уверен сейчас – использование проекта CBSD вместе с FreeBSD на моем сервере позволяет мне наконец то совместить и удобство, и безопасность.

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

Итак – мои причины:

  • Простота инсталляции (установить пакет cbsd, запустить начальный мастер и ответить на типовые вопросы – это 2 минуты);
  • Скорость создания новых клеток (1 минута уходит на то, чтобы, выполнив всего одну команду получить новую клетку, с выделенным IP-адресом, назначенными квотами, размещенную в своей FS на ZFS и с уже проинициализированным pkgng, которым к работе);
  • Простота переноса клеток со всеми настройками между серверами (это очень удобно и важно – так как на текущий момент у меня есть уже 5 серверов на базе FreeBSD (дома, у родителей, у тещи, на работе парочка) – и мне достаточно сделать и настроить клетку только один раз – а в дальнейшем я могу переносить ее куда угодно через export/import либо clone/migrate;
  • Безопасность и удобство. Обычно слабо совместимые вещи. Но – тут кажется это удалось совместить:

  1. Можно делать клетки с Read-Only корневой системой. Что на порядок усложняет внедрение в клетку RootKit-инструментария (подменяющего базовые утилиты);
  2. Просто ограничить взаимодействие клетки с другими клетками и с сетью интернет – в CBSD встроено управление PF/IPFW;
  3. За счет простоты и скорости создания новых окружений нет соблазна новое ПО поставить в базовую систему (лень лень…);
  4. Клетки просто резервировать export/import – значит можно чаще и по расписанию делать копии;
  5. Клетки просто обновлять, управляя ими из основной системы (обновлять world и обновлять установленное ПО). При этом не нужно поднимать SSH службу и настраивать Ansible и ему подобные;
  6. Безопасность контента. В CBSD есть встроенная возможность размещать контент и сам Jail в разных местах. И при старте клетки монтировать каталог с контентом в Jail в указанный каталог через mount_nullfs. Причем можно в режиме Read-Write, а можно в Read-Only. Это очень удобно – так как позволяет, например, написать скрипт, останавливающий клетку, производящий бекап (экспорт), и снова запускающий клетку. В итоге в архиве будет только ПО и настройки (в сжатом виде 200-300 мбайт), а контент будет отдельно и в экспорт не пойдет (например, у меня это 1 Тб торрентов). Аналогично и с OwnCloud. Серверами Samba. И т.д.

Наконец-то pkgng


Отдельное огромное спасибо хочу сказать создателям pkgng. Без разработки новой современной системы пакетного(бинарного) менеджмента проект CBSD не был бы настолько удобным как сейчас.

Появление pkgng повод «почти полностью» отказаться от /usr/ports – а точнее рассматривать его как дополнение к pkg. Я пользуюсь следующими принципами:

1. Все возможное ПО устанавливаю через pkg. При этом обновления получаю из ветки latest (правка файла /etc/pkg/FreeBSD.conf);
2. Если я понимаю (pkg info ), что какое-то ПО собрано в репозитории pkg с флагами, которые меня не устраивают, я монтирую /usr/ports внутрь клетки (причем не руками, а через фреймворк CBSD — cbsd jset mode=quiet jname=dokuwiki mount_ports=«1»), и собираю данное ПО из портов с нужными USE флагами;
3. С помощью pkg lock данное ПО, собранное с уникальными опциями, закрывается от дальнейшего автоматического обновления через pkg upgrade;

Итог – на любом количестве клеток я могу обновить 99% программ одним скриптом и с вероятностью 99% не сломаю при этом работу сервисов. Увы – 1 % всегда остается. НО – есть автоматизированные бекапы клеток. А также есть каталог с кэшем предыдущих установленных пакетов. Поэтому есть два варианта отката (откатить пакет либо откатить всю клетку). Напомню – у меня одна клетка – одна служба/сервис.

Примеры скриптов и настроек, написанных в ходе изучения CBSD:


Тестируем наличие в клетках уязвимого ПО:
#!/bin/sh

echo «Checking local SYSTEM»
pkg audit -F
echo ""
echo «Checking DokuWiki JAIL»
/usr/local/bin/cbsd jexec jname=dokuwiki pkg audit -F
echo ""
echo «Checking OwnCloud JAIL»
/usr/local/bin/cbsd jexec jname=owncloud pkg audit -F
echo ""
echo «Checking FTP Backup JAIL»
/usr/local/bin/cbsd jexec jname=ftpbackup pkg audit -F
echo ""
echo «Checking SAMBA JAIL»
/usr/local/bin/cbsd jexec jname=samba pkg audit –F

Вывод скрипта после запуска:
Checking local SYSTEM
vulnxml file up-to-date
0 problem(s) in the installed packages found.

Checking DokuWiki JAIL
vulnxml file up-to-date
0 problem(s) in the installed packages found.

Checking OwnCloud JAIL
vulnxml file up-to-date
0 problem(s) in the installed packages found.

Checking FTP Backup JAIL
vulnxml file up-to-date
0 problem(s) in the installed packages found.

Checking SAMBA JAIL
vulnxml file up-to-date
0 problem(s) in the installed packages found.

Выводим список доступных для обновления пакетов:
#!/bin/sh

echo «Checking local SYSTEM»
pkg upgrade -n
echo ""
echo «Checking DokuWiki JAIL»
/usr/local/bin/cbsd jexec jname=dokuwiki pkg upgrade -n
echo ""
echo «Checking OwnCloud JAIL»
/usr/local/bin/cbsd jexec jname=owncloud pkg upgrade -n
echo ""
echo «Checking FTP Backup JAIL»
/usr/local/bin/cbsd jexec jname=ftpbackup pkg upgrade -n
echo ""
echo «Checking SAMBA JAIL»
/usr/local/bin/cbsd jexec jname=samba pkg upgrade –n

Запуск обоих предыдущих скриптов и отсылка на почту по расписанию:
#!/bin/sh

sleep 1
echo «To: vershinin.e@gmail.com» > /root/Scripts/audit-pkg.mail
echo «Subject: Audit PKG on MAIN and JAILed systems!!!» >> /root/Scripts/audit-pkg.mail
echo "" >> /root/Scripts/audit-pkg.mail
echo "" >> /root/Scripts/audit-pkg.mail
sleep 1
`/root/Scripts/pkg-audit-all-sys.sh >> /root/Scripts/audit-pkg.mail`
sleep 1
`/root/Scripts/pkg-upgrade-all-sys.sh >> /root/Scripts/audit-pkg.mail`
sleep 1
`cat /root/Scripts/audit-pkg.mail | /usr/local/bin/msmtp vershinin.e@gmail.com`
sleep 1

Правила PF, ограничивающие доступ к клеткам и из клеток:
###### JAIL RULES ######

###### DokuWiki ########
# Default block rule
block from $dokuwiki to any
block from any to $dokuwiki
# Pass from ANY to Dokuwiki Apache HTTP
pass proto tcp from any to $dokuwiki port 80 keep state

###### FTP BACKUP ######
# Default block rule
block from $ftpbackup to any
block from any to $ftpbackup
# Pass from LAN to FTP Ports:
pass proto tcp from $mylans to $ftpbackup port 21
pass proto tcp from $mylans to $ftpbackup port {20000><20100}

###### OwnCloud ########
# Default block rule
block from $owncloud to any
block from any to $owncloud
# Pass from LAN to OwnCloud HTTP port
pass proto tcp from $mylans to $owncloud port 80 keep state
# Pass from WAN to OwnCloud HTTPS port
pass proto tcp from any to $owncloud port 443 keep state

###### ALL Rules for JAILs #######
pass proto icmp from $mylans to $mylans
pass proto udp from $mylans to {$dns_local $dns_google} port 53 keep state
pass proto tcp from $mylans to {$pkg_mirror1 $pkg_mirror2 $pkg_mirror3 $pkg_mirror4} keep state

Пример команды, выводящий список всех клеток и их статусов со всех подключенных серверов:
cbsd jls alljails=1 shownode=1 (alias jall)

Ее вывод:



Скрипт для регулярного экспорта клеток:
#!/bin/sh

jailname=$1

CBSDPATH=/CBSD

JAILBACKUPTARGET=/data/JAILS

backupdate=`/bin/date "+%Y-%m-%d"`

jstatus=`/usr/local/bin/cbsd jstatus $jailname`

if [ $jstatus -ne «0» ]; then
/usr/local/bin/cbsd jstop $jailname
sleep 15
fi

jstatus2=`/usr/local/bin/cbsd jstatus $jailname`

if [ $jstatus2 -eq «0» ]; then
/usr/local/bin/cbsd jexport jname=$jailname compress=0
sleep 15
fi

if [ -f $CBSDPATH/export/$jailname.img ]; then
cp $CBSDPATH/export/$jailname.img $JAILBACKUPTARGET/$jailname-$backupdate.img
sleep 5
fi

jstatus3=`/usr/local/bin/cbsd jstatus $jailname`

if [ $jstatus3 -eq «0» ]; then
/usr/local/bin/cbsd jstart $jailname
sleep 5
fi

jstatus4=`/usr/local/bin/cbsd jstatus $jailname`

if [ $jstatus4 -ne «0» ]; then
echo «Backup JAIL Finish Successfull! Jail restarted!»
fi

Резюме:


CBSD весьма интересный проект, с которым я рекомендую познакомиться поближе и иметь его в своем «портфеле готовых и удачных решений».
Поделиться с друзьями
-->

Комментарии (4)


  1. alexyr
    04.06.2017 12:56

    Насколько я понял функционал CBSD, аналог на Убунту: lxd


    1. Dorlas
      04.06.2017 13:10
      +1

      Да, если рассматривать только контейнеризацию.

      Но в CBSD есть еще поддержка Xen и Bhyve. Если учитывать это, а также то, что Web-интерфейс уже практически готов (будет как отдельный дистрибутив, так и в составе портов) — то CBSD можно сравнивать с ProxMox.


  1. firk
    04.06.2017 21:50
    +1

    Сложно представить, как можно было перейти на линукс после знакомства с freebsd jails, даже без упрощений в виде CBSD. Ну и ничего из демонов и прочего сетевого софта не ставить в базовую систему вне клеток (за теми редкими случаями, где в клетке оно не заработает) по-моему само собой разумеется.


  1. Ivan_83
    05.06.2017 03:11

    Хз что у вас там были за проблемы с портапгрейдом, давно перешёл с него на портмастер, который нынче тоже многими считается живым трупом и все фапают на poudriere.
    Кроме него ещё есть ports-mgmt/synth.
    Я лично запатчил себе портмастер чтобы он снова стал уметь работать с пакетами: https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=218348
    и дико счастлив теперь: собираю с портов всё на домашнем десктопе, оно автоматом ложится на домашний сервер в виде пакаджей. Остальные десктопные компы у меня прямо от туда обновляются этими пакаджами. Если чего то там нет то они локально компиляют, обычно это мелочи на фоне llvm, firefox и либреофиса.
    Говорят пудрель сильно круче, но мне пока не охота разбираться, хотя и придётся теперь…
    Сервера своё барахло собирают сами — обычно там малелькие пакеты которые шустро собираются, да и опции часто специфичны.

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

    Касательно PF.
    Нет никакого смысла писать 100500 раз block с разными адресами.
    Для внешних сетей лучше использовать block drop all — и вообще это годный дефолтный дроп если не нашлось разрешающего правила, а для внутренних block return in quick…
    А дальше, ИМХО, нужно писать правила только для входящего трафика, а весь исходящий разрешать, ибо для маршрутизируемого трафика мы уже проверили его на входе.

    # All from self and any inputed hosts to any, we use input checks
    pass out quick inet proto udp to 224.0.0.0/4 no state allow-opts
    pass out quick inet proto igmp to 224.0.0.0/4 no state allow-opts
    pass out quick inet proto icmp no state allow-opts
    pass out quick inet6 proto udp to ff00::/8 no state allow-opts # Allow send multicast
    pass out quick inet6 proto icmp6 no state allow-opts # mld (igmp6) also here
    pass out quick flags S/SA allow-opts

    Имеет смысл разрешать весь исходящий с опциями, чтобы игмп и ипв6 мог работать, поскольку пф дропает опции всегда, пока ему явно не разрешишь.

    ## Rules exception
    pass in quick inet proto udp to 224.0.0.0/4 no state # Allow receive multicast
    pass in quick inet proto igmp to 224.0.0.0/4 no state allow-opts
    pass in quick inet proto icmp no state
    pass in quick inet6 proto udp to ff00::/8 no state # Allow receive multicast
    pass in quick inet6 proto icmp6 no state allow-opts # mld (igmp6) also here

    Аналогично исключение для входящего локального трафика с опциями.

    Не вижу объективных причин пихать приложения по клеткам и боятся ставить их в систему.
    Даже переносимость — и то спорна. Как правило для переноса достаточно собрать приложение с такими же/нужными опциями и скопировать 1+ конфиг.
    Бэкап уже давно не проблема, начиная с дамп/ресторе которым 100 лет в обед и заканчивая модными снэпшотами как в юфс так и в зфс, ну и рсинки всякие и прочее что в портах.
    Для безопасности часто достаточно chroot, да и нужно оно мало где. У меня только php и mysql в них сидят.
    Но в целом если хочется есть MAC фреймворк, есть секуритилевел.

    Джейлы, как и виртуализации, ИМХО, хороши для:
    — тестов, когда система убивается в хлам
    — для шаред хостингов и всяких облаков: где много клиентов со своими помойками да ещё их и переносить иногда надо
    — для изоляции помоечных служб, которые написаны так криво что по другому просто никак
    — для запуска другой ОС

    2 firk
    Вирусов боятся — в сеть не ходить :)
    Приводи примеры уже, чего тебя так в сетевых службах пугает что ты их боишься?