dotnet / Kerberos.NET

A Kerberos implementation built entirely in managed code.
MIT License
514 stars 89 forks source link

Cannot locate SRV record in docker container #375

Closed LordXaosa closed 1 week ago

LordXaosa commented 1 week ago

I'm trying to authorize httpclient using following code:

var kerbCred = new KerberosPasswordCredential($"{config.User}@{config.DomainName}", $"{config.Password}");
await client.Authenticate(kerbCred);
var ticket = await client.GetServiceTicket($"http/{config.Host}");
var header = Convert.ToBase64String(ticket.EncodeGssApi().ToArray());
httpclient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Negotiate", header);

On windows works perfect, but in docker container on same machine it doesn't work:

System.AggregateException: One or more errors occurred. (Cannot locate SRV record for DOMAIN) (KDC KRB_ERR_RESPONSE_TOO_BIG: Response too big for UDP; retry with TCP) (Cannot locate a KDC Proxy endpoint for DOMAIN)
 ---> Kerberos.NET.Transport.KerberosTransportException: Cannot locate SRV record for DOMAIN
   at Kerberos.NET.Transport.KerberosTransportBase.SelectedPreferredInstance(String domain, String servicePrefix, IEnumerable1 results, Int32 defaultPort) in D:\a\1\s\Kerberos.NET\Client\Transport\KerberosTransportBase.cs:line 187
   at Kerberos.NET.Transport.KerberosTransportBase.LocatePreferredKdc(String domain, String servicePrefix) in D:\a\1\s\Kerberos.NET\Client\Transport\KerberosTransportBase.cs:line 168
   at Kerberos.NET.Transport.TcpKerberosTransport.GetClient(Func1 locatePreferredServer) in D:\a\1\s\Kerberos.NET\Client\Transport\TcpKerberosTransport.cs:line 99
   at Kerberos.NET.Transport.TcpKerberosTransport.SendMessageTCP(String domain, ReadOnlyMemory1 encoded, CancellationToken cancellation, Func1 locatePreferredServer) in D:\a\1\s\Kerberos.NET\Client\Transport\TcpKerberosTransport.cs:line 75
   at Kerberos.NET.Transport.TcpKerberosTransport.SendMessage(String domain, ReadOnlyMemory1 encoded, CancellationToken cancellation) in D:\a\1\s\Kerberos.NET\Client\Transport\TcpKerberosTransport.cs:line 54
   at Kerberos.NET.Transport.KerberosTransportSelector.<>c__DisplayClass7_0.<<SendMessage>b__0>d.MoveNext() in D:\a\1\s\Kerberos.NET\Client\Transport\KerberosTransportSelector.cs:line 76
--- End of stack trace from previous location ---
   at Kerberos.NET.Transport.KerberosTransportSelector.SendMessageOnTransport(String domain, Func2 cbSend) in D:\a\1\s\Kerberos.NET\Client\Transport\KerberosTransportSelector.cs:line 126
   --- End of inner exception stack trace ---
   at Kerberos.NET.Transport.KerberosTransportSelector.SendMessageOnTransport(String domain, Func2 cbSend) in D:\a\1\s\Kerberos.NET\Client\Transport\KerberosTransportSelector.cs:line 145
   at Kerberos.NET.Transport.KerberosTransportSelector.SendMessage(String domain, ReadOnlyMemory1 encoded, CancellationToken cancellation) in D:\a\1\s\Kerberos.NET\Client\Transport\KerberosTransportSelector.cs:line 72
   at Kerberos.NET.Transport.KerberosTransportBase.SendMessage[T](String domain, ReadOnlyMemory1 req, CancellationToken cancellation) in D:\a\1\s\Kerberos.NET\Client\Transport\KerberosTransportBase.cs:line 112
   at Kerberos.NET.Client.KerberosClient.RequestTgt(KerberosCredential credential, KrbPrincipalName tgtServicePrincipal) in D:\a\1\s\Kerberos.NET\Client\KerberosClient.cs:line 1325
   at Kerberos.NET.Client.KerberosClient.AuthenticateCredential(KerberosCredential credential, String tgtServiceName) in D:\a\1\s\Kerberos.NET\Client\KerberosClient.cs:line 384
   at Kerberos.NET.Client.KerberosClient.AuthenticateCore(KerberosCredential credential, String tgtServiceName) in D:\a\1\s\Kerberos.NET\Client\KerberosClient.cs:line 365
   at Kerberos.NET.Client.KerberosClient.Authenticate(KerberosCredential credential) in D:\a\1\s\Kerberos.NET\Client\KerberosClient.cs:line 322

