use serde::Deserialize; /// SMTP 收信服务配置(临时邮箱核心) #[derive(Debug, Deserialize, Clone)] pub struct SmtpConfig { /// 是否启用 SMTP 收信(监听 25 端口) #[serde(default = "default_enabled")] pub enabled: bool, /// 监听地址 #[serde(default = "default_listen_host")] pub listen_host: String, /// 监听端口(默认 25) #[serde(default = "default_listen_port")] pub listen_port: u16, /// 本机主机名(SMTP 问候时使用,如 mail.shenjianl.cn) #[serde(default = "default_hostname")] pub hostname: String, /// 允许的收件域名白名单(只收这些域名的邮件) #[serde(default = "default_local_domains")] pub local_domains: Vec, /// 单封邮件最大字节数 #[serde(default = "default_max_message_bytes")] pub max_message_bytes: usize, /// 单连接超时秒数 #[serde(default = "default_connection_timeout_seconds")] pub connection_timeout_seconds: u64, /// 单封邮件最大收件人数 #[serde(default = "default_max_recipients")] pub max_recipients_per_message: u32, // ===== 限流(IP 连接 + 发件域 + 收件地址) ===== /// 单 IP 每分钟最大连接数 #[serde(default = "default_ip_connect_per_min")] pub ip_connect_per_min: u32, /// 单发件域每分钟最大邮件数 #[serde(default = "default_domain_per_min")] pub domain_per_min: u32, /// 单收件地址每分钟最大邮件数 #[serde(default = "default_rcpt_per_min")] pub rcpt_per_min: u32, /// 单发件人每分钟最大邮件数 #[serde(default = "default_sender_per_min")] pub sender_per_min: u32, /// 单(发件域→收件地址)每 10 分钟最大邮件数 #[serde(default = "default_pair_per_10min")] pub pair_per_10min: u32, // ===== PTR 反查 ===== /// 是否要求来源 IP 有有效 PTR 记录 #[serde(default = "default_require_ptr")] pub require_ptr: bool, // ===== 灰名单 ===== #[serde(default = "default_greylist_enabled")] pub greylist_enabled: bool, #[serde(default = "default_greylist_retry_delay_seconds")] pub greylist_retry_delay_seconds: i64, #[serde(default = "default_greylist_entry_ttl_seconds")] pub greylist_entry_ttl_seconds: i64, // ===== 滥用评分 ===== /// 达到此分数的邮件进入隔离区 #[serde(default = "default_quarantine_threshold")] pub quarantine_threshold: i32, #[serde(default = "default_score_weight_subject_code")] pub score_weight_subject_code: i32, #[serde(default = "default_score_weight_spf_fail")] pub score_weight_spf_fail: i32, #[serde(default = "default_score_weight_ptr_missing")] pub score_weight_ptr_missing: i32, #[serde(default = "default_score_weight_bad_attachment")] pub score_weight_bad_attachment: i32, // ===== 保留期与配额 ===== /// 邮件保留天数(超过自动清理) #[serde(default = "default_email_ttl_days")] pub email_ttl_days: i64, /// 新建临时邮箱默认有效期(小时) #[serde(default = "default_mailbox_ttl_hours")] pub mailbox_ttl_hours: i64, /// 单邮箱最大容量(字节) #[serde(default = "default_mailbox_max_quota_bytes")] pub mailbox_max_quota_bytes: i64, /// 随机生成的邮箱本地部分长度 #[serde(default = "default_address_local_part_len")] pub address_local_part_len: usize, /// 邮件正文加密密钥(必须恰好 32 字符;留空则不加密) #[serde(default)] pub body_encryption_key: String, } fn default_enabled() -> bool { true } fn default_listen_host() -> String { "0.0.0.0".to_string() } fn default_listen_port() -> u16 { 25 } fn default_hostname() -> String { "mail.shenjianl.cn".to_string() } fn default_local_domains() -> Vec { vec!["mail.shenjianl.cn".to_string(), "shenjianl.cn".to_string()] } fn default_max_message_bytes() -> usize { 1024 * 1024 } fn default_connection_timeout_seconds() -> u64 { 30 } fn default_max_recipients() -> u32 { 1 } fn default_ip_connect_per_min() -> u32 { 20 } fn default_domain_per_min() -> u32 { 10 } fn default_rcpt_per_min() -> u32 { 10 } fn default_sender_per_min() -> u32 { 10 } fn default_pair_per_10min() -> u32 { 5 } fn default_require_ptr() -> bool { true } fn default_greylist_enabled() -> bool { true } fn default_greylist_retry_delay_seconds() -> i64 { 300 } fn default_greylist_entry_ttl_seconds() -> i64 { 86400 } fn default_quarantine_threshold() -> i32 { 60 } fn default_score_weight_subject_code() -> i32 { 30 } fn default_score_weight_spf_fail() -> i32 { 20 } fn default_score_weight_ptr_missing() -> i32 { 15 } fn default_score_weight_bad_attachment() -> i32 { 25 } fn default_email_ttl_days() -> i64 { 7 } fn default_mailbox_ttl_hours() -> i64 { 24 } fn default_mailbox_max_quota_bytes() -> i64 { 10 * 1024 * 1024 } fn default_address_local_part_len() -> usize { 10 } impl Default for SmtpConfig { fn default() -> Self { Self { enabled: default_enabled(), listen_host: default_listen_host(), listen_port: default_listen_port(), hostname: default_hostname(), local_domains: default_local_domains(), max_message_bytes: default_max_message_bytes(), connection_timeout_seconds: default_connection_timeout_seconds(), max_recipients_per_message: default_max_recipients(), ip_connect_per_min: default_ip_connect_per_min(), domain_per_min: default_domain_per_min(), rcpt_per_min: default_rcpt_per_min(), sender_per_min: default_sender_per_min(), pair_per_10min: default_pair_per_10min(), require_ptr: default_require_ptr(), greylist_enabled: default_greylist_enabled(), greylist_retry_delay_seconds: default_greylist_retry_delay_seconds(), greylist_entry_ttl_seconds: default_greylist_entry_ttl_seconds(), quarantine_threshold: default_quarantine_threshold(), score_weight_subject_code: default_score_weight_subject_code(), score_weight_spf_fail: default_score_weight_spf_fail(), score_weight_ptr_missing: default_score_weight_ptr_missing(), score_weight_bad_attachment: default_score_weight_bad_attachment(), email_ttl_days: default_email_ttl_days(), mailbox_ttl_hours: default_mailbox_ttl_hours(), mailbox_max_quota_bytes: default_mailbox_max_quota_bytes(), address_local_part_len: default_address_local_part_len(), body_encryption_key: String::new(), } } }