cryptography pycrypto ansible

cryptography - ¿Cómo creo un usuario y establezco una contraseña usando ansible?



pycrypto (8)

El ejemplo de python que se muestra en la documentación depende de la versión de crypt que se ejecuta en el sistema operativo que está utilizando.

Generé la cripta en OS X y el servidor al que estaba apuntando es ubuntu.

Debido a las diferencias en las que el sistema operativo ofrece la implementación de crypt, el resultado es diferente e incompatible.

Use esto en su lugar:

http://pythonhosted.org/passlib/

Passlib es una biblioteca de hashing de contraseñas para Python 2 y 3, que proporciona implementaciones multiplataforma de más de 30 algoritmos de hashing de contraseñas, así como un marco para administrar los hashes de contraseñas existentes. Está diseñado para ser útil para una amplia gama de tareas, desde verificar un hash encontrado en / etc / shadow, hasta proporcionar un hashing de contraseña completo para aplicaciones multiusuario.

>>> # import the hash algorithm >>> from passlib.hash import sha512_crypt >>> # generate new salt, and hash a password >>> hash = sha512_crypt.encrypt("password") >>> hash

''$ 6 $ redondea = 656000 $ BthPsosdEpqOM7Qd $ l / ln9nyEfxM67ea8Bvb79JoW50pGjf6iM87taIvfSmpjasE4 / wBG1.60pFS6W992T7Q1q2wikMbxYUvMHD1t1''

La documentation nos remite al example github, pero esto es un poco escaso y misterioso.

Dice esto:

# created with: # crypt.crypt(''This is my Password'', ''$1$SomeSalt'') password: $1$SomeSalt$UqddPX3r4kH3UL5jq5/ZI.

pero crypt.crypt no emite lo que muestra el ejemplo. También utiliza MD5.

Intenté esto:

# python import crypt crypt.crypt(''This is my Password'', ''$6$somereallyniceandbigrandomsalt$'') >> ''$69LxCegsnIwI''

pero el campo de contraseña del usuario debería obtener algo como esto:

password: $6$somereallyniceandbigrandomsalt$UqddPX3r4kH3UL5jq5/ZI.

que incluye tres delimitadores $ que separan los 6 (lo que significa que es un hash SHA-512), el salt y la contraseña encriptada.

Tenga en cuenta que los crypt.crypt Python no mencionan nada sobre el formato $ N.

Preguntas:

  1. ¿ crypt.crypt supone que la sal, como se suministra a crypt.crypt , termina con un $ final o está en formato $ N $ SALT ?

  2. Los documentos de Python se refieren a DES, pero ¿cómo se llama SHA-512 o MD5 y dónde está la documentación para esto?

  3. ¿Se supone que debo tomar la salida de crypt.crypt y cortar los primeros $ 6 y hacer $ N $ SALT $ CRYPTED ? ¿Es esto lo que ansible necesita?


Esto ha sido actualizado en los documentos de Ansible . Hay dos formas preferidas:

¿Cómo genero contraseñas encriptadas para el módulo de usuario?

La utilidad mkpasswd que está disponible en la mayoría de los sistemas Linux es una excelente opción:

mkpasswd --method=SHA-512 Si esta utilidad no está instalada en su sistema (por ejemplo, está usando OS X), aún puede generar estas contraseñas fácilmente usando Python. Primero, asegúrese de que la biblioteca de hashing de contraseña Passlib esté instalada.

pip install passlib

Una vez que la biblioteca está lista, los valores de contraseña de SHA512 se pueden generar de la siguiente manera:

python -c "from passlib.hash import sha512_crypt; import getpass; print sha512_crypt.encrypt(getpass.getpass())"


Esto me funcionó (usando Python 2.7.4):

python >>> import crypt >>> crypt.crypt(''thisismypassword'', ''$6$Som3S@lt$'') ''$6$Som3S@lt$XGoe9ONI00NaTkYn46CLDr8TSkvkovahinFqy95vrSe5Hzx2999C9mgF76ODFRnXMJHUCWFHLdkYd3c7AB9WV.''

Tengo un vars.yml que se ve así:

--- password: $6$Som3S@lt$XGoe9ONI00NaTkYn46CLDr8TSkvkovahinFqy95vrSe5Hzx2999C9mgF76ODFRnXMJHUCWFHLdkYd3c7AB9WV.

y un playbook.yml como este:

--- - hosts: vagrant vars_files: - vars.yml user: vagrant tasks: - name: create artefactual user user: name=artefactual state=present password={{password}} shell=/bin/bash

Ejecuto mi libro de juegos usando vagrant, vagrant up , y luego desde otra consola puedo enviar un ssh al vm recién creado usando el usuario artificial creado por ansible, con la contraseña thisismypassword .

Acabo de copiar la salida de crypt.crypt en la variable ansible llamada contraseña y la utilicé. La salida de cripta que muestra en su pregunta parece demasiado breve, no estoy seguro de por qué lo obtuvo, ¿quizás una versión diferente de python?


Esto necesita pwgen instalado en el host de destino:

- name: generate linux user password local_action: shell /usr/bin/pwgen 16 1 register: generated_linux_user_password

Use hosts: localhost , set_fact y hostvars, si necesita que la ''variable'' esté disponible globalmente (los hechos se lean solo después de la creación):

{{hostvars[''localhost'']["new_fact"]}}


He estado usando el siguiente comando de shell para establecer la contraseña.

- name: "Set user password: someuser" command: ''echo "somepassword"| passwd --stdin "someuser"'' sudo: yes


Puede usar los filtros jinja2 que tienen la capacidad de manejar la generación de contraseñas encriptadas. Aquí hay un ejemplo de trabajo para crear el usuario de Linux con la contraseña proporcionada:

- name: Creating Linux User user: name: "{{ myuser }}" password: "{{ mypassword | password_hash(''sha512'') }}"

Espero que esto te ayude a ti y a los demás.


Tomé la respuesta de @ felix y la convertí en un guión que podría incluir en un proyecto docker en el que estoy trabajando. Sé que muchos desarrolladores utilizan macOS / OSX y que no hay mkpasswd en esa plataforma, así que les estoy guardando el Google.

He añadido las siguientes opciones:

  • PROCESS_TIME (booleano)
    • Habilita la segunda línea de salida con número de rondas y tiempo de CPU
  • RONDAS (entero)
    • Anula el valor de default_rounds que está sintonizado para tomar ~ 300 ms en un sistema "promedio". Desea un mínimo de 100 ms, pero debe ser lo mejor que pueda pagar.

#!/usr/bin/env python3 # Because OSX doesn''t have mkpasswd... # Based on https://.com/a/17992126/117471 # python3 -c "from passlib.hash import sha512_crypt; print(sha512_crypt.encrypt(input()))" <<< bruno # NOQA # Usage: # # $ ./mkpasswd.py # Password: # $6$rounds=656000$pfFmQISGcjWHOCxW$rBptiSK.tqSPnUiq6KiSHzz6LvvW/x1SjkkWFwxWB9Dt75NLNBs0N3OyGV4K5ejjBs/u.o3jtigvUKbmmwVQP. # # $ PROCESS_TIME=1 ./mkpasswd.py # Password: # $6$rounds=656000$e0OGrad82DBrUo9T$ldqtOdN54gmXI6nb0D.Y5mm5ih.LIQm/Ep/bkNL76.3hE65FqXA9wyZ.M5YOrv6dSvwhPAktXGJ6LJT0Fgd4x. # 656000 rounds in 1.008705 seconds of cpu time # # $ ROUNDS=1280000 PROCESS_TIME=1 ./mkpasswd.py <<< bruno # $6$rounds=1280000$QO5FSyw5rQpiY6PI$0zRMJ4RzCbH61XxIdpsUm/79.VZ13Mm9TBN9GvJwt1LI1U5FVzakrLya5VJsXlTou3p5ZeWmo29bIUjubRuc31 # 1280000 rounds in 1.9206560000000001 seconds of cpu time import os import sys import time from getpass import getpass from passlib.hash import sha512_crypt rounds = os.environ.get(''ROUNDS'') if not rounds: rounds = sha512_crypt.default_rounds passwd = input() if not sys.stdin.isatty() else getpass() proc = sha512_crypt.using(rounds=rounds) start = time.process_time() out = proc.encrypt(passwd) end = time.process_time() print(out) if os.environ.get(''PROCESS_TIME''): print(''{} rounds in {} seconds of cpu time''.format(rounds, end-start))


prueba de esta manera

vars_prompt: - name: "user_password" prompt: "Enter a password for the user" private: yes encrypt: "md5_crypt" #need to have python-passlib installed in local machine before we can use it confirm: yes salt_size: 7 - name: "add new user" user: name="{{user_name}}" comment="{{description_user}}" password="{{user_password}}" home="{{home_dir}}" shell="/bin/bash"