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的六步流程,包括添加服务器、配置部署选项、设置应用服务器及启动,并提及Maven依赖可能因约定大于配置导致问题,需检查依赖版本... 目录第一步第二步第三步第四步第五步第六步总结第一步选择这个方框第二步选择+号,找到Tomca

Win10安装Maven与环境变量配置过程

《Win10安装Maven与环境变量配置过程》本文介绍Maven的安装与配置方法,涵盖下载、环境变量设置、本地仓库及镜像配置,指导如何在IDEA中正确配置Maven,适用于Java及其他语言项目的构建... 目录Maven 是什么?一、下载二、安装三、配置环境四、验证测试五、配置本地仓库六、配置国内镜像地址

SpringBoot多环境配置数据读取方式

《SpringBoot多环境配置数据读取方式》SpringBoot通过环境隔离机制,支持properties/yaml/yml多格式配置,结合@Value、Environment和@Configura... 目录一、多环境配置的核心思路二、3种配置文件格式详解2.1 properties格式(传统格式)1.

Debian系和Redhat系防火墙配置方式

《Debian系和Redhat系防火墙配置方式》文章对比了Debian系UFW和Redhat系Firewalld防火墙的安装、启用禁用、端口管理、规则查看及注意事项,强调SSH端口需开放、规则持久化,... 目录Debian系UFW防火墙1. 安装2. 启用与禁用3. 基本命令4. 注意事项5. 示例配置R

PyCharm中配置PyQt的实现步骤

《PyCharm中配置PyQt的实现步骤》PyCharm是JetBrains推出的一款强大的PythonIDE,结合PyQt可以进行pythion高效开发桌面GUI应用程序,本文就来介绍一下PyCha... 目录1. 安装China编程PyQt1.PyQt 核心组件2. 基础 PyQt 应用程序结构3. 使用 Q

Redis MCP 安装与配置指南

《RedisMCP安装与配置指南》本文将详细介绍如何安装和配置RedisMCP,包括快速启动、源码安装、Docker安装、以及相关的配置参数和环境变量设置,感兴趣的朋友一起看看吧... 目录一、Redis MCP 简介二、安www.chinasem.cn装 Redis MCP 服务2.1 快速启动(推荐)2.

Spring Boot配置和使用两个数据源的实现步骤

《SpringBoot配置和使用两个数据源的实现步骤》本文详解SpringBoot配置双数据源方法,包含配置文件设置、Bean创建、事务管理器配置及@Qualifier注解使用,强调主数据源标记、代... 目录Spring Boot配置和使用两个数据源技术背景实现步骤1. 配置数据源信息2. 创建数据源Be

Spring Boot Maven 插件如何构建可执行 JAR 的核心配置

《SpringBootMaven插件如何构建可执行JAR的核心配置》SpringBoot核心Maven插件,用于生成可执行JAR/WAR,内置服务器简化部署,支持热部署、多环境配置及依赖管理... 目录前言一、插件的核心功能与目标1.1 插件的定位1.2 插件的 Goals(目标)1.3 插件定位1.4 核

RabbitMQ消息总线方式刷新配置服务全过程

《RabbitMQ消息总线方式刷新配置服务全过程》SpringCloudBus通过消息总线与MQ实现微服务配置统一刷新,结合GitWebhooks自动触发更新,避免手动重启,提升效率与可靠性,适用于配... 目录前言介绍环境准备代码示例测试验证总结前言介绍在微服务架构中,为了更方便的向微服务实例广播消息,

Ubuntu 24.04启用root图形登录的操作流程

《Ubuntu24.04启用root图形登录的操作流程》Ubuntu默认禁用root账户的图形与SSH登录,这是为了安全,但在某些场景你可能需要直接用root登录GNOME桌面,本文以Ubuntu2... 目录一、前言二、准备工作三、设置 root 密码四、启用图形界面 root 登录1. 修改 GDM 配