ssh-agent reenvío y sudo a otro usuario

153

Si tengo un servidor A en el que puedo iniciar sesión con mi clave ssh y tengo la capacidad de "sudo su - otheruser", pierdo el reenvío de claves, porque las variables env se eliminan y el usuario original solo puede leer el socket. ¿Hay alguna forma de que pueda unir el reenvío de claves a través del "sudo su - otheruser", para poder hacer cosas en un servidor B con mi clave reenviada (git clone y rsync en mi caso)?

La única forma en que puedo pensar es agregar mi clave a las claves autorizadas de otheruser y "ssh otheruser @ localhost", pero eso es engorroso para cada combinación de usuario y servidor que pueda tener.

En breve:

$ sudo -HE ssh user@host
(success)
$ sudo -HE -u otheruser ssh user@host
Permission denied (publickey). 
Kolypto
fuente

Respuestas:

182

Como mencionó, las variables de entorno se eliminan por sudorazones de seguridad.

Pero afortunadamente sudoes bastante configurable: puede decirle con precisión en qué variables de entorno desea mantener gracias a la env_keepopción de configuración /etc/sudoers.

Para el reenvío de agentes, debe mantener SSH_AUTH_SOCKvariable el entorno. Para hacerlo, simplemente edite su /etc/sudoersarchivo de configuración (siempre usando visudo) y configure la env_keepopción para los usuarios apropiados. Si desea que esta opción se configure para todos los usuarios, use la Defaultslínea como esta:

Defaults    env_keep+=SSH_AUTH_SOCK

man sudoers para más detalles.

Ahora debería poder hacer algo como esto (siempre que user1la clave pública esté presente ~/.ssh/authorized_keysen user1@serverAy user2@serverB, y serverAel /etc/sudoersarchivo esté configurado como se indicó anteriormente):

user1@mymachine> eval `ssh-agent`  # starts ssh-agent
user1@mymachine> ssh-add           # add user1's key to agent (requires pwd)
user1@mymachine> ssh -A serverA    # no pwd required + agent forwarding activated
user1@serverA> sudo su - user2     # sudo keeps agent forwarding active :-)
user2@serverA> ssh serverB         # goto user2@serverB w/o typing pwd again...
user2@serverB>                     # ...because forwarding still works
MiniQuark
fuente
1
Esta es la respuesta correcta, debe marcarse.
Xealot
41
Esto solo funciona, si lo user2anterior es root! De lo contrario, user2tendrá SSH_AUTH_SOCK configurado correctamente, pero user2no podrá acceder, por ejemplo, / tmp / ssh-GjglIJ9337 /. roottiene ese acceso. Por lo tanto, esto puede resolver parte del problema, pero no los OP: " y el usuario solo puede leer el socket"
Peter V. Mørch
66
Defaults>root env_keep+=SSH_AUTH_SOCKDebe asegurarse de que solo se reenvíe cuando sudo a la raíz. No quiere hacer eso de todos modos a otros usuarios por razones de seguridad. Mejor ejecute un agente ssh separado para otro y agregue las claves apropiadas.
Paul Schyska
1
sudo su -no funciona para mí, presumiblemente no puede preservar el medio ambiente porque no está sudoen el inicio del shell. sudo suparece funcionar.
Alex Fortuna
3
Nunca he entendido por qué la gente usa de sudo sutodos modos. Si necesita un shell raíz, para eso es sudo -so sudo -ipara qué sirve.
Eaj
68
sudo -E -s
  • -E preservará el medio ambiente
  • -s ejecuta un comando, por defecto es un shell

Esto le dará un shell raíz con las claves originales aún cargadas.

Joao Costa
fuente
2
Al igual que con el comentario anterior, esto solo responde a la pregunta si se está convirtiendo en root, porque en ese caso el root puede evitar los permisos de acceso habituales en $ SSH_AUTH_SOCK.
doshea
35

Permita que otro usuario acceda al $SSH_AUTH_SOCKarchivo y su directorio, por ejemplo, mediante la ACL correcta, antes de cambiar a ellos. El ejemplo asume Defaults:user env_keep += SSH_AUTH_SOCKen la /etc/sudoersmáquina host:

$ ssh -A user@host
user@host$ setfacl -m otheruser:x   $(dirname "$SSH_AUTH_SOCK")
user@host$ setfacl -m otheruser:rwx "$SSH_AUTH_SOCK"
user@host$ sudo su - otheruser
otheruser@host$ ssh server
otheruser@server$

Más seguro y funciona también para usuarios no root ;-)

Viliam Pucik
fuente
66
Recuerde que cuando usa este método, otras personas que inician sesión otherusertambién pueden usar su autenticación ssh.
gitaarik
Esto funciona para mí, excepto que tuve que cambiar "sudo su - otheruser" a "sudo su otheruser" (eliminar el -).
Charles Finkel
1
¿Por qué rwxy no rw(o ren absoluto)?
anatoly techtonik
3
@anatolytechtonik Desde man 7 unix: en Linux, la conexión al socket requiere permisos de lectura y escritura en ese socket. También necesita buscar (ejecutar) y escribir permiso en el directorio donde crea el socket o solo buscar (ejecutar) permiso cuando se conecta a este socket. Entonces, en la respuesta anterior, el permiso de ejecución en el socket es redundante.
mixel
en lugar de tener que editar / etc / sudoers que puede usarsudo -u otheruser --preserve-env=HOME -s
Sec
14

He descubierto que esto también funciona.

sudo su -l -c "export SSH_AUTH_SOCK=$SSH_AUTH_SOCK; bash"

Como otros han señalado, esto no funcionará si el usuario al que se está cambiando no tiene permisos de lectura en $ SSH_AUTH_SOCK (que es prácticamente cualquier usuario además de root). Puede evitar esto estableciendo $ SSH_AUTH_SOCK y el directorio en el que se encuentra para tener los permisos 777.

chmod 777 -R `dirname $SSH_AUTH_SOCK`
sudo su otheruser -l -c "export SSH_AUTH_SOCK=$SSH_AUTH_SOCK; bash"

Sin embargo, esto es bastante arriesgado. Básicamente, le está dando permiso a todos los demás usuarios del sistema para usar su Agente SSH (hasta que cierre la sesión). También puede configurar el grupo y cambiar los permisos a 770, lo que podría ser más seguro. Sin embargo, cuando intenté cambiar el grupo, obtuve "Operación no permitida".

phylae
fuente
66
Esto es extremadamente arriesgado. Darle permiso a todos los demás usuarios para usar su agente SSH es equivalente a darles todas sus credenciales (y si alguna vez usa sudo o su, ¡darles poder raíz sobre todos los demás usuarios en el sistema, así como todos los demás sistemas a los que ssh!) . ¡Esto NUNCA debe hacerse!
Matija Nalis
44
No estoy de acuerdo con la afirmación de que "¡Esto NUNCA debe hacerse!" Hay muchos casos en los que este riesgo es aceptable. Por ejemplo, un pequeño equipo donde todos tienen los mismos permisos y usted confía en todos los demás usuarios. Nunca debe hacerse sin comprender los riesgos que implica. Pero una vez que se comprenden esos riesgos, hay ocasiones en que ese riesgo es aceptable.
phylae
6

Si está autorizado para hacerlo sudo su - $USER, probablemente tenga un buen argumento para que se le permita hacer una ssh -AY $USER@localhost, con su clave pública válida en el directorio de inicio de $ USER. Entonces su reenvío de autenticación se llevaría a cabo con usted.

David Mackintosh
fuente
Mencionó eso al final de su pregunta y dijo que sería difícil de hacer.
Fahad Sadah
Esta es probablemente la mejor solución, pero se vuelve difícil si $ USER es una persona real (tm): pueden eliminar la clave de SA de claves autorizadas o cambiar su contraseña ...
voretaq7
Puede eliminar su acceso de escritura a claves_autorizadas (aunque si realmente están configurados para denegar el acceso a Florian, pueden eliminarlo y volver a crearlo, ya que está en un directorio que poseen)
Fahad Sadah
4

Siempre puede simplemente ssh a localhost con reenvío de agente en lugar de usar sudo:

ssh -A otheruser@localhost

