Opensmtpd and Dovecot - Outgoing mail works, Incoming does not

I have to install a new mail setup on our office server to replace an old QMAIL + dovecot setup (currently working and in use every day). I created a FreeBSD virtual machine on another office computer so I can get all of my configuration correct before I do it on the real server.

I created a subdomain (for this post I'll call it sub2.mydomain.com) and set up the DNS for it. After the install I can connect over SSL from the generic mail app on my Android phone and SEND a message through my new SMTP server and it arrives in my Gmail INBOX!!

However, when I reply from Gmail, I never get the message in my forms@sub2.mydomain.com mailbox. I also tried sending a message locally from forms@sub2.mydomain.com to itself. Nope. It never arrives.

I feel like I'm overlooking something simple but I've been making dozens of changes over the past couple of days and I either make it worse, or I'm back to being able to send but not receive.

I'm hoping one of you can spot what I've done wrong. One of the problems I had when looking at documentation was- many of the guides were written for OpenBSD and I don't really know the differences between FreeBSD and OpenBSD. Some of the paths are different because there were paths that don't exist on my machine. I mainly used this guide: https://prefetch.eu/blog/2020/email-server/ but I didn't do everything he said. I also looked at the official docs and fixed mailer.conf and a few other things he doesn't mention (because OpenBSD is different? Idk)

Here are the basics. Let me know what else you need. Thanks!!

Code:
# uname -a
FreeBSD sub2.mydomain.com 12.2-RELEASE-p12 FreeBSD 12.2-RELEASE-p12 GENERIC  amd64

smtpd.conf
Code:
# sub2.mydomain.com v02.23.2022 
# Define two tables stored in plain text files for mail aliases and email/password hashes
table aliases file:/etc/mail/aliases
table passwds file:/etc/mail/passwds

# Set up the certificates
pki sub2.mydomain.com key "/usr/local/etc/letsencrypt/live/sub2.mydomain.com/privkey.pem"
pki sub2.mydomain.com cert "/usr/local/etc/letsencrypt/live/sub2.mydomain.com/fullchain.pem"

srs key "ofzuKRoCHANGEDoFORoPRIVACYoJ88esXig"

filter   "rdns" phase connect match   !rdns disconnect "550 DNS error"
filter "fcrdns" phase connect match !fcrdns disconnect "550 DNS error"

# Inbound
listen on em0 port 25 tls pki "sub2.mydomain.com" filter { "rdns", "fcrdns" }
action "RECV" lmtp "/usr/local/libexec/dovecot/lmtp" rcpt-to virtual <aliases>
match from any for domain "sub2.mydomain.com" action "RECV"

# Outbound
listen on em0 port 465 smtps       pki "sub2.mydomain.com" auth <passwds>
listen on em0 port 587 tls-require pki "sub2.mydomain.com" auth <passwds>
action "SEND" relay srs
match from any auth for any action "SEND"

dovecot.conf
Code:
# dovecot conf for sub2.mydomain.com 02.23.2022 v1.0
ssl = required
ssl_cert = </usr/local/etc/letsencrypt/live/sub2.mydomain.com/fullchain.pem
ssl_key  = </usr/local/etc/letsencrypt/live/sub2.mydomain.com/privkey.pem

ssl_min_protocol = TLSv1.2
ssl_prefer_server_ciphers = yes

disable_plaintext_auth = yes

protocols = lmtp imap

service lmtp {
    unix_listener lmtp {
        user  = vmail
        group = vmail
    }
}

service imap-login {
    inet_listener imap {
        port = 143
    }
    inet_listener imaps {
        port = 993
    }
}

passdb {
    driver = passwd-file
    args = scheme=SHA512-CRYPT username_format=%u /usr/local/etc/dovecot/users
}

userdb {
    driver = passwd-file
     args = username_format=%u /usr/local/etc/dovecot/users
    override_fields = uid=vmail gid=vmail home=/usr/home/vmail/%d/%n
}

mail_location = maildir:~/Maildir


# from conf.d/10-mail.conf
namespace inbox {
  inbox = yes
}

# from conf.d/15-mailboxes.conf
namespace inbox {
  # These mailboxes are widely used and could perhaps be created automatically:
  mailbox Drafts {
    special_use = \Drafts
    auto = create
  }
  mailbox Junk {
    special_use = \Junk
    auto = create
  }
  mailbox Trash {
    special_use = \Trash
    auto = create
  }

  # For \Sent mailboxes there are two widely used names. We'll mark both of
  # them as \Sent. User typically deletes one of them if duplicates are created.
  mailbox Sent {
    special_use = \Sent
    auto = create
  }
  mailbox "Sent Messages" {
    special_use = \Sent
  }
}
 
I created a subdomain (for this post I'll call it sub2.mydomain.com) and set up the DNS for it. After the install I can connect over SSL from the generic mail app on my Android phone and SEND a message through my new SMTP server and it arrives in my Gmail INBOX!!

However, when I reply from Gmail, I never get the message in my forms@sub2.mydomain.com mailbox. I also tried sending a message locally from forms@sub2.mydomain.com to itself. Nope. It never arrives.
Did you create the MX records too? drill sub2.mydomain.com MX
 
Did you create the MX records too? drill sub2.mydomain.com MX
Yes, I did.
Code:
;; QUESTION SECTION:
;sub2.mydomain.com.        IN    MX

;; ANSWER SECTION:
sub2.mydomain.com.    3600    IN    MX    10 sub2.mydomain.com.

;; Query time: 23 msec

By the way, I tried both
action "RECV" lmtp "/usr/local/libexec/dovecot/lmtp" rcpt-to virtual <aliases>
and
action "RECV" lmtp "/var/run/dovecot/lmtp" rcpt-to virtual <aliases>
but I didn't see a difference either way.

I'm sure only one of those is correct but I don't know which one because there is obviously something else set wrong.
 
Okay, I have it working!! I think I made the common mistake of changing more than one thing at a time and not realizing which thing needed to be changed and which one didn't.

smtpd.conf (WORKS for both incoming and outgoing mail)
Code:
# sub2.mydomain.com v02.25.2022 
# Define two tables stored in plain text files for mail aliases and email/password hashes
table aliases file:/etc/mail/aliases
table passwds file:/etc/mail/passwds

# Set up the certificates
pki sub2.mydomain.com key "/usr/local/etc/letsencrypt/live/sub2.mydomain.com/privkey.pem"
pki sub2.mydomain.com cert "/usr/local/etc/letsencrypt/live/sub2.mydomain.com/fullchain.pem"

srs key "ofzuKRoCHANGEDoFORoPRIVACYoJ88esXig"

filter   "rdns" phase connect match   !rdns disconnect "550 DNS error"
filter "fcrdns" phase connect match !fcrdns disconnect "550 DNS error"

# Inbound
listen on em0 port 25 tls pki "sub2.mydomain.com" filter { "rdns", "fcrdns" }
action "RECV" lmtp "/var/run/dovecot/lmtp" rcpt-to virtual <aliases>
match from any for domain "sub2.mydomain.com" action "RECV"

# Outbound
listen on em0 port 465 smtps       pki "sub2.mydomain.com" auth <passwds>
listen on em0 port 587 tls-require pki "sub2.mydomain.com" auth <passwds>
action "SEND" relay srs
match from any auth for any action "SEND"

I'm still not sure why it didn't work the first time I tried "/var/run/dovecot/lmtp" instead of "/usr/local/libexec/dovecot/lmtp" but it seems to be working now.
 
Back
Top