Samba 的加密密码支持

作者:John Blair

默认情况下,Samba 使用明文密码来验证访问网络资源的客户端。Samba 也支持使用 LanManager 和 NT 加密密码认证。在 Samba 中使用加密密码既有优点也有缺点。从积极的方面来看,加密密码意味着当用户登录 Samba 共享时,明文密码不会被“嗅探”到网络上。当用户通过公共广域网(如 Internet)连接到 Samba 服务器时,这一点尤为重要。此外,Windows 95 和 Windows NT 的最新服务包不允许在连接到 SMB 服务器时使用明文认证。当使用最新版本的 Windows 时,要么必须将 Samba 配置为使用加密密码,要么必须编辑注册表以启用明文密码。

从消极的方面来看,使用加密密码需要一些额外的管理工作。SMB 加密密码算法与标准的 UNIX 加密方法不兼容。因此,必须创建一个包含每个用户的 LanManager 和 NT 密码哈希值的第二个密码文件。如果有人使用服务器上的其他服务,则必须使用一种技术来保持两个密码文件同步。

自 Samba 1.9.18 版本起,不使用加密密码认证的最佳理由已被消除。早期版本的 Samba 使用数据加密标准 (DES) 库来计算 LanManager 密码哈希值。因为它链接到 DES 库,编译后的 Samba 版本在美国出口是非法的。像 DES 这样的强加密仍然被美国法律视为军需品。为了方便 Samba FTP 存档在美国境内的镜像站点分发 Samba,预编译的 Samba 二进制文件通常不包含对加密密码的支持。从 1.9.18 版本开始,Samba 使用了一个弱化版的 DES,它仍然适用于计算 LanManager 哈希值,但在美国出口是合法的。

由于 Windows NT 和 Windows 95 的最新服务包禁用了连接到共享的能力,因此将 Samba 设置为处理加密密码变得更加理想。虽然可以编辑所有机器上的注册表以重新启用明文密码的使用,但配置 Samba 以使用加密密码可能更容易。

SMB 密码哈希值

SMB 加密密码认证有两种风格:LanManager 和 Windows NT。这两种技术都使用一个文件,该文件包含用户密码的哈希值,而不是明文密码,就像标准的 UNIX 认证方法一样。但是,每种技术都使用自己的方法来生成此哈希值。

LanManager 风格的哈希值使用以下算法生成

  1. 将用户输入的密码转换为全部大写。

  2. 如果结果密码超过 14 个字符,则截断为 14 个字符;如果短于 14 个字符,则用空字节填充。

  3. 使用此 14 字节值作为两个 56 位 DES 密钥,对一个 8 字节的秘密值加密两次,创建一个 16 字节的值。此值是存储在密码文件中的哈希密码。这个秘密值是一个由字符 KGS!@#$% 组成的字符串。

不幸的是,此算法存在严重的弱点。首先,密码在哈希之前转换为全部大写。这会将密码中可能的字符数从 95 减少到 69。但是,由于大多数标点符号也被拒绝,因此可能的字符数更接近 40。这会将密钥空间的实际大小从 9514 减少到大约 4014。此外,密码的每一半都是独立加密的。这意味着可以恢复密码的任何一半,而无需恢复另一半。更好的方法是将两次加密“链接”在一起,即将第一次加密的输出馈送到第二次加密中。这种技术称为密码块链接 (cipher block chaining)。整个 16 字节哈希密码的可能密钥空间为 2128,或 3.4 x 1038。不使用密码块链接会将可能的哈希密码数量从该值减少到 2(40*7) 或 3.2 x 1011

因此,可以使用暴力破解在相当短的时间内破解 LanManager 密码。L0pht Heavy Industries (http://www.l0pht.com/) 的 L0phtcrack 已被证明可以在四核 Pentium Pro 200 SMP 机器上在 62 小时内耗尽密钥空间。由于即使是偏执的用户也极少每几周更频繁地更改密码,因此系统容易受到拥有更传统硬件的系统破解者的攻击。

相比之下,Windows NT 哈希算法要强大得多。NT 哈希算法包括计算用户密码的 Unicode 版本的 128 位 MD4 哈希值。由于密码未被截断,并且可以使用整个 Unicode 字符集,因此该技术利用了整个 128 位密钥空间。不幸的是,为了向后兼容性,几乎所有 SMB 服务器都允许使用任一种哈希技术进行访问。这意味着像 Samba 这样的 SMB 服务器必须在其密码数据库中存储两种哈希值。因此,至少在可预见的将来,NT 算法更强大这一点并不重要。

SMB 加密认证的过程

无论使用 LanManager 还是 NT 加密,SMB 加密认证的过程都是相同的。当客户端在协议协商阶段表明它可以支持加密密码认证时,服务器将使用一个随机的 8 字节值(称为挑战)进行响应。对于每个客户端请求,挑战都不同。服务器存储挑战,直到客户端通过身份验证或被拒绝访问。

客户端从用户获取密码后,它会使用先前定义的算法之一计算哈希值。生成的 16 字节值附加 5 个空字节。此 21 字节值用作三个 56 位 DES 密钥,以加密 8 字节的挑战值三次。生成的 24 字节值称为响应。

服务器也执行相同的算法,使用存储的哈希密码。如果服务器计算的值与客户端返回的值匹配,则客户端必须知道密码,或者至少知道从密码生成的 16 字节哈希值。因此,将授予作为已验证用户的访问权限。否则,访问将被拒绝。在任何一种情况下,明文密码都不会通过网络传输,从而可以被窃听者嗅探。

但是,使用此技术存在一个问题。与 UNIX 密码哈希不同,SMB 密码哈希等同于密码。这意味着即使它不是明文,但也可能等同于明文。身份验证客户端有责任接受明文密码并生成哈希值,然后再使用它来加密来自服务器的挑战。不幸的是,可以编写一个自定义客户端,它不是从明文密码生成密码哈希值,而是简单地接受密码哈希值并使用它来生成对服务器的适当响应。smbclient,Samba 套件的一个组件,可以被修改以完成此任务。总而言之,即使可以在相当短的时间内破解 LanManager 密码,但如果您已经知道密码哈希值,则实际上没有必要获取对共享的访问权限。底线是 Samba 加密密码文件和 NT 安全帐户管理器 (SAM) 都包含敏感信息。不要因为它是“加密的”就认为您不必保护它免受窥探者的侵害。

在 Samba 中使用加密密码

配置 Samba 以使用加密密码很容易——只需将此设置包含在配置文件的全局部分中

encrypt passwords = yes

加密密码适用于所有三个安全级别:共享、用户和服务器。将安全选项设置为 usershare 要求 Samba 加密密码文件存在。如果安全级别设置为 server,则无需进一步配置,因为所有身份验证请求都将传递到不同的 SMB 服务器。服务器安全选项提供了一种将 Samba 服务器集成到现有 NT 域中的简便方法。但是,大多数 Samba 安装将使用用户或共享级别的安全性。最常见的配置是这样的

security = user
encrypt passwords = yes
共享和用户模式都需要 smbpasswd 文件,该文件包含将要访问 Samba 服务器的每个用户的 LanManager 和 NT 密码哈希值。

Samba 加密密码文件 smbpasswd 默认存储在 /usr/local/samba/private 中。此目录通常由 root 拥有,其权限设置为 500,以便只有 root 可以查看其内容。但是,此配置并非严格要求——您的 smbpasswd 文件可以存储在您希望的任何位置。Samba Red Hat 包将 smbpasswd 文件存储在 /etc/smbpasswd 这个合理的位置。无论 smbpasswd 文件存储在哪里,其权限都应设置为 600(仅用户读写),并且必须由 root 拥有。除了 root 之外,任何用户都不能读取此文件。

可以通过多种方式将用户添加到 smbpasswd 文件。最好的方法是使用 smbpasswd -add 命令。例如,

smbpasswd -add jdblair foobar

将为 jdblair 添加一个条目,密码为 foobar。在 Samba 服务器运行时添加用户时,必须使用此命令以确保在修改 smbpasswd 文件之前正确锁定它。

创建新 smbpasswd 文件的另一种方法是使用 Samba 附带的 mksmbpasswd.sh 脚本。奇怪的是,此脚本存储在 Samba 发行版的 /source 子目录中。例如

cat /etc/passwd | mksmbpasswd.sh > \
        /usr/local/samba/private/smbpasswd

如果系统使用 NIS,则应使用此命令

ypcat passwd | mksmbpasswd.sh > \
        /usr/local/samba/private/smbpasswd
使用 mksmbpasswd.sh 脚本后,手动编辑文件以删除 root、bin 和 daemon,以确保安全。

最后,为了允许用户更新其加密密码,请按如下所示将 smbpasswd 的权限设置为 setuid root

chmod u+s /usr/local/samba/bin/smbpasswd

最后需要注意的问题是保持 smbpasswd 文件与默认 UNIX 身份验证方法同步。如果用户仅通过 Samba 服务器访问 UNIX 机器,则这不是问题。但是,大多数系统还允许用户访问 shell 帐户、pop 服务器或其他将使用默认 UNIX 密码文件进行身份验证的服务。许多技术可以帮助保持这两个文件同步。有一个 passwd 命令的破解版本可用,它将同时更新这两个文件。许多人使用 expect 脚本来更新用户密码,在提示用户输入新密码后,输入 passwd 和 smbpasswd 命令。据报道,一个 PAM 模块正在开发中,以几乎透明地处理更新,并且可能会在本文印刷时可用。在 Samba 邮件列表 (samba@samba.anu.edu.au) 上询问其他人提出的解决此问题的方案可以节省大量时间。

总结思考

尽管对与 SMB 加密密码相关的问题进行了冗长的解释,但使用它们仍然是一个好主意。即使是稍微不成熟的加密密码算法也优于通过网络传输明文密码。保持 smbpasswd 文件的安全并确保用户不选择容易猜测的密码将有助于最大限度地降低风险。

Samba's Encrypted Password Support
John Blair 目前在 Cobalt Microserver 担任软件工程师。当他不破解 Cobalt 可爱的蓝色 Qube 时,他会与妻子 Rachel 和新生儿子 Ethan 一起度过时光。John 也是 SSC 出版的《Samba: Integrating UNIX and Windows》的作者。欢迎通过 jdblair@cobaltmicro.com 与他联系。
加载 Disqus 评论