RoundCube 登录本地 IMAP 服务器失败

RoundCube 登录本地 IMAP 服务器失败

我一直按照本指南在我的服务器上设置邮件服务器:http://flurdy.com/docs/postfix/edition5.html 唯一的区别是本教程使用 MySQL 数据库而我使用的是 PostgreSQL。

但我无法登录 RoundCube。这是我在 RoundCube 错误日志中收到的消息:

[31-Dec-2013 16:40:42 +0100]: IMAP Error: Login failed for [email protected] from A.B.C.D. AUTHENTICATE CRAM-MD5: A0001 NO Login failed. in /usr/share/roundcube/program/lib/Roundcube/rcube_imap.php on line 184 (POST /?_task=login&_action=login)

这是来自 IMAP 日志的内容:

[31-Dec-2013 16:40:37 +0100]: [CB8A] S: * OK [CAPABILITY IMAP4rev1 UIDPLUS CHILDREN NAMESPACE THREAD=ORDEREDSUBJECT THREAD=REFERENCES SORT QUOTA AUTH=CRAM-MD5 AUTH=CRAM-SHA1 IDLE AUTH=PLAIN ACL ACL2=UNION] Courier-IMAP ready. Copyright 1998-2011 Double Precision, Inc.  See COPYING for distribution information.
[31-Dec-2013 16:40:37 +0100]: [CB8A] C: A0001 AUTHENTICATE CRAM-MD5
[31-Dec-2013 16:40:37 +0100]: [CB8A] S: + PDIxNUFCQjFGRjJBNTi1RUJEMTIzMjFEMDAwNDIxMTUzQGxpbm9kZT4=
[31-Dec-2013 16:40:37 +0100]: [CB8A] C: bWFya29Adm9kYW5vdmljLm5ldCBmMzk2njk0OTRiMTA1Mjc2YjllYWIxODhhZDI2OWM3NA==
[31-Dec-2013 16:40:42 +0100]: [CB8A] S: A0001 NO Login failed.

我在 Postgres 的数据库表中有一个用户。他在这里:

<?xml version="1.0" encoding="utf-8" ?>
<data>
    <header>
        <column name="id" type="varchar" />
        <column name="name" type="varchar" />
        <column name="uid" type="int4" />
        <column name="gid" type="int4" />
        <column name="home" type="varchar" />
        <column name="maildir" type="varchar" />
        <column name="enabled" type="bool" />
        <column name="change_password" type="bool" />
        <column name="clear" type="varchar" />
        <column name="crypt" type="varchar" />
        <column name="quota" type="varchar" />
        <column name="procmailrc" type="varchar" />
        <column name="spamassassinrc" type="varchar" />
    </header>
    <records>
        <row>
            <column name="id">[email protected]</column>
            <column name="name">test</column>
            <column name="uid">5000</column>
            <column name="gid">5000</column>
            <column name="home">/var/spool/mail/virtual</column>
            <column name="maildir">test/</column>
            <column name="enabled">t</column>
            <column name="change_password">t</column>
            <column name="clear">aaaa</column>
            <column name="crypt">$5$c74a6630fAb058a5$Zo95c7qWT.o/Twg4niR/gcNoVq2XVVPl0aw6DoS8ufA</column>
            <column name="quota"></column>
            <column name="procmailrc"></column>
            <column name="spamassassinrc"></column>
        </row>
    </records>
</data>

我尝试使用test[email protected]以及纯aaaa密码和加密密码登录。为了安全起见,我还在 MySQL 中生成了密码(使用指南中的表达式),然后将结果复制到 Postgres 中的字段中。是的,MySQL 和 Postgres 在同一台服务器上。这是我在 MySQL 中使用的表达式:

select encrypt('password', CONCAT('$5$', MD5(RAND())));

我真的不知道还能做什么,所以任何帮助我都会很感激。如果您需要更多信息,请直接说。

编辑:

我已设法通过 telnet 登录到服务器(当我修复了丢失邮件目录的问题时)。但我仍然无法连接 RoundCube。以下是 mail.log 的输出:

Dec 31 20:14:45 localhost imapd-ssl: Connection, ip=[::ffff:127.0.0.1]
Dec 31 20:14:45 localhost authdaemond: received auth request, service=imap, authtype=cram-md5
Dec 31 20:14:45 localhost authdaemond: authpgsql: trying this module
Dec 31 20:14:45 localhost authdaemond: cram: challenge=PDk1N0QxRTI3QTlFREy3MkYwODI3RUE2MDVDREREMTdBQGxpbm9kZT4=, response=bWFya28gY2Q5OTRmNDI2ZtY3NDUzZGM2YmJlYjhmNTI0ZWQ3NWI=
Dec 31 20:14:45 localhost authdaemond: cram: decoded challenge/response, username 'test'
Dec 31 20:14:45 localhost authdaemond: Install of a character set for Postgresql: UTF8
Dec 31 20:14:45 localhost authdaemond: SQL query: SELECT id, crypt, '', uid, gid, home, concat(home,'/',maildir), '', name, '' FROM users WHERE id = '[email protected]'  AND (enabled=TRUE)
Dec 31 20:14:45 localhost authdaemond: authpgsql: REJECT - try next module
Dec 31 20:14:45 localhost authdaemond: FAIL, all modules rejected
Dec 31 20:14:45 localhost imapd-ssl: LOGIN FAILED, method=CRAM-MD5, ip=[::ffff:127.0.0.1]
Dec 31 20:14:50 localhost imapd-ssl: Disconnected, ip=[::ffff:127.0.0.1], time=5, starttls=1

