version=pmwiki-2.2.130 ordered=1 urlencoded=1 agent=Mozilla/5.0 (X11; OpenBSD amd64; rv:68.0) Gecko/20100101 Firefox/68.0 SeaMonkey/2.53.14 author=mkf charset=UTF-8 csum=mention root mail ctime=1621253792 host=198.251.81.133 name=Opensmtpd.Configure rev=51 targets=Dns.Overview,Nsd.Configure,DNS.Mail,Acme-client.Configure,Opensmtpd.Openrelay,Dovecot.Install,DNS.DKIM,Opensmtpd.Troubleshoot text=Let's set up a mail server with dkim signing and basic spam checks:%0a%0a!! Before we begin%0a%0aRead the the man pages for [[https://man.openbsd.org/smtpd|opensmtpd]], [[https://man.openbsd.org/smtpd.conf|smtpd.conf]], and [[https://man.openbsd.org/smtpctl|smtpctl]]. %0a%0aRead the [[https://github.com/poolpOrg/OpenSMTPD-book|free OpenSMTPd book]] by the%0aauthor of OpenSMTPd%0a%0a!! DNS%0a%0aRunning a mail server requires proper DNS records. If you have not already, you will%0awant to read up on [[dns/overview|DNS]] and [[nsd/configure|set up your name server]].%0a%0aYou will need to [[DNS/Mail|add proper DNS records]] to your domain and make sure they work.%0a%0a!! Install%0a%0aOpensmtpd is part of OpenBSD base, but we will also want to install some%0aopensmtpd-related packages and dovecot:%0a%0a[@%0a$ doas pkg_add opensmtpd-extras opensmtpd-filter-dkimsign-- dovecot%0a@]%0a%0a!! Configuration%0a%0a!!! TLS%0a%0aYou will want to use [[acme-client/configure|acme-client]] to request a TLS public cert and private key%0ain @@/etc/ssl/@@.%0a%0aNext, we'll create our smtpd configuration file in @@/etc/mail/smtpd.conf@@:%0a%0a[@%0a# PKI for TLS%0apki example.com cert "/etc/ssl/example.com.fullchain.pem"%0apki example.com key "/etc/ssl/private/example.com.key"%0a@]%0a%0aThis defines our public and private key pair for TLS encryption.%0a%0a!!! Tables%0a%0aNext, we define 5 tables:%0a%0a[@%0a# tables setup%0atable domains file:/etc/mail/domains%0atable passwd passwd:/etc/mail/passwd%0atable virtuals file:/etc/mail/virtuals%0atable hosts file:/etc/mail/hosts%0atable users file:/etc/mail/users%0a@]%0a%0aThe domains table contains a list of domains that our mail server should %0areceive mail on.%0a%0aThe passwd table contains a colon-separated list of username/password/disk quota%0aentries.%0a%0aThe virtuals file shows which virtual user should handle whose mail. They are written as @@key: value@@ pairs.%0aSee [[https://man.openbsd.org/aliases|aliases(5)]] for more information.%0a%0aThe hosts file contains a list of trusted sending hosts.%0a%0aThe users file contains a list of valid sending users.%0a%0aAll of these tables will be explained further in the following sections.%0a%0a!!! Dealing with Spam%0a%0a[@%0a# Blocks junk mail%0afilter check_rdns phase connect match !rdns junk%0afilter check_fcrdns phase connect match !fcrdns junk%0afilter "dkimsign" proc-exec "filter-dkimsign -d example.com -s mail -k /etc/mail/dkim/private.key" user _smtpd group _smtpd%0a@]%0a%0aThe first filter will check if the sender has an rdns entry. If not, the mail%0awill be labeled as junk.%0a%0aThe second filter will check if the sender's forward and reverse dns entry match. If%0anot, the mail will be labeled as junk.%0a%0aThe third filter will sign any email with the DKIM private key.%0a%0a# -d specifies the domain name to sign for; you must replace example.com with your real domain.%0a# -s specifies the selector (in this case mail).%0a# -k specifies the path of the private key.%0a# user and group both specify _smtpd, the user and group that does the signing%0a%0a!!! Macros%0a%0aA macro defines a variable that will be replaced with a block of text:%0a%0a[@%0a# macros%0aipv4 = "192.168.0.1"%0aipv6 = "2001:db8::"%0acheck = "pki example.com mask-src filter { check_rdns check_fcrdns } hostname example.com"%0aauthcheck = "pki example.com auth %3cpasswd> mask-src senders %3cusers> filter { check_rdns check_fcrdns dkimsign } hostname example.com"%0a@]%0a%0aLines 2 and 3 define the IPv4 and IPv6 addresses used for sending and receiving mail.%0a%0aLine 4 tells opensmtpd to use the public/private keys we defined earlier for @@example.com@@. We mask the sender's source (the '''from''' part of the @@Received@@ header). We also apply two filters to check for proper forward and reverse confirmed DNS entries. Finally, we indicate that the sending hostname must be example.com instead of the default server name.%0a%0aLine 5 is identical to line 4 except it requires authentication with the password file and it checks if the sender is allowed.%0a%0a!!! Listeners%0a%0aThe listeners tell us what network interfaces, IP addresses, and ports to listen on.%0a%0a[@%0a# listeners%0alisten on socket filter "dkimsign"%0alisten on lo0 filter "dkimsign"%0alisten on $ipv4 port 25 tls $check%0alisten on $ipv6 port 25 tls $check%0alisten on $ipv4 port 465 smtps $authcheck%0alisten on $ipv6 port 465 smtps $authcheck%0alisten on $ipv4 port 587 tls-require $authcheck%0alisten on $ipv6 port 587 tls-require $authcheck%0a@]%0a%0aLine 2 tells smtpd to listen to the UNIX domain socket and to DKIM sign all %0aemails. Line 3 tells us to listen to the loopback interface and also%0asign all emails.%0a%0aLines 4-5 tells smtpd to listen on the IPv4 and IPv6 address on port 25, to provide%0aTLS if supported but to offer plaintext as a fallback. Only basic checking is done.%0a%0aLines 6-7 tells smtpd to listen on the IPv4 and IPv6 address on port 465, for SMTPS.%0aTLS encryption is required and authentication checking is forced because this socket%0acan be used for sending mail to other servers. We want to avoid an%0a[[opensmtpd/openrelay|open mail relay]].%0a%0aLines 8-9 is similar except it's for port 587, which is the SMTP submission port.%0a%0a!!! Rules%0a%0aNext we define the actions that opensmtpd can take and how to decide which%0aaction to follow:%0a%0a[@%0a# rules%0aaction "lmtp" lmtp "/var/dovecot/lmtp" rcpt-to virtual %3cvirtuals>%0aaction "outbound" relay src $ipv4%0a%0amatch from any for domain %3cdomains> action "lmtp"%0amatch from local for any action "outbound"%0amatch from src %3chosts> for any action "outbound"%0amatch auth from any for any action "outbound"%0a@]%0a%0aIn line 2, we define the action "lmtp": we pass the mail to dovecot to handle using the Local Mail Transfer Protocol (LMTP). The actual recipient will be translated using the virtuals table.%0a%0aIn line 3, we define the action "outbound": we relay (send) the email out.%0a%0aLine 4 defines our first matching rule: any email headed for one of our domains should be handed over to lmtp (handed over to dovecot).%0a%0aLine 5 defines our second matching rule: any email from a local IP address or queue can relay (send) without authentication.%0a%0aLine 6 defines our third matching rule: any email from our trusted @@/etc/mail/hosts@@ file will automatically be relayed (sent) without authentication.%0a%0aLine 7 defines our last matching rule: any email that has been properly authenticated will be relayed (sent).%0a%0a!!! Complete configuration file%0a%0aHere is the entire configuration file in @@/etc/mail/smtpd.conf@@:%0a%0a[@%0a# PKI for TLS%0apki example.com cert "/etc/ssl/example.com.fullchain.pem"%0apki example.com key "/etc/ssl/private/example.com.key"%0a%0a# tables setup%0atable domains file:/etc/mail/domains%0atable passwd passwd:/etc/mail/passwd%0atable virtuals file:/etc/mail/virtuals%0atable hosts file:/etc/mail/hosts%0atable users file:/etc/mail/users%0a%0a# Blocks junk mail%0afilter check_rdns phase connect match !rdns junk%0afilter check_fcrdns phase connect match !fcrdns junk%0afilter "dkimsign" proc-exec "filter-dkimsign -d example.com -s mail -k /etc/mail/dkim/private.key" user _smtpd group _smtpd%0a%0a# macros%0aipv4 = "192.168.0.1"%0aipv6 = "2001:db8::"%0acheck = "pki example.com mask-src filter { check_rdns check_fcrdns } hostname example.com"%0aauthcheck = "pki example.com auth %3cpasswd> mask-src senders %3cusers> filter { check_rdns check_fcrdns dkimsign } hostname example.com"%0a%0a# listeners%0alisten on socket filter "dkimsign"%0alisten on lo0 filter "dkimsign"%0alisten on $ipv4 port 25 tls $check%0alisten on $ipv6 port 25 tls $check%0alisten on $ipv4 port 465 smtps $authcheck%0alisten on $ipv6 port 465 smtps $authcheck%0alisten on $ipv4 port 587 tls-require $authcheck%0alisten on $ipv6 port 587 tls-require $authcheck%0a%0a# rules%0aaction "lmtp" lmtp "/var/dovecot/lmtp" rcpt-to virtual %3cvirtuals>%0aaction "outbound" relay src $ipv4%0a%0amatch from any for domain %3cdomains> action "lmtp"%0amatch from local for any action "outbound"%0amatch from src %3chosts> for any action "outbound"%0amatch auth from any for any action "outbound"%0a@]%0a%0a!! Configuring Virtual Users%0a%0aA single user vmail will receive mail for all virtual users:%0a%0a[@%0a$ doas useradd -m -g =uid -c "Virtual Mail" -d /var/vmail -s /sbin/nologin vmail%0a@]%0a%0a/var/vmail will be used to store virtual users' maildir folders. It will be managed by dovecot, which receives mail via LMTP.%0a%0a!! Adding users%0a%0aCreate a new file @@/etc/mail/virtuals@@ and add these lines:%0a%0a[@%0aroot admin@example.com%0aadmin@example.com vmail%0ausername@example.com vmail%0a@]%0a%0aNow, any mail sent to root will get forwarded to admin@example.com.%0a%0aThis is recommended to do so, as daily(8) and other programs will send mails to root. check the mail account linked to root account often!%0a%0aYou can optionally add one line for each user to provide aliases.%0a%0aFor each new user account, you will want to create a new line.%0a%0aYou'll also need to create one line for each user in @@/etc/mail/users@@:%0a%0a[@%0aadmin@example.com: admin@example.com%0ausername@example.com: username@example.com%0a@]%0a%0aA whitelist of known good senders goes into @@/etc/mail/hosts@@:%0a%0a[@%0alocalhost%0a127.0.0.1%0a192.168.1.1%0a2001:db8::%0a@]%0a%0aReplace IP addresses 192.168.1.1 and 2001:db8:: with your server's real IP addresses.%0a%0aIn @@/etc/mail/mailname@@, put in the name you want to use for your mail server. This%0ais very important for passing anti-spam checks:%0a%0a[@%0aexample.com%0a@]%0a%0aThe list of domains this mail server can receive emails for will go inside @@/etc/mail/domains@@:%0a%0a[@%0aexample.com%0amail.example.com%0a@]%0a%0aIn @@/etc/mail/passwd@@, we have a list of colon-separated user credentials:%0a%0a[@%0aadmin@example.com:$2b$10$h5itbhzs73T4jsHAj9YX6Tf63yRatAquGBxoCX67wyekhCH4ZqioD6lKh::::::userdb_quota_rule=*:storage=1G%0ausername@example.com:$2b$10$h5itbhzs73T4jsHAj9YX6Tf63yRatAquGBxoCX67wyekhCH4ZqioD6lKh::::::userdb_quota_rule=*:storage=1G%0a@]%0a%0aEach field is separated with a colon.%0a%0aThe first field tells you the username. Note that usernames include a domain -- this is because you might host mail for multiple domains. So, when logging in to the mail server, your mail client must be of the format username@example.com.%0a%0aThe second field is the password hash. To generate a hash, you can run encrypt:%0a%0a[@%0a$ encrypt%0a@]%0a%0aType your password, then press @@enter@@. Type @@ctrl+d@@ to quit.%0a%0a@@smtpctl encrypt@@ also does the same thing:%0a%0a[@%0a$ smtpctl encrypt%0a@]%0a%0a'''WARNING''': Special characters like $, when used in passwords, may cause issues with your mail client or with opensmtpd. To be safe, you might want to use only alphanumeric characters for your password. You can increase the length of the password for more security.%0a%0aThe last field sets how much data storage each user is allowed. The default here is 1 gigabyte.%0a%0a!!! File Permissions%0a%0aMake sure to set the proper permissions:%0a%0a[@%0a$ doas chown -R _smtpd:_dovecot /etc/mail/%0a$ doas chmod -R o-rx /etc/mail/%0a@]%0a%0a!! IMAP and POP3 via dovecot%0a%0aTo finish the setup, we need to [[dovecot/install|install and configure dovecot]].%0a%0a!! DKIM signing%0a%0aWe will need to set up [[DNS/DKIM|dkim]] to have the mail properly signed.%0a%0a!! Troubleshooting%0a%0aOpenSMTPD may end up in an inconsistent state. This can happen due to a misconfiguration. One symptom is you see this error:%0a%0asmtpd[]: pony express: smtpd: socket: Too many open files%0a%0aTo fix this, you can delete all the temporary files inside OpenSMTPD.%0a%0a'''WARNING''': this will delete any messages in the queue:%0a%0a[@%0a$ doas rcctl stop smtpd%0a$ doas rm -r /var/spool/smtpd/queue/*%0a$ doas rm -r /var/spool/smtpd/offline/*%0a@]%0a%0aAt times, opensmtpd may be unable to connect because outgoing packets are being filtered. For example, suppose you are trying to send a letter to yahoo, but you get errors similar to following, showing a connection timeout:%0a%0a[@%0asmtpd[]: smtp-out: Enabling route [] %3c-> 67.195.204.77 (mtaproxy1.free.mail.vip.bf1.yahoo.com)%0asmtpd[]: smtp-out: Enabling route [] %3c-> 67.195.228.106 (mtaproxy2.free.mail.vip.gq1.yahoo.com)%0asmtpd[]: mta error reason=Connection timeout%0asmtpd[]: smtp-out: Disabling route [] %3c-> 104.47.55.33 (104.47.55.33) for 15s%0a@]%0a%0aAn easy way to test if your packets are being filtered is:%0a%0a[@%0a$ dig -t mx yahoo.com%0a;; ANSWER SECTION:%0ayahoo.com. 395 IN MX 1 mta6.am0.yahoodns.net.%0ayahoo.com. 395 IN MX 1 mta5.am0.yahoodns.net.%0ayahoo.com. 395 IN MX 1 mta7.am0.yahoodns.net.%0a$ nc mta5.am0.yahoodns.net 25%0a@]%0a%0aIf you get no response, then outgoing packets to port 25 are being blocked (often due to firewalls by your VPS provider to block spam). If mail is working, you should see a 220 reply:%0a%0a[@%0a$ nc mta5.am0.yahoodns.net 25%0a220 mtaproxy511.free.mail.ne1.yahoo.com ESMTP ready%0a@]%0a%0aIt is also possible that TLS is being dropped by the firewall. You can test using openssl:%0a%0a[@%0a$ openssl s_client -starttls smtp -connect mta5.am0.yahoodns.net:25%0aCONNECTED(00000003)%0adepth=2 C = US, O = DigiCert Inc, OU = www.digicert.com, CN = DigiCert High Assurance EV Root CA%0averify return:1%0adepth=1 C = US, O = DigiCert Inc, OU = www.digicert.com, CN = DigiCert SHA2 High Assurance Server CA%0averify return:1%0adepth=0 C = US, ST = California, L = Sunnyvale, O = Oath Inc, CN = *.am0.yahoodns.net%0a...%0a250 STARTTLS%0a@]%0a%0aYou should see the entire SSL cert plus 250 STARTTLS reply. If you see the response hang at any point (eg, it returns CONNECTED(00000003) and nothing else), then TLS on port 25 is being filtered.%0a%0aIf you see this warning message in /var/log/maillog:%0a%0a[@%0aDec 6 03:44:17 smtpd[]: info: OpenSMTPD 6.7.0 starting %0aDec 6 03:44:17 smtpd[]: pony express: smtpd: socket: Too many open files %0aDec 6 03:44:17 smtpd[]: warn: lost child: pony express exited abnormally %0a@]%0a%0aThis is due to having too many IP addresses that opensmtpd tries to bind to. This happens when you have a rule that says @@listen on egress@@:%0a%0a[@%0alisten on egress port 25 tls pki fruit.ircnow.org mask-src filter { check_rdns check_fcrdns }%0alisten on egress port 587 tls-require pki fruit.ircnow.org auth %3cpasswd> mask-src filter { check_rdns check_fcrdns }%0a@]%0a%0aThese two lines mean that opensmtpd will listen to '''all''' available ip addresses, including the hundreds of IPv6 addresses you may have in @@/etc/hostname.vio0@@ and @@ifconfig vio0@@. To fix this, you must specify the IP addresses you want to listen to:%0a%0a[@%0aipv4 = "38.81.163.143"%0aipv6 = "2602:fccf:1:143::"%0acheck = "pki example.com filter { check_rdns check_fcrdns } hostname example.com"%0aauthcheck = "pki example.com auth %3cpasswd> filter { check_rdns check_fcrdns dkimsign } hostname example.com"%0a%0a# listeners%0alisten on socket filter "dkimsign"%0alisten on lo0 filter "dkimsign"%0alisten on $ipv4 port 25 tls $check%0alisten on $ipv6 port 25 tls $check%0alisten on $ipv4 port 465 smtps $authcheck%0alisten on $ipv6 port 465 smtps $authcheck%0alisten on $ipv4 port 587 tls-require $authcheck%0alisten on $ipv6 port 587 tls-require $authcheck%0a@]%0a%0a!!! Open Mail Relay%0a%0aIf all your email is being marked as spam, check @@/var/log/maillog@@ . If you see a message like the following:%0a[@%0aJan 8 11:00:29 smtpd[39035]: 83bd6b3b1669649f mta delivery evpid=a8d16cd2144222fa from=%3cspammer@example.com> to=%3cvictim@example.com> rcpt=%3c-> source="192.168.0.1" relay="10.0.0.1 (10.0.0.1)" delay=16h2s result="TempFail" stat="451 4.7.650 The mail server [192.168.0.1] has been temporarily rate limited due to IP reputation. For e-mail delivery information, see https://postmaster.example.com (S843)"%0a@]%0aThen your server is being exploited as an [[opensmtpd/openrelay|open mail relay]]! Please follow the guide to fix it.%0a%0a!! [[opensmtpd/troubleshoot|Troubleshooting OpenSMTPd]]%0a time=1672417020 author:1672417020=mkf csum:1672417020=mention root mail diff:1672417020:1667566017:=237,238d236%0a%3c %0a%3c This is recommended to do so, as daily(8) and other programs will send mails to root. check the mail account linked to root account often!%0a host:1672417020=198.251.81.133 author:1667566017=fossdev diff:1667566017:1645948808:=31,34c31,34%0a%3c in @@/etc/ssl/@@.%0a%3c %0a%3c Next, we'll create our smtpd configuration file in @@/etc/mail/smtpd.conf@@:%0a%3c %0a---%0a> in /etc/ssl/.%0a> %0a> Next, we'll create our smtpd configuration file in /etc/mail/smtpd.conf:%0a> %0a165,166c165,166%0a%3c Line 6 defines our third matching rule: any email from our trusted @@/etc/mail/hosts@@ file will automatically be relayed (sent) without authentication.%0a%3c %0a---%0a> Line 6 defines our third matching rule: any email from our trusted /etc/mail/hosts file will automatically be relayed (sent) without authentication.%0a> %0a171,172c171,172%0a%3c Here is the entire configuration file in @@/etc/mail/smtpd.conf@@:%0a%3c %0a---%0a> Here is the entire configuration file in /etc/mail/smtpd.conf:%0a> %0a228,229c228,229%0a%3c Create a new file @@/etc/mail/virtuals@@ and add these lines:%0a%3c %0a---%0a> Create a new file /etc/mail/virtuals and add these lines:%0a> %0a242,243c242,243%0a%3c You'll also need to create one line for each user in @@/etc/mail/users@@:%0a%3c %0a---%0a> You'll also need to create one line for each user in /etc/mail/users:%0a> %0a249,250c249,250%0a%3c A whitelist of known good senders goes into @@/etc/mail/hosts@@:%0a%3c %0a---%0a> A whitelist of known good senders goes into /etc/mail/hosts:%0a> %0a260c260%0a%3c In @@/etc/mail/mailname@@, put in the name you want to use for your mail server. This%0a---%0a> In /etc/mail/mailname, put in the name you want to use for your mail server. This%0a267,268c267,268%0a%3c The list of domains this mail server can receive emails for will go inside @@/etc/mail/domains@@:%0a%3c %0a---%0a> The list of domains this mail server can receive emails for will go inside /etc/mail/domains:%0a> %0a274,275c274,275%0a%3c In @@/etc/mail/passwd@@, we have a list of colon-separated user credentials:%0a%3c %0a---%0a> In /etc/mail/passwd, we have a list of colon-separated user credentials:%0a> %0a291,292c291,292%0a%3c Type your password, then press @@enter@@. Type @@ctrl+d@@ to quit.%0a%3c %0a---%0a> Type your password, then press enter. Type ctrl+d to quit.%0a> %0a394c394%0a%3c These two lines mean that opensmtpd will listen to '''all''' available ip addresses, including the hundreds of IPv6 addresses you may have in @@/etc/hostname.vio0@@ and @@ifconfig vio0@@. To fix this, you must specify the IP addresses you want to listen to:%0a---%0a> These two lines mean that opensmtpd will listen to '''all''' available ip addresses, including the hundreds of IPv6 addresses you may have in /etc/hostname.vio0 and @@ifconfig vio0@@. To fix this, you must specify the IP addresses you want to listen to:%0a host:1667566017=2405:201:a40c:a132:4223:43ff:fec0:1a01 author:1645948808=Limits csum:1645948808=Updated instructions for /etc/mail/domains diff:1645948808:1641289680:minor=267c267%0a%3c The list of domains this mail server can receive emails for will go inside /etc/mail/domains:%0a---%0a> The list of domains you want to receive mail for will go inside /etc/mail/domains:%0a host:1645948808=2409:4060:18:a55b:cb97:acd0:80cb:9543 author:1641289680=Naglfar csum:1641289680=Rename action (relay to outbound) as is on smtpd.conf(5). diff:1641289680:1638775014:=149,150c149,150%0a%3c action "outbound" relay src $ipv4%0a%3c %0a---%0a> action "relay" relay src $ipv4%0a> %0a152,154c152,154%0a%3c match from local for any action "outbound"%0a%3c match from src %3chosts> for any action "outbound"%0a%3c match auth from any for any action "outbound"%0a---%0a> match from local for any action "relay"%0a> match from src %3chosts> for any action "relay"%0a> match auth from any for any action "relay"%0a159,160c159,160%0a%3c In line 3, we define the action "outbound": we relay (send) the email out.%0a%3c %0a---%0a> In line 3, we define the action "relay": we relay (send) the email out.%0a> %0a208,209c208,209%0a%3c action "outbound" relay src $ipv4%0a%3c %0a---%0a> action "relay" relay src $ipv4%0a> %0a211,213c211,213%0a%3c match from local for any action "outbound"%0a%3c match from src %3chosts> for any action "outbound"%0a%3c match auth from any for any action "outbound"%0a---%0a> match from local for any action "relay"%0a> match from src %3chosts> for any action "relay"%0a> match auth from any for any action "relay"%0a host:1641289680=92.191.225.58 author:1638775014=jrmu diff:1638775014:1638453453:=152d151%0a%3c match from local for any action "relay"%0a163,168c162,165%0a%3c Line 5 defines our second matching rule: any email from a local IP address or queue can relay (send) without authentication.%0a%3c %0a%3c Line 6 defines our third matching rule: any email from our trusted /etc/mail/hosts file will automatically be relayed (sent) without authentication.%0a%3c %0a%3c Line 7 defines our last matching rule: any email that has been properly authenticated will be relayed (sent).%0a%3c %0a---%0a> Line 5 defines our second matching rule: any email from our trusted /etc/mail/hosts file will automatically be relayed (sent) without authentication.%0a> %0a> Line 6 defines our last matching rule: any email that has been properly authenticated will be relayed (sent).%0a> %0a211d207%0a%3c match from local for any action "relay"%0a host:1638775014=38.87.162.8 author:1638453453=jrmu diff:1638453453:1637076046:=23c23%0a%3c $ doas pkg_add opensmtpd-extras opensmtpd-filter-dkimsign-- dovecot%0a---%0a> $ doas pkg_add opensmtpd-extras opensmtpd-filter-dkimsign dovecot%0a host:1638453453=38.87.162.8 author:1637076046=Hawk diff:1637076046:1636545387:=12c12%0a%3c Running a mail server requires proper DNS records. If you have not already, you will%0a---%0a> Running a mail server requires a proper DNS records. If you have not already, you will%0a65,66c65,66%0a%3c The hosts file contains a list of trusted sending hosts.%0a%3c %0a---%0a> The hosts file contains a list of trusted sending hosts:%0a> %0a137,138c137,138%0a%3c [[opensmtpd/openrelay|open mail relay]].%0a%3c %0a---%0a> [[openbsd/mailopenproxy|open mail relay]].%0a> %0a164,165c164,165%0a%3c Line 6 defines our last matching rule: any email that has been properly authenticated will be relayed (sent).%0a%3c %0a---%0a> Line 6 defines our last matching rule: any email that has been properly authenticated will be related (sent).%0a> %0a234,235c234,235%0a%3c You can optionally add one line for each user to provide aliases.%0a%3c %0a---%0a> You can optionally one line for each user to provide aliases.%0a> %0a263,264c263,264%0a%3c The list of domains you want to receive mail for will go inside /etc/mail/domains:%0a%3c %0a---%0a> The list of domains you can want to receive mail for will go inside /etc/mail/domains:%0a> %0a390c390%0a%3c These two lines mean that opensmtpd will listen to '''all''' available ip addresses, including the hundreds of IPv6 addresses you may have in /etc/hostname.vio0 and @@ifconfig vio0@@. To fix this, you must specify the IP addresses you want to listen to:%0a---%0a> These two lines mean that opensmtpd will listen to '''all''' available ip address, including the hundreds of IPv6 addresses you may have in /etc/hostname.vio0 and @@ifconfig vio0@@. To fix this, you must specify the IP addresses you want to listen to:%0a host:1637076046=2001:8a0:6813:4501:18d4:42f5:d6fb:184f author:1636545387=Hawk diff:1636545387:1635519284:minor=415c415%0a%3c Then your server is being exploited as an [[opensmtpd/openrelay|open mail relay]]! Please follow the guide to fix it.%0a---%0a> Then your server is being exploited as an [[openbsd/mailopenproxy|open mail relay]]! Please follow the guide to fix it.%0a host:1636545387=2001:8a0:6813:4501:18d4:42f5:d6fb:184f author:1635519284=jrmu diff:1635519284:1635518599:=62c62%0a%3c The virtuals file shows which virtual user should handle whose mail. They are written as @@key: value@@ pairs.%0a---%0a> The virtuals file shows which virtual user should handle whose mail.%0a231,234d230%0a%3c %0a%3c Now, any mail sent to root will get forwarded to admin@example.com.%0a%3c %0a%3c You can optionally one line for each user to provide aliases.%0a host:1635519284=38.87.162.8 author:1635518599=noisytoot csum:1635518599=Replace aliases with virtuals diff:1635518599:1635518379:=45,46c45,46%0a%3c Next, we define 5 tables:%0a%3c %0a---%0a> Next, we define 6 tables:%0a> %0a55a56,58%0a> The aliases table provides a list of aliases in @@key: value@@ pairs.%0a> See [[https://man.openbsd.org/aliases|aliases(5)]] for more information.%0a> %0a63,64c66%0a%3c See [[https://man.openbsd.org/aliases|aliases(5)]] for more information.%0a%3c %0a---%0a> %0a175a178%0a> table aliases file:/etc/mail/aliases%0a224,225c227,228%0a%3c Create a new file /etc/mail/virtuals and add these lines:%0a%3c %0a---%0a> At the bottom of /etc/mail/aliases, add these lines:%0a> %0a227c230,241%0a%3c root admin@example.com%0a---%0a> vmail: /dev/null%0a> root: admin@example.com%0a> @]%0a> %0a> Now, any mail sent to vmail will get thrown away; and any mail send to root will get%0a> forwarded to admin@example.com.%0a> %0a> You can optionally one line for each user to provide aliases.%0a> %0a> Create a new file /etc/mail/virtuals and add these lines:%0a> %0a> [@%0a host:1635518599=2.29.34.246 author:1635518379=noisytoot csum:1635518379=The aliases table is unused diff:1635518379:1631377045:=48a49%0a> table aliases file:/etc/mail/aliases%0a host:1635518379=2.29.34.246 author:1631377045=jrmu diff:1631377045:1629671234:=124,125c124,125%0a%3c listen on $ipv4 port 465 smtps $authcheck%0a%3c listen on $ipv6 port 465 smtps $authcheck%0a---%0a> listen on $ipv4 port 465 tls-require $authcheck%0a> listen on $ipv6 port 465 tls-require $authcheck%0a202,203c202,203%0a%3c listen on $ipv4 port 465 smtps $authcheck%0a%3c listen on $ipv6 port 465 smtps $authcheck%0a---%0a> listen on $ipv4 port 465 tls-require $authcheck%0a> listen on $ipv6 port 465 tls-require $authcheck%0a414,415c414,415%0a%3c listen on $ipv4 port 465 smtps $authcheck%0a%3c listen on $ipv6 port 465 smtps $authcheck%0a---%0a> listen on $ipv4 port 465 tls-require $authcheck%0a> listen on $ipv6 port 465 tls-require $authcheck%0a host:1631377045=38.87.162.8 author:1629671234=mkf diff:1629671234:1628156436:=423c423%0a%3c [@%0a---%0a> %0a425c425%0a%3c @]%0a---%0a> %0a host:1629671234=198.251.81.133 author:1628156436=jrmu diff:1628156436:1625798671:=316c316%0a%3c $ doas chmod -R o-rx /etc/mail/%0a---%0a> $ doas chmod o-rx /etc/mail/%0a host:1628156436=38.87.162.8 author:1625798671=jrmu diff:1625798671:1625229708:=68,69c68,69%0a%3c The hosts file contains a list of trusted sending hosts:%0a%3c %0a---%0a> The hosts file contains a list of trusted sending hosts.%0a> %0a260d259%0a%3c 127.0.0.1%0a265c264%0a%3c Replace IP addresses 192.168.1.1 and 2001:db8:: with your server's real IP addresses.%0a---%0a> Replace the IP addresses above with real IP addresses.%0a host:1625798671=38.81.163.143 author:1625229708=jrmu diff:1625229708:1624190558:=152,153c152,153%0a%3c action "relay" relay src $ipv4%0a%3c %0a---%0a> action "relay" relay%0a> %0a209c209%0a%3c action "relay" relay src $ipv4%0a---%0a> action "relay" relay%0a host:1625229708=125.231.34.36 author:1624190558=jrmu diff:1624190558:1624172254:=184d183%0a%3c table users file:/etc/mail/users%0a host:1624190558=125.224.16.135 author:1624172254=jrmu diff:1624172254:1623807106:=105c105%0a%3c authcheck = "pki example.com auth %3cpasswd> mask-src senders %3cusers> filter { check_rdns check_fcrdns dkimsign } hostname example.com"%0a---%0a> authcheck = "pki example.com auth %3cpasswd> mask-src senders %3cusers> filter { check_rdns check_fcrdns } hostname example.com"%0a194,195c194,195%0a%3c authcheck = "pki example.com auth %3cpasswd> mask-src senders %3cusers> filter { check_rdns check_fcrdns dkimsign } hostname example.com"%0a%3c %0a---%0a> authcheck = "pki example.com auth %3cpasswd> mask-src senders %3cusers> filter { check_rdns check_fcrdns } hostname example.com"%0a> %0a405c405%0a%3c authcheck = "pki example.com auth %3cpasswd> filter { check_rdns check_fcrdns dkimsign } hostname example.com"%0a---%0a> authcheck = "pki example.com auth %3cpasswd> filter { check_rdns check_fcrdns } hostname example.com"%0a host:1624172254=38.81.163.143 author:1623807106=jrmu diff:1623807106:1623806972:=191,194c191,194%0a%3c ipv4 = "192.168.0.1"%0a%3c ipv6 = "2001:db8::"%0a%3c check = "pki example.com mask-src filter { check_rdns check_fcrdns } hostname example.com"%0a%3c authcheck = "pki example.com auth %3cpasswd> mask-src senders %3cusers> filter { check_rdns check_fcrdns } hostname example.com"%0a---%0a> ipv4 = "38.81.163.143"%0a> ipv6 = "2602:fccf:1:143::"%0a> check = "pki example.com filter { check_rdns check_fcrdns } hostname example.com"%0a> authcheck = "pki example.com auth %3cpasswd> filter { check_rdns check_fcrdns } hostname example.com"%0a host:1623807106=125.231.25.80 author:1623806972=jrmu diff:1623806972:1623806787:= host:1623806972=125.231.25.80 author:1623806787=jrmu diff:1623806787:1623223089:=188c188%0a%3c filter "dkimsign" proc-exec "filter-dkimsign -d example.com -s mail -k /etc/mail/dkim/private.key" user _smtpd group _smtpd%0a---%0a> filter "dkimsign" proc-exec "filter-dkimsign -d example.com -s mail -k /etc/mail/dkim/private.key" user _dkimsign group _dkimsign%0a host:1623806787=125.231.25.80 author:1623223089=jrmu diff:1623223089:1623222265:=425,426d424%0a%3c %0a%3c !! [[opensmtpd/troubleshoot|Troubleshooting OpenSMTPd]]%0a host:1623223089=38.81.163.143 author:1623222265=jrmu diff:1623222265:1623222095:=313c313,315%0a%3c $ doas chown -R _smtpd:_dovecot /etc/mail/%0a---%0a> $ doas groupadd -v _mail%0a> $ doas usermod -G _mail _smtpd%0a> $ doas chown -R _smtpd:_mail /etc/mail/%0a host:1623222265=38.81.163.143 author:1623222095=jrmu diff:1623222095:1622985626:=80c80%0a%3c filter "dkimsign" proc-exec "filter-dkimsign -d example.com -s mail -k /etc/mail/dkim/private.key" user _smtpd group _smtpd%0a---%0a> filter "dkimsign" proc-exec "filter-dkimsign -d example.com -s mail -k /etc/mail/dkim/private.key" user _dkimsign group _mail%0a94c94%0a%3c # user and group both specify _smtpd, the user and group that does the signing%0a---%0a> # user and group both specify _dkimsign, the user and group that does the signing%0a host:1623222095=38.81.163.143 author:1622985626=jrmu diff:1622985626:1622963097:=325c325%0a%3c We will need to set up [[DNS/DKIM|dkim]] to have the mail properly signed.%0a---%0a> We will need to set up [[dkim/dkimsign|dkim]] to have the mail properly signed.%0a host:1622985626=38.81.163.143 author:1622963097=mkf csum:1622963097=w diff:1622963097:1622798643:=396d395%0a%3c [@%0a399d397%0a%3c @]%0a host:1622963097=104.200.30.145 author:1622798643=jrmu diff:1622798643:1622797573:=80c80%0a%3c filter "dkimsign" proc-exec "filter-dkimsign -d example.com -s mail -k /etc/mail/dkim/private.key" user _dkimsign group _mail%0a---%0a> filter "dkimsign" proc-exec "filter-dkimsign -d example.com -s mail -k /etc/mail/dkim/private.key" user _dkimsign group _dkimsign%0a host:1622798643=38.81.163.143 author:1622797573=jrmu diff:1622797573:1622797526:=314d313%0a%3c $ doas usermod -G _mail _smtpd%0a host:1622797573=38.81.163.143 author:1622797526=jrmu diff:1622797526:1622720574:=313,314c313%0a%3c $ doas groupadd -v _mail%0a%3c $ doas chown -R _smtpd:_mail /etc/mail/%0a---%0a> $ doas chown -R _smtpd:_dovecot /etc/mail/%0a host:1622797526=38.81.163.143 author:1622720574=jrmu diff:1622720574:1622719953:=105c105%0a%3c authcheck = "pki example.com auth %3cpasswd> mask-src senders %3cusers> filter { check_rdns check_fcrdns } hostname example.com"%0a---%0a> authcheck = "pki example.com auth %3cpasswd> mask-src senders filter { check_rdns check_fcrdns } hostname example.com"%0a host:1622720574=38.81.163.143 author:1622719953=jrmu diff:1622719953:1622719371:=247,253d246%0a%3c %0a%3c You'll also need to create one line for each user in /etc/mail/users:%0a%3c %0a%3c [@%0a%3c admin@example.com: admin@example.com%0a%3c username@example.com: username@example.com%0a%3c @]%0a host:1622719953=38.81.163.143 author:1622719371=jrmu diff:1622719371:1621334412:=102,103c102,103%0a%3c ipv4 = "192.168.0.1"%0a%3c ipv6 = "2001:db8::"%0a---%0a> ipv4 = "38.81.163.143"%0a> ipv6 = "2602:fccf:1:143::"%0a host:1622719371=38.81.163.143 author:1621334412=jrmu diff:1621334412:1621334369:=15c15%0a%3c You will need to [[DNS/Mail|add proper DNS records]] to your domain and make sure they work.%0a---%0a> You will need to [[dns/mail|add proper DNS records]] to your domain and make sure they work.%0a host:1621334412=38.81.163.143 author:1621334369=jrmu diff:1621334369:1621333842:=10,11d9%0a%3c !! DNS%0a%3c %0a14,15d11%0a%3c %0a%3c You will need to [[dns/mail|add proper DNS records]] to your domain and make sure they work.%0a host:1621334369=38.81.163.143 author:1621333842=jrmu diff:1621333842:1621332833:=184,185c184,185%0a%3c filter "dkimsign" proc-exec "filter-dkimsign -d example.com -s mail -k /etc/mail/dkim/private.key" user _dkimsign group _dkimsign%0a%3c %0a---%0a> filter "dkimsign" proc-exec "filter-dkimsign -d jrmu.coconut.ircnow.org -s mail -k /etc/mail/dkim/private.key" user _dkimsign group _dkimsign%0a> %0a189,191c189,191%0a%3c check = "pki example.com filter { check_rdns check_fcrdns } hostname example.com"%0a%3c authcheck = "pki example.com auth %3cpasswd> filter { check_rdns check_fcrdns } hostname example.com"%0a%3c %0a---%0a> check = "pki jrmu.coconut.ircnow.org filter { check_rdns check_fcrdns } hostname jrmu.coconut.ircnow.org"%0a> authcheck = "pki jrmu.coconut.ircnow.org auth %3cpasswd> filter { check_rdns check_fcrdns } hostname jrmu.coconut.ircnow.org"%0a> %0a210a211,212%0a> To finish the configuration, we need to [[dovecot/install|install and configure dovecot]].%0a> %0a295,298d296%0a%3c The last field sets how much data storage each user is allowed. The default here is 1 gigabyte.%0a%3c %0a%3c !!! File Permissions%0a%3c %0a306,313c304,310%0a%3c !! IMAP and POP3 via dovecot%0a%3c %0a%3c To finish the setup, we need to [[dovecot/install|install and configure dovecot]].%0a%3c %0a%3c !! DKIM signing%0a%3c %0a%3c We will need to set up [[dkim/dkimsign|dkim]] to have the mail properly signed.%0a%3c %0a---%0a> !! IMAP and POP3 via dovecot; mail signing via dkimproxy%0a> %0a> Take a look at the sample [[openbsd.dovecot|dovecot]] setup for IMAP and POP3, and the sample [[dkimproxy|dkimproxy]] setup for mail signing.%0a> %0a> There are some additional steps for how to add a new user here:%0a> %0a> %0a316,317c313,314%0a%3c OpenSMTPD may end up in an inconsistent state. This can happen due to a misconfiguration. One symptom is you see this error:%0a%3c %0a---%0a> Sometimes OpenSMTPD may end up in an inconsistent state. This can happen due to a misconfiguration. One symptom is you see this error:%0a> %0a320,323c317,318%0a%3c To fix this, you can delete all the temporary files inside OpenSMTPD.%0a%3c %0a%3c '''WARNING''': this will delete any messages in the queue:%0a%3c %0a---%0a> To fix this, you can delete all the temporary files inside OpenSMTPD. '''WARNING''': this will delete any messages in the queue:%0a> %0a389,393d383%0a%3c ipv4 = "38.81.163.143"%0a%3c ipv6 = "2602:fccf:1:143::"%0a%3c check = "pki example.com filter { check_rdns check_fcrdns } hostname example.com"%0a%3c authcheck = "pki example.com auth %3cpasswd> filter { check_rdns check_fcrdns } hostname example.com"%0a%3c %0a395,402c385,396%0a%3c listen on socket filter "dkimsign"%0a%3c listen on lo0 filter "dkimsign"%0a%3c listen on $ipv4 port 25 tls $check%0a%3c listen on $ipv6 port 25 tls $check%0a%3c listen on $ipv4 port 465 tls-require $authcheck%0a%3c listen on $ipv6 port 465 tls-require $authcheck%0a%3c listen on $ipv4 port 587 tls-require $authcheck%0a%3c listen on $ipv6 port 587 tls-require $authcheck%0a---%0a> ipv4 = "192.168.1.1"%0a> ipv6 = "2001:db8::"%0a> %0a> ...%0a> %0a> # listeners%0a> listen on lo0 mask-src%0a> listen on lo0 port 10028 tag DKIM mask-src%0a> listen on $ipv4 port 25 tls pki mail.ircnow.org mask-src filter { check_rdns check_fcrdns } hostname ircnow.org%0a> listen on $ipv6 port 25 tls pki mail.ircnow.org mask-src filter { check_rdns check_fcrdns } hostname ircnow.org%0a> listen on $ipv4 port 587 tls-require pki mail.ircnow.org auth %3cpasswd> mask-src filter { check_rdns check_fcrdns } hostname ircnow.org%0a> listen on $ipv6 port 587 tls-require pki mail.ircnow.org auth %3cpasswd> mask-src filter { check_rdns check_fcrdns } hostname ircnow.org%0a host:1621333842=38.81.163.143 author:1621332833=jrmu diff:1621332833:1621330901:=213,214d212%0a%3c !! Configuring Virtual Users%0a%3c %0a221,226c219,220%0a%3c /var/vmail will be used to store virtual users' maildir folders. It will be managed by dovecot, which receives mail via LMTP.%0a%3c %0a%3c !! Adding users%0a%3c %0a%3c At the bottom of /etc/mail/aliases, add these lines:%0a%3c %0a---%0a> The /etc/passwd file will contain a line similar to this:%0a> %0a228,229c222%0a%3c vmail: /dev/null%0a%3c root: admin@example.com%0a---%0a> vmail:*:1000:1000:Virtual Mail:/var/vmail:/sbin/nologin%0a232,238c225,230%0a%3c Now, any mail sent to vmail will get thrown away; and any mail send to root will get%0a%3c forwarded to admin@example.com.%0a%3c %0a%3c You can optionally one line for each user to provide aliases.%0a%3c %0a%3c Create a new file /etc/mail/virtuals and add these lines:%0a%3c %0a---%0a> /var/vmail is used to store virtual users' maildir folders. It will be managed by dovecot, which receives mail via LMTP.%0a> %0a> !! Adding users%0a> %0a> At the bottom of /etc/mail/aliases, add these lines:%0a> %0a240,241c232,235%0a%3c admin@example.com vmail%0a%3c username@example.com vmail%0a---%0a> vmail: /dev/null%0a> root: admin@ircnow.org%0a> jrmu: jrmu@ircnow.org%0a> username: username@ircnow.org%0a244,247c238,241%0a%3c For each new user account, you will want to create a new line.%0a%3c %0a%3c A whitelist of known good senders goes into /etc/mail/hosts:%0a%3c %0a---%0a> Add one line for each user.%0a> %0a> Create a new file /etc/mail/virtuals and add these lines:%0a> %0a249,251c243,245%0a%3c localhost%0a%3c 192.168.1.1%0a%3c 2001:db8::%0a---%0a> admin@ircnow.org vmail%0a> jrmu@ircnow.org vmail%0a> username@ircnow.org vmail%0a254,258c248,249%0a%3c Replace the IP addresses above with real IP addresses.%0a%3c %0a%3c In /etc/mail/mailname, put in the name you want to use for your mail server. This%0a%3c is very important for passing anti-spam checks:%0a%3c %0a---%0a> A whitelist of known good senders goes into /etc/mail/hosts:%0a> %0a260c251,253%0a%3c example.com%0a---%0a> localhost%0a> 192.168.1.1%0a> 2001:db8::%0a263,264c256,259%0a%3c The list of domains you can want to receive mail for will go inside /etc/mail/domains:%0a%3c %0a---%0a> For /etc/mail/spammers, create a blank file.%0a> %0a> The mail sender's hostname goes in /etc/mail/mailname:%0a> %0a266,267c261%0a%3c example.com%0a%3c mail.example.com%0a---%0a> mail.ircnow.org%0a270,271c264,265%0a%3c In /etc/mail/passwd, we have a list of colon-separated user credentials:%0a%3c %0a---%0a> The list of domains you send mail for go in /etc/mail/domains:%0a> %0a273,274c267,268%0a%3c admin@example.com:$2b$10$h5itbhzs73T4jsHAj9YX6Tf63yRatAquGBxoCX67wyekhCH4ZqioD6lKh::::::userdb_quota_rule=*:storage=1G%0a%3c username@example.com:$2b$10$h5itbhzs73T4jsHAj9YX6Tf63yRatAquGBxoCX67wyekhCH4ZqioD6lKh::::::userdb_quota_rule=*:storage=1G%0a---%0a> ircnow.org%0a> mail.ircnow.org%0a277,282c271,272%0a%3c Each field is separated with a colon.%0a%3c %0a%3c The first field tells you the username. Note that usernames include a domain -- this is because you might host mail for multiple domains. So, when logging in to the mail server, your mail client must be of the format username@example.com.%0a%3c %0a%3c The second field is the password hash. To generate a hash, you can run encrypt:%0a%3c %0a---%0a> In /etc/mail/passwd, we have a list of colon-separated user credentials:%0a> %0a284c274,276%0a%3c $ encrypt%0a---%0a> admin@ircnow.org:$2b$10$h5itbhzs73T4jsHAj9YX6Tf63yRatAquGBxoCX67wyekhCH4ZqioD6lKh::::::userdb_quota_rule=*:storage=1G%0a> jrmu@ircnow.org:$2b$10$h5itbhzs73T4jsHAj9YX6Tf63yRatAquGBxoCX67wyekhCH4ZqioD6lKh::::::userdb_quota_rule=*:storage=1G%0a> username@ircnow.org:$2b$10$h5itbhzs73T4jsHAj9YX6Tf63yRatAquGBxoCX67wyekhCH4ZqioD6lKh::::::userdb_quota_rule=*:storage=1G%0a287,290c279,282%0a%3c Type your password, then press enter. Type ctrl+d to quit.%0a%3c %0a%3c @@smtpctl encrypt@@ also does the same thing:%0a%3c %0a---%0a> '''WARNING''': Some special characters like $, when used in passwords, will cause issue with opensmtpd. To be safe, you may want to use alphanumeric characters only for your password.%0a> %0a> Make sure to set the proper permissions:%0a> %0a292c284,285%0a%3c $ smtpctl encrypt%0a---%0a> $ doas chown -R _smtpd:_dovecot /etc/mail/%0a> $ doas chmod o-rx /etc/mail/%0a295,303c288,291%0a%3c '''WARNING''': Special characters like $, when used in passwords, may cause issues with your mail client or with opensmtpd. To be safe, you might want to use only alphanumeric characters for your password. You can increase the length of the password for more security.%0a%3c %0a%3c Make sure to set the proper permissions:%0a%3c %0a%3c [@%0a%3c $ doas chown -R _smtpd:_dovecot /etc/mail/%0a%3c $ doas chmod o-rx /etc/mail/%0a%3c @]%0a%3c %0a---%0a> !! Spammers%0a> %0a> In /etc/mail/spammers, we have IP addresses separated by newlines.%0a> %0a309a298,303%0a> %0a> To get hashes:%0a> %0a> [@%0a> $ smtpctl encrypt%0a> @]%0a host:1621332833=38.81.163.143 author:1621330901=jrmu diff:1621330901:1621330719:=9,11d8%0a%3c %0a%3c Running a mail server requires a proper DNS records. If you have not already, you will%0a%3c want to read up on [[dns/overview|DNS]] and [[nsd/configure|set up your name server]].%0a host:1621330901=38.81.163.143 author:1621330719=jrmu diff:1621330719:1621329978:=156,161c156,157%0a%3c Line 4 defines our first matching rule: any email headed for one of our domains should be handed over to lmtp (handed over to dovecot).%0a%3c %0a%3c Line 5 defines our second matching rule: any email from our trusted /etc/mail/hosts file will automatically be relayed (sent) without authentication.%0a%3c %0a%3c Line 6 defines our last matching rule: any email that has been properly authenticated will be related (sent).%0a%3c %0a---%0a> Line 4%0a> %0a208c204,206%0a%3c To finish the configuration, we need to [[dovecot/install|install and configure dovecot]].%0a---%0a> # If mail is for any of our domains, pass it to dovecot%0a> # If mail comes from a trusted host, send it%0a> # If the user is authenticated, send it%0a host:1621330719=38.81.163.143 author:1621329978=jrmu diff:1621329978:1621329891:=103c103%0a%3c Line 4 tells opensmtpd to use the public/private keys we defined earlier for @@example.com@@. We mask the sender's source (the '''from''' part of the @@Received@@ header). We also apply two filters to check for proper forward and reverse confirmed DNS entries. Finally, we indicate that the sending hostname must be example.com instead of the default server name.%0a---%0a> Line 4 tells opensmtpd to use the public/private keys we defined earlier for @@example.com@@. We mask the sender's source (the '''from''' part of the @@Received@@ header). We also apply two filters to check for proper forward and reverse confirmed DNS entries. Finally, we indicate that the sending hostname must be example.com instead of default server name.%0a host:1621329978=38.81.163.143 author:1621329891=jrmu diff:1621329891:1621329393:=84c84,85%0a%3c # -d specifies the domain name to sign for; you must replace example.com with your real domain.%0a---%0a> # -d specifies the domain name to sign for; you must replace example.com with your real%0a> domain.%0a host:1621329891=38.81.163.143 author:1621329393=jrmu diff:1621329393:1621329048:=129,137c129,130%0a%3c TLS if supported but to offer plaintext as a fallback. Only basic checking is done.%0a%3c %0a%3c Lines 6-7 tells smtpd to listen on the IPv4 and IPv6 address on port 465, for SMTPS.%0a%3c TLS encryption is required and authentication checking is forced because this socket%0a%3c can be used for sending mail to other servers. We want to avoid an%0a%3c [[openbsd/mailopenproxy|open mail relay]].%0a%3c %0a%3c Lines 8-9 is similar except it's for port 587, which is the SMTP submission port.%0a%3c %0a---%0a> TLS if supported but to offer plaintext as a fallback.%0a> %0a140,142d132%0a%3c Next we define the actions that opensmtpd can take and how to decide which%0a%3c action to follow:%0a%3c %0a152,157d141%0a%3c %0a%3c In line 2, we define the action "lmtp": we pass the mail to dovecot to handle using the Local Mail Transfer Protocol (LMTP). The actual recipient will be translated using the virtuals table.%0a%3c %0a%3c In line 3, we define the action "relay": we relay (send) the email out.%0a%3c %0a%3c Line 4%0a host:1621329393=38.81.163.143 author:1621329048=jrmu diff:1621329048:1621328344:=98,99c98,99%0a%3c check = "pki example.com mask-src filter { check_rdns check_fcrdns } hostname example.com"%0a%3c authcheck = "pki example.com auth %3cpasswd> mask-src senders filter { check_rdns check_fcrdns } hostname example.com"%0a---%0a> check = "pki example.com filter { check_rdns check_fcrdns } hostname example.com"%0a> authcheck = "pki example.com auth %3cpasswd> filter { check_rdns check_fcrdns } hostname example.com"%0a104,106c104,106%0a%3c Line 4 tells opensmtpd to use the public/private keys we defined earlier for @@example.com@@. We mask the sender's source (the '''from''' part of the @@Received@@ header). We also apply two filters to check for proper forward and reverse confirmed DNS entries. Finally, we indicate that the sending hostname must be example.com instead of default server name.%0a%3c %0a%3c Line 5 is identical to line 4 except it requires authentication with the password file and it checks if the sender is allowed.%0a---%0a> Line 4 tells opensmtpd to use the public/private keys we defined earlier for @@example.com@@. We also apply two filters to check for proper forward and reverse confirmed DNS entries. Finally, we indicate that the sending hostname must be example.com instead of default server name.%0a> %0a> Line 5 is identical to line 4 except it requires authentication with the password file.%0a host:1621329048=38.81.163.143 author:1621328344=jrmu diff:1621328344:1621328329:= host:1621328344=38.81.163.143 author:1621328329=jrmu diff:1621328329:1621327178:=38,39c38,39%0a%3c Next, we define 6 tables:%0a%3c %0a---%0a> Next, we define 4 tables:%0a> %0a47d46%0a%3c table users file:/etc/mail/users%0a63,64d61%0a%3c The users file contains a list of valid sending users.%0a%3c %0a102,107c99,102%0a%3c Lines 2 and 3 define the IPv4 and IPv6 addresses used for sending and receiving mail.%0a%3c %0a%3c Line 4 tells opensmtpd to use the public/private keys we defined earlier for @@example.com@@. We also apply two filters to check for proper forward and reverse confirmed DNS entries. Finally, we indicate that the sending hostname must be example.com instead of default server name.%0a%3c %0a%3c Line 5 is identical to line 4 except it requires authentication with the password file.%0a%3c %0a---%0a> In the first two lines, we define the IPv4 and IPv6 addresses used for sending and receiving mail.%0a> %0a> In the third line, we tell opensmtpd to use the public/private keys we defined earlier for @@example.com@@. We also apply two filters to check for proper forward and reverse confirmed DNS entries. Finally, we indicate that the sending hostname must be example.com instead of default server name.%0a> %0a110,111d104%0a%3c The listeners tell us what network interfaces, IP addresses, and ports to listen on.%0a%3c %0a123,129d115%0a%3c %0a%3c Line 2 tells smtpd to listen to the UNIX domain socket and to DKIM sign all %0a%3c emails. Line 3 tells us to listen to the loopback interface and also%0a%3c sign all emails.%0a%3c %0a%3c Lines 4-5 tells smtpd to listen on the IPv4 and IPv6 address on port 25, to provide%0a%3c TLS if supported but to offer plaintext as a fallback.%0a host:1621328329=38.81.163.143 author:1621327178=jrmu diff:1621327178:1621265244:=52c52%0a%3c The domains table contains a list of domains that our mail server should %0a---%0a> The domains table contains a list of domains that our mail server should to%0a55,57c55,56%0a%3c The passwd table contains a colon-separated list of username/password/disk quota%0a%3c entries.%0a%3c %0a---%0a> The passwd table contains a list of username/password/quota entries.%0a> %0a70c69%0a%3c filter "dkimsign" proc-exec "filter-dkimsign -d example.com -s mail -k /etc/mail/dkim/private.key" user _dkimsign group _dkimsign%0a---%0a> filter "dkimsign" proc-exec "filter-dkimsign -d jrmu.coconut.ircnow.org -s mail -k /etc/mail/dkim/private.key" user _dkimsign group _dkimsign%0a73,129d71%0a%3c The first filter will check if the sender has an rdns entry. If not, the mail%0a%3c will be labeled as junk.%0a%3c %0a%3c The second filter will check if the sender's forward and reverse dns entry match. If%0a%3c not, the mail will be labeled as junk.%0a%3c %0a%3c The third filter will sign any email with the DKIM private key.%0a%3c %0a%3c # -d specifies the domain name to sign for; you must replace example.com with your real%0a%3c domain.%0a%3c # -s specifies the selector (in this case mail).%0a%3c # -k specifies the path of the private key.%0a%3c # user and group both specify _dkimsign, the user and group that does the signing%0a%3c %0a%3c !!! Macros%0a%3c %0a%3c A macro defines a variable that will be replaced with a block of text:%0a%3c %0a%3c [@%0a%3c # macros%0a%3c ipv4 = "38.81.163.143"%0a%3c ipv6 = "2602:fccf:1:143::"%0a%3c check = "pki example.com filter { check_rdns check_fcrdns } hostname example.com"%0a%3c authcheck = "pki example.com auth %3cpasswd> filter { check_rdns check_fcrdns } hostname example.com"%0a%3c @]%0a%3c %0a%3c In the first two lines, we define the IPv4 and IPv6 addresses used for sending and receiving mail.%0a%3c %0a%3c In the third line, we tell opensmtpd to use the public/private keys we defined earlier for @@example.com@@. We also apply two filters to check for proper forward and reverse confirmed DNS entries. Finally, we indicate that the sending hostname must be example.com instead of default server name.%0a%3c %0a%3c !!! Listeners%0a%3c %0a%3c [@%0a%3c # listeners%0a%3c listen on socket filter "dkimsign"%0a%3c listen on lo0 filter "dkimsign"%0a%3c listen on $ipv4 port 25 tls $check%0a%3c listen on $ipv6 port 25 tls $check%0a%3c listen on $ipv4 port 465 tls-require $authcheck%0a%3c listen on $ipv6 port 465 tls-require $authcheck%0a%3c listen on $ipv4 port 587 tls-require $authcheck%0a%3c listen on $ipv6 port 587 tls-require $authcheck%0a%3c @]%0a%3c %0a%3c !!! Rules%0a%3c %0a%3c [@%0a%3c # rules%0a%3c action "lmtp" lmtp "/var/dovecot/lmtp" rcpt-to virtual %3cvirtuals>%0a%3c action "relay" relay%0a%3c %0a%3c match from any for domain %3cdomains> action "lmtp"%0a%3c match from src %3chosts> for any action "relay"%0a%3c match auth from any for any action "relay"%0a%3c @]%0a%3c %0a%3c !!! Complete configuration file%0a host:1621327178=38.81.163.143 author:1621265244=jrmu diff:1621265244:1621263438:=21,22d20%0a%3c !!! TLS%0a%3c %0a26,27c24,25%0a%3c Next, we'll create our smtpd configuration file in /etc/mail/smtpd.conf:%0a%3c %0a---%0a> In my /etc/mail/smtpd.conf:%0a> %0a32,40c30%0a%3c @]%0a%3c %0a%3c This defines our public and private key pair for TLS encryption.%0a%3c %0a%3c !!! Tables%0a%3c %0a%3c Next, we define 4 tables:%0a%3c %0a%3c [@%0a---%0a> %0a47,65c37%0a%3c @]%0a%3c %0a%3c The aliases table provides a list of aliases in @@key: value@@ pairs.%0a%3c See [[https://man.openbsd.org/aliases|aliases(5)]] for more information.%0a%3c %0a%3c The domains table contains a list of domains that our mail server should to%0a%3c receive mail on.%0a%3c %0a%3c The passwd table contains a list of username/password/quota entries.%0a%3c %0a%3c The virtuals file shows which virtual user should handle whose mail.%0a%3c %0a%3c The hosts file contains a list of trusted sending hosts.%0a%3c %0a%3c All of these tables will be explained further in the following sections.%0a%3c %0a%3c !!! Dealing with Spam%0a%3c %0a%3c [@%0a---%0a> %0a70,91c42%0a%3c @]%0a%3c %0a%3c %0a%3c Here is the entire configuration file in /etc/mail/smtpd.conf:%0a%3c %0a%3c [@%0a%3c # PKI for TLS%0a%3c pki example.com cert "/etc/ssl/example.com.fullchain.pem"%0a%3c pki example.com key "/etc/ssl/private/example.com.key"%0a%3c %0a%3c # tables setup%0a%3c table aliases file:/etc/mail/aliases%0a%3c table domains file:/etc/mail/domains%0a%3c table passwd passwd:/etc/mail/passwd%0a%3c table virtuals file:/etc/mail/virtuals%0a%3c table hosts file:/etc/mail/hosts%0a%3c %0a%3c # Blocks junk mail%0a%3c filter check_rdns phase connect match !rdns junk%0a%3c filter check_fcrdns phase connect match !fcrdns junk%0a%3c filter "dkimsign" proc-exec "filter-dkimsign -d jrmu.coconut.ircnow.org -s mail -k /etc/mail/dkim/private.key" user _dkimsign group _dkimsign%0a%3c %0a---%0a> %0a111a63%0a> # If mail is for any of our domains, pass it to dovecot%0a112a65,66%0a> %0a> # If mail comes from a trusted host, send it%0a113a68,69%0a> %0a> # If the user is authenticated, send it%0a116,119d71%0a%3c %0a%3c # If mail is for any of our domains, pass it to dovecot%0a%3c # If mail comes from a trusted host, send it%0a%3c # If the user is authenticated, send it%0a host:1621265244=38.81.163.143 author:1621263438=jrmu diff:1621263438:1621263299:minor=21,23d20%0a%3c You will want to use [[acme-client/configure|acme-client]] to request a TLS public cert and private key%0a%3c in /etc/ssl/.%0a%3c %0a28,29c25,26%0a%3c pki example.com cert "/etc/ssl/example.com.fullchain.pem"%0a%3c pki example.com key "/etc/ssl/private/example.com.key"%0a---%0a> pki jrmu.coconut.ircnow.org cert "/etc/ssl/jrmu.coconut.ircnow.org.fullchain.pem"%0a> pki jrmu.coconut.ircnow.org key "/etc/ssl/private/jrmu.coconut.ircnow.org.key"%0a host:1621263438=38.81.163.143 author:1621263299=jrmu diff:1621263299:1621263186:minor=7c7%0a%3c Read the [[https://github.com/poolpOrg/OpenSMTPD-book|free OpenSMTPd book]] by the%0a---%0a> Read the [[github.com/poolpOrg/OpenSMTPD-book|free OpenSMTPd book]] by the%0a host:1621263299=38.81.163.143 author:1621263186=jrmu diff:1621263186:1621262883:minor=3,9d2%0a%3c !! Before we begin%0a%3c %0a%3c Read the the man pages for [[https://man.openbsd.org/smtpd|opensmtpd]], [[https://man.openbsd.org/smtpd.conf|smtpd.conf]], and [[https://man.openbsd.org/smtpctl|smtpctl]]. %0a%3c %0a%3c Read the [[github.com/poolpOrg/OpenSMTPD-book|free OpenSMTPd book]] by the%0a%3c author of OpenSMTPd%0a%3c %0a154a148%0a> Based on: https://cvsweb.openbsd.org/cgi-bin/cvsweb/~checkout~/www/opensmtpd/faq/Attic/example1.html?rev=1.14%0a host:1621263186=38.81.163.143 author:1621262883=jrmu diff:1621262883:1621253792:=1,2c1,2%0a%3c Let's set up a mail server with dkim signing and basic spam checks:%0a%3c %0a---%0a> Here is how I set up my independent mail server. It is based on the old (now deleted) [[https://cvsweb.openbsd.org/cgi-bin/cvsweb/~checkout~/www/opensmtpd/faq/Attic/example1.html?rev=1.14|OpenSMTPd FAQ]].%0a> %0a5,7c5,6%0a%3c Opensmtpd is part of OpenBSD base, but we will also want to install some%0a%3c opensmtpd-related packages and dovecot:%0a%3c %0a---%0a> Make sure to install opensmtpd-extras:%0a> %0a9c8%0a%3c $ doas pkg_add opensmtpd-extras opensmtpd-filter-dkimsign dovecot%0a---%0a> $ doas pkg_add opensmtpd-extras%0a18,20c17,19%0a%3c pki jrmu.coconut.ircnow.org cert "/etc/ssl/jrmu.coconut.ircnow.org.fullchain.pem"%0a%3c pki jrmu.coconut.ircnow.org key "/etc/ssl/private/jrmu.coconut.ircnow.org.key"%0a%3c %0a---%0a> pki mail.ircnow.org cert "/etc/ssl/ircnow.org.fullchain.pem"%0a> pki mail.ircnow.org key "/etc/ssl/private/ircnow.org.key"%0a> %0a27c26,27%0a%3c %0a---%0a> table spammers file:/etc/mail/spammers%0a> %0a31,38c31,32%0a%3c filter "dkimsign" proc-exec "filter-dkimsign -d jrmu.coconut.ircnow.org -s mail -k /etc/mail/dkim/private.key" user _dkimsign group _dkimsign%0a%3c %0a%3c # macros%0a%3c ipv4 = "38.81.163.143"%0a%3c ipv6 = "2602:fccf:1:143::"%0a%3c check = "pki jrmu.coconut.ircnow.org filter { check_rdns check_fcrdns } hostname jrmu.coconut.ircnow.org"%0a%3c authcheck = "pki jrmu.coconut.ircnow.org auth %3cpasswd> filter { check_rdns check_fcrdns } hostname jrmu.coconut.ircnow.org"%0a%3c %0a---%0a> filter check_spammers phase connect match src %3cspammers> junk%0a> %0a40,49c34,44%0a%3c listen on socket filter "dkimsign"%0a%3c listen on lo0 filter "dkimsign"%0a%3c listen on $ipv4 port 25 tls $check%0a%3c listen on $ipv6 port 25 tls $check%0a%3c listen on $ipv4 port 465 tls-require $authcheck%0a%3c listen on $ipv6 port 465 tls-require $authcheck%0a%3c listen on $ipv4 port 587 tls-require $authcheck%0a%3c listen on $ipv6 port 587 tls-require $authcheck%0a%3c %0a%3c # rules%0a---%0a> ipv4 = "192.168.1.1"%0a> ipv6 = "2001:db8::"%0a> %0a> # listeners%0a> listen on lo0 mask-src%0a> listen on lo0 port 10028 tag DKIM mask-src%0a> listen on $ipv4 port 25 tls pki mail.ircnow.org mask-src filter { check_rdns check_fcrdns } hostname ircnow.org%0a> listen on $ipv6 port 25 tls pki mail.ircnow.org mask-src filter { check_rdns check_fcrdns } hostname ircnow.org%0a> listen on $ipv4 port 587 tls-require pki mail.ircnow.org auth %3cpasswd> mask-src filter { check_rdns check_fcrdns } hostname ircnow.org%0a> listen on $ipv6 port 587 tls-require pki mail.ircnow.org auth %3cpasswd> mask-src filter { check_rdns check_fcrdns } hostname ircnow.org%0a> %0a52c47,48%0a%3c %0a---%0a> action "relay_dkim" relay host smtp://127.0.0.1:10027%0a> %0a56,60c52,57%0a%3c # If mail comes from a trusted host, send it%0a%3c match from src %3chosts> for any action "relay"%0a%3c %0a%3c # If the user is authenticated, send it%0a%3c match auth from any for any action "relay"%0a---%0a> # If mail is tagged with DKIM, relay it out%0a> match tag DKIM for any action "relay"%0a> %0a> # If mail comes from known good hosts or has been authenticated, relay it to dkimproxy_out%0a> match from src %3chosts> for any action "relay_dkim"%0a> match auth from any for any action "relay_dkim"%0a host:1621262883=38.81.163.143 author:1621253792=jrmu diff:1621253792:1621253792:=1,247d0%0a%3c Here is how I set up my independent mail server. It is based on the old (now deleted) [[https://cvsweb.openbsd.org/cgi-bin/cvsweb/~checkout~/www/opensmtpd/faq/Attic/example1.html?rev=1.14|OpenSMTPd FAQ]].%0a%3c %0a%3c !! Install%0a%3c %0a%3c Make sure to install opensmtpd-extras:%0a%3c %0a%3c [@%0a%3c $ doas pkg_add opensmtpd-extras%0a%3c @]%0a%3c %0a%3c !! Configuration%0a%3c %0a%3c In my /etc/mail/smtpd.conf:%0a%3c %0a%3c [@%0a%3c # PKI for TLS%0a%3c pki mail.ircnow.org cert "/etc/ssl/ircnow.org.fullchain.pem"%0a%3c pki mail.ircnow.org key "/etc/ssl/private/ircnow.org.key"%0a%3c %0a%3c # tables setup%0a%3c table aliases file:/etc/mail/aliases%0a%3c table domains file:/etc/mail/domains%0a%3c table passwd passwd:/etc/mail/passwd%0a%3c table virtuals file:/etc/mail/virtuals%0a%3c table hosts file:/etc/mail/hosts%0a%3c table spammers file:/etc/mail/spammers%0a%3c %0a%3c # Blocks junk mail%0a%3c filter check_rdns phase connect match !rdns junk%0a%3c filter check_fcrdns phase connect match !fcrdns junk%0a%3c filter check_spammers phase connect match src %3cspammers> junk%0a%3c %0a%3c # listeners%0a%3c ipv4 = "192.168.1.1"%0a%3c ipv6 = "2001:db8::"%0a%3c %0a%3c # listeners%0a%3c listen on lo0 mask-src%0a%3c listen on lo0 port 10028 tag DKIM mask-src%0a%3c listen on $ipv4 port 25 tls pki mail.ircnow.org mask-src filter { check_rdns check_fcrdns } hostname ircnow.org%0a%3c listen on $ipv6 port 25 tls pki mail.ircnow.org mask-src filter { check_rdns check_fcrdns } hostname ircnow.org%0a%3c listen on $ipv4 port 587 tls-require pki mail.ircnow.org auth %3cpasswd> mask-src filter { check_rdns check_fcrdns } hostname ircnow.org%0a%3c listen on $ipv6 port 587 tls-require pki mail.ircnow.org auth %3cpasswd> mask-src filter { check_rdns check_fcrdns } hostname ircnow.org%0a%3c %0a%3c action "lmtp" lmtp "/var/dovecot/lmtp" rcpt-to virtual %3cvirtuals>%0a%3c action "relay" relay%0a%3c action "relay_dkim" relay host smtp://127.0.0.1:10027%0a%3c %0a%3c # If mail is for any of our domains, pass it to dovecot%0a%3c match from any for domain %3cdomains> action "lmtp"%0a%3c %0a%3c # If mail is tagged with DKIM, relay it out%0a%3c match tag DKIM for any action "relay"%0a%3c %0a%3c # If mail comes from known good hosts or has been authenticated, relay it to dkimproxy_out%0a%3c match from src %3chosts> for any action "relay_dkim"%0a%3c match auth from any for any action "relay_dkim"%0a%3c @]%0a%3c %0a%3c A single user vmail will receive mail for all virtual users:%0a%3c %0a%3c [@%0a%3c $ doas useradd -m -g =uid -c "Virtual Mail" -d /var/vmail -s /sbin/nologin vmail%0a%3c @]%0a%3c %0a%3c The /etc/passwd file will contain a line similar to this:%0a%3c %0a%3c [@%0a%3c vmail:*:1000:1000:Virtual Mail:/var/vmail:/sbin/nologin%0a%3c @]%0a%3c %0a%3c /var/vmail is used to store virtual users' maildir folders. It will be managed by dovecot, which receives mail via LMTP.%0a%3c %0a%3c !! Adding users%0a%3c %0a%3c At the bottom of /etc/mail/aliases, add these lines:%0a%3c %0a%3c [@%0a%3c vmail: /dev/null%0a%3c root: admin@ircnow.org%0a%3c jrmu: jrmu@ircnow.org%0a%3c username: username@ircnow.org%0a%3c @]%0a%3c %0a%3c Add one line for each user.%0a%3c %0a%3c Create a new file /etc/mail/virtuals and add these lines:%0a%3c %0a%3c [@%0a%3c admin@ircnow.org vmail%0a%3c jrmu@ircnow.org vmail%0a%3c username@ircnow.org vmail%0a%3c @]%0a%3c %0a%3c A whitelist of known good senders goes into /etc/mail/hosts:%0a%3c %0a%3c [@%0a%3c localhost%0a%3c 192.168.1.1%0a%3c 2001:db8::%0a%3c @]%0a%3c %0a%3c For /etc/mail/spammers, create a blank file.%0a%3c %0a%3c The mail sender's hostname goes in /etc/mail/mailname:%0a%3c %0a%3c [@%0a%3c mail.ircnow.org%0a%3c @]%0a%3c %0a%3c The list of domains you send mail for go in /etc/mail/domains:%0a%3c %0a%3c [@%0a%3c ircnow.org%0a%3c mail.ircnow.org%0a%3c @]%0a%3c %0a%3c In /etc/mail/passwd, we have a list of colon-separated user credentials:%0a%3c %0a%3c [@%0a%3c admin@ircnow.org:$2b$10$h5itbhzs73T4jsHAj9YX6Tf63yRatAquGBxoCX67wyekhCH4ZqioD6lKh::::::userdb_quota_rule=*:storage=1G%0a%3c jrmu@ircnow.org:$2b$10$h5itbhzs73T4jsHAj9YX6Tf63yRatAquGBxoCX67wyekhCH4ZqioD6lKh::::::userdb_quota_rule=*:storage=1G%0a%3c username@ircnow.org:$2b$10$h5itbhzs73T4jsHAj9YX6Tf63yRatAquGBxoCX67wyekhCH4ZqioD6lKh::::::userdb_quota_rule=*:storage=1G%0a%3c @]%0a%3c %0a%3c '''WARNING''': Some special characters like $, when used in passwords, will cause issue with opensmtpd. To be safe, you may want to use alphanumeric characters only for your password.%0a%3c %0a%3c Make sure to set the proper permissions:%0a%3c %0a%3c [@%0a%3c $ doas chown -R _smtpd:_dovecot /etc/mail/%0a%3c $ doas chmod o-rx /etc/mail/%0a%3c @]%0a%3c %0a%3c !! Spammers%0a%3c %0a%3c In /etc/mail/spammers, we have IP addresses separated by newlines.%0a%3c %0a%3c !! IMAP and POP3 via dovecot; mail signing via dkimproxy%0a%3c %0a%3c Take a look at the sample [[openbsd.dovecot|dovecot]] setup for IMAP and POP3, and the sample [[dkimproxy|dkimproxy]] setup for mail signing.%0a%3c %0a%3c There are some additional steps for how to add a new user here:%0a%3c %0a%3c Based on: https://cvsweb.openbsd.org/cgi-bin/cvsweb/~checkout~/www/opensmtpd/faq/Attic/example1.html?rev=1.14%0a%3c %0a%3c To get hashes:%0a%3c %0a%3c [@%0a%3c $ smtpctl encrypt%0a%3c @]%0a%3c %0a%3c !! Troubleshooting%0a%3c %0a%3c Sometimes OpenSMTPD may end up in an inconsistent state. This can happen due to a misconfiguration. One symptom is you see this error:%0a%3c %0a%3c smtpd[]: pony express: smtpd: socket: Too many open files%0a%3c %0a%3c To fix this, you can delete all the temporary files inside OpenSMTPD. '''WARNING''': this will delete any messages in the queue:%0a%3c %0a%3c [@%0a%3c $ doas rcctl stop smtpd%0a%3c $ doas rm -r /var/spool/smtpd/queue/*%0a%3c $ doas rm -r /var/spool/smtpd/offline/*%0a%3c @]%0a%3c %0a%3c At times, opensmtpd may be unable to connect because outgoing packets are being filtered. For example, suppose you are trying to send a letter to yahoo, but you get errors similar to following, showing a connection timeout:%0a%3c %0a%3c [@%0a%3c smtpd[]: smtp-out: Enabling route [] %3c-> 67.195.204.77 (mtaproxy1.free.mail.vip.bf1.yahoo.com)%0a%3c smtpd[]: smtp-out: Enabling route [] %3c-> 67.195.228.106 (mtaproxy2.free.mail.vip.gq1.yahoo.com)%0a%3c smtpd[]: mta error reason=Connection timeout%0a%3c smtpd[]: smtp-out: Disabling route [] %3c-> 104.47.55.33 (104.47.55.33) for 15s%0a%3c @]%0a%3c %0a%3c An easy way to test if your packets are being filtered is:%0a%3c %0a%3c [@%0a%3c $ dig -t mx yahoo.com%0a%3c ;; ANSWER SECTION:%0a%3c yahoo.com. 395 IN MX 1 mta6.am0.yahoodns.net.%0a%3c yahoo.com. 395 IN MX 1 mta5.am0.yahoodns.net.%0a%3c yahoo.com. 395 IN MX 1 mta7.am0.yahoodns.net.%0a%3c $ nc mta5.am0.yahoodns.net 25%0a%3c @]%0a%3c %0a%3c If you get no response, then outgoing packets to port 25 are being blocked (often due to firewalls by your VPS provider to block spam). If mail is working, you should see a 220 reply:%0a%3c %0a%3c [@%0a%3c $ nc mta5.am0.yahoodns.net 25%0a%3c 220 mtaproxy511.free.mail.ne1.yahoo.com ESMTP ready%0a%3c @]%0a%3c %0a%3c It is also possible that TLS is being dropped by the firewall. You can test using openssl:%0a%3c %0a%3c [@%0a%3c $ openssl s_client -starttls smtp -connect mta5.am0.yahoodns.net:25%0a%3c CONNECTED(00000003)%0a%3c depth=2 C = US, O = DigiCert Inc, OU = www.digicert.com, CN = DigiCert High Assurance EV Root CA%0a%3c verify return:1%0a%3c depth=1 C = US, O = DigiCert Inc, OU = www.digicert.com, CN = DigiCert SHA2 High Assurance Server CA%0a%3c verify return:1%0a%3c depth=0 C = US, ST = California, L = Sunnyvale, O = Oath Inc, CN = *.am0.yahoodns.net%0a%3c ...%0a%3c 250 STARTTLS%0a%3c @]%0a%3c %0a%3c You should see the entire SSL cert plus 250 STARTTLS reply. If you see the response hang at any point (eg, it returns CONNECTED(00000003) and nothing else), then TLS on port 25 is being filtered.%0a%3c %0a%3c If you see this warning message in /var/log/maillog:%0a%3c %0a%3c [@%0a%3c Dec 6 03:44:17 smtpd[]: info: OpenSMTPD 6.7.0 starting %0a%3c Dec 6 03:44:17 smtpd[]: pony express: smtpd: socket: Too many open files %0a%3c Dec 6 03:44:17 smtpd[]: warn: lost child: pony express exited abnormally %0a%3c @]%0a%3c %0a%3c This is due to having too many IP addresses that opensmtpd tries to bind to. This happens when you have a rule that says @@listen on egress@@:%0a%3c %0a%3c listen on egress port 25 tls pki fruit.ircnow.org mask-src filter { check_rdns check_fcrdns }%0a%3c listen on egress port 587 tls-require pki fruit.ircnow.org auth %3cpasswd> mask-src filter { check_rdns check_fcrdns }%0a%3c %0a%3c These two lines mean that opensmtpd will listen to '''all''' available ip address, including the hundreds of IPv6 addresses you may have in /etc/hostname.vio0 and @@ifconfig vio0@@. To fix this, you must specify the IP addresses you want to listen to:%0a%3c %0a%3c [@%0a%3c # listeners%0a%3c ipv4 = "192.168.1.1"%0a%3c ipv6 = "2001:db8::"%0a%3c %0a%3c ...%0a%3c %0a%3c # listeners%0a%3c listen on lo0 mask-src%0a%3c listen on lo0 port 10028 tag DKIM mask-src%0a%3c listen on $ipv4 port 25 tls pki mail.ircnow.org mask-src filter { check_rdns check_fcrdns } hostname ircnow.org%0a%3c listen on $ipv6 port 25 tls pki mail.ircnow.org mask-src filter { check_rdns check_fcrdns } hostname ircnow.org%0a%3c listen on $ipv4 port 587 tls-require pki mail.ircnow.org auth %3cpasswd> mask-src filter { check_rdns check_fcrdns } hostname ircnow.org%0a%3c listen on $ipv6 port 587 tls-require pki mail.ircnow.org auth %3cpasswd> mask-src filter { check_rdns check_fcrdns } hostname ircnow.org%0a%3c @]%0a%3c %0a%3c !!! Open Mail Relay%0a%3c %0a%3c If all your email is being marked as spam, check @@/var/log/maillog@@ . If you see a message like the following:%0a%3c %0a%3c Jan 8 11:00:29 smtpd[39035]: 83bd6b3b1669649f mta delivery evpid=a8d16cd2144222fa from=%3cspammer@example.com> to=%3cvictim@example.com> rcpt=%3c-> source="192.168.0.1" relay="10.0.0.1 (10.0.0.1)" delay=16h2s result="TempFail" stat="451 4.7.650 The mail server [192.168.0.1] has been temporarily rate limited due to IP reputation. For e-mail delivery information, see https://postmaster.example.com (S843)"%0a%3c %0a%3c Then your server is being exploited as an [[openbsd/mailopenproxy|open mail relay]]! Please follow the guide to fix it.%0a host:1621253792=38.81.163.143