We are using Elasticemail for our SMTP server and running in issues where our server would fail to connect to the SMTP server for various reasons. Currently, we only find out about the issue when a user complains.
We want to monitor the connection to the server on a regular interval and notify Admin if there is a connection failure.
Is there any way to test the connection to the server without sending an actual email using Python3?
import smtplib
smtpObj = smtplib.SMTP('smtp.office365.com', 587)
smtpObj.ehlo()
smtpObj.starttls()
smtpObj.login('xxx#gmail.com', ' abcde')
smtpObj.sendmail('xxx#gmail.com', 'yyyy#outlook.com', 'Subject: So long.\nDear Alice, so long and thanks for all the fish. Sincerely, Bob')
{}
smtpObj.close()
The error I am getting
SMTPAuthenticationError: (535, b'5.7.3 Authentication unsuccessful [BM1PR01CA0150.INDPRD01.PROD.OUTLOOK.COM]').
Most likely, the authenticated SMTP (SMTP AUTH protocol) is disabled in your Exchange Online organization.
SMTP AUTH can be enabled/disabled on the organization level, or per-mailbox. Because SMTP AUTH only uses basic authentication, Microsoft recommends to disable it on the organization level and enable it only for individual accounts that still require it.
If security defaults are enabled in the organization, then SMTP AUTH is disabled.
SMTP AUTH can be enabled in Microsoft 365 admin center or using Exchange Online Powershell.
To make it simple, to enable SMTP AUTH for a single account:
Go to the Microsoft 365 admin center (https://admin.microsoft.com/) > Users > Active users.
Select the user you are going to send emails from, and go to the Mail tab.
In the Email apps section click Manage email apps.
Enable Authenticated SMTP and click Save changes.
After that you should be able to authenticate using the respective account.
Important: You need admin rights in your Office 365 organization to do that. Otherwise, ask your O365 org admin for help.
Further details: https://learn.microsoft.com/exchange/clients-and-mobile-in-exchange-online/authenticated-client-smtp-submission
#wombatonfire gave a terrific answer, but if for any reason those steps aren't possible (as was my situation), the following solved the OP problem for me.
I'm on a Mac. Can't get to admin center. Had to use powershell.
Also, powershell on my Mac had to connect to MSFT exchange server before I could change the setting for my mailbox. The following makes email work as designed.
There is a critical hoop to jump through to make this all work.
To connect your Mac to MSFT Exchange server, your Mac must use TLS1.2 from/via/through OpenSSL1.0. OpenSSL1.1 is a no go.
Get a terminal window on your Mac:
Click LaunchPad, type "term", click Terminal
In the terminal window, check what version(s) of OpenSSL are on your Mac:
>ls -al /usr/local/Cellar/openssl*
See which what version is active:
>openssl version -a
OpenSSL 1.1.* is bad.
OpenSSL 1.0.* is good.
NORMALLY, you can use brew to switch versions of a package is active with:
>brew switch openssl 1.0.2s
>brew link --overwrite openssl
But I got this error: Warning: Refusing to link macOS provided/shadowed software: openssl.
So I had to get tricky.
Change PATH environment variable (just in this terminal session, not permanently).
>PATH=/usr/local/Cellar/openssl/1.0.2s/bin:$PATH
Now the check, shows good version:
>openssl version -a
Next, I followed steps to install powershell documented here:
https://learn.microsoft.com/en-us/powershell/scripting/install/installing-powershell-core-on-macos?view=powershell-7
Now, open powershell as admin.
>sudo su - root
<your mac password>
root>pwsh
At the powershell prompt, double check your powershell version. Version 7 is needed.
>$host.version
I have: 7.0.3 Revision -1
Check what modules are installed in powershell:
>Get-Module -ListAvailable
If "PowerShellGet" is not listed, install it:
>Install-Module -Name PowerShellGet -Force
This next step is critical to success on the Mac. Only the latest "preview version 2.0.4" of "ExchangeOnlineManagement" package is going to work on Mac.
I don't know if this is needed, but I uninstalled the released version of "ExchangeOnlineManagement" package with:
>Uninstall-Module -Name ExchangeOnlineManagement -RequiredVersion 2.0.3
If preview version not present, install it:
>Install-Module -Name ExchangeOnlineManagement -AllowPrerelease -Force
One last detail to take care of. Tell powershell what version of TLS you want "ExchangeOnlineManagement" package to use:
>[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
Finally, it's time to connect to the mothership:
(Again, this is trickier on a Mac than in Windows, probably).
>Connect-ExchangeOnline -UserPrincipalName youremail#yourdomain
The above command will try to open a browser to a special authentication page. At least on my Mac, it couldn't. So:
COPY the giant link that gets displayed in the powershell window
PASTE the giant link into a web browser (I used Safari).
After you enter your Exchange credentials on that browser page, your powershell will show a progress bar for a short time, then magically be connected to MSFT Exchange server!
And the last step to set the SMTP setting on the mailbox you want to use:
Set-CASMailbox -Identity youremail#yourdomain -SmtpClientAuthenticationDisabled $false
Lastly, apparently it's important to always explicitly disconnect (before closing the terminal window):
>Disconnect-ExchangeOnline
That's the ballgame. You are changing the "disabled" setting to false for each/any/all mailboxes you want to send email from.
Now the fully documented, oft repeated python code seen in the OP will use SMTP and TLS to send email via MSFT Exchange (until something else breaks it all again :-O ).
Enjoy!
Thanks #wombatonfire - very helpful - I have a small addition to your answer.
I tried for a few hours to setup up multiple email addresses to send mail from a Python script; all of the accounts I was working with showed Authenticated SMTP to be enabled on the Active User page, but I was still getting authentication errors.
Not until I deselected and re-selected the "Authenticated SMTP" checkbox for each account did the script work.
Thanks
When I am running a Python micro-service in a dockerized or kubernetes container it works just fine. But with Istio service mesh, it is not working.
I have added ServiceEntry for two of my outbound external http apis. It seems I can access the url content form inside the container using curl command which is inside service mesh. So, I think the service entries are fine and working.
But when I try from the micro-service which uses xml.sax parser in Python, it gives me the upstream connect error or disconnect/reset before headers though the same application works fine without Istio.
I think it is something related to Istio or Envoy or Python.
Update: I did inject the Istio-proxy side-car. I have also added ServiceEntry for external MySQL database and mysql is connected from the micro-service.
I have found the reason for this not working. My Python service is using xml.sax parser library to parse xml form the internet, which is using the legacy urllib package which initiate http/1.0 request.
Envoy doesn't support http/1.0 protocol version. Hence, it is not working. I made the workaround by setting global.proxy.includeIPRanges="10.x.0.1/16" for Istio using helm. This actually bypass the entire envoy proxy for all outgoing connections outside the given ip ranges.
But I would prefer not to globally bypass Istio.
Need help to send mail `(smtp.gmail.com)` through proxy settings.
Not working even after trying multiple libraries (Including socks)
Latest - Using `xsmtplib`.. but getting following error.
The HTTP proxy server may not be supported by PySocks (must be a CONNECT tunnel proxy)
Any help will be really appreciated.
Below code for connecting with SMTP server via Proxy
"""from xsmtplib import SMTP
server = SMTP(proxy_host,proxy_port,host,port,timeout)
server.sendmail("aaaa#gmail.com", "bbbb#gmail.com", "Test Msg")
server.quit()"""
You can use xsmtplib, an extension of standard smtplib, which supports proxy tunneling.
I'm trying to send emails using python smtp library but get the following an error message when trying to send to external email addresses (internal email works):
smtplib.SMTPRecipientsRefused: {'test#gmail.com': (550, ' Relaying denied')}
This is because we have rules setup on our exchange that prevent relaying from client machines.
What I don't understand is how come I can send emails over SMTP with an SSIS package without getting the relay error.
Is there a setting I need to enable in my python to bypass this or is SSIS sending the email to SQL Server to send on its behalf.
I believe you are getting this due to authentication. SSIS is probably passing your windows credentials through but when you are trying to send with python your credentials are being denied.
Not 100% sure that is your issue. But a thought.