Some Computer Hints


Ubuntu Mail Configuration

Mail server configuration is one of the most difficult aspects of Linux server configuration. I generally use Postfix and Dovecot on my Ubuntu VPS’s. I have prepared the following rough checklist which I used during my latest (Ubuntu 22.04) mail server configuration.

The following assumes that:

  • You have created your Ubuntu VPS Server and you have command line root access (via sudo -i) to your server.
  • All DNS configuration for your domain(s) is completed and you have control of your DNS server(s).
  • You have opened inbound ports 25/tcp (smtp), 587/tcp (submission), and 995/tcp (pop3s).
  • Your VPS provider supports outbound 25/tcp (smtp) connections (most providers do not).
  • Your domain name is something like mydomain.com, your server hostname is something like mysrv.mydomain.com, and your MX record for your domain is something like mail.mydomain.com.

Installation and Initial Configurations

👉 https://help.ubuntu.com/community/Postfix

# apt install postfix
# dpkg-reconfigure postfix
# /etc/init.d/postfix restart
# cat >/etc/postfix/sasl/smtpd.conf
pwcheck_method: saslauthd
mech_list: plain login

👉 https://help.ubuntu.com/community/PostfixBasicSetupHowto

# cat >/etc/profile.d/mailenv.sh
export MAIL=$HOME/Maildir

Use the instructions at https://help.ubuntu.com/community/PostfixVirtualMailBoxClamSmtpHowto to create virtual mailboxes for separate domains and non-Linux accounts; to create a virtual mailbox owner; and to set up Postfix to use virtual mailboxes.

Install Dovecot:

# apt install dovecot-core dovecot-imapd dovecot-pop3d
# apt autoremove

Configure /etc/dovecot/local.conf file (as explained in “Configure Dovecot / file /etc/dovecot/dovecot.conf / Ubuntu 12.04”) and change ssl = yes in the file.

Add /usr/local/sbin/adddovecotuser and /usr/local/sbin/deldovecotuser scripts.

Add Dovecot (POP3, IMAP) users, like:

# adddovecotuser myuser@mydomain.com

Check configurations once more with the below:

👉 https://www.krizna.com/ubuntu/setup-mail-server-ubuntu-14-04/

👉 https://doc.dovecot.org/configuration_manual/dovecot_ssl_configuration/

SSL & Auth

👉 https://help.ubuntu.com/lts/serverguide/postfix.htmlhttps://ubuntu.com/server/docs/mail-postfix

Configure Postfix for SMTP-AUTH using SASL (Dovecot SASL):

# postconf -e 'smtpd_sasl_auth_enable = yes'
# postconf -e 'smtpd_sasl_security_options = noanonymous'
# postconf -e 'smtpd_recipient_restrictions = permit_sasl_authenticated,permit_mynetworks,reject_unauth_destination'
# postconf -e 'smtpd_sasl_type = dovecot'
# postconf -e 'smtpd_sasl_path = private/auth'
# postconf -e 'smtpd_sasl_local_domain ='
# postconf -e 'broken_sasl_auth_clients = yes'

👉 https://ubuntu.com/server/docs/security-certificates

If your secure server is to be used in a production environment, you probably need a CA-signed certificate. It is not recommended to use a self-signed certificate. Obtain a digital certificate for TLS from Let’s Encrypt. Assuming the CA (letsencrypt) certificate resides in the /etc/letsencrypt/live/mydomain.com/ directory, run the following:

# postconf -e 'smtpd_tls_key_file = /etc/letsencrypt/live/mydomain.com/privkey.pem'
# postconf -e 'smtpd_tls_cert_file = /etc/letsencrypt/live/mydomain.com/fullchain.pem'

Configure Postfix to provide TLS encryption for both incoming and outgoing mail:

# postconf -e 'smtp_tls_security_level = may'
# postconf -e 'smtpd_tls_security_level = may'
# postconf -e 'smtp_tls_note_starttls_offer = yes'
# postconf -e 'smtpd_tls_loglevel = 1'
# postconf -e 'smtpd_tls_received_header = yes'
# postconf -e 'myhostname = mysrv.mydomain.com'
# postconf -e 'smtp_helo_name = mail.mydomain.com'

SMTP Authentication

Postfix supports two SASL implementations Cyrus SASL and Dovecot SASL.

Check the files /etc/dovecot/conf.d/10-master.conf and /etc/dovecot/conf.d/10-auth.conf as described in https://ubuntu.com/server/docs/mail-postfix (Configuring SASL):

File /etc/dovecot/conf.d/10-master.conf:

[...]
  # Postfix smtp-auth
  unix_listener /var/spool/postfix/private/auth {
    mode = 0666
    user = postfix
    group = postfix
  }
[...]

File /etc/dovecot/conf.d/10-auth.conf:

[...]
auth_mechanisms = plain login
[...]

and uncomment the following line:

disable_plaintext_auth = yes

Change also the following files:

/etc/dovecot/conf.d/10-mail.conf:

mail_location = maildir:~/Maildir

/etc/dovecot/conf.d/20-pop3.conf:

pop3_uidl_format = %08Xu%08Xv

Dovecot SSL Configuration

After a letsencrypt certificate is obtained and assuming that the certificate files are in /etc/letsencrypt/live/mydomain.com/ directory:

# cd /etc/dovecot/private
# mv dovecot.key dovecot.key.old
# mv dovecot.pem dovecot.pem.old
# ln -s /etc/letsencrypt/live/mydomain.com/privkey.pem   dovecot.key
# ln -s /etc/letsencrypt/live/mydomain.com/fullchain.pem dovecot.pem

Note: The configuration file for Dovecot SSL is: /etc/dovecot/conf.d/10-ssl.conf. As an alternative, you can change the ssl_cert and ssl_key entries in that file.

Configure for Mail Submission (port 587)

Edit /etc/postfix/master.cf like this:

submission inet n       -       y       -       -       smtpd
  -o syslog_name=postfix/submission
  -o smtpd_tls_security_level=encrypt
  -o smtpd_sasl_auth_enable=yes
#  -o smtpd_tls_auth_only=yes
#  -o smtpd_reject_unlisted_recipient=no
#  -o smtpd_client_restrictions=$mua_client_restrictions
#  -o smtpd_helo_restrictions=$mua_helo_restrictions
#  -o smtpd_sender_restrictions=$mua_sender_restrictions
#  -o smtpd_recipient_restrictions=
  -o smtpd_relay_restrictions=permit_sasl_authenticated,reject
  -o milter_macro_daemon_name=ORIGINATING

and run:

# /etc/init.d/postfix restart

Other Configurations

Banner:

# postconf -e ' smtpd_banner = mail.mydomain.com ESMTP'

Check your IP address’ abuse status (replace myipaddress with your real external IP address in the link below):

👉 https://www.anti-abuse.org/multi-rbl-check-results/?host=myipaddress

Extra configurations for spam control

👉 http://www.postfix.org/SMTPD_ACCESS_README.html#lists

Put _SPF and _DMARC records in your DNS

👉 https://www.linuxbabe.com/mail-server/setting-up-dkim-and-spf

👉 https://www.linuxbabe.com/mail-server/create-dmarc-record

Add the following TXT DNS records to your mail sending (mydomain.com) zone configuration file:

	IN TXT	"v=spf1 include:_spf.mydomain.com ~all"
mail	IN TXT	"v=spf1 include:_spf.mydomain.com ~all"
_dmarc	IN TXT	"v=DMARC1; p=none; rua=mailto:your_email_address; ruf=mailto:your_email_address; sp=reject; ri=86400"
_spf	IN TXT	"v=spf1 ip4:ip_addr1 ip6:ip_addr2 ip4:ip_addr3 ~all"

Here, ip_addrX is the IP address(es) of your email server(s).

Check SPF records at https://dmarcian.com/.

Tell Postfix to check for SPF records for incoming emails

👉 https://www.linuxbabe.com/mail-server/setting-up-dkim-and-spf

Install:

# apt install postfix-policyd-spf-python

Add the following lines at the end of /etc/postfix/master.cf:

policyd-spf  unix  -       n       n       -       0       spawn
    user=policyd-spf argv=/usr/bin/policyd-spf

Merge the following lines into /etc/postfix/main.cf:

