Linux命令行邮件收发:邮件通信与snail
真得好好学学电子邮件的工作原理
最近因为工作需要,需要使用Linux
收发一下电子邮件。想想一下系统管理员能够将负载信息等内容通过邮件发送过来,或者是在模型训练结束后发送邮件提醒,就会很有用。
本来以为会很简单,但是没想到,不做不知道一做吓一跳,简简单单的电子邮件收发,里面还藏着不少知识,只不过因为平时太常使用,以至于我们忽略了电子邮件背后的工作原理。
身为计算机从业人员,还真得学学电子邮件的原理。
1. 邮件通信模型
A. 从TCP协议说起
两台计算机如果需要通信,那么需要双方互相知道对方的IP地址,这样才能建立连接。而两台计算机之间经常需要可靠的、像管道一样的连接,但是IP层不提供这样的流机制,而是提供不可靠的包交换。
所以在此基础上,就出现了TCP协议,即传输控制协议(英语:Transmission Control Protocol,缩写:TCP)。TCP协议是一种面向连接的、可靠的、基于字节流的传输层通信协议。所谓面向连接的意思是指,使用TCP协议进行通信的双方在进行数据传输之前,发送方和接收方需要先建立一个连接。
因此,一般的网络服务程序在传输信息时就像拨打电话,需要双方同时保持在线。但是在电子邮件系统中,双方不需要同时在线。用户发送邮件后不必等待投递工作完成(即对方收到邮件)即可下线。如果邮件的接收方若在发送方发送邮件时离线,则在上线后还是能够看到发送方发来的邮件。
所以TCP协议实际上是没有办法满足邮件的使用场景的。
B. 解决方案:邮件服务器
为了解决TCP协议需要保证双方同时在线而无法实现邮件通信这一问题,我们在邮件发送方、接收方之外,引入一个第三方角色:邮件服务器,来实现邮件通信。
邮件服务器会一直保持在线状态。所以相比于用户自己接收、发送邮件,引入邮件服务器之后:
- 发送邮件时,用户把需要发送的邮件委托给邮件服务器,由邮件服务器进行发送处理
- 此外,用户还在邮件服务器设置一个信箱,由邮件服务器代替用户接受邮件
所以我用的QQ邮箱(xxxxxxxxxx@qq.com
)给我的GMail邮箱(xxxxxxxxx@gmail.com
)发送一封邮件,实际上是由QQ邮箱的邮件服务器把我们的邮件投递给GMail邮箱的邮件服务器。
因此,我们电脑上使用的各种邮箱APP,例如OutLook、Thunderbird,亦或者网页版的QQ邮箱、GMail邮箱,本质上都是一个前端应用,每次用户登录之后会向邮箱服务器发送请求,以获取保存在邮件服务器上的用户邮箱中的信件。
考虑到发送者和接受者的邮箱服务器可能不是同一个,因此发送邮件的全过程为:
- 发送方通过前端应用将邮件发送给发送方的邮件服务器
- 发送方邮件服务器将邮件发送给接收方邮件服务器
- 接收方邮件服务器保存邮件
- 接收方登录前端应用后,会主动去接收方邮件服务器获取收到的邮件
在这个过程中,邮件服务器充当了邮局的角色。
C. 几个术语:MUA、MDA、MTA
上面我们介绍了邮件发送的全过程,下面我们介绍其中的几个角色的专业术语(未来我们会使用这些术语):
邮件用户代理
(Mail User Agent
):MUA
是邮件系统中的用户端应用程序,也称为邮件客户端
,即我们使用的OutLook、网页版QQ邮箱、手机上的网易邮箱大师等APP。它提供了用户与邮件服务器交互的界面,用于创建、发送、接收和管理电子邮件。常见的MUA
包括Outlook、Thunderbird、Gmail等。当用户编写邮件并点击发送时,MUA
负责将邮件发送到MTA
。邮件传输代理
(Mail Transfer Agent
):MTA
是负责电子邮件在网络中的传输的中间代理,也称为邮件服务器
。它接收来自MUA
的邮件,并负责将邮件传递给下一个MTA
或最终的MDA
(需要MDA
主动请求)。MTA
使用SMTP
协议来进行邮件的传输,通过在不同的邮件服务器之间转发邮件,最终将邮件发送到目标服务器。常见的MTA
包括Sendmail、Postfix、Exim等。邮件投递代理
(Mail Delivery Agent
)
我们上面介绍的邮件投递的过程中实际上不包含MDA
,所以这里额外介绍下MDA
。
用户需要再MTA
中设置一个信箱,但是这个信箱的大小是有限的,所以每次用户通过MUA
登录之后,MUA
会把邮件的内容和附件等等数据下载到用户的计算机中。这样就避免了用户数据保存在邮件服务器中,即MTA
中。
因此,在用户计算机上额外多添加了一个软件,即MDA
,其作用就是把来自于MTA
的邮件保存到本地的收件箱中。这样就是解耦了用户交互和数据保存:
- 与用户的交互交给
MUA
- 用户数据的保存和上传(即传输邮件给邮件服务器和从邮件服务器下载邮件)交给
MDA
D. SMTP协议、POP3协议和IAMP4协议
我们上面只介绍了邮件通信模型中的几个角色,我们没有介绍几个角色间通信所使用到的协议。但凡通信,必有协议。因为协议规定了双方通信的格式,只有双方遵守统一的约定,才能够正确的传输信息。
邮件通信模型中涉及三种通信类型:
MUA
发送邮件给MTA
:即发信人发信给发送方邮件服务器MTA
发送邮件给MTA
:即发送方邮件服务器发信给收信方邮件服务器MTA
发送邮件给MUA
/MUA
从MTA
收取邮件:即收信方从收信方邮件服务器获取邮件
其中使用到了三种通信协议:
MUA
发信给MTA
、MTA
发信给MTA
:使用SMTP
协议MTA
发信给MUA
:使用POP3
协议或者IMAP4
协议
POP3
协议和IMAP4
协议的本质区别在于邮件保存在谁那里,到底是保存在邮件服务器还是收信方:
POP3
协议允许邮件客户端从邮件服务器上下载邮件,并将邮件从服务器上删除(可选),即邮件存储于收信方。POP3通常使用110端口。IMAP
协议允许邮件客户端在邮件服务器上管理邮件的状态,如标记已读、删除等,即邮件存储于发信方。IMAP通常使用143端口。
2. 常用软件
Linux
平台上,常用的软件和对应的角色如下:
可以看到:
- 如果我们想在命令行中使用QQ邮箱发送邮件出去,那么使用
Mail Client
中的程序即可 - 如果我们想有自己的邮件服务器,即能以
jackwang@MyMailServer.com
的邮箱发送出去,那么需要下载、配置Sender Mail Server
中的程序 - 接受同理
一般来说,企业会为自己假设一个邮箱服务器,从而实现企业邮箱功能。例如我们自己创建了一家名字叫做Coax
的公司,我们未来想要使用xxxx@coax.com
的企业邮箱:
- 招聘邮件使用
career@coax.com
的邮箱发送 - 工作邮件使用
work@coax.com
的邮箱发送 - ……
这样的话就需要使用Sendmail
这样的程序了。但是我们这里只需要能够命令行收发QQ邮件、163邮件之类的。所以我们只需要Mail Client
即可。
3. 使用Linux收发邮件
我们前面介绍了邮件通信模型,使用Linux
收发邮件其实本质上就是我们在Linux
上下载一个基于命令行的MUA
即可。然后因为MUA
需要查看保存在MTA
上的邮件,所以MUA
往往还需要登录到MTA
的用户信息中。
为此,通常MTA
会提供一个授权码,使用授权码MUA
就可以使用第三方的MUA
连接到MTA
A. 获得授权码
不同的邮箱获得授权码的方式不同。这里以QQ邮箱为例,一般都是大差不差的
B. 使用s-nail发送邮件
s-nail
是Ubuntu 20.04
中发送邮件比较好用的客户端,后面我们使用这个客户端来发送邮件
网上有不少过时文章介绍使用
mailx
或者heirloom-mailx
,这个已经过时了,不用考虑
A. 安装
sudo apt update & sudo apt install s-nail -y
B. 配置s-nail
sudo vim /etc/s-nail.rc
添加如下内容:
set from="xxx@qq.com" # 发信人的QQ邮箱
set smtp="smtps://smtp.qq.com:465" # QQ邮箱邮件服务器地址
set smtp-auth-user="xxx@qq.com" # QQ邮箱邮件服务器中的账号,就是QQ邮箱
set smtp-auth-password="xxx" # QQ邮箱设置->账户->开启“POP3/SMTP服务”生成得到的
set smtp-auth=login
C. 发送邮件
后面的是收件人邮箱,这里是测试,就是我自己给自己发邮件
ps aux | s-nail -s "系统当前进程信息" 2232123545@qq.com
最后成功收到邮件: