AnonAddy 1.7.3 配置参数详解

逐项详解 AnonAddy 1.7.3 全部 .env 配置参数(含 config/anonaddy.php 实测映射),并给出 SPF/DKIM/DMARC 邮件加固完整方案

AnonAddyAnonAddy邮件别名Postfix自托管2026/10/25

AnonAddy 1.7.3 配置参数详解

目标:逐项讲清 AnonAddy(addy.io)v1.7.3 全部配置参数的含义、取值与生效方式,并给出一套可直接照做的 SPF/DKIM/DMARC 邮件加固方案。参数定义以应用内 config/anonaddy.php(v1.7.3 实取)与官方 .env.example 为准,所有命令回显均在 Ubuntu 22.04 + AnonAddy 1.7.3 真实环境实测。安装过程见《Ubuntu 22.04 安装 AnonAddy 1.7.3 指南》。

一、配置体系总览

AnonAddy 是标准 Laravel 应用,配置分三层:

  1. .env(项目根目录):环境变量源头,部署时唯一需要手工维护的文件。
  2. config/*.php:应用代码通过 env('KEY', 默认值) 读取 .env,AnonAddy 自有参数集中在 config/anonaddy.php,Laravel 框架参数分布在 config/app.php、config/mail.php 等。
  3. 配置缓存:生产环境用 php artisan config:cache 把全部配置编译进 bootstrap/cache/config.php,此后 .env 改动必须重建缓存才生效。

实测验证:用 Laravel 自带的 config:show 查看 AnonAddy 全部生效配置(截取前 26 行):

$ cd /var/www/anonaddy && php artisan config:show anonaddy

  anonaddy ...................................................................
  version ............................................................... null
  return_path ............................................. mailer@example.com
  admin_username ....................................................... admin
  non_admin_username_subdomains ..............................................
  non_admin_shared_domains ..................................................
  enable_registration ................................................... true
  domain ......................................................... example.com
  hostname .................................................. mail.example.com
  dns_resolver ..................................................... 127.0.0.1
  blocklist ⇁ allowed_ips ⇁ 0 ...................................... 127.0.0.1
  blocklist ⇁ secret .......................... uStu5BoDvDoxGi1AHCfEW3ougDcgty
  postfix_log_path ......................................... /var/log/mail.log
  all_domains ⇁ 0 ................................................ example.com
  secret .... 6671089a52ee47fbe79afb42d72be70f2ace421800d4d08a3e9400027b82ba32
  limit .................................................................. 200
  bandwidth_limit_enabled ............................................... true
  bandwidth_limit .................................................. 104857600
  new_alias_hourly_limit ................................................. 100
  additional_username_limit ............................................... 10
  signing_key_fingerprint ....................................................
  gnupg_home .......................................................... .gnupg
  dkim_signing_key ...................................................... null
  dkim_selector ...................................................... default
  auto_verify_new_recipients ........................................... false
  use_proxy_authentication ............................................. false

这份输出就是后文逐项详解的对照基准。

二、应用基础参数(APP_*)

参数示例值说明
APP_NAMEaddy.io应用名称,显示在页面标题与通知邮件中,可改为自己的品牌名
APP_ENVproduction运行环境,生产必须 production(影响错误页与调试行为)
APP_KEYbase64:DSzQlrIt...Laravel 加密密钥,用于 Cookie、会话、数据库加密字段。安装时用 php artisan key:generate --force 生成,丢失后所有加密数据不可恢复,务必备份
APP_DEBUGfalse生产必须 false;为 true 时错误页会泄露路径、SQL 与配置
APP_LOG_LEVELdebug日志最低级别,生产建议 info 或 warning 减少噪音
APP_URLhttps://app.example.com实例对外 URL,邮件中的链接、Vite 前端构建都依赖它。非标准端口必须带端口号(如 https://example.test:8000),结尾不要带 /
LOG_CHANNELstack日志通道,默认写 storage/logs/laravel.log

注意:APP_URL 不只是展示用——前端资源构建(npm run production)时 Vite 会读取它,改域名后若页面资源 404,需检查 .env 的 APP_URL 并重新构建。

三、数据库与缓存会话参数

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=addy_database
DB_USERNAME=addy
DB_PASSWORD=secret

BROADCAST_DRIVER=log
CACHE_DRIVER=redis
QUEUE_CONNECTION=redis
SESSION_DRIVER=redis
SESSION_LIFETIME=10080
SESSION_SECURE_COOKIE=true
SAME_SITE_COOKIES=lax

REDIS_CLIENT=phpredis
REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379
参数说明
DB_*MySQL/MariaDB 连接。库、账号在安装篇已建好,密码务必替换为强随机值
QUEUE_CONNECTION队列驱动。必须 redis:别名转发、退信处理都走队列;若设为 sync 则收信管道内同步处理,高并发下会拖慢 Postfix
CACHE_DRIVER / SESSION_DRIVER缓存与会话存 Redis,多实例部署时必需
SESSION_LIFETIME会话有效期(分钟),默认 10080 = 7 天
SESSION_SECURE_COOKIE仅 HTTPS 下回传 Cookie。HTTP 访问时必须改 false,否则登录报 419 Page Expired(实测踩坑,见安装篇排障)
REDIS_CLIENTPHP 的 Redis 客户端,推荐 phpredis(C 扩展,性能优于 predis)
REDIS_PASSWORD无密码时保留字面量 null,不要留空

四、外发邮件参数(MAIL_*)

MAIL_FROM_NAME=Example
MAIL_FROM_ADDRESS=mailer@example.com
MAIL_DRIVER=smtp
MAIL_HOST=mail.example.com
MAIL_PORT=25
MAIL_ENCRYPTION=tls
MAIL_EHLO_DOMAIN=mail.example.com
MAIL_VERIFY_PEER=true
参数说明
MAIL_FROM_NAME系统通知邮件(注册验证、别名失效提醒等)的发件人显示名
MAIL_FROM_ADDRESS系统通知邮件的发件地址,建议与 GPG 签名密钥的邮箱一致(见第六章)
MAIL_HOST / MAIL_PORT本机 Postfix,即 127.0.0.1:25 或服务器 FQDN;通知邮件经 Postfix 投递可享受 DKIM 签名与队列重试
MAIL_ENCRYPTION本机投递用 tls;Postfix 未配 TLS 时改为 null
MAIL_EHLO_DOMAINSMTP EHLO 主机名,必须与服务器 FQDN(ANONADDY_HOSTNAME)一致,否则严格的对端会拒收
MAIL_VERIFY_PEER校验对端 TLS 证书,本机 Postfix 用自签证书时设 false

五、AnonAddy 核心参数(ANONADDY_*)

这是别名服务的业务核心,全部映射到 config/anonaddy.php。

5.1 域名与身份

参数示例值说明
ANONADDY_DOMAINexample.com主域名。设置后可在根域收发(@example.com),同时作为别名默认域
ANONADDY_ALL_DOMAINSexample.com,example2.com全部可用域名的逗号分隔列表,必须包含主域。多域时 Postfix 的 virtual 查询也要覆盖这些域
ANONADDY_HOSTNAMEmail.example.com服务器 FQDN,用于校验用户自定义域名的 MX 记录是否指向本服务
ANONADDY_ADMIN_USERNAMEadmin管理员用户名。设置后该用户可在根域接收邮件(*@example.com catch-all),普通用户只能用 *@用户名.example.com 子域
ANONADDY_DNS_RESOLVER127.0.0.1校验自定义域名 DNS 记录时使用的解析器。本机有缓存 DNS(如 bind9)用 127.0.0.1,否则填 1.1.1.1 等公共解析器

5.2 安全密钥

参数说明
ANONADDY_SECRET64 位以上随机串,用于匿名回复/发送的哈希计算与 VERP 退信地址校验。泄露意味着任何人可伪造退信回调,生成:openssl rand -hex 32

5.3 限额

参数默认值说明
ANONADDY_LIMIT200单用户每小时可转发+回复的邮件数上限,防滥用
ANONADDY_BANDWIDTH_LIMIT_ENABLEDtrue是否启用月度带宽限额,设 false 关闭执行
ANONADDY_BANDWIDTH_LIMIT104857600单用户月度带宽上限(字节),默认 100MB。超限后该用户别名暂停转发
ANONADDY_NEW_ALIAS_LIMIT100单用户每小时可新建别名数
ANONADDY_ADDITIONAL_USERNAME_LIMIT10单用户可添加的附加用户名(子域)数量上限

5.4 行为开关

参数默认值说明
ANONADDY_ENABLE_REGISTRATIONtrue是否开放注册。私有实例设 false,此后只能用 php artisan anonaddy:create-user 建号
ANONADDY_NON_ADMIN_USERNAME_SUBDOMAINStrue设 false 则禁止非管理员创建用户名子域别名(*@username.example.com)
ANONADDY_NON_ADMIN_SHARED_DOMAINStrue设 false 则禁止非管理员在共享域(根域)创建别名
ANONADDY_AUTO_VERIFY_NEW_RECIPIENTSfalse设 true 则新收件人邮箱免验证(官方 .env.example 未列出,见 config/anonaddy.php),自托管信任内部收件人时可开启
ANONADDY_RETURN_PATHmailer@example.com外发邮件的 Return-Path 兜底地址。当别名地址不能作为发件人时(如自定义域未验证发信权限)使用该地址接收退信

实测验证——改限额并重建缓存后立刻生效:

$ sed -i 's/^ANONADDY_LIMIT=.*/ANONADDY_LIMIT=500/' .env
$ php artisan config:cache

   INFO  Configuration cached successfully.