I tried nslookup on both environments, windows:

╤хЁтхЁ:  server.internal
Address:  10.129.0.X

_kerberos._udp.DOMAIN  SRV service location:
          priority       = 0
          weight         = 100
          port           = 88
          svr hostname   = adhost.DOMAIN
adhost.DOMAIN internet address = 10.129.0.X

on docker container:

nslookup -type=SRV _kerberos._udp.DOMAIN
Server:         192.168.65.7
Address:        192.168.65.7#53

Non-authoritative answer:
_kerberos._udp.DOMAIN  service = 0 100 88 adhost.DOMAIN.

So seems that dns works fine.

Expected behavior All works fine

What am I doing wrong?

LordXaosa commented 1 week ago

Weird thing. If I nslookup domain only I will get different answers from docker and windows. Windows:

nslookup -type=SRV DOMAIN
╤хЁтхЁ: server.internal
Address:  10.129.0.X

DOMAIN
        primary name server = adhost.DOMAIN
        responsible mail addr = hostmaster.DOMAIN
        serial  = 2564
        refresh = 900 (15 mins)
        retry   = 600 (10 mins)
        expire  = 86400 (1 day)
        default TTL = 3600 (1 hour)

But docker seems can't find it:

nslookup -type=SRV DOMAIN
Server:         192.168.65.7
Address:        192.168.65.7#53

Non-authoritative answer:
*** Can't find DOMAIN: No answer

Authoritative answers can be found from:
DOMIAN
        origin = adhost.DOMAIN
        mail addr = hostmaster.DOMAIN
        serial = 2564
        refresh = 900
        retry = 600
        expire = 86400
        minimum = 3600
nslookup -type=SRV DOMAIN 10.129.0.X
Server:         10.129.0.X
Address:        10.129.0.X#53

*** Can't find DOMAIN: No answer

May be it's relevant

DanielMGoldberg commented 1 week ago

Hi! This is a duplicate of https://github.com/dotnet/Kerberos.NET/issues/185 The solution is to use DnsQuerry in your code.

LordXaosa commented 1 week ago

Wow! Thank you so much it worked! May be it could be a part of main library?

DanielMGoldberg commented 1 week ago

Wow! Thank you so much it worked! May be it could be a part of main library?

You're welcome. I think the nugget author was working on it, I don't really know if it's been completed.

SteveSyfuhs commented 1 week ago

The goal is to keep 3rd party dependencies to a minimum. There aren't many Linux users of this library so there hasn't been a big demand, though that is changing. Another contributer started work on native DNS support but it hasn't gone anywhere recently. I suspect it was a bigger job than they thought it would be. https://github.com/dotnet/Kerberos.NET/pull/334

LordXaosa commented 1 week ago

The goal is to keep 3rd party dependencies to a minimum. There aren't many Linux users of this library so there hasn't been a big demand, though that is changing. Another contributer started work on native DNS support but it hasn't gone anywhere recently. I suspect it was a bigger job than they thought it would be. #334

I thought there are many users of docker. Sound reasonable about 3d party. Thanks.

SteveSyfuhs commented 1 week ago

I'm just basing that on cases I've debugged. Could be higher. There's no telemetry to say one way or another. Submissions to finish the PR are of course always welcome.