iLO パスワードの暗号化 – Helion OpenStack 2.x
2016-01-16
Machine-translated — the English original is authoritative.
最近、Helion OpenStack 2.X のインストールで、顧客から iLO パスワードの暗号化を依頼されました。これが、Helion OpenStack に付属している暗号化スクリプト `hosencrypt.py` を扱うのは初めてでした。
これは、各パスワードを手動で取得し、暗号化スクリプトに供給するという骨の折れる作業になりました。各結果は、その後 `servers.yml` ファイルにコピーして戻す必要がありました。
インストール規模がますます大きくなるにつれ(60台以上のサーバー)、この手動プロセスを繰り返すのは嫌です – 残業代はもらえませんので 😉
以下のスクリプト `hosencryptfile.py` は、`servers.yml` ファイルを入力として受け取り、暗号化または復号化されたバージョンを生成します。詳細については、スクリプト内のコメントをお読みください。
#!/usr/bin/env python
#
# A utility to encrypt passwords for auxiliary HOS systems like IPMI.
#
# (c) Copyright 2015 Hewlett Packard Enterprise Development Company LP
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
#
# Author: Graham J Land
# Date: 16/01/2016
# Modification: Hacked this file by adding a new function file_decrypt_encrypt(switch,infile,outfile="temp")
# to automagically encrypt or decrypt the ilo-passwords in a servers.yml file
# Name: hosencryptfile.py
#
# PREREQUISITES
# This script expects an environment variable HOS_USER_PASSWORD_ENCRYPT_KEY which should hold the encryption key
# For example enter the following command before running the script:
#
# export HOS_USER_PASSWORD_ENCRYPT_KEY=EnterASecretKeyHere
#
# COMMANDLINE PARAMETERS
# switch: 2nd commandline parameter [optional]
# "" no comandline parameters then you'll be prompted to enter a password to encrypt
# "-d" you'll be prompted for a password to decrypt
# "-fe" will cause the following servers.yml file to have it's ilo-passwords encrypted
# "-fd" (or anything else for that matter) will cause the supplied servers.yml file to have it's passwords decrypted
#
# infile: 3rd commandline parameter [optional]
# the input servers.yml file that is to be processed
#
# outfile: 4th commandline parameter [optional]
# the new servers.yml file with the encrypted/decrypted passwords
# if this file is left blank then the input file will be overwritten
#
# EXAMPLE
# ~/helion/hos/ansible/hosencryptfile.py -fe ~/helion/hos/ansible/myfile.yml ~/helion/hos/ansible/my_file9.yml
#
# WARNING
# I'm not a programmer, this is the first time I've looked at python - please backup all files before use and test in labs
# No error checking included - if you enter an invalid file name IT WILL CRASH - as I get more familiar with python I'll stick in the try/catch error controls
from subprocess import PIPE, Popen
encryption_env = 'HOS_USER_PASSWORD_ENCRYPT_KEY'
class aes256:
prefix = '@hos_aes256@'
def __init__(self, key):
pass
def encrypt(self, raw):
return ""
def decrypt(self, cooked):
return ""
class openssl:
prefix = '@hos@'
def __init__(self, key=None):
pass
def delegate(self, cmd, value):
# Note that I'm passing the environment variable's name to the subprocess, not its value.
argv = ('/usr/bin/openssl', 'aes-256-cbc', '-a', cmd, '-pass', 'env:%s' % encryption_env)
p = Popen(argv, close_fds=True, stdin=PIPE, stdout=PIPE, stderr=PIPE)
result = p.communicate(input=value)
if p.returncode != 0:
errmsg = result[1].strip()
if errmsg.startswith('bad decrypt'):
errmsg = 'incorrect encryption key'
elif errmsg.startswith('error reading input file') or errmsg.startswith('bad magic number'):
errmsg = 'bad input data'
raise OSError('openssl: %s' % errmsg)
return result[0].strip()
def encrypt(self, raw):
return self.delegate('-salt', raw)
def decrypt(self, cooked):
# openssl expects a newline at the end of the string.
if cooked[-1] != '\n':
cooked += '\n'
return self.delegate('-d', cooked)
def main():
import getpass
import sys
import yaml
def file_decrypt_encrypt(switch,infile,outfile="temp"):
if outfile == "temp":
outfile = infile
with open(infile) as f:
list_doc = yaml.load(f)
for servers in list_doc['servers']:
value = servers["ilo-password"]
if switch == '-fe':
x = obj.prefix + obj.encrypt(value)
else:
if value.startswith(obj.prefix):
value = value[len(obj.prefix):]
x = obj.decrypt(value)
servers["ilo-password"] = x
#print x
f.close
with open(outfile, "w") as f:
yaml.dump(list_doc, f, default_flow_style=False)
f.close
return
obj = openssl()
# encrypt or decrypt one file to a new file
if len(sys.argv) == 4:
file_decrypt_encrypt(sys.argv[1],sys.argv[2],sys.argv[3])
# encrypt or decrypt the file inplace
elif len(sys.argv) == 3 and sys.argv[1] != '-d':
file_decrypt_encrypt(sys.argv[1],sys.argv[2])
# prompt user for value to decrypt
elif len(sys.argv) > 1 and sys.argv[1] == '-d':
value = getpass.getpass('encrypted value? ')
if value.startswith(obj.prefix):
value = value[len(obj.prefix):]
x = obj.decrypt(value)
print x
# prompt user for value to encrypt
else:
value = getpass.getpass('unencrypted value? ')
x = obj.encrypt(value)
print obj.prefix + x
if __name__ == '__main__':
main()
以下は、ファイルの使用方法の例です。
注意: 出力は yaml ファイルのフォーマットを変更し、コメントを削除しますが、処理には有効なファイルであるはずです – まだテストしていませんが。
入力ファイル exampleServers.yml
#
# (c) Copyright 2015 Hewlett Packard Enterprise Development Company LP
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
#
---
product:
version: 2
baremetal:
# NOTE: These values need to be changed to match your environment.
# Define the network range that contains the ip-addr values for
# the individual servers listed below.
subnet: 172.16.60.0
netmask: 255.255.255.0
servers:
# NOTE: Addresses of servers need to be changed to match your environment.
#
# Add additional servers as required
#
# Controllers
- id: controller1
ip-addr: 172.16.60.3
role: CONTROLLER-ROLE
server-group: RACK1
nic-mapping: HP-SL230-4PORT
ilo-ip: 172.30.0.45
ilo-password: "Guinness";
ilo-user: Administrator
mac-addr: 8c:dc:d4:b5:cc:d0
- id: controller2
ip-addr: 172.16.60.4
role: CONTROLLER-ROLE
server-group: RACK2
nic-mapping: HP-SL230-4PORT
ilo-ip: 172.30.0.46
ilo-password: "Smithwicks";
ilo-user: Administrator
mac-addr: 8c:dc:d4:b5:c6:40
- id: controller3
ip-addr: 172.16.60.5
role: CONTROLLER-ROLE
server-group: RACK3
nic-mapping: HP-SL230-4PORT
ilo-ip: 172.30.0.47
ilo-password: "Blackthorn";
ilo-user: Administrator
mac-addr: 8c:dc:d4:b5:c9:74
# Compute Nodes
- id: compute1
ip-addr: 172.16.60.6
role: COMPUTE-ROLE
server-group: RACK1
nic-mapping: HP-SL230-4PORT
ilo-ip: 172.30.0.48
ilo-password: "Budweiser";
ilo-user: Administrator
mac-addr: 8c:dc:d4:b5:c9:00
- id: compute2
ip-addr: 172.16.60.7
role: COMPUTE-ROLE
server-group: RACK2
nic-mapping: HP-SL230-4PORT
ilo-ip: 172.30.0.49
ilo-password: "Magners"
ilo-user: Administrator
mac-addr: 8c:dc:d4:b5:ce:80
- id: compute3
ip-addr: 172.16.60.8
role: COMPUTE-ROLE
server-group: RACK1
nic-mapping: HP-SL230-4PORT
ilo-ip: 172.30.0.50
ilo-password: "Bulmers"
ilo-user: Administrator
mac-addr: 8c:dc:d4:b5:cd:3c
- id: compute4
ip-addr: 172.16.60.12
role: COMPUTE-ROLE
server-group: RACK2
nic-mapping: HP-SL230-4PORT
ilo-ip: 172.30.0.51
ilo-password: "Heineken"
ilo-user: Administrator
mac-addr: 8c:dc:d4:b5:c4:e8
# Ceph OSD Nodes
- id: osd1
ip-addr: 172.16.60.9
role: OSD-ROLE
server-group: RACK1
nic-mapping: HP-DL360-8PORT
ilo-ip: 172.30.0.86
ilo-password: "Harp"
ilo-user: Administrator
mac-addr: 5c:b9:01:8d:6b:68
- id: osd2
ip-addr: 172.16.60.10
role: OSD-ROLE
server-group: RACK2
nic-mapping: HP-DL360-8PORT
ilo-ip: 172.30.0.87
ilo-password: "Kronenburg"
ilo-user: Administrator
mac-addr: 5c:b9:01:8d:70:0c
- id: osd3
ip-addr: 172.16.60.11
role: OSD-ROLE
server-group: RACK3
nic-mapping: HP-DL360-8PORT
ilo-ip: 172.30.0.88
ilo-password: "Carlsberg"
ilo-user: Administrator
mac-addr: 5c:b9:01:8d:73:dc
上記のファイルのパスワードを暗号化するには、次のコマンドを実行します。
export HOS_USER_PASSWORD_ENCRYPT_KEY=EnterASecretKeyHere
hosencryptfile.py -fe exampleServers.yml encryptedServers.yml

