From 0b578c4a5961baf85275a5cbc93676aca61758b5 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Fri, 18 Apr 2014 00:43:37 -0400 Subject: [PATCH] Make it easy to install mutiple server instances Signed-off-by: Simo Sorce --- ipsilon/install/ipsilon-server-install | 33 ++++++++++++++++++++++---- ipsilon/login/authkrb.py | 23 ++++++++---------- ipsilon/providers/saml2idp.py | 7 ++---- templates/install/idp.conf | 8 +++---- templates/install/ipsilon.conf | 8 +++---- 5 files changed, 48 insertions(+), 31 deletions(-) diff --git a/ipsilon/install/ipsilon-server-install b/ipsilon/install/ipsilon-server-install index 4ae0c8f..dd30c9a 100755 --- a/ipsilon/install/ipsilon-server-install +++ b/ipsilon/install/ipsilon-server-install @@ -20,6 +20,7 @@ from ipsilon.login.common import LoginMgrsInstall from ipsilon.providers.common import ProvidersInstall from ipsilon.util.data import Store +from ipsilon.tools import files import argparse import cherrypy import logging @@ -33,6 +34,7 @@ import time TEMPLATES = '/usr/share/ipsilon/templates/install' CONFDIR = '/etc/ipsilon' +DATADIR = '/var/lib/ipsilon' HTTPDCONFD = '/etc/httpd/conf.d' @@ -76,19 +78,33 @@ def openlogs(): def install(plugins, args): logger.info('Installation initiated') now = time.strftime("%Y%m%d%H%M%S", time.gmtime()) + instance_conf = os.path.join(CONFDIR, args['instance']) logger.info('Installing default config files') - ipsilon_conf = os.path.join(CONFDIR, 'ipsilon.conf') - idp_conf = os.path.join(CONFDIR, 'idp.conf') - args['httpd_conf'] = os.path.join(HTTPDCONFD, 'idp.conf') + ipsilon_conf = os.path.join(instance_conf, 'ipsilon.conf') + idp_conf = os.path.join(instance_conf, 'idp.conf') + args['httpd_conf'] = os.path.join(HTTPDCONFD, + 'ipsilon-%s.conf' % args['instance']) + args['data_dir'] = os.path.join(DATADIR, args['instance']) if os.path.exists(ipsilon_conf): shutil.move(ipsilon_conf, '%s.bakcup.%s' % (ipsilon_conf, now)) if os.path.exists(idp_conf): shutil.move(idp_conf, '%s.backup.%s' % (idp_conf, now)) - shutil.copy(os.path.join(TEMPLATES, 'ipsilon.conf'), CONFDIR) - shutil.copy(os.path.join(TEMPLATES, 'idp.conf'), CONFDIR) + if not os.path.exists(instance_conf): + os.makedirs(instance_conf, 0700) + confopts = {'instance': args['instance'], 'datadir': args['data_dir']} + files.write_from_template(ipsilon_conf, + os.path.join(TEMPLATES, 'ipsilon.conf'), + confopts) + files.write_from_template(idp_conf, + os.path.join(TEMPLATES, 'idp.conf'), + confopts) if not os.path.exists(args['httpd_conf']): os.symlink(idp_conf, args['httpd_conf']) + os.makedirs(os.path.join(args['data_dir'], 'sessions'), 0700) + data_conf = os.path.join(args['data_dir'], 'ipsilon.conf') + if not os.path.exists(data_conf): + os.symlink(ipsilon_conf, data_conf) # Load the cherrypy config from the newly installed file so # that db paths and all is properly set before configuring # components @@ -116,6 +132,9 @@ def install(plugins, args): plugin = plugins['Auth Providers'][plugin_name] plugin.configure(args) + # Fixup permissions so only the ipsilon user can read these files + files.fix_user_dirs(instance_conf, opts['system_user'], mode=0500) + files.fix_user_dirs(args['data_dir'], opts['system_user']) def uninstall(plugins, args): logger.info('Uninstallation initiated') @@ -138,6 +157,8 @@ def parse_args(plugins): help='Comma separated list of login managers') parser.add_argument('--hostname', help="Machine's fully qualified host name") + parser.add_argument('--instance', default='idp', + help="IdP instance name, each is a separate idp") parser.add_argument('--system-user', default='ipsilon', help="User account used to run the server") parser.add_argument('--admin-user', default='admin', @@ -186,6 +207,8 @@ def parse_args(plugins): args['lm_order'] = ['pam'] args['pam'] = 'yes' + #FIXME: check instance is only alphanums + return args if __name__ == '__main__': diff --git a/ipsilon/login/authkrb.py b/ipsilon/login/authkrb.py index d012ea8..c67b93b 100755 --- a/ipsilon/login/authkrb.py +++ b/ipsilon/login/authkrb.py @@ -87,7 +87,7 @@ plugin for actual authentication. """ CONF_TEMPLATE = """ - + AuthType Kerberos AuthName "Kerberos Login" KrbMethodNegotiate on @@ -100,7 +100,7 @@ CONF_TEMPLATE = """ # KrbLocalUserMapping On Require valid-user - ErrorDocument 401 /idp/login/krb/unauthorized + ErrorDocument 401 /${instance}/login/krb/unauthorized """ @@ -124,23 +124,20 @@ class Installer(object): if opts['krb'] != 'yes': return - keytab = ' # Krb5KeyTab - No Keytab provided' - if opts['krb_httpd_keytab'] is None: - if os.path.exists('/etc/httpd/conf/http.keytab'): - keytab = ' Krb5KeyTab /etc/httpd/conf/http.keytab' + confopts = {'instance': opts['instance']} + + if os.path.exists(opts['krb_httpd_keytab']): + confopts['keytab'] = ' Krb5KeyTab %s' % opts['krb_httpd_keytab'] else: - if os.path.exists(opts['krb_httpd_keytab']): - keytab = ' Krb5KeyTab %s' % opts['krb_httpd_keytab'] - else: - raise Exception('Keytab not found') + raise Exception('Keytab not found') if opts['krb_realms'] is None: - realms = ' # KrbAuthRealms - Any trusted realm is allowed' + confopts['realms'] = ' # KrbAuthRealms - Any realm is allowed' else: - realms = ' KrbAuthRealms %s' % opts['krb_realms'] + confopts['realms'] = ' KrbAuthRealms %s' % opts['krb_realms'] tmpl = Template(CONF_TEMPLATE) - hunk = tmpl.substitute(keytab=keytab, realms=realms) + hunk = tmpl.substitute(**confopts) # pylint: disable=star-args with open(opts['httpd_conf'], 'a') as httpd_conf: httpd_conf.write(hunk) diff --git a/ipsilon/providers/saml2idp.py b/ipsilon/providers/saml2idp.py index 0ac2a72..3f3ab87 100755 --- a/ipsilon/providers/saml2idp.py +++ b/ipsilon/providers/saml2idp.py @@ -246,16 +246,13 @@ class Installer(object): def install_args(self, group): group.add_argument('--saml2', choices=['yes', 'no'], default='yes', help='Configure SAML2 Provider') - group.add_argument('--saml2-storage', - default='/var/lib/ipsilon/saml2', - help='SAML2 Provider storage area') def configure(self, opts): if opts['saml2'] != 'yes': return # Check storage path is present or create it - path = opts['saml2_storage'] + path = os.path.join(opts['data_dir'], 'saml2') if not os.path.exists(path): os.makedirs(path, 0700) @@ -264,7 +261,7 @@ class Installer(object): cert.generate('idp', opts['hostname']) # Generate Idp Metadata - url = 'https://' + opts['hostname'] + '/idp/saml2' + url = 'https://' + opts['hostname'] + '/' + opts['instance'] + '/saml2' meta = metadata.Metadata(metadata.IDP_ROLE) meta.set_entity_id(url + '/metadata') meta.add_certs(cert, cert) diff --git a/templates/install/idp.conf b/templates/install/idp.conf index 6d5c493..ea4a769 100644 --- a/templates/install/idp.conf +++ b/templates/install/idp.conf @@ -1,7 +1,7 @@ -Alias /idp/ui /usr/share/ipsilon/ui -WSGIScriptAlias /idp /usr/sbin/ipsilon -WSGIDaemonProcess idp user=ipsilon group=ipsilon -WSGIProcessGroup idp +Alias /${instance}/ui /usr/share/ipsilon/ui +WSGIScriptAlias /${instance} /usr/sbin/ipsilon +WSGIDaemonProcess ${instance} user=ipsilon group=ipsilon home=${datadir} +WSGIProcessGroup ${instance} Require all granted diff --git a/templates/install/ipsilon.conf b/templates/install/ipsilon.conf index b73fc89..3c9226f 100644 --- a/templates/install/ipsilon.conf +++ b/templates/install/ipsilon.conf @@ -2,13 +2,13 @@ debug = False log.screen = False -base.mount = "/idp" +base.mount = "/${instance}" base.dir = "/usr/share/ipsilon" -admin.config.db = "/var/lib/ipsilon/adminconfig.sqlite" -user.prefs.db = "/var/lib/ipsilon/userprefs.sqlite" +admin.config.db = "${datadir}/adminconfig.sqlite" +user.prefs.db = "${datadir}/userprefs.sqlite" tools.sessions.on = True tools.sessions.storage_type = "file" -tools.sessions.storage_path = "/var/lib/ipsilon/sessions" +tools.sessions.storage_path = "${datadir}/sessions" tools.sessions.timeout = 60 tools.protect.on = True -- 2.20.1