July 29th, 2002, 21:59
Postfix Configuration How-to for OpenBSD

The latest installment of how-to's, postfix a great mailer. OK as I've said before in most
of my how-to's I do not claim to be an expert on postfix. Merely an amature and avid admirer!
So many of you may know more about postfix and that's ok this how-to is meant to be a rough
guide to setting up postfix on OpenBSD. Your own research as always is highly recommended
i.e. DON'T JUST TAKE MY WORD FOR IT! Find out for yourself and judge! With that being said
lets go on and get started!

Postfix is a replacement for sendmail, it can be downloaded from postfix.org or made right
out of the ports collection on openbsd. It's goals are stability, security, and speed! Not
necessarily in that order, ok install from source or from the ports collection either one
it doesn't really matter to me. We're not going to cover the installation here just configuration.

Once installed change into your postfix installation dir. unless you specified differently
this directory should be /etc/postfix. The first thing we're going to do is modify the main.cf
file. This is your main configuration file. It will contain all the essential information to
getting postfix up and running!

First things first open up your main.cf file in your favorite editor (vi)
The first thing you're going to modify is the following line:

"myhostname = your.servername.here"

This line will set the mail server host name of your box. This
cannot be any arbitrary name, it MUST be a fully qualified domain
name!! Moving on.

The next line to modify is:

"mydomain = some.domain.name"

Again this sets the default domain of the box, this must be a
Fully Qualified Domain Name Here!

The next line to look at is the following line:

"myorigin = $mydomain"

Make sure this variable is set correctly! "$mydomain" is a
valid global variable for the file so you should be good with that!

The next line to modify is the following:

"mydestination = $myhostname, localhost.$mydomain $mydomain virtualdomain1 virtual domain2"

Obviously this example assumes you'll be setting up virtual domains, It also assumes you'll be
setting up sendmail style virtual domains, now I know the file says use the virtual file instead
I don't do that, I specify here, sendmail style, you may not want to do that that's fine with me
just understand in this how-to we'll be setting up sendmail style virutal domains.

Moving On, the next line I modify is the following:

"home_mailbox = Maildir/"

DO NOT uncomment this line if you do not intend to use imap. if you are
using pop or traditional /var/mail spool to deliver mail this is not needed
and will undoubtedly mess up your mail delivery. If you are using courier-imap
this line needs to be uncommented!

Moving right along the next line I modify is the:

"relay_domains = $mydestination,"

This will only allow messages to be accepted where the final destination domain
is on this box. It also allows delivery over the loopback interface!

Now, modify the following:

"mynetworks = xxx.xxx.xxx.xxx/zz,"

This only allows mail to be sent out to the internet from the specified ips!
This can be an entire subnet or just one box you decide.

This brings us to the next lines to modify:

"local_destination_concurrency_limit = 2"
"default_destination_concurrency_limit = 10"

These lines limit the amount of concurrent connections to a domain.
Good to have espwcially if you have a user that is forwarding mail
out of his home via the use of a .forward file.

The next lines I actually insert into the file. The are for
the canonical maps, you'll need these if the following is true:

A) you have virtual domains
B) you have virtual usernames like full.name@somehost.com mapped back to username@somehost.com

If your using one of the above add it in, if not don't worry about it!

"sender_canonical_maps = hash:/etc/postfix/canonical"
"recipient_canonical_maps = hash:/etc/postfix/canonical-receive"

We'll be going over canonical tables in more depth in a little while.
For now what you need to know is that on table modifies the incoming
mail and one will modify outgoing mail.

The following lines I also add, you may or may not want to add these,
It depends on how true you want to be to to the rfc and how strict you want
to be on other hosts trying to send mail to you! These lines will lay down
the framework for cutting down on your spam!

"smtpd_client_restrictions = reject_maps_rbl,"
"check_client_access hash:/etc/postfix/client_access,"

"smtpd_recipient_restrictions = regexp:/etc/postfix/regexp_access,"
"check_recipient_access hash:/etc/postfix/access,"

"smtpd_sender_restrictions = regexp:/etc/postfix/sender_checks.regexp,"
"check_sender_access hash:/etc/postfix/sender_access,"

ok the first section specifies rejection if a client is not in an access list
An access list is a list I use which details the exact usernames on the box.
This list is a necessity if you are running virtual domains, if you don't use it
userid1@virtualdomain1 can receive an e-mail to userid1@virtualdomain2 and so on
and so forth. This is the most effcient way I know to block this! I is also a
good practice to do even if you aren't running virtual domains (opinion). It also
specifies a lookup to the rbl list! a real time black hole list for open-relay mail servers
It also doen not allow anauthorized pipelining, not exactly sure why that's needed but it is.
If you know, let me know!

The second section does much of the same but is it for outside connections.
People trying to send mail in. It specifies a regular expression file
which sorts through the headers and look for junk, the access list, it rejects
mail from computers that don;t have a fqdn it also reject is it can't get the
computer hostname through nslookup, it also rejects via the rbl list and the pipelining again!

Ok the next section is a lot more of the same. Nothing really new to explain here!

