zookeeper-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Martin Gainty <mgai...@hotmail.com>
Subject Re: SASL jaas.conf principal="*" problem
Date Thu, 08 Feb 2018 20:16:37 GMT

MG>a few questions on modifying Subject Principals

MG>security manager must grant AuthPermissionHolder.MODIFY_PRINCIPALS_PERMISSION for your

MG>assume $JRE_HOME/lib/security/java.policy contains something like:

grant {
    // There is no restriction to any algorithms.
    permission javax.crypto.CryptoAllPermission;
    //no restrictions to modifying Principals
    permission AuthPermissionHolder.MODIFY_PRINCIPALS_PERMISSION;

MG>then ZK should pass SecurityManager MODIFY_PRINCIPALS_PERMISSION

 java.lang.SecurityManager sm = System.getSecurityManager();
               if (sm != null) {
                   switch (which) {
                   case Subject.PRINCIPAL_SET:

MG>assuming you have -Djava.security.debug=ALL have you seen permission errors?

MG>Zookeeper implementation consideration:
MG>if ZK session is quiesced you may lose Principal credentials (as there is no serialization
for credentials)

       "credentials associated with the <code>Subject</code> are not. Note that
the "
      "< code>java.security.Principal</code> class does not implement <code>Serializable</code>.
      "Therefore ALL concrete <code>Principal</code> implementations associated
with Subjects MUST"
       "IMPLEMENT <code>Serializable</code>."

MG>Zookeeper devs where are Zookeeper Principal concrete classes (which implement Serializable)?

MG>Jaas.conf CallbackHandlers are *usually* one of predefined LoginModules:

  *   JndiLoginModule<https://docs.oracle.com/javase/7/docs/jre/api/security/jaas/spec/com/sun/security/auth/module/JndiLoginModule.html>
  *   KeyStoreLoginModule<https://docs.oracle.com/javase/7/docs/jre/api/security/jaas/spec/com/sun/security/auth/module/KeyStoreLoginModule.html>
  *   Krb5LoginModule<https://docs.oracle.com/javase/7/docs/jre/api/security/jaas/spec/com/sun/security/auth/module/Krb5LoginModule.html>
  *   NTLoginModule<https://docs.oracle.com/javase/7/docs/jre/api/security/jaas/spec/com/sun/security/auth/module/NTLoginModule.html>
  *   UnixLoginModule<https://docs.oracle.com/javase/7/docs/jre/api/security/jaas/spec/com/sun/security/auth/module/UnixLoginModule.html>

MG>questions on Zookeeper org.apache.zookeeper.server.auth.DigestLoginModule

MG>org.apache.zookeeper.server.auth.DigestLoginModule implements LoginModule

    public void initialize(Subject subject, CallbackHandler callbackHandler, Map<String,?>
sharedState, Map<String,?> options) { //assume options is JAAS options

        if (options.containsKey("username")) {
            // Zookeeper client: get username and password from JAAS conf (only used if using
            this.subject = subject;
            String username = (String)options.get("username");
            String password = (String)options.get("password");

MG>since following is NOT overridden by ZK concrete class.. can we can lose credentials
during session quiesce?

   public boolean login() {
//Unlike Krb5LoginModule, we don't do any actual login or credential passing here:
//authentication to Zookeeper is done later, through the SASLClient object.

        return true;

  MG>DigestLoginModule::login authentication would happen @
  MG>ZooKeeperSaslClient.ZooKeeperSaslClient(final String serverPrincipal) which calls
to createSaslClient below:

MG>createSaslClient reference from ZK .\org\apache\zookeeper\client\ZooKeeperSaslClient.java

  synchronized private SaslClient createSaslClient(final String servicePrincipal,
                                                     final String loginContext) throws LoginException
        try {
            if (login == null) {
                if (LOG.isDebugEnabled()) {
                    LOG.debug("JAAS loginContext is: " + loginContext);
                // note that the login object is static: it's shared amongst ALL zookeeper-related
                // createSaslClient() must be declared synchronized so that login is initialized
only once.
                login = new Login(loginContext, new ClientCallbackHandler(null));
MG>where ClientCallbackHandler is inner class
            Subject subject = login.getSubject();
MG>Regular/Public/Private Principals *should* be contained with Subject (from login
            SaslClient saslClient;
            // Use subject.getPrincipals().isEmpty() as an indication of which SASL mechanism
to use:
            // if empty, use DIGEST-MD5; otherwise, use GSSAPI.
            if (subject.getPrincipals().isEmpty()) {
                // no principals: must not be GSSAPI: use DIGEST-MD5 mechanism instead.
                LOG.info("Client will use DIGEST-MD5 as SASL mechanism.");
                String[] mechs = {"DIGEST-MD5"};
MG>Login *contains* Subject *which contains* PublicCredentials/PrivateCredentials
                String username = (String)(subject.getPublicCredentials().toArray()[0]);
                String password = (String)(subject.getPrivateCredentials().toArray()[0]);
                // "zk-sasl-md5" is a hard-wired 'domain' parameter shared with zookeeper
server code (see ServerCnxnFactory.java)
                saslClient = Sasl.createSaslClient(mechs, username, "zookeeper",
"zk-sasl-md5", null, new ClientCallbackHandler(password));
                return saslClient;

MG>instead of obtaining thru Private Creds via (String)(subject.getPrivateCredentials().toArray()[0])MG>confused
on reason 4 hardcoded 'zookeeper' password referenced from above Sasl.createSaslClient?

MG>$JRE_HOME/lib/security/java.security entries verification :
MG>can you verify

MG>can you verify authentication Principal is set to EITHER u as in
Context.SECURITY_PRINCIPAL="u: cuser"
MG>OR authentication Principal is set to DistinguishedName
Context.SECURITY_PRINCIPAL="dn: cn=C. User, ou=NewHires, o=JNDITutorial"

MG>ZooKeeperSaslClient considerations:

   ZooKeeperSaslClient(final String serverPrincipal)  is instantiated in org.apache.zookeeper.ClientCnxn.java

    String principalUserName = System.getProperty("zookeeper.sasl.client.username", "zookeeper");
                    if(principalUserName!=null) zooKeeperSaslClient =
                        new ZooKeeperSaslClient(

MG>what is value of zookeeper.sasl.client.username System Property

From: Martin Gainty <mgainty@hotmail.com>
Sent: Wednesday, February 7, 2018 12:03 PM
To: user@zookeeper.apache.org
Subject: Re: SASL jaas.conf principal="*" problem

MG>i agree.. DIGEST-MD5 (and not kerberos) seems to be default authentication for zookeeper

SaslServer saslServer = Sasl.createSaslServer("DIGEST-MD5","zookeeper","zk-sasl-md5",null,

MG>to ask a dumb question..where is DIGEST-MD5.conf located in zookeeper binary distro?
MG>or is it sufficient to supply DIGEST-MD5.conf parameters in jaas.conf?

From: Andor Molnar <andor@cloudera.com>
Sent: Wednesday, February 7, 2018 10:29 AM
To: user@zookeeper.apache.org
Subject: Re: SASL jaas.conf principal="*" problem

Hi Botond,

I believe the guy who originally implemented this (Rakesh) can give some
color to your question, but until that you could dig the original Jira:
[ZOOKEEPER-1045] Support Quorum Peer mutual authentication ...<https://issues.apache.org/jira/browse/ZOOKEEPER-1045>
ZOOKEEPER-938 addresses mutual authentication between clients and servers. This bug, on the
other hand, is for authentication among quorum peers.

[ZOOKEEPER-1045] Support Quorum Peer mutual authentication ...<https://issues.apache.org/jira/browse/ZOOKEEPER-1045>
[ZOOKEEPER-1045] Support Quorum Peer mutual authentication ...<https://issues.apache.org/jira/browse/ZOOKEEPER-1045>
ZOOKEEPER-938 addresses mutual authentication between clients and servers. This bug, on the
other hand, is for authentication among quorum peers.

ZOOKEEPER-938 addresses mutual authentication between clients and servers. This bug, on the
other hand, is for authentication among quorum peers.

for more information.

Other than that, if you believe that you can either fix the issue or
implement it in a better way, your contribution will be highly
appreciated and it would be very kind of you to open new Jira and new pull
request on GitHub.

We can discuss further details there.


On Mon, Feb 5, 2018 at 7:21 PM, Botond Hejj <Botond.Hejj@morganstanley.com>

> Hi,
> Java 8 introduced the possibility to use * for the principal in treadmill
> which is great and would allow us to run treadmill behind multiple
> interfaces and SASL would pick the right keytab.
> Unfortunately this doesn't work in ZooKeeper I have dived in the code a bit
> and what I have found is that ZooKeeper is using DIGEST-MD5 in that case
> even though I don't use the DigestLoginModule. The reason for that is line
> 251 here:
> https://github.com/apache/zookeeper/blob/master/src/java/main/org/apache/

zookeeper - Mirror of Apache Hadoop ZooKeeper



zookeeper - Mirror of Apache Hadoop ZooKeeper

zookeeper - Mirror of Apache Hadoop ZooKeeper

> zookeeper/util/SecurityUtils.java
> It falls back to Digest if the principal list is empty which is the case
> when * is specified.
> Why is that and why not the login type is checked?
> Anyway this can only be fixed in a nonbackward compatible way or with a
> flag in a backward compatible way.
> I could prepare a patch.
> I would just like to understand the reason behind the implementation. Is
> there any particular reason why this fallback is there? What would the
> implication if I remove that? If I understand the reason maybe I could
> patch it without breaking backward compatibility.
> There is also a comment: TODO: use 'authMech=' value in zoo.cfg.
> Is there any jira or patch for that?
> Regards,
> Botond Hejj
> Morgan Stanley | Technology
> Lechner Odon fasor 8 | Floor 07
> Budapest, 1095
> Phone: +36 1 881-3962
> Botond.Hejj@MorganStanley.com

  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message