Open brlbil opened 4 years ago
Hi @brlbil
The error KDC_ERR_S_PRINCIPAL_UNKNOWN Server not found in Kerberos database
means that you don't have an SPN registered in the KDC for HTTP/acxyz.pklngnt-zum.example.com
This is not the same as a DNS entry. If you are using Active Directory this may help: https://docs.microsoft.com/en-gb/archive/blogs/autz_auth_stuff/what-is-a-spn-and-why-should-you-care
Hi @jcmturner
After some strace to see what curl does I found out that curl was using credentials cache to connect to the service. I could make this work by using CCache.
..........
Apparently, I spoke too soon. Earlier it worked because the library was using a ticket issued by using curl. But it cannot get a valid ticket on its own. Let me clarify
When I ran command below and run my code later it worked.
KRB5CCNAME=FILE:/tmp/krb5cc_test kinit -k -t /etc/krb5.keytab host/`hostname --fqdn`
KRB5CCNAME=FILE:/tmp/krb5cc_root curl -k -u : --negotiate https://acxyz.pklngnt-zum.example.com
klist -c /tmp/krb5cc_test
Ticket cache: FILE:/tmp/krb5cc_test
Default principal: host/xxxx.ipa.pklcst-zum.example.com@IPA.PKLCST-ZUM.EXAMPLE.COM
Valid starting Expires Service principal
02/10/2020 10:28:11 02/10/2020 20:28:11 krbtgt/IPA.PKLCST-ZUM.EXAMPLE.COM@IPA.PKLCST-ZUM.EXAMPLE.COM
renew until 02/11/2020 10:28:11
02/10/2020 10:29:27 02/10/2020 20:28:11 krbtgt/PKLNGNT-ZUM.EXAMPLE.COM@IPA.PKLCST-ZUM.EXAMPLE.COM
renew until 02/11/2020 10:28:11
02/10/2020 10:28:43 02/10/2020 20:28:11 HTTP/acxyz.pklngnt-zum.example.com@PKLNGNT-ZUM.EXAMPLE.COM
renew until 02/11/2020 10:28:11
and my code is minus error handling
cache, err := credentials.LoadCCache(cacheFile)
cfg, err := config.Load(confFile)
l := log.New(os.Stderr, "krb5-client", log.Lshortfile)
c, err := kclient.NewFromCCache(cache, cfg, kclient.DisablePAFXFAST(true), kclient.Logger(l))
c.Login()
sc := spnego.NewClient(k.c, http.DefaultClient, "")
// tansport not copied by default, so if service has unsigned certs it fails.
sc.Transport = c.Transport
sc.Do(req)
The second try after I removed the cache file I only ran kinit then my code then it failed.
KRB5CCNAME=FILE:/tmp/krb5cc_test kinit -k -t /etc/krb5.keytab host/`hostname --fqdn`
klist -c /tmp/krb5cc_test
Ticket cache: FILE:/tmp/krb5cc_test
Default principal: host/xxxx.ipa.pklcst-zum.example.com@IPA.PKLCST-ZUM.EXAMPLE.COM
Valid starting Expires Service principal
02/10/2020 14:50:15 02/11/2020 00:50:15 krbtgt/IPA.PKLCST-ZUM.EXAMPLE.COM@IPA.PKLCST-ZUM.EXAMPLE.COM
renew until 02/11/2020 14:50:15
//got error
krb5-clientsettings.go:67: using SPN HTTP/acxyz.pklngnt-zum.example.com
could not initialize context: [Root cause: KDC_Error] KDC_Error: TGS Exchange Error: kerberos error response from KDC when requesting for HTTP/acxyz.pklngnt-zum.example.com: KRB Error: (7) KDC_ERR_S_PRINCIPAL_UNKNOWN Server not found in Kerberos database - LOOKING_UP_SERVER
I could not figure out what curl does differently than this library, or am I setting it wrong?
Thanks
Can you post your krb5.conf that you are using on this line:
cfg, err := config.Load(confFile)
I also see you are passing k.c
to the spnego.NewClient function. What is this as it is not declared in the code you have posted.
When I look into the code more dept, I realized that a TGT ticket for IPA.PKLCST-ZUM.EXAMPLE.COM is gotten, but there was no TGT for PKLNGNT-ZUM.EXAMPLE.COM, thus service ticket for HTTP/acxyz.pklngnt-zum.example.com was also failing.
I made this work last week in a very hacky way. I got the TGT for PKLNGNT-ZUM.EXAMPLE.COM and also Service ticket for HTTP/acxyz.pklngnt-zum.example.com like below.
TGSREQGenerateAndExchange(spn, kdcRealm, tgt, key, false)
Then if I make get request it worked.
Later I found the real cause for it. When we make a request GetServiceTicket function is called, in the function, a realm is resolved from config and later it will get a ticket for the realm if not already in the session.
func (cl *Client) GetServiceTicket(spn string) .....
......
realm := cl.Config.ResolveRealm(princ.NameString[len(princ.NameString)-1])
tgt, skey, err := cl.sessionTGT(realm)
..........
But in our configuration file, there is no domain to realm mapping.
[domain_realm]
.ipa.pklcst-zum.example.com = IPA.PKLCST-ZUM.EXAMPLE.COM
ipa.pklcst-zum.example.com = IPA.PKLCST-ZUM.EXAMPLE.COM
xxxx.ipa.pklcst-zum.example.com = IPA.PKLCST-ZUM.EXAMPLE.COM
[capaths]
IPA.PKLCST-ZUM.EXAMPLE.COM = {
PKLCST-ZUM.EXAMPLE.COM = .
PKLNGNT-ZUM.EXAMPLE.COM = .
}
I made a better workaround by simply adding a domain to realm mapping from code.
h := strings.SplitN(req.URL.Host, ".", 2)[1]
c.Config.DomainRealm["."+h] = strings.ToUpper(h)
Since curl works with this configuration, I suspect it uses [capaths] of the configuration. For reference link for [capaths] : https://web.mit.edu/kerberos/krb5-1.5/krb5-1.5.4/doc/krb5-admin/capaths.html
The question is should the library try to cross-realm authentication if resolution from domain to the realm is failed? As I said in the first comment I do not know Kerberos that well so I am not sure.
If I am not mistaken [capaths] is not even parsed in the config.
Regards Birol
Hi
Thanks for the library. I have only a basic understanding of kerberos. I looked all over the examples and issues to make this work. But I could not make it work. I am trying to authenticate to a service using keytab for the host account, not a logged-in user. Basically I am trying the procedure below in golang. Domain names are changed.
The code that is run is below.
I got the below error
Below are the logs from client
Below are the klist -k /etc/krb5.keytab
Part of /etc/krb5.conf file is below
I also checked the DNS resolution of acxyz.pklngnt-zum.example.com, and reverse lookup for the ip and it resolves to the same name. But I am not sure it is related.
go version go1.13 library version github.com/jcmturner/gokrb5/v8 v8.0.1