java hdfs kerberos 认证超时 Receive timed out

java hdfs kerberos 认证超时 Receive timed out,第1张

java hdfs kerberos 认证超时 Receive timed out 背景

cdh6 集群为阿里服务器,三台机器搭建而成,并且开启了 kerberos,现在想尝试一下用 java api 读取 hdfs 数据。
代码如下:

public class ReadHdfsOnKerberos {

    public static void main(String[] args) throws IOException {
        String krbConfigPath = "D:\Code\kk-architecture-bigdata-practice\Hadoop-Practice\src\main\resources\";
        System.setProperty("java.security.krb5.conf", krbConfigPath + "krb5.conf");

        Configuration conf = new Configuration();
        conf.set("hadoop.security.authentication", "Kerberos");
        conf.set("java.security.krb5.conf", krbConfigPath + "krb5.conf");

        UserGroupInformation.setConfiguration(conf);

        System.out.println("开始登录 kerberos");

        UserGroupInformation.loginUserFromKeytab("hdfs/admin@KKARCH.COM", krbConfigPath + "root.keytab");

        System.out.println("登录结束");

        String file = "hdfs://ip1:8020";
        FileSystem fs = FileSystem.get(URI.create(file), conf);

        System.out.println(fs.exists(new Path("/")));
    }
}

报错如下:

[2021-11-28 00:30:43 上午]:DEBUG org.apache.hadoop.security.UserGroupInformation$HadoopLoginModule.login(UserGroupInformation.java:222)hadoop login
Exception in thread "main" java.io.IOException: Login failure for hdfs/admin@KKARCH.COM from keytab D:Codekk-architecture-bigdata-practiceHadoop-Practicesrcmainresourcesroot.keytab: javax.security.auth.login.LoginException: Receive timed out
	at org.apache.hadoop.security.UserGroupInformation.loginUserFromKeytab(UserGroupInformation.java:983)
	at com.kkarch.hadoop.rpc.kerberos.ReadHdfsOnKerberos.main(ReadHdfsOnKerberos.java:29)
Caused by: javax.security.auth.login.LoginException: Receive timed out
	at com.sun.security.auth.module.Krb5LoginModule.attemptAuthentication(Krb5LoginModule.java:808)
	at com.sun.security.auth.module.Krb5LoginModule.login(Krb5LoginModule.java:617)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at javax.security.auth.login.LoginContext.invoke(LoginContext.java:755)
	at javax.security.auth.login.LoginContext.access0(LoginContext.java:195)
	at javax.security.auth.login.LoginContext.run(LoginContext.java:682)
	at javax.security.auth.login.LoginContext.run(LoginContext.java:680)
	at java.security.AccessController.doPrivileged(Native Method)
	at javax.security.auth.login.LoginContext.invokePriv(LoginContext.java:680)
	at javax.security.auth.login.LoginContext.login(LoginContext.java:587)
	at org.apache.hadoop.security.UserGroupInformation.loginUserFromKeytab(UserGroupInformation.java:974)
	... 1 more
Caused by: java.net.SocketTimeoutException: Receive timed out
	at java.net.DualStackPlainDatagramSocketImpl.socketReceiveOrPeekData(Native Method)
	at java.net.DualStackPlainDatagramSocketImpl.receive0(DualStackPlainDatagramSocketImpl.java:124)
	at java.net.AbstractPlainDatagramSocketImpl.receive(AbstractPlainDatagramSocketImpl.java:143)
	at java.net.DatagramSocket.receive(DatagramSocket.java:812)
	at sun.security.krb5.internal.UDPClient.receive(NetClient.java:206)
	at sun.security.krb5.KdcComm$KdcCommunication.run(KdcComm.java:411)
	at sun.security.krb5.KdcComm$KdcCommunication.run(KdcComm.java:364)
	at java.security.AccessController.doPrivileged(Native Method)
	at sun.security.krb5.KdcComm.send(KdcComm.java:348)
	at sun.security.krb5.KdcComm.sendIfPossible(KdcComm.java:253)
	at sun.security.krb5.KdcComm.send(KdcComm.java:229)
	at sun.security.krb5.KdcComm.send(KdcComm.java:200)
	at sun.security.krb5.KrbAsReqBuilder.send(KrbAsReqBuilder.java:316)
	at sun.security.krb5.KrbAsReqBuilder.action(KrbAsReqBuilder.java:361)
	at com.sun.security.auth.module.Krb5LoginModule.attemptAuthentication(Krb5LoginModule.java:776)
	... 14 more

Process finished with exit code 1

真是百思不得其解,初步怀疑是阿里云的端口没开。
kerberos 用了两个端口,一个是 88 ,kdc 在用;另一个是 749 , kadmin 在用,但是都开了:

打开 cmd ,telnet 88 和 749 端口,都是可以通的,但是报错始终提示,接收数据异常。

我一想,是不是出的方向我没配啊。但是它提示我,出方向始终是放行的

于是继续去服务器上看日志:
/var/log/krb5kdc.log
/var/log/kadmind.log
都没有新增的日志。

一筹莫展…陷入了僵局…

继续看本地的日志,突然发现,咦,这个 UDPClient,好像是在接收 udp 的请求,说明发出去的也是一个 udp 请求!
然而,阿里云的安全配置是区分 tcp 和 udp 的,我配的是一个 tcp 的策略。

于是赶紧改成了 udp

然后就特么可以了,搞了好久!!!

最后把 749 端口去掉,发现也是可以的,说明客户端认证只请求了 kdc 就可以完成认证了。

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/zaji/5624611.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-12-15
下一篇2022-12-15

发表评论

登录后才能评论

评论列表(0条)

    保存