Maia Mailguard SVN 1581 Ubuntu 12.04 or Debian squeeze FAST install


Absolutely no warranty, use entirely at your own risk. See the disclaimer at http://verchick.com/mecham/public_html/spam/

This document assists with QUICKLY setting up Maia Mailguard (SVN 1581), Postfix, SpamAssassin, Razor, Pyzor, DCC, MySQL, Apache, ClamAV, SaneSecurity and optionally Postgrey and/or Bind9, on a new Debian squeeze or Ubuntu Precise Pangolin Server computer. The script that does most of the work assumes that you just installed the OS and have not configured anything on it yet. Initially Postfix will be configured to relay mail for one domain through this spamfilter machine. You provide the IP address where the mail will be relayed to. This document is not a tutorial in any fashion.

Save this document to your computer. If using Internet Explorer, save as "Web Page, HTML only (*.htm,*,html)" then use a plain text editor - like WordPad for example, and replace the text sfa with a hostname of your choice. You also need to replace the text example.com with the domain name of your server. Lastly, replace the text Widgits Inc. with the name for your company. Once completed, open this page from the copy you saved. Do not replace these items more than once.

A few hints on OS installation:
Your machine should have at least 1GB RAM.
If using Ubuntu, install Ubuntu Server 12.04. Here is a starting point http://www.ubuntu.com/download/server/download
If using Debian squeeze, use either the i386 (32-bit) or amd64 (64-bit) netinst CD http://www.debian.org/releases/squeeze/debian-installer/
Note that amd64 CDs are for Intel and AMD X86-64 processors. The ia64 CDs are only for Itanium processors.
When you get to the point the installer asks for the Hostname:, choose [Go Back] and then Configure network manually.
For the DNS server address, please use the IP address of a real DNS server, not your broadband router's gateway address.
I do not choose to install any additional packages in Ubuntu.
In Debian, during tasksel, please deselect [  ] Graphical desktop environment.
In Ubuntu, I run as root during setup. Either run 'sudo su' and then 'cd' before running the install script, or enable root account by entering the following command:
sudo passwd root
This will prompt for your current user's password, then prompt for a new root password, and once you confirm it, you can start using the root account to login.
See Debian squeeze installation walkthrough or Debian squeeze installation walkthrough using software RAID1
Ubuntu installation is somewhat similar.

This guide does not cover important configuration settings that need to be made once the software is in place; it just gets you to the point where you can log into Maia. This guide does not explain how to use Maia Mailguard, it merely gets it up and running. It uses many of the default settings (which may not filter mail). I don't use Maia myself, so I cannot be helpful regarding the configuration or use of the program. In order to get ClamAV working with Maia on Ubuntu, my script does remove AppArmor. On Debian, it disables NFS and portmap from starting up. The Postfix configuration is minimal for a relay server. There is no support for this document. For help with Maia, you should join the Maia users mailing list http://www.renaissoft.com/cgi-bin/mailman/listinfo/maia-users. I'm sure the provided script could be improved, but given the correct circumstances, it does get the job done and it saves a lot of work.

https://www.maiamailguard.com/svn/branches/1.0
https://www.maiamailguard.com/maia/browser/branches/1.0

This is for my benefit, so I can SSH into the box using PuTTY and copy and paste the rest of the commands. Running SSH does have potential security risks. Note also that I'm logged in as root:
apt-get update
apt-get install ssh vim


Change the default shell from dash to bash:
dpkg-reconfigure dash

Answer: Use dash as the default system shell (/bin/sh)? <No>

In PuTTY I suggest making (and saving) a few changes to the saved session.
In Terminal->Features check "Disable application keypad mode".
In 'Window' change Lines of scrollback from 200 to 1000.
In Window->Colours change ANSI Blue from 0,0,187 to something like 155,155,255 (a lighter color).

First, download the script and then open it in your editor in order to configure it (I use vim):
cd
wget http://verchick.com/mecham/public_html/ubuntu1204/maiascript.txt
chmod 0700 maiascript.txt
vim maiascript.txt


At the top of the script you will see the variables that need to be changed:
# configuration variables (no spaces please)
#
ROOTS_MYSQL_PASSWORD=roots_password
MAIA_MYSQL_PASSWORD=maia_password
# short hostname of your machine
HOSTNAME=sfa
# domain name of the server 
# this will also be set as a relay domain in /etc/postfix/transport
DOMAIN_NAME=example.com
# the ip address of your current SMTP/POP3/IMAP email server that we will relay mail to
RELAY_SERVER_IP=192.168.1.223
# the address of the network the spamfilter is on
NETWORK_ADDRESS=192.168.1.0
# the SVN version of Maia you are about to install
# ONLY tested with version 1581, so beware!
SVN_VERSION=1581
# users may send a message to this address if they need help
HELP_ME_EMAIL_ADDRESS=postmaster@example.com
Then run the script:
./maiascript.txt

You can expect some "errors" that are not going to affect installation:
E: Unable to locate package libperl5.10
E: Couldn't find any package by regex 'libperl5.10'

WARNING: /etc/aliases exists, but does not have a root alias.

dpkg: error: version 'configure' has bad syntax: version number does not start with digit

Sep  3 06:02:56.587 [9607] warn: config: created user preferences file: 
                                                 /var/lib/amavis/.spamassassin/user_prefs

WARNING: "pear/DB" is deprecated in favor of "pear/MDB2"

LibClamAV Warning: **************************************************
LibClamAV Warning: ***  The virus database is older than 7 days!  ***
LibClamAV Warning: ***   Please update it as soon as possible.    ***
LibClamAV Warning: **************************************************

     *************************
     *     !!! ALERT !!!     *
     * CLAMD IS NOT RUNNING! *
     *************************
Once the script completes, there will be additional instructions:
cat instructions

Hint: when you run http://sfa.example.com/mail/login.php?super=register and enter the e-mail address of the Super User (probably you), the e-mail with the password will be sent to Postfix, but Postfix may not be able to deliver it for one reason or another (maybe you still need to configure additional relay_domains and transports for example). If it's stuck in the queue, use the mailq command to see the message and obtain the message ID (the message ID will also be displayed when you use the registration page). Once you have the message ID, you can view the contents of the message and retrieve your initial password. Use the command 'postcat -q <message ID>'

Please reboot after setting the Super User (to make sure things work after a reboot):
reboot

Since the Maia system has not been configured, the default is to pass everything (including viruses and executables). Set up a domain (or at least one user account) in Maia and configure it to block spam, viruses and banned files (I never block bad headers).
I use spam settings of -999,6,6. Send a few test messages through and look for errors. Try sending a message that has the EICAR virus test string in it. Always send test messages from a remote machine, not from the shell prompt on this box. I simply set up an MUA to use this box as its SMTP server.
You can keep an eye out for errors by using:
tail -f /var/log/mail.log

If for some reason you need to temporarily switch from Maia to amavisd-new, first you would stop maiad, then turn the init scripts off and on like this:
/etc/init.d/maia stop
update-rc.d -f maia remove
chown root:amavis /etc/spamassassin/local.cf
sed -i "s/maiad/amavisd-new/" /usr/sbin/sa-update.sh
sed -i "s/maia/amavis/" /usr/sbin/sa-update.sh
update-rc.d amavis defaults
/etc/init.d/amavis start

Then to switch back to Maia:
/etc/init.d/amavis stop
update-rc.d -f amavis remove
chown root:maia /etc/spamassassin/local.cf
sed -i "s/amavisd-new/maiad/" /usr/sbin/sa-update.sh
sed -i "s/amavis/maia/" /usr/sbin/sa-update.sh
update-rc.d maia defaults
/etc/init.d/maia start

Once you are finished with basic configuration, I suggest you reboot to insure the system still functions correctly after a reboot.

Another hint. The error "WARNING: /etc/aliases exists, but does not have a root alias." can be resolved by editing /etc/aliases and setting up an alias for root. For example:
postmaster: root
clamav: root
root: garyv@example.com

And then running:
newaliases

Also vim /etc/postfix/virtual and add an alias there:
root garyv@example.com

and then:
postmap /etc/postfix/virtual


OPTIONAL: install Postgrey

Of course Greylisting will reject a ton of spam - but at a cost. Some mail will be delayed. To help out I cut the retry time from 6 minutes to 29 seconds. We will use 'selective greylisting' with the idea being we will attempt to only target clients that appear to come from dial-up and dynamic IP addresses. If you decide to implement this I also recommend you whitelist clients you trust. The whitelists are located in the /etc/postgrey/ directory. We can also whitelist senders, clients or networks in Postfix.
apt-get install postgrey

sed -i 's/--inet=127.0.0.1:60000/--inet=127.0.0.1:60000 --delay=29/' /etc/default/postgrey
sed -i 's/--inet=10023/--inet=127.0.0.1:60000 --delay=29/' /etc/default/postgrey
/etc/init.d/postgrey restart
ps aux | grep postgrey | grep -v grep

cd /etc/postfix
wget http://verchick.com/mecham/public_html/spam/check_client_fqdn
cp -ip main.cf main.cf-before-grey

postconf -e "smtpd_restriction_classes = check_greylist"
postconf -e "check_greylist = check_policy_service inet:127.0.0.1:60000"
touch greylist_sender_exceptions
postmap greylist_sender_exceptions
touch cidr_greylist_network_exceptions


In main.cf, our smtpd_recipient_restrictions should already look pretty like the sample below. Read the beginning (half dozen lines or so) of http://www.postfix.org/postconf.5.html. Now we need to add greylisting and a sender whitelist for greylisting.
Either vim /etc/postfix/main.cf or use the WinSCP editor and edit smtpd_recipient_restrictions, adding the items in red:
smtpd_recipient_restrictions =
    permit_mynetworks,
    permit_sasl_authenticated,
    reject_unauth_destination,
    check_recipient_access hash:/etc/postfix/greylist_sender_exceptions,
    check_client_access cidr:/etc/postfix/cidr_greylist_network_exceptions,
    check_client_access pcre:/etc/postfix/check_client_fqdn
Once the file is saved:
postfix reload
tail -f /var/log/mail.log


Set your MUA to deliver normally to port 25 (no authentication) and then attempt to send a message through and see if your client gets greylisted like mine did. If I wait 30 seconds I should be able to send the message. Note that my client IP is not included in mynetworks in main.cf (if it were, everything in smtpd_recipient_restrictions would be bypassed):
Jun 15 21:12:19 sfa postfix/smtpd[10095]: NOQUEUE: reject: RCPT from
 unknown[192.168.1.41]: 450 4.7.1 <unknown[192.168.1.41]>: Client host rejected:
  Greylisted, see http://isg.ee.ethz.ch/tools/postgrey/help/example.com.html;
   from=<gary@example.net> to=<garyv@example.com> proto=ESMTP helo=<nobody>


I am going to whitelist 192.168.1.0 so clients on my internal network are not subjected to greylisting. Note that typically you would simply add your internal network to the mynetworks setting in main.cf. Cidr type tables do not need to be postmapped. http://www.postfix.org/cidr_table.5.html. I will place the whitelist entry in
vim /etc/postfix/cidr_greylist_network_exceptions
192.168.0.0/16 OK

postfix reload

I am going to wipe out the entire Postgrey database in order to prove to myself that my change did in fact whitelist my network. You don't want to do this once the system is up and running (unless the database becomes corrupt). Then I am going to try to send another message.

