- 背景
- 目的
- 验证准备
- 前提
- 前置过程
- 网络约束
- 节点信息
- 账号信息
- 具体验证过程
- 转发测试
- 相关问题
背景
在当前现场环境中,我们面临着一个重要的问题。我们的系统部署在一个内网环境中,邮件告警模块需要连接公网的邮件服务器以便发送邮件来及时通知我们关键事件和紧急情况,而集群与公共互联网络隔离,导致邮件无法发送。为了解决邮件无法发送的问题,我们需要一个可以连接公网环境的节点,通过该节点将邮件转发到对应的邮件服务器上。
目的
如何在内网集群内,将邮件通过可以连接到公网的机器,然后发送到对应的邮件服务器上,实现邮件告警的目的。
验证准备
前提
准备一个不通公网的机器,一个可以连接公网的机器
注意:当前使用的环境为centos8,postfix版本为3.x,其他版本或有不同
前置过程
安装2个虚拟机节点,即192.168.96.130和192.168.96.187
修改每个节点的hostname
网络约束
在96.130上的网络配置中将网关移除,然后重启网络服务
使得96.130无法访问公网,但可以连接局域网
节点信息
按照以上步骤完成后,得到一个内网和一个可以通公网的环境,且两者互通,并随时可以根据快照恢复至最初。
节点 | 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软件包,以实现邮件中继功能
2、alternatives --config mta命令用于查看和设置当前系统上的邮箱服务,此时选择postfix作为邮箱服务。
3、配置96.187(跳板机),使其在接收到96.130(内网机)的邮件后直接发送出去。
进入到postfix配置目录
修改主配置文件main.cf,并在其中添加如下内容
注释smtp_tls_security_level = may这一行,即736行
注释inet_interfaces = localhost这一行,即135行
然后添加下面的内容
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服务
转发测试
1、从96.187(跳板机)上下载golang相关包并传到96.130(内网机)上
在96.130(内网机)上安装相关golang包
在96.130(内网机)上编写发送邮件的go代码进行测试
package main
import (
"crypto/tls"
"fmt"
"log"
"net/smtp"
)
func main() {
from := "731413853@qq.com"
to := "lirul@snapmail.cc"
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是否收到邮件并转发
查看邮箱
相关问题
出现这种情况时
检查sasl相关包是否已经安装