Postfix Virtual Hosts- FreeBSD
Over the last few weeks I have been consolidating some mail servers that I look after onto one systetm. I had been using Sendmail and Postfix but have decided on setting them all up under Postfix using Virtual Domain Hosting. Virtual Domain Hosting works in effect like Virtual Hosts in NGINX but then again not the same. In many ways it is less complicated and if you choose, you do not even have to issue TLS certificates for each domain, as TLS can be authenicated from the main mailhost.
So, over the next few weeks, I am going to post about the notes on configuration that I have taken. These are not thorough guides but I hope, if you have similar needs, it can be a quick jump start to get you up and running. FreeBSD and Postfix has excellent documentation and this should be your main reference to accompany this post.
So without further ado, let's get started...
- Install Postfix
- Cyrus SASL Authentication
- Postfix Virtual Domains Configuration
- Testing Cyrus SASL Authentication
- Postfix TLS Configuration
- Postfix Submission Configuration
- Bits That Are Really Important That I Didn't Cover
The best place to start is at the beginning, so that means it's time to install Postfix.
1# pkg install postfix-sasl
Now that wasn't too difficult. Now on with a little bit of housekeeping to make sure Postfix is the default mail server under FreeBSD.
First start by adding the initial directives to
1# sysrc postfix_enable="YES" 2# sysrc sendmail_enable="NONE"
Next, we have to setup the
1# mkdir -p /usr/local/etc/mail 2# install -m 0644 /usr/local/share/postfix/mailer.conf.postfix /usr/local/etc/mail/mailer.conf
And we should disable the jobs the system would normally run in regards to Sendmail in the
1# cat /etc/periodic.conf 2daily_clean_hoststat_enable="NO" 3daily_status_mail_rejects_enable="NO" 4daily_status_include_submit_mailq="NO" 5daily_submit_queuerun="NO"
If it is not too much trouble, it would be good to reboot the system right about now to make sure all these changes will take effect.
Now we are back up and running again, I would like to mention one precaution to take before starting in on any serious changes to the Postfix configuration files.
It is advisable to set
set_bounce = yes as this parameter provides a limited safety net for testing. When
soft_bounce is enabled, mail will remain queued that would otherwise bounce. This parameter disables locally-generated bounces, and prevents the SMTP server from rejecting mail permanently.
The following can be appended to
1# -------------------------------- 2# TEMPORARY TEST SETTINGS 3# -------------------------------- 4# 5soft_bounce = yes
In fact, all the settings made to
/usr/local/etc/postfix/main.cf will be made by appending to the file rather than editing the directeves set in the file.
Don't restart Postfix just yet as we will be making more changes to the
main.cf file in the next section.
Cyrus SASL Authentication
Before jumpng into setting up Virtual Domains for Postfix, I will take care of making sure SASL Authentication is configured for Postfix. Later we will test this Authentication, but not just yet.
The configuration of SASL is satisfied with making the following additions to
1# -------------------------------- 2# SASL CONFIGURATION 3# -------------------------------- 4# 5smtpd_sasl_auth_enable = yes 6smtpd_sasl_type = cyrus 7smtpd_sasl_path = smtpd
smtpd_sasl_path directive references the
/usr/local/lib/sasl2/smtpd.conf file. This needs to be created, and should contain the following:
1pwcheck_method: auxprop 2auxprop_plugin: sasldb 3mech_list: PLAIN LOGIN DIGEST-MD5
OK, that is enough appending to the
main.cf file for now, but we will be back soon, so there is no need to restart Postfix just yet.
Let's Add Some Users to the Cyrus SASL Database
1# saslpasswd2 email@example.com 2# saslpasswd2 firstname.lastname@example.org 3# saslpasswd2 email@example.com
Though lacking in creativity, the above takes care of creating our user accounts for multiple domains under Cyrus SASL.
Postfix Virtual Domains Configuration
Ladies & Gentleman, the part we have all been waiting for, this is the main configuration for allowing Virtual Hosts under Posfix.
You guessed it, the following can be appended to
1# -------------------------------- 2# VIRTUAL DOMAINS CONFIGURATION 3# -------------------------------- 4# 5# This is set in anticipation of having a working cyrus imap server running in cahoots 6# with Postfix. For now, mail delivery will not work but that will be resolved in my i 7# next post on setting up virtual hosts under Cyrus Imapd. 8# 9mailbox_transport = lmtp:unix:/var/imap/socket/lmtp 10 11# A list of domains that Postfix will accept mail for. 12# 13virtual_mailbox_domains = example-1.net 14 example-2.net 15 example-3.net 16 17# This is the spool directory for our hosts that we added immeadiately above. 18# 19virtual_mailbox_base = /var/mail/vhosts 20 21# this is a file that contains a list of mailboxes that Postfix will deliver to. 22# When we create this file shortly, this directive will become more apparent. 23# 24virtual_mailbox_maps = hash:/usr/local/etc/postfix/vmailbox 25 26# Optional lookup tables that alias specific mail addresses or domains to other 27# local or remote address. For now, this file needs to be created but will be left 28# empty as I will no be configuring such intricate features in this post. 29# 30virtual_alias_maps = hash:/usr/local/etc/postfix/virtual 31 32# stuff that needs to be here so Postfix works =) 33# Consult http://www.postfix.org/postconf.5.htm for more detail 34# 35virtual_minimum_uid = 100 36virtual_uid_maps = static:125 37virtual_gid_maps = static:125 38 39# The maximal size in bytes of an individual virtual(8) mailbox or maildir file, 40# or zero (no limit). 41# 42virtual_mailbox_limit = 1000000000 43 44# The default mail delivery transport and next-hop destination for final delivery 45# to domains listed with $virtual_mailbox_domains. This points to the Cyrus transport 46# that was set earlier. 47# 48virtual_transport=$mailbox_transport
While I have made some inline comments, it is strongly advised to reference the Postfix VIRTUAL_README document to get a full understanding of these directives.
With Virtual Host configuration now entered, we must create databases that Postfix can read from the
virtual_alias_maps directives that were created.
This is done by creating these files and using the
postmap command to create the databases, as follows:
/usr/local/etc/postfix/vmailbox file should be as such for the purposes I am demonstrating:
firstname.lastname@example.org example-1.net/pbd/ email@example.com example-2.net/pbd/ firstname.lastname@example.org example-3.net/pbd/
This is a list of each user that we created with the
/usr/local/etc/postfix/virtual will be an empty file in this instance.
postmap will create the databases as previously mentioned:
1# postmap /usr/local/etc/postfix/vmailbox 2# postmap /usr/local/etc/postfix/virtual
So far, so good! Everything is setup for Postfix and Virtual hosts. We are just missing TLSconfiguration but we will return to this shortly. First we will test the Cyrus SASL Authentication.
... so now is the time to issue a restart for Postfix.
1# service postfix restart
Testing Cyrus SASL Authentication
base64 encoding so we have to generate our username and password in base64 so we can use in a telnet session to the mail server.
I will be telneting to localhost to avoid sending these passwords over the internet, however, you should renew these passwords after testing, just to keep a sufficient level or paranoia.
On a fresh install of FreeBSD, the program
base64 is not available so can be installed as follows:
1# pkg install base64
Generate Base 64 Credentials
I have used the same feeble password for all email accounts. Please, don't do this.
1# echo -n 'email@example.com' |base64 2cGJkQGV4YW1wbGUtMS5uZXQ= 3# echo -n 'firstname.lastname@example.org' | base64 4cGJkQGV4YW1wbGUtMi5uZXQ= 5# echo -n 'email@example.com' | base64 6cGJkQGV4YW1wbGUtMy5uZXQ= 7# echo -n 'password-lol' | base64 8cGFzc3dvcmQtbG9s
Test Cyrus SASL with base64 credentials
1root@freebsd13:~ # telnet localhost 25 2Trying 127.0.0.1... 3Connected to localhost. 4Escape character is '^]'. 5220 freebsd13.localdomain ESMTP Postfix 6AUTH LOGIN cGJkQGV4YW1wbGUtMS5uZXQ= < AUTH LOGIN + base64 encoded login 7334 UGFzc3dvcmQ6 8cGFzc3dvcmQtbG9s < Password base64 encoded 9235 2.7.0 Authentication successful 10quit < Quit 11221 2.0.0 Bye 12Connection closed by foreign host.
Actual input entered has been denoted on the same line with < and a comment.
If you do not recieve a
Authentication successful reply, you need to go back through this post and make sure that you can authenticate before moving on.
Postfix TLS Configuration
Postfix requires a TLS certificate for the server, and virtual domains it hosts. It is sufficient to issue one certificate for the hostname and then Subject Alternate Names for the virtual hosts.
I am not going to go into creating certificates in this post, but in this day and age, there is no reason to still be using self signed certificates, on public facing services, when you have Let's Encrypt Certificates available to all and for free.
Create bundle pem ceritficate for Postfix
Once we have our certificates, we need to bundle the fullchain and private key into a single file for Postfix to use:
1# cp /etc/pki/tls/private/mail.key /etc/pki/tls/private/mail.bundle.pem 2# cat /etc/pki/tls/certs/letsencrypt-fullchain.pem >> /etc/pki/tls/private/mail.bundle.pem
This will be stored in a location where Postfix has access and necessary permissions to use this file. The one thing I will mention is that this bundle contains the private key so protect it as you would your private key.
Settings for the SMTP Server & Client
One thing to keep in mind when configuring TLS for Postfix is that:
- smtp is the client: ie, when your server connects to another mail server
- smtpd is the server: ie, when a remote server connects to your mail server
Submission is not yet covered in this section, this will be covered later when we edit the
There is a lot going on here so make sure that you understand what the directives mean. You can get in a whole lot of trouble with an unprotected mail server.
The Postfix TLS_README document is what you should be consulting to help understand the following settings. Another excellent resource is: bettercrypto.org. Also a neat tool is the Mozilla SSL Configuration Generator.
Onwards! We can now append TLS settings to
1# -------------------------------- 2# TLS CERTIFICATE CONFIGURATION 3# -------------------------------- 4 5# postfix tls enable-client 6smtp_tls_security_level = must 7smtp_tls_loglevel = 1 8smtp_tls_session_cache_database = btree:/var/db/postfix/smtp_scache 9tls_random_source = dev:/dev/urandom 10 11# disable sslv2 ,sslv3, tlsv1, tlsv1.1 in smtp --> smtpd connections 12smtp_tls_mandatory_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1 13smtp_tls_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1 14 15# enforce strong ciphers for smtp --> smtpd connections 16smtp_tls_mandatory_ciphers = high 17 18# postfix tls enable-server 19smtpd_tls_security_level = must 20smtpd_tls_loglevel = 1 21smtpd_tls_received_header = yes 22 23# disable sslv2, sslv3, tlsv1, tlsv1.1 in smtpd <-- smtp connections 24smtpd_tls_mandatory_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1 25smtpd_tls_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1 26 27# enforce strong ciphers for smtpd <-- smtp connections 28smtpd_tls_mandatory_ciphers = high 29 30# tls certs and keys 31smtpd_tls_chain_files = /etc/pki/tls/private/mail.bundle.pem 32 33# cipher list and settings 34tls_high_cipherlist = EDH+aRSA+AES256:EECDH+aRSA+AES256:!SSLv3 35tls_preempt_cipherlist = yes 36 37# Enable EECDH key exchange for Forward Security 38smtpd_tls_eecdh_grade = ultra 39 40# TLS Options 41tls_ssl_options = NO_COMPRESSION
NOTE: I have used
smtp_tls_security_level = must&
smtpd_tls_security_level = mustwhich is technically against the standard recommendations, however, all reputable e-mail sites will support encryption, and anyone sending in plain is probably a spammer.
Postfix Submission Configuration
IETF has changed its tune on whether submission should be made as STARTTLS or Implicit TLS. From January 2018, the IETF reccommends in RFC8314 submission should be made as Implicit TLS. I will implement Implicit TLS as follows:
This time we need to edit the file related to SMTPS Submissions. It is simply uncommenting the following lines that are displayed below in the
1... 2... 3smtps inet n - n - - smtpd 4 -o syslog_name=postfix/smtps 5 -o smtpd_tls_wrappermode=yes 6 -o smtpd_sasl_auth_enable=yes 7... 8...
Now is a good time to restart Postfix so the changes above will be in full effect.
That's it! All the postfix configuration is done, but we do not have a complete mail sytem as yet. We still need to configure Cyrus IMAPD to recieve the mail that has been sent to us. I will cover this in my next post.
BITS THAT ARE REALLY IMPORTANT THAT I DIDN'T COVER
DNS: We are not going to recieve any mail if we do not have an MX record that points to the mail server. I leave this to you to configure on which ever DNS System that you use. If you want a primer on ISC-Bind, it is available in the 9.3-RELEASE Handbook handbook. ISC-Bind has not been part of the base install since the 9.3-RELEASE and this documnetation has been now been removed from the current handbook.
File Permissions: This is very important and must be done in order to get a working Mail server. You want to make the least privledge permissions possible whilst allowing the mail server to operate. Again I leave this to the reader to make sure that these settings are suffiecient.
SPAM Prevention: Very soon I will make a couple of posts outlining what can be done to prevent spam. This will cover directives that can be set in the
main.cf, Postfix tools such as
postscreenand external tools such as using Spamassassin with a Milter.
To continue virtual hosting with Postfix, click here to setup Cyrus IMAPD.
Until next time...