Autenticación SSH de Ansible y escalada de privilegios

En este artículo, nos vamos a centrar en dos conceptos importantes de Ansible. El primer concepto será cómo funciona la autenticación basada en claves y contraseñas SSH en Ansible. El segundo concepto es cómo elevar el privilegio cuando se trabaja con libros de jugadas y comandos ad hoc.

Tengo una configuración de laboratorio de tres nodos que ejecuta máquinas Ubuntu 20.04 LTS usando VirtualBox y vagabundo. Hay un artículo detallado sobre la configuración del laboratorio que puede leer en el siguiente enlace.

  • Configuración automatizada de Ansible Lab con Vagrant y Virtualbox en Linux

Autenticación basada en claves en Ansible

Lo primero que debe comprender al aprender ansible es cómo se produce la comunicación entre el controlador y los nodos administrados. Usos de Ansibleprotocolo SSHpara conectarse a los nodos administrados y ejecutar la tarea.

Cada vez que ejecuta un libro de jugadas o comandos ad hoc, debe proporcionar la contraseña de SSH para que ansible se autentique en los nodos administrados a través de SSH.

Para eliminar esto, se recomienda crear un par de claves SSH y compartir la clave pública con todos los nodos para que ansible pueda comunicarse usando el par de claves.

He creado dos pares de claves llamadosprimera_claveysegunda_claveutilizando el siguiente script para la demostración.

Crea un archivo de texto llamadocreate_keypair.shcon los siguientes contenidos.

#!/usr/bin/env bash

# THIS SCRIPT WILL CREATE SSH KEY PAIR AND DISTRIBUTE ACROSS ALL NODES

read -p "Enter the name for the key : " KEY_NAME
ssh-keygen -b 2048 -t rsa -f /home/vagrant/.ssh/${KEY_NAME} -q -N ""

# LOOPING THROUGH AND DISTRIBUTING THE KEY

for val in controller managed1 managed2; do
    echo "-------------------- COPYING KEY TO ${val^^} NODE ------------------------------"
    sshpass -p 'vagrant' ssh-copy-id -f -i /home/vagrant/.ssh/${KEY_NAME}.pub -o "StrictHostKeyChecking=no" [email protected]$val
done

Otorgue permiso de ejecución al script y ejecútelo.

$ chmod +x path/to/create_keypair.sh
$ ./create_keypair.sh

He creado este script para la configuración de mi laboratorio. Puede editar la sección de bucle for y agregar sus nombres de nodos administrados en consecuencia.

$ tree .ssh/
.ssh/
??? authorized_keys
??? first_key
??? first_key.pub
??? known_hosts
??? second_key
??? second_key.pub

Cuando tiene claves creadas con nombres diferentes al nombre predeterminado (id_rsa), ssh intentará encontrar los nombres de clave predeterminados y, si no los encuentra, solicitará una autenticación basada en contraseña.

debug1: SSH2_MSG_SERVICE_ACCEPT received
debug1: Authentications that can continue: publickey,password
debug1: Next authentication method: publickey
debug1: Trying private key: /home/vagrant/.ssh/id_rsa
debug1: Trying private key: /home/vagrant/.ssh/id_dsa
debug1: Trying private key: /home/vagrant/.ssh/id_ecdsa
debug1: Trying private key: /home/vagrant/.ssh/id_ecdsa_sk
debug1: Trying private key: /home/vagrant/.ssh/id_ed25519
debug1: Trying private key: /home/vagrant/.ssh/id_ed25519_sk
debug1: Trying private key: /home/vagrant/.ssh/id_xmss
debug1: Next authentication method: password
[email protected]'s password:

En este caso, debe mencionar el archivo de clave privada explícitamente usando el-ibandera.

$ ssh -v -i /home/vagrant/.ssh/first_key [email protected]

Cuando ejecuta un comando ad hoc o un libro de jugadas, puede usar el--key-fileoh--private-keymarcar y pasar el archivo de clave privada como argumento. en la parte inferior examplepuede ver que he usado ambas claves (first_key y second_key) para comunicarme con éxito con los nodos administrados.

# USING --key-file FLAG

$ ansible managed1 -m ping --key-file /home/vagrant/.ssh/second_key

managed1 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python3"
    },
    "changed": false,
    "ping": "pong"
}
# USING --private-key FLAG

$ ansible managed1 -m ping --private-key /home/vagrant/.ssh/first_key

managed1 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python3"
    },
    "changed": false,
    "ping": "pong"
}

También puede agregar el parámetro “private_key_file” en elansible.cfgarchivo de configuración que se aplicará a los comandos adhoc y todas las tareas del libro de jugadas.

$ vim ansible.cfg

