Thomas Larsson created OOZIE-2809:
-------------------------------------

             Summary: Oozie HA with secure zookeeper access fails because 
ZKUtils#setJaasConfiguration does not replace "_HOST" in principal string
                 Key: OOZIE-2809
                 URL: https://issues.apache.org/jira/browse/OOZIE-2809
             Project: Oozie
          Issue Type: Bug
          Components: core
    Affects Versions: 4.3.0, 4.2.0, trunk
            Reporter: Thomas Larsson


Setting "oozie.zookeeper.secure" = true causes the oozie server not to start if 
"oozie.service.HadoopAccessorService.kerberos.principal" is defined with a 
"_HOST" token instead of an actual hostname.

The symptom when this happens is that the oozie log shows something like this:
{noformat}
org.apache.oozie.service.ServiceException: E1700: Issue communicating with 
ZooKeeper: KeeperErrorCode = NoAuth for /oozie/services/servers
        at org.apache.oozie.service.ZKLocksService.init(ZKLocksService.java:76)
        at 
org.apache.oozie.service.Services.setServiceInternal(Services.java:386)
        at org.apache.oozie.service.Services.setService(Services.java:372)
        at org.apache.oozie.service.Services.loadServices(Services.java:305)
        at org.apache.oozie.service.Services.init(Services.java:213)
        at 
org.apache.oozie.servlet.ServicesLoader.contextInitialized(ServicesLoader.java:46)
        at 
org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4210)
        at 
org.apache.catalina.core.StandardContext.start(StandardContext.java:4709)
        at 
org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:802)
        at 
org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:779)
        at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:583)
        at 
org.apache.catalina.startup.HostConfig.deployDescriptor(HostConfig.java:676)
        at 
org.apache.catalina.startup.HostConfig.deployDescriptors(HostConfig.java:602)
        at 
org.apache.catalina.startup.HostConfig.deployApps(HostConfig.java:503)
        at org.apache.catalina.startup.HostConfig.start(HostConfig.java:1322)
        at 
org.apache.catalina.startup.HostConfig.lifecycleEvent(HostConfig.java:325)
        at 
org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(LifecycleSupport.java:142)
        at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1068)
        at org.apache.catalina.core.StandardHost.start(StandardHost.java:822)
        at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1060)
        at 
org.apache.catalina.core.StandardEngine.start(StandardEngine.java:463)
        at 
org.apache.catalina.core.StandardService.start(StandardService.java:525)
        at 
org.apache.catalina.core.StandardServer.start(StandardServer.java:759)
        at org.apache.catalina.startup.Catalina.start(Catalina.java:595)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at 
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
        at 
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:606)
        at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:289)
        at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:414)
Caused by: org.apache.zookeeper.KeeperException$NoAuthException: 
KeeperErrorCode = NoAuth for /oozie/services/servers
        at org.apache.zookeeper.KeeperException.create(KeeperException.java:113)
        at org.apache.zookeeper.KeeperException.create(KeeperException.java:51)
        at org.apache.zookeeper.ZooKeeper.create(ZooKeeper.java:783)
        at org.apache.curator.utils.ZKPaths.mkdirs(ZKPaths.java:199)
        at 
org.apache.curator.framework.imps.CreateBuilderImpl$11.call(CreateBuilderImpl.java:682)
        at 
org.apache.curator.framework.imps.CreateBuilderImpl$11.call(CreateBuilderImpl.java:660)
        at org.apache.curator.RetryLoop.callWithRetry(RetryLoop.java:107)
        at 
org.apache.curator.framework.imps.CreateBuilderImpl.pathInForeground(CreateBuilderImpl.java:656)
        at 
org.apache.curator.framework.imps.CreateBuilderImpl.protectedPathInForeground(CreateBuilderImpl.java:441)
        at 
org.apache.curator.framework.imps.CreateBuilderImpl.forPath(CreateBuilderImpl.java:431)
        at 
org.apache.curator.framework.imps.CreateBuilderImpl.forPath(CreateBuilderImpl.java:44)
        at 
org.apache.curator.x.discovery.details.ServiceDiscoveryImpl.internalRegisterService(ServiceDiscoveryImpl.java:176)
        at 
org.apache.curator.x.discovery.details.ServiceDiscoveryImpl.registerService(ServiceDiscoveryImpl.java:150)
        at org.apache.oozie.util.ZKUtils.advertiseService(ZKUtils.java:217)
        at org.apache.oozie.util.ZKUtils.<init>(ZKUtils.java:141)
        at org.apache.oozie.util.ZKUtils.register(ZKUtils.java:154)
        at org.apache.oozie.service.ZKLocksService.init(ZKLocksService.java:70)
        ... 29 more
2017-02-24 14:03:23,683  INFO Services:520 - 
SERVER[datavault-dev-app1.internal.machines] Shutdown
{noformat}

This seems to come from the class 
[org.apache.oozie.util.ZKUtils|https://git-wip-us.apache.org/repos/asf?p=oozie.git;a=blob;f=core/src/main/java/org/apache/oozie/util/ZKUtils.java;h=5835fb2bd7460809743d21ac16f2992c353ada71;hb=HEAD#l357]

{code}
    private void setJaasConfiguration() throws ServiceException, IOException {
        String keytabFile = Services.get().getConf().get(KERBEROS_KEYTAB, 
System.getProperty("user.home") + "/oozie.keytab").trim();
        if (keytabFile.length() == 0) {
            throw new ServiceException(ErrorCode.E0026, KERBEROS_KEYTAB);
        }
        String principal = Services.get().getConf().get(KERBEROS_PRINCIPAL, 
"oozie/localhost@LOCALHOST");
        if (principal.length() == 0) {
            throw new ServiceException(ErrorCode.E0026, KERBEROS_PRINCIPAL);
        }

        // This is equivalent to writing a jaas.conf file and setting the 
system property, "java.security.auth.login.config", to
        // point to it (but this way we don't have to write a file, and it 
works better for the tests)
        JaasConfiguration.addEntry("Client", principal, keytabFile);
        Configuration.setConfiguration(JaasConfiguration.getInstance());
    }
{code}

Compare how the principal is set without any string replacement with how it is 
done in class 
[org.apache.oozie.service.HadoopAccessorService|https://git-wip-us.apache.org/repos/asf?p=oozie.git;a=blob;f=core/src/main/java/org/apache/oozie/service/HadoopAccessorService.java;h=5377127736cf189bcf4aa3d62bbbeab6b3a29d52;hb=HEAD#l226]

{code}
    private void kerberosInit(Configuration serviceConf) throws 
ServiceException {
            try {
                String keytabFile = ConfigurationService.get(serviceConf, 
KERBEROS_KEYTAB).trim();
                if (keytabFile.length() == 0) {
                    throw new ServiceException(ErrorCode.E0026, 
KERBEROS_KEYTAB);
                }
                String principal = SecurityUtil.getServerPrincipal(
                        serviceConf.get(KERBEROS_PRINCIPAL, 
"oozie/localhost@LOCALHOST"),
                        InetAddress.getLocalHost().getCanonicalHostName());
                if (principal.length() == 0) {
                    throw new ServiceException(ErrorCode.E0026, 
KERBEROS_PRINCIPAL);
                }
                Configuration conf = new Configuration();
                conf.set("hadoop.security.authentication", "kerberos");
                UserGroupInformation.setConfiguration(conf);
                UserGroupInformation.loginUserFromKeytab(principal, keytabFile);
                LOG.info("Got Kerberos ticket, keytab [{0}], Oozie principal 
principal [{1}]",
                        keytabFile, principal);
            }
            catch (ServiceException ex) {
                throw ex;
            }
            catch (Exception ex) {
                throw new ServiceException(ErrorCode.E0100, 
getClass().getName(), ex.getMessage(), ex);
            }
    }
{code}

In the latter case, the SecurityUtil class is used to replace "_HOST" 
occurrences with an actual hostname.

I guess something similar should be done in the ZKUtils class as well.

Best Regards
/Thomas



--
This message was sent by Atlassian JIRA
(v6.3.15#6346)

Reply via email to