可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
The documentation refers us to the github example, but this is a bit sparse and mysterious.
It says this:
# created with:
# crypt.crypt('This is my Password', '$1$SomeSalt')
password: $1$SomeSalt$UqddPX3r4kH3UL5jq5/ZI.
but crypt.crypt
doesn't emit what the example shows. It also uses MD5.
I tried this:
# python
import crypt
crypt.crypt('This is my Password', '$6$somereallyniceandbigrandomsalt$')
>> '$69LxCegsnIwI'
but the password field of user should get something like this:
password: $6$somereallyniceandbigrandomsalt$UqddPX3r4kH3UL5jq5/ZI.
which includes three $ delimiters separating the 6
(which signifies that its a SHA-512 hash), the salt, and the crypted password.
Note that the python crypt docs don't mention anything about the $N format.
Questions:
Is the salt, as supplied to crypt.crypt
, supposed to end with a trailing $ or is it in $N$SALT format?
Python docs refer to DES, but how is SHA-512 or MD5 being called and where is the documention for this?
Am I really supposed to take the output of crypt.crypt
and cut off the first $6 and make $N$SALT$CRYPTED? Is this what ansible needs?
回答1:
The python example shown in the documentation depends on what version of crypt is running on the OS you are using.
I generated the crypt on OS X and the server I was targetting is ubuntu.
Due to differences in which implementation of crypt is offered by the OS, the result is different and incompatible.
Use this instead:
http://pythonhosted.org/passlib/
Passlib is a password hashing library for Python 2 & 3, which provides
cross-platform implementations of over 30 password hashing algorithms,
as well as a framework for managing existing password hashes. It’s
designed to be useful for a wide range of tasks, from verifying a hash
found in /etc/shadow, to providing full-strength password hashing for
multi-user application.
>>> # import the hash algorithm
>>> from passlib.hash import sha512_crypt
>>> # generate new salt, and hash a password
>>> hash = sha512_crypt.encrypt("password")
>>> hash
'$6$rounds=656000$BthPsosdEpqOM7Qd$l/ln9nyEfxM67ea8Bvb79JoW50pGjf6iM87taIvfSmpjasE4/wBG1.60pFS6W992T7Q1q2wikMbxYUvMHD1tT1'
回答2:
This worked for me (using python 2.7.4):
python
>>> import crypt
>>> crypt.crypt('thisismypassword', '$6$Som3S@lt$')
'$6$Som3S@lt$XGoe9ONI00NaTkYn46CLDr8TSkvkovahinFqy95vrSe5Hzx2999C9mgF76ODFRnXMJHUCWFHLdkYd3c7AB9WV.'
I have a vars.yml that looks like this:
---
password: $6$Som3S@lt$XGoe9ONI00NaTkYn46CLDr8TSkvkovahinFqy95vrSe5Hzx2999C9mgF76ODFRnXMJHUCWFHLdkYd3c7AB9WV.
and a playbook.yml like this:
---
- hosts: vagrant
vars_files:
- vars.yml
user: vagrant
tasks:
- name: create artefactual user
user: name=artefactual state=present password={{password}} shell=/bin/bash
I run my playbook using vagrant, vagrant up
, and then from another console I can ssh to the newly created vm using the artefactual user created by ansible, with the password thisismypassword
.
I just copied the output of crypt.crypt into the ansible variable called password and used that. The output of crypt that you show in your question looks too short, I am not sure why you got that, perhaps a different version of python?
回答3:
This has been updated in the Ansible docs. There are two preferred ways:
How do I generate crypted passwords for the user module?
The mkpasswd utility that is available on most Linux systems is a great option:
mkpasswd --method=SHA-512
If this utility is not installed on your
system (e.g. you are using OS X) then you can still easily generate
these passwords using Python. First, ensure that the Passlib password
hashing library is installed.
pip install passlib
Once the library is ready, SHA512 password values
can then be generated as follows:
python -c "from passlib.hash import sha512_crypt; import getpass; print sha512_crypt.encrypt(getpass.getpass())"
回答4:
I took @felix's answer and made it into a script that I could include in a docker project that I am working on. I know that a lot of developers use macOS/OSX and that there is no mkpasswd
on that platform, so I'm saving them the Googling.
I have added the following options:
- PROCESS_TIME (boolean)
- Enables 2nd line of output with number of rounds and CPU time
- ROUNDS (integer)
- Overrides the default_rounds value which is tuned to take ~300ms on an "average" system. You want a minimum of 100ms, but should be as great as you can afford.
#!/usr/bin/env python3
# Because OSX doesn't have mkpasswd...
# Based on https://stackoverflow.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))
回答5:
I have been using the following shell command to set the password.
- name: "Set user password: someuser"
command: 'echo "somepassword"| passwd --stdin "someuser"'
sudo: yes
回答6:
try like this
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"
回答7:
You can use the jinja2 filters that have the capability to handle the generation of encrypted passwords. Here is a working example to create the linux user with the provided password:
- name: Creating Linux User
user:
name: "{{ myuser }}"
password: "{{ mypassword | password_hash('sha512') }}"
Hope this will help you and others.
回答8:
This needs pwgen
installed on target host:
- name: generate linux user password
local_action: shell /usr/bin/pwgen 16 1
register: generated_linux_user_password
Use hosts: localhost
, set_fact
and hostvars, if you need the 'variable' be globally available (facts are readonly after creation):
{{hostvars['localhost']["new_fact"]}}