🔐 Transferencia Segura de Archivos con SCP
El comando SCP (Secure Copy Protocol) permite transferir archivos de forma segura entre equipos locales y remotos en sistemas Linux. Utiliza el protocolo SSH para garantizar la confidencialidad e integridad de los datos.
📦 ¿Para qué sirve SCP?
- Copiar archivos desde tu máquina local a un servidor remoto.
- Descargar archivos desde un servidor remoto a tu máquina local.
- Transferir archivos entre dos servidores remotos sin intervención local.
✅ Ventajas de SCP
- 🔒 Seguridad mediante cifrado SSH.
- ⚡ Transferencia rápida y directa.
- 🧩 Fácil integración en scripts y automatizaciones.
🔄 Actualización del Servidor
Antes de comenzar con la configuración de SCP y la automatización de respaldos, es fundamental asegurarse de que el servidor esté actualizado. Esto garantiza estabilidad, seguridad y compatibilidad con las herramientas que se utilizarán.
sudo apt update && sudo apt upgrade -y
💡 Consejo: Puedes agregar apt dist-upgrade
si deseas actualizar también los paquetes que cambian dependencias o eliminan otros.
🔐 Instalación de Herramientas de Seguridad
Para facilitar la autenticación sin intervención manual durante las transferencias, instala sshpass
:
sudo apt install sshpass -y
🔑 Generación de Claves SSH
Genera un par de claves pública/privada para establecer una conexión segura entre el servidor local y el remoto:
ssh-keygen
Presiona Enter en cada paso para aceptar los valores por defecto. Luego, copia la clave pública al servidor remoto:
Generating public/private rsa key pair.
Enter file in which to save the key (/home/debian/.ssh/id_rsa):[Pulse Intro aquí]
Enter passphrase (empty for no passphrase): [Pulse Intro aquí]
Enter same passphrase again: [Pulse Intro aquí]
Your identification has been saved in /home/debian/.ssh/id_rsa.
Your public key has been saved in /home/debian/.ssh/id_rsa.pub.
The key fingerprint is:
33:b3:fe:af:95:95:18:11:31:d5:de:96:2f:f2:35:f9 debian@local-host
Copie la clave pública al host remoto usando ssh-copy-id:
ssh-copy-id -i ~/.ssh/id_rsa.pub 192.168.1.200
debian@remote-host's password:
Now try logging into the machine, with "ssh 'remote-host'", and check in:
.ssh/authorized_keys
to make sure we haven't added extra keys that you weren't expecting.
✅ Esto permitirá conectarte sin necesidad de ingresar la contraseña cada vez.
Nota: ssh-copy-id añade las claves para el control remoto ssh-anfitrión / authorized_key.
Entrar al host remoto sin introducir la contraseña:
ssh 192.168.1.200
Last login: Sun Nov 16 17:22:33 2012 from 192.168.1.2
[Note: SSH no preguntará por el password.]

Si ha cargado llaves del ssh-agent con el ssh-add, entonces ssh-copy-id recibirá las llaves del ssh-agent para copiar en el host remoto, es decir, que copia las claves proporcionadas por el comando ssh-add -L para el host remoto, cuando no pasa la opción -i para el ssh-copy-id.
>> Si al escribir, obtenemos un resultado similar a este:
debian@debian:~$ ssh-add -L
The agent has no identities.
>> Escribimos lo siguiente para pasar la "shell al sistema remoto".
debian@debian:~$ ssh-agent $SHELL
>> Introducimos la clave (si procede, vacía, para no pedirla)
debian@debian:~$ ssh-add
Identity added: /home/debian/.ssh/id_rsa (/home/debian/.ssh/id_rsa)
>> Lo verificamos
debian@debian:~$ ssh-add -L
ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAsJIEILxftj8aSxMa3d8t6JvM79DyBV
aHrtPhTYpq7kIEMUNzApnyxsHpH1tQ/Ow== /home/debian/.ssh/id_rsa
>> (En princpio, podría no hacer falta, pero si quieres puedes copiar la Id al host remoto.)
debian@local-host$ ssh-copy-id -i remote-host
debian@remote-host's password:
Now try logging into the machine, with "ssh 'remote-host'",
and check in: .ssh/authorized_keys to make sure we haven't added extra keys that you weren't expecting.
[Nota: Esto ha añadido la clave mostrado por ssh-add -L]
Crear la relación entre los servidores:
sshpass -p "debian" scp -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -r debian@192.168.1.200:/home/debian /home/debian/
Crear un archivo de nombre scp.sh
nano scp.sh
Incrustar el siguiente código:
#!/bin/bash
date
# Shell script que es ejecutado por medio de crontab, el
# cual contiene código que servirá para eliminar carpetas
# de respaldo que no hayan sido modificados en 90 días.
# ------------------------------------------------------
find /home/debian/backups/* -type f -ctime +18 | xargs rm -rf
sshpass -p "debian" ssh debian@192.168.1.200 "find backups/debian/* -type f -ctime +18 | xargs rm -rf"
# Scrip Basico de Respaldo de MySQL
# Directorio de Trabajo
backup_parent_dir="/home/debian/backups"
# MySQL - Ingresar las credenciales de un usuario con permisos para usar mysqldump para exportar las BDs
mysql_user="root"
mysql_password="debian"
# Verificacion de MySQL password
echo exit | mysql --user=${mysql_user} --password=${mysql_password} -B 2>/dev/null
if [ "$?" -gt 0 ]; then
echo "Contraseña del usuario ${mysql_user} incorrecto"
exit 1
fi
# Creando Respaldo y Configurando los Permisos
backup_date=`date +%d-%m-%Y_%H%M`
backup_dir="${backup_parent_dir}/${backup_date}"
echo "Directorio de respaldo: ${backup_dir}"
mkdir -p "${backup_dir}"
chmod 700 "${backup_dir}"
# Capturar la Base de Datos de MySQL
mysql_databases=`echo 'show databases' | mysql --user=${mysql_user} --password=${mysql_password} -B | sed /^Database$/d`
# Respaldando y Comprimiendo las Bases de Datos
for database in $mysql_databases
do
if [ "${database}" == "information_schema" ] || [ "${database}" == "performance_schema" ]; then
additional_mysqldump_params="--skip-lock-tables"
else
additional_mysqldump_params=""
fi
echo "Creando respaldo de base de datos \"${database}\"."
mysqldump ${additional_mysqldump_params} --user=${mysql_user} --password=${mysql_password} ${database} | gzip > "${backup_dir}/${database}.gz"
chmod 600 "${backup_dir}/${database}.gz"
done
echo "Copiando archivos"
cp -R /home/debian "${backup_dir}/debian"
echo "Copia finalizada"
echo "Se hara compresion"
tar -C backups/ -zcf backups/"${backup_date}".tar.gz "${backup_date}" --remove-files
echo "Compresión finalizada"
# Mandar carpeta a servidor remoto (se necesita el equipo ya
# esté autorizado para ssh con el fin de evitar autenticación
echo "Iniciando subida de archivo a servidor"
sshpass -p "debian" scp -r "${backup_dir}.tar.gz" debian@192.168.1.200:/home/debian/backups/
echo "Terminada la subida de respaldo a servidor"
echo "Fin del script"
date
Ejecutar el archivo
sudo bash scp.sh
Pasando el tiempo de espera de la transferencia de archivos el resultado sera el siguiente en el servidor remoto:

Tres pequeñas molestias de ssh-copy-id
A continuación se presentan algunas molestias menores del ssh-copy-id.
Default public key: ssh-copy-id utiliza ~/.ssh/ identity.pub como el archivo predeterminado de clave pública (es decir, cuando no hay valor se pasa a la opción -i). En su lugar, me gustaría utilizar id_dsa.pub o id_rsa.pub o identity.pub como claves predeterminadas. es decir, si cualquiera de ellos existe, se debe copiar para el host remoto. Si dos o tres de ellos existen, se debe copiar identity.pub como predeterminado.
El agente no tiene identidad: Cuando el ssh-agent se está ejecutando y ssh-add -L devuelve «El agente no tiene identidad» (es decir, no hay claves que se agregan al ssh-agent), el ssh-copy-id todavía copiará el mensaje «El agente no tiene identidad» para la entrada de la máquina remota de authorized_keys.
Duplicar entrada en authorized_keys: Deseo ssh-copy-id valida la entrada duplicada en authorized_keys del host remoto. Si ejecuta ssh-copy-id varias veces en el host local, se mantendrá anexar la misma clave en el archivo de authorized_keys del host remoto sin comprobación de duplicados. Incluso con las entradas duplicadas, todo funciona como se esperaba.
Archivo de ejemplo funcionando:
#!/bin/bash
date
# Shell script que es ejecutado por medio de crontab, el
# cual contiene código que servirá para eliminar carpetas
# de respaldo que no hayan sido modificados en 90 días.
# ------------------------------------------------------
find /home/debian/backups/* -type f -ctime +18 | xargs rm -rf
sshpass -p "debian" ssh debian@192.168.1.11 "find /home/debian/backups/* -type f -ctime +18 | xargs rm -rf"
# Scrip Basico de Respaldo de MySQL
# Directorio de Trabajo
backup_parent_dir="/home/debian/backups"
# MySQL - Ingresar las credenciales de un usuario con permisos para usar mysqldump para exportar las BDs
mysql_user="root"
mysql_password="debian"
# Verificacion de MySQL password
echo exit | mysql --user=${mysql_user} --password=${mysql_password} -B 2>/dev/null
if [ "$?" -gt 0 ]; then
echo "Contraseña del usuario ${mysql_user} incorrecto"
exit 1
fi
# Creando Respaldo y Configurando los Permisos
backup_date=`date +%d-%m-%Y_%H%M`
backup_dir="${backup_parent_dir}/${backup_date}"
echo "Directorio de respaldo: ${backup_dir}"
mkdir -p "${backup_dir}"
chmod 700 "${backup_dir}"
# Capturar la Base de Datos de MySQL
mysql_databases=`echo 'show databases' | mysql --user=${mysql_user} --password=${mysql_password} -B | sed /^Database$/d`
# Respaldando y Comprimiendo las Bases de Datos
for database in $mysql_databases
do
if [ "${database}" == "information_schema" ] || [ "${database}" == "performance_schema" ]; then
additional_mysqldump_params="--skip-lock-tables"
else
additional_mysqldump_params=""
fi
echo "Creando respaldo de base de datos \"${database}\"."
mysqldump ${additional_mysqldump_params} --user=${mysql_user} --password=${mysql_password} ${database} | gzip > "${backup_dir}/${database}.gz"
chmod 600 "${backup_dir}/${database}.gz"
done
echo "Copiando archivos"
cp -R /home/debian "${backup_dir}/debian"
echo "Copia finalizada"
echo "Se hara compresion"
tar -C backups/ -zcf backups/"${backup_date}".tar.gz "${backup_date}" --remove-files
echo "Compresión finalizada"
# Mandar carpeta a servidor remoto (se necesita el equipo ya
# esté autorizado para ssh con el fin de evitar autenticación
echo "Iniciando subida de archivo a servidor"
sshpass -p "debian" scp -r "${backup_dir}.tar.gz" debian@192.168.1.11:/home/debian/backups/
echo "Terminada la subida de respaldo a servidor"
echo "Fin del script"
date
Videos:
Referencias:
linuxize.com (2020). How to Use SCP Command to Securely Transfer Files. Recuperado Julio 12, 2021 de https://linuxize.com/post/how-to-use-scp-command-to-securely-transfer-files/
haydenjames.io (2020). SCP Linux – Securely Copy Files Using SCP examples. Recuperado Julio 12, 2021 de https://haydenjames.io/linux-securely-copy-files-using-scp/
hypexr.org (2021). Example syntax for Secure Copy (scp). Recuperado Julio 12, 2021 de http://www.hypexr.org/linux_scp_help.php