Esempio n. 1
0
File: apt.py Progetto: mbr/remand
def add_repo(distribution,
             components=['main'],
             site='http://httpredir.debian.org/debian',
             src=False,
             arch=[],
             name=None):
    comps = ' '.join(components)

    options = ''
    if arch:
        options = ' [ arch={} ]'.format(','.join(arch))

    line = '{}{} {} {} {}\n'.format('deb-src' if src else 'deb',
                                    options,
                                    site,
                                    distribution,
                                    comps, )

    if name is None:
        name = '{}_{}{}'.format(distribution, '_'.join(components), '' if
                                not src else '-sources')

    path = remote.path.join(config['apt_sources_list_d'], name + '.list')
    upload = fs.upload_string(line, path, create_parent=True)

    if upload.changed:
        info_update_timestamp().mark_stale()
        return Changed(msg='Added apt repository: {}'.format(line))
    return Unchanged(msg='Already present: {}'.format(line))
Esempio n. 2
0
def add_repo(distribution,
             components=['main'],
             site='http://deb.debian.org/debian',
             src=False,
             arch=[],
             name=None):
    comps = ' '.join(components)

    options = ''
    if arch:
        options = ' [ arch={} ]'.format(','.join(arch))

    line = '{}{} {} {} {}\n'.format(
        'deb-src' if src else 'deb',
        options,
        site,
        distribution,
        comps,
    )

    if name is None:
        name = '{}_{}{}'.format(distribution, '_'.join(components), ''
                                if not src else '-sources')

    path = remote.path.join(config['apt_sources_list_d'], name + '.list')
    upload = fs.upload_string(line, path, create_parent=True)

    if upload.changed:
        info_update_timestamp().mark_stale()
        return Changed(msg='Added apt repository: {}'.format(line))
    return Unchanged(msg='Already present: {}'.format(line))
Esempio n. 3
0
def run():
    # create source.list.d
    fs.create_dir('/etc/apt/sources.list.d')

    if info['lsb.dist_id'] == 'Ubuntu':
        fs.upload_string(tpl.render(),
                         '/etc/apt/sources.list.d/ubuntu-mirrors.list')
    elif info['lsb.dist_id'] == 'Debian':
        raise NotImplementedError
    else:
        raise NotImplementedError

    # FIXME: do not do this for raspbian, needs os-release check
    fs.remove_file('/etc/apt/sources.list')

    apt.update(max_age=60)
    apt.update(max_age=60)
    apt.update(max_age=60)
Esempio n. 4
0
File: ssl.py Progetto: mbr/remand
def ensure_certificate(hostname):
    cert_rpath = remote.path.join(config['sslcert_cert_dir'],
                                  hostname + '.crt')
    chain_rpath = remote.path.join(config['sslcert_cert_dir'],
                                   hostname + '.chain.crt')
    key_rpath = remote.path.join(config['sslcert_key_dir'], hostname + '.pem')

    # first, ensure any certificate exists on the host. otherwise,
    # webservers like nginx will likely not start
    if not (remote.lstat(cert_rpath) and remote.lstat(key_rpath)
            and remote.lstat(chain_rpath)):
        log.debug('Remote certificate {}, key {}, chain {} not found'.format(
            cert_rpath, key_rpath, chain_rpath))

        key, cert = generate_self_signed_cert(hostname)

        # FIXME: maybe use install cert here.
        fs.upload_string(key, key_rpath)
        fs.upload_string(cert, cert_rpath)
        fs.upload_string(cert, chain_rpath)

        return Changed(
            msg='No certificate {} / key {} / chain {} found. A self-signed '
            'certficate from a reputable snake-oil vendor was installed.'.
            format(cert_rpath, key_rpath, chain_rpath))

    return Unchanged(
        'Certificate for hostname {} already preset'.format(hostname))
Esempio n. 5
0
def install_unit_string(unit_name, buf, reload=True):
    _, ext = os.path.splitext(unit_name)

    if ext not in UNIT_EXTS:
        raise ValueError('unit_name should be one of {}'.format(UNIT_EXTS))

    remote_unit = os.path.join(config['systemd_unit_dir'],
                               os.path.basename(unit_name))

    if fs.upload_string(buf, remote_unit).changed:
        if reload:
            daemon_reload()
        return Changed(msg='Installed {}'.format(remote_unit))

    return Unchanged(msg='{} already installed'.format(remote_unit))
