Пример #1
0
def main():
    global wapt_folder, NGINX_GID

    parser = OptionParser(usage=usage, version=__version__)
    parser.add_option('-c',
                      '--config',
                      dest='configfile',
                      default=waptserver.config.DEFAULT_CONFIG_FILE,
                      help='Config file full path (default: %default)')
    parser.add_option(
        "-s",
        "--force-https",
        dest="force_https",
        default=False,
        action='store_true',
        help=
        "Use https only, http is 301 redirected to https (default: False). Requires a proper DNS name"
    )
    parser.add_option(
        '-q',
        '--quiet',
        dest='quiet',
        default=False,
        action="store_true",
        help=
        'Run quiet postconfiguration - default password and simple behavior')

    (options, args) = parser.parse_args()

    quiet = options.quiet

    if not quiet:
        if postconf.yesno("Do you want to launch post configuration tool ?"
                          ) != postconf.DIALOG_OK:
            print("canceling wapt postconfiguration")
            sys.exit(1)
    else:
        print('WAPT silent post-configuration')

    # SELinux rules for CentOS/RedHat
    if type_redhat():
        if re.match('^SELinux status:.*enabled', run('sestatus')):
            if not quiet:
                postconf.msgbox(
                    'SELinux detected, tweaking httpd permissions.')
                selinux_rules()
                postconf.msgbox(
                    'SELinux correctly configured for Nginx reverse proxy')
            else:
                print('[*] Redhat/Centos detected, tweaking SELinux rules')
                selinux_rules()
                print(
                    '[*] Nginx - SELinux correctly configured for Nginx reverse proxy'
                )

    # Load existing config file
    server_config = waptserver.config.load_config(options.configfile)

    if os.path.isfile(options.configfile):
        print('[*] Making a backup copy of the configuration file')
        datetime_now = datetime.datetime.now()
        shutil.copyfile(
            options.configfile,
            '%s.bck_%s' % (options.configfile, datetime_now.isoformat()))

    wapt_folder = server_config['wapt_folder']

    # add secret key initialisation string (for session token)
    if not server_config['secret_key']:
        server_config['secret_key'] = ''.join(
            random.SystemRandom().choice(string.letters + string.digits)
            for _ in range(64))

    # add user db and password in ini file
    if server_config['db_host'] in (None, '', 'localhost', '127.0.0.1', '::1'):
        ensure_postgresql_db(db_name=server_config['db_name'],
                             db_owner=server_config['db_name'],
                             db_password=server_config['db_password'])

    # Password setup/reset screen
    if not quiet:
        if not server_config['wapt_password'] or \
                postconf.yesno("Do you want to reset admin password ?",yes_label='skip',no_label='reset') != postconf.DIALOG_OK:
            wapt_password_ok = False
            while not wapt_password_ok:
                wapt_password = ''
                wapt_password_check = ''

                while wapt_password == '':
                    (code, wapt_password) = postconf.passwordbox(
                        "Please enter the wapt server password (min. 10 characters):  ",
                        insecure=True,
                        width=100)
                    if code != postconf.DIALOG_OK:
                        exit(0)

                while wapt_password_check == '':
                    (code, wapt_password_check) = postconf.passwordbox(
                        "Please enter the wapt server password again:  ",
                        insecure=True,
                        width=100)
                    if code != postconf.DIALOG_OK:
                        exit(0)

                if wapt_password != wapt_password_check:
                    postconf.msgbox('Password mismatch !')
                elif len(wapt_password) < 10:
                    postconf.msgbox(
                        'Password must be at least 10 characters long !')
                else:
                    wapt_password_ok = True

            password = pbkdf2_sha256.hash(wapt_password.encode('utf8'))
            server_config['wapt_password'] = password
    else:
        wapt_password = ''
        if not server_config['wapt_password']:
            print('[*] Generating random password for WAPT server')
            wapt_password = pwd.genword(entropy=56, charset="ascii_62")
            print('[*] WAPT admin password : %s' % wapt_password)
            password = pbkdf2_sha256.hash(wapt_password.encode('utf8'))
            server_config['wapt_password'] = password

    if not server_config['server_uuid']:
        server_config['server_uuid'] = str(uuid.uuid1())

    # waptagent authentication method
    if not quiet:
        choices = [
            ("1",
             "Allow unauthenticated registration, same behavior as WAPT 1.3",
             True),
            ("2",
             "Enable kerberos authentication required for machines registration",
             False),
            ("3",
             "Disable Kerberos but registration require strong authentication",
             False),
        ]

        code, t = postconf.radiolist("WaptAgent Authentication type?",
                                     choices=choices,
                                     width=120)
        if code == 'cancel':
            print("\n\npostconfiguration canceled\n\n")
            sys.exit(1)
        if t == "1":
            server_config['allow_unauthenticated_registration'] = True
            server_config['use_kerberos'] = False
        if t == "2":
            server_config['allow_unauthenticated_registration'] = False
            server_config['use_kerberos'] = True
        if t == "3":
            server_config['allow_unauthenticated_registration'] = False
            server_config['use_kerberos'] = False
    else:
        print(
            '[*] Set default registration method to : Allow anyone to register + Kerberos disabled'
        )
        server_config['allow_unauthenticated_registration'] = True
        server_config['use_kerberos'] = False

    # Guess fqdn using socket
    fqdn = guess_fqdn()

    clients_signing_certificate = server_config.get(
        'clients_signing_certificate')
    clients_signing_key = server_config.get('clients_signing_key')
    clients_signing_crl = server_config.get('clients_signing_crl')

    if not clients_signing_certificate or not clients_signing_key:
        clients_signing_certificate = os.path.join(wapt_root_dir, 'conf',
                                                   'ca-%s.crt' % fqdn)
        clients_signing_key = os.path.join(wapt_root_dir, 'conf',
                                           'ca-%s.pem' % fqdn)

        server_config[
            'clients_signing_certificate'] = clients_signing_certificate
        server_config['clients_signing_key'] = clients_signing_key

    if clients_signing_certificate is not None and clients_signing_key is not None and not os.path.isfile(
            clients_signing_certificate):
        print('Create a certificate and key for clients certificate signing')

        key = SSLPrivateKey(clients_signing_key)
        if not os.path.isfile(clients_signing_key):
            print('Create SSL RSA Key %s' % clients_signing_key)
            key.create()
            key.save_as_pem()

        crt = key.build_sign_certificate(cn=fqdn,
                                         is_code_signing=False,
                                         is_ca=True)
        print('Create X509 cert %s' % clients_signing_certificate)
        crt.save_as_pem(clients_signing_certificate)

    if clients_signing_certificate is not None and clients_signing_key is not None and clients_signing_crl is not None and not os.path.isfile(
            clients_signing_crl):
        print('Create a CRL for clients certificate signing')
        key = SSLPrivateKey(clients_signing_key)
        crt = SSLCertificate(clients_signing_certificate)
        crl = SSLCRL(clients_signing_crl, cacert=crt, cakey=key)
        crl.revoke_cert()
        crl.save_as_pem()

    waptserver.config.write_config_file(cfgfile=options.configfile,
                                        server_config=server_config,
                                        non_default_values_only=True)

    print('[*] Protecting WAPT config file')
    run("/bin/chmod 640 %s" % options.configfile)
    run("/bin/chown wapt %s" % options.configfile)

    print('[*] Update WAPT repository')
    repo = WaptLocalRepo(wapt_folder)
    repo.update_packages_index(force_all=True)

    final_msg = [
        '[*] Postconfiguration completed.',
    ]
    if not quiet:
        postconf.msgbox("Press ok to start waptserver and wapttasks daemons")
    enable_waptserver()
    start_waptserver()

    # In this new version Apache is replaced with Nginx? Proceed to disable Apache. After migration one can remove Apache install altogether
    stop_disable_httpd()

    # Nginx configuration
    if quiet:
        try:
            generate_dhparam()
            nginx_cleanup()
            make_httpd_config('/opt/wapt/waptserver', fqdn,
                              options.force_https, server_config)
            enable_nginx()
            restart_nginx()
            setup_firewall()
        except subprocess.CalledProcessError as cpe:
            final_msg += [
                'Error while trying to configure Nginx!',
                'errno = ' + str(cpe.returncode) + ', output: ' + cpe.output
            ]
        except Exception as e:
            import traceback
            final_msg += [
                'Error while trying to configure Nginx!',
                traceback.format_exc()
            ]
    else:
        reply = postconf.yesno("Do you want to configure nginx?")
        if reply == postconf.DIALOG_OK:
            try:
                msg = 'FQDN for the WAPT server (eg. wapt.acme.com)'
                (code, reply) = postconf.inputbox(text=msg,
                                                  width=len(msg) + 4,
                                                  init=fqdn)
                if code != postconf.DIALOG_OK:
                    exit(1)
                else:
                    fqdn = reply

                generate_dhparam()
                nginx_cleanup()

                if server_config['use_kerberos']:
                    if type_debian():
                        if not check_if_deb_installed(
                                'libnginx-mod-http-auth-spnego'):
                            print(
                                '[*] Nginx - Missing dependency libnginx-mod-http-auth-spnego, please install first before configuring kerberos'
                            )
                            sys.exit(1)

                make_httpd_config('/opt/wapt/waptserver', fqdn,
                                  options.force_https, server_config)
                final_msg.append('Please connect to https://' + fqdn +
                                 '/ to access the server.')
                postconf.msgbox(
                    "The Nginx config is done. We need to restart Nginx?")
                run_verbose('systemctl enable nginx')
                run_verbose('systemctl restart nginx')
                setup_firewall()

            except subprocess.CalledProcessError as cpe:
                final_msg += [
                    'Error while trying to configure Nginx!', 'errno = ' +
                    str(cpe.returncode) + ', output: ' + cpe.output
                ]
            except Exception as e:
                import traceback
                final_msg += [
                    'Error while trying to configure Nginx!',
                    traceback.format_exc()
                ]

    # known certificates
    ssl_dir = server_config['known_certificates_folder']
    if not os.path.isdir(ssl_dir):
        # move existing ssl dir in wapt repo to parent dir (default location)
        if os.path.isdir(os.path.join(server_config['wapt_folder'], 'ssl')):
            shutil.move(os.path.join(server_config['wapt_folder'], 'ssl'),
                        ssl_dir)
        else:
            os.makedirs(ssl_dir)

    #Migrate file for new version waptwua
    wuafolder = server_config['waptwua_folder']
    for (root, dirs, files) in list(os.walk(wuafolder, topdown=False)):
        if root == os.path.join(wuafolder, '.stfolder'):
            continue
        for f in files:
            oldpath = os.path.join(root, f)
            newpath = os.path.join(wuafolder, f)
            if os.path.isfile(newpath):
                continue
            print('Move %s --> %s' % (oldpath, newpath))
            shutil.move(oldpath, newpath)
        for d in dirs:
            if d == '.stfolder':
                continue
            print('Delete folder %s' % os.path.join(root, d))
            shutil.rmtree(os.path.join(root, d))

    final_msg.append('Please connect to https://' + fqdn +
                     '/ to access the server.')

    # Check if Mongodb > PostgreSQL migration is necessary
    if not quiet:
        if check_mongo2pgsql_upgrade_needed(options.configfile) and\
                postconf.yesno("It is necessary to migrate current database backend from mongodb to postgres. Press yes to start migration",no_label='cancel') == postconf.DIALOG_OK:
            upgrade2postgres(options.configfile)
    else:
        if check_mongo2pgsql_upgrade_needed(options.configfile):
            upgrade2postgres(options.configfile)

    WAPT_UID = good_pwd.getpwnam('wapt').pw_uid

    # CHOWN of waptservertasks.sqlite it seems to be created before

    location_waptservertasks = os.path.join(wapt_root_dir, 'db',
                                            'waptservertasks.sqlite')

    if os.path.isfile(location_waptservertasks):
        os.chown(location_waptservertasks, WAPT_UID,
                 os.stat(location_waptservertasks).st_gid)

    # Create empty sync.json and rules.json file for all installations

    sync_json = os.path.join(
        os.path.abspath(os.path.join(wapt_folder, os.pardir)), u'sync.json')
    rules_json = os.path.join(
        os.path.abspath(os.path.join(wapt_folder, os.pardir)), u'rules.json')

    diff_rules_dir = wapt_folder + u'-diff-repos/'

    paths_to_modify = [
        sync_json, rules_json, wapt_folder + '/', wuafolder + '/',
        diff_rules_dir, ssl_dir + '/'
    ]

    for apath in paths_to_modify:
        if os.path.isdir(apath):
            os.chown(apath, WAPT_UID, NGINX_GID)
            os.chmod(apath, 0o750)
            for root, dirs, files in os.walk(apath):
                for d in dirs:
                    full_path = os.path.join(root, d)
                    os.chown(full_path, WAPT_UID, NGINX_GID)
                    os.chmod(full_path, 0o750)
                for f in files:
                    full_path = os.path.join(root, f)
                    os.chown(full_path, WAPT_UID, NGINX_GID)
                    os.chmod(full_path, 0o640)
        else:
            if apath.endswith('/'):
                os.mkdir(apath)
                os.chmod(apath, 0o750)
            else:
                if not (os.path.isfile(apath)):
                    with open(apath, 'w'):
                        pass
                os.chmod(apath, 0o640)
            os.chown(apath, WAPT_UID, NGINX_GID)

    # Final message
    if not quiet:
        width = 4 + max(10, len(max(final_msg, key=len)))
        height = 2 + max(20, len(final_msg))
        postconf.msgbox('\n'.join(final_msg), height=height, width=width)
    else:
        if wapt_password:
            final_msg.append('[*] WAPT admin password : %s\n' % wapt_password)
        for line in final_msg:
            print(line)
