Postfix:转发邮件配置启用SSL/TLS

2024-03-25 16:58

本文主要是介绍Postfix:转发邮件配置启用SSL/TLS,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Postfix:转发邮件配置启用SSL/TLS

Postfix Version:

[root@localhost postfix]# postconf -d | grep mail_version
mail_version = 2.6.6

Postfix在收到一封邮件后,会将其通过MTA进行转发到指定邮箱服务器。

默认情况下,Postfix在转发邮件时并不适用SSL/TLS,而是传统的TCP+SMTP(Port:25)。

如何配置Postfix使其在转发邮件时自动探测目的邮件服务器是否支持SSL/TLS?并尽可能用TLS/SSL呢?

查阅Postfix官网:

http://www.postfix.org/postconf.5.html#smtp_tls_security_level
http://www.postfix.org/TLS_README.html#client_tls_may


smtp_tls_security_level (default: empty)
默认是empty,并非”may”。

when a non-empty value is specified, this overrides the obsolete parameters smtp_use_tls, smtp_enforce_tls, and smtp_tls_enforce_peername.
有两个信息:
1) smtp_use_tls等配置项是已废弃的;
2)配置项优先级smtp_tls_security_level高于已废弃的smtp_tls_security_level等配置项;

Use TLS if this is supported by the remote SMTP server, otherwise use plaintext.
smtp_tls_security_level配置为may时,若remote SMTP server支持TLS/SSL,则使用TLS/SSL传输,否则使用传统的SMTP+TCP。

When TLS handshakes fail, the connection is retried with TLS disabled.
当TLS握手失败时,将使用without TLS/SSL重试。

The SMTP transaction is encrypted if the STARTTLS ESMTP feature is supported by the server. Otherwise, messages are sent in the clear.

With opportunistic TLS, mail delivery continues even if the server certificate is untrusted or bears the wrong name.
即使remote SMTP server SSL/TLS证书不被信任,Postfix也会继续发送邮件。

注:

smtp_use_tls (default: no)
This feature is available in Postfix 2.2 and later. With Postfix 2.3 and later use smtp_tls_security_level instead.

smtp_use_tls 是已废弃的配置项,请尽可能使用smtp_tls_security_level。


默认Postfix配置文件为:

/etc/postfix/main.cf

注:重启Postfix,配置文件生效。

修改配置文件,在末尾添加:

smtp_tls_security_level = may

重启Postfix:

[root@localhost postfix]# service postfix restart
Shutting down postfix:                                     [  OK  ]
Starting postfix:                                          [  OK  ]

OVER!!!

以下内容为使用libcurl发送邮件自测过程,如不感兴趣可忽略:

在未开启(smtp_tls_security_level = may)时:

Code:

#include <stdio.h>
#include <string.h>
#include <curl/curl.h>#define FROM_ADDR    "jiangjinwang@ebupt.com"
#define TO_ADDR      "1158801411@qq.com"#define FROM_MAIL "jiangjinwang@ebupt.com"
#define TO_MAIL   "1158801411@qq.com"static const char *payload_text[] = {"To: " TO_MAIL "\r\n","From: " FROM_MAIL "\r\n","Subject: SMTP example message\r\n","\r\n", /* empty line to divide headers from body, see RFC5322 */"The body of the message starts here.\r\n","\r\n","It could be a lot of lines, could be MIME encoded, whatever.\r\n","Check RFC5322.\r\n",NULL
};struct upload_status {int lines_read;
};static size_t payload_source(void *ptr, size_t size, size_t nmemb, void *userp)
{struct upload_status *upload_ctx = (struct upload_status *)userp;const char *data;if((size == 0) || (nmemb == 0) || ((size*nmemb) < 1)) {
    return 0;}data = payload_text[upload_ctx->lines_read];if(data) {size_t len = strlen(data);memcpy(ptr, data, len);upload_ctx->lines_read++;
return len;}
return 0;
}int main(void)
{CURL *curl;CURLcode res = CURLE_OK;struct curl_slist *recipients = NULL;struct upload_status upload_ctx;upload_ctx.lines_read = 0;curl = curl_easy_init();if(curl) {/* This is the URL for your mailserver */curl_easy_setopt(curl, CURLOPT_URL, "smtp://localhost:25");/* Note that this option isn't strictly required, omitting it will result* in libcurl sending the MAIL FROM command with empty sender data. All* autoresponses should have an empty reverse-path, and should be directed* to the address in the reverse-path which triggered them. Otherwise,* they could cause an endless loop. See RFC 5321 Section 4.5.5 for more* details.*/curl_easy_setopt(curl, CURLOPT_MAIL_FROM, FROM_ADDR);/* Add two recipients, in this particular case they correspond to the* To: and Cc: addressees in the header, but they could be any kind of* recipient. */recipients = curl_slist_append(recipients, TO_ADDR);curl_easy_setopt(curl, CURLOPT_MAIL_RCPT, recipients);/* We're using a callback function to specify the payload (the headers and* body of the message). You could just use the CURLOPT_READDATA option to* specify a FILE pointer to read from. */curl_easy_setopt(curl, CURLOPT_READFUNCTION, payload_source);curl_easy_setopt(curl, CURLOPT_READDATA, &upload_ctx);curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L);/*DEBUG*/curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);/* Send the message */res = curl_easy_perform(curl);/* Check for errors */if(res != CURLE_OK)fprintf(stderr, "curl_easy_perform() failed: %s\n",curl_easy_strerror(res));/* Free the list of recipients */curl_slist_free_all(recipients);/* curl won't send the QUIT command until you call cleanup, so you should* be able to re-use this connection for additional messages (setting* CURLOPT_MAIL_FROM and CURLOPT_MAIL_RCPT as required, and calling* curl_easy_perform() again. It may not be a good idea to keep the* connection open for a very long time though (more than a few minutes* may result in the server timing out the connection), and you do want to* clean up in the end.*/curl_easy_cleanup(curl);}
return (int)res;
}

编译 && 执行:

[ismp@localhost ssl3]$ gcc -o ssl ssl.c -lcurl
[ismp@localhost ssl3]$ ./ssl

由于libcurl开启了DEBUG模式,所以有DEBUG信息,便于观察:

