Curator: "Will not attempt to authenticate using SASL (unknown error)

created at 08-16-2021 views: 317

problem

In the later stage of the project, we plan to use zookeeper as a distributed service configuration center, and use Curator as a client middleware operation to access zookeeper. During the test and verification phase, an error "Will not attempt to authenticate using SASL (unknown error)" is reported all the time. What the fuck is "SASL"? I haven't set up "SASL" before! 

Environmental

  • zookeeper: 3.5.5
  • curator: 4.2.0

possible reason

Check the log, know the "Will not attempt to authenticate using SASL (unknown error)" pot. Then google, there are various reasons, for example, the local host file is needed because of the local IP mapping problem. I did not use SASL authentication mode, but used a simple digest authentication mode. So eliminate the local IP mapping problem. In addition, I personally feel that modifying the local host file itself is not a reasonable measure. In the end, we can only go back to the source, let's look at the source code.

There is a piece of code in the org.apache.zookeeper.ClientCnxn class as follows:

private void startConnect(InetSocketAddress addr) throws IOException {
            // initializing it for new connection
            saslLoginFailed = false;
            if(!isFirstConnect){
                try {
                    Thread.sleep(r.nextInt(1000));
                } catch (InterruptedException e) {
                    LOG.warn("Unexpected exception", e);
                }
            }
            state = States.CONNECTING;

            String hostPort = addr.getHostString() + ":" + addr.getPort();
            MDC.put("myid", hostPort);
            setName(getName().replaceAll("\\(.*\\)", "(" + hostPort + ")"));
            if (clientConfig.isSaslClientEnabled()) {
                try {
                    if (zooKeeperSaslClient != null) {
                        zooKeeperSaslClient.shutdown();
                    }
                    zooKeeperSaslClient = new ZooKeeperSaslClient(SaslServerPrincipal.getServerPrincipal(addr, clientConfig),
                        clientConfig);
                } catch (LoginException e) {
                    // An authentication error occurred when the SASL client tried to initialize:
                    // for Kerberos this means that the client failed to authenticate with the KDC.
                    // This is different from an authentication error that occurs during communication
                    // with the Zookeeper server, which is handled below.
                    LOG.warn("SASL configuration failed: " + e + " Will continue connection to Zookeeper server without "
                      + "SASL authentication, if Zookeeper server allows it.");
                    eventThread.queueEvent(new WatchedEvent(
                      Watcher.Event.EventType.None,
                      Watcher.Event.KeeperState.AuthFailed, null));
                    saslLoginFailed = true;
                }
            }
            logStartConnect(addr);

            clientCnxnSocket.connect(addr);
        }

Among them, clientConfig.isSaslClientEnabled() caught my attention. Check out its implementation:

public boolean isSaslClientEnabled() {
        return Boolean.valueOf(getProperty(ENABLE_CLIENT_SASL_KEY, ENABLE_CLIENT_SASL_DEFAULT));
    }

Found that it is true by default.

Finally, find the code that Curator configures to generate the zookeeper client instance (Curator uses ZookeeperFactory to create the zookeeper client instance)

package org.apache.curator.utils;

import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.ZooKeeper;

public class DefaultZookeeperFactory implements ZookeeperFactory
{
    @Override
    public ZooKeeper newZooKeeper(String connectString, int sessionTimeout, Watcher watcher, boolean canBeReadOnly) throws Exception
    {
        return new ZooKeeper(connectString, sessionTimeout, watcher, canBeReadOnly);
    }
}

Well, it seems that Curator is not configured by default, so it goes straight to the default value of true.

solution

The solution is actually only one step: change the value of ENABLE_CLIENT_SASL_KEY to false

The problem is how to set it to false in Curator. 

The answer is still in ZookeeperFactory. You can replace the ZookeeperFactory of CuratorFrameworkFactory.builder with a new ZookeeperFactory when creating an instance of CuratorFramework.

public ZooKeeper newZooKeeper(String connectString, int sessionTimeout, Watcher watcher, boolean canBeReadOnly)
            throws Exception {
            ZKClientConfig config = new ZKClientConfig();
         config.setProperty(ZKClientConfig.ENABLE_CLIENT_SASL_KEY, "false");

         return new ZooKeeper(connectString, sessionTimeout, watcher, canBeReadOnly, config);
}

PS: the above method is suitable for zookeeper applications that do not use SASL authentication mode. If you use SASL, please do not refer to the above solutions. In addition, there may be a solution to disable SASL on the server side. You don't have to go all the way, maybe this kind of solution is the best.

created at:08-16-2021
edited at: 08-16-2021: