ADVERTENCIA : creatividad por delante, que a menudo es perjudicial para la seguridad (al menos sin una revisión exhaustiva).
Esto suena como un caso en el que un agente de SSH podría ser útil. Un agente de SSH proporciona una interfaz de socket a través de la cual los clientes de SSH pueden pedirle al agente que realice las operaciones clave para ellos, lo que permite los siguientes usos comunes:
- Puede hacer que el agente de larga duración descifre su clave privada una vez, en lugar de que cada cliente descifre la clave por separado.
- Puede hacer que su cliente SSH reenvíe la conexión del agente, lo que le permite usar su clave desde el host remoto sin almacenarla allí o revelarla de otra manera.
Este segundo caso, en particular, se parece mucho a su caso de uso, excepto que en lugar de otorgar acceso a un host diferente, desea otorgar acceso a múltiples usuarios en el mismo host.
Se vería algo como esto:
sshkeeper@bastion$ eval "$(ssh-agent -a /path/to/socket)"
sshkeeper@bastion$ echo $SSH_AUTH_SOCK
/path/to/socket
sshkeeper@bastion$ ssh-add
Enter passphrase for /home/sshkeeper/.ssh/id_rsa:
sshkeeper@bastion$ chmod 660 /path/to/socket
sshkeeper@bastion$ chgrp ssh-users /path/to/socket
La clave no necesariamente necesita una frase de contraseña; Incluí uno para ilustración.
En cualquier caso, ahora cualquier persona con permisos de lectura y escritura en el socket puede usar el ...
jander@bastion$ export SSH_AUTH_SOCK=/path/to/socket
jander@bastion$ ssh private_server
Error reading response length from authentication socket.
Permission denied (publickey).
Uy. Es un poco más complicado que eso, porque ssh-agent
es paranoico y comprueba dos veces el ID de usuario de quien se conecta al socket. Así que necesitamos una solución. Intentemos usar socat
como proxy:
sshkeeper@bastion$ eval "$(ssh-agent -a /home/sshkeeper/ssh_agent_socket)"
sshkeeper@bastion$ ssh-add
Enter passphrase for /home/sshkeeper/.ssh/id_rsa:
sshkeeper@bastion$ rm /path/to/socket
sshkeeper@bastion$ umask 117
sshkeeper@bastion$ socat UNIX-LISTEN:/path/to/socket,fork,group=ssh-users UNIX-CONNECT:/home/sshkeeper/ssh_agent_socket &
Ahora es el proceso socat
de propiedad de sshkeeper el que se conecta al agente, y no el cliente SSH de propiedad de jander, por lo que el agente no tiene ninguna queja:
jander@bastion$ export SSH_AUTH_SOCK=/path/to/socket
jander@bastion$ ssh private_server
jander@private_server$ █
Querrá tener cuidado con los permisos del sistema de archivos para acceder al socket, ya que eso es todo lo que queda para protegerlo. No le dé a nadie excepto a sshkeeper
acceso de escritura a lo largo de la ruta al socket. Tenga en cuenta también que algunos sistemas derivados de BSD ignoran los permisos en el propio archivo socket; prueba esto a fondo en tu sistema.
Finalmente, ten en cuenta que este no es un uso estándar del agente de SSH: de hecho, tuve que solucionar una característica de seguridad para que funcionara. Creo que en un sistema Linux con los permisos adecuados del sistema de archivos, puede ser al menos tan seguro o más seguro que la solución sudo
... pero no debería confiar en mi palabra. Asegúrese de entender exactamente lo que está pasando aquí antes de usar esto.
ACTUALIZACIÓN : he echado un vistazo a la Código fuente de ssh-agent de openssh para ver qué puede hacer con un socket de agente, y puedo ver un par de oportunidades para hacer travesuras leves. Es decir, sus usuarios pueden pedirle al agente que agregue o elimine claves.
Entonces, una persona podría decirle al agente que elimine la clave, bloqueando a todos los demás fuera de los servidores hasta que usted (o un script) vuelva a agregar la clave.
Una persona también podría agregar una clave, dando a todos los demás acceso a servidores adicionales. Sin embargo, esta persona también podría entregar la clave a otras personas directamente (sin usar el servidor), o usar su propio agente compartido, por lo que este punto es relativamente menor.