我们的邮件服务器遇到了安全问题,希望得到一些建议。
背后的故事
在我们的邮件服务器(Postfix 2.9.6 + Dovecot 2.1.7)上,我们希望能够创建受限制的电子邮件帐户。这些帐户(由学员使用)将只能向本地域发送/接收电子邮件(出于安全原因,我们不希望他们能够向其他邮件服务器发送或接收电子邮件)。为了简单起见,我们为受限制的电子邮件帐户创建了一个特定的子域。
在我们的基础架构上,所有电子邮件帐户均基于 LDAP,配置文件包含在下面。
我们做了什么
在 Postfix 中,可以在文件中创建限制规则/etc/postfix/main.cf
,因此我们添加了规则:
check_sender_access ldap:/etc/postfix/ldap_restricted_senders.cf
check_recipient_access ldap:/etc/postfix/ldap_restricted_recipients.cf
至章节:
smtpd_recipient_restrictions
当然,还添加了以下几行:
smtpd_restriction_classes =
local_only,
insiders_only
local_only = check_recipient_access ldap:/etc/postfix/ldap_virtual_domains_restrict.cf, reject
insiders_only = check_sender_access ldap:/etc/postfix/ldap_virtual_domains_restrict.cf, reject
的内容/etc/postfix/ldap_restricted_senders.cf
是:
bind = yes
bind_dn = uid=postfix,ou=service,dc=example,dc=com
bind_pw = *******
server_host = ldap://127.0.0.1:389
search_base = ou=domain,dc=example,dc=com
query_filter = (&(ObjectClass=DNSDomain)(dc=%s))
result_attribute = description
当允许该域向外发送电子邮件时,这将返回“ok”。
的内容/etc/postfix/ldap_restricted_recipients.cf
是:
bind = yes
bind_dn = uid=postfix,ou=service,dc=example,dc=com
bind_pw = ******
server_host = ldap://127.0.0.1:389
search_base = ou=domain,dc=example,dc=com
query_filter = (&(description=local_only)(dc=%s))
result_attribute = description
result_filter = insiders_only
当只有本地域可以访问该域时,这将返回“insiders_only”。
的内容/etc/postfix/ldap_virtual_domains_restrict.cf
是:
bind = yes
bind_dn = uid=postfix,ou=service,dc=example,dc=com
bind_pw = ******
server_host = ldap://127.0.0.1:389
search_base = ou=domain,dc=example,dc=com
query_filter = (&(ObjectClass=dNSDomain)(dc=%s))
result_attribute = dc
result_filter = OK
当域是本地域时(可以向受限子域发送电子邮件),这将返回“ok”。
为了更加精确,后缀smtpd_recipient_restrictions
部分包含:
smtpd_recipient_restrictions =
permit_mynetworks,
reject_sender_login_mismatch
check_sender_access ldap:/etc/postfix/ldap_restricted_senders.cf
check_recipient_access ldap:/etc/postfix/ldap_restricted_recipients.cf
permit_sasl_authenticated,
reject_non_fqdn_hostname,
reject_non_fqdn_sender,
reject_non_fqdn_recipient,
reject_unauth_destination,
reject_unauth_pipelining,
reject_invalid_hostname,
check_policy_service unix:private/policy-spf
从某种意义上说,这很有效,因为来自子域的所有电子邮件只能向其他本地域发送电子邮件,并且只能接收来自本地域的电子邮件。
但...
自从我们启用此功能后,我们注意到人们可以使用邮件服务器发送垃圾邮件(因此我们暂时将其删除)。
我们注意到了这个问题,因为日志文件/var/log/mail.log
包含如下行:
Jul 22 11:59:24 mail postfix/qmgr[366]: F342F42AE4: from=<[email protected]>, size=2171, nrcpt=11 (queue active)
Jul 22 11:59:24 mail postfix/smtp[382]: 1344D42ACC: to=<iraci@*******>, relay=127.0.0.1[127.0.0.1]:10024, delay=1197348, delays=1197334/12/0.17/2.2, dsn=2.0.0, status=sent (250 2.0.0 from MTA(smtp:[127.0.0.1]:10025): 250 2.0.0 Ok: queued as F342F42AE4)
Jul 22 11:59:24 mail postfix/smtp[382]: 1344D42ACC: to=<hugocesar_007@*******>, relay=127.0.0.1[127.0.0.1]:10024, delay=1197348, delays=1197334/12/0.17/2.2, dsn=2.0.0, status=sent (250 2.0.0 from MTA(smtp:[127.0.0.1]:10025): 250 2.0.0 Ok: queued as F342F42AE4)
Jul 22 11:59:24 mail postfix/smtp[382]: 1344D42ACC: to=<reginadanielian@*******>, relay=127.0.0.1[127.0.0.1]:10024, delay=1197348, delays=1197334/12/0.17/2.2, dsn=2.0.0, status=sent (250 2.0.0 from MTA(smtp:[127.0.0.1]:10025): 250 2.0.0 Ok: queued as F342F42AE4)
Jul 22 11:59:24 mail postfix/smtp[382]: 1344D42ACC: to=<thais_jp@*******>, relay=127.0.0.1[127.0.0.1]:10024, delay=1197348, delays=1197334/12/0.17/2.2, dsn=2.0.0, status=sent (250 2.0.0 from MTA(smtp:[127.0.0.1]:10025): 250 2.0.0 Ok: queued as F342F42AE4)
Jul 22 11:59:24 mail postfix/smtp[382]: 1344D42ACC: to=<tropicalfmcomerciais@*******>, relay=127.0.0.1[127.0.0.1]:10024, delay=1197348, delays=1197334/12/0.17/2.2, dsn=2.0.0, status=sent (250 2.0.0 from MTA(smtp:[127.0.0.1]:10025): 250 2.0.0 Ok: queued as F342F42AE4)
Jul 22 11:59:24 mail postfix/smtp[382]: 1344D42ACC: to=<valeria.x@*******>, relay=127.0.0.1[127.0.0.1]:10024, delay=1197348, delays=1197334/12/0.17/2.2, dsn=2.0.0, status=sent (250 2.0.0 from MTA(smtp:[127.0.0.1]:10025): 250 2.0.0 Ok: queued as F342F42AE4)
Jul 22 11:59:24 mail postfix/smtp[382]: 1344D42ACC: to=<veloso1071@*******>, relay=127.0.0.1[127.0.0.1]:10024, delay=1197348, delays=1197334/12/0.17/2.2, dsn=2.0.0, status=sent (250 2.0.0 from MTA(smtp:[127.0.0.1]:10025): 250 2.0.0 Ok: queued as F342F42AE4)
Jul 22 11:59:24 mail postfix/smtp[382]: 1344D42ACC: to=<termopiso@*******>, relay=127.0.0.1[127.0.0.1]:10024, delay=1197348, delays=1197334/12/0.17/2.2, dsn=2.0.0, status=sent (250 2.0.0 from MTA(smtp:[127.0.0.1]:10025): 250 2.0.0 Ok: queued as F342F42AE4)
Jul 22 11:59:24 mail postfix/smtp[382]: 1344D42ACC: to=<rafaelpm84@*******>, relay=127.0.0.1[127.0.0.1]:10024, delay=1197348, delays=1197334/12/0.17/2.2, dsn=2.0.0, status=sent (250 2.0.0 from MTA(smtp:[127.0.0.1]:10025): 250 2.0.0 Ok: queued as F342F42AE4)
Jul 22 11:59:24 mail postfix/smtp[382]: 1344D42ACC: to=<vanessyca@*******>, relay=127.0.0.1[127.0.0.1]:10024, delay=1197348, delays=1197334/12/0.17/2.2, dsn=2.0.0, status=sent (250 2.0.0 from MTA(smtp:[127.0.0.1]:10025): 250 2.0.0 Ok: queued as F342F42AE4)
Jul 22 11:59:24 mail postfix/qmgr[366]: 1344D42ACC: removed
我们的假设
由于我们设置的限制仅与域(对于发件人)匹配,因此有人使用我们的服务器作为中继,并伪造发件人以匹配[电子邮件保护]并会被接受。
我们将更改设置以使规则匹配整个电子邮件,但我们不确定它是否能防止欺骗。
您对此有何看法?我们做错了什么吗?还有其他方法(或功能)可以实现这样的限制吗?
附言:如有需要,我们可以发布更多信息
答案1
由于我们设置的限制仅与域(对于发件人)匹配,因此有人使用我们的服务器作为中继,并伪造发件人以匹配[电子邮件保护]并会被接受。
是的,这是由于此限制造成的smtpd_recipient_restrictions
check_sender_access ldap:/etc/postfix/ldap_restricted_senders.cf
您上面说过,当发件人允许发送外发电子邮件时,此查询将返回“OK”。这意味着 postfix 将允许该电子邮件并绕过其下面的限制
check_recipient_access ldap:/etc/postfix/ldap_restricted_recipients.cf
permit_sasl_authenticated,
reject_non_fqdn_hostname,
reject_non_fqdn_sender,
reject_non_fqdn_recipient,
reject_unauth_destination,
reject_unauth_pipelining,
reject_invalid_hostname,
check_policy_service unix:private/policy-spf
也许解决方案是将“OK”查询结果替换为“DUNNO”。这两个参数之间的区别是,
- 当 OK 时,postfix 终止限制检查列表
- 当不知道时,postfix 将转到下一个限制检查列表
也可以看看man 5 访问。
好的 接受与模式匹配的地址等。
不知道 假装未找到查找键。这可防止 Postfix 尝试查找键的子字符串(例如子域名或网络地址子网)。
Postfix 2.0 及更高版本中提供此功能。
答案2
对于有兴趣实施类似限制的人:
仅当创建额外文件时此方法才有效,例如/etc/postfix/ldap_virtual_domains_restrict_access.cf
包含以下内容
bind = yes
bind_dn = uid=postfix,ou=service,dc=example,dc=com
bind_pw = xxxxxx
server_host = ldap://127.0.0.1:389
search_base = ou=domain,dc=example,dc=com
query_filter = (&(ObjectClass=dNSDomain)(dc=%s))
result_attribute = dc
result_filter = dunno
result_format = OK
然后,在文件中将/etc/postfix/main.cf
行更改为:
local_only = check_recipient_access ldap:/etc/postfix/ldap_virtual_domains_restrict_access.cf, reject
insiders_only = check_sender_access ldap:/etc/postfix/ldap_virtual_domains_restrict_access.cf, reject
这样,请求功能就可以正常工作了!否则,当匹配“local_only”或“insiders_only”时,如果 ldap 查询的结果为“DUNNO”,则发件人或收件人将被拒绝(因为请求后的下一条规则是“拒绝”)。
当result_format = OK
结果为“DUNNO”时,ldap 请求的结果为“OK”。
希望这对其他人有帮助
答案3
相关/etc/postfix/main.cf
限制似乎也只适用于:
smtpd_sender_restrictions =
check_sender_access ldap:/etc/postfix/ldap_restricted_senders.cf, reject
我的ldap_restricted_senders.cf
例子:
bind = yes
bind_dn = cn=admin,dc=example,dc=com
bind_pw = mySecretPass
server_host = ldap://localhost/
search_base = dc=example,dc=com
query_filter = (&(&(objectClass=VirtualMailAccount)(mail=%s))(accountActive=TRUE)(delete=FALSE)(smtpAuth=TRUE))
result_attribute = smtpAuth
result_filter = TRUE
result_format = OK