mirror of
https://github.com/kevingruesser/bootstrap-vz.git
synced 2025-08-22 18:00:35 +00:00
[admin_user]: Added support for password and static pubkey auth
This commit adds authentication optionally with passwords or static ssh pubkeys for the admin user. There are now three ways to grant access to the admin user: - Set a password for the user, or - Provide a ssh public key to allow remote ssh login, or - Use the EC2 public key (EC2 machines only) If a password is provided, this plugin sets the admin password. This also re-enables password login (off by default in Jessie). If the optional argument pubkey is present (it should be a full path to a ssh public key), it will ensure that the ssh public key is used to set up password less remote login for the admin user. Only one of these options (password, or pubkey) may be specified. If neither the password not a ssh public key location are specified, and if the EC2 init scripts are installed, the script for fetching the SSH authorized keys will be adjust to match the username specified. Fixes: https://github.com/andsens/bootstrap-vz/issues/248 Signed-off-by: Manoj Srivastava <srivasta@google.com>
This commit is contained in:
parent
5189c03e8a
commit
67284eaae5
4 changed files with 90 additions and 11 deletions
|
@ -2,11 +2,29 @@ Admin user
|
|||
----------
|
||||
|
||||
This plugin creates a user with passwordless sudo privileges. It also
|
||||
disables the SSH root login. If the EC2 init scripts are installed, the
|
||||
script for fetching the SSH authorized keys will be adjust to match the
|
||||
username specified.
|
||||
disables the SSH root login. There are three ways to grant access to
|
||||
the admin user:
|
||||
- Set a password for the user, or
|
||||
- Provide a ssh public key to allow remote ssh login, or
|
||||
- Use the EC2 public key (EC2 machines only)
|
||||
|
||||
If a password is provided, this plugin sets the admin password. This
|
||||
also re-enables password login (off by default in Jessie).
|
||||
|
||||
If the optional argument pubkey is present (it should be a full path
|
||||
to a ssh public key), it will ensure that the ssh public key is used
|
||||
to set up password less remote login for the admin user.
|
||||
|
||||
Only one of these options (password, or pubkey) may be specified.
|
||||
|
||||
If neither the password not a ssh public key location are specified,
|
||||
and if the EC2 init scripts are installed, the script for fetching the
|
||||
SSH authorized keys will be adjust to match the username specified.
|
||||
|
||||
Settings
|
||||
~~~~~~~~
|
||||
|
||||
- ``username``: The username of the account to create. ``required``
|
||||
- ``password``: An optional password for the account to create. ``optional``
|
||||
- ``pubkey``: The full path to an ssh public key to allow
|
||||
remote access into the admin account. ``optional``
|
||||
|
|
|
@ -10,13 +10,18 @@ def resolve_tasks(taskset, manifest):
|
|||
import tasks
|
||||
from bootstrapvz.common.tasks import ssh
|
||||
from bootstrapvz.providers.ec2.tasks import initd
|
||||
if initd.AddEC2InitScripts in taskset:
|
||||
taskset.add(tasks.AdminUserCredentials)
|
||||
|
||||
from bootstrapvz.common.releases import jessie
|
||||
if manifest.release < jessie:
|
||||
taskset.update([ssh.DisableRootLogin])
|
||||
|
||||
if 'password' in manifest.plugins['admin_user']:
|
||||
taskset.discard(ssh.DisableSSHPasswordAuthentication)
|
||||
taskset.add(tasks.AdminUserCredentials)
|
||||
else:
|
||||
if initd.AddEC2InitScripts in taskset or 'pubkey' in manifest.plugins['admin_user']:
|
||||
taskset.add(tasks.AdminUserCredentials)
|
||||
|
||||
taskset.update([tasks.AddSudoPackage,
|
||||
tasks.CreateAdminUser,
|
||||
tasks.PasswordlessSudo,
|
||||
|
|
|
@ -10,5 +10,11 @@ properties:
|
|||
type: object
|
||||
properties:
|
||||
username: {type: string}
|
||||
password: {type: string}
|
||||
pubkey: {$ref: '#/definitions/absolute_path'}
|
||||
required: [username]
|
||||
additionalProperties: false
|
||||
definitions:
|
||||
absolute_path:
|
||||
pattern: ^/[^\0]+$
|
||||
type: string
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
from bootstrapvz.base import Task
|
||||
from bootstrapvz.common import phases
|
||||
from bootstrapvz.common.tasks.initd import InstallInitScripts
|
||||
import logging
|
||||
import os
|
||||
|
||||
|
||||
|
@ -42,13 +43,62 @@ class PasswordlessSudo(Task):
|
|||
|
||||
|
||||
class AdminUserCredentials(Task):
|
||||
description = 'Modifying ec2-get-credentials to copy the ssh public key to the admin user'
|
||||
description = 'Set up access credentials for the admin user'
|
||||
phase = phases.system_modification
|
||||
predecessors = [InstallInitScripts]
|
||||
predecessors = [InstallInitScripts, CreateAdminUser]
|
||||
|
||||
@classmethod
|
||||
def run(cls, info):
|
||||
from bootstrapvz.common.tools import sed_i
|
||||
getcreds_path = os.path.join(info.root, 'etc/init.d/ec2-get-credentials')
|
||||
username = info.manifest.plugins['admin_user']['username']
|
||||
sed_i(getcreds_path, 'username=\'root\'', 'username=\'{username}\''.format(username=username))
|
||||
from bootstrapvz.common.exceptions import TaskError
|
||||
from bootstrapvz.common.tools import sed_i
|
||||
from bootstrapvz.common.tools import log_check_call
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
if 'password' in info.manifest.plugins['admin_user']:
|
||||
if 'pubkey' in info.manifest.plugins['admin_user']:
|
||||
msg = 'The options password and pubkey are mutually exclusive'
|
||||
raise TaskError(msg)
|
||||
log_check_call(['chroot', info.root, 'chpasswd'],
|
||||
info.manifest.plugins['admin_user']['username'] +
|
||||
':' + info.manifest.plugins['admin_user']['password'])
|
||||
return
|
||||
|
||||
getcreds_path = os.path.join(info.root, 'etc/init.d/ec2-get-credentials')
|
||||
if 'pubkey' in info.manifest.plugins['admin_user']:
|
||||
import stat
|
||||
from shutil import copy
|
||||
full_path = info.manifest.plugins['admin_user']['pubkey']
|
||||
if not os.path.exists(full_path):
|
||||
msg = 'Could not find public key at {full_path}'.format(full_path=full_path)
|
||||
raise TaskError(msg)
|
||||
log.debug('Copying public key from {path}'.format(path=full_path))
|
||||
|
||||
if os.path.exists(getcreds_path):
|
||||
log.warn('You are using a static public key for the admin account.'
|
||||
' This will conflict with the ec2 public key njection mechanisn.'
|
||||
' The ec2-get-credentials startup script has therefore been disabled.')
|
||||
log_check_call(['chroot', info.root, 'insserv', '--remove',
|
||||
'ec2-get-credentials'])
|
||||
username = info.manifest.plugins['admin_user']['username']
|
||||
|
||||
ssh_file = os.path.join('/home/'
|
||||
'{username}/.ssh/authorized_keys'.format(username=username))
|
||||
rel_ssh_file = os.path.realpath(info.root + '/{ssh_file}'.format(ssh_file=ssh_file))
|
||||
|
||||
ssh_dir = os.path.dirname(ssh_file)
|
||||
rel_ssh_dir = os.path.realpath(info.root + '/{ssh_dir}'.format(ssh_dir=ssh_dir))
|
||||
if not os.path.exists(rel_ssh_dir):
|
||||
log.debug('Creating {ssh_dir} mode 700'.format(ssh_dir=rel_ssh_dir))
|
||||
os.mkdir(rel_ssh_dir, 0700)
|
||||
else:
|
||||
log.debug('setting {ssh_dir} mode 700'.format(ssh_dir=rel_ssh_dir))
|
||||
os.chmod(rel_ssh_dir, 0700)
|
||||
copy(full_path, rel_ssh_file)
|
||||
mode = (stat.S_IRUSR | stat.S_IWUSR)
|
||||
os.chmod(rel_ssh_file, mode)
|
||||
log_check_call(['chroot', info.root, 'chown', '-R', username, ssh_dir])
|
||||
return
|
||||
|
||||
log.debug('Updating EC2 get credentials script.')
|
||||
username = info.manifest.plugins['admin_user']['username']
|
||||
sed_i(getcreds_path, 'username=\'root\'', 'username=\'{username}\''.format(username=username))
|
||||
|
|
Loading…
Add table
Reference in a new issue