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)
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
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...')
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...')
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)
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')
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
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')
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)