Páginas

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

lunes, 6 de abril de 2026

Configuración de LAGG failover en FreeBSD 14.4

LAGG failover en FreeBSD 14.4 em0 (primaria) y wlan0 (respaldo via iwm0)

Fuente:


https://www.ccammack.com/posts/configure-a-wifi-client-on-freebsd
https://wiki.freebsd.org/Devd
https://headthirst.com/freebsd-suspend.html
https://forums.freebsd.org/threads/freebsd-command-line-wifi-manager.89090/
https://www.dwarmstrong.org/freebsd-network-laptop/
https://libreboot.org/docs/bsd/suspend-resume-speedup.html
https://forums.freebsd.org/threads/freebsd-command-line-wifi-manager.89090/
https://forums.freebsd.org/threads/wifi-stops-working-after-suspend-resume.85889/
https://www.reddit.com/r/voidlinux/comments/1lfxurz/wifi_disappears_after_waking_from_suspend_i

Nombres de los dispositivos 802.11 disponibles

sysctl net.wlan.devices
net.wlan.devices: iwm0

Tomando como ejemplo mi computadora portátil (Dell Latitude 7390), la interfaz Ethernet em0 funcionará como puerto maestro y la interfaz inalámbrica wlan0 será el dispositivo de respaldo. Combino las dos interfaces en una interfaz virtual sobrescribiendo la dirección MAC de la interfaz Ethernet con la dirección MAC de la interfaz inalámbrica.

Determinar la dirección MAC de la interfaz inalámbrica

ifconfig wlan0 | grep ether
	ether 18:56:80:f8:98:e6

Cambiar la dirección MAC de la interfaz Ethernet para que coincidan

ifconfig em0 ether 18:56:80:f8:98:e6	

/etc/rc.conf

...
ifconfig_em0="ether 18:56:80:f8:98:e6"
wlans_iwm0="wlan0"
ifconfig_wlan0="WPA"
cloned_interfaces="lagg0"
ifconfig_lagg0="laggproto failover laggport em0 laggport wlan0 SYNCDHCP"
create_args_wlan0="country ES"
defaultrouter="192.168.88.1"
defaultroute_delay="10"
background_dhclient_lagg0="YES"
... 
Archivo /etc/wpa_supplicant
/etc/wpa_supplicant.conf
ctrl_interface=/var/run/wpa_supplicant
eapol_version=2
fast_reauth=1

network={
	ssid="MikroTik-39F9C0"	
        psk=755862a5b1a4ef59e2e62590677a75f5317193637a8629dccb18c40e8634a68e
}

Reiniciar

Estado general del LAGG

ifconfig lagg0
lagg0: flags=1008843 UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST,LOWER_UP metric 0 mtu 1500
	options=0
	ether 18:56:80:f8:98:e6
	hwaddr 00:00:00:00:00:00
	inet 192.168.88.50 netmask 0xffffff00 broadcast 192.168.88.255
	laggproto failover lagghash l2,l3,l4
	laggport: em0 flags=1 MASTER
	laggport: wlan0 flags=4 ACTIVE
	groups: lagg
	media: Ethernet autoselect
	status: active
	nd6 options=29 PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL

Ver puerto activo

ifconfig lagg0 | grep -E "laggport|status"
	laggport: em0 flags=1 MASTER 
	laggport: wlan0 flags=4 ACTIVE
	status: active

Estadísticas en detalle

sysctl net.link.lagg
net.link.lagg.lacp.default_strict_mode: 1
net.link.lagg.lacp.debug: 0
net.link.lagg.default_flowid_shift: 16
net.link.lagg.default_use_numa: 1
net.link.lagg.default_use_flowid: 0
net.link.lagg.failover_rx_all: 0

En /etc/rc.conf em0 no debe tener IP propia, es gestionado por lagg0 wlan0 no debe tener DHCP propio cuando está bajo lagg0; el DHCP lo gestiona lagg0. El failover es automático, al detectar pérdida de carrier en em0, el tráfico pasa a wlan0 sin intervención manual.

Sin conexión a Internet después de salir de hibernación

Al salir de hibernación, devd no recrea lagg0 de forma automática. La solución es un script de resume que se ejecute al despertar.

Crear el script de resume-network.sh

/usr/local/sbin/resume-network.sh

#!/bin/sh
sleep 3

# Destruir interfaces
ifconfig lagg0 destroy 2>/dev/null
ifconfig wlan0 destroy 2>/dev/null

# Recrear wlan0 sin country (lo hereda de rc.conf al crear)
ifconfig wlan0 create wlandev iwm0
ifconfig wlan0 country ES 2>/dev/null

# Recrear lagg0
ifconfig lagg0 create
ifconfig lagg0 laggproto failover
ifconfig lagg0 laggport em0
ifconfig lagg0 laggport wlan0
ifconfig lagg0 up

# Arrancar wpa_supplicant
wpa_supplicant -B -i wlan0 -c /etc/wpa_supplicant.conf

# Esperar asociacion (max 30s)
i=0
while [ $i -lt 30 ]; do
    status=$(ifconfig wlan0 | grep "status:" | awk '{print $2}')
    [ "$status" = "associated" ] && break
    sleep 1
    i=$((i + 1))
done

logger "resume-network: wlan0 status=$status tras ${i}s"

# Matar dhclient previo si existe
pkill -F /var/run/dhclient/dhclient.lagg0.pid 2>/dev/null
sleep 1

# Obtener IP
dhclient lagg0

# Ruta por defecto si dhclient no la puso
sleep 2
netstat -rn | grep -q "^default" || route add default 192.168.88.1

logger "resume-network: completado"

Aumentar timeout de dhclient

vim /etc/dhclient.conf
interface "lagg0" {
    timeout 60;
    retry 10;
}

Configurar devd para se ejecute al despertar

vim /etc/devd/resume-network.conf
notify 100 {
    match "system"      "ACPI";
    match "subsystem"   "Resume";
    action "/usr/local/sbin/resume-network.sh &";
};

Reinicar devd

sudo service devd restart

Comprobar que devd capta el evento revisando tras salir de hibernación

tail -5 /var/log/messages
Apr  5 16:11:50 solaris dhclient[13642]: New IP Address (lagg0): 192.168.88.50
Apr  5 16:11:50 solaris dhclient[13646]: New Subnet Mask (lagg0): 255.255.255.0
Apr  5 16:11:50 solaris dhclient[13650]: New Broadcast Address (lagg0): 192.168.88.255
Apr  5 16:11:50 solaris dhclient[13654]: New Routers (lagg0): 192.168.88.1
Apr  5 16:11:51 solaris root[13671]: resume-network: completado

Al hibernar, FreeBSD destruye las interfaces clonadas (lagg0) y en algunos casos también wlan0. Al despertar, rc.conf no se reprocesa. devd es el mecanismo correcto para reaccionar a eventos ACPI como Resume.

El sleep 3 inicial es importante porque iwm0 necesita unos segundos para que el firmware del adaptador WiFi Intel esté operativo tras el resume.

Ver si devd captó el evento Resume

grep -E "Resume|resume-network" /var/log/messages | tail -5

Apr  5 15:48:07 solaris carlos[12362]: resume-network: wlan0 status=associated tras 3s
Apr  5 15:48:09 solaris carlos[12527]: resume-network: completado
Apr  5 16:11:39 solaris kernel: rtsx0: Resume
Apr  5 16:11:49 solaris root[13506]: resume-network: wlan0 status=associated tras 3s
Apr  5 16:11:51 solaris root[13671]: resume-network: completado

Comprobar que dhclient obtuvo IP

Apr  5 16:11:50 solaris dhclient[27343]: My address (192.168.88.50) was deleted, dhclient exiting
Apr  5 16:11:51 solaris dhclient[28339]: dhclient already running, pid: 28314.
Apr  5 16:11:51 solaris dhclient[28339]: exiting.
Apr  5 16:11:52 solaris dhclient[28317]: connection closed
Apr  5 16:11:52 solaris dhclient[28317]: exiting.
Apr  5 16:11:54 solaris dhclient[28659]: New IP Address (lagg0): 192.168.88.50
Apr  5 16:11:54 solaris dhclient[28663]: New Subnet Mask (lagg0): 255.255.255.0
Apr  5 16:11:55 solaris dhclient[28667]: New Broadcast Address (lagg0): 192.168.88.255
Apr  5 16:11:55 solaris dhclient[28671]: New Routers (lagg0): 192.168.88.1
FreeBSD es genial!.

lunes, 19 de enero de 2026

Crear conjunto de datos cifrado ZFS NFSv4 (tls)

Conjunto de datos cifrado

=> Cifrado NFS sobre TLS <=

En el servidor (tormenta.local.com)

Crear el keyfile para cifrado automático

Generar un keyfile seguro de 32 bytes (requerido para keyformat=raw):

dd if=/dev/urandom of=/etc/zfs/secifrado.key bs=32 count=1
chmod 400 /etc/zfs/secifrado.key

Este archivo contiene la clave binaria. Respaldar en un lugar seguro, su pérdida implica perder permanentemente el acceso al dataset.

Creación del dataset padre ZFS (no cifrado)

zfs create -o mountpoint=/nfsv4 zroot/nfsv4

A continuación crear el dataset hijo cifrado

zfs create -o encryption=aes-256-gcm -o \
keyformat=raw -o keylocation=file:///etc/zfs/secifrado.key -o \
mountpoint=/nfsv4/secifrado zroot/nfsv4/secifrado

Utiliza AES-256-GCM (recomendado por seguridad y rendimiento). El comando cargará la clave automáticamente durante la creación.

Verificar con el comando siguiente

zfs get encryption,keyformat,keylocation,mountpoint zroot/nfsv4/secifrado
NAME                   PROPERTY     VALUE                          SOURCE
zroot/nfsv4/secifrado  encryption   aes-256-gcm                    -
zroot/nfsv4/secifrado  keyformat    raw                            -
zroot/nfsv4/secifrado  keylocation  file:///etc/zfs/secifrado.key  local
zroot/nfsv4/secifrado  mountpoint   /nfsv4/secifrado               local

Configurar el desbloqueo automático en el arranque

Script rc.d personalizado que cargará la clave y montará el dataset después de importar los pools ZFS, pero antes de iniciar los servicios NFS (evita la intervención manual)

vim /usr/local/etc/rc.d/zfskeys
#############################################################
#!/bin/sh

# PROVIDE: zfskeys
# REQUIRE: zfs
# BEFORE: mountd
# KEYWORD: 

. /etc/rc.subr

name=zfskeys
rcvar=zfskeys_enable
start_cmd="${name}_start"

zfskeys_start() {
    zfs load-key zroot/nfsv4/secifrado
    zfs mount -a  # Montar cualquier dataset despues de cargar la clave
}

load_rc_config $name
run_rc_command "$1"
#############################################################

Convertir el archivo en ejecutable y habilitarlo

chmod +x /usr/local/etc/rc.d/zfskeys
sysrc zfskeys_enable="YES"

Esto permite que la clave se cargue desde el keyfile automáticamente al arranque, asumiendo que zroot raíz no está cifrado y el keyfile es accesible al inicio.

En caso de que zroot esté cifrado, ajustar el keyfile a un dataset no cifrado.

Archivo /etc/exports

#############################################################
V4: /nfsv4 -tls
---
/nfsv4/docs 	    -maproot=root -network 192.168.88.0/24
/nfsv4/secifrado    -maproot=root 192.168.88.51
---
#############################################################

Recargar configuración y reiniciar servicios

service mountd reload
service nfsd restart
service tlsservd restart

En el cliente (solaris.local.com)

service tlsclntd restart

Montar el recurso compartido NFSv4 con tls

mkdir /nizs4
mount -t nfs -o nfsv4,tls tormenta:/secifrado /nizs4

Montaje automático agregar en /etc/fstab

tormenta:/secifrado  /nizs4   nfs   rw,nfsv4,tls,noatime,bg   0  0

Seguridad: El keyfile permite desbloqueo sin intervención, mejor proteger (permisos 400, backups). Si el servidor es sustraido, el keyfile en disco permite acceso, considera almacenarlo en un dispositivo externo removible.

Reiniciar el servidor, comprobar que el dataset está montado y accesible via NFS desde el cliente.

Si TLS falla, comprobar logs (dmesg | grep tls, /var/log/messages). Verificar que los puertos NFS (2049/TCP) están abiertos en el firewall PF. Para depuración usar mount -vv

zfs mount | grep "secifrado" 
nfsstat -m
---
tormenta:/secifrado on /nizs4
nfsv4,minorversion=2,tcp,resvport,tls,nconnect=1,hard,cto,sec=sys,acdirmin=3,\
acdirmax=60,acregmin=5,acregmax=60,nametimeo=60,negnametimeo=60,rsize=65536,\
wsize=65536,readdirsize=65536,readahead=1,wcommitsize=16777216,timeout=120,\
retrans=2147483647
---

Archivo /etc/exports

V4: /nfsv4 -tls
...
/nfsv4/secifrado     -maproot=root 192.168.88.51
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

Fuente:

https://www.iceflatline.com/2015/07/using-zfs-replication-features-in-freebsd-to-improve-my-offsite-backups/

El autor de este sencillo e ingenioso guión es iceflatline. Contiene algunas modificaciones para adaptarlo a este laboratorio

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!.

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!.

lunes, 8 de noviembre de 2021

ZFS FreeBSD en modo monousuario

Proceso de arranque

En el proceso de arranque, FreeBSD ofrece un menú de arranque beastie-start con algunas opciones simples de carga. Para iniciar el modo monousuario se pulsa el numero 2 (Boot single user).

Para que todos sus conjuntos de datos ZFS estén disponibles se utiliza zfs mount. También pueden montarse conjuntos de datos individuales por nombre.


 Enter root password, or ˆD to go multi-user
 Password: Enter full pathname of shell or RETURN for /bin/sh:

 zfs mount -a
 mount zroot/ROOT/default on / (zfs, local, noatime, read-ly, nfs4acls)

Montar conjunto de datos en modo rw

ZFS realizará sus comprobaciones de integridad habituales antes de montar los conjunto de datos.La mayoría de los conjuntos de datos serán exactamente tan accesibles como en el modo multiusuario, pero el conjunto de datos montado como raíz seguirá siendo de solo lectura. Montar el conjunto de datos raíz en modo lectura-escritura (rw)) en una instalación predeterminada de FreeBSD.


  zfs set readonly=off zroot/ROOT/default
 

Para tener conectividad de red en modo de usuario único, se ejecuta el shell script


 /etc/netstart.

Ejecutar scripts

Este script llama a los scripts apropiados para iniciar la red, proporciona direcciones IP a las interfaces y habilita el filtrado de paquetes y el enrutamiento. Si determina que hay un error tipográfico en /etc/fstab que confunde al sistema y lo hace no arrancable, puede editar /etc/fstab para resolver el problema. Si hay un programa que hace que el sistema entre en pánico al arrancar y hay que detener ese programa para que no se inicie de nuevo, puede editar


  vim /etc/rc.conf
 

