Restoring mail server aliases

From CobaltFAQs

Jump to: navigation, search

The below procedure is based on one originally posted by Al-Juhani (aljuhani at zajil dot net) to the cobalt-users mailing list. I have made some changes to give the script more flexibility in dealing with hostnames other than www, addressing some other sections in /etc/mail/virtusertable, etc.

If you don't need all the explanation of each step, jump to the end for just the command list.

NOTE: This procedure does NOT address multiple mail server aliases for a given
domain. You will still have to enter those aliases via the admin UI.

For example, if www.example.com is also supposed to accept mail for www.example.net, the example.net and www.example.net aliases need to be added, in a comma-separated list, to the Mail Server Alias field for www.example.com.

If you have a lot of sites on your RaQ 4, manually restoring mail server aliases after losing/restoring the site admin UI pages could take LONG time. Because this information isn't stored in the PostgreSQL database, but is taken from the system files, we can easily make repairs using some command-line "scripts".

What we need to accomplish is adding each full hostname, and each domain name, to /etc/mail/local-host-names, as well as placing entries for each domain into a couple of places in /etc/mail/virtusertable. So let's get started!

Contents

Shell in and become root

You have to be root to edit these files. So SSH (preferable) or telnet (not secure) into your RaQ as admin then do

su -

to become root. Change directories to /etc/mail by doing

cd /etc/mail

I like to make backup files and work with them, instead of playing with "live" files. Once we're sure the temp file is what we want, we put it in place of the "live" file.

So we'll make working copies

cp local-host-names /tmp/tmp-lhn
cp virtusertable /tmp/vt

Add all domains to local-host-names

Append the "new" site info to the temp file:

ls -1 /home/sites | awk -F '.' ' {if ($0 != $1) {print $0; \
if ($4 != "") {print $2"."$3"."$4} else {print $2"."$3}}}' >> /tmp/tmp-lhn

This generates a list of all domains on the system, according to the symlink entries in /home/sites. The components $1 through $4 are derived when awk splits the full domain name (in $0) into pieces at the "."s We then do a couple of tests to see how we should output the result. The

if ($0 != $1)

test weeds out all the siteX and home entries in /home/sites, only continuing the script if there is a full domain name present. The

if ($4 != "")

