Postfix - Mail Transfer Agent¶
Postfix is a free and open-source mail transfer agent that routes and delivers electronic mail.
Install postfix¶
Now we can install the postfix packages.
apt install postfix postfix-mysql sasl2-bin
You will have to answer two question about the type of mail and the name of your mail server. Make sure to replace the hostname and domain values with yours
- the type of mail configuration: Internet Site
- the system mail name: hostname.domain.com
Make sure that sasl run at the startup by editing its configuration file(/etc/default/saslauthd)
# Should saslauthd run automatically on startup? (default: no) START=yes
Now restart the service
# systemctl restart saslauthd
As we are configuring a mail server with virtual users, we need an owner of all mailboxes so will create a system user which will be used by all virtual users to access email on the server. First, create the group owner and the folder which will store the mailboxes.
# groupadd -g 5000 vmail && mkdir -p /var/mail/vmail
Now create the owner
# useradd -u 5000 vmail -g vmail -s /usr/sbin/nologin -d /var/mail/vmail
Make sure to give the permission of the mail directory to the owner so that it can store the mails into the appropriate directories.
# chown -R vmail:vmail /var/mail/vmail
If you don’t do this, dovecot will not be able to create the required folders to store the emails.
Create the configuration files for the database¶
Now create a folder which will contain some database files
# mkdir -p /etc/postfix/sql
Postfix need 03 database files which will allow it to access the database that we created earlier:
Domains to contain the list of domain names hosted on the server. it will allow postfix to determine if our server is in charge of a domain (mytuto.com) when it receives an email (user@mytuto.com) on it. If it’s the case, it will mean that the domain is in our database.
# vim /etc/postfix/sql/mysql_virtual_domains_maps.cf user = postfix password = postfix-db-password hosts = 127.0.0.1 dbname = postfix query = SELECT domain FROM domain WHERE domain='%s' AND active = '1'
We will enable the configuration and add it automatically to the /etc/postfix/main.cf file and reload the postfix configuration to avoid having to do it manually. So the file will be updated everytime you use this command with new values.
# postconf -e virtual_mailbox_domains=mysql:/etc/postfix/sql/mysql_virtual_domains_maps.cf
Now we can check the configuration. We will run a command that will execute the query contained in the file in order to search for a domain in our database. An element (the searched domain) must be returned or nothing if the domain is not present.
# postmap -q mytuto.com mysql:/etc/postfix/sql/mysql_virtual_domains_maps.cf mytuto.com
As you can see, postfix is able to retrieve the domains stored in our database
Mailbox to store all the virtual email addresses. It will be used to verify also if the mailboxes exist
# vim /etc/postfix/sql/mysql_virtual_mailbox_maps.cf user = postfix password = postfix-db-password hosts = 127.0.0.1 dbname = postfix query = SELECT maildir FROM mailbox WHERE username='%s' AND active = '1'
Now let’s update the configuration file
# postconf -e virtual_mailbox_maps=mysql:/etc/postfix/sql/mysql_virtual_mailbox_maps.cf
Run the command to test the query on the database
# postmap -q alain@mytuto.com mysql:/etc/postfix/sql/mysql_virtual_mailbox_maps.cf mytuto.com/alain/
Alias to contain the different email aliases.
# vim /etc/postfix/sql/mysql_virtual_alias_maps.cf user = postfix password = postfix-db-password hosts = 127.0.0.1 dbname = postfix query = SELECT goto FROM alias WHERE address='%s' AND active = '1'
Now add the configuration
# postconf -e virtual_alias_maps=mysql:/etc/postfix/sql/mysql_virtual_alias_maps.cf
Now run the command to test the query. It is the destination user (alain@mytuto.com) that should be displayed and not the abuse address. It shows that postfix can do the matching.
# postmap -q abuse@mytuto.com mysql:/etc/postfix/sql/mysql_virtual_alias_maps.cf alain@mytuto.com
Make sure that those files are not readable by the normal users because the passwords are stored in clear. In order for postfix to read those file, we can change the group owner to postfix
# chgrp postfix /etc/postfix/sql/mysql_*.cf
Configure postfix¶
Now we will manually edit the postfix main configuration file. So, make a copy before editing.
# cp /etc/postfix/main.cf /etc/postfix/main.cf.bak
Now we will activate SASL to force authentication for sending emails and hand off authentication to Dovecot. Be sure to add lines below
# vim /etc/postfix/main.cf # -------------------------------------- myhostname = mail.mytuto.com mydomain = mytuto.com alias_maps = hash:/etc/aliases alias_database = hash:/etc/aliases myorigin = /etc/mailname virtual_alias_domains = mail.mytuto.com mydestination = $myhostname, mail.mytuto.com, ip-172-30-1-40, localhost.localdomain, localhost 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 = ipv4 # -------------------------------------- virtual_mailbox_domains = mysql:/etc/postfix/sql/mysql_virtual_domains_maps.cf virtual_mailbox_maps = mysql:/etc/postfix/sql/mysql_virtual_mailbox_maps.cf virtual_alias_maps = mysql:/etc/postfix/sql/mysql_virtual_alias_maps.cf # -------------------------------------- ## Path to the Postfix auth socket smtpd_sasl_path = private/auth smtp_sasl_path = private/auth # -------------------------------------- ## Tells Postfix to let people send email if they've authenticated to the server. ## Otherwise they can only send if they're logged in (SSH) smtpd_sasl_auth_enable = yes smtpd_sasl_security_options = noanonymous smtp_sasl_security_options = noanonymous smtpd_sasl_local_domain = $myhostname # -------------------------------------- # TLS parameters smtpd_use_tls=yes smtp_use_tls = yes smtpd_tls_security_level = may smtpd_tls_auth_only = yes smtp_tls_security_level = may smtpd_tls_cert_file=/etc/letsencrypt/live/mail.mytuto.com/fullchain.pem smtpd_tls_key_file=/etc/letsencrypt/live/mail.mytuto.com/privkey.pem smtp_tls_cert_file=/etc/letsencrypt/live/mail.mytuto.com/fullchain.pem smtp_tls_key_file=/etc/letsencrypt/live/mail.mytuto.com/privkey.pem smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache smtpd_sender_restrictions = permit_sasl_authenticated smtpd_recipient_restrictions = check_recipient_access hash:/etc/postfix/custom_replies
Now let’s edit the /etc/postfix/master.cf configuration file. It’s the process configuration file. We will enable secure SMTP ports by adding or uncomment the lines below and make a copy before.
# cp /etc/postfix/master.cf /etc/postfix/master.cf.bak
# vim /etc/postfix/master.cf submission inet n - y - - smtpd -o syslog_name=postfix/submission -o smtpd_tls_security_level=encrypt -o smtpd_tls_ask_ccert=yes -o smtpd_sasl_auth_enable=yes -o smtpd_reject_unlisted_recipient=no -o smtpd_client_restrictions=permit_sasl_authenticated,reject -o smtpd_recipient_restrictions=permit_sasl_authenticated,reject -o milter_macro_daemon_name=ORIGINATING smtps inet n - y - - smtpd -o syslog_name=postfix/smtps -o smtpd_tls_wrappermode=yes -o smtpd_sasl_auth_enable=yes -o smtpd_client_restrictions=permit_sasl_authenticated,reject -o milter_macro_daemon_name=ORIGINATING
Now you can run the postconf -n command to check some errors.
# postconf -n alias_database = hash:/etc/aliases alias_maps = hash:/etc/aliases ... ...
To Remove Originate IP , hostname and Mailer information for security. Add the below content in /etc/postfix/header_checks file.Then you need to inegrate into postfix.
/^Received:.*with ESMTPSA/ IGNORE /^X-Originating-IP:/ IGNORE /^X-Mailer:/ IGNORE /^Mime-Version:/ IGNORE
And add into /etc/postfix/main.cf like mentioned below.
header_checks = regexp:/etc/postfix/header_checks mime_header_checks = regexp:/etc/postfix/header_checks
Execute postmap to generate database which can able to read by postfix.
#postmap /etc/postfix/header_checks
If you have no warning messages, it means that your files do not contain errors. Now you can restart the postfix service.
# systemctl restart postfix # systemctl status postfix * postfix.service - Postfix Mail Transport Agent Loaded: loaded (/lib/systemd/system/postfix.service; enabled; vendor preset: enabled) Active: active (exited) since Wed 2018-09-22 10:16:02 UTC; 27s ago Process: 12225 ExecStart=/bin/true (code=exited, status=0/SUCCESS) Main PID: 12225 (code=exited, status=0/SUCCESS)