Mejores prácticas de seguridad

37

Voy a introducir Ansible en mi centro de datos y estoy buscando algunas prácticas recomendadas de seguridad sobre dónde ubicar la máquina de control y cómo administrar las claves SSH.

Pregunta 1: la máquina de control

Por supuesto, necesitamos una máquina de control. La máquina de control tiene claves SSH públicas guardadas en ella. Si un atacante tiene acceso a la máquina de control, potencialmente tiene acceso a todo el centro de datos (o a los servidores administrados por Ansible). Entonces, ¿es mejor tener una máquina de control dedicada en el centro de datos o una máquina de control remoto (como mi computadora portátil conectada remotamente al centro de datos)?

Si la mejor práctica es usar mi computadora portátil (que podría ser robada, por supuesto, pero podría tener mis claves públicas guardadas de forma segura en línea en la nube o fuera de línea en un dispositivo cifrado portátil), ¿qué pasa si necesito usar algunas interfaces web con ¿Ansible, como Ansible Tower, Semaphore, Rundeck o Foreman, que debe instalarse en una máquina centralizada en el centro de datos? ¿Cómo asegurarlo y evitar que se convierta en un "único punto de ataque"?

Pregunta 2: las claves SSH

Suponga que necesito usar Ansible para hacer algunas tareas que requieren ser ejecutadas por root (como instalar paquetes de software o algo así). Creo que la mejor práctica es no usar el usuario root en servidores controlados, sino agregar un usuario normal para Ansible con permisos sudo. Pero, si Ansible necesita hacer casi todas las tareas, debe tener acceso a todos los comandos a través de sudo. Entonces, ¿cuál es la mejor opción?

  • deje que Ansible use el usuario raíz (con su clave pública guardada en ~/.ssh/authorized_keys
  • crear un usuario sin privilegios dedicado para Ansible con acceso a sudo
  • Deje que el usuario de Ansible ejecute todos los comandos a través de sudo especificando una contraseña (que es única para cada administrador de sistemas que usa Ansible para controlar esos servidores)
  • Deje que el usuario Ansible ejecute todos los comandos a través de sudo sin especificar ninguna contraseña
  • alguna otra pista?
Estera
fuente
desea una subred de administración dedicada (o VLAN). su computadora de control ansible está en esa subred. Si necesita comunicarse con la computadora de control, conecte su VPN a esa subred. No dejes que Ansible sea root
Neil McGuigan el
1
El host de control Ansible estará en la LAN interna y no será accesible desde el exterior, pero creo que esto no es suficiente.
Mat

Respuestas:

15

El host del bastión (el centro de control ansible) pertenece a una subred separada. ¡No debería ser accesible directamente desde el exterior, no debería ser accesible directamente desde los servidores administrados!

Su computadora portátil es el dispositivo menos seguro de todos. Un estúpido correo, una estúpida vulnerabilidad flash, un estúpido invitado Wifi y se pone pwned.

Para los servidores, no permita el acceso de root a través de ssh. Muchas auditorías se burlan de esto.

Para ansible, deje que cada administrador use su propia cuenta personal en cada servidor de destino, y que sudo con contraseñas. De esta manera no se comparte contraseña entre dos personas. Puede verificar quién hizo qué en cada servidor. Depende de usted si las cuentas personales permiten iniciar sesión con contraseña, solo con la clave ssh o si requieren ambas.

Para aclarar ansible no es necesario utilizar un solo nombre de inicio de sesión de destino . Cada administrador puede y debe tener un nombre de inicio de sesión de destino personal.

Una nota al margen: intente nunca crear una cuenta llamada alguna palabra (como "ansible" o "admin" o "cluster" u "management" u "operator") si tiene una contraseña. El único buen nombre para la cuenta que tiene una contraseña es el nombre de un ser humano, como "jkowalski". Solo un ser humano puede ser responsable de las acciones realizadas a través de la cuenta y responsable de proteger de forma incorrecta su contraseña, "ansible" no puede.

kubanczyk
fuente
Gracias, me convenció de usar un host de bastión centralizado en una subred separada en el centro de datos. También soy consciente de que es mejor usar un usuario personal por cada administrador de sistema, pero ahora tengo otra pregunta (tal vez esto sería mejor en una pregunta separada de Serverfault): cómo centralizar usuarios y claves SSH en hosts Linux sin usar NIS, NFS acciones o algo así? Tenga en cuenta que ya tengo Active Directory para los servidores de Windows.
Mat
Ok, mejor pensando en mi pregunta, tengo dos respuestas posibles: usar el almacenamiento de claves LDAP o Userify (ver dos respuestas a continuación). Pero ... ¿realmente lo necesito? No, si uso mi propio usuario para implementar nuevos usuarios y claves a través de Ansible. :-)
Mat
@Mat, totalmente de acuerdo, como dije a continuación, realmente no necesita Userify ni ninguna herramienta similar hasta que su equipo crezca. (Sin embargo, lo hace mucho más agradable). LDAP es un poco difícil de instalar (investigue pam_ldap y nss_ldap), pero hemos incorporado herramientas para integrar en segundos con Ansible, Chef, Puppet, etc. Además, es gratis para <20 servidores.
Jamieson Becker
16

> Pregunta 1: la máquina de control

En Userify (divulgación completa: en realidad ofrecemos software para administrar claves ssh), nos ocupamos de esto todo el tiempo, ya que también tenemos el mayor almacén de claves SSH. En general, recomendamos la instalación local en lugar de usar la nube, ya que tiene un mayor control, reduce su área de superficie, realmente puede bloquearlo en redes confiables recién conocidas.

Lo importante para recordar es que, en un sistema correctamente construido como este, realmente no debería haber secretos significativos que puedan ser filtrados a un atacante. Si alguien conduce una carretilla elevadora a su centro de datos y se va con su servidor, no obtendrá mucho, excepto algunas contraseñas con muchos hash, probablemente algunos archivos muy encriptados y algunas claves públicas sin sus correspondientes claves privadas. En otras palabras, no tanto.

Como usted señala, los vectores de amenazas reales aquí son lo que sucede si un atacante obtiene el control de esa máquina y la usa para implementar sus propias cuentas de usuario y claves (públicas). Este es un riesgo para prácticamente todas las plataformas en la nube (ej .: Linode). Debería concentrarse más en evitar el acceso al plano de control, lo que significa minimizar la superficie de ataque (solo exponer algunos puertos y bloquear esos puertos tanto como sea posible) y preferiblemente usar un software que esté reforzado contra la escalada de privilegios y varios ataques ( Inyección SQL, XSS, CSRF, etc.) Habilite el acceso 2FA / MFA al plano de control y concéntrese en bloquear ese plano de control tanto como sea posible.

Entonces, ¿es mejor tener una máquina de control dedicada en el centro de datos o una máquina de control remoto (como mi computadora portátil conectada remotamente al centro de datos)?

Es definitivamente mejor tener una máquina de control dedicado en un centro de datos seguro, porque se puede aislar y bloqueo hacia abajo para evitar / minimizar el riesgo de robo o acceso no autorizado.

Si la mejor práctica es usar mi computadora portátil (que podría ser robada, por supuesto, pero podría tener mis claves públicas guardadas de forma segura en línea en la nube o sin conexión en un dispositivo cifrado portátil), ¿qué pasa si necesito usar algunas interfaces web con ¿Ansible, como Ansible Tower, Semaphore, Rundeck o Foreman que debe instalarse en una máquina centralizada en el centro de datos?

No necesita ejecutar NINGUNA interfaz web o plano de control secundario para administrar sus claves (incluso Userify) hasta que sea lo suficientemente grande como para comenzar a meterse en problemas de administración debido a un mayor número de usuarios y diferentes niveles de autorización entre servidores o necesita más mano para sus usuarios que pueden no tener conocimiento o acceso a Ansible para actualizar claves. Userify al principio no era mucho más que un montón de scripts de shell (¡hoy serían Ansible, probablemente!) Y no hay nada de malo en eso, hasta que comience a necesitar control de administración adicional y formas fáciles para que las personas administren / roten sus llaves propias (¡Por supuesto, eche un vistazo a Userify si llega a ese punto!)

¿Cómo asegurarlo y evitar que se convierta en un "único punto de ataque"?

Bueno, por supuesto, revise todos los recursos en la red para bloquear las cosas, pero lo más importante es comenzar con una base segura:

1. Diseñe su solución teniendo en cuenta la seguridad desde el principio. Elija la tecnología (es decir, la base de datos o los idiomas) que tradicionalmente han tenido menos problemas y luego codifique con seguridad desde el principio. Desinfecte todos los datos entrantes, incluso de usuarios confiables. La paranoia es una virtud.

2. Eventualmente, todo se rompe. Minimice el daño cuando eso ocurra: como ya señaló, intente minimizar el manejo de material secreto.

3. Mantenlo simple. No haga las últimas cosas exóticas a menos que esté seguro de que aumentará su seguridad de manera medible y demostrable. Por ejemplo, seleccionamos X25519 / NaCl (libsodium) sobre AES para nuestra capa de encriptación (encriptamos todo, en reposo y en movimiento), porque fue originalmente diseñado y escrito por alguien en quien confiamos (DJB et al) y fue revisado por world investigadores reconocidos como Schneier y el equipo de seguridad de Google. Use cosas que tienden a la simplicidad si son más nuevas, ya que la simplicidad hace que sea más difícil ocultar errores profundos.

4. Cumplir con los estándares de seguridad. Incluso si no cae en un régimen de seguridad como PCI o la Regla de Seguridad de HIPAA, lea esos estándares y descubra cómo cumplirlos o al menos controles compensatorios muy fuertes. Esto ayudará a garantizar que realmente cumpla con las 'mejores prácticas'.

5. Traiga pruebas de penetración externas / independientes y ejecute recompensas de errores para asegurarse de que está siguiendo esas mejores prácticas de forma continua. Todo se ve muy bien hasta que algunas personas inteligentes y altamente motivadas lo golpean ... una vez que haya terminado, tendrá mucha confianza en su solución.


Pregunta 2: las claves SSH ¿Cuál es la mejor opción? Deje que Ansible use el usuario raíz (con su clave pública guardada en ~/.ssh/authorized_keys/ deje que el usuario de Ansible ejecute todos los comandos a través de sudo especificando una contraseña (que es única para cada administrador de sistemas) que usa Ansible para controlar esos servidores)

Intente evitar usar contraseñas en los servidores, incluso para sudo. Se trata de secretos y, en última instancia, socavará su seguridad (realmente no puede variar esa contraseña de sudo entre máquinas muy fácilmente, tiene que almacenarla en algún lugar, la contraseña significa que realmente no puede hacer la automatización de servidor a servidor, que es exactamente de qué se trata. Además, si deja SSH en sus valores predeterminados, esas contraseñas pueden ser forzadas, lo que hace que las claves no tengan sentido. Además, evite el uso del usuario root para cualquier propósito, y especialmente el inicio de sesión remoto.

Cree un usuario sin privilegios dedicado para Ansible con acceso a sudo / permita que el usuario de Ansible ejecute todos los comandos a través de sudo sin especificar ninguna contraseña

Exactamente. Un usuario sin privilegios que puede auditar de nuevo a ansible, con roles de sudo. Idealmente, cree un usuario estándar dedicado a las comunicaciones de servidor a servidor / ansible con acceso a sudo (sin contraseña).

... NB, si estuviera utilizando Userify, la forma en que sugeriría hacerlo sería crear un usuario Userify para ansible (también puede dividir esto por proyecto o incluso grupo de servidores si tiene varias máquinas de control ansible), generar una clave SSH en el servidor de control y proporcione su clave pública en su página de perfil de Userify. (Este cuadro de texto se convierte esencialmente /home/ansible/.ssh/authorized_keys). Debe mantener la cuenta del sistema ansible separada de otras cuentas del sistema de servidor a servidor, como una cuenta de respaldo remota, administración secreta, etc. Luego invite a sus humanos y ellos también podrán crear y administrar sus propias claves y todo permanecerá separado. Pero, al igual que al bloquear un servidor de control Ansible, intente bloquear su servidor Userify (o cualquier solución que implemente) de la misma manera.

alguna otra pista?

Creo que definitivamente está haciendo esto de la manera correcta y haciendo las preguntas correctas. Si desea hablar sobre este tipo de cosas, envíeme un correo electrónico (primer punto, apellido en userify) y estaré encantado de tener una conversación, sin importar la dirección que elija. ¡Buena suerte!

Jamieson Becker
fuente
5

Respuesta 1: la máquina de control

Un poco de ambos, puede usar su computadora portátil para conectarse a servidores a través de un host de bastión. algo como:

Host private1
  IdentityFile ~/.ssh/rsa_private_key
  ProxyCommand ssh user@bastion -W %h:%p

Host bastion
  IdentityFile ~/.ssh/bastion_rsa_key

Más información sobre los hosts bastión

Donde tiene una clave para el servidor bastion, y luego una clave separada para el host detrás de él. (personalmente usaría gpg-agent / ssh-agent)

Respuesta 2: autenticación

No estoy seguro de cómo difieren las mejores prácticas específicas "ansible" de cualquier otra práctica de conexión ssh. Pero no, desea ejecutar ansible como usted mismo, no como una cuenta de servicio y no como una cuenta raíz.

Una combinación de las siguientes autenticaciones:

Otros pensamientos:

  • Siempre almacene secretos / información privada en ansible-vault.
  • Ansible no requiere SUDO / Root para ejecutarse, a menos que lo que esté haciendo requiera sudo / root.
  • Ansible puede elevar los permisos de muchas maneras diferentes

Por último, no mencionaste nada sobre Windows. Así que solo puedo suponer que no estás usando esto. Sin embargo, en este caso, usaría la opción de delegado para que su computadora portátil use el host del bastión (delegate_to bastion.hostname.fqdn:) y kerberos / winrm https con tickets kerberos.

En caso de que se lo haya perdido, la mejor práctica para la informática, nunca haga nada como root, siempre use cuentas con nombre

Jacob Evans
fuente