The next line I add is my rbl line, defining what list to use.
I personally use the ordb list it can be found at http://ordb.org
I like it a lot and it's free!

"maps_rbl_domains = relays.ordb.org"

The next things added are the following body and header checks.
They specify lookup files to runagainst all incoming and
outgoing messages!

"header_checks = regexp:/etc/postfix/header_checks"
"body_checks = regexp:/etc/postfix/body_checks"

The final things I add are a couple of reject codes and a message
size limit self-explanatory, here they are!

"unknown_hostname_reject_code = 554"
"unknown_client_reject_code = 450"
"message_size_limit = 5000000"

With this done, we are now through with the main.cf file. Save it and let's
move on with our next section configuring the rest of postfix!


The Access file

This file is the definitive list as that decides who to accept incoming mail
from the internet for. If you defined it earlier in the main.cf file it must
be defined here. basic syntax is one user per line followed by an OK
so edit /etc/postfix/access now

"userid1@domain1 OK"
"userid2@domain1 OK"
"userid3@domain2 OK"

etc. etc. Now for a little postfix sorcery, don't specify
an account if you don't want them to have the ability to receive internet mail
for instance, if you only want the ability for someone to mail local accounts
(accounts only contained on your box, leave them out of here) Also, if you are
running lots of Virtual domains, you may want to specify system account for each domain,

"webmaster@domain1 OK"
"webmaster@domain2 OK"
"postmaster@domain1 OK"
"postmaster@domain2 OK"

remember if the specific e-mail you want to receive mail from is not listed in this
file it will bounce. Once you've entered in all your info save that file. From here you
must make that file into a hashed db, also after any updates you make to this file in the future
you must recompile that hashed db to include your new accounts. Do this by typing the following:

"/usr/local/sbin/postmap access"

Also to avoid any delay you should always reload postfix, don't do that now because we havn't
turned postfix on yet! It can be done like this:

"/usr/local/sbin/postfix reload"


The next files we'll look at are, /etc/postfix/canonical and /etc/postfix/canonical-receive.
Again, if you're not using canonical tables specified in your main.cf file, you don't need to
worry aboutit here.


The canonical file as defined in this how-to will remap a users e-mail from the default domain
to the appropriate virtual domain, if this is the case you need to specify all users except those
in the default domain of the box here! Also if you are mapping a local account to use a another
name eg. userid1 -> full.name you need to specify that here. Sysntax is:
userid@domain userid@virtualdomain, or, userid@domain full.name@domain this file handles mail
outgoing only! edit /etc/postfix/canonical now

"userid@defaultdomain userid@virtualdomain"
"userid2@defaultdomain userid2@virtualdomain"


"userid@defaultdomain full.name@defaultdomain"


This file is used for incoming mail, it is used to clean up, so that
the virtual addresses don't get remapped to the default domain. All
users should have an entry here including system accounts unless they are on the
default domain of the box alone, and not using virtual usernames. With that
let's edit /etc/postfix/canonical-receive now!

"userid1@defaultdomain userid1@defaultdomain"
"userid1@virtualdomain userid1@virtualdomain"
"userid2@virtualdomain userid2@virtualdomain"
"postmast@virtualdomain userid2@virtualdomain"
"webmaster@defaultdomain webmaster@defaultdomain"
"webmastr@virtualdomain userid2@virtualdomain"

or for virtual usernames

"full.name@domain userid@domain"

got it? Good, it's not that difficult now is it. Again once you're done
with these files youll need to make a hashed db out of them using the postmap command
and you'll need to reload postfix. you remember how to do that right? Good!
You're on your way.....


The next file we'll be looking at is the /etc/postfix client_access file.
This file will specify a list of exceptions and specific denials of
mail servers. For instance, your friend, god bless him, has a mail server
but is pretty clueless when it comes to dns, he hasn't configured his dns
to reverse lookup properly. Well you could bypass that here. also, you have
some evil spammer that keeps sending you mail and the rbl list isn't blocking
him, you could add a specific block here. syntax of this file is xxx.xxx.xxx.xxx function
where x is an ip address and function is either OK or REJECT!

"xxx.xxx.xxx.xxx OK"
"xxx.xxx.xxx.xxx REJECT"

after making this file do you know what you need to do? That right you must make
a hashed db out of this file as well! Ok that's done let's move on!


This file /etc/postfix/sender_access is where you can specify specific
e-mail addresses or domain to block. Usually bogus spam addresses. Syntax is
fakeemail@bogusdomain.com function where the function is a reject code.

"fakeemail@fakedomain.com 550 No Spam Accepted"
"fakedomain.com 550 What kind of bogus address is that?"

etc. etc. This file further solidifies you box and you your place
as an anti-spam ninja! -For you McDonald!

You'll need to make this file a hashed db as well once you're done with it!


The next file we'll be looking at is /etc/postfix/body_checks. This file is either a
regex file or a pcre file (if you compiled postfix with pcre support) I mainly use this file
to block troublesome attachments I have no use for anyways. The following blocks certain
types of attachments. Self explanatory.

