LMTP from OpenSMTPd

Sendmail won't obey me anymore, so I'm trying to replace it with the simpler OpenSMTPd. smtpd.conf(5) says:
action name method [options]

The delivery method parameter may be one of the following:

lmtp destination [rcpt-to]
Deliver the message to an LMTP server at destination. The location may be expressed as host:port or as a UNIX socket.
My Cyrus is working, active, and accepts mail from Sendmail on the following socket:
action "cyrus" lmtp /var/cyrus/socket/lmtp

Unfortunately, this entry is treated as a syntax error:
Code:
# service smtpd start
Performing sanity check on smtpd configuration:
/usr/local/etc/mail/smtpd.conf:26: syntax error
/usr/local/etc/rc.d/smtpd: WARNING: failed precmd routine for smtpd
Maybe some of you are using OpenSMTPd, do you know where to find an example of it with LMTP connection to MDA?
 
I think you need to quote the path to the unix socket, i.e., action "cyrus" lmtp "/var/cyrus/socket/lmtp" — we base this on reading parse.y in the openbsd source, which says that the lmtp keyword must be followed by a string in the grammar.
 
Oh, what a yawn I am! Configuration OK now, thank you very much. Unfortunately,
Code:
# service smtpd status
smtpd is not running.
I can't find an installation guide...
 
It seems that the reason might be something else, common to Sendmail. Here is how syslog complains:

Code:
smtpd[9896]: dispatcher: smtpd: bind: Address already in use
smtpd[9892]: smtpd: process dispatcher socket closed

And maillog:

Code:
smtpd[9891]: info: OpenSMTPD 7.6.0-portable starting
smtpd[9896]: dispatcher: smtpd: bind: Address already in use
smtpd[9892]: smtpd: process dispatcher socket closed
 
what does sockstat -l | egrep ':25|smtp' say? you might need to put sendmail_enable="NONE" into rc.conf or otherwise ensure nothing's listening on port 25.

also sometimes on openbsd we get that same error and end up having to reboot — opensmtpd seems to not like being fully restarted.
 
you might need to put sendmail_enable="NONE" into rc.conf or otherwise ensure nothing's listening on port 25.

Although I had disabled all Sendmail entries in
rc.conf,
Code:
# service sendmail status
sendmail_submit is not running.
sendmail_msp_queue is not running.
sm-msp was apparently still running, and traces of that activity were visible in the maillog.

also sometimes on openbsd we get that same error and end up having to reboot — opensmtpd seems to not like being fully restarted.
Yes, that is stated in the handbook, chapter 31.5.2:
Once everything is configured, it is recommended to reboot the system.
 
However, maybe something happened to SMTP after the FreeBSD 14.3-RELEASE upgrade. 25 port is open:
Code:
# sockstat -l | egrep ':25|smtp'
_smtpd   smtpd   5893 9   tcp4   *:25  *:*
_smtpd   smtpd   5893 10  tcp6   *:25  *:*
_smtpd   smtpd   5890 10  stream /var/run/smtpd.sock
and accepts connections, but refuses to take email:
Code:
telnet sala.online.lt smtp
Trying 217.147.40.110...
Connected to sala.online.lt.
Escape character is '^]'.
220 sala.online.lt ESMTP OpenSMTPD
EHLO ser7.online.lt
250-sala.online.lt Hello ser7.online.lt [88.223.205.169], pleased to meet you
250-8BITMIME
250-ENHANCEDSTATUSCODES
250-SIZE 36700160
250-DSN
250 HELP
MAIL FROM: valdys@online.lt
553 5.1.0 Sender address syntax error
quit
221 2.0.0 Bye
Connection closed by foreign host.

Sendmail did the same, just with a slightly different failure code:
Code:
> telnet sala.online.lt smtp
Trying 217.147.40.110...
Connected to sala.online.lt.
Escape character is '^]'.
220 sala.online.lt ESMTP Sendmail 8.18.1/8.18.1; Wed, 11 Jun 2025 12:10:09 +0300 (EEST)
EHLO ser7.online.lt
250-sala.online.lt Hello 88-223-207-19.init.lt [88.223.207.19] (may be forged), pleased to meet you
250-ENHANCEDSTATUSCODES
250-PIPELINING
250-8BITMIME
250-SIZE
250-DSN
250-ETRN
250-AUTH GSSAPI DIGEST-MD5 CRAM-MD5
250-STARTTLS
250-DELIVERBY
250 HELP
MAIL FROM: valdys@online.lt
451 4.3.2 Please try again later
quit
221 2.0.0 sala.online.lt closing connection
Connection closed by foreign host.

