Во FreeBsd средством виртуализации является jail. Примеров применения множество: вы можете создавать jailы на своем сервере для знакомых или клиентов, и это обезопасит вашу систему от их проделок, вы можете поместить (это даже рекомендуется) разные сервисы в отдельные jail, например, mysql в одной системе, apache в другой. Таким образом, взлом mysql сервера ничем не грозит веб серверу.
Управлять jailами я буду при помощи ezjail, конечно, труъ-админы могут катать километры шелл скриптов и управлять всем вручную, но уж извольте..
Для начала установим ezjail
cd /usr/ports/sysutils/ezjail make install clean rehash
Теперь проинсталируемся
ezjail-admin install
Если вы еще не собирали мир в вашей системе, то придется это сделать.
Процедура длительная, может занять несколько часов, и потребуется ребут.
cd /usr/scr make buildworld make buildkernel make installkernel reboot
На сообщения mergemaster можно нажимать enter, конфликтов быть не должно.
mergemaster -p cd /usr/src make installworld mergemaster reboot
Теперь после сборки мира и 2 ребутов можно проапргейдить наш jail (тоже не быстрое дело)
ejzail-admin update -p -i
Для успешной работы jail ему необходим ip адрес. Внешний ip адрес каждому jail это довольно жирно, поэтому давайте выделим ему локальный ip, например, 192.168.0.11
Давайте добавим этот адрес в нашу сетевую карту em0, а также не забудем разместить запись в /etc/rc.conf чтобы при перезагрузке ничего не потерялось
ifconfig em0 alias 192.168.0.11 netmask 0xffffffff echo 'ifconfig_em0_alias1="inet 192.168.0.11 netmask 255.255.255.0"' >> /etc/rc.conf
Важным условием выбора адреса является то, чтобы этот ип адрес не использовал ниодин сервис в вашей системе.
Пробуем создать jail
ezjail-admin create -r /usr/home/jails/test test 192.168.0.11
Скорее всего вы получите предупреждения, что ip 192.168.0.11 слушается другими сервисами, типа такого
This may cause some confusion, here they are: mysql mysqld 6923 11 tcp4 6 *:3306 *:* www proftpd 1400 0 tcp4 6 *:21 *:* root syslogd 1060 9 udp4 *:514 *:*
Вам нужно вырубить прослушивание всех ip адресов у этих сервисов (это логично даже с точки зрения безопасности). Как это сделать можете почитать в других статьях на этом сайте.
Когда вы отключите прослушивание ip адреса везде, тогда можно запускать jail.
Но перед запуском сначала добавим его в автозагрузку
echo 'ezjail_enable="YES"' >> /etc/rc.conf
Давайте теперь запустим созданный jail
ezjail-admin start test
Проверим запущенные jails в системе
jls
Если все нормально, то должно выдать нечто такое
# jls JID IP Address Hostname Path 1 192.168.0.11 test /usr/jails/test
Отлично, теперь у нас есть работающий jail!
Прежде чем лезть в него, нужно сразу скопировать файл /etc/resolv.conf чтобы разрешались днс адреса
cp /etc/resolv.conf /usr/jails/test/etc
Также, чтобы пинговаться внутри jail надо добавить пару строк в /etc/sysctl.conf
echo 'security.jail.allow_raw_sockets=1' >> /etc/sysctl.conf echo 'net.inet.ip.forwarding=1' >> /etc/sysctl.conf
Перезапустим сервис
service sysctl restart
Все, теперь можно зайти в клетку
jexec 1 csh
*некоторое пояснение: 1 это тот самый JID который показывался командой jls, csh это версия шелла
Первым делом в клетке необходимо создать файл /etc/fstab
touch /etc/fstab ee /etc/rc.conf
Открываем редактором /etc/rc.conf и пишем туда
network_interfaces="" rpcbind_enable="NO" cron_flags="$cron_flags -J 15" syslogd_flags="-ss" sendmail_enable="NO" sendmail_submit_enable="NO" sendmail_outbound_enable="NO" sendmail_msp_queue_enable="NO" sshd_enable="YES"
Проверяем локальный ping
test# ping 127.0.0.1 PING 127.0.0.1 (127.0.0.1): 56 data bytes 64 bytes from 127.0.0.1: icmp_seq=0 ttl=64 time=0.010 ms 64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.012 ms 64 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.014 ms
Отлично, пинг работает.
Теперь на счет внешних соединений: Если вы тестируете это на локалке, то внешние соединения из клетки заработают, если же вы делаете это на сервере, то скорее всего пакеты изнутри клетки во внешнюю сеть будут резаться уровнем выше. Для того, чтобы сеть в клетке работала нужно прибегнуть к помощи файрвола.
В качестве файрвола я буду использовать pf. Нужно выйти из клетки перед тем, как настраивать файрвол
test# exit
Оказавшись в основной системе нужно подгрузить pf как модуль ядра
kldload pf kldstat echo 'pf_enable="YES"' >> /etc/rc.conf
Создадим файл /etc/pf.conf (xxx.xxx.xxx.xxx это внешний ип адрес вашего сервера), em0 это сетевой интерфейс
В pf.conf пишем
pub="xxx.xxx.xxx.xxx" jail_net="192.168.0.11/32" jail="192.168.0.11" if="em0" set block-policy return set skip on lo scrub in nat on $if from $jail to !$jail_net -> $pub #создали nat
В конце правила не забудьте пустую строку! Теперь наша клетка находится за натом, и для хостера пакеты из нее не будут отличаться от пакетов из основной системы, и он не будет их срезать.
Теперь запустим файрвол и применим эти правила
pfctl -e pfctl -f /etc/pf.conf
Зайдем еще раз в клетку и пинганем яндекс
jexec 1 csh test# ping ya.ru PING ya.ru (87.250.250.3): 56 data bytes 64 bytes from 87.250.250.3: icmp_seq=0 ttl=57 time=65.462 ms 64 bytes from 87.250.250.3: icmp_seq=1 ttl=57 time=76.410 ms
Отлично, теперь сеть работает и у нас есть отдельная виртуальная система.