$ echo "var_dump(config(\"anonaddy.limit\"));" | php artisan tinker
int(500)

验证完毕把值改回 200 再跑一次 config:cache 即可。

六、加密与签名参数(GPG / DKIM)

参数说明
ANONADDY_SIGNING_KEY_FINGERPRINT用于给加密转发邮件签名的 GPG 私钥指纹(40 位十六进制)。留空则不签名
ANONADDY_GNUPGHOMEGPG 密钥环目录,必须是运行 PHP/队列进程用户(www-data)可读的绝对路径。生产队列 worker 环境里 HOME 常未设置,不要依赖 ~/.gnupg
ANONADDY_DKIM_SIGNING_KEYDKIM 私钥文件路径。仅在需要给用户自定义域名代签 DKIM 时才填,主域签名由 Rspamd 完成(见第九章),此处留空即可
ANONADDY_DKIM_SELECTOR上面私钥对应的 selector,默认 default

实测验证——以 www-data 身份生成无密码签名密钥(php-gnupg 无法使用带密码的密钥):

$ mkdir -p /var/www/.gnupg && chown www-data:www-data /var/www/.gnupg && chmod 700 /var/www/.gnupg
$ sudo -u www-data GNUPGHOME=/var/www/.gnupg gpg --batch --gen-key <<EOF
%no-protection
Key-Type:1
Key-Length:4096
Subkey-Type:1
Subkey-Length:4096
Name-Real: addy.io mailer
Name-Email: mailer@example.com
Expire-Date:0
EOF
gpg: keybox '/var/www/.gnupg/pubring.kbx' created
gpg: /var/www/.gnupg/trustdb.gpg: trustdb created
gpg: key 217B220E8B0FDF55 marked as ultimately trusted
gpg: directory '/var/www/.gnupg/openpgp-revocs.d' created
gpg: revocation certificate stored as '/var/www/.gnupg/openpgp-revocs.d/C6D5589A4F30EF1762F34BCD217B220E8B0FDF55.rev'