test checks for domains like www.example.com.uk that have four parts to them, and makes sure we output correct parts (don't want to leave the .uk TLD off the end!). And of course the

>> /tmp/tmp-lhn

appends the output from this command to the file /tmp/tmp-lhn.

Now that we've made the temp file, we should remove any duplicate entries:

cat /tmp/tmp-lhn | uniq > /tmp/tmp-uniq-lhn

Now we can put this "clean" file in place of the old file:

mv /etc/mail/local-host-names /etc/mail/local-host-names.`date +%Y%m%d-%H%M`
mv /tmp/tmp-uniq-lhn /etc/mail/local-host-names

(That date command will append the current date/time to the filename in the format YYMMDD-HHMM - makes it easy to keep track of stuff later...)

Remember to clean up the other temp file

rm /tmp/tmp-lhn

Restart sendmail

Make sure the new /etc/mail/local-host-names is read and processed

/etc/rc.d/init.d/sendmail restart

Add all domains to virtusertable

Now that we've told the RaQ what domains it's allowed to accept email for, we need to tell it how to process mail for users within those domains. That's where /etc/mail/virtusertable comes in. There are a couple of sections to that file; we're mainly concerned with the mail routes and the generic catchall address sections.

Entries for mail routes are in the form:

@example.com %1@host.example.com

which means "mail arriving for user@example.com should be processed as mail to user@host.example.com" (which is then re-translated again by the lines

user@host.example.com localusername

which tells sendmail to put mail into the localusername spool in /home/spool/mail). So we just need a slight modification to the local-host-names procedure above to accomplish this:

ls -1 /home/sites | awk -F '.' ' {if ($0 != $1) {if ($4 != "") \
{print "@"$2"."$3"."$4"\t%1@"$0} else {print "@"$2"."$3"\t%1@"$0}}}' > /tmp/newvirt

This will create a file /tmp/newvirt containing what you need.

Now we need to make default catchall entries for each domain. These will be in the form

@host.example.com error:nouser No such user here

So mail to user@example.com will first be rewritten to be user@www.example.com. If there is a corresponding entry for that, it will be delivered to the local spool. If there isn't a corresponding user, we want the mail to bounce. Again tweaking what we've already done:

ls -1 /home/sites | awk -F '.' ' {if ($0 != $1) {print "@"$0"\terror:nouser No such user here"}}' > /tmp/catchall

Make additions to /tmp/vt

Add the two temp files we just made to /tmp/vt. /tmp/newvirt/ should be inserted below the comment which says

# accept-email-at-domain routes

You can do this in vi by moving the cursor to the appropriate location in the file and doing

:r /tmp/newvirt

(emacs uses C-x i, pico uses ^R)

Insert /tmp/catchall, using the same method, after the comment which says:

# catch-all aliases

Exit, saving your changes. Then build a hashed .db version of /tmp/vt by doing:

makemap -v hash /tmp/vt.db < /tmp/vt

Watch for any messages that read like

makemap: vt: line 53: key mailer-daemon@www.example.com: duplicate key

This means you have the same line twice in the file, which is illegal. In a hash file, there can be only a one-to-one relationship between keys and values. Make note of all the line numbers where there are duplicates, edit the file, and remove the duplicate lines. (For vi newbies, you can jump straight to a line number by doing

:xxx  [Enter]

where xxx is the line number.) Then do the makemap command again.

Hint: to make it easier to see the errors, you can do the makemap command with a grep filter and only show lines containing an error.

makemap -v hash /tmp/vt.db < /tmp/vt | grep duplicate

Repeat until makemap runs without errors. Then backup the original virtusertable files and put the temp files in their place.

mv /etc/mail/virtusertable /etc/mail/virtusertable.`date +%Y%m%d-%H%M`
mv /etc/mail/virtusertable.db /etc/mail/virtusertable.db.`date +%Y%m%d-%H%M`
mv /tmp/vt.db /etc/mail/virtusertable.db
mv /tmp/vt /etc/mail/virtusertable

You're done

All mail should be working properly at this point. Remember again to check for multiple aliases for domains that require them, and enter those via the Site Admin UI for each virtual site.

Shortcut for experts

This is the same stuff as above, but without all the step-by-step explanation.

su -
cd /etc/mail
cp local-host-names /tmp/tmp-lhn
cp virtusertable /tmp/vt

ls -1 /home/sites | awk -F '.' ' {if ($0 != $1) {print $0; \
if ($4 != "") {print $2"."$3"."$4} else {print $2"."$3}}}' > /tmp/tmp-lhn

cat /tmp/tmp-lhn | uniq > /tmp/tmp-uniq-lhn

mv /etc/mail/local-host-names /etc/mail/local-host-names.`date +%Y%m%d-%H%M`
mv /tmp/tmp-uniq-lhn /etc/mail/local-host-names
rm /tmp/tmp-lhn

/etc/rc.d/init.d/sendmail restart

ls -1 /home/sites | awk -F '.' ' {if ($0 != $1) {if ($4 != "") \
{print "@"$2"."$3"."$4"\t%1@"$0} else {print "@"$2"."$3"\t%1@"$0}}}' > /tmp/newvirt

ls -1 /home/sites | awk -F '.' ' {if ($0 != $1) {print "@"$0"\terror:nouser No such user here"}}' > /tmp/catchall

Add /tmp/newvirt into /tmp/vt below the # accept-email-at-domain routes comment line.
Add /tmp/catchall into /tmp/vt below the # catch-all aliases comment line.

makemap -v hash /tmp/vt.db < /tmp/vt | grep duplicate

Repeat above step until no duplicates are reported.

mv /etc/mail/virtusertable /etc/mail/virtusertable.`date +%Y%m%d-%H%M`
mv /etc/mail/virtusertable.db /etc/mail/virtusertable.db.`date +%Y%m%d-%H%M`
mv /tmp/vt.db /etc/mail/virtusertable.db
mv /tmp/vt /etc/mail/virtusertable
Personal tools