S4U2Proxy for Horizon

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 combined

    
        Options 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
# base  with 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
# base  with 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
# base  with 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.

Leave a Reply

Your email address will not be published. Required fields are marked *