[openstack-dev] Keystone Split Backend Debugging

Miller, Mark M (EB SW Cloud - R&D - Corvallis) mark.m.miller at hp.com
Mon Jul 29 21:44:26 UTC 2013


Hello,

Summary:

I am attempting to configure the Keystone H-2 release to use an Enterprise Directory as the Identity backend and SQL as the Assignment backend (without TLS for now). I first installed Keystone H-2 on an Ubuntu vm server and got it up and running using a local SQL database for both the Identity and Assignment backend. I then changed the [identity] section to use "driver = keystone.identity.backends.ldap.Identity" as well as attempting to set many of the variables in the [ldap] section of file keystone.conf. I did not expect it to work right off the bat, but I am getting no error information in the keystone.log file so I am trying to figure out how to debug what is failing. I also have tcpdump on and it is not recording any requests for the ldap port:

        tcpdump -i eth0 host ldap. mycompany.com -vv

Details:

The following non-secure python test code works to test the LDAP server connection:

      host = 'ldap://ldap.mycompany.com:389'
      base = 'o= mycompany.com'
      scope = ldap.SCOPE_SUBTREE

      def get_user_public_data(userEmail):

          ldapBound = False

          try:
              attrs = ['cn', 'mail', 'uid']

              ldap_client = ldap.initialize(host)
              r = ldap_client.search_s(base, scope, '(uid=%s)' % userEmail, attrs)

              for dn, entry in r:
                  print 'dn=', repr(dn)

                  for k in entry.keys():
                      print '\t', k, '=', entry[k]

              return "LDAP get public data completed"

          except ldap.INVALID_CREDENTIALS, errMsg:
              return 'Wrong username ili password. Error: %s' % errMsg
          except ldap.SERVER_DOWN, errMsg:
              return 'AD server not awailable. Error: %s' % errMsg
          except ldap.LDAPError, errMsg:
              return "Couldn't Connect. Error: %s" % errMsg
          finally:
              if ldapBound:
                  ldap_client.unbind_s()


      print ('get_user_public_data: ' + get_user_public_data('mark.m.miller@ mycompany.com' ))

      sys.exit(0)

The following secure python test code also works:

      import sys
      import ldap
      import getpass

      host = 'ldaps://ldap. mycompany.com:636'
      base = 'o= mycompany.com'
      scope = ldap.SCOPE_SUBTREE

      binduser = "cn=KeystoneDevUser, ou=Applications, o= mycompany.com"
      bindpw = "secretword;"

      def get_user_public_data(userEmail):

          ldapBound = False

          try:
              # build a client
      #        ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT,ldap.OPT_X_TLS_DEMAND)
              ldap.set_option(ldap.OPT_X_TLS_CACERTFILE, "d:/etc/ssl/certs/hpca2ssG2_ns.cer")
      #        ldap.set_option( ldap.OPT_DEBUG_LEVEL, 255 )

              ldap_client = ldap.initialize(host)
              ldap_client.protocol_version = ldap.VERSION3

              # perform a synchronous bind
              ldap_client.simple_bind_s(binduser,bindpw)
              ldapBound = True

              filter = ('(uid=%s)' % userEmail)
              attrs = ['cn', 'mail', 'uid', ' employeeStatus']

              r = ldap_client.search_s(base, scope, filter, attrs)

              for dn, entry in r:
                  print 'dn=', repr(dn)

                  for k in entry.keys():
                      print '\t', k, '=', entry[k]

              return "LDAP get public data completed"

          except ldap.INVALID_CREDENTIALS, errMsg:
              return 'Wrong username ili password. Error: %s' % errMsg
          except ldap.SERVER_DOWN, errMsg:
              return 'AD server not awailable. Error: %s' % errMsg
          except ldap.LDAPError, errMsg:
              return "Couldn't Connect. Error: %s" % errMsg
          finally:
              if ldapBound:
                  ldap_client.unbind_s()


      print ('get_user_public_data: ' + get_user_public_data('mark.m.miller@ mycompany.com' ))

      sys.exit(0)

Here is my keystone.conf file:

      [DEFAULT]
      # A "shared secret" between keystone and other openstack services
      admin_token = 012345SECRET99TOKEN012345

      # The IP address of the network interface to listen on
      bind_host = 0.0.0.0

      # The port number which the public service listens on
      public_port = 5000

      # The port number which the public admin listens on
      admin_port = 35357

      # The base endpoint URLs for keystone that are advertised to clients
      # (NOTE: this does NOT affect how keystone listens for connections)
      public_endpoint = http://localhost:%(public_port)s/
      admin_endpoint = http://localhost:%(admin_port)s/

      # The port number which the OpenStack Compute service listens on
      compute_port = 8774

      # Path to your policy definition containing identity actions
      policy_file = policy.json

      # Rule to check if no matching policy definition is found
      # FIXME(dolph): This should really be defined as [policy] default_rule
      policy_default_rule = admin_required

      # Role for migrating membership relationships
      # During a SQL upgrade, the following values will be used to create a new role
      # that will replace records in the user_tenant_membership table with explicit
      # role grants.  After migration, the member_role_id will be used in the API
      # add_user_to_project, and member_role_name will be ignored.
      member_role_id = 9fe2ff9ee4384b1894a90878d3e92bab
      member_role_name = _member_

      # enforced by optional sizelimit middleware (keystone.middleware:RequestBodySizeLimiter)
      max_request_body_size = 114688

      # limit the sizes of user & tenant ID/names
      max_param_size = 64

      # similar to max_param_size, but provides an exception for token values
      # max_token_size = 8192
      max_token_size = 32768

      # === Logging Options ===
      # Print debugging output
      # (includes plaintext request logging, potentially including passwords)
      debug = True

      # Print more verbose output
      verbose = True

      # Name of log file to output to. If not set, logging will go to stdout.
      log_file = keystone.log

      # The directory to keep log files in (will be prepended to --logfile)
      log_dir = /var/log/keystone

      # Use syslog for logging.
      use_syslog = False

      # syslog facility to receive log lines
      # syslog_log_facility = LOG_USER

      # If this option is specified, the logging configuration file specified is
      # used and overrides any other logging options specified. Please see the
      # Python logging module documentation for details on logging configuration
      # files.
      # log_config = logging.conf

      # A logging.Formatter log message format string which may use any of the
      # available logging.LogRecord attributes.
      log_format = %(asctime)s %(levelname)8s [%(name)s] %(message)s

      # Format string for %(asctime)s in log records.
      log_date_format = %Y-%m-%d %H:%M:%S

      # onready allows you to send a notification when the process is ready to serve
      # For example, to have it notify using systemd, one could set shell command:
      # onready = systemd-notify --ready
      # or a module with notify() method:
      # onready = keystone.common.systemd

      [sql]
      # The SQLAlchemy connection string used to connect to the database
      # connection = sqlite:///keystone.db
      connection = mysql://keystonedbadmin:password@15.253.58.141/keystone

      # the timeout before idle sql connections are reaped
      idle_timeout = 200

      [identity]
      driver = keystone.identity.backends.ldap.Identity
      # driver = keystone.identity.backends.sql.Identity

      # This references the domain to use for all Identity API v2 requests (which are
      # not aware of domains). A domain with this ID will be created for you by
      # keystone-manage db_sync in migration 008.  The domain referenced by this ID
      # cannot be deleted on the v3 API, to prevent accidentally breaking the v2 API.
      # There is nothing special about this domain, other than the fact that it must
      # exist to order to maintain support for your v2 clients.
      default_domain_id = default

      [credential]
      driver = keystone.credential.backends.sql.Credential

      [trust]
      # driver = keystone.trust.backends.sql.Trust

      # delegation and impersonation features can be optionally disabled
      # enabled = True

      [os_inherit]
      # role-assignment inheritance to projects from owning domain can be
      # optionally enabled
      # enabled = False

      [catalog]
      # dynamic, sql-based backend (supports API/CLI-based management commands)
      driver = keystone.catalog.backends.sql.Catalog

      # static, file-based backend (does *NOT* support any management commands)
      # driver = keystone.catalog.backends.templated.TemplatedCatalog

      template_file = default_catalog.templates

      [token]
      # Provides token persistence.
      driver = keystone.token.backends.sql.Token

      # Controls the token construction, validation, and revocation operations.
      # provider = keystone.token.providers.pki.Provider

      # Amount of time a token should remain valid (in seconds)
      expiration = 999986400

      # External auth mechanisms that should add bind information to token.
      # eg kerberos, x509
      # bind =

      # Enforcement policy on tokens presented to keystone with bind information.
      # One of disabled, permissive, strict, required or a specifically required bind
      # mode e.g. kerberos or x509 to require binding to that authentication.
      # enforce_token_bind = permissive

      [policy]
      driver = keystone.policy.backends.sql.Policy

      [ec2]
      driver = keystone.contrib.ec2.backends.kvs.Ec2

      [assignment]
      driver = keystone.assignment.backends.sql.Assignment

      [ssl]
      #enable = True
      enable = False
      #certfile = /etc/keystone/pki/certs/ssl_cert.pem
      #keyfile = /etc/keystone/pki/private/ssl_key.pem
      #ca_certs = /etc/keystone/pki/certs/cacert.pem
      #ca_key = /etc/keystone/pki/private/cakey.pem
      #key_size = 1024
      #valid_days = 3650
      #ca_password = None
      #cert_required = False
      #cert_subject = /C=US/ST=Unset/L=Unset/O=Unset/CN=localhost

      [signing]
      # Deprecated in favor of provider in the [token] section
      token_format = UUID
      #token_format = PKI

      #certfile = /etc/keystone/pki/certs/signing_cert.pem
      #keyfile = /etc/keystone/pki/private/signing_key.pem
      #ca_certs = /etc/keystone/pki/certs/cacert.pem
      #ca_key = /etc/keystone/pki/private/cakey.pem
      #key_size = 2048
      #valid_days = 3650
      #ca_password = None
      #cert_subject = /C=US/ST=Unset/L=Unset/O=Unset/CN=www.example.com

      [ldap]
      url = "ldap://ldap. mycompany.com:389"
      # url = "ldaps://ldap. mycompany.com:636"
      user = "cn=KeystoneDevUser, ou=Applications, o= mycompany.com"
      password = "secretword;"
      suffix = "o= mycompany.com"
      # suffix = cn=example,cn=com
      use_dumb_member = False
      allow_subtree_delete = False
      # dumb_member = cn=dumb,dc=example,dc=com

      # Maximum results per page; a value of zero ('0') disables paging (default)
      page_size = 0

      # The LDAP dereferencing option for queries. This can be either 'never',
      # 'searching', 'always', 'finding' or 'default'. The 'default' option falls
      # back to using default dereferencing configured by your ldap.conf.
      # alias_dereferencing = default

      # The LDAP scope for queries, this can be either 'one'
      # (onelevel/singleLevel) or 'sub' (subtree/wholeSubtree)
      # query_scope = one

      # user_tree_dn = ou=Users,dc=example,dc=com
      user_tree_dn = ou=People,o= mycompany.com
      # user_filter =
      user_objectclass = People
      # user_domain_id_attribute = businessCategory
      # user_id_attribute = cn
      user_id_attribute = uid
      user_name_attribute = cn
      user_mail_attribute = mail
      user_pass_attribute = userPassword
      user_enabled_attribute = employeeStatus
      # user_enabled_mask = 0
      user_enabled_default = "Active"
      user_attribute_ignore = tenant_id,tenants
      user_allow_create = False
      user_allow_update = False
      user_allow_delete = False
      user_enabled_emulation = False
      # user_enabled_emulation_dn =

      # tenant_tree_dn = ou=Projects,dc=example,dc=com
      # tenant_filter =
      # tenant_objectclass = groupOfNames
      # tenant_domain_id_attribute = businessCategory
      # tenant_id_attribute = cn
      # tenant_member_attribute = member
      # tenant_name_attribute = ou
      # tenant_desc_attribute = desc
      # tenant_enabled_attribute = enabled
      # tenant_attribute_ignore =
      # tenant_allow_create = True
      # tenant_allow_update = True
      # tenant_allow_delete = True
      # tenant_enabled_emulation = False
      # tenant_enabled_emulation_dn =

      # role_tree_dn = ou=Roles,dc=example,dc=com
      # role_filter =
      # role_objectclass = organizationalRole
      # role_id_attribute = cn
      # role_name_attribute = ou
      # role_member_attribute = roleOccupant
      # role_attribute_ignore =
      # role_allow_create = True
      # role_allow_update = True
      # role_allow_delete = True

      # group_tree_dn =
      # group_filter =
      # group_objectclass = groupOfNames
      # group_id_attribute = cn
      # group_name_attribute = ou
      # group_member_attribute = member
      # group_desc_attribute = desc
      # group_attribute_ignore =
      # group_allow_create = True
      # group_allow_update = True
      # group_allow_delete = True

      # ldap TLS options
      # if both tls_cacertfile and tls_cacertdir are set then
      # tls_cacertfile will be used and tls_cacertdir is ignored
      # valid options for tls_req_cert are demand, never, and allow
      use_tls = False
      # tls_cacertfile =
      tls_cacertdir =
      # tls_req_cert = demand

      # Additional attribute mappings can be used to map ldap attributes to internal
      # keystone attributes. This allows keystone to fulfill ldap objectclass
      # requirements. An example to map the description and gecos attributes to a
      # user's name would be:
      # user_additional_attribute_mapping = description:name, gecos:name
      #
      # domain_additional_attribute_mapping =
      # group_additional_attribute_mapping =
      # role_additional_attribute_mapping =
      # project_additional_attribute_mapping =
      # user_additional_attribute_mapping =

      [auth]
      methods = external,password,token
      #external = keystone.auth.plugins.external.ExternalDefault
      password = keystone.auth.plugins.password.Password
      token = keystone.auth.plugins.token.Token

      [paste_deploy]
      # Name of the paste configuration file that defines the available pipelines
      config_file = keystone-paste.ini

Keystone.log file contents:

        Simply restates the keystone.conf file contents.



-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.openstack.org/pipermail/openstack-dev/attachments/20130729/f05f239a/attachment.html>


More information about the OpenStack-dev mailing list