Table of Contents for
Postfix: The Definitive Guide

Version ebook / Retour

Cover image for bash Cookbook, 2nd Edition Postfix: The Definitive Guide by Kyle D. Dent Published by O'Reilly Media, Inc., 2003
  1. Postfix: The Definitive Guide
  2. Cover
  3. Postfix: The Definitive Guide
  4. Foreword
  5. Preface
  6. Audience
  7. Organization
  8. Conventions Used in This Book
  9. Comments and Questions
  10. Acknowledgments
  11. 1. Introduction
  12. 1.1. Postfix Origins and Philosophy
  13. 1.2. Email and the Internet
  14. 1.3. The Role of Postfix
  15. 1.4. Postfix Security
  16. 1.5. Additional Information and How to Obtain Postfix
  17. 2. Prerequisites
  18. 2.1. Unix Topics
  19. 2.2. Email Topics
  20. 3. Postfix Architecture
  21. 3.1. Postfix Components
  22. 3.2. How Messages Enter the Postfix System
  23. 3.3. The Postfix Queue
  24. 3.4. Mail Delivery
  25. 3.5. Tracing a Message Through Postfix
  26. 4. General Configuration and Administration
  27. 4.1. Starting Postfix the First Time
  28. 4.2. Configuration Files
  29. 4.3. Important Configuration Considerations
  30. 4.4. Administration
  31. 4.5. master.cf
  32. 4.6. Receiving Limits
  33. 4.7. Rewriting Addresses
  34. 4.8. chroot
  35. 4.9. Documentation
  36. 5. Queue Management
  37. 5.1. How qmgr Works
  38. 5.2. Queue Tools
  39. 6. Email and DNS
  40. 6.1. DNS Overview
  41. 6.2. Email Routing
  42. 6.3. Postfix and DNS
  43. 6.4. Common Problems
  44. 7. Local Delivery and POP/IMAP
  45. 7.1. Postfix Delivery Transports
  46. 7.2. Message Store Formats
  47. 7.3. Local Delivery
  48. 7.4. POP and IMAP
  49. 7.5. Local Mail Transfer Protocol
  50. 8. Hosting Multiple Domains
  51. 8.1. Shared Domains with System Accounts
  52. 8.2. Separate Domains with System Accounts
  53. 8.3. Separate Domains with Virtual Accounts
  54. 8.4. Separate Message Store
  55. 8.5. Delivery to Commands
  56. 9. Mail Relaying
  57. 9.1. Backup MX
  58. 9.2. Transport Maps
  59. 9.3. Inbound Mail Gateway
  60. 9.4. Outbound Mail Relay
  61. 9.5. UUCP, Fax, and Other Deliveries
  62. 10. Mailing Lists
  63. 10.1. Simple Mailing Lists
  64. 10.2. Mailing-List Managers
  65. 11. Blocking Unsolicited Bulk Email
  66. 11.1. The Nature of Spam
  67. 11.2. The Problem of Spam
  68. 11.3. Open Relays
  69. 11.4. Spam Detection
  70. 11.5. Anti-Spam Actions
  71. 11.6. Postfix Configuration
  72. 11.7. Client-Detection Rules
  73. 11.8. Strict Syntax Parameters
  74. 11.9. Content-Checking
  75. 11.10. Customized Restriction Classes
  76. 11.11. Postfix Anti-Spam Example
  77. 12. SASL Authentication
  78. 12.1. SASL Overview
  79. 12.2. Postfix and SASL
  80. 12.3. Configuring Postfix for SASL
  81. 12.4. Testing Your Authentication Configuration
  82. 12.5. SMTP Client Authentication
  83. 13. Transport Layer Security
  84. 13.1. Postfix and TLS
  85. 13.2. TLS Certificates
  86. 14. Content Filtering
  87. 14.1. Command-Based Filtering
  88. 14.2. Daemon-Based Filtering
  89. 14.3. Other Considerations
  90. 15. External Databases
  91. 15.1. MySQL
  92. 15.2. LDAP
  93. A. Configuration Parameters
  94. A.1. Postfix Parameter Reference
  95. 2bounce_notice_recipient
  96. access_map_reject_code
  97. alias_maps
  98. allow_mail_to_files
  99. allow_percent_hack
  100. alternate_config_directories
  101. append_at_myorigin
  102. authorized_verp_clients
  103. berkeley_db_read_buffer_size
  104. biff
  105. body_checks_size_limit
  106. bounce_service_name
  107. canonical_maps
  108. command_directory
  109. command_time_limit
  110. content_filter
  111. daemon_timeout
  112. debug_peer_list
  113. default_destination_concurrency_limit
  114. default_extra_recipient_limit
  115. default_process_limit
  116. default_recipient_limit
  117. default_verp_delimiters
  118. defer_service_name
  119. delay_notice_recipient
  120. deliver_lock_attempts
  121. disable_dns_lookups
  122. disable_mime_output_conversion
  123. disable_vrfy_command
  124. double_bounce_sender
  125. empty_address_recipient
  126. error_service_name
  127. export_environment
  128. fallback_relay
  129. fast_flush_domains
  130. fast_flush_refresh_time
  131. fork_attempts
  132. forward_expansion_filter
  133. hash_queue_depth
  134. header_address_token_limit
  135. header_size_limit
  136. home_mailbox
  137. ignore_mx_lookup_error
  138. in_flow_delay
  139. initial_destination_concurrency
  140. ipc_idle
  141. line_length_limit
  142. lmtp_connect_timeout
  143. lmtp_data_init_timeout
  144. lmtp_lhlo_timeout
  145. lmtp_quit_timeout
  146. lmtp_rset_timeout
  147. lmtp_tcp_port
  148. local_destination_concurrency_limit
  149. local_recipient_maps
  150. luser_relay
  151. mail_owner
  152. mail_spool_directory
  153. mailbox_command
  154. mailbox_delivery_lock
  155. mailbox_transport
  156. manpage_directory
  157. masquerade_domains
  158. max_idle
  159. maximal_backoff_time
  160. message_size_limit
  161. mime_header_checks
  162. minimal_backoff_time
  163. mydomain
  164. mynetworks
  165. myorigin
  166. newaliases_path
  167. notify_classes
  168. parent_domain_matches_subdomains
  169. pickup_service_name
  170. process_id_directory
  171. proxy_interfaces
  172. qmgr_clog_warn_time
  173. qmgr_message_active_limit
  174. qmgr_message_recipient_minimum
  175. qmqpd_error_delay
  176. queue_directory
  177. queue_run_delay
  178. rbl_reply_maps
  179. recipient_canonical_maps
  180. reject_code
  181. relay_domains_reject_code
  182. relay_transport
  183. relocated_maps
  184. resolve_dequoted_address
  185. sample_directory
  186. sendmail_path
  187. setgid_group
  188. showq_service_name
  189. smtp_bind_address
  190. smtp_data_done_timeout
  191. smtp_data_xfer_timeout
  192. smtp_destination_recipient_limit
  193. smtp_helo_timeout
  194. smtp_mail_timeout
  195. smtp_pix_workaround_delay_time
  196. smtp_quit_timeout
  197. smtp_rcpt_timeout
  198. smtp_skip_5xx_greeting
  199. smtpd_banner
  200. smtpd_data_restrictions
  201. smtpd_error_sleep_time
  202. smtpd_expansion_filter
  203. smtpd_helo_required
  204. smtpd_history_flush_threshold
  205. smtpd_noop_commands
  206. smtpd_recipient_limit
  207. smtpd_restriction_classes
  208. smtpd_soft_error_limit
  209. soft_bounce
  210. strict_7bit_headers
  211. strict_8bitmime_body
  212. strict_rfc821_envelopes
  213. swap_bangpath
  214. syslog_name
  215. transport_retry_time
  216. undisclosed_recipients_header
  217. unknown_client_reject_code
  218. unknown_local_recipient_reject_code
  219. unknown_virtual_alias_reject_code
  220. verp_delimiter_filter
  221. virtual_alias_maps
  222. virtual_mailbox_base
  223. virtual_mailbox_limit
  224. virtual_mailbox_maps
  225. virtual_transport
  226. B. Postfix Commands
  227. C. Compiling and Installing Postfix
  228. C.1. Obtaining Postfix
  229. C.2. Postfix Compiling Primer
  230. C.3. Building Postfix
  231. C.4. Installation
  232. C.5. Compiling Add-on Packages
  233. C.6. Common Problems
  234. C.7. Wrapping Things Up
  235. D. Frequently Asked Questions
  236. Index
  237. About the Author
  238. Colophon
  239. Copyright

