GNU/Linux >> Tutoriales Linux >  >> Linux

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 que usan VirtualBox y Vagrant. 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. Ansible usa protocolo SSH para 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 llamados first_key y segunda_clave usando el siguiente script para demostración.

Cree un archivo de texto llamado create_keypair.sh con 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 -i bandera.

$ 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-file o --private-key marcar y pasar el archivo de clave privada como argumento. En el siguiente ejemplo, puede 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 el ansible.cfg archivo de configuración que se aplicará a los comandos ad hoc y a todas las tareas del libro de jugadas.

$ vim ansible.cfg

Agregue la siguiente línea:

Private_key_file = /home/vagrant/.ssh/first_key

Reemplace /home/vagrant/.ssh/first_key con el tuyo.

También puede agregar "ansible_ssh_private_key" parámetro en su archivo de inventario que tendrá mayor prioridad sobre ansible.cfg expediente. A continuación se muestra cómo mi inventario ahora está configurado. Nodo gestionado1 utilizará "first_key" y gestionado2 utilizará "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 comprobar si se utilizan las teclas adecuadas según nuestra entrada.

$ ansible -vvv all -m ping

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 y ansible.cfg archivo 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 "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 --u o --user marca 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

Para usar la autenticación basada en contraseña, puede usar -k o --ask-pass bandera. 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

También puede almacenar la contraseña en un archivo y pasar el nombre del archivo como argumento a --connection-password-file o --conn-pass-file bandera. 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 ahora 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. Por ejemplo, la gestión de paquetes. Solo puede instalar, eliminar o actualizar paquetes como root usuario o con sudo privilegio.

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

Cuando desee ejecutar cualquier tarea con root privilegio, debe usar -b o --become bandera.

$ 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, sudo se utilizará como un método de escalada de privilegios. Puede cambiar el método configurando --become-method bandera. 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 un sudo contraseña para los nodos administrados dependiendo de cómo esté configurado el usuario. En mi caso he configurado el usuario vagrant para ejecutar sudo sin solicitar contraseñas.

Si su sudo el usuario requiere una contraseña para trabajar, entonces debe usar -K o --ask-become-pass indicador que solicitará sudo clave.

Como puede ver en el siguiente error, cuando intento ejecutar sin proporcionar un sudo contraseña para el usuario "karthick", me arroja un error que dice "Falta la contraseña de sudo" .

$ 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

La contraseña de Sudo se puede almacenar en un archivo y pasar como argumento al --become-password-file o --become-pass-file bandera. 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 "become" directiva en el libro de jugadas en el nivel de tarea o nivel de juego.

La siguiente imagen representa cómo el "convertirse" la directiva se usa en el nivel de juego .

La siguiente imagen representa cómo el "convertirse" la directiva se usa en el nivel de tarea .

Como puede ver en la salida, el ssh el servicio se reinicia bien en el gestionado1 nodo.

$ 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 configurar en ansible.cfg archivo 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 para ansible.cfg archivo desde el siguiente enlace.

  • Conviértete en directivo

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

Conclusión

En este artículo, hemos visto cómo funciona la autenticación basada en clave y 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 a continuación:

  • Introducción a los comandos ad hoc de Ansible

Linux
  1. ¿Cómo maneja Linux múltiples separadores de rutas consecutivas (/home////username///file)?

  2. Linux:¿Diferencia entre /dev/console, /dev/tty y /dev/tty0?

  3. unix:///var/run/supervisor.sock no hay tal archivo

  4. Linux:diferencia entre /dev/console, /dev/tty y /dev/tty0

  5. Cómo cambiar el valor predeterminado /tmp a /home/user/tmp

Bash =~ Regex y Https://regex101.com/?

¿Qué tan portátiles son /dev/stdin, /dev/stdout y /dev/stderr?

Debian – ¿Mover /var, /home a una partición separada?

Linux – ¿Fusionar /usr/bin y /usr/sbin en /bin (gnu/linux)?

“No se puede crear el directorio de caché /home//.composer/cache/repo/https—packagist.org/, o el directorio no se puede escribir. Procediendo sin caché”?

Comprender los archivos /proc/mounts, /etc/mtab y /proc/partitions