tatu/files/user-cloud-config
2018-01-19 16:56:26 -06:00

114 lines
4.7 KiB
Plaintext

#cloud-config
mounts:
- [ /dev/disk/by-label/config-2, /mnt/config ]
packages:
- python
- python-requests
write_files:
- path: /root/setup-ssh.py
permissions: '0700'
owner: root:root
content: |
print 'Importing packages'
import json
import requests
import os
import uuid
def getVendordataFromConfigDrive():
path = '/mnt/config/openstack/latest/vendor_data2.json'
with open(path, 'r') as f:
json_string = f.read()
return json.loads(json_string)
def getInstanceAndProjectIdFromConfigDrive():
path = '/mnt/config/openstack/latest/meta_data.json'
with open(path, 'r') as f:
json_string = f.read()
metadata = json.loads(json_string)
assert 'uuid' in metadata
assert 'project_id' in metadata
return str(uuid.UUID(metadata['uuid'], version=4)), str(uuid.UUID(metadata['project_id'], version=4))
print 'Getting vendordata from ConfigDrive'
vendordata = getVendordataFromConfigDrive()
print 'Getting instance and project IDs'
instance_id, project_id = getInstanceAndProjectIdFromConfigDrive()
assert 'tatu' in vendordata
tatu = vendordata['tatu']
assert 'token' in tatu
assert 'auth_pub_key_user' in tatu
assert 'principals' in tatu
principals = tatu['principals'].split(',')
with open('/etc/ssh/ssh_host_rsa_key.pub', 'r') as f:
host_key_pub = f.read()
server = 'http://172.24.4.1:18322'
hostcert_request = {
'token_id': tatu['token'],
'host_id': instance_id,
'key.pub': host_key_pub
}
print 'Request the host certificate.'
response = requests.post(
# Hard-coded SSHaaS API address will only work for devstack and requires
# routing and SNAT or DNAT.
# This eventually needs to be either:
# 1) 169.254.169.254 if there's a SSHaaS-proxy; OR
# 2) the real address of the API, possibly supplied in the vendordata and
# still requiring routing and SNAT or DNAT.
server + '/noauth/hostcerts',
data=json.dumps(hostcert_request)
)
print 'Got the host certificate: {}'.format(response.content)
assert response.status_code == 201
assert 'location' in response.headers
location = response.headers['location']
# No need to GET the host cert - it's returned in the POST
#response = requests.get(server + location)
hostcert = json.loads(response.content)
assert 'host_id' in hostcert
assert hostcert['host_id'] == instance_id
assert 'fingerprint' in hostcert
assert 'auth_id' in hostcert
auth_id = str(uuid.UUID(hostcert['auth_id'], version=4))
assert auth_id == project_id
assert 'key-cert.pub' in hostcert
print 'Begin writing files.'
# Write the host's certificate
with open('/etc/ssh/ssh_host_rsa_key-cert.pub', 'w') as f:
f.write(hostcert['key-cert.pub'])
# Write the authorized principals file
os.mkdir('/etc/ssh/auth_principals')
with open('/etc/ssh/auth_principals/root', 'w') as f:
for p in principals:
f.write(p + os.linesep)
# Write the User CA public key file
with open('/etc/ssh/ca_user.pub', 'w') as f:
f.write(tatu['auth_pub_key_user'])
print 'All tasks completed.'
- path: /root/manage-revoked_keys.py
permissions: '0700'
owner: root:root
content: |
import base64
import json
import requests
import uuid
path = '/mnt/config/openstack/latest/meta_data.json'
with open(path, 'r') as f:
json_string = f.read()
metadata = json.loads(json_string)
auth_id = str(uuid.UUID(metadata['project_id'], version=4))
response = requests.get(server + '/noauth/revokedkeys/' + auth_id)
assert response.status_code == 200
body = json.loads(response.content)
assert 'revoked_keys_data' in body
with open('/etc/ssh/revoked-keys', 'w') as f:
f.write(base64.b64decode(crl_body['revoked_keys_data']))
runcmd:
- dnf install -y python python-requests
- python /root/setup-ssh.py > /var/log/setup-ssh.log 2>&1
- sed -i -e '$aTrustedUserCAKeys /etc/ssh/ca_user.pub' /etc/ssh/sshd_config
- sed -i -e '$aAuthorizedPrincipalsFile /etc/ssh/auth_principals/%u' /etc/ssh/sshd_config
- sed -i -e '$aHostCertificate /etc/ssh/ssh_host_rsa_key-cert.pub' /etc/ssh/sshd_config
- python /root/manage-revoked-keys.py >> /var/log/setup-ssh.log 2>&1
- sed -i -e '$aRevokedKeys /etc/ssh/revoked-keys' /etc/ssh/sshd_config
- systemctl restart sshd