Para configurar los permisos en el script de inicio y no se ejecute.


 chmod a-x /usr/local/etc/rc.d/nombredelprogram.sh

Reiniciar


 reboot
FreeBSD es genial!.

martes, 6 de noviembre de 2018

PF OpenBSD

Firewall PF OpenBSD router Soekris 2018 

Instalación OpenBSD en una monoplaca Soekris net5501
OpenBSD soekris router

# cat /etc/pf.conf
#       $OpenBSD: pf.conf,v 1.54 2014/08/23 05:49:42 deraadt Exp $
#
# See pf.conf(5) and /etc/examples/pf.conf
int_if="{ vether0 vr1 vr2 vr3 }"
ext_if="vr0"
icmp_types="echoreq"
vpn_if="tun0"
openvpn_port="1198"
lan1="192.168.3.0/24"
lan2="192.168.1.0/24"
ssh_port="21000"

# Esta es una tabla de direcciones privadas no enrutables que se utilizara mas adelante.
table <martians> { 0.0.0.0/8 224.0.0.22 127.0.0.0/8 172.16.0.0/12 \
        169.254.0.0/16 192.0.2.0/24 \
        192.0.2.0/24 198.51.100.0/24 203.0.113.0/24 \
        169.254.0.0/16 240.0.0.0/4 255.255.255.255/32 }

# Bloquear todo
block all

# Decide si los paquetes rechazados deben enviar un TCP RST o descartarse silenciosamente.
set block-policy drop

# Habilitada la recopilacion de estadisticas de bytes y paquetes en egress.
# estas estadisticas pueden verse con el comando pfctl -si
set loginterface egress

# Omitir la interfaz lo del procesamiento de paquetes
set skip on lo

# Las reglas de coincidencia que se utilizan aqui logran dos cosas: normalizar los paquetes
# entrantes y realizar la traduccion de direcciones de red, con la interfaz de salida entre
# la LAN y la Internet publica
match in all scrub (no-df max-mss 1440 reassemble tcp random-id)
match out on egress inet from !(egress:network) to any nat-to (egress:0)
match inet6 all

# La palabra clave antispoof proporciona cierta proteccion de paquetes con direcciones de 
# origen falsificadas. Los paquetes que llegan a la interfaz de egress deben eliminarse si
# parecen pertenecer a la lista de direcciones que no se pueden enrutar que definimos.  
# Dichos paquetes probablemente se enviaron debido a una configuracion incorrecta, o 
# posiblemente como parte de un ataque de suplantacion de identidad. Del mismo modo, 
# nuestros clientes no deben intentar conectarse a dichas direcciones. Especificaremos la 
# accion de "retorno" para evitar tiempos de espera molestos para los usuarios. 
antispoof quick for (egress) 
block in quick on egress from <martians> to any
block return out quick on egress from any to { <martians> no-route }
block return out quick inet6 all

# Por defecto, no permite conecciones remota a X11
block return in on ! lo0 proto tcp to port 6000:6010
  
# Permitir el trafico saliente de IPv4 desde la propia puerta de enlace y los clientes LAN.
pass out quick inet

# Permitir ICMP entrante sobre todas las interfaces
pass in inet proto icmp icmp-type $icmp_types 

# Permitir el rango predeterminado para traceroute (8):
pass out on $ext_if inet proto udp from any to any port 33433:33626 keep state

# Permitir el trafico interno LAN 
pass in on $int_if inet

# Permitir conexiones desde LAN ssh
pass in inet proto tcp from { $lan1 $lan2 } to port $ssh_port

# Permitir conexiones a Internet a través de un servidor VPN. VPN permite el salto de los 
# bloqueos geográficos, un mayor anonimato en la Red y el bloqueo de publicidad 
pass in quick proto udp to $ext_if port $openvpn_port keep state
pass in quick on $vpn_if inet from any to any keep state
#############################################################################

# pfctl -vf /etc/pf.conf
                                                  
int_if = "{ vether0 vr1 vr2 vr3 }"
ext_if = "vr0"
icmp_types = "echoreq"
vpn_if = "tun0"
openvpn_port = "1198"
lan = "192.168.3.0/24"
ssh_port = "22"
table <martians> { 0.0.0.0/8 224.0.0.22 127.0.0.0/8 172.16.0.0/12 169.254.0.0/16 192.0.2.0/24 192.0.2.0/24 198.51.100.0/24 203.0.113.0/24 169.254.0.0/16 240.0.0.0/4 255.255.255.255 }
set block-policy drop
set loginterface egress
set skip on { lo }
block drop all
match in all scrub (no-df random-id reassemble tcp max-mss 1440)
match out on egress inet from ! (egress:network) to any nat-to (egress:0) round-robin
match inet6 all
block drop in quick on ! egress from (egress:network) to any
block drop in quick from (egress) to any
block drop in quick on egress from  to any
block return out quick on egress from any to 
block return out quick on egress from any to no-route
block return out quick inet6 all
block return in on ! lo0 proto tcp from any to any port 6000:6010
pass out quick inet all flags S/SA
pass in inet proto icmp all icmp-type echoreq
pass in on vether0 inet all flags S/SA
pass in on vr1 inet all flags S/SA
pass in on vr2 inet all flags S/SA
pass in on vr3 inet all flags S/SA
pass in inet proto tcp from 192.168.3.0/24 to any port = 21000 flags S/SA
pass out on vr0 inet proto udp from any to any port 33433:33626
pass in quick inet proto udp from any to 192.168.1.99 port = 1198
pass in quick on tun0 inet all flags S/SA