Esempio n. 6
0
def install_unit_string(unit_name, buf, reload=True):
    _, ext = os.path.splitext(unit_name)

    if ext not in UNIT_EXTS:
        raise ValueError('unit_name should be one of {}'.format(UNIT_EXTS))

    remote_unit = os.path.join(config['systemd_unit_dir'],
                               os.path.basename(unit_name))

    if fs.upload_string(buf, remote_unit).changed:
        if reload:
            daemon_reload()
        return Changed(msg='Installed {}'.format(remote_unit))

    return Unchanged(msg='{} already installed'.format(remote_unit))
Esempio n. 7
0
def install_strict_ssh(allow_users=['root'],
                       allow_groups=None,
                       address_family="any",
                       permit_root=True,
                       modern_ciphers=True,
                       sftp_enabled=True,
                       agent_forwarding=False,
                       x11=False,
                       tcp_forwarding=True,
                       unix_forwarding=True,
                       tunnel=False,
                       port=22,
                       use_dns=False,
                       print_motd=False,
                       auto_restart=True,
                       check_sshd_config=True,
                       password_enabled=None):
    # FIXME: change default in jinja templates to strict reporting of missing
    #        values to avoid creating broken ssh configs
    # FIXME: add (possibly generic) support for atomic-tested-configuration
    #        swaps (i.e. run sshd -t on a config)
    tpl = ssh_preset.templates.render(
        'sshd_config',
        allow_users=allow_users,
        allow_groups=allow_groups,
        address_family=address_family,
        permit_root=permit_root,
        modern_ciphers=modern_ciphers,
        sftp_enabled=sftp_enabled,
        agent_forwarding=agent_forwarding,
        x11=x11,
        tcp_forwarding=tcp_forwarding,
        unix_forwarding=unix_forwarding,
        tunnel=tunnel,
        ports=port if isinstance(port, list) else [port],
        print_motd=print_motd,
        password_enabled=password_enabled)

    if fs.upload_string(tpl, '/etc/ssh/sshd_config').changed:
        if check_sshd_config:
            proc.run(['sshd', '-t'])

        # FIXME: we may want to abstract the init-system here
        if auto_restart:
            systemd.restart_unit('ssh.service')
        return Changed(msg='Changed sshd configuration')
    return Unchanged(msg='sshd config already strict')
Esempio n. 8
0
def setup_rsyslog(server_addr):
    # setup papertrail
    # FIXME: this is part of remand now
    changed = False
    changed = apt.install_packages(['rsyslog-gnutls']).changed
    changed |= fs.upload_file(papertrail.files['papertrail-bundle.pem'],
                              '/etc/papertrail-bundle.pem').changed
    changed |= fs.upload_string(
        papertrail.templates.render('papertrail.conf',
                                    addr=server_addr),
        '/etc/rsyslog.d/papertrail.conf', ).changed

    if changed:
        systemd.restart_unit('rsyslog.service')
        return Changed(
            msg='Setup papertrail logging to {}'.format(server_addr))
    return Unchanged(msg='Papertrail already setup to {}'.format(server_addr))
Esempio n. 9
0
def setup_rsyslog(server_addr):
    # setup papertrail
    # FIXME: this is part of remand now
    changed = False
    changed = apt.install_packages(['rsyslog-gnutls']).changed
    changed |= fs.upload_file(papertrail.files['papertrail-bundle.pem'],
                              '/etc/papertrail-bundle.pem').changed
    changed |= fs.upload_string(
        papertrail.templates.render('papertrail.conf', addr=server_addr),
        '/etc/rsyslog.d/papertrail.conf',
    ).changed

    if changed:
        systemd.restart_unit('rsyslog.service')
        return Changed(
            msg='Setup papertrail logging to {}'.format(server_addr))
    return Unchanged(msg='Papertrail already setup to {}'.format(server_addr))
Esempio n. 10
0
def install_strict_ssh(allow_users=['root'],
                       allow_groups=None,
                       address_family="any",
                       permit_root=True,
                       modern_ciphers=True,
                       sftp_enabled=True,
                       agent_forwarding=False,
                       x11=False,
                       tcp_forwarding=True,
                       unix_forwarding=True,
                       tunnel=False,
                       port=22,
                       use_dns=False,
                       print_motd=False,
                       auto_restart=True,
                       check_sshd_config=True):
    # FIXME: change default in jinja templates to strict reporting of missing
    #        values to avoid creating broken ssh configs
    # FIXME: add (possibly generic) support for atomic-tested-configuration
    #        swaps (i.e. run sshd -t on a config)
    tpl = ssh_preset.templates.render('sshd_config',
                                      allow_users=allow_users,
                                      allow_groups=allow_groups,
                                      address_family=address_family,
                                      permit_root=permit_root,
                                      modern_ciphers=modern_ciphers,
                                      sftp_enabled=sftp_enabled,
                                      agent_forwarding=agent_forwarding,
                                      x11=x11,
                                      tcp_forwarding=tcp_forwarding,
                                      unix_forwarding=unix_forwarding,
                                      tunnel=tunnel,
                                      port=port,
                                      print_motd=print_motd)

    if fs.upload_string(tpl, '/etc/ssh/sshd_config').changed:
        if check_sshd_config:
            proc.run(['sshd', '-t'])

        # FIXME: we may want to abstract the init-system here
        if auto_restart:
            systemd.restart_unit('ssh.service')
        return Changed(msg='Changed sshd configuration')
    return Unchanged(msg='sshd config already strict')
