I’ve got a packstack install, and a Kerberos-capable Keystone. Time to call it from Horizon. Time to set up S4U2Proxy.
I’ll be following the steps laid out by Alexander Bokovoy. This is a work in progress, and I’ll update as I learn more.
First step is to enable Kerberos on the Horizon server, regardless of other login mechanism. I have /etc/httpd/conf.d/wsgi-horizon.conf with
WSGIDaemonProcess horizon_ssl user=fedora group=wheel processes=3 threads=10 home=/opt/stack/horizon SetEnv APACHE_RUN_USER fedora SetEnv APACHE_RUN_GROUP wheel WSGIProcessGroup horizon DocumentRoot /opt/stack/horizon/.blackhole/ Alias /media /opt/stack/horizon/openstack_dashboard/static Alias /static /opt/stack/horizon/static ErrorLog /var/log/httpd/horizon_error.log LogLevel warn CustomLog /var/log/httpd/horizon_access.log combinedOptions FollowSymLinks AllowOverride None Options Indexes FollowSymLinks MultiViews Require all granted AllowOverride None Order allow,deny allow from all WSGIProcessGroup horizon_ssl NSSRequireSSL AuthType Kerberos AuthName "Kerberos Login" KrbMethodNegotiate on KrbMethodK5Passwd off KrbServiceName HTTP KrbAuthRealms IPA.CLOUDLAB.FREEIPA.ORG Krb5KeyTab /etc/httpd/conf/openstack.keytab KrbSaveCredentials on #this next one is needed for S4U2 # KrbConstrainedDelegation on Require valid-user WSGISocketPrefix /var/run/httpd
For my server cn=s4u2proxy,cn=etc,$SUFFIX is going to expand to: cn=s4u2proxy,cn=etc,dc=ipa,dc=cloudlab,dc=freeipa,dc=org
$ ldapsearch -Y GSSAPI -H ldap://ipa.cloudlab.freeipa.org -b cn=s4u2proxy,cn=etc,dc=ipa,dc=cloudlab,dc=freeipa,dc=org "" SASL/GSSAPI authentication started SASL username: ayoung@IPA.CLOUDLAB.FREEIPA.ORG SASL SSF: 56 SASL data security layer installed. # extended LDIF # # LDAPv3 # basewith scope subtree # filter: (objectclass=*) # requesting: # # s4u2proxy, etc, ipa.cloudlab.freeipa.org dn: cn=s4u2proxy,cn=etc,dc=ipa,dc=cloudlab,dc=freeipa,dc=org # ipa-http-delegation, s4u2proxy, etc, ipa.cloudlab.freeipa.org dn: cn=ipa-http-delegation,cn=s4u2proxy,cn=etc,dc=ipa,dc=cloudlab,dc=freeipa,d c=org # ipa-ldap-delegation-targets, s4u2proxy, etc, ipa.cloudlab.freeipa.org dn: cn=ipa-ldap-delegation-targets,cn=s4u2proxy,cn=etc,dc=ipa,dc=cloudlab,dc=f reeipa,dc=org # ipa-cifs-delegation-targets, s4u2proxy, etc, ipa.cloudlab.freeipa.org dn: cn=ipa-cifs-delegation-targets,cn=s4u2proxy,cn=etc,dc=ipa,dc=cloudlab,dc=f reeipa,dc=org
Now, in Alexander’s article he delegates to LDAP. But Keystone is an HTTP server. There is no entry yet for an HTTP delegation target.
lets look at the LDAP one:
$ ldapsearch -Y GSSAPI -H ldap://ipa.cloudlab.freeipa.org -b cn=s4u2proxy,cn=etc,dc=ipa,dc=cloudlab,dc=freeipa,dc=org "(cn=ipa-ldap-delegation-targets)" SASL/GSSAPI authentication started SASL username: ayoung@IPA.CLOUDLAB.FREEIPA.ORG SASL SSF: 56 SASL data security layer installed. # extended LDIF # # LDAPv3 # basewith scope subtree # filter: (cn=ipa-ldap-delegation-targets) # requesting: ALL # # ipa-ldap-delegation-targets, s4u2proxy, etc, ipa.cloudlab.freeipa.org dn: cn=ipa-ldap-delegation-targets,cn=s4u2proxy,cn=etc,dc=ipa,dc=cloudlab,dc=f reeipa,dc=org objectClass: groupOfPrincipals objectClass: top cn: ipa-ldap-delegation-targets memberPrincipal: ldap/ipa.cloudlab.freeipa.org@IPA.CLOUDLAB.FREEIPA.ORG
I’m going to make a rule specific to Keystone, not a general HTTP-to-HTTP delegation, So the first ldif I need should look like this:
dn: cn=ipa-keystone-delegation-targets,cn=s4u2proxy,cn=etc,dc=ipa,dc=cloudlab,dc=freeipa,dc=org objectClass: groupOfPrincipals objectClass: top cn: ipa-http-delegation-targets memberPrincipal: HTTP/ayoungf20packstack.cloudlab.freeipa.org@IPA.CLOUDLAB.FREEIPA.ORG
It means that something can get a service ticket to ayoungf20packstack on behalf of another user. What that something will be defined by another rule. Lets look at an existing one:
$ ldapsearch -Y GSSAPI -H ldap://ipa.cloudlab.freeipa.org -b cn=s4u2proxy,cn=etc,dc=ipa,dc=cloudlab,dc=freeipa,dc=org \ "(cn=ipa-http-delegation)" SASL/GSSAPI authentication started SASL username: ayoung@IPA.CLOUDLAB.FREEIPA.ORG SASL SSF: 56 SASL data security layer installed. # extended LDIF # # LDAPv3 # basewith scope subtree # filter: (cn=ipa-http-delegation) # requesting: ALL # # ipa-http-delegation, s4u2proxy, etc, ipa.cloudlab.freeipa.org dn: cn=ipa-http-delegation,cn=s4u2proxy,cn=etc,dc=ipa,dc=cloudlab,dc=freeipa,dc=org objectClass: ipaKrb5DelegationACL objectClass: groupOfPrincipals objectClass: top cn: ipa-http-delegation memberPrincipal: HTTP/ipa.cloudlab.freeipa.org@IPA.CLOUDLAB.FREEIPA.ORG ipaAllowedTarget: cn=ipa-ldap-delegation-targets,cn=s4u2proxy,cn=etc,dc=ipa,dc =cloudlab,dc=freeipa,dc=org ipaAllowedTarget: cn=ipa-cifs-delegation-targets,cn=s4u2proxy,cn=etc,dc=ipa,dc =cloudlab,dc=freeipa,dc=org
Now, I can’t reuse this rule: it would give Horizon the ability to talk directly to LDAP as the user that logged in, and that is WAY too much power. I’m going to create a new delegation rule.
dn: cn=ipa-keystone-delegation,cn=s4u2proxy,cn=etc,dc=ipa,dc=cloudlab,dc=freeipa,dc=org objectClass: ipaKrb5DelegationACL objectClass: groupOfPrincipals objectClass: top cn: ipa-keystone-delegation memberPrincipal: HTTP/ayoungdevstack20.cloudlab.freeipa.org@IPA.CLOUDLAB.FREEIPA.ORG ipaAllowedTarget: cn=ipa-keystone-delegation-targets,cn=s4u2proxy,cn=etc,dc=ipa,dc =cloudlab,dc=freeipa,dc=org
This may be working. It may not. All I know now is I can still log in with a userid and password, but only if I’ve performed a kinit. The next step is to convert Horizon to use Kerberos to talk to Keystone. That means that Horizon has to make use of a Kerberos Auth plugin. Will this work? Tune in next time and find out.