You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过Bash脚本自动用Telnet测试SMTP?脚本优化与最佳实践

SMTP Test Script Fixes & Automation Best Practices

Error Analysis

The "improper command pipelining after DATA" error occurs because the original script sends all SMTP commands in one batch (pipelining) without waiting for the server's response after issuing the DATA command. SMTP servers require you to wait for a 354 response before transmitting the message body—skipping this step triggers the error.

Revised Script Fix

Here’s a fixed version of the script that handles command flow properly, validates server responses, and includes queue assertion:

#!/usr/bin/env bash

set -euo pipefail

# Configuration variables
SMTP_SERVER="mailserver"
SMTP_PORT=25
SENDER="sender@test.local"
RECIPIENT="recipient@test.local"
TEST_SUBJECT="Test $(date +%Y-%m-%d_%H_%M_%S)"
TEST_BODY="A nice test"
QUEUE_DIR="/var/spool/postfix/maildrop" # Adjust to your server's queue path

# Open connection to SMTP server
exec 3<>/dev/tcp/$SMTP_SERVER/$SMTP_PORT

# Wait for server banner
read -r -t 10 -u 3 line || { echo "Timeout waiting for banner"; exit 1; }
if [[ ! "$line" =~ ^220 ]]; then
  echo "Failed to connect: $line"
  exit 1
fi

# Send HELO
echo "HELO test.local" >&3
read -r -t 10 -u 3 line || { echo "Timeout waiting for HELO response"; exit 1; }
if [[ ! "$line" =~ ^250 ]]; then
  echo "HELO failed: $line"
  exit 1
fi

# Send MAIL FROM
echo "MAIL FROM:<$SENDER>" >&3
read -r -t 10 -u 3 line || { echo "Timeout waiting for MAIL FROM response"; exit 1; }
if [[ ! "$line" =~ ^250 ]]; then
  echo "MAIL FROM failed: $line"
  exit 1
fi

# Send RCPT TO
echo "RCPT TO:<$RECIPIENT>" >&3
read -r -t 10 -u 3 line || { echo "Timeout waiting for RCPT TO response"; exit 1; }
if [[ ! "$line" =~ ^250 ]]; then
  echo "RCPT TO failed: $line"
  exit 1
fi

# Send DATA command
echo "DATA" >&3
read -r -t 10 -u 3 line || { echo "Timeout waiting for DATA response"; exit 1; }
if [[ ! "$line" =~ ^354 ]]; then
  echo "DATA failed: $line"
  exit 1
fi

# Transmit message body
echo "Subject: $TEST_SUBJECT" >&3
echo "" >&3
echo "$TEST_BODY" >&3
echo "." >&3

# Wait for message acceptance
read -r -t 10 -u 3 line || { echo "Timeout waiting for DATA completion"; exit 1; }
if [[ ! "$line" =~ ^250 ]]; then
  echo "Message rejected: $line"
  exit 1
fi

# Send QUIT
echo "QUIT" >&3
read -r -t 10 -u 3 line || { echo "Timeout waiting for QUIT response"; exit 1; }

# Clean up connection
exec 3>&-
exec 3<&-

echo "Test email sent successfully"

# Assert email is in queue
if ls "$QUEUE_DIR"/* 2>/dev/null | grep -q .; then
  echo "Email confirmed in queue"
else
  echo "Email not found in queue"
  exit 1
fi

Key Improvements

  • Uses bash’s built-in /dev/tcp for granular control over command flow instead of nc
  • Adds 10-second timeouts to all read operations to prevent hanging
  • Validates every server response against expected SMTP status codes
  • Properly waits for the 354 response before sending the message body
  • Includes explicit queue assertion (adjust QUEUE_DIR to match your mail server’s queue path)
  • Enables strict error checking with set -euo pipefail

Optimization Suggestions

  • Make Configs Flexible: Allow overriding variables via command-line arguments or environment variables (e.g., SMTP_SERVER=$1 or export SMTP_SERVER=prod-mailserver)
  • Add TLS Support: For servers requiring STARTTLS, replace /dev/tcp with openssl s_client -connect $SMTP_SERVER:$SMTP_PORT -starttls smtp
  • Logging: Redirect output to a log file (e.g., ./smtp-test.sh >> test.log 2>&1) for debugging
  • Test Inbox Validation: Extend the script to check if the test email arrives in a dedicated test inbox (use curl with IMAP/POP3 APIs or tools like fetchmail)

Repeatable Automation Workflow for Config Changes

  1. Version Control Configs: Store all mail server config files (Postfix, Dovecot, etc.) in Git. Track every change to enable rollbacks.
  2. Idempotent Deployment: Use tools like Ansible or Docker Compose to apply config changes—ensure running the deployment multiple times doesn’t cause unintended side effects.
  3. Staging Environment Testing: Run the SMTP test script in a staging environment that mirrors production before applying changes to live systems.
  4. Post-Deployment Validation: Automatically run the SMTP script after config changes to confirm mail flow works. Integrate this into your CI/CD pipeline if available.
  5. Monitoring & Alerts: Set up monitoring for queue sizes, delivery rates, and error codes (e.g., Prometheus + Grafana). Trigger alerts if the test script fails.

Best Practices

  • Isolate Tests: Run tests in a dedicated container or VM to avoid impacting production mail flow.
  • Clean Up Test Data: Configure test emails to be delivered to a disposable inbox or automatically deleted from the queue after testing.
  • Document Everything: Write clear docs for the test script, deployment workflow, and config change process so the entire team can follow it.
  • Schedule Regular Tests: Set up cron jobs or CI/CD pipelines to run the SMTP script daily to catch issues early.
  • Handle Credentials Securely: If your server requires authentication, store credentials in environment variables or a secrets manager instead of hardcoding them.

内容的提问来源于stack exchange,提问作者Kristi Jorgji

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 17:24:29