【问题标题】:Limit the usage of Kerberos TGTs限制 Kerberos TGT 的使用
【发布时间】:2019-11-15 22:37:03
【问题描述】:

我对 Kerberos 还是很陌生。我正在使用 Kerberos 测试单点登录功能。环境:Windows 客户端(使用 Active Directory 身份验证)连接到在 Linux 机器上运行的 Apache 服务器。调用的 cgi 脚本(在 Perl 中)使用转发用户 TGT 连接到数据库服务器。一切正常(我有主体、keytab 文件、配置文件和来自数据库服务器的结果 :))。因此,如果在 Windows 端以 win_usr_a 身份启动 CGI 请求,CGI 脚本会连接到远程数据库并查询 select user from dual 并返回 win_usr_a@EXAMPLE.COM

我只有一个问题想要解决。目前凭证缓存存储为 FILE:.... 在中间 Apache 服务器上,运行 Apache 服务器的用户获取所有经过身份验证的用户的转发 TGT(因为它可以看到所有凭证缓存),而 TGT 的生命周期未过期它可以为这些用户请求任何服务主体。

我知道根据定义,主机在 Kerberos 中被认为是受信任的,但如果我可以限制转发的 TGT 的可用性,我会很高兴。例如,我可以将 Active Directory 设置为将转发的 TGT 限制为仅对请求给定的服务主体有效吗?和/或有没有办法定义转发的 TGT 以使其只能使用一次,即在请求任何服务主体之后变得无效。或者有没有办法让 cgi 脚本检测转发的 TGT 是否被其他人使用(也许检查使用计数器?)。

现在我只有一个解决方案。我可以将转发的 TGT 的生命周期定义为 2 秒,并在 DB 连接建立后在 CGI 脚本中启动 kdestroy(我设置 CGI 脚本可以由 apache-user 执行,但不能修改代码)。我可以多做一点吗?

凭证缓存应该以某种方式隐藏。我认为将凭证缓存定义为 API: 会很好,但这只是为 Windows 定义的。在 Linux 上,可能 KEYRING:process:name 或 MEMORY: 可能是更好的解决方案,因为它是当前进程的本地并且在进程退出时被销毁。据我所知,apache为新连接创建了一个新进程,所以这可能有效。也许 KEYRING:thread:name 是解决方案?但是 - 根据thread-keyring(7) 手册页 - 它不会被克隆继承并被 execve sys 调用清除。所以,如果例如Perl 由 execve 调用,它不会获取凭证缓存。也许使用 mod_perl + KEYRING:thread:name?

任何想法将不胜感激!提前致谢!

【问题讨论】:

    标签: active-directory kerberos


    【解决方案1】:

    简短的回答是,如果客户端碰巧在给定时间点拥有所有必要的位,Kerberos 本身并没有提供任何机制来限制谁可以使用它的范围。一旦你有了一个可用的 TGT,你就有了一个可用的 TGT,并且可以用它做你喜欢的事情。就安全问题而言,这是一个存在根本缺陷的设计。

    Windows 将此称为无约束委派,并且专门通过名为 [MS-SFU] 的 Kerberos 扩展来解决此问题,该扩展更广泛地称为约束委派。

    该协议的要点是,您向服务器 (Apache) 发送一个常规服务票证(没有附加 TGT),并且服务器足够了解它可以将该服务票证交换给自己以换取服务票证到来自 Active Directory 的委派服务器 (DB)。然后,服务器使用新的服务票证向 DB 进行身份验证,尽管由 Apache 发送,但 DB 看到它是 win_usr_a 的服务票证。

    诀窍当然是启蒙。如果不了解 CGI 中身份验证的具体细节,就不可能说您所做的一切是否支持 [MS-SFU]

    【讨论】:

    • 感谢您的帮助!我想我知道 MIT 教程中的 Kerberos 身份验证是如何工作的。我知道MS总是做自己的伎俩。 :) 所以感谢“受限代表团”,我不知道!另一方面,CGI 本身不做任何认证,它由 Apache 的mod_auth_kerb 完成,它设置了REMOTE_USER=win_usr_a@EXAMPLE.COM,CGI 可以使用这个字段。实际上不需要使用它,因为基于转发的TGT,它可以在没有用户名和密码的情况下从数据库中查询(如sqlplus /@DB_ALIAS)。
    • “就安全问题而言,这是一个存在根本缺陷的设计” >> 恕我直言,应用程序开发人员管理缓存的方式存在根本缺陷。尤其是 Microsoft Windows 开发人员,他们确保您没有简单的方法来避免全局 LSA 缓存 (极权主义原则:“所有不被禁止的东西都是强制性的”)
    • 好吗?这与此无关。它不会改变您向远程服务发送秘密的事实,该服务可以冒充您对抗任何其他服务。您必须相信该服务不会对您的票进行任何恶意操作。随着安全性的发展,这是一个糟糕的设计。期间。
    • 具有讽刺意味的是,MSFT 不得不将“有缺陷的协议”改造成 Active Directory……因为没有更好的主意。
    【解决方案2】:

    引用previous answer of mine (针对不同的问题,关注更新缓存时的“竞争条件”)

    如果多个进程独立创建票证,那么它们没有 使用相同凭据缓存的原因。在最坏的情况下,他们会 甚至使用不同的主体,副作用是...... 有趣。

    解决方法:改变各个进程的环境,使KRB5CCNAME 指向一个特定文件——最好是在一个 特定于应用程序的目录。


    如果您专注于保护凭据,请更进一步,不要使用缓存。修改您的客户端应用程序,使其即时创建 TGT 和服务票证并将其保密。

    请注意,Java 从不向 Kerberos 缓存发布任何内容;它可以从缓存中读取或完全绕过它,具体取决于 JAAS 配置。太糟糕了,Kerberos 的 Java 实现是有限的而且相当脆弱,参见。 https://steveloughran.gitbooks.io/kerberos_and_hadoop/content/sections/jdk_versions.htmlhttps://steveloughran.gitbooks.io/kerberos_and_hadoop/content/sections/jaas.html

    【讨论】:

    • 谢谢!正如我所提到的,我计划将凭据缓存放入会话密钥环,但我必须定义一个 CCache 才能使用使用 Kerberos 的数据库功能。所以这不是一个普通文件,而是内核中的内存(甚至没有交换)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多