#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 subprocess 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/ubuntu', '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.' runcmd: - 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 - systemctl restart ssh