Open evial opened 3 years ago
HI @evial ,
How you initialize nfs4j? The kerberos support must be explicitly enabled:
RpcLoginService loginService = (t, c) -> {
// call ldap or so
Subject s = new Subject();
return s;
};
GssSessionManager gss = GssSessionManager(loginService, "nfs/host.example.com@EXAMPLE.COM", "/etc/krb5.keytab");
OncRpcSvc svc = OncRpcSvcBuilder()
.withPort(port)
.withTCP()
.withAutoPublish()
.withWorkerThreadIoStrategy()
.withGssSessionManager(gss)
.build()
Many thanks for the tip. Indeed, the GSS initialization was missing. Here is my code after fixing:
RpcLoginService loginService = (t, c) -> new Subject();
GssSessionManager gss = new GssSessionManager(loginService, "nfs/krb5.test.io@TEST.IO", "/etc/krb5.keytab");
OncRpcSvc nfsSvc = new OncRpcSvcBuilder()
.withPort(Config.RPC_PORT)
.withTCP()
.withAutoPublish()
.withWorkerThreadIoStrategy()
.withGssSessionManager(gss)
.build();
NFSServerV41 nfs4 = new NFSServerV41.Builder()
.withVfs(client)
.withOperationExecutor(new MDSOperationExecutor())
.withExportTable(exportFile)
.build();
NfsServerV3 nfs3 = new NfsServerV3(exportFile, client);
MountServer mountd = new MountServer(exportFile, client);
nfsSvc.register(new OncRpcProgram(mount_prot.MOUNT_PROGRAM, mount_prot.MOUNT_V3), mountd);
nfsSvc.register(new OncRpcProgram(nfs3_prot.NFS_PROGRAM, nfs3_prot.NFS_V3), nfs3);
nfsSvc.register(new OncRpcProgram(nfs4_prot.NFS4_PROGRAM, nfs4_prot.NFS_V4), nfs4);
nfsSvc.start();
I still have the same error on the client (access denied by server while mounting localhost:) but the below warning is now issued on the server:
2021-05-20 23:39:19.554 [] [OncRpcSvc(1) SelectorRunner] WARN o.d.o.r.g.GssProtocolFilter - GSS mechanism failed Failure unspecified at GSS-API level (Mechanism level: Invalid argument (400) - Cannot find key of appropriate type to decrypt AP-REQ - AES256 CTS mode with HMAC SHA1-96)
Googling around, the message seems to be connected with the Java Cryptography Extension (JCE) not installed by default on JDK 8 and earlier but I work with JDK 11. Sorry, seems I need your help again :)
Thanks
Which jdk version are you using? For jdk earlier 8u161 you need to install additional package https://www.oracle.com/java/technologies/javase-jce-all-downloads.html. However, I will suggest to use latest openjdk-11.
I'm using OpenJDK 11. the Java Cryptography Extension is installed by default. Anyway, I checked it with the code from https://stackoverflow.com/questions/62841553/how-can-i-configure-java-cryptography-extension-jce-in-openjdk-11 and the extension is well configured. The problem doesn't seem to be related with the JCE.
What the keys that you have?
$ ktutil
ktutil: rkt /etc/krb5.keytab
ktutil: l -e
slot KVNO Principal
---- ---- ---------------------------------------------------------------------
1 1 host/mds17.nfsv4bat.org@NFSV4BAT.ORG (aes256-cts-hmac-sha1-96)
2 1 host/mds17.nfsv4bat.org@NFSV4BAT.ORG (aes128-cts-hmac-sha1-96)
3 1 nfs/mds17.nfsv4bat.org@NFSV4BAT.ORG (aes256-cts-hmac-sha1-96)
4 1 nfs/mds17.nfsv4bat.org@NFSV4BAT.ORG (aes128-cts-hmac-sha1-96)
ktutil:
Here they are:
sudo klist -e -k /etc/krb5.keytab
Keytab name: FILE:/etc/krb5.keytab
KVNO Principal
---- --------------------------------------------------------------------------
2 nfs/krb5.test.io@TEST.IO (aes256-cts-hmac-sha1-96)
2 nfs/krb5.test.io@TEST.IO (aes128-cts-hmac-sha1-96)
Hi @kofemann,
Sorry, it's still not working for me. Any idea? Is there any extra configuration to get NFS4J working with Kerberos I could have missed ?
Thanks
Try to enabe krb5 debug by properly -Dsun.security.krb5.debug=true
You cannot use localhost
with Kerberos. Kerberos uses a Service Principal Name (SPN) to indicate which service it needs a ticket for. So submitting an SPN of nfs/localhost
to the KDC is not going to find a service account to issue a ticket for. You have to use the correct DNS hostname of the service when mounting.
Although there is another gotcha. When Kerberos clients (like JGSS) create an SPN, it will first lookup the IP of the hostname, then do a reverse PTR
lookup to get the canonicalized FQDN of the host and use that to build the SPN. So for example, let's say you use krb5.test.io
but the canonicalized DNS name is actually dev02.myco.intra
. JGSS will use an SPN nfs/dev02.myco.intra
. When the NFS server gets this ticket, it's going to look in the keytab for a key that matches this name. Meaning you will have to create your keytab using SPNs that use the canonicalized name.
Aside: Kerberos has numerous dependencies that have sadly limited it's utility. IMO, the only truly correct configuration is to use dns_canonicalize_hostname = false
[1] in your krb5.conf
(only understood my Java 12+ I think) and add proper SPNs for each service to all affected service accounts. Again, this is an aside and not related to your issue regardless of the cause (especially since I'm posting this 2 years later ...). It's just appropriate to add this aside comment when explaining Kerberos DNS canonicalization.
Hi,
I'm trying to get NFS4J working with Kerberos on Ubuntu 20.04. OS native NFS server with Kerberos works fine as well as NFS4J without authentication. But with both NFS4J and Kerberos, I invariably have an access denied on the client side.
This is my export file content: / *(sec=krb5,rw,no_root_squash)
I also followed instructions from this link: https://dcache.org/old/manuals/Book-2.3/config/cf-nfs4-gss-fhs-comments.shtml
And this is the debug output from the server:
Must be something stupid but I'm stuck on it. What could I have missed ?
Thanks