Blame
Date:
Fri Dec 17 16:26:51 2021
UTC
Message:
Import sources
010
2021-12-17
targets=Dns.Overview,Nsd.Configure,DNS.Mail,Acme-client.Configure,Opensmtpd.Openrelay,Dovecot.Install,DNS.DKIM,Opensmtpd.Troubleshoot
011
2021-12-17
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 "relay" relay src $ipv4%0a%0amatch from any for domain %3cdomains> action "lmtp"%0amatch from local for any action "relay"%0amatch from src %3chosts> for any action "relay"%0amatch auth from any for any action "relay"%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 "relay": 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 "relay" relay src $ipv4%0a%0amatch from any for domain %3cdomains> action "lmtp"%0amatch from local for any action "relay"%0amatch from src %3chosts> for any action "relay"%0amatch auth from any for any action "relay"%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%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 you want to receive mail 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
014
2021-12-17
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
017
2021-12-17
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
020
2021-12-17
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
023
2021-12-17
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
026
2021-12-17
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
030
2021-12-17
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
037
2021-12-17
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
040
2021-12-17
diff:1629671234:1628156436:=423c423%0a%3c [@%0a---%0a> %0a425c425%0a%3c @]%0a---%0a> %0a
043
2021-12-17
diff:1628156436:1625798671:=316c316%0a%3c $ doas chmod -R o-rx /etc/mail/%0a---%0a> $ doas chmod o-rx /etc/mail/%0a
046
2021-12-17
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
049
2021-12-17
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
055
2021-12-17
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
058
2021-12-17
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
064
2021-12-17
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
067
2021-12-17
diff:1623223089:1623222265:=425,426d424%0a%3c %0a%3c !! [[opensmtpd/troubleshoot|Troubleshooting OpenSMTPd]]%0a
070
2021-12-17
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
073
2021-12-17
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
076
2021-12-17
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
083
2021-12-17
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
089
2021-12-17
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
092
2021-12-17
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
095
2021-12-17
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
098
2021-12-17
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
101
2021-12-17
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
104
2021-12-17
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
107
2021-12-17
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
110
2021-12-17
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
113
2021-12-17
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
116
2021-12-17
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
119
2021-12-17
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
122
2021-12-17
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
125
2021-12-17
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
128
2021-12-17
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
134
2021-12-17
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
137
2021-12-17
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
140
2021-12-17
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
143
2021-12-17
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
146
2021-12-17
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
149
2021-12-17
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
152
2021-12-17
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
155
2021-12-17
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