コンテンツにスキップ

Swaks (Swiss Army Knife for SMTP)

Swaks (Swiss Army Knife for SMTP) is a versatile command-line utility designed for SMTP protocol testing, email server validation, and email delivery troubleshooting. It provides granular control over SMTP communication, allowing security professionals and administrators to test server configurations, validate authentication mechanisms, verify TLS/SSL implementations, and diagnose email delivery issues without requiring a full email client.

  • Full SMTP protocol support: All SMTP commands and options
  • Authentication testing: PLAIN, LOGIN, CRAM-MD5, DIGEST-MD5, XOAUTH2
  • TLS/SSL testing: Secure connection validation and certificate verification
  • EHLO negotiation: Server capability discovery and testing
  • Custom headers: Arbitrary email header insertion
  • Variable substitution: Dynamic content in email payloads
  • Output control: Verbose debugging with detailed protocol traces
  • Pipe input: Read email content from stdin or files
  • Multiple servers: Test failover and backup configurations
# Debian/Ubuntu package manager
sudo apt-get update
sudo apt-get install swaks

# Arch Linux
sudo pacman -S swaks

# RHEL/CentOS
sudo yum install swaks

# From source
git clone https://github.com/jetmore/swaks.git
cd swaks
perl swaks --version

# Or download directly
wget https://www.jetmore.net/code/swaks/swaks
chmod +x swaks
sudo mv swaks /usr/local/bin/
# Using Homebrew
brew install swaks

# Or manual installation
# Download and place in PATH
curl -O https://www.jetmore.net/code/swaks/swaks
chmod +x swaks
sudo mv swaks /usr/local/bin/
# Using Chocolatey
choco install swaks

# Or via Perl
# Requires Perl installation
perl -MCPAN -e "install Mail::Send"
# Then download swaks and run with perl
perl swaks.pl --to test@example.com
# Check installation
swaks --version

# Expected output
# swaks - Version 20130209.0
┌─────────────────────────────────────────┐
│ 1. TCP Connection to SMTP server:25    │
│    Connected to mail.example.com       │
└─────────────────────────────────────────┘

┌─────────────────────────────────────────┐
│ 2. Server Banner (220)                 │
│    220 mail.example.com ESMTP           │
└─────────────────────────────────────────┘

┌─────────────────────────────────────────┐
│ 3. Client EHLO                         │
│    EHLO sender.example.com              │
└─────────────────────────────────────────┘

┌─────────────────────────────────────────┐
│ 4. Server Capabilities (250)           │
│    250-mail.example.com                 │
│    250-AUTH PLAIN LOGIN                 │
│    250-STARTTLS                         │
│    250 SIZE 52428800                    │
└─────────────────────────────────────────┘

┌─────────────────────────────────────────┐
│ 5. Authentication (optional)            │
│    AUTH PLAIN [base64 credentials]     │
│    235 Authenticated                    │
└─────────────────────────────────────────┘

┌─────────────────────────────────────────┐
│ 6. MAIL FROM                            │
│    MAIL FROM:<sender@example.com>      │
│    250 Ok                               │
└─────────────────────────────────────────┘

┌─────────────────────────────────────────┐
│ 7. RCPT TO                              │
│    RCPT TO:<recipient@example.com>     │
│    250 Accepted                         │
└─────────────────────────────────────────┘

┌─────────────────────────────────────────┐
│ 8. DATA                                 │
│    DATA                                 │
│    354 Start input; end with <CR><LF>. │
│    [email headers and body]             │
│    .                                    │
│    250 Ok                               │
└─────────────────────────────────────────┘

┌─────────────────────────────────────────┐
│ 9. QUIT                                 │
│    QUIT                                 │
│    221 Bye                              │
└─────────────────────────────────────────┘
CodeCategoryMeaning
220ConnectionServer ready
235AuthenticationAuth successful
250CommandRequest completed
354Data transferStart mail input
421ConnectionService unavailable
450MailboxUnavailable (temporary)
550MailboxUnavailable (permanent)
551UserNot local, try alternate
553UserMailbox name invalid
554TransactionRefused
# Minimal test (prompts for server)
swaks --to recipient@example.com --from sender@example.com

# With server specified
swaks --to recipient@example.com \
      --from sender@example.com \
      --server mail.example.com