查看指纹:

$ sudo -u www-data GNUPGHOME=/var/www/.gnupg gpg -k
/var/www/.gnupg/pubring.kbx
---------------------------
pub   rsa4096 2026-10-25 [SCEA]
      C6D5589A4F30EF1762F34BCD217B220E8B0FDF55
uid           [ultimate] addy.io mailer <mailer@example.com>
sub   rsa4096 2026-10-25 [SEA]

把 C6D5589A4F30EF1762F34BCD217B220E8B0FDF55 填入 ANONADDY_SIGNING_KEY_FINGERPRINT,ANONADDY_GNUPGHOME=/var/www/.gnupg,然后 php artisan config:cache 生效。注意 Name-Email 建议与 MAIL_FROM_ADDRESS 一致,签名身份才与发件人吻合。

七、反代认证与 Blocklist API

7.1 反向代理自动登录(慎用)

ANONADDY_USE_PROXY_AUTHENTICATION=false
ANONADDY_PROXY_AUTHENTICATION_USER_ID_HEADER=X-User
ANONADDY_PROXY_AUTHENTICATION_NAME_HEADER=X-Name
ANONADDY_PROXY_AUTHENTICATION_EMAIL_HEADER=X-Email

开启后,应用信任反向代理(OAuth2-Proxy、Authentik 等)注入的请求头并自动登录/注册。只有在流量必然经过可信代理时才能开启,否则任何人伪造 X-User 头即可登录任意账号。

7.2 Blocklist API(配合 Rspamd 用户黑名单)

BLOCKLIST_API_ALLOWED_IPS=127.0.0.1
BLOCKLIST_API_SECRET=uStu5BoDvDoxGi1AHCfEW3ougDcgty
参数说明
BLOCKLIST_API_ALLOWED_IPS允许调用 /api/blocklist-check 的 IP 逗号列表,填 Rspamd 所在邮件服务器的实际 IP
BLOCKLIST_API_SECRET可选共享密钥;设置后必须与 Rspamd Lua 脚本(/etc/rspamd/lua.local.d/addy_blocklist.lua)中的 blocklist_secret 一致

