Do not print stack trace on Postfix's mail delivery failure notification - postfix-mta

When our service fails to deliver an email, the rejection notification returned to the sender contains the stack trace of the code that failed. Is there a way to send the delivery notification, without the attached errors?
We have a postfix server that handles incoming emails in a catchall python script. That script uploads the email to one of our services and throws an exception in case it failed.
This is the template we are using
failure_template = <<EOF
Charset: us-ascii
From: MAILER-DAEMON (Mail Delivery System)
Subject: Undelivered Mail Returned to Sender
Postmaster-Subject: Postmaster Copy: Undelivered Mail
This is the mail system at host $myhostname.
I'm sorry to have to inform you that your message could not
be delivered to one or more recipients. It's attached below.
For further assistance, please send mail to <postmaster>
If you do so, please include this problem report. You can
delete your own text from the attached returned message.
The mail system
EOF
Expected result would be just the template notification, without the strack trace of the catch-all script.

The mail server simply includes in the bounce whatever your Python program displays on its standard error. Maybe call the script via a wrapper which saves the standard error to a sane place (or even discards it, if you are sure it never contains anything useful).
#!/bin/sh
python3 /path/to/deliver.py 2>>/var/log/deliver.log
Your mail server obviously needs to have write access to the log, and you'll probably want to set up periodic log rotation for the file.
Probably a better overall approach is for the Python program to not crash.

Related

How to set hostname used in JavaMail or Apache James Message-Id header?

I am having issues with mail bouncing when sending from my own server to my own active yahoo account using JavaMail. The mails are passing SPF, DKIM and DMARC according to google mail that receives the same messages being bounced by yahoo. I can send messages from other accounts to my yahoo account without issue.
The messages send fine from my server to ZMail, GMail, Microsoft mail. Looking at the emails, the only thing that I have noticed is the message header for the Message-Id. My messages have the following header:
Message-ID: <923936395.17.1634776639078#[internally visible hostname]>
I am wondering if this header could be the problem and whether there is a way in JavaMail or in the Apache James to set the hostname or IP address that gets used in this message so that rather than using the "internally visible hostname", I can get the hostname that is externally visible. I have been searching the available documentation for Apache James and JavaMail but have not found any parameters to try in order to resolve this.
According to the Decompiled SRC of sun mail it should be possible by setting some properties for your session.
props.setProperty("mail.from", user);
props.setProperty("mail.host", host);
//props.setProperty("mail.user", user);
The Id will be updated by the save method (saveChanges()) and will trigger an new ID generation (updateHeaders() -> updateMessageID()). (Looked up in the decompiled MimeMessage.class)
Leading to the HostPart called in javax.mail.internet.InternetAddress.
The relevant method is _getLocalAddress.
Here you can see that the values get extracted from the Properties or will fallback to your local machine.
Used Fields:
user.name
mail.from
mail.user
mail.host
The user.name property can also be looked up from the system props.

Temporary block from yahoo

For quite some time we have been getting the following error from yahoo:
mail.log:6452:Apr 22 19:21:06 aegir postfix/smtp[8997]: 87BCF4C93F: host mta7.am0.yahoodns.net[67.195.228.110] said: 421 4.7.0 [IPTS04] Messages from 188.93.125.68 temporarily deferred due to user complaints - 4.16.55.1; see https://help.yahoo.com/kb/postmaster/SLN3434.html (in reply to end of DATA command)
If someone did get the similar, how did you solve this issue?
I've been trying to contact Yahoo but everytime I get automated response and ticket closure as I send it.
What other thing I can offer is DMARC report if its relevant:
https://mxtoolbox.com/DmarcReportAnalyzer.aspx?id=F-9a3a8364-6cba-41f9-b93f-cfc32155a3f6
Test for headers and every check seems to be working alright:
https://www.mail-tester.com/test-m5ytebosm
Google email is showing everything is pass:
gmail email
gmail header
For now I've tried changing OpenDKIM to relaxed/relaxed from relaxed/simple.
Removed p=quarantine and added p=none
Sorted out SPF record for official signing domain just in case, added another IP address where resourcecenter is found.
Will provide additional info if needed.

ax2009 x++ Error 0x80040211 in RunBaseBatch

I want to send email in RunBaseBatch, but I get error 0x80040211 (unknown).
I found in google that means:
The message could not be sent to the SMTP server.
The transport error code was %2. The server response was %1
public void SendReport(str email)
{
SysMailer sm = new SysMailer();
;
sm.quickSend("axmail#domain.eu", email, "Test", strfmt("body"));
}
This method is called in Run method. And if I copy this source code into job that works. Additionally in Run method I use,
permissionSet = new Set(Types::Class);
permissionSet.add(new InteropPermission(InteropKind::ClrInterop));
permissionSet.add(new InteropPermission(InteropKind::ComInterop));
permissionSet.add(new InteropPermission(InteropKind::DllInterop));
CodeAccessPermission::assertMultiple(permissionSet);
Because your email seems to work in a job (client side), your email settings in AX are not the issue.
This is most likely an authentication issue.
Take a look at this article, which describes what your are experiencing.
On the client side, your current windows user is used to authenticate with the SMTP server.
In batch, the emails are sent from the AOS. That means that the account used for authentication, is the account under which the AOS service runs.
Your mail server probably doesn't accept connections from everyone.
Take a look here on how this is achieved.
You'll have to allow the user that runs your AOS service, to authenticate to your mail server.

How to check MailMessage was delivered in .NET?

Is there a way to check if SmtpClient successfully delivered an email? SmtpClient.Send() does not appear to return anything other than an exception. So if the method completes is it safe to assume the email will be successfully sent to the appropriate email box? My code is below:
MailMessage emailMessage = new MailMessage();
emailMessage.Subject = SubjectText;
emailMessage.IsBodyHtml = IsBodyHtml;
emailMessage.Body = BodyText;
emailMessage.From = new MailAddress(Settings.Default.FromEmail,Settings.Default.FromDisplayName);
//add recipients
foreach (string recipientAddress in RecipientAddresses.Split(new char[{','},StringSplitOptions.RemoveEmptyEntries))
emailMessage.To.Add(recipientAddress);
using (SmtpClient smtpClient = new SmtpClient())
{
smtpClient.Send(emailMessage);
}
No, there is no reliable way to find out if a message was indeed delivered.
Doing so will require access to the end SMTP server for every person you are emailing.
If you do not get an exception, you can assume that the SMTP server did its best to deliver the email.
There's no way to be 100% sure that a mail message has been received when sent via SmtpClient due to the way email works. The fact that SmtpClient doesn't throw an exception essentially means that you've done everything right, but a failure can happen further down the line, for example:
The receiving mail server could reject the mail
An intermediate mail server could reject the mail
The server that SmtpClient is transmitting mail through could decide to refuse to transmit the mail
One solution you could use is to create an httphandler for your website images. If you send an HTML message which includes at least 1 image, then you could embed querystring data to the end of that image. This could even be something like a 1x1 transparent image. When the user reads the email, this sends the request to the server to fetch the image data, and in turn, you could capture that request and denote that the message was read.
This is not bulletproof however, because most email clients block images by default unless the user specifies they would like to view images in the email.
If the recipient e-mail address is valid you don't get an immediate return value about the successful delivery of the message; see the signature:
public void Send(MailMessage message)
The SMTP server will notify the sender (or whoever you specify for the notification) almost immediately with an 'Undeliverable' notification whenever the recipient e-mail address is invalid/fake.
SMTP servers are required to periodically retry delivery. When the recipient e-mail address is a valid address but for some reason the SMTP server could not deliver the message, the SMTP server will return a failure message to the sender if it cannot deliver the message after a certain period of time.
RFC 2821 contains more details.
From section 2.1 Basic Structure
In other words, message transfer can occur in a single connection
between the original SMTP-sender and the final SMTP-recipient, or can
occur in a series of hops through intermediary systems. In either
case, a formal handoff of responsibility for the message occurs: the
protocol requires that a server accept responsibility for either
delivering a message or properly reporting the failure to do so.
See sections 4.5.4 and 4.5.5
From section 6.1 Reliable Delivery and Replies by Email
If there is a delivery failure after acceptance of a message, the
receiver-SMTP MUST formulate and mail a notification message. This
notification MUST be sent using a null ("<>") reverse path in the
envelope. The recipient of this notification MUST be the address from
the envelope return path (or the Return-Path: line).

Wildcards in an email address with qmail?

I'm trying to set up an email address in qmail such that a unique identifier can be passed as part of the email address.
For example:
reply-123#example.com, reply-345#example.com, reply-99999#example.com would all go to the 'reply' user and be sent to the same shell script. Currently, email sent to reply#example.com goes to the script and I pass the unique id in the subject or message body. Would be grateful for any suggestions. Thanks!
In a default qmail setup, you can do exactly what you suggest... anything following a dash is ignored for delivery purposes, so reply-anything#example.com will be processed by the .qmail-reply file, where you would presumably send the mail to your script and look at the address to obtain the identifier.
We use this for bounce tracking - if the email is to xyz#example.com, and the sender is bounce#sender.com, then the from address is written this way:
bounce-xyz=example.com#sender.com
And a script flags the address as no good.
EDIT:
I screwed this up a bit - I guess I'm rusty on qmail. The alias thing doesn't work by default as I stated above. To support extensions for bounce#sender.com, you need a .qmail-default file in ~bounce.
See the "extension addresses" (section 4.1.5) on LWQ: http://www.lifewithqmail.org/lwq.html

Resources