Debian 邮件服务器虚拟用户部署指南
一 架构与组件
二 安装与基础配置
sudo apt update && sudo apt install postfix dovecot-core dovecot-imapd dovecot-pop3d dovecot-lmtpd mariadb-server libpam-mysqlmyhostname = mail.example.commydomain = example.commyorigin = $mydomaininet_interfaces = allinet_protocols = ipv4(或 all)sudo ufw allow 25/tcp, 587/tcp, 465/tcp, 143/tcp, 993/tcp, 110/tcp, 995/tcp三 数据库设计与初始化
sudo mysql -u root -pCREATE DATABASE maildb CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'mailuser'@'localhost' IDENTIFIED BY 'StrongPass!';
GRANT SELECT, INSERT, UPDATE, DELETE ON maildb.* TO 'mailuser'@'localhost';
FLUSH PRIVILEGES;
CREATE TABLE virtual_domains (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(255) NOT NULL UNIQUE
);
CREATE TABLE virtual_users (
id INT AUTO_INCREMENT PRIMARY KEY,
domain_id INT NOT NULL,
email VARCHAR(255) NOT NULL UNIQUE,
password VARCHAR(255) NOT NULL,
active TINYINT(1) DEFAULT 1,
FOREIGN KEY (domain_id) REFERENCES virtual_domains(id) ON DELETE CASCADE
);
CREATE TABLE virtual_aliases (
id INT AUTO_INCREMENT PRIMARY KEY,
domain_id INT NOT NULL,
source VARCHAR(255) NOT NULL,
destination VARCHAR(255) NOT NULL,
FOREIGN KEY (domain_id) REFERENCES virtual_domains(id) ON DELETE CASCADE
);
INSERT INTO virtual_domains (name) VALUES ('example.com');
INSERT INTO virtual_users (domain_id, email, password) VALUES
((SELECT id FROM virtual_domains WHERE name='example.com'), 'alice@example.com', ENCRYPT('Secret123', CONCAT('$6$', SUBSTRING(SHA(RAND()),1,16))));
INSERT INTO virtual_aliases (domain_id, source, destination) VALUES
((SELECT id FROM virtual_domains WHERE name='example.com'), 'sales@example.com', 'alice@example.com');
四 Postfix 与 Dovecot 核心配置
# 基本
myhostname = mail.example.com
mydomain = example.com
myorigin = $mydomain
inet_interfaces = all
inet_protocols = ipv4
# 虚拟域与映射
virtual_mailbox_domains = mysql:/etc/postfix/mysql-virtual-mailbox-domains.cf
virtual_mailbox_maps = mysql:/etc/postfix/mysql-virtual-mailbox-maps.cf
virtual_alias_maps = mysql:/etc/postfix/mysql-virtual-alias-maps.cf
# 投递与 LMTP
virtual_transport = lmtp:unix:private/dovecot-lmtp
mailbox_size_limit = 0
message_size_limit = 102400000
# SASL 与策略
smtpd_sasl_type = dovecot
smtpd_sasl_path = private/auth
smtpd_sasl_auth_enable = yes
smtpd_sasl_security_options = noanonymous
smtpd_sasl_local_domain = $myhostname
smtpd_recipient_restrictions =
permit_mynetworks,
permit_sasl_authenticated,
reject_unauth_destination
host = 127.0.0.1
user = mailuser
password = StrongPass!
dbname = maildb
query = SELECT 1 FROM virtual_domains WHERE name='%s'
host = 127.0.0.1
user = mailuser
password = StrongPass!
dbname = maildb
query = SELECT 1 FROM virtual_users WHERE email='%s' AND active=1
host = 127.0.0.1
user = mailuser
password = StrongPass!
dbname = maildb
query = SELECT destination FROM virtual_aliases WHERE domain_id=(SELECT id FROM virtual_domains WHERE name='%d') AND source='%u'
disable_plaintext_auth = yes
auth_mechanisms = plain login
passdb {
driver = sql
args = /etc/dovecot/dovecot-sql.conf.ext
}
userdb {
driver = sql
args = /etc/dovecot/dovecot-sql.conf.ext
}
driver = mysql
connect = host=127.0.0.1 dbname=maildb user=mailuser password=StrongPass!
default_pass_scheme = SHA512-CRYPT
password_query = SELECT email AS user, password FROM virtual_users WHERE email='%u' AND active=1
user_query = SELECT email AS user, '/var/mail/vhosts/%d/%n' AS home, 'maildir:/var/mail/vhosts/%d/%n' AS mail, 5000 AS uid, 5000 AS gid, 'maildir:/var/mail/vhosts/%d/%n' AS quota_rule
mail_location = maildir:/var/mail/vhosts/%d/%n
namespace inbox {
inbox = yes
}
service lmtp {
unix_listener /var/spool/postfix/private/dovecot-lmtp {
mode = 0600
user = postfix
group = postfix
}
}
service auth {
unix_listener /var/spool/postfix/private/auth {
mode = 0666
user = postfix
group = postfix
}
}
sudo mkdir -p /var/mail/vhosts/example.com/alice
sudo chown -R 5000:5000 /var/mail/vhosts
sudo chmod -R 0700 /var/mail/vhosts
sudo systemctl restart postfix dovecot
sudo postfix check
sudo doveconf -n
五 安全与测试
smtpd_tls_cert_file = /etc/letsencrypt/live/mail.example.com/fullchain.pem
smtpd_tls_key_file = /etc/letsencrypt/live/mail.example.com/privkey.pem
smtpd_use_tls = yes
smtpd_tls_security_level = may
smtp_tls_security_level = may
ssl = required
ssl_cert = </etc/letsencrypt/live/mail.example.com/fullchain.pem
ssl_key = </etc/letsencrypt/live/mail.example.com/privkey.pem
openssl s_client -connect mail.example.com:993 -quiet
nc -vz mail.example.com 25
swaks --to alice@example.com --from test@example.org --server mail.example.com:587 --auth LOGIN --auth-user alice@example.com --auth-password Secret123sudo tail -f /var/log/mail.log /var/log/dovecot.log