Ansible 加密模块 Vault

ansible-vault 只要用于配置文件加密,能够加密或解密,具体使用方式以下:html

Usage: ansible-vault [create|decrypt|edit|encrypt|encrypt_string|rekey|view] [options] [vaultfile.yml]

能够看到有不少子命令:shell

  • create: 建立一个新文件,并直接对其进行加密
  • decrypt: 解密文件
  • edit: 用于编辑 ansible-vault 加密过的文件
  • encrypy: 加密文件
  • encrypt_strin: 加密字符串,字符串从命令行获取
  • view: 查看通过加密的文件

加密文件

先本身建立一个文件,写入一些内容:安全

[root@Ansible ~]# echo "123456" > pass.txt
[root@Ansible ~]# cat pass.txt 
123456
[root@Ansible ~]#

而后用 ansible-vault encrypt 加密文件:ssh

[root@Ansible ~]# ansible-vault encrypt pass.txt
New Vault password: 
Confirm New Vault password: 
Encryption successful
[root@Ansible ~]#

这里会要求输入密码。ide

如今再去打开文件看看:工具

[root@Ansible ~]# cat pass.txt 
$ANSIBLE_VAULT;1.1;AES256
62633762393035316438663662343964656465376634393131313466313536336361333163313238
6162356161653365623961353533356264386134653830640a353531623635653337636564383763
38316636383334323533363666383963666161633332663461316338333332623434376162326265
6565623130373539330a313737646431626131336637663033656664383932393934633337383666
6334
[root@Ansible ~]#

查看文件内容,能够用 ansible-vault view 命令:测试

[root@Ansible ~]# ansible-vault view pass.txt
Vault password: 
123456
[root@Ansible ~]#

把文件还原能够用 ansible-vault decrypt 命令:加密

[root@Ansible ~]# ansible-vault decrypt pass.txt
Vault password: 
Decryption successful
[root@Ansible ~]# cat pass.txt 
123456
[root@Ansible ~]#

加密配置文件

上面的演示内容只是一个小工具的单独使用,这里看看结合ansible命令的使用。
在/etc/ansible/hosts文件中新加一台主机用于测试:命令行

host1 ansible_host=127.0.0.1 ansible_connection=local

这里加的就是本机。debug

而后单首创建这台主机的变量文件 /etc/ansible/host_vars/host1 ,随便写入一些变量:

---
key1: vaule1
key2: VALUE2

先来验证一下:

[root@Ansible ~]# ansible host1 -a "echo key1={{key1}}, key2={{key2}}" 
host1 | CHANGED | rc=0 >>
key1=vaule1, key2=VALUE2
[root@Ansible ~]#

如今把配置文件加密:

[root@Ansible ~]# ansible-vault encrypt /etc/ansible/host_vars/host1 
New Vault password: 
Confirm New Vault password: 
Encryption successful
[root@Ansible ~]# ansible host1 -a "echo key1={{key1}}, key2={{key2}}" 
ERROR! Attempting to decrypt but no vault secrets found
[root@Ansible ~]#

加密后再运行就无论用了,这里须要加一个参数 --ask-vault-pass 来提供vault加密的密码:

[root@Ansible ~]# ansible host1 -a "echo key1={{key1}}, key2={{key2}}"  --ask-vault-pass
Vault password: 
host1 | CHANGED | rc=0 >>
key1=vaule1, key2=VALUE2
[root@Ansible ~]#

使用文件加密

以前都是直接使用密码进行加密。对咱们来讲,其实只是把一个密码用另外一个密码加密了。在使用的时候,咱们不使用原来的密码,而是使用vault的密码。
为了方便不用每次都输入密码,能够把密码写在文件中。不过直接把密码明文写在文件中老是不安全的。利用 ansible-vault 就是让咱们能够把密码直接写在配置中(也能够是一个单独的配置文件),而后把有敏感信息的文件加密。这样作的好处是,整个项目全部的配置信息都是全的,包括项目中使用的密码,而且是加密的。
若是每次使用时仍然不想输入密码,也能够把vault的密码写到文件中(明文的),这样每次使用时就不是手动输入,而是让ansible自动从文件中获取这个密码。

仍是重复使用以前的配置文件,先把文件进行解密:

[root@Ansible ~]# ansible-vault decrypt /etc/ansible/host_vars/host1 
Vault password: 
Decryption successful
[root@Ansible ~]#

而后再生成文件后用文件进行加密:

