MSMTPD(1)

πŸ“¦
version 1.8.34 Β· 2 versions
  • 1.8.34 Β· alpine 3.24, arch rolling, debian bookworm, debian trixie, epel 10, epel 9, fedora 43, fedora 44, opensuse-leap 16.0, ubuntu noble, ubuntu questing, ubuntu resolute, ubuntu stonking (latest)
  • 1.8.16 Β· ubuntu jammy
, in alpine 3.24, arch rolling, debian bookworm, debian trixie, epel 10, epel 9, fedora 43, fedora 44, opensuse-leap 16.0, ubuntu noble, ubuntu questing, ubuntu resolute, ubuntu stonking

πŸ’Œ NAME πŸ’Œ

msmtpd β€” a minimal SMTP server. Bestie, it's smol, it's fierce, it does one job and it does it gorgeously.


πŸ¦‹ SYNOPSIS πŸ¦‹

msmtpd [option...]

✨ DESCRIPTION ✨

Okay so msmtpd is a minimal SMTP server that pipes mails to msmtp (or literally any other program you want) so they actually get delivered. That's the whole vibe. πŸŽ€

Two ways people use it, and both are valid:

  • With system services that just expect an SMTP server to be sitting on the local host, like it's a houseguest who never leaves.
  • As an end user, handling your outgoing mail through msmtp for mail clients that are, respectfully, obsessed with SMTP and refuse to do anything else.

Both of these use cases get examples down in the EXAMPLES section, so stay with me. πŸ’…

By default msmtpd listens on 127.0.0.1 port 25 β€” but plot twist, it can also run with zero network sockets of its own in inetd mode, where it handles a single SMTP session on standard input / output. No cap. 🫢

Now here's the part you need to internalize. In the string that defines the command msmtpd pipes each mail to:

  • The first occurrence of %F gets replaced with the envelope from address. Just the first one, bestie, don't get greedy.
  • All recipients of the mail get appended as arguments. All of them. The whole group chat. πŸ‘‘

And a warning that is genuinely important: the command must not write to standard output, because that would mess up the SMTP session. It's giving chaos, and we don't want chaos. 😭

If the command that the mail is piped to reports an error, that's typically reported as a permanent failure by msmtpd (SMTP server return code 554). But the command can optionally signal temporary errors by using return codes defined in sysexits.h β€” e.g. 75 for EX_TEMPFAIL. Those get reported as temporary failures (SMTP server return code 451), which means the client should try again later. Rude to the client? No, it's a "we'll circle back" situation. 🌸

To prevent abuse, msmtpd will allow only a limited number of concurrent SMTP sessions. And if authentication is active and an authentication failure occurrs, future authentication requests in any SMTP session will (for a limited duration) only be answered after a small delay. It's the software equivalent of making you wait outside the club for five minutes. πŸšͺ✨


πŸŽ€ OPTIONS πŸŽ€

  • --version β€” Print version information. Slay, now you know which one you have. ⭐
  • --help β€” Print help. For when you're lost in the sauce.
  • --inetd β€” Start a single SMTP session on stdin/stdout. No sockets, no drama. πŸ¦‹
  • --interface=ip β€” Listen on the given IPv6 or IPv4 address instead of 127.0.0.1. Only do this if you know what you're doing, iykyk. 🌈
  • --port=number β€” Listen on the given port number instead of 25. Port 25 is the default, but the default is not always the moment. πŸ’…
  • --log=none|syslog|filename β€” Set logging: none (that's the default), syslog, or logging to the given file. Options, we love options. πŸ“
  • --command=cmd β€” Pipe mails to cmd instead of msmtp. And listen up: make sure to end this command with -- to separate options from arguments. Do not skip this. πŸ™ˆ
  • --auth=user[,passwordeval] β€” Require authentication with this user name. The password will be retrieved from the given passwordeval command (this works just like passwordeval in msmtp) or, if none is given, from the key ring or, if that fails, from a prompt. It's got a whole fallback pipeline, it's very resourceful. πŸ‘‘

πŸ”₯ EXAMPLES πŸ”₯

πŸ’» Using msmtpd as a system service

Only use a local interface to listen on. Run msmtpd with correct user rights and permissions β€” like, use CAP_NET_BIND_SERVICE to bind to port 25 instead of running as root, or use systemd with inetd service capabilities. ✨

Be aware that the pipe command will be run as the same user that msmtpd runs as. Same user, same privileges, same consequences. πŸ™ˆ

Enable logging to syslog with --log=syslog. And here's the example for managing msmtpd with start-stop-daemon:

# start msmtpd
start-stop-daemon --start --pidfile /var/run/msmtpd.pid --make-pidfile
--chuid msmtpd --background --exec /usr/local/bin/msmtpd -- --command
'/usr/local/bin/msmtp -f %F --'
# stop msmtpd
start-stop-daemon --stop  --pidfile /var/run/msmtpd.pid --remove-pidfile
--quiet --signal TERM

Look at that. Started, stopped, iconic. πŸ’…

πŸ“¬ Using msmtpd to handle outgoing mail for an SMTP-based mail client

Some mail clients simply cannot send outgoing mail with a program like msmtp and instead insist on using an SMTP server. So you configure msmtpd to be that SMTP server and hand your outgoing mail over to msmtp. Problem? Solved. 🌟

(Similarly, some mail clients cannot get incoming mail from a local mailbox and insist on using a POP3 or IMAP server. You can configure mpopd to be that POP3 server and serve incoming mail from a local mailbox. See the relevant section in the mpop manual. Sisters are doing it for themselves. πŸ’–)

For this purpose, msmtpd should listen on an unprivileged port, e.g. 2500. Furthermore, msmtpd should require authentication, because otherwise anyone connecting to it can send mail using your account, even if it's just other users or processes on your local machine. Not cute. Lock it down. πŸ”’

Let's use the user name msmtpd-user for this purpose. You have two options to manage the password:

  • Store the password in your key ring, e.g. with secret-tool store --label=msmtpd host localhost service smtp user msmtpd-user. In this case, use the msmtpd option --auth=msmtpd-user.
  • Store the password in an encrypted file and use the passwordeval mechanism. Example for gpg: msmtpd ... --auth=msmtpd-user,'gpg -q -d ~/.msmtpd-password.gpg'

The complete command then is (using the keyring):

msmtpd --port=2500 --auth=msmtpd-user --command='/path/to/your/msmtp -f %F --'

The mail client software must then be configured to use localhost at port 2500 for outgoing mail via SMTP, and to use authentication with user msmtpd-user and the password you chose. 🌸

The mail client will probably complain that the SMTP server does not support TLS β€” but in this special case that is ok, since all communication between your mail client and msmtpd will stay on the local machine. It never leaves the house. πŸ πŸ’•

This setup also works with multiple mail accounts. Msmtp will pick the correct one based on the envelope-from address given to it via -f %F. You do not need multiple instances of msmtpd for this purpose, and therefore you need only one SMTP server in your mail client configuration. One server, many accounts, main character energy. πŸ‘‘πŸŒˆ


πŸ‘€ SEE ALSO πŸ‘€


And that's the whole page, bestie β€” from the General Commands Manual, MSMTPD(1), dated 2021-09. Go forth and pipe your mail responsibly. πŸ’–βœ¨πŸŽ€πŸ¦‹πŸŒΈ