web-dev-qa-db-ja.com

Linux DockerコンテナーでのWindows認証

私は、kubernetesの下のLinux DockerコンテナーでWindows認証を使用しようとしています。

私はこの設定に従っています: 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イメージを作成し、次の環境変数を追加し、ビルドを/ 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

アプリはrun.shによって実行されています

service syslog-ng start
kinit HTTP/[email protected] -k -t /app/is.k01.HTTP.keytab
klist
dotnet dev-certs https
dotnet /app/SampleApi.dll

klistは、SPNをマシンに割り当てたプリンシパルをリストします

ieとfirefoxでnetwork.negotiate-auth.trusted-urisをアプリに追加しました

しかし、ログインダイアログが表示され、ログインできません

だから問題は:

Microsoft.AspNetCore.Authentication.Negotiateパッケージでデバッグログを有効にするにはどうすればよいですか?

私の仮定は、このパッケージがKerberosと適切に通信しないことです。おそらく、いくつかのパッケージが欠落しているか、実行されていないか、または何かです。

また、機能するデータベースへの接続に統合セキュリティを使用しているため、コンテナと.netアプリがドメインに正常に接続されていることにも注意してください。

****編集>最初の部分への回答

ログを有効にするには、appsettings.jsonのkestrel:でログを有効にする必要があります。

  "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;
            }
        };
    }
);

****編集

一方、.netコアDocker WebアプリでWindows認証を許可するという私の目標によれば、.netコアのソースコードを調べ、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

どういうわけかOSでGSSAPIをトリガーするはずです

Dotnetランタイムgitで、aspnetコアのドキュメントに何も記載されていない場合でも、動作するにはgss-ntlmsspが必要であることを伝えています。

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

それにもかかわらず、私はgss-ntlmsspをコンパイルし、このライブラリがないとエラー「サポートされていないメカニズムが要求されました。」をスローすることがわかりました。私のライブラリでは、「資格情報が提供されていないか、資格情報が利用できないかアクセスできません。」というエラーがスローされますが、gss_ *メソッドにはアクセスできません。

私はgssメソッドの使用をテストしましたが、発生しなかったログエントリをファイルに追加しました。fe:

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 image(カスタマイズされた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

これまでのところ、私はmitソースから新しい最新のgssapiをコンパイルしていて、「サポートされていないメカニズムが要求されました」というエラーが発生していることがわかりました。 gssapiには、提供されていないgssインタープリターが必要なためです。 centos7では、opensslライブラリが互換性のない共有kerberosライブラリを使用していたため、yumが機能しなくなったという別の問題がありました。

***編集

Gss-ntlmsspにフラグGSS_C_MA_NOT_DFLT_MECHがあるため、「資格情報が提供されなかったか、資格情報が利用できないかアクセスできない」というメッセージで失敗しました。解決策は、デフォルトの認証メカニズムとして使用したいので、この属性なしでカスタムgss-ntlmsspを構築することです。

資格情報をチェックするためのサンプルコンソールアプリが機能するようになりました。今、それをDockerコンテナーに配置してみます。

***編集

私は自分の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)

***編集ここで失敗します: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()は、広告からユーザーを確認したいため、特定のファイルが設定されていないため、エラーを返します

external_get_creds()はここで失敗します:

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

external_get_credsはwinbindライブラリで認証を試みますが、明らかに認証情報キャッシュにユーザーが存在しません

私はそれをsambaが提供したwinbindライブラリを使ってコンパイルすることができました

だから今の質問は:ADと通信するようにwinbindライブラリをセットアップする方法は?

***編集

Githubで.net 5を使用しようとしましたが、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/[email protected] -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

私の意見では、私が知る限り、Negotiateはブラウザー間でサポートされていないため、NegotiateよりもNTLMを使用したいと思います。たとえば、Firefoxでは、ネゴシエートサーバーのabout:configをセットアップする必要があります。ワイルドカードはサポートされていません...

それにもかかわらず、ntlmでは.net core 5 Webアプリを実行できないようです。そのため、gssntlmsspライブラリなしで、デフォルトのkerberosメカニズムを使用してセットアップを試みます。 krb5.conf設定の何が問題になっていますか?

****編集したがって、私は現在2つの異なるアプローチを試みています。

  1. NTLM-私の意見では、これは、たとえばダイアログボックスなしでiisエクスプレスでntlmがユーザーを認証するのを見て、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

しかし、今私は他の問題を抱えています:Request ticket server HTTP/[email protected] kvno 3 found in keytab but not not enctype rc4-hmac

これは、keytabがrc4-hmacに含まれていないように思えます。これは、keytabが

ktpass -princ HTTP/[email protected] -pass *****  -mapuser MYDOMAIN\is.k01.kerb -pType KRB5_NT_PRINCIPAL -out c:\temp\is.k01.HTTP.keytab -crypto AES256-SHA1

