LOCAL(8) LOCAL(8)
名称
local - Postfix 本地邮件投递代理
摘要
local [通用 Postfix 守护进程选项]
描述
local(8) 守护进程负责处理来自 Postfix 队列管理器的本地邮件投递请求。每个投递请求包含以下信息:
- 队列文件
- 发件人地址
- 目标域名或主机名
- 一个或多个收件人地址
该程序需通过 master(8) 进程管理器启动运行。
主要功能包括:
1. 更新队列文件状态
2. 标记已完成投递的收件人
3. 通知队列管理器需要延迟重试的投递任务
投递状态报告将根据情况发送至:
- bounce(8)(退信)
- defer(8)(延迟投递)
- trace(8)(跟踪信息)
大小写处理
所有投递决策均基于收件人地址的本地部分(@符号前的部分),并统一转换为小写形式处理。例外情况请参考下文"地址扩展"部分。
系统级与用户级别名
系统管理员可配置:
1. 系统范围的 sendmail 风格别名数据库
2. 用户个人的 sendmail 风格 ~/.forward 文件
邮件投递优先级:
1. 匹配别名 name
2. 查找 ~name/.forward 中的投递目标
3. 投递到用户 name 的邮箱
4. 退回无法投递的邮件
通过 forward_path 参数,管理员可以指定多个 .forward 文件的搜索路径(以逗号/空格分隔)。投递时会按顺序尝试这些路径,直到找到有效文件。
安全注意事项:
- 使用收件人权限执行 .forward 文件投递
- .forward 文件必须对收件人可读
- 父目录必须对收件人开放执行权限
变量扩展支持:
- $user(用户名)
- $home(主目录)
- $shell(Shell路径)
- $recipient(完整地址)
- $extension(地址扩展)
- $domain(域名)
- $local(本地部分)
- $recipient_delimiter
条件扩展语法(Postfix 3.0+):
- ${name?value}:当$name定义时展开
- ${name:value}:当$name未定义时展开
- ${name?{value1}:{value2}}:条件选择展开
特殊字符将通过 forward_expansion_filter 参数定义的规则转换为下划线。
邮件转发
可靠性保障机制:
1. 转发的邮件会作为新消息重新提交
2. 每个收件人有独立的投递状态记录
防循环机制:
- 添加 Delivered-To: 头记录最终收件人
- 当检测到重复的 Delivered-To 地址时自动退回邮件
邮箱投递
默认邮箱位置:
- UNIX 邮件池目录(/var/mail/ 或 /var/spool/mail/)
- 可通过 mail_spool_directory 参数配置
- 以 / 结尾的路径表示 qmail 风格的 maildir 格式
替代位置:
- 用户主目录下的文件
- 通过 home_mailbox 参数指定相对路径
- 以 / 结尾表示 maildir 格式
外部投递方式:
1. 外部命令:通过 mailbox_command_maps 和 mailbox_command 配置
- 使用收件人权限执行(root 时使用 default_privs 权限)
2. 替代传输:在 master.cf 中定义
- mailbox_transport_maps:按收件人指定
- mailbox_transport:全局默认
- fallback_transport_maps:未知用户处理
- fallback_transport:全局后备方案
UNIX 邮箱格式处理:
1. 添加 "From sender" 信封头
2. 添加 X-Original-To 头记录原始地址
3. 可选添加 Delivered-To 头
4. 添加 Return-Path 头
5. 对 "From " 开头的行添加 > 前缀
6. 末尾添加空行
7. 投递期间独占锁定邮箱
8. 出错时尝试恢复原始文件
Maildir 格式处理:
1. 可选添加 Delivered-To 头
2. 添加 X-Original-To 头
3. 添加 Return-Path 头
外部命令投递
安全限制:
- 通过 allow_mail_to_commands 参数控制(默认允许 alias 和 forward)
- 禁止在 :include: 文件中使用命令目标
工作目录:
- 可通过 command_execution_directory 指定(Postfix 2.2+)
- 目录切换失败会导致邮件延迟
变量扩展:
支持与 forward_path 相同的变量集和条件语法
特殊字符通过 execution_directory_expansion_filter 过滤
执行方式:
- 直接执行(无特殊字符时)
- 通过 /bin/sh 执行(含特殊字符或内置命令时)
输出处理:
- 捕获标准输出/错误(有限大小)
- 超时通过 command_time_limit 控制(默认1000秒)
- 返回码遵循 规范
- Postfix 2.3+ 支持 RFC 3463 增强状态码
环境变量:
| SHELL | 收件人的登录 Shell |
| HOME | 收件人主目录 |
| USER | 收件人用户名 |
| EXTENSION | 地址扩展部分 |
| DOMAIN | 域名部分 |
| LOGNAME | 同 USER |
| LOCAL | 本地部分(@前的内容) |
| ORIGINAL_RECIPIENT | 原始收件人地址(Postfix 2.5+) |
| RECIPIENT | 最终收件人地址 |
| SENDER | 发件人地址 |
| ENVID | RFC 3461 信封ID(Postfix 3.9+) |
客户端信息(Postfix 2.2+):
| CLIENT_ADDRESS | 客户端网络地址 |
| CLIENT_HELO | EHLO 参数 |
| CLIENT_HOSTNAME | 客户端主机名 |
| CLIENT_PROTOCOL | 协议类型 |
| SASL_METHOD | 认证方法 |
| SASL_SENDER | MAIL FROM 地址 |
| SASL_USERNAME | 认证用户名 |
其他说明:
- PATH 变量会被重置为系统默认值
- 通过 export_environment 指定的变量会原样传递
- 工作目录为邮件队列目录
- 消息处理:
1. 添加 "From sender" 头
2. 添加 X-Original-To 头
3. 可选添加 Delivered-To 头
4. 添加 Return-Path 头
5. 不添加空行
外部文件投递
格式说明:
- 默认:UNIX 邮箱格式
- 以 / 结尾的路径:qmail 风格的 maildir 格式
安全限制:
- 通过 allow_mail_to_files 控制(默认允许 alias 和 forward)
- 禁止在 :include: 文件中使用文件目标
UNIX 邮箱处理:
1. 添加 "From sender" 信封头
2. 添加 X-Original-To 头
3. 可选添加 Delivered-To 头
4. 添加 Return-Path 头
5. 对 "From " 开头的行添加 > 前缀
6. 末尾添加空行
7. 普通文件会独占锁定
8. 出错时尝试截断恢复
Maildir 处理:
1. 可选添加 Delivered-To 头
2. 添加 X-Original-To 头
3. 添加 Return-Path 头
地址扩展
通过 recipient_delimiter 参数指定分隔符(如 +)
示例(分隔符=+):
name+foo 的投递顺序:
1. 别名 name+foo
2. 别名 name
3. ~name/.forward+foo
4. ~name/.forward
5. 用户 name 的邮箱
6. 退回邮件
投递权限
权限规则:
- 外部文件/命令:使用收件人权限
- 无用户上下文时:使用 :include: 或别名文件所有者权限
- 超级用户拥有的文件:使用 default_privs 指定权限
遵循标准
RFC 822(ARPA 互联网文本消息)
RFC 3463(增强状态码)
诊断
日志记录:
- 通过 syslogd(8) 或 postlogd(8) 记录
- 损坏的消息文件会被特殊标记
通知机制:
- 根据 notify_classes 设置通知 postmaster
安全
安全特性:
1. 双重身份:
- 访问 Postfix 内部队列和 IPC
- 模拟收件人执行投递
2. 禁止别名映射中的正则替换($1等)
3. 静默忽略 proxymap 请求(Postfix 2.2+)
已知问题
1. 外部命令/文件的投递状态不持久化:
- 可能导致重复投递
2. 相互递归的别名/forward 文件:
- 只能通过 Delivered-To 头检测循环
配置参数
生效方式:
- 修改 main.cf 后自动加载(因 local 进程生命周期短)
- 执行 "postfix reload" 加速生效
注意:
- 以下仅为摘要,详见 postconf(5)
兼容性控制
biff (yes)
是否启用本地 biff 服务
expand_owner_alias (no)
当向具有 owner-aliasname 伴随别名的 aliasname 投递时,
将信封发件人设为 owner-aliasname 的扩展形式
owner_request_special (yes)
特殊处理 owner-listname 条目:
- 在别名文件中有效
- 当 recipient_delimiter="-" 时不拆分 owner-listname 和 listname-request
sun_mailtool_compatibility (no)
已废弃的 Sun mailtool 兼容模式
Postfix 2.3+:
frozen_delivered_to (yes)
Delivered-To 地址仅在投递开始时确定一次,
不随别名/forward 扩展更新
Postfix 2.5.3+:
strict_mailbox_ownership (yes)
邮箱文件属主不符时延迟投递
reset_owner_alias (no)
当子别名没有对应 owner 别名时,
重置本地投递代理的 owner-alias 属性
Postfix 3.0+:
local_delivery_status_filter ($default_delivery_status_filter)
可过滤修改投递状态码和说明文本
投递方式控制
优先级从高到低:
1. 别名
2. .forward 文件
3. mailbox_transport_maps
4. mailbox_transport
5. mailbox_command_maps
6. mailbox_command
7. home_mailbox
8. mail_spool_directory
9. fallback_transport_maps
10. fallback_transport
11. luser_relay
alias_maps (参见 'postconf -d' 输出)
仅用本地部分(无域名)查询的别名表,
区别于 virtual_alias_maps(全地址查询)
forward_path (参见 'postconf -d' 输出)
.forward 文件的搜索路径
mailbox_transport_maps (empty)
按收件人指定的替代传输方式
mailbox_transport (empty)
所有本地收件人的统一替代传输
mailbox_command_maps (empty)
按收件人指定的外部命令
mailbox_command (empty)
全局外部命令
home_mailbox (empty)
用户主目录下的邮箱路径(相对路径)
mail_spool_directory (参见 'postconf -d' 输出)
UNIX 邮箱的默认存储目录
fallback_transport_maps (empty)
未知用户的按地址后备传输
fallback_transport (empty)
全局后备传输
luser_relay (empty)
未知本地用户的中继地址
Postfix 2.2+:
command_execution_directory (empty)
外部命令执行的工作目录
邮箱锁定控制
deliver_lock_attempts (20)
最大锁定尝试次数
deliver_lock_delay (1s)
重试锁定间隔
stale_lock_time (500s)
过期锁文件的保留时间
mailbox_delivery_lock (参见 'postconf -d' 输出)
UNIX 邮箱的锁定机制
资源与速率控制
command_time_limit (1000s)
外部命令超时
duplicate_filter_limit (1000)
重复地址过滤器的记忆容量
mailbox_size_limit (51200000)
单个邮箱大小限制(0表示无限制)
qmgr(8) 相关:
local_destination_concurrency_limit (2)
同一收件人/域的最大并行投递数
local_destination_recipient_limit (1)
单消息的最大本地收件人数
安全控制
allow_mail_to_commands (alias, forward)
外部命令许可
allow_mail_to_files (alias, forward)
外部文件许可
command_expansion_filter (参见 'postconf -d' 输出)
命令扩展的字符过滤
default_privs (nobody)
默认执行权限
forward_expansion_filter (参见 'postconf -d' 输出)
forward 扩展的字符过滤
Postfix 2.2+:
execution_directory_expansion_filter (参见 'postconf -d' 输出)
执行目录扩展的字符过滤
Postfix 2.5.3+:
strict_mailbox_ownership (yes)
严格检查邮箱属主
杂项控制
config_directory (参见 'postconf -d' 输出)
Postfix 主配置文件路径:
- main.cf
- master.cf
daemon_timeout (18000s)
守护进程处理请求的超时时间(5小时)
delay_logging_resolution_limit (2)
延迟日志的小数精度(位)
export_environment (参见 'postconf -d' 输出)
传递给外部程序的环境变量白名单
ipc_timeout (3600s)
内部进程通信的超时时间(1小时)
local_command_shell (empty)
非 Postfix 命令的执行 Shell
max_idle (100s)
守护进程空闲超时时间
max_use (100)
守护进程最大服务请求数
prepend_delivered_header (command, file, forward)
添加 Delivered-To 头的场景:
- 外部命令投递
- 外部文件投递
- 转发投递
process_id (read-only)
进程 ID(只读)
process_name (read-only)
进程名称(只读)
propagate_unmatched_extensions (canonical, virtual)
地址扩展的传播规则:
- 规范映射
- 虚拟映射
queue_directory (参见 'postconf -d' 输出)
队列目录位置
recipient_delimiter (empty)
收件人地址分隔符(如 +)
require_home_directory (no)
要求收件人主目录必须存在
syslog_facility (mail)
系统日志设施
syslog_name (参见 'postconf -d' 输出)
系统日志前缀(如 prefix/smtpd)
Postfix 3.3+:
enable_original_recipient (yes)
支持地址重写前的原始收件人
service_name (read-only)
master.cf 中定义的服务名(只读)
Postfix 3.5+:
info_log_address_format (external)
非调试日志的地址显示格式
文件
典型文件位置:
- $HOME/.forward(用户级转发配置)
- /etc/aliases(系统别名数据库)
- /var/spool/mail(系统邮箱目录)
参见
qmgr(8) 队列管理器
bounce(8) 投递状态报告
newaliases(1) 创建/更新别名数据库
postalias(1) 别名数据库工具
aliases(5) 别名数据库格式
postconf(5) 配置参数参考
master(5) 主进程配置
postlogd(8) Postfix 日志服务
syslogd(8) 系统日志服务
许可证
必须随本软件分发 Secure Mailer 许可证
历史
- Delivered-To: 头源自 Daniel Bernstein 的 qmail 系统
- maildir 结构源自 Daniel Bernstein 的 qmail 系统
作者
Wietse Venema
IBM T.J. Watson 研究中心
邮政信箱 704
美国纽约州约克镇高地 10598
Wietse Venema
Google 公司
纽约第八大道 111 号
美国纽约州纽约市 10011
Wietse Venema
porcupine.org
LOCAL(8)