分类 电脑 下的文章

iredmail - 注册页 - register - 简单制作

需求:有一个简单的 web 表单,让未登录的访客 注册 邮箱
思路:iredadmin 里,有 Create 的类,照它样子,复制出一个 Register 类来;同样,模仿着添加好 web 访问的路径 和 html 表单

环境:debian 12 里安装好的 iredmail - 1.7.1 SQL 版本

请注意,我不会 Python ,这是我在 Poe GPT 帮助下,简单制作的,仅用于测试。

步骤:

文件内容:iRedAdmin-2.6/controllers/sql/urls.py 中,添加 访问路径 :

'/register', 'controllers.sql.basic.Register',

文件内容:iRedAdmin-2.6/controllers/sql/basic.py 中,添加 Register 的类 :

from libs import iredpwd
from libs.sqllib import general as sql_lib_general
class Register:
    def GET(self):
        available_domains = ['iredmail.demo.anqun.org', 'imap.demo.2xinxian.top', 'example.net']  # 示例域名列表
        form = web.input()
        return web.render(
            'register.html',
            available_domains=available_domains,
            msg=form.get('msg'),
        )

    def POST(self):
        form = web.input()

        domain = form.get('domainName', '').strip().lower()
        username = form.get('username', '').strip().lower()
        newpw = form.get('newpw', '').strip()
        confirmpw = form.get('confirmpw', '').strip()
        cn = form.get('cn', '').strip()  # 获取可选的显示名称

        if not username or not newpw or not confirmpw or not domain:
            return web.seeother(f'/register?msg=INVALID_INPUT')

        if newpw != confirmpw:
            return web.seeother(f'/register?msg=PASSWORDS_DO_NOT_MATCH')

        # 生成密码哈希
        pwscheme = 'SSHA512'
        passwd_hash = iredpwd.generate_password_hash(newpw, pwscheme=pwscheme)

        result = self.add_user(domain, username, passwd_hash, cn)  # 将 cn 传递给 add_user

        if result[0]:
            return web.seeother(f'/register?msg=CREATED')
        else:
            return web.seeother(f'/register?msg={web.urlquote(result[1])}')

    def add_user(self, domain, username, password, cn):
        mail = f"{username}@{domain}"

        if sql_lib_general.is_email_exists(mail):
            return (False, 'ALREADY_EXISTS')

        record = {
            'domain': domain,
            'username': mail,
            'password': password,
            'active': 1,
            'name': cn
        }

        try:
            _wrap = SQLWrap()
            conn = _wrap.conn
            conn.insert('mailbox', **record)
            return (True, )
        except Exception as e:
            return (False, repr(e))

创建模板文件 iRedAdmin-2.6/templates/default/register.html

{% extends "layout.html" %}

{% block title %}{{ _('Add mail user') }}{% endblock title %}
{% block navlinks_create %}class="active"{% endblock %}

