一 簡介
注:本文demo使用ansible2.7穩定版
眾所周知,ansible是很火的一個自動化部署工具,在ansible控制節點內,存放着當前環境服務的所有服務的配置信息,其中自然也包括一些敏感的信息,例如明文密碼、IP地址等等。
從安全角度來講,這些敏感數據的文件不應該以明文的形式存在。此時就用到了ansible加密的特性。
ansible通過命令行「ansible-vault」給你目標文件/字符串進行加密。在執行playbook時,通過指定相應參數來給目標文件解密,從而實現ansible vault的功能。
ansible可以加密任何部署相關的文件數據,例如:
- 主機/組變量等所有的變量文件
- tasks、hanlders等所有的playbook文件
- 命令行導入的文件(eg : -e @file.yaml ,-e @file.json)
- copy,template的模塊里src參數所使用的文件,甚至是二進制文件。
- playbook里用到的某個字符串參數也可以加密(Ansible>=2.3)
本節主要介紹下ansible數據文件/字符串的加解密及加密文件的使用方法等知識點。
二 給文件加密
創建加密文件
ansible-vault create foo.yml
執行該命令后,交互式輸入兩次相同的密碼,則創建加密文件成功。
給現有文件加密
ansible-vault encrypt foo.yml bar.yml baz.yml
如示例所示,該命令可以為多個文件同時加密,同樣需要輸入兩次相同的密碼,則加密成功。
案例分析
很多情況下,我們需要給主機(組)部分變量文件進行加密,而不是全加密。這里介紹下加密和非加密需要同時存在時推薦的用法。以創建組變量為例:
定義了一個「nodes」主機組
➜ inventory cat hosts.yaml --- # inventory/hosts nodes: hosts: node1: node2: node3:
組變量文件我們這樣創建,目錄結構如下:
➜ inventory tree group_vars
group_vars
└── nodes
├── vars.yaml
└── vault.yaml
文件「inventory/group_vars/nodes/vault.yaml」內容如下:
--- vault_db_name: test vault_db_host: 127.0.0.1
上面示例中,我們為「nodes」主機組創建了一個「group_vars/nodes」目錄用於存放該主機組的變量文件,其中「vars.yaml」和「vault.yaml」文件分別存放不加密和加密變量,通過這種拆分變量的方法,實現了加密和非加密同時存在的功能。
另外,為了便於識別,「vault.yaml」文件里的所有key值建議使用「vault_」開頭,這樣再playbook調用這些變量時,可以有很高的辨識度。
三 編輯加密文件
對加密過的文件進行編輯也是我們常遇到的,命令為:
ansible-vault edit foo.yml
這個命令會將該文件解密,並放到一個臨時文件,編輯完后再保存到原文件。
四 查看加密文件
有時我們不是想編輯文件,而是簡單查看下文件內容,命令為:
ansible-vault view foo.yml bar.yml baz.yml
從示例中我們可以看出,一行命令可以查看多個加密文件。
五 更改密碼
給加密文件更改密碼,命令為:
ansible-vault rekey foo.yml bar.yml baz.yml
先交互式輸入舊的密碼,然后再交互式輸入兩次新密碼,即更改密碼成功。
六 取消加密
取消加密的命令為:
ansible-vault decrypt foo.yml bar.yml baz.yml
交互式輸入密碼,即取消加密成功。
七 encypt_string創建加密變量
Vault ID和多密碼
ansible2.4版本以后,新增了Vault ID和多密碼的特性。Vault ID可以理解為為一個密碼設置一個標簽,用於管理員識別使用的是哪個密碼,例如dev,prod,cloud等等;多密碼指執行一次playbook時可以指定多個密碼文件。
注:vault_id不會影響加密文件的解密,只是為了便於管理員識別是哪個密碼。
encypt_string創建加密變量
在plabook文件中,我們也可以為某個字符串加密,從而達到加密變量嵌套在未加密YAML文件內的效果。
「ansible-vault encrypt_string」命令用於給某個字符串加密。
不設置vault_id,示例如下:
➜ lab-ansible ansible-vault encrypt_string --vault-id playbooks/test_vault.yaml 'maurice' --name 'the_name' the_name: !vault | $ANSIBLE_VAULT;1.1;AES256 ... ...
設置vault_id為「dev」(給密碼打標簽)(加密參數也會有「dev」的標識):
➜ lab-ansible ansible-vault encrypt_string --vault-id dev@playbooks/test_vault.yaml 'maurice' --name 'the_name' the_name: !vault | $ANSIBLE_VAULT;1.2;AES256;dev ... ...
從stdin讀取密碼:
➜ lab-ansible echo -n 'maurice' | ansible-vault encrypt_string --vault-id dev@playbooks/test_vault.yaml --stdin-name 'the_name' Reading plaintext input from stdin. (ctrl-d to end input) the_name: !vault | $ANSIBLE_VAULT;1.2;AES256;dev ... ...
交互式設置密碼,設置完密碼后按Ctrl+d:
➜ lab-ansible ansible-vault encrypt_string --vault-id dev@playbooks/test_vault.yaml --stdin-name 'the_name' Reading plaintext input from stdin. (ctrl-d to end input) maurice the_name: !vault | $ANSIBLE_VAULT;1.2;AES256;dev ... ...
八 使用加密文件
上面我們主要介紹了密碼文件/變量的創建方式,接下來介紹下如何使用。
ansible執行playbook時,可以通過交互式或指定密碼文件的方式來解密文件。
交互式
執行playbook時在終端以交互式的形式輸入密碼,示例:
ansible版本<=2.4,該方式只支持一個密碼,不能指定vault_id。
ansible-playbook --ask-vault-pass site.yml
ansible2.4版本后,對應命令行如下,該方式只支持一個密碼,能指定vault_id:
ansible-playbook --vault-id dev@prompt playbooks/test_vault.yaml
指定密碼文件
另外一種使用方式,是將密碼放在某個文件內,執行playbook時,通過指定該密碼文件進行解密。
ansible版本<=2.4,可以使用「--vault-password」參數:
ansible-playbook --vault-password-file dev-password site.yml
ansible2.4版本以后,又增加了「--vault-id」的參數,用來指定密碼文件:
ansible-playbook --vault-id /path/to/my/vault-password-file site.yml
從可執行腳本獲取密碼:
ansible-playbook --vault-id my-vault-password.py
指定密碼文件同時指定vault_id:
ansible-playbook --vault-id dev@prompt site.yml
指定多vault_id+多密碼文件:
ansible-playbook --vault-id dev@dev-password --vault-id prod@prompt site.yml
其他知識點
- 在僅使用多密碼文件的情況下,默認的,ansible會按照命令行的排列順序,逐個嘗試。直到成功解密或失敗。
- 在使用vault_id+多密碼的情況下,ansible會優先匹配與vault_id相同的加密變量(這個標識上面加密變量有提到),如果不能解密再匹配其他vault_id變量文件。
- 除了命令行,密碼文件的默認路徑也可以通過ansible.cfg的「vault_password_file」或環境變量「ANSIBLE_VAULT_PASSWORD_FILE」獲取。
九 本節應該掌握的技能
- 掌握變量文件創建、查看、編輯、更改、取消加密等方法
- 掌握字符串加密的方法
- 掌握含加密文件時playbook的執行方法
十 參考鏈接
- https://docs.ansible.com/ansible/latest/user_guide/vault.html
歡迎大家關注我的公眾號: