ubuntu自建企业邮箱(ipv6+postfix+dovecot+mysql)
国内免费邮箱限制多,最近部署odoo要用到邮箱的bounce,和catchall功能,国内免费邮箱都不支持,于是准备自己架设一个邮件服务器记录一下。
前置条件
有公网IP/服务器25端口能通信(如无此条件,放弃)
本来想搞个☁️服务器做邮件服务器,但国内都是封了25端口,所以放弃。家里有条中国移动的宽带有IPV6,而且25端口也能通信(伟大的中国移动)中国电信就不行。
首先域名解析设置:
1.安装nginx 本站教程
2.安装acme.sh 方便搞到ssl证书。
curl https://get.acme.sh | sh -s email=xnb.mail@gmail.com
国内把证书服务器换成 letsencrypt
acme.sh --set-default-ca --server letsencrypt
申请证书
#进入nginx配置文件目录
cd /etc/nginx/conf.d
mv default.conf xnb.xyz.conf
vi xnb.xyz.conf
#将server_name改成 xnb.xyz
nginx -s reload
acme.sh --issue -d xnb.xyz
将证书布署到相应目录以便使用,我喜欢在/etc/nginx/cert下每个域名一个目录。
cd /etc/nginx
mkdir cert
mkdir -p /etc/nginx/cert/xnb.xyz
acme.sh --install-cert -d xnb.xyz --key-file /etc/nginx/cert/xnb.xyz/key.pem --fullchain-file /etc/nginx/cert/xnb.xyz/cert.pem --reloadcmd "service nginx force-reload"
方正先放在这里,等一会使用。记住这个路径
新建一个数据库 mailserver,管理账号为:mail/Mail202$
创建虚拟域表,作为认证域。该表是邮件服务器用以接收邮件的域名:
-- 建立表
CREATE TABLE `virtual_domains` (
`id` INT NOT NULL AUTO_INCREMENT,
`name` VARCHAR(50) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- 插入一条记录
insert into virtual_domains values(1,'xnb.xyz');
创建用户表,用于用户身份认证。
-- 创建用户表
CREATE TABLE `virtual_users` (
`id` INT NOT NULL AUTO_INCREMENT,
`domain_id` INT NOT NULL,
`password` VARCHAR(106) NOT NULL,
`email` VARCHAR(120) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `email` (`email`),
FOREIGN KEY (domain_id) REFERENCES virtual_domains(id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- 插入两个用户,以md5加密密码,实际应用中应该选择强度更高的算法,md5目前以及不安全了
insert into virtual_users values(1,1,md5('123456'),'a@xnb.xyz');
insert into virtual_users values(2,1,md5('123456'),'b@xnb.xyz');
创建别名表.该表作用相当于当 source 收到邮件时,该邮件会自动转发到 destination 上。
-- 创建表
CREATE TABLE `virtual_aliases` (
`id` int(11) NOT NULL auto_increment,
`domain_id` int(11) NOT NULL,
`source` varchar(100) NOT NULL,
`destination` varchar(100) NOT NULL,
PRIMARY KEY (`id`),
FOREIGN KEY (domain_id) REFERENCES virtual_domains(id) ON DELETE CASCADE)
ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- 插入数据,所有发给first的邮件都会自动转发给second
insert into virtual_aliases values(1,1,'a@xnb.xyz','b@xnb.xyz');
4.安装postfix及相关软件
apt update
apt install postfix postfix-mysql dovecot-core dovecot-pop3d dovecot-imapd dovecot-lmtpd dovecot-mysql
正常会出现向导配置,如果没有。运行 sudo dpkg-reconfigure postfix 会出现向导。
有几张图忘截了,一般按默认值,和你需要选择。
接下来配置main.cf
cp /etc/postfix/main.cf /etc/postfix/main.cf.bak
vim /etc/postfix/main.cf
参考我的修改
# See /usr/share/postfix/main.cf.dist for a commented, more complete version
# Debian specific: Specifying a file name will cause the first
# line of that file to be used as the name. The Debian default
# is /etc/mailname.
#myorigin = /etc/mailname
smtpd_banner = $myhostname ESMTP $mail_name (Ubuntu)
biff = no
# appending .domain is the MUA's job.
append_dot_mydomain = no
# Uncomment the next line to generate "delayed mail" warnings
#delay_warning_time = 4h
readme_directory = no
# See http://www.postfix.org/COMPATIBILITY_README.html -- default to 3.6 on
# fresh installs.
compatibility_level = 3.6
#
## TLS parameters
#smtpd_tls_cert_file=/etc/ssl/certs/ssl-cert-snakeoil.pem
#smtpd_tls_key_file=/etc/ssl/private/ssl-cert-snakeoil.key
#smtpd_tls_security_level=may
#
#smtp_tls_CApath=/etc/ssl/certs
#smtp_tls_security_level=may
#smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache
# 使用自己的ssl证书
smtpd_tls_cert_file=/etc/nginx/cert/xnb.xyz/fullchain.pem
smtpd_tls_key_file=/etc/nginx/cert/xnb.xyz/privkey.pem
smtpd_use_tls=yes
smtpd_tls_auth_only = yes
# 使用dovecot来做身份认证
smtpd_sasl_type = dovecot
smtpd_sasl_path = private/auth
smtpd_sasl_auth_enable = yes
smtpd_recipient_restrictions = permit_sasl_authenticated,permit_mynetworks,reject_unauth_destination
smtpd_relay_restrictions = permit_mynetworks permit_sasl_authenticated defer_unauth_destination
#修改 myhostname为如下的值:
myhostname = xnb.xyz
alias_maps = hash:/etc/aliases
alias_database = hash:/etc/aliases
#myorigin = /etc/mailname
#修改 myorigin 为如下的值:
myorigin = $myhostname
#mydestination = $myhostname, ithb.vip, ali-cd2, localhost.localdomain, localhost
mydestination = localhost
relayhost =
mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128
mailbox_size_limit = 0
recipient_delimiter = +
inet_interfaces = all
inet_protocols = all
#确保将邮件投递给 mysql 表中列出的虚拟域。
virtual_transport = lmtp:unix:private/dovecot-lmtp
#以下三项参数,告知 Postfix 配置虚拟域、用户和别名
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
创建main.cf里面最后加入的三项参数对应的文件。
创建/etc/postfix/mysql-virtual-mailbox-domains.cf,内容如下:
#数据库用户,密码,数据库名 按你的配置
user = mail
password = passowd
port = 3306
hosts = 127.0.0.1
dbname = mailserver
query = SELECT 1 FROM virtual_domains WHERE name='%s'
接着重启 postfix,并测试 postfix 能否找到域,如果成功返回 1:
service postfix restart
postmap -q xnb.xyz mysql:/etc/postfix/mysql-virtual-mailbox-domains.cf
创建/etc/postfix/mysql-virtual-mailbox-maps.cf,内容如下:
user = mail
password = password
port = 3306
hosts = 127.0.0.1
dbname = mailserver
query = SELECT 1 FROM virtual_users WHERE email='%s'
接着重启 postfix,并测试其能否找到邮箱地址,成功返回 1:
service postfix restart
postmap -q a@xnb.xyz mysql:/etc/postfix/mysql-virtual-mailbox-maps.cf
最后创建/etc/postfix/mysql-virtual-alias-maps.cf,内容如下:
user = mail
password = password
port = 3306
hosts = 127.0.0.1
dbname = mailserver
query = SELECT destination FROM virtual_aliases WHERE source='%s'
同样重启 postfix,验证能否正确找到别名,并返回:
service postfix restart
postmap -q b@xnb.xyz mysql:/etc/postfix/mysql-virtual-mailbox-maps.cf
修改/etc/postfix/master.cf
参考如下:
#
# Postfix master process configuration file. For details on the format
# of the file, see the master(5) manual page (command: "man 5 master" or
# on-line: http://www.postfix.org/master.5.html).
#
# Do not forget to execute "postfix reload" after editing this file.
#
# ==========================================================================
# service type private unpriv chroot wakeup maxproc command + args
# (yes) (yes) (no) (never) (100)
# ==========================================================================
smtp inet n - y - - smtpd
#smtp inet n - y - 1 postscreen
#smtpd pass - - y - - smtpd
#dnsblog unix - - y - 0 dnsblog
#tlsproxy unix - - y - 0 tlsproxy
# Choose one: enable submission for loopback clients only, or for any client.
#127.0.0.1:submission inet n - y - - smtpd
submission inet n - y - - smtpd
-o syslog_name=postfix/submission
-o smtpd_tls_security_level=encrypt
-o smtpd_sasl_auth_enable=yes
# -o smtpd_tls_auth_only=yes
# -o smtpd_reject_unlisted_recipient=no
-o smtpd_client_restrictions=$mua_client_restrictions
# -o smtpd_helo_restrictions=$mua_helo_restrictions
# -o smtpd_sender_restrictions=$mua_sender_restrictions
# -o smtpd_recipient_restrictions=
-o smtpd_relay_restrictions=permit_sasl_authenticated,reject
# -o milter_macro_daemon_name=ORIGINATING
# Choose one: enable smtps for loopback clients only, or for any client.
#127.0.0.1:smtps inet n - y - - smtpd
#smtps inet n - y - - smtpd
# -o syslog_name=postfix/smtps
# -o smtpd_tls_wrappermode=yes
# -o smtpd_sasl_auth_enable=yes
# -o smtpd_reject_unlisted_recipient=no
# -o smtpd_client_restrictions=$mua_client_restrictions
# -o smtpd_helo_restrictions=$mua_helo_restrictions
# -o smtpd_sender_restrictions=$mua_sender_restrictions
# -o smtpd_recipient_restrictions=
# -o smtpd_relay_restrictions=permit_sasl_authenticated,reject
# -o milter_macro_daemon_name=ORIGINATING
#628 inet n - y - - qmqpd
pickup unix n - y 60 1 pickup
cleanup unix n - y - 0 cleanup
qmgr unix n - n 300 1 qmgr
#qmgr unix n - n 300 1 oqmgr
tlsmgr unix - - y 1000? 1 tlsmgr
rewrite unix - - y - - trivial-rewrite
bounce unix - - y - 0 bounce
defer unix - - y - 0 bounce
trace unix - - y - 0 bounce
verify unix - - y - 1 verify
flush unix n - y 1000? 0 flush
proxymap unix - - n - - proxymap
proxywrite unix - - n - 1 proxymap
smtp unix - - y - - smtp
relay unix - - y - - smtp
-o syslog_name=postfix/$service_name
# -o smtp_helo_timeout=5 -o smtp_connect_timeout=5
showq unix n - y - - showq
error unix - - y - - error
retry unix - - y - - error
discard unix - - y - - discard
local unix - n n - - local
virtual unix - n n - - virtual
lmtp unix - - y - - lmtp
anvil unix - - y - 1 anvil
scache unix - - y - 1 scache
postlog unix-dgram n - n - 1 postlogd
#
# ====================================================================
# Interfaces to non-Postfix software. Be sure to examine the manual
# pages of the non-Postfix software to find out what options it wants.
#
# Many of the following services use the Postfix pipe(8) delivery
# agent. See the pipe(8) man page for information about ${recipient}
# and other message envelope options.
# ====================================================================
#
# maildrop. See the Postfix MAILDROP_README file for details.
# Also specify in main.cf: maildrop_destination_recipient_limit=1
#
maildrop unix - n n - - pipe
flags=DRXhu user=vmail argv=/usr/bin/maildrop -d ${recipient}
#
# ====================================================================
#
# Recent Cyrus versions can use the existing "lmtp" master.cf entry.
#
# Specify in cyrus.conf:
# lmtp cmd="lmtpd -a" listen="localhost:lmtp" proto=tcp4
#
# Specify in main.cf one or more of the following:
# mailbox_transport = lmtp:inet:localhost
# virtual_transport = lmtp:inet:localhost
#
# ====================================================================
#
# Cyrus 2.1.5 (Amos Gouaux)
# Also specify in main.cf: cyrus_destination_recipient_limit=1
#
#cyrus unix - n n - - pipe
# flags=DRX user=cyrus argv=/cyrus/bin/deliver -e -r ${sender} -m ${extension} ${user}
#
# ====================================================================
# Old example of delivery via Cyrus.
#
#old-cyrus unix - n n - - pipe
# flags=R user=cyrus argv=/cyrus/bin/deliver -e -m ${extension} ${user}
#
# ====================================================================
#
# See the Postfix UUCP_README file for configuration details.
#
uucp unix - n n - - pipe
flags=Fqhu user=uucp argv=uux -r -n -z -a$sender - $nexthop!rmail ($recipient)
#
# Other external delivery methods.
#
ifmail unix - n n - - pipe
flags=F user=ftn argv=/usr/lib/ifmail/ifmail -r $nexthop ($recipient)
bsmtp unix - n n - - pipe
flags=Fq. user=bsmtp argv=/usr/lib/bsmtp/bsmtp -t$nexthop -f$sender $recipient
scalemail-backend unix - n n - 2 pipe
flags=R user=scalemail argv=/usr/lib/scalemail/bin/scalemail-store ${nexthop} ${user} ${extension}
mailman unix - n n - - pipe
flags=FRX user=list argv=/usr/lib/mailman/bin/postfix-to-mailman.py ${nexthop} ${user}
5.配置 dovecot
首先编辑主配置文件/etc/dovecot/dovecot.conf:
首先确保下面一行是启用的:
!include conf.d/*.conf
然后在配置文件的最后加入如下配置,启用各协议:
#加入如下配置,启用各协议: protocols = imap lmtp pop3
修改/etc/dovecot/conf.d/10-mail.conf,确保存在以下两个配置:
mail_location = maildir:/var/mail/vhosts/%d/%n
mail_privileged_group = mail
上面的配置将邮件存放目录设置在/var/mail 中,因此将该文件夹的所属人改为 vmail/vmail.命令如下:
groupadd -g 5000 vmail
useradd -g vmail -u 5000 vmail -d /var/mail
chown -R vmail:vmail /var/mail
修改/etc/dovecot/conf.d/10-auth.conf。首先确保如下两个配置存在且值正确:
disable_plaintext_auth = yes
auth_mechanisms = plain login
然后修改配置以禁用系统用户登陆,并开启 mysql 支持,如下图所示:
#!include auth-system.conf.ext
!include auth-sql.conf.ext
修改/etc/dovecot/conf.d/auth-sql.conf.ext 文件,将内容改成下面的内容:
passdb {
driver = sql
args = /etc/dovecot/dovecot-sql.conf.ext
}
userdb {
driver = static
args = uid=vmail gid=vmail home=/var/mail/vhosts/%d/%n
}
我的文件参考:
# Authentication for SQL users. Included from 10-auth.conf.
#
# <doc/wiki/AuthDatabase.SQL.txt>
passdb {
driver = sql
# Path for SQL configuration file, see example-config/dovecot-sql.conf.ext
args = /etc/dovecot/dovecot-sql.conf.ext
}
# "prefetch" user database means that the passdb already provided the
# needed information and there's no need to do a separate userdb lookup.
# <doc/wiki/UserDatabase.Prefetch.txt>
#userdb {
# driver = prefetch
#}
userdb {
driver = sql
# args = /etc/dovecot/dovecot-sql.conf.ext
args = uid=vmail gid=vmail home=/var/mail/vhosts/%d/%n
}
# If you don't have any user-specific settings, you can avoid the user_query
# by using userdb static instead of userdb sql, for example:
# <doc/wiki/UserDatabase.Static.txt>
#userdb {
#driver = static
#args = uid=vmail gid=vmail home=/var/vmail/%u
#}
修改/etc/dovecot/dovecot-sql.conf.ext: 在大约33行加入:
driver = mysql
connect = host=127.0.0.1 port=3306 dbname=mailserver user=mail password=password
#换成你的数据库用户和密码
接着取消 default_pass_scheme 行的注释并改为 MD5
接着取消 password_query 行的注释并设置为以下信息:
password_query = SELECT email as user, password FROM virtual_users WHERE email='%u';
最后将/etc/dovecot的拥有者改为 vmail:dovecot
chown -R vmail:dovecot /etc/dovecot
chmod -R o-rwx /etc/dovecot
修改/etc/dovecot/conf.d/10-master.conf:
首先将 启用pop3s和imaps收信,如下图所示:
然后找到service lmtp将其修改为如下:
service lmtp {
unix_listener /var/spool/postfix/private/dovecot-lmtp {
mode = 0600
user = postfix
group = postfix
}
# Create inet listener only if you can't use the above UNIX socket
#inet_listener lmtp {
# Avoid making LMTP visible for the entire internet
#address =
#port =
#}
}
然后找到service auth将其内容修改为如下:
service auth {
unix_listener auth-userdb {
mode = 0600
user = vmail
#group =
}
# Postfix smtp-auth
unix_listener /var/spool/postfix/private/auth {
mode = 0666
user = postfix
group = postfix
}
# Auth process is run as this user.
#user = $default_internal_user
}
参考如图
最后找到service auth-worker改为如下内容:
service auth-worker {
# Auth worker process is run as root by default, so that it can access
# /etc/shadow. If this isn't necessary, the user should be changed to
# $default_internal_user.
user = vmail
}
最后要改的就是/etc/dovecot/conf.d/10-ssl.conf,以开启 ssl 认证.
首先将 ssl 参数改为 required:
ssl = required
然后设置 ssl 证书路径就 ok 了,就是之前用acme.sh部署的证书路:
# PEM encoded X.509 SSL/TLS certificate and private key. They're opened before
# dropping root privileges, so keep the key file unreadable by anyone but
# root. Included doc/mkcert.sh can be used to easily generate self-signed
# certificate, just make sure to update the domains in dovecot-openssl.cnf
ssl_cert = </etc/nginx/cert/xnb.xyz/cert.pem
ssl_key = </etc/nginx/cert/xnb.xyz/key.pem
如图
到这里所有的配置都 OK,重启 postfix,dovecot 后就可以用邮箱客户端(比如 foxmail)连接了。
service postfix restart
service dovecot restart
结束
配合一个邮件客户端看似很简单,实际上还是有很多坑的,看看上面那么多的配置项就知道了,一定要耐心。
如果无法登陆,可以看看 postfix 和 dovecot 的日志报错情况,再去修改。日志位置在/var/log
版权声明:
作者:xiaoniba
链接:https://blog.xiaoniba.com/2024/02/07/ubuntu%e8%87%aa%e5%bb%ba%e4%bc%81%e4%b8%9a%e9%82%ae%e7%ae%b1%ef%bc%88ipv6postfixdovecotmysql/
来源:小泥吧的博客
文章版权归作者所有,未经允许请勿转载。
共有 0 条评论