ls -l /var/lib/postgrey/
/etc/init.d/postgrey stop
rm /var/lib/postgrey/*
/etc/init.d/postgrey start

ls -l /var/lib/postgrey/


tail -f /var/log/mail.log

And it worked:
Jun 15 21:36:51 sfa postfix/smtpd[10167]: connect from unknown[192.168.1.41]
Jun 15 21:36:52 sfa postfix/smtpd[10167]: 1EDD624218: client=unknown[192.168.1.41]



OPTIONAL: Create and install SSL Certificate and use https:

This assumes you do not already other have web sites and/or certificates set up on this machine. If you do, I would hate to see you mess that up.
apt-get install openssl

Every client that connects to this server will need to be able to resolve the hostname of the server. Hopefully you have already create an A record and an MX record for the server. We are going to be our own Certificate Authority and sign our own certificates. These commands are dependent on /etc/ssl/openssl.cnf as supplied by Debian. We start by making a small change to /etc/ssl/openssl.cnf. We make it so by default our certificates are good for 10 years instead of 1:
sed -i 's/= 365\t/= 3653\t/' /etc/ssl/openssl.cnf
grep 365 /etc/ssl/openssl.cnf


We will set up a common place to put our certificates:
cd /root
mkdir CA
cd CA
mkdir demoCA
cd demoCA
mkdir newcerts
mkdir private
echo '01' > serial
touch index.txt
cd ..


Create a Root Certificate:
openssl req -new -x509 -extensions v3_ca -keyout demoCA/private/cakey.pem -out cacert.pem -days 3653

Enter a passphrase when prompted. You will need this passphrase in the future. What I mean is: make it unique and don't ever loose it. You will be asked questions. Sample answers follow. Be sure to use the full name for your state or province name and the Common Name should be something that describes you as an authority (like Widgits Inc. RootCA):
Country Name US
State or Province Name Utah
Locality Name Salt Lake City
Organisation Name Widgits Inc.
Organisational Unit Name WebMail Server
Common Name (eg, YOUR name) Widgits Inc. RootCA
Email Address postmaster@example.com


This process produces two files as output: a private key in demoCA/private/cakey.pem and a root CA certificate in cacert.pem. Any and all key files we produce will need to be protected from unauthorized persons reading them, and must not be lost for the next 10 years. Also realize that the CA you created can sign any number of certificates (until it expires 10 years from now) so you only need to (or want to) create the CA once. We will copy our cert and our key to something more descriptive:
cp -i demoCA/private/cakey.pem demoCA/private/cakey.example.com.pem
chmod 600 demoCA/private/*
cp -i cacert.pem cacert.example.com.pem
cp -i cacert.pem cacert.example.com.crt


We will copy the root CA certificate to the web server so we can install it on clients by having them browse to it:
cp -i cacert.example.com.crt /var/www/
chmod 0644 /var/www/cacert.example.com.crt


We copy the root CA certificate to /usr/share/ca-certificates/self:
mkdir /usr/share/ca-certificates/self
cp -i cacert.example.com.crt /usr/share/ca-certificates/self/


Now, run dpkg-reconfigure ca-certificates, answer yes to "Trust new certificates from certificate authorities?" and then scroll down to self/cacert.example.com.crt, use the spacebar to select it, Tab to Ok, and press Enter to finish the job. This will create a sym-link to our CA certificate in /etc/ssl/certs:
dpkg-reconfigure ca-certificates

The cacert.example.com.pem and cacert.example.com.crt are copies of our certificate and are the files that can be distributed and installed on the client's machines. Windows clients would use the .crt file. On my Windows 2000 system, double clicking this file would install it in Internet Explorer (which is exactly what want). Simply browsing to our server will give us the opportunity to install the web server certificate we will create (this will be the Common Name sfa.example.com) but this is not the same as installing the CA certificate in the Trusted Root Certification Authorities store (seen as the Common Name you entered above). Just in case you are not familiar, in IE6 it's Tools->Internet Options->Content->Certificates->Trusted Root Certification Authorities. Outlook and Outlook Express use the same certificate store as Internet Explorer. In Mozilla Thunderbird it's Tools->Options->Privacy->Security->View Certificates->Authorities. In Firefox it's Tools->Options->Advanced->Encryption->View Certificates->Authorities->Import. If you go through this process more than once while testing, don't install duplicate certificates. Delete any old 'test' certificate you previously installed before adding your new one that replaces it. In my old version of The Bat! I add a new contact in the "Trusted Root CA" section of the address book and import the certificate from there. I suggest using WinSCP to transfer the cacert.example.com.crt certificate to your machine. I think the worst part of getting this server set up is getting the CA certificates installed on the clients. Sometimes it's worth it to buy a certificate from a well known commercial CA that is already in the Trusted Root Certification Authorities store.

OK, we are a certificate authority. We have the ability to sign our own certificates. We are now going to create a request for a certificate from the CA (which is us - but could be a commercial CA if you like). Everyone that connects to us will connect to the hostname of this machine. The Secure Web server, Secure IMAP server, Secure POP server and Postfix Secure SMTP server will all be sfa.example.com, so the Common Name MUST BE our FQDN hostname when we create the request. The Organization name needs to be the same as the one in the CA cert. Do not enter your email address, challenge password or an optional company name when generating the CSR:
openssl req -new -nodes -out req.pem

Country Name US
State or Province Name Utah
Locality Name Salt Lake City
Organisation Name Widgits Inc.
Organisational Unit Name WebMail Server
Common Name (eg, YOUR name) sfa.example.com
Email Address


This process produces two files as output, a private key in privkey.pem and a certificate signing request in req.pem. These files should be kept. The private key is of course necessary for SSL encryption. We will make backup copies of these files with more descriptive names:
cp -i privkey.pem privkey.sfa.example.com.pem

chmod 600 privkey.*
cp -i req.pem req.sfa.example.com.pem


Sign the Certificate (you will be asked for the pass phrase):
openssl ca -out cert.pem -cert cacert.pem -infiles req.pem

This process updates the CA database and produces two files as output, a certificate in cert.pem and a copy of the certificate in demoCA/newcerts/ named xx.pem, where xx is the serial number. We will copy the cert to a more descriptive name. The certificate has both the encoded version and a human-readable version in the same file. We want to strip off the human-readable portion as follows:
mv -i cert.pem temp.cert.sfa.example.com.pem

openssl x509 -in temp.cert.sfa.example.com.pem -out cert.pem
cp -i cert.pem cert.sfa.example.com.pem


Postfix will want the cert and the key in two separate files, apache2 will want the two combined (but can use two separate files if configured to do so).
cat privkey.sfa.example.com.pem cert.sfa.example.com.pem >key-cert.pem
cp -i key-cert.pem key-cert.sfa.example.com.pem

chmod -R 600 /root/CA


After those steps, you have three installable components (and some more descriptive backup copies):
A private key in privkey.pem (with a copy in privkey.sfa.example.com.pem)
A certificate in cert.pem (with a copy in cert.sfa.example.com.pem)
A combined private key and certificate in key-cert.pem (with a copy in key-cert.sfa.example.com.pem)

Now give a copy of the combined certificate to Apache2. We will configure sfa.example.com in Apache2 to use /etc/apache2/key-cert.sfa.example.com.pem:
/etc/init.d/apache2 restart

cd /root/CA/
cp key-cert.sfa.example.com.pem /etc/apache2/
chmod 600 /etc/apache2/key-cert.sfa.example.com.pem


Now we will configure Apache2. First enable the SSL module, and we will also enable the rewrite module so we can optionally redirect port 80 requests to port 443:
a2enmod ssl
a2enmod rewrite


We will make a copy of the default site. This copy will be used for configuration of the SSL site:
cp /etc/apache2/sites-available/default /etc/apache2/sites-available/ssl

Now edit /etc/apache2/sites-available/default:
vi /etc/apache2/sites-available/default

And change:
<VirtualHost *:80>
        ServerAdmin webmaster@localhost

        DocumentRoot /var/www/
To:
<VirtualHost *:80>
        ServerAdmin webmaster@example.com
        ServerName sfa.example.com
        DocumentRoot /var/www/
Now edit /etc/apache2/sites-available/ssl:
vi /etc/apache2/sites-available/ssl

And change:
<VirtualHost *:80>
        ServerAdmin webmaster@localhost

        DocumentRoot /var/www/
To:
<VirtualHost *:443>
        ServerAdmin webmaster@example.com
        ServerName sfa.example.com
        SSLEngine on
        SSLCertificateFile /etc/apache2/key-cert.sfa.example.com.pem
        DocumentRoot /var/www/
Once the files have been edited, enable the new site we called ssl, and restart Apache2:
a2ensite ssl
/etc/init.d/apache2 restart


If you did it like I did it, you should have no errors when it shuts down or starts up. If it does not start up, you can disable the ssl site with 'a2dissite ssl'. See /var/log/apache2/error.log for clues to the problem. Now you should be able to browse to both: http://sfa.example.com/mail and https://sfa.example.com/mail.

If you have not already installed the Root CA certificate on your computer, see if you can install it by downloading it via your browser at http://sfa.example.com/cacert.example.com.crt

Note that if you created a root certificate and installed it on your computer, and then started this process over and created a new one with the same name, you would have to remove the duplicate "test" certificate and install the new certificate. I have enabled port 80 only as a convenience. We don't want people to connect to our site without using SSL, so I am going to set up redirection. This is optional, but highly recommended. Edit /etc/apache2/sites-available/default once again:
vi /etc/apache2/sites-available/default

And insert these additional items in the location shown:
<VirtualHost *:80>
        RewriteEngine   on
        RewriteCond     %{SERVER_PORT} ^80$
        RewriteRule     ^(.*)$ https://%{SERVER_NAME}$1 [L,R]
        RewriteLog      "/var/log/apache2/rewrite.log"
        RewriteLogLevel 2
Then restart Apache2:
/etc/init.d/apache2 restart

Now, if you close down the browser window for http://sfa.example.com and then browse to it again, you should be redirected to the SSL site. This is a bit wasteful however as twice as many processes are required to maintain both port 80 and port 443. If you like, you can optionally prevent Apache2 from starting up processes on port 80 by editing /etc/apache2/ports.conf and commenting out 'Listen 80' then restarting Apache2. Of course, then your users will always have to remember to use the https:// URL. BTW, personally I use lsof -P | grep LISTEN to show what ports are in use. Note that I am an Apache noob. If you want to host multiple http sites with multiple certificates, I leave it up to you to figure out how to do it. I can tell you that you can create and sign as many certificates as you want, just make sure you do not create a new certificate authority. The one and only certificate authority you created can sign all your certificates. And from what I understand, if more than one site uses SSL, each site will need a different IP address. Google is your friend. To be clear, you can host as many email domains as you need, but in my setup, I access all of them through one and only one http interface. Let's continue on...

Tell Postfix where to find the certificates (and set a couple other TLS parameters). We also make a backup of main.cf before we modify it for the first time:
cd /root/CA/
cp -i cert.sfa.example.com.pem /etc/ssl/certs

cp -i privkey.sfa.example.com.pem /etc/ssl/private

cp -i /etc/postfix/main.cf /etc/postfix/main.cf-11dec2010

postconf -e "smtpd_tls_cert_file = /etc/ssl/certs/cert.sfa.example.com.pem"
postconf -e "smtpd_tls_key_file = /etc/ssl/private/privkey.sfa.example.com.pem"
postconf -e "smtpd_tls_CAfile = /etc/ssl/certs/cacert.example.com.pem"
postconf -e "smtpd_tls_received_header = yes"
postfix reload
tail -f /var/log/mail.log


And make sure Postfix is still working OK. Running some of these commands again will result in overwriting keys and certificates. That may not be good. Some files will necessarily be overwritten if additional certificates are requested, signed and created. That is expected, and is the reason we make host-specific copies of everything as we go along. Just be careful not to overwrite any host-specific files we have created. And remember, only one Root Certificate Authority needs creation. Make a backup of the session, both on and off the system (transfer the directory via WinSCP).
cp -r /root/CA /root/CA-11jun2011



OPTIONAL Install Bind9

A local caching name server can improve performance of the server.
apt-get install bind9
/etc/init.d/bind9 stop
touch /var/cache/bind/managed-keys.bind
chown bind:bind /var/cache/bind/managed-keys.bind
/etc/init.d/bind9 start


Now edit /etc/resolv.conf. Change the IP address of the nameserver to be the IP address of this box. Place the current nameserver below what is now your primary server:
vi /etc/resolv.conf

The result would look similar to this:
search example.com
nameserver 192.168.1.222
nameserver 68.87.85.98


So far we have set up bind9 as a local caching only name server. Here we add an additional security measure that prevents unauthorized machines from using our name server:
vi /etc/bind/named.conf.options

On the line below "directory" we want to add a line that restricts use of our name server to the network our mailserver is on. Place a [Tab] in front of the entry so it lines up with the other entries. You can add more than one network here if you like. Place a ";" (semicolon) after each network. The network address shown is only an example.
allow-query {192.168.1.0/24;};

Fix a missing file:
touch /var/cache/bind/managed-keys.bind
chown bind:bind /var/cache/bind/managed-keys.bind


We need to suppress some logging:
vi /etc/bind/named.conf

And insert (below the first set of comments}:
logging {
category lame-servers {null; };
category edns-disabled { null; };
};


Save and exit the file, then I would restart bind9 and check that it is running:
/etc/init.d/bind9 restart
lsof -i | grep :domain


We will get a number of 'RFC 1918 response' related entries in our log unless we include the RFC 1918 zones:
vi /etc/bind/named.conf.local

Remove the comment marks "// " from the beginning of this option:
// include "/etc/bind/zones.rfc1918";

Then restart bind9 and check for errors:
/etc/init.d/bind9 restart
lsof -i | grep :domain
tail -27 /var/log/syslog


We added a new user to /etc/passwd so give Postfix a copy:
/etc/init.d/postfix restart

Check that we can resolve names:
dig yahoo.com

In the ANSWER SECTION you should see some A records with IP addresses and near the bottom the SERVER: should be this server.


What you should know regarding recipient verification on a Postfix relay server


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 that 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.

When you configure a Postfix email server as a firewall for another server (or servers), by default Postfix has no knowledge of whom the valid recipients are. Let's say we have two domains we relay mail to, 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 Postfix relay 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 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 relay domains. The question is - who will maintain the adding and deleting of email addresses?
vim /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

vim /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,
    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 in main.cf.

With the other domain (example.org on the Exchange server) we need to set up relay_recipient_maps. We will create a file called /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:
vim /etc/postfix/relay_recipients

@example.net 1
@example.org 1


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


Then of course:
postmap /etc/postfix/relay_recipients

The "1" after each entry could be something else, like "OK" 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


Don't forget to uncomment #unverified_recipient_reject_code = 550 once address verification is known to work as expected (assuming you are using reject_unverified_recipient via the verify_domains map). Then test, test, test. If you are using Exchange, there are some HOWTOs out there that may help with pulling data out of Active Directory:
http://verchick.com/mecham/public_html/spam/relay_recipients.html
http://verchick.com/mecham/public_html/spam/postfix_exchange.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

You can create a script that uses the Maia database to create the relay_recipients file. Here is a sample:
#!/bin/bash
# Extract e-mail addresses from Maia
mysql -umaia -pmaia_password maia -B -N -e "SELECT concat(email,' 1') FROM users" >/etc/postfix/relay_recipients.tmp1
# Remove any domain only addresses and check for duplicates
egrep -v ^@ /etc/postfix/relay_recipients.tmp1 | sort -u >/etc/postfix/relay_recipients.tmp
# If desired, add domains that CAN use reject_unlisted_recipient
echo "example.net 1" >> /etc/postfix/relay_recipients.tmp
echo "example.org 1" >> /etc/postfix/relay_recipients.tmp
# Make sure the file contains at least one valid address, otherwise exit
if ! grep -q garyv@example.com /etc/postfix/relay_recipients.tmp; then
  echo "there was a problem creating the relay_recipients map" 2>&1
  exit 1
else
  cp /etc/postfix/relay_recipients.tmp /etc/postfix/relay_recipients
  postmap /etc/postfix/relay_recipients.tmp
  cp /etc/postfix/relay_recipients.tmp.db /etc/postfix/relay_recipients.db
fi



Keep an eye out for errors in /var/log/apache2/error.log (Notices are simply Notices).
Note also that there is a new log file at /var/log/maia/process-quarantine.log (once there are items to process).

mr88talent at yahoo dot com
31 MAR 2012