出力ファイル encryptedServers.yml
baremetal: {netmask: 255.255.255.0, subnet: 172.16.60.0}
product: {version: 2}
servers:
- {id: controller1, ilo-ip: 172.30.0.45, ilo-password: U2FsdGVkX1/svbU2PdGmSnWIxrDF9rjPklwGFOhpFBs=,
ilo-user: Administrator, ip-addr: 172.16.60.3, mac-addr: '8c:dc:d4:b5:cc:d0', nic-mapping: HP-SL230-4PORT,
role: CONTROLLER-ROLE, server-group: RACK1}
- {id: controller2, ilo-ip: 172.30.0.46, ilo-password: U2FsdGVkX18QFPVovYHsTgjYB8ZOenUrykOdqXW95GA=,
ilo-user: Administrator, ip-addr: 172.16.60.4, mac-addr: '8c:dc:d4:b5:c6:40', nic-mapping: HP-SL230-4PORT,
role: CONTROLLER-ROLE, server-group: RACK2}
- {id: controller3, ilo-ip: 172.30.0.47, ilo-password: U2FsdGVkX19Axzja/HsLmfg9+b1aIlPqOvRJ3yHTslg=,
ilo-user: Administrator, ip-addr: 172.16.60.5, mac-addr: '8c:dc:d4:b5:c9:74', nic-mapping: HP-SL230-4PORT,
role: CONTROLLER-ROLE, server-group: RACK3}
- {id: compute1, ilo-ip: 172.30.0.48, ilo-password: U2FsdGVkX18tgkJDrLCcMjiVxoMu6h/QwW9nnBckVpk=,
ilo-user: Administrator, ip-addr: 172.16.60.6, mac-addr: '8c:dc:d4:b5:c9:00', nic-mapping: HP-SL230-4PORT,
role: COMPUTE-ROLE, server-group: RACK1}
- {id: compute2, ilo-ip: 172.30.0.49, ilo-password: U2FsdGVkX19elEQowinOUuKEebF4qN9MfjRaKH7rWZY=,
ilo-user: Administrator, ip-addr: 172.16.60.7, mac-addr: '8c:dc:d4:b5:ce:80', nic-mapping: HP-SL230-4PORT,
role: COMPUTE-ROLE, server-group: RACK2}
- {id: compute3, ilo-ip: 172.30.0.50, ilo-password: U2FsdGVkX19ESJpnlW4GJz71+hPHHOuIY89xfMJzvOU=,
ilo-user: Administrator, ip-addr: 172.16.60.8, mac-addr: '8c:dc:d4:b5:cd:3c', nic-mapping: HP-SL230-4PORT,
role: COMPUTE-ROLE, server-group: RACK1}
- {id: compute4, ilo-ip: 172.30.0.51, ilo-password: U2FsdGVkX1/h5WJBJV8TyokBCCukBUtXGILRtioFx44=,
ilo-user: Administrator, ip-addr: 172.16.60.12, mac-addr: '8c:dc:d4:b5:c4:e8', nic-mapping: HP-SL230-4PORT,
role: COMPUTE-ROLE, server-group: RACK2}
- {id: osd1, ilo-ip: 172.30.0.86, ilo-password: U2FsdGVkX1+EjNiCBUB4EJ+xI2kb7PjtNOSYbk1Vf3I=,
ilo-user: Administrator, ip-addr: 172.16.60.9, mac-addr: '5c:b9:01:8d:6b:68', nic-mapping: HP-DL360-8PORT,
role: OSD-ROLE, server-group: RACK1}
- {id: osd2, ilo-ip: 172.30.0.87, ilo-password: U2FsdGVkX18Nw74ANA6kFGaaB1zz4YWm6CfThyKe8Ok=,
ilo-user: Administrator, ip-addr: 172.16.60.10, mac-addr: '5c:b9:01:8d:70:0c', nic-mapping: HP-DL360-8PORT,
role: OSD-ROLE, server-group: RACK2}
- {id: osd3, ilo-ip: 172.30.0.88, ilo-password: U2FsdGVkX1++WaEFBBZWASXkR17xLEszyeN/bcG8yIE=,
ilo-user: Administrator, ip-addr: 172.16.60.11, mac-addr: '5c:b9:01:8d:73:dc', nic-mapping: HP-DL360-8PORT,
role: OSD-ROLE, server-group: RACK3}
プロセスを元に戻すには、単に以下を実行するだけです(またはバックアップから復元します)。
export HOS_USER_PASSWORD_ENCRYPT_KEY=EnterASecretKeyHere
hosencryptfile.py -fd encryptedServers.yml decryptedServers.yml

