Páginas

Mostrando entradas con la etiqueta backup. Mostrar todas las entradas
Mostrando entradas con la etiqueta backup. Mostrar todas las entradas

martes, 1 de septiembre de 2026

Script Copia de Seguridad de un Conjunto de Datos ZFS Hacia un Dispositivo Remoto

Script de Replicación ZFS (zfsrep.sh)

shell zsh

Este script automatiza la copia de seguridad y replicación incremental de snapshots de ZFS desde el sistema local (solaris.local.com FreeBSD 14.4 ZFS) hacia un servidor remoto (tormenta.local.com FreeBSD 14.4 ZFS). Gestiona la creación de la snapshot diaria, el envío incremental a través de SSH y la purga automática de snapshots antiguas tanto en origen como en destino, respetando una retención de, (el valor de retention), 15 snapshots.

Descripción del funcionamiento

El script utiliza zfs send y zfs receive para transferir los datos. Detecta la última snapshot disponible en el destino para realizar un envío incremental (ahorrando ancho de banda), o realiza un envío completo si no encuentra una base común. Todo el proceso queda registrado en un archivo de log ubicado en /home/carlos/cronlog.

Contenido del script

#!/bin/sh
### BEGIN INFO
# PROVIDE:
# REQUIRE:
# KEYWORD:
### END INFO

### INICIO DEL GUION
# Estas variables se nombran primero porque están anidadas en otras variables.
snap_prefix=snap
retention=15

# Se necesitan rutas completas a estas utilidades al ejecutar el script desde cron.
date=/bin/date
cut=/usr/bin/cut
grep=/usr/bin/grep
sed=/usr/bin/sed
sort=/usr/bin/sort
xargs=/usr/bin/xargs
zfs=/sbin/zfs

src_0="zroot/home/carlos"
dst_0="zbackup/solaris/home/carlos"
host="root@192.168.88.160"
today="$snap_prefix-`$date +%Y%m%d`"
snap_today="$src_0@$today"

# Patrón grep con sufijo numérico para evitar falsos positivos.
snap_old=`$zfs list -t snapshot -o name \
  | $grep "${src_0}@${snap_prefix}-[0-9]" \
  | $sort -r \
  | $sed 1,${retention}d \
  | $sort \
  | $xargs -n 1`

# Detecta la snapshot más reciente del destino remoto para usarla como base.
# Todo el pipeline corre en tormenta vía SSH.
snap_base_name=`ssh $host "$zfs list -t snapshot -o name \
  | grep '${dst_0}@${snap_prefix}-[0-9]' \
  | sort -r \
  | sed 1q \
  | cut -d@ -f2"`
snap_base="${src_0}@${snap_base_name}"

# snap_old_dst_0 lista las snapshots > retention en el destino remoto.
snap_old_dst_0=`ssh $host "$zfs list -t snapshot -o name \
  | grep '${dst_0}@${snap_prefix}-[0-9]' \
  | sort -r \
  | sed 1,${retention}d \
  | sort"`

log=/home/carlos/cronlog

echo >> $log
echo "zfsrep.sh" >> $log
$date >> $log
echo >> $log

# Busca la instantánea de hoy en origen y, si no la encuentras, créala.
if $zfs list -H -o name -t snapshot \
  | $sort \
  | $grep "${snap_today}$" > /dev/null
then
	echo "La instantánea de hoy '$snap_today' ya existe." >> $log
else
	echo "Tomando la instantánea de hoy: $snap_today" >> $log
	$zfs snapshot -r $snap_today >> $log 2>&1
fi

echo >> $log

# Comprueba si la instantánea de hoy ya existe en el destino remoto.
# Si existe, no hay nada que enviar; saltar directamente a la purga.
if ssh $host "$zfs list -H -o name -t snapshot \
  | grep '${dst_0}@${today}$'" > /dev/null 2>&1
then
	echo "La instantánea de hoy ya existe en destino remoto. Nada que enviar." >> $log
else
	# Detecta la base del incremental y replica.
	# Permite recuperarse de huecos de sincronización sin intervención manual.
	if [ -n "$snap_base_name" ] && $zfs list -H -o name -t snapshot \
	  | $grep "${snap_base}$" > /dev/null
	then
		echo "Usando '$snap_base' como base del incremental..." >> $log
		$zfs send -R -i $snap_base $snap_today \
		  | ssh $host $zfs receive -vuF -x mountpoint $dst_0 >> $log 2>&1
		echo >> $log
		echo "Replicacion completada." >> $log
	else
		echo "No se encontró snapshot común entre origen y destino." >> $log
		echo "Realizando envío completo (puede tardar)..." >> $log
		$zfs send -R $snap_today \
		  | ssh $host $zfs receive -vuF -x mountpoint $dst_0 >> $log 2>&1
		echo >> $log
		echo "Envío completo finalizado." >> $log
	fi
fi

echo >> $log

# Eliminar instantáneas locales más antiguas que el valor asignado a $retention.
echo "Intentando destruir instantáneas antiguas $src_0..." >> $log

if [ -n "$snap_old" ]
then
	echo "Destruyendo las siguientes instantáneas antiguas:" >> $log
	echo "$snap_old" >> $log
	$zfs list -t snapshot -o name \
	  | $grep "${src_0}@${snap_prefix}-[0-9]" \
	  | $sort -r \
	  | $sed 1,${retention}d \
	  | $sort \
	  | $xargs -n 1 $zfs destroy -r >> $log 2>&1
else
	echo "No se pudo encontrar ninguna instantánea local para destruir." >> $log
fi

echo >> $log

# Eliminar instantáneas remotas más antiguas que el valor asignado a $retention.
# Todo el pipeline, incluido zfs destroy, corre en tormenta vía SSH.
echo "Intentando destruir instantáneas antiguas $dst_0..." >> $log

if [ -n "$snap_old_dst_0" ]
then
	echo "Destruyendo las siguientes instantáneas antiguas en $host:" >> $log
	echo "$snap_old_dst_0" >> $log
	ssh $host "$zfs list -t snapshot -o name \
	  | grep '${dst_0}@${snap_prefix}-[0-9]' \
	  | sort -r \
	  | sed 1,${retention}d \
	  | sort \
	  | xargs -n 1 $zfs destroy -r" >> $log 2>&1
else
	echo "No se pudo encontrar ninguna instantánea remota para destruir." >> $log
fi

echo "**********" >> $log

### FIN DEL SCRIPT

Estructura de zbackup (servidor)

carlos@tormenta:~ % zfs list -r zbackup
NAME                          USED  AVAIL  REFER  MOUNTPOINT
zbackup                      1008G   791G  92.5M  none
zbackup/dellhome             56.6G   791G  56.6G  none
zbackup/nfsv4                36.6G   791G    96K  none
zbackup/nfsv4/docs           7.80G   791G  7.80G  none
zbackup/nfsv4/secrets        28.8G   791G  28.8G  none
zbackup/recovery              755G   791G   104K  none
zbackup/recovery/solaris      282G   791G   282G  none
zbackup/recovery/tormenta     473G   791G   473G  none
zbackup/reserved               50G   841G    96K  none
zbackup/solaris              80.9G   791G    96K  none
zbackup/solaris/home         80.9G   791G    96K  none
zbackup/solaris/home/carlos  80.9G   791G  73.2G  none
zbackup/usr                   147M   791G   104K  none
zbackup/usr/home              147M   791G   140M  none

zfsrep.sh - Funcionamiento

Asigna rutas absolutas a los binarios (zfs, date, grep, etc.) para evitar problemas de $PATH al ejecutarse desde cron

date=/bin/date
cut=/usr/bin/cut
grep=/usr/bin/grep
sed=/usr/bin/sed
sort=/usr/bin/sort
xargs=/usr/bin/xargs
zfs=/sbin/zfs

Contexto

El script corre en solaris (cliente) y replica el dataset zroot/home/carlos hacia zbackup/solaris/home/carlos en tormenta (servidor), usando SSH como canal de transporte.

1 - Definición de variables

src_0="zroot/home/carlos"
dst_0="zbackup/solaris/home/carlos"
host="root@192.168.88.160"
today="snap-20260901"
snap_today="zroot/home/carlos@snap-fecha_de_hoy"

Se calculan los nombres de las snapshots y rutas antes de hacer nada. today se genera en este momento con $date, así que si el script corre a las 2:00 AM o a las 23:00 del mismo día, el nombre es idéntico - eso es lo que permite la comprobación de duplicado más adelante.

2 - Inventario de snapshots antiguas a purgar (local)

snap_old=`$zfs list -t snapshot -o name
  | $grep "${src_0}@${snap_prefix}-[0-9]"
  | $sort -r
  | $sed 1,${retention}d
  | $sort
  | $xargs -n 1`

Se calcula en este momento, antes de crear la snapshot de hoy. El pipeline:

Lista todas las snapshots del sistema Filtra las de zroot/home/carlos@snap- seguido de dígito Las ordena de más reciente a más antigua (sort -r) Elimina las primeras 15 líneas (sed 1,15d) - las 15 más recientes se conservan Lo que queda son las candidatas a destruir

Este cálculo es previo a la snapshot de hoy para que retention=15 sea exacto.

3 - Inventario remoto: base del incremental y purga

snap_base_name=`ssh $host "...pipeline en tormenta..."`
snap_old_dst_0=`ssh $host "...pipeline en tormenta..."`

Se abren dos conexiones SSH a tormenta para:

snap_base_name: la snapshot más reciente que tiene zbackup/solaris/home/carlos. Será el punto de partida del incremental. Si el destino tiene snap-20260831, el incremental enviará solo los cambios entre ese día y hoy. snap_old_dst_0: lista de snapshots en destino que superan retention=15, candidatas a purga remota.

Todo el pipeline de grep/sort/sed corre dentro del SSH, en tormenta, para que el resultado que llega a solaris sea solo texto limpio.

4 - Snapshot de hoy en origen

if zfs list ... | grep "${snap_today}$"
then
    "ya existe"
else
    zfs snapshot -r $snap_today
fi

Comprueba si zroot/home/carlos@snap-20260901 ya existe. El flag -r crea la snapshot de forma recursiva - si hubiera datasets hijo bajo zroot/home/carlos, también se snapshotearían. Si ya existe (segunda ejecución del día), simplemente lo anota en el log y continúa.

5 - Comprobación de duplicado en destino

if ssh $host "zfs list ... | grep '${dst_0}@${today}$'"
then
    "Nada que enviar"
else
    # continuar con el send
fi

Pregunta a tormenta: ¿ya tienes zbackup/solaris/home/carlos@snap-20260901? Si la respuesta es sí, el script salta directamente a la purga - no hay nada que transferir. Esto evita el reenvío innecesario si cron lanza el script más de una vez al día.

6 - Replicación incremental (o completa)

Caso normal - base común encontrada:

zfs send -R -i $snap_base $snap_today \
  | ssh $host zfs receive -vuF -x mountpoint $dst_0

zfs send genera un stream binario con los bloques que cambiaron entre snap_base y snap_today. Ese stream se pasa directamente por el pipe a SSH, que lo entrega a zfs receive en tormenta. No se escribe nada en disco en solaris - es un flujo directo en memoria.

Los flags:

-R: incluye snapshots hijas recursivamente
-i: incremental entre dos snapshots
-v: verbose en el log
-u: no monta el dataset recibido
-F: destruye en destino lo que no existe en el stream (mantiene coherencia)
-x mountpoint: ignora la propiedad mountpoint del stream — el destino mantiene mountpoint=none

Caso de hueco - sin base común:

zfs send -R $snap_today | ssh $host zfs receive -vuF -x mountpoint $dst_0

Si no hay ninguna snapshot común entre origen y destino, se hace un envío completo. Más lento, pero garantiza que el destino queda sincronizado desde cero.

7 - Purga local

zfs list -t snapshot -o name
  | grep "${src_0}@${snap_prefix}-[0-9]"
  | sort -r | sed 1,15d | sort
  | xargs -n 1 zfs destroy -r

Mismo pipeline que en el paso 2, pero esta vez ejecutando zfs destroy -r sobre cada snapshot antigua. El -r destruye también las snapshots hijas si las hubiera. Las 15 más recientes quedan intactas.

8 - Purga remota

ssh $host "zfs list ... | grep ... | sort -r | sed 1,15d | sort | xargs -n 1 zfs destroy -r"

Ídem pero en tormenta. Todo el pipeline - incluido el zfs destroy - corre dentro del SSH. Esto es crítico: si el destroy corriera en local, intentaría destruir zbackup/... en solaris, donde ese dataset no existe.

Entrada en cron para ejecución diaria a las 2:00 AM

 crontab -e
# Ejecución diaria de la copia de seguridad ZFS a las 2:00 AM
0 2 * * * /home/carlos/bin/zfsrep.sh
Guardar y salir

Que sea ejcutable

chmod +x /home/carlos/bin/zfsrep.sh

Comprobar que el script funciona manualmente antes de programarlo

sh -x /home/carlos/bin/zfsrep.sh

Ejemplo de crontab completo (para root)

SHELL=/bin/sh
PATH=/bin:/usr/bin:/sbin:/usr/sbin
MAILTO=root

# Ejecución diaria de la copia de seguridad ZFS a las 2:00 AM
0 2 * * * /home/carlos/bin/zfsrep.sh

Notas Finales

Robustez: La lógica de incremental/completo permite que el script se recupere automáticamente si se borra una instantánea intermedia.

Eficiencia: La mejora que evita reenvíos el mismo día ahorra ancho de banda y CPU.

Mantenimiento: La limpieza automática en origen y destino evita que el espacio se llene con instantáneas antiguas.

Portabilidad: Al usar rutas absolutas, el script funciona correctamente desde cron.

Con este sistema, tus datos están respaldados diariamente en un dispositivo remoto, con una política de retención clara y la capacidad de recuperación ante fallos de sincronización.

FreeBSD es genial!.

martes, 15 de abril de 2025

Script sh Replicar Instantáneas de Conjunto de Datos ZFS desde Servidor FreeBSD Local a otra Máquina FreeBSD Externa

El autor de este sencillo e ingenioso guión es iceflatline. Lamentablemente su sitio web está caido. Contiene algunas modificaciones para adaptarlo a este laboratorio

Script mejorado

https://gnulinuxcodigo.blogspot.com/2025/03/crear-particiones-en-disco-duro-usb-con.html

Crear el pool de respaldo zbackup

 zpool create -o ashift=12 \
-O compression=lz4 \
-O atime=off \
-O mountpoint=none \
backup /dev/gpt/zbackup

Conjuntos de datos zbackup

 sudo zfs create -o mountpoint=none zbackup/solaris
 sudo zfs create -o mountpoint=none zbackup/solaris/home
 sudo zfs create -o mountpoint=none zbackup/solaris/home/carlos
 sudo zfs create -o mountpoint=none zbackup/tormenta-confiles
 sudo zfs create -o mountpoint=none zbackup/usr/
 sudo zfs create -o mountpoint=none zbackup/usr/backup
 sudo zfs create -o mountpoint=none zbackup/usr/backup/docs
 sudo zfs create -o mountpoint=none zbackup/usr/home

Flujo de trabajo recomendado para un disco de respaldo mountpoint=none

Seguridad contra modificaciones accidentales

Evita conflictos de rutas

Comportamiento en el arranque — Con mountpoint=none ZFS no intenta montar nada del pool zbackup al arrancar, lo que acelera el boot y evita errores si el disco USB no está conectado en ese momento.

Acceso bajo demanda — Cuando se necesita recuperar algo, se monta puntualmente el dataset de interés, se hace lo que se necesita, y luego se desmonta.

Los scripts no se ven afectados — zfs receive escribe directamente al dataset sin necesidad de que esté montado. mountpoint=none no interfiere en absoluto con zfs send/receive.

carlos@tormenta:~ % zfs list -r zbackup
zbackup                            48.9G  1.71T  4.86M  none
zbackup/solaris                    40.8G  1.71T    96K  none
zbackup/solaris/home               40.8G  1.71T    96K  none
zbackup/solaris/home/carlos        40.8G  1.71T  39.9G  none
zbackup/tormenta-confiles           800K  1.71T   800K  none
zbackup/usr                        8.16G  1.71T   104K  none
zbackup/usr/backup                 7.80G  1.71T   104K  none
zbackup/usr/backup/docs            7.80G  1.71T  7.80G  none
zbackup/usr/home                    368M  1.71T   132M  none
#!/bin/sh
### BEGIN INFO
# PROVIDE:
# REQUIRE:
# KEYWORD:

### INICIO DEL GUION
# Estas variables se nombran primero porque están anidadas en otras variables.
snap_prefix=snap
retention=15

# Se necesitan rutas completas a estas utilidades al ejecutar el script desde \
cron.
date=/bin/date
grep=/usr/bin/grep
sed=/usr/bin/sed
sort=/usr/bin/sort
xargs=/usr/bin/xargs
zfs=/sbin/zfs

src_0="zroot/home/carlos"
dst_0="zbackup/solaris/home/carlos"
host="root@192.168.88.160"

# Usar $date en lugar de date para consistencia con rutas absolutas.
today="$snap_prefix-`$date +%Y%m%d`"
yesterday="$snap_prefix-`$date -v -1d +%Y%m%d`"
snap_today="$src_0@$today"
snap_yesterday="$src_0@$yesterday"

# Patrón grep con sufijo numérico para evitar falsos positivos.
snap_old=`$zfs list -t snapshot -o name \
  | $grep "${src_0}@${snap_prefix}-[0-9]" \
  | $sort -r \
  | $sed 1,${retention}d \
  | $sort \
  | $xargs -n 1`

log=/home/carlos/cronlog

# Todo el pipeline de listado remoto corre en tormenta vía SSH.
snap_old_dst_0=`ssh $host "$zfs list -t snapshot -o name \
  | grep '${dst_0}@${snap_prefix}-[0-9]' \
  | sort -r \
  | sed 1,${retention}d \
  | sort"`

# Crea una línea en blanco entre la entrada de registro anterior y esta.
echo >> $log

# Imprimir el nombre del script.
echo "zfsrep.sh" >> $log
# Imprime la fecha de hoy.
$date >> $log
# Crea una línea en blanco.
echo >> $log

# Buscar instantánea de hoy y, si no la encuentra, créala.
if $zfs list -H -o name -t snapshot \
  | $sort \
  | $grep "${snap_today}$" > /dev/null
then
	echo "La instantánea de hoy '$snap_today' ya existe." >> $log
else
	echo "Tomando la instantánea de hoy: $snap_today" >> $log
	$zfs snapshot -r $snap_today >> $log 2>&1
fi

echo >> $log

# Replicar el snapshot diario (ayer) o mostrar error si falta.
if $zfs list -H -o name -t snapshot \
  | $sort \
  | $grep "${snap_yesterday}$" > /dev/null
then
	echo "La instantánea de ayer '$snap_yesterday' existe. Continuando \
    con la replicacion..." >> $log
	$zfs send -R -i $snap_yesterday $snap_today \
	  | ssh $host $zfs receive -vuF -x mountpoint $dst_0 >> $log 2>&1
	echo >> $log
	echo "Replicacion completada." >> $log
else
	echo "Error: Replicacion no completada. Falta la instantánea de \
    ayer." >> $log
fi

echo >> $log

# Eliminar instantáneas locales más antiguas que el valor asignado a retention.
echo "Intentando destruir instantáneas antiguas $src_0..." >> $log

if [ -n "$snap_old" ]
then
	echo "Destruyendo las siguientes instantáneas antiguas:" >> $log
	echo "$snap_old" >> $log
	$zfs list -t snapshot -o name \
	  | $grep "${src_0}@${snap_prefix}-[0-9]" \
	  | $sort -r \
	  | $sed 1,${retention}d \
	  | $sort \
	  | $xargs -n 1 $zfs destroy -r >> $log 2>&1
else
	echo "No se pudo encontrar ninguna instantánea local para \
    destruir." >> $log
fi

echo >> $log

# Purgar snaps remotos > retention
# Todo el pipeline, incluido zfs destroy, corre en tormenta vía SSH.
echo "Intentando destruir instantáneas antiguas $dst_0..." >> $log

if [ -n "$snap_old_dst_0" ]
then
	echo "Destruyendo las siguientes instantáneas antiguas en $host:" >> $log
	echo "$snap_old_dst_0" >> $log
	ssh $host "$zfs list -t snapshot -o name \
	  | grep '${dst_0}@${snap_prefix}-[0-9]' \
	  | sort -r \
	  | sed 1,${retention}d \
	  | sort \
	  | xargs -n 1 $zfs destroy -r" >> $log 2>&1
else
	echo "No se pudo encontrar ninguna instantánea remota para \
    destruir." >> $log
fi

# Marcar el fin del script con un delimitador.
echo "**********" >> $log

### FIN DEL SCRIPT

Luego, agregue una tarea a la tabla cron bajo la cuenta del usuario. El script se ejecuta todos los días a las 22:00 (hora local):

# Ejecuta script backup cada día a las 22:00
0 22 * * * /home/carlos/bin/zfsrep.sh

Las entradas del archivo /home/carlos/cronlog se verán así:

**********

zfsrep.sh
Tue Apr 15 09:45:19 CEST 2025

Tomando la instantánea de hoy: zroot/home@snap-20250415

La instantánea de ayer 'zroot/home@snap-20250414' existe. \
Continuando con la replicacion...
receiving incremental stream of zroot/home@snap-20250415 into \
zbackup/solaris/home/carlos@snap-20250415
received 312B stream in 0.91 seconds (341B/sec)
receiving incremental stream of zroot/home/carlos@snap-20250415 \
into zbackup/solaris/home/carlos@snap-20250415
received 16.3M stream in 7.07 seconds (2.30M/sec)

Replicacion completada.

Intentando destruir instantáneas antiguas zroot/home...
Destruyendo las siguientes instantáneas antiguas:
zroot/home@snap-20250327

Intentando destruir instantáneas antiguas zbackup/solaris...
No se pudo encontrar ninguna instantánea para destruir.
FreeBSD es genial!.

sábado, 14 de diciembre de 2024

Replicación de datos ZFS FreeBSD

Bibliografía:
klarasystems.com
Klara Inc. Allan Jude y Jim Salter
Illumos ZFS Administracion

Diagrama Dia

Replication ZFS en FreeBSD

Lo que hace la replicación ZFS es poder serializar un sistema de archivos. Cuando serializa un objeto en ciencia de datos o programación de computadoras se trata de hacerlo en formato que pueda transportarse con facilidad de tal manera que podamos recrear ese sistema de archivos en el otro lado, de forma que nos permite cruzar sistemas operativos, no importa si la fuente es FreeBSD y el destino es Linux, Illumos, Mac o Windows, etc.

Recrea el sistema de archivo exactamente igual sin depender que sea byte por byte. Eso también proporciona compatibilidad hacia delante y hacia atrás, puede hacer una transmisión ZFS 10 con la última versión de ZFS y aún recibirlo con una versión de ZFS de hace 10 años o viceversa.

Otra cosa importante sobre la forma en que esto funciona en la replicación ZFS es que es unidireccional, por lo que el remitente controla todo lo que empaqueta el sistema de archivos en el formato serializado y lo enviará, no requiere ninguna interacción con el lado que lo va a recibir, lo que significa que no tiene que recibirlo ahora mismo.

Lo interesante sobre la forma en que esto funciona es que no requiere un manejo especial para cosas como permisos, atributos extentidos de ACLS y cualquier otra cosa que pueden estar adjuntos al sistema de archivos, todos son sólo datos que se serializan de la misma manera que el contenido de los archivos, por lo que ZFS no tiene que realizar comprobaciones adicionales ni nigún trabajo extra, simplemente envía los datos y el resto, el lado es responsable de interpretarlo, por lo que si usa algunas de las herramientas de depuración de ZFS podemos ver lo que hay dentro de una secuencia de envío, pero básicamente es un comando de objeto que dice que necesitamos crear un nuevo objeto.

Como toda copia de seguridad todavía debe probar y asegurarse de que puede restaurar el sistema de archivos desde su copia de seguridad.

Sumas de Verificación de un Extremo a Otro

ZFS utiliza sumas de verificación de extremo a extremo por lo que sabemos que ZFS almacena una suma de verificación para cada bloque en el que escribe incluido sus propios metadatos internos. Antes de enviar ZFS se asegura de que los datos que está a punto de enviar son correctos comprobando la suma de verificación, luego los envía con la suma de verificación para que cuando llegue al otro lado verificar que lo que recibe sigue siendo los datos correctos. Después se escriben en disco y al volver a leerlos desde la copia de seguridad verifica de nuevo que sigue siendo la misma suma de verificación y que los datos sobrevivieron intactos. Si los datos están cifrados, también hay un código de verificación allí, asegurándose de que no solo los datos estén intactos sino también que no han sido modificados maliciosamente porque verifica que se descibra correctamente.

¿Que ocurre si por algún motivo se interrumpe la replicación?.

En el lado receptor aparece una propiedad llamada token de reanudación y contiene en qué instantánea estábamos, en que objeto en esa instantánea, que tan lejos en ese objeto y permite reanudar esa replicación. Si ejecutamos

  zfs get -H receive_resume_token zroot/backup
 zstream token 1-ca6584b3f-c0-bb2...
 object: 128
 offset: 1507590144
 bytes: 1511357704
 toguid: 2687048938072742180
 toname: 'zroot/usr/home@snap-20241214'
 

Nos dará una cadena, vemos que estamos enviando el objeto 128, este desplazamiento de 1.5 GB y que tenemos otros 1.5 GB para enviar, la cuadrícula de la instantánea y el nombre de la instantánea.

Como toda copia de seguridad todavía debe probar y asegurarse de que puede restaurar el sistema de archivos desde su backup

En el lado de envío (origen) se utiliza:

zfs send -t receive_resume_token 1-ca6584b3f-c0-bb2...

El token contiene el resto de la información sobre exactamente desde dónde continuar y dejaremos que este envio continue.

Conectar al servidor tormenta vía SSH desde el cliente solaris

El archivo de hosts contiene información sobre los hosts conocidos en la red.

Archivo /etc/hosts

cat /etc/hosts| grep tormenta
192.168.88.160   tormenta

Archivo ~/.ssh/config

$ cat .ssh/config
Host tormenta
	HostName 192.168.88.160
	User carlos
	Port 30000
	AddressFamily inet
	BindInterface em0
	CheckHostIP yes
...
$ ssh tormenta
Last login: Sat Dec 14 06:50:20 2024 from solaris
...

Compruebe que el ssh basado en clave funciona

Copiar la clave publica id_rsa.pub del cliente en el archivo authorized_keys de su cuenta en el servidor

 ssh-keygen

 cat ~/.ssh/id_rsa.pub | ssh remote_host "cat >> .ssh/authorized_keys"

 ssh tormenta
 
 carlos@tormenta:~ %

Particionar el Disco Para las Copias de Seguridad

El disco debe estar desmontado, para averiguar el punto de montaje se utiliza mount y unmount para desmontarlo.

Es importante asegurarse del disco sobre el que va a trabajar. Para ello dispone de múltiples opciones.

 gpart
 gpart show

 lsblk
 lsblk -d
 
 Mostrar discos físicos
 sysctl kern.disks

Y por último usando dmesg para identificar discos conectados, por ejemplo, si conecta un dispositivo de almacenamiento vía USB aparece al final del archivo dmesg

 /sbin/dmesg | tail
 

Preparar el dispositivo de almacenamiento

El comando gpart destroy DESTRUYE EL ESQUEMA DE PARTICIONAMIENTO implementado por GEOM. Es un proceso irreversible. Destruye todos los datos. -F Fuerza la destrucción de la tabla de particiones incluso si no está vacía.

Ya conoce el disco a particionar?

En esta laboratorio es (da1) /dev/da1 de 2 TB con una capacidad real de 1862 GB (2x0.9313 = 1.862 TB = 1862 GB)

gpart destroy -F /dev/da1

gpart create -s gpt /dev/da1
gpart add -t freebsd-zfs -a 1m da1
da1p1 created

zpool create backups /dev/da1p1

zpool set autoexpand=on backups
zpool set listsnapshots=on backups

zfs set mountpoint=/export backups

Consultar propiedades

zfs get mountpoint,name backups
NAME     PROPERTY    VALUE       SOURCE
backups  mountpoint  /export     local
backups  name        backups     -

Crear Conjunto de Datos en pool backups

zfs create -p backups/usr/backup/docs
zfs create backps/usr/home
zfs create -p backups/solarishome/home
zfs create -p backups/recovery/solaris
zfs create backups/recovery/tormenta
zfs create backups/reserved

Listar recursivamente backups

zfs list -r backups
NAME                             USED  AVAIL     REFER  MOUNTPOINT
backups                          480G  1.29T      192K  /export
backups/recovery                 330G  1.29T       96K  /export/recovery
backups/recovery/solaris        67.9G  1.29T     67.9G  /export/recovery/solaris
backups/recovery/tormenta        262G  1.29T      262G  /export/recovery/tormenta
backups/reserved                  96K  1.34T       96K  /export/reserved
backups/solarishome             62.8G  1.29T       96K  /export/solarishome
backups/solarishome/home        62.8G  1.29T     40.4G  /export/solarishome/home
backups/usr                     7.78G  1.29T       96K  /export/usr
backups/usr/backup              7.78G  1.29T       96K  /export/usr/backup
backups/usr/backup/docs         7.78G  1.29T     7.78G  /export/usr/backup/docs
backups/usr/home                6.14M  1.29T     5.97M  /export/usr/home

Listar recursivamente pool zroot servidor tormenta

zfs list -r zroot 
NAME                                   USED  AVAIL   REFER  MOUNTPOINT
zroot                                  170G   264G    112K  /zroot
zroot/ROOT                            40.8G   264G     96K  none
zroot/ROOT/default                    40.8G   264G   36.0G  /
zroot/confsolaris                     1.16M   264G   1.16M  /zroot/confsolaris
zroot/jails                           1.25G   264G     96K  /jails
zroot/jails/loghost                   1.25G   264G   1.25G  /jails/loghost
zroot/jails/media                       96K   264G     96K  /jails/media
zroot/reserved                          96K   289G     96K  /zroot/reserved
zroot/tmp                             2.87G   264G   2.87G  /tmp
zroot/usr                             90.7G   264G     96K  /usr
zroot/usr/backup                      88.5G   264G    128K  /usr/backup
zroot/usr/backup/confiles              284M   264G     96K  /usr/backup/confiles
zroot/usr/backup/confiles/tormenta    4.71M   264G    860K  /usr/backup/confiles/tormenta
zroot/usr/backup/docs                 7.78G   264G   7.78G  /usr/backup/docs
zroot/usr/home                        6.57M   264G   4.82M  /usr/home
zroot/usr/ports                        924M   264G    924M  /usr/ports
zroot/usr/src                         1.26G   264G   1.26G  /usr/src
zroot/var                             1.27G   264G     96K  /var
zroot/var/audit                         96K   264G     96K  /var/audit
zroot/var/crash                         96K   264G     96K  /var/crash
zroot/var/db                            96K   264G     96K  /var/db
zroot/var/jail                        1.26G   264G     96K  /var/jail
zroot/var/jail/www                    1.26G   264G   1.26G  /var/jail/www
zroot/var/log                         3.86M   264G   2.64M  /var/log
zroot/var/mail                         144K   264G    144K  /var/mail
zroot/var/tmp                          152K   264G     96K  /var/tmp

Exportar e Importar backups

Esto asegura que el pool se cierre correctamente y se liberen todos los recursos asociados. Luego, el disco puede ser desconectado de forma segura.

zpool export backups

Grupos disponibles para importar