.netドキュメントが言うように。

私はrc4-hmacの使用を許可せず、新しいエンコーディングのみを許可することができなかったので、インフラ部門に古いrc4-hmacエンコーディングで新しいキータブを生成するように依頼しました。

このステップは私をさらに動かし、代わりにこのエラーを受け取ります:Request ticket server HTTP/[email protected] kvno 4 not found in keytab;キータブが古くなっている可能性があります*

キータブが古くなることはなく、パスワードは変更されておらず、キータブが生成された1時間前に100%有効であり、Webに情報がないため、これは非常に奇妙です-"kvno 4 not found in keytab" fetch only 4結果はグーグルになります。

****編集

だから最後に私はそれをうまく動かすことができました:)

「keytabにkvno 4が見つからない」の問題は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でテストしましたが、まだ機能しません。

上記のビルドが機能するときにdockerコンテナーでネゴシエートする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            = 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

だから今の質問:多くのサービスを1つずつspnに追加せずにネゴシエートプロトコルを実行させ、手動でブラウザを設定する方法はありますか?

したがって、現時点では、すべての新しいWebサービスに以下が必要です。

setspn -S HTTP/mywebservice.mydomain.com mymachine
setspn -S HTTP/[email protected] mymachine

internet Explorer>設定>セキュリティ>ウェブ>詳細>ドメインで許可する必要がありますabout:config> network.negotiate-auth.trusted-uris chrome i Internet Explorerの設定を知っている

internet Explorerの設定は、ドメイングループポリシーによって何らかの方法で更新できるはずだと思います。誰でもどのようにしたらいいですか?

****編集ブラウザでのネゴシエート設定についてドメインでワイルドカードをテストしました。結果は次のとおりです。

  • chrome:サポート* .k01.mydomain.com
  • ie:サポート* .k01.mydomain.com
  • firefox(73.0.1(64-bit)):* .k01.mydomain.comはサポートされません-is.k01.mydomain.comなどの完全なドメインのみ
  • Edge44.18362.449.0-理由はわかりませんが、IE設定のどれも反映されませんでした.. * .k01.mydomain.comでもis.k01.mydomain.comでも機能しません

****編集ネゴシエートでwin authを使い始めましたが、.netコアでいくつかの問題が発生します

IIS expressの下のこのコードは、MYDOMAIN\myuserの形式でユーザーを表示します:

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

Linuxでは、myuser @ mydomain.comと表示されます

IIS expressの下のUser.Indentities.First()はWindowsIdentityであり、ユーザーのすべてのグループを一覧表示できます

LinuxでのUser.Indentities.First()は、グループ情報のないClaimsIdentityです。

IIS Expressのグループでそれを制限しようとすると、次のようになります:

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

Linux kestrel with negotiate:

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

したがって、チョウゲンボウの交渉ではグループが適切にリストされないようです。だから私は今調査するつもりです、ケストレルでWindowsIdentityを取得する方法

5
Scholtz

Dotnetランタイムgitで、aspnetコアのドキュメントに何も記載されていない場合でも、動作するにはgss-ntlmsspが必要であることを伝えています。

'gss-ntlmssp'パッケージは、GSS-APIのNTLMプロトコルをサポートするためのプラグインです。未加工のNTLMプロトコルと、「ネゴシエート」(SPNEGOプロトコル)が使用されているときにKerberosからNTLMへのフォールバックとして使用されるNTLMの両方をサポートします。参照: https://docs.Microsoft.com/en-us/openspecs/windows_protocols/MS-SPNG/f377a379-c24f-4a0f-a3eb-0d835389e28a

上記の説明と投稿した画像を読むと、アプリケーションが実際にKerberosではなくNTLMを使用しようとしているようです。 based64でエンコードされたトークンが「Y」ではなく「T」で始まるため、わかります。

ASP.NET Coreサーバー(Kestrel)は、LinuxのNTLMサーバー側をまったくサポートしていません。 「Www-Authenticate:Negotiate」がクライアントに送り返されることのみを提供します。そして通常、これはKerberosが使用されることを意味します。 NegotiateはNTLMの使用にフォールバックできます。ただし、まだ出荷されていない.NET 5を除いて、ASP.NET Coreでは機能しません。

アプリケーションがNTLMにフォールバックすることを期待していますか?そうでない場合は、おそらくKerberos環境が完全にセットアップされていません。これは、SPNやLinuxキータブファイルが正しくないなど、さまざまな問題が原因で発生する可能性があります。また、クライアントがKerberosレルムの一部ではないユーザー名/パスワードを使用しようとしたことが原因である可能性もあります。

この問題はここで議論されています: https://github.com/dotnet/aspnetcore/issues/19397

Aspnetコアリポジトリの問題のディスカッションで会話を続けることをお勧めします。

1
David - MSFT