Пример #2
0
def make_nginx_config(wapt_root_dir, wapt_folder, force=False):
    """Create a nginx default config file to server wapt_folder and reverse proxy waptserver
    Create a key and self signed certificate.

    Args:
        wapt_root_dir (str)
        wapt_folder (str) : local path to wapt rdirectory for packages
                             wapt-host and waptwua are derived from this.

    Returns:
        str: path to nginx conf file
    """

    ap_conf_dir = os.path.join(wapt_root_dir, 'waptserver', 'nginx', 'conf')
    ap_file_name = 'nginx.conf'
    ap_conf_file = os.path.join(ap_conf_dir, ap_file_name)
    ap_ssl_dir = os.path.join(wapt_root_dir, 'waptserver', 'nginx', 'ssl')

    if os.path.isfile(ap_conf_file) and not force:
        if 'waptserver' in open(ap_conf_file, 'r').read():
            return ap_conf_file

    setuphelpers.mkdirs(ap_ssl_dir)

    key_fn = os.path.join(ap_ssl_dir, 'key.pem')
    key = SSLPrivateKey(key_fn)
    if not os.path.isfile(key_fn):
        print('Create SSL RSA Key %s' % key_fn)
        key.create()
        key.save_as_pem()

    cert_fn = os.path.join(ap_ssl_dir, 'cert.pem')
    if os.path.isfile(cert_fn):
        crt = SSLCertificate(cert_fn)
        if crt.cn != fqdn():
            os.rename(
                cert_fn, "%s-%s.old" % (cert_fn, '{:%Y%m%d-%Hh%Mm%Ss}'.format(
                    datetime.datetime.now())))
            crt = key.build_sign_certificate(cn=fqdn(), is_code_signing=False)
            print('Create X509 cert %s' % cert_fn)
            crt.save_as_pem(cert_fn)
    else:
        crt = key.build_sign_certificate(cn=fqdn(), is_code_signing=False)
        print('Create X509 cert %s' % cert_fn)
        crt.save_as_pem(cert_fn)

    # write config file
    jinja_env = jinja2.Environment(loader=jinja2.FileSystemLoader(
        os.path.join(wapt_root_dir, 'waptserver', 'scripts')))
    template = jinja_env.get_template('waptwindows.nginxconfig.j2')
    template_variables = {
        'wapt_repository_path':
        os.path.dirname(conf['wapt_folder']).replace('\\', '/'),
        'waptserver_port':
        conf['waptserver_port'],
        'windows':
        True,
        'ssl':
        True,
        'force_https':
        False,
        'use_kerberos':
        False,
        'wapt_ssl_key_file':
        key_fn.replace('\\', '/'),
        'wapt_ssl_cert_file':
        cert_fn.replace('\\', '/'),
        'log_dir':
        os.path.join(wapt_root_dir, 'waptserver', 'nginx',
                     'logs').replace('\\', '/'),
        'wapt_root_dir':
        wapt_root_dir.replace('\\', '/'),
        'nginx_http':
        conf['nginx_http'],
        'nginx_https':
        conf['nginx_https']
    }

    config_string = template.render(template_variables)
    print('Create nginx conf file %s' % ap_conf_file)
    with open(ap_conf_file, 'wt') as dst_file:
        dst_file.write(config_string)
    return ap_conf_file
