JavaMail Not Working on Amazon EC2

2019-03-27 13:30发布

问题:


PROBLEM:

I'm trying to use JavaMail to send email from an EC2 Ubuntu 12.04 Server but it's not working.


BACKGROUND:

I intend to send an auto generated mail from a Tomcat Server to a few team members. I used JavaMail 1.4.7 for this task and I've successfully tried it on a local installation of Tomcat (on a personal laptop).

The next step was where I put this module on an EC2 Server but it started failing with the below given error:


ERROR:

DEBUG SMTP: AUTH LOGIN failed javax.mail.AuthenticationFailedException: 535-5.7.1 Username and Password not accepted. Learn more at 535 5.7.1 http://support.google.com/mail/bin/answer.py?answer=14257 j13sm1603739pat.17 - gsmtp

at com.sun.mail.smtp.SMTPTransport$Authenticator.authenticate(SMTPTransport.java:826)
at com.sun.mail.smtp.SMTPTransport.authenticate(SMTPTransport.java:761)
at com.sun.mail.smtp.SMTPTransport.protocolConnect(SMTPTransport.java:685)
at javax.mail.Service.connect(Service.java:295)
at javax.mail.Service.connect(Service.java:176)

Code Snippet:

Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());
Properties props = new Properties();
props.put("mail.smtps.host","smtp.gmail.com");
props.put("mail.transport.protocol", "smtp");
props.put("mail.smtps.auth", "true");
props.put("mail.smtp.debug", "true");
props.put("mail.smtp.port", 465);
props.put("mail.smtp.socketFactory.port", 465);
props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
props.put("mail.smtp.socketFactory.fallback", "false");
props.put("mail.smtp.ssl.enable", true);

Session session = Session.getDefaultInstance(props);
session.setDebug(debug);

Message msg = new MimeMessage(session);
InternetAddress addressFrom = new InternetAddress("fromId@gmail.com");
msg.setFrom(addressFrom);

InternetAddress[] addressTo = new InternetAddress[recipients.length];
for (int i = 0; i < recipients.length; i++) {
addressTo[i] = new InternetAddress(recipients[i]);
}
msg.setRecipients(Message.RecipientType.TO, addressTo);
msg.setSubject("test subject");
msg.setContent("test message", "text/plain");
Transport tp = session.getTransport("smtp");
tp.connect(SMTP_HOST_NAME, "dummyId@gmail.com", "dummypassword");
tp.sendMessage(msg, addressTo);
tp.close();

ADDITIONAL INFO:

  1. I've added permissions for all ports on the EC2 instance. Also, I've added explicit permissions for ports 465(SMTPS) and 25(SMTP).
  2. I've cross checked the correctness of the username and password provided in the code.

回答1:

In the past, spam sent from servers within EC2 has been a major problem for both Amazon and mail service providers. Initially, Amazon deliberately had insufficient DNS information to pass anti-spam checking of common email services (lack of DNS reverse lookup PTR records), then Amazon introduced low mail quotas, followed approval processes to give full access to EC2 or SES mail (provides specific technical setup to fully enable outgoing email).

Here's a link describing some of the history: http://shlomoswidler.com/2009/07/sending-email-from-ec2.html

While the error you're getting is a failed authentication at Gmail server, it may be (probably is) because Gmail identifies your sender IP address as a potential spammer, because you didn't setup Amazon reverse DNS lookup properties correctly.

  1. Setup Amazon Reverse DNS lookup details, so that your mail is not detected as spam by Gmail. It seems this can only be done by submitting a request form to lift Email Sending quota. From Amazon EC2 IP Information FAQs:

    Q: Can I configure the reverse DNS record for my Elastic IP address?

    Yes, you can configure the reverse DNS record of your Elastic IP address (submit the Request to Remove Email Sending Limitations Form). Note that a corresponding forward DNS record pointing to that Elastic IP address must exist before we can create the reverse DNS record.

    Here's an example of an email sent out by Amazon when an email quota is exhausted - again spelling out request & approval for DNS PTR configuration: http://www.practicalclouds.com/content/guide/sending-email-ec2-instances

  2. Precisely follow all the instructions in the link included in you Gmail error message: http://support.google.com/mail/bin/answer.py?answer=14257. This will reset your Gmail account status, if Gmail thinks your account is spamming from your IP address.

  3. Alternatively, you can send mail via Amazon SES, also requiring request, approval and appropriate Amazon-provided configuration. This allows mail to be sent via com.amazonaws.services.simpleemail.AmazonSimpleEmailServiceClient.sendEmail. If you use this, add authorisation for your code to sendmail: Unable to send email from Amazon EC2 Server in Java.