policyd-spf_time_limit = 3600
smtpd_recipient_restrictions =
   […],
   check_policy_service unix:private/policyd-spf

The first line specifies the Postfix policy agent timeout setting. The following lines will impose restriction on incoming emails by checking SPF records.

# systemctl restart postfix

Setting up DKIM

👉 https://www.linuxbabe.com/mail-server/setting-up-dkim-and-spf

Install:

# apt install opendkim opendkim-tools

Add postfix user to opendkim group:

# gpasswd -a postfix opendkim

Uncomment the following lines in /etc/opendkim.conf: (Replace simple with relaxed/simple.)

Canonicalization   relaxed/simple
Mode               sv
SubDomains         no

Add the following below “SubDomains no”:

AutoRestart		yes
AutoRestartRate		10/1M
Background		yes
DNSTimeout		5
SignatureAlgorithm 	rsa-sha256

Add the following to the end of the file:

#OpenDKIM user
# Remember to add user postfix to group opendkim
UserID		opendkim

# Map domains in From addresses to keys used to sign messages
KeyTable		/etc/opendkim/key.table
SigningTable		refile:/etc/opendkim/signing.table

# Hosts to ignore when verifying signatures
ExternalIgnoreList	/etc/opendkim/trusted.hosts
InternalHosts		/etc/opendkim/trusted.hosts

Create signing table, key table and trusted hosts file:

# mkdir /etc/opendkim
# mkdir /etc/opendkim/keys
# chown -R opendkim:opendkim /etc/opendkim
# chmod go-rw /etc/opendkim/keys
# echo '*@mydomain.com default._domainkey.mydomain' \
 >/etc/opendkim/signing.table
# echo 'default._domainkey.mydomain' \
 'mydomain.com:default:/etc/opendkim/keys/mydomain.com/default.private' \
 >/etc/opendkim/key.table
# echo '127.0.0.1
localhost
*.mydomain.com' >/etc/opendkim/trusted.hosts

Generate private/public key pair:

# mkdir /etc/opendkim/keys/mydomain.com
# opendkim-genkey -b 2048 -d mydomain.com \
 -D /etc/opendkim/keys/mydomain.com -s default -v
# chown opendkim:opendkim /etc/opendkim/keys/mydomain.com/default.private

Get contents of public key:

# cat /etc/opendkim/keys/mydomain.com/default.txt

Insert it into your DNS records (for example, update /etc/bind/db.mydomain.com if you are using BIND) and check:

# opendkim-testkey -d mydomain.com -s default -vvv
opendkim-testkey: using default configfile /etc/opendkim.conf
opendkim-testkey: checking key 'default._domainkey.mydomain.com'
opendkim-testkey: key not secure
opendkim-testkey: key OK

Connect Postfix to OpenDKIM:

# mkdir /var/spool/postfix/opendkim
# chown opendkim:postfix /var/spool/postfix/opendkim

Edit the socket configuration file /etc/opendkim.conf and replace “Socket local:/var/run/opendkim/opendkim.sock” with:

Socket			local:/var/spool/postfix/opendkim/opendkim.sock

Add the following to the end of /etc/postfix/main.cf:

# Milter configuration
# OpenDKIM
milter_default_action = accept
milter_protocol = 2
smtpd_milters = local:/opendkim/opendkim.sock
non_smtpd_milters = local:/opendkim/opendkim.sock

Restart:

# systemctl restart opendkim ; systemctl restart postfix

To check DKIM send a test email to check-auth@verifier.port25.com. A report like this should be returned from port25.com:

==========================================================
Summary of Results
==========================================================
SPF check:           pass
"iprev" check:       pass
DKIM check:          pass
SpamAssassin check:  ham

Whitelist Hosts/IP Addresses

To whitelist some servers from spam lists:

# cat >/etc/postfix/rbl_override
## Don't forget: postmap /etc/postfix/rbl_override
my_ip OK
mydomain.com OK

add a:

	check_client_access hash:/etc/postfix/rbl_override,

line to smtpd_recipient_restrictions = entry in /etc/postfix/main.cf file and run:

# postmap /etc/postfix/rbl_override
# /etc/init.d/postfix restart

Mail Operations

# postmap /etc/postfix/vmaps; \
  postmap /etc/postfix/valiases; \
  systemctl restart postfix

Sample contents of configuration files

# cat /etc/postfix/vhosts
mydomain.com
mydomain2.com
mydomain3.com
# cat /etc/postfix/vmaps
myuser@mydomain.com mydomain.com/myuser/

To define mail address aliases:

# cat /etc/postfix/valiases
### mydomain.com:
myuser@mydomain.com     mygmailuser@gmail.com
postmaster@mydomain.com mygmailuser@gmail.com

Mail Queue Management

# mailq
# qshape deferred	# show deferred mails
# mailq -q		# attempt to deliver all queued mail!
# postsuper -d ALL	# delete all (or specific) queued mails from mailq
# postcat -q queue_id	# show contents of mail queued with queue_id

👉 https://www.lukehebert.com/2014/05/17/postfix-message-flows-and-common-issues/

👉 https://www.lukehebert.com/2014/05/04/postfix-command-reference/

👉 http://www.postfix.org/QSHAPE_README.html

Final contents of /etc/postfix/main.cf

The order of lines may be different:

smtpd_banner = mail.mydomain.com ESMTP
biff = no
append_dot_mydomain = no
readme_directory = no
compatibility_level = 3.6
smtpd_tls_cert_file = /etc/letsencrypt/live/mydomain.com/fullchain.pem
smtpd_tls_key_file = /etc/letsencrypt/live/mydomain.com/privkey.pem
smtpd_use_tls=yes
smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache
smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache
smtpd_relay_restrictions = permit_mynetworks,permit_sasl_authenticated,defer_unauth_destination
myhostname = mysrv.mydomain.com
alias_maps = hash:/etc/aliases
alias_database = hash:/etc/aliases
myorigin = /etc/mailname
mydestination = mysrv.mydomain.com mydomain.com localhost.localdomain, localhost
relayhost =
mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128
mailbox_size_limit = 0
recipient_delimiter = +
inet_interfaces = all
inet_protocols = all
smtpd_recipient_restrictions = permit_sasl_authenticated,permit_mynetworks,reject_unauth_destination,
	check_client_access hash:/etc/postfix/rbl_override,
	reject_rbl_client zen.spamhaus.org,
	reject_rhsbl_reverse_client dbl.spamhaus.org,
	reject_rhsbl_helo dbl.spamhaus.org,
	reject_rhsbl_sender dbl.spamhaus.org,
	check_policy_service unix:private/policyd-spf
smtp_tls_security_level = may
smtpd_tls_security_level = may
smtp_tls_note_starttls_offer = yes
smtpd_tls_loglevel = 1
smtpd_tls_received_header = yes
home_mailbox = Maildir/
virtual_mailbox_domains = /etc/postfix/vhosts
virtual_mailbox_base = /home/vmail
virtual_mailbox_maps = hash:/etc/postfix/vmaps
virtual_minimum_uid = 1000
virtual_uid_maps = static:5000
virtual_gid_maps = static:5000
virtual_alias_maps = hash:/etc/postfix/valiases
smtpd_sasl_type = dovecot
smtpd_sasl_path = private/auth
smtpd_sasl_local_domain =
smtpd_sasl_security_options = noanonymous
broken_sasl_auth_clients = yes
smtpd_sasl_auth_enable = yes
smtp_helo_name = mail.mydomain.com
disable_vrfy_command = yes
smtpd_sender_restrictions = reject_unknown_sender_domain
smtpd_data_restrictions = reject_unauth_pipelining
anvil_rate_time_unit = 600
anvil_status_update_time = 3600
policyd-spf_time_limit = 3600
milter_default_action = accept
milter_protocol = 2
smtpd_milters = local:/opendkim/opendkim.sock
non_smtpd_milters = local:/opendkim/opendkim.sock

Checking Once More Everything

Step by step check:

👉 https://www.linuxbabe.com/mail-server/setup-basic-postfix-mail-sever-ubuntu

Test your sending email configuration using:

👉 https://www.mail-tester.com/

DMARC:

👉 https://dmarcguide.globalcyberalliance.org/

👉 https://www.immuniweb.com/ssl/