Postfix

From Wildsong
Jump to navigationJump to search

Postfix is my preferred SMTP server. Dovecot is my preferred IMAP server.

2023-02-19 I copied content here from the Leaving Google page. I am rewriting . updating the old content here.

Quick tips

Checking the postfix queue

mailq

Monitoring and graphing

I want to know how my server is doing, so I am going to try Prometheus.

https://gitlab.com/anarcat/grafana-dashboards

https://grafana.com/grafana/dashboards/10013-postfix/

SMTP server: Postfix

Install Postfix

Starting with a VPS at Tektonic that runs a basic Debian image. Out goes Exim4, in with Postfix. I tried putting Postfix in a Docker and failed. Maybe later.

apt remove exim4-base exim4-config exim4-daemon-light 
apt install postfix postgrey clamav spamassassin

You have to configure in /etc/postfix especially main.cf before starting it.

Set up DNS

You need to make sure that the SPF, DKIM, DMARC and MX records are set up correctly in DNS (Cloudflare). Read this Google doc to learn more.

MX: Set DNS records

The MX record(s) tell a mail server where to direct mail, for example, I want wildsong.biz mail to be handled by my VPS so I set it to tell mail senders that mail for wildsong.biz should be sent to w6gkd.w6gkd.radio. Note there is also a reverse entry that has to be set up by the service provider for the VPS (Tektonic.net in my case) so that the sender can check to make sure the IP address points to the same place as the DNS name.

Currently there are about 6 MX records for wildsong.biz and they all point at various Google servers. When I am done there will be just one and it will point at w6gkd.w6gkd.radio.

SPF

Should be a TXT record for the domain (e.g. wildsong.biz) set to v=spf1 ip4:108.161.129.155 ip6:fe80::216:3eff:fea2:8358 -all

Google also made me add another TXT similar to "google-site-verification=-Y...."

DMARC

Should be a TXT record for "_dmarc" similar to this

v=DMARC1; p=quarantine; rua=mailto:[email protected]

DKIM

How does DKIM work? https://mailtrap.io/blog/dkim/

OpenDKIM runs as a service on my VPS. It listens on port 12301.There is a config file, /etc/opendkim.conf.

You can check /var/log/mail.log for messages to see it's working. I sent a message, and Google called back to make sure I am legit.

Jan 29 03:31:51 w6gkd opendkim[729097]: A8F6485D: mail-qk1-f201.google.com [209.85.222.201] not internal
Jan 29 03:31:51 w6gkd opendkim[729097]: A8F6485D: not authenticated
Jan 29 03:31:52 w6gkd opendkim[729097]: A8F6485D: DKIM verification successful
Jan 29 03:31:52 w6gkd opendkim[729097]: A8F6485D: s=20210112 d=google.com a=rsa-sha256 SSL

Install and configure OpenDKIM
apt install opendkim opendkim-tools

Help with Postfix: https://www.digitalocean.com/community/tutorials/how-to-install-and-configure-dkim-with-postfix-on-debian-wheezy

I have to make keys for each domain supported. Currently that's hupi.org, map46.com, wildsong.biz, and w6gkd.radio

Keys go in /etc/opendkim/keys/ and there needs to be an entry for each domain in /etc/opendkim/KeyTable and SigningTable

Generate keys for each domain,

cd /etc/opendkim/keys/
mkdir wildsong.biz
cd wildsong.biz
opendkim-genkey -s mail -d wildsong.biz
chown opendkim:opendkim mail.private

The file "mail.txt" contains the text to put in the DNS DKIM record for mail._domainkey

Remember to restart opendkim and postfix.

Test it by sending mail to [/cdn-cgi/l/email-protection [email protected]] and also by sending mail to a gmail.com address and checking the "original message".

I installed postfixadmin for web access and administration.

dbconfig-common: writing config to /etc/dbconfig-common/postfixadmin.conf

Creating config file /etc/dbconfig-common/postfixadmin.conf with new version 

Creating config file /etc/postfixadmin/dbconfig.inc.php with new version
granting access to database postfixadmin for [/cdn-cgi/l/email-protection [email protected]]: success.
verifying access for [/cdn-cgi/l/email-protection [email protected]]: success.


The user that owns the top level mail folders is vmailbox. There are UID's assigned own the individual folders, starting at 20001. See the 'users' table below. Actual mail folders are here, organized by virtual host domain name:

/var/mail/vhosts/domainname

Postfix config files

I need to update this. I currently run my own server, not a forwarder.

This is a config that uses Google aka gmail as a smarthost for outbound mail. This config also supports virtual mailboxes via postgresql.

main.cf

smtpd_banner = $myhostname ESMTP $mail_name (AlseaGeOS)
biff = no

# Uncomment the next line to generate "delayed mail" warnings
delay_warning_time = 4h

queue_directory = /var/spool/postfix

myorigin = alseageo.net

# ---------------------------------------------------------

relayhost = [smtp.gmail.com]:587

disable_dns_lookups = yes

# authentication via SASL
# incoming connections
smtpd_sasl_auth_enable = no
smtpd_sasl_local_domain = $myhostname

# outgoing connections
smtp_sasl_auth_enable = yes
smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd
smtp_sasl_security_options = noanonymous
smtp_sasl_tls_security_options = noanonymous

# tls 
smtp_tls_loglevel = 1

#smtp_enforce_tls = yes
smtp_tls_per_site = hash:/etc/postfix/tls_per_site

smtp_tls_enforce_peername = no

smtp_tls_CAfile = /etc/postfix/certs/cakey.pem
smtp_tls_cert_file=/etc/postfix/certs/alseageo.pem
smtp_tls_key_file=/etc/postfix/certs/alseageo.key
smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache
smtp_use_tls = yes

smtpd_tls_CAfile = /etc/postfix/certs/cacert.pem
smtpd_tls_cert_file=/etc/postfix/certs/alseageo.pem
smtpd_tls_key_file=/etc/postfix/certs/alseageo.key
smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache
smtpd_use_tls = yes

#-------------------------------------------                                    
# Virtual mail support                                                          
#                                                                               
virtual_mailbox_base = /var/mail/vhosts
virtual_minimum_uid = 20000
#                                                                               
# Old file version                                                              
#transport_maps = hash:/etc/postfix/transport
#virtual_uid_maps = static:20000
#virtual_gid_maps = static:20000
#virtual_mailbox_domains = dispatch.incidentview.com
#virtual_mailbox_maps = hash:/etc/postfix/vmailbox
#virtual_alias_maps = hash:/etc/postfix/virtual
#                                                                               
# New SQL version                                                               
transport_maps = pgsql:/etc/postfix/transport.cf
virtual_uid_maps = pgsql:/etc/postfix/uid.cf
virtual_gid_maps = pgsql:/etc/postfix/gid.cf
virtual_mailbox_domains = pgsql:dispatch.incidentview.com
virtual_mailbox_maps = pgsql:/etc/postfix/mailbox.cf
virtual_maps = pgsql:/etc/postfix/virtual.cf


# ---------------------------------------------------------

command_directory = /usr/sbin
daemon_directory = /usr/lib/postfix

mail_owner = postfix

myhostname = kilchis.alseageo.com
mydomain = alseageo.com

inet_interfaces = all

# This is to allow the /etc/aliases file to have an effect.    
mydestination =
        kilchis.alseageo.com kilchis
        roaring.alseageo.com roaring
        minam.alseageo.com minam
        white.alseageo.com white
        dev.alseageo.com dev
        fall.alseageo.com fall
        localhost localhost.localdomain kilchis.localdomain

mailbox_size_limit = 0
recipient_delimiter = +
inet_interfaces = all

mail_spool_directory=/var/spool/mail

mynetworks = 127.0.0.0/8 10.1.10.0/24 10.8.0.0/24
alias_maps = hash:/etc/aliases
alias_database = hash:/etc/aliases

aliases.cf

user=mailreader
password=<secret>
dbname=mail
hosts=localhost
query=SELECT forw_addr FROM aliases WHERE alias='%s'

transport.cf

user=mailreader
password=<secret>
dbname=mail
hosts=localhost
query=SELECT transport FROM transport WHERE domain='%s'

mailbox.cf

user=mailreader
password=secret
dbname=mail
hosts=localhost
query=SELECT mailbox FROM postfix_mailboxes WHERE userid='%s'

uid.cf

user=mailreader
password=<secret>
dbname=mail
hosts=localhost
query=SELECT uid FROM users WHERE userid='%s'

gid.cf

user=mailreader
password=<secret>
dbname=mail
hosts=localhost
query=SELECT gid FROM users WHERE userid='%s'

virtual.cf

user=mailreader
password=secret
dbname=mail
hosts=localhost
query=SELECT userid FROM postfix_virtual WHERE address='%s'

virtual-domains.cf

user=mailreader
password=secret
dbname=mail
hosts=localhost
query=SELECT domain FROM virtual_domains WHERE domain='%s'

Testing Postfix

To send mail on the host, I want the address to have the domain not the hostname,

date | mail bwilson

should go to [/cdn-cgi/l/email-protection [email protected]] not [/cdn-cgi/l/email-protection [email protected]]

This is controlled by "mail" NOT postfix. So put this in /etc/mailutils.conf

address {
   email-domain w6gkd.radio;
}
  1. Can I send from w6gkd.radio?
  2. Can I send to [/cdn-cgi/l/email-protection [email protected]]?
  3. Are the letsencrypt keys working?

/etc/cron.weekly runs /usr/local/sbin/renew_certs.sh

See /etc/letsencrypt/live to see what is set up

Additional Postfix configuration: Filters

2023-02 I will be working on these soon but I did not let them impede leaving Google.

2023-07-31 Postgrey operational-- https://postgrey.schweikert.ch/ -- works by delaying connections.

2023-08-01 I enabled a DNSBL block list because it was so easy. See https://docs.iredmail.org/enable.dnsbl.html

Postgrey: whitelisting / greylisting / blacklisting

I installed it from "apt". To enable it I created postfix/main.cf.POSTGREY and main.cf.NOPOSTGREY. I changed master.cf to remove the smtpd_recipient_restrictions and moved them to the main.cf files. I used files in /usr/share/postgrey to create the files in /etc/postgrey to give it whitelists for common servers.

In postgrey its possible to whitelist senders as well as recipients. All that needs doing in order to whitelist a host is to add its fully qualified domain name or its ip address to the /etc/postfix/postgrey_whitelist_clients.local file. eg:

192.168.1.10
mydesktop.office.mydomain.com

IMAP server: Dovecot

I made a valiant effort at installing Dovecot into a Docker container. I failed. It's installed in the host.

I wonder if it might be better to install it at home and just keep the SMTP agent on the VPS.

Install Dovecot

Currently I have installed Dovecot from apt. Specifically "dovecot-core" and "dovecot-imapd". I am only using files (well, postfix maps) for auth and mail delivery. No fancy SQL mailboxes right now, it's only me here, that would be massive overkill.

I am migrating it to a Docker container soon.

Test Dovecot

Dovecot is the IMAP server so it has to work alongside Postfix. http://wiki2.dovecot.org/TestInstallation

Resources

The Book of Postfix at Percipio