zpool import
  pool: backups
     id: 10639314260213971789
  state: ONLINE
 action: The pool can be imported using its name or numeric identifier.
 config:

	backups     ONLINE
	  da0p1     ONLINE
zpool import backups	  

Listar Información Sobre los Grupos de Almacenamiento ZFS

zpool list 
NAME      SIZE  ALLOC   FREE  CKPOINT  EXPANDSZ   FRAG    CAP  DEDUP    HEALTH
backups  1.81T   430G  1.39T        -         -     0%    23%  1.00x    ONLINE
zroot     448G   142G   306G        -         -     4%    31%  1.00x    ONLINE

Disponible para importar

zpool import
no pools available to import

Crear las instantáneas

Para crear instantáneas y todos sus sistemas de archivos descendientes se utiliza -r Crear las instantáneas de los conjunto de datos zroot/usr/backup/docs y zroot/usr/home

zfs snapshot -r zroot/usr/home@snap-`date +%Y%m%d`
zfs snapshot -r zroot/usr/backup/docs@snap-`date +%Y%m%d`

Listar instantáneas creadas

zfs list -t snapshot zroot/usr/home@snap-20241213
NAME                           USED  AVAIL     REFER  MOUNTPOINT
zroot/usr/home@snap-20241213   172K      -     5.97M  -

zfs list -t snapshot zroot/usr/backup/docs@snap-20241213
NAME                                  USED  AVAIL     REFER  MOUNTPOINT
zroot/usr/backup/docs@snap-20241213   216K      -     7.78G  -

Enviar la primera instantánea completa

-R con el comando zfs send. Esta opción preservará las propiedades ZFS de cualquier conjunto de datos, instantáneas y clones descendientes en la secuencia.
-d Utilice la ruta completa de la instantánea enviada sin el primer elemento (sin el nombre del grupo) para determinar el nombre de la nueva instantánea
-u No montar el flujo recibido
-v Imprime información detallada sobre la secuencia y el tiempo necesario para realizar la operación de recepción

En el primer envío se utiliza la ruta de destino completa (backups/usr/backup/docs)
En el flujo incremental sólo se utiliza el nombre del pool (backups)

zfs send -R -v zroot/usr/home@snap-20241213 | zfs receive -vd backups/usr/home
zfs send -R -v zroot/usr/backup/docs@snap-20241213 | zfs receive -vdF \
backups/usr/backup/docs

Envío incremental

Tenga en cuenta que el envío de un flujo incremental sólo tendrá éxito si ya existe una instantánea completa inicial en el lado receptor.

Envía todos los bloques que tienen una hora de creacion entre zroot@snap-20241213 y zroot@snap-20241214, se serializan y envían al otro lado que ya tiene zroot@snap-20241213 por lo que puede aplicar los cambios y tener eso también sin tener que mirar lo que hay en zroot@snap-20241213, al contrario que rsync que tiene que revisar archivo por archivo.

Si recibe un error como este al realizar una replicación incremental: "No se puede recibir el flujo incremental las copias de seguridad de destino se han modificado desde la snapshot más reciente", es decir, que las instantáneas de origen y destino ya no son idénticas ZFS aborta la replicación. Use receive -F para forzar al sistema receptor a retroceder al estado de la última instantánea recibida para que los sistemas estén nuevamente sincronizados.

Tomar las instantáneas

zfs snapshot zroot/usr/home@snap-`date +%Y%m%d`
zfs snapshot zroot/usr/backup/docs@snap-`date +%Y%m%d`

Listar instantáneas creadas

zfs list -t snapshot zroot/usr/home@snap-20241213
NAME                           USED  AVAIL   REFER  MOUNTPOINT
zroot/usr/home@snap-20241214   172K      -   5.97M  -

zfs list -t snapshot zroot/usr/backup/docs@snap-20241213
NAME                                  USED  AVAIL   REFER  MOUNTPOINT
zroot/usr/backup/docs@snap-20241214   216K      -   7.78G  -

Enviar el flujo de datos

-F Fuerce una reversión del sistema de archivos a la instantánea más reciente antes de realizar la operación de recepción. Si recibe un flujo de replicación incremental (por ejemplo, uno generado por zfs send -R [-i|-I]), destruya las instantáneas y los sistemas de archivos que no existan en el lado de envío.

zfs send -R -i zroot/usr/home@snap-20241213 zroot/usr/home@snap-20241214 | zfs \
>receive -vdF backups
zfs send -R -i  zroot/usr/backup/docs@snap-20241213 \
zroot/usr/backup/docs@snap-20241214 | zfs receive -vdF backups

Replicación remota a través de SSH

Origen FreeBSD solaris, destino backups servidor tormenta

Tomar la instatánea del conjunto de datos zroot/home

solaris~ # zfs snapshot zroot/home@snap-`date +%Y%m%d`
 

Listar instantánea

solaris~ # zfs list -t snapshot zroot/home@snap-20241213
NAME                       USED  AVAIL  REFER  MOUNTPOINT
zroot/home@snap-20241213  25.4M      -  39.2G  -
solaris~ # zfs send -Rv zroot/home@snap-20241213 | ssh root@tormenta "zfs \
receive -vdF backups/solarishome/home"
 

Replicación remota incremental

Tomar la instantánea

solaris~ # zfs snapshot zroot/home@snap-`date +%Y%m%d`

Listar las intantáneas

solaris~ # zfs list -t snapshot | grep "zroot/home@snap-*"   
zroot/home@snap-20241213           185M      -  39.2G  -
zroot/home@snap-20241214            53.4M    -  39.2G  -

Replicar el flujo de datos

 solaris~ # zfs send -R -v zroot/home@snap-20241213 zroot/home@snap-20241214 | \
 ssh root@tormenta "zfs receive -vdF backups"

Exportar e importar pool backups

 zfs export backups
 zfs import backups
 

Donde están las instantáneas?

Conectarse al servidor tormenta vía SSH

solaris~ $ ssh tormenta
carlos@tormenta~ $ % ls -l /export/solarishome/home/.zfs/snapshot
total 1
drwxr-xr-x  5 root  wheel  5 May 30  2024 snap-20241213
drwxr-xr-x  5 root  wheel  5 May 30  2024 snap-20241214

carlos@tormenta~ $ % ls -l /export/usr/home/.zfs/snapshot
total 1
drwxr-xr-x  4 root  wheel  4 Jul 24 17:31 snap-20241213
drwxr-xr-x  4 root  wheel  4 Jul 24 17:31 snap-20241214

carlos@tormenta:~ % ls -l /export/usr/backup/docs/.zfs/snapshot
total 289
drwxr-xr-x  30 carlos  wheel  923 Dec 12 08:19 snap-20241212
drwxr-xr-x  30 carlos  wheel  926 Dec 13 07:34 snap-20241214

carlos@tormenta:~ % zfs list -t snapshot -o name | grep "zroot/usr/backup/docs@snap-"
zroot/usr/backup/docs@snap-20241213    248K    -   7.78G  -
zroot/usr/backup/docs@snap-20241214    216K    -   7.78G  -

carlos@tormenta:~ % zfs list -t snapshot -o name | grep "zroot/usr/home@snap-"
zroot/usr/home@snap-20241213    172K    -   5.97M  -
zroot/usr/home@snap-20241214    172K    -   5.97M  -

Listar todas las instantáneas en backups

carlos@tormenta:~ % zfs list -t snapshot -r backups
NAME                                     USED  AVAIL   REFER  MOUNTPOINT
backups/solarishome/home@snap-20241213  22.5G      -   62.8G  -
backups/solarishome/home@snap-20241214     0B      -   40.4G  -
backups/usr/backup/docs@snap-20241213    276K      -   7.78G  -
backups/usr/backup/docs@snap-20241214      0B      -   7.78G  -
backups/usr/home@snap-20241213           172K      -   5.97M  -
backups/usr/home@snap-20241214             0B      -   5.97M  -

Tenga en cuenta las siguientes consideraciones al restaurar una instantánea:

. Se restaura la instantánea y el sistema de archivos.
. El sistema de archivos y todos los sistemas de archivos descendientes se desmontan.
. Los sistemas de archivos son inaccesibles mientras se restauran.
. El sistema de archivos original que e va a restaurar no debe exister mientras está siendo restaurado.
. Si existe un nombre de sistema de archivos en conflicto, puede utilizarse zfs rename para cambiar el nombre del sistema de archivos.

Restaurar instantánea de forma remota

-d Utilice la ruta completa de la instantánea enviada sin el primer elemento (sin el nombre del grupo) para determinar el nombre de la nueva instantánea.

 
ssh root@tormenta "zfs send -Rv backups/filesolaris/confsolaris@snap-20241215" \
| zfs receive -vFd zroot

full send of toshiba/filesolaris/confsolaris@snap-20241215 estimated size is 1.20M
total estimated size is 1.20M
receiving full stream of toshiba/filesolaris/confsolaris@snap-20241215 into \
zroot/filesolaris/confsolaris@snap-20241215
received 1.20M stream in 0.06 seconds (19.0M/sec)

Recuperar el flujo de datos desde tormenta (pool backups) a solaris

solaris~ # ssh root@tormenta "zfs send -Rv backups/usr/backup/docs@snap-20241216" \
zfs receive zroot/documentos

full send of toshiba/usr/backup/docs@snap-20241216 estimated size is 7.88G
send from @snap-20241216 to toshiba/usr/backup/docs@snap-20241217 estimated size is 105K
total estimated size is 7.88G
TIME   SENT   SNAPSHOT toshiba/usr/backup/docs@snap-20241216
...

 zfs list | grep "zroot/documentos"
zroot/documentos    96K   330G   96K  /zroot/documentos

Enviar el flujo de datos a un archivo

zfs send zroot/usr/home@-20241222-snap1 > usr.home.20241222.servidor

Podemos utilizar el comando receive y proporcionar el grupo en el que desea importarlo y podría ser un grupo completamente diferente, y es probablemente la principal razon por la que usarias esto para transferir un conjunto de datos a otro sistema, especifica el grupo y el conjunto de datos al que desea importarlo, si no proporciona uno simplemente creará un conjunto de datos con el nombre que se usó desde el momento en que se creo la instantánea. Ahora, usando cat nombre del archivo y canalizarlo a través de una tuberia a zfs receive, se creará un nuevo conjunto de datos llamado zroot/homeservidor

 cat usr.home.20241222.tormenta | zfs receive zroot/home.20241222.servidor

Listar el conjunto de datos
 zfs list | grep "zroot/homeservidor"
zroot/homeservidor  4.82M  264G  4.82M  /zroot/home.20241222.servidor


Otro ejemplo de envío y recepción de datos ZFS:

El comando zfs send crea una representación de flujo de una instantánea que está escrita, a la salida estándar. Puede redirigir la salida a un archivo o a un sistema diferente. El comando zfs receive crea una instantánea cuyo contenido se especifica en la secuencia que se proporciona en la entrada estándar. Si se recibe una transmisión completa, un nuevo sistema de archivos también se crea.

Creacion de los conjuntos de datos

 zfs -p create zroot/usuarios/user1
 zfs create zroot/usuarios/user2
 zfs create zroot/usuarios/user3

 zfs list -r zroot/usuarios
 NAME                   USED  AVAIL  REFER  MOUNTPOINT
 zroot/usuarios        63.5M   351G  63.2M  /zroot/usuarios
 zroot/usuarios/user1    96K   351G    96K  /zroot/usuarios/user1
 zroot/usuarios/user2    96K   351G    96K  /zroot/usuarios/user2
 zroot/usuarios/user3    96K   351G    96K  /zroot/usuarios/user3

Tomar las instantáneas

 zfs snapshot -r zroot/usuarios@hoy

Se crea una secuencia de replicación para todas las instantáneas de usuarios

 zfs send -R zroot/usuarios@hoy > /snaps/usuarios

A continuación, los sistemas de archivos originales y las instantáneas se destruyen

 zfs destroy -r zroot/usuarios
 zfs list -r zroot/usuarios
 cannot open 'zroot/usuarios': dataset does not exist

Y luego se recuperan

 zfs receive -Fd zroot < /snaps/usuarios
 zfs list -r zroot/usuarios
 NAME                   USED  AVAIL  REFER  MOUNTPOINT
 zroot/usuarios        63.6M   351G   112K  /zroot/usuarios
 zroot/usuarios/user1    96K   351G    96K  /zroot/usuarios/user1
 zroot/usuarios/user2    96K   351G    96K  /zroot/usuarios/user2
 zroot/usuarios/user3    96K   351G    96K  /zroot/usuarios/user3
FreeBSD es genial!.

martes, 31 de enero de 2023

Jails VNET iocage FreeBSD 13.1

Usar VNET con una jail usando iocage

klara Systems. Virtualise your network on FreeBSD with VNET iocage 1.2 documentation

Las pilas de red virtual VNET de FreeBSD, una potente tecnología de aislamiento de pila de red que otorga superpoderes a las cárceles de FreeBSD.

iocage es un administrador de cárceles (jails) que combina algunas de las características y tecnologiías de FreeBSD, iocage requiere ZFS para funcionar. Utiliza archivos de configuración almacenados con cada cárcel individual. Cuando iocage inicia, lee sus propios archivos de configuración y activa jail para crear e iniciar todas las cárceles que ha marcado para el inicio automático.

Las cárceles configuradas en jail.conf no entran en conflicto con las adminstradas por iocage. Ambos sistemas funcionan de forma independiente.

La gestión de hosts Unix se hace a través de sshd. Cada cárcel tendrá su propia IP.

Las reglas de TCP/IP dicen que solo un proceso puede escuchar en una combinación de dirección IP y puerto a la vez. SSH por defecto se conecta al puerto 22 en todas las direcciones IP en un huésped. Los host usan el puerto 22, las cárceles usan el puerto 23.

Entrar al host (tormenta) vía SSH

 ssh carlos@tormenta

Restringir la dirección IP de escucha del host

ListenAddress 192.168.88.160

Reiniciar el servicio sshd

 service sshd restart

El demonio ntpd escucha en todas las direcciones IP posible. Las cárceles toman su tiempo del anfitrión.

Instalar iocage

 pkg install py39-iocage

Dependencias de iocage

 pkg search -d py39-iocage
py39-iocage-1.2_10
Comment        : FreeBSD jail manager written in Python3
Depends on     :
        py39-requests-2.28.1_1
        py39-texttable-1.6.7
        ca_root_nss-3.87
        py39-netifaces-0.11.0
        py39-tqdm-4.64.1
        python39-3.9.16
        py39-dnspython-2.2.1_1,1
        rcs57-5.7
        py39-typing-extensions-4.4.0
        py39-setuptools-63.1.0
        py39-libzfs-1.1.2022081600
        py39-jsonschema-4.16.0
        py39-gitpython-3.1.30
        py39-coloredlogs-15.0.1
        py39-click-8.1.3
        git-2.39.1

Montar el sistema de ficheros de descriptores de ficheros

 mount -t fdescfs null/dev/fd

Agregamos esta entrada a /etc/fstab para hacerlo permanente

 fdesc  /dev/fd   fdescfs rw    0       0

uname -a

FreeBSD tormenta 13.1-RELEASE-p3 FreeBSD 13.1-RELEASE-p3 GENERIC amd64

Comprobar el nombre del zpool

 zpool list
NAME    SIZE  ALLOC   FREE  CKPOINT  EXPANDSZ   FRAG    CAP  DEDUP    HEALTH  ALTROOT
zroot   448G  79.3G   369G        -         -     1%    17%  1.00x    ONLINE  -

Activar el zpool

 iocage activate zroot
ZFS pool 'zroot' successfully activated.

Descargar la versión de FreeBSD que será la base de nuestros jails

 iocage fetch

Press [Enter] to fetch the default selection: (13.1)
ENTER

Creación de una Jail con VNET activada

FreeBSD 13.1 habilita la compatibilidad con VNET de forma predeterminada, lo que otorga a cada cárcel su propia pila de red y facilita el encarcelamiento de aplicaciones individuales utilizando iocage.

Dirección IP estática del servidor tormenta y router por defecto /etc/rc.conf

...
ifconfig_re0="inet 192.168.88.160 netmask 255.255.255.0"
defaultrouter="192.168.88.1"
...

Archivo revolv.conf

cat /etc/resolv.conf
# Generated by resolvconf
nameserver 192.168.88.200

interface Ethernet

 ifconfig
re0: flags=8943<UP,BROADCAST,RUNNING,PROMISC,SIMPLEX,MULTICAST> metric 0 mtu 1500
        options=82099<RXCSUM,VLAN_MTU,VLAN_HWTAGGING,VLAN_HWCSUM,WOL_MAGIC,LINKSTATE>
        ether 88:ae:dd:0c:a5:c6
        inet 192.168.88.160 netmask 0xffffff00 broadcast 192.168.88.255

media: Ethernet autoselect (1000baseT <full-duplex,master>)
        status: active
...

Habilitar iocage

 sysrc iocage_enable=YES

Crear un bridge

# VNET iocage
cloned_interfaces="bridge0"
ifconfig_bridge0="addm re0 up"

Agregue estos parámetros ajustables a /etc/sysctl.conf

net.inet.ip.forwarding=1       # Enable IP forwarding between interfaces
net.link.bridge.pfil_onlyip=0  # Only pass IP packets when pfil is enabled
net.link.bridge.pfil_bridge=0  # Packet filter on the bridge interface
net.link.bridge.pfil_member=0  # Packet filter on the member interface

Crear una jail llamada vikingo con VNET activada, una direccón IP estática (192.168.88.254) defaultrouter 192.168.88.1

bpf="yes"         # Alternar el inicio de la jaula con los dispositivos Berkely 
                    Packet Filter habilitados
-n "vikingo"      # Nombre de la jail
-r                # jail basada en 13.1-RELEASE FreeBSD
allow_raw_sockets # Permitir ping
vnet="on"         # Usar VNET
boot="on"         # Inicar jail al arranque
defaultrouter="192.168.88.1" # Router por defecto
ip4_addr="192.168.88.250/24 # Dirección IP fija de la jail

Creación de la jail

 iocage create -n "vikingo" -r 13.1-RELEASE vnet="on" bpf="yes" \
allow_raw_sockets="1" boot="on" defaultrouter="192.168.88.1" \
ip4_addr="192.168.88.254/24"
vikingo successfully created!

Al inicio de una cárcel, el sistema copia automáticamente /etc/resolv.conf del host a la cárcel. Si la información no es correcta, puede utilizar la propiedad resolver de iocage para actualizarla.

 iocage set resolver="nameserver 192.168.88.200" vikingo
resolver: /etc/resolv.conf -> nameserver 192.168.88.200

Comprobar ping desde otra máquina en la red

solaris:~ % ping -c 2 192.168.88.254
PING 192.168.88.254 (192.168.88.254): 56 data bytes
64 bytes from 192.168.88.254: icmp_seq=0 ttl=64 time=0.546 ms
64 bytes from 192.168.88.254: icmp_seq=1 ttl=64 time=0.314 ms

--- 192.168.88.254 ping statistics ---
2 packets transmitted, 2 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 0.314/0.430/0.546/0.116 ms

Visualizar las cárceles

# iocage list
+-----+----------+-------+--------------+-------------------+
| JID |   NAME   | STATE |   RELEASE    |        IP4        |
+=====+==========+=======+==============+===================+
+-----+----------+-------+--------------+-------------------+
| 1   | vikingo  | up    | 13.1-RELEASE | 192.168.88.254/24 |
+-----+----------+-------+--------------+-------------------+

Para acceder a la consola de una jail

 iocage console jailnombre

La jail no ve la red del host

exec - Iniciar comando dentro de la jail

iocage exec vikingo ifconfig

 lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> metric 0 mtu 16384
        options=680003<RXCSUM,TXCSUM,LINKSTATE,RXCSUM_IPV6,TXCSUM_IPV6>
        inet6 ::1 prefixlen 128
        inet6 fe80::1%lo0 prefixlen 64 scopeid 0x1
        inet 127.0.0.1 netmask 0xff000000
        groups: lo
        nd6 options=21<PERFORMNUD,AUTO_LINKLOCAL>
epair0b: flags=8863<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
        options=8<VLAN_MTU>
        ether 88:ae:dd:ff:a6:c2
        hwaddr 02:3f:a6:be:0e:0b
        inet 192.168.88.254 netmask 0xffffff00 broadcast 192.168.88.255
        inet6 fe80::8aae:ddff:feff:a6c2%epair0b prefixlen 64 scopeid 0x2
        groups: epair
        media: Ethernet 10Gbase-T (10Gbase-T <full-duplex>)
        status: active
        nd6 options=21<PERFORMNUD,AUTO_LINKLOCAL>

interfaces en el host

 ifconfig
re0: flags=8943<UP,BROADCAST,RUNNING,PROMISC,SIMPLEX,MULTICAST> metric 0 mtu 1500
        options=8209b<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,VLAN_HWCSUM,WOL_MAGIC,LINKSTATE>
        ether 88:ae:dd:0c:a5:c6
        inet 192.168.88.160 netmask 0xffffff00 broadcast 192.168.88.255
        inet 192.168.88.210 netmask 0xffffff00 broadcast 192.168.88.255
        media: Ethernet autoselect (1000baseT <full-duplex,master>)
        status: active
        nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL>
lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> metric 0 mtu 16384
        options=680003<RXCSUM,TXCSUM,LINKSTATE,RXCSUM_IPV6,TXCSUM_IPV6>
        inet6 ::1 prefixlen 128
        inet6 fe80::1%lo0 prefixlen 64 scopeid 0x2
        inet 127.0.0.1 netmask 0xff000000
        groups: lo
        nd6 options=21<PERFORMNUD,AUTO_LINKLOCAL>
vnet0.5: flags=8862<BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
        description: associated with jail: vikingo as nic: epair0b
        options=8<VLAN_MTU>
        ether 88:ae:dd:ff:a6:c1
        hwaddr 02:35:3d:4b:cb:0a
        groups: epair
        media: Ethernet 10Gbase-T (10Gbase-T <full-duplex>)
        status: active
        nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL>
bridge0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
        ether 58:9c:fc:10:ff:ba
        id 00:00:00:00:00:00 priority 32768 hellotime 2 fwddelay 15
        maxage 20 holdcnt 6 proto rstp maxaddr 2000 timeout 1200
        root id 00:00:00:00:00:00 priority 32768 ifcost 0 port 0
        member: re0 flags=143<LEARNING,DISCOVER,AUTOEDGE,AUTOPTP>
                ifmaxaddr 0 port 1 priority 128 path cost 20000
        groups: bridge
        nd6 options=9<PERFORMNUD,IFDISABLED>

Python3 está instalado en el host y como nuestro jail no aísla el sistema de archivos, todo el software instalado también está disponible para el jail podemos usar el servidor http integrado en python3 para mostrar un servicio de red simple que se ejecuta dentro de la cárcel.

 iocage exec vikingo sh -c "cd /root; python3 -m http.server"
Serving HTTP on :: port 8000 (http://[::]:8000/) ...
::ffff:192.168.88.51 - - [30/Jan/2023 14:56:29] "GET / HTTP/1.1" 200 -

Un navegador web en una máquina host puede apuntar a 192.168.88.254:8000 y podemos navegar por la estructura del árbol fuente de FreeBSD que vive en /root de la jail

http://192.168.88.254:8000

Entramos en la jail vikingo

 iocage console vikingo

Vamos a crear el directorio /usr/local/www

mkdir /usr/local/www

Y dentro del directorio www el archivo index.html

<html><body><p><em>vikingo: Lunes 30 enero 16:47 PDT 2023</p></em></body></html>

Salimos de la jaula tecleando exit y usamos el servidor http integrado en python para mostrar index.html en el navegador

tormenta: # iocage exec vikingo sh -c "cd /usr/local/www; python3 -m http.server"
Serving HTTP on :: port 8000 (http://[::]:8000/) ...

Desde otra máquina de la red

http://192.168.8.26.254:8000

# iocage exec vikingo sh -c "cd /usr/local/www; python3 -m http.server"
Serving HTTP on :: port 8000 (http://[::]:8000/) ...
::ffff:192.168.88.51 - - [30/Ene/2023 19:10:08] "GET / HTTP/1.1" 304 -

El archivo config.json creado automáticamente por iocage de la jail

 # cat /iocage/jails/vikingo/config.json
{
    "allow_raw_sockets": 1,
    "boot": 1,
    "bpf": 1,
    "cloned_release": "13.1-RELEASE",
    "defaultrouter": "192.168.88.1",
    "host_hostname": "vikingo",
    "host_hostuuid": "vikingo",
    "ip4_addr": "192.168.88.254/24",
    "jail_zfs_dataset": "iocage/jails/vikingo/data",
    "last_started": "2023-01-28 21:04:54",
    "release": "13.1-RELEASE-p5",
    "resolver": "nameserver 192.168.88.200",
    "vnet": 1,
    "vnet0_mac": "88aeddffa6c1 88aeddffa6c2"
}

Entrar en la jaula

 iocage console vikingo
Last login: Wed Feb  8 18:49:10 on pts/1
FreeBSD 13.1-RELEASE-p3 GENERIC

Welcome to FreeBSD!

Release Notes, Errata: https://www.FreeBSD.org/releases/
Security Advisories:   https://www.FreeBSD.org/security/
FreeBSD Handbook:      https://www.FreeBSD.org/handbook/
FreeBSD FAQ:           https://www.FreeBSD.org/faq/
Questions List: https://lists.FreeBSD.org/mailman/listinfo/freebsd-questions/
FreeBSD Forums:        https://forums.FreeBSD.org/

Documents installed with the system are in the /usr/local/share/doc/freebsd/
directory, or can be installed later with:  pkg install en-freebsd-doc
For other languages, replace "en" with a language code like de or fr.

Show the version of FreeBSD installed:  freebsd-version ; uname -a
Please include that output and any error messages when posting questions.
Introduction to manual pages:  man man
FreeBSD directory layout:      man hier

To change this login announcement, see motd(5).
root@vikingo:~ # 

Instalar wget

# pkg install wget
The package management tool is not yet installed on your system.
Do you want to fetch and install it now? [y/N]: y
Bootstrapping pkg from pkg+http://pkg.FreeBSD.org/FreeBSD:13:amd64/quarterly, please wait...
Verifying signature with trusted certificate pkg.freebsd.org.2013102301... done
[vikingo] Installing pkg-1.19.0...
[vikingo] Extracting pkg-1.19.0: 100%
Updating FreeBSD repository catalogue...
[vikingo] Fetching meta.conf: 100%    163 B   0.2kB/s    00:01
[vikingo] Fetching packagesite.pkg: 100%    6 MiB   1.1MB/s    00:06
Processing entries: 100%
FreeBSD repository update completed. 32411 packages processed.
All repositories are up to date.
Updating database digests format: 100%
The following 5 package(s) will be affected (of 0 checked):

New packages to be INSTALLED:
        gettext-runtime: 0.21.1
        indexinfo: 0.3.1
        libidn2: 2.3.4
        libunistring: 1.1
        wget: 1.21.3_1

Number of packages to be installed: 5

The process will require 8 MiB more space.
2 MiB to be downloaded.

Proceed with this action? [y/N]:

Detener una jail

# iocage stop vikingo
* Stopping vikingo
  + Executing prestop OK
  + Stopping services OK
  + Removing devfs_ruleset: 1001 OK
  + Removing jail process OK
  + Executing poststop OK

Inicar jail vikingo

 iocage start vikingo
* Starting vikingo
  + Started OK
  + Using devfs_ruleset: 1000 (iocage generated default)
  + Configuring VNET OK
  + Using IP options: vnet
  + Starting services OK
  + Executing poststart OK

Obtener el hostid de una jail

 iocage get hostid vikingo
1867b930-d81e-6f28-017a-88aedd0ca5c6

Destruir una jail

-f Destruye la jaula sin advertencias o intervención del usuario

 iocage destroy nombrejail -f

Reiniciar jail

 iocage restart vikingo
* Stopping vikingo
  + Executing prestop OK
  + Stopping services OK
  + Tearing down VNET OK
  + Removing devfs_ruleset: 1000 OK
  + Removing jail process OK
  + Executing poststop OK
* Starting vikingo
  + Started OK
  + Using devfs_ruleset: 1000 (iocage generated default)
  + Configuring VNET OK
  + Using IP options: vnet
  + Starting services OK
  + Executing poststart OK

Gestión de snapshots

Una de las funcionalidades más interesantes son los snapshots. Se crean ejecutando el siguiente comando

 iocage snapshot -n snap_vikingo00 vikingo
Snapshot: zroot/iocage/jails/vikingo@snap_vikingo00 created.

Ver los snapshots de una jail

 iocage snaplist vikingo
+---------------------+-----------------------+-------+------+
|        NAME         |        CREATED        | RSIZE | USED |
+=====================+=======================+=======+======+
| snap_vikingo00      | Tue Jan 31  7:41 2023 | 108K  | 0B   |
+---------------------+-----------------------+-------+------+
| snap_vikingo00/root | Tue Jan 31  7:41 2023 | 1.64G | 0B   |
+---------------------+-----------------------+-------+------+

El primer snapshot contiene el directorio de configuración de la jail (config.json fstab). El segundo snapshot de la raiz de la jail

Revertir la jail

Antes se detiene la jail

 iocage stop vikingo

Revertir el conjunto de datos a una instantánea

 iocage rollback -n snap_vikingo00 vikingo

Dump snapshot

Crear snapshot de la carcel con iocage

 iocage snapshot -n snap00_vikingo vikingo
Snapshot: zroot/iocage/jails/vikingo@snap00_vikingo created.

Listar snapshots

iocage snaplist vikingo

 iocage snaplist vikingo
+---------------------+-----------------------+-------+------+
|        NAME         |        CREATED        | RSIZE | USED |
+=====================+=======================+=======+======+
| snap00_vikingo      | Tue Jan 31  9:35 2023 | 116K  | 0B   |
+---------------------+-----------------------+-------+------+
| snap00_vikingo/root | Tue Jan 31  9:35 2023 | 1.47G | 0B   |
+---------------------+-----------------------+-------+------+

Visualizar desde ZFS

zfs list -t snapshot| grep vikingo
zroot/iocage/jails/vikingo@snap00_vikingo        0B      -      116K  -
zroot/iocage/jails/vikingo/root@snap00_vikingo   0B      -     1.47G  -
zroot/iocage/releases/13.1-RELEASE/root@vikingo  0B      -     1.46G  -

Tenemos dos snapshots, nos interesa el del sistema de ficheros raiz

Dump snapshot a un fichero

 zfs send zroot/iocage/jails/vikingo/root@snap00_vikingo > /root/vikingo.raw

Es recomendable hacer copias los ficheros de configuracion

 cp /iocage/jails/vikingo/config.json /root/vikingo
 cp /iocage/jails/vikingo/fstab /root/vikingo

Destruir el snapshot

 iocage snapremove -n snap00_vikingo vikingo
Snapshot: zroot/iocage/jails/vikingo@snap00_vikingo destroyed

Comprobar

 zfs list -t snapshot | grep vikingo
zroot/iocage/releases/13.1-RELEASE/root@vikingo   0B   -     1.46G  -

Restaurar el dataset ZFS

 zfs recv -dvu zroot/iocage/jails/vikingo < /root/vikingo/vikingo.raw
receiving full stream of zroot/iocage/jails/vikingo/root@snap01_vikingo_310123 \
into zroot/iocage/jails/vikingo/iocage/jails/vikingo/root@snap01_vikingo_310123
received 2.74G stream in 5 seconds (561M/sec)
FreeBSD es genial!.

domingo, 18 de diciembre de 2022

Replicar, Recuperar Pool Root FreeBSD ZFS

NFS Sistema de Archivos en Red FreeBSD
Montaje de Sistema de Archivos NFS Usando Autofs
Replicar, Recuperar Pool Root ZFS FreeBSD

Contruir o reconstruir un sistema a partir de instantáneas (snapshot)

Replicar instantáneas en otro sistema es una característica de OpenZFS que mejora la administración de datos, proporciona un mecanismo para manejar una falla de hardware con una pérdida de datos y un tiempo de inactividad mínimos. La replicación también es una forma conveniente de transferir una copia de un sistema existente a otro, por ejemplo, implementar un laboratorio completo de sistemas similares.

Escenario

Servidor: tormenta FreeBSD 13.1 NUC 11 Essential DDR4-2933 CPU 4 \
          32GB RAM M.2 NVMe PCIe 3.0
Cliente: solaris FreeBSD 13.1 Dell Latitude 7390 DDR4-2400 CPU 8 \
          16GB RAM M.2 NVMe PCIe 3.0

Enviar una copia de seguridad al servidor vía ssh utilizando zfs send receive

% cat /etc/hosts | grep tormenta
...
192.168.88.160          tormenta
...

Configurar acceso SSH

OpenZFS utiliza SSH para cifrar la replicación durante la transferencia de red.

Puede generar un par de claves con ssh-keygen y luego enviar una copia de la clave pública al servidor. Presione enter en todas las indicaciones para aceptar los valores predeterminados y no solicitar una frase de contraseña.

Dado que root enviará la replica, cambie esta línea en el archivo de configuración del demonio SSH /etc/ssh/sshd_config

#PermitRootLogin no

a

PermitRootLogin yes

Recargar la configuración del demonio SSH

service sshd reload

Enviar una copia de la clave pública al sistema recector (tormenta)

cat ~/.ssh/id_rsa.pub | ssh 192.168.88.160 'cat >>.ssh/authorized_keys' 
Password for root@192.168.88.160: 
exit

Crear un conjunto de datos para almacenar las instatáneas replicadas /usr/backup/poolrecovery.

tormenta # zfs create -p zroot/usr/backup/poolrecovery

Creamos la instantánea recursiva del conjunto de datos del pool zroot que incluye los sistemas de archivos secundarios

solaris # zfs snapshot -r zroot@zroot.snap1_dell

Comprobar los recursos compartidos por el servidor tormenta

solaris % showmount -e tormenta
Exports list on tormenta:
...
/usr/backup/poolrecovery        192.168.88.0 
...

Montar el recurso compartido

# mount -o soft,intr,rw tormenta:/usr/backup/poolrecovery /mnt

Enviar la instantánea de forma recursiva, redirigimos (como archivo comprimido .gz) a la ubicación compartida para poder acceder a esta ubicación al construir el cliente

# zfs send -Rv zroot@snap1_dell | gzip > /mnt/zroot.snap1.gz

Enviar a un sistema que se encuentra en otra ubicación geografica a través de una conexión ssh

zfs send -Rv zroot@snap-20241125 | ssh root@185.166.84.138 "gzip > \ 
/export/recovery/solaris/zroot@snap-solaris-20241125.gz"

Enviar al servidor de la red local a través de una conexión ssh

zfs send -Rv zroot@snap-20241125 | ssh root@192.168.88.160 "gzip > \ 
/export/recovery/solaris/zroot@snap-solaris-20241125.gz"

Proceso de recuperación

Asumimos que ha realizado una instalación limpia en el sistema a restaurar eligiendo el particionado auto ZFS en el instalador FreeBSD.

Iniciar con una memoria usb que contenga una img de FreeBSD 13.1 (misma RELEASE usada en la instalación del sistema a recuperar)

En la pantalla de instalacion

Install Shell Live cd

Elegir (live cd)

login: root

Intro (no necesita contrasena)

Iniciar la red con el comando

dhclient em0

Ver información de la conexión

# ifconfig

Comprobar conectividad

# ping freebsd.org

Importar el zpool

mkdir /tmp/zroot
zpool import -fR /tmp/zroot zroot

Para poder recibir directamente sobre zroot (sin el error de hijos), renombrar los conjuntos de datos de la instalación limpia a .old antes de lanzar el zfs receive.

Alternativa más elegante (un solo comando para todos)

Renombrar TODOS los hijos directos de zroot

for ds in $(zfs list -H -o name zroot | grep -v "^zroot$"); do 
	zfs rename -r "$ds" "${ds}.old"
done

Esto captura ROOT, tmp, usr, var, home y cualquier otro que haya aparecido.

Inspeccionar el contenido del backup antes de recibirlo (por comprobar su estructura)

ssh root@192.168.88.160 "cat /zbackup/recovery/solaris/zroot@snap-freebsd-14.3-release-p7-2026-5-enero.gz" | gzcat | zfs receive -nv zroot

La opción -n (dry-run) simula la recepción y muestra qué datasets se crearían, sin escribir nada.

Si se quere ver el progreso en porcentaje durante la transferencia, se puede intercalar pv (si está instalado)

ssh root@192.168.88.160 "cat /zbackup/recovery/solaris/zroot@snap-freebsd-14.3-release-p7-2026-5-enero.gz" | gzcat | pv | zfs receive -Fv zroot

Justo después de renombrar los datasets viejos (.old), y antes del zfs receive real, puedes añadir este paso de verificación robusta:

Verificación robusta

Verificación con zstreamdump (muestra resumen + checksum). zstreamdump puede ser lento con backups grandes y es opcional, pero muy recomendable para detectar corrupción antes de empezar.

ssh root@192.168.88.160 "cat /zbackup/recovery/solaris/zroot@snap-freebsd-14.3-release-p7-2026-5-enero.gz" | gzcat | zstreamdump

Si todo está bien, verás algo parecido a

BEGIN record
...
Total write size = 1234567890
END checksum = f1e2d3c4b5a6...

Pasar el archivo por red sin montar ningún directorio


Restaurar el backup (recibe directamente sobre zroot)

ssh root@192.168.88.160 "cat /zbackup/recovery/solaris/zroot@snap-freebsd-14.3-release-p7-2026-5-enero.gz" | gzcat | zfs receive -Fv zroot

VERIFICAR la Estructura Restaurada ANTES DE REINICIAR


Listar toda la jerarquía restaurada

zfs list -r zroot

Buscar el dataset que contiene el directorio /boot (señal inequívoca de sistema base)

zfs list -r zroot/ROOT
NAME                                           USED  AVAIL  REFER  MOUNTPOINT
zroot/ROOT                                     110G   177G    96K  none
zroot/ROOT/default                             110G   177G  26.5G  /

Confirmar el arranque apuntando a este conjunto de datos

zpool set bootfs=zroot/ROOT/default zroot

Ajustar el punto de montaje para que al reiniciar se monte en /

zfs set mountpoint=/ zroot/ROOT/default

Exportar el zpool y reiniciar

zpool export zroot
shutdown -r now

Si después de reiniciar todo funciona, limpiar los restos de la vieja instalación (ya dentro del nuevo sistema)

zfs destroy -rf zroot/ROOT.old zroot/tmp.old zroot/usr.old zroot/var.old zroot/home.old

-r recursivamente destruye todos los hijos
-f Si algún dataset está montado fuerza el desmontaje del conjunto de datos

FreeBSD es genial!.

Beadm ZFS Boot Environments FreeBSD

Desarrollador: vermaden

https://vermaden.wordpress.com/2022/03/14/zfs-boot-environments-revolutions/comment-page-1/

Instalar beadm

pkg install -y beadm

Listar entornos de arranque

beadm list
BE                     Active Mountpoint  Space Created
default                -      -            2.0M 2022-12-15 12:19
pkg_update_171222      -      -            7.0G 2022-12-17 21:49
# beadm create pkg_upgrade_1712222335

Activar el be

# beadm activate pkg_upgrade_1712222335
Activated successfully

Listar boot environments

BE                     Active Mountpoint  Space Created
default                N      -            2.0M 2022-12-15 12:19
pkg_update_171222      -      -            7.0G 2022-12-17 21:49
pkg_upgrade_1712222335 R     /           34.2G 2022-12-17 23:35

N = activo ahora
R = estara activo el proximo reinicio

Reiniciar

# reboot
beadm list
BE                     Active Mountpoint  Space Created
default                -      -            2.0M 2022-12-15 12:19
pkg_update_171222      -      -            7.0G 2022-12-17 21:49
pkg_upgrade_1712222335 NR     /           34.2G 2022-12-17 23:35
mount
zroot/ROOT/pkg_upgrade_1712222335 on / (zfs, local, noatime, nfsv4acls)

Ya puede instalar los ultimos parches de FreeBSD sin estropear su sistema predeterminado.

pkg update
pkg upgrade
freebsd-update fetch
freebsd-update install

reroot reroot Utiliza la función 'reroot' del comando reboot(8) -r.

reroot sólo está presente en beadm, le dira a freebsd que vuelva a rootear su nucleo en ejecucion en el be especificado. Ahorra mucho tiempo en un un servidor o máquina física.

beadm reroot pkg_upgrade_1712202335

Genial

beadm

sage:
beadm activate <
  beadm create 
  beadm create 
  beadm destroy 
  beadm export 
  beadm import
  beadm list 
  beadm rename 
  beadm mount 
  beadm 
  beadm chroot 
  beadm 
  beadm version
FreeBSD es genial!.

miércoles, 21 de septiembre de 2022

Freebsd tar Excluir Directorios

Fuente:
https://www.gnu.org/software/tar/manual/html_node/exclude.html#exclude

Ciertas opciones para tar le permite especificar un nombre para su archivo. Otras opciones le permiten decidir qué archivos incluir o excluir del archivo, en función de cuándo o si se modificaron los archivos, si los nombres de los archivos coinciden o no con los patrones especificados, o si los archivos están en directorios especificados.

Realizar copias con tar excluyendo directorios listados dentro de un archivo, utilizando la opción --exclude-from

Importamos el zpool copias

# zpool import copias
# zpool status
  pool: copias
 state: ONLINE
config:

	NAME        STATE     READ WRITE CKSUM
	copias      ONLINE       0     0     0
	  da0p1     ONLINE       0     0     0

errors: No known data errors

  pool: zroot
 state: ONLINE
config:

	NAME        STATE     READ WRITE CKSUM
	zroot       ONLINE       0     0     0
	  nvd0p4    ONLINE       0     0     0

errors: No known data errors

Creamos el archivo excluir_dirs.txt donde incluiremos todos los directorios a excluir de la copia

carlos@foo:~ % pwd

/usr/home/carlos

carlos@foo:~ % touch excluir_dirs.txt

Tenga en cuenta que las líneas del archivo se leen palabra por palabra. Uno de los los errores frecuentes es dejar espacios en blanco adicionales después de un nombre de archivo, que es difícil de detectar usando editores de texto. Sin embargo, las líneas vacías están bien

carlos@foo:~ % cat excluir_dirs.txt

./.ssh
./.dbus
./.mozilla
./.cache
./Descargas
./DevOps_Bootcamp
./Musica
# tar cfCv - /usr/home/carlos/ --exclude-from excluir_dirs.txt . | \
tar xpfC - /copias/tar_home_fbsd

-c Crear un nuevo archivo que contenga los elementos especificados

-f Leer el archivo desde o escribir el archivo en el fichero especificado

-C directorio, --cd directorio. En el modo c y r, esto cambia el directorio antes de añadir los siguientes archivos.

-v Produce una salida detallada. En los modos de creación y extracción, tar enumerará cada nombre de archivo a medida que se lea o escriba en el archivo.

-x Extraer al disco desde el archivo. Si un archivo con el mismo nombre aparece más de una vez en el archivo, cada copia será extraído, y las copias posteriores sobrescribirán las anteriores copias.

-p --preserve-permissions (sólo en modo x) Preserva los permisos de los archivos. Intenta restaurar los permisos completos

Exportar el zpool copias

# zpool export copias

carlos@foo:~ % ls -Fa

...
.ssh/
.cache/
.dbus/
.mozilla
Avanzado/
bhyve/
Dell-7390/
Descargas/
DevOps_Bootcamp/
docs/
Documentos/
Ebooks/
Escritorio/
excluir_dirs.txt
Imagenes/
Musica/
Plantillas/
Publico/
scripts/
Videos/

FreeBSD es genial!.

martes, 19 de octubre de 2021

ZFS Local Replication en FreeBSD

Disco ZFS Local Send Receive Snapshots en FreeBSD La replicación de ZFS consta de dos partes: zfs send que serializa una instantánea o una serie de instantáneas en un flujo de datos mezclado, y zfs receive, que convierte ese flujo en un sistema de archivos ZFS. La replicación basada en instantáneas significa que puede hacer una replicación incremental, enviando sólo los bloques que han cambiado; los mismos datos nunca se envían dos veces. El conjunto de datos ZFS transmitido es totalmente coherente, a diferencia del volcado o rsyncing de un sistema de archivos en vivo. Crear un punto de montaje # mkdir /mnt/zbackupsConectar la unidad usb # lsblk

 DEVICE         MAJ:MIN SIZE TYPE                          LABEL MOUNT
ada0             0:96  112G GPT                               - -
  ada0p1         0:97  260M efi                          gpt/efiboot0 /boot/efi
  ada0p2         0:98  512K freebsd-boot                 gpt/gptboot0 -
  free         -:-   492K -                                       - -
  ada0p3         0:99  2.0G freebsd-swap                    gpt/swap0 SWAP
  ada0p3.eli     0:93  2.0G freebsd-swap                           - SWAP
  ada0p4         0:100 110G freebsd-zfs                      gpt/zfs0 zfs
  free         -:-   452K -                                       - -
da0              1:164 932G GPT                               - -
  da0p1          1:166 932G freebsd-zfs                             - zfs

# geom disk list

Geom name: ada0
Providers:
1. Name: ada0
   Mediasize: 120034123776 (112G)
   Sectorsize: 512
   Stripesize: 4096
   Stripeoffset: 0
   Mode: r3w3e6
   descr: Samsung SSD 850 EVO 120GB
   lunid: 5002538d4010a7f6
   ident: S21UNXAG517311N
   rotationrate: 0
   fwsectors: 63
   fwheads: 16

Geom name: da0
Providers:
1. Name: da0
   Mediasize: 1000204886016 (932G)
   Sectorsize: 512
   Stripesize: 4096
   Stripeoffset: 0
   Mode: r0w0e0
   descr: HGST HTS 541010A9E680
   lunname: HGST HTS541010A9E680    160324JD1042ZF1J
   lunid: 3016032414104216
   ident: 160324A41042A61A4543
   rotationrate: unknown
   fwsectors: 63
   fwheads: 255

Particionar el disco externo. Esta es una operación destructiva e irreversible

# gpart destroy -F da0 
  # gpart create -s gpt da0
  da0 created 
  # gpart add -t freebsd-zfs -s 900G -l zbackups da0
  da0p1 added 
  # gpart show da0
=>        40  1953525088  da0  GPT  (932G)
          40  1887436800    1  freebsd-zfs  (900G)
  1887436840    66088288       - free -  (32G)

gpart show -p da0
=>        40  1953525088    da0  GPT  (932G)
          40  1887436800  da0p1  freebsd-zfs  (900G)
  1887436840    66088288         - free -  (32G)

# zpool create zbackups da0p1

Establecer el punto de montaje

# zfs set mountpoint=/mnt/zbackups zbackups

Crear conjunto de datos (dataset) en la unidad zbackups - los puntos de montaje se crean automáticamente.

# zfs create zbackups/carlos
# zfs create zbackups/vm
# zfs create zbackups/vm/alpine
# zfs create zbackups/vm/arch
# zfs create zbackups/vm/freebsd
# zfs list

NAME                           USED  AVAIL     REFER  MOUNTPOINT
zbackups                      1.02M   868G       96K  /mnt/zbackups
zbackups/carlos                104K   868G      104K  /mnt/zbackups/carlos
zbackups/vm                    384K   868G       96K  /mnt/zbackups/vm
zbackups/vm/alpine              96K   868G       96K  /mnt/zbackups/vm/alpine
zbackups/vm/arch                96K   868G       96K  /mnt/zbackups/vm/arch
zbackups/vm/freebsd             96K   868G       96K  /mnt/zbackups/vm/freebsd
...

Listar snapshot

# zfs list -t snapshot

Enviar el conjunto de datos del directorio personal a la unidad externa zbackups.

Primero crear la instantánea para después enviar

(snap_`date +%d%m%y%H%M`)
zfs snapshot zroot/usr/home@/carlos@snap_`date +%d%m%y%H%M`
# zfs snapshot zroot/usr/home/carlos@snap_1910211203

Enviar el conjunto de datos a zbackups/carlos

# zfs send -v zroot/usr/home/carlos@snap_1910211203 | zfs receive -F \ 
zbackups/carlos

# zfs snapshot zroot/vm@snap_1910211203

# zfs send -v zroot/vm@snap_1910211203 | zfs receive -F zbackups/vm

# zfs snapshot zroot/vm/alpine@snap_1910211203

# zfs send -v zroot/vm/alpine@snap_1910211203 | zfs receive -F \ 
zbackups/vm/alpine

# zfs snapshot zroot/vm/arch@snap_1910211203

# zfs send -v zroot/vm/arch@snap_1910211203 | zfs receive -F zbackups/vm/arch

# zfs snapshot zroot/vm/freebsd-12-2@snap_1910211203
# zfs snapshot zroot/vm/freebsd-12-2/disk1@snap_1910211203

# zfs send -Rv zroot/vm/freebsd-12-2@snap_1910211203 | zfs receive \
-F zbackups/vm/freebsd

snapshot del pool completo zroot

# zfs snapshot -r zroot@snap1_021121

Crear dataset zbackups

# zfs create zbackups/snap1full

Enviar recursivamente las snpashots

# zfs send -vR zroot@snap_021121 | zfs receive zbackups/snap1full

Los conjuntos de datos de las instantáneas recibidas deben estar impecables para que los zfs reciban aceptar actualizaciones incrementales o diferenciales. La bandera -F le dice a zfs Receive que revierte cualquier cambio que impida aceptar esto instantánea.

# zfs send -vR zroot@snap_021121 | zfs receive -F zbackups/snap1full 
# grc zfs list -t all -r zbackups

Instantáneas incrementales

Crear las instantánea(s)
# zfs snapshot zroot/usr/home/carlos@snap_20102112020

Enviar instantáneas incrementales.

# zfs send -i zroot/usr/home/carlos@snap_1910211203 \ 
zroot/usr/home/carlos@snap_20102112020 | zfs receive \ 
-F zbackups/carlos

% smartctl -a /dev/ada0

smartctl 7.2 2020-12-30 r5155 [FreeBSD 13.0-RELEASE-p4 amd64] (local build)
Copyright (C) 2002-20, Bruce Allen, Christian Franke, www.smartmontools.org

=== START OF INFORMATION SECTION ===
Model Family:     Samsung based SSDs
Device Model:     Samsung SSD 850 EVO 120GB
Serial Number:    S21UNXAG517311N
LU WWN Device Id: 5 002538 d4010a7f6
Firmware Version: EMT01B6Q
User Capacity:    120.034.123.776 bytes [120 GB]
Sector Size:      512 bytes logical/physical
Rotation Rate:    Solid State Device
TRIM Command:     Available
Device is:        In smartctl database [for details use: -P show]
ATA Version is:   ACS-2, ATA8-ACS T13/1699-D revision 4c
SATA Version is:  SATA 3.1, 6.0 Gb/s (current: 6.0 Gb/s)
Local Time is:    Wed Oct 20 00:00:26 2021 CEST
SMART support is: Available - device has SMART capability.
SMART support is: Enabled

=== START OF READ SMART DATA SECTION ===
SMART overall-health self-assessment test result: PASSED
...

% smartctl -a /dev/da0
martctl 7.2 2020-12-30 r5155 [FreeBSD 13.0-RELEASE-p4 amd64] (local build)
Copyright (C) 2002-20, Bruce Allen, Christian Franke, www.smartmontools.org

=== START OF INFORMATION SECTION ===
Model Family:     HGST Travelstar 5K1000
Device Model:     HGST HTS541010A9E680
Serial Number:    160324JD1042ZF1J45DS
LU WWN Device Id: 5 000cca 887d56d1c
Firmware Version: JA0OA5M0
User Capacity:    1.000.204.886.016 bytes [1,00 TB]
Sector Sizes:     512 bytes logical, 4096 bytes physical
Rotation Rate:    5400 rpm
Form Factor:      2.5 inches
Device is:        In smartctl database [for details use: -P show]
ATA Version is:   ATA8-ACS T13/1699-D revision 6
SATA Version is:  SATA 2.6, 3.0 Gb/s (current: 3.0 Gb/s)
Local Time is:    Wed Oct 20 00:02:24 2021 CEST
SMART support is: Available - device has SMART capability.
SMART support is: Enabled

=== START OF READ SMART DATA SECTION ===
SMART Status not supported: Incomplete response, ATA output registers missing
SMART overall-health self-assessment test result: PASSED
...
FreeBSD es genial!.