Agregue la siguiente línea:

Private_key_file = /home/vagrant/.ssh/first_key

Reemplazar/home/vagrant/.ssh/first_keycontigo mismo.

Archivo de clave privada

También puedes agregar“ansible_ssh_clave_privada”parámetro en su archivo de inventario que tendrá mayor prioridad sobreansible.cfgexpediente. A continuación se muestra cómo mi inventario ahora está configurado. Nodogestionado1utilizará“primera_clave”ygestionado2utilizará“segunda_clave”.

[ubuntu1]
managed1 ansible_ssh_private_key_file=/home/vagrant/.ssh/first_key

[ubuntu2]
managed2 ansible_ssh_private_key_file=/home/vagrant/.ssh/second_key

Ahora, si ejecuta el comando adhoc o el libro de jugadas nuevamente, puede ver que ambas claves se autenticarán con éxito. Puede aumentar la verbosidad para verificar si se usan las teclas apropiadas según nuestra entrada.

$ ansible -vvv all -m ping
Diferentes pares de claves

Ahora debería tener una buena comprensión de cómo funciona la autenticación basada en claves en ansible. Es importante comprender la precedencia al agregar el parámetro en diferentes archivos. La opción de línea de comandos tiene mayor prioridad seguida por el archivo de inventario yansible.cfgarchivo de configuración.

Autenticación basada en contraseña SSH en Ansible

Cuando ejecuta cualquier tarea, ansible usará el usuario actual en el nodo del controlador para comunicarse con los nodos administrados a través de SSH. Puede usar el módulo de shell y ejecutar el “whoami” comando para verificar el nombre de usuario en los nodos administrados. En mi caso, el nombre de usuario es"vagabundo". El usuario vagabundo se está autenticando usando claves que configuré en la sección anterior.

$ whoami
vagrant
$ ansible all -m shell -a "whoami"
managed2 | CHANGED | rc=0 >>
vagrant
managed1 | CHANGED | rc=0 >>
vagrant

Si desea conectarse a los nodos administrados como un usuario diferente, puede usar--uoh--usermarca y pasa el nombre de usuario como argumento. Si ve la imagen a continuación, trato de usar el usuario “karthick”, que no tiene una configuración de clave SSH y no se distribuyen claves a los nodos administrados, por lo que la conectividad falla.

$ ansible all -m shell -a "whoami" -u karthick
$ ansible all -m shell -a "whoami" --user karthick
Error de conectividadError de conectividad

Para usar la autenticación basada en contraseña, puede usar el-koh--ask-passbandera. Le pedirá que ingrese la contraseña SSH para el usuario (karthick). Asegúrese de que la contraseña sea la misma en todos los nodos del usuario.

$ ansible all -m shell -a "whoami" -u karthick -k
$ ansible all -m shell -a "whoami" -u karthick --ask-pass
Solicitud de contraseña SSHSolicitud de contraseña SSH

También puede almacenar la contraseña en un archivo y pasar el nombre del archivo como argumento para--connection-password-fileoh--conn-pass-filebandera. Esta no es una forma recomendada ya que está almacenando la contraseña en un archivo de texto sin formato. Puede usar la bóveda de ansible para cifrar el archivo de contraseña, pero este es un tema aparte para discutir.

$ ansible all -m shell -a "whoami" -u karthick --connection-password-file pass.txt
$ ansible all -m shell -a "whoami" -u karthick --conn-pass-file pass.txt

También puede pasar el nombre de usuario y la contraseña como parámetros en el archivo de inventario. Nuevamente, esta no es la mejor manera de almacenar la contraseña. A continuación se muestra cómo está configurado mi archivo de inventario.

[ubuntu1]
managed1 ansible_ssh_private_key_file=/home/vagrant/.ssh/first_key ansible_user=vagrant

[ubuntu2]
managed2 ansible_user=karthick ansible_ssh_pass=password
$ ansible all -m shell -a "whoami" -u karthick

managed1 | CHANGED | rc=0 >>
vagrant
managed2 | CHANGED | rc=0 >>
karthick

Aviso:Puede que esté ejecutando los ejemplos usando comandos adhoc, pero las mismas banderas también se aplican al libro de jugadas.

Escalada de privilegios en Ansible

Hay momentos en que su tarea requiere un privilegio elevado (raíz) para ejecutarse correctamente. Para example, gestión de paquetes. Solo puede instalar, eliminar o actualizar paquetes comorootusuario o estafasudoprivilegio.

Cuando ejecuta el indicador de ayuda junto con ansible o ansible-playbook, encontrará una sección de escalada de privilegios como se muestra en la imagen.

