后缀返回无效地址; 454 <to@domain.com>: 中继访问被拒绝

Postfix returning Invalid Addresses; 454 <to@domain.com>: Relay access denied

我正在使用预配置的 Postfix 服务器并使用 JavaMail 与其交互。我正在尝试向可能请求它的任何外部域发送电子邮件通知。

这里是java发送测试邮件的方法:

public void TestEmail() {

    String to = "to@domain.com";

    String from = "noreply@hostdomain.com";
    final String username = "user";
    final String password = "password";

    String host = "xxx.xxx.xxx.xxx";

    Properties props = new Properties();
    props.put("mail.smtp.auth", "true");
    props.put("mail.smtp.starttls.enable", "true");
    props.put("mail.smtp.host", host);
    props.put("mail.smtp.port", "587");

    Session session = Session.getInstance(props,
            new Authenticator() {
                protected PasswordAuthentication getPasswordAuthentication() {
                    return new PasswordAuthentication(username, password);
                }
    });
    try {
        Message message = new MimeMessage(session);

        message.setFrom(new InternetAddress(from));

        message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(to));

        message.setSubject("Test Email");

        message.setContent("This is a test email", "text/html");

        Transport.send(message);

        System.out.println("The test message was sent!");
    } catch (MessagingException e) {
        throw new RuntimeException(e);
    }

}

当我运行包含Java邮件代码的方法时,我得到
generalError: javax.mail.SendFailedException: Invalid Addresses; nested exception is: com.sun.mail.smtp.SMTPAddressFailedException: 454 4.7.1 <to@domain.com>: Relay access denied

我能够使用
测试从 Postfix 服务器发出的邮件 echo "This is the body" | mail -s "This is the subject" to@domain.com
并确实在测试收件箱中收到了电子邮件。

我不是 100% 确定 Postfix 服务器上的所有设置,但我怀疑这就是问题所在,但我对它还不够熟悉,无法开始深入研究和更改所有内容情不自禁。

编辑: 我从会话创建中删除了 Authenticator() 设置,并用推荐的代码块

替换了 Transport.send()
        Transport transport = session.getTransport("smtp");
        transport.connect(host, 587, username, password);
        transport.sendMessage(message, message.getAllRecipients());
        transport.close();  

整套新代码是:

    String host = "xxx.xxx.xxx.xxx";

    Properties props = new Properties();
    props.put("mail.smtp.auth", "true");
    props.put("mail.smtp.starttls.enable", "true");
    props.put("mail.smtp.host", host);
    props.put("mail.smtp.port", "587");

    Session session = Session.getInstance(props, null);

    try {
        Message message = new MimeMessage(session);

        message.setFrom(new InternetAddress(from));

        message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(to));

        message.setSubject("Test Email");

        message.setContent("This is a test email", "text/html");

        Transport transport = session.getTransport("smtp");
        transport.connect(host, 587, username, password);
        transport.sendMessage(message, message.getAllRecipients());
        transport.close();

        System.out.println("The test message was sent!");
    } catch (MessagingException e) {
        System.out.println("Error: " + e);
        e.printStackTrace();
        throw new RuntimeException(e);
    }

}

这已将我收到的错误消息更改为:Unrecognized SSL message, plaintext connection?


已解决

解决方案:Java 代码不是问题所在。 Postfix 服务器未配置为接受来自非本地 IP/host 的电子邮件。 IP 已添加到 mynetworks 变量中的 main.cf。

This article 有更多信息。

首先,按照 JavaMail FAQ. That will ensure that it's really trying to authenticate to the server. Turn on JavaMail session debugging 中所述删除 Authenticator 以确保它正在验证。

注意可以替换

    Transport transport = session.getTransport("smtp");
    transport.connect(host, 587, username, password);
    transport.sendMessage(message, message.getAllRecipients());
    transport.close();

    Transport.send(message, username, password);

您可以删除 mail.smtp.auth 设置,但保留其他属性。

确保您使用的是 most current version of JavaMail

如果还是不行,上面的文章可能会提供一些关于如何更改 Postfix 配置的线索。