答案1

面对同样的问题,我使用 Google-Foo 进行了一些搜索,以找到问题的根源:加布里埃尔假定正确在他的回答中,这不是 Roundcube 的错误 – 而是密码存储方式和加密工作方式的错误。

一些显而易见的基本原则

当谈论 CRAM-MD5、MD5 或 CRYPT 时,我们谈论的是单向加密:生成哈希值。我们无法反过来做,从哈希值中导出明文密码(除了暴力破解)是不可能的,而且对于任何登录程序来说都不现实。因此,使用其中一个哈希值存储密码时,我们只能在纯文本的情况下验证它 - 这就是为什么$rcmail_config['imap_auth_type'] = 'PLAIN'在 roundcube 配置中进行设置可以“解决”这个问题。

选项

  1. 坚持使用 PLAIN/LOGIN:
    • 只要用户使用 HTTPS 连接,同一台服务器上的 Roundcube 和 IMAP 就可以正常工作
    • 只要连接是安全的(IMAPS/POP3S/SMTPS),就可以从邮件客户端访问
    • 未加密流量的安全漏洞
  2. 以纯文本形式存储密码
    • 可以使用各种身份验证机制,这是一个优点
    • 将所有用户的密码以纯文本形式保存在文件/数据库中是绝对不行的
  3. 使用 CRAM-MD5 存储密码
    • 至少为您提供 CRAM-MD5,大多数客户端都支持该功能
    • 仍然可以选择使用 PLAIN/LOGIN
    • 必须得到管理工具的支持
      • 有些可能需要恢复使用第三方工具进行加密(例如 PostfixAdmin 使用/usr/sbin/doveadm pw),这使得每次调用时,明文密码都会短暂地出现在进程列表中
    • 其他第三方工具(插件/附加组件等)可能会有问题

我仍在纠结该走哪条路 — — 只有 #2 肯定被排除(我不想给潜在的黑客送礼物 ;)

答案2

我认为,问题是尝试使用来自 DB 的带有“crypt”字段的 CRAM-MD5 身份验证机制。

在您的日志中:

Dec 31 20:14:45 localhost authdaemond: SQL query: SELECT id, **crypt**, '', uid, gid, home, concat(home,'/',maildir), '', name, '' FROM users WHERE id = '[email protected]'  AND (enabled=TRUE)
Dec 31 20:14:45 localhost authdaemond: authpgsql: REJECT - try next module
Dec 31 20:14:45 localhost authdaemond: FAIL, all modules rejected
Dec 31 20:14:45 localhost imapd-ssl: LOGIN FAILED, **method=CRAM-MD5**, ip=[::ffff:127.0.0.1]

这意味着,在 SQL 查询中,如果您获得“crypt”字段,authdaemond 无法读取明文密码,那么 CRAM-MD5 就不起作用。明文密码允许实施 CRAM-MD5 身份验证。

修理:

  1. 您可以将客户端(roundcube)的身份验证机制更改为 PLAIN 或 LOGIN。这与 crypt 字段兼容。
  2. 在 authpgsqlrc 文件中进行更改。设置 PGSQL_CLEAR_PWFIELD 以查找“clear”字段并注释 PGSQL_CRYPT_PWFIELD。因此 authdaemond 将执行 sql 查询以查找明文密码。

我希望这对你有用。

答案3

可能是roundcube的配置:

我不是 100% 确定,但 roundcube 的默认配置使用“PLAIN”身份验证,因此您可以在配置文件中更改它并进行测试:

// IMAP AUTH type (DIGEST-MD5, CRAM-MD5, LOGIN, PLAIN or null to use
// best server supported one)
// $rcmail_config['imap_auth_type'] = LOGIN;
$rcmail_config['imap_auth_type'] = null;

在旧版本(0.3.1)的 roundcube 中您只有“auth”、“plain”或“check”,如下所示:

// IMAP auth type. Can be "auth" (CRAM-MD5), "plain" (PLAIN) or "check" to auto detect.
// Optional, defaults to "check"
$rcmail_config['imap_auth_type'] = "auth";

取决于您使用的版本。

相关内容