[root@Ansible ~]# echo "123456" > vault-pass-file
[root@Ansible ~]# ansible host1 -a "echo key1={{key1}}, key2={{key2}}"
ERROR! Attempting to decrypt but no vault secrets found
[root@Ansible ~]# ansible host1 -a "echo key1={{key1}}, key2={{key2}}" --vault-password-file vault-pass-file
host1 | CHANGED | rc=0 >>
key1=vaule1, key2=VALUE2
[root@Ansible ~]# ansible host1 -a "echo key1={{key1}}, key2={{key2}}" --ask-vault-pass
Vault password: 
host1 | CHANGED | rc=0 >>
key1=vaule1, key2=VALUE2
[root@Ansible ~]#

这里最后还试了一下使用密码 --ask-vault-pass 效果其实和使用 --vault-password-file 是同样的。一个是手动输入密码,一个是从文件中读取密码字符串。

加密变量

上面的加密方式是加密整个文件。加密后,文件中敏感的内容不敏感的内容就都看不到了,这样也很不方便。一个解决办法是把敏感的和不敏感的内容分开,写在不一样的文件中,只加密敏感文件。就像以前的示例中那样。
还有一个更灵活的方式,使用 ansible-vault encrypt_string 把值进行加密。

经过文件加密

准备好用做vault认证的文件:

[root@Ansible ~]# ansible-vault encrypt_string --vault-id vault-pass-file 'ssh_pass' --name 'key3'
key3: !vault |
          $ANSIBLE_VAULT;1.1;AES256
          66613666353739356536663965336234383363373563353231353939303839313430616161336365
          6662336162386231316132633365366232363936613561650a313637643339323861626364633864
          32653666626333623961643866656235653764646333613533343231303734313862376232393734
          6563343539393264650a653438326463646364646338656339356236383537663135633935313239
          3664
Encryption successful
[root@Ansible ~]#

参数--name,能够不写。写上后最后生成的内容就是带key的,不然只是生成值的部分,key咱们也能够手动加上。

手动输入密码

若是不使用文件,而是要手动输入,能够将指定的文件名替换为prompt,这样就会让咱们输入2次密码确认了:

[root@Ansible ~]# ansible-vault encrypt_string --vault-id prompt 'ssh_pass' --name 'key3'
New vault password (default): 
Confirm new vault password (default): 
key3: !vault |
          $ANSIBLE_VAULT;1.1;AES256
          30666333366265346464383165373062613165666130373066613930316364363432376336613938
          3131663337633863373539666134643661623734613330350a616661613934633335303365366266
          36363433613334386664663839346435656534373732333632303532303939383466303662396438
          3433633535333130350a323934373162356139363762383739386139333937666237613564313939
          3137
Encryption successful
[root@Ansible ~]#

加上用户标识

官方的文档以下:
https://docs.ansible.com/ansible/latest/network/getting_started/first_inventory.html#protecting-sensitive-variables-with-ansible-vault

在官方文档的示例中 --vault-id 的参数值,都是加上了用户名称表示的,加在文件名或者prompt前,用@隔开:

$ ansible-vault encrypt_string --vault-id steed@vault-pass-file 'ssh_pass' --name 'key3'
$ ansible-vault encrypt_string --vault-id steed@prompt 'ssh_pass' --name 'key3'

貌似也没什么用,可是生成的内容中会有这个用户标识。仍是尽可能参考官方的建议来比较好。

生成一个新的变量,将加密的值写到配置文件中:

[root@Ansible ~]# ansible-vault encrypt_string --vault-id steed@vault-pass-file 'ssh_pass' --name 'key3' >> /etc/ansible/host_vars/host1
[root@Ansible ~]# cat /etc/ansible/host_vars/host1
---
key1: vaule1
key2: VALUE2
key3: !vault |
          $ANSIBLE_VAULT;1.2;AES256;steed
          30343264386638623133383632353762356632643531643735653131663662623164303533373163
          3032646663363765386135386362376433326131333262310a366636396233653038646133336334
          62376532343064396639623835646563643663613530383739666239663565386364303931316637
          6137343936636266340a306233633039323537346332336132313766383039653565646230393662
          6332
[root@Ansible ~]#

这里能够看到密文上一行的内容的最后,有以前加上的用户标识信息。

使用的时候,使用密码仍是指定文件均可以:

[root@Ansible ~]# ansible host1 -a "echo key1={{key1}}, key3={{key3}}" --vault-id vault-pass-file 
host1 | CHANGED | rc=0 >>
key1=vaule1, key3=ssh_pass
[root@Ansible ~]# ansible host1 -a "echo key1={{key1}}, key3={{key3}}" --vault-password-file vault-pass-file 
host1 | CHANGED | rc=0 >>
key1=vaule1, key3=ssh_pass
[root@Ansible ~]#

