用自己的服务器接受邮件是可以的,但是为了少点头疼的事,不要用自己的服务器发送邮件。这事一篇关于不要相信互联网上的你读到的内容的警示,也是一篇关于一种被全世界广泛采用的通信协议被一家大型广告技术公司捂死的内容,但首先这事一篇关于我给我妈妈发邮件的内容。

2016年的某个寒冷的早上。在像一个普通人一样使用了20年电子邮件以后我终于受不了了。我打算搭建自己的电子邮件服务器且打算把这件事做好,这样我就不必仍受使用别人的邮件服务器遇到的这些破事。啥事呢?垃圾邮件过滤!

有次我给我妈妈的一个 Gmail 邮箱回复邮件,一周后她打过来问我是否还活着因为她从来没有收到过我的邮件。然后我给我的邮件服务商同时也是我的网络服务商打电话说这事,他们告诉我说 Gmail 把他们的列入了几天黑名单因为有人用他们的服务器发送垃圾邮件。但是别担心现在已经解除拉黑了。当然了,也许只是今天解除了,或许明天我妈妈又不得不有一次担心了因为没人设置邮件退回通知。(有趣的是:随后网络服务商关闭了我的电子邮件账号由于他们期待收购而终止了 B2C 服务。)

你是否曾经注册某个网络服务并且好奇为啥要等两小时的验证邮件呢?这事以前对我来说是个普遍问题但是现在我知道了这是由一项叫做灰名单(graylisting)的反垃圾邮件技术导致的。灰名单的意思是来自未知服务器的邮件会被带上一个“请稍后再试”的注释被退回,然后发送服务器重试了一次一次又一次。几个小时以后接受服务器说:“试了这么多次,我猜你可能不是垃圾邮件发送者。”最终邮件进入了收件箱。好吧,所以,首先我们把光纤布满整个地球这样我们就可以在全世界发送几乎即时的消息了。然后就有人看着这个系统说:“我知道我们如何可以做的更好:让我们来创建一个可以把消息几小时的协议吧!”

个人邮件服务器

关于建立邮件服务器你首先要知道它不是一个邮件协议的事而是一个完整的系统的事。如果你想玩得高级一些的话大概有包括 DNS,DKIM,SFP,HELO等在内的12个其他我试图忘记也不想一一列举的协议。之后你又要经历一些莫名其妙的事情。如果你的邮件还没到达对方收件箱的话你得祈祷了,因为高冷的家伙(Gmail 和 Outlook)是不会告诉你哪儿有问题的。

所以我搞定了整个系统,然后用了一系列工具比如 DKIMValidator, mail-tester 和 Glockapps 来验证我的系统是否运行正常。我搞定了这些工具告诉我的每个可能影响系统的小问题,一直到不再有问题提示。尽管我这么努力了,但是我的邮件仍然被视为垃圾邮件过滤器拦截了。这让我觉得有点不可思议:我是独立域名和IP地址的唯一发件人,我只发送个人邮件,但是不知为什么这仍然被视为垃圾邮件了。

也许有人获得了访问我的服务器的权限,并在我不知情的情况下将其用于垃圾邮件? 我知道情况并非如此,因为我已经配置了DMARC,并且Gmail向我发送了DMARC报告,该报告显示了在我给妈妈发送电子邮件的那一天从我的服务器到Gmail的一封外发电子邮件。 我还定期检查我的域和IP是否不在垃圾邮件发送者黑名单中。

雨神,你听到我的祈祷了吗?

Outlook和Gmail都提供反馈邮件投递问题的地方,Gmail没有回应我。 Outlook回答我说“不关我的事”。 他们不会说为什么,但是他们很友好地提供了一些有用的提示,例如“确保您的电子邮件列表是最新的”。 我再次尝试向他们解释,我主要是给妈妈发送电子邮件,并且因为我不是垃圾邮件发送者而没有任何电子邮件列表。 他们“核实我的问题后”回答说,我应“确保取消订阅的过程可见”,以及他们认为对试图向亲人发送个人电子邮件的人有用的其他技巧。

邮件服务商们还提供了一些交互式工具来监视电子邮件的可传递性并帮助解决问题。 Gmail提供的服务称为Postmaster工具,而Outlook提供的垃圾邮件报告程序和智能网络数据服务程序。这些我都试了但是它们都没有什么数据反馈给我,因为我不是垃圾邮件发送者。

Gmail为那些有兴趣改善其Gmail邮件投递能力的人提供了一篇标题是《Spammer Bulk Sender Guidelines》的文章,这也表明了Gmail希望提高他们的邮件投递成功率。

这是一个小的电子邮件服务商叫做 Migadu 的引述:

某些情况下收件服务器只是因为我们的发件人数量少而故意拒绝了合规的电子邮件。 讽刺的是,合规的发送者确实就是这样。

等等,为什么有人这样做呢? AWS对此有一些说明:

如果您使用专用IP地址,则有责任通过发送一致且可预测的电子邮件量来保持发件人的声誉[...]您必须通过发送每天逐渐增加的电子邮件量来预热这些地址[...] IP地址已预热,您必须保持一致的发送模式[…]大多数Internet服务提供商(ISP)仅在给定IP地址从该地址接收大量邮件的情况下跟踪其信誉。

我敢肯定,您已经注意到了这种模式,但是无论如何,我都会加以说明:Gmail和Outlook并未从低流量发件人处发送明显合法的电子邮件。 可传递性工具,缓解措施和准则仅适用于垃圾邮件发送者大批量发送者。 在最大的电子邮件提供商是大型广告技术公司的反乌托邦中,这几乎是您所期望的。

放弃

在过去两年的时间里,我一直在积极使用自己的服务器从相同的域和IP发送电子邮件,但一段时间以来,我的电子邮件仍在Gmail的收件箱中发送。 然后有一段时间,我的电子邮件被放入垃圾邮件中,有时被彻底反弹,有时甚至在没有降落到垃圾邮件文件夹的情况下被接收和丢弃。 您永远无法知道Gmail将如何处理您的电子邮件。 前景更糟。 在过去的两年中,我再也无法将电子邮件发送到Outlook的收件箱。 甚至没有送给我的女友,后者经常从同一个地址给我发电子邮件。 是的,Outlook的垃圾邮件过滤在某种程度上甚至比Gmail还要差。

但是你做这件事吗?
是的,我确实做了。 是的,我确实加入了DNSWL。 是的,我确实配置了return-path标头以匹配回复标头。 是的,我确实告诉我的服务器,当它告诉其他服务器来自127.0.0.1时,这很顽皮。 是的,我确实配置了SPF 3.0,这甚至不是真实的东西,您甚至都不会注意到我刚刚完成了配置,因为电子邮件的可传递性是反乌托邦式的。

由于某些原因,当我讲这个故事时,许多人都难以置信。 常见的回答是“您是在喊大雨神的名字的同时做逆时针旋转这件事吗……”是的,我也尝试过顺时针旋转,以防万一可行,为什么呢? 这件事吗? 只是为了争辩,让我们假设我做错了什么。 假设可以从您的个人电子邮件服务器向Outlook和Gmail发送电子邮件。 如果这很难实现,那似乎是值得的努力吗?

我不是唯一遇到此问题的人。黑客新闻定期发布有关电子邮件可传递性的话题,很多人都在抱怨同一问题。这是一个这些线索似乎也使个人电子邮件传播者脱颖而出,说诸如“很容易发送电子邮件。只需做一件事……”即使有许多知名人士重复说,也不要相信您在互联网上看到的所有内容。这些人的意思很好,但是他们没有提供任何证据,这使我得出一个明显的结论,即他们实际上并未衡量其可交付性。他们只是觉得自己的电子邮件已送达。当偶发邮件丢失时,很容易假定目标收件人只是选择不回信。而且您知道吗,也许其中一个实际上拥有秘密的秘诀,可以通过圣少女IP块(幸运的兔子脚碰到的域)发送电子邮件,IP。我再次问:这似乎是值得的吗?

免责声明:反乌托邦地狱的笑话被约翰·奥利弗(John Oliver)偷走了。
Gmail的垃圾邮件过滤功能几乎总是让我通过电子邮件向妈妈发送电子邮件,真正的麻烦是通过电子邮件发送了新联系人。

本文描述的情况使用的操作系统如下所示,可能不适用于正在阅读本文的时候已经更新的版本或不同的主机商的不同配置:

#cat /proc/version 
Linux version 4.9.0-9-amd64 ([email protected]) (gcc version 6.3.0 20170516 (Debian 6.3.0-18+deb9u1) ) #1 SMP Debian 4.9.168-1+deb9u5 (2019-08-11)

#lsb_release -a
No LSB modules are available.
Distributor ID: Debian
Description:    Debian GNU/Linux 9.9 (stretch)
Release:        9.9
Codename:       stretch

当执行 sudo 的时候若收到如下提示:

sudo: unable to resolve host xxxxxx

则需要修改 /etc/hosts 文件 文件,把 xxxxxx 解析为 127.0.0.1 即可,即:


127.0.0.1    localhost xxxxxx

某些主机商(比如 Amazon AWS/Lightsail)的虚拟机(VM)上使用的 Debian 系统由于初始配置问题,不能修改 hosts 文件,会被告知如下信息:

#cat /etc/hosts

# Your system has configured 'manage_etc_hosts' as True.
# As a result, if you wish for changes to this file to persist
# then you will need to either
# a.) make changes to the master file in /etc/cloud/templates/hosts.tmpl
# b.) change or remove the value of 'manage_etc_hosts' in
#     /etc/cloud/cloud.cfg or cloud-config from user-data
#
127.0.1.1 ip-172-26-40-252.eu-west-1.compute.internal ip-172-26-40-252
127.0.0.1 localhost

# The following lines are desirable for IPv6 capable hosts
::1 ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
ff02::3 ip6-allhosts

但是查找上述文件(/etc/cloud/templates/hosts.tmpl 和 /etc/cloud/cloud.cfg 以及 /etc/init.d/cloud-config)的时候并没有 manage_etc_hosts 这个选项。

只要编辑 /etc/cloud/cloud.cfg.d/01_debian_cloud.cfg 并在其中加入 manage_etc_hosts: false 即可,如下:

#sudo vim /etc/cloud/cloud.cfg.d/01_debian_cloud.cfg 

apt_preserve_sources_list: true
manage_etc_hosts: false
system_info:
  default_user:
    name: admin
    sudo: ALL=(ALL) NOPASSWD:ALL
    shell: /bin/bash
    lock_passwd: True
    gecos: Debian
    groups: [adm, audio, cdrom, dialout, dip, floppy, netdev, plugdev, sudo, video]
    sudo: ["ALL=(ALL) NOPASSWD:ALL"]
    shell: /bin/bash

重启,即可修改 /etc/hosts 文件。

本来,对于 RHEL/CentOS 系统 mosh 应该在第三方源 EPEL 里面,可是当前(2019年7月)的时间节点正是 RHEL8 发布后,CentOS8 和 EPEL8 还没有发布。所以给 RHEL8 安装 mosh 则不能使用 EPEL 源了。

编译安装 mosh:

安装需要的工具软件:

#如果已有则会自动跳过
sudo dnf install gcc gcc-c++ autoconf automake libtool make unzip ncurses-devel git

安装 Google Protocol Buffers 库:
解决:“ configure: error: cannot find protoc, the Protocol Buffers compiler ”问题

#安装 Google Protocol Buffers 库
git clone https://github.com/protocolbuffers/protobuf.git
cd protobuf
git submodule update --init --recursive
./autogen.sh
./configure --prefix=/usr #参考安装指导“Hint on install location”部分,后面 mosh 则会找不到该库
make #可能需要等待较长时间
make check
make install
ldconfig #刷新共享库缓存

编译安装 Mosh:

git clone https://github.com/mobile-shell/mosh
cd mosh
./autogen.sh
./configure
make
make install

参考链接:

需要注意“Hit on install location”部分

https://github.com/protocolbuffers/protobuf/blob/master/src/README.md
https://fedoraproject.org/wiki/EPEL
https://fedoraproject.org/wiki/Infrastructure_2020/EPEL-8
https://github.com/mobile-shell/mosh/wiki/Build-Instructions
https://gist.github.com/palexander/2975305
https://gist.github.com/samsonjs/4076746
https://gist.github.com/andrewgiessel/4486779
https://gist.github.com/jaywilliams/c9ffab789b3f622abc932dd4cfaaeef5

openSUSE 15.1 于 2019年5月22日发布了。

openSUSE 15.1 中文 发行注记/发行说明: https://doc.opensuse.org/release-notes/x86_64/openSUSE/Leap/15.1/

备份现有源:

sudo cp -Rv /etc/zypp/repos.d /etc/zypp/repos.d.Old

替换 openSUSE 15.0 源为 openSUSE 15.1 源:

sudo sed -i 's/15.0/15.1/g' /etc/zypp/repos.d/*

如果复制上面的命令到控制台出现字符错误提示,那么手动输入。

刷新源:

sudo zypper --gpg-auto-import-keys ref

更新:

sudo zypper dup

最后重启完成。

参考来源: https://en.opensuse.org/SDB:System_upgrade

概要:这篇文章说的是在 Linux 上(包括 Ubuntu 和 CentOS)上安装 MongoDB 社区版(Community Edition)遇到的几个坑。

软件包的区别

对于 Ubuntu 来说:先看官方的一个说明片段。【这里】

【mongodb】是由 Ubuntu 维护的,不是由 MongoDB 公司维护的软件包,这个软件包和官方的 mongodb-org 冲突。这个软件包大多数情况下当前都不是最新的正式版,要检查非官方的 mongodb 包是否已经安装在你的系统上,使用如下命令:

sudo apt list --installed | grep mongodb

如果已经安装了非官方的软件包并且需要卸载,使用如下命令:

sudo apt remove mongodb
sudo apt purge mongodb

【mongodb-org】是由 MongoDB 公司维护的,并且始终保持为当前数据库的最新正式版。

对于 CentOS 来说:

软件包的区别和 Ubuntu 类似。

名称区别区别

对于官方的 【mongodb-org】 包来说,一系列名称都使用的是【mongod】

对于非官方的【mongodb】包来说,一些列名称都使用的是【mongodb】

管理方式区别

对于非官方源安装的,使用如下命令管理:

sudo systemctl enable mongodb
sudo systemctl disable mongodb
sudo systemctl start mongodb
sudo systemctl restart mongodb
sudo systemctl stop mongodb
sudo systemctl status mongdob

对于官方源安装的,使用如下命令管理:

sudo systemctl enable mongod
sudo systemctl disable mongod
sudo systemctl start mongod
sudo systemctl restart mongod
sudo systemctl stop mongod
sudo systemctl status mongdo

启动方式

无论使用何种方式安装何种源的何种版本,对于非图形界面的 CUI 界面而言启动 mongo-shell 都使用的是 【mongo】这个名称,而非其他!!!而非其他!!!而非其他!!!(重要的话说三遍!!!)(特别重要!!!)

错误提示:Failed to unlink socket file /tmp/mongodb-27017.sock Unknown error

网上的文章别人会告诉你是 root 用户和非 root 用户的区别,让你删除这个文件云云。nope,因为你可能使用了【mongod】打算启动 shell,换个启动名称试试试试【mongo】没准就没了。这个文件,当然也不用删~因为你每次删除,以后更新或者重新启动,它都可能生成这样一个文件(你觉得 MongoDB 没有考虑到这个问题?)

错误提示:Failed to set up listener: SocketException: Address already in use

当你出现了上一个临时文件的错误提示,然后删除了那个临时文件后满怀信心重新启动的时候,又可能蹦出了这个错误。网上告诉你是字面意思,已经启动使用中了,让你去使用 kill 杀掉一下再重新启动云云。nope,因为你可能使用了【mongod】打算启动 shell,换个启动名称试试试试【mongo】没准就没了。

卸载

使用上述管理方式里的方式停止数据库实例

sudo systemctl stop mongod

删除相关软件包

# Ubuntu
sudo apt purge mongodb-org*
# CentOS
sudo yum erase $(rpm -qa | grep mongodb-org)

删除相关目录(注意备份)

# Ubuntu
sudo rm -r /var/log/mongodb
sudo rm -r /var/lib/mongodb
# CentOS
sudo rm -r /var/log/mongodb
sudo rm -r /var/lib/mongo