我目前正在努力扩展多服务器环境的一对一简单 Kerberos/SPNEGO 配置并寻求一些帮助。
假设
- 我有两个 Active Directory 域和两个领域
EXAMPLE1.COM
,并EXAMPLE2.COM
与它们关联, - 我在它们两个中都有多个域控制器(分别是
dc1.example1.com
、dc2.example1.com
和),dc1.example2.com
dc2.example2.com
- 我还在两个不同的服务器上部署了两个 PHP 应用程序实例
app1.example1.com
,并且在它们前面有app2.example1.com
一个 NGINX 负载均衡器。lb.example1.com
我尝试在图片。
我希望两个域中的用户都能够将请求发送到lb.example1.com
,然后 再将请求转发到应用程序服务器,用户必须通过 SPNEGO/Kerberos 协议获得授权。为了实现 SPNEGO,我使用了使用附加 编译的 NGINX spnego-http-auth-nginx-module
。
我的问题如下:
- 我是否必须在
app1.example1.com
和 处授权用户app2.example1.com
?或者,也许lb.example1.com
应该是授权点?那么,我如何安全地将有关授权用户的信息转发到应用服务器? - 在这种情况下我的
/etc/krb5.conf
配置应该是什么样子?你能为我的配置提供一个示例吗? - 如何使用 生成密钥表文件
ktpass
?我是否应该为 和 创建一个密钥表文件app1.example1.com
,还是app2.example1.com
应该创建不同的文件?我应该在每个域控制器上运行吗?我是否应该为和ktpass
都创建两个不同的 SPN ?将它们映射到不同的用户?如果您提供应执行的全套 PowerShell 命令并指定应执行这些命令的域控制器,那就太好了。app1.example1.com
app2.example1.com
答案1
我是否应该为 app1.example1.com 和 app2.example1.com 创建两个不同的 SPN?
对于 HTTP 身份验证,URL 决定了客户端将查找哪个 SPN。(这很像“我应该在 TLS 证书中输入什么主机名”——输入的主机名。)在 Unix 系统上可能涉及 rDNS,但在 Windows 上它直接只是输入。
因此,如果 URL 说https://app2.example1.com
,则服务器需要 的 SPN HTTP/app2.example.com
,对于每个 URL 依此类推。
将它们映射到不同的用户?
这主要取决于你。
我是否应该为 app1.example1.com 和 app2.example1.com 创建一个密钥表文件,还是应该是不同的文件?
传统上,GSSAPI 没有很好的方法来设置每个上下文的密钥表路径——软件必须为 libkrb5 设置环境变量才能找到正确的密钥表。
因此,如果两个域都由 上的单个 Nginx 实例处理lb
,则默认答案是“单个密钥表,除非软件正确执行以允许多个密钥表”,而如果它们由app1
/上的不同实例处理app2
,则使用单独的密钥表会更简单。
查看 Nginx 模块的源代码,它不使用 GSSAPI“凭证存储扩展”来处理 keytab - 它使用一个进程范围的函数 - 所以我相信如果您选择处理 Kerberos,您将需要一个 keytab lb
。
我应该在每个域控制器上运行 ktpass 吗?
我认为你不需要运行它在域控制器上完全没有特别之处——它与所有其他 AD 用户管理工具没有任何不同。您可以在任何能够交谈域控制器,并且每个域只需要执行一次,因为更改将自动同步到该域中的所有其他 DC。
(ktpass 在 AD 级别所做的只是为帐户设置一个新密码 - Kerberos 密钥(例如在 keytabs 中找到的密钥)是从用户帐户的密码派生出来的,因此在生成它们时没有特殊的机制。)
我必须授权 app1.example1.com 和 app2.example1.com 上的用户,对吗?或者,也许 lb.example1.com 应该是授权点?
两种情况都有可能,但如果您有两个完全独立的 Kerberos 领域,并且它们之间没有信任,我可能会让每个应用服务器为其自己的领域处理 Kerberos,而无需在 LB 上进行任何复杂的配置。LB 需要做的就是转发原始标头,而根本不需要尝试执行 SPNEGO,并且“安全转发”部分会自动解决。
但不要混淆“身份验证”和“授权”——Kerberos 只进行身份验证;一旦客户端被认证为特定用户,检查他们是否被授权执行操作是一项单独的任务,并且它不会真的身份验证在何处进行对 Kerberos 来说并不重要。(当然,您仍然需要安全地将身份验证数据转发到需要的地方。)
(虽然 AD 票证确实携带了对授权有用的 PAC 数据,但看起来 Nginx 不知道如何提取这些数据——你只能得到他们拥有的主体名称已认证但没有团体成员资格或任何东西。)
在这种情况下,我的 /etc/krb5.conf 应该是什么样子?你能为我的配置提供一个示例吗?
如果要在单独的应用服务器上执行 Kerberos(每个服务器仅处理自己的领域),那么您只需要default_realm =
在 [libdefaults] 下定义。服务特定的配置(例如 keytabs)根本不需要进入 krb5.conf。
(我相信 AD 域会自动为 Kerberos 设置 SRV 记录,因此我不需要手动定义kdc =
。)