{"id":1404,"date":"2026-02-23T02:15:22","date_gmt":"2026-02-23T02:15:22","guid":{"rendered":"https:\/\/derecho.unap.edu.pe\/mespinoza\/?p=1404"},"modified":"2026-02-24T19:58:04","modified_gmt":"2026-02-24T19:58:04","slug":"sincronizacion-de-datos-entre-servidores-con-gnu-debian-backup-o-copia-de-seguridad","status":"publish","type":"post","link":"https:\/\/derecho.unap.edu.pe\/mespinoza\/2026\/02\/sincronizacion-de-datos-entre-servidores-con-gnu-debian-backup-o-copia-de-seguridad\/","title":{"rendered":"Sincronizaci\u00f3n de datos entre servidores con GNU Debian (backup o copia de seguridad de web Apache base de datos Mariadb o Mysql)"},"content":{"rendered":"\n<p>La migraci\u00f3n o respaldo de grandes directorios (en este caso,&nbsp;<strong>36 GB<\/strong>) entre servidores remotos presenta desaf\u00edos de permisos, estabilidad de conexi\u00f3n y seguridad. A continuaci\u00f3n, se detalla el procedimiento profesional para realizar una sincronizaci\u00f3n \u00edntegra utilizando&nbsp;<code>rsync<\/code>&nbsp;sobre un puerto SSH no est\u00e1ndar y con elevaci\u00f3n de privilegios.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">1. Introducci\u00f3n al Escenario<\/h2>\n\n\n\n<p>El objetivo es copiar el contenido de un directorio protegido (<code>\/mnt\/www_data\/<\/code>) desde un&nbsp;<strong>Servidor Origen<\/strong>&nbsp;(Remote) hacia un&nbsp;<strong>Servidor de Destino<\/strong>&nbsp;(Local), bajo las siguientes condiciones:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Acceso SSH:<\/strong>&nbsp;Puerto personalizado (ej. 2222).<\/li>\n\n\n\n<li><strong>Privilegios:<\/strong>&nbsp;El usuario requiere&nbsp;<code>sudo<\/code>&nbsp;para leer los datos de origen.<\/li>\n\n\n\n<li><strong>Eficiencia:<\/strong>&nbsp;Sincronizaci\u00f3n incremental (solo copia lo que ha cambiado).<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">2. Preparaci\u00f3n del Servidor Origen<\/h2>\n\n\n\n<p>Para que el proceso sea automatizado o fluido, el usuario remoto debe poder ejecutar el binario de&nbsp;<code>rsync<\/code>&nbsp;con privilegios de superusuario sin que la terminal se bloquee pidiendo una contrase\u00f1a de&nbsp;<code>sudo<\/code>.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Configuraci\u00f3n de Sudoers<\/h3>\n\n\n\n<ol start=\"1\" class=\"wp-block-list\">\n<li>Acceda al servidor de origen v\u00eda SSH.<\/li>\n\n\n\n<li>Ejecute el comando:&nbsp;<code>sudo visudo<\/code>.<\/li>\n\n\n\n<li>Al final del archivo, a\u00f1ada la siguiente regla (reemplace\u00a0<code>usuario_remoto<\/code>\u00a0por el suyo):<br><code>usuario_remoto<\/code>ALL=(ALL) NOPASSWD: \/usr\/bin\/mysqldump, \/usr\/bin\/mysql, \/usr\/bin\/mkdir, \/usr\/bin\/chown, \/usr\/bin\/rsync, \/usr\/bin\/rm<br><em>Esta configuraci\u00f3n permite que\u00a0<code>rsync<\/code>y Mariadb\u00a0lean archivos restringidos sin intervenci\u00f3n humana durante la transferencia.<\/em><\/li>\n<\/ol>\n\n\n\n<h2 class=\"wp-block-heading\">3. Ejecuci\u00f3n del Comando de Sincronizaci\u00f3n<\/h2>\n\n\n\n<p>Desde el&nbsp;<strong>Servidor de Destino<\/strong>, utilizaremos&nbsp;<code>rsync<\/code>&nbsp;con una combinaci\u00f3n de flags optimizada para grandes vol\u00famenes de datos.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">El comando maestro<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>rsync -avhP -e \"ssh -p 2222\" --rsync-path=\"sudo rsync\" usuario_remoto@servidor_origen.pe:\/mnt\/www_data \/ruta\/local\/backup\/\n<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Desglose de Par\u00e1metros:<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong><code>-a<\/code>&nbsp;(Archive):<\/strong>&nbsp;Preserva permisos, propietarios, grupos y fechas de modificaci\u00f3n. Es recursivo.<\/li>\n\n\n\n<li><strong><code>-v<\/code>&nbsp;(Verbose):<\/strong>&nbsp;Muestra los detalles de los archivos que se est\u00e1n procesando.<\/li>\n\n\n\n<li><strong><code>-h<\/code>&nbsp;(Human-readable):<\/strong>&nbsp;Muestra los tama\u00f1os de archivo en formato legible (KB, MB, GB).<\/li>\n\n\n\n<li><strong><code>-P<\/code>&nbsp;(Progress + Partial):<\/strong>&nbsp;* Muestra una barra de progreso y velocidad en tiempo real.\n<ul class=\"wp-block-list\">\n<li>Permite reanudar la transferencia si la conexi\u00f3n se corta, manteniendo los archivos parcialmente descargados.<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong><code>-e \"ssh -p 2222\"<\/code>:<\/strong>&nbsp;Especifica el protocolo de transporte y el puerto personalizado.<\/li>\n\n\n\n<li><strong><code>--rsync-path=\"sudo rsync\"<\/code>:<\/strong>&nbsp;Instruye al servidor remoto a ejecutar rsync como root, permitiendo la lectura de archivos con permisos restringidos.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">4. Consideraciones sobre el Slash (<code>\/<\/code>) en las Rutas<\/h2>\n\n\n\n<p>En&nbsp;<code>rsync<\/code>, la barra diagonal final en la ruta de origen cambia el comportamiento dr\u00e1sticamente:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong><code>...\/mnt\/www_data<\/code>&nbsp;(Sin barra):<\/strong>&nbsp;Copia la carpeta y su contenido. El resultado ser\u00e1&nbsp;<code>\/backup\/www_data\/...<\/code><\/li>\n\n\n\n<li><strong><code>...\/mnt\/www_data\/<\/code>&nbsp;(Con barra):<\/strong>&nbsp;Copia \u00fanicamente el&nbsp;<strong>contenido<\/strong>&nbsp;de la carpeta. El resultado ser\u00e1&nbsp;<code>\/backup\/archivo1<\/code>,&nbsp;<code>\/backup\/archivo2<\/code>, etc.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">5. Gesti\u00f3n de Sesiones con&nbsp;<code>Screen<\/code><\/h2>\n\n\n\n<p>Debido a que 36 GB pueden tardar varias horas, es cr\u00edtico evitar que la transferencia se detenga si cerramos nuestra terminal local o si el equipo entra en suspensi\u00f3n.<\/p>\n\n\n\n<ol start=\"1\" class=\"wp-block-list\">\n<li>Instale screen:&nbsp;<code>sudo apt install screen<\/code>.<\/li>\n\n\n\n<li>Inicie una sesi\u00f3n:&nbsp;<code>screen -S backup_proceso<\/code>.<\/li>\n\n\n\n<li>Ejecute el comando&nbsp;<code>rsync<\/code>.<\/li>\n\n\n\n<li>Para desconectarse sin detener el proceso: Presione&nbsp;<code>Ctrl + A<\/code>&nbsp;y luego&nbsp;<code>D<\/code>.<\/li>\n\n\n\n<li>Para retomar el monitoreo: Escribe&nbsp;<code>screen -r backup_proceso<\/code>.<\/li>\n<\/ol>\n\n\n\n<h2 class=\"wp-block-heading\">6. Verificaci\u00f3n de Integridad<\/h2>\n\n\n\n<p>Una vez finalizada la transferencia, es vital confirmar que el tama\u00f1o de los datos en ambos extremos coincida.<\/p>\n\n\n\n<p><strong>En el Origen y Destino ejecute:<\/strong><\/p>\n\n\n\n<p>Bash<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>du -sh \/ruta\/del\/directorio\n<\/code><\/pre>\n\n\n\n<p><strong>Para una verificaci\u00f3n m\u00e1s exhaustiva (Checksum):<\/strong>&nbsp;Si sospecha de archivos corruptos, a\u00f1ada el flag&nbsp;<code>-c<\/code>&nbsp;a su comando rsync. Esto comparar\u00e1 los archivos mediante hashes MD5 en lugar de solo tama\u00f1o y fecha, aunque consume m\u00e1s recursos de CPU.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">7. Seguridad Post-Transferencia<\/h2>\n\n\n\n<p>Una vez completada la migraci\u00f3n, se recomienda revertir los cambios en el archivo&nbsp;<code>sudoers<\/code>&nbsp;del servidor origen para mantener el principio de menor privilegio:<\/p>\n\n\n\n<ol start=\"1\" class=\"wp-block-list\">\n<li>Ejecute&nbsp;<code>sudo visudo<\/code>.<\/li>\n\n\n\n<li>Comente la l\u00ednea agregada:Bash<code># usuario_remoto ALL=(ALL) NOPASSWD: \/usr\/bin\/rsync<\/code><\/li>\n<\/ol>\n\n\n\n<h2 class=\"wp-block-heading\">8. Automatizaci\u00f3n mediante Cron Jobs (Respaldo Incremental)<\/h2>\n\n\n\n<p>Una de las mayores ventajas de&nbsp;<code>rsync<\/code>&nbsp;es su capacidad para realizar respaldos&nbsp;<strong>incrementales<\/strong>. Esto significa que, despu\u00e9s de la primera copia de 36 GB, las siguientes ejecuciones solo transferir\u00e1n los archivos nuevos o modificados, reduciendo el tiempo de horas a pocos minutos.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Paso 1: Configuraci\u00f3n de Llaves SSH (Sin Contrase\u00f1a)<\/h3>\n\n\n\n<p>Para que un script automatice la tarea, no puede detenerse a pedir una contrase\u00f1a. Debemos establecer una relaci\u00f3n de confianza entre los servidores.<\/p>\n\n\n\n<ol start=\"1\" class=\"wp-block-list\">\n<li><strong>Generar llave en el servidor de destino:<\/strong>&nbsp;<code>ssh-keygen -t rsa -b 4096<\/code>&nbsp;(Presione Enter a todo).<\/li>\n\n\n\n<li><strong>Enviar la llave al servidor de origen:<\/strong>&nbsp;<code>ssh-copy-id -p 2222 usuario_remoto@servidor_origen.pe<\/code><br>o<br>ssh-copy-id -p 2222 usuario_remoto@192.168.1.2<br>Qu\u00e9 pasar\u00e1 despu\u00e9s:<br>Te pedir\u00e1 la&nbsp;contrase\u00f1a&nbsp;de&nbsp;<code>usuario_remoto<\/code>. o preguntar\u00e1 con. \u00abAre you sure you want to continue connecting (yes\/no\/[fingerprint])?\u00bb responder: Yes<\/li>\n\n\n\n<li>Ver\u00e1s un mensaje confirmando:&nbsp;<code>Number of key(s) added: 1<\/code>.<\/li>\n\n\n\n<li>\u00a1Listo! A partir de ese segundo, el \u00abt\u00fanel\u00bb entre tu servidor destino y el servidor origen estar\u00e1 abierto y ser\u00e1 permanente.<\/li>\n\n\n\n<li><strong>Prueba:<\/strong>&nbsp;Intente conectar por SSH. Si entra sin pedir clave, la automatizaci\u00f3n es posible.<\/li>\n<\/ol>\n\n\n\n<p><\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Paso 2: Creaci\u00f3n del Script de Respaldo<\/h3>\n\n\n\n<p>Antes de crear el archivo&nbsp;<code>.sh<\/code>, debemos preparar la estructura de carpetas y los registros (logs) en tu m\u00e1quina local.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">1. Definir la Estructura de Directorios<\/h3>\n\n\n\n<p>Es una buena pr\u00e1ctica separar el script de los datos y de los reportes de error. Ejecuta estos comandos en tu Debian 11:<\/p>\n\n\n\n<p>Bash<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># Crear carpeta para los scripts\nmkdir -p ~\/scripts\n\n# Crear carpeta para los registros (logs)\nmkdir -p ~\/backup\/logs\n\n# Crear la carpeta donde se mantendr\u00e1 la copia sincronizada\nmkdir -p ~\/backup\/sincronizacion_continua\n<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">2. Verificar la Ruta del Binario de Rsync<\/h3>\n\n\n\n<p>El script necesita saber exactamente d\u00f3nde est\u00e1&nbsp;<code>rsync<\/code>&nbsp;para evitar errores de \u00abcomando no encontrado\u00bb. Confirma la ruta con:<\/p>\n\n\n\n<p>Bash<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>which rsync\n<\/code><\/pre>\n\n\n\n<p><em>(Normalmente responder\u00e1&nbsp;<code>\/usr\/bin\/rsync<\/code>)<\/em>.<\/p>\n\n\n\n<p>Cree un archivo llamado&nbsp;<code>backup_diario.sh<\/code>&nbsp;en su servidor de destino con el siguiente contenido:<\/p>\n\n\n\n<p><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#!\/bin\/bash\n\n# =================================================================\n# SCRIPT DE RESPALDO DIARIO\n# Descripci\u00f3n: Genera volcados SQL individuales y sincroniza archivos\n# =================================================================\n\n# 1. CONFIGURACI\u00d3N\nFECHA=$(date +%Y-%m-%d_%H-%M)\nLOG_FILE=\"\/home\/usuariodestino\/backup\/logs\/backup_$FECHA.log\"\nORIGEN_IP=\"192.168.1.2\"\nUSUARIO_REMOTO=\"usuario_remoto\"\nPUERTO_SSH=\"2222\"\nDIR_ORIGEN=\"\/mnt\/www_data\"\nDIR_DESTINO=\"\/home\/usuariodestino\/backup\/sincronizacion_continua\"\nDIR_SQL_REMOTO=\"\/mnt\/www_data\/backups_sql\"\n\n# Crear carpetas locales si no existen\nmkdir -p \/home\/usuariodestino\/backup\/logs\nmkdir -p $DIR_DESTINO\n\necho \"==========================================================\" >> $LOG_FILE\necho \"INICIO DEL PROCESO: $(date)\" >> $LOG_FILE\necho \"==========================================================\" >> $LOG_FILE\n\n# 2. GENERACI\u00d3N DE SQL EN EL SERVIDOR REMOTO (DERECHO)\necho \"&#91;1\/3] Generando volcados SQL en origen...\" >> $LOG_FILE\nssh -p $PUERTO_SSH $USUARIO_REMOTO@$ORIGEN_IP &lt;&lt; 'EOF' >> $LOG_FILE 2>&amp;1\n    # Preparar directorio de volcado\n    sudo mkdir -p \/mnt\/www_data\/backups_sql\n    sudo chown usuario_remoto:usuario_remoto \/mnt\/www_data\/backups_sql\n\n    # Rutas absolutas\n    MYSQL=\"\/usr\/bin\/mysql\"\n    DUMP=\"\/usr\/bin\/mysqldump\"\n\n    # Obtener lista de bases de datos con sudo\n    DBS=$(sudo $MYSQL -e \"SHOW DATABASES;\" | grep -Ev \"(Database|information_schema|performance_schema|mysql|sys)\")\n\n    for DB in $DBS; do\n        echo \"Exportando base de datos: $DB\"\n        sudo $DUMP --single-transaction --quick --lock-tables=false \"$DB\" > \"\/mnt\/www_data\/backups_sql\/${DB}.sql\"\n    done\n    echo \"Volcados SQL completados con \u00e9xito.\"\nEOF\n\n# 3. SINCRONIZACI\u00d3N DE ARCHIVOS Y SQL (RSYNC)\necho \"&#91;2\/3] Iniciando sincronizaci\u00f3n Rsync (36GB aprox)...\" >> $LOG_FILE\n# -a: archivo, -v: verboso, -h: legible, --delete: para espejar exactamente el origen\nrsync -avh --delete -e \"ssh -p $PUERTO_SSH\" --rsync-path=\"sudo rsync\" \\\n$USUARIO_REMOTO@$ORIGEN_IP:$DIR_ORIGEN\/ $DIR_DESTINO\/ >> $LOG_FILE 2>&amp;1\n\n# 4. VALIDACI\u00d3N DE RESULTADO Y LIMPIEZA\nif &#91; $? -eq 0 ]; then\n    echo \"&#91;3\/3] Sincronizaci\u00f3n exitosa. Limpiando archivos temporales en origen...\" >> $LOG_FILE\n    ssh -p $PUERTO_SSH $USUARIO_REMOTO@$ORIGEN_IP \"sudo rm -f $DIR_SQL_REMOTO\/*.sql\" >> $LOG_FILE 2>&amp;1\n    echo \"==========================================================\" >> $LOG_FILE\n    echo \"RESULTADO: RESPALDO COMPLETADO Y LIMPIO\" >> $LOG_FILE\nelse\n    echo \"==========================================================\" >> $LOG_FILE\n    echo \"RESULTADO: ERROR EN LA TRANSFERENCIA. REVISAR LOG.\" >> $LOG_FILE\nfi\n\necho \"FIN DEL PROCESO: $(date)\" >> $LOG_FILE\necho \"==========================================================\" >> $LOG_FILE<\/code><\/pre>\n\n\n\n<p>Script opcional para notificaci\u00f3n v\u00eda email desde el servidor de origen, para ello debe tener instalado \u00abmsmtp\u00bb el servidor de origen.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#!\/bin\/bash\n\n# =================================================================\n# SCRIPT DE RESPALDO COMPLETO + NOTIFICACION CON EMAIL\n# Emisor\/Receptor: usuario.remoto@servidororigen.pe\n# =================================================================\n\n# 1. CONFIGURACI\u00d3N\nFECHA=$(date +%Y-%m-%d_%H-%M)\nLOG_FILE=\"\/home\/usuariodestino\/backup\/logs\/backup_$FECHA.log\"\nORIGEN_IP=\"192.168.1.2\"\nUSUARIO_REMOTO=\"usuario_remoto\"\nPUERTO_SSH=\"2222\"\nDIR_ORIGEN=\"\/mnt\/www_data\"\nDIR_DESTINO=\"\/home\/usuariodestino\/backup\/sincronizacion_continua\"\nDIR_SQL_REMOTO=\"\/mnt\/www_data\/backups_sql\"\nEMAIL_CUENTA=\"usuario.remoto@servidororigen.pe\"\n\nmkdir -p \/home\/usuariodestino\/backup\/logs\n\necho \"==========================================================\" >> $LOG_FILE\necho \"INICIO DEL PROCESO: $(date)\" >> $LOG_FILE\necho \"==========================================================\" >> $LOG_FILE\n\n# 2. GENERACI\u00d3N DE SQL EN ORIGEN\necho \"&#91;1\/3] Generando volcados SQL en origen...\" >> $LOG_FILE\nssh -p $PUERTO_SSH $USUARIO_REMOTO@$ORIGEN_IP &lt;&lt; 'EOF' >> $LOG_FILE 2>&amp;1\n    sudo mkdir -p \/mnt\/www_data\/backups_sql\n    sudo chown usuario_remoto:usuario_remoto \/mnt\/www_data\/backups_sql\n    \n    DBS=$(sudo \/usr\/bin\/mysql -e \"SHOW DATABASES;\" | grep -Ev \"(Database|information_schema|performance_schema|mysql|sys)\")\n    \n    for DB in $DBS; do\n        echo \"Respaldando: $DB\"\n        sudo \/usr\/bin\/mysqldump --single-transaction --quick --lock-tables=false \"$DB\" > \"\/mnt\/www_data\/backups_sql\/${DB}.sql\"\n    done\nEOF\n\n# 3. SINCRONIZACI\u00d3N RSYNC\necho \"&#91;2\/3] Sincronizando archivos hacia Debian 11...\" >> $LOG_FILE\nrsync -avh --delete -e \"ssh -p $PUERTO_SSH\" --rsync-path=\"sudo rsync\" \\\n$USUARIO_REMOTO@$ORIGEN_IP:$DIR_ORIGEN\/ $DIR_DESTINO\/ >> $LOG_FILE 2>&amp;1\n\n# 4. VALIDACI\u00d3N Y LIMPIEZA\nif &#91; $? -eq 0 ]; then\n    echo \"&#91;3\/3] Sincronizaci\u00f3n exitosa. Limpiando origen...\" >> $LOG_FILE\n    ssh -p $PUERTO_SSH $USUARIO_REMOTO@$ORIGEN_IP \"sudo rm -f $DIR_SQL_REMOTO\/*.sql\" >> $LOG_FILE 2>&amp;1\n    ESTADO_FINAL=\"EXITOSO\"\nelse\n    echo \"&#91;!] ERROR EN RSYNC. No se limpi\u00f3 el origen.\" >> $LOG_FILE\n    ESTADO_FINAL=\"FALLIDO\"\nfi\n\necho \"FIN: $(date)\" >> $LOG_FILE\necho \"==========================================================\" >> $LOG_FILE\n\n# 5. ENV\u00cdO DE CORREO (AUTO-ENV\u00cdO)\n# Forzamos el remitente con el flag -from de msmtp para asegurar la entrega\n(\n  echo \"Subject: Reporte Backup FCJP ($ESTADO_FINAL) - $FECHA\"\n  echo \"From: $EMAIL_CUENTA\"\n  echo \"To: $EMAIL_CUENTA\"\n  echo \"\"\n  tail -n 35 \"$LOG_FILE\"\n) | ssh -p $PUERTO_SSH $USUARIO_REMOTO@$ORIGEN_IP \"msmtp --from=$EMAIL_CUENTA $EMAIL_CUENTA\"<\/code><\/pre>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\"><\/blockquote>\n\n\n\n<h2 class=\"wp-block-heading\">Notas<\/h2>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p>El flag\u00a0<code>--delete<\/code>\u00a0es opcional. Si lo activa, los archivos que borre en el servidor de origen tambi\u00e9n se borrar\u00e1n en el destino, manteniendo un espejo exacto.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Explicaci\u00f3n:<\/h3>\n\n\n\n<ol start=\"1\" class=\"wp-block-list\">\n<li><strong>Validaci\u00f3n de Red (<code>ping<\/code>):<\/strong>&nbsp;Antes de intentar copiar nada, el script verifica si el servidor origen responde por la IP privada. Si el cable se desconect\u00f3, el script se detiene y te avisa en el log.<\/li>\n\n\n\n<li><strong>Opci\u00f3n&nbsp;<code>--delete<\/code>:<\/strong>&nbsp;Es vital para un respaldo incremental tipo \u00abespejo\u00bb. Si borras una imagen basura en el servidor origen, el script tambi\u00e9n la borrar\u00e1 en tu Debian 11 para no acumular basura y ahorrar espacio.<\/li>\n\n\n\n<li><strong>Manejo de Logs:<\/strong>&nbsp;Cada vez que el script corra, crear\u00e1 un archivo con la fecha (ej.&nbsp;<code>backup_2026-02-24_02-00.log<\/code>). Esto te permite auditar qu\u00e9 archivos se bajaron y si hubo errores.<\/li>\n\n\n\n<li><strong>BatchMode=yes:<\/strong>&nbsp;Fuerza a SSH a fallar de inmediato si por alguna raz\u00f3n vuelve a pedir contrase\u00f1a, evitando que el script se quede \u00abcolgado\u00bb infinitamente esperando una entrada manual.<br><strong>Seguridad Anti-Fallos:<\/strong>&nbsp;Explica que el condicional&nbsp;<code>if [ $? -eq 0 ]<\/code>&nbsp;act\u00faa como un seguro de vida. Si el cable de red se desconecta o el disco se llena en medio del proceso, los archivos SQL se quedan en el servidor origen para que no pierdas nada.<\/li>\n\n\n\n<li><strong>Higiene del Servidor:<\/strong>&nbsp;Al usar&nbsp;<code>rm -f $DIR_SQL_REMOTO\/*.sql<\/code>&nbsp;al final, el servidor de producci\u00f3n (origen) se mantiene siempre con espacio libre, evitando que los respaldos afecten el funcionamiento de la web.<\/li>\n\n\n\n<li><strong>Persistencia en el Destino:<\/strong>&nbsp;Aunque se borren en el&nbsp;<strong>origen<\/strong>, en tu&nbsp;<strong>Debian 11 (destino)<\/strong>&nbsp;los archivos seguir\u00e1n existiendo dentro de la carpeta&nbsp;<code>sincronizacion_continua\/backups_sql\/<\/code>&nbsp;hasta que el pr\u00f3ximo respaldo exitoso los actualice.<\/li>\n<\/ol>\n<\/blockquote>\n\n\n\n<p>Para que el sistema lo reconozca como un programa ejecutable, debes darle el permiso&nbsp;<code>x<\/code>. Ejecuta este comando:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>chmod +x ~\/scripts\/backup_diario.sh<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Pruebas<\/h2>\n\n\n\n<p>Es totalmente comprensible, esperar a que se sincronicen 36 GB solo para ver si el script funciona es poco pr\u00e1ctico. Para probar la \u00abl\u00f3gica\u00bb del script (que conecte bien, que escriba el log y que encuentre las rutas) sin transferir los datos, tienes dos caminos r\u00e1pidos:<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Opci\u00f3n 1: El \u00abSimulador\u00bb (<code>--dry-run<\/code>)<\/h3>\n\n\n\n<p>Esta es la mejor opci\u00f3n. Le dice a&nbsp;<code>rsync<\/code>&nbsp;que haga todo&nbsp;<strong>excepto<\/strong>&nbsp;copiar los archivos. Te mostrar\u00e1 qu\u00e9 archivos copiar\u00eda pero sin mover un solo byte real.<\/p>\n\n\n\n<ol start=\"1\" class=\"wp-block-list\">\n<li>Abre tu script:&nbsp;<code>nano ~\/scripts\/backup_diario.sh<\/code><\/li>\n\n\n\n<li>Busca la l\u00ednea de&nbsp;<code>rsync<\/code>&nbsp;y a\u00f1ade&nbsp;<code>--dry-run<\/code>:Bash<code>rsync -avh --delete --dry-run \\ -e \"ssh -p $PUERTO_SSH -o BatchMode=yes\" \\ ...<\/code><\/li>\n\n\n\n<li>Guarda (<code>Ctrl+O<\/code>) y sal (<code>Ctrl+X<\/code>).<\/li>\n\n\n\n<li>Ejec\u00fatalo:&nbsp;<code>bash ~\/scripts\/backup_diario.sh<\/code>.<\/li>\n\n\n\n<li>Revisa el log:&nbsp;<code>cat ~\/backup\/logs\/backup_*.log<\/code>. Ver\u00e1s que termina en segundos y dice \u00ab(DRY RUN)\u00bb.<\/li>\n<\/ol>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">Opci\u00f3n 2: Probar con un solo archivo peque\u00f1o<\/h3>\n\n\n\n<p>Si quieres ver un archivo real siendo transferido para estar 100% seguro, puedes limitar el&nbsp;<code>rsync<\/code>&nbsp;para que solo vea un archivo espec\u00edfico (por ejemplo, el SQL que generamos).<\/p>\n\n\n\n<p>Modifica temporalmente la variable&nbsp;<code>DIR_ORIGEN<\/code>&nbsp;en tu script:<\/p>\n\n\n\n<p>Bash<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># Cambia esto solo para la prueba:\nDIR_ORIGEN=\"\/mnt\/www_data\/backups_sql\/db_full_backup.sql.gz\"\n<\/code><\/pre>\n\n\n\n<p>Al ejecutar el script, solo buscar\u00e1 ese archivo, lo transferir\u00e1 (o ver\u00e1 que ya existe) y terminar\u00e1 de inmediato.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">\u00bfQu\u00e9 debes revisar en el Log tras la prueba?<\/h3>\n\n\n\n<ol start=\"1\" class=\"wp-block-list\">\n<li><strong>Verifica el resultado en la carpeta de destino:<\/strong><br><code>ls -l \/home\/usuariodestino\/backup\/sincronizacion_continua\/ <\/code><em>(Deber\u00edas ver el archivo&nbsp;<code>nombrearchivoprueba.php<\/code>&nbsp;all\u00ed, o la estructura de carpetas que lo contiene).<\/em><\/li>\n\n\n\n<li><strong>Verifica que el log se haya creado correctamente:<\/strong>Bash<code>ls -l ~\/backup\/logs\/ cat ~\/backup\/logs\/backup_$(date +%Y-%m-%d)*.log<\/code><\/li>\n<\/ol>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<p>Independientemente de la opci\u00f3n que elijas, verifica que el log contenga estas l\u00edneas:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>\u00abSincronizando datos&#8230;\u00bb<\/strong>: Indica que pas\u00f3 la prueba del&nbsp;<code>ping<\/code>.<\/li>\n\n\n\n<li><strong>\u00abSENT&#8230; RECEIVED&#8230;\u00bb<\/strong>: Al final del log de rsync, esto confirma que hubo comunicaci\u00f3n.<\/li>\n\n\n\n<li><strong>\u00abRESPALDO COMPLETADO EXITOSAMENTE\u00bb<\/strong>: Esto confirma que la l\u00f3gica de salida (<code>$?<\/code>) del script funciona.<\/li>\n<\/ul>\n\n\n\n<p><strong>Importante:<\/strong>&nbsp;Una vez que est\u00e9s satisfecho con la prueba, recuerda quitar el&nbsp;<code>--dry-run<\/code>&nbsp;o restaurar la ruta&nbsp;<code>DIR_ORIGEN<\/code>original para que el respaldo real pueda suceder.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Paso 3: Programaci\u00f3n en el Crontab<\/h3>\n\n\n\n<p>Para que el script se ejecute, por ejemplo, todos los d\u00edas a las&nbsp;<strong>01:00 horas<\/strong>, siga estos pasos:<\/p>\n\n\n\n<ol start=\"1\" class=\"wp-block-list\">\n<li>De permisos de ejecuci\u00f3n al script:&nbsp;<code>chmod +x backup_diario.sh<\/code><\/li>\n\n\n\n<li>Abra el editor de cron:&nbsp;<code>crontab -e<\/code><br>si es la primera vez, aparcera algo parecido a esto, presiona 1 para usar nano:<br><\/li>\n<\/ol>\n\n\n\n<pre class=\"wp-block-code\"><code>usuariodestino@debian11:~\/backup\/scripts$ crontab -e\nno crontab for usuariodestino - using an empty one\n\nSelect an editor.  To change later, run 'select-editor'.\n  1. \/bin\/nano        &lt;---- easiest\n  2. \/usr\/bin\/vim.tiny\n\nChoose 1-2 &#91;1]: \n<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">1. Agregar la tarea<\/h3>\n\n\n\n<p>Baja hasta el final del archivo con las flechas del teclado y pega esta l\u00ednea:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>00 01 * * * \/home\/usuariodestino\/backup\/scripts\/backup_diario.sh\n<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">2. Guardar y Salir<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Presiona&nbsp;<strong><code>Ctrl + O<\/code><\/strong>&nbsp;(para escribir los cambios).<\/li>\n\n\n\n<li>Presiona&nbsp;<strong><code>Enter<\/code><\/strong>&nbsp;(para confirmar el nombre del archivo).<\/li>\n\n\n\n<li>Presiona&nbsp;<strong><code>Ctrl + X<\/code><\/strong>&nbsp;(para salir del editor).<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">3. Confirmar que se guard\u00f3<\/h3>\n\n\n\n<p>Si todo sali\u00f3 bien, la terminal te mostrar\u00e1 el mensaje:&nbsp;<code>crontab: installing new crontab<\/code><\/p>\n\n\n\n<p>Puedes verificarlo listando las tareas activas:<\/p>\n\n\n\n<p><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>crontab -l<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>La migraci\u00f3n o respaldo de grandes directorios (en este caso,&nbsp;36 GB) entre servidores remotos presenta desaf\u00edos de permisos, estabilidad de conexi\u00f3n y seguridad. A continuaci\u00f3n,&#8230;<\/p>\n<div class=\"more-link-wrapper\"><a class=\"more-link\" href=\"https:\/\/derecho.unap.edu.pe\/mespinoza\/2026\/02\/sincronizacion-de-datos-entre-servidores-con-gnu-debian-backup-o-copia-de-seguridad\/\">Seguir leyendo<span class=\"screen-reader-text\">Sincronizaci\u00f3n de datos entre servidores con GNU Debian (backup o copia de seguridad de web Apache base de datos Mariadb o Mysql)<\/span><\/a><\/div>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[7],"tags":[],"class_list":["post-1404","post","type-post","status-publish","format-standard","hentry","category-manuales","entry"],"_links":{"self":[{"href":"https:\/\/derecho.unap.edu.pe\/mespinoza\/wp-json\/wp\/v2\/posts\/1404","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/derecho.unap.edu.pe\/mespinoza\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/derecho.unap.edu.pe\/mespinoza\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/derecho.unap.edu.pe\/mespinoza\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/derecho.unap.edu.pe\/mespinoza\/wp-json\/wp\/v2\/comments?post=1404"}],"version-history":[{"count":24,"href":"https:\/\/derecho.unap.edu.pe\/mespinoza\/wp-json\/wp\/v2\/posts\/1404\/revisions"}],"predecessor-version":[{"id":1449,"href":"https:\/\/derecho.unap.edu.pe\/mespinoza\/wp-json\/wp\/v2\/posts\/1404\/revisions\/1449"}],"wp:attachment":[{"href":"https:\/\/derecho.unap.edu.pe\/mespinoza\/wp-json\/wp\/v2\/media?parent=1404"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/derecho.unap.edu.pe\/mespinoza\/wp-json\/wp\/v2\/categories?post=1404"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/derecho.unap.edu.pe\/mespinoza\/wp-json\/wp\/v2\/tags?post=1404"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}