MySQL

MySQL is an open source relational database system that uses Structured Query Language (SQL) for querying and managing its data. You don’t have to know SQL to use Postfix with MySQL, but it will help to understand how they interact. Normally, you would use MySQL because you already have a database of information about each user such as a full name, account name, phone numbers, etc. You have to make sure your database includes the information you need to accomplish a particular task with Postfix. A common use is to map an email alias to the local account name. For this to work there must be one database column containing email aliases and another with local account names. Postfix can query your database with the recipient address of an email message as the key to look up the value of the local account for delivery. Any of the Postfix lookup table parameters can work with MySQL queries. You just have to figure out which columns contain the information you need.

MySQL Configuration

MySQL maps are specified like any other map in Postfix. You specify the map type and the file containing the mappings. In the case of MySQL, however, the file you specify is not the lookup map itself, but rather a file that contains configuration information that specifies how to get the desired value from your database:

alias_maps = mysql:/etc/postfix/mysql-aliases.cf

The file mysql-aliases.cf contains configuration information that specifies how to get the information from MySQL. The parameters for this file are explained below.

MySQL parameters

MySQL parameters provide the information necessary for Postfix to connect to your database server and construct an SQL statement to look up the data it needs. These parameters are placed in a MySQL map configuration file that functions like a Postfix configuration file with blanks and comments ignored. Comments are marked by a # as the first character of a line. You can have as many MySQL configuration files as needed in place of normal Postfix lookup files. All of the MySQL parameters presented here are required except for additional_conditions.

