本文目录导读:

- Python脚本(SMTP连接检测)
- Bash脚本(端口检测+HELO命令)
- PowerShell脚本(Windows环境)
- Node.js脚本
- 高级检测(带认证测试)
- 系统监控集成(Nagios/Icinga风格)
- 检测要点
Python脚本(SMTP连接检测)
import smtplib
import socket
def check_smtp_server(host, port=25, timeout=10):
try:
server = smtplib.SMTP(host, port, timeout=timeout)
server.ehlo()
server.quit()
return True, "SMTP服务正常"
except smtplib.SMTPException as e:
return False, f"SMTP错误: {str(e)}"
except socket.timeout:
return False, "连接超时"
except socket.error as e:
return False, f"网络错误: {str(e)}"
# 使用示例
status, msg = check_smtp_server("smtp.example.com")
print(f"状态: {status}, 信息: {msg}")
Bash脚本(端口检测+HELO命令)
#!/bin/bash
check_mail_server() {
HOST="$1"
PORT="${2:-25}"
TIMEOUT="${3:-5}"
# 测试TCP端口连通性
if ! timeout "$TIMEOUT" bash -c "echo > /dev/tcp/$HOST/$PORT" 2>/dev/null; then
echo "端口 $PORT 未开放"
return 1
fi
# 发送SMTP HELO命令测试
result=$(echo -e "HELO test\r\nQUIT\r\n" | timeout "$TIMEOUT" nc -w2 "$HOST" "$PORT" 2>/dev/null)
if echo "$result" | grep -q "250"; then
echo "SMTP服务正常"
return 0
else
echo "SMTP响应异常: $result"
return 2
fi
}
check_mail_server "smtp.example.com" 25
PowerShell脚本(Windows环境)
function Test-MailServer {
param(
[string]$Server = "smtp.example.com",
[int]$Port = 25,
[int]$TimeoutSeconds = 5
)
$tcpClient = New-Object System.Net.Sockets.TcpClient
$connectionResult = $tcpClient.BeginConnect($Server, $Port, $null, $null)
$wait = $connectionResult.AsyncWaitHandle.WaitOne($TimeoutSeconds * 1000, $false)
if (-not $wait) {
$tcpClient.Close()
return @{ Status = $false; Message = "连接超时" }
}
try {
$tcpClient.EndConnect($connectionResult)
$stream = $tcpClient.GetStream()
# 读取SMTP banner
$buffer = New-Object byte[] 1024
$stream.Read($buffer, 0, $buffer.Length) | Out-Null
$response = [System.Text.Encoding]::ASCII.GetString($buffer)
if ($response -match "220") {
return @{ Status = $true; Message = "SMTP服务正常" }
} else {
return @{ Status = $false; Message = "收到异常响应: $response" }
}
}
finally {
$tcpClient.Close()
}
}
Test-MailServer -Server "smtp.example.com" -Port 25
Node.js脚本
const net = require('net');
async function checkMailServer(host, port = 25, timeout = 5000) {
return new Promise((resolve) => {
const socket = new net.Socket();
let response = '';
socket.setTimeout(timeout);
socket.on('connect', () => {
// 发送HELO命令
socket.write('HELO test\r\n');
});
socket.on('data', (data) => {
response += data.toString();
if (response.includes('250')) {
socket.write('QUIT\r\n');
resolve({
status: true,
message: 'SMTP服务正常',
response: response
});
}
});
socket.on('error', (err) => {
resolve({
status: false,
message: `连接错误: ${err.message}`
});
});
socket.on('timeout', () => {
socket.destroy();
resolve({
status: false,
message: '连接超时'
});
});
socket.connect(port, host);
});
}
checkMailServer('smtp.example.com', 25).then(result => {
console.log(`状态: ${result.status}, 信息: ${result.message}`);
});
高级检测(带认证测试)
import smtplib
from email.mime.text import MIMEText
def full_mail_server_test(host, port, username, password, test_recipient):
"""完整测试:连接、认证、发送测试邮件"""
results = {}
# 步骤1:基础连接测试
try:
server = smtplib.SMTP(host, port, timeout=10)
server.ehlo()
results['connection'] = '成功'
except Exception as e:
return {'error': f'连接失败: {str(e)}'}
# 步骤2:TLS/SSL测试(如果可用)
if server.has_extn('STARTTLS'):
try:
server.starttls()
server.ehlo()
results['tls'] = '支持并成功'
except Exception as e:
results['tls'] = f'支持但失败: {str(e)}'
else:
results['tls'] = '不支持'
# 步骤3:认证测试
if username:
try:
server.login(username, password)
results['auth'] = '成功'
except smtplib.SMTPAuthenticationError:
results['auth'] = '认证失败'
except Exception as e:
results['auth'] = f'认证错误: {str(e)}'
# 步骤4:发送测试邮件
if test_recipient and 'auth' in results and results['auth'] == '成功':
try:
msg = MIMEText('This is a test email from mail server checker')
msg['Subject'] = 'Mail Server Test'
msg['From'] = username
msg['To'] = test_recipient
server.sendmail(username, [test_recipient], msg.as_string())
results['send_test'] = '成功'
except Exception as e:
results['send_test'] = f'失败: {str(e)}'
server.quit()
return results
系统监控集成(Nagios/Icinga风格)
#!/bin/bash
# check_smtp.sh - 兼容Nagios插件的输出格式
STATE_OK=0
STATE_WARNING=1
STATE_CRITICAL=2
STATE_UNKNOWN=3
HOST=$1
PORT=${2:-25}
WARNING=${3:-5}
CRITICAL=${4:-10}
start_time=$(date +%s%N)
# 执行检测
if timeout "$CRITICAL" bash -c "echo > /dev/tcp/$HOST/$PORT" 2>/dev/null; then
end_time=$(date +%s%N)
duration=$(( (end_time - start_time) / 1000000 ))
if [ "$duration" -gt "$CRITICAL" ]; then
echo "CRITICAL - 响应时间${duration}ms超过阈值"
exit $STATE_CRITICAL
elif [ "$duration" -gt "$WARNING" ]; then
echo "WARNING - 响应时间${duration}ms超过阈值"
exit $STATE_WARNING
else
echo "OK - SMTP端口开放,响应时间${duration}ms"
exit $STATE_OK
fi
else
echo "CRITICAL - 无法连接到 ${HOST}:${PORT}"
exit $STATE_CRITICAL
fi
检测要点
基础检测
- 端口连通性:25(SMTP)、465(SMTPS)、587(Submission)
- SMTP握手:检查220响应码
- HELO/EHLO响应:检查250响应码
高级检测
- STARTTLS支持:检查是否支持加密
- 认证测试:用户名密码验证
- 邮件发送测试:实际发送测试邮件
- 响应时间:监控连接和响应延迟
常见问题处理
- 连接超时:检查防火墙规则
- 认证失败:验证账号权限
- 黑名单检测:检查服务器IP是否被列入黑名单
- DNS查询:确保MX记录解析正常
选择哪种方法取决于你的技术栈、安全要求和是否需要实际发送测试邮件,对于生产环境监控,建议使用完整的SMTP协议交互测试。