Пример #3
0
def make_httpd_config(waptserver_root_dir, fqdn, force_https, server_config):
    ssl_dir = os.path.join(waptserver_root_dir, 'ssl')
    scripts_dir = os.path.join(waptserver_root_dir, 'scripts')
    wapt_ssl_key_file = os.path.join(ssl_dir,'key.pem')
    wapt_ssl_cert_file = os.path.join(ssl_dir,'cert.pem')
    mkdir(ssl_dir)

    # write the apache configuration fragment
    jinja_env = jinja2.Environment(loader=jinja2.FileSystemLoader(scripts_dir))
    template = jinja_env.get_template('wapt.nginxconfig.template')
    krb5_realm = '.'.join(fqdn.split('.')[1:]).upper()

    template_vars = {
        'waptserver_port': server_config['waptserver_port'],
        'wapt_repository_path': os.path.dirname(server_config['wapt_folder']),
        'windows': False,
        'debian': type_debian(),
        'redhat': type_redhat(),
        'force_https': force_https,
        'wapt_ssl_key_file': wapt_ssl_key_file,
        'wapt_ssl_cert_file': wapt_ssl_cert_file,
        'fqdn': fqdn,
        'use_kerberos': server_config.get('use_kerberos',False),
        'KRB5_REALM': krb5_realm,
        'wapt_root_dir': wapt_root_dir,
        'clients_signing_certificate' : server_config.get('clients_signing_certificate'),
        'use_ssl_client_auth' : server_config.get('use_ssl_client_auth',False)
        }

    if quiet:
        print('[*] Nginx - creating wapt.conf virtualhost')

    config_string = template.render(template_vars)
    if type_debian():
        dst_file = file('/etc/nginx/sites-available/wapt.conf', 'wt')
        if not os.path.exists('/etc/nginx/sites-enabled/wapt.conf'):
            print(subprocess.check_output('ln -s /etc/nginx/sites-available/wapt.conf /etc/nginx/sites-enabled/wapt.conf',shell=True))
        if os.path.exists('/etc/nginx/sites-enabled/default'):
            os.unlink('/etc/nginx/sites-enabled/default')

    elif type_redhat():
        dst_file = file('/etc/nginx/conf.d/wapt.conf', 'wt')
    dst_file.write(config_string)
    dst_file.close()

    # create keys for https:// access
    if not os.path.exists(wapt_ssl_key_file) or \
            not os.path.exists(wapt_ssl_cert_file):
        if quiet:
            print('[*] Nginx - generate self-signed certs')
        old_apache_key = '/opt/wapt/waptserver/apache/ssl/key.pem'
        old_apache_cert = '/opt/wapt/waptserver/apache/ssl/cert.pem'

        if os.path.isfile(old_apache_cert) and os.path.isfile(old_apache_key):
            shutil.copyfile(old_apache_cert,wapt_ssl_cert_file)
            shutil.copyfile(old_apache_key,wapt_ssl_key_file)

        else:
            key = SSLPrivateKey(wapt_ssl_key_file)
            if not os.path.isfile(wapt_ssl_key_file):
                print('Create SSL RSA Key %s' % wapt_ssl_key_file)
                key.create()
                key.save_as_pem()

            if os.path.isfile(wapt_ssl_cert_file):
                crt = SSLCertificate(wapt_ssl_cert_file)
                if crt.cn != fqdn:
                    os.rename(wapt_ssl_cert_file,"%s-%s.old" % (wapt_ssl_cert_file,'{:%Y%m%d-%Hh%Mm%Ss}'.format(datetime.datetime.now())))
                    crt = key.build_sign_certificate(cn=fqdn,dnsname=fqdn,is_code_signing=False)
                    print('Create X509 cert %s' % wapt_ssl_cert_file)
                    crt.save_as_pem(wapt_ssl_cert_file)
            else:
                crt = key.build_sign_certificate(cn=fqdn,dnsname=fqdn,is_code_signing=False)
                print('Create X509 cert %s' % wapt_ssl_cert_file)
                crt.save_as_pem(wapt_ssl_cert_file)


    else:
        if quiet:
	        print('[*] Nginx - self-signed certs already exists, skipping...')
Пример #4
0
def make_httpd_config(waptserver_root_dir, fqdn, force_https, server_config):
    ssl_dir = os.path.join(waptserver_root_dir, 'ssl')
    scripts_dir = os.path.join(waptserver_root_dir, 'scripts')
    wapt_ssl_key_file = os.path.join(ssl_dir, 'key.pem')
    wapt_ssl_cert_file = os.path.join(ssl_dir, 'cert.pem')
    mkdir(ssl_dir)

    # write the apache configuration fragment
    jinja_env = jinja2.Environment(loader=jinja2.FileSystemLoader(scripts_dir))
    template = jinja_env.get_template('wapt.nginxconfig.template')
    krb5_realm = '.'.join(fqdn.split('.')[1:]).upper()

    template_vars = {
        'waptserver_port':
        server_config['waptserver_port'],
        'wapt_repository_path':
        os.path.dirname(server_config['wapt_folder']),
        'windows':
        False,
        'debian':
        type_debian(),
        'redhat':
        type_redhat(),
        'force_https':
        force_https,
        'wapt_ssl_key_file':
        wapt_ssl_key_file,
        'wapt_ssl_cert_file':
        wapt_ssl_cert_file,
        'fqdn':
        fqdn,
        'use_kerberos':
        server_config.get('use_kerberos', False),
        'KRB5_REALM':
        krb5_realm,
        'wapt_root_dir':
        wapt_root_dir,
        'use_ssl_client_auth':
        server_config.get('use_ssl_client_auth', False),
        'clients_signing_certificate':
        server_config.get('clients_signing_certificate'),
        'known_certificates_folder':
        server_config.get('known_certificates_folder', None),
        'clients_signing_crl':
        server_config.get('clients_signing_crl', None),
        'htpasswd_path':
        server_config.get('htpasswd_path', None),
    }

    if quiet:
        print('[*] Nginx - creating wapt.conf virtualhost')

    config_string = template.render(template_vars)
    if type_debian():
        dst_file = file('/etc/nginx/sites-available/wapt.conf', 'wt')
        if not os.path.exists('/etc/nginx/sites-enabled/wapt.conf'):
            print(
                subprocess.check_output(
                    'ln -s /etc/nginx/sites-available/wapt.conf /etc/nginx/sites-enabled/wapt.conf',
                    shell=True))
        if os.path.exists('/etc/nginx/sites-enabled/default'):
            os.unlink('/etc/nginx/sites-enabled/default')

    elif type_redhat():
        dst_file = file('/etc/nginx/conf.d/wapt.conf', 'wt')
    dst_file.write(config_string)
    dst_file.close()

    # create keys for https:// access
    if not os.path.exists(wapt_ssl_key_file) or \
            not os.path.exists(wapt_ssl_cert_file):
        if quiet:
            print('[*] Nginx - generate self-signed certs')
        old_apache_key = '/opt/wapt/waptserver/apache/ssl/key.pem'
        old_apache_cert = '/opt/wapt/waptserver/apache/ssl/cert.pem'

        if os.path.isfile(old_apache_cert) and os.path.isfile(old_apache_key):
            shutil.copyfile(old_apache_cert, wapt_ssl_cert_file)
            shutil.copyfile(old_apache_key, wapt_ssl_key_file)

        else:
            key = SSLPrivateKey(wapt_ssl_key_file)
            if not os.path.isfile(wapt_ssl_key_file):
                print('Create SSL RSA Key %s' % wapt_ssl_key_file)
                key.create()
                key.save_as_pem()

            if os.path.isfile(wapt_ssl_cert_file):
                crt = SSLCertificate(wapt_ssl_cert_file)
                if crt.cn != fqdn:
                    shutil.move(
                        wapt_ssl_cert_file, "%s-%s.old" %
                        (wapt_ssl_cert_file, '{:%Y%m%d-%Hh%Mm%Ss}'.format(
                            datetime.datetime.now())))
                    crt = key.build_sign_certificate(cn=fqdn,
                                                     dnsname=fqdn,
                                                     is_code_signing=False)
                    print('Create X509 cert %s' % wapt_ssl_cert_file)
                    crt.save_as_pem(wapt_ssl_cert_file)
            else:
                crt = key.build_sign_certificate(cn=fqdn,
                                                 dnsname=fqdn,
                                                 is_code_signing=False)
                print('Create X509 cert %s' % wapt_ssl_cert_file)
                crt.save_as_pem(wapt_ssl_cert_file)

    else:
        if quiet:
            print('[*] Nginx - self-signed certs already exists, skipping...')
Пример #5
0
def main():
    global wapt_folder,NGINX_GID

    parser = OptionParser(usage=usage, version=__version__)
    parser.add_option(
        '-c',
        '--config',
        dest='configfile',
        default=waptserver.config.DEFAULT_CONFIG_FILE,
        help='Config file full path (default: %default)')
    parser.add_option(
        "-s",
        "--force-https",
        dest="force_https",
        default=False,
        action='store_true',
        help="Use https only, http is 301 redirected to https (default: False). Requires a proper DNS name")
    parser.add_option(
        '-q',
        '--quiet',
        dest='quiet',
        default=False,
        action="store_true",
        help='Run quiet postconfiguration - default password and simple behavior')

    (options, args) = parser.parse_args()

    quiet = options.quiet

    if not quiet:
        if postconf.yesno("Do you want to launch post configuration tool ?") != postconf.DIALOG_OK:
            print "canceling wapt postconfiguration"
            sys.exit(1)
    else:
        print('WAPT silent post-configuration')

    # SELinux rules for CentOS/RedHat
    if type_redhat():
        if re.match('^SELinux status:.*enabled', run('sestatus')):
            if not quiet:
                postconf.msgbox('SELinux detected, tweaking httpd permissions.')
                selinux_rules()
                postconf.msgbox('SELinux correctly configured for Nginx reverse proxy')
            else:
                print('[*] Redhat/Centos detected, tweaking SELinux rules')
                selinux_rules()
                print('[*] Nginx - SELinux correctly configured for Nginx reverse proxy')

    # Load existing config file
    server_config = waptserver.config.load_config(options.configfile)

    if os.path.isfile(options.configfile):
        print('[*] Making a backup copy of the configuration file')
        datetime_now = datetime.datetime.now()
        shutil.copyfile(options.configfile,'%s.bck_%s'%  (options.configfile,datetime_now.isoformat()) )

    wapt_folder = server_config['wapt_folder']

    # add secret key initialisation string (for session token)
    if not server_config['secret_key']:
        server_config['secret_key'] = ''.join(random.SystemRandom().choice(string.letters + string.digits) for _ in range(64))

    # add user db and password in ini file
    if server_config['db_host'] in (None,'','localhost','127.0.0.1','::1'):
        ensure_postgresql_db(db_name=server_config['db_name'],db_owner=server_config['db_name'],db_password=server_config['db_password'])

    # Password setup/reset screen
    if not quiet:
        if not server_config['wapt_password'] or \
                postconf.yesno("Do you want to reset admin password ?",yes_label='skip',no_label='reset') != postconf.DIALOG_OK:
            wapt_password_ok = False
            while not wapt_password_ok:
                wapt_password = ''
                wapt_password_check = ''

                while wapt_password == '':
                    (code,wapt_password) = postconf.passwordbox("Please enter the wapt server password (min. 10 characters):  ", insecure=True,width=100)
                    if code != postconf.DIALOG_OK:
                        exit(0)

                while wapt_password_check == '':
                    (code,wapt_password_check) = postconf.passwordbox("Please enter the wapt server password again:  ", insecure=True,width=100)
                    if code != postconf.DIALOG_OK:
                        exit(0)

                if wapt_password != wapt_password_check:
                    postconf.msgbox('Password mismatch !')
                elif len(wapt_password) < 10:
                    postconf.msgbox('Password must be at least 10 characters long !')
                else:
                    wapt_password_ok = True

            password = pbkdf2_sha256.hash(wapt_password.encode('utf8'))
            server_config['wapt_password'] = password
    else:
        wapt_password = ''
        if not server_config['wapt_password']:
            print('[*] Generating random password for WAPT server')
            wapt_password = pwd.genword(entropy=56, charset="ascii_62")
            print('[*] WAPT admin password : %s' % wapt_password)
            password = pbkdf2_sha256.hash(wapt_password.encode('utf8'))
            server_config['wapt_password'] = password

    if not server_config['server_uuid']:
        server_config['server_uuid'] = str(uuid.uuid1())

    # waptagent authentication method
    if not quiet:
        choices = [
                ("1","Allow unauthenticated registration, same behavior as WAPT 1.3", True),
                ("2","Enable kerberos authentication required for machines registration", False),
                ("3","Disable Kerberos but registration require strong authentication", False),
                ]

        code, t = postconf.radiolist("WaptAgent Authentication type?", choices=choices,width=120)
        if code=='cancel':
            print("\n\npostconfiguration canceled\n\n")
            sys.exit(1)
        if t=="1":
            server_config['allow_unauthenticated_registration'] = True
            server_config['use_kerberos'] = False
        if t=="2":
            server_config['allow_unauthenticated_registration'] = False
            server_config['use_kerberos'] = True
        if t=="3":
            server_config['allow_unauthenticated_registration'] = False
            server_config['use_kerberos'] = False
    else:
        print('[*] Set default registration method to : Allow anyone to register + Kerberos disabled')
        server_config['allow_unauthenticated_registration'] = True
        server_config['use_kerberos'] = False


    # Guess fqdn using socket
    fqdn = guess_fqdn()

    clients_signing_certificate =  server_config.get('clients_signing_certificate')
    clients_signing_key = server_config.get('clients_signing_key')

    if not clients_signing_certificate or not clients_signing_key:
        clients_signing_certificate = os.path.join(wapt_root_dir,'conf','ca-%s.crt' % fqdn)
        clients_signing_key = os.path.join(wapt_root_dir,'conf','ca-%s.pem' % fqdn)

        server_config['clients_signing_certificate'] = clients_signing_certificate
        server_config['clients_signing_key'] = clients_signing_key

    if clients_signing_certificate is not None and clients_signing_key is not None and not os.path.isfile(clients_signing_certificate):
        print('Create a certificate and key for clients certificate signing')

        key = SSLPrivateKey(clients_signing_key)
        if not os.path.isfile(clients_signing_key):
            print('Create SSL RSA Key %s' % clients_signing_key)
            key.create()
            key.save_as_pem()

        crt = key.build_sign_certificate(cn=fqdn,is_code_signing=False,is_ca=True)
        print('Create X509 cert %s' % clients_signing_certificate)
        crt.save_as_pem(clients_signing_certificate)

    waptserver.config.write_config_file(cfgfile=options.configfile,server_config=server_config,non_default_values_only=True)

    print('[*] Protecting WAPT config file')
    run("/bin/chmod 640 %s" % options.configfile)
    run("/bin/chown wapt %s" % options.configfile)

    print('[*] Update WAPT repository')
    repo = WaptLocalRepo(wapt_folder)
    repo.update_packages_index(force_all=True)

    final_msg = ['[*] Postconfiguration completed.',]
    if not quiet:
        postconf.msgbox("Press ok to start waptserver and wapttasks daemons")
    enable_waptserver()
    start_waptserver()

    # In this new version Apache is replaced with Nginx? Proceed to disable Apache. After migration one can remove Apache install altogether
    stop_disable_httpd()

    # Nginx configuration
    if quiet:
        try:
            generate_dhparam()
            nginx_cleanup()
            make_httpd_config('/opt/wapt/waptserver', fqdn, options.force_https,server_config)
            enable_nginx()
            restart_nginx()
            setup_firewall()
        except subprocess.CalledProcessError as cpe:
            final_msg += [
                'Error while trying to configure Nginx!',
                'errno = ' + str(cpe.returncode) + ', output: ' + cpe.output
                ]
        except Exception as e:
                import traceback
                final_msg += [
                'Error while trying to configure Nginx!',
                traceback.format_exc()
                ]
    else:
        reply = postconf.yesno("Do you want to configure nginx?")
        if reply == postconf.DIALOG_OK:
            try:
                msg = 'FQDN for the WAPT server (eg. wapt.acme.com)'
                (code, reply) = postconf.inputbox(text=msg, width=len(msg)+4, init=fqdn)
                if code != postconf.DIALOG_OK:
                    exit(1)
                else:
                    fqdn = reply

                generate_dhparam()
                nginx_cleanup()

                if server_config['use_kerberos']:
                    if type_debian():
                        if not check_if_deb_installed('libnginx-mod-http-auth-spnego'):
                            print('[*] Nginx - Missing dependency libnginx-mod-http-auth-spnego, please install first before configuring kerberos')
                            sys.exit(1)

                make_httpd_config('/opt/wapt/waptserver', fqdn, options.force_https, server_config)
                final_msg.append('Please connect to https://' + fqdn + '/ to access the server.')
                postconf.msgbox("The Nginx config is done. We need to restart Nginx?")
                run_verbose('systemctl enable nginx')
                run_verbose('systemctl restart nginx')
                setup_firewall()

            except subprocess.CalledProcessError as cpe:
                final_msg += [
                    'Error while trying to configure Nginx!',
                    'errno = ' + str(cpe.returncode) + ', output: ' + cpe.output
                    ]
            except Exception as e:
                import traceback
                final_msg += [
                'Error while trying to configure Nginx!',
                traceback.format_exc()
                ]

    final_msg.append('Please connect to https://' + fqdn + '/ to access the server.')

    # Check if Mongodb > PostgreSQL migration is necessary
    if not quiet:
        if check_mongo2pgsql_upgrade_needed(options.configfile) and\
                postconf.yesno("It is necessary to migrate current database backend from mongodb to postgres. Press yes to start migration",no_label='cancel') == postconf.DIALOG_OK:
            upgrade2postgres(options.configfile)
    else:
        if check_mongo2pgsql_upgrade_needed(options.configfile):
            upgrade2postgres(options.configfile)

    # Final message
    if not quiet:
        width = 4 + max(10, len(max(final_msg, key=len)))
        height = 2 + max(20, len(final_msg))
        postconf.msgbox('\n'.join(final_msg), height=height, width=width)
    else:
        if wapt_password:
            final_msg.append('[*] WAPT admin password : %s\n' % wapt_password)
        for line in final_msg:
            print(line)
Пример #6
0
def install_waptserver_service(options,conf=None):
    if setuphelpers.service_installed('WAPTServer'):
        if setuphelpers.service_is_running('WAPTServer'):
            setuphelpers.service_stop('WAPTServer')
        setuphelpers.service_delete('WAPTServer')

    if conf is None:
        conf = waptserver.config.load_config(options.configfile)

    conf_dir =  os.path.join(wapt_root_dir,'conf')
    if not os.path.isdir(conf_dir):
        os.makedirs(conf_dir)
    run(r'icacls "%s" /t /grant  "*S-1-5-20":(OI)(CI)(M)' % conf_dir)

    print("install waptserver")
    service_binary = os.path.abspath(os.path.join(wapt_root_dir,'waptpython.exe'))
    service_parameters = '"%s"' % os.path.join(wapt_root_dir,'waptserver','server.py')
    service_logfile = os.path.join(log_directory, 'nssm_waptserver.log')
    service_dependencies = 'WAPTPostgresql'
    install_windows_nssm_service('WAPTServer',service_binary,service_parameters,service_logfile,service_dependencies)

    tasks_db = os.path.join(wapt_root_dir,'db')
    mkdir_p(tasks_db)
    setuphelpers.run(r'icacls "%s" /grant  "*S-1-5-20":(OI)(CI)(M)' % tasks_db)

    if not conf.get('secret_key'):
        conf['secret_key'] = ''.join(random.SystemRandom().choice(string.letters + string.digits) for _ in range(64))
        waptserver.config.write_config_file(options.configfile,conf)

    if options.setpassword:
        conf['wapt_password'] = pbkdf2_sha256.hash(base64.b64decode(options.setpassword).encode('utf8'))
        waptserver.config.write_config_file(options.configfile,conf)

    clients_signing_certificate =  conf.get('clients_signing_certificate')
    clients_signing_key = conf.get('clients_signing_key')

    if not clients_signing_certificate or not clients_signing_key:
        clients_signing_certificate = os.path.join(wapt_root_dir,'conf','ca-%s.crt' % fqdn())
        clients_signing_key = os.path.join(wapt_root_dir,'conf','ca-%s.pem' % fqdn())

        conf['clients_signing_certificate'] = clients_signing_certificate
        conf['clients_signing_key'] = clients_signing_key
        waptserver.config.write_config_file(options.configfile,conf)

    if clients_signing_certificate is not None and clients_signing_key is not None and not os.path.isfile(clients_signing_certificate):
        print('Create a certificate and key for clients certificate signing')

        key = SSLPrivateKey(clients_signing_key)
        if not os.path.isfile(clients_signing_key):
            print('Create SSL RSA Key %s' % clients_signing_key)
            key.create()
            key.save_as_pem()

        crt = key.build_sign_certificate(cn=fqdn(),is_code_signing=False,is_ca=True)
        print('Create X509 cert %s' % clients_signing_certificate)
        crt.save_as_pem(clients_signing_certificate)

    # ensure Packages index
    repo = WaptLocalRepo(conf['wapt_folder'])
    repo.update_packages_index()

    if setuphelpers.service_installed('WAPTServer'):
        if not setuphelpers.service_is_running('WAPTServer'):
            setuphelpers.service_start('WAPTServer')
Пример #7
0
def make_nginx_config(wapt_root_dir, wapt_folder, force = False):
    """Create a nginx default config file to server wapt_folder and reverse proxy waptserver
    Create a key and self signed certificate.

    Args:
        wapt_root_dir (str)
        wapt_folder (str) : local path to wapt rdirectory for packages
                             wapt-host and waptwua are derived from this.

    Returns:
        str: path to nginx conf file
    """

    ap_conf_dir = os.path.join(
        wapt_root_dir,
        'waptserver',
        'nginx',
        'conf')
    ap_file_name = 'nginx.conf'
    ap_conf_file = os.path.join(ap_conf_dir, ap_file_name)
    ap_ssl_dir = os.path.join(wapt_root_dir,'waptserver','nginx','ssl')

    if os.path.isfile(ap_conf_file) and not force:
        if 'waptserver' in open(ap_conf_file,'r').read():
            return ap_conf_file

    setuphelpers.mkdirs(ap_ssl_dir)

    key_fn = os.path.join(ap_ssl_dir,'key.pem')
    key = SSLPrivateKey(key_fn)
    if not os.path.isfile(key_fn):
        print('Create SSL RSA Key %s' % key_fn)
        key.create()
        key.save_as_pem()

    cert_fn = os.path.join(ap_ssl_dir,'cert.pem')
    if os.path.isfile(cert_fn):
        crt = SSLCertificate(cert_fn)
        if crt.cn != fqdn():
            os.rename(cert_fn,"%s-%s.old" % (cert_fn,'{:%Y%m%d-%Hh%Mm%Ss}'.format(datetime.datetime.now())))
            crt = key.build_sign_certificate(cn=fqdn(),dnsname=fqdn(),is_code_signing=False)
            print('Create X509 cert %s' % cert_fn)
            crt.save_as_pem(cert_fn)
    else:
        crt = key.build_sign_certificate(cn=fqdn(),dnsname=fqdn(),is_code_signing=False)
        print('Create X509 cert %s' % cert_fn)
        crt.save_as_pem(cert_fn)

    # write config file
    jinja_env = jinja2.Environment(loader=jinja2.FileSystemLoader(os.path.join(wapt_root_dir,'waptserver','scripts')))
    template = jinja_env.get_template('waptwindows.nginxconfig.j2')
    template_variables = {
        'wapt_repository_path': os.path.dirname(conf['wapt_folder']).replace('\\','/'),
        'waptserver_port': conf['waptserver_port'],
        'windows': True,
        'ssl': True,
        'force_https': False,
        'use_kerberos': False,
        'wapt_ssl_key_file': key_fn.replace('\\','/'),
        'wapt_ssl_cert_file': cert_fn.replace('\\','/'),
        'log_dir': os.path.join(wapt_root_dir,'waptserver','nginx','logs').replace('\\','/'),
        'wapt_root_dir' : wapt_root_dir.replace('\\','/'),
        'nginx_http'  : conf['nginx_http'],
        'nginx_https' : conf['nginx_https'],
        'clients_signing_certificate' : conf.get('clients_signing_certificate') and conf.get('clients_signing_certificate').replace('\\','/'),
        'use_ssl_client_auth' : conf.get('use_ssl_client_auth',False)
    }

    config_string = template.render(template_variables)
    print('Create nginx conf file %s' % ap_conf_file)
    with open(ap_conf_file, 'wt') as dst_file:
        dst_file.write(config_string)
    return ap_conf_file
Пример #8
0
def install_waptserver_service(options,conf=None):
    if setuphelpers.service_installed('WAPTServer'):
        if setuphelpers.service_is_running('WAPTServer'):
            setuphelpers.service_stop('WAPTServer')
        setuphelpers.service_delete('WAPTServer')

    if conf is None:
        conf = waptserver.config.load_config(options.configfile)

    conf_dir =  os.path.join(wapt_root_dir,'conf')
    if not os.path.isdir(conf_dir):
        os.makedirs(conf_dir)
    run(r'icacls "%s" /t /grant  "*S-1-5-20":(OI)(CI)(M)' % conf_dir)

    if not conf.get('server_uuid'):
        conf['server_uuid'] = str(uuid.uuid1())
        waptserver.config.write_config_file(options.configfile,conf)

    print("install waptserver")
    service_binary = os.path.abspath(os.path.join(wapt_root_dir,'waptpython.exe'))
    service_parameters = '"%s"' % os.path.join(wapt_root_dir,'waptserver','server.py')
    service_logfile = os.path.join(log_directory, 'nssm_waptserver.log')
    service_dependencies = 'WAPTPostgresql'
    install_windows_nssm_service('WAPTServer',service_binary,service_parameters,service_logfile,service_dependencies)

    tasks_db = os.path.join(wapt_root_dir,'db')
    mkdir_p(tasks_db)
    setuphelpers.run(r'icacls "%s" /grant  "*S-1-5-20":(OI)(CI)(M)' % tasks_db)

    if not conf.get('secret_key'):
        conf['secret_key'] = ''.join(random.SystemRandom().choice(string.letters + string.digits) for _ in range(64))
        waptserver.config.write_config_file(options.configfile,conf)

    if options.setpassword:
        conf['wapt_password'] = pbkdf2_sha256.hash(base64.b64decode(options.setpassword).encode('utf8'))
        waptserver.config.write_config_file(options.configfile,conf)

    clients_signing_certificate =  conf.get('clients_signing_certificate')
    clients_signing_key = conf.get('clients_signing_key')

    if not clients_signing_certificate or not clients_signing_key:
        clients_signing_certificate = os.path.join(wapt_root_dir,'conf','ca-%s.crt' % fqdn())
        clients_signing_key = os.path.join(wapt_root_dir,'conf','ca-%s.pem' % fqdn())

        conf['clients_signing_certificate'] = clients_signing_certificate
        conf['clients_signing_key'] = clients_signing_key
        waptserver.config.write_config_file(options.configfile,conf)

    if clients_signing_certificate is not None and clients_signing_key is not None and not os.path.isfile(clients_signing_certificate):
        print('Create a certificate and key for clients certificate signing')

        key = SSLPrivateKey(clients_signing_key)
        if not os.path.isfile(clients_signing_key):
            print('Create SSL RSA Key %s' % clients_signing_key)
            key.create()
            key.save_as_pem()

        crt = key.build_sign_certificate(cn=fqdn(),is_code_signing=False,is_ca=True)
        print('Create X509 cert %s' % clients_signing_certificate)
        crt.save_as_pem(clients_signing_certificate)

    # ensure Packages index
    repo = WaptLocalRepo(conf['wapt_folder'])
    repo.update_packages_index()

    #Migrate file for new version waptwua
    wuafolder = conf['waptwua_folder']
    for (root,dirs,files) in list(os.walk(wuafolder,topdown=False)):
        if root == os.path.join(wuafolder,'.stfolder'):
            continue
        for f in files:
            oldpath = os.path.join(root,f)
            newpath = os.path.join(wuafolder,f)
            if os.path.isfile(newpath):
                continue
            print('Move %s --> %s' % (oldpath,newpath))
            os.rename(oldpath,newpath)
        for d in dirs:
            if d == '.stfolder':
                continue
            print('Delete folder %s' % os.path.join(root,d))
            shutil.rmtree(os.path.join(root,d))

    if setuphelpers.service_installed('WAPTServer'):
        if not setuphelpers.service_is_running('WAPTServer'):
            setuphelpers.service_start('WAPTServer')
Пример #9
0
def make_nginx_config(wapt_root_dir, wapt_folder):

    if conf['wapt_folder'].endswith('\\') or conf['wapt_folder'].endswith('/'):
        conf['wapt_folder'] = conf['wapt_folder'][:-1]

    ap_conf_dir = os.path.join(wapt_root_dir, 'waptserver', 'nginx', 'conf')
    ap_file_name = 'nginx.conf'
    ap_conf_file = os.path.join(ap_conf_dir, ap_file_name)
    ap_ssl_dir = os.path.join(wapt_root_dir, 'waptserver', 'nginx', 'ssl')

    setuphelpers.mkdirs(ap_ssl_dir)

    key_fn = os.path.join(ap_ssl_dir, 'key.pem')
    key = SSLPrivateKey(key_fn)
    if not os.path.isfile(key_fn):
        print('Create SSL RSA Key %s' % key_fn)
        key.create()
        key.save_as_pem()

    cert_fn = os.path.join(ap_ssl_dir, 'cert.pem')
    if os.path.isfile(cert_fn):
        crt = SSLCertificate(cert_fn)
        if crt.cn != fqdn():
            os.rename(
                cert_fn, "%s-%s.old" % (cert_fn, '{:%Y%m%d-%Hh%Mm%Ss}'.format(
                    datetime.datetime.now())))
            crt = key.build_sign_certificate(cn=fqdn(), is_code_signing=False)
            print('Create X509 cert %s' % cert_fn)
            crt.save_as_pem(cert_fn)
    else:
        crt = key.build_sign_certificate(cn=fqdn(), is_code_signing=False)
        print('Create X509 cert %s' % cert_fn)
        crt.save_as_pem(cert_fn)

    # write config file
    jinja_env = jinja2.Environment(loader=jinja2.FileSystemLoader(
        os.path.join(wapt_root_dir, 'waptserver', 'scripts')))
    template = jinja_env.get_template('waptwindows.nginxconfig.j2')
    template_variables = {
        'wapt_repository_path':
        os.path.dirname(conf['wapt_folder']).replace('\\', '/'),
        'windows':
        True,
        'ssl':
        True,
        'force_https':
        False,
        'use_kerberos':
        False,
        'wapt_ssl_key_file':
        key_fn.replace('\\', '/'),
        'wapt_ssl_cert_file':
        cert_fn.replace('\\', '/'),
        'log_dir':
        os.path.join(wapt_root_dir, 'waptserver', 'nginx',
                     'logs').replace('\\', '/'),
        'wapt_root_dir':
        wapt_root_dir.replace('\\', '/'),
    }

    config_string = template.render(template_variables)
    print('Create nginx conf file %s' % ap_conf_file)
    with open(ap_conf_file, 'wt') as dst_file:
        dst_file.write(config_string)