最近作了一個應用,須要用郵件發通知,可是免費的郵箱天天發信數量是有限制的,因此呢就想着搭建一個本身的郵件服務器,可以實現郵件的發送和接收便可,其中大概花了一個星期找資料,測試,終於成功了,寫個教程分享給你們。mysql
本教程基於 ubuntu 18.04(其餘的 linux 理論上也是能夠的,只是安裝的軟件包不同)。用到的主要軟件爲:postfix,dovecot,mysql.廢話很少說,下面是教程:linux
切換到 root 用戶下,執行如下命令:算法
apt update apt install postfix postfix-mysql dovecot-core dovecot-pop3d dovecot-imapd dovecot-lmtpd dovecot-mysql
安裝過程當中 postfix 會彈出提示:sql
這裏咱們選擇第二項:Internet Site。
接着會有以下提示:shell
這裏填入:test.com
數據庫
在域名提供商增長如下解析:ubuntu
test.com
指向 服務器IP
pop3.test.com
指向 服務器IP
smtp.test.com
指向 服務器IP
新建一個數據庫 mailserver,管理帳號爲:admin/123456vim
建立虛擬域表,做爲認證域。該表是郵件服務器用以接收郵件的域名:安全
-- 創建表 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,'test.com')
建立用戶表,用於用戶身份認證。bash
-- 建立用戶表 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'),'first@test.com'); insert into virtual_users values(2,1,md5('123456'),'second@test.com');
建立別名表.該表做用至關於當 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,'first@test.com','second@test.com')
生成 ssl 證書可參考這一篇https://www.jianshu.com/p/b47d862bceeb.爲 test.com 生成 ssl 證書,假設證書存放地址爲:
首選備份 postfix 的默認配置文件,而後編輯main.cf
cp /etc/postfix/main.cf /etc/postfix/main.cf.bak vim /etc/postfix/main.cf
註釋下面的配置:
而後加入以下的配置:
# 使用本身的ssl證書 smtpd_tls_cert_file=/etc/letsencrypt/live/test.com/fullchain.pem smtpd_tls_key_file=/etc/letsencrypt/live/test.com/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
修改 myhostname,myorigin 爲以下的值:
myhostname = test.com myorigin = $myhostname
修改 mydestination 值爲 localhost,以啓動 mysql 中的虛擬域。:
mydestination = localhost
在配置文件的最後加入如下行,確保將郵件投遞給 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
接下來建立上面最後加入的三項參數對應的文件。
建立/etc/postfix/mysql-virtual-mailbox-domains.cf
,內容以下:
user = admin password = 123456 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 test.com mysql:/etc/postfix/mysql-virtual-mailbox-domains.cf
建立/etc/postfix/mysql-virtual-mailbox-maps.cf
,內容以下:
user = admin password = 123456 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 first@test.com mysql:/etc/postfix/mysql-virtual-mailbox-maps.cf
最後建立/etc/postfix/mysql-virtual-alias-maps.cf
,內容以下:
user = admin password = 123456 port = 3306 hosts = 127.0.0.1 dbname = mailserver query = SELECT destination FROM virtual_aliases WHERE source='%s'
一樣重啓 postfix,驗證可否正確找到別名,並返回:
service postfix restart postmap -q first@test.com mysql:/etc/postfix/mysql-virtual-mailbox-maps.cf
若是響應使用 587 端口來進行俺的 smtp 通訊,需修改/etc/postfix/master.cf 文件:
取消如下行的註釋:
postfix 配置完畢,如今來配置 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 支持,以下圖所示:
修改/etc/dovecot/dovecot-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 }
修改/etc/dovecot/dovecot-sql.conf.ext
:
首選取消 driver 參數註釋並設置爲 mysql
driver = mysql
而後取消 connect 行註釋並設置爲以下內容:
connect = host=127.0.0.1 port=3306 dbname=mailserver user=admin password=123456
接着取消 default_pass_scheme 行的註釋並改成 MD5
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
:
首先將 imap-login , pop3-login 下第一個的 port 設置爲 0,以禁用非 ssl 加密的 imap 和 pop3 協議,以下圖所示:
而後找到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 /var/spool/postfix/private/auth { mode = 0666 user = postfix group = postfix } unix_listener auth-userdb { mode = 0600 user = vmail #group = } user = dovecot }
最後找到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 了,仍是用以前的 ssl 證書:
ssl_cert = </etc/letsencrypt/live/test.com/fullchain.pem ssl_key = </etc/letsencrypt/live/test.com/privkey.pem
到這裏全部的配置都 OK,重啓 postfix,dovecot 後就能夠用郵箱客戶端(好比 foxmail)鏈接了。
service postfix restart service dovecot restart
配合一個郵件客戶端看似很簡單,實際上仍是有不少坑的,看看上面那麼多的配置項就知道了,必定要耐心。
若是沒法登錄,能夠看看 postfix 和 dovecot 的日誌報錯狀況,再去修改。日誌位置在/var/log
注意:
被這個問題困擾了好幾天,未找到解決辦法,最後放棄.
目前不少主機廠商都不支持和其餘服務器的 25 端口通訊,已知的有(谷歌雲,阿里雲),這樣就致使在這些機器上搭建的 postfix 郵件服務器,沒法向其餘的外網郵箱發送郵件,由於沒法和其餘 smtp 服務器的 25 端口創建鏈接。貌似是爲了不有人惡意搭建郵件服務器向其餘的郵件服務器發送大量的垃圾郵件,從而致使此服務器 IP 被反垃圾郵件組織列入 SML。