从零实现邮件中继服务

    • 背景
    • 目的
    • 验证准备
      • 前提
      • 前置过程
      • 网络约束
      • 节点信息
      • 账号信息
    • 具体验证过程
    • 转发测试
    • 相关问题
    • 补充

背景

在当前现场环境中,我们面临着一个重要的问题。我们的系统部署在一个内网环境中,邮件告警模块需要连接公网的邮件服务器以便发送邮件来及时通知我们关键事件和紧急情况,而集群与公共互联网络隔离,导致邮件无法发送。为了解决邮件无法发送的问题,我们需要一个可以连接公网环境的节点,通过该节点将邮件转发到对应的邮件服务器上。

目的

如何在内网集群内,将邮件通过可以连接到公网的机器,然后发送到对应的邮件服务器上,实现邮件告警的目的。
从零实现邮件中继服务_第1张图片

验证准备

前提

准备一个不通公网的机器,一个可以连接公网的机器
注意:当前使用的环境为centos8,postfix版本为3.x,其他版本或有不同

前置过程

安装2个虚拟机节点,即192.168.96.130和192.168.96.187
在这里插入图片描述

修改每个节点的hostname
从零实现邮件中继服务_第2张图片
从零实现邮件中继服务_第3张图片

网络约束

在96.130上的网络配置中将网关移除,然后重启网络服务

从零实现邮件中继服务_第4张图片
从零实现邮件中继服务_第5张图片

使得96.130无法访问公网,但可以连接局域网
从零实现邮件中继服务_第6张图片

节点信息

按照以上步骤完成后,得到一个内网和一个可以通公网的环境,且两者互通,并随时可以根据快照恢复至最初。

节点 IP 外网访问权限
fs_96_130 192.168.96.130 ×
fs_96_187 192.168.96.187

账号信息

选项
发信人账号 xxx
发信人授权码 xxx
邮件服务器 smtp.qq.com
邮件服务器端口 465
收件人地址 xxx

具体验证过程

1、在96.187(跳板机)上安装postfix软件包,以实现邮件中继功能

从零实现邮件中继服务_第7张图片

2、alternatives --config mta命令用于查看和设置当前系统上的邮箱服务,此时选择postfix作为邮箱服务。
从零实现邮件中继服务_第8张图片

3、配置96.187(跳板机),使其在接收到96.130(内网机)的邮件后直接发送出去。
进入到postfix配置目录
在这里插入图片描述

修改主配置文件main.cf,并在其中添加如下内容

注释smtp_tls_security_level = may这一行,即736行
在这里插入图片描述

注释inet_interfaces = localhost这一行,即135行

从零实现邮件中继服务_第9张图片

然后添加下面的内容

smtp_sasl_auth_enable = yes
# 设置qq发件邮箱的发信人和授权码
smtp_sasl_password_maps = static:发信人账户:发信人授权码
smtp_sasl_security_options = noanonymous
smtp_tls_wrappermode = yes
smtp_tls_security_level = encrypt
header_size_limit = 4096000

# 设置发件邮箱的邮件服务器地址和端口号
relayhost = [smtp.qq.com]:465
# 设置允许接收来自xx网络的邮件
mynetworks=192.168.96.0/24

# 指定邮件服务器监听的网络接口
inet_interfaces = all

然后保存退出

5、重启postfix服务
从零实现邮件中继服务_第10张图片

转发测试

1、从96.187(跳板机)上下载golang相关包并传到96.130(内网机)上
从零实现邮件中继服务_第11张图片
在96.130(内网机)上安装相关golang包
从零实现邮件中继服务_第12张图片
在96.130(内网机)上编写发送邮件的go代码进行测试

package main
 
import (
    "crypto/tls"
    "fmt"
    "log"
    "net/smtp"
)
 
func main() {
    from := "[email protected]"
    to := "[email protected]"
    smtpServer := "192.168.96.187"
    smtpPort := 25
 
    // 邮件内容
    subject := "Hello"
    body := fmt.Sprintf("hello %s, This is the test mail", from)
 
    // 构建邮件内容,包括发件人、收件人、主题和正文
    message := []byte(fmt.Sprintf("From: %s\r\nTo: %s\r\nSubject: %s\r\n\r\n%s", from, to, subject, body))
 
    // 连接到SMTP服务器
    addr := fmt.Sprintf("%s:%d", smtpServer, smtpPort)
    client, err := smtp.Dial(addr)
    if err != nil {
        log.Fatal("connect mail server failed: ", err)
    }
    defer client.Close()
 
    // 配置TLS并跳过证书验证
    tlsConfig := &tls.Config{InsecureSkipVerify: true}
    if err = client.StartTLS(tlsConfig); err != nil {
        log.Fatal("set tls config failed: ", err)
    }
    // 设置发件人
    if err = client.Mail(from); err != nil {
        log.Fatal("set mail sender failed: ", err)
    }
 
    // 设置收件人
    if err = client.Rcpt(to); err != nil {
        log.Fatal("set mail receiver failed: ", err)
    }
 
    // 发送邮件内容
    w, Er := client.Data()
    if Er != nil {
        log.Fatal("set mail data failed:", Er)
    }
 
    _, err = w.Write(message)
    if err != nil {
        log.Fatal("set mail content failed:", err)
    }
 
    if err = w.Close(); err != nil {
        log.Fatal("set mail writer close failed:", err)
    }
 
    if err = client.Quit(); err != nil {
        log.Fatal("set client quit failed:", err)
    }
    log.Println("send success")
}

在96.130(内网机)上执行代码
在这里插入图片描述
查看96.187(跳板机)的邮件中继服务postfix是否收到邮件并转发
从零实现邮件中继服务_第13张图片
查看邮箱
在这里插入图片描述

相关问题

1、出现这种情况时
从零实现邮件中继服务_第14张图片
检查sasl相关包是否已经安装
从零实现邮件中继服务_第15张图片
2、邮件服务状态显示有类似这种连接ipv6失败的
在这里插入图片描述
可以在配置里更改为只使用ipv4
在这里插入图片描述

补充

由于写时没遇到该问题,后续验证截图略有不同:96.54(内网机),96.60(跳板机)

以上在使用代码时发送可以,若要使用命令行直接从96.54(内网机)发送到96.60(跳板机),则需要在发送和接收是分别处理。

96.54(内网机)发送时需要指定连接的smtp地址

例如:
在这里插入图片描述
由于qq邮箱需要邮件中的From和上面配置的发件人相应,所以有两个解决办法:

法一:发送时处理,在发件时指定From,此时跳板机不用单独处理,例如
在这里插入图片描述
缺陷是如果改了跳板机的发件人则发不出去,因为发件人和From不同,尤其是两个公司信息不同步时错过一些重要邮件,不推荐

法二:在跳板机处理(推荐),以后只需更改跳板机的配置即可

使96.60(跳板机)中继邮件时,统一重写为发件人邮箱,使其保持一致,增加两个配置

sender_canonical_maps = regexp:/etc/postfix/sender_canonical
header_checks = regexp:/etc/postfix/header_checks

从零实现邮件中继服务_第16张图片
创建 /etc/postfix/sender_canonical 文件,用于重写发件人地址
在这里插入图片描述

/^.*$/   731413853@qq.com  # 替换对应邮箱

编辑 /etc/postfix/header_checks 文件,用于更改邮件头中的 “From” 地址。
从零实现邮件中继服务_第17张图片

/^From:(.*)$/ REPLACE From: 731413853@qq.com # 替换对应邮箱

重启服务
从零实现邮件中继服务_第18张图片
然后96.54(内网机)发送时,指定或不指定From都会被重写为固定的发件人
在这里插入图片描述
查看邮箱
从零实现邮件中继服务_第19张图片

你可能感兴趣的:(内网,公网,邮件,中继,转发)