Acting as a relay server

You may have domains that are not going to store their mail on this server but instead want this box to clean up their mail for them and then relay it on to them. You use relay_domains and transport_maps to configure those domains you wish to relay to. The biggest issue you have to deal with in this scenario is how to reject mail to invalid users. The downstream servers may know who their valid users are, but this server does not. Nonetheless, you must obtain this information one way or another so you can reject mail to invalid users. Each domain you relay for will need an entry in the transport map. The left hand side is the domain and the right hand side is the host name or IP address of the next hop server (with square brackets used to turn off MX lookups). This is the general format of the contents of /etc/postfix/transport:
example.net relay:[777.777.777.777]
example.org relay:[mail.example.org]


Postfix offers two different ways of figuring out if a recipient's address is valid or not. In one method, you supply a list of valid recipients, and Postfix looks up the address in the table. If a recipient is not in the table, the mail is rejected. In the second method, Postfix probes the downstream server prior to accepting the message. If the downstream server rejects the attempt to send a message to a particular recipient, then Postfix will also reject the message. The second method only works when the downstream server in fact does immediately reject mail to invalid users (not all do). In my example below, I use a combination of both.

Let's say we have added two domains, one (example.net) relays mail to a server running sendmail and the other (example.org) relays mail to a server running Microsoft Exchange 2000. Our server will accept mail addressed to any recipient in either domain. This particular sendmail server is configured to immediately reject mail to invalid users. When it rejects a message, Postfix will create a bounce notice and attempt to deliver it to the sender. If the sender is completely bogus, the message will sit in our deferred queue for days while delivery attempts are made. If the sender is faked, but points to a real address, then we are spamming an innocent victim. This victim is getting "joe jobbed" - and we are facilitating it - and now we are a source of backscatter. If we send a message to the domain that forwards to the sendmail server, we can see from the bounce notice that the downstream server (at the hypothetical address of 777.777.777.777) rejected it:
<testgarbage@example.net>: host sfa.example.com[111.111.111.111] said: 550
    <testgarbage@example.net>: Recipient address rejected: undeliverable
    address: host 777.777.777.777[777.777.777.777] said: 550 5.1.1
    <testgarbage@example.net>... User unknown (in reply to RCPT TO command)
    (in reply to RCPT TO command)
In this case (the case being the downstream server immediately rejects mail to invalid users) we can use either address verification or relay_recipient_maps. Basically, with address verification (reject_unverified_recipient), Postfix first checks the downstream server to see if it will accept a message to the recipient or not, prior to accepting the message. If the downstream server rejects the message (due to invalid recipient address), so will Postfix (before it accepts the message). On the other hand, if you use relay_recipient_maps, relay_recipient_maps requires that all known good recipient addresses (for the domains listed in relay_domains) are in a lookup table. Mail addressed to a recipient whose domain is listed in relay_domains, that is not also listed in the table defined in relay_recipient_maps, is rejected.

If we relay a message to the Exchange server, the particular Exchange server in our example accepts the message and later generates a bounce notice which it mails to the sender. We can only use relay_recipient_maps in this case where the downstream server does not immediately reject messages addressed to invalid users. Let's continue by first setting up address verification for example.net (the domain using the sendmail server). I will illustrate this mixed setup in which both reject_unverified_recipient and relay_recipient_maps will be utilized. Keep in mind that for your setup, you will have to discover which relay domains of yours will immediately reject mail to invalid users and which will not (if you want to use reject_unverified_recipient that is). Keep in mind that use of reject_unverified_recipient is a convenience over use of relay_recipient_maps, but the ideal situation would be exclusive use of relay_recipient_maps for all your recipients in your relay domains. The question is - who will maintain the adding and deleting of email addresses?
vi /etc/postfix/verify_domains

and insert the domain(s) that use server(s) that will immediately reject mail to unknown users:
example.net reject_unverified_recipient

then postmap it:
postmap /etc/postfix/verify_domains

vi /etc/postfix/main.cf , make smtpd_recipient_restrictions pretty like this and add the red item in the position shown. Read the beginning (half dozen lines or so) of http://www.postfix.org/postconf.5.html:
smtpd_recipient_restrictions = 
    permit_mynetworks,
    permit_sasl_authenticated,
    reject_unauth_destination,
    reject_unlisted_recipient,
    check_recipient_access hash:/etc/postfix/verify_domains
Also add these items to main.cf:
address_verify_map = btree:/var/lib/postfix/verify_cache
# Uncomment this next line when finished testing address verification:
#unverified_recipient_reject_code = 550


postfix reload and test the setup (by sending mail to invalid users in the relay domain and reading the log). When finished testing, uncomment the unverified_recipient_reject_code line.

With the other domain (example.org on the Exchange server) we need to set up relay_recipient_maps. We will create /etc/postfix/relay_recipients. Once relay_recipient_maps is configured in main.cf, any recipient or recipient domain of a relay domain not listed in /etc/postfix/relay_recipients will get rejected. This means /etc/postfix/relay_recipients must contain every single recipient of every single relay domain this machine accepts mail for. However, domain wildcards can be used as placeholders. In our example case, example.net is already using address verification to reject mail to invalid users, so we can use a wildcard for that domain: @example.net. For example.org, we can start out with a wildcard while we are in the process of gathering valid addresses:
vi /etc/postfix/relay_recipients

@example.net OK
@example.org OK


but once we have all the address gathered, we need to get rid of the wildcard:
@example.net OK
#@example.org OK
user1@example.org OK
user2@example.org OK
user3@example.org OK
user4@example.org OK


Then of course:
postmap /etc/postfix/relay_recipients

The "OK" after each entry could be something else, like "1" or something. It's not important what the actual text is, because it's not used for anything, but it must exist. To set up relay_recipient_maps:
postconf -e "relay_recipient_maps = hash:/etc/postfix/relay_recipients"
postfix reload


If you have an Exchange server, there are some links available that may provide some help on using programs that help gather the list of valid users.
http://verchick.com/mecham/public_html/spam/postfix_exchange.html
http://verchick.com/mecham/public_html/spam/relay_recipients.html
http://www.unixwiz.net/techtips/postfix-exchange-users.html
http://postfix.state-of-mind.de/patrick.koetter/mailrelay/
http://verchick.com/mecham/public_html/spam/PostfixAddressExtract.vbs.txt