7.3 Postfix 日志路径

POSTFIX_LOG_PATH 默认 /var/log/mail.log,用于解析入站拒信记录。日志路径非默认时才需设置。

八、词表与黑名单参数

随机生成的别名(如 red.panda123@...)来自内置词表,保留用户名来自黑名单。config/anonaddy.php 通过统一的 $resolveList 机制加载:值为空则用默认词表文件;值为逗号分隔字符串则直接作为列表;值为路径(绝对或相对项目根目录的 .php 文件)则加载该文件返回的数组。

参数默认文件用途
ANONADDY_BLACKLISTconfig/lists/blacklist.php禁止注册的用户名(含 HTTP 状态码、保留名等)
ANONADDY_WORDLISTconfig/lists/wordlist.php随机别名单词表
ANONADDY_ADJECTIVES / ANONADDY_NOUNS同名默认文件别名生成的形容词/名词表
ANONADDY_MALE_FIRST_NAMES / ANONADDY_FEMALE_FIRST_NAMES / ANONADDY_SURNAMES同名默认文件人名风格别名生成

例如 .env 中写 ANONADDY_BLACKLIST=reserved,admin,root 即追加自定义保留名。

九、SPF/DKIM/DMARC 邮件加固

别名转发服务的投递信誉完全取决于这三套记录。未配置时,转发的邮件在 Gmail/QQ 邮箱大概率进垃圾箱甚至被拒收。先看一个生产级参照——官方托管服务 addy.io 的真实记录(2026-10-25 实测):

$ dig +short TXT addy.io
"v=spf1 ip4:213.108.105.57 ip4:185.70.196.149 ip4:94.237.47.233 ip6:2a00:c6c0:0:108:3::10 ip6:2a04:3544:8000:1000:e8b5:6ff:fe29:56c ip6:2a04:3544:1000:1510:e8b5:6ff:fe29:1d32 -all"
$ dig +short TXT _dmarc.addy.io
"v=DMARC1; p=reject; pct=100; rua=mailto:dmarc@notifications.uriports.com; ruf=mailto:dmarc@notifications.uriports.com; sp=reject; aspf=r; fo=1:d:s"
$ dig +short TXT default._domainkey.addy.io
"v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3zaLO8stjapEtX5FcAwYi69Hlt53DOF89+KjCjsoutvB/+KcoWdr1X1PEFECkO01UaCSH/O3ReXn7CKSLmUCuNWN1vJWeut/EbTq+M6j9W7HS/CLv4SxF+y0PtWBSgLxZiIHDwVxhd9y9ahWT/AUTlg9C7wxx0ZLsf7UmFT5pEUOVpsUMXbebIA3P9S9RbBNk" "9t4y26QoFAn6kOwqwAaBKfum0MzF/WRdb4HamIRjbBlKmy58skxAQYePpLSl75Nq5WmDArE03zFkknIgdGXnfR0RrgCRpEbTXrHeRMpa5O49FcABUWF9ALEQzSalVOaMaSddLLe4qX0gEt5Iix99wIDAQAB"

注意官方用的是最严格的 -all 与 p=reject,DKIM 为 2048 位 RSA。下面按官方 SELF-HOSTING 指南的路径自建同等配置。

9.1 SPF 记录

在域名 DNS 添加 TXT 记录,授权 MX 主机发信:

TXT  @   "v=spf1 mx ~all"
TXT  *   "v=spf1 mx ~all"

第二条通配记录覆盖所有用户名子域(username.example.com),别名地址在这些子域下,不可省略。运行稳定后建议把 ~all(软拒绝)收紧为 -all(硬拒绝),与官方一致。

9.2 DKIM:Rspamd 签名

安装 Rspamd 后生成 2048 位密钥对。实测验证:

$ mkdir /var/lib/rspamd/dkim
$ rspamadm dkim_keygen -s 'default' -b 2048 -d example.com -k /var/lib/rspamd/dkim/example.com.default.key | tee -a /var/lib/rspamd/dkim/example.com.default.pub
default._domainkey IN TXT ( "v=DKIM1; k=rsa; "
	"p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAw5ZTN7f2lE+ghPcVZzml34RVPvJBJ1xZ330qYgc2QiJIKixJAtVTDaBoWkch7KMX7/zJDqhOxkVP84iIJ3Da8eZEU6331u6/OXb1ojx0/RkFmGatmFEZhD3ckh4PYkaZuCDbowLHSpIJdT3KHvaMKCsNIZQ9lOFj2ANvPl/trjNga+7Iqj+J31ScNDXR/Q/YouLdrx2945+3xVOrr"
	"3yXXUlB6Q5q6FGjMIwpEkjEP/o+g1pJQVoxea+0FtsNbd5/slfP9CHMHybAQcC8JU9b51+/LD4qpz4AsSwfRoHHn5hMbAeQNfox6whw4LSwCaqu7vpFRZHqNxG7AMETWHqK2QIDAQAB"
) ;
$ chown -R _rspamd: /var/lib/rspamd/dkim
$ chmod 750 /var/lib/rspamd/dkim
$ chmod 440 /var/lib/rspamd/dkim/example.com.default.key /var/lib/rspamd/dkim/example.com.default.pub

