Cómo funciona SCP

Cómo funciona SCP

La herramienta WinSCP puede realizar una sudooperación en la máquina remota scpcomo usuario sudo. Eso me lleva a pensar que esto scptambién debe ser posible con la versión de línea de comandos .

En secreto, ¿cómo ejecuta esto WinSCP?

no quiero trabajar a travésuna solución con un directorio provisional de usuarios. Los archivos pueden ser tan grandes que debo publicarlos directamente utilizando el sudousuario. Como resultado, el archivo se copió, pero en mi directorio local, no en el directorio Sudo.

Una solución podría ser porcanalización manual sobre ssh:

tar zcvf -  MyBackups | ssh user@server "cat > /path/to/backup/foo.tgz"

Lo cual supongo que podría personalizar para hacer el sudo de la siguiente manera:

cat local.txt | ssh user@server "sudo -u sudouser cat > ~/remote_file"

El único problema es que al hacerlo de esta manera, tengo mucha carga que resolver que scpya se ha implementado usando la base. Por este y otros motivos tampoco quiero utilizar esta solución.

¿Cómo puedo permitir que scpse maneje una copia directa a control remoto usando un sudopara cambiar el usuario y obtener acceso a sus privilegios?

Respuesta1

Scp funciona estableciendo una conexión ssh con el servidor remoto y luego usando esa conexión para ejecutar otro scpcomando en el sistema remoto. La instancia scp local y la instancia remota se comunican a través del enlace ssh para enviar o recibir archivos.

OpenSSH scp en particular construye una cadena de comando scp para ejecutarse en el sistema remoto. Luego inicia ssh para ejecutar ese comando. El comando ssh final invocado es el equivalente a esto:

/path/to/ssh [ssh options...] "scp [scp options...]"
  • /ruta/a/ssh normalmente es una ruta integrada al programa ssh.
  • [opciones de ssh...] es una o más opciones para el programa ssh.
  • "scp [opciones de scp...]" es un argumento único que contiene el comando scp y sus argumentos para ejecutarse en el sistema remoto.

OpenSSH scp no proporciona muchas opciones para alterar la forma del comando scp remoto. No hay manera de que invoque algo que no sea "scp", o de insertar algo como "sudo" delante de la parte "scp".

Como habrás notado, scp tiene una opción para invocar algún otro programa en lugar de ssh. Alguien que supiera cómo podría escribir un programa contenedor ssh y hacer que scp invoque el contenedor en lugar de invocar ssh directamente. El contenedor tendría que examinar sus argumentos de línea de comandos para encontrar el que contiene el comando scp, modificar el comando como desee y luego invocar ssh con los argumentos de línea de comandos modificados.

Respuesta2

Cómo funciona SCP

El funcionamiento interno de scpdepende de dos formas no documentadas de scp, que es scp -fy scp -t. Básicamente son servidores remotos que escuchan la entrada estándar y generan datos a través de la salida estándar. Esos procesos utilizan un protocolo similar al que haría sftp. Puede encontrar más información en unBlog de Oráculo.

Cuando scpse inicie, primero iniciará una sesión ssh para iniciar scp -to scp -f. Luego, su proceso local scpse comunicará con el scpproceso remoto a través de stdout y stdin canalizado a ssh (completamente cifrado) y servirá como stdin/stdout para su scpsesión remota.

Cómo personalizar

El scpcomando proporciona una opción -sque le permite personalizar el programa utilizado para configurar la scpsesión remota. Se espera que maneje todas las opciones típicas de ssh. Para ayudar a depurar cómo se vería eso, configuramos un programa ficticio que simplemente descarga los parámetros:

/tmp/scp-dump.sh:

echo $0 $*

Lo ejecutaremos de la siguiente manera:

scp -S /tmp/scp-dump.sh /tmp/dump.txt [email protected]:/tmp

Y apropiadamente obtenemos el siguiente resultado:

/home/me/dump.sh \
    -x -oForwardAgent=no \
    -oPermitLocalCommand=no \
    -oClearAllForwardings=yes \
    -l me -- server.com scp -t /tmp

Se agregaron saltos de línea con barra invertida para facilitar la lectura.

Eso nos brinda la oportunidad de modificar los parámetros y comandos antes de enviarlos al sshcomando.

Configurando sudo

ahora podemos escribir un programa para modificar los parámetros según sea necesario, iniciar ssh y usar un formulario modificado para iniciar scp -t. Básicamente, capturaremos los parámetros, atraparemos aquellos que queremos usar internamente, solo agregaremos otros adicionales y haremos cambios.

/tmp/scp-sudo.sh:

add_ssh_option() {
  local option
  if [ $# = 2 ]; then
    option="$1 \"$2\""
  else
    option="$1"
  fi
  if [ -z "${ssh_options}" ]; then
    ssh_options=${option}
  else
    ssh_options="${ssh_options} ${option}"
  fi
}

parse_options() {
  ssh_options=
  local option
  while [ $# > 0 ] ; do
    case $1 in
      -oSudoUser=* )
        SSH_SUDO_USER=${option##*=}
        shift
        ;;
      -l ) ssh_user=$2 ; shift 2 ;;
      -i ) add_ssh_option "$1" "$2" ; shift 2 ;;
      -- ) shift ; break ;;
      -* ) add_ssh_option "${1}" ; shift ;;
      *  ) break ;;
    esac
  done
  ssh_host=$1
  shift
  ssh_command="$*"
}

parse_options "$@"
# To avoid intererence with Standard-In, we change this to
# Strict:
add_ssh_option "-oStrictHostKeyChecking=yes"

if [ -z "${SSH_SUDO_USER}" ]; then
  # As before without sudo
  cat | ssh $ssh_options -l $ssh_user $ssh_host $ssh_command
  exit $?
else
  # Send standard-in to the customized "scp -t" sink.
  cat | ssh $ssh_options -l $ssh_user $ssh_host sudo -i -u ${SSH_SUDO_USER} $ssh_command
  exit $?
fi

Ahora podemos usar el formulario scp modificado:

scp -oSudoUser=other \
    -i /tmp/me-id_rsa \
    /tmp/scp-sudo.sh \
    /tmp/dump.txt \
    [email protected]:/tmp

Esto funciona bien para enviar un archivo a un control remoto. Sin embargo, cuando recupero un archivo remoto, de alguna manera se bloquea. Cuando interrumpo la sesión (control-c), veo que la transferencia fue exitosa, pero de alguna manera tengo un archivo adicional llamado "0". ¿Me pregunto si alguien puede ayudarme con eso?

Mejor opción: sftp

Sin embargo, SFTP es mucho mejor.

  1. tiene la -Sopción que permite configurar toda la línea de comando ssh. Tuve problemas para entenderlo y hacerlo funcionar. Sospecho que no entiendo cómo vincular correctamente stdin/stdout desde un contenedor shell-ssh.
  2. tiene una -sopción (en minúsculas), que permite configurar solo el subcomando responsable de configurar el servidor remoto únicamente. Me resultó más fácil hacerlo funcionar.
  3. Puede configurar la ruta remota, los permisos de archivos remotos, realizar ambas funciones, poner/obtener, etc. según las páginas de manual de sftp.

En este caso simplemente

sftp -s "sudo -u sudo-user -- /usr/libexec/openssh/sftp-server" [email protected]

Eso me dio el feliz sftp>mensaje " "

Tenga en cuenta que el subprograma a veces se encuentra en rutas diferentes, por ejemplo /usr/libexec/openssh/sftp-server. ¿Sugeriría analizar desde la Subsystem sftpcadena " " dentro del /etc/ssh/sshd_confarchivo?

información relacionada