Nuestro tan ponderado y benemérito Webmin, y su vástago Virtualmin, me han dado una lección de humildad que, con el permiso de Miguel, paso a narrarles…
Necesito realizar una copia de seguridad de las bases de datos en un servidor que, su único propósito, es enviar correos y proveer del servicio de bases de datos MySQL. Sólo eso.
La solución es, relativamente, sencilla (reconozco que me costó hallarla):
webmin->Servers->MySQL Database Server y allí, al final de la página, el botón Backup Databases…
Indiqué que guardara las copias diarias en
/home/pepe/misBackups/%Y%m%d
De modo que cada día tendría una carpeta diferente…
NB: Para que efectivamente reemplace la máscara de fecha, en el módulo de MySQL Database Server, arriba a la izquierda hay un engranaje (o disco dentado) donde se accede a las propiedades del módulo y allí poner en «yes» la entrada que reza «Do strftime substitution of backup destinations?» (¡Para encontrarlo!)
Luego de varios intentos infructuosos y revolviendo Google, llegué a estas conclusiones:
- Webmin no incluye los archivos anexos indicados en la configuración de Configuration Backup…
- Virtualmin es inútil si no hay servidores virtuales definidos, tal es mi caso pues este servidor sólo manda correo y provee de bases de datos…
- Webmin no es capaz de transferir el paquete creado en «Filedump Backup» vía SSH si nuestro servidor destino utiliza un puerto diferente al estándar (22). Esto es debido a que para tal operación utiliza el comando tar y éste no incluye un parámetro para indicar el puerto SSH de nuestra conveniencia.
Objetivo: Realizar la copia de los archivos necesarios (cuales sean, en mi caso los volcados por el módulo MySQL) en mi espacio de almacenamiento…
Elementos necesarios:
- Un servidor con acceso SSH (local)
- Un servidor con acceso SSH (remoto)
- Una taza de café
- Paciencia
Etapa 1: Permitir que el REMOTO pueda realizar conexiones SSH al LOCAL sin tener que ingresar contraseña.. Y al mismo tiempo que el LOCAL no quede expuesto.
Para ello realizaremos estos pasos:
En nuestro servidor local crearemos nuestras claves SSH
[local-host]$ ssh-keygen Generating public/private rsa key pair. Enter file in which to save the key (/home/pepe/.ssh/id_rsa):<Hit enter> Enter passphrase (empty for no passphrase): <Enter your passphrase here> Enter same passphrase again:<Enter your passphrase again> Your identification has been saved in /home/pepe/.ssh/id_rsa. Your public key has been saved in /home/pepe/.ssh/id_rsa.pub. The key fingerprint is: XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX pepe@local-host
Es bueno remarcar que la clave PRIVADA (id_rsa) NO DEBE COMPARTIRSE
Ahora, debemos copiar el contenido de la clave PÚBLICA (id_rsa.pub) en el servidor REMOTO…
[local-host:~]$ cat ~/.ssh/id_rsa.pub ssh-rsa XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX pepe@local-host [local-host:~]$ ssh -p 99999 pepe@remote-host pepe@remote-host-s password: [remote-host:~]$ cd .ssh bash: cd: .ssh: No existe el archivo o el directorio [remote-host:~]$ mkdir .ssh [remote-host:~]$ cd .ssh [remote-host:~/.ssh]$ nano authorized_keys
Copiamos y pegamos la salida de cat en el archivo authorized_keys guardamos, cerramos y antes de probar, para asegurarnos:
[remote-host:~/.ssh] cd .. [remote-host:~]$ chmod 755 ~/.ssh [remote-host:~]$ chmod 644 ~/.ssh/authorized_keys [remote-host:~]$ exit [local-host:~]$
Ahora, cuando volvamos a conectarnos vía SSH (aún con SCP) el REMOTO no nos pedirá la clave pues ya conoce nuestra clave pública, y con eso le alcanza para saber quien soy y no soy otro.
Etapa 2:
En Webmin, vamos a System/Scheduled Cron Jobs… Allí configuraremos nuestra tarea para que ejecute el siguiente script (en mi caso, realizo un rsync sobre SSH)
#!/bin/bash # Empezamos... inicio=`date +%s` # Limpiemos lo viejo find /home/pepe/misBackups/. -type d -mtime +10 | xargs rm -rf # find Buscar # -type d Directorios # -ctime Con una antiguedad mayor a 10 dias # xargs rm -rf Eliminarlos segun listado por find # copiamos lo nuevo a casa if [ "$1" == "test" ] then test="--dry-run" fi rsync $test \ --checksum \ --human-readable \ --archive \ --verbose \ --compress \ --delete \ --partial \ --progress \ -O \ --rsh='ssh -p99999' \ --stats \ /home/pepe/misBackups/ \ pepe@remote-host:/home/pepe/remoto/misBackups/ # $test Para pruebas, contendrá --dry-run que simulas las acciones # --checksum Determina si el archivo es difernte en la suma del archivo # y no su fecha/hora. Más lento, más seguro. # --human-readable Los datos se muestran más sencillos de leer # --archive Es recursivo, conserva symlinks, permisos, propietario, # grupos, fechas y otras dos opciones más que omito explicar # --verbose Más detalles # --compress Comprime los archivos para la transferencia # --delete Elimina en destino lo que no existe en origen # --partial Mantiene los archivos parcialmente transferidos para reanudar # --progress Muestra el progreso mientras trabaja # -O (guión cero) Indica que los archivos terminan en un \0 (nulo). # Honestamente no recuerdo porqué lo utilizo, pero funciona. # --rsh='ssh -p99999' # Le indico a rsync que utilizaré SSH con un puerto diferente al # estándar # --stats Estadísticas de la transferencia # /home/pepe/misBackups/ # Carpeta origen # pepe@remote-host:/home/pepe/remoto/misBackups/ # Carpeta destino. Observar que es igual que si utilizara SCP # Terminamos fin=`date +%s` let tiempoTotal=$fin-$inicio echo "Ha tardado: $tiempoTotal segundos en procesar"
En el cron job podemos redirigir la salida a un archivo y luego ese archivo indicarle a logrotate que haga lo suyo… Es bueno indicar que no podrá estar en /var/log así tan sencillamente, pero vale lo mismo una carpeta que tengamos acceso…
Etapa 3:
Descansar tranquilo, finalmente…