I use SES for sending emails to users. Sometimes users reported to me that they did not receive any emails from me. I started to collect bounced emails via sns topic and found a lot of errors with status = 5.5.1 and
diagnosticCode
"smtp; 550 5.1.1 Remote MTA does not support STARTTLS. Message can be delivered only over a TLS connection."
I use the aws-sdk and my code which sends emais:
let params = {
Destination: {
ToAddresses: [emailDestination]
},
Message: {
Body: {
Html: {
Charset: "UTF-8",
Data: template({
...templateData
})
},
},
Subject: {
Charset: 'UTF-8',
Data: templateData.subject
}
},
Source: SOURCE_EMAIL,
ConfigurationSetName: CONFIGURATION_SET_NAME
};
await ses.sendEmail(params).promise()
My ConfigurationSet has TLS Required
What did I do wrong and could it be a remote configuration issue of the user?
I think you are on the right track of it being a remote issue. From the sound of the error, Amazon SES is trying to connect to a remote mail relay but failing to create a TLS connection and canceling instead.
Your configuration set is enforcing a policy of sending only when a TLS connection can be established to receiving server (and message is encrypted) all the way to the end-user. Depending on how sensitive your emails are, this may be the desired behavior.
However, if you want to continue to send the mail, even when unencrypted, you can disable the require TLS setting. Amazon will still use TLS when possible, according to their documentation -
https://docs.aws.amazon.com/ses/latest/DeveloperGuide/security.html
By default, Amazon SES uses opportunistic TLS. This means that Amazon SES always attempts to make a secure connection to the receiving mail server. If Amazon SES can't establish a secure connection, it sends the message unencrypted.
Related
I've been looking for my problem in Vesta Forum. I found some information, but still sending mail doesn't work.
My IP isn't on any black list
I turned Off ipv6, spamassasin and clamd in exim configuration like this:
SPAMASSASSIN = no
SPAM_SCORE = 50
CLAMD = no
disable_ipv6=true
Mail are not sending from:
PHP mail() and Wordpress
Roundcube
In Roundcube I got following error, while sending to gmail:
A message that you sent could not be delivered to one or more of its recipients. This is a permanent error. The following address(es) failed:
***#gmail.com
host alt2.gmail-smtp-in.l.google.com [108.177.14.26]
SMTP error from remote mail server after pipelined end of data:
550-5.7.1 [52.210.16.21 7] Our system has detected that this message is
550-5.7.1 likely unsolicited mail. To reduce the amount of spam sent to Gmail,
550-5.7.1 this message has been blocked. Please visit
550-5.7.1 https://support.google.com/mail/?p=UnsolicitedMessageError
550 5.7.1 for more information. b10si20481ljd.189 - gsmtp
Reporting-MTA: dns; bobcars.pl
Action: failed
Final-Recipient: rfc822;***#gmail.com
Status: 5.0.0
Remote-MTA: dns; alt2.gmail-smtp-in.l.google.com
Diagnostic-Code: smtp; 550-5.7.1 [52.210.16.21 7] Our system has detected that this message is
550-5.7.1 likely unsolicited mail. To reduce the amount of spam sent to Gmail,
550-5.7.1 this message has been blocked. Please visit
550-5.7.1 https://support.google.com/mail/?p=UnsolicitedMessageError
550 5.7.1 for more information. b10si20481ljd.189 - gsmtp
While I'm sending to another (polish o2.pl)
This message was created automatically by mail delivery software.
A message that you sent could not be delivered to one or more of its
recipients. This is a permanent error. The following address(es) failed:
pzatorski#o2.pl
all hosts for 'o2.pl' have been failing for a long time (and retry time not reached)
Reporting-MTA: dns; bobcars.pl
Action: failed
Final-Recipient: rfc822;pzatorski#o2.pl
Status: 5.0.0
Can anyone help me please?
Thanks to offical VestaCP forum i've noticed that you need to contact AWS to reduce your sending email limits.
So I have a domain purchased through SES which I have verified with SES.I have tested that sending/receiving works by signing into the email with the workmail web app.I am getting the following error when trying to send email with my spring app.
javax.mail.MessagingException: Could not connect to SMTP host: email-smtp.eu-west-1.amazonaws.com, port: 25, response: 421
Appconfig.Java
#Configuration
#PropertySource("app.properties")
#EnableTransactionManagement
public class AppConfig {
#Autowired
private Environment env;
#Bean
public JavaMailSender getJavaMailSender() {
JavaMailSenderImpl mailSender = new JavaMailSenderImpl();
mailSender.setHost("email-smtp.eu-west-1.amazonaws.com");
mailSender.setPort(25);
mailSender.setUsername("noreply#mydomain.com");
mailSender.setPassword("mypassword");
Properties props = mailSender.getJavaMailProperties();
props.put("mail.transport.protocol", "smtp");
props.put("mail.smtp.auth", "true");
props.put("mail.smtp.starttls.enable", "true");
props.put("mail.smtp.starttls.required", "true");
props.put("mail.debug", "true");
return mailSender;
}}
EmailServiceImpl.java
#Component
public class EmailServiceImpl {
#Autowired
public JavaMailSender emailSender;
public void sendSimpleMessage(String toAddress, String subject, String text)
{
SimpleMailMessage message = new SimpleMailMessage();
message.setTo(toAddress);
message.setSubject(subject);
message.setText(text);
emailSender.send(message);
}
}
EmailServiceImpl is autowired into my web controller where I send an email after generating a password reset token
First of all,you have done everything right as said in the AWS docs.
You are right in using your smtp credentials as you are using their smtp interface to send mail,and not their aws sdk(if you use,aws sdk,you have to use acces key and password).
But,here comes some other issues which might help you resolve the issues which we have to do as it is not there in the docs.
You have to troubleshoot the error code sent by smtp.
Mostly,SMTP error code 421 shows up when the recipient mail server is very busy as it is receiving a lot of messages,so it temporarily defers your message by giving this error code or your recipient client have some problems.
You can study here.
https://sendgrid.com/blog/smtp-server-response-codes-explained/#:~:text=421%20%E2%80%93%20Your%20message%20was%20temporarily,locked%20or%20is%20not%20routable.
https://www.arclab.com/en/kb/email/smtp-response-codes-error-messages.html#:~:text=The%20SMTP%20error%20421%20is,see%20SMTP%20Error%20451%20below).
You can try sending the mail after sometime or you can try sending with different port.
My Incident:
I was using AWS SES for sending mail from my Springboot Application.
I was also using SMTP interface of AWS ses like you.
There are 3 ports which are listed on AWS management console to send mail.
But,when I was using Port 465,it was not working.
But,when I was using Port 25 or Port 587,it was working.
But,even then,It is always recommended to use 587 as it is recommended by IETF and is safest to use with TLS.
Using Port 465 is least recommended.You can study here but AWS supports it.There are many clients still supporting it but it is not widely in use.
As,I told you in my case it was failing.
You can study here about all the 3 ports and how port 465 functioning is different from port 25 and 587
But,you can solve the issue of port 465 by using smtps protocol with it.
Port-25,587(use smtp as protocol)
Port-465(use smtps as protocol,as in this case client has to initiate the tls encryption)
https://docs.aws.amazon.com/ses/latest/DeveloperGuide/smtp-connect.html
You can get a guide from where to chose a port.
https://pepipost.com/blog/25-465-587-2525-choose-the-right-smtp-port/
You are using port 25. SES uses port 465 or 2465. Also remember to use SES SMTP credentials and not your IAM credentials (AccessKey).
Connecting to the Amazon SES SMTP Endpoint
Using Grails 2.5.5 with the spring-websockets plugin 1.3.1 and tomcat 8.0.37.
While using an AWS Elastic Load Balancer, the following error is shown in the Javascript console when loading the application in the browser
WebSocket connection to 'ws://...s.com/Application/stomp/059/uyqk9cdn/websocket' failed: Error during WebSocket handshake: Unexpected response code: 400
From research it has been found that the ELB doesn't support websockets and proxying within the ELB, a third party load balancer or potentially using a new Application Load Balancer (the applications are not in a VPC so this is not an easy solution) might be required.
However, after the error, the following logging is received:
Web Socket Opened...
>>> CONNECT
accept-version:1.1,1.0
heart-beat:10000,10000
<<< CONNECTED
version:1.1
heart-beat:0,0
user-name:admin
connected to server undefined
>>> SUBSCRIBE
id:sub-0
destination:/topic/someTopic
Messages are then received by the client fine when they are broadcast
<<< MESSAGE
destination:/topic/someTopic
content-type:application/json;charset=UTF-8
subscription:sub-0
message-id:xb71g__u-16
content-length:89
The code to initiate the websocket connection is
<r:require module="spring-websocket"/>
<r:script>
var socket = new SockJS("${createLink(uri: '/stomp')}");
var client = Stomp.over(socket);
client.connect({}, function () {
var topic = "/topic/digTicketUpdated";
console.log("Subscribing to -> " + topic);
client.subscribe(topic, function (message) {
console.log("Push Message Received From Server");
updateStatus(message.body);
});
});
</r:script>
This is taken from the grails-spring-websocket github page.
Is it possible to figure out if this is fallback that has kicked in, the websocket actually working or some other scenario. To summarise :
Is the websocket falling back to another protocol?
Is there any way to get rid of the 400 error?
Thanks to the suggestions in the comments, it was found that after the "Unexpected response code: 400" was thrown, SockJS attempted to use a long POST XHR request to emulate the web socket and it worked. This was viewable in the Network tab of Chrome Developer Tools as "xhr_streaming".
To prevent the 400 error showing in the development console, a configurable switch was implemented so web socket connections are not attempted when it is known they are not supported, such as on an AWS ELB. This was achieved by passing by removing "websocket" from the allowed protocols when instantiating SockJS :
var allowedProtocols = ['xdr-streaming', 'xhr-streaming', 'iframe-eventsource', 'iframe-htmlfile', 'xdr-polling', 'xhr-polling', 'iframe-xhr-polling', 'jsonp-polling']
var socket = new SockJS(uri, {}, {protocols_whitelist : allowedProtocols});
var client = Stomp.over(socket);
I'm having trouble getting Amazon SNS to send a subscription message to my HTTPS endpoint. The CloudWatch logs report the following:
{
"delivery": {
"deliveryId": "7bdda6a5-0000-5d6d-b0c0-e9b254fde521",
"destination": "https://www.beta.yogacentre.com/webhooks/sns",
"providerResponse": "SSLPeerUnverifiedException in HttpClient",
"dwellTimeMs": 63661,
"attempts": 4
},
"status": "FAILURE"
}
It looks like it doesn't like the SSL certificate I'm using, but I confirmed that the root CA is on the list SNS checks. Chrome reports my connection uses TLS 1.2, so it should be compatible with the recent end of SSLv3 support.
As a sanity check I tried subscribing to a regular HTTP endpoint and it worked right away. What could be causing the problem? My certificate can be found at https://www.beta.yogacentre.com/ in case there is something I missed.
Have a look at the report for this site from SSLLabs and you will see:
This server's certificate chain is incomplete. Grade capped to B.
This means that the server is not properly setup in that it does not sent all needed chain certificates, i.e. everything in the trust path between the leaf certificate for the site and the root certificate trusted by the browser or system. Looking at the details you will see that the server sends only the leaf certificate and the missing certificate for "COMODO RSA Domain Validation Secure Server CA" is marked as "Extra Download".
While some browsers like Chrome will download missing certificates from the internet others don't and applications outside of browsers don't do it either. Thus all these clients which don't know the missing chain certificate will fail because they cannot build the trust chain, which causes the SSLPeerUnverifiedException you see. Therefore you need to fix your server configuration to also sent the missing chain certificates. Details depend on the server configuration.
Although the issue in your case turned out to be the certificate chain, there's another potential cause. As of writing, SNS callbacks don't support TLSv1.3 and will spit back this error if your endpoint only supports TLSv1.3. For the time being, the only way around this appears to be to enable TLSv1.2. I wasn't able to find any documentation notating this.
I encountered this issue with Cloudflare Universal SSL with the minimum version set to TLSv1.3. Changing the minimum version to TLSv1.2 resolved the issue.
I am trying to connect to an amazon server for sending emails by editing by web.config
<system.net>
<mailSettings>
<smtp deliveryMethod="Network">
<network enableSsl="true" port="587" host="email-smtp.us-east-1.amazonaws.com" password="actual password" userName="actual username"/>
</smtp>
</mailSettings>
</system.net>
These settings are being set as evidenced below:
All I am doing in code is
SmtpClient client = new SmtpClient();
client.SendCompleted += SendCompletedCallback;
string userState = _id.ToString();
client.SendAsync(msg, userState);
but the error I get back is always
A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond 184.73.222.29:587
Before I was using an internal mail server, but since this will be getting pushed to the amazon cloud, I will not have access to the local server. In the case of the local server, all i had to do was specify the ip address for host and it ran just fine.
There were three issues at hand:
1: The email address it was being sent from was not verified with Amazon, and neither was the recipient (verification of recipient only needed in sandbox mode)
2: The out port I was using, 587, is blocked by my company, which seems to be common practice
3: Using async can only be done when you specify the page uses async in the aspx "header"