Home           RSS           Search

March 13, 2013





Postfix config "how to" ( main.cf )



Postfix is an excellent replacement for sendmail. It is a fast and secure message transfer agent (MTA). It is intended as an easy-to-administer and secure alternative to the widely-used Sendmail MTA.

Postfix is powerful enough to allow the flexibility to deliver mail locally just on your own machine, setup as a full mail server for a corporation or with the help of clustering software it can serve as a full mail cluster. There is no reason you need to be stuck with the options your local ISP gives you. With Postfix as your MTA you can setup your mail the way you want to, abiding by only your rules. If you want to block all spam from China or Russia then do it. You only want to accept mail from trusted associates, then you can. What about setting up an email address for all your friends and family? No problem. The best part is it is Open Source, completely free and runs on almost every operating system (Irix Solaris Linux OpenBSD FreeBSD NetBSD).



Install postfix and setup the environment

To get started, you need to first install Postfix on your machine. The source code is available from the Postfix site and practically every distribution has pre-made packages if you prefer those. The install is very easy and it will not take you much time.

Once the install is done you need to look at the config file for Postfix called "main.cf". This file is the primary config file and will contain all of the directives needed to make postfix work like you want it to. The main.cf file can normally be found under the /etc directory Postfix was installed under. For example /etc/postfix/main.cf

Below you will find the link to the postfix example file and below that is the same main.cf file in a text box. Both formats are available to make it easier for you to review the code. This main.cf is a fully working config file with the exception of setting up a few variables for your environment.

#
### Calomel.org Postfix main.cf
#
### Verify these directory settings - they are critical to Postfix operation.
biff = no
recipient_delimiter =
command_directory = /usr/sbin
daemon_directory = /usr/libexec/postfix
program_directory = /usr/libexec/postfix

### Interface to listen on
inet_interfaces = 127.0.0.1

### smtp banner
mail_name = YOUR_HOST Daemon
smtpd_banner = $mail_name. All Spam Is Reported. ESMTP

### Who delivers the mail (never root for security).
mail_owner = postfix
setgid_group = postdrop

### Default user to deliver mail to (NEVER ENABLE)
luser_relay =

### The myorigin parameter specifies the domain that appears in mail that is posted on/through this machine.
append_dot_mydomain = no
append_at_myorigin = yes

### alias's
alias_maps = hash:/etc/aliases
alias_database = hash:/etc/aliases

### Whitelist of accepted recipients. $alias_maps means only addreses in
### /etc/aliases are accepted to be locally delivered.
# local_recipient_maps = $alias_maps

### the internet hostname of this mail system
myhostname = YOUR_HOST.com
myorigin = $myhostname

### The mydestination parameter specifies what domains this machine will deliver locally, instead
### of forwarding to another machine. The default is to receive mail for the machine itself.
mydestination =  $myhostname, localhost.localdomain, ,localhost

### Relay Host this mail server should send its mail to. (NONE)
relayhost = your_isps_smtp_server.com

### External Networks to accept RELAYED mail from.
mynetworks = 127.0.0.0/8

### Where to send mail that is delivered locally.
mailbox_command = procmail -a "$EXTENSION"

### How much of the message in bytes will be bounced back to the sender.
bounce_size_limit = 1000

### No limit on mailbox size.
mailbox_size_limit = 0

### Message Restrictions
# header_checks = regexp:/etc/postfix/header_checks

### Limit sent/recieved emails to 100 Megs "(header+body+attachment)x(mime-encoding) <= 100 meg"
message_size_limit = 102400000

### How long do messages stay in the queue before being sent back to the sender. (in days)
### By default, postfix attempts to resend the message every (1000 secs)x(# attempts)x(days).
bounce_queue_lifetime = 4h
maximal_queue_lifetime = 4h
delay_warning_time = 1h

### Parallel delivery force (local=2 and dest=20 are aggressive)
local_destination_concurrency_limit = 2
default_destination_concurrency_limit = 20

### Max flow rate (1 sec delay per 50 emails/sec over the number of emails delivered/sec) 
in_flow_delay = 1s

### Require strict RFC 821-style envelope addresses
strict_rfc821_envelopes = yes

### Limit the info given to outside servers
show_user_unknown_table_name = no

### no one needs to ask our server who is on it
disable_vrfy_command = yes

### clients must send a HELO (or EHLO) command at the beginning of an SMTP session.
smtpd_helo_required = yes

### Notification and delimiter
biff = no
recipient_delimiter =

#### user%domain != user@domain
allow_percent_hack = no

#### user!domain != user@domain
swap_bangpath = no

### Tarpit until RCPT TO: to reject the email for nagios compatability
smtpd_delay_reject = yes

### Tarpit those bots/clients/spammers who send errors or scan for accounts
smtpd_error_sleep_time = 20
smtpd_soft_error_limit = 1
smtpd_hard_error_limit = 3
smtpd_junk_command_limit = 2

### Reject codes == 554
access_map_reject_code = 554
invalid_hostname_reject_code = 554
maps_rbl_reject_code = 554
multi_recipient_bounce_reject_code = 554
non_fqdn_reject_code = 554
plaintext_reject_code = 554
reject_code = 554
relay_domains_reject_code = 554
unknown_address_reject_code = 554
unknown_client_reject_code = 450
unknown_hostname_reject_code = 450
unknown_local_recipient_reject_code = 554
unknown_relay_recipient_reject_code = 554
unknown_virtual_alias_reject_code = 554
unknown_virtual_mailbox_reject_code = 554
unverified_recipient_reject_code = 554
unverified_sender_reject_code = 554

### SMTP Restrictions
smtpd_client_restrictions = permit_mynetworks,
                                reject_invalid_hostname,
                                reject_rbl_client zen.spamhaus.org,
                                reject_unknown_client,
                                permit

smtpd_helo_restrictions = permit_mynetworks,
                                check_helo_access hash:/etc/postfix/helo_access,
                                reject_unauth_pipelining,
                                reject_non_fqdn_hostname,
                                reject_invalid_hostname,
                                warn_if_reject reject_unknown_hostname,
                                permit

smtpd_recipient_restrictions =  reject_non_fqdn_sender,
                                reject_non_fqdn_recipient,
                                reject_non_fqdn_hostname,
                                reject_invalid_hostname,
                                permit_mynetworks,
                                reject_unauth_pipelining,
                                reject_unknown_sender_domain,
                                reject_unknown_recipient_domain,
                                reject_unauth_destination,
                                reject_unknown_client,
                                permit

smtpd_sender_restrictions =  permit_mynetworks,
                                reject_non_fqdn_sender,
                                reject_unknown_sender_domain,
                                reject_unknown_address

smtpd_etrn_restrictions = permit_mynetworks,
                                reject

smtpd_data_restrictions = reject_unauth_pipelining,
                                reject_multi_recipient_bounce,
                                permit

#####################  END  #####################################################





If you are using OpenBSD or FreeBSD then you may also want to check out another highly secure mail daemon on our OpenSMTPD "how to" (smtpd.conf) Guide.







Customize your configuration

Now that you have Postfix installed and you have the example main.cf file from above lets take a look a each of the required changes that need to be made. We will not be going over every directive in the main.cf file as there are entire books written on the subject. We tried to make the comments in the main.cf clear enough that you could quickly decide what the directive is for and if you want to use it. What we are going to do is make sure you know what changes you need to make to the current example to get it working. Once you have the daemon up you can then goto the Postfix site and take a look at the man pages and full documentation. I would also highly suggest getting a book like "Absolute Postfix" in book form or electronically.

There are a few directories we need to tell postfix about and some extra files in the example we can define.

The binary directories - The three(3) directories postfix needs to know about are the command_directory, daemon_directory and program_directory. The command_directory is where the "postfix" binary is located. You can do a "which postfix" as root to verify. The daemon_directory and program_directory directories are where postfix will find its own daemons. Check in /usr/libexec/postfix and make sure you can see files like master, qmgr and smtpd.

Listening interface - Take a look at the inet_interfaces directive as it will tell postfix what interface or ip to listen on. By default for this example we will be listening on localhost.

Options: YOUR_HOST - You will see a few references through the main.cf to YOUR_HOST. This is a place holder so you can customize how your mail server looks to the outside world and what mail it will accept. Replace the YOUR_HOST string with the host name you mail server will be known as.

Options: relayhost - The relayhost is what you will use if you wish all of your mail _not_ destined for your machine to be sent to another relay mail server. If you are a subscriber to an ISP then this will be your service providers SMTP server. It is a very good idea for smaller mail systems to always send their mail though their ISP and not directly deliver from a DHCP address. The majority of the spam is sent from compromised machines and those machines are normally using a DHCP address. As you will see later in this "how to" we will be filtering hosts on what hostname they come from. On the other hand, if you have a register hostname associated to an ip then you want to send you mail out directly from that ip.

Message Restrictions - In the regular expression file /etc/postfix/header_checks is where we are going to filter the mail that include the headers we do not want to accept. The example below is a collection of lines you may want to consider using. Take some time and look though them to see if they work for your environment. if you decide to _not_ use the entries in header_checks then just comment out the lines, but still keep the file around. You can always decide to use checks after the spam comes rolling in. The argument IGNORE will strip out those header lines, but the mail will still be let through. The lines with argument REJECT will block the email from being delivered from the remote server and give them the text that follows the REJECT word.


#### Header checks file
#### header_checks = regexp:/etc/postfix/header_checks
#### Checks are done in order, top to bottom.

#### Remove the following from the header to protect internal lans 
#/^Received:.*.internal.lan/ IGNORE

#### non-RFC Compliance headers
/[^[:print:]]{7}/  REJECT 2047rfc
/^.*=20[a-z]*=20[a-z]*=20[a-z]*=20[a-z]*/ REJECT 822rfc1
/(.*)?\{6,\}/ REJECT 822rfc2
/(.*)[X|x]\{3,\}/ REJECT 822rfc3

#### Unreadable Language Types? -- NON-acsii un-printable
/^Subject:.*=\?(GB2312|big5|euc-kr|ks_c_5601-1987|koi8)\?/ REJECT NotReadable1
/^Content-Type:.*charset="?(GB2312|big5|euc-kr|ks_c_5601-1987|koi8)/ REJECT NotReadable2

#### Hidden Word Subject checks
/^Subject:.*      / REJECT TooManySpaces
/^Subject:.*r[ _\.\*\-]+o[ _\.\*\-]+l[ _\.\*\-]+e[ _\.\*\-]+x/ REJECT NoHiddenWords1
/^Subject:.*p[ _\.\*\-]+o[ _\.\*\-]+r[ _\.\*\-]+n/ REJECT NoHiddenWords2

#### Do not accept these types of attachments
/^Content-(Type|Disposition):.*(file)?name=.*\.(bat|com|exe)/ REJECT Bad Attachment .${3}



SMTP Restrictions

check_client_access -The /etc/postfix/client_restrictions file includes rules to check the hostnames or ips of the remote servers that connect to you. Postfix will do a host name lookup (nslookup) on the connecting ip address. Then Postfix will decided to accept the mail or reject depending on the following conditions. For example, mail from google.com is allowed, but mail from host names starting with "dhcp" or mail from the spammer friendly ISP "wanadoo" will be rejected.

The S25R anti-spam system in the client_restrictions file is an excellent collection of regular expressions for postix that limit a significant amount of spam from DHCP or dynamically addressed systems. These machines are normally compromised windows boxes or poorly setup mail servers. Check out the study report of an Anti-spam System with a 99% Block Rate by looking at the Selective SMTP Rejection (S25R) System.

### client restrictions
### check_client_access regexp:/etc/postfix/client_restrictions

### WHITE LIST mostly trusted host names ###
/\.hotmail\.com$/      OK
/\.google\.com$/       OK
/\.yahoo\.com$/        OK

### Generic Block of DHCP machines or those with many numbers in the hostname ###
/^(dhcp|dialup|ppp|adsl|pool)[^.]*[0-9]/  550 S25R6 check

### BLACK LIST known spammer friendly ISPs ###
/\.(internetdsl|adsl|sdi)\.tpnet\.pl$/  550 domain check tpnet
/^user.+\.mindspring\.com$/             550 domain check mind
/[0-9a-f]{4}\.[a-z]+\.pppool\.de$/      550 domain check pppool
/\.dip\.t-dialin\.net$/                 550 domain check t-dialin
/\.(adsl|cable)\.wanadoo\.nl$/          550 domain check wanadoo


check_helo_access -The /etc/postfix/helo_access file holds a list of helo statements you expect to allow or deny. The helo statement is sent as a courtesy from the remote system. The RFC says you can check the helo statement is of a valid format, but you can not block the host if the helo is illegal. We say, if the remote mail server is sending false information then we do not want anything to do with it. The majority of spam tries to trick the receiving mail server by lying to it. So, this check_helo_access check will reject mail that sends a helo statement saying it is localhost or my hostname (YOUR_HOST.com). Since a remote server can not be either of these it must be lying.

NOTE: in the main.cf file the helo_access file is listed as a hash file. This means we need to make a db file out of it before Postfix can use it. To make a db file just cd into the /etc/postfix directory and execute "postmap helo_access". You will notice the new "helo_access.db" and the old "helo_access" files. Remember that every time you edit the helo_access files you need to make a db file for postfix to be able to use it and execute "postfix reload".

### helo access
### check_helo_access hash:/etc/postfix/helo_access

localhost             REJECT 554 BadSender1
127.0.0.1             REJECT 554 BadSender2
YOUR_HOST.com         REJECT 554 BadSender3
YOUR_STATIC_IP        REJECT 554 BadSender3


Finally, I highly suggest joining the Postfix mailing list. They have new user lists that can answer all kinds of setup questions.

Now that you have the basics of Postfix down make sure to check the main page of Calomel.org for the mail reporting tool called "pflogsumm". It can send you daily reports of mail server statistics about your server. It can be setup is less than five(5) minutes.



Want more speed? Make sure to also check out the Network Speed and Performance Guide. With a little time and understanding you could easily double your firewall's throughput.





Reduce SPAM by greylisting ips using Postgrey with Postfix

Greylisting (or graylisting) is a method of defending e-mail users against spam. It is an extremly effective tool. A mail transfer agent (MTA) using greylisting will "temporarily reject" any email from a sender it does not recognize with a code 450. If the mail is legitimate the originating server will, after a delay, try again and if sufficient time has elapsed the email will be accepted. If the mail is from a spam sender, sending to many thousands of email addresses, it will probably not be retried and thus spam will never get to the users mail box.

NOTE: greylisting is not tarpitting. Tarpitting like what is used in OpenBSD's spamd daemon will slowly communicate with the remote server at one character per second thus wasting the spammer's time. Greylisting simply tells the server to go away and check back later. Both methods have their uses depending on how you want to run your mail server.

By default, Postgrey will deny the delivery of email for 5 minutes the first time a remote ip is seen. After 5 minutes the ip is allowed to be white listed and then postfix will use the rest of the checks you have configured. A white listed ip address can deliver mail without being slowed down. If the ip has not been seen in at least 35 days the ip is removed from the database at which time the ip will have to go through the greylisting processes again.

To install, most modern OS's already have a package made for postgrey. You can use the package manager or build it from source.

## Ubuntu
   apt-get install postgrey

## OpenBSD
   pkg_add -i postgrey 

Once postgrey is installed we need to tell postfix to check in with the postgrey daemon running on localhost port 60000. Add The check_policy_service directive to the smtpd recipient checks line. We suggest adding this check as the very first check as it is very inexpensive to run. For example, doing a DNS lookup to check if the doamin is vailid takes more network and CPU time then simply checking with postgrey to see if we should communicate with the remote ip in the first place. Here we see the check_policy_service directive added to the checks from our postfix example above.

smtpd_recipient_restrictions =  check_policy_service inet:127.0.0.1:60000,
                                reject_non_fqdn_sender,
                                reject_non_fqdn_recipient,
                                reject_non_fqdn_hostname,
                                reject_invalid_hostname,
                                permit_mynetworks,
                                reject_unauth_pipelining,
                                reject_unknown_sender_domain,
                                reject_unknown_recipient_domain,
                                reject_unauth_destination,
                                reject_unknown_client,
                                permit

The last step is to start the postgrey daemon (/etc/init.d/postgrey restart or similar) and then restart the postfix deamon (postfix reload). Thats it.





Comcast now requires sending mail through smtp.comcast.net port 587. What can I do?

In an effort to reduce the amount of spam coming from their networks, certain ISPs are now requiring their users to use authenticated smtp (SASL). Smtp-Auth requires the user to connect to the ISP's mail server on a given port and authenticate with their user-name and password.

Our goal here is to:

We can setup Postfix to relay mail through the ISP's mail server using SASL and still accept mail using plain text. Lets get started.

First, you must check if the version of postfix you are using is "cyrus" enabled. If it is _NOT_ you must either build one or find a postfix package that has it built in. For example, OpenBSD has a postfix package with cyrus as well as sasl2. Execute the following to see a list of allowed SASL client implementations:

root@machine: postconf -A
cyrus

Next, add the following lines into your /etc/postfix/main.cf file. For example, this config relays all outgoing mail through the Comcast server smtp.comcast.net port 587 using SASL authentication (default security type is cyrus). Add these lines to the example configuration above for a complete example.

### Relay Host this mail server should send its mail to.
relayhost = [smtp.comcast.net]:587

### Relay Client SASL Authentication 
smtp_sasl_auth_enable = yes
smtp_sasl_security_options =
smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd

Lastly, we need to setup the SASL password file. Edit or make a file called /etc/postfix/sasl_passwd. Use the following format:

smtp.comcast.net USERNAME:PASSWORD

The username and password were given to you by the ISP. They are the same u/p you would use to pop3 your mail or log into webmail.

Once you have all the files edited you need to make a db hash of the sasl_passwd file and reload postfix for the changes to take effect.

postmap /etc/postfix/sasl_passwd
postfix reload

Now, send some mail and watch the /var/log/maillog file for any problems. Also, make sure that mail from external sources can get back to your box and are delivered properly if you have postfix setup to receive mail.

OPTIONAL STEP: As a precaution you might want to blocked all traffic _out_ of your box to port 25. This might be a bit paranoid, but you do not want to accidentally contact the comcast servers on port 25 and get blocked.

If you use OpenBSD and Pf you can use the following rule:

# Relay mail through Comcast (do not allow port 25 out to avoid getting blocked)
block out log quick on $ExtIf inet proto tcp from any to any port smtp

After this line is in place you can try "telnet smtp.comcast.net 25". The firewall will block the packet and give the error, no route to host.





How can I use Google's Gmail as a SMTP server instead of using my ISP's mail server?

Google offers the ability to relay mail through their servers using TLS encryption and SASL2 authentication. This is a great way to bypass your ISP's mail limitations or aggressive spam filtering like Comcast and Verizon do. They are notorious for incorrectly configured or overly aggressive spam filters that deny outgoing email from their customers.

