Fedora 7 Postfix Smart-hosting with SASL and MySQL
Contents |
Introduction
The following is a tutorial that explains how to install and configure Postfix on Fedora 7. Specifically, Postfix will be configured to use virtual users, domains and aliases. In addition the server will be configured to forward all mail through a smart host using SASL authorization.
The content of this tutorial has been compiled from a number of sources and will likely need to be further refined as others attempt to follow these steps. I give credit to the following tutorial for most of the information consolidated in this tutorial.
How to set up a mail server on a GNU / Linux system
This tutorial assumes you have already installed MySQL along with a number of other dependent packages. If you are prompted that certain libraries must be installed to continue use yum to install the appropriate packages.
Install Postfix with SASL and MySQL Support
Remove Previous Installation
The first step is to obtain and install the Postfix mail transfer agent. Postfix must be built with both MySQL and SASL and at this time I have not been able to locate a binary RPM that already has been compiled with this support enabled. As a result I chose to download and build the RPM myself.
Before performing the following steps make sure Postfix is not currently installed on your system. This can be done by opening your terminal and typing the following commands:
yum remove postfix
This will give an error if you do not have it installed, and you may proceed. If it is installed yum will remove it and you may proceed.
Begin Installation
Change location to standard location for source rpms.
cd /usr/src
Download and extract source files.
wget http://ftp.wl0.org/official/2.4/SRPMS/postfix-2.4.6-1.src.rpm rpm -ivh postfix-2.4.6-1.src.rpm
Note: You may get a bunch of sjmudd errors, but these are fine.
Configure the build to include MySQL, SASL, and optional quota support.
cd /usr/src/redhat/SOURCES export POSTFIX_MYSQL_REDHAT=1 export POSTFIX_SASL=2 # optional quota support export VDA=1 chmod 744 make-postfix.spec ./make-postfix.spec
Build binary RPM. This may take some time, go take a break, you deserve it. (You may need to install mysql-devel, type yum install mysql-devel)
cd /usr/src/redhat/SPECS rpmbuild -ba postfix.spec
Install the built RPM.
cd /usr/src/redhat/RPMS/i386 rpm -ivh postfix-2.4.6-1.mysql.sasl2.fc7.i386.rpm
Configure the system for virtual hosting.
cp /etc/aliases /etc/postfix/aliases postalias /etc/postfix/aliases # to add if there is not a virtual user mkdir /var/spool/mail/virtual groupadd virtual -g 5000 useradd virtual -u 5000 -g 5000 chown -R virtual:virtual /var/spool/mail/virtual # to modify if a virtual user is already set groupmod -g 5000 virtual usermod -g virtual -u 5000 virtual chown -R virtual:virtual /var/spool/mail/virtual
Set up MySQL for Virtual and Smart Hosting
This tutorial assumes you are familar with how to manage MySQL. Refer to other tutorials if you need instruction on how to execute the following actions:
1. Add a new database entitled maildb.
2. Add the following tables to the database using the following SQL commands
Create table `aliases`
CREATE TABLE `aliases` ( `pkid` smallint(3) NOT NULL auto_increment, `mail` varchar(120) NOT NULL, `destination` varchar(120) NOT NULL, `enabled` tinyint(1) NOT NULL default '1', PRIMARY KEY (`pkid`), UNIQUE KEY `mail` (`mail`) ) ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
Create table `domains`
CREATE TABLE `domains` ( `pkid` smallint(6) NOT NULL auto_increment, `domain` varchar(120) NOT NULL, `transport` varchar(120) NOT NULL default 'virtual:', PRIMARY KEY (`pkid`) ) ;
Create table `smtp_auth`
CREATE TABLE `smtp_auth` ( `sasl_server` varchar(128) NOT NULL, `password` varchar(128) NOT NULL, PRIMARY KEY (`sasl_server`) ) ;
Create table `users`
CREATE TABLE `users` ( `id` varchar(128) NOT NULL, `crypt` varchar(128) NOT NULL default 'sdtrusfX0Jj66', `name` varchar(128) NOT NULL, `uid` smallint(5) unsigned NOT NULL default '5000', `gid` smallint(5) unsigned NOT NULL default '5000', `home` varchar(255) NOT NULL default '/var/spool/mail/virtual/', `maildir` varchar(255) NOT NULL, `quota` varchar(255) NOT NULL, `enabled` tinyint(3) unsigned NOT NULL default '1', `change_password` tinyint(3) unsigned NOT NULL default '1', `clear` varchar(128) NOT NULL default 'ChangeMe', PRIMARY KEY (`id`) ) ;
I am not extremely comfortable with the users table and I am not sure if all the fields are necessary. I know that id, maildir, enabled, uid, and gid are necessary but I believe the other fields are for other features not covered in this tutorial. I also added the quota field if you have optional quota support.
After adding these tables to the database it is recommended that you create a special user that has privileges to access only the maildb database. This user must have at least SELECT, INSERT, UPDATE, DELETE, CREATE, and DROP privileges on the maildb database. I chose the user name mail for my configuration. In the configuration files that follow I will use this name.
We will fill these tables with data later in the tutorial.
Add MySQL Configuration Files
Postfix communicates with the MySQL database using parameters setup in specific configuration files. All of the data Postfix uses, whether from MySQL or some other database is understood as a set of key-value pairs. Since our database structure is more complicated that this simple paradigm these files will let Postfix know which fields in a given table make up a key-value pair.
Add the following files to /etc/postfix: (change password into the password of the mail MySQL user)
mysql_alias.cf:
user=mail password=password dbname=maildb table=aliases select_field=destination where_field=mail hosts=localhost additional_conditions = and enabled = 1
mysql_mailbox.cf
user=mail password=password dbname=maildb table=users select_field=maildir where_field=id hosts=localhost additional_conditions = and enabled = 1
mysql_uid.cf:
user=mail password=password dbname=maildb table=users select_field=uid where_field=id hosts=localhost
mysql_gid.cf
user=mail password=password dbname=maildb table=users select_field=gid where_field=id hosts=localhost
mysql_domains.cf
user=mail password=password dbname=maildb table=domains select_field=domain where_field=domain hosts=localhost
smtp_auth.cf
user=mail password=password dbname=maildb table=smtp_auth select_field=password where_field=sasl_server hosts=localhost
mysql_quota.cf
user=mail password=password dbname=maildb table=users select_field=quota where_field=id hosts=localhost
Configure /etc/postfix/main.cf
Edit or add the following lines to the main.cf file. Not all these options are necessary but they reflect my choices in setting up the postfix server. As others attempt to install and use the Postfix server in the same way, hopefully these can be refined.
The myhostname parameter must have a valid DNS entry. So if your DNS provider does not have an entry for mail.yourdomain.com, just use yourdomain.com. This parameter is used to tell the recipient smarthost where the mail is coming from, and will be verified in most cases.
main.cf:
# Basic Server Configuration
myhostname = mail.yourdomain.com inet_interfaces = all mydestination = local_recipient_maps = mynetworks_style = host # Configuration of SMTP Authorization smtp_sasl_auth_enable = yes smtp_sasl_password_maps = mysql:/etc/postfix/smtp_auth.cf smtp_sasl_security_options = noanonymous relayhost = sasl.smtp.pobox.com:25 # Setup Alias Maps alias_maps = hash:/etc/postfix/aliases alias_database = hash:/etc/postfix/aliases # Configure Virtual Hosting virtual_mailbox_base = /var/spool/mail/virtual virtual_mailbox_maps = mysql:/etc/postfix/mysql_mailbox.cf virtual_uid_maps = mysql:/etc/postfix/mysql_uid.cf virtual_gid_maps = mysql:/etc/postfix/mysql_gid.cf virtual_alias_maps = mysql:/etc/postfix/mysql_alias.cf virtual_mailbox_domains = mysql:/etc/postfix/mysql_domains.cf # Configure Virtual Quota virtual_mailbox_limit_maps = mysql:/etc/postfix/mysql_quota.cf virtual_mailbox_limit_override = yes virtual_mailbox_limit_message = User has overpassed quota
# Additional Configuration:
# how long if undelivered before sending warning update to sender
delay_warning_time = 4h
# will it be a permanent error or temporary
unknown_local_recipient_reject_code = 450
# how long to keep message on queue before return as failed.
# some have 3 days, I have 16 days as I am backup server for some people
# whom go on holiday with their server switched off.
maximal_queue_lifetime = 7d
# max and min time in seconds between retries if connection failed
minimal_backoff_time = 1000s
maximal_backoff_time = 8000s
# how long to wait when servers connect before receiving rest of data
smtp_helo_timeout = 60s
# how many address can be used in one message.
#effective stopper to mass spammers, accidental copy in whole address list
# but may restrict intentional mail shots.
smtpd_recipient_limit = 35
# how many error before back off.
smtpd_soft_error_limit = 3
# how many max errors before blocking it.
smtpd_hard_error_limit = 12
# Requirements for the HELO statement - prevents becoming open relay
smtpd_helo_restrictions = permit_mynetworks, warn_if_reject
reject_non_fqdn_hostname, reject_invalid_hostname, permit
# Requirements for the sender details
smtpd_sender_restrictions = permit_mynetworks, warn_if_reject
reject_non_fqdn_sender, reject_unknown_sender_domain,
reject_unauth_pipelining, permit
# Requirements for the connecting server
smtpd_client_restrictions = reject_rbl_client sbl.spamhaus.org,
reject_rbl_client dnsbl.njabl.org
# Requirement for the recipient address
smtpd_recipient_restrictions = reject_unauth_pipelining, permit_mynetworks,
reject_non_fqdn_recipient, reject_unknown_recipient_domain,
reject_unauth_destination, permit
Add Domains, Aliases, Users, and SMTP Password to MySQL Tables
It is finally time to enter all our user data to MySQL. Below are some examples of the entries in my table as well as some brief descriptions.
Domains
I added the following to my domains table:
| domain | transport |
| happystoddards.com | virtual: |
| mail.happystoddards.com | virtual: |
| localhost | virtual: |
You can add any additional domains you are hosting to the table as well.
Users
The users table defines users that can have email stored on the server. You do not need to create users for email accounts that are always forwarded. I added the following to my user table in case I would like to have the accounts in the future:
| id | name | uid | gid | home | maildir | quota | enabled |
| [email protected] | root | 5000 | 5000 | /var/spool/mail/virtual/ | root/ | 0 | 1 |
| [email protected] | neil | 5001 | 5001 | /var/spool/mail/virtual | neil/ | 2048000 | 1 |
Aliases
The aliases table is perhaps the most important. It defines all the email forwarding for you email addresses. It is cascaded in form. In other words, rules are followed from one to the next until a final destination does not have any other aliases.
For example I have defined in my aliases table:
| destination | enabled | |
| [email protected] | [email protected] | 1 |
| [email protected] | [email protected] | 1 |
| [email protected] | [email protected] | 1 |
| [email protected] | [email protected] | 1 |
| @mail.happystoddards.com | [email protected] | 1 |
| @happystoddards.com | [email protected] | 1 |
| @happystoddards.com | [email protected] | 1 |
| @localhost | [email protected] | 1 |
| neil@localhost | [email protected] | 1 |
| [email protected] | [email protected] | 1 |
| [email protected] | [email protected] | 1 |
| [email protected] | [email protected] | 1 |
With this configuration mail from [email protected], [email protected], and a number of others are forwarded to [email protected] This in turn is forwarded to [email protected] Mail set to neil@localhost or [email protected] are forwarded to [email protected] which is also in turn routed to [email protected] [email protected] is the final location for all mail.
SMTP_AUTH
My smtp_auth table only has a single entry:
| sasl_server | password |
| smtp.server.tld:25 | user : password |
Troubleshooting Configuration
If everything goes as planned when you restart your Postfix MTA you should have a working mail server.
Restart the server by opening the terminal and typing:
service postfix restart
To troubleshoot the configuration take a look at the Postfix log file located at /var/log/maillog.
You can monitor this log by opening the terminal and typing:
watch tail -n 25 /var/log/maillog
Hit Ctrl+C to quit watch
This log can be extremely useful to see what may be causing issues with your configuration.
To send a mail message to test your server open the terminal and type:
echo "Hello" > letter mail -s "Test Email" email@yourdomain.tld < letter