From d5efec8885e9a8e37ec309ea3304a554c039d435 Mon Sep 17 00:00:00 2001 From: Anders Ingemann Date: Sat, 3 May 2014 12:56:40 +0200 Subject: [PATCH] Add ssh_group, which configures SSH properly --- bootstrapvz/common/task_groups.py | 11 ++- bootstrapvz/common/tasks/cleanup.py | 18 ----- bootstrapvz/common/tasks/initd.py | 23 ------ bootstrapvz/common/tasks/security.py | 23 ------ bootstrapvz/common/tasks/ssh.py | 80 +++++++++++++++++++ bootstrapvz/plugins/cloud_init/__init__.py | 3 +- bootstrapvz/plugins/root_password/__init__.py | 4 +- bootstrapvz/plugins/vagrant/__init__.py | 7 +- bootstrapvz/providers/azure/__init__.py | 5 +- bootstrapvz/providers/azure/tasks/packages.py | 1 - bootstrapvz/providers/ec2/__init__.py | 1 - bootstrapvz/providers/ec2/tasks/packages.py | 1 - bootstrapvz/providers/gce/__init__.py | 3 +- bootstrapvz/providers/kvm/__init__.py | 5 +- bootstrapvz/providers/kvm/tasks/packages.py | 1 - bootstrapvz/providers/virtualbox/__init__.py | 1 - 16 files changed, 107 insertions(+), 80 deletions(-) create mode 100644 bootstrapvz/common/tasks/ssh.py diff --git a/bootstrapvz/common/task_groups.py b/bootstrapvz/common/task_groups.py index 882476f..df05ca4 100644 --- a/bootstrapvz/common/task_groups.py +++ b/bootstrapvz/common/task_groups.py @@ -11,6 +11,8 @@ from tasks import apt from tasks import security from tasks import locale from tasks import network +from tasks import initd +from tasks import ssh def get_standard_groups(manifest): @@ -67,9 +69,12 @@ mounting_group = [filesystem.CreateMountDir, filesystem.DeleteMountDir, ] -ssh_group = [security.DisableSSHPasswordAuthentication, - security.DisableSSHDNSLookup, - cleanup.ShredHostkeys, +ssh_group = [ssh.AddOpenSSHPackage, + ssh.DisableSSHPasswordAuthentication, + ssh.DisableSSHDNSLookup, + ssh.AddSSHKeyGeneration, + initd.InstallInitScripts, + ssh.ShredHostkeys, ] diff --git a/bootstrapvz/common/tasks/cleanup.py b/bootstrapvz/common/tasks/cleanup.py index 33957da..471c1e8 100644 --- a/bootstrapvz/common/tasks/cleanup.py +++ b/bootstrapvz/common/tasks/cleanup.py @@ -14,24 +14,6 @@ class ClearMOTD(Task): pass -class ShredHostkeys(Task): - description = 'Securely deleting ssh hostkeys' - phase = phases.system_cleaning - - @classmethod - def run(cls, info): - ssh_hostkeys = ['ssh_host_dsa_key', - 'ssh_host_rsa_key'] - if info.manifest.system['release'] != 'squeeze': - ssh_hostkeys.append('ssh_host_ecdsa_key') - - private = [os.path.join(info.root, 'etc/ssh', name) for name in ssh_hostkeys] - public = [path + '.pub' for path in private] - - from ..tools import log_check_call - log_check_call(['shred', '--remove'] + private + public) - - class CleanTMP(Task): description = 'Removing temporary files' phase = phases.system_cleaning diff --git a/bootstrapvz/common/tasks/initd.py b/bootstrapvz/common/tasks/initd.py index 97adb89..1bb51d4 100644 --- a/bootstrapvz/common/tasks/initd.py +++ b/bootstrapvz/common/tasks/initd.py @@ -38,29 +38,6 @@ class AddExpandRoot(Task): info.initd['install']['expand-root'] = os.path.join(init_scripts_dir, 'expand-root') -class AddSSHKeyGeneration(Task): - description = 'Adding SSH private key generation init scripts' - phase = phases.system_modification - successors = [InstallInitScripts] - - @classmethod - def run(cls, info): - init_scripts_dir = os.path.join(assets, 'init.d') - install = info.initd['install'] - from subprocess import CalledProcessError - try: - log_check_call(['chroot', info.root, - 'dpkg-query', '-W', 'openssh-server']) - if info.manifest.system['release'] == 'squeeze': - install['generate-ssh-hostkeys'] = os.path.join(init_scripts_dir, 'squeeze/generate-ssh-hostkeys') - else: - install['generate-ssh-hostkeys'] = os.path.join(init_scripts_dir, 'generate-ssh-hostkeys') - except CalledProcessError: - import logging - logging.getLogger(__name__).warn('The OpenSSH server has not been installed, ' - 'not installing SSH host key generation script.') - - class RemoveHWClock(Task): description = 'Removing hardware clock init scripts' phase = phases.system_modification diff --git a/bootstrapvz/common/tasks/security.py b/bootstrapvz/common/tasks/security.py index 37bd575..634b9b6 100644 --- a/bootstrapvz/common/tasks/security.py +++ b/bootstrapvz/common/tasks/security.py @@ -1,6 +1,5 @@ from bootstrapvz.base import Task from .. import phases -import os.path class EnableShadowConfig(Task): @@ -11,25 +10,3 @@ class EnableShadowConfig(Task): def run(cls, info): from ..tools import log_check_call log_check_call(['chroot', info.root, 'shadowconfig', 'on']) - - -class DisableSSHPasswordAuthentication(Task): - description = 'Disabling SSH password authentication' - phase = phases.system_modification - - @classmethod - def run(cls, info): - from ..tools import sed_i - sshd_config_path = os.path.join(info.root, 'etc/ssh/sshd_config') - sed_i(sshd_config_path, '^#PasswordAuthentication yes', 'PasswordAuthentication no') - - -class DisableSSHDNSLookup(Task): - description = 'Disabling sshd remote host name lookup' - phase = phases.system_modification - - @classmethod - def run(cls, info): - sshd_config_path = os.path.join(info.root, 'etc/ssh/sshd_config') - with open(sshd_config_path, 'a') as sshd_config: - sshd_config.write('UseDNS no') diff --git a/bootstrapvz/common/tasks/ssh.py b/bootstrapvz/common/tasks/ssh.py new file mode 100644 index 0000000..242330d --- /dev/null +++ b/bootstrapvz/common/tasks/ssh.py @@ -0,0 +1,80 @@ +from bootstrapvz.base import Task +from .. import phases +from ..tools import log_check_call +import os.path +from . import assets +import apt +import initd + + +class AddOpenSSHPackage(Task): + description = 'Adding openssh package' + phase = phases.preparation + predecessors = [apt.AddDefaultSources] + + @classmethod + def run(cls, info): + info.packages.add('openssh-server') + + +class AddSSHKeyGeneration(Task): + description = 'Adding SSH private key generation init scripts' + phase = phases.system_modification + successors = [initd.InstallInitScripts] + + @classmethod + def run(cls, info): + init_scripts_dir = os.path.join(assets, 'init.d') + install = info.initd['install'] + from subprocess import CalledProcessError + try: + log_check_call(['chroot', info.root, + 'dpkg-query', '-W', 'openssh-server']) + if info.manifest.system['release'] == 'squeeze': + install['generate-ssh-hostkeys'] = os.path.join(init_scripts_dir, 'squeeze/generate-ssh-hostkeys') + else: + install['generate-ssh-hostkeys'] = os.path.join(init_scripts_dir, 'generate-ssh-hostkeys') + except CalledProcessError: + import logging + logging.getLogger(__name__).warn('The OpenSSH server has not been installed, ' + 'not installing SSH host key generation script.') + + +class DisableSSHPasswordAuthentication(Task): + description = 'Disabling SSH password authentication' + phase = phases.system_modification + + @classmethod + def run(cls, info): + from ..tools import sed_i + sshd_config_path = os.path.join(info.root, 'etc/ssh/sshd_config') + sed_i(sshd_config_path, '^#PasswordAuthentication yes', 'PasswordAuthentication no') + + +class DisableSSHDNSLookup(Task): + description = 'Disabling sshd remote host name lookup' + phase = phases.system_modification + + @classmethod + def run(cls, info): + sshd_config_path = os.path.join(info.root, 'etc/ssh/sshd_config') + with open(sshd_config_path, 'a') as sshd_config: + sshd_config.write('UseDNS no') + + +class ShredHostkeys(Task): + description = 'Securely deleting ssh hostkeys' + phase = phases.system_cleaning + + @classmethod + def run(cls, info): + ssh_hostkeys = ['ssh_host_dsa_key', + 'ssh_host_rsa_key'] + if info.manifest.system['release'] != 'squeeze': + ssh_hostkeys.append('ssh_host_ecdsa_key') + + private = [os.path.join(info.root, 'etc/ssh', name) for name in ssh_hostkeys] + public = [path + '.pub' for path in private] + + from ..tools import log_check_call + log_check_call(['shred', '--remove'] + private + public) diff --git a/bootstrapvz/plugins/cloud_init/__init__.py b/bootstrapvz/plugins/cloud_init/__init__.py index a207e2f..c08eebe 100644 --- a/bootstrapvz/plugins/cloud_init/__init__.py +++ b/bootstrapvz/plugins/cloud_init/__init__.py @@ -10,6 +10,7 @@ def resolve_tasks(taskset, manifest): import tasks import bootstrapvz.providers.ec2.tasks.initd as initd_ec2 from bootstrapvz.common.tasks import initd + from bootstrapvz.common.tasks import ssh if manifest.system['release'] in ['wheezy', 'stable']: taskset.add(tasks.AddBackports) @@ -27,4 +28,4 @@ def resolve_tasks(taskset, manifest): taskset.discard(initd_ec2.AddEC2InitScripts) taskset.discard(initd.AddExpandRoot) taskset.discard(initd.AdjustExpandRootScript) - taskset.discard(initd.AddSSHKeyGeneration) + taskset.discard(ssh.AddSSHKeyGeneration) diff --git a/bootstrapvz/plugins/root_password/__init__.py b/bootstrapvz/plugins/root_password/__init__.py index e93aa90..7ca6870 100644 --- a/bootstrapvz/plugins/root_password/__init__.py +++ b/bootstrapvz/plugins/root_password/__init__.py @@ -7,7 +7,7 @@ def validate_manifest(data, validator, error): def resolve_tasks(taskset, manifest): - from bootstrapvz.common.tasks.security import DisableSSHPasswordAuthentication + from bootstrapvz.common.tasks import ssh from tasks import SetRootPassword - taskset.discard(DisableSSHPasswordAuthentication) + taskset.discard(ssh.DisableSSHPasswordAuthentication) taskset.add(SetRootPassword) diff --git a/bootstrapvz/plugins/vagrant/__init__.py b/bootstrapvz/plugins/vagrant/__init__.py index c84de64..e0b1fc1 100644 --- a/bootstrapvz/plugins/vagrant/__init__.py +++ b/bootstrapvz/plugins/vagrant/__init__.py @@ -8,9 +8,12 @@ def validate_manifest(data, validator, error): def resolve_tasks(taskset, manifest): - from bootstrapvz.common.tasks import security + from bootstrapvz.common import task_groups + from bootstrapvz.common.tasks import ssh + taskset.update(task_groups.ssh_group) + taskset.discard(ssh.DisableSSHPasswordAuthentication) + from bootstrapvz.common.tasks import loopback - taskset.discard(security.DisableSSHPasswordAuthentication) taskset.discard(loopback.MoveImage) from bootstrapvz.common.tasks import volume diff --git a/bootstrapvz/providers/azure/__init__.py b/bootstrapvz/providers/azure/__init__.py index 0d7d015..ebd34e4 100644 --- a/bootstrapvz/providers/azure/__init__.py +++ b/bootstrapvz/providers/azure/__init__.py @@ -9,6 +9,7 @@ from bootstrapvz.common.tasks import bootstrap from bootstrapvz.common.tasks import security from bootstrapvz.common.tasks import network from bootstrapvz.common.tasks import initd +from bootstrapvz.common.tasks import ssh from bootstrapvz.common.tasks import cleanup from bootstrapvz.common.tasks import workspace @@ -33,8 +34,10 @@ def resolve_tasks(taskset, manifest): taskset.update([tasks.packages.DefaultPackages, loopback.Create, security.EnableShadowConfig, - initd.AddSSHKeyGeneration, initd.InstallInitScripts, + ssh.AddOpenSSHPackage, + ssh.ShredHostkeys, + ssh.AddSSHKeyGeneration, tasks.packages.Waagent, tasks.boot.ConfigureGrub, tasks.image.ConvertToVhd, diff --git a/bootstrapvz/providers/azure/tasks/packages.py b/bootstrapvz/providers/azure/tasks/packages.py index efcb67f..6cb4fa0 100644 --- a/bootstrapvz/providers/azure/tasks/packages.py +++ b/bootstrapvz/providers/azure/tasks/packages.py @@ -16,7 +16,6 @@ class DefaultPackages(Task): info.packages.add(kernels.get(info.manifest.system['architecture'])) info.packages.add('openssl') info.packages.add('python-openssl') - info.packages.add('openssh-server') info.packages.add('python-pyasn1') info.packages.add('sudo') diff --git a/bootstrapvz/providers/ec2/__init__.py b/bootstrapvz/providers/ec2/__init__.py index 59c47a6..5d0f295 100644 --- a/bootstrapvz/providers/ec2/__init__.py +++ b/bootstrapvz/providers/ec2/__init__.py @@ -66,7 +66,6 @@ def resolve_tasks(taskset, manifest): security.EnableShadowConfig, tasks.network.EnableDHCPCDDNS, initd.AddExpandRoot, - initd.AddSSHKeyGeneration, initd.RemoveHWClock, tasks.initd.AddEC2InitScripts, initd.InstallInitScripts, diff --git a/bootstrapvz/providers/ec2/tasks/packages.py b/bootstrapvz/providers/ec2/tasks/packages.py index 62107cd..596d3fb 100644 --- a/bootstrapvz/providers/ec2/tasks/packages.py +++ b/bootstrapvz/providers/ec2/tasks/packages.py @@ -10,7 +10,6 @@ class DefaultPackages(Task): @classmethod def run(cls, info): - info.packages.add('openssh-server') info.packages.add('file') # Needed for the init scripts info.packages.add('dhcpcd') # isc-dhcp-client doesn't work properly with ec2 diff --git a/bootstrapvz/providers/gce/__init__.py b/bootstrapvz/providers/gce/__init__.py index a9c464d..975d4cf 100644 --- a/bootstrapvz/providers/gce/__init__.py +++ b/bootstrapvz/providers/gce/__init__.py @@ -5,6 +5,7 @@ import tasks.image import tasks.host import tasks.packages from bootstrapvz.common.tasks import loopback +from bootstrapvz.common.tasks import ssh from bootstrapvz.common.tasks import security from bootstrapvz.common.tasks import initd import bootstrapvz.plugins.cloud_init.tasks @@ -36,7 +37,7 @@ def resolve_tasks(tasklist, manifest): security.EnableShadowConfig, tasks.host.DisableIPv6, tasks.boot.ConfigureGrub, - initd.AddSSHKeyGeneration, + ssh.AddSSHKeyGeneration, tasks.apt.CleanGoogleRepositoriesAndKeys, loopback.MoveImage, diff --git a/bootstrapvz/providers/kvm/__init__.py b/bootstrapvz/providers/kvm/__init__.py index 2343ef1..0e24cef 100644 --- a/bootstrapvz/providers/kvm/__init__.py +++ b/bootstrapvz/providers/kvm/__init__.py @@ -7,6 +7,7 @@ from bootstrapvz.common.tasks import bootstrap from bootstrapvz.common.tasks import security from bootstrapvz.common.tasks import network from bootstrapvz.common.tasks import initd +from bootstrapvz.common.tasks import ssh from bootstrapvz.common.tasks import cleanup from bootstrapvz.common.tasks import workspace @@ -31,8 +32,10 @@ def resolve_tasks(taskset, manifest): taskset.update([tasks.packages.DefaultPackages, loopback.Create, security.EnableShadowConfig, - initd.AddSSHKeyGeneration, initd.InstallInitScripts, + ssh.AddOpenSSHPackage, + ssh.ShredHostkeys, + ssh.AddSSHKeyGeneration, loopback.MoveImage, ]) diff --git a/bootstrapvz/providers/kvm/tasks/packages.py b/bootstrapvz/providers/kvm/tasks/packages.py index 97eec67..85ad028 100644 --- a/bootstrapvz/providers/kvm/tasks/packages.py +++ b/bootstrapvz/providers/kvm/tasks/packages.py @@ -13,4 +13,3 @@ class DefaultPackages(Task): kernels = {'amd64': 'linux-image-amd64', 'i386': 'linux-image-686', } info.packages.add(kernels.get(info.manifest.system['architecture'])) - info.packages.add('openssh-server') diff --git a/bootstrapvz/providers/virtualbox/__init__.py b/bootstrapvz/providers/virtualbox/__init__.py index 882c971..f33d5f2 100644 --- a/bootstrapvz/providers/virtualbox/__init__.py +++ b/bootstrapvz/providers/virtualbox/__init__.py @@ -31,7 +31,6 @@ def resolve_tasks(taskset, manifest): taskset.update([tasks.packages.DefaultPackages, loopback.Create, security.EnableShadowConfig, - initd.AddSSHKeyGeneration, initd.InstallInitScripts, loopback.MoveImage, ])