Windows аутентификация в linux docker контейнере - PullRequest
2 голосов
/ 19 февраля 2020

Я пытаюсь использовать windows аутентификацию в linux docker контейнере под kubernetes.

Я выполняю следующие настройки: https://docs.microsoft.com/en-us/aspnet/core/security/authentication/windowsauth?view=aspnetcore-3.1&tabs=visual-studio#kestrel

Приложение находится в. net core3, с nuget Microsoft.AspNetCore.Authentication.Negotiate и работает в kestrel

Я добавил

services.AddAuthentication(Microsoft.AspNetCore.Authentication.Negotiate.NegotiateDefaults.AuthenticationScheme).AddNegotiate();

, а также

app.UseAuthentication();

и настройте мой образ devbase как

FROM mcr.microsoft.com/dotnet/core/sdk:3.1-buster as final
USER root
RUN whoami
RUN apt update && apt dist-upgrade -y

ADD ca/ca.crt /usr/local/share/ca-certificates/ca.crt
RUN chmod 644 /usr/local/share/ca-certificates/*
RUN update-ca-certificates


RUN DEBIAN_FRONTEND=noninteractive apt install -y krb5-config krb5-user

COPY krb5.conf /etc/krb5.conf
RUN mkdir /app

RUN echo BQIAAA..== | base64 -d > /app/is.k01.HTTP.keytab
WORKDIR /app

#RUN docker version

RUN groupadd --gid 1000 app && useradd --uid 1000 --gid app --shell /bin/bash -d /app app

RUN apt install -y mc sudo syslog-ng realmd gss-ntlmssp

сборка в конвейере tfs создает приложение docker образ, полученный из вышеупомянутого, и добавляет следующие переменные env, а также копирует сборку в / app

RUN chmod 0700 run.sh
ENV KRB5_KTNAME=/app/is.k01.HTTP.keytab
ENV KRB5_TRACE=/dev/stdout
ENV ASPNETCORE_URLS=http://*:80;https://+:443
RUN chown app:app /app -R
USER app

приложение запускается при запуске. sh

service syslog-ng start
kinit HTTP/is.k01.mydomain.com@MYDOMAIN.COM -k -t /app/is.k01.HTTP.keytab
klist
dotnet dev-certs https
dotnet /app/SampleApi.dll

klist содержит список участника, который назначил SPN для машины

в ie и firefox i я добавил network.negotiate-auth.trusted-uris в мое приложение

, однако я получаю диалоговое окно входа в систему безуспешно, чтобы войти в систему

, поэтому вопрос:

Как включить журнал отладки с помощью пакета Microsoft.AspNetCore.Authentication.Negotiate?

My предполагается, что этот пакет не взаимодействует с Kerberos должным образом, возможно, какой-то пакет отсутствует, не запущен или что-то в этом роде.

Также обратите внимание, что контейнер и приложение. net успешно подключены к домену, поскольку я использую встроенный безопасность для подключения к базе данных, которая работает.

**** Редактировать> Ответ на первую часть

Чтобы включить журналы, необходимо включить журналы в kestrel: in appsettings. json:

  "Logging": {
    "LogLevel": {
      "Default": "Debug",
    }
  },

В program.cs:

Host.CreateDefaultBuilder(args)
.ConfigureLogging(logging =>
{
    logging.AddFilter("Microsoft", LogLevel.Debug);
    logging.AddFilter("System", LogLevel.Debug);
    logging.ClearProviders();
    logging.AddConsole();
})
.ConfigureWebHostDefaults(webBuilder =>
{

В Startup.cs можно отслеживать события согласования:

services.AddAuthentication(NegotiateDefaults.AuthenticationScheme).AddNegotiate(

    options =>
    {
        options.PersistKerberosCredentials = true;
        options.Events = new NegotiateEvents()
        {
            OnAuthenticated = challange =>
            {
                ..
            },
            OnChallenge = challange =>
            {
                ..
            },
            OnAuthenticationFailed = context =>
            {
                // context.SkipHandler();
                Console.WriteLine($"{DateTimeOffset.Now.ToString(czechCulture)} OnAuthenticationFailed/Scheme: {context.Scheme.Str()}, Request: {context.Request.Str()}");
                Console.WriteLine("context?.HttpContext?.Features?.Select(f=>f.Key.Name.ToString())");
                var items = context?.HttpContext?.Features?.Select(f => "- " + f.Key?.Name?.ToString());
                if (items != null)
                {
                    Console.WriteLine(string.Join("\n", items));
                }
                Console.WriteLine("context.HttpContext.Features.Get<IConnectionItemsFeature>()?.Items " + context.HttpContext.Features.Get<IConnectionItemsFeature>()?.Items?.Count);
                var items2 = context.HttpContext?.Features.Get<IConnectionItemsFeature>()?.Items?.Select(f => "- " + f.Key?.ToString() + "=" + f.Value?.ToString());
                if (items2 != null) {
                    Console.WriteLine(string.Join("\n", items2));
                }
                return Task.CompletedTask;
            }
        };
    }
);

**** Редактировать

Между тем, в соответствии с моей целью разрешить windows аутентификацию в. net core docker веб-приложении, я просматривал исходный код. net core, и corefx и переписал код авторизации в этот пример консольного приложения. :

try
{
    var token = "MyToken==";
    var secAssembly = typeof(AuthenticationException).Assembly;
    Console.WriteLine("var ntAuthType = secAssembly.GetType(System.Net.NTAuthentication, throwOnError: true);");
    var ntAuthType = secAssembly.GetType("System.Net.NTAuthentication", throwOnError: true);
    Console.WriteLine("var _constructor = ntAuthType.GetConstructors(BindingFlags.NonPublic | BindingFlags.Instance).First();");
    var _constructor = ntAuthType.GetConstructors(BindingFlags.NonPublic | BindingFlags.Instance).First();
    Console.WriteLine("var credential = CredentialCache.DefaultCredentials;");
    var credential = CredentialCache.DefaultCredentials;
    Console.WriteLine("var _instance = _constructor.Invoke(new object[] { true, Negotiate, credential, null, 0, null });");
    var _instance = _constructor.Invoke(new object[] { true, "Negotiate", credential, null, 0, null });

    var negoStreamPalType = secAssembly.GetType("System.Net.Security.NegotiateStreamPal", throwOnError: true);
    var _getException = negoStreamPalType.GetMethods(BindingFlags.NonPublic | BindingFlags.Static).Where(info => info.Name.Equals("CreateExceptionFromError")).Single();


    Console.WriteLine("var _getOutgoingBlob = ntAuthType.GetMethods(BindingFlags.NonPublic | BindingFlags.Instance).Where(info => info.Name.Equals(GetOutgoingBlob) && info.GetParameters().Count() == 3).Single();");
    var _getOutgoingBlob = ntAuthType.GetMethods(BindingFlags.NonPublic | BindingFlags.Instance).Where(info => info.Name.Equals("GetOutgoingBlob") && info.GetParameters().Count() == 3).Single();
    Console.WriteLine("var decodedIncomingBlob = Convert.FromBase64String(token);;");
    var decodedIncomingBlob = Convert.FromBase64String(token);
    Console.WriteLine("var parameters = new object[] { decodedIncomingBlob, false, null };");
    var parameters = new object[] { decodedIncomingBlob, false, null };
    Console.WriteLine("var blob = (byte[])_getOutgoingBlob.Invoke(_instance, parameters);");
    var blob = (byte[])_getOutgoingBlob.Invoke(_instance, parameters);
    if (blob != null)
    {
        Console.WriteLine("var out1 = Convert.ToBase64String(blob);");
        var out1 = Convert.ToBase64String(blob);
        Console.WriteLine(out1);
    }
    else
    {
        Console.WriteLine("null blob value returned");


        var securityStatusType = secAssembly.GetType("System.Net.SecurityStatusPal", throwOnError: true);
        var _statusException = securityStatusType.GetField("Exception");
        var securityStatus = parameters[2];
        var error = (Exception)(_statusException.GetValue(securityStatus) ?? _getException.Invoke(null, new[] { securityStatus }));
        Console.WriteLine("Error:");
        Console.WriteLine(error);
        Console.WriteLine("securityStatus:");
        Console.WriteLine(securityStatus.ToString());
    }
}
catch(Exception exc)
{
    Console.WriteLine(exc.Message);
}

Итак, я обнаружил, что библиотека взаимодействует с System. Net .NTAuthentication , которая взаимодействует с System. Net .Security.NegotiateStreamPal которые общаются unix версия Interop.NetSecurityNative.InitSecContext

, которая должна каким-то образом вызывать GSSAPI в ОС

In do tnet runtime git, они сообщают нам что gss-ntlmssp необходим для того, чтобы это работало, даже если это не упоминается в документации ядра pnet.

https://github.com/dotnet/runtime/issues?utf8=%E2%9C%93&q=gss-ntlmssp

Тем не менее я скомпилировал gss-ntlmssp и обнаружил, что без этой библиотеки он выдает ошибку " Запрошен неподдерживаемый механизм. ». В моей библиотеке выдается ошибка « Учетные данные не были предоставлены или учетные данные были недоступны или недоступны. », но никогда не было доступа ни к каким методам gss_ *.

Я проверил использование методов gss добавив запись журнала в файл, который никогда не происходил .. например:

OM_uint32 gss_init_sec_context(OM_uint32 *minor_status,
                               gss_cred_id_t claimant_cred_handle,
                               gss_ctx_id_t *context_handle,
                               gss_name_t target_name,
                               gss_OID mech_type,
                               OM_uint32 req_flags,
                               OM_uint32 time_req,
                               gss_channel_bindings_t input_chan_bindings,
                               gss_buffer_t input_token,
                               gss_OID *actual_mech_type,
                               gss_buffer_t output_token,
                               OM_uint32 *ret_flags,
                               OM_uint32 *time_rec)
{
   FILE *fp;
   fp = fopen("/tmp/gss-debug.log", "w+");
   fprintf(fp, "gss_init_sec_context\n");
   fclose(fp);
    return gssntlm_init_sec_context(minor_status,
                                    claimant_cred_handle,
                                    context_handle,
                                    target_name,
                                    mech_type,
                                    req_flags,
                                    time_req,
                                    input_chan_bindings,
                                    input_token,
                                    actual_mech_type,
                                    output_token,
                                    ret_flags,
                                    time_rec);
}

Итак. net вызывает gssapi, а gssapi не вызывает механизм.

Я наблюдал такое же поведение в centos7 vm, подсистеме ubuntu windows и образе debian docker (настроенный mcr.microsoft.com/dotnet/core/sdk:3.1-buster)

Итак, вопрос в том, как я могу отладить gssapi?

Я предполагаю, что мой текущий gssapi управляется этой библиотекой:

readelf -d /usr/lib64/libgssapi_krb5.so
Dynamic section at offset 0x4aa48 contains 34 entries:
  Tag        Type                         Name/Value
 0x0000000000000001 (NEEDED)             Shared library: [libkrb5.so.3]
 0x0000000000000001 (NEEDED)             Shared library: [libk5crypto.so.3]
 0x0000000000000001 (NEEDED)             Shared library: [libcom_err.so.2]
 0x0000000000000001 (NEEDED)             Shared library: [libkrb5support.so.0]
 0x0000000000000001 (NEEDED)             Shared library: [libdl.so.2]
 0x0000000000000001 (NEEDED)             Shared library: [libkeyutils.so.1]
 0x0000000000000001 (NEEDED)             Shared library: [libresolv.so.2]
 0x0000000000000001 (NEEDED)             Shared library: [libc.so.6]
 0x000000000000000e (SONAME)             Library soname: [libgssapi_krb5.so.2]
 0x000000000000000c (INIT)               0xb1d8
 0x000000000000000d (FINI)               0x3ebcc
 0x0000000000000019 (INIT_ARRAY)         0x24a120
 0x000000000000001b (INIT_ARRAYSZ)       8 (bytes)
 0x000000000000001a (FINI_ARRAY)         0x24a128
 0x000000000000001c (FINI_ARRAYSZ)       16 (bytes)
 0x000000006ffffef5 (GNU_HASH)           0x1f0
 0x0000000000000005 (STRTAB)             0x3048
 0x0000000000000006 (SYMTAB)             0x720
 0x000000000000000a (STRSZ)              9167 (bytes)
 0x000000000000000b (SYMENT)             24 (bytes)
 0x0000000000000003 (PLTGOT)             0x24b000
 0x0000000000000002 (PLTRELSZ)           8088 (bytes)
 0x0000000000000014 (PLTREL)             RELA
 0x0000000000000017 (JMPREL)             0x9240
 0x0000000000000007 (RELA)               0x58b0
 0x0000000000000008 (RELASZ)             14736 (bytes)
 0x0000000000000009 (RELAENT)            24 (bytes)
 0x000000006ffffffc (VERDEF)             0x5788
 0x000000006ffffffd (VERDEFNUM)          3
 0x000000006ffffffe (VERNEED)            0x57e0
 0x000000006fffffff (VERNEEDNUM)         4
 0x000000006ffffff0 (VERSYM)             0x5418
 0x000000006ffffff9 (RELACOUNT)          504
 0x0000000000000000 (NULL)               0x0

так Пока я скомпилировал новую версию gssapi из mit source и обнаружил, что она выдает ошибку «Запрошен неподдерживаемый механизм». потому что gssapi требует gss интерпретатор, который не предоставляется. В centos7 у меня была еще одна проблема: библиотека openssl использовала общую библиотеку kerberos, которая была несовместима, поэтому yum перестал работать.

*** edit

Я обнаружил, что gss-ntlmssp имеет пометить GSS_C_MA_NOT_DFLT_MECH, поэтому произошел сбой с сообщением «Учетные данные не предоставлены, или учетные данные были недоступны или недоступны». Решением является создание пользовательского gss-ntlmssp без этого атрибута, потому что я хочу использовать его в качестве механизма аутентификации по умолчанию.

Мой пример консольного приложения для проверки учетных данных теперь работает, я постараюсь поместить его в контейнер docker.

*** edit

Мне удалось запустить ConsoleApp успешно в kubernetes:

FROM mcr.microsoft.com/dotnet/core/sdk:3.1-buster as final
USER root
RUN whoami
RUN apt update && apt dist-upgrade -y

ADD ca/ca.crt /usr/local/share/ca-certificates/ca.crt
RUN chmod 644 /usr/local/share/ca-certificates/*
RUN update-ca-certificates


RUN DEBIAN_FRONTEND=noninteractive apt install -y krb5-config krb5-user

RUN mkdir /app

RUN apt install -y mc sudo syslog-ng python3-software-properties software-properties-common packagekit git gssproxy vim
RUN apt install -y autoconf automake libxslt-dev doxygen findutils libgettextpo-dev libtool m4 make libunistring-dev libssl-dev zlib1g-dev gettext xsltproc libxml2-utils libxml2-dev xml-core docbook-xml docbook-xsl bison libkrb5-dev
RUN systemctl enable syslog-ng
RUN mkdir /src 
RUN cd /src && wget https://web.mit.edu/kerberos/dist/krb5/1.18/krb5-1.18.tar.gz
RUN cd /src && tar -xf krb5-1.18.tar.gz
RUN cd /src/krb5-1.18/src && ./configure && make && make install

RUN cd /src && git clone https://github.com/scholtz/gss-ntlmssp.git 
RUN cd /src/gss-ntlmssp/ && autoreconf -f -i && ./configure && make && make install
RUN cp /src/gss-ntlmssp/examples/mech.ntlmssp.conf /etc/gss/mech.d/mech.ntlmssp.conf

COPY testgss /testgss
RUN cd /testgss && dotnet ConsoleApp3.dll

RUN groupadd --gid 1000 app && useradd --uid 1000 --gid app --shell /bin/bash -d /app app

RUN echo BQIA..AAAB | base64 -d > /app/user.keytab
RUN echo BQIA..oQ== | base64 -d > /etc/krb5.keytab
RUN echo BQIA..oQ== | base64 -d > /app/is.k01.HTTP.keytab
RUN echo BQIA..AAA= | base64 -d > /app/is.k01.kerb.keytab

COPY krb5.conf /etc/krb5.conf
COPY krb5.conf /usr/local/etc/krb5.conf
RUN ln -s /etc/gss /usr/local/etc/gss

RUN cd /app
WORKDIR /app

enter image description here

Однако я получаю эту ошибку сейчас:

System.Exception: An authentication exception occured (0xD0000/0x4E540016).
 ---> Interop+NetSecurityNative+GssApiException: GSSAPI operation failed with error - Unspecified GSS failure.  Minor code may provide more information (Feature not available).
   at System.Net.Security.NegotiateStreamPal.GssAcceptSecurityContext(SafeGssContextHandle& context, Byte[] buffer, Byte[]& outputBuffer, UInt32& outFlags)
   at System.Net.Security.NegotiateStreamPal.AcceptSecurityContext(SafeFreeCredentials credentialsHandle, SafeDeleteContext& securityContext, ContextFlagsPal requestedContextFlags, Byte[] incomingBlob, ChannelBinding channelBinding, Byte[]& resultBlob, ContextFlagsPal& contextFlags)

*** edit Теперь здесь происходит сбой: gssntlm_init_sec_context .. gssntlm_acquire_cred .. gssntlm_acquire_cred_from ..

    if (cred_store != GSS_C_NO_CRED_STORE) {
        retmin = get_creds_from_store(name, cred, cred_store);
    } else {
        retmin = get_user_file_creds(name, cred);
        if (retmin) {
            retmin = external_get_creds(name, cred);
        }
    }

get_user_file_creds () возвращает ошибку, так как у меня нет настроек файла c пользователей из объявления, которое я хочу проверить *

external_get_creds () терпит неудачу здесь:

    wbc_status = wbcCredentialCache(&params, &result, NULL);
    if(!WBC_ERROR_IS_OK(wbc_status)) goto done;

external_get_creds пытается аутентифицироваться с библиотекой winbind и, очевидно, в кэше учетных данных нет пользователя

мне удалось скомпилировать его с Библиотека winbind, которую samba предоставила

, поэтому теперь вопрос: Как настроить библиотеку winbind для связи с AD?

*** Edit

Я пытался использовать. net 5, как в Githu Би сказал, что NTLM работает в. net 5. Однако я получаю тот же результат, что и с. net 3.1.

Docker изображением, с которым я пробовал это:

FROM mcr.microsoft.com/dotnet/core-nightly/sdk:5.0-buster as final
USER root
RUN whoami
RUN apt update && apt dist-upgrade -y

RUN DEBIAN_FRONTEND=noninteractive apt install -y krb5-config krb5-user

RUN mkdir /app

RUN apt install -y mc sudo syslog-ng python3-software-properties software-properties-common packagekit git gssproxy vim apt-utils
RUN apt install -y autoconf automake libxslt-dev doxygen findutils libgettextpo-dev libtool m4 make libunistring-dev libssl-dev zlib1g-dev gettext xsltproc libxml2-utils libxml2-dev xml-core docbook-xml docbook-xsl bison libkrb5-dev
RUN systemctl enable syslog-ng
RUN mkdir /src 


#RUN cd /src && git clone https://github.com/scholtz/gss-ntlmssp.git 
RUN DEBIAN_FRONTEND=noninteractive apt install -y libwbclient-dev samba samba-dev
#RUN cat /usr/include/samba-4.0/wbclient.h

COPY gss-ntlmssp /usr/local/src/gss-ntlmssp
RUN cd /usr/local/src/gss-ntlmssp/ && autoreconf -f -i && ./configure && make && make install
RUN cp /usr/local/src/gss-ntlmssp/examples/mech.ntlmssp.conf /etc/gss/mech.d/mech.ntlmssp.conf
RUN groupadd --gid 1000 app && useradd --uid 1000 --gid app --shell /bin/bash -d /app app

RUN echo BQIAAABMA..ArHdoQ== | base64 -d > /etc/krb5.keytab

COPY krb5.conf /etc/krb5.conf
COPY smb.conf /etc/samba/smb.conf
COPY krb5.conf /usr/local/etc/krb5.conf

RUN DEBIAN_FRONTEND=noninteractive apt install -y winbind

ENV KRB5_TRACE=/dev/stdout

RUN mkdir /src2
WORKDIR /src2
RUN dotnet --list-runtimes
RUN dotnet new webapi --auth Windows 
RUN dotnet add package Microsoft.AspNetCore.Authentication.Negotiate


RUN sed -i '/services.AddControllers/i services.AddAuthentication(Microsoft.AspNetCore.Authentication.Negotiate.NegotiateDefaults.AuthenticationScheme).AddNegotiate();' Startup.cs 

RUN sed -i  '/app.UseAuthorization/i app.UseAuthentication();' Startup.cs
run echo a
RUN cat Startup.cs

RUN dotnet restore
RUN dotnet build


ENV ASPNETCORE_URLS="http://*:5002;https://*:5003"
EXPOSE 5002
EXPOSE 5003

RUN cd /app
WORKDIR /app
docker run -it -p 5003:5003 -it registry.k01.mydomain.com/k01-devbase:latest

В docker контейнер:

kinit HTTP/myuser@MYDOMAIN.COM -k -t /etc/krb5.keytab
klist

enter image description here

dotnet run src2.dll

enter image description here

Я поместил свою собственную информацию отладки в библиотеку gssntlmssp и поместил ее в файл

cat /tmp/gss-debug.log

enter image description here

Это точно такой же конец где я закончил. net core 3.1.

wbcCredentialCache (samba lib) не работает в точке, где он не может найти кэшированные учетные данные

Это мой krb5.conf:

[appdefaults]
    default_lifetime      = 25hrs
    krb4_convert          = false
    krb4_convert_524      = false

    ksu = {
        forwardable       = false
    }

    pam = {
        minimum_uid       = 100
        forwardable       = true
    }

    pam-afs-session = {
        minimum_uid       = 100
    }

[libdefaults]
    default_realm         = MYDOMAIN.COM

[realms]
     MYDOMAIN.COM = {
        kdc            = DC01.MYDOMAIN.COM
        default_domain = MYDOMAIN.COM
    }

[domain_realm]
    mydomain.com.    = MYDOMAIN.COM
    .mydomain.com.    = MYDOMAIN.COM

[logging]
default      = CONSOLE
default      = SYSLOG:INFO
default = FILE:/var/log/krb5-default.log
kdc = CONSOLE
kdc = SYSLOG:INFO:DAEMON
kdc = FILE:/var/log/krb5-kdc.log
admin_server = SYSLOG:INFO
admin_server = DEVICE=/dev/tty04
admin_server = FILE:/var/log/krb5-kadmin.log

и часть файла samba:

[global]
  security = domain
  workgroup = mydomain.com
  password server = *
  idmap config * : range = 16777216-33554431
  template shell = /bin/bash
  winbind use default domain = yes
  winbind offline logon = false
  wins server = 10.0.0.2

По моему мнению, я хотел бы больше иметь NTLM, чем Negotiate, потому что, насколько мне известно, Negotiate не поддерживается среди браузеров. Например, в firefox человек должен настроить about: config для сервера переговоров. Подстановочные знаки не поддерживаются, ...

тем не менее кажется, что я не смогу запустить. net Core 5 веб-приложение с помощью ntlm, поэтому я попытаюсь установить его без библиотеки gssntlmssp сейчас с некоторыми Механизм Kerberos по умолчанию. Есть идеи, что не так с моими настройками krb5.conf?

**** Редактировать Итак, я сейчас пробую два разных подхода:

  1. NTLM - in На мой взгляд, это предпочтительный способ, поскольку я видел, как ntlm аутентифицирует пользователей в iis express, например, без диалогового окна, и не требует какой-либо специальной настройки в firefox или через групповую политику (пожалуйста, исправьте меня, если я ошибаюсь)
  2. Переговоры

Что касается переговоров, мне удалось добиться некоторых успехов ..

С этим контейнером docker я смог обойти неподдерживаемый механизм :

FROM mcr.microsoft.com/dotnet/core/sdk:3.1-buster as final
USER root
RUN whoami
RUN apt update && apt dist-upgrade -y

RUN DEBIAN_FRONTEND=noninteractive apt install -y krb5-config krb5-user

RUN mkdir /app

RUN apt install -y mc sudo syslog-ng python3-software-properties software-properties-common packagekit git gssproxy vim apt-utils
RUN apt install -y autoconf automake libxslt-dev doxygen findutils libgettextpo-dev libtool m4 make libunistring-dev libssl-dev zlib1g-dev gettext xsltproc libxml2-utils libxml2-dev xml-core docbook-xml docbook-xsl bison libkrb5-dev
RUN systemctl enable syslog-ng
RUN mkdir /src 

RUN groupadd --gid 1000 app && useradd --uid 1000 --gid app --shell /bin/bash -d /app app

RUN echo BQIAAAA8..vI | base64 -d > /etc/krb5.keytab


COPY krb5.conf /etc/krb5.conf
COPY krb5.conf /usr/local/etc/krb5.conf
ADD ca/is.k01.mydomain.com.p12 /etc/ssl/certs/is.k01.mydomain.com.pfx

RUN cd /app
WORKDIR /app

Однако теперь у меня есть другая проблема: Запрос сервера запросов HTTP / is.k01.mydomain. com@MYDOMAIN.com kvno 3 найдено в keytab, но не с enctype rc4-hma c

Мне кажется, что таблица ключей не с rc4-hma c, что верно, потому что таблица ключей была сгенерирована с

ktpass -princ HTTP/is.k01.mydomain.com@MYDOMAIN.COM -pass *****  -mapuser MYDOMAIN\is.k01.kerb -pType KRB5_NT_PRINCIPAL -out c:\temp\is.k01.HTTP.keytab -crypto AES256-SHA1

в качестве документации. net говорит.

Я не смог запретить использование rc4-hma c и разрешить только более новую кодировку, поэтому я попросил мою инфраструктуру сгенерировать новую таблицу ключей со старой кодировкой rc4-hma c.

Этот шаг продвинул меня дальше, и вместо этого я получил эту ошибку: Запросить тикет сервер HTTP / is.k01.mydomain. com@MYDOMAIN.COM kvno 4 не найден в keytab; keytab, вероятно, устарел *

Что очень странно, потому что ярлыки ключей не могут устареть, пароль не был изменен и был действителен на 100% один час go, когда генерировалась таблица ключей, и нет никакой информации в Интернете - "kvno 4 не найден в keytab" получить только 4 результата в Google.

**** РЕДАКТИРОВАТЬ

Так, наконец, мне удалось заставить его работать: )

Проблема с "kvno 4 not found in keytab" была в файле krb5.conf, где я за принудительное шифрование aes добавил строки

#   default_tkt_enctypes  = aes256-cts-hmac-sha1-96 aes256-cts-hmac-sha1-9
#   default_tgs_enctypes  = aes256-cts-hmac-sha1-96 aes256-cts-hmac-sha1-9
#   permitted_enctypes    = aes256-cts-hmac-sha1-96 aes256-cts-hmac-sha1-9

После того как я их закомментировал, аутентификация с использованием Negotiate начала работать. Я протестировал NTLM с. net 5, и он по-прежнему не работает.

Файл krb5.conf, с которым выполняется согласование в контейнере docker, как работает сборка выше:

[appdefaults]
    default_lifetime      = 25hrs
    krb4_convert          = false
    krb4_convert_524      = false

    ksu = {
        forwardable       = false
    }

    pam = {
        minimum_uid       = 100
        forwardable       = true
    }

    pam-afs-session = {
        minimum_uid       = 100
    }

[libdefaults]
    default_realm         = MYDOMAIN.COM

[realms]
     MYDOMAIN.COM = {
        kdc            = DC02.MYDOMAIN.COM
        default_domain = MYDOMAIN.COM
    }

[domain_realm]
    mydomain.com.    = MYDOMAIN.COM
    .mydomain.com.    = MYDOMAIN.COM

[logging]
default      = CONSOLE
default      = SYSLOG:INFO
default = FILE:/var/log/krb5-default.log
kdc = CONSOLE
kdc = SYSLOG:INFO:DAEMON
kdc = FILE:/var/log/krb5-kdc.log
admin_server = SYSLOG:INFO
admin_server = DEVICE=/dev/tty04
admin_server = FILE:/var/log/krb5-kadmin.log

Итак, вопрос теперь: Есть ли способ разрешить многим службам запускать протокол согласования без добавления каждого в spn по одному и ручной настройки браузеров?

Итак, на данный момент каждый новый веб-служба должна иметь:

setspn -S HTTP/mywebservice.mydomain.com mymachine
setspn -S HTTP/mywebservice@MYDOMAIN.COM mymachine

и должна быть разрешена в inte rnet explorer> настройки> security> webs> Details> домен должен быть указан там в firefox about: config> network.negotiate- auth.trusted-uris chrome Насколько мне известно, требуется inte rnet настройки проводника

Я предполагаю, что настройки проводника inte rnet должны быть как-то обновлены с помощью групповой политики домена. кто-нибудь есть идеи, как?

**** РЕДАКТИРОВАТЬ Я проверил подстановочный знак в домене для согласования настроек в браузерах, и вот результаты:

  • chrome: ПОДДЕРЖКА * .k01.mydomain.com
  • ie: ПОДДЕРЖКА * .k01.mydomain.com
  • firefox (73.0.1 (64-разрядная версия)): НЕ ПОДДЕРЖИВАЕТ * .k01.mydomain.com - только полный домен, например is.k01.mydomain.com
  • edge 44.18362.449.0 - не знаю почему, но ни один из параметров ie не был распространено .. не работает ни с * .k01.mydomain.com, ни с is.k01.mydomain.com

**** РЕДАКТИРОВАТЬ Я начал использовать win-auth для ведения переговоров, однако получаю некоторые проблемы в. net core

Этот код в IIS express показывает пользователя в форме MYDOMAIN \ myuser:

var userId = string.Join(',', User?.Identities?.Select(c => c.Name)) ?? "?";

В linux он отображается как myuser@mydomain.com

User.Indentities.First () в IIS express - это WindowsIdentity, и я могу перечислить все группы пользователя

User.Indentities.First () в Linux - это ClaimsIdentity без группы информация

Когда я пытаюсь ограничить его группой в IIS Express, я получаю:

//Access granted
[Authorize(Roles = "MYDOMAIN\\GROUP1")]
//403
[Authorize(Roles = "MYDOMAIN\\GROUP_NOT_EXISTS")]

Linux пустельга с переговорами:

//403
[Authorize(Roles = "MYDOMAIN\\GROUP1")]

Так что, похоже, что переговоры в Kestrel сделать не перечислять группы должным образом. Итак, я собираюсь исследовать сейчас, как получить WindowsIdentity в kestrel .

1 Ответ

1 голос
/ 29 февраля 2020

В do tnet runtime git они говорят нам, что gss-ntlmssp необходим для того, чтобы это работало, даже если это не упоминается в документации по pnet.

Пакет 'gss-ntlmssp' представляет собой плагин для поддержки протокола NTLM для GSS-API. Он поддерживает как сырой протокол NTLM, так и NTLM, используемый в качестве запасного варианта от Kerberos к NTLM, когда используется «Согласование» (протокол SPNE GO). Ссылка: https://docs.microsoft.com/en-us/openspecs/windows_protocols/MS-SPNG/f377a379-c24f-4a0f-a3eb-0d835389e28a

Из прочтения приведенного выше обсуждения и размещенного вами изображения видно, что приложение пытается использовать NTLM вместо Kerberos. Вы можете сказать, потому что токен в кодировке base64 начинается с «T» вместо «Y».

ASP. NET Главный сервер (Kestrel) вообще не поддерживает NTLM-сторону сервера на Linux , Он предусматривает только отправку «Www-Authenticate: переговоры» клиентам. И обычно это означает, что Kerberos будет использоваться. Переговоры могут вернуться к использованию NTLM. Однако это не работает в ASP. NET Core, за исключением. NET 5, который еще не отправлен.

Ожидаете ли вы, что ваше приложение откатится к NTLM? Если нет, то, возможно, среда Kerberos настроена не полностью. Это может быть вызвано рядом проблем, включая неправильные имена SPN и файлы Linux keytab. Это также может быть вызвано тем, что клиент пытается использовать имя пользователя / пароль, который не является частью области Kerberos.

Эта проблема обсуждается здесь: https://github.com/dotnet/aspnetcore/issues/19397

Рекомендую продолжить беседу в виде pnet основного вопроса репо.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...