It is technically possible to send an email directly to the recipient's SMTP server from your computer.
Looking at it from a historical basis, if the remote SMTP server is down, you want a system to automatically handle it and keep retrying it— hence you have an SMTP server. Similarly, in the old days, not all mail servers were connected all the time—long distance links were expensive, so mail would be queued and sent when a link was established.
Moving on to where Internet is cheap, it's still useful to have mechanisms to retry sending email if a server is unavailable, and it's not ideal for this functionality to be written into the MUA (Mail user agent/end user mail program). These functions fit into an MTA (Mail server/SMTP server).
But it gets worse—spammers. Most emails (way more than 80%) are spam. So mail providers do whatever they can to reduce this problem—and a large number of techniques make assumptions about the way email is delivered—the following are important considerations:
Greylisting: Some providers will automatically drop a mail connection if the sender and recipient have not communicated before, and expect them to try a second time—because spammers often don't, while an SMTP server is always supposed to. This reduces spam volumes by about 80%. It sucks to have to do this though.
Reputation: It is a lot more likely that someone sending email through a reputable, known SMTP server is legit than a fly-by-night server. To get a feel for reputation, providers do a number of things:
Block dynamic / client addresses (Not 100%, but large chunks of the Internet have been mapped out).
Look that reverse DNS matches forward DNS: Not very hard to do, but shows some level of accountability and knowledge of best practices—and something a lot of client address blocks don't have.
Reputation: When communicating with other SMTP servers, a lot of providers keep track of the amount of spam and volumes of email sent and can reduce the amount of spam by limiting connections and keeping an eye on these parameters. (There are lots of ways this is done, not all of them obvious, but which require a known sender).
SPF and DKIM: These mechanisms tie DNS resources to the domain
name to make forging mail harder, and would be difficult (but not
necessarily impossible to deploy if the mail program (MUA) is
responsible for outgoing mail. (Added to make this answer more complete
as it's already been accepted. Credit for it should go to posters below
as it slipped my mind, but is, nonetheless, very valid)
There are probably other minor concerns, but these would be the major ones.
Disclaimer
I expect that at least some of the information below will be redundant for you. Please bear with me. =)
smtplib vs. smptd
Python comes with two modules for dealing with email — smtplib and smtpd. The difference between the two is that smtplib
is used to send emails, while smptd
is used to receive emails. In this case, for sending emails, you should only need need to use smtplib
.
Email with Python 3.6 smtplib
I want to send an email via my domain name (for example myname@mydomain.name).
Since you haven't provided your source script, I have listed a working Python 3.6 mail script for reference below:
# Python mail script with smtplib, email.utils and email.mime.text.
# --- imports ---
import smtplib
import email.utils
from email.mime.text import MIMEText
# --- create our message ---
# Create our message.
msg = MIMEText('The body of your message.')
msg['To'] = email.utils.formataddr(('Recipient Name', 'recipient@example.com'))
msg['From'] = email.utils.formataddr(('Your Name', 'yourname@yourdomain.com'))
msg['Subject'] = 'Your Subject'
# --- send the email ---
# SMTP() is used with normal, unencrypted (non-SSL) email.
# To send email via an SSL connection, use SMTP_SSL().
server = smtplib.SMTP()
# Specifying an empty server.connect() statement defaults to ('localhost', 25).
# Therefore, we specify which mail server we wish to connect to.
server.connect ('mail.example.com', 25)
# Optional login for the receiving mail_server.
# server.login ('login@example.com', 'Password')
# Dump communication with the receiving server straight to to the console.
# server.set_debuglevel(True)
# 'yourname@yourdomain.com' is our envelope address and specifies the return
# path for bounced emails.
try:
server.sendmail('yourname@yourdomain.com', ['recipient@example.com'], msg.as_string())
finally:
server.quit()
Note that while I use "server" as the smtplib
object name, you are free to continue use "s" (or whatever) in your own script. Likewise, use of the email.util and email.mime modules is not strictly necessary but they are helpful with constructing the final message.
I am new to SMTP and all I've been getting are lots of errors.
I can't say what your other errors might be caused by but the output you listed indicates a connection to sigsmileyface.ddns.net could not be established on port 25. The key lines are:
s = smtplib.SMTP('sigsmileyface.ddns.net')
, which defaults to port 25.
The final line ConnectionRefusedError: [...] the target machine actively refused it
, which could indicate a firewall or mail server configuration issue.
Troubleshooting
Check The Mail Server And Port
Establish that the server you are connecting to has an active mail server and what port it is running on (usually port 25 for incoming mail).
In your case, if you have control of sigsmileyface.ddns.net and are attempting to send emails to it, you should check that your mail server is set up correctly to receive mail on port 25. I believe that sendmail
is the standard mail server on Pi. You should also confirm that the port isn't blocked by a firewall and that any necessary port forwarding is set up correctly in your router.
On a similar note, while it shouldn't really make a difference for directly connecting to your mail server, you may want to set up MX records if you are going to be sending mail to/receiving email at sigsmileyface.ddns.net.
Check Your Connection
You should double-check that your script has the correct connection values, whether you specify them in the smptlib
object or via .connect()
. Note that the host name you specify will always either be a direct connection to the server you wish to send mail to or an intermediary mail server (local or otherwise) you expect to pass messages on your behalf.
While it seems unlikely in your case, you should also be aware of any username or passwords needed to connect to the receiving server. This is most common when using another server to relay mail but it is worth remembering.
Check If You Need To Use A Relay
Ensure that you don't need to use a relay of some sort. In short, some ISPs do certain things to prevent spam that may necessitate the use of special mail servers to initially transfer or receive messages on port 25.
For instance, the local ISP for my home service filters port 25. It forces normal outgoing mail destined for this port to be sent via an ISP SSL mail relay. Simultaneously, it blocks incoming messages on this port for home users.
This means that to send and receive email on port 25, I have to pass normal outgoing mail (what your script is attempting) to smtp.isp.com to forward it to the recipient on port 25 while using a second (third-party) service to route incoming mail from port 25 to port XXX (where my mail server actually listens).
Note that doesn't actually prevent mail from being sent or received on other open ports (which can be fine for testing or personal uses) but since most mail servers use port 25 for consistency, using a relay may be a necessity in the long run.
In case it wasn't clear enough, you can do testing on ports other than 25 assuming you put the correct values in your script and have control of the receiving mail server.
Best Answer
SMTP servers do not require authentication. Services like GMail, and my own servers, will require authentication, to send to users outside their domain. If you are sending within the intranet, it is unlikely you will require authentication.
There are minimal SMTP relay servers like SSMTP which are designed to send outgoing email without a full install. Full service servers like Exim, Postfix, and Sendmail can be configured to use a Smarthost (relay) for all outgoing mail. Usually, this would be the corporate mail server, or the ISPs relay server, neither of which is likely to require authentication. Either of these solutions would be appropriate.
Languages like PHP, Perl, and Java have packages which will connect directly to a remote SMTP server. This allows them to send email from hosts which don't have a mail server running. Normally, these would be configured to connect to a relay server as described above.
Ensure the sending address is appropriate. For something like this you may want to use an address in the form
noreply@example.com
. Use the client's domain in place of host. The client may prefer a different sending address. You may also want aReply-To:
address with the email address of someone who knows about the system, although that may need to be maintained over time.