Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

windows domain(ads) support #187

Open
wangyugui-e16 opened this issue Dec 17, 2022 · 49 comments
Open

windows domain(ads) support #187

wangyugui-e16 opened this issue Dec 17, 2022 · 49 comments

Comments

@wangyugui-e16
Copy link

wangyugui-e16 commented Dec 17, 2022

Hi,

I successed to build ksmbd-tools 3.4.6 with
LIBKRB5_CFLAGS="$(/usr/bin/krb5-config krb5 --cflags)"
LIBKRB5_LIBS="$(/usr/bin/krb5-config krb5 --libs)"
--enable-krb5

do we have a test command inside ksmbd-tools to test krb5 user/password, and then output
the user/group id assigned by windows ads/linux?

Best regards

@wangyugui-e16
Copy link
Author

when build without --enable-krb5, it is OK to access from a windows 10 client.
when build with --enable-krb5, ksmbd failed to work with local user/password.

ksmbd support krb5 and local user/passwd at the same time?

Dec 18 08:55:41 T3610 ksmbd[4958]: [ksmbd-worker/4958]: ERROR: Failed to init SPNEGO subsystem
Dec 18 08:55:41 T3610 ksmbd[4953]: [ksmbd.mountd/4953]: INFO: Worker PID 4958 changed state
Dec 18 08:55:42 T3610 ksmbd[4959]: [ksmbd-worker/4959]: ERROR: Cannot determine realm for host: while getting host name
Dec 18 08:55:42 T3610 ksmbd[4959]: [ksmbd-worker/4959]: ERROR: Failed to init Kerberos 5
Dec 18 08:55:42 T3610 ksmbd[4959]: [ksmbd-worker/4959]: ERROR: Failed to init SPNEGO subsystem
Dec 18 08:55:42 T3610 ksmbd[4953]: [ksmbd.mountd/4953]: INFO: Worker PID 4959 changed state
Dec 18 08:55:43 T3610 ksmbd[4960]: [ksmbd-worker/4960]: ERROR: Cannot determine realm for host: while getting host name
Dec 18 08:55:43 T3610 ksmbd[4960]: [ksmbd-worker/4960]: ERROR: Failed to init Kerberos 5
Dec 18 08:55:43 T3610 ksmbd[4960]: [ksmbd-worker/4960]: ERROR: Failed to init SPNEGO subsystem
Dec 18 08:55:43 T3610 ksmbd[4953]: [ksmbd.mountd/4953]: INFO: Worker PID 4960 changed state

os: rocky linux 9.1
kernel: 6.1.0
ksmbd-tools: 3.4.6(github upstream)
ksmbd.conf:

# cat /etc/ksmbd/ksmbd.conf
; see ksmbd.conf(5) for details

[global]
        ; global section parameters
        bind interfaces only = no
        deadtime = 0
        guest account = nobody
        interfaces =
        ipc timeout = 0
        kerberos keytab file =
        kerberos service name =
        map to guest = never
        max active sessions = 1024
        max open files = 10000
        netbios name = T3610
        restrict anonymous = 0
        root directory =
        server max protocol = SMB3_11
        server min protocol = SMB2_10
        server multi channel support = no
        server signing = disabled
        server string = SMB SERVER
        share:fake_fscaps = 64
        smb2 leases = no
        smb2 max credits = 8192
        smb2 max read = 4MB
        smb2 max trans = 1MB
        smb2 max write = 4MB
        smb3 encryption = no
        smbd max io size = 8MB
        tcp port = 445
        workgroup = WORKGROUP

        ; share parameters for all sections
        browseable = yes
        comment =
        create mask = 0744
        directory mask = 0755
        force create mode = 0000
        force directory mode = 0000
        force group =
        force user =
        guest ok = no
        hide dot files = yes
        inherit owner = no
        invalid users =
        max connections = 0
        oplocks = yes
        path =
        read list =
        store dos attributes = yes
        valid users =
        veto files =
        vfs objects =
        write list =
        writeable = no