The best part is Gmail is free _AND_ you can relay mail from anywhere in the world through your gmail account. Another positive feature is you can set up any "From:" addresses you want to. This make it easy to send mail through Gmail's SMTP server and have the recipient reply-to a mail account other than gmail.



What do we want to accomplish?

We want to send out all of our mail through postfix to the Gmail smtp servers using SASL2 and TLS on port 587. We want our mail to have the "From:" and "Reply-To" headers set to our private domain email address myuser@example.org as set in our client and not the gmail email address we signed up with.



1. Sign up for a free Google Gmail account

First, you need to sign up for a free gmail account. Goto Gmail: Email from Google (google search page) and sign up. Once you have the account made make note of your USERNAME and PASSWORD as we will need those two items in a later step. If you have an existing Gmail account that will work too.

While logged into your account goto the "Settings" section and then into the tab called "Accounts". We need to add the email addresses we would like to have mail go out as. The top section labeled, "Send mail as: (Use Gmail to send from your other email addresses)" is where we will add our addresses.

For example, lets say we want all email which people respond to, to be delivered to myuser@example.org . We would add that email to the "Send mail as:" section and enter the same email into the sub-option "Reply-to address:". Gmail in turn will send a verification email to the myuser@example.org address which we will get a verification code from. That verification code will be entered into gmail only once. Then the "From:" address, myuser@example.org, will be a validated address. Now, when our mail client sends mail though gmail and the From: address is myuser@example.org gmail will not overwrite the header with our gmail email address.



2. Copy in a working OpenSSL config file (/etc/ssl/openssl.cnf)

We will be making our ssl certificate on an OpenBSD box. The default openssl certificate authority configuration file in /etc/ssl/openssl.cnf on OpenBSD is striped down so much that we need to make a new file. Without a working config you will get the error, "variable lookup failed for ca::default_ca" when you try to use the "openssl ca..." command. You may not need this step on all OS's, but it does not hurt. The following text block is our new /etc/ssl/openssl.cnf . You are welcome to copy and paste it in place of the original file.

# OpenSSL configuration file. ( /etc/ssl/openssl.cnf )
# Calomel.org at https://calomel.org
#
# Establish working directory.
dir= .

[ ca ]
default_ca= CA_default

[ CA_default ]
serial= $dir/serial
database= $dir/index.txt
new_certs_dir= $dir/newcerts
certificate= $dir/cacert.pem
private_key= $dir/private/cakey.pem
default_days= 3650
default_md= md5
preserve= no
email_in_dn= no
nameopt= default_ca
certopt= default_ca
policy= policy_match

[ policy_match ]
countryName= match
stateOrProvinceName= match
organizationName= match
organizationalUnitName= optional
commonName= supplied
emailAddress= optional

[ req ]
default_bits= 1024# Size of keys
default_keyfile= key.pem# name of generated keys
default_md= md5# message digest algorithm
string_mask= nombstr# permitted characters
distinguished_name= req_distinguished_name
req_extensions= v3_req

[ req_distinguished_name ]
# Variable name  Prompt string
0.organizationName= Organization Name (company)
organizationalUnitName= Organizational Unit Name (department, division)
emailAddress= Email Address
emailAddress_max= 40
localityName= Locality Name (city, district)
stateOrProvinceName= State or Province Name (full name)
countryName= Country Name (2 letter code)
countryName_min= 2
countryName_max= 2
commonName= Common Name (hostname, IP, or your name)
commonName_max= 64

# Default values for the above, for consistency and less typing.
# Variable name  Value
0.organizationName_default= Example
localityName_default= SomeCity
stateOrProvinceName_default= HI
countryName_default= US
commonName_default= example.org

[ v3_ca ]
basicConstraints= CA:TRUE
subjectKeyIdentifier= hash
authorityKeyIdentifier= keyid:always,issuer:always