Esempio n. 11
0
File: ssh.py Progetto: mbr/remand
def set_authorized_keys(files, user='******', fix_permissions=True):
    ak_file = init_authorized_keys(user, fix_permissions).value

    kf = KeyFile()

    for fn in files:
        kf.add_from_file(fn)

    # directory is guaranteed to exist now, with correct permissions
    upload = fs.upload_string(str(kf), ak_file)

    if upload.changed and fix_permissions:
        fs.chmod(ak_file, AK_FILE_PERMS)

    fps = ', '.join(k.readable_fingerprint for k in kf.keys)

    if upload.changed:
        return Changed(
            msg='SSH authorized keys for {} set to: {}'.format(user, fps))

    return Unchanged(
        msg='SSH authorized keys for {} unchanged ({})'.format(user, fps))
Esempio n. 12
0
def set_hostname(hostname, domain=None, config_only=False):
    prev_hostname = info_hostname()

    changed = False
    changed |= fs.upload_string('{}\n'.format(hostname),
                                '/etc/hostname').changed

    if not config_only and prev_hostname != hostname:
        proc.run(['hostname', hostname])
        changed = True

    # update /etc/hosts
    # this will also set the domain name
    # see http://jblevins.org/log/hostname
    #
    # we adopt the following convention:

    host_line = '127.0.1.1\t' + hostname
    if domain:
        host_line = '127.0.1.1\t{}.{}\t{}'.format(hostname, domain, hostname)

    with fs.edit('/etc/hosts') as hosts:
        if host_line not in hosts.lines():
            hosts.comment_out(r'^127.0.1.1')

            # comment out old lines
            lines = [host_line] + hosts.lines()
            hosts.set_lines(lines)

    changed |= hosts.changed

    if changed:
        info_hostname.invalidate_cache()
        info_fqdn.invalidate_cache()
        return Changed(msg='Hostname changed from {} to {}'.format(
            prev_hostname, hostname))

    return Unchanged(msg='Hostname already set to {}'.format(hostname))
Esempio n. 13
0
File: posix.py Progetto: mbr/remand
def set_hostname(hostname, domain=None, config_only=False):
    prev_hostname = info_hostname()

    changed = False
    changed |= fs.upload_string('{}\n'.format(hostname),
                                '/etc/hostname').changed

    if not config_only and prev_hostname != hostname:
        proc.run(['hostname', hostname])
        changed = True

    # update /etc/hosts
    # this will also set the domain name
    # see http://jblevins.org/log/hostname
    #
    # we adopt the following convention:

    host_line = '127.0.1.1\t' + hostname
    if domain:
        host_line = '127.0.1.1\t{}.{}\t{}'.format(hostname, domain, hostname)

    with fs.edit('/etc/hosts') as hosts:
        if host_line not in hosts.lines():
            hosts.comment_out(r'^127.0.1.1')

            # comment out old lines
            lines = [host_line] + hosts.lines()
            hosts.set_lines(lines)

    changed |= hosts.changed

    if changed:
        info_hostname.invalidate_cache()
        info_fqdn.invalidate_cache()
        return Changed(msg='Hostname changed from {} to {}'.format(
            prev_hostname, hostname))

    return Unchanged(msg='Hostname already set to {}'.format(hostname))
Esempio n. 14
0
def set_authorized_keys(files, user='******', fix_permissions=True):
    ak_file = init_authorized_keys(user, fix_permissions).value

    kf = KeyFile()

    for fn in files:
        kf.add_from_file(fn)

    # directory is guaranteed to exist now, with correct permissions
    upload = fs.upload_string(str(kf), ak_file)

    if upload.changed and fix_permissions:
        fs.chmod(ak_file, AK_FILE_PERMS)
        fs.chown(ak_file, uid=user)

    fps = ', '.join(k.readable_fingerprint for k in kf.keys)

    if upload.changed:
        return Changed(
            msg='SSH authorized keys for {} set to: {}'.format(user, fps))

    return Unchanged(
        msg='SSH authorized keys for {} unchanged ({})'.format(user, fps))