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

相关文章

Linux中SSH服务配置的全面指南

《Linux中SSH服务配置的全面指南》作为网络安全工程师,SSH(SecureShell)服务的安全配置是我们日常工作中不可忽视的重要环节,本文将从基础配置到高级安全加固,全面解析SSH服务的各项参... 目录概述基础配置详解端口与监听设置主机密钥配置认证机制强化禁用密码认证禁止root直接登录实现双因素

嵌入式数据库SQLite 3配置使用讲解

《嵌入式数据库SQLite3配置使用讲解》本文强调嵌入式项目中SQLite3数据库的重要性,因其零配置、轻量级、跨平台及事务处理特性,可保障数据溯源与责任明确,详细讲解安装配置、基础语法及SQLit... 目录0、惨痛教训1、SQLite3环境配置(1)、下载安装SQLite库(2)、解压下载的文件(3)、

Linux如何快速检查服务器的硬件配置和性能指标

《Linux如何快速检查服务器的硬件配置和性能指标》在运维和开发工作中,我们经常需要快速检查Linux服务器的硬件配置和性能指标,本文将以CentOS为例,介绍如何通过命令行快速获取这些关键信息,... 目录引言一、查询CPU核心数编程(几C?)1. 使用 nproc(最简单)2. 使用 lscpu(详细信

Nginx 重写与重定向配置方法

《Nginx重写与重定向配置方法》Nginx重写与重定向区别:重写修改路径(客户端无感知),重定向跳转新URL(客户端感知),try_files检查文件/目录存在性,return301直接返回永久重... 目录一.try_files指令二.return指令三.rewrite指令区分重写与重定向重写: 请求

Nginx 配置跨域的实现及常见问题解决

《Nginx配置跨域的实现及常见问题解决》本文主要介绍了Nginx配置跨域的实现及常见问题解决,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来... 目录1. 跨域1.1 同源策略1.2 跨域资源共享(CORS)2. Nginx 配置跨域的场景2.1

javax.net.ssl.SSLHandshakeException:异常原因及解决方案

《javax.net.ssl.SSLHandshakeException:异常原因及解决方案》javax.net.ssl.SSLHandshakeException是一个SSL握手异常,通常在建立SS... 目录报错原因在程序中绕过服务器的安全验证注意点最后多说一句报错原因一般出现这种问题是因为目标服务器

gitlab安装及邮箱配置和常用使用方式

《gitlab安装及邮箱配置和常用使用方式》:本文主要介绍gitlab安装及邮箱配置和常用使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1.安装GitLab2.配置GitLab邮件服务3.GitLab的账号注册邮箱验证及其分组4.gitlab分支和标签的

MySQL MCP 服务器安装配置最佳实践

《MySQLMCP服务器安装配置最佳实践》本文介绍MySQLMCP服务器的安装配置方法,本文结合实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下... 目录mysql MCP 服务器安装配置指南简介功能特点安装方法数据库配置使用MCP Inspector进行调试开发指

Redis Cluster模式配置

《RedisCluster模式配置》:本文主要介绍RedisCluster模式配置,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录分片 一、分片的本质与核心价值二、分片实现方案对比 ‌三、分片算法详解1. ‌范围分片(顺序分片)‌2. ‌哈希分片3. ‌虚

SpringBoot项目配置logback-spring.xml屏蔽特定路径的日志

《SpringBoot项目配置logback-spring.xml屏蔽特定路径的日志》在SpringBoot项目中,使用logback-spring.xml配置屏蔽特定路径的日志有两种常用方式,文中的... 目录方案一:基础配置(直接关闭目标路径日志)方案二:结合 Spring Profile 按环境屏蔽关