出力ファイル decryptedServers.yml
baremetal: {netmask: 255.255.255.0, subnet: 172.16.60.0}
product: {version: 2}
servers:
- {id: controller1, ilo-ip: 172.30.0.45, ilo-password: Guinness, ilo-user: Administrator,
ip-addr: 172.16.60.3, mac-addr: '8c:dc:d4:b5:cc:d0', nic-mapping: HP-SL230-4PORT,
role: CONTROLLER-ROLE, server-group: RACK1}
- {id: controller2, ilo-ip: 172.30.0.46, ilo-password: Smithwicks, ilo-user: Administrator,
ip-addr: 172.16.60.4, mac-addr: '8c:dc:d4:b5:c6:40', nic-mapping: HP-SL230-4PORT,
role: CONTROLLER-ROLE, server-group: RACK2}
- {id: controller3, ilo-ip: 172.30.0.47, ilo-password: Blackthorn, ilo-user: Administrator,
ip-addr: 172.16.60.5, mac-addr: '8c:dc:d4:b5:c9:74', nic-mapping: HP-SL230-4PORT,
role: CONTROLLER-ROLE, server-group: RACK3}
- {id: compute1, ilo-ip: 172.30.0.48, ilo-password: Budweiser, ilo-user: Administrator,
ip-addr: 172.16.60.6, mac-addr: '8c:dc:d4:b5:c9:00', nic-mapping: HP-SL230-4PORT,
role: COMPUTE-ROLE, server-group: RACK1}
- {id: compute2, ilo-ip: 172.30.0.49, ilo-password: Magners, ilo-user: Administrator,
ip-addr: 172.16.60.7, mac-addr: '8c:dc:d4:b5:ce:80', nic-mapping: HP-SL230-4PORT,
role: COMPUTE-ROLE, server-group: RACK2}
- {id: compute3, ilo-ip: 172.30.0.50, ilo-password: Bulmers, ilo-user: Administrator,
ip-addr: 172.16.60.8, mac-addr: '8c:dc:d4:b5:cd:3c', nic-mapping: HP-SL230-4PORT,
role: COMPUTE-ROLE, server-group: RACK1}
- {id: compute4, ilo-ip: 172.30.0.51, ilo-password: Heineken, ilo-user: Administrator,
ip-addr: 172.16.60.12, mac-addr: '8c:dc:d4:b5:c4:e8', nic-mapping: HP-SL230-4PORT,
role: COMPUTE-ROLE, server-group: RACK2}
- {id: osd1, ilo-ip: 172.30.0.86, ilo-password: Harp, ilo-user: Administrator, ip-addr: 172.16.60.9,
mac-addr: '5c:b9:01:8d:6b:68', nic-mapping: HP-DL360-8PORT, role: OSD-ROLE, server-group: RACK1}
- {id: osd2, ilo-ip: 172.30.0.87, ilo-password: Kronenburg, ilo-user: Administrator,
ip-addr: 172.16.60.10, mac-addr: '5c:b9:01:8d:70:0c', nic-mapping: HP-DL360-8PORT,
role: OSD-ROLE, server-group: RACK2}
- {id: osd3, ilo-ip: 172.30.0.88, ilo-password: Carlsberg, ilo-user: Administrator,
ip-addr: 172.16.60.11, mac-addr: '5c:b9:01:8d:73:dc', nic-mapping: HP-DL360-8PORT,
role: OSD-ROLE, server-group: RACK3}
警告
私はプログラマーではありません。Python を見たのはこれが初めてです – 使用する前にすべてのファイルをバックアップし、ラボでテストしてください。エラーチェックは含まれていません – 無効なファイル名を入力するとスクリプトはクラッシュします – Python により慣れれば、時間がある限り try/catch エラー制御を追加するつもりです。
更新: 暗号化されたキーの先頭に必要なプレフィックスを含めるようにコードを修正しました。また、出力ファイルのフォーマットを、入力ファイルとより一貫性のあるものに変更しました。
Originally published on allthingscloud.eu (2016-01-16).