Restoring mail server aliases
From CobaltFAQs
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
