A perl script sending mails for testing a mail server
Posted Under: email,Linux,perl,Server admin,Software
Just set up your mail server? Congratulations! Now you should test it. In particular, check if it relays mails to other servers and if the response time is reasonable. Here’s a script for doing the testing. Just edit the arguments to send_mail() to match your setting.
#!/usr/bin/perl
use warnings;
use strict;
use Net::SMTP;
send_mail('127.0.0.1', # Host
'sender@nowhere.com', #From
'myself@myhost.com', #to
'Just a test, please ignore', #Message body
"Testing email.\n" # Subject
);
sub send_mail {
my ($SMTP_HOST, $from, $to_addr, $body, $subject, $msg) = @_;
$msg = "MIME-Version: 1.0\n"
. "From: $from\n"
. "To: " . ( ref($to_addr) ? join(';', @$to_addr) : $to_addr ) . "\n"
. "Subject: $subject\n\n" # Double \n
. $body;
#
# Open a SMTP session
#
my $smtp = Net::SMTP->new( $SMTP_HOST,
'Debug' => 1, # Change to a 1 to turn on debug messages
Port => 587,
);
die("SMTP ERROR: Unable to open smtp session.\n")
if(!defined($smtp) || !($smtp));
die("Failed to set FROM address\n")
if (! ($smtp->mail( $from ) ) );
die("Failed to set receipient\n")
if (! ($smtp->recipient( ( ref($to_addr) ? @$to_addr : $to_addr ) ) ) );
$smtp->data( $msg );
$smtp->quit;
}
Two things to note:
The Port assignment marked red above makes an encryption connection with the server. It can be changed to 25, but many servers don’t answer strangers on that port.
July 2024 update: Nowadays, the situation seems to be the opposite. Mail servers that appear in the MX records and owned by Internet actors seem to answer only to port 25, and apparently only small servers answer to 587. Possibly because port 587 is commonly used for outgoing mail by MUAs (mail clients wishing to send an email) and port 25 is used only between servers (MTAs) …?
And if this script is used to talk with a remote server, odds are it won’t work due to authentication issues. If your server runs sendmail, it can be made less picky by making the following temporary changes to allow for testing:
In /etc/mail/sendmail.mc, change confAUTH_OPTIONS from `A’ to `’ (nothing, no authentication required). Also, change
DAEMON_OPTIONS(`Port=submission, Name=MSA, M=Ea')dnl
to
DAEMON_OPTIONS(`Port=submission, Name=MSA')dnl
and then compile the configuration file and restart the server with
# make -C /etc/mail # service sendmail restart
Needless to say, it’s recommended to return the original settings after the testing is done. Your mail server should have some self-respect.
Anyhow, a typical output should look like this:
Net::SMTP>>> Net::SMTP(2.31) Net::SMTP>>> Net::Cmd(2.29) Net::SMTP>>> Exporter(5.62) Net::SMTP>>> IO::Socket::INET(1.31) Net::SMTP>>> IO::Socket(1.30_01) Net::SMTP>>> IO::Handle(1.27) Net::SMTP=GLOB(0x7c9d98)<<< 220 myhost.localdomain ESMTP Sendmail 8.14.4/8.14.4; Mon, 14 Jan 2013 14:03:26 +0200 Net::SMTP=GLOB(0x7c9d98)>>> EHLO localhost.localdomain Net::SMTP=GLOB(0x7c9d98)<<< 250-myhost.localdomain Hello localhost.localdomain [127.0.0.1], pleased to meet you Net::SMTP=GLOB(0x7c9d98)<<< 250-ENHANCEDSTATUSCODES Net::SMTP=GLOB(0x7c9d98)<<< 250-PIPELINING Net::SMTP=GLOB(0x7c9d98)<<< 250-8BITMIME Net::SMTP=GLOB(0x7c9d98)<<< 250-SIZE Net::SMTP=GLOB(0x7c9d98)<<< 250-DSN Net::SMTP=GLOB(0x7c9d98)<<< 250-ETRN Net::SMTP=GLOB(0x7c9d98)<<< 250-AUTH DIGEST-MD5 CRAM-MD5 LOGIN PLAIN Net::SMTP=GLOB(0x7c9d98)<<< 250-DELIVERBY Net::SMTP=GLOB(0x7c9d98)<<< 250 HELP Net::SMTP=GLOB(0x7c9d98)>>> MAIL FROM:<sender@nowhere.com> Net::SMTP=GLOB(0x7c9d98)<<< 250 2.1.0 <sender@nowhere.com>... Sender ok Net::SMTP=GLOB(0x7c9d98)>>> RCPT TO:<myself@myhost.com> Net::SMTP=GLOB(0x7c9d98)<<< 250 2.1.5 <myself@myhost.com>... Recipient ok Net::SMTP=GLOB(0x7c9d98)>>> DATA Net::SMTP=GLOB(0x7c9d98)<<< 354 Enter mail, end with "." on a line by itself Net::SMTP=GLOB(0x7c9d98)>>> MIME-Version: 1.0 Net::SMTP=GLOB(0x7c9d98)>>> From: sender@nowhere.com Net::SMTP=GLOB(0x7c9d98)>>> To: myself@myhost.com Net::SMTP=GLOB(0x7c9d98)>>> Subject: Testing email. Net::SMTP=GLOB(0x7c9d98)>>> Net::SMTP=GLOB(0x7c9d98)>>> Net::SMTP=GLOB(0x7c9d98)>>> Just a test, please ignore Net::SMTP=GLOB(0x7c9d98)>>> . Net::SMTP=GLOB(0x7c9d98)<<< 250 2.0.0 r0EC3Qm3030991 Message accepted for delivery Net::SMTP=GLOB(0x7c9d98)>>> QUIT Net::SMTP=GLOB(0x7c9d98)<<< 221 2.0.0 myhost.localdomain closing connection
Reader Comments
Works great and this really helped, so thanks for breaking this down for me…..
Much appreciated
Thanks for sharing, is it possible to scan smtp from file with multi threads ?