La herramienta WinSCP puede realizar una sudo
operación en la máquina remota scp
como usuario sudo. Eso me lleva a pensar que esto scp
tambié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 sudo
usuario. 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 scp
ya se ha implementado usando la base. Por este y otros motivos tampoco quiero utilizar esta solución.
¿Cómo puedo permitir que scp
se maneje una copia directa a control remoto usando un sudo
para 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 scp
comando 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 scp
depende de dos formas no documentadas de scp
, que es scp -f
y 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 scp
se inicie, primero iniciará una sesión ssh para iniciar scp -t
o scp -f
. Luego, su proceso local scp
se comunicará con el scp
proceso remoto a través de stdout y stdin canalizado a ssh (completamente cifrado) y servirá como stdin/stdout para su scp
sesión remota.
Cómo personalizar
El scp
comando proporciona una opción -s
que le permite personalizar el programa utilizado para configurar la scp
sesió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 ssh
comando.
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.
- tiene la
-S
opció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. - tiene una
-s
opció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. - 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 sftp
cadena " " dentro del /etc/ssh/sshd_conf
archivo?