官方文档中是用 --vault-id 来指定解密用的文件的,不过试了下 --vault-password-file 也是能够的。

其余技巧

还有一些其余的相关内容。

使用debug模块进行调试

官方的建议是使用debug模块就行调试:

To see the original value, you can use the debug module.

以前的示例就不改了,要用debug模块,简单的能够这么使用:

[root@Ansible ~]# ansible host1 -m debug -a 'var="key1,key2,key3"' --vault-password-file vault-pass-file
host1 | SUCCESS => {
    "key1,key2,key3": "('vaule1', 'VALUE2', 'ssh_pass')"
}
[root@Ansible ~]#

设置配置文件

每次都多打一个参数也是很麻烦,在配置文件中有对应的配置项,好比配置成下面这样:

# If set, configures the path to the Vault password file as an alternative to
# specifying --vault-password-file on the command line.
vault_password_file = ~/vault_password_file

注意:配置生效后,就不能再本身加参数指定了,不然会报错。而且这个状况不仅是在解密的时候,加密的时候也同样。

自动生成随机密码

网上方法有不少,我以为用 openssl 比较方便:

$ openssl rand -base64 10
VStCUWZZ1HfVtw==
$

能够直接生成一串长一点的到文件中:

$ openssl rand -base64 128 -out vault_password_file
$ cat vault_password_file 
MGt5jsPiFSLR3AUMxiOqcFmg3emStka72Zm6oqv8oB/uxY4QzYkWVYNLYVOF2Oiq
3smsUcJJ3yhmmjOSP0Lveb+qwtJhk2wZe+T0Er4cqa3ymrRvuGrLlmips566uFfO
doAYVPdrqYrKKb5IQ3VCQeX6tBBmJh972oiyVsg8XQg=
$

防止普通用户查看加密信息

虽然配置加密了,可是若是用户要执行任务,仍是须要加密的密码或者文件的读权限。有了这些,用户就能够解密配置获取密码了。

经过sudo限制用户
若是限制用户的文件读权限,则用户在执行命令的时候,会警告文件不可读。因此这条行不通:

[WARNING]: Error in vault password file loading (default): Could not read vault password file
/home/asb/vault-pass-file: [Errno 13] Permission denied: '/home/asb/vault-pass-file'
ERROR! Could not read vault password file /home/asb/vault-pass-file: [Errno 13] Permission denied: '/home/asb/vault-pass-file'

可行的方案是使用sudo。经过sudo提权后,用户就有了访问文件的权限。可是sudo能够限制使用的命令,这样用户拥有高权限时的行为就受到了控制。只让用户能够sudo提权执行有限的命令。
注意,若是让用户能够sudo执行ansible相关的命令,那么用户只要本身用ansible调用debug模块就能够提权后,把敏感的信息打印出来。或者本身构建playbook,提权执行ansible-playbook,同样能够获取加密信息。

须要建立一个专门存放脚本的目录,让普通用户有目录的执行权限,可是不可写。sudo则是设置用户能够提权操做该目录下的全部程序。须要用户执行的ansible或者playbook命令则是写成shell脚本,由管理员设置好属组和可执行权限,放到该目录下。

sudo 配置
下面是sudo文件的相关设置,修改sudo建议使用命令visudo:

[root@Ansible ~]# visudo

# 建立一个组,哪些命令或目录能够sudo执行。这里添加了一个目录
Cmnd_Alias ANSIBLE_SCRIPT = /home/ansible/script/
# 建立一个用户组
User_Alias ANSIBLE_USERS = adam, bob, clark
# ANSIBLE_USERS的用户 能够在任何主机上 以ansible用户的身份 免密码执行 ANSIBLE_SCRIPT指定的命令
ANSIBLE_USERS ALL=(ansible) NOPASSWD:ANSIBLE_SCRIPT

# 这个设置是没必要要的,不过不加的话,命令须要使用完整的路径,加上path后,就只须要加上文件名就行了
# 这个就是sudo下的$PATH变量。使用了sudo,查找命令就不是全局的$PATH变量了,而是下面设置的值
Defaults    secure_path = /sbin:/bin:/usr/sbin:/usr/bin:/home/ansible/script

修改完成后,也是 :wq 退出。程序在退出前会进行语法检查,若是配置文件写的不对是不能保存退出的。sudo的配置修改后当即生效。

相关文章
相关标签/搜索