Nginx 获取web服务的kerberos/Windows AD登录工作时出现的问题

Nginx 获取web服务的kerberos/Windows AD登录工作时出现的问题,nginx,active-directory,kerberos,gssapi,Nginx,Active Directory,Kerberos,Gssapi,我已经为此挣扎了很长一段时间,但我无法让它发挥作用 以下是设置: 我有一台nginx Web服务器,在mywebapp.k8s.dal1.mycompany.io上为django应用程序提供服务 它编译了SPNEGO插件,我的配置中有以下端点: location /ad-login { uwsgi_pass django; include /usr/lib/mycompany/lib/wsgi/uwsgi_params; auth_gss on; auth_gss

我已经为此挣扎了很长一段时间,但我无法让它发挥作用

以下是设置: 我有一台nginx Web服务器,在
mywebapp.k8s.dal1.mycompany.io上为django应用程序提供服务

它编译了SPNEGO插件,我的配置中有以下端点:

location /ad-login {
    uwsgi_pass django;
    include /usr/lib/mycompany/lib/wsgi/uwsgi_params;
    auth_gss on;
    auth_gss_realm BURNERDEV1.DAL1.MYCOMPANY.IO;
    auth_gss_service_name HTTP/mywebapp.k8s.dal1.mycompany.io;
    auth_gss_allow_basic_fallback off;
}
我的AD域控制器位于burnerdev1.dal1.mycompany.io,我配置了以下用户:

rep_movsd
portal
我在DC服务器上以管理提示符运行以下命令:

ktpass -out krb5.keytab -mapUser portal@BURNERDEV1.DAL1.MYCOMPANY.IO +rndPass -mapOp set +DumpSalt -crypto AES256-SHA1 -ptype KRB5_NT_PRINCIPAL -princ HTTP/mywebapp.k8s.dal1.mycompany.io@BURNERDEV1.DAL1.MYCOMPANY.IO
setspn -A HTTP/mywebapp.k8s.dal1.mycompany.io@BURNERDEV1.DAL1.MYCOMPANY.IO portal


C:\Users\myself\Documents\keytab>ktpass -out krb5.keytab -mapUser portal@BURNERDEV1.DAL1.MYCOMPANY.IO +rndPass -mapOp set +DumpSalt -crypto AES256-SHA1 -ptype KRB5_NT_PRINCIPAL -princ HTTP/mywebapp.k8s.dal1.mycompany.io@BURNERDEV1.DAL1.MYCOMPANY.IO

Targeting domain controller: dal1devdc1.burnerdev1.dal1.mycompany.io
Using legacy password setting method
Failed to set property 'servicePrincipalName' to 'HTTP/mywebapp.k8s.dal1.mycompany.io' on Dn 'CN=portal,CN=Users,DC=burnerdev1,DC=dal1,
DC=mycompany,DC=io': 0x13.
WARNING: Unable to set SPN mapping data.
If portal already has an SPN mapping installed for HTTP/mywebapp.k8s.dal1.mycompany.io, this is no cause for concern.
Building salt with principalname HTTP/mywebapp.k8s.dal1.mycompany.io and domain BURNERDEV1.DAL1.MYCOMPANY.IO (encryption type 18)...
Hashing password with salt "BURNERDEV1.DAL1.MYCOMPANY.IOHTTPmywebapp.k8s.dal1.mycompany.io".
Key created.
Output keytab to krb5.keytab:
Keytab version: 0x502
keysize 110 HTTP/mywebapp.k8s.dal1.mycompany.io@BURNERDEV1.DAL1.MYCOMPANY.IO ptype 1 (KRB5_NT_PRINCIPAL) vno 3 etype 0x12 (AES256-SHA1) k
eylength 32 (0x632d9ca3356374e9de490ec2f7718f9fb652b20da40bd212a808db4c46a72bc5)

C:\Users\myself\Documents\keytab>setspn -A HTTP/mywebapp.k8s.dal1.mycompany.io@BURNERDEV1.DAL1.MYCOMPANY.IO portal
Checking domain DC=burnerdev1,DC=dal1,DC=mycompany,DC=io

Registering ServicePrincipalNames for CN=portal,CN=Users,DC=burnerdev1,DC=dal1,DC=mycompany,DC=io
        HTTP/mywebapp.k8s.dal1.mycompany.io@BURNERDEV1.DAL1.MYCOMPANY.IO
Updated object

C:\Users\myself\Documents\keytab>
现在在“Active Directory用户和计算机”部分,我右键单击用户并选择“属性” 然后在“委派”选项卡上设置“信任此用户委派给任何服务(仅限Kerberos)”

接下来,我将krb5.keytab文件复制到我的Web服务器并重新启动nginx容器

在作为域一部分的Windows工作站上,我以rep_movsd身份登录-当我运行klist时:

C:\Users\rep_movsd>klist

Current LogonId is 0:0x208d7

Cached Tickets: (2)

#0>     Client: rep_movsd @ BURNERDEV1.DAL1.MYCOMPANY.IO
        Server: krbtgt/BURNERDEV1.DAL1.MYCOMPANY.IO @ BURNERDEV1.DAL1.MYCOMPANY.IO
        KerbTicket Encryption Type: AES-256-CTS-HMAC-SHA1-96
        Ticket Flags 0x40e10000 -> forwardable renewable initial pre_authent name_canonicalize
        Start Time: 7/16/2020 2:05:51 (local)
        End Time:   7/16/2020 12:05:51 (local)
        Renew Time: 7/23/2020 2:05:51 (local)
        Session Key Type: AES-256-CTS-HMAC-SHA1-96


#1>     Client: rep_movsd @ BURNERDEV1.DAL1.MYCOMPANY.IO
        Server: HTTP/mywebapp.k8s.dal1.mycompany.io @ BURNERDEV1.DAL1.MYCOMPANY.IO
        KerbTicket Encryption Type: AES-256-CTS-HMAC-SHA1-96
        Ticket Flags 0x40a10000 -> forwardable renewable pre_authent name_canonicalize
        Start Time: 7/16/2020 2:06:01 (local)
        End Time:   7/16/2020 12:05:51 (local)
        Renew Time: 7/23/2020 2:05:51 (local)
        Session Key Type: AES-256-CTS-HMAC-SHA1-96
我设置Firefox进行SPENGO身份验证 然后我点击mywebapp.k8s.dal1.mycompany.io/ad-login,得到一个
403禁止的
错误

nginx服务器调试日志显示:

[debug] 16#16: *195 Client sent a reasonable Negotiate header 
[debug] 16#16: *195 GSSAPI authorizing 
[debug] 16#16: *195 Use keytab /etc/krb5.keytab 
[debug] 16#16: *195 Using service principal: HTTP/mywebapp.k8s.dal1.mycompany.io@BURNERDEV1.DAL1.MYCOMPANY.IO 
[debug] 16#16: *195 my_gss_name HTTP/mywebapp.k8s.dal1.mycompany.io@BURNERDEV1.DAL1.MYCOMPANY.IO 
[debug] 16#16: *195 gss_accept_sec_context() failed: Cannot decrypt ticket for HTTP/mywebapp.k8s.dal1.mycompany.io@BURNERDEV1.DAL1.MYCOMPANY.IO using keytab key for HTTP/mywebapp.k8s.dal1.mycompany.io@BURNERDEV1.DAL1.MYCOMPANY.IO: 
[debug] 16#16: *195 GSSAPI failed 
[debug] 16#16: *195 http finalize request: 403, "/ad-login?" a:1, c:1 
[debug] 16#16: *195 http special response: 403, "/ad-login?" 
[debug] 16#16: *195 http set discard body 
[debug] 16#16: *195 charset: "" > "utf-8" 
[debug] 16#16: *195 HTTP/1.1 403 Forbidden
 
顺便说一句,在之前的闲逛中,我发现如果我用ktpass为“门户”用户设置了一个固定密码,并在工作站上以该帐户登录,登录就会成功。 我错误地认为我需要为每个用户创建一个新的键表,并将它们结合起来

非常感谢您的帮助——我读了这么多相互矛盾的文档,这让我更加困惑,我一直在为此失眠


提前谢谢

我已经仔细阅读了您的问题陈述,我认为如果您按照我在下面写的步骤操作,问题就会得到解决

  • 在创建键表的DC服务器上,(1)必须临时禁用UAC。(2) 创建密钥表的用户必须是域管理员组的成员
  • 确保SPN不重复,然后从Active Directory用户帐户门户中删除SPN。必须在对同一帐户使用相同的SPN创建新的密钥表之前执行此操作。下面的命令是一行,换行使其看起来像两行
  • setspn-d HTTP/mywebapp.k8s.dal1.mycompany。io@BURNERDEV1.DAL1.MYCOMPANY.IO入口

  • 与以前完全一样,重新创建键选项卡
  • 您不需要运行命令
    setspn-A HTTP/mywebapp.k8s.dal1.mycompany。io@BURNERDEV1.DAL1.MYCOMPANY.IO门户
    ,因为步骤3中的ktpass命令已经在Active Directory用户帐户上设置了SPN
  • 用新的键选项卡替换旧的键选项卡
  • 重新启动nginx web服务器服务
  • 清除浏览器缓存并清除Kerberos大小写(klist purge)
  • 再试一次
  • 您必须执行所有这些步骤,包括最后一步7。不要跳过任何一个

    您的服务帐户名为portal。此密码的哈希值存储在Active Directory和密钥表中。两个位置都有相同的散列。nginix服务器上的密钥表用于解密入站Kerberos服务票证,以确定用户试图访问web应用的用户。更具体地说,GSS身份验证完成了所有工作,它使用keytab解除加密服务票据的加扰。用户代表没有服务帐户凭据。它是Active Directory域的一部分,当访问nginix web服务器时,它将获得自己的Kerberos服务票证,并且只需拥有一个由keytab解密的服务票证,即可向web服务器证明其身份。如果它不是BURNERDEV1.DAL1.MYCOMPANY.IO域的一部分,或者密码过期,或者是一个被禁用的帐户,它将无法获得服务票证,因此无法证明其身份,也无法通过身份验证


    如果您有时间,请查看我的TechNet Wiki关于键表创建及其背后的逻辑,以帮助您更好地理解这一复杂主题。

    创建键表时,我发现了一个明显的问题:“无法在Dn'CN=portal,CN=Users,DC=burnerdev1,DC=dal1,DC=mycompany,DC=io:0x13上将属性'servicePrincipalName'设置为'HTTP/mywebapp.k8s.dal1.mycompany.io'”。很高兴您保存了输出。域控制器、web应用程序和客户端是在同一台机器上运行,还是在不同的机器(物理或虚拟)上运行?”?如果将它们分开进行测试,您的测试会更好。您看到的错误是因为我第二次运行了该命令—到那时spn已经设置好了,所以它失败了。至于机器—这是一个带有AD服务器的实际内部开发网络,我的本地机器有一个Windows VM,web服务器是另一个计算机群集。让我问你一个问题…告诉我我是否理解正确…服务帐户(此处为门户)与keytab中的principalname关联。keytab具有服务帐户密码的一些哈希值。GSS身份验证需要类似的哈希值。除非用户代表以某种方式具有服务帐户凭据,否则这怎么可能工作?当我在linux系统上进行实验时,我刚刚添加了多个带有ktutil的keytab-每个都是是一个用户及其密码。每个本地用户都可以修改它,然后获得访问权限。我不了解Windows逻辑!!我想我知道出了什么问题。我将尝试一个答案,并在答案中回答此问题。感谢您的回复…我重新创建了服务用户和最终用户帐户,以确保我从一个干净的状态开始。1)我的帐户已满管理员,我通过GUI禁用了UAC(一直向下设置滑块)2)setpn-L portal显示CN=portal、CN=Users、DC=burnerdev1、DC=dal1、DC=mycompany、DC=io的注册ServicePrincipalNames:3)创建keytab再次失败,原因是:无法将Dn'CN=portal、CN=Users、DC=burnerd ev1、DC=dal1、DC=mycompany、DC=io:0x13上的属性“servicePrincipalName”设置为“HTTP/mywebapp.k8s.dal1.mycompany.io”。警告:无法设置PN映射数据