Старые технологии на новый лад. FreeBSD Jails + CBSD Project
Примерно 9 лет назад, когда в моем городе появились первые безлимитные тарифы (что-то вроде 128 кбит/сек за 500 руб.), я принял решение держать в квартире собственный «сервер» для решения различных задач. Одной из первых идей было поднятие зеркала для проекта FreeBSD.org. Проработало оно где-то 2 года. Далее в этом уже не было смысла, ввиду расширения каналов и других причин.
Помимо этого, сервер принимал на себя в разные периоды времени и другие задачи:
- Хранение резервный копий данных, документов и дистрибутивов;
- Закачка торрентов;
- Раздача торрентов по DLNA и SMB на различные устройства;
- VPN-клиент к провайдеру (был даже период, когда сервер держал два PPTP соединения через MPD – для работы локального трафика и медленного безлимита);
- VPN-сервер и подключение до офисного шлюза (канал до работы);
- Asterisk сервер для IP-телефонии (в дальнейшем в доме появились всякие SPA-3112, радио-трубки и т.д.);
- FTP-служба для получения данных с IP-камеры, для сброса бекапов с Mikrotik-ов скриптами;
- И т.д. и т.п.
В качестве операционной системы первые 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;
- Безопасность и удобство. Обычно слабо совместимые вещи. Но – тут кажется это удалось совместить:
- Можно делать клетки с Read-Only корневой системой. Что на порядок усложняет внедрение в клетку RootKit-инструментария (подменяющего базовые утилиты);
- Просто ограничить взаимодействие клетки с другими клетками и с сетью интернет – в CBSD встроено управление PF/IPFW;
- За счет простоты и скорости создания новых окружений нет соблазна новое ПО поставить в базовую систему (лень лень…);
- Клетки просто резервировать export/import – значит можно чаще и по расписанию делать копии;
- Клетки просто обновлять, управляя ими из основной системы (обновлять world и обновлять установленное ПО). При этом не нужно поднимать SSH службу и настраивать Ansible и ему подобные;
- Безопасность контента. В CBSD есть встроенная возможность размещать контент и сам Jail в разных местах. И при старте клетки монтировать каталог с контентом в Jail в указанный каталог через mount_nullfs. Причем можно в режиме Read-Write, а можно в Read-Only. Это очень удобно – так как позволяет, например, написать скрипт, останавливающий клетку, производящий бекап (экспорт), и снова запускающий клетку. В итоге в архиве будет только ПО и настройки (в сжатом виде 200-300 мбайт), а контент будет отдельно и в экспорт не пойдет (например, у меня это 1 Тб торрентов). Аналогично и с OwnCloud. Серверами Samba. И т.д.
Отдельное огромное спасибо хочу сказать создателям 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: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.
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
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
###### 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 <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 port 53 keep state pass proto tcp from $mylans to keep state
cbsd jls alljails=1 shownode=1 (alias jall)
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