上网不是目的。而且很多时候,一心想着如何上网,反而忽略了更重要的数据安全问题。
两年以前买了一台联想笔记本,送了1年的office365. Foxiang同学送的移动硬盘也送了1年的office365,于是就一直用着onedrive,用了两年。
期间dropbox的空间满了,amazon的云盘不再无限空间了,box用过一段时间,被公司放弃了。现在用的是Zoolz来做冷备份(后端还是amazon),下载文件需要等待24小时,不算是可以实时工作的版本。evernote国际版也在用,主要是翻译项目的协调。
于是渐渐将所有存储都转到了onedrive。因为翻译用MemoQ,只能在windows上工作,所以这样的方式倒也方便。
几天前终于收到微软的通知,office365要到期了,如果续费,每年99美元,1T存储,吸引力不大。但是更重要的是,完全倚靠微软或者谷歌或者百度阿里云之类的数字集权实体,实在是毫无安全性可言。而且,上传的数据越多,使用越久,依赖性越强,就越发难以更换系统了。想想看,一直用的gmail上保存着我12年前的邮件,大概有6千封邮件,涉及数千人。这些东西作为google的资产,会为这家公司作出多大的贡献呀。从前觉得这是我自己的历史记录,凡事都要保留,但如今却觉得这无疑是一项负资产,早晚还是删除了干净。
我现在也几乎不再在微信上或者任何社交媒体上发孩子们的照片,把超过数万张照片存在微软的服务器上,也完全没有任何实际的理由。
思前想后,于是横下一条心,将整个存储和邮件系统全部更换了。本文是为了自我存档和自我教育,如果你不是一个系统管理员,下面的内容不需要阅读了。
服务器
订购了一台OVH的低端品牌Kimsufi的独立服务器。个人使用,不需要太多的资源。我用的这台是4G内存,2T sata硬盘。
安装
-
一个干净的ubuntu 16. 升级为18.04。
注意:服务器和客户端不一样。我把/boot 和/swep以外的所有剩余硬盘空间都分配给根目录分区。因为作为服务器,/home不太需要空间,而其他目录则需要许多数据存储。 -
当然,关闭root远程登录,修改远程登录到随机端口,创建sudo用户,用putty生成密钥对,作好安全方面的预备。
-
修改时区。
sudo timedatectl set-timezone America/New_York
sudo timedatectl set-ntp on
postfix 邮件服务器
其实iredmail可能是更好的集成。但是,为了体会unix的pipeline设计之美好,还是有必要自己试试postfix的安装。
以下过程参考LinuxBabe所写非常详细的教程以及其他一些参考资料。
dns和hostname
- 因为我想使用[email protected]收发邮件,在dns上增加两条mx记录mail.eddyemma.com:
mail MX 1h 10 mail.eddyemma.com
@ MX 1h 10 mail.eddyemma.com
- 增加一条A记录,指向mail.eddyemma.com的工作ip。
- 因为我不想用[email protected]发邮件,所以修改服务器的hostname:
sudo hostnamectl set-hostname eddyemma.com
这样,postfix自动认为邮件是通过@eddyemma.com发出去的。
- 设置系统时间和时区。
这样,服务器就预备好了。
配置postfix
这一步很简单,几乎就是安装postfix而已。
sudo apt-get update
sudo apt-get install postfix -y
sudo systemctl start postfix
sudo systemctl enable postfix
现在就可以用sendmail发邮件了。如果需要测试,安装mailutils
sudo apt install mailutils
然后就可以用mail命令发邮件。
**注意:不要用root账户发邮件。**非常危险。
为此,修改Postfix的别名文件:
sudo vi /etc/postfix/aliases
增加这样两行(请自行将本文中所有eddyemma.com替换为你自己的域名):
abuse: [email protected], [email protected], postmaster
root: eddy
保存文件。然后运行:
sudo newaliases
配置TLS加密
TLS是基本的加密服务。没有TLS,邮件就是明文在网络上传输,几乎人人都可以读取。
为了配置TLS,需要一个数字证书。现在基本上大家都使用免费的电子前线基金会证书。
为了简便起见,我安装了apache服务器。虽然nginx速度快一些,但是在支持nextcloud上,略微有点麻烦。
sudo apt-get install apache2
sudo vim /etc/apache2/sites-available/mail.eddyemma.com.conf
然后随便设定一个网站,仅作认证用:
ServerName mail.eddyemma.com
DocumentRoot /var/www/mail.eddyemma.com
关闭文件。创建根目录:
sudo mkdir /var/www/mail.eddyemma.com
sudo chown www-data:www-data /var/www/mail.eddyemma.com -R
顺手给一个管理员的支持邮件:
echo “mail.eddyemma.com
support: [email protected]” > /var/www/mail.eddyemma.com/index.html
启动apache2:
sudo a2enmod rewrite
sudo a2enmod headers
sudo a2enmod env
sudo a2enmod dir
sudo a2enmod mime
sudo a2ensite mail.eddyemma.com.conf
sudo systemctl reload apache2
安装certbot脚本:
sudo apt install software-properties-common
sudo add-apt-repository ppa:certbot/certbot
sudo apt update
sudo apt install certbot python3-certbot-apache
安装证书:
sudo certbot –apache –agree-tos –redirect –hsts –email [email protected] -d mail.eddyemma.com
设定证书自动更新任务:
sudo crontab -e
在文件最后增加一行(前面两个数字是随机的分和小时,不要和我一样):
32 3 * * * certbot renew –post-hook “systemctl reload apache2” >> /var/log/letsencrypt/renew.log
##配置postfix的imap支持
为了支持邮件客户端,需要开放postfix的邮件提交服务submission.
可以将postfix理解为一个邮件服务调度中心,smtp负责邮政收发,而submission则像一个开放的邮局,允许人来投递邮件。
postfix的所有服务,都在一个叫master.cf的配置文件中。只要开发这个配置文件相应的服务,并用管道形式一个一个连起来,加上必要的参数即可。
sudo vim /etc/postfix/master.cf
找到被注释掉的#submission一行,取消注释,在下面加上收件参数(注意,参数以 -o 开始,前面至少要有一个空格或tab):
submission inet n – y – – smtpd
-o syslog_name=postfix/submission
-o smtpd_tls_security_level=encrypt
-o smtpd_tls_wrappermode=no
-o smtpd_sasl_auth_enable=yes
-o smtpd_relay_restrictions=permit_sasl_authenticated,reject
-o smtpd_recipient_restrictions=permit_mynetworks,permit_sasl_authenticated,reject
-o smtpd_sasl_type=dovecot
-o smtpd_sasl_path=private/auth
这个参数组说的是:用submission来收邮件,转交给smtpd处理。处理日志按照“postfix/submission”为标题,所有递交的邮件需要加密,需要认证,认证的类型是dovecot,unix管道是private/auth
submission的通讯端口是587, 这也是将来webmail客户端roundcube登录smtp的端口。
保存关闭master.cf文件。打开postfix主要的配置文件main.cf:
sudo vim /etc/postfix/main.cf
然后配置TLS参数(前两行是数字eff.org的签名文件)。:
smtpd_tls_cert_file=/etc/letsencrypt/live/mail.eddyemma.com/fullchain.pem
smtpd_tls_key_file=/etc/letsencrypt/live/mail.eddyemma.com/privkey.pemsmtpd_tls_security_level=may
#smtpd_tls_protocols = !SSLv2, !SSLv3 !TLSv1
smtpd_tls_loglevel = 1
smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scachesmtp_tls_security_level = may
smtp_tls_loglevel = 1
smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache
注意,
smtpd_tls_protocols = !SSLv2, !SSLv3 !TLSv1
这一行被我注释掉了。因为有些客户端使用TLS1.1,但是最新的ssl库已经不再支持这种加密方式,所以许多从旧的苹果或者outlook发来的邮件会收不到。
关于TLS1.0客户端的问题,使用TLS2.0/3.0缺省参数。
配置dovecot服务
postfix只能收发邮件,等于一个邮局。但是,现代的邮件客户端需要通过web或者通过pop3,imap等协议来访问邮局。
dovecot就是一个这样的加密邮件服务系统。
sudo apt install dovecot-core dovecot-imapd dovecot-lmtpd
注意,如果需要支持pop3,请增加dovecot-pop3.
这就是postfix和dovecot配置上的灵活之处。
接下来修改dovecot配置文件,增加支持的两种协议:
sudo vim /etc/dovecot/dovecot.conf
在文件中增加或者取消注释,或者补充协议:
protocols = imap lmtp
修改dovecot的邮箱配置文件,设定邮箱的目录:
sudo vim /etc/dovecot/conf.d/10-mail.conf
取消注释这一行:
mail_location = mbox:~/mail:INBOX=/var/mail/%u
保存关闭文件。分配dovecot读目录的权限:
sudo gpasswd -a dovecot mail
打开认证文件,设定TLS认证方式:
sudo vim /etc/dovecot/conf.d/10-auth.conf
取消注释下面一行(不允许明文登录):
disable_plaintext_auth = yes
修改下面的配置(使用邮件全名登录。例如:[email protected]. 采用plain或login登录授权):
auth_username_format = %n
auth_mechanisms = plain login
关闭上述文件。打开SSL/STL配置文件:
sudo vim /etc/dovecot/conf.d/10-ssl.conf
修改密钥文件,强制SSL认证:
ssl = required
ssl_cert = </etc/letsencrypt/live/mail.eddyemma.com/fullchain.pem
ssl_key = </etc/letsencrypt/live/mail.eddyemma.com/privkey.pem
关闭上述文件。打开dovecot主配置文件,设定unix管道,让dovecot可以和postfix通讯:
sudo vim /etc/dovecot/conf.d/10-master.conf
修改service auth
段(注意,前后两行本来已经存在。只需要修改unix_listener等四行即可):
service auth {
unix_listener /var/spool/postfix/private/auth {
mode = 0660
user = postfix
group = postfix
}
}
保存关闭上述文件。打开imap邮箱配置文件:
sudo vim /etc/dovecot/conf.d/15-mailboxes.conf
在每个邮箱上增加 auto = create
(注意,下面仅是示例。其他mailbox也需要自动创建。):
mailbox Trash {
auto = create
special_use = \Trash
}
最后,修改postfix的主参数配置文件,设定lmtp为本地邮件投递服务,可以分门别类将邮件投递到inbox, junk, trash等邮箱之中:
sudo vim /etc/postfix/main.cf
在文件最后增加两行:
virtual_transport = lmtp:unix:private/dovecot-lmtp
mailbox_transport = lmtp:unix:private/dovecot-lmtp
保存关闭文件。好了,重启服务就行了:
sudo systemctl restart dovecot
sudo systemctl restart postfix
关于lmtp的配置,放到后面再讨论。
至此,邮件客户端可以通过 imap/993, smtp/587登录服务器,查询和发送邮件了。
垃圾邮件过滤
如果配置自己的邮件系统仅仅是这样简单,我早就配置了。要不要配置自己的邮件服务器,争议的问题很多。比如:
反方意见
正方意见
更多正方意见
我考虑的益处:
1. 邮箱大小没有限制了。
2. 不用付费邮件服务了。
3. 不用翻墙了。
4. 隐私和安全都在自己控制之下。出问题谁也不怪了。事实上,我安装服务的时候的确出现很多问题,只有自己解决。
5. 贝叶斯模型!!!我可以自己写垃圾邮件过滤器了。
要解决的问题:
1. 垃圾邮件过滤。
2. 病毒防范。
3. 被人攻陷,变成垃圾邮件中继站。
下面就逐一解决(或者整体解决)。
发送邮件的身份证明问题
首先解决发送邮件的问题。现代社会,要发送一封电子邮件,必须证明三件事:
1. eddyemma.com这个域名确实是我的,这封邮件是从我的服务器发出来的,不是伪造的(spf策略)。
2. 我在dns上发布一个公钥,然后用私钥签名,任何邮件接受服务器都可以去验证这确实是我发出来的邮件,其他人不能伪造(DKIM签名)。
3. 使用DMARC政策,告诉别的邮件服务器,我已经实施了spf和dkim。如果收到的邮件没有这两样,他们可以如何处理和报告。
spf策略
在dns上增加一条记录:
TXT @ “v=spf1 mx ~all”
表示:spf版本是1.0,所有属于mx记录的机器和ip可以用eddyemma.com发送邮件,~all表示软过,也就是说如果不是从这些机器出来的邮件,只是标注警告,不要拒绝。
SPF语法详见这个文件
本地接受邮件的spf策略
相应地,本地接受服务也需要实施spf策略,验证一封邮件是否是真实从声称的服务器发出来的。
- 首先,安装spf-python策略服务:
sudo apt install postfix-policyd-spf-python
- 修改Postfix主服务调度文件:
sudo vim /etc/postfix/master.cf
在文件末尾增加下面两行:
policyd-spf unix – n n – 0 spawn
user=policyd-spf argv=/usr/bin/policyd-spf
保存关闭。修改主参数文件:
sudo vim /etc/postfix/main.cf
在文件最后加上这样几行。
policyd-spf_time_limit = 3600
smtpd_recipient_restrictions =
reject_unauth_destination,
check_policy_service unix:private/policyd-spf
增加其他垃圾过滤方式
既然已经写了smtpd_recipient_restrictions策略,不妨顺手再增加几个。
这些策略来自邮件过滤策略,包括病毒扫描和垃圾邮件过滤。
安装软件
- Amavisd-new:内容过滤调度服务。
- Spamassassin:贝叶斯网络学习系统。我的博士论文就研究过这个东东。
- ClamAV:病毒扫描服务。
- opendkim:dkim签名验证服务。
- python-policyd-spf:前面已经实施了的spf验证服务。
工作流程:
- postfix受到一封邮件。
- 对邮件头部进行opendkim和spf验证。
- Amavisd-new进行内容过滤。
- ClamAV 做病毒扫描。如果有病毒,直接统治postfix拒绝。
- 干净的邮件,交给Spamassassin做垃圾邮件分类。标注X-Header。
- 根据Spamassassin,dovecot的sieve服务将邮件递交到相应邮箱(inbox/junk)。
安装
sudo apt install amavisd-new spamassassin clamav-daemon pyzor razor
sudo apt install opendkim postfix-policyd-spf-python
安装附件解压程序,供病毒扫描用:
sudo apt install arj cabextract cpio lhasa nomarch pax rar unrar unzip zip p7zip
配置
ClamAV
病毒扫描,直接用缺省配置。只要可以和amavis互相访问即可。
sudo adduser clamav amavis
sudo adduser amavis clamav
Spamassassin
启动服务:
sudo vim /etc/default/spamassassin
设置ENABLED=1
,然后启动服务:
sudo systemctl start spamassassin.service
Amavisd-new
修改内容过滤模式:
sudo vim /etc/amavis/conf.d/15-content_filter_mode
开放病毒扫描和垃圾邮件分类:
use strict;
You can modify this file to re-enable SPAM checking through spamassassin
and to re-enable antivirus checking.
Default antivirus checking mode
Uncomment the two lines below to enable it
@bypass_virus_checks_maps = (
\%bypass_virus_checks, \@bypass_virus_checks_acl, \$bypass_virus_checks_re);Default SPAM checking mode
Uncomment the two lines below to enable it
@bypass_spam_checks_maps = (
\%bypass_spam_checks, \@bypass_spam_checks_acl, \$bypass_spam_checks_re);1; # insure a defined return
保存关闭。修改垃圾邮件分类参数:
sudo vim /etc/amavis/conf.d/20-debian_defaults
将$final_spam_destiny
设为D_DISCARD
修改下面的参数:
$sa_tag_level_deflt = -999; # add spam info headers if at, or above that level
$sa_tag2_level_deflt = 6.0; # add ‘spam detected’ headers at that level
$sa_kill_level_deflt = 21.0; # triggers spam evasive actions
$sa_dsn_cutoff_level = 4; # spam level beyond which a DSN is not sent
因为我们希望用eddyemma.com发送邮件,而不是用mail.eddyemma.com发送,修改 /etc/amavis/conf.d/50-user
sudo vim /etc/amavis/conf.d/50-user
$myhostname = ‘mail.eddyemma.com’;
@local_domains_acl = ( “eddyemma.com”, “cloud.eddyemma.com”, “mail.eddyemma.com” );
重新启动服务:
sudo systemctl restart amavis.service
sudo systemctl enable amavis.service
配置postfix
在main.cf
中增加内容过滤机制。
sudo postconf -e ‘content_filter = smtp-amavis:[127.0.0.1]:10024’
修改master.cf
:
在文件末尾增加:
smtp-amavis unix – – – – 2 smtp
-o smtp_data_done_timeout=1200
-o smtp_send_xforward_command=yes
-o disable_dns_lookups=yes
-o max_use=20127.0.0.1:10025 inet n – – – – smtpd
-o content_filter=
-o local_recipient_maps=
-o relay_recipient_maps=
-o smtpd_restriction_classes=
-o smtpd_delay_reject=no
-o smtpd_client_restrictions=permit_mynetworks,reject
-o smtpd_helo_restrictions=
-o smtpd_sender_restrictions=
-o smtpd_recipient_restrictions=permit_mynetworks,reject
-o smtpd_data_restrictions=reject_unauth_pipelining
-o smtpd_end_of_data_restrictions=
-o mynetworks=127.0.0.0/8
-o smtpd_error_sleep_time=0
-o smtpd_soft_error_limit=1001
-o smtpd_hard_error_limit=1000
-o smtpd_client_connection_count_limit=0
-o smtpd_client_connection_rate_limit=0
-o receive_override_options=no_header_body_checks,no_unknown_recipient_checks,no_milters
并告诉系统缺省的收件服务pickup
不要再做过滤。
在pickup
服务下,添加参数:
>
-o content_filter=
-o receive_override_options=no_header_body_checks
修改main.cf
,增加各种策略:
smtpd_helo_required = yes
disable_vrfy_command = yes
strict_rfc821_envelopes = yes
invalid_hostname_reject_code = 554
multi_recipient_bounce_reject_code = 554
non_fqdn_reject_code = 554
relay_domains_reject_code = 554
unknown_address_reject_code = 554
unknown_client_reject_code = 554
unknown_hostname_reject_code = 554
unknown_local_recipient_reject_code = 554
unknown_relay_recipient_reject_code = 554
unknown_sender_reject_code = 554
unknown_virtual_alias_reject_code = 554
unknown_virtual_mailbox_reject_code = 554
unverified_recipient_reject_code = 554
unverified_sender_reject_code = 554smtpd_sender_restrictions =
permit_mynetworks
permit_sasl_authenticated
reject_unknown_sender_domain
reject_unknown_reverse_client_hostname
reject_unknown_client_hostname
smtpd_helo_restrictions =
permit_mynetworks
permit_sasl_authenticated
reject_non_fqdn_helo_hostname
reject_unknown_helo_hostname
policyd-spf_time_limit = 3600
smtpd_recipient_restrictions =
reject_invalid_hostname,
reject_unknown_recipient_domain,
reject_unauth_pipelining,
permit_mynetworks,
permit_sasl_authenticated,
reject_unauth_destination,
check_policy_service unix:private/policyd-spf
reject_rbl_client multi.uribl.com,
reject_rbl_client dsn.rfc-ignorant.org,
reject_rbl_client dul.dnsbl.sorbs.net,
reject_rbl_client sbl-xbl.spamhaus.org,
reject_rbl_client bl.spamcop.net,
reject_rbl_client dnsbl.sorbs.net,
reject_rbl_client cbl.abuseat.org,
reject_rbl_client ix.dnsbl.manitu.net,
reject_rbl_client combined.rbl.msrbl.net,
reject_rbl_client rabl.nuclearelephant.com,
permitsmtpd_relay_restrictions = permit_mynetworks permit_sasl_authenticated defer_unauth_destination
rbl_client
是各个维护垃圾邮件列表的服务器。凡是命中的地址,直接拒绝。如果你有同伴用gmail的企业邮箱,不要用sorbs.net,因为sorbs会屏蔽google的ip,所以比如我就收不到mailbox.ciu.edu的邮件了。
重新启动服务:
sudo systemctl restart postfix.service
现在已经可以很好地控制垃圾邮件和病毒了。
opendkim签名认证
安装软件
sudo apt-get install opendkim opendkim-tools
配置
Greylists
灰名单是拒绝一次不认识的邮件服务器。一般的邮件服务器都会重发邮件,但是垃圾邮件服务器就多半会放弃了。这样会延迟几分钟收到邮件,但是收到垃圾邮件的可能性更小。
sudo apt install postgrey
修改main.cf
sudo vim /etc/postfix/main.cf
在smtpd_recipient_restrictions
一节下面插入下面一行:
check_policy_service inet:127.0.0.1:10023
好了。重启系统:
sudo systemctl restart postfix
其他参考文献
autoloean=no
学习机制
测试邮件系统
访问 邮件测试系统
网站会随机给出一个邮件地址。向这个地址发送一封真实的邮件,html格式,有比较长的内容。然后可以得到测试的报告。目前eddyemma.com的得分是10/10.
太长了。以后有时间再讨论webmail系统roundcube, pgp签名和加密,以及nextcloud配置问题。