def site_conf(self, domain, context, config_template): """ Generate a configuration file for the site. """ app_name = domain.split('.')[0] document_root = os.path.join( os.sep, 'var', 'www', app_name, 'reps', app_name, 'htdocs') org_proxy_params, new_proxy_params = setup.stageFile(os.path.join( context.SYSCONFDIR, 'nginx', 'proxy_params'), context=context) with open(new_proxy_params, 'w') as proxy_params_file: proxy_params_file.write(self.proxy_params_template) certs_top = os.path.join(context.SYSCONFDIR, 'pki', 'tls', 'certs') key_top = os.path.join(context.SYSCONFDIR, 'pki', 'tls', 'private') key_path = os.path.join(key_top, '%s.key' % domain) cert_path = os.path.join(certs_top, '%s.crt' % domain) wildcard_key_path = os.path.join(key_top, 'wildcard-%s.key' % domain) wildcard_cert_path = os.path.join(certs_top, 'wildcard-%s.crt' % domain) org_site_conf, new_site_conf = setup.stageFile(self.conf_path( domain, context.host(), context.SYSCONFDIR), context=context) with open(new_site_conf, 'w') as site_conf_file: site_conf_file.write(config_template % { 'app_name': app_name, 'domain': domain, 'document_root': document_root, 'key_path': key_path, 'cert_path': cert_path, 'wildcard_key_path': wildcard_key_path, 'wildcard_cert_path': wildcard_cert_path})
def run(self, context): complete = super(openssh_serverSetup, self).run(context) ldapHost = context.value('ldapHost') domain_parts = tuple(context.value('companyDomain').split('.')) banner = os.path.join(context.value('etcDir'), 'issue.net') _, new_banner_path = stageFile(banner, context=context) with open(new_banner_path, 'w') as new_banner: new_banner.write( 'This server is private property. Authorized use only.\n') settings = {'Banner': banner} for key, vals in six.iteritems( self.managed['openssh-server']['files']): if key == self.sshd_conf: settings.update(vals[0][0]) modify_config(self.sshd_conf, settings=settings, sep=' ', context=context) ldapCertPath = os.path.join(context.value('etcDir'), 'pki', 'tls', 'certs', '%s.crt' % ldapHost) names = { 'ldapHost': ldapHost, 'domainNat': domain_parts[0], 'domainTop': domain_parts[1], 'ldapCertPath': ldapCertPath } modify_config( self.ldap_conf, settings={ 'URI': 'ldaps://%(ldapHost)s' % names, 'BASE': 'ou=people,dc=%(domainNat)s,dc=%(domainTop)s' % names, 'TLS_CACERT': ldapCertPath, 'TLS_REQCERT': 'demand', 'TIMELIMIT': '15', 'TIMEOUT': '20' }, sep=' ', context=context) config_path = os.path.join('/usr', 'libexec', 'openssh', 'ssh-ldap-wrapper') _, new_config_path = stageFile(config_path, context) with open(new_config_path, 'w') as new_config: new_config.write("""#!/bin/sh if [ "$1" == "fedora" ] ; then exit 1 fi exec /usr/libexec/openssh/ssh-ldap-helper -s "$1" """) postinst.shellCommand(['chmod', '755', config_path]) postinst.shellCommand(['chmod', '644', self.ldap_conf]) return complete
def run(self, context): complete = super(openssh_serverSetup, self).run(context) banner = os.path.join(context.SYSCONFDIR, 'issue.net') _, new_banner_path = stageFile( banner, context=context) with open(new_banner_path, 'w') as new_banner: new_banner.write( 'This server is private property. Authorized use only.\n') settings = {'Banner': banner} for key, vals in self.files.iteritems(): if key == self.sshd_conf: settings.update(vals[0][0]) modify_config(self.sshd_conf, settings=settings, sep=' ', context=context) ldapDomain = 'dbs.internal' domain_parts = tuple(context.value('domainName').split('.')) ldapCertPath = os.path.join(context.SYSCONFDIR, 'pki', 'tls', 'certs', '%s.crt' % ldapDomain) names = { 'ldapDomain': ldapDomain, 'domainNat': domain_parts[0], 'domainTop': domain_parts[1], 'ldapCertPath': ldapCertPath } modify_config(self.ldap_conf, settings={ 'URI': 'ldaps://%(ldapDomain)s' % names, 'BASE': 'ou=people,dc=%(domainNat)s,dc=%(domainTop)s' % names, 'TLS_CACERT': ldapCertPath, 'TLS_REQCERT': 'demand', 'TIMELIMIT': '15', 'TIMEOUT': '20' }, sep=' ', context=context) config_path = os.path.join( '/usr', 'libexec', 'openssh', 'ssh-ldap-wrapper') _, new_config_path = stageFile(config_path, context) with open(new_config_path, 'w') as new_config: new_config.write( """#!/bin/sh if [ "$1" == "fedora" ] ; then exit 1 fi exec /usr/libexec/openssh/ssh-ldap-helper -s "$1" """) postinst.shellCommand(['chmod', '755', config_path]) postinst.shellCommand(['chmod', '644', self.ldap_conf]) return complete
def run(self, context): complete = super(syslog_ngSetup, self).run(context) if not complete: # As long as the default setup cannot find all prerequisite # executable, libraries, etc. we cannot update configuration # files here. return complete journald_conf = "/etc/systemd/journald.conf" setup.modify_config(journald_conf, settings={'ForwardToSyslog': "yes"}, sep='=', context=context) setup.postinst.shellCommand( ['rm', '-f', '/etc/systemd/system/syslog.service']) # Configure SELinux to run syslog-ng syslog_te = os.path.join( os.path.dirname(setup.postinst.postinst_run_path), 'syslog-ng.te') _, syslog_te_path = stageFile(syslog_te, context) with open(syslog_te_path, 'w') as syslog_te_file: syslog_te_file.write(self.syslog_te_config_template) setup.postinst.install_selinux_module( syslog_te, comment="Configure SELinux to run syslog-ng.") return complete
def run(self, context): complete = super(cronSetup, self).run(context) if not complete: # As long as the default setup cannot find all prerequisite # executable, libraries, etc. we cannot update configuration # files here. return complete anacrontab_conf = os.path.join(context.value('etcDir'), 'anacrontab') crontab_conf = os.path.join(context.value('etcDir'), 'crontab') notify_email = context.value('notifyEmail') if notify_email: modify_config(anacrontab_conf, settings={'MAILTO': notify_email}, context=context) modify_config(crontab_conf, settings={'MAILTO': notify_email}, context=context) for key, vals in six.iteritems(self.managed['iptables']['files']): if key.startswith('/etc/cron.d'): for cmds in vals: lines = cmds[0] _, cron = stageFile(key, context=context) cronfile = open(cron, 'w') cronfile.write('# m h dom mon dow command\n') cronfile.write(lines) cronfile.close() return complete
def site_conf(self, domain, context, config_template, webapps="", forwards=""): """ Generate a configuration file for the site. """ app_name = domain.split('.')[0] document_root = os.path.join(os.sep, 'var', 'www', app_name, 'reps', app_name, 'htdocs') org_proxy_params, new_proxy_params = setup.stageFile(os.path.join( context.value('etcDir'), 'nginx', 'proxy_params'), context=context) with open(new_proxy_params, 'w') as proxy_params_file: proxy_params_file.write(self.proxy_params_template) certs_top = os.path.join(context.value('etcDir'), 'pki', 'tls', 'certs') key_top = os.path.join(context.value('etcDir'), 'pki', 'tls', 'private') key_path = os.path.join(key_top, '%s.key' % domain) cert_path = os.path.join(certs_top, '%s.crt' % domain) wildcard_key_path = os.path.join(key_top, 'wildcard-%s.key' % domain) wildcard_cert_path = os.path.join(certs_top, 'wildcard-%s.crt' % domain) dhparam_path = os.path.join(certs_top, 'dhparam.pem') org_site_conf, new_site_conf = setup.stageFile(self.conf_path( domain, context.host(), context.value('etcDir')), context=context) with open(new_site_conf, 'w') as site_conf_file: site_conf_file.write( config_template % { 'app_name': app_name, 'domain': domain, 'document_root': document_root, 'key_path': key_path, 'cert_path': cert_path, 'dhparam_path': dhparam_path, 'webapps': webapps, 'forwards': forwards, 'wildcard_key_path': wildcard_key_path, 'wildcard_cert_path': wildcard_cert_path })
def create_syslogng_conf(self, context): _, conf_path = stageFile(os.path.join(context.SYSCONFDIR, 'syslog-ng', 'conf.d', 'slapd.conf'), context=context) with open(conf_path, 'w') as conf_file: conf_file.write( """destination d_ldap { file("/var/log/slapd.log"); }; filter f_ldap { program(slapd); }; log { source(s_sys); filter(f_ldap); destination(d_ldap); }; """)
def create_syslogng_conf(self, context): _, conf_path = stageFile(os.path.join(context.value('etcDir'), 'syslog-ng', 'conf.d', 'slapd.conf'), context=context) with open(conf_path, 'w') as conf_file: conf_file.write( """destination d_ldap { file("/var/log/slapd.log"); }; filter f_ldap { program(slapd); }; log { source(s_sys); filter(f_ldap); destination(d_ldap); }; """)
def add_entry(filename, command, username='******', minutes='0', hours='19', dom='*', months='*', dow='*', sysconfDir='/etc', context=None): '''Add a new cron job.''' _, cron_path = stageFile( os.path.join(sysconfDir, 'cron.d', filename), context) with open(cron_path, 'w') as cron: cron.write('# m h dom mon dow user command\n') cron.write('%s %s %s %s %s %s %s\n' % (minutes, hours, dom, months, dow, username, command))
def run(self, context): complete = super(nginxSetup, self).run(context) if not complete: # As long as the default setup cannot find all prerequisite # executable, libraries, etc. we cannot update configuration # files here. return complete remove_default_server = False for name, vals in self.files.iteritems(): if name.startswith('site-config'): domain = None for elem in vals: settings = elem[0] if 'domainName' in settings: domain = settings['domainName'] port = settings.get('port', '80') if port == '443': self.site_conf(domain, context, self.https_config_template) else: self.site_conf(domain, context, self.http_config_template) remove_default_server = True # Remove default server otherwise our config for intermediate nodes # with no domain names will be overridden. if remove_default_server: org_nginx_conf, new_nginx_conf = setup.stageFile(os.path.join( context.SYSCONFDIR, 'nginx', 'nginx.conf'), context=context) with open(org_nginx_conf) as org_nginx_conf_file: with open(new_nginx_conf, 'w') as new_nginx_conf_file: remove = 0 for line in org_nginx_conf_file.readlines(): look = re.match('.*server\s+{', line) if look: remove = 1 elif remove > 0: look = re.match('{', line) if look: remove += 1 look = re.match('}', line) if look: remove -= 1 if remove == 0: new_nginx_conf_file.write(line) certs_top = os.path.join( context.SYSCONFDIR, 'ssl', 'certs') dhparam_path = os.path.join(certs_top, 'dhparam.pem') setup.postinst.shellCommand([ '[', '-f', dhparam_path, ']', '||', 'openssl', 'dhparam', '-out', dhparam_path, '4096']) setup.postinst.shellCommand([ 'setsebool', '-P', 'httpd_can_network_connect', '1']) setup.postinst.shellCommand(['systemctl', 'enable', 'nginx.service']) return complete
def create_cron_conf(self, context): """ Create a cron job to backup the database to a flat text file. """ _, new_conf_path = stageFile(os.path.join( context.value('etcDir'), 'cron.daily', 'pg_backup'), context) with open(new_conf_path, 'w') as new_conf: new_conf.write("""#!/bin/sh %(backup_script)s """ % {'backup_script': '\n'.join(self.backup_script)})
def create_cron_conf(self, context): """ Create a cron job to backup the database to a flat text file. """ _, new_conf_path = stageFile(os.path.join( context.value('etcDir'), 'cron.daily', 'ldap_backup'), context) with open(new_conf_path, 'w') as new_conf: new_conf.write("""#!/bin/sh %(backup_script)s """ % {'backup_script': '\n'.join(self.backup_script)})
def add_entry(filename, command, username='******', minutes='0', hours='19', dom='*', months='*', dow='*', sysconfDir='/etc', context=None): '''Add a new cron job.''' _, cron_path = stageFile(os.path.join(sysconfDir, 'cron.d', filename), context) with open(cron_path, 'w') as cron: cron.write('# m h dom mon dow user command\n') cron.write('%s %s %s %s %s %s %s\n' % (minutes, hours, dom, months, dow, username, command))
def run(self, context): complete = super(cronSetup, self).run(context) if not complete: # As long as the default setup cannot find all prerequisite # executable, libraries, etc. we cannot update configuration # files here. return complete for key, vals in self.managed['iptables']['files'].iteritems(): if key.startswith('/etc/cron.d'): for cmds in vals: lines = cmds[0] _, cron = stageFile(key, context=context) cronfile = open(cron, 'w') cronfile.write('# m h dom mon dow command\n') cronfile.write(lines) cronfile.close() return complete
def create_logrotate_conf(self, context): """ Rotate flat file backups. """ _, new_conf_path = stageFile(os.path.join( context.value('etcDir'), 'logrotate.d', 'ldap_backup'), context) with open(new_conf_path, 'w') as new_conf: new_conf.write("""/var/backups/ldap/people.ldif { create 0600 root root daily rotate 7 missingok notifempty compress sharedscripts postrotate %(backup_script)s endscript } """ % {'backup_script': '\n '.join(self.backup_script)})
def create_logrotate_conf(self, context): """ Rotate flat file backups. """ _, new_conf_path = stageFile(os.path.join( context.value('etcDir'), 'logrotate.d', 'pg_backup'), context) with open(new_conf_path, 'w') as new_conf: new_conf.write("""/var/backups/*.sql { create 0600 root root daily rotate 7 missingok notifempty compress sharedscripts postrotate %(backup_script)s endscript } """ % {'backup_script': '\n '.join(self.backup_script)})
def run(self, context): complete = super(syslog_ngSetup, self).run(context) if not complete: # As long as the default setup cannot find all prerequisite # executable, libraries, etc. we cannot update configuration # files here. return complete setup.postinst.shellCommand( ['rm', '-f', '/etc/systemd/system/syslog.service']) # Configure SELinux to run syslog-ng syslog_te = os.path.join( os.path.dirname(setup.postinst.postinst_run_path), 'syslog-ng.te') _, syslog_te_path = stageFile(syslog_te) with open(syslog_te_path, 'w') as syslog_te_file: syslog_te_file.write(self.syslog_te_config_template) setup.postinst.install_selinux_module(syslog_te, comment="Configure SELinux to run syslog-ng.") return complete
def run(self, context): complete = super(jenkinsSetup, self).run(context) if not complete: # As long as the default setup cannot find all prerequisite # executable, libraries, etc. we cannot update configuration # files here. return complete # Workarounds to get jetty started (webdefault.xml and command line # arguments) org_webdefault_conf, new_webdefault_conf = setup.stageFile( self.webdefault_conf_path, context=context) with open(new_webdefault_conf, 'w') as webdefault_conf_file: webdefault_conf_file.write(self.webdefault_config_template) setup.modify_config(os.path.join(self.jetty_home, 'modules/jsp.mod'), settings={ '-Dorg.apache.jasper.compiler.disablejsr199': 'true' }, sep='=', context=context) # Configure jetty/jenkins (environment variables and security context) jenkins_default_path = os.path.join( context.value('etcDir'), 'default', 'jenkins') setup.modify_config(jenkins_default_path, settings={ 'JENKINS_HOME': self.jenkins_home, 'HUDSON_HOME': self.jenkins_home }, sep='=', context=context) setup.modifyIniConfig('/usr/lib/systemd/system/jetty.service', settings={'Service': {'EnvironmentFile': '-%s' % jenkins_default_path}}, context=context) org_context_conf, new_context_conf = setup.stageFile( os.path.join(self.jetty_home, 'webapps', 'jenkins.xml'), context=context) with open(new_context_conf, 'w') as context_conf_file: context_conf_file.write( self.context_config_template % {'webapp': 'jenkins'}) setup.stageDir('/var/jenkins/jobs', context) jenkins_jobs_dir = os.path.join(self.jenkins_home, 'jobs') setup.postinst.shellCommand([ '[', '-d', jenkins_jobs_dir, ']', '&&', 'mv', jenkins_jobs_dir, os.path.join(self.jenkins_home, 'jobs.prev')]) setup.postinst.shellCommand([ 'cd', self.jenkins_home, '&&', 'ln', '-s', '/var/jenkins/jobs']) # Configure SELinux to allow jetty/jenkins jobs. jenkins_te = os.path.join( os.path.dirname(setup.postinst.postinst_run_path), 'jenkins.te') with open(jenkins_te, 'w') as jenkins_te_file: jenkins_te_file.write(self.jenkins_te_config_template) setup.postinst.install_selinux_module(jenkins_te, comment="Configure SELinux to allow jetty/jenkins jobs.") setup.postinst.shellCommand( ['setsebool', '-P', 'httpd_execmem', '1']) setup.postinst.shellCommand( ['setsebool', '-P', 'httpd_builtin_scripting', '1']) return complete
def run(self, context): complete = super(jenkinsSetup, self).run(context) if not complete: # As long as the default setup cannot find all prerequisite # executable, libraries, etc. we cannot update configuration # files here. return complete # Workarounds to get jetty started (webdefault.xml and command line # arguments) org_webdefault_conf, new_webdefault_conf = setup.stageFile( self.webdefault_conf_path, context=context) with open(new_webdefault_conf, 'w') as webdefault_conf_file: webdefault_conf_file.write(self.webdefault_config_template) setup.modify_config( os.path.join(self.jetty_home, 'modules/jsp.mod'), settings={'-Dorg.apache.jasper.compiler.disablejsr199': 'true'}, sep='=', context=context) # Configure jetty/jenkins (environment variables and security context) jenkins_default_path = os.path.join(context.value('etcDir'), 'default', 'jenkins') setup.modify_config(jenkins_default_path, settings={ 'JENKINS_HOME': self.jenkins_home, 'HUDSON_HOME': self.jenkins_home }, sep='=', context=context) setup.modifyIniConfig('/usr/lib/systemd/system/jetty.service', settings={ 'Service': { 'EnvironmentFile': '-%s' % jenkins_default_path } }, context=context) org_context_conf, new_context_conf = setup.stageFile(os.path.join( self.jetty_home, 'webapps', 'jenkins.xml'), context=context) with open(new_context_conf, 'w') as context_conf_file: context_conf_file.write(self.context_config_template % {'webapp': 'jenkins'}) setup.stageDir('/var/jenkins/jobs', context) jenkins_jobs_dir = os.path.join(self.jenkins_home, 'jobs') setup.postinst.shellCommand([ '[', '-d', jenkins_jobs_dir, ']', '&&', 'mv', jenkins_jobs_dir, os.path.join(self.jenkins_home, 'jobs.prev') ]) setup.postinst.shellCommand( ['cd', self.jenkins_home, '&&', 'ln', '-s', '/var/jenkins/jobs']) # Configure SELinux to allow jetty/jenkins jobs. jenkins_te = os.path.join( os.path.dirname(setup.postinst.postinst_run_path), 'jenkins.te') with open(jenkins_te, 'w') as jenkins_te_file: jenkins_te_file.write(self.jenkins_te_config_template) setup.postinst.install_selinux_module( jenkins_te, comment="Configure SELinux to allow jetty/jenkins jobs.") setup.postinst.shellCommand(['setsebool', '-P', 'httpd_execmem', '1']) setup.postinst.shellCommand( ['setsebool', '-P', 'httpd_builtin_scripting', '1']) return complete
def run(self, context): complete = super(postgresql_serverSetup, self).run(context) if not complete: # As long as the default setup cannot find all prerequisite # executable, libraries, etc. we cannot update configuration # files here. return complete pg_user = context.value('dbUser') vpc_cidr = context.value('vpc_cidr') postgresql_conf = '/var/lib/pgsql/data/postgresql.conf' pg_ident_conf = '/var/lib/pgsql/data/pg_ident.conf' pg_ident_conf = '/var/lib/pgsql/data/pg_ident.conf' pg_hba_conf = '/var/lib/pgsql/data/pg_hba.conf' listen_addresses = "'localhost'" for key, val in self.managed['postgresql-server']['files'].iteritems(): if key == 'listen_addresses': listen_addresses = "'%s'" % val modify_config(postgresql_conf, settings={'listen_addresses': listen_addresses}, sep=' = ', context=context) # pg_ident system_to_pg_mapping = { 'postgres': 'postgres', '/^(.*)$': pg_user } old_conf_path, new_conf_path = stageFile(pg_ident_conf, context) with open(new_conf_path, 'w') as new_conf: with open(old_conf_path) as old_conf: for line in old_conf.readlines(): look = re.match(r'^mymap\s+(\S+)\s+(\S+)', line.strip()) if look: system_user = look.group(1) if system_user in system_to_pg_mapping: new_conf.write( '%(map)s%(system_user)s%(pg_user)s\n' % { 'map': 'mymap'.ljust(16), 'system_user': system_user.ljust(24), 'pg_user': system_to_pg_mapping[system_user].ljust(16)}) else: new_conf.write(line) # pg_hba connections = [['postgres', 'postgres', vpc_cidr], ['all', pg_user, vpc_cidr]] old_conf_path, new_conf_path = stageFile(pg_hba_conf, context) with open(new_conf_path, 'w') as new_conf: with open(old_conf_path) as old_conf: for line in old_conf.readlines(): look = re.match(r'^local.*peer$', line.strip()) if look: new_conf.write(line.strip() + ' map=mymap\n') else: look = re.match( r'^host\s+(?P<db>\S+)\s+(?P<pg_user>\S+)\s+(?P<cidr>\S+)\s+(?P<method>\S+)', line.strip()) if look: found = None remains = [] for conn in connections: if (conn[0] == look.group('db') and conn[1] == look.group('pg_user')): found = conn else: remains += [conn] connections = remains if found: new_conf.write( 'host %(db)s%(pg_user)s%(cidr)smd5\n' % { 'db': found[0].ljust(16), 'pg_user': found[1].ljust(16), 'cidr': found[2].ljust(16)}) else: new_conf.write(line) else: new_conf.write(line) if len(connections) > 0: new_conf.write("# Remote connections\n") for conn in connections: new_conf.write( 'host %(db)s%(pg_user)s%(cidr)smd5\n' % { 'db': conn[0].ljust(16), 'pg_user': conn[1].ljust(16), 'cidr': conn[2].ljust(16)}) self.create_cron_conf(context) postinst.shellCommand(['[ -d /var/lib/pgsql/data/base ] ||', '/usr/bin/postgresql-setup', 'initdb']) return complete
def run(self, context): complete = super(postgresql_serverSetup, self).run(context) if not complete: # As long as the default setup cannot find all prerequisite # executable, libraries, etc. we cannot update configuration # files here. return complete pg_user = context.value('dbUser') vpc_cidr = context.value('vpc_cidr') postgresql_conf = '/var/lib/pgsql/data/postgresql.conf' pg_ident_conf = '/var/lib/pgsql/data/pg_ident.conf' pg_ident_conf = '/var/lib/pgsql/data/pg_ident.conf' pg_hba_conf = '/var/lib/pgsql/data/pg_hba.conf' if not os.path.exists(postgresql_conf): # /var/lib/pgsql/data will be empty unless we run initdb once. shell_command(['/usr/bin/postgresql-setup', 'initdb']) listen_addresses = "'localhost'" for key, val in six.iteritems( self.managed['postgresql-server']['files']): if key == 'listen_addresses': listen_addresses = ', '.join( ["'%s'" % address for address in val]) modify_config(postgresql_conf, settings={'listen_addresses': listen_addresses}, sep=' = ', context=context) # pg_ident system_to_pg_mapping = {'postgres': 'postgres', '/^(.*)$': pg_user} old_conf_path, new_conf_path = stageFile(pg_ident_conf, context) with open(new_conf_path, 'w') as new_conf: with open(old_conf_path) as old_conf: for line in old_conf.readlines(): look = re.match(r'^mymap\s+(\S+)\s+(\S+)', line.strip()) if look: system_user = look.group(1) if system_user in system_to_pg_mapping: new_conf.write( '%(map)s%(system_user)s%(pg_user)s\n' % { 'map': 'mymap'.ljust(16), 'system_user': system_user.ljust(24), 'pg_user': system_to_pg_mapping[system_user].ljust(16) }) else: new_conf.write(line) # pg_hba connections = [['postgres', 'postgres', vpc_cidr], ['all', pg_user, vpc_cidr]] old_conf_path, new_conf_path = stageFile(pg_hba_conf, context) with open(new_conf_path, 'w') as new_conf: with open(old_conf_path) as old_conf: for line in old_conf.readlines(): look = re.match(r'^local.*peer$', line.strip()) if look: new_conf.write(line.strip() + ' map=mymap\n') else: look = re.match( r'^host\s+(?P<db>\S+)\s+(?P<pg_user>\S+)\s+(?P<cidr>\S+)\s+(?P<method>\S+)', line.strip()) if look: found = None remains = [] for conn in connections: if (conn[0] == look.group('db') and conn[1] == look.group('pg_user')): found = conn else: remains += [conn] connections = remains if found: new_conf.write( 'host %(db)s%(pg_user)s%(cidr)smd5\n' % { 'db': found[0].ljust(16), 'pg_user': found[1].ljust(16), 'cidr': found[2].ljust(16) }) else: new_conf.write(line) else: new_conf.write(line) if connections: new_conf.write("# Remote connections\n") for conn in connections: new_conf.write( 'host %(db)s%(pg_user)s%(cidr)smd5\n' % { 'db': conn[0].ljust(16), 'pg_user': conn[1].ljust(16), 'cidr': conn[2].ljust(16) }) self.create_cron_conf(context) postinst.shellCommand([ '[ -d /var/lib/pgsql/data/base ] ||', '/usr/bin/postgresql-setup', 'initdb' ]) return complete
def run(self, context): complete = super(sssdSetup, self).run(context) if not complete: # As long as the default setup cannot find all prerequisite # executable, libraries, etc. we cannot update configuration # files here. return complete ldapHost = context.value('ldapHost') domain_parts = tuple(context.value('domainName').split('.')) ldapCertPath = os.path.join(context.value('etcDir'), 'pki', 'tls', 'certs', '%s.crt' % ldapHost) names = { 'ldapHost': ldapHost, 'domainNat': domain_parts[0], 'domainTop': domain_parts[1], 'ldapCertPath': ldapCertPath } _, new_config_path = stageFile(self.sssd_conf, context) with open(new_config_path, 'w') as new_config: new_config.write("""[sssd] config_file_version = 2 reconnection_retries = 3 services = nss, pam, sudo # SSSD will not start if you do not configure any domains. # Add new domain configurations as [domain/] sections, and # then add the list of domains (in the order you want them to be # queried) to the "domains" attribute below and uncomment it. domains = LDAP [nss] filter_users = root,ldap,named,avahi,haldaemon,dbus,radiusd,news,nscd reconnection_retries = 3 [pam] reconnection_retries = 3 [sudo] [domain/LDAP] # Debugging: debug_level = 9 ldap_tls_reqcert = demand # Note that enabling enumeration will have a moderate performance impact. # Consequently, the default value for enumeration is FALSE. # Refer to the sssd.conf man page for full details. enumerate = true auth_provider = ldap # ldap_schema can be set to "rfc2307", which stores group member names in the # "memberuid" attribute, or to "rfc2307bis", which stores group member DNs in # the "member" attribute. If you do not know this value, ask your LDAP # administrator. #ldap_schema = rfc2307bis ldap_schema = rfc2307 ldap_search_base = dc=%(domainNat)s,dc=%(domainTop)s ldap_group_member = uniquemember id_provider = ldap ldap_id_use_start_tls = False chpass_provider = ldap ldap_uri = ldaps://%(ldapHost)s/ ldap_chpass_uri = ldaps://%(ldapHost)s/ # Allow offline logins by locally storing password hashes (default: false). cache_credentials = True ldap_tls_cacert = %(ldapCertPath)s entry_cache_timeout = 600 ldap_network_timeout = 3 sudo_provider = ldap ldap_sudo_search_base = ou=sudoers,dc=%(domainNat)s,dc=%(domainTop)s ldap_sudo_full_refresh_interval=86400 ldap_sudo_smart_refresh_interval=3600 # Enable group mapping otherwise only the user's primary group will map # correctly. Without this defined group membership won't work ldap_group_object_class = posixGroup ldap_group_search_base = ou=groups,dc=%(domainNat)s,dc=%(domainTop)s ldap_group_name = cn ldap_group_member = memberUid """ % names) postinst.shellCommand(['chmod', '600', self.sssd_conf]) postinst.shellCommand( ['authconfig', '--update', '--enablesssd', '--enablesssdauth']) postinst.shellCommand( ['setsebool', '-P', 'authlogin_nsswitch_use_ldap', '1']) return complete
def run(self, context): complete = super(iptablesSetup, self).run(context) if not complete: # As long as the default setup cannot find all prerequisite # executable, libraries, etc. we cannot update configuration # files here. return complete ports = [] forwards = [] for key, val in self.files.iteritems(): if key == 'port': for port, _ in val: ports += [int(port)] elif key == 'forward': for forward, _ in val: orig, dest = forward.split(':') forwards += [(int(orig), int(dest))] # We completely overwrite the iptables configuration for both # ipv4 and ipv6. We own it. _, new_conf_path = setup.stageFile( self.conf_path(context.host(), sysconfdir=context.SYSCONFDIR), context=context) with open(new_conf_path, 'w') as conf: if forwards: conf.write("""*nat %s COMMIT""" % '\n'.join([ "-I PREROUTING -i eth0 -p tcp --dport %d -j REDIRECT --to-port %d" % forward for forward in forwards])) local_filter_rules = '\n'.join([ '-A INPUT -m state --state NEW -m tcp -p tcp --dport %d -j ACCEPT' % port for port in ports]) conf.write("""*filter :INPUT DROP [1000:900000] :FORWARD DROP [0:0] :LOGNDROP - [0:0] :OUTPUT DROP [0:0] -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT -A INPUT -s 127.0.0.1 -j ACCEPT %(local_filter_rules)s -A INPUT -p icmp -m icmp --icmp-type 8 -m state --state NEW,RELATED,ESTABLISHED -j ACCEPT -A INPUT -p icmp -m icmp --icmp-type 13 -m state --state NEW,RELATED,ESTABLISHED -j ACCEPT -A INPUT -p icmp -m icmp --icmp-type 30 -m state --state NEW,RELATED,ESTABLISHED -j ACCEPT -A FORWARD -j REJECT --reject-with icmp-port-unreachable -A OUTPUT -m state --state NEW,RELATED,ESTABLISHED -j ACCEPT -A INPUT -j LOGNDROP -A LOGNDROP -m limit --limit 5/min -j LOG --log-prefix "Denied: " --log-level 7 -A LOGNDROP -j DROP COMMIT """ % {'local_filter_rules': local_filter_rules}) local6_filter_rules = '\n'.join([ '-A INPUT -m state --state NEW -m tcp -p tcp --dport %d -j ACCEPT' % port for port in ports]) _, new_conf_path = setup.stageFile( self.conf_path(context.host(), ip_type=self.IPV6, sysconfdir=context.SYSCONFDIR), context=context) with open(new_conf_path, 'w') as conf: conf.write(""" *filter :INPUT DROP [1000:900000] :FORWARD DROP [0:0] :LOGNDROP - [0:0] :OUTPUT ACCEPT [0:0] -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT -A INPUT -p ipv6-icmp -j ACCEPT -A INPUT -s ::1 -j ACCEPT -A INPUT -m state --state NEW -m udp -p udp --dport 546 -d fe80::/64 -j ACCEPT %(local6_filter_rules)s -A INPUT -j LOGNDROP -A FORWARD -j REJECT --reject-with icmp6-adm-prohibited -A LOGNDROP -m limit --limit 5/min -j LOG --log-prefix "Denied: " --log-level 7 -A LOGNDROP -j DROP COMMIT """ % {'local6_filter_rules': local6_filter_rules}) # Make sure we disable firewalld, we are using static rules here. setup.postinst.shellCommand(['systemctl','stop', 'firewalld.service']) setup.postinst.shellCommand(['systemctl','disable','firewalld.service']) # Create ifup-local script to load iptables rules _, new_ifup_local = setup.stageFile( '/usr/sbin/ifup-local', context=context) with open(new_ifup_local, 'w') as conf: conf.write("""#!/bin/bash /sbin/iptables-restore < /etc/sysconfig/iptables /sbin/ip6tables-restore < /etc/sysconfig/ip6tables """) os.chmod(new_ifup_local,stat.S_IRUSR|stat.S_IWUSR|stat.S_IXUSR |stat.S_IRGRP|stat.S_IXGRP|stat.S_IROTH|stat.S_IXOTH) setup.postinst.shellCommand(['/usr/sbin/ifup-local']) return complete
def run(self, context): complete = super(openldap_serversSetup, self).run(context) if not complete: # As long as the default setup cannot find all prerequisite # executable, libraries, etc. we cannot update configuration # files here. return complete domain = 'dbs.internal' company_domain = context.value('domainName') password_hash = context.value('ldapPasswordHash') priv_key = os.path.join(context.SYSCONFDIR, 'pki', 'tls', 'private', '%s.key' % domain) config_path = os.path.join(context.SYSCONFDIR, 'openldap', 'slapd.d', 'cn=config.ldif') _, new_config_path = stageFile(config_path, context) modify_config(config_path, sep=': ', context=context, settings={ 'olcTLSCACertificatePath': os.path.join( context.SYSCONFDIR, 'pki', 'tls', 'certs'), 'olcTLSCertificateFile': os.path.join(context.SYSCONFDIR, 'pki', 'tls', 'certs', '%s.crt' % domain), 'olcTLSCertificateKeyFile': priv_key }) self._update_crc32(new_config_path) domain_parts = tuple(company_domain.split('.')) config_path = os.path.join(context.SYSCONFDIR, 'openldap', 'slapd.d', 'cn=config', 'olcDatabase={0}config.ldif') _, new_config_path = stageFile(config_path, context) modify_config(config_path, sep=': ', enter_block_sep=None, exit_block_sep=None, one_per_line=True, context=context, settings={ 'olcRootPW': '{SSHA}%s' % password_hash }) self._update_crc32(new_config_path) config_path = os.path.join(context.SYSCONFDIR, 'openldap', 'slapd.d', 'cn=config', 'olcDatabase={2}mdb.ldif') _, new_config_path = stageFile(config_path, context) modify_config(config_path, sep=': ', enter_block_sep=None, exit_block_sep=None, one_per_line=True, context=context, settings={ 'olcSuffix': 'dc=%s,dc=%s' % domain_parts, 'olcRootDN': 'cn=Manager,dc=%s,dc=%s' % domain_parts, 'olcRootPW': '{SSHA}%s' % password_hash, 'olcAccess': [ '{0}to * by dn.exact=gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth manage by * break', '{0}to attrs=userPassword by self write by dn.base="cn=Manager,dc=%s,dc=%s" write by anonymous auth by * none' % domain_parts, '{1}to * by dn.base="cn=Manager,dc=%s,dc=%s" write by self write by * read"' % domain_parts] }) self._update_crc32(new_config_path) schema_path = os.path.join(context.SYSCONFDIR, 'openldap', 'schema', 'openssh-ldap.ldif') _, new_schema_path = stageFile(schema_path, context) with open(new_schema_path, 'w') as schema_file: schema_file.write("""dn: cn=openssh-openldap,cn=schema,cn=config objectClass: olcSchemaConfig cn: openssh-openldap olcAttributeTypes: {0}( 1.3.6.1.4.1.24552.500.1.1.1.13 NAME 'sshPublicKey' DES C 'MANDATORY: OpenSSH Public key' EQUALITY octetStringMatch SYNTAX 1.3.6.1.4. 1.1466.115.121.1.40 ) olcObjectClasses: {0}( 1.3.6.1.4.1.24552.500.1.1.2.0 NAME 'ldapPublicKey' DESC 'MANDATORY: OpenSSH LPK objectclass' SUP top AUXILIARY MUST ( sshPublicKey $ uid ) ) """) postinst.shellCommand(['chmod', '750', os.path.dirname(priv_key)]) postinst.shellCommand(['chgrp', 'ldap', os.path.dirname(priv_key)]) postinst.shellCommand(['chmod', '640', priv_key]) postinst.shellCommand(['chgrp', 'ldap', priv_key]) self.create_syslogng_conf(context) postinst.shellCommand([ 'systemctl', 'enable', 'slapd.service']) postinst.shellCommand(['ldapadd', '-x', '-W', '-H', 'ldap:///', '-f', '/etc/openldap/schema/cosine.ldif', '-D', '"cn=config"']) postinst.shellCommand(['ldapadd', '-x', '-W', '-H', 'ldap:///', '-f', '/etc/openldap/schema/nis.ldif', '-D', '"cn=config"']) postinst.shellCommand(['ldapadd', '-x', '-W', '-H', 'ldap:///', '-f', '/etc/openldap/schema/inetorgperson.ldif', '-D', '"cn=config"']) postinst.shellCommand(['ldapadd', '-x', '-W', '-H', 'ldap:///', '-f', '/etc/openldap/schema/openssh-ldap.ldif', '-D', '"cn=config"']) return complete
def run(self, context): complete = super(nginxSetup, self).run(context) if not complete: # As long as the default setup cannot find all prerequisite # executable, libraries, etc. we cannot update configuration # files here. return complete last_webapps = "" last_forwards = "" remove_default_server = False for name, vals in self.managed['nginx']['files'].iteritems(): webapps = "" forwards = "" if name.startswith('site-config'): domain = None for elem in vals: settings = elem[0] if 'domainName' in settings: domain = settings['domainName'] webapp_settings = settings.get('webapp', None) if webapp_settings: if not isinstance(webapp_settings, list): webapp_settings = [webapp_settings] for webapp in webapp_settings: webapps += self.webapp_template % webapp forwards += self.forward_template % webapp port = settings.get('port', '80') if port == '443': conf_template = self.https_config_template else: conf_template = self.http_config_template remove_default_server = True self.site_conf(domain, context, conf_template, webapps=webapps, forwards=forwards) if webapps: last_webapps = webapps if forwards: last_forwards = forwards # Forward all other https to last webapp configured. # This is useful for testing staged servers. self.site_conf("stage", context, self.https_default_template, webapps=last_webapps, forwards=last_forwards) # Remove default server otherwise our config for intermediate nodes # with no domain names will be overridden. if remove_default_server: org_nginx_conf, new_nginx_conf = setup.stageFile(os.path.join( context.value('etcDir'), 'nginx', 'nginx.conf'), context=context) with open(org_nginx_conf) as org_nginx_conf_file: with open(new_nginx_conf, 'w') as new_nginx_conf_file: remove = 0 for line in org_nginx_conf_file.readlines(): look = re.match('.*server\s+{', line) if look: remove = 1 elif remove > 0: look = re.match('{', line) if look: remove += 1 look = re.match('}', line) if look: remove -= 1 if remove == 0: new_nginx_conf_file.write(line) certs_top = os.path.join(context.value('etcDir'), 'pki', 'tls', 'certs') dhparam_path = os.path.join(certs_top, 'dhparam.pem') setup.postinst.shellCommand([ '[', '-f', dhparam_path, ']', '||', 'openssl', 'dhparam', '-out', dhparam_path, '4096']) setup.postinst.shellCommand([ 'setsebool', '-P', 'httpd_can_network_connect', '1']) return complete
def site_conf(self, domain, context, config_template, webapps="", forwards="", conf_name=None): """ Generate a configuration file for the site. """ app_name = domain.split('.')[0] if conf_name is None: conf_name = app_name document_root = os.path.join(os.sep, 'var', 'www', app_name, 'reps', app_name, 'htdocs') _, new_proxy_params = setup.stageFile(os.path.join( context.value('etcDir'), 'nginx', 'proxy_params'), context=context) with open(new_proxy_params, 'w') as proxy_params_file: proxy_params_file.write(self.proxy_params_template) certs_top = os.path.join(context.value('etcDir'), 'pki', 'tls', 'certs') key_top = os.path.join(context.value('etcDir'), 'pki', 'tls', 'private') key_path = os.path.join(key_top, '%s.key' % domain) cert_path = os.path.join(certs_top, '%s.crt' % domain) wildcard_key_path = os.path.join(key_top, 'wildcard-%s.key' % domain) wildcard_cert_path = os.path.join(certs_top, 'wildcard-%s.crt' % domain) # If no TLS certificate is present, we will create a self-signed one, # this in order to start nginx correctly. wildcard_csr_path = wildcard_cert_path.replace('.crt', '.csr') domain_info = os.path.join( os.path.dirname(setup.postinst.postinst_run_path), '%s.info' % domain) _, domain_info_path = setup.stageFile(domain_info, context) with open(domain_info_path, 'w') as domain_info_file: domain_info_file.write("US\nCalifornia\nSan Francisco\n"\ "Dummy Corp\n\n*.%(domain)s\nsupport@%(email)s\n\n\n" % {'domain': domain, 'email': '*****@*****.**'}) setup.postinst.shellCommand([ '[', '-f', wildcard_key_path, ']', '||', '/usr/bin/openssl', 'req', '-new', '-newkey', 'rsa:2048', '-nodes', '-keyout', wildcard_key_path, '-out', wildcard_csr_path, '<', domain_info_path ]) setup.postinst.shellCommand([ '[', '-f', wildcard_cert_path, ']', '||', '/usr/bin/openssl', 'x509', '-req', '-days', '15', '-in', wildcard_csr_path, '-signkey', wildcard_key_path, '-out', wildcard_cert_path ]) setup.postinst.shellCommand([ '[', '-f', key_path, ']', '||', '/usr/bin/ln', '-s', wildcard_key_path, key_path ]) setup.postinst.shellCommand([ '[', '-f', cert_path, ']', '||', '/usr/bin/ln', '-s', wildcard_cert_path, cert_path ]) dhparam_path = os.path.join(certs_top, 'dhparam.pem') _, new_site_conf = setup.stageFile(self.conf_path( domain, context.host(), context.value('etcDir')), context=context) # XXX increase server name hash with amazon host names. # server_names_hash_bucket_size 64; # XXX also to fix warn: ``types_hash_bucket_size 256;`` with open(new_site_conf, 'w') as site_conf_file: site_conf_file.write( config_template % { 'app_name': app_name, 'domain': domain, 'domain_re': domain.replace('.', '\\.'), 'document_root': document_root, 'key_path': key_path, 'cert_path': cert_path, 'dhparam_path': dhparam_path, 'webapps': webapps, 'forwards': forwards, 'wildcard_key_path': wildcard_key_path, 'wildcard_cert_path': wildcard_cert_path })
def run(self, context): complete = super(nginxSetup, self).run(context) if not complete: # As long as the default setup cannot find all prerequisite # executable, libraries, etc. we cannot update configuration # files here. return complete last_webapps = "" last_forwards = "" remove_default_server = False for name, vals in six.iteritems(self.managed['nginx']['files']): webapps = "" forwards = "" if name.startswith('site-config'): domain = None for elem in vals: settings = elem[0] if 'domainName' in settings: domain = settings['domainName'] webapp_settings = settings.get('webapp', None) if webapp_settings: if not isinstance(webapp_settings, list): webapp_settings = [webapp_settings] for webapp in webapp_settings: if 'app_name' not in webapp: webapp.update( {'app_name': domain.split('.')[0]}) webapps += self.webapp_template % webapp forwards += self.forward_template % webapp port = settings.get('port', '80') if port == '443': conf_template = self.https_config_template else: conf_template = self.http_config_template remove_default_server = True self.site_conf(domain, context, conf_template, webapps=webapps, forwards=forwards) if webapps: last_webapps = webapps if forwards: last_forwards = forwards # XXX disabled: Attempts to create wildcard certificate and can't # remember why this is useful: # Forward all other https to last webapp configured. # This is useful for testing staged servers. if False: self.site_conf("stage", context, self.https_default_template, webapps=last_webapps, forwards=last_forwards) # Remove default server otherwise our config for intermediate nodes # with no domain names will be overridden. if remove_default_server: org_nginx_conf, new_nginx_conf = setup.stageFile(os.path.join( context.value('etcDir'), 'nginx', 'nginx.conf'), context=context) with open(org_nginx_conf) as org_nginx_conf_file: with open(new_nginx_conf, 'w') as new_nginx_conf_file: remove = 0 for line in org_nginx_conf_file.readlines(): look = re.match(r'.*server\s+{', line) if look: remove = 1 elif remove > 0: look = re.match('{', line) if look: remove += 1 look = re.match('}', line) if look: remove -= 1 if remove == 0: new_nginx_conf_file.write(line) certs_top = os.path.join(context.value('etcDir'), 'pki', 'tls', 'certs') dhparam_path = os.path.join(certs_top, 'dhparam.pem') setup.postinst.shellCommand([ '[', '-f', dhparam_path, ']', '||', '/usr/bin/openssl', 'dhparam', '-out', dhparam_path, '4096' ]) setup.postinst.shellCommand( ['setsebool', '-P', 'httpd_can_network_connect', '1']) return complete
def run(self, context): complete = super(sssdSetup, self).run(context) if not complete: # As long as the default setup cannot find all prerequisite # executable, libraries, etc. we cannot update configuration # files here. return complete ldapDomain = 'dbs.internal' ldapCertPath = os.path.join(context.SYSCONFDIR, 'pki', 'tls', 'certs', '%s.crt' % ldapDomain) domain_parts = tuple(context.value('domainName').split('.')) names = { 'ldapDomain': ldapDomain, 'domainNat': domain_parts[0], 'domainTop': domain_parts[1], 'ldapCertPath': ldapCertPath } _, new_config_path = stageFile(self.sssd_conf, context) with open(new_config_path, 'w') as new_config: new_config.write("""[sssd] config_file_version = 2 reconnection_retries = 3 services = nss, pam, sudo # SSSD will not start if you do not configure any domains. # Add new domain configurations as [domain/] sections, and # then add the list of domains (in the order you want them to be # queried) to the "domains" attribute below and uncomment it. domains = LDAP [nss] filter_users = root,ldap,named,avahi,haldaemon,dbus,radiusd,news,nscd reconnection_retries = 3 [pam] reconnection_retries = 3 [sudo] [domain/LDAP] # Debugging: debug_level = 9 ldap_tls_reqcert = demand # Note that enabling enumeration will have a moderate performance impact. # Consequently, the default value for enumeration is FALSE. # Refer to the sssd.conf man page for full details. enumerate = true auth_provider = ldap # ldap_schema can be set to "rfc2307", which stores group member names in the # "memberuid" attribute, or to "rfc2307bis", which stores group member DNs in # the "member" attribute. If you do not know this value, ask your LDAP # administrator. #ldap_schema = rfc2307bis ldap_schema = rfc2307 ldap_search_base = dc=%(domainNat)s,dc=%(domainTop)s ldap_group_member = uniquemember id_provider = ldap ldap_id_use_start_tls = False chpass_provider = ldap ldap_uri = ldaps://%(ldapDomain)s/ ldap_chpass_uri = ldaps://%(ldapDomain)s/ # Allow offline logins by locally storing password hashes (default: false). cache_credentials = True ldap_tls_cacert = %(ldapCertPath)s entry_cache_timeout = 600 ldap_network_timeout = 3 sudo_provider = ldap ldap_sudo_search_base = ou=sudoers,dc=%(domainNat)s,dc=%(domainTop)s ldap_sudo_full_refresh_interval=86400 ldap_sudo_smart_refresh_interval=3600 # Enable group mapping otherwise only the user's primary group will map # correctly. Without this defined group membership won't work ldap_group_object_class = posixGroup ldap_group_search_base = ou=group,dc=%(domainNat)s,dc=%(domainTop)s ldap_group_name = cn ldap_group_member = memberUid """ % names) postinst.shellCommand(['chmod', '600', self.sssd_conf]) postinst.shellCommand(['authconfig', '--update', '--enablesssd', '--enablesssdauth']) postinst.shellCommand(['setsebool', '-P', 'authlogin_nsswitch_use_ldap', '1']) postinst.shellCommand([ 'systemctl', 'enable', 'sssd.service']) return complete
def run(self, context): complete = super(openldap_serversSetup, self).run(context) if not complete: # As long as the default setup cannot find all prerequisite # executable, libraries, etc. we cannot update configuration # files here. return complete ldapHost = context.value('ldapHost') company_domain = context.value('companyDomain') password_hash = context.value('ldapPasswordHash') priv_key = os.path.join(context.value('etcDir'), 'pki', 'tls', 'private', '%s.key' % ldapHost) config_path = os.path.join(context.value('etcDir'), 'openldap', 'slapd.d', 'cn=config.ldif') _, new_config_path = stageFile(config_path, context) modify_config(config_path, sep=': ', context=context, settings={ 'olcTLSCACertificatePath': os.path.join( context.value('etcDir'), 'pki', 'tls', 'certs'), 'olcTLSCertificateFile': os.path.join(context.value('etcDir'), 'pki', 'tls', 'certs', '%s.crt' % ldapHost), 'olcTLSCertificateKeyFile': priv_key }) self._update_crc32(new_config_path) domain_parts = tuple(company_domain.split('.')) db_config_path = os.path.join(context.value('etcDir'), 'openldap', 'slapd.d', 'cn=config', 'olcDatabase={0}config.ldif') _, new_config_path = stageFile(db_config_path, context) modify_config(db_config_path, sep=': ', enter_block_sep=None, exit_block_sep=None, one_per_line=True, context=context, settings={ 'olcRootPW': '%s' % password_hash }) self._update_crc32(new_config_path) # XXX using hdb on Fedora27 with an encrypted EBS will lead # to a `BDB0126 mmap: Invalid argument` error. just delete the file! for db_path in ['olcDatabase={2}hdb.ldif', 'olcDatabase={2}mdb.ldif']: db_path = os.path.join(context.value('etcDir'), 'openldap', 'slapd.d', 'cn=config', db_path) _, new_config_path = stageFile(db_path, context) modify_config(db_path, sep=': ', enter_block_sep=None, exit_block_sep=None, one_per_line=True, context=context, settings={ 'olcSuffix': 'dc=%s,dc=%s' % domain_parts, 'olcRootDN': 'cn=Manager,dc=%s,dc=%s' % domain_parts, 'olcRootPW': '%s' % password_hash, 'olcAccess': [ '{0}to * by dn.exact=gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth manage by * break', '{0}to attrs=userPassword by self write by dn.base="cn=Manager,dc=%s,dc=%s" write by anonymous auth by * none' % domain_parts, '{1}to * by dn.base="cn=Manager,dc=%s,dc=%s" write by self write by * read"' % domain_parts] }) self._update_crc32(new_config_path) schema_path = os.path.join(context.value('etcDir'), 'openldap', 'schema', 'openssh-ldap.ldif') _, new_schema_path = stageFile(schema_path, context) with open(new_schema_path, 'w') as schema_file: schema_file.write("""dn: cn=openssh-openldap,cn=schema,cn=config objectClass: olcSchemaConfig cn: openssh-openldap olcAttributeTypes: {0}( 1.3.6.1.4.1.24552.500.1.1.1.13 NAME 'sshPublicKey' DES C 'MANDATORY: OpenSSH Public key' EQUALITY octetStringMatch SYNTAX 1.3.6.1.4. 1.1466.115.121.1.40 ) olcObjectClasses: {0}( 1.3.6.1.4.1.24552.500.1.1.2.0 NAME 'ldapPublicKey' DESC 'MANDATORY: OpenSSH LPK objectclass' SUP top AUXILIARY MUST ( sshPublicKey $ uid ) ) """) self.create_cron_conf(context) self.create_syslogng_conf(context) postinst.create_certificate(ldapHost) postinst.shellCommand(['chmod', '750', os.path.dirname(priv_key)]) postinst.shellCommand(['chgrp', 'ldap', os.path.dirname(priv_key)]) postinst.shellCommand(['chmod', '640', priv_key]) postinst.shellCommand(['chgrp', 'ldap', priv_key]) postinst.shellCommand(['chmod', '750', os.path.dirname(priv_key)]) postinst.shellCommand(['chown', 'ldap:ldap', config_path, db_config_path, db_hdb_path]) postinst.shellCommand(['chmod', '600', config_path, db_config_path, db_hdb_path]) # We need to start the server before adding the schemas. postinst.shellCommand(['service', 'slapd', 'restart']) postinst.shellCommand(['systemctl', 'enable', 'slapd.service']) postinst.shellCommand(['ldapadd', '-Y', 'EXTERNAL', '-H', 'ldapi:///', '-f', '/etc/openldap/schema/cosine.ldif', '-D', '"cn=config"']) postinst.shellCommand(['ldapadd', '-Y', 'EXTERNAL', '-H', 'ldapi:///', '-f', '/etc/openldap/schema/nis.ldif', '-D', '"cn=config"']) postinst.shellCommand(['ldapadd', '-Y', 'EXTERNAL', '-H', 'ldapi:///', '-f', '/etc/openldap/schema/inetorgperson.ldif', '-D', '"cn=config"']) postinst.shellCommand(['ldapadd', '-Y', 'EXTERNAL', '-H', 'ldapi:///', '-f', '/etc/openldap/schema/openssh-ldap.ldif', '-D', '"cn=config"']) return complete
def run(self, context): complete = super(postgresql_serverSetup, self).run(context) if not complete: # As long as the default setup cannot find all prerequisite # executable, libraries, etc. we cannot update configuration # files here. return complete db_host = context.value('dbHost') vpc_cidr = context.value('vpc_cidr') pg_user = context.value('dbUser') postgresql_conf = os.path.join(self.pgdata, 'postgresql.conf') pg_ident_conf = os.path.join(self.pgdata, 'pg_ident.conf') pg_hba_conf = os.path.join(self.pgdata, 'pg_hba.conf') if not os.path.exists(postgresql_conf): # /var/lib/pgsql/data will be empty unless we run initdb once. shell_command([self.postgresql_setup, 'initdb']) listen_addresses = "'localhost'" for key, val in six.iteritems( self.managed['%s-server' % self.daemons[0].replace('-', '')]['files']): if key == 'listen_addresses': listen_addresses = ', '.join( ["'%s'" % address[0] for address in val]) postgresql_conf_settings = {'listen_addresses': listen_addresses} if db_host: db_ssl_key_file = "/etc/pki/tls/private/%s.key" % db_host db_ssl_cert_file = "/etc/pki/tls/certs/%s.crt" % db_host dh_params = "/etc/ssl/certs/dhparam.pem" if (os.path.exists(db_ssl_key_file) and os.path.exists(db_ssl_cert_file)): postgresql_conf_settings.update({ 'ssl': "on", 'ssl_cert_file': "'%s'" % db_ssl_cert_file, 'ssl_key_file': "'%s'" % db_ssl_key_file, 'ssl_prefer_server_ciphers': "on", #ssl_ca_file = '' #ssl_crl_file = '' #ssl_ecdh_curve = 'prime256v1' #ssl_ciphers = 'HIGH:MEDIUM:+3DES:!aNULL' # allowed SSL ciphers }) if os.path.exists(dh_params): postgresql_conf_settings.update({ 'ssl_dh_params_file': "'%s'" % dh_params, }) postinst.shellCommand( ['chown', 'root:postgres', db_ssl_key_file]) postinst.shellCommand(['chmod', '640', db_ssl_key_file]) postinst.shellCommand( ['chmod', '755', os.path.dirname(db_ssl_key_file)]) modify_config(postgresql_conf, settings=postgresql_conf_settings, sep=' = ', context=context) # pg_ident system_to_pg_mapping = {'postgres': 'postgres'} if pg_user: system_to_pg_mapping.update({'/^(.*)$': pg_user}) else: logging.warning("dbUser is '%s'. No regular user will be created"\ " to access the database remotely.") old_conf_path, new_conf_path = stageFile(pg_ident_conf, context) with open(new_conf_path, 'w') as new_conf: with open(old_conf_path) as old_conf: for line in old_conf.readlines(): look = re.match(r'^mymap\s+(\S+)\s+(\S+)', line.strip()) if look: system_user = look.group(1) if system_user in system_to_pg_mapping: self.write_ident_line( new_conf, system_user, system_to_pg_mapping[system_user]) del system_to_pg_mapping[system_user] else: new_conf.write(line) for system_user, pgident_user in six.iteritems( system_to_pg_mapping): self.write_ident_line(new_conf, system_user, pgident_user) # pg_hba connections = [ ['all', 'postgres', vpc_cidr], # 'all' because we need to add a constraint on auth_user ['all', pg_user, vpc_cidr] ] old_conf_path, new_conf_path = stageFile(pg_hba_conf, context) with open(new_conf_path, 'w') as new_conf: with open(old_conf_path) as old_conf: source_host = 'host' if (postgresql_conf_settings.get('ssl') and postgresql_conf_settings.get('ssl') == "on"): source_host = 'hostssl' for line in old_conf.readlines(): look = re.match(r'^local.*peer$', line.strip()) if look: new_conf.write(line.strip() + ' map=mymap\n') else: look = re.match(r'^(host|hostssl|hostnossl)\s+'\ '(?P<db>\S+)\s+(?P<pg_user>\S+)\s+(?P<cidr>\S+)\s+(?P<method>\S+)', line.strip()) if look: found = None remains = [] for conn in connections: if (conn[0] == look.group('db') and conn[1] == look.group('pg_user')): found = conn else: remains += [conn] connections = remains if found: new_conf.write( '%(host)s %(db)s%(pg_user)s%(cidr)smd5\n' % { 'host': source_host.ljust(10), 'db': found[0].ljust(16), 'pg_user': found[1].ljust(16), 'cidr': found[2].ljust(24) }) else: new_conf.write(line) else: new_conf.write(line) if connections: new_conf.write("# Remote connections\n") for conn in connections: new_conf.write( '%(host)s %(db)s%(pg_user)s%(cidr)smd5\n' % { 'host': source_host.ljust(10), 'db': conn[0].ljust(16), 'pg_user': conn[1].ljust(16), 'cidr': conn[2].ljust(24) }) self.create_cron_conf(context) #XXX optimizations? #https://people.planetpostgresql.org/devrim/index.php?/archives/83-Using-huge-pages-on-RHEL-7-and-PostgreSQL-9.4.html postinst.shellCommand([ '[ -d %(pgdata)s/base ] ||' % { 'pgdata': self.pgdata }, self.postgresql_setup, 'initdb' ]) return complete
def run(self, context): complete = super(iptablesSetup, self).run(context) if not complete: # As long as the default setup cannot find all prerequisite # executable, libraries, etc. we cannot update configuration # files here. return complete ports = [] forwards = [] for key, val in six.iteritems(self.managed['iptables']['files']): if key == 'port': for port, _ in val: ports += [int(port)] elif key == 'forward': for forward, _ in val: orig, dest = forward.split(':') forwards += [(int(orig), int(dest))] # We completely overwrite the iptables configuration for both # ipv4 and ipv6. We own it. _, new_conf_path = setup.stageFile(self.conf_path( context.host(), sysconfdir=context.value('etcDir')), context=context) with open(new_conf_path, 'w') as conf: if forwards: conf.write("""*nat %s COMMIT""" % '\n'.join([ "-I PREROUTING -i eth0 -p tcp --dport %d -j REDIRECT --to-port %d" % forward for forward in forwards ])) local_filter_rules = '\n'.join([ '-A INPUT -m state --state NEW -m tcp -p tcp --dport %d -j ACCEPT' % port for port in ports ]) conf.write("""*filter :INPUT DROP [1000:900000] :FORWARD DROP [0:0] :LOGNDROP - [0:0] :OUTPUT DROP [0:0] -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT -A INPUT -s 127.0.0.1 -j ACCEPT %(local_filter_rules)s -A INPUT -p icmp -m icmp --icmp-type 8 -m state --state NEW,RELATED,ESTABLISHED -j ACCEPT -A INPUT -p icmp -m icmp --icmp-type 13 -m state --state NEW,RELATED,ESTABLISHED -j ACCEPT -A INPUT -p icmp -m icmp --icmp-type 30 -m state --state NEW,RELATED,ESTABLISHED -j ACCEPT -A FORWARD -j REJECT --reject-with icmp-port-unreachable -A OUTPUT -m state --state NEW,RELATED,ESTABLISHED -j ACCEPT -A INPUT -j LOGNDROP -A LOGNDROP -m limit --limit 5/min -j LOG --log-prefix "Denied: " --log-level 7 -A LOGNDROP -j DROP COMMIT """ % {'local_filter_rules': local_filter_rules}) local6_filter_rules = '\n'.join([ '-A INPUT -m state --state NEW -m tcp -p tcp --dport %d -j ACCEPT' % port for port in ports ]) _, new_conf_path = setup.stageFile(self.conf_path( context.host(), ip_type=self.IPV6, sysconfdir=context.value('etcDir')), context=context) with open(new_conf_path, 'w') as conf: conf.write(""" *filter :INPUT DROP [1000:900000] :FORWARD DROP [0:0] :LOGNDROP - [0:0] :OUTPUT ACCEPT [0:0] -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT -A INPUT -p ipv6-icmp -j ACCEPT -A INPUT -s ::1 -j ACCEPT -A INPUT -m state --state NEW -m udp -p udp --dport 546 -d fe80::/64 -j ACCEPT %(local6_filter_rules)s -A INPUT -j LOGNDROP -A FORWARD -j REJECT --reject-with icmp6-adm-prohibited -A LOGNDROP -m limit --limit 5/min -j LOG --log-prefix "Denied: " --log-level 7 -A LOGNDROP -j DROP COMMIT """ % {'local6_filter_rules': local6_filter_rules}) # Make sure we disable firewalld, we are using static rules here. setup.postinst.shellCommand(['systemctl', 'stop', 'firewalld.service']) setup.postinst.shellCommand( ['systemctl', 'disable', 'firewalld.service']) # Create ifup-local script to load iptables rules _, new_ifup_local = setup.stageFile('/usr/sbin/ifup-local', context=context) with open(new_ifup_local, 'w') as conf: conf.write("""#!/bin/bash /sbin/iptables-restore < /etc/sysconfig/iptables /sbin/ip6tables-restore < /etc/sysconfig/ip6tables IPADDR=`hostname -I` sed -i "/^.* *%(domain)s/{h;s/.* /${IPADDR}/};\${x;/^\$/{s//${IPADDR} %(domain)s/;H};x}" /etc/hosts """ % {'domain': 'private-ip.local'}) os.chmod( new_ifup_local, stat.S_IRUSR | stat.S_IWUSR | stat.S_IXUSR | stat.S_IRGRP | stat.S_IXGRP | stat.S_IROTH | stat.S_IXOTH) setup.postinst.shellCommand(['/usr/sbin/ifup-local']) return complete