"/^(.*)name="(.*). (com|vbs|vbe|js|jse|exe|bat|cmd|vxd|scr|hlp|swf|mp
eg|mpg|mov|mp3|avi|pif|mpe|shs|ini)"$/ REJECT"

This will help out with viruses among other things, you won't have to worry about vbs scripts
and that sort of stupid thing from now on. This file just needs to be in place. There is NO
need to make it a hashed db. Although after making changes DO reload postfix!


The next file we'll take a look at is /etc/postfix/header_checks. This file does
exactly as it says. It checks mail headers. Again either regex or pcre.
I will give a couple of examples here that I use:

# This will block 8 non ascii characters in a row, which shouldn't be in the
# header anyway according to the RFC... Japan and Chinese spammers...
"/[^[:print:]]{8}/ REJECT"

# Pegasus uses "Comments: ..." not "Comment: ...". spammers got it wrong.
"/^Comment: Authenticated sender is/ REJECT"

These are just a couple examples. My files is actually really large for this.
You can spend a lot of time doing this! Try to avoid going crazy, as it can
be fairly obsessive! Again no hashed bd needed, just reload postfix when you finish altering.


The next file to look at is regexp_access, this file pretty much doen some more of the
same, kicking spammers where it hurts! Here is an example I have in mine!

"/[%!@].*[%!@]/ 550 Sender specified routing is not supported here."

there you see not too bad huh. ok again reload postfix when your done no db needed
and lets move on.


lets edit /etc/aliases

The aliases file is very limited with the configuration we have specified here.
It does need some things filled in. Standard system aliases should be placed here,
aliases for root, postmaster, abuse, etc. etc. Also if you are running majordomo
you'll specify your outgoing secrets here, If you're forwading mail to another domain,
and not using a .forward file in your home, specify that here as well. Other than that
you should be good to go.


ok now our configuration is complete, let's start up postfix!
run the following

"/usr/local/sbin/postfix start"

It should start-up error free! Go have some fun!


If you found this how-to useful, send me a pm or leave a comment. I'd love to hear from you.

February 23rd, 2003, 20:57
Verry nice howto there... if i can make 1 note inside the postfix logs you get an error:

warning: restriction reject_maps_rbl is going away. Please use reject_rbl_client <domain>

still works but something to keep note of...

February 23rd, 2003, 21:15
Kewl glad you found some use for it Soup, when the how to was written, the reject stuff was right on, so I suppose I could update it now. Thanks for the input.

February 24th, 2003, 10:04
and if anybody is interested daemonnews has a good article on setting up sophis and amavis for postfix


March 8th, 2003, 16:35
If you want i've updated your howto and the spamassasin howto..

over here

i've also add in instructions on using qmails ldap, imap-ssl pop-ssl, imap, pop, and i'm also going to add in howto setup sophis and amavis

June 24th, 2003, 22:23
Hi All

K, willing to give postfix a try, everyone who is anyone in bsd sings its praises everywhere I go. Noob question No. 1 - when attempting to make install clean, I get a screen up with "Please select desired options"
I have no idea if I want Berkley BD3, PostgreSQL, tried selecting all and BSD told me (very politely I might add, BSD makes windows look like an asshole really dosen't it) that I can't do that. Read your how to on postfix elmore, looks fine, keen to give it a go but not sure of this first step, also the how to dosen't seem to say how to disable sendmail, should this be done or does postfix take over automatically ? I have read that in rc.conf you must keep sendmail enabled to get postfix to boot up with 'the world'
Anywhere I can read up on what to select at this first screen ? Been to the Postfix website, but I couldn't find what I was after there.

Thanks everyone

June 25th, 2003, 00:12
select one db or the other, postgress is prolly better. Then a make followed by a make install should take care of removing sendmail, if not try a make install replace.

June 25th, 2003, 00:24
Thanks Elmore

Kewl Banyanas, postfix is away and installing, I will prolly be back yet :)


June 25th, 2003, 09:19
last time i installed it make install clean worked, the make process will ask you if you would like to activate postfix in your mailer.conf

postfix is badass and fun to play with

August 5th, 2003, 20:40
Just wanted to ask a quick question here.

One thing i've been wondering about is setting all anti-UCE checks under smtpd_recipient_restrictions and not having a seperate smtpd_client_restrictions.

The reason I ask is: if I have smtpd_delay_reject = no, nothing will be rejected until after RCPT TO, correct? And since by default, smtpd_delay_reject is set to yes, putting everything under smtpd_recipient_restrictions would be cleaner and easier?

With that in mind, I was wondering if I could send up the following, under smtpd_recipient_restrictions, for use of rbl:

all my rejects at top
reject_rbl_client relays.ordb.org
reject_rbl_client list.dsbl.org
and so forth

Here is a quick output of my smtpd_recipient_restrictions:

[code:1:6247bd0358]smtpd_recipient_restrictions = permit_mynetworks, reject_invald_hostname, reject_unknown_hostname, reject_non_fqdn_hostname, reject_unauth_destination, reject_rbl_client relays.ordb.org, permit

Would that work?