把公钥内容(括号内拼接、去掉多余引号与空白)发布为 DNS TXT 记录:主机名 default._domainkey,值形如 "v=DKIM1; k=rsa; p=MIIBIjANBgkq..."。

配置 Rspamd 签名表 /etc/rspamd/local.d/dkim_signing.conf(覆盖根域与全部子域):

signing_table = [
"*@example.com example.com",
"*@*.example.com example.com",
];

key_table = [
"example.com example.com:default:/var/lib/rspamd/dkim/example.com.default.key",
];

use_domain = "envelope";
allow_hdrfrom_mismatch = true;
allow_hdrfrom_mismatch_sign_networks = true;
allow_username_mismatch = true;
use_esld = true;
sign_authenticated = false;

ARC(Authenticated Received Chain)签名复用同配置,转发场景下可让下游服务器信任原始认证结果:

$ cp /etc/rspamd/local.d/dkim_signing.conf /etc/rspamd/local.d/arc.conf

若还要给用户自定义域名代签 DKIM,才需要在 .env 填 ANONADDY_DKIM_SIGNING_KEY=/var/lib/rspamd/dkim/example.com.default.key,并把运行 PHP 的用户加入 _rspamd 组、给私钥加组读权限(usermod -a -G _rspamd www-data && chmod g+r .../example.com.default.key)。主域签名由 Rspamd 完成,无需该参数。

9.3 DMARC 记录与入站处置

发布 DMARC 记录(初期 p=none 只监控,确认 SPF/DKIM 全部正常后再收紧到 quarantine/reject):

TXT _dmarc  "v=DMARC1; p=none; sp=none; adkim=r; aspf=r; pct=100;"

入站方向,让 Rspamd 按对方域的 DMARC 策略处置来信,创建 /etc/rspamd/local.d/dmarc.conf:

actions = {
  quarantine = "add_header";
  reject = "reject";
}

含义:来信 DMARC 校验失败且对方策略为 p=quarantine 时加标记头,策略为 p=reject 时直接拒收。配合 /etc/rspamd/local.d/milter_headers.conf 可给通过校验的邮件添加 Authentication-Results 头,应用侧据此允许别名回复/发送,防止伪造收件人地址(完整配置见官方 SELF-HOSTING 指南)。

改完重启 Rspamd:systemctl restart rspamd。

验证清单(发布 DNS 后逐条执行):

dig +short TXT example.com                       # 应返回 v=spf1 ...
dig +short TXT default._domainkey.example.com    # 应返回 v=DKIM1 ...
dig +short TXT _dmarc.example.com                # 应返回 v=DMARC1 ...

再向别名发一封外部邮件,在真实收件箱查看原文,确认 Authentication-Results 中 spf=pass、dkim=pass、dmarc=pass 三项齐全。

十、配置修改与生效

标准变更流程:

$ nano /var/www/anonaddy/.env          # 1. 修改参数
$ cd /var/www/anonaddy
$ php artisan config:cache             # 2. 重建配置缓存(queue worker 会读取新配置)
$ systemctl restart anonaddy-worker    # 3. 重启队列 worker(Supervisor 管理的单元名以实际为准)
$ systemctl reload php8.3-fpm nginx    # 4. 重载 Web 层

常见问题:

  • 改了 .env 不生效:九成是忘了 config:cache。生产环境配置走缓存,.env 只在构建缓存时读取。
  • config:cache 后页面报错:检查 .env 是否有未加引号的特殊字符值(含空格、#、$ 的值要用双引号包起来)。
  • 排查当前生效值:php artisan config:show anonaddy 或 echo "var_dump(config('anonaddy.limit'));" | php artisan tinker,看到的才是应用真正使用的值。
  • 回滚:直接改回 .env 再 config:cache 即可,缓存文件 bootstrap/cache/config.php 也可直接删除后重建。

十一、参考链接