|
|
|
|
@@ -0,0 +1,294 @@
|
|
|
|
|
#!/usr/bin/env python3
|
|
|
|
|
"""Test script to diagnose SMTP connection issues.
|
|
|
|
|
|
|
|
|
|
This script tests SMTP connectivity with different configurations to help
|
|
|
|
|
identify whether the issue is with credentials, network, ports, or TLS settings.
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
import smtplib
|
|
|
|
|
import ssl
|
|
|
|
|
import sys
|
|
|
|
|
from datetime import datetime
|
|
|
|
|
from email.mime.multipart import MIMEMultipart
|
|
|
|
|
from email.mime.text import MIMEText
|
|
|
|
|
|
|
|
|
|
# Load configuration from config.yaml
|
|
|
|
|
try:
|
|
|
|
|
from alpine_bits_python.config_loader import load_config
|
|
|
|
|
|
|
|
|
|
print("Loading configuration from config.yaml...")
|
|
|
|
|
config = load_config()
|
|
|
|
|
email_config = config.get("email", {})
|
|
|
|
|
smtp_config = email_config.get("smtp", {})
|
|
|
|
|
|
|
|
|
|
SMTP_HOST = smtp_config.get("host", "smtp.titan.email")
|
|
|
|
|
SMTP_PORT = smtp_config.get("port", 465)
|
|
|
|
|
SMTP_USERNAME = smtp_config.get("username", "")
|
|
|
|
|
SMTP_PASSWORD = smtp_config.get("password", "")
|
|
|
|
|
USE_TLS = smtp_config.get("use_tls", False)
|
|
|
|
|
USE_SSL = smtp_config.get("use_ssl", True)
|
|
|
|
|
FROM_ADDRESS = email_config.get("from_address", "info@99tales.net")
|
|
|
|
|
FROM_NAME = email_config.get("from_name", "AlpineBits Monitor")
|
|
|
|
|
|
|
|
|
|
# Get test recipient
|
|
|
|
|
monitoring_config = email_config.get("monitoring", {})
|
|
|
|
|
daily_report = monitoring_config.get("daily_report", {})
|
|
|
|
|
recipients = daily_report.get("recipients", [])
|
|
|
|
|
TEST_RECIPIENT = recipients[0] if recipients else "jonas@vaius.ai"
|
|
|
|
|
|
|
|
|
|
print(f"✓ Configuration loaded successfully")
|
|
|
|
|
print(f" SMTP Host: {SMTP_HOST}")
|
|
|
|
|
print(f" SMTP Port: {SMTP_PORT}")
|
|
|
|
|
print(f" Username: {SMTP_USERNAME}")
|
|
|
|
|
print(f" Password: {'***' if SMTP_PASSWORD else '(not set)'}")
|
|
|
|
|
print(f" Use SSL: {USE_SSL}")
|
|
|
|
|
print(f" Use TLS: {USE_TLS}")
|
|
|
|
|
print(f" From: {FROM_ADDRESS}")
|
|
|
|
|
print(f" Test Recipient: {TEST_RECIPIENT}")
|
|
|
|
|
print()
|
|
|
|
|
|
|
|
|
|
except Exception as e:
|
|
|
|
|
print(f"✗ Failed to load configuration: {e}")
|
|
|
|
|
print("Using default values for testing...")
|
|
|
|
|
SMTP_HOST = "smtp.titan.email"
|
|
|
|
|
SMTP_PORT = 465
|
|
|
|
|
SMTP_USERNAME = input("Enter SMTP username: ")
|
|
|
|
|
SMTP_PASSWORD = input("Enter SMTP password: ")
|
|
|
|
|
USE_TLS = False
|
|
|
|
|
USE_SSL = True
|
|
|
|
|
FROM_ADDRESS = "info@99tales.net"
|
|
|
|
|
FROM_NAME = "AlpineBits Monitor"
|
|
|
|
|
TEST_RECIPIENT = input("Enter test recipient email: ")
|
|
|
|
|
print()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def create_test_message(subject: str) -> MIMEMultipart:
|
|
|
|
|
"""Create a test email message."""
|
|
|
|
|
msg = MIMEMultipart("alternative")
|
|
|
|
|
msg["Subject"] = subject
|
|
|
|
|
msg["From"] = f"{FROM_NAME} <{FROM_ADDRESS}>"
|
|
|
|
|
msg["To"] = TEST_RECIPIENT
|
|
|
|
|
msg["Date"] = datetime.now().strftime("%a, %d %b %Y %H:%M:%S %z")
|
|
|
|
|
|
|
|
|
|
body = f"""SMTP Connection Test - {datetime.now().strftime("%Y-%m-%d %H:%M:%S")}
|
|
|
|
|
|
|
|
|
|
This is a test email to verify SMTP connectivity.
|
|
|
|
|
|
|
|
|
|
Configuration:
|
|
|
|
|
- SMTP Host: {SMTP_HOST}
|
|
|
|
|
- SMTP Port: {SMTP_PORT}
|
|
|
|
|
- Use SSL: {USE_SSL}
|
|
|
|
|
- Use TLS: {USE_TLS}
|
|
|
|
|
|
|
|
|
|
If you received this email, the SMTP configuration is working correctly!
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
msg.attach(MIMEText(body, "plain"))
|
|
|
|
|
return msg
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_smtp_connection(host: str, port: int, timeout: int = 10) -> bool:
|
|
|
|
|
"""Test basic TCP connection to SMTP server."""
|
|
|
|
|
import socket
|
|
|
|
|
|
|
|
|
|
print(f"Test 1: Testing TCP connection to {host}:{port}...")
|
|
|
|
|
try:
|
|
|
|
|
sock = socket.create_connection((host, port), timeout=timeout)
|
|
|
|
|
sock.close()
|
|
|
|
|
print(f"✓ TCP connection successful to {host}:{port}")
|
|
|
|
|
return True
|
|
|
|
|
except socket.timeout:
|
|
|
|
|
print(f"✗ Connection timed out after {timeout} seconds")
|
|
|
|
|
print(f" This suggests a network/firewall issue blocking access to {host}:{port}")
|
|
|
|
|
return False
|
|
|
|
|
except socket.error as e:
|
|
|
|
|
print(f"✗ Connection failed: {e}")
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_smtp_ssl(host: str, port: int, username: str, password: str, timeout: int = 30) -> bool:
|
|
|
|
|
"""Test SMTP connection with SSL."""
|
|
|
|
|
print(f"\nTest 2: Testing SMTP with SSL (port {port})...")
|
|
|
|
|
try:
|
|
|
|
|
context = ssl.create_default_context()
|
|
|
|
|
with smtplib.SMTP_SSL(host, port, timeout=timeout, context=context) as server:
|
|
|
|
|
print(f"✓ Connected to SMTP server with SSL")
|
|
|
|
|
|
|
|
|
|
# Try to get server info
|
|
|
|
|
server.ehlo()
|
|
|
|
|
print(f"✓ EHLO successful")
|
|
|
|
|
|
|
|
|
|
# Try authentication if credentials provided
|
|
|
|
|
if username and password:
|
|
|
|
|
print(f" Attempting authentication as: {username}")
|
|
|
|
|
server.login(username, password)
|
|
|
|
|
print(f"✓ Authentication successful")
|
|
|
|
|
else:
|
|
|
|
|
print(f"⚠ No credentials provided, skipping authentication")
|
|
|
|
|
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
except smtplib.SMTPAuthenticationError as e:
|
|
|
|
|
print(f"✗ Authentication failed: {e}")
|
|
|
|
|
print(f" Check your username and password")
|
|
|
|
|
return False
|
|
|
|
|
except socket.timeout:
|
|
|
|
|
print(f"✗ Connection timed out after {timeout} seconds")
|
|
|
|
|
print(f" Try increasing timeout or check network/firewall")
|
|
|
|
|
return False
|
|
|
|
|
except Exception as e:
|
|
|
|
|
print(f"✗ SMTP SSL failed: {e}")
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_smtp_tls(host: str, port: int, username: str, password: str, timeout: int = 30) -> bool:
|
|
|
|
|
"""Test SMTP connection with STARTTLS."""
|
|
|
|
|
print(f"\nTest 3: Testing SMTP with STARTTLS (port {port})...")
|
|
|
|
|
try:
|
|
|
|
|
with smtplib.SMTP(host, port, timeout=timeout) as server:
|
|
|
|
|
print(f"✓ Connected to SMTP server")
|
|
|
|
|
|
|
|
|
|
# Try STARTTLS
|
|
|
|
|
context = ssl.create_default_context()
|
|
|
|
|
server.starttls(context=context)
|
|
|
|
|
print(f"✓ STARTTLS successful")
|
|
|
|
|
|
|
|
|
|
# Try authentication if credentials provided
|
|
|
|
|
if username and password:
|
|
|
|
|
print(f" Attempting authentication as: {username}")
|
|
|
|
|
server.login(username, password)
|
|
|
|
|
print(f"✓ Authentication successful")
|
|
|
|
|
else:
|
|
|
|
|
print(f"⚠ No credentials provided, skipping authentication")
|
|
|
|
|
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
except smtplib.SMTPAuthenticationError as e:
|
|
|
|
|
print(f"✗ Authentication failed: {e}")
|
|
|
|
|
return False
|
|
|
|
|
except socket.timeout:
|
|
|
|
|
print(f"✗ Connection timed out after {timeout} seconds")
|
|
|
|
|
return False
|
|
|
|
|
except Exception as e:
|
|
|
|
|
print(f"✗ SMTP TLS failed: {e}")
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def send_test_email(host: str, port: int, username: str, password: str,
|
|
|
|
|
use_ssl: bool, use_tls: bool, timeout: int = 30) -> bool:
|
|
|
|
|
"""Send an actual test email."""
|
|
|
|
|
print(f"\nTest 4: Sending test email...")
|
|
|
|
|
try:
|
|
|
|
|
msg = create_test_message("SMTP Test Email - AlpineBits")
|
|
|
|
|
|
|
|
|
|
if use_ssl:
|
|
|
|
|
context = ssl.create_default_context()
|
|
|
|
|
with smtplib.SMTP_SSL(host, port, timeout=timeout, context=context) as server:
|
|
|
|
|
if username and password:
|
|
|
|
|
server.login(username, password)
|
|
|
|
|
server.send_message(msg, FROM_ADDRESS, [TEST_RECIPIENT])
|
|
|
|
|
|
|
|
|
|
else:
|
|
|
|
|
with smtplib.SMTP(host, port, timeout=timeout) as server:
|
|
|
|
|
if use_tls:
|
|
|
|
|
context = ssl.create_default_context()
|
|
|
|
|
server.starttls(context=context)
|
|
|
|
|
|
|
|
|
|
if username and password:
|
|
|
|
|
server.login(username, password)
|
|
|
|
|
|
|
|
|
|
server.send_message(msg, FROM_ADDRESS, [TEST_RECIPIENT])
|
|
|
|
|
|
|
|
|
|
print(f"✓ Test email sent successfully to {TEST_RECIPIENT}")
|
|
|
|
|
print(f" Check your inbox!")
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
except Exception as e:
|
|
|
|
|
print(f"✗ Failed to send email: {e}")
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def main():
|
|
|
|
|
"""Run all SMTP tests."""
|
|
|
|
|
print("=" * 70)
|
|
|
|
|
print("SMTP Connection Test Script")
|
|
|
|
|
print("=" * 70)
|
|
|
|
|
print()
|
|
|
|
|
|
|
|
|
|
# Test 1: Basic TCP connection
|
|
|
|
|
tcp_ok = test_smtp_connection(SMTP_HOST, SMTP_PORT, timeout=10)
|
|
|
|
|
|
|
|
|
|
if not tcp_ok:
|
|
|
|
|
print("\n" + "=" * 70)
|
|
|
|
|
print("DIAGNOSIS: Cannot establish TCP connection to SMTP server")
|
|
|
|
|
print("=" * 70)
|
|
|
|
|
print("\nPossible causes:")
|
|
|
|
|
print("1. The SMTP server is down or unreachable")
|
|
|
|
|
print("2. A firewall is blocking the connection")
|
|
|
|
|
print("3. The host or port is incorrect")
|
|
|
|
|
print("4. Network connectivity issues from your container/server")
|
|
|
|
|
print("\nTroubleshooting:")
|
|
|
|
|
print(f"- Verify the server is correct: {SMTP_HOST}")
|
|
|
|
|
print(f"- Verify the port is correct: {SMTP_PORT}")
|
|
|
|
|
print("- Check if your container/server has outbound internet access")
|
|
|
|
|
print("- Try from a different network or machine")
|
|
|
|
|
print(f"- Use telnet/nc to test: telnet {SMTP_HOST} {SMTP_PORT}")
|
|
|
|
|
return 1
|
|
|
|
|
|
|
|
|
|
# Test 2 & 3: Try both SSL and TLS
|
|
|
|
|
ssl_ok = False
|
|
|
|
|
tls_ok = False
|
|
|
|
|
|
|
|
|
|
if USE_SSL:
|
|
|
|
|
ssl_ok = test_smtp_ssl(SMTP_HOST, SMTP_PORT, SMTP_USERNAME, SMTP_PASSWORD, timeout=30)
|
|
|
|
|
|
|
|
|
|
# Also try common alternative ports
|
|
|
|
|
if not ssl_ok and SMTP_PORT == 465:
|
|
|
|
|
print("\n⚠ Port 465 failed, trying port 587 with STARTTLS...")
|
|
|
|
|
tls_ok = test_smtp_tls(SMTP_HOST, 587, SMTP_USERNAME, SMTP_PASSWORD, timeout=30)
|
|
|
|
|
|
|
|
|
|
if USE_TLS:
|
|
|
|
|
tls_ok = test_smtp_tls(SMTP_HOST, SMTP_PORT, SMTP_USERNAME, SMTP_PASSWORD, timeout=30)
|
|
|
|
|
|
|
|
|
|
if not ssl_ok and not tls_ok:
|
|
|
|
|
print("\n" + "=" * 70)
|
|
|
|
|
print("DIAGNOSIS: Cannot authenticate or establish secure connection")
|
|
|
|
|
print("=" * 70)
|
|
|
|
|
print("\nPossible causes:")
|
|
|
|
|
print("1. Wrong username or password")
|
|
|
|
|
print("2. Wrong port for the encryption method")
|
|
|
|
|
print("3. SSL/TLS version mismatch")
|
|
|
|
|
print("\nTroubleshooting:")
|
|
|
|
|
print("- Verify your credentials are correct")
|
|
|
|
|
print("- Port 465 typically uses SSL")
|
|
|
|
|
print("- Port 587 typically uses STARTTLS")
|
|
|
|
|
print("- Port 25 is usually unencrypted (not recommended)")
|
|
|
|
|
return 1
|
|
|
|
|
|
|
|
|
|
# Test 4: Send actual email
|
|
|
|
|
send_ok = send_test_email(
|
|
|
|
|
SMTP_HOST, SMTP_PORT, SMTP_USERNAME, SMTP_PASSWORD,
|
|
|
|
|
USE_SSL, USE_TLS, timeout=30
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
print("\n" + "=" * 70)
|
|
|
|
|
if send_ok:
|
|
|
|
|
print("✓ ALL TESTS PASSED!")
|
|
|
|
|
print("=" * 70)
|
|
|
|
|
print("\nYour SMTP configuration is working correctly.")
|
|
|
|
|
print(f"Check {TEST_RECIPIENT} for the test email.")
|
|
|
|
|
else:
|
|
|
|
|
print("⚠ PARTIAL SUCCESS")
|
|
|
|
|
print("=" * 70)
|
|
|
|
|
print("\nConnection and authentication work, but email sending failed.")
|
|
|
|
|
print("This might be a temporary issue. Try again.")
|
|
|
|
|
|
|
|
|
|
return 0
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
|
|
try:
|
|
|
|
|
sys.exit(main())
|
|
|
|
|
except KeyboardInterrupt:
|
|
|
|
|
print("\n\nTest cancelled by user")
|
|
|
|
|
sys.exit(1)
|