[hpc-bio]
        ; share parameter overrides for `example' share
        path = /usr/hpc-bio

@wangyugui-e16
Copy link
Author

wangyugui-e16 commented Dec 18, 2022

We already have a build option to enable/disable krb5, we also need a configure option to enable/disable krb5?

a dirty patch to skip krb5 init.

diff --git a/tools/management/spnego.c b/tools/management/spnego.c
index bf2ad79..5bf1ca1 100644
--- a/tools/management/spnego.c
+++ b/tools/management/spnego.c
@@ -46,6 +46,9 @@ int spnego_init(void)
 	if (global_conf.krb5_keytab_file)
 		mech_ctx->params.krb5.keytab_name =
 			strdup(global_conf.krb5_keytab_file);
+	if(mech_ctx->params.krb5.service_name == NULL &&
+		mech_ctx->params.krb5.keytab_name == NULL)
+		return 0;
 
 	mech_ctx = &mech_ctxs[SPNEGO_MECH_KRB5];
 	mech_ctx->ops = &spnego_krb5_operations;

@namjaejeon
Copy link
Owner

@atheik Could you please help review this change ?

@namjaejeon
Copy link
Owner

@atheik Ping?

@atheik
Copy link
Contributor

atheik commented Jan 7, 2023

@namjaejeon, @wangyugui-e16,

I apologize for the delay.

If I understood correctly, your suggestion is that the authentication should silently fallback to NTLM when Kerberos 5 authentication fails. And, this issue and the suggested workaround was prompted by the Windows client failing to authenticate with Kerberos 5.

Instead of adding this fallback, wouldn't it be better to figure out how to get Kerberos 5 authentication working with the Windows client? To my knowledge, separate Active Domain Directory support in ksmbd is not a requirement to get it working:
https://serverfault.com/questions/455793/kerberos-authentication-for-workstations-not-on-domain/1025351#1025351

(Edit: Revisiting this and reading the posted log, I don't understand how I came to this conclusion.)

@wangyugui-e16,

Just to make sure, since you built ksmbd-tools with Kerberos 5 authentication in the first place, do you have some other client (e.g. cifs-utils on Linux) where Kerberos 5 authentication works with your current setup? Your ERROR: Cannot determine realm for host: while getting host name suggests to me that there's something wrong with your Kerberos 5 configuration.

@wangyugui-e16
Copy link
Author

In fact, there are two problems
1, we need build one binary to support krb5 and ksmbd.adduser at the same time. and then change the configure on demond.
this dirty patch fix one problem for this.

2, whether the krb5/ads support works as expected.
I want to test it with realm/SSSD, but the test is yet not finished.

@atheik
Copy link
Contributor

atheik commented Jan 8, 2023

@wangyugui-e16,

In fact, there are two problems 1, we need build one binary to support krb5 and ksmbd.adduser at the same time. and then change the configure on demond. this dirty patch fix one problem for this.

Sorry, I am not sure I understand what you mean by "support krb5 and ksmbd.adduser at the same time". Even with Kerberos 5 support, there is still the requirement that all users are present in ksmbdpwd.db , it's just that the password fields there are not in use then. For any existing users of ksmbd-tools relying on Kerberos 5 support, the suggested NTLM fallback (I still assume this is what you meant) would mean that the passwords in ksmbdpwd.db would suddenly become meaningful. If the user left them blank or unsafe, knowing that they wouldn't be used with Kerberos 5 enabled, that would be a problem. (Edit: This is just plain false. It is not required that the client authenticates with Kerberos 5, although the client can be configured to do so.)

@wangyugui-e16
Copy link
Author

@atheik

Can we 'yum/dnf install' just once, and then change the configure file to switch krb5 and ksmbd.adduser support?

@atheik
Copy link
Contributor

atheik commented Jan 8, 2023

@wangyugui-e16,

Can we 'yum/dnf install' just once, and then change the configure file to switch krb5 and ksmbd.adduser support?

As I said earlier, with Kerberos 5 enabled, you still need to use ksmbd.adduser to add users to ksmbdpwd.db , although the passwords fields there are then not used. (Edit: see above) And, currently support for Kerberos 5 is determined at configure-time before building, i.e. not at package-installation time, and there is currently no way to turn it off without rebuilding.

@wangyugui-e16
Copy link
Author

@atheik
with my dirty patch, we can turn off krb5 support without rebuilding.
in this dirty patch, when krb5 configure is not setting, just skip krb5 init.

@atheik
Copy link
Contributor

atheik commented Jan 8, 2023

@wangyugui-e16,

@atheik with my dirty patch, we can turn off krb5 support without rebuilding. in this dirty patch, when krb5 configure is not setting, just skip krb5 init.

Please see #187 (comment) for one potential problem.

@wangyugui-e16
Copy link
Author

wangyugui-e16 commented Jan 9, 2023

Should ksmbd allow more than ssh(SSSD/realm)? or Should ksmbd allow less than ssh(SSSD/realm)?

SSSD/realm already has 'PERMIT/DENY' feature.

for ksmbd.adduser, we may add 'PERMIT/DENY' feature for krb5 support to use a different database?

@hcbwiz
Copy link

hcbwiz commented Jan 11, 2023

@wangyugui-e16

Do you mean that?

cifs client --> NTLM auth --> ksmbd --> how to adapt? --> sssd --> windows AD

Let sssd internally handle krb5 auth, id mapping and etc.

@wangyugui-e16
Copy link
Author

@hcbwiz

If a user can login with ssh(SSSD/krb5), then In most case he should be allowed to access ksmbd?

ksmbd may allow more user than ssh(SSSD/krb5) too?

@hcbwiz
Copy link

hcbwiz commented Jan 11, 2023

About ssh + krb5, you can check here

In my understanding, ksmbd with windows ad support needs more features than krb5.

I guess this approach may work also (i don't familiar with sssd and Linux PAM)

cifs client --> krb5 TGT --> ksmbd --> bypass krb5 TGT? --> sssd --> windows AD

If sssd can do all related things with Windows AD,
The issue is how ksmbd adapts to sssd.

I'm still investigating it.

@wangyugui-e16
Copy link
Author

uid/gid mapping is very complex for smb support
1, sssd support 2 method
1a) POSIX(uidNumber/gidNumber/...)
1b) auto mapping

2, samba/winbind support more, but yet able to find one that match sssd well.
2a) rid default(mapping)
2b) idmap_ad fail to work here
2c) idmap_rfc2307/idmap_nss and more.

mapped gid/uid is saved in every file attr of linux filesystem.

for ksmbd, better to select the best known one, rather than an new one?

and what is the recommand mapping rule that is easy to reproduce?

@wangyugui-e16
Copy link
Author

wangyugui-e16 commented Jan 14, 2023

windows ads server is ready here. and linux is joined into ads with sssd.

# realm list
e16-tech.com
  type: kerberos
  realm-name: E16-TECH.COM
  domain-name: e16-tech.com
  configured: kerberos-member
  server-software: active-directory
  client-software: sssd
  required-package: oddjob
  required-package: oddjob-mkhomedir
  required-package: sssd
  required-package: adcli
  required-package: samba-common-tools
  login-formats: %[email protected]
  login-policy: allow-realm-logins

/etc/ksmbd/ksmbd.conf
[global]
kerberos keytab file =
kerberos service name = cifs/E16-TECH.COM

# systemctl status ksmbd.service
Jan 14 20:17:05 T3610 ksmbd[4775]: [ksmbd-worker/4775]: ERROR: Failed to init SPNEGO subsystem
Jan 14 20:17:05 T3610 ksmbd[4527]: [ksmbd.mountd/4527]: INFO: Worker PID 4775 changed state
Jan 14 20:17:06 T3610 ksmbd[4783]: [ksmbd-worker/4783]: ERROR: Keytab contains no suitable keys for cifs/E16-TECH.COM@:>
Jan 14 20:17:06 T3610 ksmbd[4783]: [ksmbd-worker/4783]: ERROR: Failed to init Kerberos 5
Jan 14 20:17:06 T3610 ksmbd[4783]: [ksmbd-worker/4783]: ERROR: Failed to init SPNEGO subsystem
Jan 14 20:17:06 T3610 ksmbd[4527]: [ksmbd.mountd/4527]: INFO: Worker PID 4783 changed state
Jan 14 20:17:07 T3610 ksmbd[4784]: [ksmbd-worker/4784]: ERROR: Keytab contains no suitable keys for cifs/E16-TECH.COM@:>
Jan 14 20:17:07 T3610 ksmbd[4784]: [ksmbd-worker/4784]: ERROR: Failed to init Kerberos 5
Jan 14 20:17:07 T3610 ksmbd[4784]: [ksmbd-worker/4784]: ERROR: Failed to init SPNEGO subsystem
Jan 14 20:17:07 T3610 ksmbd[4527]: [ksmbd.mountd/4527]: INFO: Worker PID 4784 changed state

any advice for /etc/ksmbd/ksmbd.conf 'kerberos keytab file'?

@hcbwiz
Copy link

hcbwiz commented Jan 16, 2023

@wangyugui-e16
Copy link
Author

  1. /etc/ksmbd/ksmbd.conf
    [global]
    kerberos keytab file =
    kerberos service name = cifs/E16-TECH.COM
    workgroup = E16-TECH

  2. sssd-kcm.service is running

  3. then ksmbd output:
    Jan 16 19:02:54 T3610 ksmbd[2292]: [ksmbd-worker/2292]: INFO: User database does not exist, only guest sessions may work
    Jan 16 19:02:54 T3610 ksmbd[2292]: [ksmbd-worker/2292]: ERROR: Keytab contains no suitable keys for cifs/E16-TECH.COM@:>
    Jan 16 19:02:54 T3610 ksmbd[2292]: [ksmbd-worker/2292]: ERROR: Failed to init Kerberos 5
    Jan 16 19:02:54 T3610 ksmbd[2292]: [ksmbd-worker/2292]: ERROR: Failed to init SPNEGO subsystem
    Jan 16 19:02:54 T3610 ksmbd[1425]: [ksmbd.mountd/1425]: INFO: Worker PID 2292 changed state

@wangyugui-e16
Copy link
Author

basic sssd(ad, ldap_id_mapping = False) and winbind(idmap ad) works here now,
They have almost same, uidNumber/gidNumber based id mapping.

sssd(ad, ldap_id_mapping = False) seems a good option for ksmbd id mapping.

but Single sign-on configure (https://wiki.samba.org/index.php/OpenSSH_Single_sign-on) is still yet able to work here.
we need 'GSSAPIStrictAcceptorCheck no' and more?

we need some Single sign-on support for ksmbd too?

@hcbwiz
Copy link

hcbwiz commented Jan 17, 2023

Kerberos would be a single-sign-on mechanism.

root@vhost:~# realm list
test.com
  type: kerberos
  realm-name: TEST.COM
  domain-name: test.com
  configured: kerberos-member
  server-software: active-directory
  client-software: sssd
  required-package: sssd-tools
  required-package: sssd
  required-package: libnss-sss
  required-package: libpam-sss
  required-package: adcli
  required-package: samba-common-bin
  login-formats: %[email protected]
  login-policy: allow-realm-logins

root@vhost:~# klist -k
Keytab name: FILE:/etc/krb5.keytab
KVNO Principal
---- --------------------------------------------------------------------------
   2 [email protected]
   2 [email protected]
   2 [email protected]
   2 host/[email protected]
   2 host/[email protected]
   2 host/[email protected]
   2 host/[email protected]
   2 host/[email protected]
   2 host/[email protected]
   2 RestrictedKrbHost/[email protected]
   2 RestrictedKrbHost/[email protected]
   2 RestrictedKrbHost/[email protected]
   2 RestrictedKrbHost/[email protected]
   2 RestrictedKrbHost/[email protected]
   2 RestrictedKrbHost/[email protected]

Then I added another SPN:
adcli update --add-service-principal=cifs/vhost.test.com --domain=TEST.COM

root@vhost:~# klist -k
Keytab name: FILE:/etc/krb5.keytab
KVNO Principal
---- --------------------------------------------------------------------------
   2 [email protected]
   2 [email protected]
   2 [email protected]
   2 host/[email protected]
   2 host/[email protected]
   2 host/[email protected]
   2 host/[email protected]
   2 host/[email protected]
   2 host/[email protected]
   2 RestrictedKrbHost/[email protected]
   2 RestrictedKrbHost/[email protected]
   2 RestrictedKrbHost/[email protected]
   2 RestrictedKrbHost/[email protected]
   2 RestrictedKrbHost/[email protected]
   2 RestrictedKrbHost/[email protected]
   2 cifs/[email protected]
   2 cifs/[email protected]
   2 cifs/[email protected]

Modified ksmbd.conf:
kerberos keytab file = /etc/krb5.keytab

However, I got the same error:

root@vhost:~# ksmbd.mountd -v -n
[ksmbd-worker/777]: DEBUG: New user `test'
[ksmbd-worker/777]: DEBUG: New share `IPC$'
[ksmbd-worker/777]: DEBUG: New share `mnt'
[ksmbd-worker/777]: DEBUG: New user `nobody'
[ksmbd-worker/777]: ERROR: Keytab contains no suitable keys for cifs/vhost.test.com@: while getting credentials for cifs/vhost.test.com@
[ksmbd-worker/777]: ERROR: Failed to init Kerberos 5
[ksmbd-worker/777]: ERROR: Failed to init SPNEGO subsystem
double free or corruption (fasttop)
[ksmbd-worker/777]: INFO: Worker received signal 6 (Aborted)
double free or corruption (fasttop)
[ksmbd-worker/777]: INFO: Worker received signal 6 (Aborted)
[ksmbd.mountd/776]: INFO: Worker PID 777 changed state

still investigate that how ksmbd works with krb5.

@hcbwiz
Copy link

hcbwiz commented Jan 17, 2023

still figure out how krb5 works.

modify the code:

diff --git a/tools/management/spnego_krb5.c b/tools/management/spnego_krb5.c
index e71d3aa..02efe38 100644
--- a/tools/management/spnego_krb5.c
+++ b/tools/management/spnego_krb5.c
@@ -153,7 +153,7 @@ static krb5_error_code acquire_creds_from_keytab(krb5_context context,
        }

        retval = krb5_sname_to_principal(context, host_name, service_name,
-                       KRB5_NT_UNKNOWN, &sprinc);
+                       KRB5_NT_SRV_HST, &sprinc);
        if (retval) {
                pr_krb5_err(context, retval, "while generating service name\n");
                goto out_err;

Got different error

root@vhost:~# KRB5_TRACE=/dev/stdout ksmbd.mountd -v -n
[ksmbd-worker/2610]: DEBUG: New user `test'
[ksmbd-worker/2610]: DEBUG: New share `IPC$'
[ksmbd-worker/2610]: DEBUG: New share `mnt'
[ksmbd-worker/2610]: DEBUG: New user `nobody'
[2610] 1673945914.310609: Getting initial credentials for cifs/vhost.test.com@
[2610] 1673945914.310610: Found entries for cifs/[email protected] in keytab: rc4-hmac, aes128-cts, aes256-cts
[2610] 1673945914.310612: Sending unauthenticated request
[2610] 1673945914.310613: Sending request (214 bytes) to TEST.COM
[2610] 1673945914.310614: Initiating TCP connection to stream 10.252.165.204:88
[2610] 1673945914.310615: Sending TCP request to stream 10.252.165.204:88
[2610] 1673945914.310616: Received answer (90 bytes) from stream 10.252.165.204:88
[2610] 1673945914.310617: Terminating TCP connection to stream 10.252.165.204:88
[2610] 1673945914.310618: Response was from primary KDC
[2610] 1673945914.310619: Received error from KDC: -1765328378/Client not found in Kerberos database
[ksmbd-worker/2610]: ERROR: Client 'cifs/[email protected]' not found in Kerberos database: while getting credentials for cifs/vhost.test.com@
[ksmbd-worker/2610]: ERROR: Failed to init Kerberos 5
[ksmbd-worker/2610]: ERROR: Failed to init SPNEGO subsystem
double free or corruption (fasttop)
[ksmbd-worker/2610]: INFO: Worker received signal 6 (Aborted)
double free or corruption (fasttop)
[ksmbd-worker/2610]: INFO: Worker received signal 6 (Aborted)
[ksmbd.mountd/2609]: INFO: Worker PID 2610 changed state

@wangyugui-e16
Copy link
Author

https://learn.microsoft.com/zh-cn/windows-server/administration/windows-commands/ktpass
[/ptype {KRB5_NT_PRINCIPAL|KRB5_NT_SRV_INST|KRB5_NT_SRV_HST}]

this info maybe helpful.

@hcbwiz
Copy link

hcbwiz commented Jan 18, 2023

after more tests:

  1. If you ever used "setspn" and "adcli update --add-service-principal=cifs/vhost.test.com --domain=TEST.COM",
    it seems to delete the entry.
    Otherwise, ktpass will show the warning:
 Failed to set property 'servicePrincipalName' to 'cifs/vhost.test.com' on Dn 'CN=vhost,DC=test,DC=com': 0x13.
WARNING: Unable to set SPN mapping data.
If vhost already has an SPN mapping installed for cifs/vhost.test.com, this is no cause for concern.
WARNING: pType and account type do not match. This might cause problems.     
you can use the command to check
    setspn -L vhost
     note: 'vhost' is the hostname of my ksmbd server.
  1. ktpass -princ cifs/[email protected] -mapuser vhost -crypto all -ptype KRB5_NT_PRINCIPAL +rndPass -out c:\cifs.keytab

Then modify the ksmbd.conf to use the keytab directly

ksmbd can start!!

root@vhost:/etc/ksmbd# KRB5_TRACE=/dev/stdout /usr/local/sbin/ksmbd.mountd -v -n
[ksmbd-worker/3653]: DEBUG: New user `test'
[ksmbd-worker/3653]: DEBUG: New share `IPC$'
[ksmbd-worker/3653]: DEBUG: New share `mnt'
[ksmbd-worker/3653]: DEBUG: New user `nobody'
[3653] 1674025209.702197: Getting initial credentials for cifs/vhost.test.com@
[3653] 1674025209.702198: Found entries for cifs/[email protected] in keytab: rc4-hmac, aes256-cts, aes128-cts
[3653] 1674025209.702200: Sending unauthenticated request
[3653] 1674025209.702201: Sending request (214 bytes) to TEST.COM
[3653] 1674025209.702202: Initiating TCP connection to stream 10.252.165.204:88
[3653] 1674025209.702203: Sending TCP request to stream 10.252.165.204:88
[3653] 1674025209.702204: Received answer (190 bytes) from stream 10.252.165.204:88
[3653] 1674025209.702205: Terminating TCP connection to stream 10.252.165.204:88
[3653] 1674025209.702206: Response was from primary KDC
[3653] 1674025209.702207: Received error from KDC: -1765328359/Additional pre-authentication required
[3653] 1674025209.702210: Preauthenticating using KDC method data
[3653] 1674025209.702211: Processing preauth types: PA-PK-AS-REQ (16), PA-PK-AS-REP_OLD (15), PA-ETYPE-INFO2 (19), PA-ENC-TIMESTAMP (2)
[3653] 1674025209.702212: Selected etype info: etype aes256-cts, salt "TEST.COMcifsvhost.test.com", params ""
[3653] 1674025209.702213: PKINIT client has no configured identity; giving up
[3653] 1674025209.702214: Preauth module pkinit (16) (real) returned: -1765328174/No pkinit_anchors supplied
[3653] 1674025209.702215: Retrieving cifs/[email protected] from FILE:/etc/ksmbd/cifs.keytab (vno 0, enctype aes256-cts) with result: 0/Success
[3653] 1674025209.702216: AS key obtained for encrypted timestamp: aes256-cts/87B3
[3653] 1674025209.702218: Encrypted timestamp (for 1674025212.197550): plain 301AA011180F32303233303131383037303031325AA10502030303AE, encrypted 81086C5C7B2047448E69C591C53B1595B4FB384F96A4A8806C211238E6E5E7C23E7CEA96B0129C0F13AC1DCF8042A68B884E57FBE4D67CE6
[3653] 1674025209.702219: Preauth module encrypted_timestamp (2) (real) returned: 0/Success
[3653] 1674025209.702220: Produced preauth for next request: PA-ENC-TIMESTAMP (2)
[3653] 1674025209.702221: Sending request (294 bytes) to TEST.COM
[3653] 1674025209.702222: Initiating TCP connection to stream 10.252.165.204:88
[3653] 1674025209.702223: Sending TCP request to stream 10.252.165.204:88
[3653] 1674025209.702224: Received answer (1571 bytes) from stream 10.252.165.204:88
[3653] 1674025209.702225: Terminating TCP connection to stream 10.252.165.204:88
[3653] 1674025209.702226: Response was from primary KDC
[3653] 1674025209.702227: Processing preauth types: PA-ETYPE-INFO2 (19)
[3653] 1674025209.702228: Selected etype info: etype aes256-cts, salt "TEST.COMcifsvhost.test.com", params ""
[3653] 1674025209.702229: Produced preauth for next request: (empty)
[3653] 1674025209.702230: AS key determined by preauth: aes256-cts/87B3
[3653] 1674025209.702231: Decrypted AS reply; session key is: aes256-cts/AAA1
[3653] 1674025209.702232: FAST negotiation: unavailable
[3653] 1674025209.702233: Getting initial credentials for cifs/vhost.test.com@
[3653] 1674025209.702234: Found entries for cifs/[email protected] in keytab: rc4-hmac, aes256-cts, aes128-cts
[3653] 1674025209.702236: Sending unauthenticated request
[3653] 1674025209.702237: Sending request (214 bytes) to TEST.COM
[3653] 1674025209.702238: Initiating TCP connection to stream 10.252.165.204:88
[3653] 1674025209.702239: Sending TCP request to stream 10.252.165.204:88
[3653] 1674025209.702240: Received answer (190 bytes) from stream 10.252.165.204:88
[3653] 1674025209.702241: Terminating TCP connection to stream 10.252.165.204:88
[3653] 1674025209.702242: Response was from primary KDC
[3653] 1674025209.702243: Received error from KDC: -1765328359/Additional pre-authentication required
[3653] 1674025209.702246: Preauthenticating using KDC method data
[3653] 1674025209.702247: Processing preauth types: PA-PK-AS-REQ (16), PA-PK-AS-REP_OLD (15), PA-ETYPE-INFO2 (19), PA-ENC-TIMESTAMP (2)
[3653] 1674025209.702248: Selected etype info: etype aes256-cts, salt "TEST.COMcifsvhost.test.com", params ""
[3653] 1674025209.702249: PKINIT client has no configured identity; giving up
[3653] 1674025209.702250: Preauth module pkinit (16) (real) returned: -1765328174/No pkinit_anchors supplied
[3653] 1674025209.702251: Retrieving cifs/[email protected] from FILE:/etc/ksmbd/cifs.keytab (vno 0, enctype aes256-cts) with result: 0/Success
[3653] 1674025209.702252: AS key obtained for encrypted timestamp: aes256-cts/87B3
[3653] 1674025209.702254: Encrypted timestamp (for 1674025212.201551): plain 301AA011180F32303233303131383037303031325AA105020303134F, encrypted D36B8F6E6D9329BD7677DBCC27BDF2B8E0E3C2F21E0A1E9972BB468D623CEAFB1F90F79C83507EC9493159F589BB4BD61AF894B48CBB67A7
[3653] 1674025209.702255: Preauth module encrypted_timestamp (2) (real) returned: 0/Success
[3653] 1674025209.702256: Produced preauth for next request: PA-ENC-TIMESTAMP (2)
[3653] 1674025209.702257: Sending request (294 bytes) to TEST.COM
[3653] 1674025209.702258: Initiating TCP connection to stream 10.252.165.204:88
[3653] 1674025209.702259: Sending TCP request to stream 10.252.165.204:88
[3653] 1674025209.702260: Received answer (1571 bytes) from stream 10.252.165.204:88
[3653] 1674025209.702261: Terminating TCP connection to stream 10.252.165.204:88
[3653] 1674025209.702262: Response was from primary KDC
[3653] 1674025209.702263: Processing preauth types: PA-ETYPE-INFO2 (19)
[3653] 1674025209.702264: Selected etype info: etype aes256-cts, salt "TEST.COMcifsvhost.test.com", params ""
[3653] 1674025209.702265: Produced preauth for next request: (empty)
[3653] 1674025209.702266: AS key determined by preauth: aes256-cts/87B3
[3653] 1674025209.702267: Decrypted AS reply; session key is: aes256-cts/B058
[3653] 1674025209.702268: FAST negotiation: unavailable

@wangyugui-e16
Copy link
Author

ksmbd can start here too. Thanks a lot.

the next step maybe the auth and id mapping.

a segment fault happen when wrong 'kerberos service name ='
wrong:
kerberos service name = cifs/vhost.test.com
right:
kerberos service name = cifs/test.com

@hcbwiz
Copy link

hcbwiz commented Jan 18, 2023

I suppose we can setup a windows client which has been
Joined to the same domain.

In my understanding, when a user logins into the client,
The user can get krb5 ticket to access cifs service directly
without another login process.

According to the above discussion, ksmbd still needs a local user database.

So we can create the accounts in Windows AD and local database with the same user name first.

Then the authentication part maybe work

For id mapping, the ksmbd server has been joined to the domain by sssd/realm. Ksmbd may adapt to it by setuid?

For ACL, ldap or kerbose may query the information.
Still need to survey it

@wangyugui-e16
Copy link
Author

wangyugui-e16 commented Jan 18, 2023

for windows client, if it already joined the domain, then it can access ksmbd service without password input.
for windows client, if it yet not join the domain, then it can access ksmbd service with the username/password input.

windows SID is 128bit, and it is not used since small value.
linux uid is 32bit(?), and it is used since small value.
so we need a id mapping.

sssd-ad have 2 id mapping policies

  • based on the attr uidNumber /gidNumber (manually set by the administator)
  • based on rid( rid is a part of SID)

winbind have many policies. such as idmap_ad, idmap_rid.

the id mapping is not an part of krb5, it is a part of sssd/winbind.

If the user direcly ssh login, the he can direct access the filesystem behind ksmb.

so we need to make the id mapping of ksmb and sssd-ad/ssh to be same?

@hcbwiz
Copy link

hcbwiz commented Jan 19, 2023

for windows client, if it yet not join the domain, then it can access ksmbd service with the username/password input.

I suppose the windows client will fallback to use NTLM, but I have no idea how ksmbd/ssd authenticate it with windows AD.

About ID mapping, I'm not familiar with this area.

root@vhost:~# id [email protected]
uid=756601112([email protected]) gid=756600513(domain [email protected]) groups=756600513(domain [email protected])
root@vhost:~# id [email protected]
uid=756600500([email protected]) gid=756600513(domain [email protected]) groups=756600513(domain [email protected]),756600518(schema [email protected]),756600520(group policy creator [email protected]),756600519(enterprise [email protected]),756600572(denied rodc password replication [email protected]),756600512(domain [email protected])

sssd can translate SID to UID.

I think ksmbd can create files on the locale filesystem with the mapped "UID/GID"

In the other hand, how ksmbd/SMB represents "file and ID mapping" to the windows client?
I have no idea about it so far. Or is it just related to file ACL?

@wangyugui-e16
Copy link
Author

'/usr/bin/id' can translate SID to UID when login in as local user.
so we can do same job(code) in ksmbd to translate SID to UID.

The real job will be done by sssd/winbind, we just call like /usr/bin/id.
It will be easy than what I expected.

when sssd, we call id as 'id u2001@e16-tech'
when winbind, we call id 'id u2001'
we need try both name policies.

@wangyugui-e16
Copy link
Author

one question about krb5_keytab_file,

why kpasswd don't need krb5_keytab_file? but ksmbd-tools need it?

@hcbwiz
Copy link

hcbwiz commented Jan 31, 2023

'/usr/bin/id' can translate SID to UID when login in as local user. so we can do same job(code) in ksmbd to translate SID to UID.

The real job will be done by sssd/winbind, we just call like /usr/bin/id. It will be easy than what I expected.

when sssd, we call id as 'id u2001@e16-tech' when winbind, we call id 'id u2001' we need try both name policies.

after joining the domain:
modify /etc/sssd/sssd.conf:
use_fully_qualified_names = False
systemctl restart sssd

root@vhost:~# id administrator
uid=756600500(administrator) gid=756600513(domain users) groups=756600513(domain users),756600520(group policy creator owners),756600512(domain admins),756600518(schema admins),756600519(enterprise admins),756600572(denied rodc password replication group)

Then I create a file from a windows client:
圖片

But it is correct in the local FS:
圖片

@wangyugui-e16
Copy link
Author

sssd-ad can be used for 'Windows SID to linux uid/gid mapping'.
but there is yet no well-known API defined for 'linux uid/gid to Windows SID mapping'?

@hcbwiz
Copy link

hcbwiz commented Jan 31, 2023

About ksmbd KRB5 authentication with windows AD,, I have figured out more details:

Windows system have two different account types: Computer and User.

Thus, it needs to use a " a dollar sign ($)" for ktpass to specify a Computer account:
ktpass -princ cifs/[email protected] -mapuser [email protected] -crypto all -ptype KRB5_NT_PRINCIPAL +rndPass -out c:\cifs.keytab

@hcbwiz
Copy link

hcbwiz commented Jan 31, 2023

So far, krb5 authentication is still not working.

If I use IP to connect the ksmbd server, it can fallback NTLM authentication with local database.
However, if I use hostname(\\vhost.test.com\mnt) to connect, it shows the error messages from ksmbd.mountd

[2334] 1675152377.871649: Retrieving cifs/[email protected] from FILE:/etc/ksmbd/cifs.keytab (vno 3, enctype aes256-cts) with result: 0/Success
[2334] 1675152377.871650: Failed to decrypt AP-REQ ticket: -1765328353/Cannot decrypt ticket for cifs/[email protected] using keytab key for cifs/[email protected]
[ksmbd-worker/2334]: ERROR: Cannot decrypt ticket for cifs/[email protected] using keytab key for cifs/[email protected]: while decoding AP_REQ with cifs/[email protected] creds
[ksmbd-worker/2334]: INFO: Error authenticating

@wangyugui-e16
Copy link
Author

'mount.nfs -o seck=krb5' works with 'setspn.exe -S nfs/T3610.e16-tech.com T3610' instead of 'ktpass.exe'.
what will happen for ksmbd if 'setspn.exe -S cifs/T3610.e16-tech.com T3610' instead of 'ktpass.exe'.

@hcbwiz
Copy link

hcbwiz commented Feb 1, 2023

'mount.nfs -o seck=krb5' works with 'setspn.exe -S nfs/T3610.e16-tech.com T3610' instead of 'ktpass.exe'. what will happen for ksmbd if 'setspn.exe -S cifs/T3610.e16-tech.com T3610' instead of 'ktpass.exe'.

ksmbd server with krb5 authentication needs a "keytab" to decrypt the ticket which comes from a client.

currently, krb5 authentication can work in my environment:

  1. create an admin user account: cifsadmin
  2. use the account to "realm join"
  3. use ktpass to generate a keytab which is mapped to the same account: cifsadmin
    ktpass -princ cifs/[email protected] -mapUser [email protected] -pass pass1234 -crypto all -pType KRB5_NT_PRINCIPAL -out c:\cifs.keytab

the ksmbd.mountd with KRB5_TRACE:

KRB5_TRACE=/dev/stdout /usr/local/sbin/ksmbd.mountd -v -n

[646] 1675218330.676792: Retrieving cifs/[email protected] from FILE:/etc/ksmbd/cifs.keytab (vno 3, enctype rc4-hmac) with result: 0/Success
[646] 1675218330.676793: Decrypted AP-REQ with specified server principal cifs/[email protected]: rc4-hmac/C385
[646] 1675218330.676794: AP-REQ ticket: [email protected] -> cifs/[email protected], session key rc4-hmac/781B
[646] 1675218330.676795: Negotiated enctype based on authenticator: aes256-cts
[646] 1675218330.676796: Authenticator contains subkey: rc4-hmac/93E1
[646] 1675218330.676797: Creating AP-REP, time 1675218359.2735, subkey rc4-hmac/93E1, seqnum 0
[ksmbd-worker/646]: INFO: Authenticated user `Administrator'

Note:

  1. It sill need to add the corresponding account into the local DB.
  2. apply the patch:
diff --git a/tools/management/spnego_krb5.c b/tools/management/spnego_krb5.c
index e71d3aa..02efe38 100644
--- a/tools/management/spnego_krb5.c
+++ b/tools/management/spnego_krb5.c
@@ -153,7 +153,7 @@ static krb5_error_code acquire_creds_from_keytab(krb5_context context,
       }

       retval = krb5_sname_to_principal(context, host_name, service_name,
-                       KRB5_NT_UNKNOWN, &sprinc);
+                       KRB5_NT_SRV_HST, &sprinc);
       if (retval) {
               pr_krb5_err(context, retval, "while generating service name\n");
               goto out_err;

  1. make sure enable CONFIG_SMB_SERVER_KERBEROS5 when you compile the ksmbd module

@wangyugui-e16
Copy link
Author

When diag 'mount.nfs -o seck=krb5' , I noticed that there are some design in windows ad maby different from other krb5.

so many documents are based on ktpass. but failed to works here.
Figure 5 in
https://www.delltechnologies.com/asset/en-us/products/storage/industry-market/h17769_integrating_onefs_with_kerberos_wp.pdf
give me some idea of 'setspn.exe'.

and another point from hcbwiz is very important too.
Windows system have two different account types: Computer and User.
Thus, it needs to use a " a dollar sign ($)" for ktpass to specify a Computer account:

"kinit -k 'nfs/[email protected]'" check is in so many documents.
but it seem that we need "kinit -k '[email protected]'".

# klist -kt
Keytab name: FILE:/etc/krb5.keytab
KVNO Timestamp           Principal
---- ------------------- ------------------------------------------------------
   5 01/31/2023 23:55:51 [email protected]
   5 01/31/2023 23:55:51 [email protected]
   5 01/31/2023 23:55:51 host/[email protected]
   5 01/31/2023 23:55:51 host/[email protected]
   5 01/31/2023 23:55:51 host/[email protected]
   5 01/31/2023 23:55:51 host/[email protected]
   5 01/31/2023 23:55:51 RestrictedKrbHost/[email protected]
   5 01/31/2023 23:55:51 RestrictedKrbHost/[email protected]
   5 01/31/2023 23:55:51 RestrictedKrbHost/[email protected]
   5 01/31/2023 23:55:51 RestrictedKrbHost/[email protected]
   5 01/31/2023 23:55:51 cifs/[email protected]
   5 01/31/2023 23:55:51 cifs/[email protected]
   5 01/31/2023 23:55:51 cifs/[email protected]
   5 01/31/2023 23:55:51 cifs/[email protected]
   5 01/31/2023 23:55:51 nfs/[email protected]
   5 01/31/2023 23:55:51 nfs/[email protected]
   5 01/31/2023 23:55:51 nfs/[email protected]
   5 01/31/2023 23:55:51 nfs/[email protected]`

default /etc/krb5.keytab should be OK. we don't need another krb5.keytab.

CONFIG_SMB_SERVER_KERBEROS5 is defined here.

@hcbwiz
Copy link

hcbwiz commented Feb 1, 2023

I suppose ktpass also implies "set service principal name".
After executing ktpass, you can use setspn -L 'account name' to check it.

krb5 authentication is also one kind of single-sign-on mechanism.
Both of client and server need to communicate with the KDC (windows AD)

@wangyugui-e16
Copy link
Author

windows ad

C:\Users\Administrator>setspn -L T3610$
Registered ServicePrincipalNames for CN=T3610,CN=Computers,DC=e16-tech,DC=com:
        cifs/T3610
        cifs/T3610.e16-tech.com
        nfs/T3610.e16-tech.com
        nfs/T3610
        RestrictedKrbHost/T3610.e16-tech.com
        RestrictedKrbHost/T3610
        host/T3610.e16-tech.com
        host/T3610

linux client

[root@T3610 ~]# klist -kt
Keytab name: FILE:/etc/krb5.keytab
KVNO Timestamp           Principal
---- ------------------- ------------------------------------------------------
   8 02/01/2023 17:07:05 [email protected]
   8 02/01/2023 17:07:05 [email protected]
   8 02/01/2023 17:07:05 host/[email protected]
   8 02/01/2023 17:07:05 host/[email protected]
   8 02/01/2023 17:07:05 host/[email protected]
   8 02/01/2023 17:07:05 host/[email protected]
   8 02/01/2023 17:07:05 RestrictedKrbHost/[email protected]
   8 02/01/2023 17:07:05 RestrictedKrbHost/[email protected]
   8 02/01/2023 17:07:05 RestrictedKrbHost/[email protected]
   8 02/01/2023 17:07:05 RestrictedKrbHost/[email protected]
   8 02/01/2023 17:07:05 cifs/[email protected]
   8 02/01/2023 17:07:05 cifs/[email protected]
   8 02/01/2023 17:07:05 cifs/[email protected]
   8 02/01/2023 17:07:05 cifs/[email protected]
   8 02/01/2023 17:07:05 nfs/[email protected]
   8 02/01/2023 17:07:05 nfs/[email protected]
   8 02/01/2023 17:07:05 nfs/[email protected]
   8 02/01/2023 17:07:05 nfs/[email protected]
[root@T3610 ~]# kinit -k '[email protected]'
[root@T3610 ~]# kinit -k 'cifs/[email protected]'
kinit: Client 'cifs/[email protected]' not found in Kerberos database while getting initial credentials
[root@T3610 ~]#

@hcbwiz
Copy link

hcbwiz commented Feb 2, 2023

windows ad

C:\Users\Administrator>setspn -L T3610$
Registered ServicePrincipalNames for CN=T3610,CN=Computers,DC=e16-tech,DC=com:
        cifs/T3610
        cifs/T3610.e16-tech.com
        nfs/T3610.e16-tech.com
        nfs/T3610
        RestrictedKrbHost/T3610.e16-tech.com
        RestrictedKrbHost/T3610
        host/T3610.e16-tech.com
        host/T3610

How did you create such SPNs?
cifs/xxxxx
nfs/xxxx

[root@T3610 ~]# klist -kt
Keytab name: FILE:/etc/krb5.keytab
KVNO Timestamp           Principal
---- ------------------- ------------------------------------------------------
   8 02/01/2023 17:07:05 [email protected]
   8 02/01/2023 17:07:05 [email protected]
   8 02/01/2023 17:07:05 host/[email protected]
   8 02/01/2023 17:07:05 host/[email protected]
   8 02/01/2023 17:07:05 host/[email protected]
   8 02/01/2023 17:07:05 host/[email protected]
   8 02/01/2023 17:07:05 RestrictedKrbHost/[email protected]
   8 02/01/2023 17:07:05 RestrictedKrbHost/[email protected]
   8 02/01/2023 17:07:05 RestrictedKrbHost/[email protected]
   8 02/01/2023 17:07:05 RestrictedKrbHost/[email protected]
   8 02/01/2023 17:07:05 cifs/[email protected]
   8 02/01/2023 17:07:05 cifs/[email protected]
   8 02/01/2023 17:07:05 cifs/[email protected]
   8 02/01/2023 17:07:05 cifs/[email protected]
   8 02/01/2023 17:07:05 nfs/[email protected]
   8 02/01/2023 17:07:05 nfs/[email protected]
   8 02/01/2023 17:07:05 nfs/[email protected]
   8 02/01/2023 17:07:05 nfs/[email protected]
[root@T3610 ~]# kinit -k '[email protected]'
[root@T3610 ~]# kinit -k 'cifs/[email protected]'
kinit: Client 'cifs/[email protected]' not found in Kerberos database while getting initial credentials
[root@T3610 ~]#

Is it okay to do "kinit -k 'nfs/T3610.e16-tech.com'"?

As I know, realm uses "adcli join" to create a "computer account".
However, it seems that using "adcli update" to create new SPNs won't be added to the "Kerberos database" in Windows AD.

There are two alternative tools can work as "AD clients" in Linux : samba-tool and mkutils, but I never try it.
I just use ktpass.exe in my windows 2016 server directly.

The other issue is that:
With Kerberos authentication, the "Kerberos service account" uses "kerberos service keytab" to authenticate the client tickets.
However, there are two types : Computer Account and User Account in Windows AD that can act as Kerberos service account.
When using a Computer Account, I have no idea to let it work so far.

@wangyugui-e16
Copy link
Author

How did you create such SPNs?
setspn.exe -S nfs/T3610 T3610; setspn.exe -S nfs/T3610.e16-tech.com T3610
setspn.exe -S cifs/T3610 T3610; setspn.exe -S cifs/T3610.e16-tech.com T3610

Is it okay to do "kinit -k 'nfs/T3610.e16-tech.com'"?
"kinit -k 'nfs/T3610.e16-tech.com'" failed.

@wangyugui-e16
Copy link
Author

wangyugui-e16 commented Feb 2, 2023

failed to access
https://access.redhat.com/solutions/6972993

Now still re-joining domain to flush SPN to client /etc/krb5.keytab.

@hcbwiz
Copy link

hcbwiz commented Feb 2, 2023

'setspn' just binds a service principal name (SPN) to the user account.
If you don't call ktpass to generate keytab, it won't to be added into "Kerberos database" of Windows AD.

Note: You need not perform setspn separately since ktpass does it automatically when creating a keytab file.

I guess the keytab in your linux client is generated by "realm join".

"realm join" calls adcli (an AD client tool) to create a Computer counts and do related thing for "host/xxxx".
Then adcli can generates the keytab for all SPNs for this account.
However, the others SPNs you manually created by setspn haven't been added into "kerberos database".

In brief, "binding a SPN to an account" and "add it into the Kerberos database of Windows AD" are necessary.

@hcbwiz
Copy link

hcbwiz commented Feb 2, 2023

About id mapping API, there are two libraries: libsss-idmap and libsss-nss-idmap

I try libsss-nss-idmap:

#include <sss_nss_idmap.h>
#include <stdio.h>
#include <stdlib.h>

int main()
{
        char *sid = NULL;
        enum sss_id_type type;
        int ret;

        ret = sss_nss_getsidbyname("administrator", &sid, &type);
        printf("ret: %d, sid: %s, type: %d\n", ret, sid, type);
        free(sid);
}

output:
ret: 0, sid: S-1-5-21-3675874838-1964521148-1538075311-500, type: 1

@wangyugui-e16
Copy link
Author

wangyugui-e16 commented Feb 3, 2023

thanks a lot for the info 'libsss-idmap and libsss-nss-idmap'.

I movded the uid to windows SID mapping to #189

@wangyugui-e16
Copy link
Author

a patch try to auto config krb5
0002-krb5-auto-config.patch

@namjaejeon
Copy link
Owner

@wangyugui-e16 Thanks for your patch:)

@atheik Atte, Do you have the time to review this patch(0002-krb5-auto-config.patch) ?

@atheik
Copy link
Contributor

atheik commented Feb 25, 2023

@wangyugui-e16, @namjaejeon,

@atheik Atte, Do you have the time to review this patch(0002-krb5-auto-config.patch) ?

You bypass krb5_kt_default() in acquire_creds_from_keytab() entirely with your changes to setup_krb5_ctx().
If the intention is to check whether the keytab file exists, then why not check it with krb5_kt_have_content() after resolving the keytab in acquire_creds_from_keytab()?
The changes to setup_mskrb5() and cleanup_krb5() do not make sense, since mech_ctx->params.krb5.service_name can be NULL in non-fallback scenarios.
Could you please also write a proper commit message and give more context there?

Comments #187 (comment) and #187 (comment) still apply to this patch.
I don't think configuration issues warrant adding a silent fallback like this.

@wangyugui-e16
Copy link
Author

it seems that nfs-utils-2.6.2/utils/gssd/krb5_util.c is a good example to auto config principal_name and realm.

krb5_appdefault_string()
krb5_get_default_realm()
krb5_build_principal_ext()
...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants