我有一个 Postfix/Dovecot 设置并使用 OpenLDAP 作为用户/密码后端。由于虚拟主机,用户必须使用完全合格的电子邮件地址作为用户名登录,因此域部分对于身份验证是必需的,即用户名类似于<local-part>@<fqdn-domain>
.
然而,不断有攻击尝试使用不带域部分的用户名进行身份验证。由于这会导致 LDAP 查询中的 DN 无效,因此我的日志中会出现大量由于 LDAP DN 无效而导致的错误消息。
是否有任何配置选项允许 Dovecot 对提供的用户名强制执行一些初始语法检查,如果失败,Dovecot 通过立即拒绝响应来缩短身份验证过程,而不是查询 LDAP 服务器然后失败?
Dovecot 中的 LDAP 配置是
uris = ldapi://%2frun%2fopenldap%2fslapd.sock
auth_bind = yes
auth_bind_userdn = uid=%n,ou=users,o=%d,dc=my-host,dc=my-domain,dc=my-tld
base = ou=users,o=%d,dc=server,dc=my-host,dc=my-domain,dc=my-tld
正如您所看到的,我的 LDAP 设置使用所谓的“连接点”在 DIT 中为不同的托管域提供不同的子分支。(o=%d
DN 中的 - 部分。)根据Dovecot 配置手册 - 用户变量,%d
如果用户名后面没有域部分,则为空@
。
当攻击者尝试使用不完整的用户名进行身份验证时,这会导致我的日志中出现多余的错误消息,例如
Dec 26 16:25:54 server dovecot[24946]: auth: Error: ldap(root,187.205.80.184): ldap_bind() failed: Invalid DN syntax
这里,来自 187.205.80.184 的攻击者尝试以用户身份进行身份验证root
,Dovecot 尝试查找uid=root,ou=users,o=,dc=my-host,dc=my-domain,dc=my-tld
这显然是无效的,因为 后没有任何内容o=
。
从 Dovecot v2.2.33 开始,您可以使用条件设置默认域:
%{if;%d;eq;;example.com;%d}
这是:
if
使用条件句%d
要比较的值 1eq
运算符:字符串相等example.com
如果条件为true
;则结果值 当%d
等于空字符串时(默认)%d
如果条件为false
;则结果值 何时%d
设置(非空)您可以在 LDAP 配置中使用它来代替
%d
:我自己找到了另一个解决方案,它不需要变量中的条件,因此也适用于旧的 Dovecot 版本。在 -variable 的特定情况下,
%d
以下配置指令可以解决问题第一行是支持的身份验证领域的空格分隔列表。根据客户端选择的 SASL 身份验证方法,这会通知客户端有关现有身份验证领域的信息。当然,这并不能阻止(愚蠢的)脚本攻击者仍然使用没有域部分的用户名。然而,正确设置该配置是一种很好的风格。
第二行定义了默认领域(或者在我的例子中为域),如果客户端无法提供,Dovecot 会自动附加该领域。这里我把它设置为虚构的名字
nowhere.notld
。该值并不重要,它应该只与任何实际域不同。最后注意:当然,这并不能阻止有关身份验证尝试失败的日志消息。但那很好。但是,它可以防止由于 DN 无效而导致 LDAP 发生致命错误。相反,Dovevot 会针对失败的身份验证发出适当的警告。