initial release

This commit is contained in:
2024-12-26 17:16:58 +01:00
parent 9097cc0bec
commit 9c131ccf14
5 changed files with 469 additions and 2 deletions

136
README.md
View File

@ -1,3 +1,135 @@
# freebsd_jails
# FreeBSD Jails implementación
Una implementación de jails en FreeBSD
Un ejemplo de implementar Jails mediante el uso de [ThinJails/NullFS](https://docs.freebsd.org/en/books/handbook/jails/#thin-jail).
Probablemente no sea la mejor ni la manera mas eficiente de hacerlo, pero puede servir para aprender como funcionan las jails en FreeBSD.
Recuerda que la comunidad dispone de otras maneras de hacer esto:
[Jail Managers](https://docs.freebsd.org/en/books/handbook/jails/#jail-managers-and-containers).
##  Detalle
Las Jails se van a apoyar en ZFS para su creacion y mantenimiento.
Se va a seguir esta estructura de archivos
### Base de la distribucion
El directorio donde se descarga el release de FreeBSD correspondiente que actuara como base para las jails usara el zfs slice / directorio:
```
zroot/jails/releases /usr/local/jails/releases
```
Ejemplo:
```shell
zroot/jails 1.14T 384G 88K /usr/local/jails
zroot/jails/releases 5.47G 384G 96K /usr/local/jails/releases
zroot/jails/releases/13.1-RELEASE 2.32G 384G 1.40G /usr/local/jails/releases/13.1-RELEASE
zroot/jails/releases/13.2-RELEASE 1.41G 384G 1.41G /usr/local/jails/releases/13.2-RELEASE
zroot/jails/releases/14.0-RELEASE 1.30G 384G 1.30G /usr/local/jails/releases/14.0-RELEASE
zroot/jails/releases/14.1-RELEASE 451M 384G 451M /usr/local/jails/releases/14.1-RELEASE
```
### Base jails
Una vez descarado el sistema base se separa en dos partes, por un lado el "userspace" de FreeBSD en solo ReadOnly y por otro los directorios escribibiles en modo RW clonando el release anterior y dividiendo en dos partes:
```shell
zroot/jails/templates /usr/local/jails/templates
# Parte solo lectura
zroot/jails/templates/base-$FREEBSD_RELEASE-RELEASE /usr/local/jails/templates/base-$FREEBSD_RELEASE-RELEASE
# Parte lectura/escritura
zroot/jails/templates/skeleton-$FREEBSD_RELEASE-RELEASE /usr/local/jails/templates/skeleton-$FREEBSD_RELEASE-RELEASE
```
Por ejemplo:
```
zroot/jails/templates 84.5M 384G 120K /srv/jails/templates
zroot/jails/templates/base-13.1-RELEASE 50.1M 384G 1.36G /srv/jails/templates/base-13.1-RELEASE
zroot/jails/templates/base-13.2-RELEASE 568K 384G 1.40G /srv/jails/templates/base-13.2-RELEASE
zroot/jails/templates/base-14.0-RELEASE 552K 384G 1.29G /srv/jails/templates/base-14.0-RELEASE
zroot/jails/templates/base-14.1-RELEASE 232K 384G 447M /srv/jails/templates/base-14.1-RELEASE
zroot/jails/templates/skeleton-12.1-RELEASE 4.85M 384G 4.46M /srv/jails/templates/skeleton-12.1-RELEASE
zroot/jails/templates/skeleton-12.2-RELEASE 4.92M 384G 4.49M /srv/jails/templates/skeleton-12.2-RELEASE
zroot/jails/templates/skeleton-13.0-RELEASE 4.78M 384G 4.34M /srv/jails/templates/skeleton-13.0-RELEASE
zroot/jails/templates/skeleton-13.1-RELEASE 4.82M 384G 4.38M /srv/jails/templates/skeleton-13.1-RELEASE
zroot/jails/templates/skeleton-13.2-RELEASE 4.48M 384G 4.41M /srv/jails/templates/skeleton-13.2-RELEASE
zroot/jails/templates/skeleton-14.0-RELEASE 4.52M 384G 4.43M /srv/jails/templates/skeleton-14.0-RELEASE
zroot/jails/templates/skeleton-14.1-RELEASE 4.42M 384G 4.42M /srv/jails/templates/skeleton-14.1-RELEASE
```
Mas detalle:
```shell
# ls -lah /usr/local/jails/templates/base-14.1-RELEASE/
total 88
drwxr-xr-x 15 root wheel 24B Jun 20 2024 .
drwxr-xr-x 13 root wheel 13B Jun 20 2024 ..
-rw-r--r-- 1 root wheel 1.0K May 31 2024 .cshrc
-rw-r--r-- 1 root wheel 495B May 31 2024 .profile
-r--r--r-- 1 root wheel 6.0K May 31 2024 COPYRIGHT
drwxr-xr-x 2 root wheel 49B Jun 20 2024 bin
drwxr-xr-x 15 root wheel 69B Jun 20 2024 boot
dr-xr-xr-x 2 root wheel 2B May 31 2024 dev
lrwxr-xr-x 1 root wheel 12B Jun 20 2024 etc -> skeleton/etc
lrwxr-xr-x 1 root wheel 13B Jun 20 2024 home -> skeleton/home
drwxr-xr-x 4 root wheel 78B Jun 20 2024 lib
drwxr-xr-x 3 root wheel 5B May 31 2024 libexec
drwxr-xr-x 2 root wheel 2B May 31 2024 media
drwxr-xr-x 2 root wheel 2B May 31 2024 mnt
drwxr-xr-x 2 root wheel 2B May 31 2024 net
dr-xr-xr-x 2 root wheel 2B May 31 2024 proc
drwxr-xr-x 2 root wheel 150B Jun 20 2024 rescue
lrwxr-xr-x 1 root wheel 13B Jun 20 2024 root -> skeleton/root
drwxr-xr-x 2 root wheel 150B Jun 20 2024 sbin
drwxr-xr-x 2 root wheel 2B Jun 20 2024 skeleton
lrwxr-xr-x 1 root wheel 11B May 31 2024 sys -> usr/src/sys
lrwxr-xr-x 1 root wheel 12B Jun 20 2024 tmp -> skeleton/tmp
drwxr-xr-x 13 root wheel 14B Jun 20 2024 usr
lrwxr-xr-x 1 root wheel 12B Jun 20 2024 var -> skeleton/var
```
```shell
ls -lah /usr/local/jails/templates/skeleton-14.1-RELEASE/
total 37
drwxr-xr-x 9 root wheel 9B Jun 20 2024 .
drwxr-xr-x 13 root wheel 13B Jun 20 2024 ..
drwxr-xr-x 30 root wheel 106B Jun 20 2024 etc
drwxr-xr-x 2 root wheel 2B Jun 20 2024 home
drwxr-xr-x 2 root wheel 2B Jun 20 2024 portsbuild
drwxr-x--- 2 root wheel 7B May 31 2024 root
drwxrwxrwt 2 root wheel 2B May 31 2024 tmp
drwxr-xr-x 4 root wheel 4B Jun 20 2024 usr
drwxr-xr-x 24 root wheel 24B May 31 2024 var
```
### Jails
Cuando se crea una jail se clonan el base / skeleton del release correspondiente con el nombre de la jail y se establece su fstab y su configuracion.
## Configuración host
Archivo /etc/rc.conf
```shell
## Jails
jail_enable="YES"
jail_set_hostname_allow="NO"
jail_list=""
jailsffss_enable="YES"
jail_sysvipc_allow="YES"
```
Archivo /etc/jail.conf
```shell
# Networking
interface = "lagg0";
ip4.addr = 192.168.50.$ip;
# Config
host.hostname = "$name.local";
path = "/usr/local/jails/services/$name";
mount.devfs;
mount.fstab = "/usr/local/jails/jail.fstab.d/$name.fstab";
exec.start = "/bin/sh /etc/rc";
exec.stop = "/bin/sh /etc/rc.shutdown";
exec.poststop = "/sbin/umount /usr/local/jails/$name/skeleton; /sbin/umount /usr/local/jails/$name";
exec.clean;
```

59
files/jail_create.sh Normal file
View File

@ -0,0 +1,59 @@
#!/bin/sh
if [ $# -eq 0 ]
then
echo "Use: $0 jailName"
exit 0
else
#Calculate next ip
grep jid /etc/jail.conf | grep -v \# | tr -d \; | awk '{print $3}' > $PWD/jid.tmp
JAILID=$(sort -hr jid.tmp|head -1)
JAILID=$((JAILID+1))
JAIL="$1"
RELEASE="14.1-RELEASE"
JAILMOUNTPOINT="/usr/local/jails"
JAILFSTAB="/usr/local/jails/jail.fstab.d/"
JAILCONFIG="/etc/jail.conf"
ZFS_SNAPSHOT=$(zfs list -t snapshot|grep skeleton-$RELEASE@base|awk '{print $1}')
ZFS_SERVICE="/srv/jails/services"
ZFS_SKELETON="/srv/jails/services/$JAIL"
if [ -z "$ZFS_SNAPSHOT" ]
then
echo "Creating SKELETON snapshot"
zfs snapshot zroot/jails/templates/skeleton-$RELEASE@base
fi
if ! [ -d "$ZFS_SERVICE" ]
then
echo "Creating services jail"
zfs create zroot/jails/services
fi
if ! [ -d "$ZFS_SKELETON" ]
then
echo "Creating $JAIL jail"
zfs clone zroot/jails/templates/skeleton-$RELEASE@base zroot/jails/services/$JAIL
else
echo "Jail $JAIL already exist, try to start or restart it"
break
fi
echo "hostname=\"$JAIL\"" > /srv/jails/services/$JAIL/etc/rc.conf
#Create mountpoint
if [ ! -d $JAILMOUNTPOINT/$JAIL ]
then
mkdir -p $JAILMOUNTPOINT/$JAIL
fi
if [ ! -f $JAILFSTAB/$JAIL.fstab ]
then
touch $JAILFSTAB/$JAIL.fstab
fi
#checking ip
echo "/srv/jails/templates/base-$RELEASE $JAILMOUNTPOINT/$JAIL/ nullfs ro 0 0" >> $JAILFSTAB/$JAIL.fstab
echo "/srv/jails/services/$JAIL $JAILMOUNTPOINT/$JAIL/skeleton nullfs rw 0 0" >> $JAILFSTAB/$JAIL.fstab
echo "$JAIL {" >> $JAILCONFIG
echo "# jid = ${JAILID};" >> $JAILCONFIG
echo '# exec.start = "/usr/local/etc/rc.d/service onestart";' >> $JAILCONFIG
echo '# exec.stop = "/usr/local/etc/rc.d/service onestop";' >> $JAILCONFIG
echo ' allow.raw_sockets = "true";' >> $JAILCONFIG
echo " \$ip = ${JAILID};" >> $JAILCONFIG
echo "}" >> $JAILCONFIG
fi

59
files/jail_create_full.sh Normal file
View File

@ -0,0 +1,59 @@
#!/bin/sh
if [ $# -eq 0 ]
then
echo "Use: $0 jailName"
exit 0
else
#Calculate next ip
grep jid /etc/jail.conf | grep -v \# | tr -d \; | awk '{print $3}' > $PWD/jid.tmp
JAILID=$(sort -hr jid.tmp|head -1)
JAILID=$((JAILID+1))
JAIL="$1"
RELEASE="14.1-RELEASE"
JAILMOUNTPOINT="/usr/local/jails"
JAILFSTAB="/usr/local/jails/jail.fstab.d/"
JAILCONFIG="/etc/jail.conf"
ZFS_SNAPSHOT=$(zfs list -t snapshot| grep releases/$RELEASE|awk '{print $1}')
ZFS_SERVICE="/srv/jails/services"
ZFS_JAIL="/srv/jails/services/$JAIL"
if [ -z "$ZFS_SNAPSHOT" ]
then
echo "Creating SKELETON snapshot"
zfs snapshot $ZFS_SNAPSHOT
fi
if ! [ -d "$ZFS_SERVICE" ]
then
echo "Creating services jail"
zfs create zroot/jails/services
fi
if ! [ -d "$ZFS_JAIL" ]
then
echo "Creating $JAIL jail"
zfs clone $ZFS_SNAPSHOT zroot/jails/services/$JAIL
else
echo "Jail $JAIL already exist, try to start or restart it"
break
fi
echo "hostname=\"$JAIL\"" > /srv/jails/services/$JAIL/etc/rc.conf
#Create mountpoint
if [ ! -d $JAILMOUNTPOINT/$JAIL ]
then
mkdir -p $JAILMOUNTPOINT/$JAIL
fi
if [ ! -f $JAILFSTAB/$JAIL.fstab ]
then
touch $JAILFSTAB/$JAIL.fstab
fi
#checking ip
#echo "/srv/jails/templates/base-$RELEASE $JAILMOUNTPOINT/$JAIL/ nullfs ro 0 0" >> $JAILFSTAB/$JAIL.fstab
echo "/srv/jails/services/$JAIL $JAILMOUNTPOINT/$JAIL nullfs rw 0 0" >> $JAILFSTAB/$JAIL.fstab
echo "$JAIL {" >> $JAILCONFIG
echo "# jid = ${JAILID};" >> $JAILCONFIG
echo '# exec.start = "/usr/local/etc/rc.d/service onestart";' >> $JAILCONFIG
echo '# exec.stop = "/usr/local/etc/rc.d/service onestop";' >> $JAILCONFIG
echo ' allow.raw_sockets = "true";' >> $JAILCONFIG
echo " \$ip = ${JAILID};" >> $JAILCONFIG
echo "}" >> $JAILCONFIG
fi

View File

@ -0,0 +1,164 @@
#!/bin/sh
USED_RELEASE="13.2-RELEASE"
ZFS_MOUNTPOINT_JAILS="/srv/jails"
ZFS_DATASET="zroot"
ZFS_DATASET_JAILS="${ZFS_DATASET}/jails"
ZFS_DATASET_RELEASES="${ZFS_DATASET_JAILS}/releases"
ZFS_DATASET_TEMPLATES="${ZFS_DATASET_JAILS}/templates"
ZFS_USED_RELEASE="${ZFS_DATASET_RELEASES}/${USED_RELEASE}"
# Variables para habilitar o deshabilitar la descarga y extracción de lib32 y ports
lib32="N" # Cambiar a "N" si no se desea descargar y extraer lib32
ports="N" # Cambiar a "N" si no se desea descargar y extraer ports
# Crear dataset si no existe
create_dataset_if_not_exists() {
local dataset=$1
local mountpoint=$2
if ! zfs list "${dataset}" >/dev/null 2>&1; then
echo "Creating ${dataset} dataset"
zfs create -o mountpoint="${mountpoint}" "${dataset}"
else
echo "Dataset ${dataset} already exists"
fi
}
# Descargar y extraer un archivo
download_and_extract_file() {
local url=$1
local destination=$2
fetch "${url}" -o /tmp/file.tar.gz
tar -xvf /tmp/file.tar.gz -C "${destination}"
}
# Copiar archivos
move_files() {
local source=$1
local destination=$2
mv "${source}" "${destination}"
}
# Crear snapshot
create_snapshot() {
local snapshot=$1
zfs snapshot "${snapshot}"
}
# Crear clon de snapshot
create_clone() {
local snapshot=$1
local clone=$2
zfs clone "${snapshot}" "${clone}"
}
# Crear enlace simbólico
create_symlink() {
local source=$1
local target=$2
ln -s "${source}" "${target}"
}
# Actualizar sistema base
update_base_system() {
local release=$1
env UNAME_r="${release}" freebsd-update -b "${ZFS_MOUNTPOINT_JAILS}/releases/${release}" fetch install
}
# Configurar resolv.conf y localtime
configure_files() {
local release=$1
cp /etc/resolv.conf "${ZFS_MOUNTPOINT_JAILS}/releases/${release}/etc/resolv.conf"
cp /etc/localtime "${ZFS_MOUNTPOINT_JAILS}/releases/${release}/etc/localtime"
}
# Ejecutar acciones de postinstalación
post_installation() {
# Detener servicios de jail
service jail stop db
# Modificar base por la nueva release en /usr/local/jails/jail.fstab.d/
# Iniciar servicios de jail
service jail start db
# Actualizar paquetes en el jail
pkg -j db update
pkg -j db upgrade
}
# Crear datasets
create_dataset_if_not_exists "${ZFS_DATASET_JAILS}"
create_dataset_if_not_exists "${ZFS_DATASET_RELEASES}" "${ZFS_MOUNTPOINT_JAILS}/releases"
create_dataset_if_not_exists "${ZFS_DATASET_TEMPLATES}" "${ZFS_MOUNTPOINT_JAILS}/templates"
# Descargar y extraer archivos base, lib32 y ports
if [ ! -d "${ZFS_MOUNTPOINT_JAILS}/releases/${USED_RELEASE}" ]; then
create_dataset_if_not_exists "${ZFS_USED_RELEASE}" "${ZFS_MOUNTPOINT_JAILS}/releases/${USED_RELEASE}"
download_and_extract_file "ftp://ftp.freebsd.org/pub/FreeBSD/releases/amd64/${USED_RELEASE}/base.txz" "${ZFS_MOUNTPOINT_JAILS}/releases/${USED_RELEASE}"
fi
# Descargar y extraer lib32 si la variable lib32 es "Y"
if [ "${lib32}" = "Y" ]; then
download_and_extract_file "ftp://ftp.freebsd.org/pub/FreeBSD/releases/amd64/${USED_RELEASE}/lib32.txz" "${ZFS_MOUNTPOINT_JAILS}/releases/${USED_RELEASE}"
fi
# Descargar y extraer ports si la variable ports es "Y"
if [ "${ports}" = "Y" ]; then
download_and_extract_file "ftp://ftp.freebsd.org/pub/FreeBSD/releases/amd64/${USED_RELEASE}/ports.txz" "${ZFS_MOUNTPOINT_JAILS}/releases/${USED_RELEASE}"
fi
# Actualizar sistema base
update_base_system "${USED_RELEASE}"
# Configurar archivos
configure_files "${USED_RELEASE}"
# Crear snapshot
create_snapshot "${ZFS_DATASET_RELEASES}/${USED_RELEASE}@p0"
# Crear clon del snapshot como template base
create_clone "${ZFS_DATASET_RELEASES}/${USED_RELEASE}@p0" "${ZFS_DATASET_TEMPLATES}/base-${USED_RELEASE}"
# Crear dataset skeleton si no existe
if ! zfs list "${ZFS_DATASET_TEMPLATES}/skeleton-${USED_RELEASE}" >/dev/null 2>&1; then
echo "Creating ${ZFS_DATASET_TEMPLATES}/skeleton-${USED_RELEASE} dataset"
zfs create "${ZFS_DATASET_TEMPLATES}/skeleton-${USED_RELEASE}"
else
echo "Dataset ${ZFS_DATASET_TEMPLATES}/skeleton-${USED_RELEASE} already exists"
fi
# Crear directorio skeleton y enlaces simbólicos
if [ "${ports}" = "Y" ]; then
mkdir -p "${ZFS_MOUNTPOINT_JAILS}/templates/skeleton-${USED_RELEASE}/usr/ports/distfiles"
fi
mkdir -p "${ZFS_MOUNTPOINT_JAILS}/templates/skeleton-${USED_RELEASE}/home"
mkdir -p "${ZFS_MOUNTPOINT_JAILS}/templates/skeleton-${USED_RELEASE}/portsbuild"
move_files "${ZFS_MOUNTPOINT_JAILS}/templates/base-${USED_RELEASE}/etc" "${ZFS_MOUNTPOINT_JAILS}/templates/skeleton-${USED_RELEASE}/etc"
move_files "${ZFS_MOUNTPOINT_JAILS}/templates/base-${USED_RELEASE}/tmp" "${ZFS_MOUNTPOINT_JAILS}/templates/skeleton-${USED_RELEASE}/tmp"
chflags noschg ${ZFS_MOUNTPOINT_JAILS}/templates/base-${USED_RELEASE}/var/empty
move_files "${ZFS_MOUNTPOINT_JAILS}/templates/base-${USED_RELEASE}/var" "${ZFS_MOUNTPOINT_JAILS}/templates/skeleton-${USED_RELEASE}/var"
move_files "${ZFS_MOUNTPOINT_JAILS}/templates/base-${USED_RELEASE}/root" "${ZFS_MOUNTPOINT_JAILS}/templates/skeleton-${USED_RELEASE}/root"
move_files "${ZFS_MOUNTPOINT_JAILS}/templates/base-${USED_RELEASE}/usr/local" "${ZFS_MOUNTPOINT_JAILS}/templates/skeleton-${USED_RELEASE}/usr/local"
# Crear enlaces simbólicos
cd ${ZFS_MOUNTPOINT_JAILS}/templates/base-$USED_RELEASE
mkdir skeleton
create_symlink "skeleton/etc" "etc"
create_symlink "skeleton/home" "home"
create_symlink "skeleton/root" "root"
create_symlink "../skeleton/usr/local" "usr/local"
if [ "${ports}" = "Y" ]; then
create_symlink "skeleton/usr/ports/distfiles" "usr/ports/distfiles"
fi
create_symlink "skeleton/tmp" "tmp"
create_symlink "skeleton/var" "var"

53
files/jail_upgrade.sh Normal file
View File

@ -0,0 +1,53 @@
#!/bin/csh
setenv USED_RELEASE "14.1-RELEASE"
zfs create -o mountpoint=/srv/jails/releases/$USED_RELEASE zroot/jails/releases/$USED_RELEASE
fetch ftp://ftp.freebsd.org/pub/FreeBSD/releases/amd64/$USED_RELEASE/base.txz -o /tmp/base.txz
tar -xvf /tmp/base.txz -C /srv/jails/releases/$USED_RELEASE
#fetch ftp://ftp.freebsd.org/pub/FreeBSD/releases/amd64/$USED_RELEASE/lib32.txz -o /tmp/lib32.txz
#tar -xvf /tmp/lib32.txz -C /srv/jails/releases/$USED_RELEASE
#fetch ftp://ftp.freebsd.org/pub/FreeBSD/releases/amd64/$USED_RELEASE/ports.txz -o /tmp/ports.txz
#tar -xvf /tmp/ports.txz -C /srv/jails/releases/$USED_RELEASE
#Update base system
env UNAME_r=$USED_RELEASE freebsd-update -b /srv/jails/releases/$USED_RELEASE fetch install
#Verify
#env UNAME_r=10.2-RELEASE freebsd-update -b /srv/jails/releases/$USED_RELEASE IDS
cp /etc/resolv.conf /srv/jails/releases/$USED_RELEASE/etc/resolv.conf
cp /etc/localtime /srv/jails/releases/$USED_RELEASE/etc/localtime
zfs snapshot zroot/jails/releases/$USED_RELEASE@p0
zfs clone zroot/jails/releases/$USED_RELEASE@p0 zroot/jails/templates/base-$USED_RELEASE
zfs create -p zroot/jails/templates/skeleton-$USED_RELEASE
mkdir -p /srv/jails/templates/skeleton-$USED_RELEASE/usr/ports/distfiles /srv/jails/templates/skeleton-$USED_RELEASE/home /srv/jails/templates/skeleton-$USED_RELEASE/portsbuild
mv /srv/jails/templates/base-$USED_RELEASE/etc /srv/jails/templates/skeleton-$USED_RELEASE/etc
#mv /srv/jails/templates/base-$USED_RELEASE/srv /srv/jails/templates/skeleton-$USED_RELEASE/srv
mv /srv/jails/templates/base-$USED_RELEASE/tmp /srv/jails/templates/skeleton-$USED_RELEASE/tmp
chflags noschg /srv/jails/templates/base-$USED_RELEASE/var/empty
mv /srv/jails/templates/base-$USED_RELEASE/var /srv/jails/templates/skeleton-$USED_RELEASE/var
mv /srv/jails/templates/base-$USED_RELEASE/root /srv/jails/templates/skeleton-$USED_RELEASE/root
mv /srv/jails/templates/base-$USED_RELEASE/usr/local /srv/jails/templates/skeleton-$USED_RELEASE/usr/local
cd /srv/jails/templates/base-$USED_RELEASE
mkdir skeleton
ln -s skeleton/etc etc
ln -s skeleton/home home
ln -s skeleton/root root
########REVISAR ANTES DE ACTUALIZAR#########
ln -s ../skeleton/usr/local usr/local && echo linkado local || echo fallo al linkar local
ln -s skeleton/usr/ports/distfiles usr/ports/distfiles
ln -s skeleton/tmp tmp
ln -s skeleton/var var
echo "WRKDIRPREFIX?= /skeleton/portbuild" >> /srv/jails/templates/skeleton-$USED_RELEASE/etc/make.conf
#POSTINSTALACION
#service jail stop db
#service jail stop ....
#cd /usr/local/jails/jail.fstab.d/
#modificar base por la nueva release
#service jail start db
#pkg -j db update
#pkg -j db upgrade