La desventaja es que necesita iniciar sesión nuevamente, pero si lo está utilizando en una pestaña screen / tmux, eso es solo un esfuerzo de una vez, sin embargo, si se desconecta del servidor, el socket se romperá (por supuesto) nuevamente . Por lo tanto, no es ideal si no puede mantener su sesión screen / tmux abierta en todo momento (sin embargo, puede actualizar manualmente su SSH_AUTH_SOCKenv var si es genial).

También tenga en cuenta que cuando usa el reenvío ssh, el root siempre puede acceder a su socket y usar su autenticación ssh (siempre que haya iniciado sesión con el reenvío ssh). Así que asegúrese de poder confiar en la raíz.

gitaarik
fuente
Esto no funciona si solo tiene acceso a otherusertravés de en sudolugar de a través de SSH (por ejemplo, si desea SCP cosas como www-data)
Gert van den Berg
3

No lo uses sudo su - USER, sino más bien sudo -i -u USER. ¡Funciona para mi!

Fahad Sadah
fuente
¿Qué versión de sudo tienes? Mine (1.6.7p5, CentOS 4.8) no tiene -i en su página de manual.
David Mackintosh
Sudo version 1.6.9p17corriendo en Debian Lenny. Prueba sudo -s?
Fahad Sadah
66
No funciona para mi
En Ubuntu, usando Sudo 1.8.9p5, sudo -sni sudo -ifunciona para mí ...
Jon L.
2

Combinando información de las otras respuestas se me ocurrió esto:

user=app
setfacl -m $user:x $(dirname "$SSH_AUTH_SOCK")
setfacl -m $user:rwx "$SSH_AUTH_SOCK"
sudo SSH_AUTH_SOCK="$SSH_AUTH_SOCK" -u $user -i

Me gusta esto porque no necesito editar el sudoersarchivo.

Probado en Ubuntu 14.04 (tuvo que instalar el aclpaquete).

warvariuc
fuente
1

Creo que hay un problema con la -opción (guión) después sude su comando:

sudo su - otheruser

Si lee la página de manual de su , puede encontrar que la opción -, -l, --logininicia el entorno de shell como shell de inicio de sesión. Este será el entorno otheruserindependientemente de las variables env donde se ejecute su.

En pocas palabras, el tablero socavará cualquier cosa de la que haya pasado sudo.

En su lugar, deberías probar este comando:

sudo -E su otheruser

Como señaló @ joao-costa, -Epreservará todas las variables en el entorno donde se ejecutó sudo. Luego, sin el tablero, suutilizará ese entorno directamente.

Koala Yeung
fuente
0

Desafortunadamente, cuando le sumas a otro usuario (o incluso usas sudo) perderás la capacidad de usar tus claves reenviadas. Esta es una característica de seguridad: no desea que usuarios aleatorios se conecten a su agente ssh y usen sus claves :)

El método "ssh -Ay $ {USER} @localhost" es un poco engorroso (y como se señaló en mi comentario sobre la respuesta de David propenso a la rotura), pero es probablemente lo mejor que puede hacer.

voretaq7
fuente
1
Hmm, pero si hago esto con ssh, entonces ese agente puede acceder a mi agente de todos modos, ¿o me equivoco?
Si ingresa SSH al usuario objetivo con el agente que reenvía sus solicitudes de agente, la cadena rebotará a donde sea que esté el agente "real". Cuando su sudo o sudo se aleja del usuario original, su socket de agente SSH no será (o no debería) accesible: el directorio en el que vive es el modo 700 y es propiedad del usuario original. (Advertencia: si está cambiando a root y reinicia el entorno SSH_AUTH_SOCK, podría funcionar, pero no confiaría en él)
voretaq7
1
En mi servidor (Ubuntu 12.04, versión ssh OpenSSH_5.9p1 Debian-5ubuntu1.1, OpenSSL 1.0.1 14 de marzo de 2012), ssh tiene -ay -Aargumentos. -ahace exactamente lo contrario de lo que se pretende, ¡deshabilita el reenvío de agentes! Entonces, bajo la versión reciente (y posiblemente toda) de Ubuntu, use -Apara habilitar el reenvío de agentes.
Knite
@knite Tienes razón: ese es un error tipográfico (¡de 3 años!) en mi respuesta. Corregido ahora :-)
voretaq7