Iocage es un gestor de contenedores(jails) que hace uso de las mejores funcionalidades y tecnologÃas que nos ofrece FreeBSD. Este nos facilitará la gestión en todo el ciclo de vida de la jail, creación, destrucción y actualización.
El artÃculo se componde de varias partes:
- Instalación
- Creación de una Jail
- Asignación de dirección ip
- Definición de dependencias de arranque
- Gestión de snapshots
- Instalación de software automáticamente
- Importación/Exportación de Jails
- Puntos de montaje en Jails
- Consulta de recursos Jail
- Tipos de Jails
- Update
- Update Base
- Update Paquetes/Ports
- Script actualización
- Script nueva jail
- Firewall
- Recomendaciones
Instalación
El primer paso será instalar el software:
Podemos indicarle que nos muestre colores:
Para que sea permanente habrá que exportar la variable en la shell que utilicemos, en mi caso se trata de bash:
export IOCAGE_COLOR=TRUE
Si se trata de un servidor que contendrá muchos jails debemos montar el
sistema de ficheros de descriptores de ficheros
, de este modo el acceso será mas rápido:
Para que sea permanente:
fdescfs /dev/fd fdescfs rw 0 0
Si tenemos mas de un zpool debemos indicarle a Iocage cual de ellos utilizar:
NAME SIZE ALLOC FREE CKPOINT EXPANDSZ FRAG CAP DEDUP HEALTH ALTROOT
storage 928G 35.8G 892G - - 1% 3% 1.00x ONLINE -
zroot 109G 16.0G 93.0G - - 3% 14% 1.00x ONLINE -
En mi caso zroot:
Nos bajamos la versión de FreeBSD que actuará como base de las jails:
Press [Enter] to fetch the default selection: (12.1)
ENTER
Para proporcionar red a las Jails se utilizan alias en la interfaz del padre, al ser alias estas son ips del padre y de la Jail simultáneamente, esto implica ciertos problemas si bindeamos en todas las direcciones disponibles los servicios del padre, por ejemplo si lo hacemos con el servicio Ssh mientras la Jail tenga el servicio arrancado se servirá en esa ip el Ssh de la Jail, si se apaga el Ssh de la Jail se servirá el Ssh del padre, esto puede llevar a confusión.
Cualquier servicio del padre se debe bindear exclusivamente a su dirección ip, en la jail no hay problema ya que solo ve la ip asignada y con un wildcard se bindea a esta única ip existente.
En el padre debemos evitar los bindeos genéricos como estos:
ListenAddress 0.0.0.0
listen *
Creación de una Jail
Creamos nuestra jail:
Comprobamos que esté up:
+-----+---------+-------+--------------+--------------+
| JID | NAME | STATE | RELEASE | IP4 |
+=====+=========+=======+==============+==============+
+-----+---------+-------+--------------+--------------+
| 5 | test | up | 12.1-RELEASE | - |
+-----+---------+-------+--------------+--------------+
Podemos acceder a la consola con el comando console:
root@test:~ # hostname
test
exit
Iocage viene con varias jails listas para ser utilizadas, las llaman plugins, con el comando list --plugins --remote podemos ver que jails hay disponibles:
Algunas de las mas populares son:
+-------------------+-------------------+-------------------+------------------+
| NAME | DESCRIPTION | PKG | ICON |
+===================+===================+===================+==================+
| Bacula-server | Manage, backup, | bacula-server | https://www.true |
+-------------------+-------------------+-------------------+------------------+
| GitLab | DevOps lifecycle | gitlab | https://www.true |
+-------------------+-------------------+-------------------+------------------+
| Jenkins | Open source build | jenkins | https://www.true |
+-------------------+-------------------+-------------------+------------------+
| Nextcloud | Suite of client- | nextcloud | https://www.true |
+-------------------+-------------------+-------------------+------------------+
| Zoneminder | Closed-circuit | zoneminder | https://www.true |
+-------------------+-------------------+-------------------+------------------+
Asignación de dirección ip
En cuanto a la asignación de direcciones ip Iocage soporta dos modos sharedIP/Vnet, pero este último es considerado inestable por lo tanto nos centraremos en sharedIP.
Las ips de las jails se configurarán en el host padre de forma automática mediante alias al arrancar la Jail en cuestión.
Primero nos aseguramos de que la jail no tenga Vnet activada:
0
Le asignamos una dirección ip:
iocage list
+-----+---------+-------+--------------+--------------+
| JID | NAME | STATE | RELEASE | IP4 |
+=====+=========+=======+==============+==============+
+-----+---------+-------+--------------+--------------+
| 5 | test | up | 12.1-RELEASE | IP_JAIL |
+-----+---------+-------+--------------+--------------+
Comprobamos que la jail conozca su ip:
nfe0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
options=8210b<RXCSUM,TXCSUM,VLAN_MTU,TSO4,WOL_MAGIC,LINKSTATE>
ether 00:00:ca:fe:00:00
inet IP_JAIL netmask 0xffffff00 broadcast 192.168.1.255
media: Ethernet autoselect (1000baseT <full-duplex,master>)
status: active
lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> metric 0 mtu 16384
options=680003<RXCSUM,TXCSUM,LINKSTATE,RXCSUM_IPV6,TXCSUM_IPV6>
groups: lo
ipfw0: flags=8800<SIMPLEX,MULTICAST> metric 0 mtu 65536
groups: ipfw
Definición de dependencias de arranque
Iocage permite definir dependencias entre jails, de este modo hasta que no arranquen las dependencias no arrancará la jail en cuestión:
Gestión de snapshots
Una de las funcionalidades mas interesantes son los snapshots, para crearlos ejecutaremos:
iocage snapshot -n testJail01 test
Para ver los snapshots de una jail:
+-----------------+-----------------------+-------+------+
| NAME | CREATED | RSIZE | USED |
+=================+=======================+=======+======+
| testJail00 | Sun Mar 29 14:06 2020 | 92K | 60K |
+-----------------+-----------------------+-------+------+
| testJail00/root | Sun Mar 29 14:06 2020 | 1.33G | 264K |
+-----------------+-----------------------+-------+------+
| testJail01 | Sun Mar 29 14:14 2020 | 92K | 0 |
+-----------------+-----------------------+-------+------+
| testJail01/root | Sun Mar 29 14:14 2020 | 1.33G | 220K |
+-----------------+-----------------------+-------+------+
NOTA: Podemos observar que hay dos snapshots, uno del directorio donde se encuentra la configuración de la Jail(config.json/fstab) y otro de la raÃz de dicha Jail.
Si queremos revertir primero paramos la jail:
Acto seguido realizamos el rollback:
NOTA: Si no revertimos al último snapshot los snapshots intermedios serán borrados, en mi caso tenÃa los snapshots testJail00 y testJail01, al revertir al testjail00, testjail01 ha sido eliminado:
+-----------------+-----------------------+-------+------+
| NAME | CREATED | RSIZE | USED |
+=================+=======================+=======+======+
| testJail00 | Sun Mar 29 14:06 2020 | 92K | 0 |
+-----------------+-----------------------+-------+------+
| testJail00/root | Sun Mar 29 14:06 2020 | 1.33G | 0 |
+-----------------+-----------------------+-------+------+
Para eliminar snapshots ejecutaremos:
Instalación de software automáticamente
Es posible instalar de forma automática ciertos paquetes en una jail cuando es creada tan solo debemos preparar la lista en formato json:
{
"pkgs": [
"ngrep",
"tcpdump"
]
}
Arrancamos la jail:
Importación/Exportación de Jails
La funcionalidad de importar en Iocage está bugeada, consume toda la RAM+SWAP del sistema, como workaround se puede exportar de forma normal, pero la importación la tendremos que hacer mediante comandos de ZFS manualmente:
scp /zroot/iocage/images/test_2020-03-28.zip REMOTE_SERVER:/zroot/iocage/images/test_2020-03-28.zip
En el servidor receptor:
zfs recv -F zroot/iocage/jails/test < zroot/iocage/images/test_2020-03-28
zfs recv -F zroot/iocage/jails/test/root < zroot/iocage/images/test_2020-03-28_root
Puntos de montaje en Jails
Si queremos montar directorios externos dentro de la jail utilizaremos el comando fstab de Iocage, en mi caso monto el directorio /storage dentro de la jail(/mnt/storage):
mkdir /mnt/storage
Podemos consultar los puntos de montaje con:
+-------+-------------------------------------------------------------------------------------------+
| INDEX | FSTAB ENTRY |
+=======+===========================================================================================+
| 0 | /storage /zroot/iocage/jails/test/root/mnt/storage nullfs rw 0 0 |
+-------+-------------------------------------------------------------------------------------------+
Consulta de recursos Jail
Otra opción muy útil es poder ver que recursos están ocupando cada jail:
+---------+-------+------+------+-------+-------+
| NAME | CRT | RES | QTA | USE | AVA |
+=========+=======+======+======+=======+=======+
| test | 1.04x | none | none | 396K | 84.1G |
+---------+-------+------+------+-------+-------+
Tipos de Jails
Iocage soporta varios tipos de jails.
-
Clone: iocage create -r [RELEASE]
Es el tipo de jail por defecto, cuando se crea una jail de este tipo se realiza un clon del snapshot de la RELEASE, consume poco espacio ya que la base es compartida entre jails y solo se guardan los datos que se cambian en su interior, cada jail de este tipo debe ser actualizada de forma independiente. Como las jails de este tipo tiene la RELEASE como base, no podremos eliminar la RELEASE hasta que hayamos eliminado todas las jails que dependan de esta. -
Base: iocage create -r [RELEASE] -b
Se trata de una jail generada a partir de una copia completa de la RELEASE pero hay ciertos directorios de la RELEASE que son montados dentro de la jail mediante nullfs, este tipo de jail ocupa menos espacio que las thick pero mas que las clone. Es el tipo ideal para parchear de forma masiva ya que mediante iocage update sobre una de las jails estaremos actualizando todas las que compartan RELEASE con esta. También se pueden actualizar todas las jails de esa RELEASE ejecutando iocage fetch RELEASE de nuevo. -
Thick: iocage create -r [RELEASE] -T
Se realiza una copia entera de la RELEASE ocupando mas espacio que los demás tipos, es una jail totalmente independiente de las demás, cada jail de este tipo debe ser actualizada de forma independiente. -
Template
Los templates son jails retocadas para servir como plantilla de despliegue rápido. Para generar un template a partir de una jail existente seguiremos los siguientes pasos:
iocage set template=yes test
Podemos consultar los templates locales:
+-----+------+-------+--------------+--------------+
| JID | NAME | STATE | RELEASE | IP4 |
+=====+======+=======+==============+==============+
| - | test | down | 12.1-RELEASE | JAIL_IP |
+-----+------+-------+--------------+--------------+
Para crear una jail a partir de un template:
El proceso de conversión a template se puede revertir mediante el parámetro template:
- Empty: iocage create -e
Son jails pensadas para testing o funcionalidades no soportadas, ideales para experimentar con RELEASES no soportadas o Linux-jails.
Normalmente utilizaremos jails de tipo clone a no ser que utilicemos templates donde debemos tener en cuenta que estos no podrán ser actualizados sin reiniciar las jails que descienden de este, para poder realizar updates en los templates sin tener que reinicar las jails estas tendrán que ser creadas de tipo Thick.
Update
Como en cualquier sistema FreeBSD la actualización del sistema operativo se divide en dos partes, el sistema base y los paquetes/ports instalados.
Update BASE
Si nos mantenemos dentro de la misma versión bastará con:
Para pasar de una versión a otra consultamos la última RELEASE disponible.
Si es una minor update, ej: 12.0 -> 12.1:
iocage update JAILNAME
Si es una major update ej: 12.1 -> 13.0, además de los pasos de una minor update debemos reinstalar los paquetes binarios/ports y terminar la actualización:
Si estamos funcionando con paquetes binarios:
pkg-static upgrade -f
exit
iocage update JAILNAME
Si estamos funcionando con ports:
git -C /usr/ports pull
cd /usr/ports
make fetchindex
for PORT in $(pkg info|awk '{print$1}'); do PORT_PATH=$(pkg info $PORT|grep Origin|awk '{print$3}') && echo PORT: $PORT - $PORT_PATH && cd /usr/ports/$PORT_PATH && export BATCH="yes" && make clean reinstall clean; done
exit
iocage update JAILNAME
NOTA: Las actualizaciones mediante Iocage realizan de forma automática un snapshot en cada actualización de este modo si algo saliese mal se podrÃa revertir sin problemas.
Update PAQUETES/PORTS
Actualizar los paquetes binarios de una jail:
Actualizar los ports de una jail:
git -C /usr/ports pull
for PORT in $(pkg info|awk '{print$1}'); do PORT_PATH=$(pkg info $PORT|grep Origin|awk '{print$3}') && echo PORT: $PORT - $PORT_PATH && cd /usr/ports/$PORT_PATH && export BATCH="yes" && make clean reinstall clean; done
Script actualización
Para que la actualización de las jails sea mas cómoda podemos escribir un script como el siguiente, este deja siempre el último snapshot por si fuese necesario revertir y los snapshots llamados PRESERVER*:
#!/usr/local/bin/bash
source /root/.scripts/cecho.sh
function sendTelegram {
message=${@:1}
curl -s -X POST https://api.telegram.org/bot535179217:AAGXRe1df_1WNgqxOCfC8VrCNKGqouhslLw/sendMessage -d chat_id=30418601 -d text="$message"
}
clear
cecho "Cyan" "<== Iocage Jail updater by kr0m ==>"
echo ""
echo ""
cecho "Cyan" ">> Converting basic_template to regular jail"
iocage set template=no basic_template
iocage start basic_template
for JAIL in $(iocage list|grep up|awk '{print$4}'); do
echo ""
echo ""
cecho "Cyan" ">> Updating Base: $JAIL"
iocage update $JAIL
done
echo ""
cecho "Green" "----------------------------------------------------"
for JAIL in $(iocage list|grep up|awk '{print$4}'); do
echo ""
echo ""
cecho "Cyan" ">> Clearing $JAIL snapshots"
SNAPSNUMBER=$(iocage snaplist $JAIL|grep -v root|grep -v '+'|grep -v 'NAME'|wc -l|awk '{print$1}')
# Check testJail
echo $JAIL |grep test_ 1>/dev/null
if [ $? -eq 0 ]; then
TESTJAIL=1
else
TESTJAIL=0
fi
if [ $SNAPSNUMBER -gt 0 ]; then
# TestJail: Delete all snapshots
if [ $TESTJAIL -eq 1 ]; then
for SNAPTOREMOVE in $(iocage snaplist $JAIL|grep -v root|grep -v '+'|grep -v 'NAME'|awk '{print$2}'); do
cecho "Cyan" "-- Removing: $SNAPTOREMOVE"
iocage snapremove -n $SNAPTOREMOVE $JAIL
done
else
# If you want to preserve some snapshot from being deleted in update process, name it PRESERVE
# Additionally we will preserve las IOC update snapshot, it always will be present because script always execute iocage update $JAIL in previous step
LAST_IOC_UPDATE=$(iocage snaplist $JAIL|grep ioc_update|grep -v 'root'|awk '{print$2}'|tail -n 1)
for SNAPTOREMOVE in $(iocage snaplist $JAIL|grep -v root|grep -v '+'|grep -v 'NAME'|grep -v 'PRESERVE'|grep -v "$LAST_IOC_UPDATE"|awk '{print$2}'); do
cecho "Cyan" "-- Removing: $SNAPTOREMOVE"
iocage snapremove -n $SNAPTOREMOVE $JAIL
done
fi
else
cecho "Cyan" "-- No snapshots to remove"
fi
done
echo ""
cecho "Green" "----------------------------------------------------"
for JAIL in $(iocage list|grep up|awk '{print$4}'); do
echo ""
echo ""
cecho "Cyan" ">> Updating PKGs: $JAIL"
iocage exec $JAIL 'ASSUME_ALWAYS_YES=yes pkg upgrade'
echo ""
cecho "Cyan" ">> Executing AUTO-REMOVE: $JAIL"
iocage exec $JAIL 'ASSUME_ALWAYS_YES=yes pkg autoremove'
done
echo ""
echo ""
cecho "Cyan" ">> Converting basic_template jail to template"
iocage stop basic_template
iocage set template=yes basic_template
echo ""
cecho "Green" "----------------------------------------------------"
echo ""
echo ""
cecho "Cyan" ">> Updating SpamAssasin: DrWho"
iocage exec DrWho 'sa-update -v'
iocage exec DrWho 'service sa-spamd restart'
echo ""
echo ""
cecho "Cyan" ">> Restarting Mail services: DrWho"
iocage exec DrWho 'service sendmail restart'
iocage exec DrWho 'service dovecot restart'
echo ""
cecho "Cyan" ">> Visit: https://mail.alfaexploit.com/?admin#/about"
echo ""
cecho "Cyan" ">> Checking if Mail system still works: DrWho"
DATE=$(date "+%d/%m/%Y %H:%M:%S")
#echo "DrWho updated: $DATE" | mail -s "DrWho updated: $DATE" kr0m@alfaexploit.com
echo -e "Subject: DrWho updated: $DATE" | sendmail -f root@alfaexploit.com kr0m@alfaexploit.com
sleep 10
grep -r "DrWho updated: $DATE" /zroot/iocage/jails/DrWho/root/var/mail/kr0m 1>/dev/null
if [ $? -ne 0 ]; then
cecho "Red" "++ ERROR: Mail system is not working"
MESSAGE="ERROR: Mail system is not working"
sendTelegram $MESSAGE
else
cecho "Cyan" ">> Mail system is working"
fi
echo ""
cecho "Green" "----------------------------------------------------"
echo ""
echo ""
cecho "Cyan" ">> Updating Python PIP: rxWod"
iocage exec rxWod 'su -l kr0m -c "/usr/home/kr0m/rxWod/bin/python3.7 -m pip install --upgrade pip"'
echo ""
cecho "Green" "----------------------------------------------------"
echo ""
echo ""
cecho "Cyan" ">> Updating git: rxWod"
iocage exec rxWod 'su -l kr0m -c "cd /home/kr0m/rxWod/rxWodProject && git status"'|grep 'nothing to commit, working tree clean' 1>/dev/null
if [ $? -eq 1 ]; then
iocage exec rxWod 'su -l kr0m -c "cd /home/kr0m/rxWod/rxWodProject && git stash"'
iocage exec rxWod 'su -l kr0m -c "cd /home/kr0m/rxWod/rxWodProject && git stash drop"'
fi
iocage exec rxWod 'su -l kr0m -c "cd /home/kr0m/rxWod/rxWodProject && git pull"'
echo ""
cecho "Green" "----------------------------------------------------"
echo ""
echo ""
cecho "Cyan" ">> Updating Python libraries: rxWod"
iocage exec rxWod 'su -l kr0m -c "cd /home/kr0m/rxWod && source bin/activate && cd rxWodProject/ && pip-upgrade -p all"'
echo ""
cecho "Green" "----------------------------------------------------"
echo ""
echo ""
cecho "Cyan" ">> Making Django migrations: rxWod"
iocage exec rxWod 'su -l kr0m -c "cd /home/kr0m/rxWod && source bin/activate && cd rxWodProject && python manage.py makemigrations"'
iocage exec rxWod 'su -l kr0m -c "cd /home/kr0m/rxWod && source bin/activate && cd rxWodProject && python manage.py migrate"'
echo ""
cecho "Green" "----------------------------------------------------"
echo ""
echo ""
cecho "Cyan" ">> Updating Yarn libraries: rxWod"
iocage exec rxWod 'su -l kr0m -c "cd /home/kr0m/rxWod/rxWodProject/ && yarn install --force"'
iocage exec rxWod 'su -l kr0m -c "cd /home/kr0m/rxWod/rxWodProject/ && yarn upgrade"'
iocage exec rxWod 'su -l kr0m -c "cd /home/kr0m/rxWod/rxWodProject/ && yarn prod-build"'
echo ""
cecho "Green" "----------------------------------------------------"
echo ""
echo ""
cecho "Cyan" ">> Collecting Django static files: rxWod"
iocage exec rxWod 'su -l kr0m -c "cd /home/kr0m/rxWod && source bin/activate && cd rxWodProject && python manage.py collectstatic --noinput"'
echo ""
cecho "Green" "----------------------------------------------------"
echo ""
echo ""
cecho "Cyan" ">> Restarting Daphne service: rxWod"
iocage exec rxWod '/usr/sbin/service daphne restart'
echo ""
cecho "Green" "----------------------------------------------------"
echo ""
echo ""
cecho "Cyan" ">> Updating owasp-modsecurity: Infinity"
iocage exec Infinity 'cd /usr/local/owasp-modsecurity-crs/ && git pull'
echo ""
cecho "Cyan" ">> Updating Hugo theme: Infinity"
iocage exec Infinity 'su -l kr0m -c "cd /home/kr0m/AlfaExploit/alfaexploit_zzo/ && git submodule update --remote --merge"'
echo ""
cecho "Cyan" ">> Redeploying Alfaexploit: Infinity"
iocage exec Infinity 'su -l kr0m -c "cd /home/kr0m/AlfaExploit/alfaexploit_zzo/ && hugo && rm -rf /usr/local/www/alfaexploit/* && cp -r public/* /usr/local/www/alfaexploit/"'
NOTA: El script cecho lo dejo un poco mas abajo, si no queremos utilizarlo tan solo debemos cambiar los cechos por echos.
Script nueva jail
Para que la creación de nuevas jails sea automática primero debemos crear una jail que servirá como base:
iocage set ip4_addr=“nfe0|192.168.69.9/24” basic_template
Instalamos el software base y realizamos la configuración básica:
Convertimos la jail en template:
iocage set template=yes basic_template
Ahora ya podemos automatizar la creación de jails con el siguiente script:
#!/usr/local/bin/bash
source /root/.scripts/cecho.sh
clear
cecho "Cyan" "<== Iocage Jail creator by kr0m ==>"
echo ""
echo ""
cecho "Green" "-- Jail name: $1"
cecho "Green" "-- IP address: $2"
if [ -z $3 ]; then
cecho "Green" "-- VNET: NO"
VNET=0
else
if [ $3 == "vnet" ]; then
cecho "Green" "-- VNET: YES"
cecho "Yellow" "-- VNET: Remember to check configuration for bridge interface"
VNET=1
else
cecho "Green" "-- VNET: NO"
VNET=0
fi
fi
echo ""
echo ""
cecho "Cyan" ">> Making basic checks"
if [ $# -ne 2 ] && [ $# -ne 3 ]; then
cecho "Red" "++ ERROR: Script needs JAIL_NAME IP_ADDRESS VNET(optional) arguments"
exit
fi
JAIL_NAME=$1
IP_ADDRESS=$2
cecho "Cyan" ">> Checking ip in correct net/range"
first_ip_address=$(echo $IP_ADDRESS|awk -F "." '{print$1}')
second_ip_address=$(echo $IP_ADDRESS|awk -F "." '{print$2}')
third_ip_address=$(echo $IP_ADDRESS|awk -F "." '{print$3}')
fourth_ip_address=$(echo $IP_ADDRESS|awk -F "." '{print$4}')
if [ $first_ip_address -eq 192 ] && [ $second_ip_address -eq 168 ] && [ $third_ip_address -eq 69 ] && [ $fourth_ip_address -lt 200 ]; then
cecho "Green" "-- Correct ip net/range"
else
if [ $first_ip_address -ne 192 ] || [ $second_ip_address -ne 168 ] || [ $third_ip_address -ne 69 ]; then
cecho "Red" "++ ERROR: Incorrect ip address NET: $IP_ADDRESS"
exit
fi
if [ $fourth_ip_address -ge 200 ]; then
cecho "Red" "++ ERROR: Ip address in DHCP range: $IP_ADDRESS"
exit
fi
fi
cecho "Cyan" ">> Checking jail names"
for JAIL in $(iocage list|grep up|awk '{print$4}'); do
if [ "$JAIL_NAME" == "$JAIL" ]; then
cecho "Red" "++ ERROR: Already running jail with name: $JAIL_NAME"
exit
fi
done
cecho "Green" "-- Correct jail name"
cecho "Cyan" ">> Checking duplicated jail ips"
for IP in $(iocage list|grep up|awk '{print$10}'); do
if [ "$IP_ADDRESS" == "$IP" ]; then
cecho "Red" "++ ERROR: Already running jail with ip: $IP_ADDRESS"
exit
fi
done
cecho "Green" "-- Correct jail ip"
cecho "Cyan" ">> Checking if base template exists"
BASE_TEMPLATE_EXISTS=$(iocage list -t|grep 'basic_template'|awk '{print$4}'|wc -l|awk '{print$1}')
if [ $BASE_TEMPLATE_EXISTS -eq 1 ]; then
cecho "Green" "-- Base template found"
else
cecho "Red" "++ ERROR: Base template not found"
exit
fi
echo ""
cecho "Green" "----------------------------------------------------"
echo ""
echo ""
cecho "Cyan" ">> Deploying: $JAIL_NAME"
iocage create -T -t basic_template -n $JAIL_NAME
if [ $VNET -eq 1 ]; then
iocage set vnet=on $JAIL_NAME
#iocage set allow_raw_sockets="1" $JAIL_NAME
iocage set defaultrouter=192.168.69.200 $JAIL_NAME
iocage set ip4_addr="vnet0|$IP_ADDRESS/24" $JAIL_NAME
else
#iocage set ip4_addr="bridge0|$IP_ADDRESS/24" $JAIL_NAME
iocage set ip4_addr="nfe0|$IP_ADDRESS/24" $JAIL_NAME
fi
iocage start $JAIL_NAME
echo ""
cecho "Green" "----------------------------------------------------"
if [ $VNET -eq 1 ]; then
echo ""
echo ""
cecho "Cyan" ">> Disabling FW: $JAIL_NAME"
iocage exec $JAIL_NAME "sysrc firewall_enable=YES"
iocage exec $JAIL_NAME "sysrc firewall_type=open"
fi
echo ""
cecho "Green" "----------------------------------------------------"
echo ""
echo ""
cecho "Cyan" ">> Setting FQDN: $JAIL_NAME"
iocage exec $JAIL_NAME "sysrc hostname=$JAIL_NAME.alfaexploit.com"
cecho "Cyan" ">> Patching /etc/hosts: $JAIL_NAME"
iocage exec $JAIL_NAME "sed -i '' 's/$JAIL_NAME//g' /etc/hosts"
JAIL_NAME2=$(echo $JAIL_NAME | tr '[:upper:]' '[:lower:]')
if [ "$JAIL_NAME" == "$JAIL_NAME2" ]; then
iocage exec $JAIL_NAME "sed -i '' 's/CUSTOM_ENTRY/$IP_ADDRESS\t\t$JAIL_NAME.alfaexploit.com $JAIL_NAME/g' /etc/hosts"
else
iocage exec $JAIL_NAME "sed -i '' 's/CUSTOM_ENTRY/$IP_ADDRESS\t\t$JAIL_NAME.alfaexploit.com $JAIL_NAME $JAIL_NAME2.alfaexploit.com $JAIL_NAME2/g' /etc/hosts"
fi
echo ""
cecho "Green" "----------------------------------------------------"
echo ""
echo ""
cecho "Cyan" ">> Restarting: $JAIL_NAME"
iocage stop $JAIL_NAME
iocage start $JAIL_NAME
echo ""
cecho "Green" "----------------------------------------------------"
echo ""
echo ""
cecho "Cyan" ">> Updating Base: $JAIL_NAME"
iocage update $JAIL_NAME
echo ""
cecho "Green" "----------------------------------------------------"
echo ""
echo ""
cecho "Cyan" ">> Clearing $JAIL_NAME snapshots"
N=$(iocage snaplist $JAIL_NAME|grep 'ioc_update'|grep -v root|grep -v '+'|grep -v 'NAME'|wc -l|awk '{print$1}')
if [ $N -gt 0 ]; then
for SNAPTOREMOVE in $(iocage snaplist $JAIL_NAME|grep 'ioc_update'|grep -v root|grep -v '+'|grep -v 'NAME'|awk '{print$2}'); do
cecho "Cyan" "-- Removing: $SNAPTOREMOVE"
iocage snapremove -n $SNAPTOREMOVE $JAIL_NAME
done
else
cecho "Cyan" "-- No snapshots to remove"
fi
echo ""
cecho "Green" "----------------------------------------------------"
echo ""
echo ""
cecho "Cyan" ">> Updating PKGs: $JAIL_NAME"
iocage exec $JAIL_NAME 'ASSUME_ALWAYS_YES=yes pkg upgrade'
iocage exec $JAIL_NAME 'ASSUME_ALWAYS_YES=yes pkg autoremove'
echo ""
cecho "Green" "----------------------------------------------------"
echo ""
echo ""
cecho "Cyan" ">> Updating pip: $JAIL_NAME"
iocage exec $JAIL_NAME 'pip install --upgrade pip'
echo ""
cecho "Green" "----------------------------------------------------"
echo ""
echo ""
cecho "Cyan" ">> Configuring SendMail Stats: $JAIL_NAME"
iocage exec $JAIL_NAME 'cd /etc/mail && make'
echo "define(\`STATUS_FILE',\`/var/log/sendmail.stats')dnl" >> /zroot/iocage/jails/$JAIL_NAME/root/etc/mail/$JAIL_NAME.alfaexploit.com.mc
iocage exec $JAIL_NAME 'cd /etc/mail && make'
iocage exec $JAIL_NAME "cp /etc/mail/$JAIL_NAME.alfaexploit.com.cf /etc/mail/sendmail.cf"
iocage exec $JAIL_NAME 'service sendmail restart'
echo ""
cecho "Green" "----------------------------------------------------"
echo ""
echo ""
cecho "Cyan" ">> Making last restart: $JAIL_NAME"
iocage stop $JAIL_NAME
iocage start $JAIL_NAME
echo ""
cecho "Green" "----------------------------------------------------"
echo ""
echo ""
cecho "Red" ">> Remember to add $JAIL_NAME to Prometheus: /etc/hosts and /usr/local/etc/prometheus.yml: sendmail_exporter"
cecho "Red" ">> Remember to add fstab entry via iocage and CRON job for backups"
echo ""
cecho "Green" "----------------------------------------------------"
echo ""
echo ""
cecho "Cyan" ">> Jail $JAIL_NAME deployed and updated"
Una primera versión del script creaba jails de tipo clone pero esto corrompÃa las jails ya creadas a partir del template, al ser clone no se puede tocar la base compartida mientras está en marcha, apagando la jail y volviéndola a arrancar volvÃan a funcionar pero para evitar ese downtime se ha decidido crearlas de tipo Thick .
A continuación el script cecho :
cecho(){
# Reset
Color_Off='\033[0m' # Text Reset
# Regular Colors
Black='\033[0;30m' # Black
Red='\033[0;31m' # Red
Green='\033[0;32m' # Green
Yellow='\033[0;33m' # Yellow
Blue='\033[0;34m' # Blue
Purple='\033[0;35m' # Purple
Cyan='\033[0;36m' # Cyan
White='\033[0;37m' # White
# Bold
BBlack='\033[1;30m' # Black
BRed='\033[1;31m' # Red
BGreen='\033[1;32m' # Green
BYellow='\033[1;33m' # Yellow
BBlue='\033[1;34m' # Blue
BPurple='\033[1;35m' # Purple
BCyan='\033[1;36m' # Cyan
BWhite='\033[1;37m' # White
# Underline
UBlack='\033[4;30m' # Black
URed='\033[4;31m' # Red
UGreen='\033[4;32m' # Green
UYellow='\033[4;33m' # Yellow
UBlue='\033[4;34m' # Blue
UPurple='\033[4;35m' # Purple
UCyan='\033[4;36m' # Cyan
UWhite='\033[4;37m' # White
# Background
On_Black='\033[40m' # Black
On_Red='\033[41m' # Red
On_Green='\033[42m' # Green
On_Yellow='\033[43m' # Yellow
On_Blue='\033[44m' # Blue
On_Purple='\033[45m' # Purple
On_Cyan='\033[46m' # Cyan
On_White='\033[47m' # White
# High Intensity
IBlack='\033[0;90m' # Black
IRed='\033[0;91m' # Red
IGreen='\033[0;92m' # Green
IYellow='\033[0;93m' # Yellow
IBlue='\033[0;94m' # Blue
IPurple='\033[0;95m' # Purple
ICyan='\033[0;96m' # Cyan
IWhite='\033[0;97m' # White
# Bold High Intensity
BIBlack='\033[1;90m' # Black
BIRed='\033[1;91m' # Red
BIGreen='\033[1;92m' # Green
BIYellow='\033[1;93m' # Yellow
BIBlue='\033[1;94m' # Blue
BIPurple='\033[1;95m' # Purple
BICyan='\033[1;96m' # Cyan
BIWhite='\033[1;97m' # White
# High Intensity backgrounds
On_IBlack='\033[0;100m' # Black
On_IRed='\033[0;101m' # Red
On_IGreen='\033[0;102m' # Green
On_IYellow='\033[0;103m' # Yellow
On_IBlue='\033[0;104m' # Blue
On_IPurple='\033[0;105m' # Purple
On_ICyan='\033[0;106m' # Cyan
On_IWhite='\033[0;107m' # White
printf "${!1}${2} ${Color_Off}\n"
}
Firewall
Como nota final debemos tener en cuenta que todas las reglas de firewall deben definirse en el host padre, cuando se haga referencia a "me" son todas las ips de los alias, por lo tanto las reglas genéricas se configurarán utilizando "me" y las mas especÃficas de cada servicio indicando la ip origen y destino de la jail.
Recomendaciones
Algunas recomendaciones son:
- Es mas eficiente reiniciar las jails mediante iocage restart -s que hacer un stop/start
- Cada cierto tiempo realizar limpieza de los snapshots antiguos sobretodo de las jails cuyos datos cambien muy a menudo.