bash 使用 Ansible 创建新用户和密码
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/19292899/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Creating a new user and password with Ansible
提问by raphael_turtle
I have an ansible task which creates a new user on ubuntu 12.04;
我有一个 ansible 任务,它在 ubuntu 12.04 上创建一个新用户;
- name: Add deployment user
action: user name=deployer password=mypassword
it completes as expected but when I login as that user and try to sudo with the password I set it always says it's incorrect. What am I doing wrong?
它按预期完成,但是当我以该用户身份登录并尝试使用我设置的密码进行 sudo 时,它总是说它不正确。我究竟做错了什么?
采纳答案by Mxx
If you read Ansible's manual for user
module, it'll direct you to the Ansible-examples github repofor details how to use password
parameter.
如果你阅读了 Ansible 的user
module手册,它会引导你到 Ansible-examples github repo了解如何使用password
parameter 的详细信息。
There you'll see that your password must be hashed.
在那里你会看到你的密码必须经过哈希处理。
- hosts: all
user: root
vars:
# created with:
# python -c 'import crypt; print crypt.crypt("This is my Password", "$SomeSalt$")'
password: $SomeSalt$UqddPX3r4kH3UL5jq5/ZI.
tasks:
- user: name=tset password={{password}}
If your playbook or ansible command line has your password as-is in plain text, this means your password hash recorded in your shadowfile is wrong. That means when you try to authenticate with your password its hash will never match.
如果您的剧本或 ansible 命令行以纯文本形式提供密码,这意味着您的影子文件中记录的密码哈希是错误的。这意味着当您尝试使用密码进行身份验证时,其哈希值永远不会匹配。
Additionally, see Ansible FAQregarding some nuances of password parameter and how to correctly use it.
此外,请参阅 Ansible常见问题解答,了解密码参数的一些细微差别以及如何正确使用它。
回答by thinkingmonster
I may be too late to reply this but recently I figured out that jinja2 filters have the capability to handle the generation of encrypted passwords. In my main.yml
I'm generating the encrypted password as:
我可能来不及回复这个问题,但最近我发现 jinja2 过滤器有能力处理加密密码的生成。在我的main.yml
生成加密密码为:
- name: Creating user "{{ uusername }}" with admin access
user:
name: {{ uusername }}
password: {{ upassword | password_hash('sha512') }}
groups: admin append=yes
when: assigned_role == "yes"
- name: Creating users "{{ uusername }}" without admin access
user:
name: {{ uusername }}
password: {{ upassword | password_hash('sha512') }}
when: assigned_role == "no"
- name: Expiring password for user "{{ uusername }}"
shell: chage -d 0 "{{ uusername }}"
"uusername " and "upassword " are passed as --extra-vars
to the playbook and notice I have used jinja2 filter here to encrypt the passed password.
“uusername”和“upassword”作为--extra-vars
剧本传递,请注意我在这里使用了jinja2过滤器来加密传递的密码。
I have added below tutorial related to this to my blog
我已将以下与此相关的教程添加到我的博客中
回答by madhead
I want to propose yet another solution:
我想提出另一个解决方案:
- name: Create madhead user
user:
name: madhead
password: "{{ 'password' | password_hash('sha512') }}"
shell: /bin/zsh
update_password: on_create
register: madhead
- name: Force madhead to change password
shell: chage -d 0 madhead
when: madhead.changed
Why it is better? Like already has been noted here, Ansible plays should be idempotent. You should think of them not as a sequence of actions in imperative style, but like a desired state, declarative style. As a result you should be able to run it multiple times and get the same result, the same server state.
为什么更好?就像这里已经指出的那样,Ansible play 应该是幂等的。您不应将它们视为命令式风格的一系列操作,而应将它们视为一种期望状态、声明式风格。因此,您应该能够多次运行它并获得相同的结果和相同的服务器状态。
This all sounds great, but there are some nuances. One of them is managing users. "Desired state" means that every time you run a play that creates a user he will be updated to match exactly that state. By "updated" I mean that his password will be changed too. But most probably it is not what you need. Usually, you need to create user, set and expire his password only once, further play runs shouldn't update his password.
这一切听起来都很棒,但也有一些细微差别。其中之一是管理用户。“期望状态”意味着每次您运行创建用户的游戏时,他都会更新以完全匹配该状态。“更新”是指他的密码也将被更改。但很可能它不是你需要的。通常,您只需要创建用户,设置和过期他的密码一次,进一步的游戏运行不应该更新他的密码。
Fortunately, Ansible has update_password
attribute in user
modulethat solves this issue. Mixing this with registered variablesyou can also expire his password only when the user is actually updated.
幸运的是,Ansibleupdate_password
在user
模块中有解决这个问题的属性。将此与注册变量混合使用,您也可以仅在用户实际更新时使他的密码过期。
Note that if you change user's shell manually (suppose, you don't like the shell that evil admin forced in his play) the user will be updated, thus his password will be expired.
请注意,如果您手动更改用户的外壳(假设您不喜欢邪恶管理员在他的游戏中强加的外壳),用户将被更新,因此他的密码将过期。
Also note how you can easily use plain text initial passwords in plays. No need to encode them somewhere else and paste hashes, you can use Jinja2 filterfor that. However, this can be a security flaw if someone happens to login before you initially do.
还要注意如何在播放中轻松使用纯文本初始密码。无需在其他地方对它们进行编码并粘贴哈希,您可以使用Jinja2 过滤器。但是,如果有人碰巧在您最初登录之前登录,这可能是一个安全漏洞。
回答by bbaassssiiee
The Ansible 'user' module manages users, in the idempotentway. In the playbook below the first task declares state=presentfor the user. Note that 'register: newuser' in the first action helps the second action to determine if the user is new (newuser.changed==True) or existing (newuser.changed==False
), to only generate the password once.
Ansible“用户”模块以幂等方式管理用户。在下面的剧本中,第一个任务为用户声明state=present。请注意,第一个操作中的' register: newuser' 帮助第二个操作确定用户是新用户 (newuser.changed==True) 还是现有用户 ( newuser.changed==False
),从而只生成一次密码。
The Ansible playbook has:
Ansible 剧本有:
tasks:
- name: create deployment user
user:
name: deployer
createhome: yes
state: present
register: newuser
- name: generate random password for user only on creation
shell: /usr/bin/openssl rand -base64 32 | passwd --stdin deployer
when: newuser.changed
回答by Artem Feofanov
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"
回答by McKelvin
The purpose of the role in this answer is to generate random password for new_user_name and expire the password immediately. The new_user_name is required to change the password on his/her first logon.
此答案中角色的目的是为 new_user_name 生成随机密码并立即使密码过期。new_user_name 需要在他/她第一次登录时更改密码。
create_user.yml:
create_user.yml:
---
# create_user playbook
- hosts: your_host_group
become: True
user: ansible
roles:
- create_user
roles/create_user/tasks/main.yml:
角色/create_user/tasks/main.yml:
---
# Generate random password for new_user_name and the new_user_name
# is required to change his/her password on first logon.
- name: Generate password for new user
shell: makepasswd --chars=20
register: user_password
- name: Generate encrypted password
shell: mkpasswd --method=SHA-512 {{ user_password.stdout }}
register: encrypted_user_password
- name: Create user account
user: name={{ new_user_name }}
password={{ encrypted_user_password.stdout }}
state=present
append=yes
shell="/bin/bash"
update_password=always
when: new_user_name is defined and new_user_name in uids
register: user_created
- name: Force user to change password
shell: chage -d 0 {{ new_user_name }}
when: user_created.changed
- name: User created
debug: msg="Password for {{ new_user_name }} is {{ user_password.stdout }}"
when: user_created.changed
When you want to create a new user:
当您要创建新用户时:
ansible-playbook -i hosts.ini create_user.yml --extra-vars "new_user_name=kelvin"
回答by pgaref
Just for completeness I will post the ad-hoc command using ansible since there is a catch there as well.
为了完整起见,我将使用 ansible 发布临时命令,因为那里也有一个问题。
First try generating an encrypted password using the mkpasswd utility that is available on most Linux systems:
首先尝试使用大多数 Linux 系统上可用的 mkpasswd 实用程序生成加密密码:
mkpasswd --method=SHA-512
Then try the ansible ad-hock command:
然后尝试 ansible ad-hock 命令:
ansible all -m user -a 'name=testuser shell=/bin/bash \
comment="Test User" password=$XXXX' -k -u admin --sudo
But make sure:
但请确保:
- The command is in single quotes and NOT double otherwise your password will never work
- You run it with
--sudo
or you end up with an error like (useradd: cannot lock /etc/passwd; try again later
)
- 该命令是单引号而不是双引号,否则您的密码将永远无法使用
- 你用它运行它
--sudo
或者你最终得到一个像 (useradd: cannot lock /etc/passwd; try again later
)这样的错误
回答by Lightmed
This is the easy way:
这是简单的方法:
---
- name: Create user
user: name=user shell=/bin/bash home=/srv/user groups=admin,sudo generate_ssh_key=yes ssh_key_bits=2048
- name: Set password to user
shell: echo user:plain_text_password | sudo chpasswd
no_log: True
回答by hecbuma
This is how it worked for me
这就是它对我的工作方式
- hosts: main
vars:
# created with:
# python -c "from passlib.hash import sha512_crypt; print sha512_crypt.encrypt('<password>')"
# above command requires the PassLib library: sudo pip install passlib
- password: '$rounds=100000$H/83rErWaObIruDw$DEX.DgAuZuuF.wOyCjGHnVqIetVt3qRDnTUvLJHBFKdYr29uVYbfXJeHg.IacaEQ08WaHo9xCsJQgfgZjqGZI0'
tasks:
- user: name=spree password={{password}} groups=sudo,www-data shell=/bin/bash append=yes
sudo: yes
回答by Dmitriy
How to create encrypted password for passing to password
var to Ansible user
task (from @Brendan Wood's comment):
如何创建加密密码以传递给password
var 到 Ansibleuser
任务(来自@Brendan Wood 的评论):
openssl passwd -salt 'some_plain_salt' -1 'some_plain_pass'
The result will look like:
结果将如下所示:
$some_pla$lmVKJwdV3Baf.o.F0OOy71
Example of user
task:
user
任务示例:
- name: Create user
user: name="my_user" password="$some_pla$lmVKJwdV3Baf.o.F0OOy71"
UPD: crypt using SHA-512 see hereand here:
Python
Python
$ python -c "import crypt, getpass, pwd; print crypt.crypt('password', '$6$saltsalt$')"
$saltsalt$qFmFH.bQmmtXzyBY0s9v7Oicd2z4XSIecDzlB5KiA2/jctKu9YterLp8wwnSq.qc.eoxqOmSuNp2xS0ktL3nh/
Perl
珀尔
$ perl -e 'print crypt("password","$6$saltsalt$") . "\n"'
$saltsalt$qFmFH.bQmmtXzyBY0s9v7Oicd2z4XSIecDzlB5KiA2/jctKu9YterLp8wwnSq.qc.eoxqOmSuNp2xS0ktL3nh/
Ruby
红宝石
$ ruby -e 'puts "password".crypt("$saltsalt$")'
$saltsalt$qFmFH.bQmmtXzyBY0s9v7Oicd2z4XSIecDzlB5KiA2/jctKu9YterLp8wwnSq.qc.eoxqOmSuNp2xS0ktL3nh/