$ ansible --help
$ ansible-playbook --help
Opciones de escalada de privilegiosOpciones de escalada de privilegios

Cuando desee ejecutar cualquier tarea conrootprivilegio, debe usar-boh--becomebandera.

$ ansible ubuntu1 -m service -a "name=sshd state=restarted" -b

managed1 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python3"
    },
    "changed": true,
    "name": "sshd",
    "state": "started",

Por defecto,sudose utilizará como un método de escalada de privilegios. Puede cambiar el método configurando el--become-methodbandera. Puede obtener la lista de métodos admitidos ejecutando el siguiente comando.

$ ansible-doc -t become -l

ansible.netcommon.enable     Switch to elevated permissions on a network device                                                             
community.general.doas       Do As user                                                                                                     
community.general.dzdo       Centrify's Direct Authorize                                                                                    
community.general.ksu        Kerberos substitute user                                                                                       
community.general.machinectl Systemd's machinectl privilege escalation                                                                      
community.general.pbrun      PowerBroker run                                                                                                
community.general.pfexec     profile based execution                                                                                        
community.general.pmrun      Privilege Manager run                                                                                          
community.general.sesu       CA Privileged Access Manager                                                                                   
community.general.sudosu     Run tasks using sudo su -                                                                                  
runas                        Run As user                                                                                                   
su                           Substitute User                                                                                               
sudo                         Substitute User DO 

Puede o no dar unasudocontraseña para los nodos administrados dependiendo de cómo esté configurado el usuario. En mi caso, he configurado el usuariovagabundocorrersudosin solicitar contraseñas.

Y túsudousuario requiere una contraseña para trabajar, entonces debe usar el-Koh--ask-become-passbandera que solicitará lasudoclave.

Como puede ver en el siguiente error, cuando intento ejecutar sin proporcionar unsudocontraseña para el usuario “karthick”, me arroja un error diciendo“Perdido sudo clave”.

$ ansible ubuntu1 -m service -a "name=sshd state=restarted" -i inventory -u karthick -k -b

SSH password:
managed1 | FAILED! => {
    "msg": "Missing sudo password"
}
$ ansible ubuntu1 -m service -a "name=sshd state=restarted" -i inventory -u karthick -k -b -K
Use el indicador -K para la solicitud de contraseña de SudoUse el indicador -K para la solicitud de contraseña de Sudo

La contraseña de Sudo se puede almacenar en un archivo y pasar como argumento al--become-password-fileoh--become-pass-filebandera. Se puede usar Ansible Vault para cifrar este archivo, pero no es una práctica recomendada.

$ ansible ubuntu1 -m service -a "name=sshd state=restarted" -i inventory -u karthick -k -b --become-password-file pass.txt

$ ansible ubuntu1 -m service -a "name=sshd state=restarted" -i inventory -u karthick -k -b --become-pass-file pass.txt

También puede incluir el“volverse”directiva en el libro de jugadas en el nivel de tarea o nivel de juego.

La siguiente imagen representa cómo el“volverse”directiva se utiliza en elnivel de juego.

Él La directiva “convertirse” en el nivel de juego

La siguiente imagen representa cómo el“volverse”directiva se utiliza en elnivel de tarea.

La directiva de convertirse en el nivel de tareaLa directiva de convertirse en el nivel de tarea

Como puede ver en la salida, elsshel servicio se reinicia bien en elgestionado1nodo.

$ ansible-playbook restart_service.yml

PLAY [Restart SSHD service] ***************************************************************************

TASK [Restart SSHD in managed1.anslab.com] ************************************************************
changed: [managed1]

PLAY RECAP ********************************************************************************************
managed1 : ok=1 changed=1    unreachable=0     failed=0 skipped=0    rescued=0 ignored=0   

La directiva “become” también se puede establecer enansible.cfgarchivo de configuración y el archivo de inventario. Pero se recomienda establecer la directiva en el libro de jugadas. Puede obtener los diferentes parámetros paraansible.cfgarchivo desde el siguiente enlace.

Si desea ejecutar la tarea como un usuario diferente después de conectarse a los nodos administrados, debe usar el--become-userbandera. De forma predeterminada, está configurado pararootusuario.

Conclusión

En este artículo, hemos visto cómo funciona la autenticación basada en claves y con contraseña en Ansible y las diferentes banderas que se admiten para la autenticación. También hemos visto cómo funciona la escalada de privilegios en Ansible.

Para profundizar, debe tener una comprensión justa de cómo funcionan los diferentes métodos de escalada de privilegios y, de acuerdo con sus necesidades, configurar el entorno sin comprometer la seguridad.

Leer siguiente:

  • Introducción a los comandos ad hoc de Ansible

Artículos Relacionados