iT邦幫忙

2025 iThome 鐵人賽

DAY 17
0
DevOps

不爆肝學習 Ansible 的短暫30天系列 第 17

Day17 - 幫敏感資訊加個密吧:Ansible Vault

  • 分享至 

  • xImage
  •  

今日目標

  • 了解 Ansible Vault 是什麼
  • 該如何保護好我們的敏感資訊

為什麼要用 Ansible Vault?

經過這幾天的洗禮後,相信大家會開始產生許多環境變數,其中一定會包含一些很敏感的資訊 (ex: api_key)。

但我們既然使用 Ansible 來設計整個自動化部署流程,那必定會需要跟同事 co-work,所以就會接觸到 git,那我們總不可能把這些敏感資訊直接放進版控然後不做任何處理吧。

這時候各位一定會想說,啊我們 Github Repository 有設定成私有的,所以敏感資訊本身就有保護的效果了啊。

的確!將 Github Repository 設定成私有的做法,就可以有效的阻擋外部人士的讀取了,但是各位別忘了資訊安全最重要的是什麼!!!

是『人』啊!,如果用 Private Repository 的話我們要如何控管內部人員的權限呢?所以我們需要用一份 password file 加密這些敏感資訊,然後再針對 password file 去做權限以及環境的區分。

比較常用的指令

# 建立或編輯加密檔
ansible-vault create group_vars/prod/vault.yaml # 建立
ansible-vault edit   group_vars/prod/vault.yaml # 編輯
ansible-vault view   group_vars/prod/vault.yaml # 檢視

# 對既有檔案加/解密
ansible-vault encrypt group_vars/prod/secrets.yaml
ansible-vault decrypt group_vars/prod/secrets.yaml

# 重新加密 (換 password)
ansible-vault rekey group_vars/prod/vault.yaml

# 直接產生加密字串
ansible-vault encrypt_string --vault-id prod@prompt 'P@ssw0rd!' --name db_password

# 執行 Playbook (互動輸入密碼或使用 vault-id)
ansible-playbook -i inventory.ini site.yml --ask-vault-pass
ansible-playbook -i inventory.ini site.yml --vault-id prod@prompt

筆者建議可以善用 vault-id,因為這樣我們可以同時使用多個 password file 去加強我們的敏感資訊的保護。
ex: --vault-id dev@prompt --vault-id prod@~/.ansible/vault/prod.pass

舉個例子

# prod@prompt.txt 其實 password file 就只是個放置密碼的地方
# Ansible Vault 真正加密的方式後面會提到
393oVwA8CDSbNyfusnHXE
---
# vault-demo.yml
- name: Day17 Vault demo
  hosts: all
  gather_facts: false
  vars_files:
    - group_vars/all.yaml           # 非敏感設定
    - group_vars/prod/vault.yaml    # 敏感設定 (使用 Ansible Vault 加密)
  tasks:
    - name: Render app env
      template:
        src: templates/app.env.j2
        dest: /tmp/app.env
        mode: '0600'

    - name: Show masked info
      debug:
        msg: "User={{ db_user }}, Password length={{ db_password | length }}"
---
# group_vars/all.yaml
db_user: appuser
app_env: production

建立一個加密過的檔案:

mkdir -p group_vars/prod
ansible-vault create group_vars/prod/vault.yaml --vault-id prod@prompt
# 內容中輸入:
# db_password: "請填你的密碼"

或者可以用加密字串貼進非加密檔:

ansible-vault encrypt_string --vault-id prod@prompt 'P@ssw0rd!' --name db_password
# 輸出內容貼到 group_vars/prod/vars.yaml
# templates/app.env.j2
# Managed by Ansible – DO NOT EDIT
DB_USER={{ db_user }}
DB_PASSWORD={{ db_password }}
ENV={{ app_env }}

重要需知

  1. 切記!請不要將 password file 也一起進版並上傳了,請一定要把 password 這份檔案趕快加到 .gitignore
  2. 筆者建議各位 password file 盡量用環境區分,不要全部都用同一把,不然有心人士真的不小心取得 password file,production 不就也可以直接被攻擊了嗎。
  3. 拜託!真的千萬不要因為一時的方便開發,而不去注意一些資訊安全的細節,用戶的資料保護從你我開始做起!

其他加解密的方案

說到這裡,肯定會有些人會問那有沒有其他的加解密方案,其實是有的,但筆者這裡會用 Ansible Vault 來做介紹是因為畢竟 Ansible Vault 就是為了 Ansible 而生,所以整體流程上體驗是最好的,每次執行 Playbook 同時帶上 password file,剩下的 Ansible 會自動幫各位處理好,不香嗎 😆

但是!!!這邊還是給大家兩種我覺得算是不錯的加解密方案,大家可以參考看看,但是流程會需要重新設計,所以這邊根據自己的需求去做取捨。

  1. SOPS
  2. git-crypt

筆者已經寫好這兩個工具的詳細使用方式跟工具,覺得不錯的可以給筆者一個 Star ⭐️⭐️⭐️ ~

Ansible Vault 加密方式

各位在前面可以看到其實我們就是將一個密碼丟進去 Ansible Vault,然後 Ansible Vault 會怎麼利用這個 password 來做加密呢?

  1. 取得 password
  2. 加上 salt,經過 10000 次的 SHA256 迭代後,會得到一把 key
  3. 取前面 32 bytes 作為 AES 的加密用金鑰,中間 32 bytes 作為 HMAC 金鑰,後面 16 bytes 作為 AES 的 IV
  4. 拿到上述材料後我們就可以來做 AES 的加密
  5. 接著我們就會得到一份加密後的檔案

看到這個流程可能開始會有小夥伴們感到滿滿的疑問,但別擔心我們只要會用就好了,詳細的細節筆者在找個時間解釋一下 AES 的加密概念。

作業練習時間

  • 練習 1:為 dev 與 prod 建立不同密碼的 vault.yaml,測試 --vault-id 切換環境。
  • 練習 2:使用 encrypt_string 將 API Token 以加密字串方式置入 group_vars/all.yaml

明日預告

明天來聊聊 tag,只能說這個東西非常好用,大家可以期待一下!


上一篇
Day16 - 今天來點比較進階的 Inventory
下一篇
Day18 - Ansible 不得不學的 Tags
系列文
不爆肝學習 Ansible 的短暫30天21
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言