[ v3_req ]
basicConstraints= CA:FALSE
subjectKeyIdentifier= hash
##########################################################################





3. Making the temporary SSL build environment

The following commands will make a directory called "working" and switch to that directory. This directory is only temporary and can be deleted once the certificates are built. To build the certificates we will need two sub directories "newcerts" and "private" which are defined in our /etc/ssl/openssl.cnf. These will hold the certificate and private keys we generate. Finally, we need a serial number file called "serial" populated with a generic value of "01" and an empty "index.txt".

mkdir working
cd working
mkdir newcerts private
echo '01' > serial
touch index.txt



4. Create the Certificate Authority files

In cryptography, a certificate authority or certification authority (CA) is an entity which issues digital certificates for use by other parties. It is an example of a trusted third party. CAs are characteristic of many public key infrastructure (PKI) schemes. We will create a CA to be used in conjunction with the Gmail CA. This is the trust relationship we establish making sure our communication with Gmail is secure. The following command will create the private "cakey.pem". You are free to answer the questions that are asked while making the certificate any way you want. The gmail server does not seem to care. If you use the openssl.cnf file from above, we put in some default answers you are welcome to use.

openssl req -new -x509 -keyout private/cakey.pem -out cacert.pem



5. Create a Public Certificate

A public key certificate (or identity certificate) is an electronic document which incorporates a digital signature to bind together a public key with an identity information such as the name of a person or an organization, their address, and so on. The certificate can be used to verify that a public key belongs to an individual. We are using some of the default answers from the openssl.cnf file above.

openssl req -new -nodes -subj '/CN=example.org/O=Example/C=US/ST=SomeCity/emailAddress=noreply@example.org' -keyout example_gmail-key.pem -out example_gmail-req.pem



6. Sign your Certificate

openssl ca -out example_gmail-cert.pem -infiles example_gmail-req.pem



7. Copy the Certificates into the Postfix directory and set permissions

The following lines will copy the necessary certificates to the postfix directory and make sure the files have the minimum necessary permissions per file.

cp cacert.pem example_gmail-key.pem example_gmail-cert.pem /etc/postfix/
chmod 644 /etc/postfix/cacert.pem /etc/postfix/example_gmail-cert.pem
chmod 400 /etc/postfix/example_gmail-key.pem



8. Retrieve the Certificates for Gmail from Thawte and add them to cacert.pem

Now, we need to get the public certificates Gmail uses and bind them to ours. Google uses thier own SSL certificate and Equifax as their certificate Authority. using the openssl secure client we can collect both certs and then add them to our postfix cacert.pem file binding them together.

echo "GET" | openssl s_client -connect smtp.gmail.com:995 -showcerts | sed -n '/BEGIN CERTIFICATE/,/END CERTIFICATE/p' > gmail_cert.pem
cat gmail_cert.pem >> /etc/postfix/cacert.pem



9. Edit the Postfix main.cf to include TLS and SASL2 for Gmail authentication

The following should be added to your /etc/postfix/main.cf file. This will add all of the TLS and SASL2 options necessary to get postfix to authenticate properly to the Gmail smtp servers. For the specifics of each option please check the postfix man page.

### GMAIL Relay Host and Smtp-Auth options
relayhost = [smtp.gmail.com]:587
smtp_tls_CAfile = /etc/postfix/cacert.pem
smtp_tls_cert_file = /etc/postfix/example_gmail-cert.pem
smtp_tls_key_file = /etc/postfix/example_gmail-key.pem
smtp_tls_session_cache_database = btree:/var/run/smtp_tls_session_cache
smtp_use_tls = yes
smtpd_tls_CAfile = /etc/postfix/cacert.pem
smtpd_tls_cert_file = /etc/postfix/example_gmail-cert.pem
smtpd_tls_key_file = /etc/postfix/example_gmail-key.pem
smtpd_tls_received_header = yes
smtpd_tls_session_cache_database = btree:/var/run/smtpd_tls_session_cache
smtpd_use_tls = yes
tls_random_source = dev:/dev/urandom
smtpd_sasl_auth_enable = no
smtp_sasl_auth_enable = yes
smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd
smtpd_sasl_local_domain = $myhostname
smtp_sasl_security_options = noanonymous
#smtp_sasl_security_options =
smtp_sasl_tls_security_options = noanonymous
smtpd_sasl_application_name = smtpd



10. Make a Postfix SASL2 username and password file

Postfix will use the following server name, port, gmail address and gmail password to authenticate you to the gmail server. This file is located in the postfix directory at /etc/postfix/sasl_passwd . Once you enter the following information into the file you will need to execute "postmap /etc/postfix/sasl_passwd" to make a db version of the file which postfix can read (/etc/postfix/sasl_passwd.db).

[smtp.gmail.com]:587 USERNAME@gmail.com:PASSWORD



11. Done. Restart Postfix, check the logs and clean up

Now is the time to start postfix and send out some mail. If your client is already setup to send mail with your From: address set as "myuser@example.org" then Gmail's smtp server will honor it and send the mail through with the proper headers. You can also delete the "working" directory and all files it contains as they are no longer needed.

start ##  postfix start
logs  ##  tail -10 /var/log/maillog







Questions?

How can I test POSIX extended regular expressions on the command line?

Postfix use POSIX extended regular expressions. For example, the client_restrictions file is in this format. You need to use grep with the "-E" flag which will interpret the pattern as an extended regular expression (i.e. force grep to behave as egrep). Lets say we had a client_restriction line we wanted to test like, "/^[0-9][0-9][0-9.][0-9A-Za-z.]/" against the known spammer hostname "80.Red-80-25-34.staticIP.rima-tde.net". If you get the string printed on the next line the pattern matches, if nothing prints on the next line then the pattern did _not_ match.
user@machine: echo "80.Red-80-25-34.staticIP.rima-tde.net" | grep -E '^[0-9][0-9][0-9.][0-9A-Za-z.]' 
80.Red-80-25-34.staticIP.rima-tde.net

How about a list of SMTP reply error codes?

Code 	Meaning
200 	(nonstandard success response, see rfc876)
211 	System status, or system help reply
214 	Help message
220 	(domain) Service ready
221 	(domain) Service closing transmission channel
250 	Requested mail action okay, completed
251 	User not local; will forward to (forward-path)
354 	Start mail input; end with (CRLF).(CRLF)
421 	(domain) Service not available, closing transmission channel
450 	Requested mail action not taken: mailbox unavailable
451 	Requested action aborted: local error in processing
452 	Requested action not taken: insufficient system storage
500 	Syntax error, command unrecognized
501 	Syntax error in parameters or arguments
502 	Command not implemented
503 	Bad sequence of commands
504 	Command parameter not implemented
521 	(domain) does not accept mail (see rfc1846)
530 	Access denied (???a Sendmailism)
550 	Requested action not taken: mailbox unavailable
551 	User not local; please try (forward-path)
552 	Requested mail action aborted: exceeded storage allocation
553 	Requested action not taken: mailbox name not allowed
554 	Transaction failed

How do I make a db file?

Postfix has a tool called "postmap" and this will convert a text file to a db file. If you have the text file in hash format /etc/postfix/helo_access and you need to make it a db file then cd to /etc/postfix and execute "postmap helo_access".

Can you suggest a Postfix statistics or reporting tool?

A really nice script called "pflogsumm" is available to give you stats on the postfix mail logs. You can find a full write up here at calomel.org on the Pflogsumm - The Postfix Log Entry Summarizer page.

Can you point me to a listing of the directive definitions in the main.cf file?

You can find a full listing of all of the directives and a descriptions of each on the Postfix Documentation page.





Questions, comments, or suggestions? Contact Calomel.org or