1

My mail needs are simple. I only want to send system notifications via a non-SMTP hook. (The hook sends out to a mailgun account over https).

I imagine all linux programs (e.g. cron) calling something like "(send)mail [options] content". Or are they calling SMTP service directly?

If they are calling "(send)mail [options] content" then it should be easy to adapt/write a shell script or program to convert that call to my hook.

I did find this reference:

Linux Standard Base PDA Specification 3.0RC1

Synopsis /usr/sbin/sendmail [options] [address...] Description

To deliver electronic mail (email), applications shall support the interface provided by sendmail (described here). This interface shall be the default delivery method for applications.

This program sends an email message to one or more recipients, routing the message as necessary. This program is not intended as a user interface routine.

With no options, sendmail reads its standard input up to an end-of-file or a line consisting only of a single dot and sends a copy of the message found there to all of the addresses listed. It determines the network(s) to use based on the syntax and contents of the addresses.

If an address is preceded by a backslash, '\', it is unspecified if the address is subject to local alias expansion.

The format of messages shall be as defined in RFC 2822:Internet Message Format.

Options

-bm
read mail from standard input and deliver it to the recipient addresses. This is the default mode of operation.

... (etc) ...

Is this what I'm looking for? In other words, a program called "sendmail" is invoked, and stdin will be mail content compliant with RFC2882.

Note: I know there is program called "nullmail" but I believe that sends outbound using SMTP, which I don't want. May it could be adapted to for the RFC2822 parsing front end.


Thanks to @ivanivan for informing that sendmail is the de facto interface. Therefore, to send all notifications to a fixed email address via a free Mailgun account (and logging it as well), the following code will suffice:

#!/bin/bash
Logfile=/var/log/sendmail-dummy.log
Tmpf=$(mktemp -t sendmail-dummy-XXXXXX.txt)
TmpCurlLog=$(mktemp -t sendmail-dummy-XXXXXX.txt)
trap 'rm -f ${Tmpf} ${TmpCurlLog}' 0

Date=$(date +%F-%T)
echo "[$Date] Caller: $(caller)" >>${Tmpf}
echo "[$Date] Caller: $0" >>${Tmpf}
echo "[$Date] Args: ${@}" >>${Tmpf}
echo "[$Date] Content:" >>${Tmpf}
while read line ; do
    echo $line  >>${Tmpf}
done
echo "" >>${Tmpf}

MailgunDomain="example.com"
# The key is assigned by Mailgun when signing up for free account 
Key="key-<some hex string>"
# not sure if the from-mail-addr has to belong to example.com
FromAddr="[email protected]"
# the to-mail-addr must be registered on Mailgun by showing you own it 
ToAddr="[email protected]"

curl -s --user "api:${Key}" "https://api.mailgun.net/v3/${MailgunDomain}/messages" \
     -F from=" <$FromAddr>" \
     -F to="${ToAddr}" \
     -F subject='Notification' \
     -F text="<${Tmpf}" > ${TmpCurlLog}
rc=$?

echo "----------------------------------------" >> ${Logfile}
echo "[$Date] curl result = $rc" >> ${Logfile}
cat ${Tmpf} >> ${Logfile}
echo "----------------------------------------" >> ${Logfile}
cat ${TmpCurlLog} >> ${Logfile}
echo "" >> ${Logfile}
echo "++++++++++++++++++++++++++++++++++++++++" >> ${Logfile}

Available as a gist

As can be seen, it doesn't try to interpret sendmail args or extract semantic information from the body. Just sends all that raw information as the preamble of the mail body.

The drawback is depending on the free, non open software service of a commercial venture, which might disappear someday. But, no real loss considering the simplicity.

As background info, I removed postfix (a sendmail replacement) because it was causing network failure on reboot. This happened possibly as some obscure side effect of having run a virtual machine with systemd-nspawn. (systemd-nspawn worked perfectly by the way). Considering the sendmail functionality was overkill for the simple need to send out system notifications, I was happy to dump the sendmail functionality in favor of the above solution, and avoid debugging.

1 Answer 1

3

Yes. Good old sendmail was one of the early mailers and the behavior and options it provided became ingrained into the various *nix and *nix-like systems (expensive Unix, the BSDs, Linux, the Hurd, etc) for both internal-to-system messages (cron output, user to user, root to user, etc) and for network based mail. It can be configured to listen on network interfaces and act as a SMTP server, or in the case of internal-to-system stuff it can be called directly at /usr/bin/sendmail or a similar location.

Now that we have plenty of other mail servers to choose from - Postfix, Exim, etc - either two mail systems have to co-exist, OR the other mail system has to provide the exact same options/behavior that sendmail does to keep from breaking just about anything having to do with internal-to-system messages.

So you have a few choices -

Install and/or configure some mailer, and set it up to act as a smarthost or relayhost. What this will do is accept mail, and if it isn't for a local recipient the smtpd will act as a mail client and connect to your ISPs (or other provider) mail server to send the mail out. A quick google shows that setting up Postfix to use mailgun is well documented and fairly straight forward as far as mail server config goes - I didn't check other mailer options simply because I like postfix. Note local recipients can be aliased to other addresses, or a ~/.forward file can be employed...

Find some other utility that gives a replacement /usr/bin/sendmail that is compliant and is configurable to send mail via a HTTPS call (I'm guessing API call to a RESTful like service?)

If that won't do, then you have one more option - fire up your favorite text editor and check your include path. Write your own implementation of the sendmail specified behavior. The man page should give you a good idea of the behaviors and options other programs/systems (like cron) would expect to be there, and you can always examine the source if needed.

4
  • Great answer. I got the free mailgun account which allows receiving mail via the https hook - but not smtp as far as I recall. Free Mailgun will the only forward to one (or a few?) registered domains which the owner has proven they own. Limited functionality, but enough for system notifications. Commented Jul 4, 2018 at 2:40
  • 1
    @CraigHicks - looks like you have a healthy start on solving the issue, now that you know what to do. It would be neat if when you are done post a self-answered question specifically about sendmail for mailgun+https and post the code
    – ivanivan
    Commented Jul 4, 2018 at 3:24
  • 1
    I have posted it. It doesn't try to interpret sendmail args or extract semantic information from the body. Just sends all that raw information as the mail body. Commented Jul 4, 2018 at 19:35
  • You forgot the option of just using sendmail as many of us do. There is nothing wrong with using sendmail and we find interfacing our web sites and APIs with it very satisfying though, admittedly, our usage is at a level most people don't use or think they need.
    – Rob
    Commented Jul 8, 2018 at 12:25

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .