Files
email-unlimit/server/src/config/smtp.rs
T

204 lines
6.6 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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<String>,
/// 单封邮件最大字节数
#[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<String> {
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(),
}
}
}