Puppet 在 Configuration 的設定內一定多多少少會有一些機敏資訊,或是不想透明化在 repository 的資料,而在使用 Puppet 資料通常都是存在 hiera 的 YAML 裡面,如果要加密資料可以使用 hiera-eyaml 來把機敏資訊加密,這個 plugin 也是採用 YAML 來寫,但他的副檔名為 eyaml,可以解釋為 encrypt yaml 的意思。
hiera-eyaml 最大的特色就是可以:
- 加密檔案 (file)
- 加密字串 (string)
- 加密密碼 (prompt for it)
這邊最常用到的就是加密字串 (string) 的方式,有些時候我只需要某些值加密,而並非整個檔案加密,就非 hiera-eyaml 莫屬,hiera-eyaml 是藉由產生 Public / Private key 的方式來加密,用 Public key 來 encrypt,Private key 來 decrypt。
Puppet master 上安裝 hiera-eyaml
Step .1 用 gem 安裝 hiera-eyaml
$ sudo gem install hiera-eyaml
Step 2. 然後還要替 puppet server 安裝 hiera-eyaml
$ sudo puppetserver gem install hiera-eyaml
Step 3. 到 /etc/puppetlabs/puppet 這邊生成 hiera-eyaml 的 keys,實際上你可以任意指定位置。
$ cd /etc/puppetlabs/puppet $ sudo eyaml createkeys
這個步驟你會生成一個 keys 目錄,並且裡面有 private_key.pkcs7.pem、public_key.pkcs7.pem 兩把 key。
Step 4. 處理 pem 權限
$ sudo chown -R puppet:puppet /etc/puppetlabs/puppet/keys/ $ sudo chmod -R 0500 /etc/puppetlabs/puppet/keys/ $ sudo chmod 0400 /etc/puppetlabs/puppet/keys/*.pem $ ls -lha /etc/puppetlabs/puppet/keys -r-------- 1 puppet puppet 1679 May 31 14:12 private_key.pkcs7.pem -r-------- 1 puppet puppet 1050 May 31 14:12 public_key.pkcs7.pem
Step 5. 設定 hiera-eyaml 的 config,這是為了在接下來的步驟使用 eyaml 指令需要用到
$ sudo vim /etc/eyaml/config.yaml --- pkcs7_private_key: /etc/puppetlabs/puppet/keys/private_key.pkcs7.pem pkcs7_public_key: /etc/puppetlabs/puppet/keys/public_key.pkcs7.pem
如果沒有設定 config 的話,你的 eyaml 預設會去讀你當前目錄的 ./keys/{public,private}_key.pkcs7.pem,為了方便可以在其他目錄操作 eyaml 所以把設定寫在 eyaml 讀的到的地方。
預設 eyaml 讀取設定檔的順序是:
- /etc/eyaml/config.yaml
- ~/.eyaml/config.yaml
- $EYAML_CONFIG 變數
Step 6. 然後在 hiera.yaml 裡面加上 hiera-eyaml 的 plugin support
--- version: 5 defaults: datadir: data data_hash: yaml_data hierarchy: - name: "Secret data: per-node, per-datacenter, common" lookup_key: eyaml_lookup_key paths: - "secrets/nodes/%{trusted.certname}.eyaml" - "common.eyaml" options: pkcs7_private_key: /etc/puppetlabs/puppet/keys/private_key.pkcs7.pem pkcs7_public_key: /etc/puppetlabs/puppet/keys/public_key.pkcs7.pem - name: "Per-node data" path: "nodes/%{trusted.certname}.yaml" - name: "Common data" path: "common.yaml"
我這邊用的是 hiera 5,如果是 hiera 3 要看 hiera-eyaml document,重點在於 lookup_key 這邊選擇 eyaml_lookup_key 這個 plugin,由於 eyaml 可以同時並存明文、密文資料,其實你也是可以通通寫在 eyaml 裡面會比較乾淨,但實際上效能會差一點,因為 eyaml 都會透過 Private key 解密後打開。
Step 7. 然後試著加密一個 string
$ eyaml encrypt -s '123' [hiera-eyaml-core] Loaded config from /Users/scottliao/.eyaml/config.yaml string: ENC[PKCS7,MIIBeQYJKoZIhvcNAQcDoIIBajCCAWYCAQAxggEhMIIBHQIBADAFMAACAQEwDQYJKoZIhvcNAQEBBQAEggEALG08ai79eR+tE1Ilh7i+Hnw585ZCGDrcL+/ae54x5em2IA0EzrtS+yZVED3x1hGQPzsi/vwDvZf0VXuFQCDa14OXVsrcz1YVY2dDRYu0lTQEb1RGFUlb1aarQdIOrrfuvMcC/awDRXkNuLl/0IbHfH20P5IRo6Zd/lDhBzFCN9hSzvJ187TmwNqXDV3HzZ/d76SNW1RA6SP/0T2iZ/8x2YOhcyYqz+l/BjSMxffGzlLFFsiiOndPqHtuldZGfqwnzvzkvMSml8no0695et8wwsFz1nAG3oyQFVWCi7TtF7nJ46SdY6pyy0GCHI0tVMyXlO5W0IBzSLkHfvh1Ukoy7DA8BgkqhkiG9w0BBwEwHQYJYIZIAWUDBAEqBBBFC79eC77bcWazzCrKwncpgBAeU+vF/bzMD9ZYjblt9WUT] OR block: > ENC[PKCS7,MIIBeQYJKoZIhvcNAQcDoIIBajCCAWYCAQAxggEhMIIBHQIBADAFMAACAQEw DQYJKoZIhvcNAQEBBQAEggEALG08ai79eR+tE1Ilh7i+Hnw585ZCGDrcL+/a e54x5em2IA0EzrtS+yZVED3x1hGQPzsi/vwDvZf0VXuFQCDa14OXVsrcz1YV Y2dDRYu0lTQEb1RGFUlb1aarQdIOrrfuvMcC/awDRXkNuLl/0IbHfH20P5IR o6Zd/lDhBzFCN9hSzvJ187TmwNqXDV3HzZ/d76SNW1RA6SP/0T2iZ/8x2YOh cyYqz+l/BjSMxffGzlLFFsiiOndPqHtuldZGfqwnzvzkvMSml8no0695et8w wsFz1nAG3oyQFVWCi7TtF7nJ46SdY6pyy0GCHI0tVMyXlO5W0IBzSLkHfvh1 Ukoy7DA8BgkqhkiG9w0BBwEwHQYJYIZIAWUDBAEqBBBFC79eC77bcWazzCrK wncpgBAeU+vF/bzMD9ZYjblt9WUT]
你會得到一個 “一行密文” 或是整理過的 “多行密文”,實際上是一樣的,但引入方式可以用 “>” 來寫
Step 8. 寫到 common.eyaml
實際上你的 eyaml 裡的值會長這樣:
users: shazi7804: password: > ENC[PKCS7,MIIBeQYJKoZIhvcNAQcDoIIBajCCAWYCAQAxggEhMIIBHQIBADAFMAACAQEw DQYJKoZIhvcNAQEBBQAEggEALG08ai79eR+tE1Ilh7i+Hnw585ZCGDrcL+/a e54x5em2IA0EzrtS+yZVED3x1hGQPzsi/vwDvZf0VXuFQCDa14OXVsrcz1YV Y2dDRYu0lTQEb1RGFUlb1aarQdIOrrfuvMcC/awDRXkNuLl/0IbHfH20P5IR o6Zd/lDhBzFCN9hSzvJ187TmwNqXDV3HzZ/d76SNW1RA6SP/0T2iZ/8x2YOh cyYqz+l/BjSMxffGzlLFFsiiOndPqHtuldZGfqwnzvzkvMSml8no0695et8w wsFz1nAG3oyQFVWCi7TtF7nJ46SdY6pyy0GCHI0tVMyXlO5W0IBzSLkHfvh1 Ukoy7DA8BgkqhkiG9w0BBwEwHQYJYIZIAWUDBAEqBBBFC79eC77bcWazzCrK wncpgBAeU+vF/bzMD9ZYjblt9WUT]
Step 9. 驗證 eyaml encrypt 的值是否正確。
$ eyaml decrypt -e common.eyaml users: shazi7804: password: > DEC::PKCS7[123]!
用 decrypt 來看會顯示 DEC,和解密後的數值
使用 hiera-eyaml 後的探討與管理
在用了 hiera-eyaml 後同時也必須思考 Public / Private key 存放的問題,基本上 repository 不會存放 key,只提供開發 Puppet 的人員 Public key (有 Public key 就可以 encrypt),讓系統管理者把 Public / Private key 塞到 Puppet master。
如果你有用 AWS 還可以參考一位在 hiera-eymal issues 提出的 hiera-eyaml-kms 利用 AWS kms 來管理 key 是一個不錯的選擇。
** 如果你將 hiera-eyaml 跑在 hiera 5 出現「Error: Could not run: Lookup of key ‘lookup_options’ failed: : Unable to find ‘lookup_key’ function named ‘eyaml_lookup_key’」的訊息的話,這是由於你的 Puppet agent 版本 hiera 5 並未內建 eyaml_lookup_key,在 PUP-7293 有提到,然後在 4.9.4 版本 bugfixes 了。