3
votes

I have a crontab that includes a [email protected]. My server uses msmtp to forward the email to Amazon Simple Email Service. My problem is that output from cron commands never arrives in my mailbox. This is what the msmtp log says:

Mar 06 14:26:02 host=email-smtp.us-east-1.amazonaws.com tls=on auth=on user=MY.SES.USER [email protected] [email protected] smtpstatus=554 smtpmsg='554 Transaction failed: User name is missing: ?Cron Daemon ?.' errormsg='the server did not accept the mail' exitcode=EX_UNAVAILABLE

What do I need to do in order to make Amazon SES accept the cron emails?

2
Are you using the SMTP credentials generated through Amazon console? Are you sending from a verified email account? Are you in sandbox or production SES? If in sandbox: are you sending to a verified email account? - Viccari
Yes, I'm using the provided SMTP credentials, and they work fine when I send email through PHP. The from address and to address are the same - they have a domain name that is verified with SES (and again, it works through PHP). Do you happen to know where I can find the full source of the email? Right now I can only see the short message in the log. - jbsteel
I do not... I suggest posting your question on Amazon Developer Forums. - Viccari
Link to @jbsteel's post at the AWS Developer Forums: forums.aws.amazon.com/thread.jspa?messageID=540183 - Arto Bendiken

2 Answers

4
votes

The suggested solution from the AWS Developer Forums:

It turns out that cron has the "from" address hard-coded in the source (q.v. "do_command.c" in the cron source), so one does not have influence over what cron transmits to sendmail (which in our case is symlinked to "/usr/bin/msmtp").

However, due to the magic of Linux, we do have the ability to alter the stream of text that goes into sendmail.

The way I worked around this cron limitation was to move the "msmtp" binary to"msmtp.bin" and then create "/usr/bin/msmtp" that was a shell script:

#! /bin/bash
sed -e 's/root .Cron Daemon./[email protected]/' | /usr/bin/msmtp.bin "$@"

This is also, AFAIK, the only means one has to set the "debug" flag to msmtp when used in a "global" setting (such as cron, or other cases where sendmail is invoked with arguments you don't control).

While the script above is rather simplistic, you can also conditionally alter the text by checking the input arguments for the magic "-FCronDaemon" which is also hard coded in the cron binary. I would be stunned if any other program calls sendmail with "-FCronDaemon".

3
votes

Had exact same problem but the answer above didn't work for me so here's what I did...

As the problem is isolated to cron, and symlinking sendmail to msmtp works everywhere else, I didn't want to change the msmtp command globally for everything. So I first created /usr/bin/msmtp_cron.bin and made it executable.

Next I had to tell cron to use this as its mail path, by editing /etc/sysconfig/crond to read:

CRONDARGS="-m '/usr/bin/msmtp_cron.bin -t'"

Then not forgetting to restart crond (reloading alone isn't enough):

$ sudo systemctl restart crond.service

Back to /usr/bin/msmtp_cron.bin, in this file, I first had to find out what cron was actually streaming to sendmail/msmtp to know what substitution I could make:

sed '' > /tmp/cron-mail-capture.txt

This yielded these headers:

From: "(Cron Daemon)" <root>

It's slightly different from the other answer so my sed script ended up looking like so:

sed -e 's/..Cron Daemon.* <root>/[email protected]/' | /usr/bin/msmtp -t "$@"

Now it successfully sends cron messages via AWS SES to my email account.