I was very pleasantly surprised how easy it was to configure canonical maps for Postfix to use an LDAP server. Using the same OpenLDAP configuration that I just recently posted for aliases, I was able to add canonical maps in a matter of minutes. The benefit was that now if an email was sent from the command line, the map would rewrite the sending address to one that could be sent over the Internet and not just to other local users. I realized the need for this when I noticed that my girlfriend was trying to use Evolution to send mail (without configuring it) and it was being rejected by Internet mail servers because it appeared to originate from an invalid fedora.test domain.
First, I did it the traditional flat file way. I added this entry to /etc/postfix/canonical:
Then, I added an entry into /etc/postfix/main.cf:
canonical_maps = hash:/etc/postfix/canonical
Now, I hashed the file using the command postmap /etc/postfix/canonical and reloaded the postfix service using the command service postfix reload.
Finally, I tested this by sending a mail from the command line while logged into the patricia account. This worked great! This would be the solution for the problem of my girlfriend trying to send mail without configuring a mail server.
However, I wanted to be able to extend this solution using my LDAP server for maps as well, so I changed my entry in /etc/postfix/main.cf to use LDAP for canonical lookups as well:
canonical_maps = hash:/etc/postfix/canonical, ldap:/etc/postfix/ldap-canonical.cf
Of course, I also needed an entry into my LDAP server, which I made with this:
[root@earth postfix]# ldapadd -x -D cn=Manager,dc=fedora,dc=test -W
Enter LDAP Password:
adding new entry "cn=keith,ou=People,dc=fedora,dc=test"
To create the /etc/postfix/ldap-canonical.cf, I copied the /etc/postfix/ldap-aliases-cf, which I blogged about an earlier post. Surprisingly, nothing in this file needed to change, but here it is for reference:
[root@earth postfix]# grep -v '^$' ldap-canonical.cf | grep -v '^#'
server_host = localhost.localdomain
server_port = 389
timeout = 10
bind = no
search_base = ou=People,dc=fedora,dc=test
result_attribute = rfc822MailMember
query_filter = (& (cn=%s)(objectClass=nisMailAlias))
debug_level = 4
Starting to test it, I executed:
[root@earth postfix]# service postfix reload
Reloading postfix: [ OK ]
[root@earth postfix]# postmap -q keith ldap:/etc/postfix/ldap-canonical.cf
Finally, I did the acid test. I logged into the keith account and sent and email out to one of my Internet email addresses. When I received the email, it indeed did appear to originate from firstname.lastname@example.org.
After further experimenting, I noticed that not just was the address rewritten outbound, but also inbound. This lead me to discover two other canonical maps. There is sender_canonical_maps and recipient_canonical_maps, as well as canonical_maps which applies to all mail in or out bound.
Ultimately, I changed the entry in the /etc/postfix/main.cf to just rewrite the address for outbound mail by using:
sender_canonical_maps = hash:/etc/postfix/canonical, ldap:/etc/postfix/ldap-canonical.cf
Now, I can still receive local mail as the user keith to my local mailbox, but when I send mail for the user keith, it always appear to come from email@example.com.