https://gnulinuxcodigo.blogspot.com/2015/12/openbsd-soekris-router.html
http://www.openbsd.org
http://www.freebsd.org
https://networkfilter.blogspot.com/2015/01/be-your-own-vpn-provider-with-openbsd.html
http://whoer.net/
https://en.wikipedia.org

OpenBSD es genial!.

miércoles, 8 de agosto de 2012

Script personalizado

Registros del consumo de memoria en el servidor

Gestionar servicio mediante niveles de ejecución.
El nivel por defecto en un servidor Debian es el nivel 2, será conservado como nivel por defecto y personalizar el nivel 3 para que la aplicación se inicie automáticamente.

Crear directorio scripts.
# mkdir /opt/scripts
# vim /opt/scripts/memoria


#!/bin/bash
while true
do
hora=$(date "+%H: %M: %S - ")
echo -n $hora >> /var/log/memoria.log
grep Dirty /proc/meminfo >> /var/log/memoria.log
sleep 25
done

Permisos de ejecución a la aplicación:
# chmod +x /opt/scripts/memoria
# ls -l /opt/scripts/memoria
-rwxr-xr-x 1 root root 162 2012-08-08 09:53 /opt/scripts/memoria

Creación del script de inicio personalizado (archivo de gestión del servicio):
# vim /etc/init.d/memoria
#!/bin/bash
case $1 in
start)
/opt/scripts/memoria & echo " * inicializando... ;; stop) pkill memoria ;; esac

Hacer archivo ejecutable.
# chmod +x /etc/init.d/memoria

Comprobar el funcionamiento del programa ejecutando el correspondiente servicio:
# /etc/init.d/memoria start
 * inicializando...

Contenido del archivo /var/log/memoria.log
# tail -f /var/log/memoria.log
09: 57: 16 -Dirty:         44 kB 09: 57: 41 -Dirty:        156 kB 09: 58: 06 -Dirty:        168 kB 09: 58: 31 -Dirty:        332 kB 09: 58: 56 -Dirty:        164 kB 09: 59: 21 -Dirty:        376 kB 09: 59: 46 -Dirty:        140 kB 10: 00: 11 -Dirty:        148 kB 10: 00: 36 -Dirty:        248 kB 10: 01: 01 -Dirty:         12 kB

# pgrep -l memoria
10095 memoria

# /etc/init.d/memoria stop
# pgrep -l memoria
#

Modificar nivel personalizado:
Crear un enlace de parada en el nivel 0
Crear enlace de parada en el nivel 1
Crear enlace de parada en el nivel 2
Crear enlace de inicio en el nivel 3 (nivel funcional completo con la aplicación memoria)
Crear enlace de parada en el nivel 6
root@zeus:/etc/rc0.d# ln -s ../init.d/memoria K05memoria
root@zeus:/etc/rc0.d# ls -l K05memoria
lrwxrwxrwx 1 root root 17 2012-08-08 11:45 K05memoria -> ../init.d/memoria
root@zeus:/etc/rc0.d# cd ../rc1.d/
root@zeus:/etc/rc1.d# ln -s ../init.d/memoria K05memoria
root@zeus:/etc/rc1.d# ls -l K05memoria
lrwxrwxrwx 1 root root 17 2012-08-08 11:45 K05memoria -> ../init.d/memoria
root@zeus:/etc/rc1.d# cd ../rc2.d/
root@zeus:/etc/rc2.d# ln -s ../init.d/memoria K05memoria
root@zeus:/etc/rc2.d# ls -l K05memoria
lrwxrwxrwx 1 root root 17 2012-08-08 11:46 K05memoria -> ../init.d/memoria
root@zeus:/etc/rc2.d# cd ../rc3.d/
root@zeus:/etc/rc3.d# ln -s ../init.d/memoria S95memoria
root@zeus:/etc/rc3.d# ls -l S95memoria
lrwxrwxrwx 1 root root 17 2012-08-08 11:47 S95memoria -> ../init.d/memoria
root@zeus:/etc/rc3.d# cd ../rc4.d/
root@zeus:/etc/rc4.d# ln -s ../init.d/memoria K05memoria
root@zeus:/etc/rc4.d# ls -l K05memoria
lrwxrwxrwx 1 root root 17 2012-08-08 11:49 K05memoria -> ../init.d/memoria
root@zeus:/etc/rc4.d# cd ../rc5.d/
root@zeus:/etc/rc5.d# ln -s ../init.d/memoria K05memoria
root@zeus:/etc/rc5.d# ls -l K05memoria
lrwxrwxrwx 1 root root 17 2012-08-08 11:49 K05memoria -> ../init.d/memoria
root@zeus:/etc/rc5.d# cd ../rc6.d/
root@zeus:/etc/rc6.d# ln -s ../init.d/memoria K05memoria
root@zeus:/etc/rc6.d# ls -l K05memoria
lrwxrwxrwx 1 root root 17 2012-08-08 11:49 K05memoria -> ../init.d/memoria
root@zeus:/etc/rc6.d#