Figure 15-1 shows an SQL statement that Postfix creates using the parameters described.

Sample SQL statement
Figure 15-1. Sample SQL statement
hosts

List of hostnames or IP addresses where a MySQL server is running. You can also indicate a Unix domain socket by preceding a path to a socket with unix:. You should list more than one host or socket only if you have multiple redundant database servers. Each host is tried in the order listed until a successful query can be made. For example:

hosts = unix:/tmp/mysql.sock, db.example.com, 192.168.150.15
user

Account name to use when logging into the MySQL server.

password

Password to use when logging into the MySQL server.

dbname

The name of the database to use for the query.

table

The name of the table to use for the query.

select_field

The name of the column that contains the lookup value.

where_field

The name of the column that contains the key value.

additional_conditions

Additional comparisons for the WHERE clause of the SQL statement built by Postfix. You must understand SQL to use this attribute. Set this parameter as if you are continuing the SQL statement. For example:

additional_conditions = and mail_type = 'local'

MySQL Example

Let’s go through an example illustrating a MySQL and Postfix configuration. The http://example.com site uses a MySQL database to manage all of the users on its network. There is a database that contains a variety of information about users on the network, including names, phone numbers, etc. Among the tables in the database is one called email_address, which contains the pertinent information for configuring Postfix. The database structure looks like the following:

+-----------------+-------------+------+-----+---------+-------+
| Field           | Type        | Null | Key | Default | Extra |
+-----------------+-------------+------+-----+---------+-------+
| localpart       | varchar(15) |      | PRI |         |       |
| type            | varchar(15) | YES  |     | NULL    |       |
| to_address      | varchar(65) | YES  |     | NULL    |       |
| password        | varchar(65) | YES  |     | NULL    |       |
| last_changed_by | varchar(15) | YES  |     | NULL    |       |
+-----------------+-------------+------+-----+---------+-------+

This table contains all of the email addresses that Postfix should accept mail for with the localpart column providing the local part of the addresses. Some of the users maintain their primary email accounts on other systems, so their http://example.com addresses are aliases that forward messages to their primary email addresses elsewhere. The type column indicates whether an address is delivered locally or forwarded to another address. The value forward indicates that this address is an alias. If an address is forwarded, the to_address column contains the address to forward messages to.

Table 15-1 contains the access information needed to configure Postfix in this scenario. You should collect the same information about your own database before starting to configure Postfix.

Table 15-1. MySQL database information for Postfix configuration

Access information:

Values

Host

mysql.example.com

Database name:

user_accounts

Database table:

email_address

Database user:

kdent

Database password:

Rumpelstiltskin

In addition to the general database information in Table 15-1, you will have to determine the columns you need for the particular Postfix maps you are replacing with your MySQL table. Example 15-1 shows a sample record from the database with the relevant columns for this configuration. In this example, you’ll be configuring the Postfix parameters local_recipient_maps and alias_maps.

Example 15-1. Sample record from email_address table
+------------+----------+-------------------+
| localpart  | type     | to_address        |
+------------+----------+-------------------+
| kdent      | forward  | kyle.dent@ora.com |
+------------+----------+-------------------+

Configuring local_recipient_maps