# With explicit subject
swaks --to recipient@example.com \
      --from sender@example.com \
      --server mail.example.com \
      --header "Subject: Test Email"
# Email with body text
swaks --to recipient@example.com \
      --from sender@example.com \
      --server mail.example.com \
      --header "Subject: Test" \
      --body "This is a test message"

# From file
swaks --to recipient@example.com \
      --from sender@example.com \
      --server mail.example.com \
      --body "$(cat /path/to/email_body.txt)"

# From stdin
cat email_body.txt | swaks --to recipient@example.com \
                           --from sender@example.com \
                           --server mail.example.com \
                           --data -
# PLAIN authentication
swaks --server mail.example.com \
      --to recipient@example.com \
      --from sender@example.com \
      --auth PLAIN \
      --auth-user user@example.com \
      --auth-password "MyPassword123"

# LOGIN authentication
swaks --server mail.example.com \
      --to recipient@example.com \
      --auth LOGIN \
      --auth-user user@example.com \
      --auth-password "MyPassword123"

# CRAM-MD5 authentication
swaks --server mail.example.com \
      --to recipient@example.com \
      --auth CRAM-MD5 \
      --auth-user user@example.com \
      --auth-password "MyPassword123"
# Store credentials securely
cat > ~/.swaksrc << 'EOF'
--auth PLAIN
--auth-user user@example.com
--auth-password MyPassword123
--server mail.example.com
EOF

# Restrict permissions
chmod 600 ~/.swaksrc

# Use in command
swaks --to recipient@example.com \
      --from sender@example.com \
      --file ~/.swaksrc

# Or use environment variables
export SWAKS_PASSWD="MyPassword123"
swaks --server mail.example.com \
      --to recipient@example.com \
      --auth PLAIN \
      --auth-user user@example.com \
      --auth-password "$SWAKS_PASSWD"
#!/bin/bash
# Test all available authentication methods

SERVER="mail.example.com"
USER="testuser@example.com"
PASS="password123"
RECIPIENT="recipient@example.com"

AUTH_METHODS=("PLAIN" "LOGIN" "CRAM-MD5" "DIGEST-MD5")

for auth_method in "${AUTH_METHODS[@]}"; do
    echo "Testing $auth_method..."
    swaks --server "$SERVER" \
          --to "$RECIPIENT" \
          --from "$USER" \
          --auth "$auth_method" \
          --auth-user "$USER" \
          --auth-password "$PASS" \
          --header "Subject: Auth Test - $auth_method" \
          --suppress-data
    
    if [ $? -eq 0 ]; then
        echo "✓ $auth_method successful"
    else
        echo "✗ $auth_method failed"
    fi
    echo "---"
done
# STARTTLS connection (upgrade after EHLO)
swaks --server mail.example.com \
      --to recipient@example.com \
      --tls

# STARTTLS with certificate verification
swaks --server mail.example.com \
      --to recipient@example.com \
      --tls \
      --tls-verify

# Ignore certificate warnings (testing only)
swaks --server mail.example.com \
      --to recipient@example.com \
      --tls \
      --tls-ignore-verify
# Direct SSL connection on port 465
swaks --server mail.example.com \
      --port 465 \
      --to recipient@example.com \
      --tls
# Show certificate details
swaks --server mail.example.com \
      --port 465 \
      --to recipient@example.com \
      --tls \
      --tls-cert

# Output certificate information and exit
openssl s_client -connect mail.example.com:465 -quit
# Show all SMTP commands and responses
swaks --server mail.example.com \
      --to recipient@example.com \
      --from sender@example.com \
      -vv

# Even more verbose (includes payload data)
swaks --server mail.example.com \
      --to recipient@example.com \
      -vvv

# Suppress data output (avoid verbose payload)
swaks --server mail.example.com \
      --to recipient@example.com \
      -vv \
      --suppress-data
# JSON output for parsing
swaks --server mail.example.com \
      --to recipient@example.com \
      --output json

# TAP format for test automation
swaks --server mail.example.com \
      --to recipient@example.com \
      --output tap
#!/bin/bash
# Discover SMTP server capabilities

SERVER="mail.example.com"
PORT="${1:-25}"

echo "Scanning: $SERVER:$PORT"
echo ""

# Use netcat to send EHLO
{
    echo "EHLO scanner.example.com"
    sleep 1
    echo "QUIT"
} | nc -w 5 "$SERVER" "$PORT"

echo ""
echo "Or using swaks:"
swaks --server "$SERVER" --port "$PORT" \
      --to "test@example.com" \
      --discover-auth \
      --suppress-data

Example 2: Email Delivery Test with Full Report

Section titled “Example 2: Email Delivery Test with Full Report”
#!/bin/bash
# Comprehensive email delivery test

SERVER="$1"
FROM="test@example.com"
TO="$2"

echo "Email Delivery Test Report"
echo "=========================="
echo "Server: $SERVER"
echo "From: $FROM"
echo "To: $TO"
echo ""

echo "1. Testing basic connectivity..."
swaks --server "$SERVER" \
      --from "$FROM" \
      --to "$TO" \
      --suppress-data || exit 1
echo "✓ Connection successful"
echo ""

echo "2. Testing with custom headers..."
swaks --server "$SERVER" \
      --from "$FROM" \
      --to "$TO" \
      --header "X-Test-Header: TestValue" \
      --header "X-Custom-ID: 12345" \
      --suppress-data
echo "✓ Headers accepted"
echo ""

echo "3. Testing with body..."
swaks --server "$SERVER" \
      --from "$FROM" \
      --to "$TO" \
      --body "Test email with body content" \
      --suppress-data
echo "✓ Email with body sent"
#!/bin/bash
# Test delivery to multiple recipients

SERVER="mail.example.com"
FROM="sender@example.com"
RECIPIENTS=("user1@example.com" "user2@example.com" "user3@example.com")

for recipient in "${RECIPIENTS[@]}"; do
    echo "Testing delivery to: $recipient"
    
    swaks --server "$SERVER" \
          --from "$FROM" \
          --to "$recipient" \
          --header "Subject: Batch Test" \
          --body "Delivery test message" \
          --suppress-data
    
    if [ $? -eq 0 ]; then
        echo "✓ Delivery confirmed"
    else
        echo "✗ Delivery failed"
    fi
done
#!/bin/bash
# Test SPF record compliance

DOMAIN="example.com"
SERVER="mail.example.com"

echo "SPF/DKIM Test for: $DOMAIN"
echo ""

# Test with proper domain
echo "1. Testing with domain-aligned sender..."
swaks --server "$SERVER" \
      --from "test@$DOMAIN" \
      --to "recipient@example.com" \
      --header "Subject: SPF Aligned" \
      --suppress-data

# Test with misaligned domain
echo ""
echo "2. Testing with domain-misaligned sender..."
swaks --server "$SERVER" \
      --from "test@otherdomain.com" \
      --to "recipient@example.com" \
      --header "Subject: SPF Misaligned" \
      --suppress-data
#!/bin/bash
# Test server rate limiting

SERVER="mail.example.com"
FROM="test@example.com"
TO="recipient@example.com"
DELAY=1  # seconds between attempts

for i in {1..10}; do
    echo "Attempt $i/10 at $(date +%H:%M:%S)"
    
    swaks --server "$SERVER" \
          --from "$FROM" \
          --to "$TO" \
          --header "Subject: Rate test $i" \
          --suppress-data
    
    if [ $i -lt 10 ]; then
        sleep "$DELAY"
    fi
done
# Verify server basic requirements

MAIL_SERVER="mail.company.com"

echo "=== Server Configuration Validation ==="
echo ""

# 1. Check if server responds
echo "1. Server Response Test"
swaks --server "$MAIL_SERVER" \
      --port 25 \
      --suppress-data \
      --quit-after-banner

echo ""

# 2. Check authentication requirements
echo "2. Authentication Requirement Test"
swaks --server "$MAIL_SERVER" \
      --to "test@example.com" \
      --from "sender@example.com" \
      --discover-auth

echo ""

# 3. Check TLS support
echo "3. TLS/STARTTLS Support Test"
swaks --server "$MAIL_SERVER" \
      --to "test@example.com" \
      --tls \
      --suppress-data
#!/bin/bash
# Diagnose email delivery issues

TARGET_SERVER="$1"
FROM_ADDRESS="$2"
TO_ADDRESS="$3"

echo "Email Delivery Diagnostics"
echo "=========================="
echo "Server: $TARGET_SERVER"
echo "From: $FROM_ADDRESS"
echo "To: $TO_ADDRESS"
echo ""

# Test 1: Basic connectivity
echo "TEST 1: Basic Connectivity"
swaks --server "$TARGET_SERVER" \
      --port 25 \
      --quit-after-banner \
      -vv
echo ""

# Test 2: Send test email
echo "TEST 2: Send Test Email"
swaks --server "$TARGET_SERVER" \
      --from "$FROM_ADDRESS" \
      --to "$TO_ADDRESS" \
      --header "Subject: Delivery Test" \
      --body "Test email from diagnostic tool" \
      -vv

# Test 3: Check auth if available
echo ""
echo "TEST 3: Authentication Methods"
swaks --server "$TARGET_SERVER" \
      --discover-auth
# Connection
--server SERVER              # SMTP server hostname/IP
--port PORT                  # TCP port (default: 25 for SMTP, 465 for SMTPS)
--timeout SECONDS           # Connection timeout

# Message Components
--to RECIPIENT              # Recipient email address
--from SENDER              # Sender email address
--header HEADER            # Add custom header (e.g., "Subject: Test")
--body TEXT                # Email body content
--data FILE                # Read message from file

# Authentication
--auth METHOD              # AUTH type (PLAIN, LOGIN, CRAM-MD5)
--auth-user USERNAME       # Username for authentication
--auth-password PASSWORD   # Password for authentication
--discover-auth            # Detect supported auth methods

# TLS/Security
--tls                      # Use STARTTLS
--tls-cert                 # Show certificate details
--tls-verify               # Verify server certificate
--tls-ignore-verify        # Skip certificate verification

# Output Control
-vv                        # Very verbose output
-vvv                       # Extra verbose (includes data)
--suppress-data            # Don't print message content
--output FORMAT            # Output format (json, tap)

# Useful Flags
--pipe COMMAND             # Pipe output to command
--quit-after-banner        # Exit after receiving banner
--quit-after-ehlo          # Exit after EHLO response
ProblemCauseSolution
Connection refusedServer not respondingCheck server, port, firewall
Authentication failedWrong credentialsVerify username/password
STARTTLS errorTLS not supportedTry without --tls flag
TimeoutServer slow/unresponsiveIncrease --timeout value
Permission deniedFirewall blockingCheck firewall rules
# Test basic connectivity
telnet mail.example.com 25

# Test TLS port
openssl s_client -connect mail.example.com:465

# Check DNS records (MX records)
dig mail.example.com MX

# Verify SPF record
dig example.com TXT

# Test from different IP
curl --smtp-auth PLAIN --user user@example.com mail.example.com

# Check firewall
nmap -p 25,465,587 mail.example.com
# Test local postfix installation
swaks --server localhost \
      --to recipient@example.com \
      --from sender@example.com
#!/bin/bash
# Monitor SMTP server health

SERVER="mail.example.com"
TIMESTAMP=$(date '+%Y-%m-%d %H:%M:%S')

RESULT=$(swaks --server "$SERVER" \
               --to "test@example.com" \
               --from "test@example.com" \
               --suppress-data 2>&1)

if [ $? -eq 0 ]; then
    echo "[$TIMESTAMP] SMTP Server OK" >> /var/log/smtp-monitor.log
else
    echo "[$TIMESTAMP] SMTP Server FAILED: $RESULT" >> /var/log/smtp-monitor.log
    # Send alert
    echo "SMTP Alert: Server down" | mail -s "Alert" admin@example.com
fi
# 1. Protect credentials
chmod 600 ~/.swaksrc

# 2. Use STARTTLS when available
swaks --server mail.example.com --tls

# 3. Verify certificates
swaks --server mail.example.com --tls --tls-verify

# 4. Avoid hardcoded passwords
# Use environment variables or credential files

# 5. Test on non-production first
# Always test configuration changes on test server
# 1. Use test addresses
--to test@example.com
--from test@example.com

# 2. Clear subject lines
--header "Subject: Testing - Do Not Reply"

# 3. Document tests
# Add comments explaining purpose of each test

# 4. Baseline establishment
# Test before and after configuration changes

# 5. Regular validation
# Include in monitoring/health check scripts

Swaks is an essential tool for email administrators and security professionals. It provides comprehensive SMTP testing capabilities, from basic connectivity validation to advanced authentication and TLS verification. Its flexibility, verbose output, and scriptability make it ideal for troubleshooting email delivery issues, validating server configurations, and testing security implementations in mail infrastructure.