网站标题切换无版权的图片素材网站
shell脚本需求说明:
1、监控系统中的cpu、内存、硬盘、、使用率超过80%进行邮件告警(可使用邮箱163、QQ、139等)
2、监控系统中的IO await大于50进行邮件告警(可使用邮箱163、QQ、139等)
3、监控系统中的网络流量下载上传超过10M(可变)进行邮件告警(可使用邮箱163、QQ、139等)
#脚本如下:[root@easy110 function]# cat jiaoben1.sh
#!/bin/bash
set -x #添加日志追踪
#参数配置
ALERT_EMAIL="1634918293@qq.com" # 接收告警的邮箱
cpu_threshold=80 #cpu阈值(%)
mem_threshold=80 #内存阈值(%)
disk_threshold=80 #硬盘阈值(%)
io_threshold=50 #io await阈值
net_threshold=10 #网络阈值(MB/s)
check_interval=60 #检查间隔(秒)#发送告警邮件
send_alert() {local subject="$1" #邮件主题local message="$2" #邮件正文内容echo -e "Subject: $subject\n\n$message" | \mail -s "$subject" \-S from="1634918293@qq.com" \
# 设置发件人邮箱地址。这里必须和认证的用户名一致-S smtp="smtp.qq.com:587" \
# 指定QQ邮箱的SMTP服务器地址和端口号(587端口通常用于STARTTLS加密,后面获取ssl证书用465端口不影响)-S smtp-auth-user="1634918293@qq.com" \-S smtp-auth-password="uogxocfexcpubfbc" \
# 提供登录SMTP服务器的认证信息。特别注意:这里的密码应该是在自己的QQ邮箱设置中生成的授权码,而不是QQ邮箱登录密码-S smtp-auth=login \
# 指定认证方式为登录认证-S smtp-use-starttls \
# 启用STARTTLS加密连接,确保邮件发送过程的安全-S ssl-verify=ignore \
# 忽略SSL证书验证。这在测试时有用,但生产环境中建议正确配置证书以避免安全风险-S nss-config-dir=/etc/pki/nssdb \
# 指定NSS证书数据库的路径,用于TLS/SSL加密连接时验证证书,可以用 nss-config-dir=/root/.certs创建目录并手动导入QQ邮箱证书,解决了证书不被信任(Unrecognized issuer)的错误"$ALERT_EMAIL"
}#监控CPU 使用率大于80 邮件警告
check_cpu(){cpu=$(top -bn1 | grep 'Cpu(s)'|awk '{print int($2+$4)}')if [ $cpu -gt $cpu_threshold ]; thensend_alert "CPU告警" "CPU使用率: $cpu% (阈值$cpu_threshold%)"fi
}#监控内存 使用率大于80 邮件警告
check_mem(){mem=$(free|grep 'Mem'|awk '{print int($3/$2*100)}')if [ $mem -gt $mem_threshold ];thensend_alert "内存告警" "内存使用率: $mem% (阈值$mem_threshold%)"fi
}#监控硬盘 使用率大于80 邮件警告
check_disk(){disk=$(df -h /|awk 'NR==2{print $5}'|sed 's/%//')if [ $disk -gt $disk_threshold ]; thensend_alert "硬盘告警" "硬盘使用率: $disk% (阈值$disk_threshold%)"fi
}#监控io await 使用率大于50 邮件警告
check_io(){io=$(iostat -x| awk '/^Device/ {getline; print int($10)}')if [ $io -gt $io_threshold ]; thensend_alert "IO告警" "IO await: $io (阈值$io_threshold)"fi
}#监控网络流量下载 上传大于10M 邮件警告
check_net(){#捕获第一个非lo的网络接口interface=$(ip -br link show | awk '/^lo/{getline; print $1}') #捕获第一个非lo的网络接口#计算每秒流量 #rx 是 receive(接收)的缩写,通常表示网络接口的接收流量(即下载流量)。#tx 是 "transmit"(发送)的缩写,代表网络上传方向的流量.tx1用于存储第一次读取到的网络接口发送字节数#1MB = 1024KB = 1024×1024 字节rx1=$(cat /sys/class/net/$interface/statistics/rx_bytes)tx1=$(cat /sys/class/net/$interface/statistics/tx_bytes)sleep 1rx2=$(cat /sys/class/net/$interface/statistics/rx_bytes)tx2=$(cat /sys/class/net/$interface/statistics/tx_bytes)rx_mb=$(echo "scale=2; ($rx2-$rx1)/1024/1024" | bc)tx_mb=$(echo "scale=2; ($tx2-$tx1)/1024/1024" | bc)if (( $(echo "$rx_mb > $net_threshold" | bc -l) )); thensend_alert "网络下载告警" "下载速度: $rx_mb MB/s (阈值$net_threshold)"fiif (( $(echo "$tx_mb > $net_threshold" | bc -l) )); thensend_alert "网络上传告警" "上传速度: $tx_mb MB/s (阈值$net_threshold)"fi
}# 循环监控
while true;
docheck_cpucheck_memcheck_diskcheck_iocheck_netsleep $check_interval
done
然后获取SMTP授权码:
(授权码是用于验证身份的16位字符串,是使用QQ邮箱SMTP服务的关键)
获取步骤如下:1.登录QQ邮箱网页版:访问 https://mail.qq.com并登录你的QQ邮箱
2.进入设置:点击邮箱页面右上角的设置图标(通常显示为齿轮⚙️)
3.选择“账户”设置:在设置页面中,选择“账户”选项卡
4.开启SMTP服务:
向下滚动找到 “POP3/IMAP/SMTP/Exchange/CardDAV/CalDAV服务” 部分
找到 “IMAP/SMTP服务” 或类似选项,点击其右侧的 “开启” 按钮
5.验证身份并获取授权码:
根据提示(通常需要通过已绑定的手机号发送短信验证)完成身份验证验证成功后,系统会生成一个16位的授权码。此授权码只会显示一次,请务必妥善保存
手动获取ssl证书:# 创建证书目录并下载QQ邮箱证书
mkdir -p /root/.certsecho -n | openssl s_client -connect smtp.qq.com:465 | sed -ne '/BEGIN CERTIFICATE/,/END CERTIFICATE/p' > /root/.certs/qq.crt# 将证书添加到NSS数据库并设置为信任
certutil -A -n "QQ Mail SMTP" -t "P,," -d /root/.certs -i /root/.certs/qq.crt
# 修改配置文件:
① vim /etc/postfix/main.cfinet_interfaces = localhost 改成 inet_interfaces = all(# inet_interfaces = localhost: 表示 Postfix 只监听本地环回地址(127.0.0.1)。这意味着它只能接收来自本机内部发送的邮件,而无法接收来自外部网络(如其他服务器或客户端)发来的邮件。这通常是用于本机测试或特定安全策略的配置。# inet_interfaces = all:如果取消这行的注释并使其生效,Postfix 将会监听服务器上所有网络接口的地址。这是希望 Postfix 能够正常接收来自外部网络邮件的最常见配置inet_interfaces = $myhostname, localhost:这种配置表示 Postfix 会监听其完整主机名(FQDN)解析对应的IP地址以及本地环回地址。)或修改成这样:
inet_interfaces = allsudo systemctl restart postfix
#inet_interfaces = $myhostname
#inet_interfaces = $myhostname, localhost
#inet_interfaces = localhost# 修改完,重启 Postfix 服务:
② sudo systemctl restart postfix# 检查 inet_interfaces的当前值是否已更新:
③ postconf inet_interfaces
输出应为 inet_interfaces = all。#发送测试
④ bash -c 'source ./jiaoben1.sh; send_alert "测试邮件" "Postfix配置修复后测试"'# 最后可以检查邮件日志: 观察邮件日志 /var/log/maillog,看是否有新的进展或错误信息:
⑤ tail -f /var/log/maillog
通过调低内存阈值可测试是否能收到告警:

遇到的问题:
1.现象:脚本 jiaoben1.sh在后台运行,但从未收到任何告警邮件。2.初步判断:可能是监控项未达到阈值,也可能是邮件发送功能本身有问题。
可以收到发一份文件确定发送端是否有问题:bash -c 'source ./jiaoben1.sh; send_alert "最终集成测试" "这是一封测试邮件,用于验证所有配置已正确集成。收到即表示全部成功!"'3.诊断手段:在脚本开头添加了 set -x命令追踪日志,启用调试模式,查看脚本执行的详细过程。排查方向(包含具体检查点及解决方法):1)网络连通性:使用 telnet smtp.qq.com 587测试网络。若失败,检查服务器网络、防火墙/安全组是否放行 587 端口。 2)SMTP配置:核对脚本中的SMTP服务器地址(smtp.qq.com)、端口(587)、加密方式(smtp-use-starttls)。确保使用QQ邮箱的授权码(非登录密码)。同时检查一下配置文件/etc/postfix/main.cf,确定是否可以监听ens333)系统邮件日志:检查 /var/log/maillog或 /var/log/mail.log,寻找如 535 Authentication failed(认证失败)等错误信息。4)邮件内容与附件:避免邮件主题或正文中有特殊字符或敏感词汇。暂时移除附件测试,或因附件过大(如超过25MB)导致发送失败。 5) 发件人信誉与认证:此点通常对个人从自有服务器发信影响较大。若域名/IP被列入黑名单,邮件易被拒或进入垃圾箱。需检查并确保域名SPF、DKIM记录正确设置。4.发现:调试输出显示,脚本确实在执行监控,但 CPU、内存、磁盘等使用率远低于设定的阈值(CPU仅6%,内存36%,磁盘7%),因此没有触发 send_alert函数。这表明监控逻辑本身是正常的。⚠️ 核心问题:邮件发送失败
当手动调低阈值(如将 disk_threshold设为 0)强制触发告警后,问题暴露出来:邮件发送失败。/var/log/maillog或脚本输出中出现了关键错误信息:1.报错显示:Missing "nss-config-dir" variable:原因:mail命令(或 mailx)需要通过 NSS (Network Security Services) 库进行 SSL/TLS 加密连接,但未指定其证书数据库的路径。解决:在 mail命令中添加 -S nss-config-dir=/etc/pki/nssdb参数,指向系统默认的证书库。2.报错显示:Error in certificate: Peer's certificate issuer is not recognized:原因:指定的证书库(如 /etc/pki/nssdb)中缺少 QQ 邮箱 SMTP 服务器所需的根证书,导致 SSL 握手失败解决:
① 手动获取并信任证书:# 创建证书目录并下载QQ邮箱证书
mkdir -p /root/.certs
echo -n | openssl s_client -connect smtp.qq.com:465 | sed -ne '/BEGIN CERTIFICATE/,/END CERTIFICATE/p' > /root/.certs/qq.crt# 将证书添加到NSS数据库并设置为信任
certutil -A -n "QQ Mail SMTP" -t "P,," -d /root/.certs -i /root/.certs/qq.crt② 修改脚本:将 mail命令中的 -S nss-config-dir参数改为指向新创建的、已包含信任证书的库 -S nss-config-dir=/root/.certs。(此处后期发现是否修改不影响,修改后更精准)3.报错显示:smtp-server: 501 Mail from address must be same as authorization user:原因:SMTP 服务器要求发件人地址(MAIL FROM)必须与认证的用户名(即你登录 SMTP 服务的邮箱地址)完全一致。这是一种常见的安全策略,旨在防止邮件伪造解决:在 mail命令中显式添加 -S from="1634918293@qq.com"参数,强制指定发件人地址与认证用户(-S smtp-auth-user)保持一致。🔧 最终解决方案
综合以上排查,对 send_alert函数中的 mail命令进行了正确配置:mail -s "$subject" \-S from="1634918293@qq.com" \ # 确保与认证用户一致-S smtp="smtp.qq.com:587" \-S smtp-auth-user="1634918293@qq.com" \-S smtp-auth-password="你的授权码" \ # 确保是授权码而非密码-S smtp-auth=login \-S smtp-use-starttls \ # 使用587端口需启用STARTTLS-S nss-config-dir=/root/.certs \ # 指向已包含信任证书的库"$ALERT_EMAIL"
💎 经验总结与最佳实践
1.权限与路径:确保脚本有执行权限,且命令路径完整2.授权码而非密码:使用SMTP服务时,务必使用邮箱服务商提供的授权码,而非邮箱登录密码。3.证书信任:在Linux系统上通过命令行工具发送加密邮件时,经常需要手动处理证书信任问题。nss-config-dir是关键配置。4.发件人一致性:大部分SMTP服务器都会要求发件人地址与认证用户一致,这是重要的反垃圾邮件和安全措施。5.日志是关键:遇到问题,第一时间查看系统日志(/var/log/maillog或 /var/log/mail.log),其中的错误信息是定位问题的黄金标准。6.测试的重要性:先手动测试发送功能,能快速隔离问题是出在监控逻辑还是邮件发送环节。
