SCP

El comando SCP (Secure Copy Protocol) de Linux es un protocolo de transferencia de archivos en red que permite la transferencia de archivos fácil y segura entre un host remoto y uno local, o entre dos ubicaciones remotas. Se basa en el Protocolo de Copia Remota de Berkeley Software Distribution.

Los desarrolladores full-stack utilizan con frecuencia el comando SCP para sus funciones de autenticación y cifrado sin requerir servicios de alojamiento de terceros como Github. Es una forma fácil de evitar la exposición de tus datos a rastreadores de paquetes, y de preservar su confidencialidad.

En esencia, SCP es una mezcla de RCP y SSH (Secure Shell). Se basa en el primero para realizar operaciones de copia y en el segundo para cifrar la información y autenticar los sistemas remotos.

A diferencia de Rsync, todo lo que necesitas para usar la línea de comandos de SCP con éxito es un nombre de usuario y contraseña o frase de contraseña para los sistemas involucrados en la transferencia. Esto agiliza el proceso ya que no es necesario iniciar sesión en ninguno de ellos.

Transferir archivos de forma segura es primordial cuando se usa un VPS. Afortunadamente, se puede hacer fácilmente usando el comando SCP. En este artículo aprenderás a usar los comandos SCP y cómo pueden ayudarte.

Actualizar el servidor:

apt update

Instalar las ultimas actualizaciones:

apt upgrade

Instalar sshpass:

apt install sshpass

Creación de claves públicas y privadas utilizando ssh-key-gen en local-anfitrión:

ssh-keygen

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.

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