Thunderbird connects via IMAP and reads my mail without any warning, it just does not receive new mail. Because external mail is not taken, and messages of local bots are held in
/var/spool/clientmquee.
 
that is invalid syntax. RFC 5321 specifies that the argument to MAIL FROM is a Reverse-Path production, which has angle brackets surrounding a mailbox name:
Code:
   Reverse-path   = Path / "<>"
   Path           = "<" [ A-d-l ":" ] Mailbox ">"

You might find the swaks utility helpful; swaks --server localhost:25 prompts for a recipient and runs a test transaction.

Also iirc /var/spool/clientmqueue is sendmail's queue...
 
Good morning and thanks for the “SWiss Army Knife SMTP”, very appreciated. Sorry, I forgot the quotes again, Sendmail may have worked without them, I no longer remember. OpenSMTPd is now accepting emails!
250 2.0.0 1b9e395a Message accepted for delivery

Unfortunately, it does not accept letters to recipients at alias addresses, nor does it deliver them even to UID addresses:
Code:
smtp connected address=88.223.205.169 host=88-223-205-169.init.lt
smtp message msgid=1b9e395a size=449 nrcpt=1 proto=ESMTP
smtp envelope evpid=1b9e395a3695e7b4 from=<valdys@localhost> to=<valp@sala.online.lt>
smtp disconnected reason=quit
mda delivery evpid=1b9e395a3695e7b4 from=<valdys@localhost> to=<valp@sala.online.lt> rcpt=<valp@sala.online.lt> user=valp delay=0s result=TempFail stat=Error (temporary failure: "")

I will keep researching further. Unfortunately, I can not find typical examples of how OpenSMTPd can be combined with LMTP anywhere. How should I resolve aliases before delivering to MDA? How to split
action "cyrus" alias <aliases> lmtp "/var/cyrus/socket/lmtp"?

I found only the unofficial mailer.conf sample file yet, not sure I have set it properly, too:
Code:
sendmail        /usr/local/sbin/smtpctl
send-mail       /usr/local/sbin/smtpctl
mailq           /usr/local/sbin/smtpctl
makemap         /usr/local/sbin/smtpctl
newaliases      /usr/local/sbin/smtpctl

Edited: I have redirected all functions to the same smtpctl in mailer.conf according to OpenBSD manual.
 
I found out how to specify the double action by trial and error — all I had to do was swap the order:
action "cyrus" lmtp "/var/cyrus/socket/lmtp alias <aliases>

The situation has improved and mail is now being received at alias addresses too, but is still not being delivered to recipients. I will keep digging.
 
OpenSMTPd accepts email from mail(1) on the same localhost, and transfers it to remote servers successfully now:
Code:
smtp connected address=local host=sala.online.lt
smtp message msgid=… size=495 nrcpt=1 proto=ESMTP
smtp envelope evpid=… from=<my-uid@sala.online.lt> to=<vienuolis@vivaldi.net>
smtp disconnected reason=quit
mta connecting address=smtp://31.209.137.13:25 host=mxi-1.vivaldi.net
mta connected
mta tls ciphers=TLSv1.3:TLS_AES_256_GCM_SHA384:256
mta cert-check result="unverified" fingerprint="SHA256:a92d69bebd0438165d28f18c660ad71c78a138e8cea9fe751d6641e2f7230a5c"
mta delivery evpid=… from=<my-uid@sala.online.lt> to=<vienuolis@vivaldi.net> rcpt=<-> source="217.147.40.110" relay="31.209.137.13 (mxi-1.vivaldi.net)" delay=2s result="Ok" stat="250 2.0.0 Ok: queued as …"
mta disconnected reason=quit messages=1

Mail to local addresses is also accepted, but not delivered to them:
Code:
> mail
Mail version 8.1 6/6/93.  Type ? for help.
"/var/mail/my-uid": 14 messages 14 unread
& m postmaster
Subject: OpenSMTPd to Cyrus
Hi, how are you?
.
EOT
&
( /var/log/maillog )
mta connecting address=smtp://217.147.40.110:25 host=sala.online.lt
mta connected
smtp connected address=217.147.40.110 host=sala.online.lt
smtp message msgid=… size=19755 nrcpt=1 proto=ESMTP
smtp envelope evpid=… from=<> to=<valdys@on.lt>
mta delivery evpid=… from=<> to=<valdys@on.lt> rcpt=<-> source="217.147.40.110" relay="217.147.40.110 (sala.online.lt)" delay=1s result="Ok" stat="250 2.0.0 … Message accepted for delivery"
smtp message msgid=… size=19934 nrcpt=1 proto=ESMTP
smtp envelope evpid=… from=<> to=<valdys@on.lt>
mta delivery evpid=… from=<> to=<valdys@on.lt> rcpt=<-> source="217.147.40.110" relay="217.147.40.110 (sala.online.lt)" delay=1s result="Ok" stat="250 2.0.0 … Message accepted for delivery"
…
warn: loop detected
smtp failed-command command="DATA" result="500 5.4.6 Routing loop detected: Loop detected"
mta delivery evpid=… from=<> to=<valdys@on.lt> rcpt=<-> source="217.147.40.110" relay="217.147.40.110 (sala.online.lt)" delay=1s result="PermFail" stat="500 5.4.6 Routing loop detected: Loop detected"

Since I sent this message to ‹postmaster›, but smtpd overwrote it with my real mail name, I have to assume that /etc/mail/aliases table (inherited from Sendmail) acts properly. Where could my settings error be causing the delivery loop?

Cyrus IMAP works with no visible issues. I have made quite simple smtpd.conf(5) (root:wheel 644):
Code:
listen on 0.0.0.0
listen on ::

pki sala key "/usr/home/my-uid/.acme.sh/sala.online.lt/sala.key"
pki sala cert "/usr/home/my-uid/.acme.sh/sala.online.lt/sala.cert"
ca zero cert "/usr/home/my-uid/.acme.sh/sala.online.lt/ca-zero.cert"

table aliases file:/etc/mail/aliases
table domains file:/etc/mail/local-host-names
table ip file:/etc/mail/relay-ip

action "cyrus" lmtp "/var/cyrus/socket/lmtp" alias <aliases>
action "outbound" relay

# match !from src <ip> mail-from "@online.lt" for any reject
match !from src <ip> mail-from "@on.lt" for any reject
match !from local !for domain <domains> reject
match from local !for local action "outbound"
match from src <ip> !for domain <domains> action "outbound"
match !from local for domain <domains> action "cyrus"
match from local for local action "cyrus"
 
looks like you're relaying to yourself, though we dunno the ins and outs of cyrus so your configuration is beyond us (our OpenSMTPD is outbound only)
 
Nothing special on Cyrus side, just one entry in cyrus.conf(5):
Code:
  # at least one LMTP is required for delivery
# lmtp          cmd="lmtpd" listen="lmtp" prefork=0
  lmtpunix      cmd="lmtpd" listen="/var/cyrus/socket/lmtp" prefork=0

I have referred to this LMTP Unix socket as a local action in smtpd.conf(5):
Code:
action "cyrus" lmtp "/var/cyrus/socket/lmtp" alias <aliases>

I have also tried appending aliases(5) with Cyrus commands — no effect:
Code:
# FreeBSD Handbook: Mail: Procmail example:
# procmail: "|/usr/local/bin/procmail"
#
procmail:       "|/var/cyrus/proc"
lmtp:           "|/usr/local/cyrus/libexec/master"
lmtpd:          "|/usr/local/cyrus/libexec/lmtpd"
lmtpunix:       "|/var/cyrus/socket/lmtp"
 
After many trials and errors I have finally overcome all the problems, and OpenSMTPD together with Cyrus IMAP are working like a charm on our FreeBSD now. Therefore I have written a summary of my experience where sensible uncertainties and errors arose (with an intro in Lithuanian language) so that others do not have to be troubled and even give up on this great software:
https://on.lt/opensmtpd
 
Back
Top