Author:
Nikolay Mihaylov, nmmm-at-nmmm-dot-nu
Purpose:
The document describes how to do migration from Sendmail mailer demon to Postfix
mailer demon.
Assumption:
I assume you know sendmail very well. I assume you know how inetd
works as well. I assume you do not know postfix
at all. I also assume you have large sendmail installation with procmal
and several domain names and several email addresses. My own installation was 579
domain names and 1767 email addresses, including system emails, rejection emails
and catch-all's.
References:
As I already said - My own e-mail server serves 579 domain names and 1767 email addresses.
I have one more additional server that process e-mail forwarding only, done using SQL database. Latest estimations is there are 1830 domains, however most of them are not "live".
I believe both sendmail and postfix are very secure, if you configure them properly. I've running sendmail for several years, and I had security issues only first month until I configured sendmail properly. I still use sendmail for servers with smaller number of domain names.
I believe both sendmail and now postfix are very extensible.
Postfix is easier to configure, even I have been written my own sendmail.cf file.
However, the reason why I migrate is:
Postfix is faster and use less resources than sendmail.
Is better to install Postfix from package provided from your Linux distribution (often RPM). The installation will create several system users such postfix etc. The installation will create /etc/postfix directory as well.
After the installation, I recommend you make a copy of /etc/postfix and delete everything there, except following files:
all other files we will create later.
The file master.cf, is similar to /etc/inetd.conf . It describe on what port postfix works etc. It provides internal information for additional postfix demons too.
If we assume we have running sendmail on same server, first thing we need to do is to "move" postfix on different port:
part of /etc/postfix/master.cf |
---|
#smtp inet n - n - 80 smtpd 2525 inet n - n - - smtpd |
smtp and 2525 are the ports. smtp (25 port) is commented, and second instance is started in 2525 port.
80 is the max connection / max child number. in case of 2525 port we use default value (often 100)
File main.cf contains the postfix configuration. We deleted the file, so we create a new one as follows:
/etc/postfix/main.cf |
---|
#queue_directory = /var/spool/postfix #command_directory = /usr/sbin #daemon_directory = /usr/libexec/postfix #mail_owner = postfix myhostname = mx1.domain.com mydomain = domain.com mydestination = mx1.domain.com virtual_alias_domains = /etc/postfix/local-host-names virtual_alias_maps = hash:/etc/postfix/virtusertable, hash:/etc/postfix/aliases, hash:/etc/postfix/virtual canonical_maps = hash:/etc/postfix/canonical # NIS overrice alias_maps = mailbox_command = /usr/bin/procmail smtpd_helo_required = yes disable_vrfy_command = yes #inet_interfaces = 127.0.0.1, 1.1.1.1, 1.1.1.2 mynetworks = 127.0.0.0/8, 1.1.1.1 #permit_mx_backup_networks = #smtpd_recipient_restrictions = # permit_mynetworks, # permit_mx_backup, # reject_invalid_hostname, # reject_non_fqdn_sender, # reject_non_fqdn_recipient, # reject_unknown_sender_domain, # reject_unknown_recipient_domain, # reject_unauth_destination, # reject_unauth_pipelining # reject_non_fqdn_hostname |
Now, the explanation
queue_directory and so on describe where the queue and so on are. Since we used RPM to install, we probably do not need to change these.
myhostname, mydomain is the main domain name. This does not mean we can not host additional domain names.
mydestination is good to be same as myhostname. This is default domain for emails. Currently emails will be something@mx1.domain.com . This is because we want to have something@domain.com as virtual address (will be explained later).
virtual_alias_domains is the local domain. get /etc/mail/local-host-names or /etc/sendmail.cw and copy file to /etc/postfix/local-host-names . File from sendmail is unchanged.
virtual_alias_maps - this is similar as /etc/mail/virtusertable. Because there are little difference, I will get back to this later.
canonical_maps - will get back to this later.
alias_maps - this is redhat / fedora option override, because they use NIS configuration.
mailbox_command - this tell postfix to use procmail as mailbox delivery. When you put this, your delivery immediately became same as in sendmail. I for example used sendmail + maildir, made via procmail. Now, postfix deliver mail to same mailboxes without any modifications.
smtpd_helo_required and disable_vrfy_command - these are good options for security.
inet_interfaces - this tell postfix on what interface to listen.
mynetworks - this tell postfix what network must be relayed. This is same as /etc/mail/access but is inline. In case you have several networks, you always can do:
part of /etc/postfix/main.cf |
---|
mynetworks = /etc/postfix/networks |
/etc/postfix/networks looks like:
part or whole /etc/postfix/networks |
---|
127.0.0.0/8 1.1.1.1 1.1.1.2 192.168.0.1/24 |
One note here, postfix may have a file called /etc/postfix/access. It looks like /etc/mail/access, but it can not do following:
part or whole /etc/mail/access |
---|
#this is sendmail example, is not postfix file. from:info@domain.com REJECT |
smtpd_recipient_restrictions - good security issues. After you go live, you want these, except probably permit_mx_backup. permit_mx_backup works exactly as sendmail option relay-based-on-mx.
Both sendmail and postfix have aliases file (/etc/aliases, /etc/mail/aliases, /etc/postfix/aliases etc.), however there are some differences. Lets assume we have following:
/etc/aliases, /etc/mail/aliases, /etc/postfix/aliases etc. |
---|
# /etc/aliases #name@aaa.com : bbbb name@dom.com : ime@host.com ime@dom.com : user@xxx.com |
in aliases, sendmail do not pay attention to domain name.
name@aaa.com is same as name@dom.com (and in such case is illegal)
however, on the right side, domain is important.
if we send mail to name@anydomain it will go to ime@anydomain, then will go to user@xxx.com . In case xxx.com is on different server it will be forwarded there. In case is on same server, it will be delivered to mailbox "user" (we assume there is no virtusertable)
well, here postfix is even worse :-)
in aliases postfix do not pay attention to any domain name. This is because aliases in postfix are for LOCAL DELIVERY ONLY.
the example file will be parsed as:
name@anydomain will directly go to mailbox "ime".
ime@anydomain will directly go to mailbox "user"
These issues can be easy fixed if we view "aliases" file as additional "virtusertable" file.
part of /etc/postfix/main.cf |
---|
virtual_alias_maps = hash:/etc/postfix/virtusertable, hash:/etc/postfix/aliases, hash:/etc/postfix/virtual |
in such case, 99% of cases, you can use sendmail aliases unchanged in postfix.
Even postfix have support for virtusertable file (i do not mean /etc/postfix/virtual), is better once again to use virtual_alias_maps
part of /etc/postfix/main.cf |
---|
virtual_alias_maps = hash:/etc/postfix/virtusertable, hash:/etc/postfix/aliases, hash:/etc/postfix/virtual |
However there is one sendmail feature that is NOT supported in postfix. Here are an example:
/etc/mail/virtusertable |
---|
user@dom.com user_dom_com name@dom.com name_dom_com @dom.com all_dom_com # here the problem: @host.com %1@dom.com |
host.com have same emails like dom.com. user@host.com go to user@dom.com and so on. Often this is 1 hosting with 2 or more domain names.
To solve this, we can use Postfix option called canonical_maps:
part of /etc/postfix/main.cf |
---|
canonical_maps = hash:/etc/postfix/canonical |
You need to create a file called canonical :
/etc/postfix/canonical |
---|
@host.com @dom.com |
this can be done using grep:
grep '%1' /etc/mail/virtusertable | sed 's/%1//g' > canonical
when you do that, you will NOT NEED to remove "%1@dom.com" from sendmail virtusertable. you may use /etc/mail/virtusertable unchanged.
It is good to create this file, is same as virtusertable (and aliases), and to put any NEW emails/hosts there after you finish migration. At the beginning you start with empty file.
Several of configuration files had "hash:" in front. This means that those files are similar to /etc/aliases.db. However instead of newaliases command, you need to use following commands:
cd /etc/postfix postmap canonical postmap virtual postmap virtusertable postalias aliases
Commands postmap and postalias working in same way, but postalias expect column as delimiter. If you want to be precise, you can use:
cd /etc/postfix postmap hash:canonical postmap hash:virtual postmap hash:virtusertable postalias hash:aliases
I personally created /usr/local/sbin/newpostmap file.
Postfix executable can be start/stop/reload in following way:
postfix -c /etc/postfix start postfix -c /etc/postfix stop postfix -c /etc/postfix reload
Note reload just reload the configuration. It does not restart the demon.
Often you may omit -c <conf directory>
This is the redhat / fedora init script
/etc/init.d/postfix start /etc/init.d/postfix stop /etc/init.d/postfix restart
Note restart stopping the demon, then start it again.
there are two commands I am aware of - postqueue and qshape.
I noted that on very large queue, postqueue command works faster if you first stop postfix demon.
If you follow all those steps, you will have postfix running on port 2525.
You may try telnet there and check if everything works. If it works for you, just stop sendmail, edit master.cf, make postfix works on port 25 (smtp), reload.