The local_recipient_maps parameter points to lists of local users that should receive email at this system. By default it points to the user accounts and aliases on the system, so that mail sent to a nonexistent user is rejected by the SMTP server. This lookup map is a bit different from others in that it doesn’t require a return value to map to. It matters only that the recipient is in the lookup table or not. In this example, the MySQL database contains the list of all email accounts that should receive mail on the system. You can point the local_recipient_maps parameter to a MySQL configuration that extracts the list of email users. You’ll use a file called mysql-local.cf for the query configuration. First, set local_recipient_maps to point to the query configuration file, indicating that the lookup type is mysql:

local_recipient_maps = mysql:/etc/postfix/mysql-local.cf

The file mysql-local.cf contains parameters for each of the items listed in Table 15-1, plus the select_field and where_field for this specific query:

#
# mysql-local.cf - local recipients for mail server.
#
hosts = mysql.example.com
user = kdent
password = Rumpelstiltskin

dbname = user_accounts
table = email_address

select_field = localpart
where_field = localpart

The select_field and where_field both point to the localpart column. The select_field in this case is not particularly important since you don’t need a value back from the map. You don’t need the additional_conditions parameter because you want every record that appears in the table. After reloading, Postfix uses the MySQL configuration to determine local users and reject mail for recipients not listed in the MySQL table.

You can easily check your MySQL configuration file with the postmap command:

$ postmap -q 'kdent' mysql:/etc/postfix/mysql-local.cf
kdent

The -q option tells postmap to query the map using the specified key. If your query has any problems, postmap reports them to your terminal.

Configuring alias_maps

Some users do not receive their mail on this system, but rather have it forwarded to another account. By pointing alias_maps to another MySQL configuration, you can obtain the list of users that have aliases and determine what the forwarding address is. You’ll use a file called mysql-alias.cf for this query configuration. First, set the alias_maps parameter to point to the query configuration file:

alias_maps = mysql:/etc/postfix/mysql-alias.cf

The mysql-alias.cf file contains the following parameters:

# 
# mysql-alias.cf - forwarding aliases
#
hosts = mysql.example.com
user = kdent
password = Rumpelstiltskin

dbname = user_accounts
table = email_address
 
select_field = to_address
where_field = localpart

additional_conditions = and type = 'forward'

In this case, you set the select_field to to_address since that’s the value needed by alias_maps to forward messages. You also specified additional_conditions because you want only the addresses that have aliases. After reloading Postfix, it uses this MySQL configuration to determine addresses with aliases and where messages should be forwarded.

Configuring virtual domains

MySQL databases are often used by sites that host many virtual domains. This last MySQL example walks through configuring virtual mailbox domains. Be sure to read Chapter 8 for information about virtual hosting in general, as this section discusses only the MySQL configuration.

In this example, you’ll use a table called email_address from a database called customer. The table contains a record for every virtual address at all the domains the system accepts mail for. It includes the following fields that are of interest:

domain

The virtual domain name for this record.

mail_address

The public email address that messages can be sent to. Messages are delivered to the local virtual mail store.

mailbox

Contains the filename for delivery into the local mail store. The name should be relative to the path set in virtual_mailbox_base. You can append the name with a slash for maildir-style delivery.

Example 15-2 shows a sample record from the database with the relevant columns.

Example 15-2. Sample record for virtual mailbox alias
+------------+---------------+---------------+
| domain     | mail_address  | mailbox       |
+------------+---------------+---------------+
| ora.com    | kdent@ora.com | ora.com/kdent |
+------------+---------------+---------------+

In this example, all virtual deliveries occur under the same user and group, vmail:vmail. If you require different user and group privileges for the different users or domains, you should have additional columns for uid and gid in your table and then create mysql maps for them as well.

You are using a static uid and gid for deliveries and your message store is simply a directory on the local filesystem:

virtual_mailbox_base = /usr/local/vmail
virtual_uid_maps = static:1003
virtual_gid_maps = static:1003

The list of virtual domains and mailbox maps comes from two MySQL configuration files:

virtual_mailbox_domains = mysql:/etc/postfix/virtual_domains.cf
virtual_mailbox_maps = mysql:/etc/postfix/virtual_mailboxes.cf

The virtual_mailboxes.cf configuration maps email addresses to the mail store file where messages should be delivered:

hosts = mysql.example.com
user = kdent
password = Rumpelstiltskin
  
dbname = customer
table = email_address
select_field = mailbox
where_field = mail_address