* Rebuilt URL to: smtp://localhost:25/
*   Trying ::1...
* TCP_NODELAY set
* Connected to localhost (::1) port 25 (#0)
< 220 localhost.localdomain ESMTP Postfix
> EHLO localhost
< 250-localhost.localdomain
< 250-PIPELINING
< 250-SIZE 10240000
< 250-VRFY
< 250-ETRN
< 250-ENHANCEDSTATUSCODES
< 250-8BITMIME
< 250 DSN
> MAIL FROM:<jiangjinwang@ebupt.com>
< 250 2.1.0 Ok
> RCPT TO:<1158801411@qq.com>
< 250 2.1.5 Ok
> DATA
< 354 End data with <CR><LF>.<CR><LF>
< 250 2.0.0 Ok: queued as AC68A7F996
* Connection #0 to host localhost left intact

查看Postfix日志:

/var/log/maillog

Mar  5 14:26:28 localhost postfix/smtpd[4536]: connect from localhost[::1]
Mar  5 14:26:28 localhost postfix/smtpd[4536]: AC68A7F996: client=localhost[::1]
Mar  5 14:26:28 localhost postfix/cleanup[4539]: AC68A7F996: message-id=<20180305222628.AC68A7F996@localhost.localdomain>
Mar  5 14:26:28 localhost postfix/qmgr[4444]: AC68A7F996: from=<jiangjinwang@ebupt.com>, size=488, nrcpt=1 (queue active)
Mar  5 14:26:28 localhost postfix/smtpd[4536]: disconnect from localhost[::1]
Mar  5 14:26:28 localhost postfix/smtp[4540]: connect to mx3.qq.com[240e:ff:f040:28::f]:25: Network is unreachable
Mar  5 14:26:29 localhost postfix/smtp[4540]: AC68A7F996: to=<1158801411@qq.com>, relay=mx3.qq.com[183.57.48.35]:25, delay=0.93, delays=0.02/0/0.15/0.76, dsn=2.0.0, status=sent (250 Ok: queued as ) Mar  5 14:26:29 localhost postfix/qmgr[4444]: AC68A7F996: removed

看到“Sent”,OK!!!

抓包看下:

[root@localhost ~]# tcpdump port 25 -i eth0 -s 0 -w withoutSSL.cap

用wireshark打开cap包:

withoutSSL.cap

在开启(smtp_tls_security_level = may)时:

代码不变,只修改/etc/postfix/main.cf配置文件 && 重启Postfix,然后测试:

libcurl的DEBUG输出:

* Rebuilt URL to: smtp://localhost:25/
*   Trying ::1...
* TCP_NODELAY set
* Connected to localhost (::1) port 25 (#0)
< 220 localhost.localdomain ESMTP Postfix
> EHLO localhost
< 250-localhost.localdomain
< 250-PIPELINING
< 250-SIZE 10240000
< 250-VRFY
< 250-ETRN
< 250-ENHANCEDSTATUSCODES
< 250-8BITMIME
< 250 DSN
> MAIL FROM:<jiangjinwang@ebupt.com>
< 250 2.1.0 Ok
> RCPT TO:<1158801411@qq.com>
< 250 2.1.5 Ok
> DATA
< 354 End data with <CR><LF>.<CR><LF>
< 250 2.0.0 Ok: queued as B10387F996
* Connection #0 to host localhost left intact

Postfix Logs(/var/log/maillog):

Mar  5 14:35:20 localhost postfix/smtpd[4704]: connect from localhost[::1]
Mar  5 14:35:20 localhost postfix/smtpd[4704]: B10387F996: client=localhost[::1]
Mar  5 14:35:20 localhost postfix/cleanup[4707]: B10387F996: message-id=<20180305223520.B10387F996@localhost.localdomain>
Mar  5 14:35:20 localhost postfix/qmgr[4700]: B10387F996: from=<jiangjinwang@ebupt.com>, size=488, nrcpt=1 (queue active)
Mar  5 14:35:20 localhost postfix/smtpd[4704]: disconnect from localhost[::1]
Mar  5 14:35:20 localhost postfix/smtp[4708]: connect to mx3.qq.com[240e:ff:f040:28::f]:25: Network is unreachable
Mar  5 14:35:20 localhost postfix/smtp[4708]: certificate verification failed for mx3.qq.com[183.57.48.35]:25: untrusted issuer /C=US/O=GeoTrust Inc./CN=GeoTrust Global CA
Mar  5 14:35:21 localhost postfix/smtp[4708]: B10387F996: to=<1158801411@qq.com>, relay=mx3.qq.com[183.57.48.35]:25, delay=1, delays=0.01/0.03/0.32/0.67, dsn=2.0.0, status=sent (250 Ok: queued as )
Mar  5 14:35:21 localhost postfix/qmgr[4700]: B10387F996: removed

看到”certificate verification failed”失败没关系,Postfix即使证书不信任,但依然会发送邮件。

看到Sent,已发送邮件成功(到目的邮箱服务器)。

抓包看下:

tcpdump host 183.57.48.35 -i eth0 -s 0 -w withSSL.cap

withSSL.cap

看到了吗?协议是TLSv1.2。这个时候已经无法通过抓包来获取邮件明文内容!

其实,libcurl的DEBUG信息在本测试中并无关紧要,是由于libcurl的DEBUG信息,仅指明了libcurl(client)和本地邮局Postfix(server)之间的交互过程,无论Postfix是否配置转发启用SSL/TLS配置项,这个过程都是不变的。

libcurl(client MUA)–>postfix(server MTA)–>目的邮箱服务器(MTA,例如QQ企业邮箱,163,etc)–>MUA

这篇关于Postfix:转发邮件配置启用SSL/TLS的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/845645

相关文章

最新版IDEA配置 Tomcat的详细过程

《最新版IDEA配置Tomcat的详细过程》本文介绍如何在IDEA中配置Tomcat服务器,并创建Web项目,首先检查Tomcat是否安装完成,然后在IDEA中创建Web项目并添加Web结构,接着,... 目录配置tomcat第一步,先给项目添加Web结构查看端口号配置tomcat    先检查自己的to

Servlet中配置和使用过滤器的步骤记录

《Servlet中配置和使用过滤器的步骤记录》:本文主要介绍在Servlet中配置和使用过滤器的方法,包括创建过滤器类、配置过滤器以及在Web应用中使用过滤器等步骤,文中通过代码介绍的非常详细,需... 目录创建过滤器类配置过滤器使用过滤器总结在Servlet中配置和使用过滤器主要包括创建过滤器类、配置过滤

Ubuntu 怎么启用 Universe 和 Multiverse 软件源?

《Ubuntu怎么启用Universe和Multiverse软件源?》在Ubuntu中,软件源是用于获取和安装软件的服务器,通过设置和管理软件源,您可以确保系统能够从可靠的来源获取最新的软件... Ubuntu 是一款广受认可且声誉良好的开源操作系统,允许用户通过其庞大的软件包来定制和增强计算体验。这些软件

在 VSCode 中配置 C++ 开发环境的详细教程

《在VSCode中配置C++开发环境的详细教程》本文详细介绍了如何在VisualStudioCode(VSCode)中配置C++开发环境,包括安装必要的工具、配置编译器、设置调试环境等步骤,通... 目录如何在 VSCode 中配置 C++ 开发环境:详细教程1. 什么是 VSCode?2. 安装 VSCo

Django中使用SMTP实现邮件发送功能

《Django中使用SMTP实现邮件发送功能》在Django中使用SMTP发送邮件是一个常见的需求,通常用于发送用户注册确认邮件、密码重置邮件等,下面我们来看看如何在Django中配置S... 目录1. 配置 Django 项目以使用 SMTP2. 创建 Django 应用3. 添加应用到项目设置4. 创建

在Spring中配置Quartz的三种方式

《在Spring中配置Quartz的三种方式》SpringQuartz是一个任务调度框架,它允许我们定期执行特定的任务,在Spring中,我们可以通过多种方式来配置Quartz,包括使用​​@Sche... 目录介绍使用 ​​@Scheduled​​ 注解XML 配置Java 配置1. 创建Quartz配置

Kibana的安装和配置全过程

《Kibana的安装和配置全过程》Kibana是一个开源的数据分析和可视化平台,它与Elasticsearch紧密集成,提供了一个直观的Web界面,使您可以快速地搜索、分析和可视化数据,在本文中,我们... 目录Kibana的安装和配置1.安装Java运行环境2.下载Kibana3.解压缩Kibana4.配

tomcat在nginx中的配置方式

《tomcat在nginx中的配置方式》文章介绍了如何在Linux系统上安装和配置Tomcat,并通过Nginx进行代理,首先,下载并解压Tomcat压缩包,然后启动Tomcat并查看日志,接着,配置... 目录一、下载安装tomcat二、启动tomcat三、配置nginx总结提示:文章写完后,目录可以自动

Zookeeper安装和配置说明

一、Zookeeper的搭建方式 Zookeeper安装方式有三种,单机模式和集群模式以及伪集群模式。 ■ 单机模式:Zookeeper只运行在一台服务器上,适合测试环境; ■ 伪集群模式:就是在一台物理机上运行多个Zookeeper 实例; ■ 集群模式:Zookeeper运行于一个集群上,适合生产环境,这个计算机集群被称为一个“集合体”(ensemble) Zookeeper通过复制来实现

CentOS7安装配置mysql5.7 tar免安装版

一、CentOS7.4系统自带mariadb # 查看系统自带的Mariadb[root@localhost~]# rpm -qa|grep mariadbmariadb-libs-5.5.44-2.el7.centos.x86_64# 卸载系统自带的Mariadb[root@localhost ~]# rpm -e --nodeps mariadb-libs-5.5.44-2.el7