X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=ceph%2Fqa%2Ftasks%2Fcephadm.py;h=e9fc25d6a86d17d1143466eecc0bf74cf5f34053;hb=aee94f6923ba628a85d855d0c5316d0da78bfa2a;hp=84685b824bf462e669e1099310f85f3e73580603;hpb=27f45121cc74e31203777ad565f78d8aad9b92a2;p=ceph.git diff --git a/ceph/qa/tasks/cephadm.py b/ceph/qa/tasks/cephadm.py index 84685b824..e9fc25d6a 100644 --- a/ceph/qa/tasks/cephadm.py +++ b/ceph/qa/tasks/cephadm.py @@ -441,6 +441,70 @@ def pull_image(ctx, config): finally: pass +@contextlib.contextmanager +def setup_ca_signed_keys(ctx, config): + # generate our ca key + cluster_name = config['cluster'] + bootstrap_remote = ctx.ceph[cluster_name].bootstrap_remote + bootstrap_remote.run(args=[ + 'sudo', 'ssh-keygen', '-t', 'rsa', '-f', '/root/ca-key', '-N', '' + ]) + + # not using read_file here because it runs dd as a non-root + # user and would hit permission issues + r = bootstrap_remote.run(args=[ + 'sudo', 'cat', '/root/ca-key.pub' + ], stdout=StringIO()) + ca_key_pub_contents = r.stdout.getvalue() + + # make CA key accepted on each host + for remote in ctx.cluster.remotes.keys(): + # write key to each host's /etc/ssh dir + remote.run(args=[ + 'sudo', 'echo', ca_key_pub_contents, + run.Raw('|'), + 'sudo', 'tee', '-a', '/etc/ssh/ca-key.pub', + ]) + # make sshd accept the CA signed key + remote.run(args=[ + 'sudo', 'echo', 'TrustedUserCAKeys /etc/ssh/ca-key.pub', + run.Raw('|'), + 'sudo', 'tee', '-a', '/etc/ssh/sshd_config', + run.Raw('&&'), + 'sudo', 'systemctl', 'restart', 'sshd', + ]) + + # generate a new key pair and sign the pub key to make a cert + bootstrap_remote.run(args=[ + 'sudo', 'ssh-keygen', '-t', 'rsa', '-f', '/root/cephadm-ssh-key', '-N', '', + run.Raw('&&'), + 'sudo', 'ssh-keygen', '-s', '/root/ca-key', '-I', 'user_root', '-n', 'root', '-V', '+52w', '/root/cephadm-ssh-key', + ]) + + # for debugging, to make sure this setup has worked as intended + for remote in ctx.cluster.remotes.keys(): + remote.run(args=[ + 'sudo', 'cat', '/etc/ssh/ca-key.pub' + ]) + remote.run(args=[ + 'sudo', 'cat', '/etc/ssh/sshd_config', + run.Raw('|'), + 'grep', 'TrustedUserCAKeys' + ]) + bootstrap_remote.run(args=[ + 'sudo', 'ls', '/root/' + ]) + + ctx.ca_signed_key_info = {} + ctx.ca_signed_key_info['ca-key'] = '/root/ca-key' + ctx.ca_signed_key_info['ca-key-pub'] = '/root/ca-key.pub' + ctx.ca_signed_key_info['private-key'] = '/root/cephadm-ssh-key' + ctx.ca_signed_key_info['ca-signed-cert'] = '/root/cephadm-ssh-key-cert.pub' + + try: + yield + finally: + pass @contextlib.contextmanager def ceph_bootstrap(ctx, config): @@ -510,8 +574,20 @@ def ceph_bootstrap(ctx, config): '--output-config', '/etc/ceph/{}.conf'.format(cluster_name), '--output-keyring', '/etc/ceph/{}.client.admin.keyring'.format(cluster_name), - '--output-pub-ssh-key', '{}/{}.pub'.format(testdir, cluster_name), ] + + if not config.get("use-ca-signed-key", False): + cmd += ['--output-pub-ssh-key', '{}/{}.pub'.format(testdir, cluster_name)] + else: + # ctx.ca_signed_key_info should have been set up in + # setup_ca_signed_keys function which we expect to have + # run before bootstrap if use-ca-signed-key is true + signed_key_info = ctx.ca_signed_key_info + cmd += [ + "--ssh-private-key", signed_key_info['private-key'], + "--ssh-signed-cert", signed_key_info['ca-signed-cert'], + ] + if config.get("no_cgroups_split") is True: cmd.insert(cmd.index("bootstrap"), "--no-cgroups-split") @@ -562,21 +638,22 @@ def ceph_bootstrap(ctx, config): ctx.ceph[cluster_name].mon_keyring = \ bootstrap_remote.read_file(f'/var/lib/ceph/{fsid}/mon.{first_mon}/keyring', sudo=True) - # fetch ssh key, distribute to additional nodes - log.info('Fetching pub ssh key...') - ssh_pub_key = bootstrap_remote.read_file( - f'{testdir}/{cluster_name}.pub').decode('ascii').strip() + if not config.get("use-ca-signed-key", False): + # fetch ssh key, distribute to additional nodes + log.info('Fetching pub ssh key...') + ssh_pub_key = bootstrap_remote.read_file( + f'{testdir}/{cluster_name}.pub').decode('ascii').strip() - log.info('Installing pub ssh key for root users...') - ctx.cluster.run(args=[ - 'sudo', 'install', '-d', '-m', '0700', '/root/.ssh', - run.Raw('&&'), - 'echo', ssh_pub_key, - run.Raw('|'), - 'sudo', 'tee', '-a', '/root/.ssh/authorized_keys', - run.Raw('&&'), - 'sudo', 'chmod', '0600', '/root/.ssh/authorized_keys', - ]) + log.info('Installing pub ssh key for root users...') + ctx.cluster.run(args=[ + 'sudo', 'install', '-d', '-m', '0700', '/root/.ssh', + run.Raw('&&'), + 'echo', ssh_pub_key, + run.Raw('|'), + 'sudo', 'tee', '-a', '/root/.ssh/authorized_keys', + run.Raw('&&'), + 'sudo', 'chmod', '0600', '/root/.ssh/authorized_keys', + ]) # set options if config.get('allow_ptrace', True): @@ -1636,16 +1713,18 @@ def task(ctx, config): with contextutil.nested( #if the cluster is already bootstrapped bypass corresponding methods - lambda: _bypass() if (ctx.ceph[cluster_name].bootstrapped)\ + lambda: _bypass() if (ctx.ceph[cluster_name].bootstrapped) \ else initialize_config(ctx=ctx, config=config), lambda: ceph_initial(), lambda: normalize_hostnames(ctx=ctx), - lambda: _bypass() if (ctx.ceph[cluster_name].bootstrapped)\ + lambda: _bypass() if (ctx.ceph[cluster_name].bootstrapped) \ else download_cephadm(ctx=ctx, config=config, ref=ref), lambda: ceph_log(ctx=ctx, config=config), lambda: ceph_crash(ctx=ctx, config=config), lambda: pull_image(ctx=ctx, config=config), - lambda: _bypass() if (ctx.ceph[cluster_name].bootstrapped)\ + lambda: _bypass() if not (config.get('use-ca-signed-key', False)) \ + else setup_ca_signed_keys(ctx, config), + lambda: _bypass() if (ctx.ceph[cluster_name].bootstrapped) \ else ceph_bootstrap(ctx, config), lambda: crush_setup(ctx=ctx, config=config), lambda: ceph_mons(ctx=ctx, config=config),