{% block main %}
{# Show system message #}
{% if msg %}
    {% if msg.startswith('PW_') %}
        {% set _pw_errors = msg.split(',') %}
        {% for _err in _pw_errors %}
            {{ user_msg_handler(_err) }}
        {% endfor %}
    {% else %}
    {#        {{ user_msg_handler(msg) }} #}
        <p>{{ msg }}</p>
    {% endif %}
{% endif %}

    <div class="content-box">
        <div class="box-body">
            <div class="box-header clear">
                <ul class="tabs clear">
                    <li class="active"><a href="#user_add"><i class="fa fa-plus"></i> {{ _('User') }}</a>
                </ul>

                <h2>{{ _('Add mail user') }}</h2>
            </div>

            <div id="user_add" class="box-wrap clear">
                <form name="form_add_user" method="post" action="{{ctx.homepath}}/register">
                    <div class="form-field clear">
                        <h4 class="size-250 fl-space">{{ _('Mail Domain') }} <span class="required">*</span></h4>
                        <span class="clean-padding">
                            <select name="domainName" id="domainSelect" required>
                                {% for domain in available_domains %}
                                    <option value="{{ domain }}">{{ domain }}</option>
                                {% endfor %}
                            </select>
                        </span>
                    </div>
                
                    <div class="form-field clear">
                        <h4 class="size-250 fl-space">{{ _('Mail Address') }} <span class="required">*</span></h4>
                        <span class="clean-padding">
                            <input type="text" size="35" name="username" value="" autocomplete="off" class="text fl-space" required />@
                        </span>
                    </div>
                
                    <div class="form-field clear">
                        <h4 class="size-250 fl-space">{{ _('Password') }} <span class="required">*</span></h4>
                        <span class="clean-padding">
                            <input type="password" name="newpw" required class="text fl-space" />
                        </span>
                    </div>
                    
                    <div class="form-field clear">
                        <h4 class="size-250 fl-space">{{ _('Confirm Password') }} <span class="required">*</span></h4>
                        <span class="clean-padding">
                            <input type="password" name="confirmpw" required class="text fl-space" />
                        </span>
                    </div>

                    <div class="form-field clear">
                        <h4 class="size-250 fl-space">{{ _('Display Name (Optional)') }}</h4>
                        <span class="clean-padding">
                            <input type="text" name="cn" value="" autocomplete="off" class="text fl-space" />
                        </span>
                    </div>                    
                
                    <div class="form-field clear">
                        <span>
                            <input type="submit" name="submit_add_user" value="{{ _('Add') }}" class="button green"/>
                        </span>
                    </div>
                </form>
            </div>{# -- End box-wrap -- #}
        </div>{# -- End content-box -- #}
    </div>{# -- End box-body -- #}
{% endblock main %}

iredmail 自定义注册页 表单

iredmail 自助注册邮箱成功

iredmail 自助注册的邮箱,成功登录到 Webmail

参考:

mailcow - 554.5.7.1 this message does not meet our delivery requirements - rspamd - aliyun.com - 白名单

问题:从 example@aliyun.com 发往 mailcow 邮局,被打回了。提示:554.5.7.1 this message does not meet our delivery requirements in replay to end of data command

步骤:登录到 mailcow 管理 web 界面,查看 rspamd 的 “日志” 。可以看到发自 example@aliyun.com 的邮件被邮局拒收(reject)了。点击查看详细,在各项扣分中,如 FREEMAIL_POLICY_FAILURE (16) 这一项就被扣了 16 分?相比较,从 example@qq.com 发过来的,没有这个扣分项。难道 aliyun.com 或由 阿里云 托管的邮局 不如 qq.com 的“知名”?

FREEMAIL_POLICY_FAILURE (16)
DMARC_POLICY_QUARANTINE (8) [aliyun.com : SPF not aligned (relaxed), No valid DKIM, quarantine]
FORGED_W_BAD_POLICY (3)
TO_EXCESS_BASE64 (1.5)
MV_CASE (0.5)
CTE_CASE (0.5)
ONCE_RECEIVED (0.2)
MIME_BASE64_TEXT (0.1)
RWL_MAILSPIKE_VERYGOOD (-0.2) [54.207.22.56:from]
R_SPF_ALLOW (-0.2) [+ip4:54.207.22.56]
MIME_GOOD (-0.1) [multipart/alternative, text/plain]
MX_GOOD (-0.01) []

尝试:将 aliyun.com 添加到全局的 header-from 白名单中。再次测试,能正常收到邮件了。

在 iredmail 1.7.1 - roundcube 1.6.8 里安装 kolab_2fa 3.5.11 插件

环境和已下载的文件,请看上一篇。继续安装插件 kolab_2fa 。

步骤:

  1. cd /opt/www/roundcubemail/plugins/ # 转到 roundcube 插件目录
  2. cp -a /opt/www/roundcubemail-plugins-kolab/plugins/kolab_2fa ./ # 复制 tasklist 插件文件
  3. cp kolab_2fa/config.inc.php.dist kolab_2fa/config.inc.php # 创建配置文件
  4. vi kolab_2fa/config.inc.php # 创建配置文件
  5. cd /opt/www/roundcubemail # 转到 roundcube 目录
  6. sudo -u www-data php /opt/www/composer.phar require "spomky-labs/otphp" "~10.0.3" # 安装 otphp
  7. sudo -u www-data php /opt/www/composer.phar require "endroid/qr-code" "~1.6.5" # 安装 qr-code
  8. sudo -u www-data php /opt/www/composer.phar require "enygma/yubikey" "~3.2" # 安装 yubikey
  9. vi /opt/www/roundcubemail/config/config.inc.php # 启用 kolab_2fa 插件

参考:https://git.kolab.org/diffusion/RPK/browse/master/plugins/kolab_2fa/

roundcube 前端添加 2fa 二次验证

roundcube 常规用户名和密码登录后,会再次要求 2fa 验证

在 iredmail 1.7.1 - roundcube 1.6.8 里安装 kolab_activesync 3.5.6 插件 - 未成功配置 - 需要 kolab 配套

环境和已下载的文件,请看上一篇。继续安装插件 kolab_activesync 。

步骤:

  1. cd /opt/www/roundcubemail/plugins/ # 转到 roundcube 插件目录
  2. cp -a /opt/www/roundcubemail-plugins-kolab/plugins/kolab_activesync ./ # 复制 tasklist 插件文件
  3. cp kolab_activesync/config.inc.php.dist kolab_activesync/config.inc.php # 创建配置文件
  4. vi kolab_activesync/config.inc.php # 创建配置文件
  5. vi /opt/www/roundcubemail/config/config.inc.php # 启用 tasklist 插件

问题:在 roundcube 前端 设置 里点击 Activesync ,会提示 Your server does not support metadata/annotations 。 在 plugins/kolab_activesync/kolab_activesync.php 文件里有写 ActiveSync configuration utility for Kolab accounts. 且有如 public const ASYNC_KEY = '/private/vendor/kolab/activesync'; 的设置,估计是这个 kolab_activesync 是专为 kolab 使用的,不适合公共版本的 roundcube 使用。

参考:https://git.kolab.org/diffusion/RPK/browse/master/plugins/kolab_activesync/

roundcube 前端 设置 里点击 Activesync ,提示出错

相应出现在 syslog 里的日志内容

debian 里的 apache traffice server - 帝国cms 站点 - 访问设置

现象1:站点前台,用户登录异常,如输入密码登录成功后,显示“未登录”;又或者未登录的用户显示是某个用户登录状态。
应对:proxy.config.http.cache.cache_urls_that_look_dynamic 设置为 0 。即默认缓存 php 的,设置为不缓存 php 。

现象2:站点后台,管理页面输入用户和密码登录后,页面空白。
应对:proxy.config.url_remap.pristine_host_hdr INT 设置为 1 。即默认不保持客户请求头的,设置为 保存 。

参考:https://docs.trafficserver.apache.org/admin-guide/files/records.config.en.html