Linux es genial!.

jueves, 5 de julio de 2012

Colorear logs

En la página de Christian Schneider, (programador alemán  Linux, Perl, Html, Css y PHP - guru , originario de la preciosa ciudad de Regensburg http://www.strcat.de/ ), encontré un script para colorear la salida por terminal, de los logs, mensajes del kernel (dmesg), etc de manera que resulte más facil su lectura.

Es un script en Perl de nombre colorlog.pl Utilizando un editor de texto lo guardamos en, por ejemplo, /usr/bin con permisos de ejecución.
#!/usr/bin/perl
 
$black    = "\033[30m";
$red      = "\033[31m";
$green    = "\033[32m";
$yellow   = "\033[33m";
$blue     = "\033[34m";
$magenta  = "\033[35m";
$purple   = "\033[35m";
$cyan     = "\033[36m";
$white    = "\033[37m";
$darkgray = "\033[30m";
@word_good=("starting\n", "Freeing", "Detected", "starting.", "accepted.\n", "authenticated.\n", "Ready", "active", "reloading", "saved;", "restarting", "ONLINE\n");
@word_warn=("dangling", "closed.\n", "Assuming", "root", "root\n", "exiting\n", "missing", "Ignored", "adminalert:", "deleting", "OFFLINE\n");
@word_bad=("bad");
@word_note=("LOGIN", "DHCP_OFFER", "optimized", "reset:", "unloaded", "disconnected", "connect", "Successful", "registered\n");
@line_good=("up", "DHCP_ACK", "Cleaned", "Initializing", "Starting", "success", "successfully", "alive", "found", "ONLINE\n");
@line_warn=("warning:", "WARNING:", "invalid", "obsolete", "bad", "Password", "detected", "timeout", "timeout:", "attackalert:", "wrong", "Lame", "FAILED", "failing", "unknown", "obsolete", "stopped.\n", "terminating.", "disabled\n", "disabled", "Lost");
@line_bad=("DENY", "lost", "shutting", "dead", "DHCP_NAK", "failure;", "Unable", "inactive", "terminating", "refused", "rejected", "down", "OFFLINE\n", "error\n", "ERROR\n", "ERROR:", "error", "ERROR", "error:", "failed:");
@daemons=("named");
$col_good = $green;
$col_warn = $yellow;
$col_bad = $red;
$col_note = $purple;
$col_norm =  "\033[00m";
$col_background = "\033[07m";
$col_brighten =  "\033[01m";
$col_underline =  "\033[04m";
$col_blink =   "\033[05m";
$col_default = "$col_norm$white";
print "$col_norm$cyan";
$datespace=0;
mainloop: while (<>)
{
 $thisline = $_;
 $timestamp = substr($_,0,15);
 s/................//;
 @rec = split (/ /, $_);
 $output="$col_brighten$cyan$timestamp"; 
 $output.=" $col_brighten$blue$rec[0]"; 
 if ($rec[1] eq "last")
 {
  $output.="$col_norm$green last message repeated ";
  $output.="$col_brighten$rec[4]$col_norm$green times\n";
  print "$output$col_default";
  next mainloop;
 }
 if ($rec[1] =~ /\[(\d+)\]\:/)
 {
  my($pid) = $1;
  $rec[1]=~s/\[$1\]\:// ;
  $output .= "$col_norm$green $rec[1]" .
             "$col_brighten$green\[";
  $output .= "$col_brighten$white$pid" .
             "$col_brighten$green\]: ";
 }
 else {
  $output .= "$col_norm$green $rec[1] ";
 }
 $restcolor="$col_norm$cyan";
 $restoftheline="";
 for ($therest=(2); $therest<=$#rec; $therest++)
 { $highlight=0;
  for ($i=0; $i<=$#word_good; $i++)
  { if ($word_good[$i] eq $rec[$therest])
   { $restoftheline.="$col_brighten$col_good"; $highlight=1; }
  }
  for ($i=0; $i<=$#word_warn; $i++)
  { if ($word_warn[$i] eq $rec[$therest])
   { $restoftheline.="$col_brighten$col_warn"; $highlight=1; } 
  }
  for ($i=0; $i<=$#word_bad; $i++)
  { if ($word_bad[$i] eq $rec[$therest])
   { $restoftheline.="$col_brighten$col_bad"; $highlight=1; } 
  }
  for ($i=0; $i<=$#word_note; $i++) 
  { if ($word_note[$i] eq $rec[$therest])
   { $restoftheline.="$col_brighten$col_note"; $highlight=1; } 
  }
  for ($i=0; $i<=$#line_good; $i++)
  { if ($line_good[$i] eq $rec[$therest])
   { $restcolor="$col_norm$col_good";
     $restoftheline.="$col_brighten$col_good"; $highlight=1; }
  }
  for ($i=0; $i<=$#line_warn; $i++)
  { if ($line_warn[$i] eq $rec[$therest])
   { $restcolor="$col_norm$col_warn";
     $restoftheline.="$col_brighten$col_warn"; $highlight=1; }
  }
  for ($i=0; $i<=$#line_bad; $i++)
  { if ($line_bad[$i] eq $rec[$therest])
   { $restcolor="$col_norm$col_bad";
     $restoftheline.="$col_brighten$col_bad"; $highlight=1; }
  }
  $restoftheline.="$rec[$therest] ";
  if ($highlight == 1)
  { $restoftheline.=$restcolor; }
 }
 $output.="$restcolor$restoftheline";
 print "$output$col_default\033[1G";
}
exit(0);


Ejemplos de utilización:
cat /var/log/dmesg | colorlog.pl | less


tail -n 20 /var/log/messages | colorlog.pl


tail -n 20 /var/log/dmesg | colorlog.pl


Linux es genial!.

domingo, 14 de agosto de 2011

Migrar Gentoo a otra maquina

Este script adaptado por BrianW a partir de los creados por fdavid y nianderson lo he encontrado www.foro.ethek.com. Se utiliza para realizar una migración de un sistema Gentoo Linux a otra máquina. He decidido copiar y pegar el script completo, sin cambios.

Antes de realizar el copiado del archivo previamente generado en el pc origen iniciar con un live-cd de gentoo particionar y formatear el disco duro del ordenador al que queremos migrar, montar las particiones hacer un chroot y seguir los pasos para una instalación gentoo.

En principio otro ordenador con otros componentes de hardware necesitará recompilar el kernel, ajustar parámetros en el archivo /etc/make.conf, instalar grub, etc. Esto no es un tutorial, he migrado un sistema gentoo de un disco duro a otro en mi portátil por sustitución de disco, el nuevo es un SSD de 120Gb sata II, en ese caso utilicé fsarchiver para realizar imágenes de las particiones, las puse en un disco duro externo y luego restauré las imágenes con el fsarchiver (aplicación potente y versátil incluida en el system rescue cd de linux).

Especial atención a los directorios y archivos excluidos. Boot está en una partición que se monta automáticamente o no?. Indicar donde está la partición /boot. Caso que se encuentre en /dev/sda1 tendría que modificar mount /boot por  mount /dev/sda1 /boot. La opción para dividir el archivo .tar.bz2 resultante está comentada, con la capacidad de los discos duros actuales practicamente no se utiliza. Fíjese que la partición de arranque es copiada como /bootcpy primero es copiada y luego borrada. Es un script bash al estilo de Linux: sencillo, claro, transparente y fácilmente modificable.

Lo más interesante de todo esto es que los sistemas basados Linux no son temporales ni efímeros. Están hechos para siempre.


#!/bin/bash
    ##  Backup script for Gentoo Linux
    ##  Author: BrianW
    ##  Date: 2004.10.26.
    ##  Adapted from backupHome.sh by fdavid
    ##  Adapted from mkstage4.sh by nianderson

    ##  This is a script to create a custom stage 4 tarball (System and
    ##  boot backup)
    ##  I use this script to make a snapshot of my system. Meant to be 
    ## done weekly in my case

    ##  Please check the options and adjust to your specifics.

    echo -=- Starting the Backup Script...
    echo -=-

    echo -=- Setting the variables...

    ##  The location of the stage 4 tarball.
    ##  Be sure to include a trailing /
    stage4Location=/root/

    ##  The name of the stage 4 tarball.
    archive=$stage4Location$(hostname)-stage4.tar.bz2

    ##  Directories/files that will be exluded from the stage 4 tarball.
    ##
    ##  Add directories that will be recursively excluded, delimited 
    ## by a space.
    ##  Be sure to omit the trailing /
    dir_excludes="/dev /proc /sys /tmp /usr/portage /var/tmp /root /home"
    ##
    ##  Add files that will be excluded, delimited by a space.
    ##  You can use the * wildcard for multiple matches.
    ##  There should always be $archive listed or bad things will happen.
    file_excludes="$archive"
    ##
    ##  Combine the two *-excludes variables into the $excludes variable
    excludes="$(for i in $dir_excludes; do if [ -d $i ]; then echo -n " --exclude=$i
    /*"; fi; done) $(for i in $file_excludes; do echo -n " --exclude=$i"; done)"

    ##  The options for the stage 4 tarball.
    tarOptions="$excludes --create --absolute-names --preserve-permissions --bzip2 -
    -verbose --totals --file"

    echo -=- Done!
    echo -=-

    ##  Mounting the boot partition
    echo -=- Mounting boot partition, then sleeping for 5 seconds...
    mount /boot
    sleep 5
    echo -=- Done!
    echo -=-

    ##  Creating a copy of the boot partition (copy /boot to /bootcpy).
    ##  This will allow the archiving of /boot without /boot needing to
    ##  be mounted.
    ##  This will aid in restoring the system.
    echo -=- Copying /boot to /bootcpy ...
    cp -R /boot /bootcpy
    echo -=- Done!
    echo -=-

    ##  Unmounting /boot
    echo -=- Unmounting /boot then sleeping for 5 seconds...
    umount /boot
    sleep 5
    echo -=- Done!
    echo -=-

    ##  Creating the stage 4 tarball.
    echo -=- Creating custom stage 4 tarball \=\=\> $archive
    echo -=-
    echo -=- Running the following command:
    echo -=- tar ${tarOptions} ${archive} /
    tar ${tarOptions} ${archive} /;
    echo -=- Done!

    ##  Split the stage 4 tarball in cd size tar files.
    ##  To combine the tar files after copying them to your
    ##  chroot do the following: "cat *.tar.bz2 >> stage4.tar.bz2".
    ##  Uncomment the following lines to enable this feature.
    #echo -=- Splitting the stage 4 tarball into CD size tar files...
    #split --bytes=700000000 ${archive} ${archive}.
    #echo -=- Done!

    ##  Removing the directory /bootcpy.
    ##  You may safely uncomment this if you wish to keep /bootcpy.
    echo -=- Removing the directory /bootcpy ...
    rm -rf /bootcpy
    echo -=- Done!
    echo -=-

    ##  This is the end of the line.
    echo -=- The Backup Script has completed!



Linux es genial!.

martes, 10 de mayo de 2011

Respaldar basedatos MySQL

Después de instalar MySQL, php5, apache2, phpMyAdmin y el gestor de contenidos joomla! (versión 1.6) corriendo en una máquina linux, realizar copias de seguridad de la base de datos y mantener las últimas 10, cron y este script serán suficiente.
En un CMS el contenido y continente son independientes y es en la base de datos donde se guarda el contenido del sitio. Cabe recordar que desde phpMyAdmin es posible realizar copias y restaurar base de datos.

Script original modificado.
Autores Script: Mauricio Vergara y Carlos Molina de la Universidad Técnica Federico Santa María de Valparaiso, hace mucho, mucho tiempo.

#################Inicio script##############
#!/bin/bash
#mysql backup
# declaracion de variables
EMAIL="admin@misitio.com"
HOST="localhost"
DB="joomla16"
USER="dina45r3_jo151"
PASSWD="8vb#4uA*7Sv"
DIR="/opt/backup"
FECHA="$(date +%Y.%m.%d)"
CONT=10
FILE="$DIR/testin-bak-$FECHA.sql"
MAQ=$(uname -n)
GZIP="1" #0 no, 1 yes

# comprobar que existe $DIR y si no existe crearlo
# con permiso rwx solo para root
if [ ! -d $DIR ] ; then
    mkdir -p $DIR &> /dev/null
    chmod 700 $DIR &> /dev/null
fi

# Haciendo el Dump
mysqldump --add-drop-table -h$HOST -u$USER -p$PASSWD $DB > $FILE 2> $DIR/error

# comprimir el archivo resultante
if [ "$GZIP" = "1" ] ; then
   gzip -9 $FILE &> /dev/null
fi

# cuantos backups existen?
num=$(ls $DIR/*.sq* | wc -l) &> /dev/null

# dejando solo los $CONT archivos
cd $DIR
while ( [ $num -gt $CONT ] ); do
   rm -f $(ls -t | tail -n 1)
   num=$(ls $DIR/*.sq* | wc -l) &> /dev/null
done

# enviar email si hay erro en $DIR
tam_error=$(du $DIR/error|cut -d '/' -f 1)

if ( [ $tam_error -ne 0  ] ); then
    echo -e "\nError (auto)" >> $DIR/error
    cat $DIR/error|mail -s"Backup :(" $EMAIL
fi
##################Fin script##################

Permisos de ejecución al archivo
# chmod +x mysql.backup.sh

  Para ejecutar todos los días a las 8:00 de la mañana:
# mv mysql.backup.sh /opt/backup/mysql.backup.sh
# export EDITOR=vim
# crontab -e
# 0 8 * * *  /opt/backup/mysql.backup.sh
# :wq

Pasan de las 8:00 A.M. Ejecuto el script por primera vez. (Si deseo ejecutarlo nuevamente durante el mismo día tendré que borrar manualmente el realizado con anterioridad, vigilando que corresponda a la fecha deseada).
# ./mysql.backup.sh

Para comprobar que la copia ha ido bien entro en phpMyAdmin y desde la pestaña exportar realizar una copia de la basedatos comprimida con gzip. Al comparar ambos dos archivos comprueba que son idénticos. Si no, revisa que los parámetros user db passwd sean correctos. :-)

Linux es genial!.